1 /* ProcFS - root.c - generators for static files in the root directory */ 2 3 #include "inc.h" 4 5 #if defined (__i386__) 6 #include <machine/pci.h> 7 #endif 8 #include <minix/dmap.h> 9 10 static void root_hz(void); 11 static void root_uptime(void); 12 static void root_loadavg(void); 13 static void root_kinfo(void); 14 static void root_meminfo(void); 15 #if defined(__i386__) 16 static void root_pci(void); 17 #endif 18 static void root_dmap(void); 19 static void root_ipcvecs(void); 20 static void root_mounts(void); 21 22 struct file root_files[] = { 23 { "hz", REG_ALL_MODE, (data_t) root_hz }, 24 { "uptime", REG_ALL_MODE, (data_t) root_uptime }, 25 { "loadavg", REG_ALL_MODE, (data_t) root_loadavg }, 26 { "kinfo", REG_ALL_MODE, (data_t) root_kinfo }, 27 { "meminfo", REG_ALL_MODE, (data_t) root_meminfo }, 28 #if defined(__i386__) 29 { "pci", REG_ALL_MODE, (data_t) root_pci }, 30 #endif 31 { "dmap", REG_ALL_MODE, (data_t) root_dmap }, 32 #if defined(__i386__) 33 { "cpuinfo", REG_ALL_MODE, (data_t) root_cpuinfo }, 34 #endif 35 { "ipcvecs", REG_ALL_MODE, (data_t) root_ipcvecs }, 36 { "mounts", REG_ALL_MODE, (data_t) root_mounts }, 37 { NULL, 0, NULL } 38 }; 39 40 /* 41 * Print the system clock frequency. 42 */ 43 static void 44 root_hz(void) 45 { 46 47 buf_printf("%lu\n", (unsigned long)sys_hz()); 48 } 49 50 /* 51 * Print load averages. 52 */ 53 static void 54 root_loadavg(void) 55 { 56 struct load loads[3]; 57 ldiv_t avg[3]; 58 59 if (procfs_getloadavg(loads, 3) != 3) 60 return; 61 62 avg[0] = ldiv(100L * loads[0].proc_load / loads[0].ticks, 100); 63 avg[1] = ldiv(100L * loads[1].proc_load / loads[1].ticks, 100); 64 avg[2] = ldiv(100L * loads[2].proc_load / loads[2].ticks, 100); 65 66 buf_printf("%ld.%02ld %ld.%02ld %ld.%02ld\n", 67 avg[0].quot, avg[0].rem, avg[1].quot, avg[1].rem, 68 avg[2].quot, avg[2].rem); 69 } 70 71 /* 72 * Print the current uptime. 73 */ 74 static void 75 root_uptime(void) 76 { 77 ldiv_t division; 78 79 division = ldiv(100L * getticks() / sys_hz(), 100L); 80 81 buf_printf("%ld.%0.2ld\n", division.quot, division.rem); 82 } 83 84 /* 85 * Print general kernel information. 86 */ 87 static void 88 root_kinfo(void) 89 { 90 struct kinfo kinfo; 91 92 if (sys_getkinfo(&kinfo) != OK) 93 return; 94 95 buf_printf("%u %u\n", kinfo.nr_procs, kinfo.nr_tasks); 96 } 97 98 /* 99 * Print general memory information. 100 */ 101 static void 102 root_meminfo(void) 103 { 104 struct vm_stats_info vsi; 105 106 if (vm_info_stats(&vsi) != OK) 107 return; 108 109 buf_printf("%u %lu %lu %lu %lu\n", vsi.vsi_pagesize, vsi.vsi_total, 110 vsi.vsi_free, vsi.vsi_largest, vsi.vsi_cached); 111 } 112 113 #if defined(__i386__) 114 /* 115 * Print information about PCI devices present in the system. 116 */ 117 static void 118 root_pci(void) 119 { 120 u16_t vid, did, subvid, subdid; 121 u8_t bcr, scr, pifr, rev; 122 char *slot_name, *dev_name; 123 int r, devind; 124 static int first = TRUE; 125 126 /* This should be taken care of behind the scenes by the PCI lib. */ 127 if (first) { 128 pci_init(); 129 first = FALSE; 130 } 131 132 /* Iterate over all devices, printing info for each of them. */ 133 r = pci_first_dev(&devind, &vid, &did); 134 while (r == 1) { 135 slot_name = pci_slot_name(devind); 136 dev_name = pci_dev_name(vid, did); 137 138 bcr = pci_attr_r8(devind, PCI_BCR); 139 scr = pci_attr_r8(devind, PCI_SCR); 140 pifr = pci_attr_r8(devind, PCI_PIFR); 141 rev = pci_attr_r8(devind, PCI_REV); 142 subvid = pci_attr_r16(devind, PCI_SUBVID); 143 subdid = pci_attr_r16(devind, PCI_SUBDID); 144 145 buf_printf("%s %x/%x/%x/%x %04X:%04X:%04X:%04X %s\n", 146 slot_name ? slot_name : "-1.-1.-1.-1", 147 bcr, scr, pifr, rev, 148 vid, did, subvid, subdid, 149 dev_name ? dev_name : ""); 150 151 r = pci_next_dev(&devind, &vid, &did); 152 } 153 } 154 #endif /* defined(__i386__) */ 155 156 /* 157 * Print a list of drivers that have been assigned major device numbers. 158 */ 159 static void 160 root_dmap(void) 161 { 162 struct dmap dmap[NR_DEVICES]; 163 int i; 164 165 if (getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap, sizeof(dmap)) != OK) 166 return; 167 168 for (i = 0; i < NR_DEVICES; i++) { 169 if (dmap[i].dmap_driver == NONE) 170 continue; 171 172 buf_printf("%u %s %u\n", i, dmap[i].dmap_label, 173 dmap[i].dmap_driver); 174 } 175 } 176 177 /* 178 * Print a list of IPC vectors with their addresses. 179 */ 180 static void 181 root_ipcvecs(void) 182 { 183 extern struct minix_ipcvecs _minix_ipcvecs; 184 185 /* 186 * Only print this if the kernel provides the info; otherwise binaries 187 * will be using their own in-libc vectors that are normal symbols in 188 * the binary. 189 */ 190 if (!(get_minix_kerninfo()->ki_flags & MINIX_KIF_IPCVECS)) 191 return; 192 193 /* 194 * Print the vectors with an descriptive name and the additional (k) 195 * to distinguish them from regular symbols. 196 */ 197 #define PRINT_ENTRYPOINT(name) \ 198 buf_printf("%08lx T %s(k)\n", \ 199 (unsigned long)_minix_ipcvecs.name, #name) 200 201 PRINT_ENTRYPOINT(sendrec); 202 PRINT_ENTRYPOINT(send); 203 PRINT_ENTRYPOINT(notify); 204 PRINT_ENTRYPOINT(senda); 205 PRINT_ENTRYPOINT(sendnb); 206 PRINT_ENTRYPOINT(receive); 207 PRINT_ENTRYPOINT(do_kernel_call); 208 } 209 210 /* 211 * Print the list of mounted file systems. 212 */ 213 static void 214 root_mounts(void) 215 { 216 struct statvfs buf[NR_MNTS]; 217 int i, count; 218 219 if ((count = getvfsstat(buf, sizeof(buf), ST_NOWAIT)) < 0) 220 return; 221 222 for (i = 0; i < count; i++) { 223 buf_printf("%s on %s type %s (%s)\n", buf[i].f_mntfromname, 224 buf[i].f_mntonname, buf[i].f_fstypename, 225 (buf[i].f_flag & ST_RDONLY) ? "ro" : "rw"); 226 } 227 } 228