Changeset c01bb5f9 in mainline


Ignore:
Timestamp:
2012-02-16T21:21:39Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
39aa8ce, 856a36b, f943dd3
Parents:
edd7c63c (diff), 21063c2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/mm.

Files:
30 edited

Legend:

Unmodified
Added
Removed
  • abi/include/ddi/irq.h

    redd7c63c rc01bb5f9  
    3636#define ABI_DDI_IRQ_H_
    3737
     38typedef struct {
     39        uintptr_t base;
     40        size_t size;
     41} irq_pio_range_t;
     42
    3843typedef enum {
    3944        /** Read 1 byte from the I/O space. */
     
    6772        CMD_PIO_WRITE_A_32,
    6873       
    69         /** Read 1 byte from the memory space. */
    70         CMD_MEM_READ_8,
    71         /** Read 2 bytes from the memory space. */
    72         CMD_MEM_READ_16,
    73         /** Read 4 bytes from the memory space. */
    74         CMD_MEM_READ_32,
    75        
    76         /** Write 1 byte to the memory space. */
    77         CMD_MEM_WRITE_8,
    78         /** Write 2 bytes to the memory space. */
    79         CMD_MEM_WRITE_16,
    80         /** Write 4 bytes to the memory space. */
    81         CMD_MEM_WRITE_32,
    82        
    83         /** Write 1 byte from the source argument to the memory space. */
    84         CMD_MEM_WRITE_A_8,
    85         /** Write 2 bytes from the source argument to the memory space. */
    86         CMD_MEM_WRITE_A_16,
    87         /** Write 4 bytes from the source argument to the memory space. */
    88         CMD_MEM_WRITE_A_32,
    89        
    9074        /**
    9175         * Perform a bit masking on the source argument
     
    118102
    119103typedef struct {
     104        size_t rangecount;
     105        irq_pio_range_t *ranges;
    120106        size_t cmdcount;
    121107        irq_cmd_t *cmds;
  • kernel/arch/arm32/src/mach/integratorcp/integratorcp.c

    redd7c63c rc01bb5f9  
    332332        sysinfo_set_item_val("kbd", NULL, true);
    333333        sysinfo_set_item_val("kbd.inr", NULL, ICP_KBD_IRQ);
    334         sysinfo_set_item_val("kbd.address.status", NULL,
    335             (uintptr_t) icp_hw_map.kbd_stat);
    336         sysinfo_set_item_val("kbd.address.data", NULL,
    337             (uintptr_t) icp_hw_map.kbd_data);
     334        sysinfo_set_item_val("kbd.address.physical", NULL,
     335            ICP_KBD);
    338336
    339337}
  • kernel/arch/arm32/src/mach/testarm/testarm.c

    redd7c63c rc01bb5f9  
    128128        sysinfo_set_item_val("kbd", NULL, true);
    129129        sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
    130         sysinfo_set_item_val("kbd.address.virtual", NULL, (sysarg_t) gxemul_kbd);
     130        sysinfo_set_item_val("kbd.address.physical", NULL,
     131            GXEMUL_KBD_ADDRESS);
    131132#endif
    132133}
  • kernel/arch/ia64/src/ia64.c

    redd7c63c rc01bb5f9  
    188188        sysinfo_set_item_val("kbd.address.physical", NULL,
    189189            (uintptr_t) NS16550_BASE);
    190         sysinfo_set_item_val("kbd.address.kernel", NULL,
    191             (uintptr_t) NS16550_BASE);
    192190#endif
    193191       
  • kernel/arch/mips32/src/mips32.c

    redd7c63c rc01bb5f9  
    196196        sysinfo_set_item_val("kbd", NULL, true);
    197197        sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
    198         sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
     198        sysinfo_set_item_val("kbd.address.physical", NULL,
     199            PA2KA(MSIM_KBD_ADDRESS));
    199200#endif
    200201}
  • kernel/arch/ppc32/src/ppc32.c

    redd7c63c rc01bb5f9  
    232232                sysinfo_set_item_val("cuda.inr", NULL, IRQ_CUDA);
    233233                sysinfo_set_item_val("cuda.address.physical", NULL, pa);
    234                 sysinfo_set_item_val("cuda.address.kernel", NULL,
    235                     (uintptr_t) cuda);
    236234#endif
    237235        }
  • kernel/arch/sparc64/src/drivers/kbd.c

    redd7c63c rc01bb5f9  
    133133        sysinfo_set_item_val("kbd", NULL, true);
    134134        sysinfo_set_item_val("kbd.inr", NULL, inr);
    135         sysinfo_set_item_val("kbd.address.kernel", NULL,
    136             (uintptr_t) ns16550);
    137135        sysinfo_set_item_val("kbd.address.physical", NULL, pa);
    138136        sysinfo_set_item_val("kbd.type.ns16550", NULL, true);
  • kernel/generic/include/ddi/irq.h

    redd7c63c rc01bb5f9  
    134134        /** Notification configuration structure. */
    135135        ipc_notif_cfg_t notif_cfg;
    136        
    137         as_t *driver_as;
    138136} irq_t;
    139137
  • kernel/generic/include/ipc/irq.h

    redd7c63c rc01bb5f9  
    3636#define KERN_IPC_IRQ_H_
    3737
    38 /** Maximum length of IPC IRQ program */
     38/** Maximum number of IPC IRQ programmed I/O ranges. */
     39#define IRQ_MAX_RANGE_COUNT     8
     40
     41/** Maximum length of IPC IRQ program. */
    3942#define IRQ_MAX_PROG_SIZE  20
    4043
  • kernel/generic/src/ipc/irq.c

    redd7c63c rc01bb5f9  
    7474#include <arch.h>
    7575#include <mm/slab.h>
     76#include <mm/page.h>
     77#include <mm/km.h>
    7678#include <errno.h>
    7779#include <ddi/irq.h>
     
    8183#include <console/console.h>
    8284#include <print.h>
     85#include <macros.h>
     86
     87static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount)
     88{
     89        size_t i;
     90
     91        for (i = 0; i < rangecount; i++) {
     92#ifdef IO_SPACE_BOUNDARY
     93                if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY)
     94#endif
     95                        km_unmap(ranges[i].base, ranges[i].size);
     96        }
     97}
     98
     99static int ranges_map_and_apply(irq_pio_range_t *ranges, size_t rangecount,
     100    irq_cmd_t *cmds, size_t cmdcount)
     101{
     102        uintptr_t *pbase;
     103        size_t i, j;
     104
     105        /* Copy the physical base addresses aside. */
     106        pbase = malloc(rangecount * sizeof(uintptr_t), 0);
     107        for (i = 0; i < rangecount; i++)
     108                pbase[i] = ranges[i].base;
     109
     110        /* Map the PIO ranges into the kernel virtual address space. */
     111        for (i = 0; i < rangecount; i++) {
     112#ifdef IO_SPACE_BOUNDARY
     113                if ((void *) ranges[i].base < IO_SPACE_BOUNDARY)
     114                        continue;
     115#endif
     116                ranges[i].base = km_map(pbase[i], ranges[i].size,
     117                    PAGE_READ | PAGE_WRITE | PAGE_KERNEL | PAGE_NOT_CACHEABLE);
     118                if (!ranges[i].base) {
     119                        ranges_unmap(ranges, i);
     120                        free(pbase);
     121                        return ENOMEM;
     122                }
     123        }
     124
     125        /* Rewrite the pseudocode addresses from physical to kernel virtual. */
     126        for (i = 0; i < cmdcount; i++) {
     127                uintptr_t addr;
     128                size_t size;
     129
     130                /* Process only commands that use an address. */
     131                switch (cmds[i].cmd) {
     132                case CMD_PIO_READ_8:
     133                case CMD_PIO_WRITE_8:
     134                case CMD_PIO_WRITE_A_8:
     135                        size = 1;
     136                        break;
     137                case CMD_PIO_READ_16:
     138                case CMD_PIO_WRITE_16:
     139                case CMD_PIO_WRITE_A_16:
     140                        size = 2;
     141                        break;
     142                case CMD_PIO_READ_32:
     143                case CMD_PIO_WRITE_32:
     144                case CMD_PIO_WRITE_A_32:
     145                        size = 4;
     146                        break;
     147                default:
     148                        /* Move onto the next command. */
     149                        continue;
     150                }
     151
     152                addr = (uintptr_t) cmds[i].addr;
     153               
     154                for (j = 0; j < rangecount; j++) {
     155
     156                        /* Find the matching range. */
     157                        if (!iswithin(pbase[j], ranges[j].size, addr, size))
     158                                continue;
     159
     160                        /* Switch the command to a kernel virtual address. */
     161                        addr -= pbase[j];
     162                        addr += ranges[j].base;
     163
     164                        cmds[i].addr = (void *) addr;
     165                        break;
     166                }
     167
     168                if (j == rangecount) {
     169                        /*
     170                         * The address used in this command is outside of all
     171                         * defined ranges.
     172                         */
     173                        ranges_unmap(ranges, rangecount);
     174                        free(pbase);
     175                        return EINVAL;
     176                }
     177        }
     178
     179        free(pbase);
     180        return EOK;
     181}
    83182
    84183/** Free the top-half pseudocode.
     
    90189{
    91190        if (code) {
     191                ranges_unmap(code->ranges, code->rangecount);
     192                free(code->ranges);
    92193                free(code->cmds);
    93194                free(code);
     
    104205static irq_code_t *code_from_uspace(irq_code_t *ucode)
    105206{
     207        irq_pio_range_t *ranges = NULL;
     208        irq_cmd_t *cmds = NULL;
     209
    106210        irq_code_t *code = malloc(sizeof(*code), 0);
    107211        int rc = copy_from_uspace(code, ucode, sizeof(*code));
    108         if (rc != 0) {
    109                 free(code);
    110                 return NULL;
    111         }
    112        
    113         if (code->cmdcount > IRQ_MAX_PROG_SIZE) {
    114                 free(code);
    115                 return NULL;
    116         }
    117        
    118         irq_cmd_t *ucmds = code->cmds;
    119         code->cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
    120         rc = copy_from_uspace(code->cmds, ucmds,
     212        if (rc != EOK)
     213                goto error;
     214       
     215        if ((code->rangecount > IRQ_MAX_RANGE_COUNT) ||
     216            (code->cmdcount > IRQ_MAX_PROG_SIZE))
     217                goto error;
     218       
     219        ranges = malloc(sizeof(code->ranges[0]) * code->rangecount, 0);
     220        rc = copy_from_uspace(ranges, code->ranges,
     221            sizeof(code->ranges[0]) * code->rangecount);
     222        if (rc != EOK)
     223                goto error;
     224
     225        cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
     226        rc = copy_from_uspace(cmds, code->cmds,
    121227            sizeof(code->cmds[0]) * code->cmdcount);
    122         if (rc != 0) {
    123                 free(code->cmds);
    124                 free(code);
    125                 return NULL;
    126         }
    127        
     228        if (rc != EOK)
     229                goto error;
     230
     231        rc = ranges_map_and_apply(ranges, code->rangecount, cmds,
     232            code->cmdcount);
     233        if (rc != EOK)
     234                goto error;
     235
     236        code->ranges = ranges;
     237        code->cmds = cmds;
     238
    128239        return code;
     240
     241error:
     242        if (cmds)
     243                free(cmds);
     244        if (ranges)
     245                free(ranges);
     246        free(code);
     247        return NULL;
    129248}
    130249
     
    174293        irq->notif_cfg.code = code;
    175294        irq->notif_cfg.counter = 0;
    176         irq->driver_as = AS;
    177295       
    178296        /*
     
    365483                return IRQ_DECLINE;
    366484       
    367         as_t *current_as = AS;
    368         if (current_as != irq->driver_as)
    369                 as_switch(AS, irq->driver_as);
    370        
    371485        for (size_t i = 0; i < code->cmdcount; i++) {
    372486                uint32_t dstval;
    373                 void *va;
    374                 uint8_t val8;
    375                 uint16_t val16;
    376                 uint32_t val32;
    377487               
    378488                uintptr_t srcarg = code->cmds[i].srcarg;
     
    431541                        }
    432542                        break;
    433                 case CMD_MEM_READ_8:
    434                         va = code->cmds[i].addr;
    435                         memcpy_from_uspace(&val8, va, sizeof(val8));
    436                         if (dstarg)
    437                                 scratch[dstarg] = val8;
    438                         break;
    439                 case CMD_MEM_READ_16:
    440                         va = code->cmds[i].addr;
    441                         memcpy_from_uspace(&val16, va, sizeof(val16));
    442                         if (dstarg)
    443                                 scratch[dstarg] = val16;
    444                         break;
    445                 case CMD_MEM_READ_32:
    446                         va = code->cmds[i].addr;
    447                         memcpy_from_uspace(&val32, va, sizeof(val32));
    448                         if (dstarg)
    449                                 scratch[dstarg] = val32;
    450                         break;
    451                 case CMD_MEM_WRITE_8:
    452                         val8 = code->cmds[i].value;
    453                         va = code->cmds[i].addr;
    454                         memcpy_to_uspace(va, &val8, sizeof(val8));
    455                         break;
    456                 case CMD_MEM_WRITE_16:
    457                         val16 = code->cmds[i].value;
    458                         va = code->cmds[i].addr;
    459                         memcpy_to_uspace(va, &val16, sizeof(val16));
    460                         break;
    461                 case CMD_MEM_WRITE_32:
    462                         val32 = code->cmds[i].value;
    463                         va = code->cmds[i].addr;
    464                         memcpy_to_uspace(va, &val32, sizeof(val32));
    465                         break;
    466                 case CMD_MEM_WRITE_A_8:
    467                         if (srcarg) {
    468                                 val8 = scratch[srcarg];
    469                                 va = code->cmds[i].addr;
    470                                 memcpy_to_uspace(va, &val8, sizeof(val8));
    471                         }
    472                         break;
    473                 case CMD_MEM_WRITE_A_16:
    474                         if (srcarg) {
    475                                 val16 = scratch[srcarg];
    476                                 va = code->cmds[i].addr;
    477                                 memcpy_to_uspace(va, &val16, sizeof(val16));
    478                         }
    479                         break;
    480                 case CMD_MEM_WRITE_A_32:
    481                         if (srcarg) {
    482                                 val32 = scratch[srcarg];
    483                                 va = code->cmds[i].addr;
    484                                 memcpy_to_uspace(va, &val32, sizeof(val32));
    485                         }
    486                         break;
    487543                case CMD_BTEST:
    488544                        if ((srcarg) && (dstarg)) {
     
    498554                        break;
    499555                case CMD_ACCEPT:
    500                         if (AS != current_as)
    501                                 as_switch(AS, current_as);
    502556                        return IRQ_ACCEPT;
    503557                case CMD_DECLINE:
    504558                default:
    505                         if (AS != current_as)
    506                                 as_switch(AS, current_as);
    507559                        return IRQ_DECLINE;
    508560                }
    509561        }
    510        
    511         if (AS != current_as)
    512                 as_switch(AS, current_as);
    513562       
    514563        return IRQ_DECLINE;
  • kernel/generic/src/syscall/copy.c

    redd7c63c rc01bb5f9  
    5656 * @param size Size of the data to be copied.
    5757 *
    58  * @return 0 on success or error code from @ref errno.h.
     58 * @return EOK on success or error code from @ref errno.h.
    5959 */
    6060int copy_from_uspace(void *dst, const void *uspace_src, size_t size)
     
    9494
    9595        interrupts_restore(ipl);
    96         return !rc ? EPERM : 0;
     96        return !rc ? EPERM : EOK;
    9797}
    9898
  • uspace/drv/bus/usb/ohci/hc.c

    redd7c63c rc01bb5f9  
    4747    (I_SO | I_WDH | I_UE | I_RHSC)
    4848
    49 static const irq_cmd_t ohci_irq_commands[] =
    50 {
    51         { .cmd = CMD_MEM_READ_32, .dstarg = 1, .addr = NULL /*filled later*/ },
     49static const irq_pio_range_t ohci_pio_ranges[] = {
     50        {
     51                .base = 0,      /* filled later */
     52                .size = sizeof(ohci_regs_t)
     53        }
     54};
     55
     56static const irq_cmd_t ohci_irq_commands[] = {
     57        { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ },
    5258        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = OHCI_USED_INTERRUPTS },
    5359        { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    54         { .cmd = CMD_MEM_WRITE_A_32, .srcarg = 1, .addr = NULL /*filled later*/ },
     60        { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ },
    5561        { .cmd = CMD_ACCEPT },
    5662};
     
    6369static int hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    6470/*----------------------------------------------------------------------------*/
     71/** Get number of PIO ranges used in IRQ code.
     72 * @return Number of ranges.
     73 */
     74size_t hc_irq_pio_range_count(void)
     75{
     76        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
     77}
     78/*----------------------------------------------------------------------------*/
     79/*----------------------------------------------------------------------------*/
    6580/** Get number of commands used in IRQ code.
    6681 * @return Number of commands.
     
    7186}
    7287/*----------------------------------------------------------------------------*/
    73 /** Generate IRQ code commands.
    74  * @param[out] cmds Place to store the commands.
    75  * @param[in] cmd_size Size of the place (bytes).
     88/** Generate IRQ code.
     89 * @param[out] ranges PIO ranges buffer.
     90 * @param[in] ranges_size Size of the ranges buffer (bytes).
     91 * @param[out] cmds Commands buffer.
     92 * @param[in] cmds_size Size of the commands buffer (bytes).
    7693 * @param[in] regs Physical address of device's registers.
    7794 * @param[in] reg_size Size of the register area (bytes).
     
    7996 * @return Error code.
    8097 */
    81 int hc_get_irq_commands(
    82     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
    83 {
    84         if (cmd_size < sizeof(ohci_irq_commands)
    85             || reg_size < sizeof(ohci_regs_t))
     98int
     99hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
     100    size_t cmds_size, uintptr_t regs, size_t reg_size)
     101{
     102        if ((ranges_size < sizeof(ohci_pio_ranges)) ||
     103            (cmds_size < sizeof(ohci_irq_commands)) ||
     104            (reg_size < sizeof(ohci_regs_t)))
    86105                return EOVERFLOW;
    87106
    88         /* Create register mapping to use in IRQ handler.
    89          * This mapping should be present in kernel only.
    90          * Remove it from here when kernel knows how to create mappings
    91          * and accepts physical addresses in IRQ code.
    92          * TODO: remove */
    93         ohci_regs_t *registers;
    94         const int ret = pio_enable((void*)regs, reg_size, (void**)&registers);
    95         if (ret != EOK)
    96                 return ret;
    97 
    98         /* Some bogus access to force create mapping. DO NOT remove,
    99          * unless whole virtual addresses in irq is replaced
    100          * NOTE: Compiler won't remove this as ohci_regs_t members
    101          * are declared volatile.
    102          *
    103          * Introducing CMD_MEM set of IRQ code commands broke
    104          * assumption that IRQ code does not cause page faults.
    105          * If this happens during idling (THREAD == NULL)
    106          * it causes kernel panic.
    107          */
    108         registers->revision;
     107        memcpy(ranges, ohci_pio_ranges, sizeof(ohci_pio_ranges));
     108        ranges[0].base = regs;
    109109
    110110        memcpy(cmds, ohci_irq_commands, sizeof(ohci_irq_commands));
    111 
    112         void *address = (void*)&registers->interrupt_status;
    113         cmds[0].addr = address;
    114         cmds[3].addr = address;
     111        ohci_regs_t *registers = (ohci_regs_t *) regs;
     112        cmds[0].addr = (void *) &registers->interrupt_status;
     113        cmds[3].addr = (void *) &registers->interrupt_status;
     114
    115115        return EOK;
    116116}
  • uspace/drv/bus/usb/ohci/hc.h

    redd7c63c rc01bb5f9  
    7474} hc_t;
    7575
     76size_t hc_irq_pio_range_count(void);
    7677size_t hc_irq_cmd_count(void);
    77 int hc_get_irq_commands(
    78     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     78int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
     79    size_t);
    7980int hc_register_hub(hc_t *instance, ddf_fun_t *hub_fun);
    8081int hc_init(hc_t *instance, uintptr_t regs, size_t reg_size, bool interrupts);
  • uspace/drv/bus/usb/ohci/ohci.c

    redd7c63c rc01bb5f9  
    187187            (void *) reg_base, reg_size, irq);
    188188
    189         const size_t cmd_count = hc_irq_cmd_count();
    190         irq_cmd_t irq_cmds[cmd_count];
    191         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
    192 
    193         ret =
    194             hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
    195         CHECK_RET_DEST_FREE_RETURN(ret,
    196             "Failed to generate IRQ commands: %s.\n", str_error(ret));
     189        const size_t ranges_count = hc_irq_pio_range_count();
     190        const size_t cmds_count = hc_irq_cmd_count();
     191        irq_pio_range_t irq_ranges[ranges_count];
     192        irq_cmd_t irq_cmds[cmds_count];
     193        irq_code_t irq_code = {
     194                .rangecount = ranges_count,
     195                .ranges = irq_ranges,
     196                .cmdcount = cmds_count,
     197                .cmds = irq_cmds
     198        };
     199
     200        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     201            sizeof(irq_cmds), reg_base, reg_size);
     202        CHECK_RET_DEST_FREE_RETURN(ret,
     203            "Failed to generate IRQ code: %s.\n", str_error(ret));
    197204
    198205
  • uspace/drv/bus/usb/uhci/hc.c

    redd7c63c rc01bb5f9  
    4848    (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)
    4949
    50 
    51 static const irq_cmd_t uhci_irq_commands[] =
    52 {
     50static const irq_pio_range_t uhci_irq_pio_ranges[] = {
     51        {
     52                .base = 0,      /* filled later */
     53                .size = sizeof(uhci_regs_t)
     54        }
     55};
     56
     57static const irq_cmd_t uhci_irq_commands[] = {
    5358        { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/},
    5459        { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2,
     
    6873
    6974/*----------------------------------------------------------------------------*/
     75/** Get number of PIO ranges used in IRQ code.
     76 * @return Number of ranges.
     77 */
     78size_t hc_irq_pio_range_count(void)
     79{
     80        return sizeof(uhci_irq_pio_ranges) / sizeof(irq_pio_range_t);
     81}
     82/*----------------------------------------------------------------------------*/
    7083/** Get number of commands used in IRQ code.
    7184 * @return Number of commands.
     
    7689}
    7790/*----------------------------------------------------------------------------*/
    78 /** Generate IRQ code commands.
    79  * @param[out] cmds Place to store the commands.
    80  * @param[in] cmd_size Size of the place (bytes).
     91/** Generate IRQ code.
     92 * @param[out] ranges PIO ranges buffer.
     93 * @param[in] ranges_size Size of the ranges buffer (bytes).
     94 * @param[out] cmds Commands buffer.
     95 * @param[in] cmds_size Size of the commands buffer (bytes).
    8196 * @param[in] regs Physical address of device's registers.
    8297 * @param[in] reg_size Size of the register area (bytes).
     
    8499 * @return Error code.
    85100 */
    86 int hc_get_irq_commands(
    87     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size)
    88 {
    89         if (cmd_size < sizeof(uhci_irq_commands)
    90             || reg_size < sizeof(uhci_regs_t))
     101int
     102hc_get_irq_code(irq_pio_range_t ranges[], size_t ranges_size, irq_cmd_t cmds[],
     103    size_t cmds_size, uintptr_t regs, size_t reg_size)
     104{
     105        if ((ranges_size < sizeof(uhci_irq_pio_ranges)) ||
     106            (cmds_size < sizeof(uhci_irq_commands)) ||
     107            (reg_size < sizeof(uhci_regs_t)))
    91108                return EOVERFLOW;
    92109
    93         uhci_regs_t *registers = (uhci_regs_t*)regs;
     110        memcpy(ranges, uhci_irq_pio_ranges, sizeof(uhci_irq_pio_ranges));
     111        ranges[0].base = regs;
    94112
    95113        memcpy(cmds, uhci_irq_commands, sizeof(uhci_irq_commands));
    96 
    97         cmds[0].addr = (void*)&registers->usbsts;
    98         cmds[3].addr = (void*)&registers->usbsts;
     114        uhci_regs_t *registers = (uhci_regs_t *) regs;
     115        cmds[0].addr = &registers->usbsts;
     116        cmds[3].addr = &registers->usbsts;
     117
    99118        return EOK;
    100119}
  • uspace/drv/bus/usb/uhci/hc.h

    redd7c63c rc01bb5f9  
    121121} hc_t;
    122122
     123size_t hc_irq_pio_range_count(void);
    123124size_t hc_irq_cmd_count(void);
    124 int hc_get_irq_commands(
    125     irq_cmd_t cmds[], size_t cmd_size, uintptr_t regs, size_t reg_size);
     125int hc_get_irq_code(irq_pio_range_t [], size_t, irq_cmd_t [], size_t, uintptr_t,
     126    size_t);
    126127void hc_interrupt(hc_t *instance, uint16_t status);
    127128int hc_init(hc_t *instance, void *regs, size_t reg_size, bool interupts);
  • uspace/drv/bus/usb/uhci/uhci.c

    redd7c63c rc01bb5f9  
    198198            "Failed to disable legacy USB: %s.\n", str_error(ret));
    199199
    200         const size_t cmd_count = hc_irq_cmd_count();
    201         irq_cmd_t irq_cmds[cmd_count];
    202         ret =
    203             hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
     200        const size_t ranges_count = hc_irq_pio_range_count();
     201        const size_t cmds_count = hc_irq_cmd_count();
     202        irq_pio_range_t irq_ranges[ranges_count];
     203        irq_cmd_t irq_cmds[cmds_count];
     204        ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
     205            sizeof(irq_cmds), reg_base, reg_size);
    204206        CHECK_RET_DEST_FREE_RETURN(ret,
    205207            "Failed to generate IRQ commands: %s.\n", str_error(ret));
    206208
    207         irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
     209        irq_code_t irq_code = {
     210                .rangecount = ranges_count,
     211                .ranges = irq_ranges,
     212                .cmdcount = cmds_count,
     213                .cmds = irq_cmds
     214        };
    208215
    209216        /* Register handler to avoid interrupt lockup */
  • uspace/drv/char/i8042/i8042.c

    redd7c63c rc01bb5f9  
    105105};
    106106
     107static const irq_pio_range_t i8042_ranges[] = {
     108        {
     109                .base = 0,
     110                .size = sizeof(i8042_regs_t)
     111        }
     112};
     113
    107114/** i8042 Interrupt pseudo-code. */
    108115static const irq_cmd_t i8042_cmds[] = {
     
    239246        while (pio_read_8(&dev->regs->status) & i8042_OUTPUT_FULL)
    240247                (void) pio_read_8(&dev->regs->data);
    241        
     248
     249        const size_t range_count = sizeof(i8042_ranges) /
     250            sizeof(irq_pio_range_t);
     251        irq_pio_range_t ranges[range_count];
     252        memcpy(ranges, i8042_ranges, sizeof(i8042_ranges));
     253        ranges[0].base = (uintptr_t) regs;
     254
    242255        const size_t cmd_count = sizeof(i8042_cmds) / sizeof(irq_cmd_t);
    243256        irq_cmd_t cmds[cmd_count];
    244257        memcpy(cmds, i8042_cmds, sizeof(i8042_cmds));
    245         cmds[0].addr = (void *) &dev->regs->status;
    246         cmds[3].addr = (void *) &dev->regs->data;
    247        
     258        cmds[0].addr = (void *) &(((i8042_regs_t *) regs)->status);
     259        cmds[3].addr = (void *) &(((i8042_regs_t *) regs)->data);
     260
    248261        irq_code_t irq_code = {
     262                .rangecount = range_count,
     263                .ranges = ranges,
    249264                .cmdcount = cmd_count,
    250265                .cmds = cmds
  • uspace/drv/nic/e1k/e1k.c

    redd7c63c rc01bb5f9  
    228228static void e1000_send_frame(nic_t *, void *, size_t);
    229229
     230/** PIO ranges used in the IRQ code. */
     231irq_pio_range_t e1000_irq_pio_ranges[] = {
     232        {
     233                .base = 0,
     234                .size = PAGE_SIZE,      /* XXX */
     235        }
     236};
     237
    230238/** Commands to deal with interrupt
    231239 *
     
    256264/** Interrupt code definition */
    257265irq_code_t e1000_irq_code = {
     266        .rangecount = sizeof(e1000_irq_pio_ranges) /
     267            sizeof(irq_pio_range_t),
     268        .ranges = e1000_irq_pio_ranges,
    258269        .cmdcount = sizeof(e1000_irq_commands) / sizeof(irq_cmd_t),
    259270        .cmds = e1000_irq_commands
     
    12521263        fibril_mutex_lock(&irq_reg_mutex);
    12531264       
    1254         e1000_irq_code.cmds[0].addr = e1000->reg_base_virt + E1000_ICR;
    1255         e1000_irq_code.cmds[2].addr = e1000->reg_base_virt + E1000_IMC;
     1265        e1000_irq_code.ranges[0].base = (uintptr_t) e1000->reg_base_phys;
     1266        e1000_irq_code.cmds[0].addr = e1000->reg_base_phys + E1000_ICR;
     1267        e1000_irq_code.cmds[2].addr = e1000->reg_base_phys + E1000_IMC;
    12561268       
    12571269        int rc = register_interrupt_handler(nic_get_ddf_dev(nic),
  • uspace/drv/nic/ne2k/ne2k.c

    redd7c63c rc01bb5f9  
    6464#define NE2K(device) ((ne2k_t *) nic_get_specific(DRIVER_DATA(device)))
    6565
     66static irq_pio_range_t ne2k_ranges_prototype[] = {
     67        {
     68                .base = 0,
     69                .size = NE2K_IO_SIZE,
     70        }
     71};
     72
    6673/** NE2000 kernel interrupt command sequence.
    6774 *
     
    122129
    123130        if (ne2k->code.cmdcount == 0) {
    124                 irq_cmd_t *ne2k_cmds = malloc(sizeof(ne2k_cmds_prototype));
    125                 if (ne2k_cmds == NULL) {
     131                irq_pio_range_t *ne2k_ranges;
     132                irq_cmd_t *ne2k_cmds;
     133
     134                ne2k_ranges = malloc(sizeof(ne2k_ranges_prototype));
     135                if (!ne2k_ranges)
     136                        return ENOMEM;
     137                memcpy(ne2k_ranges, ne2k_ranges_prototype,
     138                    sizeof(ne2k_ranges_prototype));
     139                ne2k_ranges[0].base = (uintptr_t) ne2k->base_port;
     140
     141                ne2k_cmds = malloc(sizeof(ne2k_cmds_prototype));
     142                if (!ne2k_cmds) {
     143                        free(ne2k_ranges);
    126144                        return ENOMEM;
    127145                }
    128                 memcpy(ne2k_cmds, ne2k_cmds_prototype, sizeof (ne2k_cmds_prototype));
    129                 ne2k_cmds[0].addr = ne2k->port + DP_ISR;
    130                 ne2k_cmds[3].addr = ne2k->port + DP_IMR;
     146                memcpy(ne2k_cmds, ne2k_cmds_prototype,
     147                    sizeof(ne2k_cmds_prototype));
     148                ne2k_cmds[0].addr = ne2k->base_port + DP_ISR;
     149                ne2k_cmds[3].addr = ne2k->base_port + DP_IMR;
    131150                ne2k_cmds[4].addr = ne2k_cmds[0].addr;
    132                 ne2k_cmds[5].addr = ne2k->port + DP_TSR;
    133 
    134                 ne2k->code.cmdcount = sizeof(ne2k_cmds_prototype) / sizeof(irq_cmd_t);
     151                ne2k_cmds[5].addr = ne2k->base_port + DP_TSR;
     152
     153                ne2k->code.rangecount = sizeof(ne2k_ranges_prototype) /
     154                    sizeof(irq_pio_range_t);
     155                ne2k->code.ranges = ne2k_ranges;
     156
     157                ne2k->code.cmdcount = sizeof(ne2k_cmds_prototype) /
     158                    sizeof(irq_cmd_t);
    135159                ne2k->code.cmds = ne2k_cmds;
    136160        }
     
    148172                ne2k_t *ne2k = NE2K(dev);
    149173                if (ne2k) {
     174                        free(ne2k->code.ranges);
    150175                        free(ne2k->code.cmds);
    151176                }
  • uspace/drv/nic/rtl8139/driver.c

    redd7c63c rc01bb5f9  
    661661
    662662
     663irq_pio_range_t rtl8139_irq_pio_ranges[] = {
     664        {
     665                .base = 0,
     666                .size = RTL8139_IO_SIZE
     667        }
     668};
    663669
    664670/** Commands to deal with interrupt
     
    670676 */
    671677irq_cmd_t rtl8139_irq_commands[] = {
    672                 {
    673                                 /* Get the interrupt status */
    674                                 .cmd = CMD_PIO_READ_16,
    675                                 .addr = NULL,
    676                                 .dstarg = 2
    677                 },
    678                 {
    679                                 .cmd = CMD_PREDICATE,
    680                                 .value = 3,
    681                                 .srcarg = 2
    682                 },
    683                 {
    684                                 /* Mark interrupts as solved */
    685                                 .cmd = CMD_PIO_WRITE_16,
    686                                 .addr = NULL,
    687                                 .value = 0xFFFF
    688                 },
    689                 {
    690                                 /* Disable interrupts until interrupt routine is finished */
    691                                 .cmd = CMD_PIO_WRITE_16,
    692                                 .addr = NULL,
    693                                 .value = 0x0000
    694                 },
    695                 {
    696                                 .cmd = CMD_ACCEPT
    697                 }
     678        {
     679                /* Get the interrupt status */
     680                .cmd = CMD_PIO_READ_16,
     681                .addr = NULL,
     682                .dstarg = 2
     683        },
     684        {
     685                .cmd = CMD_PREDICATE,
     686                .value = 3,
     687                .srcarg = 2
     688        },
     689        {
     690                /* Mark interrupts as solved */
     691                .cmd = CMD_PIO_WRITE_16,
     692                .addr = NULL,
     693                .value = 0xFFFF
     694        },
     695        {
     696                /* Disable interrupts until interrupt routine is finished */
     697                .cmd = CMD_PIO_WRITE_16,
     698                .addr = NULL,
     699                .value = 0x0000
     700        },
     701        {
     702                .cmd = CMD_ACCEPT
     703        }
    698704};
    699705
    700706/** Interrupt code definition */
    701707irq_code_t rtl8139_irq_code = {
    702         .cmdcount = sizeof(rtl8139_irq_commands)/sizeof(irq_cmd_t),
     708        .rangecount = sizeof(rtl8139_irq_pio_ranges) / sizeof(irq_pio_range_t),
     709        .ranges = rtl8139_irq_pio_ranges,
     710        .cmdcount = sizeof(rtl8139_irq_commands) / sizeof(irq_cmd_t),
    703711        .cmds = rtl8139_irq_commands
    704712};
     
    890898        RTL8139_IRQ_STRUCT_LOCK();
    891899
    892         rtl8139_irq_code.cmds[0].addr = rtl8139->io_port + ISR;
    893         rtl8139_irq_code.cmds[2].addr = rtl8139->io_port + ISR;
    894         rtl8139_irq_code.cmds[3].addr = rtl8139->io_port + IMR;
     900        rtl8139_irq_code.ranges[0].base = (uintptr_t) rtl8139->io_addr;
     901        rtl8139_irq_code.cmds[0].addr = rtl8139->io_addr + ISR;
     902        rtl8139_irq_code.cmds[2].addr = rtl8139->io_addr + ISR;
     903        rtl8139_irq_code.cmds[3].addr = rtl8139->io_addr + IMR;
    895904        int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
    896                 rtl8139->irq, rtl8139_interrupt_handler, &rtl8139_irq_code);
     905            rtl8139->irq, rtl8139_interrupt_handler, &rtl8139_irq_code);
    897906
    898907        RTL8139_IRQ_STRUCT_UNLOCK();
  • uspace/lib/drv/generic/interrupt.c

    redd7c63c rc01bb5f9  
    6868
    6969static irq_code_t default_pseudocode = {
     70        0,
     71        NULL,
    7072        sizeof(default_cmds) / sizeof(irq_cmd_t),
    7173        default_cmds
  • uspace/srv/hid/input/port/gxemul.c

    redd7c63c rc01bb5f9  
    5757static kbd_dev_t *kbd_dev;
    5858
     59static irq_pio_range_t gxemul_ranges[] = {
     60        {
     61                .base = 0,
     62                .size = 1
     63        }
     64};
     65
    5966static irq_cmd_t gxemul_cmds[] = {
    6067        {
     
    6976
    7077static irq_code_t gxemul_kbd = {
     78        sizeof(gxemul_ranges) / sizeof(irq_pio_range_t),
     79        gxemul_ranges,
    7180        sizeof(gxemul_cmds) / sizeof(irq_cmd_t),
    7281        gxemul_cmds
     
    8190       
    8291        sysarg_t addr;
    83         if (sysinfo_get_value("kbd.address.virtual", &addr) != EOK)
     92        if (sysinfo_get_value("kbd.address.physical", &addr) != EOK)
    8493                return -1;
    8594       
     
    8998       
    9099        async_set_interrupt_received(gxemul_irq_handler);
     100        gxemul_ranges[0].base = addr;
    91101        gxemul_cmds[0].addr = (void *) addr;
    92102        irq_register(inr, device_assign_devno(), 0, &gxemul_kbd);
  • uspace/srv/hid/input/port/msim.c

    redd7c63c rc01bb5f9  
    5757static kbd_dev_t *kbd_dev;
    5858
     59static irq_pio_range_t msim_ranges[] = {
     60        {
     61                .base = 0,
     62                .size = 1
     63        }
     64};
     65
    5966static irq_cmd_t msim_cmds[] = {
    6067        {
     
    6976
    7077static irq_code_t msim_kbd = {
     78        sizeof(msim_ranges) / sizeof(irq_pio_range_t),
     79        msim_ranges,
    7180        sizeof(msim_cmds) / sizeof(irq_cmd_t),
    7281        msim_cmds
     
    7988        kbd_dev = kdev;
    8089
    81         sysarg_t vaddr;
    82         if (sysinfo_get_value("kbd.address.virtual", &vaddr) != EOK)
     90        sysarg_t paddr;
     91        if (sysinfo_get_value("kbd.address.physical", &paddr) != EOK)
    8392                return -1;
    8493       
     
    8796                return -1;
    8897       
    89         msim_cmds[0].addr = (void *) vaddr;
     98        msim_ranges[0].base = paddr;
     99        msim_cmds[0].addr = (void *) paddr;
    90100        async_set_interrupt_received(msim_irq_handler);
    91101        irq_register(inr, device_assign_devno(), 0, &msim_kbd);
  • uspace/srv/hid/input/port/ns16550.c

    redd7c63c rc01bb5f9  
    7070#define LSR_DATA_READY  0x01
    7171
     72static irq_pio_range_t ns16550_ranges[] = {
     73        {
     74                .base = 0,
     75                .size = 8
     76        }
     77};
     78
    7279static irq_cmd_t ns16550_cmds[] = {
    7380        {
     
    98105
    99106irq_code_t ns16550_kbd = {
     107        sizeof(ns16550_ranges) / sizeof(irq_pio_range_t),
     108        ns16550_ranges,
    100109        sizeof(ns16550_cmds) / sizeof(irq_cmd_t),
    101110        ns16550_cmds
     
    105114
    106115static uintptr_t ns16550_physical;
    107 static uintptr_t ns16550_kernel;
    108116
    109117static kbd_dev_t *kbd_dev;
     
    124132                return -1;
    125133       
    126         if (sysinfo_get_value("kbd.address.kernel", &ns16550_kernel) != EOK)
    127                 return -1;
    128        
    129134        sysarg_t inr;
    130135        if (sysinfo_get_value("kbd.inr", &inr) != EOK)
    131136                return -1;
    132137       
    133         ns16550_kbd.cmds[0].addr = (void *) (ns16550_kernel + LSR_REG);
    134         ns16550_kbd.cmds[3].addr = (void *) (ns16550_kernel + RBR_REG);
     138        ns16550_kbd.ranges[0].base = ns16550_physical;
     139        ns16550_kbd.cmds[0].addr = (void *) (ns16550_physical + LSR_REG);
     140        ns16550_kbd.cmds[3].addr = (void *) (ns16550_physical + RBR_REG);
    135141       
    136142        async_set_interrupt_received(ns16550_irq_handler);
  • uspace/srv/hid/input/port/pl050.c

    redd7c63c rc01bb5f9  
    6161static kbd_dev_t *kbd_dev;
    6262
     63#define PL050_STAT      4
     64#define PL050_DATA      8
     65
    6366#define PL050_STAT_RXFULL  (1 << 4)
     67
     68static irq_pio_range_t pl050_ranges[] = {
     69        {
     70                .base = 0,
     71                .size = 9,
     72        }
     73};
    6474
    6575static irq_cmd_t pl050_cmds[] = {
     
    91101
    92102static irq_code_t pl050_kbd = {
     103        sizeof(pl050_ranges) / sizeof(irq_pio_range_t),
     104        pl050_ranges,
    93105        sizeof(pl050_cmds) / sizeof(irq_cmd_t),
    94106        pl050_cmds
     
    102114       
    103115        sysarg_t addr;
    104         if (sysinfo_get_value("kbd.address.status", &addr) != EOK)
     116        if (sysinfo_get_value("kbd.address.physical", &addr) != EOK)
    105117                return -1;
    106118       
    107         pl050_kbd.cmds[0].addr = (void *) addr;
    108        
    109         if (sysinfo_get_value("kbd.address.data", &addr) != EOK)
    110                 return -1;
    111        
    112         pl050_kbd.cmds[3].addr = (void *) addr;
     119        pl050_kbd.ranges[0].base = addr;
     120        pl050_kbd.cmds[0].addr = (void *) addr + PL050_STAT;
     121        pl050_kbd.cmds[3].addr = (void *) addr + PL050_DATA;
    113122       
    114123        sysarg_t inr;
  • uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c

    redd7c63c rc01bb5f9  
    6262
    6363static irq_code_t ts_irq_code = {
     64        0,
     65        NULL,
    6466        sizeof(ts_irq_cmds) / sizeof(irq_cmd_t),
    6567        ts_irq_cmds
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    redd7c63c rc01bb5f9  
    104104enum {
    105105        ADB_MAX_ADDR    = 16
     106};
     107
     108static irq_pio_range_t cuda_ranges[] = {
     109        {
     110                .base = 0,
     111                .size = sizeof(cuda_t)
     112        }
    106113};
    107114
     
    130137
    131138static irq_code_t cuda_irq_code = {
     139        sizeof(cuda_ranges) / sizeof(irq_pio_range_t),
     140        cuda_ranges,
    132141        sizeof(cuda_cmds) / sizeof(irq_cmd_t),
    133142        cuda_cmds
     
    255264                return -1;
    256265       
    257         if (sysinfo_get_value("cuda.address.kernel", &(instance->cuda_kernel)) != EOK)
    258                 return -1;
    259        
    260266        void *vaddr;
    261267        if (pio_enable((void *) instance->cuda_physical, sizeof(cuda_t), &vaddr) != 0)
     
    274280        pio_write_8(&dev->ier, IER_CLR | ALL_INT);
    275281
    276         cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_kernel)->ifr;
     282        cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;
     283        cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
    277284        async_set_interrupt_received(cuda_irq_handler);
    278285        irq_register(10, device_assign_devno(), 0, &cuda_irq_code);
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.h

    redd7c63c rc01bb5f9  
    111111        cuda_t *cuda;
    112112        uintptr_t cuda_physical;
    113         uintptr_t cuda_kernel;
    114113
    115114        uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
  • uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c

    redd7c63c rc01bb5f9  
    6060
    6161static irq_code_t uart_irq_code = {
     62        0,
     63        NULL,
    6264        sizeof(uart_irq_cmds) / sizeof(irq_cmd_t),
    6365        uart_irq_cmds
Note: See TracChangeset for help on using the changeset viewer.