Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset b446b02 in mainline


Ignore:
Timestamp:
2017-10-17T17:47:11Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master
Children:
b1efe3e
Parents:
a416d070
Message:

Enumerate APIC and i8259 via DDF.

Files:
6 added
8 edited
4 moved

Legend:

Unmodified
Added
Removed
  • .bzrignore

    ra416d070 rb446b02  
    196196uspace/dist/demo.xm
    197197uspace/dist/drv/ahci/
     198uspace/dist/drv/apic/
    198199uspace/dist/drv/ar9271/
    199200uspace/dist/drv/ata_bd/
     
    204205uspace/dist/drv/hdaudio/
    205206uspace/dist/drv/i8042/
     207uspace/dist/drv/i8259/
    206208uspace/dist/drv/icp/
    207209uspace/dist/drv/icp-ic/
     
    235237uspace/dist/inc/c/
    236238uspace/dist/logo.tga
    237 uspace/dist/srv/apic
    238239uspace/dist/srv/cdfs
    239240uspace/dist/srv/clipboard
     
    249250uspace/dist/srv/file_bd
    250251uspace/dist/srv/hound
    251 uspace/dist/srv/i8259
    252252uspace/dist/srv/inetsrv
    253253uspace/dist/srv/input
     
    296296uspace/drv/fb/amdm37x_dispc/amdm37x_dispc
    297297uspace/drv/fb/kfb/kfb
     298uspace/drv/intctl/apic/apic
     299uspace/drv/intctl/i8259/i8259
    298300uspace/drv/intctl/icp-ic/icp-ic
    299301uspace/drv/nic/ar9271/ar9271
     
    382384uspace/srv/hw/bus/cuda_adb/cuda_adb
    383385uspace/srv/hw/char/s3c24xx_uart/s3c24ser
    384 uspace/srv/hw/irc/apic/apic
    385 uspace/srv/hw/irc/i8259/i8259
    386386uspace/srv/hw/irc/obio/obio
    387387uspace/srv/klog/klog
  • boot/arch/amd64/Makefile.inc

    ra416d070 rb446b02  
    2929RD_SRVS_ESSENTIAL += \
    3030        $(USPACE_PATH)/srv/audio/hound/hound \
    31         $(USPACE_PATH)/srv/devman/devman \
    32         $(USPACE_PATH)/srv/hw/irc/apic/apic \
    33         $(USPACE_PATH)/srv/hw/irc/i8259/i8259
    34 
     31        $(USPACE_PATH)/srv/devman/devman
    3532
    3633RD_DRVS_ESSENTIAL += \
     34        intctl/apic \
     35        intctl/i8259 \
    3736        platform/pc \
    38         block/ata_bd \
    3937        bus/pci/pciintel \
    4038        bus/isa \
  • uspace/Makefile

    ra416d070 rb446b02  
    135135        srv/hid/remcons \
    136136        srv/hw/char/s3c24xx_uart \
    137         srv/hw/irc/apic \
    138         srv/hw/irc/i8259 \
    139137        srv/hw/irc/obio \
    140138        srv/hid/rfb \
     
    169167        drv/fb/amdm37x_dispc \
    170168        drv/fb/kfb \
     169        drv/intctl/apic \
     170        drv/intctl/i8259 \
    171171        drv/intctl/icp-ic \
    172172        drv/nic/ne2k \
  • uspace/app/init/init.c

    ra416d070 rb446b02  
    338338       
    339339        srv_start("/srv/devman");
    340         srv_start("/srv/apic");
    341         srv_start("/srv/i8259");
    342340        srv_start("/srv/obio");
    343341        srv_start("/srv/s3c24xx_uart");
  • uspace/drv/bus/isa/isa.c

    ra416d070 rb446b02  
    453453}
    454454
     455static void isa_fun_add_mem_range(isa_fun_t *fun, uintptr_t addr, size_t len)
     456{
     457        size_t count = fun->hw_resources.count;
     458        hw_resource_t *resources = fun->hw_resources.resources;
     459
     460        isa_bus_t *isa = isa_bus(ddf_fun_get_dev(fun->fnode));
     461
     462        if (count < ISA_MAX_HW_RES) {
     463                resources[count].type = MEM_RANGE;
     464                resources[count].res.mem_range.address = addr;
     465                resources[count].res.mem_range.address += isa->pio_win.mem.base;
     466                resources[count].res.mem_range.size = len;
     467                resources[count].res.mem_range.relative = true;
     468                resources[count].res.mem_range.endianness = LITTLE_ENDIAN;
     469
     470                fun->hw_resources.count++;
     471
     472                ddf_msg(LVL_NOTE, "Added mem range (addr=0x%zx, size=0x%x) to "
     473                    "function %s", (uintptr_t) addr, (unsigned int) len,
     474                    ddf_fun_get_name(fun->fnode));
     475        }
     476}
     477
    455478static void fun_parse_irq(isa_fun_t *fun, const char *val)
    456479{
     
    496519}
    497520
     521static void fun_parse_mem_range(isa_fun_t *fun, const char *val)
     522{
     523        uintptr_t addr;
     524        size_t len;
     525        char *end = NULL;
     526
     527        val = skip_spaces(val);
     528        addr = strtoul(val, &end, 0x10);
     529
     530        if (val == end)
     531                return;
     532
     533        val = skip_spaces(end);
     534        len = strtol(val, &end, 0x10);
     535
     536        if (val == end)
     537                return;
     538
     539        isa_fun_add_mem_range(fun, addr, len);
     540}
     541
    498542static void get_match_id(char **id, const char *val)
    499543{
     
    564608
    565609        if (!prop_parse(fun, line, "io_range", &fun_parse_io_range) &&
     610            !prop_parse(fun, line, "mem_range", &fun_parse_mem_range) &&
    566611            !prop_parse(fun, line, "irq", &fun_parse_irq) &&
    567612            !prop_parse(fun, line, "dma", &fun_parse_dma) &&
  • uspace/drv/bus/isa/isa.dev

    ra416d070 rb446b02  
     1i8259:
     2        match 100 isa/i8259
     3        mem_range 0x20 2
     4        mem_range 0xa0 2
     5
     6apic:
     7        match 100 isa/apic
     8        mem_range 0xfec00000 0x14
    19com1:
    210        match 100 isa/ns8250
  • uspace/drv/intctl/apic/Makefile

    ra416d070 rb446b02  
    2727#
    2828
    29 USPACE_PREFIX = ../../../..
     29USPACE_PREFIX = ../../..
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
    3032BINARY = apic
    3133
    3234SOURCES = \
    33         apic.c
     35        apic.c \
     36        main.c
    3437
    3538include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/intctl/apic/apic.c

    ra416d070 rb446b02  
    4040#include <sysinfo.h>
    4141#include <as.h>
     42#include <ddf/driver.h>
     43#include <ddf/log.h>
    4244#include <ddi.h>
    4345#include <stdbool.h>
     
    4547#include <async.h>
    4648#include <stdio.h>
     49
     50#include "apic.h"
    4751
    4852#define NAME  "apic"
     
    8993} __attribute__ ((packed)) io_redirection_reg_t;
    9094
    91 // FIXME: get the address from the kernel
    92 #define IO_APIC_BASE    0xfec00000UL
    9395#define IO_APIC_SIZE    20
    9496
    95 ioport32_t *io_apic = NULL;
    96 
    9797/** Read from IO APIC register.
    9898 *
     99 * @param apic APIC
    99100 * @param address IO APIC register address.
    100101 *
     
    102103 *
    103104 */
    104 static uint32_t io_apic_read(uint8_t address)
     105static uint32_t io_apic_read(apic_t *apic, uint8_t address)
    105106{
    106107        io_regsel_t regsel;
    107108
    108         regsel.value = io_apic[IOREGSEL];
     109        regsel.value = pio_read_32(&apic->regs[IOREGSEL]);
    109110        regsel.reg_addr = address;
    110         io_apic[IOREGSEL] = regsel.value;
    111         return io_apic[IOWIN];
     111        pio_write_32(&apic->regs[IOREGSEL], regsel.value);
     112        return pio_read_32(&apic->regs[IOWIN]);
    112113}
    113114
    114115/** Write to IO APIC register.
    115116 *
     117 * @param apic    APIC
    116118 * @param address IO APIC register address.
    117119 * @param val     Content to be written to the addressed IO APIC register.
    118120 *
    119121 */
    120 static void io_apic_write(uint8_t address, uint32_t val)
     122static void io_apic_write(apic_t *apic, uint8_t address, uint32_t val)
    121123{
    122124        io_regsel_t regsel;
    123125
    124         regsel.value = io_apic[IOREGSEL];
     126        regsel.value = pio_read_32(&apic->regs[IOREGSEL]);
    125127        regsel.reg_addr = address;
    126         io_apic[IOREGSEL] = regsel.value;
    127         io_apic[IOWIN] = val;
     128        pio_write_32(&apic->regs[IOREGSEL], regsel.value);
     129        pio_write_32(&apic->regs[IOWIN], val);
    128130}
    129131
     
    137139}
    138140
    139 static int apic_enable_irq(sysarg_t irq)
     141static int apic_enable_irq(apic_t *apic, sysarg_t irq)
    140142{
    141143        io_redirection_reg_t reg;
     
    148150                return ENOENT;
    149151
    150         reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2));
     152        reg.lo = io_apic_read(apic, (uint8_t) (IOREDTBL + pin * 2));
    151153        reg.masked = false;
    152         io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo);
     154        io_apic_write(apic, (uint8_t) (IOREDTBL + pin * 2), reg.lo);
    153155
    154156        return EOK;
     
    165167        ipc_callid_t callid;
    166168        ipc_call_t call;
     169        apic_t *apic;
    167170       
    168171        /*
     
    170173         */
    171174        async_answer_0(iid, EOK);
     175       
     176        apic = (apic_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
    172177       
    173178        while (true) {
     
    182187                switch (IPC_GET_IMETHOD(call)) {
    183188                case IRC_ENABLE_INTERRUPT:
    184                         async_answer_0(callid, apic_enable_irq(IPC_GET_ARG1(call)));
     189                        async_answer_0(callid, apic_enable_irq(apic,
     190                            IPC_GET_ARG1(call)));
    185191                        break;
    186192                case IRC_DISABLE_INTERRUPT:
     
    199205}
    200206
    201 /** Initialize the APIC driver.
    202  *
    203  */
    204 static bool apic_init(void)
    205 {
    206         sysarg_t apic;
    207         category_id_t irc_cat;
    208         service_id_t svc_id;
    209        
    210         if ((sysinfo_get_value("apic", &apic) != EOK) || (!apic)) {
     207/** Add APIC device. */
     208int apic_add(apic_t *apic, apic_res_t *res)
     209{
     210        sysarg_t have_apic;
     211        ddf_fun_t *fun_a = NULL;
     212        void *regs;
     213        int rc;
     214       
     215        if ((sysinfo_get_value("apic", &have_apic) != EOK) || (!have_apic)) {
    211216                printf("%s: No APIC found\n", NAME);
    212                 return false;
    213         }
    214 
    215         int rc = pio_enable((void *) IO_APIC_BASE, IO_APIC_SIZE,
    216                 (void **) &io_apic);
     217                return ENOTSUP;
     218        }
     219       
     220        rc = pio_enable((void *) res->base, IO_APIC_SIZE, &regs);
    217221        if (rc != EOK) {
    218222                printf("%s: Failed to enable PIO for APIC: %d\n", NAME, rc);
    219                 return false;   
    220         }
    221        
    222         async_set_fallback_port_handler(apic_connection, NULL);
    223        
    224         rc = loc_server_register(NAME);
     223                return EIO;
     224        }
     225
     226        apic->regs = (ioport32_t *)regs;
     227
     228        fun_a = ddf_fun_create(apic->dev, fun_exposed, "a");
     229        if (fun_a == NULL) {
     230                ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
     231                rc = ENOMEM;
     232                goto error;
     233        }
     234
     235        ddf_fun_set_conn_handler(fun_a, apic_connection);
     236
     237        rc = ddf_fun_bind(fun_a);
    225238        if (rc != EOK) {
    226                 printf("%s: Failed registering server. (%d)\n", NAME, rc);
    227                 return false;
    228         }
    229        
    230         rc = loc_service_register("irc/" NAME, &svc_id);
    231         if (rc != EOK) {
    232                 printf("%s: Failed registering service. (%d)\n", NAME, rc);
    233                 return false;
    234         }
    235        
    236         rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
    237         if (rc != EOK) {
    238                 printf("%s: Failed resolving category 'iplink' (%d).\n", NAME,
    239                     rc);
    240                 return false;
    241         }
    242        
    243         rc = loc_service_add_to_cat(svc_id, irc_cat);
    244         if (rc != EOK) {
    245                 printf("%s: Failed adding service to category (%d).\n", NAME,
    246                     rc);
    247                 return false;
    248         }
    249        
    250         return true;
    251 }
    252 
    253 int main(int argc, char **argv)
    254 {
    255         printf("%s: HelenOS APIC driver\n", NAME);
    256        
    257         if (!apic_init())
    258                 return -1;
    259        
    260         printf("%s: Accepting connections\n", NAME);
    261         task_retval(0);
    262         async_manager();
    263        
    264         /* Never reached */
    265         return 0;
     239                ddf_msg(LVL_ERROR, "Failed binding function 'a'. (%d)", rc);
     240                goto error;
     241        }
     242
     243        rc = ddf_fun_add_to_category(fun_a, "irc");
     244        if (rc != EOK)
     245                goto error;
     246
     247        return EOK;
     248error:
     249        if (fun_a != NULL)
     250                ddf_fun_destroy(fun_a);
     251        return rc;
     252}
     253
     254/** Remove APIC device */
     255int apic_remove(apic_t *apic)
     256{
     257        return ENOTSUP;
     258}
     259
     260/** APIC device gone */
     261int apic_gone(apic_t *apic)
     262{
     263        return ENOTSUP;
    266264}
    267265
  • uspace/drv/intctl/i8259/Makefile

    ra416d070 rb446b02  
    2727#
    2828
    29 USPACE_PREFIX = ../../../..
     29USPACE_PREFIX = ../../..
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include
    3032BINARY = i8259
    3133
    3234SOURCES = \
    33         i8259.c
     35        i8259.c \
     36        main.c
    3437
    3538include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/intctl/i8259/i8259.c

    ra416d070 rb446b02  
    4040#include <sysinfo.h>
    4141#include <as.h>
     42#include <ddf/log.h>
    4243#include <ddi.h>
    4344#include <align.h>
     
    4748#include <stdio.h>
    4849
     50#include "i8259.h"
     51
    4952#define NAME  "i8259"
    5053
    51 #define IO_RANGE0_START  ((ioport8_t *) 0x0020U)
    5254#define IO_RANGE0_SIZE   2
    53 
    54 #define IO_RANGE1_START  ((ioport8_t *) 0x00a0U)
    5555#define IO_RANGE1_SIZE   2
    56 
    57 static ioport8_t *io_range0;
    58 static ioport8_t *io_range1;
    5956
    6057#define PIC_PIC0PORT1  0
     
    6663#define PIC_MAX_IRQ  15
    6764
    68 static int pic_enable_irq(sysarg_t irq)
     65static int pic_enable_irq(i8259_t *i8259, sysarg_t irq)
    6966{
    7067        if (irq > PIC_MAX_IRQ)
     
    7572       
    7673        if (irqmask & 0xff) {
    77                 val = pio_read_8(io_range0 + PIC_PIC0PORT2);
    78                 pio_write_8(io_range0 + PIC_PIC0PORT2,
     74                val = pio_read_8(i8259->regs0 + PIC_PIC0PORT2);
     75                pio_write_8(i8259->regs0 + PIC_PIC0PORT2,
    7976                    (uint8_t) (val & (~(irqmask & 0xff))));
    8077        }
    8178       
    8279        if (irqmask >> 8) {
    83                 val = pio_read_8(io_range1 + PIC_PIC1PORT2);
    84                 pio_write_8(io_range1 + PIC_PIC1PORT2,
     80                val = pio_read_8(i8259->regs1 + PIC_PIC1PORT2);
     81                pio_write_8(i8259->regs1 + PIC_PIC1PORT2,
    8582                    (uint8_t) (val & (~(irqmask >> 8))));
    8683        }
     
    9996        ipc_callid_t callid;
    10097        ipc_call_t call;
     98        i8259_t *i8259 = NULL /* XXX */;
    10199       
    102100        /*
     
    104102         */
    105103        async_answer_0(iid, EOK);
     104       
     105        i8259 = (i8259_t *)ddf_dev_data_get(ddf_fun_get_dev((ddf_fun_t *)arg));
    106106       
    107107        while (true) {
     
    116116                switch (IPC_GET_IMETHOD(call)) {
    117117                case IRC_ENABLE_INTERRUPT:
    118                         async_answer_0(callid, pic_enable_irq(IPC_GET_ARG1(call)));
     118                        async_answer_0(callid, pic_enable_irq(i8259,
     119                            IPC_GET_ARG1(call)));
    119120                        break;
    120121                case IRC_DISABLE_INTERRUPT:
     
    133134}
    134135
    135 /** Initialize the i8259 driver.
    136  *
    137  */
    138 static bool i8259_init(void)
    139 {
    140         sysarg_t i8259;
    141         category_id_t irc_cat;
    142         service_id_t svc_id;
     136/** Add i8259 device. */
     137int i8259_add(i8259_t *i8259, i8259_res_t *res)
     138{
     139        sysarg_t have_i8259;
     140        ioport8_t *regs0;
     141        ioport8_t *regs1;
     142        ddf_fun_t *fun_a = NULL;
    143143        int rc;
    144144       
    145         if ((sysinfo_get_value("i8259", &i8259) != EOK) || (!i8259)) {
     145        if ((sysinfo_get_value("i8259", &have_i8259) != EOK) || (!have_i8259)) {
    146146                printf("%s: No i8259 found\n", NAME);
    147                 return false;
    148         }
    149        
    150         if ((pio_enable((void *) IO_RANGE0_START, IO_RANGE0_SIZE,
    151             (void **) &io_range0) != EOK) ||
    152             (pio_enable((void *) IO_RANGE1_START, IO_RANGE1_SIZE,
    153             (void **) &io_range1) != EOK)) {
     147                return ENOTSUP;
     148        }
     149       
     150        if ((pio_enable((void *) res->base0, IO_RANGE0_SIZE,
     151            (void **) &regs0) != EOK) ||
     152            (pio_enable((void *) res->base1, IO_RANGE1_SIZE,
     153            (void **) &regs1) != EOK)) {
    154154                printf("%s: i8259 not accessible\n", NAME);
    155                 return false;
    156         }
    157        
    158         async_set_fallback_port_handler(i8259_connection, NULL);
    159 
    160         rc = loc_server_register(NAME);
     155                return EIO;
     156        }
     157       
     158        i8259->regs0 = regs0;
     159        i8259->regs1 = regs1;
     160       
     161        fun_a = ddf_fun_create(i8259->dev, fun_exposed, "a");
     162        if (fun_a == NULL) {
     163                ddf_msg(LVL_ERROR, "Failed creating function 'a'.");
     164                rc = ENOMEM;
     165                goto error;
     166        }
     167       
     168        ddf_fun_set_conn_handler(fun_a, i8259_connection);
     169       
     170        rc = ddf_fun_bind(fun_a);
    161171        if (rc != EOK) {
    162                 printf("%s: Failed registering server. (%d)\n", NAME, rc);
    163                 return false;
    164         }
    165 
    166         rc = loc_service_register("irc/" NAME, &svc_id);
    167         if (rc != EOK) {
    168                 printf("%s: Failed registering service. (%d)\n", NAME, rc);
    169                 return false;
    170         }
    171 
    172         rc = loc_category_get_id("irc", &irc_cat, IPC_FLAG_BLOCKING);
    173         if (rc != EOK) {
    174                 printf("%s: Failed resolving category 'iplink' (%d).\n", NAME,
    175                     rc);
    176                 return false;
    177         }
    178 
    179         rc = loc_service_add_to_cat(svc_id, irc_cat);
    180         if (rc != EOK) {
    181                 printf("%s: Failed adding service to category (%d).\n", NAME,
    182                     rc);
    183                 return false;
    184         }
    185        
    186         return true;
    187 }
    188 
    189 int main(int argc, char **argv)
    190 {
    191         printf("%s: HelenOS i8259 driver\n", NAME);
    192        
    193         if (!i8259_init())
    194                 return -1;
    195        
    196         printf("%s: Accepting connections\n", NAME);
    197         task_retval(0);
    198         async_manager();
    199        
    200         /* Never reached */
    201         return 0;
     172                ddf_msg(LVL_ERROR, "Failed binding function 'a'. (%d)", rc);
     173                goto error;
     174        }
     175       
     176        rc = ddf_fun_add_to_category(fun_a, "irc");
     177        if (rc != EOK)
     178                goto error;
     179       
     180        return EOK;
     181error:
     182        if (fun_a != NULL)
     183                ddf_fun_destroy(fun_a);
     184        return rc;
     185}
     186
     187/** Remove i8259 device */
     188int i8259_remove(i8259_t *i8259)
     189{
     190        return ENOTSUP;
     191}
     192
     193/** i8259 device gone */
     194int i8259_gone(i8259_t *i8259)
     195{
     196        return ENOTSUP;
    202197}
    203198
  • uspace/drv/intctl/icp-ic/icp-ic.c

    ra416d070 rb446b02  
    4242#include <errno.h>
    4343#include <ipc/irc.h>
    44 #include <loc.h>
    4544#include <stdint.h>
    4645
  • uspace/drv/platform/icp/icp.c

    ra416d070 rb446b02  
    279279        int rc;
    280280
    281         rc = icp_add_fun(dev, "kbd", "arm/pl050", &icp_kbd_fun_proto);
    282         if (rc != EOK)
    283                 return rc;
    284 
    285         rc = icp_add_fun(dev, "mouse", "arm/pl050", &icp_mouse_fun_proto);
    286         if (rc != EOK)
    287                 return rc;
    288 
    289281        rc = icp_add_fun(dev, "intctl", "integratorcp/intctl",
    290282            &icp_ic_fun_proto);
     
    292284                return rc;
    293285
     286        rc = icp_add_fun(dev, "kbd", "arm/pl050", &icp_kbd_fun_proto);
     287        if (rc != EOK)
     288                return rc;
     289
     290        rc = icp_add_fun(dev, "mouse", "arm/pl050", &icp_mouse_fun_proto);
     291        if (rc != EOK)
     292                return rc;
     293
    294294        return EOK;
    295295}
Note: See TracChangeset for help on using the changeset viewer.