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

Changeset 8486c07 in mainline


Ignore:
Timestamp:
2012-07-21T14:01:12Z (9 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master
Children:
eb3683a
Parents:
56c167c
Message:

IRQ pseudocode improvements

  • rename CMD_BTEST to CMD_AND (less cryptic)
  • implement CMD_LOAD to load a constant value into a scratch register
  • implement simple pseudocode static checker
  • slightly alter the semantics of several pseudocode commands (scratch[0] is a usable field, although not propagated to the IPC notification)
Files:
9 edited

Legend:

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

    r56c167c r8486c07  
    9696        CMD_PIO_WRITE_A_32,
    9797       
    98         /**
    99          * Perform a bit masking on the source argument
    100          * and store the result into the destination argument.
     98        /** Load value.
     99         *
     100         * value -> scratch[dstarg]
    101101         */
    102         CMD_BTEST,
     102        CMD_LOAD,
     103       
     104        /** Perform bitwise conjunction.
     105         *
     106         * scratch[srcarg] & value -> scratch[dstarg]
     107         */
     108        CMD_AND,
    103109       
    104110        /** Predicate the execution of the following commands.
  • kernel/generic/src/ipc/irq.c

    r56c167c r8486c07  
    176176}
    177177
     178/** Statically check the top-half pseudocode
     179 *
     180 * Check the top-half pseudocode for invalid or unsafe
     181 * constructs.
     182 *
     183 */
     184static int code_check(irq_cmd_t *cmds, size_t cmdcount)
     185{
     186        for (size_t i = 0; i < cmdcount; i++) {
     187                /*
     188                 * Check for accepted ranges.
     189                 */
     190                if (cmds[i].cmd >= CMD_LAST)
     191                        return EINVAL;
     192               
     193                if (cmds[i].srcarg >= IPC_CALL_LEN)
     194                        return EINVAL;
     195               
     196                if (cmds[i].dstarg >= IPC_CALL_LEN)
     197                        return EINVAL;
     198               
     199                switch (cmds[i].cmd) {
     200                case CMD_PREDICATE:
     201                        /*
     202                         * Check for control flow overflow.
     203                         * Note that jumping just beyond the last
     204                         * command is a correct behaviour.
     205                         */
     206                        if (i + cmds[i].value > cmdcount)
     207                                return EINVAL;
     208                       
     209                        break;
     210                default:
     211                        break;
     212                }
     213        }
     214       
     215        return EOK;
     216}
     217
    178218/** Free the top-half pseudocode.
    179219 *
     
    223263        if (rc != EOK)
    224264                goto error;
    225 
     265       
     266        rc = code_check(cmds, code->cmdcount);
     267        if (rc != EOK)
     268                goto error;
     269       
    226270        rc = ranges_map_and_apply(ranges, code->rangecount, cmds,
    227271            code->cmdcount);
     
    492536       
    493537        for (size_t i = 0; i < code->cmdcount; i++) {
    494                 uint32_t dstval;
    495                
    496538                uintptr_t srcarg = code->cmds[i].srcarg;
    497539                uintptr_t dstarg = code->cmds[i].dstarg;
    498540               
    499                 if (srcarg >= IPC_CALL_LEN)
    500                         break;
    501                
    502                 if (dstarg >= IPC_CALL_LEN)
    503                         break;
    504        
    505541                switch (code->cmds[i].cmd) {
    506542                case CMD_PIO_READ_8:
    507                         dstval = pio_read_8((ioport8_t *) code->cmds[i].addr);
    508                         if (dstarg)
    509                                 scratch[dstarg] = dstval;
     543                        scratch[dstarg] =
     544                            pio_read_8((ioport8_t *) code->cmds[i].addr);
    510545                        break;
    511546                case CMD_PIO_READ_16:
    512                         dstval = pio_read_16((ioport16_t *) code->cmds[i].addr);
    513                         if (dstarg)
    514                                 scratch[dstarg] = dstval;
     547                        scratch[dstarg] =
     548                            pio_read_16((ioport16_t *) code->cmds[i].addr);
    515549                        break;
    516550                case CMD_PIO_READ_32:
    517                         dstval = pio_read_32((ioport32_t *) code->cmds[i].addr);
    518                         if (dstarg)
    519                                 scratch[dstarg] = dstval;
     551                        scratch[dstarg] =
     552                            pio_read_32((ioport32_t *) code->cmds[i].addr);
    520553                        break;
    521554                case CMD_PIO_WRITE_8:
     
    532565                        break;
    533566                case CMD_PIO_WRITE_A_8:
    534                         if (srcarg) {
    535                                 pio_write_8((ioport8_t *) code->cmds[i].addr,
    536                                     (uint8_t) scratch[srcarg]);
    537                         }
     567                        pio_write_8((ioport8_t *) code->cmds[i].addr,
     568                            (uint8_t) scratch[srcarg]);
    538569                        break;
    539570                case CMD_PIO_WRITE_A_16:
    540                         if (srcarg) {
    541                                 pio_write_16((ioport16_t *) code->cmds[i].addr,
    542                                     (uint16_t) scratch[srcarg]);
    543                         }
     571                        pio_write_16((ioport16_t *) code->cmds[i].addr,
     572                            (uint16_t) scratch[srcarg]);
    544573                        break;
    545574                case CMD_PIO_WRITE_A_32:
    546                         if (srcarg) {
    547                                 pio_write_32((ioport32_t *) code->cmds[i].addr,
    548                                     (uint32_t) scratch[srcarg]);
    549                         }
    550                         break;
    551                 case CMD_BTEST:
    552                         if ((srcarg) && (dstarg)) {
    553                                 dstval = scratch[srcarg] & code->cmds[i].value;
    554                                 scratch[dstarg] = dstval;
    555                         }
     575                        pio_write_32((ioport32_t *) code->cmds[i].addr,
     576                            (uint32_t) scratch[srcarg]);
     577                        break;
     578                case CMD_LOAD:
     579                        scratch[dstarg] = code->cmds[i].value;
     580                        break;
     581                case CMD_AND:
     582                        scratch[dstarg] = scratch[srcarg] &
     583                            code->cmds[i].value;
    556584                        break;
    557585                case CMD_PREDICATE:
    558                         if ((srcarg) && (!scratch[srcarg])) {
     586                        if (scratch[srcarg] == 0)
    559587                                i += code->cmds[i].value;
    560                                 continue;
    561                         }
     588                       
    562589                        break;
    563590                case CMD_ACCEPT:
  • uspace/drv/bus/usb/ohci/hc.c

    r56c167c r8486c07  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
     28
    2829/** @addtogroup drvusbohcihc
    2930 * @{
     
    3233 * @brief OHCI Host controller driver routines
    3334 */
     35
    3436#include <errno.h>
    3537#include <str_error.h>
     
    4951static const irq_pio_range_t ohci_pio_ranges[] = {
    5052        {
    51                 .base = 0,      /* filled later */
     53                .base = 0,
    5254                .size = sizeof(ohci_regs_t)
    5355        }
     
    5557
    5658static const irq_cmd_t ohci_irq_commands[] = {
    57         { .cmd = CMD_PIO_READ_32, .dstarg = 1, .addr = NULL /* filled later */ },
    58         { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2, .value = 0 /* filled later */ },
    59         { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    60         { .cmd = CMD_PIO_WRITE_A_32, .srcarg = 1, .addr = NULL /* filled later */ },
    61         { .cmd = CMD_ACCEPT },
     59        {
     60                .cmd = CMD_PIO_READ_32,
     61                .dstarg = 1,
     62                .addr = NULL
     63        },
     64        {
     65                .cmd = CMD_AND,
     66                .srcarg = 1,
     67                .dstarg = 2,
     68                .value = OHCI_USED_INTERRUPTS
     69        },
     70        {
     71                .cmd = CMD_PREDICATE,
     72                .srcarg = 2,
     73                .value = 2
     74        },
     75        {
     76                .cmd = CMD_PIO_WRITE_A_32,
     77                .srcarg = 1,
     78                .addr = NULL
     79        },
     80        {
     81                .cmd = CMD_ACCEPT
     82        }
    6283};
    6384
     
    7697        return sizeof(ohci_pio_ranges) / sizeof(irq_pio_range_t);
    7798}
    78 
    7999
    80100/** Get number of commands used in IRQ code.
     
    111131        ohci_regs_t *registers = (ohci_regs_t *) regs;
    112132        cmds[0].addr = (void *) &registers->interrupt_status;
    113         cmds[1].value = OHCI_USED_INTERRUPTS;
    114133        cmds[3].addr = (void *) &registers->interrupt_status;
    115134
     
    445464                return;
    446465        }
     466
    447467        const unsigned hc_status = C_HCFS_GET(instance->registers->control);
    448468        /* Interrupt routing disabled && status != USB_RESET => BIOS active */
  • uspace/drv/bus/usb/uhci/hc.c

    r56c167c r8486c07  
    5050static const irq_pio_range_t uhci_irq_pio_ranges[] = {
    5151        {
    52                 .base = 0,      /* filled later */
     52                .base = 0,
    5353                .size = sizeof(uhci_regs_t)
    5454        }
     
    5656
    5757static const irq_cmd_t uhci_irq_commands[] = {
    58         { .cmd = CMD_PIO_READ_16, .dstarg = 1, .addr = NULL/*filled later*/},
    59         { .cmd = CMD_BTEST, .srcarg = 1, .dstarg = 2,
    60           .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS },
    61         { .cmd = CMD_PREDICATE, .srcarg = 2, .value = 2 },
    62         { .cmd = CMD_PIO_WRITE_A_16, .srcarg = 1, .addr = NULL/*filled later*/},
    63         { .cmd = CMD_ACCEPT },
     58        {
     59                .cmd = CMD_PIO_READ_16,
     60                .dstarg = 1,
     61                .addr = NULL
     62        },
     63        {
     64                .cmd = CMD_AND,
     65                .srcarg = 1,
     66                .dstarg = 2,
     67                .value = UHCI_STATUS_USED_INTERRUPTS | UHCI_STATUS_NM_INTERRUPTS
     68        },
     69        {
     70                .cmd = CMD_PREDICATE,
     71                .srcarg = 2,
     72                .value = 2
     73        },
     74        {
     75                .cmd = CMD_PIO_WRITE_A_16,
     76                .srcarg = 1,
     77                .addr = NULL
     78        },
     79        {
     80                .cmd = CMD_ACCEPT
     81        }
    6482};
    6583
  • uspace/drv/char/i8042/i8042.c

    r56c167c r8486c07  
    120120        },
    121121        {
    122                 .cmd = CMD_BTEST,
     122                .cmd = CMD_AND,
    123123                .value = i8042_OUTPUT_FULL,
    124124                .srcarg = 1,
  • uspace/drv/nic/ne2k/ne2k.c

    r56c167c r8486c07  
    8383        {
    8484                /* Mask supported interrupt causes */
    85                 .cmd = CMD_BTEST,
     85                .cmd = CMD_AND,
    8686                .value = (ISR_PRX | ISR_PTX | ISR_RXE | ISR_TXE | ISR_OVW |
    8787                    ISR_CNT | ISR_RDC),
  • uspace/srv/hid/input/port/ns16550.c

    r56c167c r8486c07  
    8484        },
    8585        {
    86                 .cmd = CMD_BTEST,
     86                .cmd = CMD_AND,
    8787                .value = LSR_DATA_READY,
    8888                .srcarg = 1,
  • uspace/srv/hid/input/port/pl050.c

    r56c167c r8486c07  
    8080        },
    8181        {
    82                 .cmd = CMD_BTEST,
     82                .cmd = CMD_AND,
    8383                .value = PL050_STAT_RXFULL,
    8484                .srcarg = 1,
  • uspace/srv/hw/bus/cuda_adb/cuda_adb.c

    r56c167c r8486c07  
    116116        {
    117117                .cmd = CMD_PIO_READ_8,
    118                 .addr = NULL,   /* will be patched in run-time */
     118                .addr = NULL,
    119119                .dstarg = 1
    120120        },
    121121        {
    122                 .cmd = CMD_BTEST,
     122                .cmd = CMD_AND,
    123123                .value = SR_INT,
    124124                .srcarg = 1,
Note: See TracChangeset for help on using the changeset viewer.