Changeset 8d2760f in mainline
- Timestamp:
- 2008-11-29T20:24:47Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 57e76cb
- Parents:
- dfd77382
- Location:
- kernel
- Files:
-
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/include/drivers/fhc.h
rdfd77382 r8d2760f 45 45 extern fhc_t *central_fhc; 46 46 47 extern fhc_t *fhc_init(ofw_tree_node_t * node);48 extern void fhc_enable_interrupt(fhc_t * fhc, int inr);49 extern void fhc_clear_interrupt( fhc_t *fhc, int inr);47 extern fhc_t *fhc_init(ofw_tree_node_t *); 48 extern void fhc_enable_interrupt(fhc_t *, int); 49 extern void fhc_clear_interrupt(void *, int); 50 50 51 51 #endif -
kernel/arch/sparc64/include/drivers/pci.h
rdfd77382 r8d2760f 52 52 53 53 struct pci_operations { 54 void (* enable_interrupt)(pci_t * pci, int inr);55 void (* clear_interrupt)(pci_t * pci, int inr);54 void (* enable_interrupt)(pci_t *, int); 55 void (* clear_interrupt)(pci_t *, int); 56 56 }; 57 57 … … 62 62 }; 63 63 64 extern pci_t *pci_init(ofw_tree_node_t * node);65 extern void pci_enable_interrupt(pci_t * pci, int inr);66 extern void pci_clear_interrupt( pci_t *pci, int inr);64 extern pci_t *pci_init(ofw_tree_node_t *); 65 extern void pci_enable_interrupt(pci_t *, int); 66 extern void pci_clear_interrupt(void *, int); 67 67 68 68 #endif -
kernel/arch/sparc64/src/drivers/fhc.c
rdfd77382 r8d2760f 102 102 } 103 103 104 void fhc_clear_interrupt( fhc_t *fhc, int inr)104 void fhc_clear_interrupt(void *fhcp, int inr) 105 105 { 106 fhc_t *fhc = (fhc_t *)fhcp; 106 107 ASSERT(fhc->uart_imap); 107 108 -
kernel/arch/sparc64/src/drivers/kbd.c
rdfd77382 r8d2760f 64 64 ofw_tree_property_t *prop; 65 65 const char *name; 66 cir_t cir; 67 void *cir_arg; 66 68 67 69 name = ofw_tree_node_name(node); … … 110 112 } 111 113 if (!ofw_fhc_map_interrupt(node->parent, 112 ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { 114 ((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, 115 &cir_arg)) { 113 116 printf("Failed to determine keyboard interrupt.\n"); 114 117 return; … … 124 127 } 125 128 if (!ofw_ebus_map_interrupt(node->parent, 126 ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { 129 ((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, 130 &cir_arg)) { 127 131 printf("Failed to determine keyboard interrupt.\n"); 128 132 return; … … 147 151 #ifdef CONFIG_Z8530 148 152 case KBD_Z8530: 149 z8530_init(devno, inr, vaddr);153 z8530_init(devno, vaddr, inr, cir, cir_arg); 150 154 break; 151 155 #endif 152 156 #ifdef CONFIG_NS16550 153 157 case KBD_NS16550: 154 ns16550_init(devno, inr, (ioport_t)vaddr);158 ns16550_init(devno, (ioport_t)vaddr, inr, cir, cir_arg); 155 159 break; 156 160 #endif -
kernel/arch/sparc64/src/drivers/pci.c
rdfd77382 r8d2760f 55 55 #define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) 56 56 57 static void obio_enable_interrupt(pci_t * pci, int inr);58 static void obio_clear_interrupt(pci_t * pci, int inr);59 60 static pci_t *pci_sabre_init(ofw_tree_node_t * node);61 static pci_t *pci_psycho_init(ofw_tree_node_t * node);57 static void obio_enable_interrupt(pci_t *, int); 58 static void obio_clear_interrupt(pci_t *, int); 59 60 static pci_t *pci_sabre_init(ofw_tree_node_t *); 61 static pci_t *pci_psycho_init(ofw_tree_node_t *); 62 62 63 63 /** PCI operations for Sabre model. */ … … 209 209 } 210 210 211 void pci_clear_interrupt(pci_t *pci, int inr) 212 { 211 void pci_clear_interrupt(void *pcip, int inr) 212 { 213 pci_t *pci = (pci_t *)pcip; 214 213 215 ASSERT(pci->op && pci->op->clear_interrupt); 214 216 pci->op->clear_interrupt(pci, inr); -
kernel/arch/sparc64/src/trap/interrupt.c
rdfd77382 r8d2760f 80 80 */ 81 81 irq->handler(irq, irq->arg); 82 /* 83 * See if there is a clear-interrupt-routine and call it. 84 */ 85 if (irq->cir) { 86 irq->cir(irq->cir_arg, irq->inr); 87 } 82 88 spinlock_unlock(&irq->lock); 83 89 } else if (data0 > config.base) { … … 99 105 #ifdef CONFIG_DEBUG 100 106 printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64 101 107 ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); 102 108 #endif 103 109 } -
kernel/genarch/include/kbd/ns16550.h
rdfd77382 r8d2760f 39 39 40 40 #include <console/chardev.h> 41 #include <ddi/irq.h> 41 42 #include <ipc/irq.h> 42 43 43 extern void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr);44 extern void ns16550_init(devno_t, uintptr_t, inr_t, cir_t, void *); 44 45 extern void ns16550_poll(void); 45 46 extern void ns16550_grab(void); 46 47 extern void ns16550_release(void); 47 extern char ns16550_key_read(chardev_t * d);48 extern char ns16550_key_read(chardev_t *); 48 49 extern irq_ownership_t ns16550_claim(void); 49 extern void ns16550_irq_handler(irq_t * irq, void *arg, ...);50 extern void ns16550_irq_handler(irq_t *, void *, ...); 50 51 51 52 #include <arch/types.h> -
kernel/genarch/include/kbd/z8530.h
rdfd77382 r8d2760f 40 40 #include <console/chardev.h> 41 41 #include <ipc/irq.h> 42 #include <ddi/irq.h> 42 43 43 44 extern bool z8530_belongs_to_kernel; 44 45 45 extern void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr);46 extern void z8530_init(devno_t, uintptr_t, inr_t, cir_t, void *); 46 47 extern void z8530_poll(void); 47 48 extern void z8530_grab(void); 48 49 extern void z8530_release(void); 49 50 extern void z8530_interrupt(void); 50 extern char z8530_key_read(chardev_t * d);51 extern char z8530_key_read(chardev_t *); 51 52 extern irq_ownership_t z8530_claim(void); 52 extern void z8530_irq_handler(irq_t * irq, void *arg, ...);53 extern void z8530_irq_handler(irq_t *, void *, ...); 53 54 54 55 #endif -
kernel/genarch/include/ofw/ofw_tree.h
rdfd77382 r8d2760f 31 31 32 32 #include <arch/types.h> 33 #include <ddi/irq.h> 33 34 #include <typedefs.h> 34 35 … … 44 45 ofw_tree_node_t *child; 45 46 46 uint32_t node_handle; 47 48 char *da_name; 49 50 unsigned properties; 47 uint32_t node_handle; /**< Old OpenFirmware node handle. */ 48 49 char *da_name; /**< Disambigued name. */ 50 51 unsigned properties; /**< Number of properties. */ 51 52 ofw_tree_property_t *property; 52 53 … … 106 107 uint32_t child_base; 107 108 uint32_t parent_space; 108 uint64_t parent_base; 109 uint64_t parent_base; /* group phys.mid and phys.lo together */ 109 110 uint32_t size; 110 111 } __attribute__ ((packed)); … … 128 129 129 130 struct ofw_pci_reg { 130 uint32_t space; 131 uint64_t addr; 131 uint32_t space; /* needs to be masked to obtain pure space id */ 132 uint64_t addr; /* group phys.mid and phys.lo together */ 132 133 uint64_t size; 133 134 } __attribute__ ((packed)); … … 136 137 struct ofw_pci_range { 137 138 uint32_t space; 138 uint64_t child_base; 139 uint64_t child_base; /* group phys.mid and phys.lo together */ 139 140 uint64_t parent_base; 140 141 uint64_t size; … … 161 162 typedef struct ofw_upa_reg ofw_upa_reg_t; 162 163 163 extern void ofw_tree_init(ofw_tree_node_t * root);164 extern void ofw_tree_init(ofw_tree_node_t *); 164 165 extern void ofw_tree_print(void); 165 extern const char *ofw_tree_node_name(const ofw_tree_node_t *node); 166 extern ofw_tree_node_t *ofw_tree_lookup(const char *path); 167 extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name); 168 extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name); 169 extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type); 170 extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type); 171 extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle); 172 173 extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa); 174 extern bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa); 175 extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa); 176 extern bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa); 177 extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *node, ofw_sbus_reg_t *reg, uintptr_t *pa); 178 extern bool ofw_upa_apply_ranges(ofw_tree_node_t *node, ofw_upa_reg_t *reg, uintptr_t *pa); 179 180 extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out); 181 182 extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr); 183 extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr); 184 extern bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr); 166 extern const char *ofw_tree_node_name(const ofw_tree_node_t *); 167 extern ofw_tree_node_t *ofw_tree_lookup(const char *); 168 extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *, 169 const char *); 170 extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *); 171 extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *, 172 const char *); 173 extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *, 174 const char *); 175 extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *, 176 uint32_t); 177 178 extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *, 179 uintptr_t *); 180 extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *, 181 uintptr_t *); 182 extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *, 183 uintptr_t *); 184 extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *, 185 uintptr_t *); 186 extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *, 187 uintptr_t *); 188 extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *, 189 uintptr_t *); 190 191 extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *, 192 ofw_pci_reg_t *); 193 194 extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *, 195 uint32_t, int *, cir_t *, void **); 196 extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *, 197 uint32_t, int *, cir_t *, void **); 198 extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *, 199 int, int *, cir_t *, void **); 185 200 186 201 #endif -
kernel/genarch/src/kbd/ns16550.c
rdfd77382 r8d2760f 108 108 /** Initialize ns16550. 109 109 * 110 * @param devno Device number. 111 * @param inr Interrupt number. 112 * @param vaddr Virtual address of device's registers. 113 */ 114 void ns16550_init(devno_t devno, inr_t inr, ioport_t port) 110 * @param devno Device number. 111 * @param port Virtual/IO address of device's registers. 112 * @param inr Interrupt number. 113 * @param cir Clear interrupt function. 114 * @param cir_arg First argument to cir. 115 */ 116 void 117 ns16550_init(devno_t devno, ioport_t port, inr_t inr, cir_t cir, void *cir_arg) 115 118 { 116 119 chardev_initialize("ns16550_kbd", &kbrd, &ops); … … 125 128 ns16550_irq.claim = ns16550_claim; 126 129 ns16550_irq.handler = ns16550_irq_handler; 130 ns16550_irq.cir = cir; 131 ns16550_irq.cir_arg = cir_arg; 127 132 irq_register(&ns16550_irq); 128 133 -
kernel/genarch/src/kbd/z8530.c
rdfd77382 r8d2760f 44 44 #include <arch/interrupt.h> 45 45 #include <arch/drivers/kbd.h> 46 #include <arch/drivers/fhc.h>47 46 #include <cpu.h> 48 47 #include <arch/asm.h> … … 84 83 z8530_write_a(&z8530, WR0, WR0_TX_IP_RST); 85 84 86 z8530_write_a(&z8530, WR1, WR1_IARCSC); /* interrupt on all characters */ 85 /* interrupt on all characters */ 86 z8530_write_a(&z8530, WR1, WR1_IARCSC); 87 87 88 88 /* 8 bits per character and enable receiver */ 89 89 z8530_write_a(&z8530, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); 90 90 91 z8530_write_a(&z8530, WR9, WR9_MIE); /* Master Interrupt Enable. */ 91 /* Master Interrupt Enable. */ 92 z8530_write_a(&z8530, WR9, WR9_MIE); 92 93 93 94 spinlock_lock(&z8530_irq.lock); … … 109 110 110 111 /** Initialize z8530. */ 111 void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr) 112 void 113 z8530_init(devno_t devno, uintptr_t vaddr, inr_t inr, cir_t cir, void *cir_arg) 112 114 { 113 115 chardev_initialize("z8530_kbd", &kbrd, &ops); … … 122 124 z8530_irq.claim = z8530_claim; 123 125 z8530_irq.handler = z8530_irq_handler; 126 z8530_irq.cir = cir; 127 z8530_irq.cir_arg = cir_arg; 124 128 irq_register(&z8530_irq); 125 129 … … 198 202 void z8530_irq_handler(irq_t *irq, void *arg, ...) 199 203 { 200 /*201 * So far, we know we got this interrupt through the FHC.202 * Since we don't have enough documentation about the FHC203 * and because the interrupt looks like level sensitive,204 * we cannot handle it by scheduling one of the level205 * interrupt traps. Process the interrupt directly.206 */207 204 if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) 208 205 ipc_irq_send_notif(irq); 209 206 else 210 207 z8530_interrupt(); 211 fhc_clear_interrupt(central_fhc, irq->inr);212 208 } 213 209 -
kernel/genarch/src/ofw/ebus.c
rdfd77382 r8d2760f 45 45 46 46 /** Apply EBUS ranges to EBUS register. */ 47 bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) 47 bool 48 ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) 48 49 { 49 50 ofw_tree_property_t *prop; … … 63 64 if (reg->space != range[i].child_space) 64 65 continue; 65 if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { 66 if (overlaps(reg->addr, reg->size, range[i].child_base, 67 range[i].size)) { 66 68 ofw_pci_reg_t pci_reg; 67 69 68 70 pci_reg.space = range[i].parent_space; 69 pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base); 71 pci_reg.addr = range[i].parent_base + 72 (reg->addr - range[i].child_base); 70 73 pci_reg.size = reg->size; 71 74 … … 77 80 } 78 81 79 bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr) 82 bool 83 ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, 84 uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) 80 85 { 81 86 ofw_tree_property_t *prop; … … 105 110 unsigned int i; 106 111 for (i = 0; i < count; i++) { 107 if ((intr_map[i].space == space) && (intr_map[i].addr == addr)108 112 if ((intr_map[i].space == space) && 113 (intr_map[i].addr == addr) && (intr_map[i].intr == intr)) 109 114 goto found; 110 115 } … … 114 119 /* 115 120 * We found the device that functions as an interrupt controller 116 * for the interrupt. We also found partial mapping from interrupt to INO. 121 * for the interrupt. We also found partial mapping from interrupt to 122 * INO. 117 123 */ 118 124 119 controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle); 125 controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), 126 intr_map[i].controller_handle); 120 127 if (!controller) 121 128 return false; … … 131 138 * Let the PCI do the next step in mapping the interrupt. 132 139 */ 133 if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr)) 140 if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, 141 inr, cir, cir_arg)) 134 142 return false; 135 143 -
kernel/genarch/src/ofw/fhc.c
rdfd77382 r8d2760f 110 110 } 111 111 112 bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr) 112 bool 113 ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, 114 uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) 113 115 { 114 116 fhc_t *fhc = NULL; … … 127 129 128 130 *inr = interrupt; 131 *cir = fhc_clear_interrupt; 132 *cir_arg = fhc; 129 133 return true; 130 134 } -
kernel/genarch/src/ofw/pci.c
rdfd77382 r8d2760f 50 50 #define PCI_IGN 0x1f 51 51 52 bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) 52 bool 53 ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) 53 54 { 54 55 ofw_tree_property_t *prop; … … 69 70 70 71 for (i = 0; i < ranges; i++) { 71 if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK)) 72 if ((reg->space & PCI_SPACE_MASK) != 73 (range[i].space & PCI_SPACE_MASK)) 72 74 continue; 73 if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { 74 *pa = range[i].parent_base + (reg->addr - range[i].child_base); 75 if (overlaps(reg->addr, reg->size, range[i].child_base, 76 range[i].size)) { 77 *pa = range[i].parent_base + 78 (reg->addr - range[i].child_base); 75 79 return true; 76 80 } … … 80 84 } 81 85 82 bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out) 86 bool 87 ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, 88 ofw_pci_reg_t *out) 83 89 { 84 90 if (reg->space & PCI_ABS_MASK) { … … 104 110 105 111 for (i = 0; i < assigned_addresses; i++) { 106 if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) { 112 if ((assigned_address[i].space & PCI_REG_MASK) == 113 (reg->space & PCI_REG_MASK)) { 107 114 out->space = assigned_address[i].space; 108 115 out->addr = reg->addr + assigned_address[i].addr; … … 120 127 * to a PCI bridge. 121 128 */ 122 bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr) 129 bool 130 ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, 131 int *inr, cir_t *cir, void **cir_arg) 123 132 { 124 133 pci_t *pci = node->device; … … 133 142 134 143 *inr = (PCI_IGN << IGN_SHIFT) | ino; 144 *cir = pci_clear_interrupt; 145 *cir_arg = pci; 135 146 136 147 return true; -
kernel/generic/include/ddi/irq.h
rdfd77382 r8d2760f 84 84 typedef void (* irq_handler_t)(struct irq *irq, void *arg, ...); 85 85 86 /** Type for function used to clear the interrupt. */ 87 typedef void (* cir_t)(void *arg, inr_t inr); 88 86 89 /** IPC notification config structure. 87 90 * … … 145 148 void *arg; 146 149 150 /** Clear interrupt routine. */ 151 cir_t cir; 152 /** First argument to the clear interrupt routine. */ 153 void *cir_arg; 154 147 155 /** Notification configuration structure. */ 148 156 ipc_notif_cfg_t notif_cfg; -
kernel/generic/src/ddi/irq.c
rdfd77382 r8d2760f 146 146 irq->handler = NULL; 147 147 irq->arg = NULL; 148 irq->cir = NULL; 149 irq->cir_arg = NULL; 148 150 irq->notif_cfg.notify = false; 149 151 irq->notif_cfg.answerbox = NULL;
Note:
See TracChangeset
for help on using the changeset viewer.