1 /* The kernel call implemented in this file:
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)
14 #include "kernel/system.h"
19 #include <minix/u64.h>
20 #include <sys/resource.h>
22 /*===========================================================================*
24 *===========================================================================*/
25 static void update_idle_time(void)
28 struct proc
* idl
= proc_addr(IDLE
);
30 idl
->p_cycles
= make64(0, 0);
32 for (i
= 0; i
< CONFIG_MAX_CPUS
; i
++) {
33 idl
->p_cycles
+= get_cpu_var(i
, idle_proc
).p_cycles
;
37 /*===========================================================================*
39 *===========================================================================*/
40 int do_getinfo(struct proc
* caller
, message
* m_ptr
)
42 /* Request system information to be copied to caller's address space. This
43 * call simply copies entire data structures to the caller.
48 int wipe_rnd_bin
= -1;
50 struct rusage r_usage
;
52 /* Set source address and length based on request type. */
53 switch (m_ptr
->I_REQUEST
) {
55 length
= sizeof(struct machine
);
56 src_vir
= (vir_bytes
) &machine
;
60 length
= sizeof(struct kinfo
);
61 src_vir
= (vir_bytes
) &kinfo
;
65 length
= sizeof(struct loadinfo
);
66 src_vir
= (vir_bytes
) &kloadinfo
;
70 length
= sizeof(cpu_info
);
71 src_vir
= (vir_bytes
) &cpu_info
;
75 length
= sizeof(system_hz
);
76 src_vir
= (vir_bytes
) &system_hz
;
80 length
= sizeof(struct boot_image
) * NR_BOOT_PROCS
;
81 src_vir
= (vir_bytes
) image
;
85 length
= sizeof(struct irq_hook
) * NR_IRQ_HOOKS
;
86 src_vir
= (vir_bytes
) irq_hooks
;
91 length
= sizeof(struct proc
) * (NR_PROCS
+ NR_TASKS
);
92 src_vir
= (vir_bytes
) proc
;
96 length
= sizeof(struct priv
) * (NR_SYS_PROCS
);
97 src_vir
= (vir_bytes
) priv
;
101 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
102 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
103 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
104 length
= sizeof(struct proc
);
105 src_vir
= (vir_bytes
) proc_addr(nr
);
109 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
110 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
111 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
112 length
= sizeof(struct priv
);
113 src_vir
= (vir_bytes
) priv_addr(nr_to_id(nr
));
117 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
118 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
119 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
121 length
= sizeof(p
->p_reg
);
122 src_vir
= (vir_bytes
) &p
->p_reg
;
127 /* GET_WHOAMI uses m3 and only uses the message contents for info. */
128 m_ptr
->GIWHO_EP
= caller
->p_endpoint
;
129 len
= MIN(sizeof(m_ptr
->GIWHO_NAME
), sizeof(caller
->p_name
))-1;
130 strncpy(m_ptr
->GIWHO_NAME
, caller
->p_name
, len
);
131 m_ptr
->GIWHO_NAME
[len
] = '\0';
132 m_ptr
->GIWHO_PRIVFLAGS
= priv(caller
)->s_flags
;
135 case GET_MONPARAMS
: {
136 src_vir
= (vir_bytes
) kinfo
.param_buf
;
137 length
= sizeof(kinfo
.param_buf
);
140 case GET_RANDOMNESS
: {
141 static struct k_randomness copy
; /* copy to keep counters */
145 for (i
= 0; i
<RANDOM_SOURCES
; i
++) {
146 krandom
.bin
[i
].r_size
= 0; /* invalidate random data */
147 krandom
.bin
[i
].r_next
= 0;
149 length
= sizeof(copy
);
150 src_vir
= (vir_bytes
) ©
;
153 case GET_RANDOMNESS_BIN
: {
154 int bin
= m_ptr
->I_VAL_LEN2_E
;
156 if(bin
< 0 || bin
>= RANDOM_SOURCES
) {
157 printf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin
);
161 if(krandom
.bin
[bin
].r_size
< RANDOM_ELEMENTS
)
164 length
= sizeof(krandom
.bin
[bin
]);
165 src_vir
= (vir_bytes
) &krandom
.bin
[bin
];
171 case GET_IRQACTIDS
: {
172 length
= sizeof(irq_actids
);
173 src_vir
= (vir_bytes
) irq_actids
;
179 idl
= proc_addr(IDLE
);
180 length
= sizeof(idl
->p_cycles
);
181 src_vir
= (vir_bytes
) &idl
->p_cycles
;
185 struct proc
*target
= NULL
;
188 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
189 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
191 if (!isokendpt(nr_e
, &target_slot
))
194 target
= proc_addr(target_slot
);
195 if (isemptyp(target
))
198 length
= sizeof(r_usage
);
199 memset(&r_usage
, 0, sizeof(r_usage
));
200 usec
= target
->p_user_time
* 1000000 / system_hz
;
201 r_usage
.ru_utime
.tv_sec
= usec
/ 1000000;
202 r_usage
.ru_utime
.tv_usec
= usec
% 100000;
203 usec
= target
->p_sys_time
* 1000000 / system_hz
;
204 r_usage
.ru_stime
.tv_sec
= usec
/ 1000000;
205 r_usage
.ru_stime
.tv_usec
= usec
% 100000;
206 r_usage
.ru_nsignals
= target
->p_signal_received
;
207 src_vir
= (vir_bytes
) &r_usage
;
211 printf("do_getinfo: invalid request %d\n", m_ptr
->I_REQUEST
);
215 /* Try to make the actual copy for the requested data. */
216 if (m_ptr
->I_VAL_LEN
> 0 && length
> m_ptr
->I_VAL_LEN
) return (E2BIG
);
217 r
= data_copy_vmcheck(caller
, KERNEL
, src_vir
, caller
->p_endpoint
,
218 (vir_bytes
) m_ptr
->I_VAL_PTR
, length
);
220 if(r
!= OK
) return r
;
222 if(wipe_rnd_bin
>= 0 && wipe_rnd_bin
< RANDOM_SOURCES
) {
223 krandom
.bin
[wipe_rnd_bin
].r_size
= 0;
224 krandom
.bin
[wipe_rnd_bin
].r_next
= 0;
230 #endif /* USE_GETINFO */