Changeset cea12e9 in mainline


Ignore:
Timestamp:
2006-10-27T11:13:13Z (18 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
16d71f41
Parents:
8c84448
Message:

ia32: adopt new IRQ interface, mouse not tested yet

Location:
kernel
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/include/interrupt.h

    r8c84448 rcea12e9  
    4646
    4747#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)
    5050
    51 #define IRQ_CLK         0
    52 #define IRQ_KBD         1
    53 #define IRQ_PIC1        2
     51#define IRQ_CLK                 0
     52#define IRQ_KBD                 1
     53#define IRQ_PIC1                2
    5454#define IRQ_PIC_SPUR    7
    5555
    5656/* 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)
    5858
    59 #if (((VECTOR_APIC_SPUR + 1)%16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
     59#if (((VECTOR_APIC_SPUR + 1) % 16) || VECTOR_APIC_SPUR >= IVT_ITEMS)
    6060#error Wrong definition of VECTOR_APIC_SPUR
    6161#endif
    6262
    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)
    7169
    7270struct istate {
     
    111109extern void (* eoi_function)(void);
    112110
    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 
     111extern void decode_istate(istate_t *istate);
     112extern void interrupt_init(void);
    122113extern void trap_virtual_enable_irqs(uint16_t irqmask);
    123114extern void trap_virtual_disable_irqs(uint16_t irqmask);
    124 extern void trap_virtual_eoi(void);
    125115
    126116#endif
  • kernel/arch/ia32/src/drivers/i8254.c

    r8c84448 rcea12e9  
    5050#include <arch.h>
    5151#include <time/delay.h>
    52 #include <interrupt.h>
     52#include <ddi/irq.h>
     53#include <ddi/device.h>
    5354
    5455#define CLK_PORT1       0x40
     
    5859#define MAGIC_NUMBER    1194
    5960
    60 static void i8254_interrupt(int n, istate_t *istate);
     61static irq_t i8254_irq;
     62
     63static irq_ownership_t i8254_claim(void)
     64{
     65        return IRQ_ACCEPT;
     66}
     67
     68static void i8254_irq_handler(irq_t *irq, void *arg, ...)
     69{
     70        clock();
     71}
    6172
    6273void i8254_init(void)
    6374{
     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       
    6482        i8254_normal_operation();
    6583}
     
    6886{
    6987        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);
    7592}
    7693
     
    130147}
    131148
    132 void i8254_interrupt(int n, istate_t *istate)
    133 {
    134         trap_virtual_eoi();
    135         clock();
    136 }
    137 
    138149/** @}
    139150 */
  • kernel/arch/ia32/src/ia32.c

    r8c84448 rcea12e9  
    5858#include <arch/mm/memory_init.h>
    5959#include <interrupt.h>
     60#include <ddi/irq.h>
    6061#include <arch/debugger.h>
    6162#include <proc/thread.h>
    6263#include <syscall/syscall.h>
    6364#include <console/console.h>
     65#include <ddi/device.h>
    6466
    6567#ifdef CONFIG_SMP
     
    7274
    7375        if (config.cpu_active == 1) {
     76                interrupt_init();
    7477                bios_init();
    75                 i8259_init();   /* PIC */
    76                 i8254_init();   /* hard clock */
    7778               
    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();
    8481        }
    8582}
     
    8885{
    8986        if (config.cpu_active == 1) {
     87                /* Initialize IRQ routing */
     88                irq_init(IRQ_COUNT, IRQ_COUNT);
     89               
     90                /* hard clock */
     91                i8254_init();
    9092
    9193#ifdef CONFIG_FB
     
    9597#endif
    9698                        ega_init();     /* video */
    97                
    9899               
    99100                /* Enable debugger */
     
    127128void arch_post_smp_init(void)
    128129{
    129         i8042_init();   /* keyboard controller */
     130        /* keyboard controller */
     131        i8042_init(device_assign_devno(), IRQ_KBD);
    130132}
    131133
  • kernel/arch/ia32/src/interrupt.c

    r8c84448 rcea12e9  
    5252#include <ipc/sysipc.h>
    5353#include <interrupt.h>
     54#include <ddi/irq.h>
    5455
    5556/*
     
    6162void (* eoi_function)(void) = NULL;
    6263
    63 void PRINT_INFO_ERRCODE(istate_t *istate)
     64void decode_istate(istate_t *istate)
    6465{
    6566        char *symbol = get_symtab_entry(istate->eip);
     
    8485}
    8586
    86 void null_interrupt(int n, istate_t *istate)
     87static void trap_virtual_eoi(void)
     88{
     89        if (eoi_function)
     90                eoi_function();
     91        else
     92                panic("no eoi_function\n");
     93
     94}
     95
     96static void null_interrupt(int n, istate_t *istate)
    8797{
    8898        fault_if_from_uspace(istate, "unserviced interrupt: %d", n);
    8999
    90         PRINT_INFO_ERRCODE(istate);
     100        decode_istate(istate);
    91101        panic("unserviced interrupt: %d\n", n);
    92102}
    93103
    94104/** General Protection Fault. */
    95 void gp_fault(int n, istate_t *istate)
     105static void gp_fault(int n, istate_t *istate)
    96106{
    97107        if (TASK) {
     
    116126        }
    117127
    118         PRINT_INFO_ERRCODE(istate);
     128        decode_istate(istate);
    119129        panic("general protection fault\n");
    120130}
    121131
    122 void ss_fault(int n, istate_t *istate)
     132static void ss_fault(int n, istate_t *istate)
    123133{
    124134        fault_if_from_uspace(istate, "stack fault");
    125135
    126         PRINT_INFO_ERRCODE(istate);
     136        decode_istate(istate);
    127137        panic("stack fault\n");
    128138}
    129139
    130 void simd_fp_exception(int n, istate_t *istate)
     140static void simd_fp_exception(int n, istate_t *istate)
    131141{
    132142        uint32_t mxcsr;
     
    139149                             (unative_t)mxcsr);
    140150
    141         PRINT_INFO_ERRCODE(istate);
     151        decode_istate(istate);
    142152        printf("MXCSR: %#zx\n",(unative_t)(mxcsr));
    143153        panic("SIMD FP exception(19)\n");
    144154}
    145155
    146 void nm_fault(int n, istate_t *istate)
     156static void nm_fault(int n, istate_t *istate)
    147157{
    148158#ifdef CONFIG_FPU_LAZY     
     
    154164}
    155165
    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
     167static void tlb_shootdown_ipi(int n, istate_t *istate)
    162168{
    163169        trap_virtual_eoi();
    164170        tlb_shootdown_ipi_recv();
    165171}
     172#endif
     173
     174/** Handler of IRQ exceptions */
     175static 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
     201void 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}
    166222
    167223void trap_virtual_enable_irqs(uint16_t irqmask)
     
    181237}
    182238
    183 void trap_virtual_eoi(void)
    184 {
    185         if (eoi_function)
    186                 eoi_function();
    187         else
    188                 panic("no eoi_function\n");
    189 
    190 }
    191 
    192239/** @}
    193240 */
  • kernel/arch/ia32/src/mm/page.c

    r8c84448 rcea12e9  
    112112                fault_if_from_uspace(istate, "Page fault: %#x", page);
    113113
    114                 PRINT_INFO_ERRCODE(istate);
     114                decode_istate(istate);
    115115                printf("page fault address: %#x\n", page);
    116116                panic("page fault\n");
  • kernel/arch/ia32/src/pm.c

    r8c84448 rcea12e9  
    140140                }
    141141               
    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);
    144143        }
    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);
    149144}
    150145
  • kernel/genarch/include/kbd/i8042.h

    r8c84448 rcea12e9  
    3838#include <typedefs.h>
    3939
    40 extern void i8042_init(void);
     40extern void i8042_init(devno_t devno, inr_t inr);
    4141extern void i8042_poll(void);
    4242extern void i8042_grab(void);
  • kernel/genarch/src/kbd/i8042.c

    r8c84448 rcea12e9  
    4242#include <genarch/kbd/scanc_pc.h>
    4343#include <arch/drivers/i8042.h>
    44 #include <arch/interrupt.h>
    4544#include <cpu.h>
    4645#include <arch/asm.h>
     
    5049#include <console/console.h>
    5150#include <interrupt.h>
     51#include <sysinfo/sysinfo.h>
     52#include <ddi/irq.h>
    5253
    5354/* Keyboard commands. */
     
    8788};
    8889
    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. */
     91static irq_t i8042_irq;
     92
     93/** Wait until the controller reads its data. */
     94static void i8042_wait(void) {
     95        while (i8042_status_read() & i8042_WAIT_MASK) {
     96                /* wait */
     97        }
     98}
     99
    94100void i8042_grab(void)
    95101{
    96         oldvector = exc_register(VECTOR_KBD, "i8042_interrupt", (iroutine) i8042_interrupt);
     102        ipl_t ipl = interrupts_disable();
     103       
    97104        i8042_wait();
    98105        i8042_command_write(i8042_SET_COMMAND);
     
    100107        i8042_data_write(i8042_COMMAND);
    101108        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
    104116void i8042_release(void)
    105117{
    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
     126static irq_ownership_t i8042_claim(void)
     127{
     128        return IRQ_ACCEPT;
     129}
     130
     131static 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        }
    108151}
    109152
    110153/** 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);
     154void i8042_init(devno_t devno, inr_t inr)
     155{
    122156        chardev_initialize("i8042_kbd", &kbrd, &ops);
    123157        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       
    125168        /*
    126169         * Clear input buffer.
    127170         * Number of iterations is limited to prevent infinite looping.
    128171         */
     172        int i;
    129173        for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) {
    130174                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();
    163182}
    164183
Note: See TracChangeset for help on using the changeset viewer.