Changeset 62ba2cbe in mainline


Ignore:
Timestamp:
2017-06-16T01:25:16Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cb89430
Parents:
ce6e001
Message:

xhci: dumping operational state

Location:
uspace/drv/bus/usb/xhci
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/debug.c

    rce6e001 r62ba2cbe  
    3838
    3939#include "debug.h"
     40#include "hc.h"
     41
     42#define PX "\t%-21s = "
    4043
    4144#define DUMP_REG_FIELD(ptr, title, size, ...) \
    42         usb_log_debug2(title "%" PRIu##size, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__))
     45        usb_log_debug2(PX "%" PRIu##size, title, XHCI_REG_RD_FIELD(ptr, size, ##__VA_ARGS__))
    4346
    4447#define DUMP_REG_RANGE(ptr, title, size, ...) \
    45         usb_log_debug2(title "%" PRIu##size, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__))
     48        usb_log_debug2(PX "%" PRIu##size, title, XHCI_REG_RD_RANGE(ptr, size, ##__VA_ARGS__))
    4649
    4750#define DUMP_REG_FLAG(ptr, title, size, ...) \
    48         usb_log_debug2(title "%s", XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false")
     51        usb_log_debug2(PX "%s", title, XHCI_REG_RD_FLAG(ptr, size, ##__VA_ARGS__) ? "true" : "false")
    4952
    5053#define DUMP_REG_INNER(set, title, field, size, type, ...) \
    5154        DUMP_REG_##type(&(set)->field, title, size, ##__VA_ARGS__)
    5255
    53 #define DUMP_REG(set, c) DUMP_REG_INNER(set, "\t" #c ": ", c)
     56#define DUMP_REG(set, c) DUMP_REG_INNER(set, #c, c)
    5457
    5558/**
     
    9295}
    9396
     97void xhci_dump_port(xhci_port_regs_t *port)
     98{
     99        DUMP_REG(port, XHCI_PORT_CCS);
     100        DUMP_REG(port, XHCI_PORT_PED);
     101        DUMP_REG(port, XHCI_PORT_OCA);
     102        DUMP_REG(port, XHCI_PORT_PR);
     103        DUMP_REG(port, XHCI_PORT_PLS);
     104        DUMP_REG(port, XHCI_PORT_PP);
     105        DUMP_REG(port, XHCI_PORT_PIC);
     106        DUMP_REG(port, XHCI_PORT_LWS);
     107        DUMP_REG(port, XHCI_PORT_CSC);
     108        DUMP_REG(port, XHCI_PORT_PEC);
     109        DUMP_REG(port, XHCI_PORT_WRC);
     110        DUMP_REG(port, XHCI_PORT_OCC);
     111        DUMP_REG(port, XHCI_PORT_PRC);
     112        DUMP_REG(port, XHCI_PORT_PLC);
     113        DUMP_REG(port, XHCI_PORT_CEC);
     114        DUMP_REG(port, XHCI_PORT_CAS);
     115        DUMP_REG(port, XHCI_PORT_WCE);
     116        DUMP_REG(port, XHCI_PORT_WDE);
     117        DUMP_REG(port, XHCI_PORT_WOE);
     118        DUMP_REG(port, XHCI_PORT_DR);
     119        DUMP_REG(port, XHCI_PORT_WPR);
     120}
     121
     122void xhci_dump_state(xhci_hc_t *hc)
     123{
     124        usb_log_debug2("Operational registers:");
     125
     126        DUMP_REG(hc->op_regs, XHCI_OP_RS);
     127        DUMP_REG(hc->op_regs, XHCI_OP_RS);
     128        DUMP_REG(hc->op_regs, XHCI_OP_HCRST);
     129        DUMP_REG(hc->op_regs, XHCI_OP_INTE);
     130        DUMP_REG(hc->op_regs, XHCI_OP_HSEE);
     131        DUMP_REG(hc->op_regs, XHCI_OP_LHCRST);
     132        DUMP_REG(hc->op_regs, XHCI_OP_CSS);
     133        DUMP_REG(hc->op_regs, XHCI_OP_CRS);
     134        DUMP_REG(hc->op_regs, XHCI_OP_EWE);
     135        DUMP_REG(hc->op_regs, XHCI_OP_EU3S);
     136        DUMP_REG(hc->op_regs, XHCI_OP_CME);
     137        DUMP_REG(hc->op_regs, XHCI_OP_HCH);
     138        DUMP_REG(hc->op_regs, XHCI_OP_HSE);
     139        DUMP_REG(hc->op_regs, XHCI_OP_EINT);
     140        DUMP_REG(hc->op_regs, XHCI_OP_PCD);
     141        DUMP_REG(hc->op_regs, XHCI_OP_SSS);
     142        DUMP_REG(hc->op_regs, XHCI_OP_RSS);
     143        DUMP_REG(hc->op_regs, XHCI_OP_SRE);
     144        DUMP_REG(hc->op_regs, XHCI_OP_CNR);
     145        DUMP_REG(hc->op_regs, XHCI_OP_HCE);
     146        DUMP_REG(hc->op_regs, XHCI_OP_PAGESIZE);
     147        DUMP_REG(hc->op_regs, XHCI_OP_NOTIFICATION);
     148        DUMP_REG(hc->op_regs, XHCI_OP_RCS);
     149        DUMP_REG(hc->op_regs, XHCI_OP_CS);
     150        DUMP_REG(hc->op_regs, XHCI_OP_CA);
     151        DUMP_REG(hc->op_regs, XHCI_OP_CRR);
     152        DUMP_REG(hc->op_regs, XHCI_OP_CRCR_LO);
     153        DUMP_REG(hc->op_regs, XHCI_OP_CRCR_HI);
     154
     155        const size_t num_ports = XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PORTS);
     156        for (size_t i = 0; i < num_ports; i++) {
     157                usb_log_debug2("Port %zu state:", i);
     158
     159                xhci_dump_port(&hc->op_regs->portrs[i]);
     160        }
     161}
    94162/**
    95163 * @}
  • uspace/drv/bus/usb/xhci/debug.h

    rce6e001 r62ba2cbe  
    4040#include "hw_struct/regs.h"
    4141
     42typedef struct xhci_hc xhci_hc_t;
     43
    4244void xhci_dump_cap_regs(xhci_cap_regs_t *);
     45void xhci_dump_port(xhci_port_regs_t *);
     46void xhci_dump_state(xhci_hc_t *);
    4347
    4448#endif
  • uspace/drv/bus/usb/xhci/hc.c

    rce6e001 r62ba2cbe  
    3636#include <errno.h>
    3737#include <usb/debug.h>
     38#include <usb/host/ddf_helpers.h>
    3839#include "debug.h"
    3940#include "hc.h"
    4041
    41 int xhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
     42const ddf_hc_driver_t xhci_ddf_hc_driver = {
     43        .hc_speed = USB_SPEED_SUPER,
     44        .init = xhci_hc_init,
     45        .fini = xhci_hc_fini,
     46        .name = "XHCI-PCI",
     47        .ops = {
     48                .schedule       = xhci_hc_schedule,
     49                .irq_hook       = xhci_hc_interrupt,
     50                .status_hook    = xhci_hc_status,
     51        }
     52};
     53
     54int xhci_hc_init(hcd_t *hcd, const hw_res_list_parsed_t *hw_res, bool irq)
    4255{
    43         assert(code);
    44         assert(hw_res);
     56        int err;
    4557
    46         usb_log_debug("Gen IRQ code, got %zu IRQs, %zu DMA chs, %zu mem rngs, %zu IO rngs",
    47             hw_res->irqs.count,
    48             hw_res->dma_channels.count,
    49             hw_res->mem_ranges.count,
    50             hw_res->io_ranges.count);
    51        
    52         if (hw_res->irqs.count != 1
    53                 || hw_res->dma_channels.count != 0
    54                 || hw_res->mem_ranges.count != 1
    55                 || hw_res->io_ranges.count != 0) {
    56                 usb_log_debug("Unexpected HW resources, bailing out.");
     58        assert(hcd);
     59        assert(hcd_get_driver_data(hcd) == NULL);
     60
     61        if (hw_res->mem_ranges.count != 1) {
     62                usb_log_debug("Unexpected MMIO area, bailing out.");
    5763                return EINVAL;
    5864        }
    5965
     66        xhci_hc_t *hc = malloc(sizeof(xhci_hc_t));
     67        if (!hc)
     68                return ENOMEM;
     69
    6070        addr_range_t mmio_range = hw_res->mem_ranges.ranges[0];
    6171
    62         usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
     72        usb_log_debug("MMIO area at %p (size %zu), IRQ %d.\n",
    6373            RNGABSPTR(mmio_range), RNGSZ(mmio_range), hw_res->irqs.irqs[0]);
    6474
    65         xhci_cap_regs_t *cap_regs = NULL;
    66         int ret = pio_enable_range(&mmio_range, (void **)&cap_regs);
    67         if (ret != EOK)
    68                 return ret;
     75        if ((err = pio_enable_range(&mmio_range, (void **)&hc->cap_regs)))
     76                goto err_hc;
    6977
    70         xhci_dump_cap_regs(cap_regs);
     78        xhci_dump_cap_regs(hc->cap_regs);
    7179
    72         /*
    73          * XHCI uses an Interrupter mechanism. Possibly, we want to set it up here.
    74          */
    75         code->rangecount = 0;
    76         code->ranges = NULL;
    77         code->cmdcount = 0;
    78         code->cmds = NULL;
     80        uintptr_t base = (uintptr_t) hc->cap_regs;
     81
     82        hc->op_regs = (xhci_op_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_LENGTH));
     83        hc->rt_regs = (xhci_rt_regs_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_RTSOFF));
     84        hc->db_arry = (xhci_doorbell_t *) (base + XHCI_REG_RD(hc->cap_regs, XHCI_CAP_DBOFF));
     85
     86        usb_log_debug("Initialized MMIO reg areas:");
     87        usb_log_debug("\tCapability regs: %p", hc->cap_regs);
     88        usb_log_debug("\tOperational regs: %p", hc->op_regs);
     89        usb_log_debug("\tRuntime regs: %p", hc->rt_regs);
     90        usb_log_debug("\tDoorbell array base: %p", hc->db_arry);
     91
     92        xhci_dump_state(hc);
     93
     94        hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops);
     95
     96        // TODO: check if everything fits into the mmio_area
    7997
    8098        return EOK;
     99
     100err_hc:
     101        free(hc);
     102        return err;
    81103}
    82104
     
    98120}
    99121
     122void xhci_hc_fini(hcd_t *hcd)
     123{
     124        assert(hcd);
     125        usb_log_info("Finishing");
     126
     127        xhci_hc_t *hc = hcd_get_driver_data(hcd);
     128        free(hc);
     129        hcd_set_implementation(hcd, NULL, NULL);
     130}
     131
    100132
    101133/**
  • uspace/drv/bus/usb/xhci/hc.h

    rce6e001 r62ba2cbe  
    4040        xhci_cap_regs_t *cap_regs;
    4141        xhci_op_regs_t *op_regs;
     42        xhci_rt_regs_t *rt_regs;
     43        xhci_doorbell_t *db_arry;
    4244} xhci_hc_t;
    4345
     46extern const ddf_hc_driver_t xhci_ddf_hc_driver;
     47
     48int xhci_hc_init(hcd_t *, const hw_res_list_parsed_t *, bool irq);
    4449int xhci_hc_gen_irq_code(irq_code_t *, const hw_res_list_parsed_t *);
    4550int xhci_hc_status(hcd_t *, uint32_t *);
    4651int xhci_hc_schedule(hcd_t *, usb_transfer_batch_t *);
    4752void xhci_hc_interrupt(hcd_t *, uint32_t);
     53void xhci_hc_fini(hcd_t *);
    4854
    4955
  • uspace/drv/bus/usb/xhci/hw_struct/regs.h

    rce6e001 r62ba2cbe  
    3232/** @file
    3333 * Memory-mapped register structures of the xHC.
     34 *
     35 * The main pr
    3436 */
    3537
     
    4244
    4345/*
    44  * The macros XHCI_REG_* might seem a bit magic. It is the most compact way to
    45  * provide flexible interface abstracting from the real storage of given
    46  * register, but to avoid having to specify several constants per register.
    4746 */
    4847
     
    134133
    135134        /*
    136          *  0:3  - IST
     135         *  3:0  - IST
    137136         *  7:4  - ERST Max
    138          * 21:25 - Max Scratchpad Bufs Hi
     137         * 24:21 - Max Scratchpad Bufs Hi
    139138         *    26 - SPR
    140139         * 31:27 - Max Scratchpad Bufs Lo
     
    188187#define XHCI_CAP_IST          hcsparams2, 32, RANGE,  3,  0
    189188#define XHCI_CAP_ERST_MAX     hcsparams2, 32, RANGE,  7,  4
    190 #define XHCI_CAP_SPR          hcsparams2, 32, RANGE, 26, 26
     189#define XHCI_CAP_MAX_SPBUF_LO hcsparams2, 32, RANGE, 25,  4
     190#define XHCI_CAP_SPR          hcsparams2, 32,  FLAG, 26
     191#define XHCI_CAP_MAX_SPBUF_HI hcsparams2, 32, RANGE, 31, 27
    191192#define XHCI_CAP_U1EL         hcsparams3, 32, RANGE,  7,  0
    192193#define XHCI_CAP_U2EL         hcsparams3, 32, RANGE, 31, 16
     
    203204#define XHCI_CAP_SEC          hccparams1, 32,  FLAG, 10
    204205#define XHCI_CAP_CFC          hccparams1, 32,  FLAG, 11
    205 #define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32,  FLAG, 12
    206 #define XHCI_CAP_XECP         hccparams1, 32,  FLAG, 13
     206#define XHCI_CAP_MAX_PSA_SIZE hccparams1, 32, RANGE, 15, 12
     207#define XHCI_CAP_XECP         hccparams1, 32, RANGE, 31, 16
    207208#define XHCI_CAP_DBOFF             dboff, 32, FIELD
    208209#define XHCI_CAP_RTSOFF           rtsoff, 32, FIELD
     
    450451#define XHCI_RT_MFINDEX        mfindex, 32, FIELD
    451452
     453/**
     454 * XHCI Doorbel Registers: section 5.6
     455 *
     456 * These registers are write-only, thus convenience macros are useless.
     457 */
     458typedef ioport32_t xhci_doorbell_t;
     459
    452460#endif
    453461/**
  • uspace/drv/bus/usb/xhci/main.c

    rce6e001 r62ba2cbe  
    4545#define NAME "xhci"
    4646
    47 static int xhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
    48 static void xhci_driver_fini(hcd_t *);
    49 
    50 static const ddf_hc_driver_t xhci_ddf_hc_driver = {
    51         .hc_speed = USB_SPEED_SUPER,
    52         .irq_code_gen = xhci_hc_gen_irq_code,
    53         .init = xhci_driver_init,
    54         .fini = xhci_driver_fini,
    55         .name = "XHCI-PCI",
    56         .ops = {
    57                 .schedule       = xhci_hc_schedule,
    58                 .irq_hook       = xhci_hc_interrupt,
    59                 .status_hook    = xhci_hc_status,
    60         }
    61 };
    62 
    63 static int xhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
    64 {
    65         usb_log_info("Initializing");
    66         return ENOTSUP;
    67 }
    68 
    69 static void xhci_driver_fini(hcd_t *hcd)
    70 {
    71         usb_log_info("Finishing");
    72         assert(hcd);
    73 }
    74 
    7547/** Initializes a new ddf driver instance of XHCI hcd.
    7648 *
Note: See TracChangeset for help on using the changeset viewer.