- Timestamp:
- 2006-06-06T07:40:51Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0dbc4e7
- Parents:
- 6f9a9bc
- Location:
- generic
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/interrupt.h
r6f9a9bc r874621f 33 33 #include <typedefs.h> 34 34 #include <arch/types.h> 35 #include <proc/task.h> 36 #include <proc/thread.h> 37 #include <arch.h> 38 #include <console/klog.h> 39 #include <ipc/irq.h> 35 40 36 41 #ifndef IVT_ITEMS … … 42 47 #endif 43 48 49 #define fault_if_from_uspace(istate, cmd, ...) \ 50 { \ 51 if (istate_from_uspace(istate)) { \ 52 klog_printf(cmd, ##__VA_ARGS__); \ 53 klog_printf("Task %lld got exception at PC:%P. Task killed.", TASK->taskid, istate_get_pc(istate)); \ 54 task_kill(TASK->taskid); \ 55 thread_exit(); \ 56 } \ 57 } 58 59 44 60 extern iroutine exc_register(int n, const char *name, iroutine f); 45 61 extern void exc_dispatch(int n, istate_t *t); -
generic/include/ipc/irq.h
r6f9a9bc r874621f 30 30 #define __IRQ_H__ 31 31 32 /** Maximum length of IPC IRQ program */ 32 33 #define IRQ_MAX_PROG_SIZE 10 34 35 /** Reserved 'virtual' messages for kernel notifications */ 36 #define IPC_IRQ_RESERVED_VIRTUAL 10 37 38 #define IPC_IRQ_KLOG (-1) 33 39 34 40 typedef enum { … … 60 66 #ifdef KERNEL 61 67 68 #include <ipc/ipc.h> 69 62 70 extern void ipc_irq_make_table(int irqcount); 63 71 extern int ipc_irq_register(answerbox_t *box, int irq, irq_code_t *ucode); 64 72 extern void ipc_irq_send_notif(int irq); 73 extern void ipc_irq_send_msg(int irq, __native a2, __native a3); 65 74 extern void ipc_irq_unregister(answerbox_t *box, int irq); 66 75 extern void irq_ipc_bind_arch(__native irq); -
generic/include/ipc/sysipc.h
r6f9a9bc r874621f 48 48 __native method, __native arg1); 49 49 __native sys_ipc_hangup(int phoneid); 50 __native sys_ipc_register_irq( __nativeirq, irq_code_t *ucode);51 __native sys_ipc_unregister_irq( __nativeirq);50 __native sys_ipc_register_irq(int irq, irq_code_t *ucode); 51 __native sys_ipc_unregister_irq(int irq); 52 52 53 53 #endif -
generic/include/proc/thread.h
r6f9a9bc r874621f 151 151 extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task, int flags, char *name); 152 152 extern void thread_ready(thread_t *t); 153 extern void thread_exit(void) ;153 extern void thread_exit(void) __attribute__((noreturn)); 154 154 155 155 #ifndef thread_create_arch -
generic/include/stackarg.h
r6f9a9bc r874621f 50 50 (*((type *)((ap).last + ((ap).pos += sizeof(type) ) - sizeof(type)))) 51 51 52 #define va_copy(dst,src) dst=src 52 53 #define va_end(ap) 53 54 -
generic/include/stdarg.h
r6f9a9bc r874621f 41 41 #define va_arg(ap, type) __builtin_va_arg(ap, type) 42 42 #define va_end(ap) __builtin_va_end(ap) 43 #define va_copy(dst,src) __builtin_va_copy(dst,src) 43 44 44 45 #endif -
generic/src/interrupt/interrupt.c
r6f9a9bc r874621f 91 91 static void exc_undef(int n, istate_t *istate) 92 92 { 93 fault_if_from_uspace(istate, "Unhandled exception %d.", n); 93 94 panic("Unhandled exception %d.", n); 94 95 } -
generic/src/ipc/ipc.c
r6f9a9bc r874621f 336 336 list_append(&request->link, &box->dispatched_calls); 337 337 } else { 338 /* This can happen regularly after ipc_cleanup, remove 339 * the warning in the future when the IPC is 340 * more debugged */ 341 printf("WARNING: Spurious IPC wakeup.\n"); 338 /* This can happen regularly after ipc_cleanup */ 342 339 spinlock_unlock(&box->lock); 343 340 goto restart; -
generic/src/ipc/irq.c
r6f9a9bc r874621f 157 157 { 158 158 ipl_t ipl; 159 int mq = irq + IPC_IRQ_RESERVED_VIRTUAL; 159 160 160 161 ipl = interrupts_disable(); 161 spinlock_lock(&irq_conns[ irq].lock);162 if (irq_conns[ irq].box == box) {163 irq_conns[ irq].box = NULL;164 code_free(irq_conns[ irq].code);165 irq_conns[ irq].code = NULL;166 } 167 168 spinlock_unlock(&irq_conns[ irq].lock);162 spinlock_lock(&irq_conns[mq].lock); 163 if (irq_conns[mq].box == box) { 164 irq_conns[mq].box = NULL; 165 code_free(irq_conns[mq].code); 166 irq_conns[mq].code = NULL; 167 } 168 169 spinlock_unlock(&irq_conns[mq].lock); 169 170 interrupts_restore(ipl); 170 171 } … … 175 176 ipl_t ipl; 176 177 irq_code_t *code; 178 int mq = irq + IPC_IRQ_RESERVED_VIRTUAL; 177 179 178 180 ASSERT(irq_conns); … … 186 188 187 189 ipl = interrupts_disable(); 188 spinlock_lock(&irq_conns[ irq].lock);189 190 if (irq_conns[ irq].box) {191 spinlock_unlock(&irq_conns[ irq].lock);190 spinlock_lock(&irq_conns[mq].lock); 191 192 if (irq_conns[mq].box) { 193 spinlock_unlock(&irq_conns[mq].lock); 192 194 interrupts_restore(ipl); 193 195 code_free(code); 194 196 return EEXISTS; 195 197 } 196 irq_conns[ irq].box = box;197 irq_conns[ irq].code = code;198 atomic_set(&irq_conns[ irq].counter, 0);199 spinlock_unlock(&irq_conns[ irq].lock);198 irq_conns[mq].box = box; 199 irq_conns[mq].code = code; 200 atomic_set(&irq_conns[mq].counter, 0); 201 spinlock_unlock(&irq_conns[mq].lock); 200 202 interrupts_restore(ipl); 201 203 … … 203 205 } 204 206 205 /** Notify process that an irq had happend 206 * 207 * We expect interrupts to be disabled 208 */ 209 void ipc_irq_send_notif(int irq) 207 /** Add call to proper answerbox queue 208 * 209 * Assume irq_conns[mq].lock is locked */ 210 static void send_call(int mq, call_t *call) 211 { 212 spinlock_lock(&irq_conns[mq].box->irq_lock); 213 list_append(&call->link, &irq_conns[mq].box->irq_notifs); 214 spinlock_unlock(&irq_conns[mq].box->irq_lock); 215 216 waitq_wakeup(&irq_conns[mq].box->wq, 0); 217 } 218 219 /** Send notification message 220 * 221 */ 222 void ipc_irq_send_msg(int irq, __native a2, __native a3) 210 223 { 211 224 call_t *call; 212 213 ASSERT(irq_conns); 214 spinlock_lock(&irq_conns[ irq].lock);215 216 if (irq_conns[ irq].box) {225 int mq = irq + IPC_IRQ_RESERVED_VIRTUAL; 226 227 spinlock_lock(&irq_conns[mq].lock); 228 229 if (irq_conns[mq].box) { 217 230 call = ipc_call_alloc(FRAME_ATOMIC); 218 231 if (!call) { 219 spinlock_unlock(&irq_conns[ irq].lock);232 spinlock_unlock(&irq_conns[mq].lock); 220 233 return; 221 234 } … … 223 236 IPC_SET_METHOD(call->data, IPC_M_INTERRUPT); 224 237 IPC_SET_ARG1(call->data, irq); 225 IPC_SET_ARG3(call->data, atomic_preinc(&irq_conns[irq].counter)); 238 IPC_SET_ARG2(call->data, a2); 239 IPC_SET_ARG3(call->data, a3); 240 241 send_call(mq, call); 242 } 243 spinlock_unlock(&irq_conns[mq].lock); 244 } 245 246 /** Notify process that an irq had happend 247 * 248 * We expect interrupts to be disabled 249 */ 250 void ipc_irq_send_notif(int irq) 251 { 252 call_t *call; 253 int mq = irq + IPC_IRQ_RESERVED_VIRTUAL; 254 255 ASSERT(irq_conns); 256 spinlock_lock(&irq_conns[mq].lock); 257 258 if (irq_conns[mq].box) { 259 call = ipc_call_alloc(FRAME_ATOMIC); 260 if (!call) { 261 spinlock_unlock(&irq_conns[mq].lock); 262 return; 263 } 264 call->flags |= IPC_CALL_NOTIF; 265 IPC_SET_METHOD(call->data, IPC_M_INTERRUPT); 266 IPC_SET_ARG1(call->data, irq); 267 IPC_SET_ARG3(call->data, atomic_preinc(&irq_conns[mq].counter)); 226 268 227 269 /* Execute code to handle irq */ 228 code_execute(call, irq_conns[irq].code); 229 230 spinlock_lock(&irq_conns[irq].box->irq_lock); 231 list_append(&call->link, &irq_conns[irq].box->irq_notifs); 232 spinlock_unlock(&irq_conns[irq].box->irq_lock); 233 234 waitq_wakeup(&irq_conns[irq].box->wq, 0); 235 } 270 code_execute(call, irq_conns[mq].code); 236 271 237 spinlock_unlock(&irq_conns[irq].lock); 238 } 239 240 241 /** Initialize table of interrupt handlers */ 272 send_call(mq, call); 273 } 274 275 spinlock_unlock(&irq_conns[mq].lock); 276 } 277 278 279 /** Initialize table of interrupt handlers 280 * 281 * @param irqcount Count of required hardware IRQs to be supported 282 */ 242 283 void ipc_irq_make_table(int irqcount) 243 284 { 244 285 int i; 286 287 irqcount += IPC_IRQ_RESERVED_VIRTUAL; 245 288 246 289 irq_conns_size = irqcount; -
generic/src/ipc/sysipc.c
r6f9a9bc r874621f 554 554 555 555 /** Connect irq handler to task */ 556 __native sys_ipc_register_irq( __nativeirq, irq_code_t *ucode)556 __native sys_ipc_register_irq(int irq, irq_code_t *ucode) 557 557 { 558 558 if (!(cap_get(TASK) & CAP_IRQ_REG)) 559 559 return EPERM; 560 560 561 if (irq >= IRQ_COUNT )561 if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL) 562 562 return (__native) ELIMIT; 563 563 564 564 irq_ipc_bind_arch(irq); 565 565 … … 568 568 569 569 /* Disconnect irq handler from task */ 570 __native sys_ipc_unregister_irq( __nativeirq)570 __native sys_ipc_unregister_irq(int irq) 571 571 { 572 572 if (!(cap_get(TASK) & CAP_IRQ_REG)) 573 573 return EPERM; 574 574 575 if (irq >= IRQ_COUNT )575 if (irq >= IRQ_COUNT || irq <= -IPC_IRQ_RESERVED_VIRTUAL) 576 576 return (__native) ELIMIT; 577 577 -
generic/src/main/main.c
r6f9a9bc r874621f 75 75 #include <macros.h> 76 76 #include <adt/btree.h> 77 #include <console/klog.h> 77 78 78 79 #ifdef CONFIG_SMP … … 219 220 thread_init(); 220 221 futex_init(); 222 klog_init(); 221 223 222 224 for (i = 0; i < init.cnt; i++) -
generic/src/proc/thread.c
r6f9a9bc r874621f 389 389 spinlock_unlock(&THREAD->lock); 390 390 scheduler(); 391 392 /* Not reached */ 393 while (1) 394 ; 391 395 } 392 396
Note:
See TracChangeset
for help on using the changeset viewer.