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