Changeset 075c1eb in mainline


Ignore:
Timestamp:
2011-05-06T13:09:39Z (14 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6c6a95d2, 9350e837
Parents:
310c4df (diff), 3d4aa055 (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:

OHCI interrupts

Kernel support for accessing memory mapped registers in irq handler(AS switch)

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/ddi/irq.h

    r310c4df r075c1eb  
    7777         */
    7878        CMD_PIO_WRITE_A_32,
    79        
     79
     80        /** Read 1 byte from the memory space. */
     81        CMD_MEM_READ_8,
     82        /** Read 2 bytes from the memory space. */
     83        CMD_MEM_READ_16,
     84        /** Read 4 bytes from the memory space. */
     85        CMD_MEM_READ_32,
     86
     87        /** Write 1 byte to the memory space. */
     88        CMD_MEM_WRITE_8,
     89        /** Write 2 bytes to the memory space. */
     90        CMD_MEM_WRITE_16,
     91        /** Write 4 bytes to the memory space. */
     92        CMD_MEM_WRITE_32,
     93
     94        /** Write 1 byte from the source argument to the memory space. */
     95        CMD_MEM_WRITE_A_8,
     96        /** Write 2 bytes from the source argument to the memory space. */
     97        CMD_MEM_WRITE_A_16,
     98        /** Write 4 bytes from the source argument to the memory space. */
     99        CMD_MEM_WRITE_A_32,
     100
    80101        /**
    81102         * Perform a bit masking on the source argument
     
    203224        /** Notification configuration structure. */
    204225        ipc_notif_cfg_t notif_cfg;
     226
     227        as_t *driver_as;
    205228} irq_t;
    206229
  • kernel/generic/src/ipc/irq.c

    r310c4df r075c1eb  
    174174        irq->notif_cfg.code = code;
    175175        irq->notif_cfg.counter = 0;
     176        irq->driver_as = AS;
    176177       
    177178        /*
     
    364365                return IRQ_DECLINE;
    365366       
     367#define CMD_MEM_READ(target) \
     368do { \
     369        void *va = code->cmds[i].addr; \
     370        if (AS != irq->driver_as) \
     371                as_switch(AS, irq->driver_as); \
     372        printf("Copying data from address: %p.\n", va); \
     373        memcpy_from_uspace(&target, va, (sizeof(target))); \
     374        if (dstarg) \
     375                scratch[dstarg] = target; \
     376} while(0)
     377
     378#define CMD_MEM_WRITE(val) \
     379do { \
     380        void *va = code->cmds[i].addr; \
     381        if (AS != irq->driver_as) \
     382                as_switch(AS, irq->driver_as); \
     383        printf("Writing data to address: %p.\n", va); \
     384        memcpy_to_uspace(va, &val, sizeof(val)); \
     385} while (0)
     386
     387        as_t *current_as = AS;
    366388        size_t i;
    367389        for (i = 0; i < code->cmdcount; i++) {
     
    422444                        }
    423445                        break;
     446                case CMD_MEM_READ_8: {
     447                        uint8_t val;
     448                        CMD_MEM_READ(val);
     449                        break;
     450                        }
     451                case CMD_MEM_READ_16: {
     452                        uint16_t val;
     453                        CMD_MEM_READ(val);
     454                        break;
     455                        }
     456                case CMD_MEM_READ_32: {
     457                        uint32_t val;
     458                        CMD_MEM_READ(val);
     459                        printf("mem READ value: %x.\n", val);
     460                        break;
     461                        }
     462                case CMD_MEM_WRITE_8: {
     463                        uint8_t val = code->cmds[i].value;
     464                        CMD_MEM_WRITE(val);
     465                        break;
     466                        }
     467                case CMD_MEM_WRITE_16: {
     468                        uint16_t val = code->cmds[i].value;
     469                        CMD_MEM_WRITE(val);
     470                        break;
     471                        }
     472                case CMD_MEM_WRITE_32: {
     473                        uint32_t val = code->cmds[i].value;
     474                        CMD_MEM_WRITE(val);
     475                        break;
     476                        }
     477                case CMD_MEM_WRITE_A_8:
     478                        if (srcarg) {
     479                                uint8_t val = scratch[srcarg];
     480                                CMD_MEM_WRITE(val);
     481                        }
     482                        break;
     483                case CMD_MEM_WRITE_A_16:
     484                        if (srcarg) {
     485                                uint16_t val = scratch[srcarg];
     486                                CMD_MEM_WRITE(val);
     487                        }
     488                        break;
     489                case CMD_MEM_WRITE_A_32:
     490                        if (srcarg) {
     491                                uint32_t val = scratch[srcarg];
     492                                CMD_MEM_WRITE(val);
     493                        }
     494                        break;
    424495                case CMD_BTEST:
    425496                        if ((srcarg) && (dstarg)) {
     
    435506                        break;
    436507                case CMD_ACCEPT:
     508                        if (AS != current_as)
     509                                as_switch(AS, current_as);
    437510                        return IRQ_ACCEPT;
    438511                case CMD_DECLINE:
    439512                default:
     513                        if (AS != current_as)
     514                                as_switch(AS, current_as);
    440515                        return IRQ_DECLINE;
    441516                }
    442517        }
     518        if (AS != current_as)
     519                as_switch(AS, current_as);
    443520       
    444521        return IRQ_DECLINE;
  • uspace/drv/ehci-hcd/pci.c

    r310c4df r075c1eb  
    186186        CHECK_RET_HANGUP_RETURN(ret, "Failed(%d) to read PCI config space.\n",
    187187            ret);
    188         usb_log_info("Register space BAR at %p:%" PRIxn ".\n", (void *) address, value);
     188        usb_log_info("Register space BAR at %p:%" PRIxn ".\n",
     189            (void *) address, value);
    189190
    190191        /* clear lower byte, it's not part of the BASE address */
  • uspace/drv/ohci/hc.c

    r310c4df r075c1eb  
    4545#include "hcd_endpoint.h"
    4646
     47#define OHCI_USED_INTERRUPTS \
     48    (I_SO | I_WDH | I_UE | I_RHSC)
    4749static int interrupt_emulator(hc_t *instance);
    4850static void hc_gain_control(hc_t *instance);
     
    285287{
    286288        assert(instance);
    287         if ((status & ~IS_SF) == 0) /* ignore sof status */
     289        usb_log_debug("OHCI interrupt: %x.\n", status);
     290        if ((status & ~I_SF) == 0) /* ignore sof status */
    288291                return;
    289         if (status & IS_RHSC)
     292        if (status & I_RHSC)
    290293                rh_interrupt(&instance->rh);
    291294
    292         usb_log_debug("OHCI interrupt: %x.\n", status);
    293 
    294         if (status & IS_WDH) {
     295
     296        if (status & I_WDH) {
    295297                fibril_mutex_lock(&instance->guard);
    296298                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
     
    421423            instance->registers->control);
    422424
    423         /* Disable interrupts */
    424         instance->registers->interrupt_disable = I_SF | I_OC;
    425         usb_log_debug2("Disabling interrupts: %x.\n",
    426             instance->registers->interrupt_disable);
    427         instance->registers->interrupt_disable = I_MI;
     425        /* Enable interrupts */
     426        instance->registers->interrupt_enable = OHCI_USED_INTERRUPTS;
    428427        usb_log_debug2("Enabled interrupts: %x.\n",
    429428            instance->registers->interrupt_enable);
     429        instance->registers->interrupt_enable = I_MI;
    430430
    431431        /* Set periodic start to 90% */
     
    492492            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    493493
     494        /* Init interrupt code */
     495        instance->interrupt_code.cmds = instance->interrupt_commands;
     496        {
     497                /* Read status register */
     498                instance->interrupt_commands[0].cmd = CMD_MEM_READ_32;
     499                instance->interrupt_commands[0].dstarg = 1;
     500                instance->interrupt_commands[0].addr =
     501                    (void*)&instance->registers->interrupt_status;
     502
     503                /* Test whether we are the interrupt cause */
     504                instance->interrupt_commands[1].cmd = CMD_BTEST;
     505                instance->interrupt_commands[1].value =
     506                    OHCI_USED_INTERRUPTS;
     507                instance->interrupt_commands[1].srcarg = 1;
     508                instance->interrupt_commands[1].dstarg = 2;
     509
     510                /* Predicate cleaning and accepting */
     511                instance->interrupt_commands[2].cmd = CMD_PREDICATE;
     512                instance->interrupt_commands[2].value = 2;
     513                instance->interrupt_commands[2].srcarg = 2;
     514
     515                /* Write clean status register */
     516                instance->interrupt_commands[3].cmd = CMD_MEM_WRITE_A_32;
     517                instance->interrupt_commands[3].srcarg = 1;
     518                instance->interrupt_commands[3].addr =
     519                    (void*)&instance->registers->interrupt_status;
     520
     521                /* Accept interrupt */
     522                instance->interrupt_commands[4].cmd = CMD_ACCEPT;
     523
     524                instance->interrupt_code.cmdcount = OHCI_NEEDED_IRQ_COMMANDS;
     525        }
     526
    494527        return EOK;
    495528}
  • uspace/drv/ohci/hc.h

    r310c4df r075c1eb  
    5151#include "hw_struct/hcca.h"
    5252
     53#define OHCI_NEEDED_IRQ_COMMANDS 5
     54
    5355typedef struct hc {
    5456        ohci_regs_t *registers;
     
    6567        fid_t interrupt_emulator;
    6668        fibril_mutex_t guard;
     69
     70        /** Code to be executed in kernel interrupt handler */
     71        irq_code_t interrupt_code;
     72
     73        /** Commands that form interrupt code */
     74        irq_cmd_t interrupt_commands[OHCI_NEEDED_IRQ_COMMANDS];
    6775} hc_t;
    6876
  • uspace/drv/ohci/ohci.c

    r310c4df r075c1eb  
    202202
    203203        /* It does no harm if we register this on polling */
    204         ret = register_interrupt_handler(device, irq, irq_handler, NULL);
     204        ret = register_interrupt_handler(device, irq, irq_handler,
     205            &instance->hc.interrupt_code);
    205206        CHECK_RET_FINI_RETURN(ret,
    206207            "Failed(%d) to register interrupt handler.\n", ret);
  • uspace/drv/ohci/ohci_regs.h

    r310c4df r075c1eb  
    7272#define CS_SOC_SHIFT (16)
    7373
     74        /** Interupt enable/disable/status,
     75         * reads give the same value,
     76         * writing causes enable/disable,
     77         * status is write-clean (writing 1 clears the bit*/
    7478        volatile uint32_t interrupt_status;
    75 #define IS_SO   (1 << 0)  /* Scheduling overrun */
    76 #define IS_WDH  (1 << 1)  /* Write-back done head */
    77 #define IS_SF   (1 << 2)  /* Start of frame */
    78 #define IS_RD   (1 << 3)  /* Resume detected */
    79 #define IS_UE   (1 << 4)  /* Unrecoverable error */
    80 #define IS_FNO  (1 << 5)  /* Frame number overflow */
    81 #define IS_RHSC (1 << 6)  /* Root hub status change */
    82 #define IS_OC   (1 << 30) /* Ownership change */
    83 
    84         /** Interupt enable/disable, reads give the same value, writing causes
    85          * enable/disable */
    8679        volatile uint32_t interrupt_enable;
    8780        volatile uint32_t interrupt_disable;
  • uspace/drv/ohci/pci.c

    r310c4df r075c1eb  
    146146int pci_enable_interrupts(ddf_dev_t *device)
    147147{
    148         return ENOTSUP;
    149148        int parent_phone =
    150149            devman_parent_device_connect(device->handle, IPC_FLAG_BLOCKING);
  • uspace/lib/usb/src/host/batch.c

    r310c4df r075c1eb  
    128128        memcpy(instance->buffer, instance->data_buffer, instance->buffer_size);
    129129
    130         usb_log_debug("Batch %p done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
     130        usb_log_debug("Batch(%p) done (T%d.%d, %s %s in, %zuB): %s (%d).\n",
    131131            instance, instance->ep->address, instance->ep->endpoint,
    132132            usb_str_speed(instance->ep->speed),
    133133            usb_str_transfer_type_short(instance->ep->transfer_type),
    134             instance->transfered_size, str_error(instance->error), instance->error);
     134            instance->transfered_size, str_error(instance->error),
     135            instance->error);
    135136
    136137        instance->callback_in(instance->fun, instance->error,
     
    147148        assert(instance->callback_out);
    148149
    149         usb_log_debug("Batch %p done (T%d.%d, %s %s out): %s (%d).\n",
     150        usb_log_debug("Batch(%p) done (T%d.%d, %s %s out): %s (%d).\n",
    150151            instance, instance->ep->address, instance->ep->endpoint,
    151152            usb_str_speed(instance->ep->speed),
Note: See TracChangeset for help on using the changeset viewer.