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 clock_t ticks; 78 ldiv_t division; 79 80 if (getticks(&ticks) != OK) 81 return; 82 division = ldiv(100L * ticks / sys_hz(), 100L); 83 84 buf_printf("%ld.%0.2ld\n", division.quot, division.rem); 85 } 86 87 /* 88 * Print general kernel information. 89 */ 90 static void 91 root_kinfo(void) 92 { 93 struct kinfo kinfo; 94 95 if (sys_getkinfo(&kinfo) != OK) 96 return; 97 98 buf_printf("%u %u\n", kinfo.nr_procs, kinfo.nr_tasks); 99 } 100 101 /* 102 * Print general memory information. 103 */ 104 static void 105 root_meminfo(void) 106 { 107 struct vm_stats_info vsi; 108 109 if (vm_info_stats(&vsi) != OK) 110 return; 111 112 buf_printf("%u %lu %lu %lu %lu\n", vsi.vsi_pagesize, vsi.vsi_total, 113 vsi.vsi_free, vsi.vsi_largest, vsi.vsi_cached); 114 } 115 116 #if defined(__i386__) 117 /* 118 * Print information about PCI devices present in the system. 119 */ 120 static void 121 root_pci(void) 122 { 123 u16_t vid, did, subvid, subdid; 124 u8_t bcr, scr, pifr, rev; 125 char *slot_name, *dev_name; 126 int r, devind; 127 static int first = TRUE; 128 129 /* This should be taken care of behind the scenes by the PCI lib. */ 130 if (first) { 131 pci_init(); 132 first = FALSE; 133 } 134 135 /* Iterate over all devices, printing info for each of them. */ 136 r = pci_first_dev(&devind, &vid, &did); 137 while (r == 1) { 138 slot_name = pci_slot_name(devind); 139 dev_name = pci_dev_name(vid, did); 140 141 bcr = pci_attr_r8(devind, PCI_BCR); 142 scr = pci_attr_r8(devind, PCI_SCR); 143 pifr = pci_attr_r8(devind, PCI_PIFR); 144 rev = pci_attr_r8(devind, PCI_REV); 145 subvid = pci_attr_r16(devind, PCI_SUBVID); 146 subdid = pci_attr_r16(devind, PCI_SUBDID); 147 148 buf_printf("%s %x/%x/%x/%x %04X:%04X:%04X:%04X %s\n", 149 slot_name ? slot_name : "-1.-1.-1.-1", 150 bcr, scr, pifr, rev, 151 vid, did, subvid, subdid, 152 dev_name ? dev_name : ""); 153 154 r = pci_next_dev(&devind, &vid, &did); 155 } 156 } 157 #endif /* defined(__i386__) */ 158 159 /* 160 * Print a list of drivers that have been assigned major device numbers. 161 */ 162 static void 163 root_dmap(void) 164 { 165 struct dmap dmap[NR_DEVICES]; 166 int i; 167 168 if (getsysinfo(VFS_PROC_NR, SI_DMAP_TAB, dmap, sizeof(dmap)) != OK) 169 return; 170 171 for (i = 0; i < NR_DEVICES; i++) { 172 if (dmap[i].dmap_driver == NONE) 173 continue; 174 175 buf_printf("%u %s %u\n", i, dmap[i].dmap_label, 176 dmap[i].dmap_driver); 177 } 178 } 179 180 /* 181 * Print a list of IPC vectors with their addresses. 182 */ 183 static void 184 root_ipcvecs(void) 185 { 186 extern struct minix_kerninfo *_minix_kerninfo; 187 extern struct minix_ipcvecs _minix_ipcvecs; 188 189 /* 190 * Only print this if the kernel provides the info; otherwise binaries 191 * will be using their own in-libc vectors that are normal symbols in 192 * the binary. 193 */ 194 if (!_minix_kerninfo || 195 !(_minix_kerninfo->ki_flags & MINIX_KIF_IPCVECS)) 196 return; 197 198 /* 199 * Print the vectors with an descriptive name and the additional (k) 200 * to distinguish them from regular symbols. 201 */ 202 #define PRINT_ENTRYPOINT(name) \ 203 buf_printf("%08lx T %s(k)\n", \ 204 (unsigned long)_minix_ipcvecs.name, #name) 205 206 PRINT_ENTRYPOINT(sendrec); 207 PRINT_ENTRYPOINT(send); 208 PRINT_ENTRYPOINT(notify); 209 PRINT_ENTRYPOINT(senda); 210 PRINT_ENTRYPOINT(sendnb); 211 PRINT_ENTRYPOINT(receive); 212 PRINT_ENTRYPOINT(do_kernel_call); 213 } 214 215 /* 216 * Print the list of mounted file systems. 217 */ 218 static void 219 root_mounts(void) 220 { 221 struct statvfs buf[NR_MNTS]; 222 int i, count; 223 224 if ((count = getvfsstat(buf, sizeof(buf), ST_NOWAIT)) < 0) 225 return; 226 227 for (i = 0; i < count; i++) { 228 buf_printf("%s on %s type %s (%s)\n", buf[i].f_mntfromname, 229 buf[i].f_mntonname, buf[i].f_fstypename, 230 (buf[i].f_flag & ST_RDONLY) ? "ro" : "rw"); 231 } 232 } 233