Ignore:
File:
1 edited

Legend:

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

    rf5d51de 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>
     51#include <stdio.h>
     52#include <ipc/devmap.h>
    4753
    4854#define NAME  "apic"
    4955
    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 
    13756static int apic_enable_irq(sysarg_t irq)
    13857{
    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;
    15360}
    15461
     
    15764 * @param iid   Hash of the request that opened the connection.
    15865 * @param icall Call data of the request that opened the connection.
    159  * @param arg   Local argument.
     66 *
    16067 */
    161 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)
    16269{
    16370        ipc_callid_t callid;
     
    17178        while (true) {
    17279                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                 }
    17980               
    18081                switch (IPC_GET_IMETHOD(call)) {
     
    201102       
    202103        if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
    203                 printf("%s: No APIC found\n", NAME);
     104                printf(NAME ": No APIC found\n");
    204105                return false;
    205106        }
    206 
    207         if (pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE,
    208             (void **) &io_apic) != EOK)
    209                 return false;   
    210107       
    211108        async_set_client_connection(apic_connection);
     
    217114int main(int argc, char **argv)
    218115{
    219         printf("%s: HelenOS APIC driver\n", NAME);
     116        printf(NAME ": HelenOS APIC driver\n");
    220117       
    221118        if (!apic_init())
    222119                return -1;
    223120       
    224         printf("%s: Accepting connections\n", NAME);
    225         task_retval(0);
     121        printf(NAME ": Accepting connections\n");
    226122        async_manager();
    227123       
Note: See TracChangeset for help on using the changeset viewer.