XHCI volatile and memory barriers
This commit is contained in:
19
kernel/amd64/memorybarrier.h
Normal file
19
kernel/amd64/memorybarrier.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef _KERNEL_AMD64_MEMORYBARRIER_H
|
||||||
|
#define _KERNEL_AMD64_MEMORYBARRIER_H
|
||||||
|
|
||||||
|
#define memory_barrier() \
|
||||||
|
do { \
|
||||||
|
__asm__ volatile ("mfence" ::: "memory"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define read_memory_barrier() \
|
||||||
|
do { \
|
||||||
|
__asm__ volatile ("lfence" ::: "memory"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define write_memory_barrier() \
|
||||||
|
do { \
|
||||||
|
__asm__ volatile ("sfence" ::: "memory"); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#endif // _KERNEL_AMD64_MEMORYBARRIER_H
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
#include <proc/suspension_q.h>
|
#include <proc/suspension_q.h>
|
||||||
#include <status.h>
|
#include <status.h>
|
||||||
#include <sys/debug.h>
|
#include <sys/debug.h>
|
||||||
|
#include <sys/memorybarrier.h>
|
||||||
#include <sys/spin_lock.h>
|
#include <sys/spin_lock.h>
|
||||||
#include <sys/stall.h>
|
#include <sys/stall.h>
|
||||||
|
|
||||||
@@ -510,6 +511,9 @@ static void xhci_endpoint0_put_trb (struct xhci_pdevice* pdevice, struct xhci_tr
|
|||||||
struct xhci_trb* link = &pdevice->endpoint0_ring.trbs[pdevice->endpoint0_ring.idx];
|
struct xhci_trb* link = &pdevice->endpoint0_ring.trbs[pdevice->endpoint0_ring.idx];
|
||||||
link->param = pdevice->endpoint0_ring.phys;
|
link->param = pdevice->endpoint0_ring.phys;
|
||||||
link->status = 0;
|
link->status = 0;
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) |
|
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) |
|
||||||
(1 << XHCI_LNKTRB_CTRL_TC) |
|
(1 << XHCI_LNKTRB_CTRL_TC) |
|
||||||
pdevice->endpoint0_ring.cycle_bit;
|
pdevice->endpoint0_ring.cycle_bit;
|
||||||
@@ -521,6 +525,9 @@ static void xhci_endpoint0_put_trb (struct xhci_pdevice* pdevice, struct xhci_tr
|
|||||||
struct xhci_trb* trb = &pdevice->endpoint0_ring.trbs[pdevice->endpoint0_ring.idx];
|
struct xhci_trb* trb = &pdevice->endpoint0_ring.trbs[pdevice->endpoint0_ring.idx];
|
||||||
trb->param = put_trb.param;
|
trb->param = put_trb.param;
|
||||||
trb->status = put_trb.status;
|
trb->status = put_trb.status;
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
trb->ctrl = (put_trb.ctrl & ~XHCI_LNKTRB_CTRL_TC) | pdevice->endpoint0_ring.cycle_bit;
|
trb->ctrl = (put_trb.ctrl & ~XHCI_LNKTRB_CTRL_TC) | pdevice->endpoint0_ring.cycle_bit;
|
||||||
|
|
||||||
pdevice->endpoint0_ring.idx++;
|
pdevice->endpoint0_ring.idx++;
|
||||||
@@ -544,6 +551,9 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_pdevice* pdev
|
|||||||
memset (&trb, 0, sizeof (trb));
|
memset (&trb, 0, sizeof (trb));
|
||||||
trb.param = setup;
|
trb.param = setup;
|
||||||
trb.status = 8;
|
trb.status = 8;
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
|
trb.ctrl = (XHCI_TRB_SETUP_STAGE << XHCI_SSTRB_CTRL_TRB_TYPE) |
|
||||||
(1 << XHCI_SSTRB_CTRL_IDT) |
|
(1 << XHCI_SSTRB_CTRL_IDT) |
|
||||||
(XHCI_SSTRB_TRT_IN_DATA_STAGE << XHCI_SSTRB_CTRL_TRT);
|
(XHCI_SSTRB_TRT_IN_DATA_STAGE << XHCI_SSTRB_CTRL_TRT);
|
||||||
@@ -554,6 +564,9 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_pdevice* pdev
|
|||||||
trb.param = data_phys;
|
trb.param = data_phys;
|
||||||
trb.status = length;
|
trb.status = length;
|
||||||
trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE) | (1 << XHCI_DSTRB_CTRL_DIR);
|
trb.ctrl = (XHCI_TRB_DATA_STAGE << XHCI_DSTRB_CTRL_TRB_TYPE) | (1 << XHCI_DSTRB_CTRL_DIR);
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
xhci_endpoint0_put_trb (pdevice, trb);
|
xhci_endpoint0_put_trb (pdevice, trb);
|
||||||
|
|
||||||
/* status stage */
|
/* status stage */
|
||||||
@@ -561,6 +574,9 @@ static bool xhci_endpoint0_ctrl_in (struct xhci* xhci, struct xhci_pdevice* pdev
|
|||||||
trb.param = 0;
|
trb.param = 0;
|
||||||
trb.status = 0;
|
trb.status = 0;
|
||||||
trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) | (1 << XHCI_STSTRB_CTRL_IOC);
|
trb.ctrl = (XHCI_TRB_STATUS_STAGE << XHCI_STSTRB_CTRL_TRB_TYPE) | (1 << XHCI_STSTRB_CTRL_IOC);
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
xhci_endpoint0_put_trb (pdevice, trb);
|
xhci_endpoint0_put_trb (pdevice, trb);
|
||||||
|
|
||||||
atomic_store (&xhci->pending, true);
|
atomic_store (&xhci->pending, true);
|
||||||
@@ -590,6 +606,9 @@ static void xhci_send_cmd (struct xhci* xhci, uint64_t param, uint32_t status, u
|
|||||||
struct xhci_trb* link = &xhci->cmd_ring.trbs[xhci->cmd_ring.idx];
|
struct xhci_trb* link = &xhci->cmd_ring.trbs[xhci->cmd_ring.idx];
|
||||||
link->param = xhci->cmd_ring.phys;
|
link->param = xhci->cmd_ring.phys;
|
||||||
link->status = 0;
|
link->status = 0;
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) |
|
link->ctrl = (XHCI_TRB_LINK << XHCI_LNKTRB_CTRL_TRB_TYPE) |
|
||||||
(1 << XHCI_LNKTRB_CTRL_TC) |
|
(1 << XHCI_LNKTRB_CTRL_TC) |
|
||||||
xhci->cmd_ring.cycle_bit;
|
xhci->cmd_ring.cycle_bit;
|
||||||
@@ -601,6 +620,9 @@ static void xhci_send_cmd (struct xhci* xhci, uint64_t param, uint32_t status, u
|
|||||||
struct xhci_trb* trb = &xhci->cmd_ring.trbs[xhci->cmd_ring.idx];
|
struct xhci_trb* trb = &xhci->cmd_ring.trbs[xhci->cmd_ring.idx];
|
||||||
trb->param = param;
|
trb->param = param;
|
||||||
trb->status = status;
|
trb->status = status;
|
||||||
|
|
||||||
|
write_memory_barrier ();
|
||||||
|
|
||||||
trb->ctrl = (ctrl & ~XHCI_LNKTRB_CTRL_TC) | xhci->cmd_ring.cycle_bit;
|
trb->ctrl = (ctrl & ~XHCI_LNKTRB_CTRL_TC) | xhci->cmd_ring.cycle_bit;
|
||||||
|
|
||||||
xhci->cmd_ring.idx++;
|
xhci->cmd_ring.idx++;
|
||||||
|
|||||||
@@ -12,24 +12,24 @@
|
|||||||
|
|
||||||
/* event ring segment table entry */
|
/* event ring segment table entry */
|
||||||
struct xhci_erst_entry {
|
struct xhci_erst_entry {
|
||||||
uint64_t ptr;
|
volatile uint64_t ptr;
|
||||||
uint32_t size;
|
volatile uint32_t size;
|
||||||
uint32_t _rsvd;
|
volatile uint32_t _rsvd;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
/* transfer request block */
|
/* transfer request block */
|
||||||
struct xhci_trb {
|
struct xhci_trb {
|
||||||
uint64_t param;
|
volatile uint64_t param;
|
||||||
uint32_t status;
|
volatile uint32_t status;
|
||||||
uint32_t ctrl;
|
volatile uint32_t ctrl;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct xhci_ctx32 {
|
struct xhci_ctx32 {
|
||||||
uint32_t dw[8];
|
volatile uint32_t dw[8];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct xhci_ctx64 {
|
struct xhci_ctx64 {
|
||||||
uint32_t dw[16];
|
volatile uint32_t dw[16];
|
||||||
} PACKED;
|
} PACKED;
|
||||||
|
|
||||||
struct xhci_input_ctx32 {
|
struct xhci_input_ctx32 {
|
||||||
|
|||||||
8
kernel/sys/memorybarrier.h
Normal file
8
kernel/sys/memorybarrier.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _KERNEL_SYS_MEMORYBARRIER_H
|
||||||
|
#define _KERNEL_SYS_MEMORYBARRIER_H
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#include <amd64/memorybarrier.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _KERNEL_SYS_MEMORYBARRIER_H
|
||||||
Reference in New Issue
Block a user