@@ -199,9 +199,9 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
199
199
ohci_data .hcca .interrupt_table [i ] = (uint32_t ) _phys_addr (& ohci_data .period_head_ed );
200
200
}
201
201
202
- ohci_data .control [0 ].ed .skip = 1 ;
203
- ohci_data .bulk_head_ed .skip = 1 ;
204
- ohci_data .period_head_ed .skip = 1 ;
202
+ ohci_data .control [0 ].ed .w0 . skip = 1 ;
203
+ ohci_data .bulk_head_ed .w0 . skip = 1 ;
204
+ ohci_data .period_head_ed .w0 . skip = 1 ;
205
205
206
206
//If OHCI hardware is in SMM mode, gain ownership (Ref OHCI spec 5.1.1.3.3)
207
207
if (OHCI_REG -> control_bit .interrupt_routing == 1 )
@@ -300,7 +300,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
300
300
// addr0 serves as static head --> only set skip bit
301
301
if ( dev_addr == 0 )
302
302
{
303
- ohci_data .control [0 ].ed .skip = 1 ;
303
+ hcd_dcache_uncached ( ohci_data .control [0 ].ed . w0 ) .skip = 1 ;
304
304
}else
305
305
{
306
306
// remove control
@@ -323,11 +323,11 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
323
323
//--------------------------------------------------------------------+
324
324
// List Helper
325
325
//--------------------------------------------------------------------+
326
- static inline tusb_xfer_type_t ed_get_xfer_type (ohci_ed_t const * const p_ed )
326
+ static inline tusb_xfer_type_t ed_get_xfer_type (ohci_ed_word0 w0 )
327
327
{
328
- return (p_ed -> ep_number == 0 ) ? TUSB_XFER_CONTROL :
329
- (p_ed -> is_iso ) ? TUSB_XFER_ISOCHRONOUS :
330
- (p_ed -> is_interrupt_xfer ) ? TUSB_XFER_INTERRUPT : TUSB_XFER_BULK ;
328
+ return (w0 . ep_number == 0 ) ? TUSB_XFER_CONTROL :
329
+ (w0 . is_iso ) ? TUSB_XFER_ISOCHRONOUS :
330
+ (w0 . is_interrupt_xfer ) ? TUSB_XFER_INTERRUPT : TUSB_XFER_BULK ;
331
331
}
332
332
333
333
static void ed_init (ohci_ed_t * p_ed , uint8_t dev_addr , uint16_t ep_size , uint8_t ep_addr , uint8_t xfer_type , uint8_t interval )
@@ -337,21 +337,25 @@ static void ed_init(ohci_ed_t *p_ed, uint8_t dev_addr, uint16_t ep_size, uint8_t
337
337
// address 0 is used as async head, which always on the list --> cannot be cleared
338
338
if (dev_addr != 0 )
339
339
{
340
- tu_memclr (p_ed , sizeof (ohci_ed_t ));
340
+ hcd_dcache_uncached (p_ed -> td_tail ) = 0 ;
341
+ hcd_dcache_uncached (p_ed -> td_head ).address = 0 ;
342
+ hcd_dcache_uncached (p_ed -> next ) = 0 ;
341
343
}
342
344
343
345
tuh_bus_info_t bus_info ;
344
346
tuh_bus_info_get (dev_addr , & bus_info );
345
347
346
- p_ed -> dev_addr = dev_addr ;
347
- p_ed -> ep_number = ep_addr & 0x0F ;
348
- p_ed -> pid = (xfer_type == TUSB_XFER_CONTROL ) ? PID_FROM_TD : (tu_edpt_dir (ep_addr ) ? PID_IN : PID_OUT );
349
- p_ed -> speed = bus_info .speed ;
350
- p_ed -> is_iso = (xfer_type == TUSB_XFER_ISOCHRONOUS ) ? 1 : 0 ;
351
- p_ed -> max_packet_size = ep_size ;
352
-
353
- p_ed -> used = 1 ;
354
- p_ed -> is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0 );
348
+ ohci_ed_word0 w0 = {.u = 0 };
349
+ w0 .dev_addr = dev_addr ;
350
+ w0 .ep_number = ep_addr & 0x0F ;
351
+ w0 .pid = (xfer_type == TUSB_XFER_CONTROL ) ? PID_FROM_TD : (tu_edpt_dir (ep_addr ) ? PID_IN : PID_OUT );
352
+ w0 .speed = bus_info .speed ;
353
+ w0 .is_iso = (xfer_type == TUSB_XFER_ISOCHRONOUS ) ? 1 : 0 ;
354
+ w0 .max_packet_size = ep_size ;
355
+
356
+ w0 .used = 1 ;
357
+ w0 .is_interrupt_xfer = (xfer_type == TUSB_XFER_INTERRUPT ? 1 : 0 );
358
+ hcd_dcache_uncached (p_ed -> w0 ) = w0 ;
355
359
}
356
360
357
361
static void gtd_init (ohci_gtd_t * p_td , uint8_t * data_ptr , uint16_t total_bytes ) {
@@ -381,8 +385,9 @@ static ohci_ed_t * ed_from_addr(uint8_t dev_addr, uint8_t ep_addr)
381
385
382
386
for (uint32_t i = 0 ; i < ED_MAX ; i ++ )
383
387
{
384
- if ( (ed_pool [i ].dev_addr == dev_addr ) &&
385
- ep_addr == tu_edpt_addr (ed_pool [i ].ep_number , ed_pool [i ].pid == PID_IN ) )
388
+ ohci_ed_word0 w0 = hcd_dcache_uncached (ed_pool [i ].w0 );
389
+ if ( (w0 .dev_addr == dev_addr ) &&
390
+ ep_addr == tu_edpt_addr (w0 .ep_number , w0 .pid == PID_IN ) )
386
391
{
387
392
return & ed_pool [i ];
388
393
}
@@ -397,41 +402,44 @@ static ohci_ed_t * ed_find_free(void)
397
402
398
403
for (uint8_t i = 0 ; i < ED_MAX ; i ++ )
399
404
{
400
- if ( !ed_pool [i ].used ) return & ed_pool [i ];
405
+ if ( !hcd_dcache_uncached ( ed_pool [i ]. w0 ) .used ) return & ed_pool [i ];
401
406
}
402
407
403
408
return NULL ;
404
409
}
405
410
406
411
static void ed_list_insert (ohci_ed_t * p_pre , ohci_ed_t * p_ed )
407
412
{
408
- p_ed -> next = p_pre -> next ;
409
- p_pre -> next = (uint32_t ) _phys_addr (p_ed );
413
+ hcd_dcache_uncached ( p_ed -> next ) = hcd_dcache_uncached ( p_pre -> next ) ;
414
+ hcd_dcache_uncached ( p_pre -> next ) = (uint32_t ) _phys_addr (p_ed );
410
415
}
411
416
412
417
static void ed_list_remove_by_addr (ohci_ed_t * p_head , uint8_t dev_addr )
413
418
{
414
419
ohci_ed_t * p_prev = p_head ;
415
420
416
- while ( p_prev -> next )
421
+ uint32_t ed_pa ;
422
+ while ( (ed_pa = hcd_dcache_uncached (p_prev -> next )) )
417
423
{
418
- ohci_ed_t * ed = (ohci_ed_t * ) _virt_addr ((void * )p_prev -> next );
424
+ ohci_ed_t * ed = (ohci_ed_t * ) _virt_addr ((void * )ed_pa );
419
425
420
- if (ed -> dev_addr == dev_addr )
426
+ if (hcd_dcache_uncached ( ed -> w0 ). dev_addr == dev_addr )
421
427
{
422
428
// Prevent Host Controller from processing this ED while we remove it
423
- ed -> skip = 1 ;
429
+ hcd_dcache_uncached ( ed -> w0 ). skip = 1 ;
424
430
425
431
// unlink ed, will also move up p_prev
426
- p_prev -> next = ed -> next ;
432
+ hcd_dcache_uncached ( p_prev -> next ) = hcd_dcache_uncached ( ed -> next ) ;
427
433
428
434
// point the removed ED's next pointer to list head to make sure HC can always safely move away from this ED
429
- ed -> next = (uint32_t ) _phys_addr (p_head );
430
- ed -> used = 0 ;
431
- ed -> skip = 0 ;
435
+ hcd_dcache_uncached (ed -> next ) = (uint32_t ) _phys_addr (p_head );
436
+ ohci_ed_word0 w0 = hcd_dcache_uncached (ed -> w0 );
437
+ w0 .used = 0 ;
438
+ w0 .skip = 0 ;
439
+ hcd_dcache_uncached (ed -> w0 ) = w0 ;
432
440
}else
433
441
{
434
- p_prev = (ohci_ed_t * ) _virt_addr ((void * )p_prev -> next );
442
+ p_prev = (ohci_ed_t * ) _virt_addr ((void * )ed_pa );
435
443
}
436
444
}
437
445
}
@@ -477,7 +485,7 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const
477
485
// control of dev0 is used as static async head
478
486
if ( dev_addr == 0 )
479
487
{
480
- p_ed -> skip = 0 ; // only need to clear skip bit
488
+ hcd_dcache_uncached ( p_ed -> w0 ). skip = 0 ; // only need to clear skip bit
481
489
return true;
482
490
}
483
491
@@ -519,7 +527,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
519
527
hcd_dcache_clean (qtd , sizeof (ohci_gtd_t ));
520
528
521
529
//------------- Attach TDs list to Control Endpoint -------------//
522
- ed -> td_head .address = (uint32_t ) _phys_addr (qtd );
530
+ hcd_dcache_uncached ( ed -> td_head .address ) = (uint32_t ) _phys_addr (qtd );
523
531
524
532
OHCI_REG -> command_status_bit .control_list_filled = 1 ;
525
533
@@ -554,12 +562,13 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
554
562
gtd -> delay_interrupt = OHCI_INT_ON_COMPLETE_YES ;
555
563
hcd_dcache_clean (gtd , sizeof (ohci_gtd_t ));
556
564
557
- ed -> td_head .address = (uint32_t ) _phys_addr (gtd );
565
+ hcd_dcache_uncached ( ed -> td_head ) .address = (uint32_t ) _phys_addr (gtd );
558
566
559
567
OHCI_REG -> command_status_bit .control_list_filled = 1 ;
560
568
}else
561
569
{
562
570
ohci_ed_t * ed = ed_from_addr (dev_addr , ep_addr );
571
+ tusb_xfer_type_t xfer_type = ed_get_xfer_type ( hcd_dcache_uncached (ed -> w0 ) );
563
572
ohci_gtd_t * gtd = (ohci_gtd_t * )_virt_addr ((void * )hcd_dcache_uncached (ed -> td_tail ));
564
573
565
574
gtd_init (gtd , buffer , buflen );
@@ -576,7 +585,6 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *
576
585
577
586
hcd_dcache_uncached (ed -> td_tail ) = (uint32_t )_phys_addr (new_gtd );
578
587
579
- tusb_xfer_type_t xfer_type = ed_get_xfer_type ( ed_from_addr (dev_addr , ep_addr ) );
580
588
if (TUSB_XFER_BULK == xfer_type ) OHCI_REG -> command_status_bit .bulk_list_filled = 1 ;
581
589
}
582
590
@@ -595,13 +603,12 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) {
595
603
(void ) rhport ;
596
604
ohci_ed_t * const p_ed = ed_from_addr (dev_addr , ep_addr );
597
605
598
- p_ed -> is_stalled = 0 ;
599
- p_ed -> td_tail &= 0x0Ful ; // set tail pointer back to NULL
600
-
601
- p_ed -> td_head .toggle = 0 ; // reset data toggle
602
- p_ed -> td_head .halted = 0 ;
606
+ ohci_ed_td_head td_head = hcd_dcache_uncached (p_ed -> td_head );
607
+ td_head .toggle = 0 ; // reset data toggle
608
+ td_head .halted = 0 ;
609
+ hcd_dcache_uncached (p_ed -> td_head ) = td_head ;
603
610
604
- if ( TUSB_XFER_BULK == ed_get_xfer_type (p_ed ) ) OHCI_REG -> command_status_bit .bulk_list_filled = 1 ;
611
+ if ( TUSB_XFER_BULK == ed_get_xfer_type (hcd_dcache_uncached ( p_ed -> w0 ) ) ) OHCI_REG -> command_status_bit .bulk_list_filled = 1 ;
605
612
606
613
return true;
607
614
}
@@ -665,7 +672,7 @@ static void done_queue_isr(uint8_t hostid)
665
672
(void ) hostid ;
666
673
667
674
// done head is written in reversed order of completion --> need to reverse the done queue first
668
- ohci_td_item_t * td_head = list_reverse ( (ohci_td_item_t * ) tu_align16 (ohci_data .hcca .done_head ) );
675
+ ohci_td_item_t * td_head = list_reverse ( (ohci_td_item_t * ) tu_align16 (hcd_dcache_uncached ( ohci_data .hcca ) .done_head ) );
669
676
ohci_data .hcca .done_head = 0 ;
670
677
671
678
while ( td_head != NULL )
0 commit comments