Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/hw/irc/apic/apic.c

    rb50bf6c2 rccca251  
    3838#include <ipc/services.h>
    3939#include <ipc/irc.h>
    40 #include <ns.h>
     40#include <ipc/ns.h>
    4141#include <sysinfo.h>
    4242#include <as.h>
    4343#include <ddi.h>
     44#include <libarch/ddi.h>
     45#include <align.h>
    4446#include <bool.h>
    4547#include <errno.h>
    4648#include <async.h>
     49#include <align.h>
     50#include <async.h>
    4751#include <stdio.h>
     52#include <ipc/devmap.h>
    4853
    4954#define NAME  "apic"
    5055
    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         if (irq == 0)
    136                 return 2;
    137         return irq;
    138 }
    139 
    14056static int apic_enable_irq(sysarg_t irq)
    14157{
    142         io_redirection_reg_t reg;
    143 
    144         if (irq > APIC_MAX_IRQ)
    145                 return ELIMIT;
    146 
    147         int pin = irq_to_pin(irq);
    148         if (pin == -1)
    149                 return ENOENT;
    150 
    151         reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
    152         reg.masked = false;
    153         io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
    154 
    155         return EOK;
     58        // FIXME: TODO
     59        return ENOTSUP;
    15660}
    15761
     
    16064 * @param iid   Hash of the request that opened the connection.
    16165 * @param icall Call data of the request that opened the connection.
    162  * @param arg   Local argument.
     66 *
    16367 */
    164 static void apic_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     68static void apic_connection(ipc_callid_t iid, ipc_call_t *icall)
    16569{
    16670        ipc_callid_t callid;
     
    17478        while (true) {
    17579                callid = async_get_call(&call);
    176                
    177                 if (!IPC_GET_IMETHOD(call)) {
    178                         /* The other side has hung up. */
    179                         async_answer_0(callid, EOK);
    180                         return;
    181                 }
    18280               
    18381                switch (IPC_GET_IMETHOD(call)) {
     
    204102       
    205103        if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
    206                 printf("%s: No APIC found\n", NAME);
     104                printf(NAME ": No APIC found\n");
    207105                return false;
    208         }
    209 
    210         int rc = pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE,
    211                 (void **) &io_apic);
    212         if (rc != EOK) {
    213                 printf("%s: Failed to enable PIO for APIC: %d\n", NAME, rc);
    214                 return false;   
    215106        }
    216107       
     
    223114int main(int argc, char **argv)
    224115{
    225         printf("%s: HelenOS APIC driver\n", NAME);
     116        printf(NAME ": HelenOS APIC driver\n");
    226117       
    227118        if (!apic_init())
    228119                return -1;
    229120       
    230         printf("%s: Accepting connections\n", NAME);
    231         task_retval(0);
     121        printf(NAME ": Accepting connections\n");
    232122        async_manager();
    233123       
Note: See TracChangeset for help on using the changeset viewer.