Skip to content

Commit 915d212

Browse files
committed
ohci: Perform explicit cache operations on TDs, buffers
1 parent 330d9d7 commit 915d212

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

src/portable/ohci/ohci.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,8 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
225225
#endif
226226
}
227227

228+
hcd_dcache_clean(&ohci_data, sizeof(ohci_data));
229+
228230
// reset controller
229231
OHCI_REG->command_status_bit.controller_reset = 1;
230232
while( OHCI_REG->command_status_bit.controller_reset ) {} // should not take longer than 10 us
@@ -506,12 +508,15 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
506508
ohci_ed_t* ed = &ohci_data.control[dev_addr].ed;
507509
ohci_gtd_t *qtd = &ohci_data.control[dev_addr].gtd;
508510

511+
hcd_dcache_clean(setup_packet, 8);
512+
509513
gtd_init(qtd, (uint8_t*)(uintptr_t) setup_packet, 8);
510514
gtd_get_extra_data(qtd)->dev_addr = dev_addr;
511515
gtd_get_extra_data(qtd)->ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT);
512516
qtd->pid = PID_SETUP;
513517
qtd->data_toggle = GTD_DT_DATA0;
514518
qtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES;
519+
hcd_dcache_clean(qtd, sizeof(ohci_gtd_t));
515520

516521
//------------- Attach TDs list to Control Endpoint -------------//
517522
ed->td_head.address = (uint32_t) _phys_addr(qtd);
@@ -528,6 +533,13 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
528533
uint8_t const epnum = tu_edpt_number(ep_addr);
529534
uint8_t const dir = tu_edpt_dir(ep_addr);
530535

536+
// IN transfer: invalidate buffer, OUT transfer: clean buffer
537+
if (dir) {
538+
hcd_dcache_invalidate(buffer, buflen);
539+
} else {
540+
hcd_dcache_clean(buffer, buflen);
541+
}
542+
531543
if ( epnum == 0 )
532544
{
533545
ohci_ed_t* ed = &ohci_data.control[dev_addr].ed;
@@ -540,6 +552,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
540552
gtd->pid = dir ? PID_IN : PID_OUT;
541553
gtd->data_toggle = GTD_DT_DATA1; // Both Data and Ack stage start with DATA1
542554
gtd->delay_interrupt = OHCI_INT_ON_COMPLETE_YES;
555+
hcd_dcache_clean(gtd, sizeof(ohci_gtd_t));
543556

544557
ed->td_head.address = (uint32_t) _phys_addr(gtd);
545558

@@ -559,6 +572,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
559572
TU_ASSERT(new_gtd);
560573

561574
gtd->next = (uint32_t)_phys_addr(new_gtd);
575+
hcd_dcache_clean(gtd, sizeof(ohci_gtd_t));
562576

563577
hcd_dcache_uncached(ed->td_tail) = (uint32_t)_phys_addr(new_gtd);
564578

@@ -603,6 +617,12 @@ static ohci_td_item_t* list_reverse(ohci_td_item_t* td_head)
603617
while(td_head != NULL)
604618
{
605619
td_head = _virt_addr(td_head);
620+
// FIXME: This is not the correct object size.
621+
// However, because we have hardcoded the assumption that
622+
// a cache line is at least 32 bytes (in ohci.h), and
623+
// because both types of TD structs are <= 32 bytes, this
624+
// nonetheless still works without error.
625+
hcd_dcache_invalidate(td_head, sizeof(ohci_td_item_t));
606626
uint32_t next = td_head->next;
607627

608628
// make current's item become reverse's first item

0 commit comments

Comments
 (0)