Changeset cea12e9 in mainline
- Timestamp:
- 2006-10-27T11:13:13Z (18 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 16d71f41
- Parents:
- 8c84448
- Location:
- kernel
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/ia32/include/interrupt.h
r8c84448 rcea12e9 46 46 47 47 #define IVT_EXCBASE 0 48 #define IVT_IRQBASE (IVT_EXCBASE +EXC_COUNT)49 #define IVT_FREEBASE (IVT_IRQBASE+IRQ_COUNT)48 #define IVT_IRQBASE (IVT_EXCBASE + EXC_COUNT) 49 #define IVT_FREEBASE (IVT_IRQBASE + IRQ_COUNT) 50 50 51 #define IRQ_CLK 052 #define IRQ_KBD 153 #define IRQ_PIC1 251 #define IRQ_CLK 0 52 #define IRQ_KBD 1 53 #define IRQ_PIC1 2 54 54 #define IRQ_PIC_SPUR 7 55 55 56 56 /* this one must have four least significant bits set to ones */ 57 #define VECTOR_APIC_SPUR (IVT_ITEMS -1)57 #define VECTOR_APIC_SPUR (IVT_ITEMS - 1) 58 58 59 #if (((VECTOR_APIC_SPUR + 1) %16) || VECTOR_APIC_SPUR >= IVT_ITEMS)59 #if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS) 60 60 #error Wrong definition of VECTOR_APIC_SPUR 61 61 #endif 62 62 63 #define VECTOR_DEBUG 1 64 #define VECTOR_PIC_SPUR (IVT_IRQBASE+IRQ_PIC_SPUR) 65 #define VECTOR_CLK (IVT_IRQBASE+IRQ_CLK) 66 #define VECTOR_KBD (IVT_IRQBASE+IRQ_KBD) 67 68 #define VECTOR_SYSCALL (IVT_FREEBASE+0) 69 #define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE+1) 70 #define VECTOR_DEBUG_IPI (IVT_FREEBASE+2) 63 #define VECTOR_DEBUG 1 64 #define VECTOR_CLK (IVT_IRQBASE + IRQ_CLK) 65 #define VECTOR_PIC_SPUR (IVT_IRQBASE + IRQ_PIC_SPUR) 66 #define VECTOR_SYSCALL IVT_FREEBASE 67 #define VECTOR_TLB_SHOOTDOWN_IPI (IVT_FREEBASE + 1) 68 #define VECTOR_DEBUG_IPI (IVT_FREEBASE + 2) 71 69 72 70 struct istate { … … 111 109 extern void (* eoi_function)(void); 112 110 113 extern void PRINT_INFO_ERRCODE(istate_t *istate); 114 extern void null_interrupt(int n, istate_t *istate); 115 extern void gp_fault(int n, istate_t *istate); 116 extern void nm_fault(int n, istate_t *istate); 117 extern void ss_fault(int n, istate_t *istate); 118 extern void simd_fp_exception(int n, istate_t *istate); 119 extern void syscall(int n, istate_t *istate); 120 extern void tlb_shootdown_ipi(int n, istate_t *istate); 121 111 extern void decode_istate(istate_t *istate); 112 extern void interrupt_init(void); 122 113 extern void trap_virtual_enable_irqs(uint16_t irqmask); 123 114 extern void trap_virtual_disable_irqs(uint16_t irqmask); 124 extern void trap_virtual_eoi(void);125 115 126 116 #endif -
kernel/arch/ia32/src/drivers/i8254.c
r8c84448 rcea12e9 50 50 #include <arch.h> 51 51 #include <time/delay.h> 52 #include <interrupt.h> 52 #include <ddi/irq.h> 53 #include <ddi/device.h> 53 54 54 55 #define CLK_PORT1 0x40 … … 58 59 #define MAGIC_NUMBER 1194 59 60 60 static void i8254_interrupt(int n, istate_t *istate); 61 static irq_t i8254_irq; 62 63 static irq_ownership_t i8254_claim(void) 64 { 65 return IRQ_ACCEPT; 66 } 67 68 static void i8254_irq_handler(irq_t *irq, void *arg, ...) 69 { 70 clock(); 71 } 61 72 62 73 void i8254_init(void) 63 74 { 75 irq_initialize(&i8254_irq); 76 i8254_irq.devno = device_assign_devno(); 77 i8254_irq.inr = IRQ_CLK; 78 i8254_irq.claim = i8254_claim; 79 i8254_irq.handler = i8254_irq_handler; 80 irq_register(&i8254_irq); 81 64 82 i8254_normal_operation(); 65 83 } … … 68 86 { 69 87 outb(CLK_PORT4, 0x36); 70 pic_disable_irqs(1<<IRQ_CLK); 71 outb(CLK_PORT1, (CLK_CONST/HZ) & 0xf); 72 outb(CLK_PORT1, (CLK_CONST/HZ) >> 8); 73 pic_enable_irqs(1<<IRQ_CLK); 74 exc_register(VECTOR_CLK, "i8254_clock", (iroutine) i8254_interrupt); 88 pic_disable_irqs(1 << IRQ_CLK); 89 outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf); 90 outb(CLK_PORT1, (CLK_CONST / HZ) >> 8); 91 pic_enable_irqs(1 << IRQ_CLK); 75 92 } 76 93 … … 130 147 } 131 148 132 void i8254_interrupt(int n, istate_t *istate)133 {134 trap_virtual_eoi();135 clock();136 }137 138 149 /** @} 139 150 */ -
kernel/arch/ia32/src/ia32.c
r8c84448 rcea12e9 58 58 #include <arch/mm/memory_init.h> 59 59 #include <interrupt.h> 60 #include <ddi/irq.h> 60 61 #include <arch/debugger.h> 61 62 #include <proc/thread.h> 62 63 #include <syscall/syscall.h> 63 64 #include <console/console.h> 65 #include <ddi/device.h> 64 66 65 67 #ifdef CONFIG_SMP … … 72 74 73 75 if (config.cpu_active == 1) { 76 interrupt_init(); 74 77 bios_init(); 75 i8259_init(); /* PIC */76 i8254_init(); /* hard clock */77 78 78 exc_register(VECTOR_SYSCALL, "syscall", (iroutine) syscall); 79 80 #ifdef CONFIG_SMP 81 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", 82 (iroutine) tlb_shootdown_ipi); 83 #endif /* CONFIG_SMP */ 79 /* PIC */ 80 i8259_init(); 84 81 } 85 82 } … … 88 85 { 89 86 if (config.cpu_active == 1) { 87 /* Initialize IRQ routing */ 88 irq_init(IRQ_COUNT, IRQ_COUNT); 89 90 /* hard clock */ 91 i8254_init(); 90 92 91 93 #ifdef CONFIG_FB … … 95 97 #endif 96 98 ega_init(); /* video */ 97 98 99 99 100 /* Enable debugger */ … … 127 128 void arch_post_smp_init(void) 128 129 { 129 i8042_init(); /* keyboard controller */ 130 /* keyboard controller */ 131 i8042_init(device_assign_devno(), IRQ_KBD); 130 132 } 131 133 -
kernel/arch/ia32/src/interrupt.c
r8c84448 rcea12e9 52 52 #include <ipc/sysipc.h> 53 53 #include <interrupt.h> 54 #include <ddi/irq.h> 54 55 55 56 /* … … 61 62 void (* eoi_function)(void) = NULL; 62 63 63 void PRINT_INFO_ERRCODE(istate_t *istate)64 void decode_istate(istate_t *istate) 64 65 { 65 66 char *symbol = get_symtab_entry(istate->eip); … … 84 85 } 85 86 86 void null_interrupt(int n, istate_t *istate) 87 static void trap_virtual_eoi(void) 88 { 89 if (eoi_function) 90 eoi_function(); 91 else 92 panic("no eoi_function\n"); 93 94 } 95 96 static void null_interrupt(int n, istate_t *istate) 87 97 { 88 98 fault_if_from_uspace(istate, "unserviced interrupt: %d", n); 89 99 90 PRINT_INFO_ERRCODE(istate);100 decode_istate(istate); 91 101 panic("unserviced interrupt: %d\n", n); 92 102 } 93 103 94 104 /** General Protection Fault. */ 95 void gp_fault(int n, istate_t *istate)105 static void gp_fault(int n, istate_t *istate) 96 106 { 97 107 if (TASK) { … … 116 126 } 117 127 118 PRINT_INFO_ERRCODE(istate);128 decode_istate(istate); 119 129 panic("general protection fault\n"); 120 130 } 121 131 122 void ss_fault(int n, istate_t *istate)132 static void ss_fault(int n, istate_t *istate) 123 133 { 124 134 fault_if_from_uspace(istate, "stack fault"); 125 135 126 PRINT_INFO_ERRCODE(istate);136 decode_istate(istate); 127 137 panic("stack fault\n"); 128 138 } 129 139 130 void simd_fp_exception(int n, istate_t *istate)140 static void simd_fp_exception(int n, istate_t *istate) 131 141 { 132 142 uint32_t mxcsr; … … 139 149 (unative_t)mxcsr); 140 150 141 PRINT_INFO_ERRCODE(istate);151 decode_istate(istate); 142 152 printf("MXCSR: %#zx\n",(unative_t)(mxcsr)); 143 153 panic("SIMD FP exception(19)\n"); 144 154 } 145 155 146 void nm_fault(int n, istate_t *istate)156 static void nm_fault(int n, istate_t *istate) 147 157 { 148 158 #ifdef CONFIG_FPU_LAZY … … 154 164 } 155 165 156 void syscall(int n, istate_t *istate) 157 { 158 panic("Obsolete syscall handler."); 159 } 160 161 void tlb_shootdown_ipi(int n, istate_t *istate) 166 #ifdef CONFIG_SMP 167 static void tlb_shootdown_ipi(int n, istate_t *istate) 162 168 { 163 169 trap_virtual_eoi(); 164 170 tlb_shootdown_ipi_recv(); 165 171 } 172 #endif 173 174 /** Handler of IRQ exceptions */ 175 static void irq_interrupt(int n, istate_t *istate) 176 { 177 ASSERT(n >= IVT_IRQBASE); 178 179 int inum = n - IVT_IRQBASE; 180 ASSERT(inum < IRQ_COUNT); 181 ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); 182 183 irq_t *irq = irq_dispatch_and_lock(inum); 184 if (irq) { 185 /* 186 * The IRQ handler was found. 187 */ 188 irq->handler(irq, irq->arg); 189 spinlock_unlock(&irq->lock); 190 } else { 191 /* 192 * Spurious interrupt. 193 */ 194 #ifdef CONFIG_DEBUG 195 printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); 196 #endif 197 } 198 trap_virtual_eoi(); 199 } 200 201 void interrupt_init(void) 202 { 203 int i; 204 205 for (i = 0; i < IVT_ITEMS; i++) 206 exc_register(i, "null", (iroutine) null_interrupt); 207 208 for (i = 0; i < IRQ_COUNT; i++) { 209 if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) 210 exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt); 211 } 212 213 exc_register(7, "nm_fault", (iroutine) nm_fault); 214 exc_register(12, "ss_fault", (iroutine) ss_fault); 215 exc_register(13, "gp_fault", (iroutine) gp_fault); 216 exc_register(19, "simd_fp", (iroutine) simd_fp_exception); 217 218 #ifdef CONFIG_SMP 219 exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi); 220 #endif 221 } 166 222 167 223 void trap_virtual_enable_irqs(uint16_t irqmask) … … 181 237 } 182 238 183 void trap_virtual_eoi(void)184 {185 if (eoi_function)186 eoi_function();187 else188 panic("no eoi_function\n");189 190 }191 192 239 /** @} 193 240 */ -
kernel/arch/ia32/src/mm/page.c
r8c84448 rcea12e9 112 112 fault_if_from_uspace(istate, "Page fault: %#x", page); 113 113 114 PRINT_INFO_ERRCODE(istate);114 decode_istate(istate); 115 115 printf("page fault address: %#x\n", page); 116 116 panic("page fault\n"); -
kernel/arch/ia32/src/pm.c
r8c84448 rcea12e9 140 140 } 141 141 142 idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i*interrupt_handler_size); 143 exc_register(i, "undef", (iroutine) null_interrupt); 142 idt_setoffset(d, ((uintptr_t) interrupt_handlers) + i * interrupt_handler_size); 144 143 } 145 exc_register(13, "gp_fault", (iroutine) gp_fault);146 exc_register( 7, "nm_fault", (iroutine) nm_fault);147 exc_register(12, "ss_fault", (iroutine) ss_fault);148 exc_register(19, "simd_fp", (iroutine) simd_fp_exception);149 144 } 150 145 -
kernel/genarch/include/kbd/i8042.h
r8c84448 rcea12e9 38 38 #include <typedefs.h> 39 39 40 extern void i8042_init( void);40 extern void i8042_init(devno_t devno, inr_t inr); 41 41 extern void i8042_poll(void); 42 42 extern void i8042_grab(void); -
kernel/genarch/src/kbd/i8042.c
r8c84448 rcea12e9 42 42 #include <genarch/kbd/scanc_pc.h> 43 43 #include <arch/drivers/i8042.h> 44 #include <arch/interrupt.h>45 44 #include <cpu.h> 46 45 #include <arch/asm.h> … … 50 49 #include <console/console.h> 51 50 #include <interrupt.h> 51 #include <sysinfo/sysinfo.h> 52 #include <ddi/irq.h> 52 53 53 54 /* Keyboard commands. */ … … 87 88 }; 88 89 89 static void i8042_interrupt(int n, istate_t *istate); 90 static void i8042_wait(void); 91 92 static iroutine oldvector; 93 /** Initialize keyboard and service interrupts using kernel routine */ 90 /** Structure for i8042's IRQ. */ 91 static irq_t i8042_irq; 92 93 /** Wait until the controller reads its data. */ 94 static void i8042_wait(void) { 95 while (i8042_status_read() & i8042_WAIT_MASK) { 96 /* wait */ 97 } 98 } 99 94 100 void i8042_grab(void) 95 101 { 96 oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt); 102 ipl_t ipl = interrupts_disable(); 103 97 104 i8042_wait(); 98 105 i8042_command_write(i8042_SET_COMMAND); … … 100 107 i8042_data_write(i8042_COMMAND); 101 108 i8042_wait(); 102 } 103 /** Resume the former interrupt vector */ 109 110 spinlock_lock(&i8042_irq.lock); 111 i8042_irq.notif_cfg.notify = false; 112 spinlock_unlock(&i8042_irq.lock); 113 interrupts_restore(ipl); 114 } 115 104 116 void i8042_release(void) 105 117 { 106 if (oldvector) 107 exc_register(VECTOR_KBD, "user_interrupt", oldvector); 118 ipl_t ipl = interrupts_disable(); 119 spinlock_lock(&i8042_irq.lock); 120 if (i8042_irq.notif_cfg.answerbox) 121 i8042_irq.notif_cfg.notify = true; 122 spinlock_unlock(&i8042_irq.lock); 123 interrupts_restore(ipl); 124 } 125 126 static irq_ownership_t i8042_claim(void) 127 { 128 return IRQ_ACCEPT; 129 } 130 131 static void i8042_irq_handler(irq_t *irq, void *arg, ...) 132 { 133 if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) 134 ipc_irq_send_notif(irq); 135 else { 136 uint8_t x; 137 uint8_t status; 138 139 while (((status = i8042_status_read()) & i8042_BUFFER_FULL_MASK)) { 140 x = i8042_data_read(); 141 142 if ((status & i8042_MOUSE_DATA)) 143 continue; 144 145 if (x & KEY_RELEASE) 146 key_released(x ^ KEY_RELEASE); 147 else 148 key_pressed(x); 149 } 150 } 108 151 } 109 152 110 153 /** Initialize i8042. */ 111 void i8042_init(void) 112 { 113 int i; 114 115 i8042_grab(); 116 /* Prevent user from accidentaly releasing calling i8042_resume 117 * and disabling keyboard 118 */ 119 oldvector = NULL; 120 121 trap_virtual_enable_irqs(1<<IRQ_KBD); 154 void i8042_init(devno_t devno, inr_t inr) 155 { 122 156 chardev_initialize("i8042_kbd", &kbrd, &ops); 123 157 stdin = &kbrd; 124 158 159 irq_initialize(&i8042_irq); 160 i8042_irq.devno = devno; 161 i8042_irq.inr = inr; 162 i8042_irq.claim = i8042_claim; 163 i8042_irq.handler = i8042_irq_handler; 164 irq_register(&i8042_irq); 165 166 trap_virtual_enable_irqs(1 << inr); 167 125 168 /* 126 169 * Clear input buffer. 127 170 * Number of iterations is limited to prevent infinite looping. 128 171 */ 172 int i; 129 173 for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) { 130 174 i8042_data_read(); 131 } 132 } 133 134 /** Process i8042 interrupt. 135 * 136 * @param n Interrupt vector. 137 * @param istate Interrupted state. 138 */ 139 void i8042_interrupt(int n, istate_t *istate) 140 { 141 uint8_t x; 142 uint8_t status; 143 144 while (((status=i8042_status_read()) & i8042_BUFFER_FULL_MASK)) { 145 x = i8042_data_read(); 146 147 if ((status & i8042_MOUSE_DATA)) 148 continue; 149 150 if (x & KEY_RELEASE) 151 key_released(x ^ KEY_RELEASE); 152 else 153 key_pressed(x); 154 } 155 trap_virtual_eoi(); 156 } 157 158 /** Wait until the controller reads its data. */ 159 void i8042_wait(void) { 160 while (i8042_status_read() & i8042_WAIT_MASK) { 161 /* wait */ 162 } 175 } 176 177 sysinfo_set_item_val("kbd", NULL, true); 178 sysinfo_set_item_val("kbd.devno", NULL, devno); 179 sysinfo_set_item_val("kbd.inr", NULL, inr); 180 181 i8042_grab(); 163 182 } 164 183
Note:
See TracChangeset
for help on using the changeset viewer.