Changeset 0d107f31 in mainline


Ignore:
Timestamp:
2006-10-13T20:42:54Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7dcf22a
Parents:
8ce8499
Message:

Prototypical implementation of new IRQ redirector in sparc64.
The new code can support shared IRQs in kernel (and multiple IRQs per device).
Userspace support is yet to be written.
The only architecture that uses this code is actually sparc64 only.

Location:
kernel
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r8ce8499 r0d107f31  
    149149        generic/src/ddi/ddi.c \
    150150        generic/src/interrupt/interrupt.c \
     151        generic/src/interrupt/irq.c \
    151152        generic/src/main/main.c \
    152153        generic/src/main/kinit.c \
  • kernel/arch/sparc64/src/drivers/kbd.c

    r8ce8499 r0d107f31  
    4141#include <genarch/kbd/ns16550.h>
    4242#endif
    43 
     43#include <irq.h>
    4444#include <arch/mm/page.h>
    4545#include <arch/types.h>
     
    5252
    5353kbd_type_t kbd_type = KBD_UNKNOWN;
     54
     55static irq_t kbd_irq;
    5456
    5557/** Initialize keyboard.
     
    102104        int inr;
    103105       
     106        irq_initialize(&kbd_irq);
     107       
    104108        switch (kbd_type) {
    105109        case KBD_Z8530:
     
    112116                        printf("Failed to determine keyboard interrupt.\n");
    113117                        return;
     118                } else {
     119                        kbd_irq.inr = inr;
     120                        kbd_irq.devno = 0;                      /* FIXME: assign unique devno */
     121                        kbd_irq.trigger = IRQ_TRIGGER_LEVEL;
     122                        kbd_irq.claim = z8530_claim;
     123                        kbd_irq.handler = z8530_irq_handler;
     124                        irq_register(&kbd_irq);
    114125                }
    115126                break;
     127               
    116128        case KBD_NS16550:
    117129                size = ((ofw_ebus_reg_t *) prop->value)->size;
     
    123135                        printf("Failed to determine keyboard interrupt.\n");
    124136                        return;
     137                } else {
     138                        kbd_irq.inr = inr;
     139                        kbd_irq.devno = 0;                      /* FIXME: assign unique devno */
     140                        kbd_irq.trigger = IRQ_TRIGGER_LEVEL;
     141                        kbd_irq.claim = ns16550_claim;
     142                        kbd_irq.handler = ns16550_irq_handler;
     143                        irq_register(&kbd_irq);
    125144                }
    126145                break;
     146
    127147        default:
    128148                panic("Unexpected type.\n");
  • kernel/arch/sparc64/src/sparc64.c

    r8ce8499 r0d107f31  
    4747#include <genarch/ofw/ofw_tree.h>
    4848#include <userspace.h>
     49#include <irq.h>
    4950
    5051bootinfo_t bootinfo;
     
    7778void arch_post_mm_init(void)
    7879{
    79         if (config.cpu_active == 1)
     80        if (config.cpu_active == 1) {
     81                irq_init(1<<11, 128);
    8082                standalone_sparc64_console_init();
     83        }
    8184}
    8285
  • kernel/arch/sparc64/src/trap/interrupt.c

    r8ce8499 r0d107f31  
    3636#include <arch/trap/interrupt.h>
    3737#include <interrupt.h>
    38 #include <arch/drivers/fhc.h>
    39 #include <arch/drivers/kbd.h>
     38#include <irq.h>
    4039#include <typedefs.h>
    4140#include <arch/types.h>
     
    4544#include <arch/barrier.h>
    4645#include <print.h>
    47 #include <genarch/kbd/z8530.h>
    4846#include <arch.h>
    4947#include <mm/tlb.h>
    5048#include <config.h>
     49
     50/*
     51 * To be removed once we get rid of the dependency in ipc_irq_bind_arch().
     52 */
     53#include <arch/drivers/kbd.h>
     54#include <genarch/kbd/z8530.h>
    5155
    5256/** Register Interrupt Level Handler.
     
    7276}
    7377
     78/** Process hardware interrupt.
     79 *
     80 * @param n Ignored.
     81 * @param istate Ignored.
     82 */
    7483void interrupt(int n, istate_t *istate)
    7584{
     
    8089        data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
    8190
    82         switch (data0) {
    83 #ifdef CONFIG_Z8530
    84         case Z8530_INTRCV_DATA0:
    85                 if (kbd_type != KBD_Z8530)
    86                         break;
     91        irq_t *irq = irq_dispatch(data0);
     92        if (irq) {
    8793                /*
    88                  * So far, we know we got this interrupt through the FHC.
    89                  * Since we don't have enough information about the FHC and
    90                  * because the interrupt looks like level sensitive,
    91                  * we cannot handle it by scheduling one of the level
    92                  * interrupt traps. Call the interrupt handler directly.
     94                 * The IRQ handler was found.
    9395                 */
    94 
    95                 if (z8530_belongs_to_kernel)
    96                         z8530_interrupt();
    97                 else
    98                         ipc_irq_send_notif(0);
    99                 fhc_clear_interrupt(central_fhc, data0);
    100                 break;
    101 
     96                irq->handler(irq, irq->arg);
     97        } else if (data0 > config.base) {
     98                /*
     99                 * This is a cross-call.
     100                 * data0 contains address of kernel function.
     101                 * We call the function only after we verify
     102                 * it is on of the supported ones.
     103                 */
     104#ifdef CONFIG_SMP
     105                if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
     106                        tlb_shootdown_ipi_recv();
     107                }
    102108#endif
    103         default:
    104                 if (data0 > config.base) {
    105                         /*
    106                          * This is a cross-call.
    107                          * data0 contains address of kernel function.
    108                          * We call the function only after we verify
    109                          * it is on of the supported ones.
    110                          */
    111 #ifdef CONFIG_SMP
    112                         if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {
    113                                 tlb_shootdown_ipi_recv();
    114                                 break;
    115                         }
     109        } else {
     110                /*
     111                 * Spurious interrupt.
     112                 */
     113#ifdef CONFIG_DEBUG
     114                printf("cpu%d: spurious interrupt (intrcv=%#llx, data0=%#llx)\n", CPU->id, intrcv, data0);
    116115#endif
    117                 }
    118                        
    119                 printf("cpu%d: spurious interrupt (intrcv=%#llx, data0=%#llx)\n", CPU->id, intrcv, data0);
    120                 break;
    121116        }
    122117
  • kernel/genarch/include/kbd/ns16550.h

    r8ce8499 r0d107f31  
    3939
    4040#include <typedefs.h>
     41#include <irq.h>
    4142
    4243extern void ns16550_init(void);
     
    4546extern void ns16550_release(void);
    4647extern char ns16550_key_read(chardev_t *d);
     48extern irq_ownership_t ns16550_claim(void);
     49extern void ns16550_irq_handler(irq_t *irq, void *arg, ...);
    4750
    4851#endif
  • kernel/genarch/include/kbd/z8530.h

    r8ce8499 r0d107f31  
    3838#define KERN_Z8530_H_
    3939
     40#include <irq.h>
    4041#include <typedefs.h>
    41 
    42 #define Z8530_INTRCV_DATA0      0x39    /* hardcoded for use in Simics */
    4342
    4443extern bool z8530_belongs_to_kernel;
     
    5049extern void z8530_interrupt(void);
    5150extern char z8530_key_read(chardev_t *d);
     51extern irq_ownership_t z8530_claim(void);
     52extern void z8530_irq_handler(irq_t *irq, void *arg, ...);
    5253
    5354#endif
  • kernel/genarch/src/kbd/ns16550.c

    r8ce8499 r0d107f31  
    4040#include <genarch/kbd/scanc_sun.h>
    4141#include <arch/drivers/ns16550.h>
     42#include <irq.h>
    4243#include <arch/interrupt.h>
    4344#include <cpu.h>
     
    161162}
    162163
     164irq_ownership_t ns16550_claim(void)
     165{
     166        /* TODO */
     167        return IRQ_ACCEPT;
     168}
     169
     170void ns16550_irq_handler(irq_t *irq, void *arg, ...)
     171{
     172        panic("Not yet implemented.\n");
     173}
     174
    163175/** @}
    164176 */
  • kernel/genarch/src/kbd/z8530.c

    r8ce8499 r0d107f31  
    4040#include <genarch/kbd/scanc_sun.h>
    4141#include <arch/drivers/z8530.h>
     42#include <irq.h>
    4243#include <arch/interrupt.h>
    4344#include <arch/drivers/kbd.h>
     45#include <arch/drivers/fhc.h>
    4446#include <cpu.h>
    4547#include <arch/asm.h>
     
    170172}
    171173
     174irq_ownership_t z8530_claim(void)
     175{
     176        return (z8530_read_a(RR0) & RR0_RCA);
     177}
     178
     179void z8530_irq_handler(irq_t *irq, void *arg, ...)
     180{
     181        /*
     182         * So far, we know we got this interrupt through the FHC.
     183         * Since we don't have enough information about the FHC and
     184         * because the interrupt looks like level sensitive,
     185         * we cannot handle it by scheduling one of the level
     186         * interrupt traps. Process the interrupt directly.
     187         */
     188        if (z8530_belongs_to_kernel)
     189                z8530_interrupt();
     190        else
     191                ipc_irq_send_notif(0);
     192        fhc_clear_interrupt(central_fhc, irq->inr);
     193}
     194
    172195/** @}
    173196 */
  • kernel/generic/include/ipc/irq.h

    r8ce8499 r0d107f31  
    3333 */
    3434
    35 #ifndef KERN_IRQ_H_
    36 #define KERN_IRQ_H_
     35#ifndef KERN_IPC_IRQ_H_
     36#define KERN_IPC_IRQ_H_
    3737
    3838/** Maximum length of IPC IRQ program */
Note: See TracChangeset for help on using the changeset viewer.