Changeset e2cc9a0 in mainline


Ignore:
Timestamp:
2006-10-06T22:37:15Z (18 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
33b1903
Parents:
233af8c5
Message:

Add support for interrupt mapping in the Sabre PCI controller.
Add support for PCI and EBUS interrupt mapping via the OpenFirmware device tree.
Unfortunatelly, the code is not capable enough to earn single ns16550 interrupt.
I suspect something needs to be enabled in the EBUS registers.

Location:
kernel
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc64/Makefile.inc

    r233af8c5 re2cc9a0  
    101101        arch/$(ARCH)/src/drivers/tick.c \
    102102        arch/$(ARCH)/src/drivers/kbd.c \
    103         arch/$(ARCH)/src/drivers/scr.c
     103        arch/$(ARCH)/src/drivers/scr.c \
     104        arch/$(ARCH)/src/drivers/pci.c
    104105
    105106ifeq ($(CONFIG_SMP),y)
  • kernel/arch/sparc64/include/asm.h

    r233af8c5 re2cc9a0  
    325325        uint64_t v;
    326326       
    327         __asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" (asi));
     327        __asm__ volatile ("ldxa [%1] %2, %0\n" : "=r" (v) : "r" (va), "i" ((unsigned) asi));
    328328       
    329329        return v;
     
    338338static inline void asi_u64_write(asi_t asi, uintptr_t va, uint64_t v)
    339339{
    340         __asm__ volatile ("stxa %0, [%1] %2\n" : :  "r" (v), "r" (va), "i" (asi) : "memory");
     340        __asm__ volatile ("stxa %0, [%1] %2\n" : :  "r" (v), "r" (va), "i" ((unsigned) asi) : "memory");
    341341}
    342342
  • kernel/arch/sparc64/include/drivers/ns16550.h

    r233af8c5 re2cc9a0  
    3939#include <arch/drivers/kbd.h>
    4040
     41/* NS16550 registers */
    4142#define RBR_REG         0       /** Receiver Buffer Register. */
    4243#define IER_REG         1       /** Interrupt Enable Register. */
     44#define IIR_REG         2       /** Interrupt Ident Register (read). */
     45#define FCR_REG         2       /** FIFO control register (write). */
     46#define LCR_REG         3       /** Line Control register. */
    4347#define LSR_REG         5       /** Line Status Register. */
     48
     49#define IER_ERBFI       0x01    /** Enable Receive Buffer Full Interrupt. */
     50
     51#define LCR_DLAB        0x80    /** Divisor Latch Access bit. */
    4452
    4553static inline uint8_t ns16550_rbr_read(void)
     
    5866}
    5967
     68static inline uint8_t ns16550_iir_read(void)
     69{
     70        return kbd_virt_address[IIR_REG];
     71}
     72
     73static inline void ns16550_fcr_write(uint8_t v)
     74{
     75        kbd_virt_address[FCR_REG] = v;
     76}
     77
     78static inline uint8_t ns16550_lcr_read(void)
     79{
     80        return kbd_virt_address[LCR_REG];
     81}
     82
     83static inline void ns16550_lcr_write(uint8_t v)
     84{
     85        kbd_virt_address[LCR_REG] = v;
     86}
     87
    6088static inline uint8_t ns16550_lsr_read(void)
    6189{
  • kernel/arch/sparc64/include/trap/interrupt.h

    r233af8c5 re2cc9a0  
    4040#include <arch/trap/trap_table.h>
    4141#include <arch/stack.h>
     42
     43/* IMAP register bits */
     44#define IGN_MASK        0x7c0
     45#define INO_MASK        0x1f
     46#define IMAP_V_MASK     (1ULL<<31)
     47
     48#define IGN_SHIFT       6
     49
    4250
    4351/* Interrupt ASI registers. */
  • kernel/arch/sparc64/src/drivers/kbd.c

    r233af8c5 re2cc9a0  
    100100        uintptr_t pa;
    101101        size_t size;
    102         int ino;
     102        int inr;
    103103       
    104104        switch (kbd_type) {
     
    109109                        return;
    110110                }
    111                 if (!ofw_fhc_map_interrupts(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &ino)) {
     111                if (!ofw_fhc_map_interrupts(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
    112112                        printf("Failed to determine keyboard interrupts.\n");
    113113                        return;
     
    120120                        return;
    121121                }
    122                 if (!ofw_ebus_map_interrupts(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &ino)) {
     122                if (!ofw_ebus_map_interrupts(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
    123123                        printf("Failed to determine keyboard interrupts.\n");
    124124                        return;
  • kernel/genarch/src/kbd/ns16550.c

    r233af8c5 re2cc9a0  
    9191        sysinfo_set_item_val("kbd.irq", NULL, 0);
    9292        sysinfo_set_item_val("kbd.address.virtual", NULL, (uintptr_t) kbd_virt_address);
     93       
     94        ns16550_ier_write(IER_ERBFI);                           /* enable receiver interrupt */
     95       
     96        while (ns16550_lsr_read() & LSR_DATA_READY)
     97                (void) ns16550_rbr_read();
    9398}
    9499
     
    145150        uint8_t x;
    146151
    147         while (((x = ns16550_lsr_read() & LSR_DATA_READY))) {
     152        while (ns16550_lsr_read() & LSR_DATA_READY) {
    148153                x = ns16550_rbr_read();
    149154                if (x != IGNORE_CODE) {
  • kernel/genarch/src/ofw/ebus.c

    r233af8c5 re2cc9a0  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
     39#include <arch/drivers/pci.h>
    3940#include <arch/memstr.h>
     41#include <arch/trap/interrupt.h>
    4042#include <func.h>
    4143#include <panic.h>
     
    4345#include <macros.h>
    4446
     47/** Apply EBUS ranges to EBUS register. */
    4548bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
    4649{
     
    113116         * We found the device that functions as an interrupt controller
    114117         * for the interrupt. We also found mapping from interrupt to INR.
     118         * What needs to be done now is to verify that this indeed is a PCI
     119         * node.
    115120         */
    116121
    117122        controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
     123        if (!controller)
     124                return false;
     125               
     126        if (strcmp(ofw_tree_node_name(controller), "pci") != 0) {
     127                /*
     128                 * This is not a PCI node.
     129                 */
     130                return false;
     131        }
     132
     133        pci_t *pci = controller->device;
     134        if (!pci) {
     135                pci = pci_init(controller);
     136                if (!pci)
     137                        return false;
     138                controller->device = pci;
     139               
     140        }
     141        pci_enable_interrupt(pci, intr_map[i].controller_inr);
     142
     143        *inr = intr_map[i].controller_inr;
     144        *inr |= 0x1f << IGN_SHIFT;              /* 0x1f is hardwired IGN */
    118145       
    119         *inr = intr_map[i].controller_inr;
    120146        return true;
    121147}
  • kernel/genarch/src/ofw/upa.c

    r233af8c5 re2cc9a0  
    4646{
    4747        *pa = reg->addr;
    48         return false;
     48        return true;
    4949}
    5050
Note: See TracChangeset for help on using the changeset viewer.