Changeset bd5f3b7 in mainline for uspace/srv/hw/irc/apic/apic.c
- Timestamp:
- 2011-08-21T13:07:35Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 00aece0, f1a9e87
- Parents:
- 86a34d3e (diff), a6480d5 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/irc/apic/apic.c
r86a34d3e rbd5f3b7 42 42 #include <as.h> 43 43 #include <ddi.h> 44 #include <libarch/ddi.h>45 #include <align.h>46 44 #include <bool.h> 47 45 #include <errno.h> 48 46 #include <async.h> 49 #include <align.h>50 #include <async.h>51 47 #include <stdio.h> 52 #include <ipc/devmap.h>53 48 54 49 #define NAME "apic" 55 50 51 #define APIC_MAX_IRQ 15 52 53 #define IOREGSEL (0x00U / sizeof(uint32_t)) 54 #define IOWIN (0x10U / sizeof(uint32_t)) 55 56 #define IOREDTBL 0x10U 57 58 /** I/O Register Select Register. */ 59 typedef union { 60 uint32_t value; 61 struct { 62 uint8_t reg_addr; /**< APIC Register Address. */ 63 unsigned int : 24; /**< Reserved. */ 64 } __attribute__ ((packed)); 65 } io_regsel_t; 66 67 /** I/O Redirection Register. */ 68 typedef struct io_redirection_reg { 69 union { 70 uint32_t lo; 71 struct { 72 uint8_t intvec; /**< Interrupt Vector. */ 73 unsigned int delmod : 3; /**< Delivery Mode. */ 74 unsigned int destmod : 1; /**< Destination mode. */ 75 unsigned int delivs : 1; /**< Delivery status (RO). */ 76 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 77 unsigned int irr : 1; /**< Remote IRR (RO). */ 78 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 79 unsigned int masked : 1; /**< Interrupt Mask. */ 80 unsigned int : 15; /**< Reserved. */ 81 } __attribute__ ((packed)); 82 }; 83 union { 84 uint32_t hi; 85 struct { 86 unsigned int : 24; /**< Reserved. */ 87 uint8_t dest : 8; /**< Destination Field. */ 88 } __attribute__ ((packed)); 89 }; 90 } __attribute__ ((packed)) io_redirection_reg_t; 91 92 // FIXME: get the address from the kernel 93 #define IO_APIC_BASE 0xfec00000UL 94 #define IO_APIC_SIZE 20 95 96 ioport32_t *io_apic = NULL; 97 98 /** Read from IO APIC register. 99 * 100 * @param address IO APIC register address. 101 * 102 * @return Content of the addressed IO APIC register. 103 * 104 */ 105 static uint32_t io_apic_read(uint8_t address) 106 { 107 io_regsel_t regsel; 108 109 regsel.value = io_apic[IOREGSEL]; 110 regsel.reg_addr = address; 111 io_apic[IOREGSEL] = regsel.value; 112 return io_apic[IOWIN]; 113 } 114 115 /** Write to IO APIC register. 116 * 117 * @param address IO APIC register address. 118 * @param val Content to be written to the addressed IO APIC register. 119 * 120 */ 121 static void io_apic_write(uint8_t address, uint32_t val) 122 { 123 io_regsel_t regsel; 124 125 regsel.value = io_apic[IOREGSEL]; 126 regsel.reg_addr = address; 127 io_apic[IOREGSEL] = regsel.value; 128 io_apic[IOWIN] = val; 129 } 130 131 static int irq_to_pin(int irq) 132 { 133 // FIXME: get the map from the kernel, even though this may work 134 // for simple cases 135 return irq; 136 } 137 56 138 static int apic_enable_irq(sysarg_t irq) 57 139 { 58 // FIXME: TODO 59 return ENOTSUP; 140 io_redirection_reg_t reg; 141 142 if (irq > APIC_MAX_IRQ) 143 return ELIMIT; 144 145 int pin = irq_to_pin(irq); 146 if (pin == -1) 147 return ENOENT; 148 149 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 150 reg.masked = false; 151 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 152 153 return EOK; 60 154 } 61 155 … … 111 205 return false; 112 206 } 207 208 if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE, 209 (void **) &io_apic) != EOK) 210 return false; 113 211 114 212 async_set_client_connection(apic_connection);
Note:
See TracChangeset
for help on using the changeset viewer.