Drop main() prototype. Syncs with NetBSD-8
[minix.git] / minix / kernel / system / do_getinfo.c
blob98b5db40cbaf2d8ac8db79da90d2abd7f78e8eec
1 /* The kernel call implemented in this file:
2 * m_type: SYS_GETINFO
4 * The parameters for this kernel call are:
5 * m_lsys_krn_sys_getinfo.request (what info to get)
6 * m_lsys_krn_sys_getinfo.val_ptr (where to put it)
7 * m_lsys_krn_sys_getinfo.val_len (maximum length expected, optional)
8 * m_lsys_krn_sys_getinfo.val_ptr2 (second, optional pointer)
9 * m_lsys_krn_sys_getinfo.val_len2_e (second length or process nr)
11 * Upon return of the GETWHOAMI request the following parameters are used:
12 * m_krn_lsys_sys_getwhoami.endpt (the caller endpoint)
13 * m_krn_lsys_sys_getwhoami.privflags (the caller priviledes)
14 * m_krn_lsys_sys_getwhoami.initflags (the caller initflags)
15 * m_krn_lsys_sys_getwhoami.name (the caller process name)
19 #include <string.h>
21 #include "kernel/system.h"
24 #if USE_GETINFO
26 #include <minix/u64.h>
27 #include <sys/resource.h>
29 /*===========================================================================*
30 * update_idle_time *
31 *===========================================================================*/
32 static void update_idle_time(void)
34 int i;
35 struct proc * idl = proc_addr(IDLE);
37 idl->p_cycles = make64(0, 0);
39 for (i = 0; i < CONFIG_MAX_CPUS ; i++) {
40 idl->p_cycles += get_cpu_var(i, idle_proc).p_cycles;
44 /*===========================================================================*
45 * do_getinfo *
46 *===========================================================================*/
47 int do_getinfo(struct proc * caller, message * m_ptr)
49 /* Request system information to be copied to caller's address space. This
50 * call simply copies entire data structures to the caller.
52 size_t length;
53 vir_bytes src_vir;
54 int nr_e, nr, r;
55 int wipe_rnd_bin = -1;
56 struct proc *p;
57 struct rusage r_usage;
59 /* Set source address and length based on request type. */
60 switch (m_ptr->m_lsys_krn_sys_getinfo.request) {
61 case GET_MACHINE: {
62 length = sizeof(struct machine);
63 src_vir = (vir_bytes) &machine;
64 break;
66 case GET_KINFO: {
67 length = sizeof(struct kinfo);
68 src_vir = (vir_bytes) &kinfo;
69 break;
71 case GET_LOADINFO: {
72 length = sizeof(struct loadinfo);
73 src_vir = (vir_bytes) &kloadinfo;
74 break;
76 case GET_CPUINFO: {
77 length = sizeof(cpu_info);
78 src_vir = (vir_bytes) &cpu_info;
79 break;
81 case GET_HZ: {
82 length = sizeof(system_hz);
83 src_vir = (vir_bytes) &system_hz;
84 break;
86 case GET_IMAGE: {
87 length = sizeof(struct boot_image) * NR_BOOT_PROCS;
88 src_vir = (vir_bytes) image;
89 break;
91 case GET_IRQHOOKS: {
92 length = sizeof(struct irq_hook) * NR_IRQ_HOOKS;
93 src_vir = (vir_bytes) irq_hooks;
94 break;
96 case GET_PROCTAB: {
97 update_idle_time();
98 length = sizeof(struct proc) * (NR_PROCS + NR_TASKS);
99 src_vir = (vir_bytes) proc;
100 break;
102 case GET_PRIVTAB: {
103 length = sizeof(struct priv) * (NR_SYS_PROCS);
104 src_vir = (vir_bytes) priv;
105 break;
107 case GET_PROC: {
108 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ?
109 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e;
110 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
111 length = sizeof(struct proc);
112 src_vir = (vir_bytes) proc_addr(nr);
113 break;
115 case GET_PRIV: {
116 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ?
117 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e;
118 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
119 length = sizeof(struct priv);
120 src_vir = (vir_bytes) priv_addr(nr_to_id(nr));
121 break;
123 case GET_REGS: {
124 nr_e = (m_ptr->m_lsys_krn_sys_getinfo.val_len2_e == SELF) ?
125 caller->p_endpoint : m_ptr->m_lsys_krn_sys_getinfo.val_len2_e;
126 if(!isokendpt(nr_e, &nr)) return EINVAL; /* validate request */
127 p = proc_addr(nr);
128 length = sizeof(p->p_reg);
129 src_vir = (vir_bytes) &p->p_reg;
130 break;
132 case GET_WHOAMI: {
133 int len;
134 m_ptr->m_krn_lsys_sys_getwhoami.endpt = caller->p_endpoint;
135 len = MIN(sizeof(m_ptr->m_krn_lsys_sys_getwhoami.name),
136 sizeof(caller->p_name))-1;
137 strncpy(m_ptr->m_krn_lsys_sys_getwhoami.name, caller->p_name, len);
138 m_ptr->m_krn_lsys_sys_getwhoami.name[len] = '\0';
139 m_ptr->m_krn_lsys_sys_getwhoami.privflags = priv(caller)->s_flags;
140 m_ptr->m_krn_lsys_sys_getwhoami.initflags = priv(caller)->s_init_flags;
141 return OK;
143 case GET_MONPARAMS: {
144 src_vir = (vir_bytes) kinfo.param_buf;
145 length = sizeof(kinfo.param_buf);
146 break;
148 case GET_RANDOMNESS: {
149 static struct k_randomness copy; /* copy to keep counters */
150 int i;
152 copy = krandom;
153 for (i= 0; i<RANDOM_SOURCES; i++) {
154 krandom.bin[i].r_size = 0; /* invalidate random data */
155 krandom.bin[i].r_next = 0;
157 length = sizeof(copy);
158 src_vir = (vir_bytes) &copy;
159 break;
161 case GET_RANDOMNESS_BIN: {
162 int bin = m_ptr->m_lsys_krn_sys_getinfo.val_len2_e;
164 if(bin < 0 || bin >= RANDOM_SOURCES) {
165 printf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin);
166 return EINVAL;
169 if(krandom.bin[bin].r_size < RANDOM_ELEMENTS)
170 return ENOENT;
172 length = sizeof(krandom.bin[bin]);
173 src_vir = (vir_bytes) &krandom.bin[bin];
175 wipe_rnd_bin = bin;
177 break;
179 case GET_IRQACTIDS: {
180 length = sizeof(irq_actids);
181 src_vir = (vir_bytes) irq_actids;
182 break;
184 case GET_IDLETSC: {
185 struct proc * idl;
186 update_idle_time();
187 idl = proc_addr(IDLE);
188 length = sizeof(idl->p_cycles);
189 src_vir = (vir_bytes) &idl->p_cycles;
190 break;
192 case GET_CPUTICKS: {
193 uint64_t ticks[MINIX_CPUSTATES];
194 unsigned int cpu;
195 cpu = (unsigned int)m_ptr->m_lsys_krn_sys_getinfo.val_len2_e;
196 if (cpu >= CONFIG_MAX_CPUS)
197 return EINVAL;
198 get_cpu_ticks(cpu, ticks);
199 length = sizeof(ticks);
200 src_vir = (vir_bytes)ticks;
201 break;
203 default:
204 printf("do_getinfo: invalid request %d\n",
205 m_ptr->m_lsys_krn_sys_getinfo.request);
206 return(EINVAL);
209 /* Try to make the actual copy for the requested data. */
210 if (m_ptr->m_lsys_krn_sys_getinfo.val_len > 0 &&
211 length > m_ptr->m_lsys_krn_sys_getinfo.val_len)
212 return (E2BIG);
214 r = data_copy_vmcheck(caller, KERNEL, src_vir, caller->p_endpoint,
215 m_ptr->m_lsys_krn_sys_getinfo.val_ptr, length);
217 if(r != OK) return r;
219 if(wipe_rnd_bin >= 0 && wipe_rnd_bin < RANDOM_SOURCES) {
220 krandom.bin[wipe_rnd_bin].r_size = 0;
221 krandom.bin[wipe_rnd_bin].r_next = 0;
224 return(OK);
227 #endif /* USE_GETINFO */