Skip to content

Commit

Permalink
ehci ohci ok
Browse files Browse the repository at this point in the history
  • Loading branch information
sakumisu committed Dec 12, 2024
1 parent 886f1ec commit 940e086
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 5 deletions.
19 changes: 19 additions & 0 deletions common/usb_dcache.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USB_DCACHE_H
#define USB_DCACHE_H

#ifdef CONFIG_USB_DCACHE_ENABLE
#if CONFIG_USB_ALIGN_SIZE % 32
#error "CONFIG_USB_ALIGN_SIZE must be multiple of 32"
#endif
#else
#define usb_dcache_clean(addr, size)
#define usb_dcache_invalidate(addr, size)
#define usb_dcache_flush(addr, size)
#endif

#endif /* USB_DCACHE_H */
1 change: 1 addition & 0 deletions common/usb_errno.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@
#define USB_ERR_IO 12
#define USB_ERR_SHUTDOWN 13
#define USB_ERR_TIMEOUT 14
#define USB_ERR_ALIGN 15

#endif /* USB_ERRNO_H */
1 change: 1 addition & 0 deletions core/usbh_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "usb_osal.h"
#include "usbh_hub.h"
#include "usb_memcpy.h"
#include "usb_dcache.h"
#include "usb_version.h"

#ifdef __cplusplus
Expand Down
43 changes: 43 additions & 0 deletions port/ehci/usb_hc_ehci.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,36 @@ static void ehci_qh_free(struct usbh_bus *bus, struct ehci_qh_hw *qh)
}
}

#ifdef CONFIG_USB_DCACHE_ENABLE
static inline void usb_ehci_qh_qtd_flush(struct ehci_qh_hw *qh)
{
struct ehci_qtd_hw *qtd;

qtd = EHCI_ADDR2QTD(qh->first_qtd);

while (qtd) {
usb_dcache_clean((uintptr_t)&qtd->hw, CONFIG_USB_EHCI_ALIGN_SIZE);

if (!qtd->dir_in) {
usb_dcache_clean(qtd->bufaddr, USB_ALIGN_UP(qtd->length, CONFIG_USB_ALIGN_SIZE));
}
qtd = EHCI_ADDR2QTD(qtd->hw.next_qtd);
}

usb_dcache_clean((uintptr_t)&qh->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
}
#else
#define usb_ehci_qh_qtd_flush(qh)
#endif

static inline void ehci_qh_add_head(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
{
n->hw.hlp = head->hw.hlp;
usb_ehci_qh_qtd_flush(n);

head->hw.hlp = QH_HLP_QH(n);

usb_dcache_clean((uintptr_t)&head->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
}

static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)
Expand All @@ -92,6 +118,7 @@ static inline void ehci_qh_remove(struct ehci_qh_hw *head, struct ehci_qh_hw *n)

if (tmp) {
tmp->hw.hlp = n->hw.hlp;
usb_dcache_clean((uintptr_t)&tmp->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
}
}

Expand Down Expand Up @@ -255,6 +282,8 @@ static void ehci_qtd_fill(struct ehci_qtd_hw *qtd, uint32_t bufaddr, size_t bufl
qtd->hw.token = token;

ehci_qtd_bpl_fill(qtd, bufaddr, buflen);
qtd->dir_in = ((token & QTD_TOKEN_PID_MASK) == QTD_TOKEN_PID_IN) ? true : false;
qtd->bufaddr = bufaddr;
qtd->length = buflen;
}

Expand Down Expand Up @@ -591,6 +620,9 @@ static void ehci_qh_scan_qtds(struct usbh_bus *bus, struct ehci_qh_hw *qhead, st
qtd = EHCI_ADDR2QTD(qh->first_qtd);

while (qtd) {
if (qtd->dir_in) {
usb_dcache_invalidate(qtd->bufaddr, USB_ALIGN_UP(qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT), CONFIG_USB_ALIGN_SIZE));
}
qtd->urb->actual_length += (qtd->length - ((qtd->hw.token & QTD_TOKEN_NBYTES_MASK) >> QTD_TOKEN_NBYTES_SHIFT));

qh->first_qtd = qtd->hw.next_qtd;
Expand All @@ -611,6 +643,7 @@ static void ehci_check_qh(struct usbh_bus *bus, struct ehci_qh_hw *qhead, struct
}

while (qtd) {
usb_dcache_invalidate((uintptr_t)&qtd->hw, CONFIG_USB_EHCI_ALIGN_SIZE);
token = qtd->hw.token;

if (token & QTD_TOKEN_STATUS_ERRORS) {
Expand Down Expand Up @@ -766,6 +799,10 @@ int usb_hc_init(struct usbh_bus *bus)
g_framelist[bus->hcd.hcd_id][i] = QH_HLP_QH(&g_periodic_qh_head[bus->hcd.hcd_id]);
}

usb_dcache_clean((uintptr_t)&g_async_qh_head[bus->hcd.hcd_id].hw, CONFIG_USB_EHCI_ALIGN_SIZE);
usb_dcache_clean((uintptr_t)&g_periodic_qh_head[bus->hcd.hcd_id].hw, CONFIG_USB_EHCI_ALIGN_SIZE);
usb_dcache_clean((uintptr_t)g_framelist[bus->hcd.hcd_id], sizeof(uint32_t) * CONFIG_USB_EHCI_FRAME_LIST_SIZE);

usb_hc_low_level_init(bus);

USB_LOG_INFO("EHCI HCIVERSION:0x%04x\r\n", (unsigned int)EHCI_HCCR->hciversion);
Expand Down Expand Up @@ -1138,6 +1175,12 @@ int usbh_submit_urb(struct usbh_urb *urb)
return -USB_ERR_INVAL;
}

#ifdef CONFIG_USB_DCACHE_ENABLE
if (((uintptr_t)urb->setup % CONFIG_USB_ALIGN_SIZE) || ((uintptr_t)urb->transfer_buffer % CONFIG_USB_ALIGN_SIZE)) {
USB_LOG_ERR("urb buffer is not align with %d\r\n", CONFIG_USB_ALIGN_SIZE);
return -USB_ERR_ALIGN;
}
#endif
bus = urb->hport->bus;

/* find active hubport in roothub */
Expand Down
12 changes: 9 additions & 3 deletions port/ehci/usb_hc_ehci.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,19 @@
#ifndef CONFIG_USB_EHCI_ISO_NUM
#define CONFIG_USB_EHCI_ISO_NUM 4
#endif
#ifndef CONFIG_USB_EHCI_ALIGN_SIZE
#define CONFIG_USB_EHCI_ALIGN_SIZE 64
#endif

extern uint8_t usbh_get_port_speed(struct usbh_bus *bus, const uint8_t port);

struct ehci_qtd_hw {
struct ehci_qtd hw;
struct usbh_urb *urb;
bool dir_in;
uintptr_t bufaddr;
uint32_t length;
} __attribute__((aligned(32)));
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));

struct ehci_qh_hw {
struct ehci_qh hw;
Expand All @@ -46,7 +51,7 @@ struct ehci_qh_hw {
struct usbh_urb *urb;
usb_osal_sem_t waitsem;
uint8_t remove_in_iaad;
} __attribute__((aligned(32)));
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));

