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
root_hz(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
root_loadavg(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
root_uptime(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
root_kinfo(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
root_meminfo(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
root_pci(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
root_dmap(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
root_ipcvecs(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
root_mounts(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