aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-10-16 14:37:53 +0530
committerNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-11-15 10:36:51 +0530
commitce91e6a2827c0921be774c7ba9bfd3056778b57d (patch)
tree8008447a1cc285fbf3fb501582d786ff89b42a25
parent8e5245abc8bdfbfc9438cc2e56f80ef8e394259f (diff)
downloadSLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.zip
SLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.tar.gz
SLOF-ce91e6a2827c0921be774c7ba9bfd3056778b57d.tar.bz2
usb-xhci: add xhci support
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
-rw-r--r--lib/libusb/Makefile3
-rw-r--r--lib/libusb/usb-core.c2
-rw-r--r--lib/libusb/usb-xhci.c105
-rw-r--r--lib/libusb/usb-xhci.h108
-rw-r--r--lib/libusb/usb.code9
-rw-r--r--lib/libusb/usb.h4
-rw-r--r--lib/libusb/usb.in1
-rw-r--r--slof/fs/devices/pci-class_0c.fs8
-rw-r--r--slof/fs/pci-class-code-names.fs3
-rw-r--r--slof/fs/usb/usb-static.fs14
10 files changed, 250 insertions, 7 deletions
diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile
index 9e009a4..ee065be 100644
--- a/lib/libusb/Makefile
+++ b/lib/libusb/Makefile
@@ -22,7 +22,8 @@ TARGET = ../libusb.a
all: $(TARGET)
-SRCS = usb-core.c usb-ohci.c usb-ehci.c usb-slof.c usb-key.c usb-hid.c usb-hub.c
+SRCS = usb-core.c usb-ohci.c usb-ehci.c usb-slof.c usb-key.c usb-hid.c \
+ usb-hub.c usb-xhci.c
OBJS = $(SRCS:%.c=%.o)
diff --git a/lib/libusb/usb-core.c b/lib/libusb/usb-core.c
index b169e74..6c40913 100644
--- a/lib/libusb/usb-core.c
+++ b/lib/libusb/usb-core.c
@@ -182,7 +182,7 @@ void usb_hcd_exit(void *_hcidev)
struct usb_hcd_dev *hcidev = _hcidev;
dprintf("%s: enter \n", __func__);
- if (!hcidev || !hcidev->ops) {
+ if (!hcidev) {
printf("Device Error");
return;
}
diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c
new file mode 100644
index 0000000..c6022f9
--- /dev/null
+++ b/lib/libusb/usb-xhci.c
@@ -0,0 +1,105 @@
+/*****************************************************************************
+ * Copyright (c) 2013 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+
+#include <string.h>
+#include "usb.h"
+#include "usb-core.h"
+#include "usb-xhci.h"
+#include "tools.h"
+#include "paflof.h"
+
+#undef XHCI_DEBUG
+//#define XHCI_DEBUG
+#ifdef XHCI_DEBUG
+#define dprintf(_x ...) do { printf("%s: ", __func__); printf(_x); } while (0)
+#else
+#define dprintf(_x ...) do { } while (0)
+#endif
+
+static void dump_xhci_regs(struct xhci_hcd *xhcd)
+{
+#ifdef XHCI_DEBUG
+ struct xhci_cap_regs *cap;
+ struct xhci_op_regs *op;
+ struct xhci_run_regs *run;
+
+ cap = xhcd->cap_regs;
+ op = xhcd->op_regs;
+ run = xhcd->run_regs;
+
+ dprintf("\n");
+ dprintf(" - CAPLENGTH %02X\n", read_reg8 (&cap->caplength));
+ dprintf(" - HCIVERSION %04X\n", read_reg16(&cap->hciversion));
+ dprintf(" - HCSPARAMS1 %08X\n", read_reg32(&cap->hcsparams1));
+ dprintf(" - HCSPARAMS2 %08X\n", read_reg32(&cap->hcsparams2));
+ dprintf(" - HCSPARAMS3 %08X\n", read_reg32(&cap->hcsparams3));
+ dprintf(" - HCCPARAMS %08X\n", read_reg32(&cap->hccparams));
+ dprintf(" - DBOFF %08X\n", read_reg32(&cap->dboff));
+ dprintf(" - RTSOFF %08X\n", read_reg32(&cap->rtsoff));
+ dprintf("\n");
+
+ dprintf(" - USBCMD %08X\n", read_reg32(&op->usbcmd));
+ dprintf(" - USBSTS %08X\n", read_reg32(&op->usbsts));
+ dprintf(" - PAGESIZE %08X\n", read_reg32(&op->pagesize));
+ dprintf(" - DNCTRL %08X\n", read_reg32(&op->dnctrl));
+ dprintf(" - CRCR %016llX\n", read_reg64(&op->crcr));
+ dprintf(" - DCBAAP %016llX\n", read_reg64(&op->dcbaap));
+ dprintf(" - CONFIG %08X\n", read_reg32(&op->config));
+ dprintf("\n");
+
+ dprintf(" - MFINDEX %08X\n", read_reg32(&run->mfindex));
+ dprintf("\n");
+#endif
+}
+
+static void xhci_init(struct usb_hcd_dev *hcidev)
+{
+ struct xhci_hcd *xhcd;
+
+ printf(" XHCI: Initializing\n");
+ dprintf("%s: device base address %p\n", __func__, hcidev->base);
+
+ hcidev->base = (void *)((uint64_t)hcidev->base & ~7);
+ xhcd = SLOF_alloc_mem(sizeof(*xhcd));
+ if (!xhcd) {
+ printf("usb-xhci: Unable to allocate memory\n");
+ return;
+ }
+ memset(xhcd, 0, sizeof(*xhcd));
+
+ hcidev->nextaddr = 1;
+ hcidev->priv = xhcd;
+ xhcd->hcidev = hcidev;
+ xhcd->cap_regs = (struct xhci_cap_regs *)(hcidev->base);
+ xhcd->op_regs = (struct xhci_op_regs *)(hcidev->base +
+ read_reg8(&xhcd->cap_regs->caplength));
+ xhcd->run_regs = (struct xhci_run_regs *)(hcidev->base +
+ read_reg32(&xhcd->cap_regs->rtsoff));
+ xhcd->db_regs = (struct xhci_db_regs *)(hcidev->base +
+ read_reg32(&xhcd->cap_regs->dboff));
+
+#ifdef XHCI_DEBUG
+ dump_xhci_regs(xhcd);
+#endif
+}
+
+struct usb_hcd_ops xhci_ops = {
+ .name = "xhci-hcd",
+ .init = xhci_init,
+ .usb_type = USB_XHCI,
+ .next = NULL,
+};
+
+void usb_xhci_register(void)
+{
+ usb_hcd_register(&xhci_ops);
+}
diff --git a/lib/libusb/usb-xhci.h b/lib/libusb/usb-xhci.h
new file mode 100644
index 0000000..02e83f7
--- /dev/null
+++ b/lib/libusb/usb-xhci.h
@@ -0,0 +1,108 @@
+/******************************************************************************
+ * Copyright (c) 2013 IBM Corporation
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ * IBM Corporation - initial implementation
+ *****************************************************************************/
+/*
+ * Definitions for XHCI Controller - Revision 1.0 (5/21/10)
+ *
+ */
+
+#ifndef USB_XHCI_H
+#define USB_XHCI_H
+
+#include <stdint.h>
+#include "usb-core.h"
+
+/* 5.3 Host Controller Capability Registers
+ * Table 19
+ */
+struct xhci_cap_regs {
+ uint8_t caplength;
+ uint8_t reserved;
+ uint16_t hciversion;
+ uint32_t hcsparams1;
+ uint32_t hcsparams2;
+ uint32_t hcsparams3;
+ uint32_t hccparams;
+ uint32_t dboff;
+ uint32_t rtsoff;
+} __attribute__ ((packed));
+
+/* Table 27: Host Controller USB Port Register Set */
+struct xhci_port_regs {
+ uint32_t portsc;
+ uint32_t portpmsc;
+ uint32_t portli;
+ uint32_t reserved;
+} __attribute__ ((packed));
+
+/* 5.4 Host Controller Operational Registers
+ * Table 26
+ */
+struct xhci_op_regs {
+ uint32_t usbcmd;
+ uint32_t usbsts;
+ uint32_t pagesize;
+ uint8_t reserved[8]; /* 0C - 13 */
+ uint32_t dnctrl; /* Device notification control */
+ uint64_t crcr; /* Command ring control */
+ uint8_t reserved1[16]; /* 20 - 2F */
+ uint64_t dcbaap; /* Device Context Base Address Array Pointer */
+ uint8_t config; /* Configure */
+ uint8_t reserved2[964]; /* 3C - 3FF */
+ /* USB Port register set */
+#define XHCI_PORT_MAX 256
+ struct xhci_port_regs prs[XHCI_PORT_MAX];
+} __attribute__ ((packed));
+
+/*
+ * 5.5.2 Interrupter Register Set
+ * Table 42: Interrupter Registers
+ */
+struct xhci_int_regs {
+ uint32_t iman;
+ uint32_t imod;
+ uint32_t erstsz;
+ uint32_t reserved;
+ uint64_t erstba;
+ uint64_t erdp;
+} __attribute__ ((packed));
+
+/* 5.5 Host Controller Runtime Registers */
+struct xhci_run_regs {
+ uint32_t mfindex; /* microframe index */
+ uint8_t reserved[28];
+#define XHCI_IRS_MAX
+ struct xhci_int_regs irs[XHCI_IRS_MAX];
+} __attribute__ ((packed));
+
+/* 5.6 Doorbell Registers*/
+struct xhci_db_regs {
+ uint32_t db[256];
+} __attribute__ ((packed));
+
+struct xhci_hcd {
+ struct xhci_cap_regs *cap_regs;
+ struct xhci_op_regs *op_regs;
+ struct xhci_run_regs *run_regs;
+ struct xhci_db_regs *db_regs;
+ struct usb_hcd_dev *hcidev;
+ struct usb_pipe *freelist;
+ struct usb_pipe *end;
+ void *pool;
+ long pool_phys;
+};
+
+struct xhci_pipe {
+ struct usb_pipe pipe;
+ long qh_phys;
+};
+
+#endif /* USB_XHCI_H */
diff --git a/lib/libusb/usb.code b/lib/libusb/usb.code
index 81e548d..fd92d9e 100644
--- a/lib/libusb/usb.code
+++ b/lib/libusb/usb.code
@@ -35,6 +35,15 @@ PRIM(USB_X2d_EHCI_X2d_REGISTER)
MIRP
/************************************************/
+/* Register with the usb-core */
+/* SLOF: USB-XHCI-REGISTER ( -- ) */
+/* LIBNEWUSB: usb_xhci_register(void) */
+/************************************************/
+PRIM(USB_X2d_XHCI_X2d_REGISTER)
+ usb_xhci_register();
+MIRP
+
+/************************************************/
/* Initialize hcidev with the usb-core */
/* SLOF: USB-HCD-INIT ( hcidev -- ) */
/* LIBNEWUSB: usb_hcd_init(hcidev) */
diff --git a/lib/libusb/usb.h b/lib/libusb/usb.h
index 2be0a7d..fba19d2 100644
--- a/lib/libusb/usb.h
+++ b/lib/libusb/usb.h
@@ -25,6 +25,10 @@ extern void usb_ohci_register(void);
/*******************************************/
extern void usb_ehci_register(void);
/*******************************************/
+/* SLOF: USB-XHCI-REGISTER */
+/*******************************************/
+extern void usb_xhci_register(void);
+/*******************************************/
/* SLOF: USB-HCD-INIT */
/*******************************************/
extern void usb_hcd_init(void *hcidev);
diff --git a/lib/libusb/usb.in b/lib/libusb/usb.in
index dc7b7a9..7ceba7d 100644
--- a/lib/libusb/usb.in
+++ b/lib/libusb/usb.in
@@ -15,6 +15,7 @@
cod(USB-OHCI-REGISTER)
cod(USB-EHCI-REGISTER)
+cod(USB-XHCI-REGISTER)
cod(USB-HCD-INIT)
cod(USB-HCD-EXIT)
cod(USB-HID-INIT)
diff --git a/slof/fs/devices/pci-class_0c.fs b/slof/fs/devices/pci-class_0c.fs
index 9ee2bde..9c47325 100644
--- a/slof/fs/devices/pci-class_0c.fs
+++ b/slof/fs/devices/pci-class_0c.fs
@@ -55,10 +55,10 @@ CONSTANT /hci-dev
handle-usb-class
set-ehci-alias
ENDOF
-\ 0330 OF \ XHCI controller
-\ handle-usb-class
-\ set-xhci-alias
-\ ENDOF
+ 0330 OF \ XHCI controller
+ handle-usb-class
+ set-xhci-alias
+ ENDOF
ENDCASE
;
diff --git a/slof/fs/pci-class-code-names.fs b/slof/fs/pci-class-code-names.fs
index 4156fba..f3a4945 100644
--- a/slof/fs/pci-class-code-names.fs
+++ b/slof/fs/pci-class-code-names.fs
@@ -174,7 +174,8 @@
0200 OF s" ssa" ENDOF
0300 OF s" usb-uhci" ENDOF
0310 OF s" usb-ohci" ENDOF
- 0320 OF s" usb-ehci" ENDOF
+ 0320 OF s" usb-ehci" ENDOF
+ 0330 OF s" usb-xhci" ENDOF
0380 OF s" usb" ENDOF
03FE OF s" usb-device" ENDOF
0400 OF s" fibre-channel" ENDOF
diff --git a/slof/fs/usb/usb-static.fs b/slof/fs/usb/usb-static.fs
index 73a7176..726ef6d 100644
--- a/slof/fs/usb/usb-static.fs
+++ b/slof/fs/usb/usb-static.fs
@@ -71,5 +71,19 @@
THEN
LOOP
+ xhci-alias-num 1 >= IF
+ USB-XHCI-REGISTER
+ THEN
+
+ xhci-alias-num 0 ?DO
+ " xhci" i $cathex find-device
+ " get-hci-dev" get-node find-method
+ IF
+ execute usb-enumerate
+ ELSE
+ ." get-base-address method not found for xhci" i . cr
+ THEN
+ LOOP
+
0 set-node \ FIXME Setting it back
;