Changes in uspace/srv/hw/irc/apic/apic.c [f5d51de:ccca251] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/hw/irc/apic/apic.c
rf5d51de rccca251 38 38 #include <ipc/services.h> 39 39 #include <ipc/irc.h> 40 #include < ns.h>40 #include <ipc/ns.h> 41 41 #include <sysinfo.h> 42 42 #include <as.h> 43 43 #include <ddi.h> 44 #include <libarch/ddi.h> 45 #include <align.h> 44 46 #include <bool.h> 45 47 #include <errno.h> 46 48 #include <async.h> 49 #include <align.h> 50 #include <async.h> 51 #include <stdio.h> 52 #include <ipc/devmap.h> 47 53 48 54 #define NAME "apic" 49 55 50 #define APIC_MAX_IRQ 1551 52 #define IOREGSEL (0x00U / sizeof(uint32_t))53 #define IOWIN (0x10U / sizeof(uint32_t))54 55 #define IOREDTBL 0x10U56 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 kernel92 #define IO_APIC_BASE 0xfec00000UL93 #define IO_APIC_SIZE 2094 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 work133 // for simple cases134 return irq;135 }136 137 56 static int apic_enable_irq(sysarg_t irq) 138 57 { 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; 58 // FIXME: TODO 59 return ENOTSUP; 153 60 } 154 61 … … 157 64 * @param iid Hash of the request that opened the connection. 158 65 * @param icall Call data of the request that opened the connection. 159 * @param arg Local argument.66 * 160 67 */ 161 static void apic_connection(ipc_callid_t iid, ipc_call_t *icall , void *arg)68 static void apic_connection(ipc_callid_t iid, ipc_call_t *icall) 162 69 { 163 70 ipc_callid_t callid; … … 171 78 while (true) { 172 79 callid = async_get_call(&call); 173 174 if (!IPC_GET_IMETHOD(call)) {175 /* The other side has hung up. */176 async_answer_0(callid, EOK);177 return;178 }179 80 180 81 switch (IPC_GET_IMETHOD(call)) { … … 201 102 202 103 if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) { 203 printf( "%s: No APIC found\n", NAME);104 printf(NAME ": No APIC found\n"); 204 105 return false; 205 106 } 206 207 if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE,208 (void **) &io_apic) != EOK)209 return false;210 107 211 108 async_set_client_connection(apic_connection); … … 217 114 int main(int argc, char **argv) 218 115 { 219 printf( "%s: HelenOS APIC driver\n", NAME);116 printf(NAME ": HelenOS APIC driver\n"); 220 117 221 118 if (!apic_init()) 222 119 return -1; 223 120 224 printf("%s: Accepting connections\n", NAME); 225 task_retval(0); 121 printf(NAME ": Accepting connections\n"); 226 122 async_manager(); 227 123
Note:
See TracChangeset
for help on using the changeset viewer.