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