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 | ||