[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 01/10] drivers/char: Add support for USB3 DbC debugger
On Thu, Aug 04, 2022 at 02:57:49PM +0200, Jan Beulich wrote: > On 26.07.2022 05:23, Marek Marczykowski-Górecki wrote: > > +/* Defines the size in bytes of TRB rings as 2^DBC_TRB_RING_ORDER * 4096 */ > > +#ifndef DBC_TRB_RING_ORDER > > +#define DBC_TRB_RING_ORDER 4 > > +#endif > > +#define DBC_TRB_RING_CAP (DBC_TRB_PER_PAGE * (1 << DBC_TRB_RING_ORDER)) > > I have to admit that I'm always puzzled when seeing such - why not > > #define DBC_TRB_RING_CAP (DBC_TRB_PER_PAGE << DBC_TRB_RING_ORDER) > > ? I think the former is a bit more clear what's the actual size, but the end result is the same, I can change that. > > +struct dbc { > > + struct dbc_reg __iomem *dbc_reg; > > + struct xhci_dbc_ctx *dbc_ctx; > > + struct xhci_erst_segment *dbc_erst; > > + struct xhci_trb_ring dbc_ering; > > + struct xhci_trb_ring dbc_oring; > > + struct xhci_trb_ring dbc_iring; > > + struct dbc_work_ring dbc_owork; > > + struct xhci_string_descriptor *dbc_str; > > I'm afraid I still don't see why the static page this field is being > initialized with is necessary. Can't you have a static variable (of > some struct type) all pre-filled at build time, which you then apply > virt_to_maddr() to in order to fill the respective dbc_ctx fields? I need to keep this structure somewhere DMA-reachable for the device (as in - included in appropriate IOMMU context). Patch 8/10 is doing it. And also, patch 8/10 is putting it together with other DMA-reachable structures (not a separate page on its own). If I'd make it a separate static variable (not part of that later struct), I'd need to reserve the whole page for it - to guarantee no unrelated data lives on the same (DMA-reachable) page. As for statically initializing it, if would require the whole (multi-page DMA-reachable) thing living in .data, not .bss, so a bigger binary (not a huge concern due to compression, but still). But more importantly, I don't know how to do it in a readable way, and you have complained about readability of initializer of this structure in v2. > That struct will be quite a bit less than a page's worth in size. See above - it cannot share page with unrelated Xen data. > If you build the file with -fshort-wchar, you may even be able to > use easy to read string literals for the initializer. I can try, but I'm not exactly sure how to make readable UTF-16 literals... > > +static void *dbc_sys_map_xhc(uint64_t phys, size_t size) > > +{ > > + size_t i; > > + > > + if ( size != MAX_XHCI_PAGES * DBC_PAGE_SIZE ) > > + return NULL; > > + > > + for ( i = FIX_XHCI_END; i >= FIX_XHCI_BEGIN; i-- ) > > + { > > + set_fixmap_nocache(i, phys); > > + phys += DBC_PAGE_SIZE; > > While there may be an assumption of DBC_PAGE_SIZE == PAGE_SIZE, the > constant used here clearly needs to be PAGE_SIZE, as that's the unit > set_fixmap_nocache() deals with. Ok. > > +static bool __init dbc_init_xhc(struct dbc *dbc) > > +{ > > + uint32_t bar0; > > + uint64_t bar1; > > + uint64_t bar_size; > > + uint64_t devfn; > > + uint16_t cmd; > > + size_t xhc_mmio_size; > > + > > + /* > > + * Search PCI bus 0 for the xHC. All the host controllers supported so > > far > > + * are part of the chipset and are on bus 0. > > + */ > > + for ( devfn = 0; devfn < 256; devfn++ ) > > + { > > + pci_sbdf_t sbdf = PCI_SBDF(0, 0, devfn); > > + uint8_t hdr = pci_conf_read8(sbdf, PCI_HEADER_TYPE); > > + > > + if ( hdr == 0 || hdr == 0x80 ) > > + { > > + if ( (pci_conf_read32(sbdf, PCI_CLASS_REVISION) >> 8) == > > DBC_XHC_CLASSC ) > > + { > > + dbc->sbdf = sbdf; > > + break; > > + } > > + } > > + } > > + > > + if ( !dbc->sbdf.sbdf ) > > + { > > + dbc_error("Compatible xHC not found on bus 0\n"); > > + return false; > > + } > > + > > + /* ...we found it, so parse the BAR and map the registers */ > > + bar0 = pci_conf_read32(dbc->sbdf, PCI_BASE_ADDRESS_0); > > + bar1 = pci_conf_read32(dbc->sbdf, PCI_BASE_ADDRESS_1); > > + > > + /* IO BARs not allowed; BAR must be 64-bit */ > > + if ( (bar0 & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_MEMORY > > || > > + (bar0 & PCI_BASE_ADDRESS_MEM_TYPE_MASK) != > > PCI_BASE_ADDRESS_MEM_TYPE_64 ) > > + return false; > > + > > + cmd = pci_conf_read16(dbc->sbdf, PCI_COMMAND); > > + pci_conf_write16(dbc->sbdf, PCI_COMMAND, cmd & ~PCI_COMMAND_MEMORY); > > + > > + pci_conf_write32(dbc->sbdf, PCI_BASE_ADDRESS_0, 0xFFFFFFFF); > > + pci_conf_write32(dbc->sbdf, PCI_BASE_ADDRESS_1, 0xFFFFFFFF); > > + bar_size = pci_conf_read32(dbc->sbdf, PCI_BASE_ADDRESS_0); > > + bar_size |= (uint64_t)pci_conf_read32(dbc->sbdf, PCI_BASE_ADDRESS_1) > > << 32; > > + xhc_mmio_size = ~(bar_size & PCI_BASE_ADDRESS_MEM_MASK) + 1; > > + pci_conf_write32(dbc->sbdf, PCI_BASE_ADDRESS_0, bar0); > > + pci_conf_write32(dbc->sbdf, PCI_BASE_ADDRESS_1, bar1); > > + > > + pci_conf_write16(dbc->sbdf, PCI_COMMAND, cmd); > > + > > + dbc->xhc_mmio_phys = (bar0 & PCI_BASE_ADDRESS_MEM_MASK) | (bar1 << 32); > > + dbc->xhc_mmio = dbc_sys_map_xhc(dbc->xhc_mmio_phys, xhc_mmio_size); > > Before actually using the address to map the MMIO you will want to make > somewhat sure firmware did initialize it: The EHCI driver checks for > all zeroes or all ones in the writable bits. Ok. > > > +/** > > + * The first register of the debug capability is found by traversing the > > + * host controller's capability list (xcap) until a capability > > + * with ID = 0xA is found. The xHCI capability list begins at address > > + * mmio + (HCCPARAMS1[31:16] << 2). > > + */ > > +static struct dbc_reg __iomem *xhci_find_dbc(struct dbc *dbc) > > +{ > > + uint32_t *xcap; > > const? > > > + uint32_t xcap_val; > > + uint32_t next; > > + uint32_t id = 0; > > + uint8_t *mmio = (uint8_t *)dbc->xhc_mmio; > > Can't this be const void * (and probably wants to also use __iomem), > avoiding the cast here, ... > > > + uint32_t *hccp1 = (uint32_t *)(mmio + 0x10); > > ... here, ... > > > + const uint32_t DBC_ID = 0xA; > > + int ttl = 48; > > + > > + xcap = (uint32_t *)dbc->xhc_mmio; > > ... and here (if actually using the local variable you've got). Ok. > > +/* > > + * Note that if IN transfer support is added, then this > > + * will need to be changed; it assumes an OUT transfer ring only > > + */ > > Hmm, is this comment telling me that this driver is an output-only one? At this point, yes. Input support is added in patch 10/10. > Or is it simply that input doesn't use this code path? > > > +static void dbc_init_string_single(struct xhci_string_descriptor *string, > > + char *ascii_str, > > If this function has to survive, then const please here and ... > > > + uint64_t *str_ptr, > > + uint8_t *str_size_ptr) > > +{ > > + size_t i, len = strlen(ascii_str); > > + > > + string->size = offsetof(typeof(*string), string) + len * 2; > > + string->type = XHCI_DT_STRING; > > + /* ASCII to UTF16 conversion */ > > + for (i = 0; i < len; i++) > > ... this missing blanks added here. Ok. > > +static struct xhci_trb evt_trb[DBC_TRB_RING_CAP]; > > +static struct xhci_trb out_trb[DBC_TRB_RING_CAP]; > > +static struct xhci_trb in_trb[DBC_TRB_RING_CAP]; > > +static struct xhci_erst_segment erst __aligned(64); > > +static struct xhci_dbc_ctx ctx __aligned(64); > > +static uint8_t out_wrk_buf[DBC_WORK_RING_CAP] __aligned(DBC_PAGE_SIZE); > > +static struct xhci_string_descriptor str_buf[DBC_STRINGS_COUNT]; > > +static char __initdata opt_dbgp[30]; > > + > > +string_param("dbgp", opt_dbgp); > > This duplicates what ehci-dbgp.c already has. I guess we can live with > it for now and de-duplicate later, but it's still a little odd. In any > even please move the blank line up be a line, so that string_param() > and its referenced array are kept together. > > > +void __init xhci_dbc_uart_init(void) > > +{ > > + struct dbc_uart *uart = &dbc_uart; > > + struct dbc *dbc = &uart->dbc; > > + > > + if ( strncmp(opt_dbgp, "xhci", 4) ) > > + return; > > + > > + memset(dbc, 0, sizeof(*dbc)); > > Why? dbc_uart is a static variable, and hence already zero-initialized. Ok. -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab Attachment:
signature.asc
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |