xref: /minix3/minix/fs/procfs/root.c (revision 3956ee9eeda988648c3f2092c7d31faa0a0e7294)
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