3#include "pedigree/kernel/TargetInfo.h"
4#include "pedigree/kernel/processor/PhysicalMemoryManager.h"
5#include "pedigree/kernel/processor/VirtualAddressSpace.h"
6#include "pedigree/kernel/utilities/assert.h"
7#include "pedigree/kernel/utilities/utility.h"
9bool allocate(
MemoryRegion& region,
size_t pages,
bool contiguous) {
20Ring::Ring() : m_Memory(
"xHCI ring"), m_Tail(0), m_Used(0), m_Cycle(true), m_Wraps(0) {}
21bool Ring::initialise() {
22 return allocate(m_Memory, 1);
24bool Ring::enqueue(
const Trb* entries,
size_t count, uint64_t* addresses) {
25 if (!count || count > 32 || m_Used + count > RingEntries - 1)
32 auto* ring =
static_cast<volatile Trb*
>(m_Memory.virtualAddress());
33 for (
size_t i = 0; i < count; ++i) {
34 if (m_Tail == RingEntries - 1) {
35 const uint32_t flags = (6U << 10) | 2U | m_Cycle | (i ? entries[i - 1].control & Chain : 0);
36 ring[m_Tail].parameter = address();
37 ring[m_Tail].status = 0;
38 ring[m_Tail].control = flags ^ Cycle;
39 publications[published++] = {m_Tail, flags};
44 const uint32_t flags = (entries[i].control & ~Cycle) | m_Cycle;
45 ring[m_Tail].parameter = entries[i].parameter;
46 ring[m_Tail].status = entries[i].status;
47 ring[m_Tail].control = flags ^ Cycle;
48 addresses[i] = address() + m_Tail *
sizeof(Trb);
49 publications[published++] = {m_Tail++, flags};
54 const auto& publication = publications[--published];
55 ring[publication.index].control = publication.control;
61void Ring::retire(
size_t count) {
62 assert(count <= m_Used);
Special memory entity in the kernel's virtual address space.
void * virtualAddress() const
static const size_t continuous
static PhysicalMemoryManager & instance()
static const size_t below4GB
static constexpr size_t getPageSize() noexcept