only check local benchmark dir if it exists
[minix.git] / kernel / system / do_getinfo.c
blob93f88eac79620404957ed055af6a276df5d3439b
1 /* The kernel call implemented in this file:
2 * m_type: SYS_GETINFO
4 * The parameters for this kernel call are:
5 * m1_i3: I_REQUEST (what info to get)
6 * m1_p1: I_VAL_PTR (where to put it)
7 * m1_i1: I_VAL_LEN (maximum length expected, optional)
8 * m1_p2: I_VAL_PTR2 (second, optional pointer)
9 * m1_i2: I_VAL_LEN2_E (second length or process nr)
12 #include <string.h>
13 #include <minix/endpoint.h>
15 #include "../system.h"
18 #if USE_GETINFO
20 /*===========================================================================*
21 * do_getinfo *
22 *===========================================================================*/
23 PUBLIC int do_getinfo(struct proc * caller, message * m_ptr)
25 /* Request system information to be copied to caller's address space. This
26 * call simply copies entire data structures to the caller.
28 size_t length;
29 vir_bytes src_vir;
30 int nr_e, nr, r;
31 int wipe_rnd_bin = -1;
32 struct exec e_hdr;
34 /* Set source address and length based on request type. */
35 switch (m_ptr->I_REQUEST) {
36 case GET_MACHINE: {
37 length = sizeof(struct machine);
38 src_vir = (vir_bytes) &machine;
39 break;
41 case GET_KINFO: {
42 length = sizeof(struct kinfo);
43 src_vir = (vir_bytes) &kinfo;
44 break;
46 case GET_LOADINFO: {
47 length = sizeof(struct loadinfo);
48 src_vir = (vir_bytes) &kloadinfo;
49 break;
51 case GET_HZ: {
52 length = sizeof(system_hz);
53 src_vir = (vir_bytes) &system_hz;
54 break;
56 case GET_IMAGE: {
57 length = sizeof(struct boot_image) * NR_BOOT_PROCS;
58 src_vir = (vir_bytes) image;
59 break;
61 case GET_IRQHOOKS: {
62 length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
63 src_vir = (vir_bytes) irq_hooks;
64 break;
66 case GET_PROCTAB: {
67 length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
68 src_vir = (vir_bytes) proc;
69 break;
71 case GET_PRIVTAB: {
72 length = sizeof(struct priv) * (NR_SYS_PROCS);
73 src_vir = (vir_bytes) priv;
74 break;
76 case GET_PROC: {
77 nr_e = (m_ptr->I_VAL_LEN2_E == SELF) ?
78 caller->p_endpoint : m_ptr->I_VAL_LEN2_E;
79 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
80 length = sizeof(struct proc);
81 src_vir = (vir_bytes) proc_addr(nr);
82 break;
84 case GET_PRIV: {
85 nr_e = (m_ptr->I_VAL_LEN2_E == SELF) ?
86 caller->p_endpoint : m_ptr->I_VAL_LEN2_E;
87 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
88 length = sizeof(struct priv);
89 src_vir = (vir_bytes) priv_addr(nr_to_id(nr));
90 break;
92 case GET_WHOAMI: {
93 int len;
94 /* GET_WHOAMI uses m3 and only uses the message contents for info. */
95 m_ptr->GIWHO_EP = caller->p_endpoint;
96 len = MIN(sizeof(m_ptr->GIWHO_NAME), sizeof(caller->p_name))-1;
97 strncpy(m_ptr->GIWHO_NAME, caller->p_name, len);
98 m_ptr->GIWHO_NAME[len] = '\0';
99 return OK;
101 case GET_MONPARAMS: {
102 src_vir = (vir_bytes) params_buffer;
103 length = sizeof(params_buffer);
104 break;
106 case GET_RANDOMNESS: {
107 static struct k_randomness copy; /* copy to keep counters */
108 int i;
110 copy = krandom;
111 for (i= 0; i<RANDOM_SOURCES; i++) {
112 krandom.bin[i].r_size = 0; /* invalidate random data */
113 krandom.bin[i].r_next = 0;
115 length = sizeof(copy);
116 src_vir = (vir_bytes) &copy;
117 break;
119 case GET_RANDOMNESS_BIN: {
120 int bin = m_ptr->I_VAL_LEN2_E;
122 if(bin < 0 || bin >= RANDOM_SOURCES) {
123 kprintf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin);
124 return EINVAL;
127 if(krandom.bin[bin].r_size < RANDOM_ELEMENTS)
128 return ENOENT;
130 length = sizeof(krandom.bin[bin]);
131 src_vir = (vir_bytes) &krandom.bin[bin];
133 wipe_rnd_bin = bin;
135 break;
137 case GET_KMESSAGES: {
138 length = sizeof(struct kmessages);
139 src_vir = (vir_bytes) &kmess;
140 break;
142 #if DEBUG_TIME_LOCKS
143 case GET_LOCKTIMING: {
144 length = sizeof(timingdata);
145 src_vir = (vir_bytes) timingdata;
146 break;
148 #endif
149 case GET_IRQACTIDS: {
150 length = sizeof(irq_actids);
151 src_vir = (vir_bytes) irq_actids;
152 break;
154 case GET_IDLETSC: {
155 #ifdef CONFIG_IDLE_TSC
156 length = sizeof(idle_tsc);
157 src_vir = (vir_bytes) &idle_tsc;
158 break;
159 #else
160 kprintf("do_getinfo: kernel not compiled with CONFIG_IDLE_TSC\n");
161 return(EINVAL);
162 #endif
164 case GET_AOUTHEADER: {
165 int hdrindex, index = m_ptr->I_VAL_LEN2_E;
166 if(index < 0 || index >= NR_BOOT_PROCS) {
167 return EINVAL;
169 if (iskerneln(_ENDPOINT_P(image[index].endpoint))) {
170 hdrindex = 0;
171 } else {
172 hdrindex = 1 + index-NR_TASKS;
174 arch_get_aout_headers(hdrindex, &e_hdr);
175 length = sizeof(e_hdr);
176 src_vir = (vir_bytes) &e_hdr;
177 break;
180 default:
181 kprintf("do_getinfo: invalid request %d\n", m_ptr->I_REQUEST);
182 return(EINVAL);
185 /* Try to make the actual copy for the requested data. */
186 if (m_ptr->I_VAL_LEN > 0 && length > m_ptr->I_VAL_LEN) return (E2BIG);
187 r = data_copy_vmcheck(caller, SYSTEM, src_vir, caller->p_endpoint,
188 (vir_bytes) m_ptr->I_VAL_PTR, length);
190 if(r != OK) return r;
192 if(wipe_rnd_bin >= 0 && wipe_rnd_bin < RANDOM_SOURCES) {
193 krandom.bin[wipe_rnd_bin].r_size = 0;
194 krandom.bin[wipe_rnd_bin].r_next = 0;
197 return(OK);
200 #endif /* USE_GETINFO */