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>
21 /*===========================================================================*
23 *===========================================================================*/
24 static void update_idle_time(void)
27 struct proc
* idl
= proc_addr(IDLE
);
29 idl
->p_cycles
= make64(0, 0);
31 for (i
= 0; i
< CONFIG_MAX_CPUS
; i
++) {
32 idl
->p_cycles
= add64(idl
->p_cycles
,
33 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;
51 /* Set source address and length based on request type. */
52 switch (m_ptr
->I_REQUEST
) {
54 length
= sizeof(struct machine
);
55 src_vir
= (vir_bytes
) &machine
;
59 length
= sizeof(struct kinfo
);
60 src_vir
= (vir_bytes
) &kinfo
;
64 length
= sizeof(struct loadinfo
);
65 src_vir
= (vir_bytes
) &kloadinfo
;
69 length
= sizeof(cpu_info
);
70 src_vir
= (vir_bytes
) &cpu_info
;
74 length
= sizeof(system_hz
);
75 src_vir
= (vir_bytes
) &system_hz
;
79 length
= sizeof(struct boot_image
) * NR_BOOT_PROCS
;
80 src_vir
= (vir_bytes
) image
;
84 length
= sizeof(struct irq_hook
) * NR_IRQ_HOOKS
;
85 src_vir
= (vir_bytes
) irq_hooks
;
90 length
= sizeof(struct proc
) * (NR_PROCS
+ NR_TASKS
);
91 src_vir
= (vir_bytes
) proc
;
95 length
= sizeof(struct priv
) * (NR_SYS_PROCS
);
96 src_vir
= (vir_bytes
) priv
;
100 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
101 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
102 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
103 length
= sizeof(struct proc
);
104 src_vir
= (vir_bytes
) proc_addr(nr
);
108 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
109 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
110 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
111 length
= sizeof(struct priv
);
112 src_vir
= (vir_bytes
) priv_addr(nr_to_id(nr
));
116 nr_e
= (m_ptr
->I_VAL_LEN2_E
== SELF
) ?
117 caller
->p_endpoint
: m_ptr
->I_VAL_LEN2_E
;
118 if(!isokendpt(nr_e
, &nr
)) return EINVAL
; /* validate request */
120 length
= sizeof(p
->p_reg
);
121 src_vir
= (vir_bytes
) &p
->p_reg
;
126 /* GET_WHOAMI uses m3 and only uses the message contents for info. */
127 m_ptr
->GIWHO_EP
= caller
->p_endpoint
;
128 len
= MIN(sizeof(m_ptr
->GIWHO_NAME
), sizeof(caller
->p_name
))-1;
129 strncpy(m_ptr
->GIWHO_NAME
, caller
->p_name
, len
);
130 m_ptr
->GIWHO_NAME
[len
] = '\0';
131 m_ptr
->GIWHO_PRIVFLAGS
= priv(caller
)->s_flags
;
134 case GET_MONPARAMS
: {
135 src_vir
= (vir_bytes
) kinfo
.param_buf
;
136 length
= sizeof(kinfo
.param_buf
);
139 case GET_RANDOMNESS
: {
140 static struct k_randomness copy
; /* copy to keep counters */
144 for (i
= 0; i
<RANDOM_SOURCES
; i
++) {
145 krandom
.bin
[i
].r_size
= 0; /* invalidate random data */
146 krandom
.bin
[i
].r_next
= 0;
148 length
= sizeof(copy
);
149 src_vir
= (vir_bytes
) ©
;
152 case GET_RANDOMNESS_BIN
: {
153 int bin
= m_ptr
->I_VAL_LEN2_E
;
155 if(bin
< 0 || bin
>= RANDOM_SOURCES
) {
156 printf("SYSTEM: GET_RANDOMNESS_BIN: %d out of range\n", bin
);
160 if(krandom
.bin
[bin
].r_size
< RANDOM_ELEMENTS
)
163 length
= sizeof(krandom
.bin
[bin
]);
164 src_vir
= (vir_bytes
) &krandom
.bin
[bin
];
170 case GET_IRQACTIDS
: {
171 length
= sizeof(irq_actids
);
172 src_vir
= (vir_bytes
) irq_actids
;
178 idl
= proc_addr(IDLE
);
179 length
= sizeof(idl
->p_cycles
);
180 src_vir
= (vir_bytes
) &idl
->p_cycles
;
184 printf("do_getinfo: invalid request %d\n", m_ptr
->I_REQUEST
);
188 /* Try to make the actual copy for the requested data. */
189 if (m_ptr
->I_VAL_LEN
> 0 && length
> m_ptr
->I_VAL_LEN
) return (E2BIG
);
190 r
= data_copy_vmcheck(caller
, KERNEL
, src_vir
, caller
->p_endpoint
,
191 (vir_bytes
) m_ptr
->I_VAL_PTR
, length
);
193 if(r
!= OK
) return r
;
195 if(wipe_rnd_bin
>= 0 && wipe_rnd_bin
< RANDOM_SOURCES
) {
196 krandom
.bin
[wipe_rnd_bin
].r_size
= 0;
197 krandom
.bin
[wipe_rnd_bin
].r_next
= 0;
203 #endif /* USE_GETINFO */