Драйвер Xhci в пользовательской ОС: кольцо событий не генерирует TRB завершенияC++

Программы на C++. Форум разработчиков
Ответить Пред. темаСлед. тема
Anonymous
 Драйвер Xhci в пользовательской ОС: кольцо событий не генерирует TRB завершения

Сообщение Anonymous »

Я разрабатываю свою собственную ОС и пытаюсь реализовать очень простой каркасный драйвер xhci. Я перезагрузил контроллер, выделил DCBAA и настроил кольца команд и событий. В качестве «Hello World» для драйвера я пытаюсь отправить образец TRB через кольцо команд и увидеть TRB завершения события в кольце событий, но TRB в кольце событий не генерируется. Я тестирую это в QEMU с включенными журналами трассировки xhci, поэтому могу подтвердить, что кольцо команд работает успешно, но кольцо событий не создает никаких записей в журнале.
Это мой драйвер код инициализации:

Код: Выделить всё

    bool XhciDriver::init(PciDeviceInfo& deviceInfo) {
_mapDeviceMmio(deviceInfo.barAddress);

uint64_t opRegBase = (uint64_t)m_capRegisters + m_capRegisters->caplength;
m_opRegisters = (volatile XhciOperationalRegisters*)opRegBase;

m_runtimeRegisterBase = opRegBase + m_capRegisters->rtsoff;
m_rtRegisters = (volatile XhciRuntimeRegisters*)m_runtimeRegisterBase;

m_maxDeviceSlots = XHCI_MAX_DEVICE_SLOTS(m_capRegisters);
m_numPorts = XHCI_NUM_PORTS(m_capRegisters);

printXhciCapabilityRegisters(m_capRegisters);
printXhciOperationalRegisters(m_opRegisters);

_assumeOwnershipFromBios();

if (!_resetController()) {
return false;
}
kuPrint("[XHCI] Reset the controller\n");

// Set the Max Device Slots Enabled field
uint32_t configReg = XHCI_SET_MAX_SLOTS_EN(m_opRegisters->config, m_maxDeviceSlots);
m_opRegisters->config = configReg;

m_opRegisters->dnctrl |= 0b1111111111111111;

if (_checkForHostControllerError()) {
return false;
}

// ============================== Initialize DCBAA ============================== //
kuPrint("[XHCI] device slots: %llu   ports: %llu\n", m_maxDeviceSlots, m_numPorts);
kuPrint("[XHCI] 64-byte contexts: %s\n", _is64ByteContextUsed() ? "true" : "false");

size_t contextEntrySize = _is64ByteContextUsed() ? 64 : 32;
void* dcbaaVirtualBase = _allocXhciMemory(contextEntrySize * (m_maxDeviceSlots + 1));
zeromem(dcbaaVirtualBase, contextEntrySize * (m_maxDeviceSlots + 1));
kuPrint("[XHCI] dcbaa va: %llx  pa: %llx\n", dcbaaVirtualBase, (uint64_t)__pa(dcbaaVirtualBase));

/*
// xHci Spec Section 6.1 (page 404)

If the Max Scratchpad Buffers field of the HCSPARAMS2 register is > ‘0’, then
the first entry (entry_0) in the DCBAA shall contain a pointer to the Scratchpad
Buffer Array.  If the Max Scratchpad Buffers field of the HCSPARAMS2 register is
= ‘0’, then the first entry (entry_0) in the DCBAA is reserved and shall be
cleared to ‘0’ by software.
*/
uint32_t maxScratchpadBuffers = XHCI_MAX_SCRATCHPAD_BUFFERS(m_capRegisters);
kuPrint("[XHCI] Scratchpad buffer: %s\n", maxScratchpadBuffers > 0 ? "required" : "not required");

// Initialize scratchpad buffer array if needed
if (maxScratchpadBuffers > 0) {
void* scratchpadArray = _allocXhciMemory(contextEntrySize * maxScratchpadBuffers);
zeromem(scratchpadArray, contextEntrySize * maxScratchpadBuffers);
((uint64_t*)dcbaaVirtualBase)[0] = (uint64_t)__pa(scratchpadArray);
}

m_opRegisters->dcbaap = (uint64_t)__pa(dcbaaVirtualBase);

//  ============================== Initialize command ring ============================== //
size_t cmdRingSize = sizeof(XhciTrb_t) * 256;
XhciTrb_t* commandRing = (XhciTrb_t*)_allocXhciMemory(cmdRingSize);
zeromem(commandRing, cmdRingSize);

// Initialize the command ring TRBs
for (int i = 0; i < 256; i++) {
commandRing[i].control = 1; // Set cycle bit to 1 for each TRB
}

// Set the last TRB as a link TRB to point back to the first TRB
commandRing[255].parameter = (uint64_t)__pa(commandRing);
commandRing[255].control = (XHCI_TRB_TYPE_LINK crcr = cmdRingPhysicalBase | XHCI_CRCR_RING_CYCLE_STATE;

kuPrint("[XHCI] Command ring initialized: %llx\n", (uint64_t)commandRing);

//  ============================== Initialize event ring  ============================== //
// Define the size of the event ring
const size_t eventRingSize = 256 * sizeof(XhciTrb_t);

// Allocate memory for the event ring
void* eventRingVirtualBase = _allocXhciMemory(eventRingSize);
zeromem(eventRingVirtualBase, eventRingSize);

XhciTrb_t* eventRing = (XhciTrb_t*)eventRingVirtualBase;

// Set up the Link TRB to create a circular buffer
eventRing[255].parameter = (uint64_t)__pa(eventRingVirtualBase); // Link to the start of the ring
eventRing[255].status = 0;
eventRing[255].control = (XHCI_TRB_TYPE_LINK crcr;

// Allocate and clear a test TRB
XhciTrb_t testTrb;
zeromem(&testTrb, sizeof(XhciTrb_t));
// noOpTrb.control = (XHCI_TRB_TYPE_NOOP crcr);

// Poll the event ring for a completion event
kuPrint("[XHCI] Polling Event Ring at address: %llx\n", eventRing);

while (true) {
for (int i = 0; i < 256; ++i) {
if (eventRing[i].control != 0 && (eventRing[i].control >> 10) != XHCI_TRB_TYPE_LINK) {
kuPrint("[XHCI] Event Ring TRB[%i]: parameter = %llx, status = %x, control = %x\n",
i, eventRing[i].parameter, eventRing[i].status, eventRing[i].control);
if ((eventRing[i].control >> 10) == XHCI_TRB_TYPE_ENABLE_SLOT_CMD) {
kuPrint("[XHCI] Enable Slot TRB processed successfully\n");
return true;
}
}
}
kuPrint("[XHCI] No TRBs found in the event ring...\n");
sleep(2);
}

kuPrint("\n");
return true;
}
Я утверждал, что контроллер xhci не сталкивается с какими-либо системными ошибками (мониторинг регистра usbsts), и все адреса выровнены по 64 байтам. Ниже приведен журнал qemu событий xhci:

Код: Выделить всё

usb_xhci_oper_read off 0x0004, ret 0x00000001
usb_xhci_cap_read off 0x0010, ret 0x00087001
usb_xhci_cap_read off 0x0010, ret 0x00087001
usb_xhci_cap_read off 0x0008, ret 0x0000000f
usb_xhci_cap_read off 0x0008, ret 0x0000000f
usb_xhci_oper_write off 0x0030, val 0x01512880
usb_xhci_oper_write off 0x0034, val 0x00000000
usb_xhci_oper_write off 0x0018, val 0x01513101
usb_xhci_oper_write off 0x001c, val 0x00000000
usb_xhci_runtime_write off 0x0068, val 0x00000001
usb_xhci_runtime_write off 0x0078, val 0x01514140
usb_xhci_runtime_write off 0x007c, val 0x00000000
usb_xhci_runtime_write off 0x0070, val 0x015122c0
usb_xhci_runtime_write off 0x0074, val 0x00000000
usb_xhci_runtime_read off 0x0070, ret 0x015122c0
usb_xhci_runtime_read off 0x0074, ret 0x00000000
usb_xhci_runtime_read off 0x0068, ret 0x00000001
usb_xhci_runtime_read off 0x0078, ret 0x01514140
usb_xhci_runtime_read off 0x007c, ret 0x00000000
usb_xhci_oper_read off 0x0000, ret 0x00000000
usb_xhci_oper_write off 0x0000, val 0x00000001
usb_xhci_run
usb_xhci_oper_read off 0x0004, ret 0x00000000
usb_xhci_oper_read off 0x0000, ret 0x00000001
usb_xhci_oper_read off 0x0004, ret 0x00000000
usb_xhci_oper_read off 0x0008, ret 0x00000001
usb_xhci_oper_read off 0x0014, ret 0x0000ffff
usb_xhci_oper_read off 0x0018, ret 0x01513101
usb_xhci_oper_read off 0x001c, ret 0x00000000
usb_xhci_oper_read off 0x0030, ret 0x01512880
usb_xhci_oper_read off 0x0034, ret 0x00000000
usb_xhci_oper_read off 0x0038, ret 0x00000040
usb_xhci_oper_read off 0x0004, ret 0x00000000
usb_xhci_oper_read off 0x0018, ret 0x01513101
usb_xhci_oper_read off 0x001c, ret 0x00000000
usb_xhci_cap_read off 0x0014, ret 0x00002000
usb_xhci_doorbell_write off 0x0000, val 0x00000000
usb_xhci_fetch_trb addr 0x0000000001513100, CR_ENABLE_SLOT, p 0x0000000000000000, s 0x00000000, c 0x00002400
usb_xhci_oper_read off 0x0018, ret 0x01513101
usb_xhci_oper_read off 0x001c, ret 0x00000000
Я тестировал это и на реальном оборудовании, и там оно тоже не работает, так что это не просто проблема qemu.

Подробнее здесь: https://stackoverflow.com/questions/785 ... etion-trbs
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Как я могу реализовать минимальную поддержку XHCI (USB 3.0) в ОС Pintos?
    Anonymous » » в форуме Linux
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous
  • кольцо Новаринг
    НастяZAv » » в форуме Товары для здоровья
    1 Ответы
    3584 Просмотры
    Последнее сообщение aishapuck
  • Как расположить кольцо кругов с максимальным радиусом кольца
    Anonymous » » в форуме C#
    0 Ответы
    125 Просмотры
    Последнее сообщение Anonymous
  • Поместите кольцо на проекцию картопического сюжета.
    Anonymous » » в форуме Python
    0 Ответы
    127 Просмотры
    Последнее сообщение Anonymous
  • Как удалить серое кольцо вокруг линии?
    Anonymous » » в форуме Html
    0 Ответы
    107 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C++»