1 /* The kernel call implemented in this file:
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)
21 #include "kernel/system.h"
26 #include <minix/u64.h>
27 #include <sys/resource.h>
29 /*===========================================================================*
31 *===========================================================================*/
32 static void update_idle_time(void)
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 /*===========================================================================*
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.
55 int wipe_rnd_bin
= -1;
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
) {
62 length
= sizeof(struct machine
);
63 src_vir
= (vir_bytes
) &machine
;
67 length
= sizeof(struct kinfo
);
68 src_vir
= (vir_bytes
) &kinfo
;
72 length
= sizeof(struct loadinfo
);
73 src_vir
= (vir_bytes
) &kloadinfo
;
77 length
= sizeof(cpu_info
);
78 src_vir
= (vir_bytes
) &cpu_info
;
82 length
= sizeof(system_hz
);
83 src_vir
= (vir_bytes
) &system_hz
;
87 length
= sizeof(struct boot_image
) * NR_BOOT_PROCS
;
88 src_vir
= (vir_bytes
) image
;
92 length
= sizeof(struct irq_hook
) * NR_IRQ_HOOKS
;
93 src_vir
= (vir_bytes
) irq_hooks
;
98 length
= sizeof(struct proc
) * (NR_PROCS
+ NR_TASKS
);
99 src_vir
= (vir_bytes
) proc
;
103 length
= sizeof(struct priv
) * (NR_SYS_PROCS
);
104 src_vir
= (vir_bytes
) priv
;
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
);
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
));
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 */
128 length
= sizeof(p
->p_reg
);
129 src_vir
= (vir_bytes
) &p
->p_reg
;
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
;
143 case GET_MONPARAMS
: {
144 src_vir
= (vir_bytes
) kinfo
.param_buf
;
145 length
= sizeof(kinfo
.param_buf
);
148 case GET_RANDOMNESS
: {
149 static struct k_randomness copy
; /* copy to keep counters */
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
) ©
;
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
);
169 if(krandom
.bin
[bin
].r_size
< RANDOM_ELEMENTS
)
172 length
= sizeof(krandom
.bin
[bin
]);
173 src_vir
= (vir_bytes
) &krandom
.bin
[bin
];
179 case GET_IRQACTIDS
: {
180 length
= sizeof(irq_actids
);
181 src_vir
= (vir_bytes
) irq_actids
;
187 idl
= proc_addr(IDLE
);
188 length
= sizeof(idl
->p_cycles
);
189 src_vir
= (vir_bytes
) &idl
->p_cycles
;
193 uint64_t ticks
[MINIX_CPUSTATES
];
195 cpu
= (unsigned int)m_ptr
->m_lsys_krn_sys_getinfo
.val_len2_e
;
196 if (cpu
>= CONFIG_MAX_CPUS
)
198 get_cpu_ticks(cpu
, ticks
);
199 length
= sizeof(ticks
);
200 src_vir
= (vir_bytes
)ticks
;
204 printf("do_getinfo: invalid request %d\n",
205 m_ptr
->m_lsys_krn_sys_getinfo
.request
);
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
)
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;
227 #endif /* USE_GETINFO */