Rev 2823 | Rev 2825 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2823 | Rev 2824 | ||
---|---|---|---|
Line 187... | Line 187... | ||
187 | task_t *ta; |
187 | task_t *ta; |
188 | void *uspace_buffer; |
188 | void *uspace_buffer; |
189 | unative_t to_copy; |
189 | unative_t to_copy; |
190 | int rc; |
190 | int rc; |
191 | istate_t *state; |
191 | istate_t *state; |
- | 192 | istate_t state_copy; |
|
- | 193 | ipl_t ipl; |
|
192 | 194 | ||
193 | klog_printf("debug_regs_read()"); |
195 | klog_printf("debug_regs_read()"); |
194 | // FIXME: verify task/thread state |
196 | // FIXME: verify task/thread state |
195 | 197 | ||
196 | state = THREAD->uspace_state; |
- | |
197 | if (state == NULL) { |
- | |
198 | klog_printf("debug_regs_read() - istate not available"); |
- | |
199 | return EBUSY; |
- | |
200 | } |
- | |
201 | - | ||
202 | ta = get_lock_callee_task(phone); |
198 | ta = get_lock_callee_task(phone); |
- | 199 | spinlock_unlock(&ta->lock); |
|
- | 200 | ||
- | 201 | ipl = interrupts_disable(); |
|
- | 202 | spinlock_lock(&threads_lock); |
|
- | 203 | ||
203 | t = (thread_t *) IPC_GET_ARG2(call->data); |
204 | t = (thread_t *) IPC_GET_ARG2(call->data); |
204 | if (!thread_exists(t)) { |
205 | if (!thread_exists(t)) { |
205 | spinlock_unlock(&ta->lock); |
- | |
206 | return ENOENT; |
206 | return ENOENT; |
207 | } |
207 | } |
208 | 208 | ||
- | 209 | state = t->uspace_state; |
|
- | 210 | if (state == NULL) { |
|
- | 211 | spinlock_unlock(&threads_lock); |
|
- | 212 | interrupts_restore(ipl); |
|
- | 213 | klog_printf("debug_regs_read() - istate not available"); |
|
- | 214 | return EBUSY; |
|
- | 215 | } |
|
- | 216 | ||
- | 217 | /* Copy to a local buffer so that we can release the lock */ |
|
- | 218 | memcpy(&state_copy, state, sizeof(state_copy)); |
|
- | 219 | spinlock_unlock(&threads_lock); |
|
- | 220 | interrupts_restore(ipl); |
|
- | 221 | ||
209 | uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
222 | uspace_buffer = (void *)IPC_GET_ARG3(call->data); |
210 | to_copy = IPC_GET_ARG4(call->data); |
223 | to_copy = IPC_GET_ARG4(call->data); |
211 | if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t); |
224 | if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t); |
212 | 225 | ||
213 | rc = copy_to_uspace(uspace_buffer, t->uspace_state, to_copy); |
226 | rc = copy_to_uspace(uspace_buffer, &state_copy, to_copy); |
214 | if (rc != 0) { |
227 | if (rc != 0) { |
215 | spinlock_unlock(&ta->lock); |
228 | spinlock_unlock(&ta->lock); |
216 | klog_printf("debug_regs_read() - copy failed"); |
229 | klog_printf("debug_regs_read() - copy failed"); |
217 | return rc; |
230 | return rc; |
218 | } |
231 | } |
219 | 232 | ||
220 | spinlock_unlock(&ta->lock); |
- | |
221 | - | ||
222 | IPC_SET_ARG1(call->data, to_copy); |
233 | IPC_SET_ARG1(call->data, to_copy); |
223 | IPC_SET_ARG2(call->data, sizeof(istate_t)); |
234 | IPC_SET_ARG2(call->data, sizeof(istate_t)); |
224 | 235 | ||
225 | klog_printf("debug_regs_read() done"); |
236 | klog_printf("debug_regs_read() done"); |
226 | return 1; /* actually need becksend with retval 0 */ |
237 | return 1; /* actually need becksend with retval 0 */ |
Line 232... | Line 243... | ||
232 | task_t *ta; |
243 | task_t *ta; |
233 | void *uspace_data; |
244 | void *uspace_data; |
234 | unative_t to_copy; |
245 | unative_t to_copy; |
235 | int rc; |
246 | int rc; |
236 | istate_t *state; |
247 | istate_t *state; |
- | 248 | istate_t data_copy; |
|
- | 249 | ipl_t ipl; |
|
237 | 250 | ||
238 | klog_printf("debug_regs_write()"); |
251 | klog_printf("debug_regs_write()"); |
239 | // FIXME: verify task/thread state |
- | |
240 | 252 | ||
241 | state = THREAD->uspace_state; |
- | |
242 | if (state == NULL) { |
- | |
243 | klog_printf("debug_regs_write() - istate not available"); |
- | |
244 | return EBUSY; |
- | |
245 | } |
- | |
246 | - | ||
247 | ta = get_lock_callee_task(phone); |
253 | /* First copy to a local buffer */ |
248 | t = (thread_t *) IPC_GET_ARG2(call->data); |
- | |
249 | if (!thread_exists(t)) { |
- | |
250 | spinlock_unlock(&ta->lock); |
- | |
251 | return ENOENT; |
- | |
252 | } |
- | |
253 | 254 | ||
254 | uspace_data = (void *)IPC_GET_ARG3(call->data); |
255 | uspace_data = (void *)IPC_GET_ARG3(call->data); |
255 | to_copy = IPC_GET_ARG4(call->data); |
256 | to_copy = IPC_GET_ARG4(call->data); |
256 | if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t); |
257 | if (to_copy > sizeof(istate_t)) to_copy = sizeof(istate_t); |
257 | 258 | ||
258 | rc = copy_from_uspace(t->uspace_state, uspace_data, to_copy); |
259 | rc = copy_from_uspace(&data_copy, uspace_data, to_copy); |
259 | if (rc != 0) { |
260 | if (rc != 0) { |
260 | spinlock_unlock(&ta->lock); |
- | |
261 | klog_printf("debug_regs_write() - copy failed"); |
261 | klog_printf("debug_regs_write() - copy failed"); |
262 | return rc; |
262 | return rc; |
263 | } |
263 | } |
264 | 264 | ||
- | 265 | // FIXME: verify task/thread state |
|
- | 266 | ||
- | 267 | ta = get_lock_callee_task(phone); |
|
265 | spinlock_unlock(&ta->lock); |
268 | spinlock_unlock(&ta->lock); |
266 | 269 | ||
- | 270 | /* Now try to change the thread's uspace_state */ |
|
- | 271 | ||
- | 272 | ipl = interrupts_disable(); |
|
- | 273 | spinlock_lock(&threads_lock); |
|
- | 274 | ||
- | 275 | t = (thread_t *) IPC_GET_ARG2(call->data); |
|
- | 276 | if (!thread_exists(t)) { |
|
- | 277 | spinlock_unlock(&threads_lock); |
|
- | 278 | interrupts_restore(ipl); |
|
- | 279 | return ENOENT; |
|
- | 280 | } |
|
- | 281 | ||
- | 282 | state = t->uspace_state; |
|
- | 283 | if (state == NULL) { |
|
- | 284 | spinlock_unlock(&threads_lock); |
|
- | 285 | interrupts_restore(ipl); |
|
- | 286 | klog_printf("debug_regs_write() - istate not available"); |
|
- | 287 | return EBUSY; |
|
- | 288 | } |
|
- | 289 | ||
- | 290 | memcpy(t->uspace_state, &data_copy, sizeof(t->uspace_state)); |
|
- | 291 | ||
- | 292 | spinlock_unlock(&threads_lock); |
|
- | 293 | interrupts_restore(ipl); |
|
- | 294 | ||
- | 295 | /* Set answer values */ |
|
- | 296 | ||
267 | IPC_SET_ARG1(call->data, to_copy); |
297 | IPC_SET_ARG1(call->data, to_copy); |
268 | IPC_SET_ARG2(call->data, sizeof(istate_t)); |
298 | IPC_SET_ARG2(call->data, sizeof(istate_t)); |
269 | 299 | ||
270 | klog_printf("debug_regs_write() done"); |
300 | klog_printf("debug_regs_write() done"); |
271 | return 1; /* actually need becksend with retval 0 */ |
301 | return 1; /* actually need becksend with retval 0 */ |
Line 277... | Line 307... | ||
277 | link_t *cur; |
307 | link_t *cur; |
278 | task_t *ta; |
308 | task_t *ta; |
279 | unative_t *uspace_buffer; |
309 | unative_t *uspace_buffer; |
280 | unative_t to_copy; |
310 | unative_t to_copy; |
281 | int rc; |
311 | int rc; |
282 | unsigned copied, total; |
312 | unsigned total_bytes; |
283 | unsigned buf_size; |
313 | unsigned buf_size; |
284 | unative_t tid; |
314 | unative_t tid; |
- | 315 | unsigned num_threads, copied_ids; |
|
- | 316 | ipl_t ipl; |
|
- | 317 | unative_t *buffer; |
|
- | 318 | int flags; |
|
285 | 319 | ||
286 | klog_printf("debug_thread_read()"); |
320 | klog_printf("debug_thread_read()"); |
287 | // FIXME: verify task/thread state |
321 | // FIXME: verify task/thread state |
288 | 322 | ||
- | 323 | ipl = interrupts_disable(); |
|
289 | ta = get_lock_callee_task(phone); |
324 | ta = get_lock_callee_task(phone); |
290 | klog_printf("task %llu", ta->taskid); |
- | |
291 | - | ||
292 | uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
- | |
293 | buf_size = IPC_GET_ARG3(call->data); |
- | |
294 | 325 | ||
- | 326 | /* Count the threads first */ |
|
- | 327 | ||
295 | copied = total = 0; |
328 | num_threads = 0; |
296 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
329 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
297 | t = list_get_instance(cur, thread_t, th_link); |
330 | /* Count all threads, to be on the safe side */ |
- | 331 | ++num_threads; |
|
- | 332 | } |
|
298 | 333 | ||
299 | /* Not interested in kernel threads */ |
334 | /* Allocate a buffer and copy down the threads' ids */ |
300 | if ((t->flags & THREAD_FLAG_USPACE) == 0) |
335 | buffer = malloc(num_threads * sizeof(unative_t), 0); // ??? |
301 | continue; |
- | |
302 | 336 | ||
- | 337 | copied_ids = 0; |
|
303 | /* Using thread struct pointer for identification */ |
338 | for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
304 | tid = (unative_t) t; |
339 | t = list_get_instance(cur, thread_t, th_link); |
305 | 340 | ||
306 | to_copy = sizeof(unative_t); |
341 | spinlock_lock(&t->lock); |
307 | if (copied + to_copy >= buf_size) |
- | |
308 | to_copy = buf_size - copied; |
- | |
309 | - | ||
310 | if (to_copy > 0) { |
342 | flags = t->flags; |
311 | rc = copy_to_uspace(uspace_buffer, &tid, to_copy); |
- | |
312 | if (rc != 0) { |
- | |
313 | spinlock_unlock(&ta->lock); |
343 | spinlock_unlock(&t->lock); |
314 | klog_printf("debug_thread_read() - copy failed"); |
- | |
315 | return rc; |
- | |
316 | } |
- | |
317 | } |
- | |
318 | 344 | ||
319 | ++uspace_buffer; |
345 | /* Not interested in kernel threads */ |
- | 346 | if ((flags & THREAD_FLAG_USPACE) != 0) { |
|
- | 347 | /* Using thread struct pointer for identification */ |
|
320 | total += sizeof(unative_t); |
348 | tid = (unative_t) t; |
321 | copied += to_copy; |
349 | buffer[copied_ids++] = tid; |
- | 350 | } |
|
322 | } |
351 | } |
323 | 352 | ||
324 | spinlock_unlock(&ta->lock); |
353 | spinlock_unlock(&ta->lock); |
- | 354 | interrupts_restore(ipl); |
|
- | 355 | ||
- | 356 | /* Now copy to userspace */ |
|
- | 357 | ||
- | 358 | uspace_buffer = (void *)IPC_GET_ARG2(call->data); |
|
- | 359 | buf_size = IPC_GET_ARG3(call->data); |
|
325 | 360 | ||
- | 361 | total_bytes = copied_ids * sizeof(unative_t); |
|
- | 362 | ||
- | 363 | if (buf_size > total_bytes) |
|
- | 364 | to_copy = total_bytes; |
|
- | 365 | else |
|
- | 366 | to_copy = buf_size; |
|
- | 367 | ||
- | 368 | rc = copy_to_uspace(uspace_buffer, buffer, to_copy); |
|
- | 369 | free(buffer); |
|
- | 370 | ||
- | 371 | if (rc != 0) { |
|
- | 372 | klog_printf("debug_thread_read() - copy failed"); |
|
- | 373 | return rc; |
|
- | 374 | } |
|
- | 375 | ||
326 | IPC_SET_ARG1(call->data, copied); |
376 | IPC_SET_ARG1(call->data, to_copy); |
327 | IPC_SET_ARG2(call->data, total); |
377 | IPC_SET_ARG2(call->data, total_bytes); |
328 | 378 | ||
329 | klog_printf("debug_thread_read() done"); |
379 | klog_printf("debug_thread_read() done"); |
330 | return 1; /* actually need becksend with retval 0 */ |
380 | return 1; /* actually need becksend with retval 0 */ |
331 | } |
381 | } |
332 | 382 |