struct ehci_itd_hw {
struct ehci_itd hw;
Expand All @@ -55,7 +60,8 @@ struct ehci_itd_hw {
uint8_t mf_unmask;
uint8_t mf_valid;
uint32_t pkt_idx[8];
} __attribute__((aligned(32)));
bool dir_in;
} __attribute__((aligned(CONFIG_USB_EHCI_ALIGN_SIZE)));

struct ehci_iso_hw
{
Expand Down
8 changes: 6 additions & 2 deletions port/ohci/usb_hc_ohci.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,26 @@
#ifndef CONFIG_USB_OHCI_TD_NUM
#define CONFIG_USB_OHCI_TD_NUM 3
#endif
#ifndef CONFIG_USB_OHCI_ALIGN_SIZE
#define CONFIG_USB_OHCI_ALIGN_SIZE 64
#endif

struct ohci_ed_hw;
struct ohci_td_hw {
struct ohci_gtd hw;
struct usbh_urb *urb;
bool dir_in;
uint32_t buf_start;
uint32_t length;
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */

struct ohci_ed_hw {
struct ohci_ed hw;
struct ohci_td_hw td_pool[CONFIG_USB_OHCI_TD_NUM];
uint32_t td_count;
uint8_t ed_type;
usb_osal_sem_t waitsem;
} __attribute__((aligned(32))); /* min is 16bytes, we use 32 for cacheline */
} __attribute__((aligned(CONFIG_USB_OHCI_ALIGN_SIZE))); /* min is 16bytes, we use CONFIG_USB_OHCI_ALIGN_SIZE for cacheline */

struct ohci_hcd {
bool ohci_ed_used[CONFIG_USB_OHCI_ED_NUM];
Expand Down

0 comments on commit 940e086

Please sign in to comment.