1#![allow(dead_code)]
2
3pub mod descriptors;
4pub mod models;
5pub mod registers;
6
7use descriptors::*;
8use models::*;
9use registers::*;
10
11use crate::mem::zero;
12use crate::phys::addrs::*;
13use crate::phys::irq::*;
14use crate::phys::read_word;
15use crate::system::vector::*;
16use crate::*;
17use crate::{assembly, phys::*};
18
19type IrqFn = fn(status: u32);
20
21const BLANK_QUEUE_HEAD: UsbEndpointQueueHead = UsbEndpointQueueHead {
22 config: 0,
23 current: 0,
24 next: 0,
25 status: 0,
26 pointer0: 0,
27 pointer1: 0,
28 pointer2: 0,
29 pointer3: 0,
30 pointer4: 0,
31 reserved: 0,
32 setup0: 0,
33 setup1: 0,
34 callback: noop,
35 first_transfer: 0,
36 last_transfer: 0,
37};
38
39const MAX_ENDPOINTS: usize = 8;
40
41#[no_mangle]
42#[link_section = ".endpoint_queue"]
43static mut ENDPOINT_HEADERS: [UsbEndpointQueueHead; MAX_ENDPOINTS * 2] =
44 [BLANK_QUEUE_HEAD; MAX_ENDPOINTS * 2];
45
46#[link_section = ".dmabuffers"]
47static mut USB_DESCRIPTOR_BUFFER: BufferPage = BufferPage::new();
48
49#[no_mangle]
50#[link_section = ".dmabuffers"]
51static mut ENDPOINT0_BUFFER: BufferPage = BufferPage::new();
52
53#[no_mangle]
54static mut ENDPOINT0_TRANSFER_DATA: UsbEndpointTransferDescriptor =
55 UsbEndpointTransferDescriptor::new();
56
57#[no_mangle]
58static mut ENDPOINT0_TRANSFER_ACK: UsbEndpointTransferDescriptor =
59 UsbEndpointTransferDescriptor::new();
60
61static mut ENDPOINT0_NOTIFY_MASK: u32 = 0;
62static mut IRQ_CALLBACKS: Vector<IrqFn> = Vector::new();
63static mut CONFIGURATION_CALLBACKS: Vector<ConfigFn> = Vector::new();
64static mut CONFIGURATION: u16 = 0;
65static mut HIGHSPEED: bool = false;
66
67pub fn usb_attach_setup_callback(callback: ConfigFn) {
70 unsafe {
71 CONFIGURATION_CALLBACKS.push(callback);
72 }
73}
74
75pub fn usb_attach_irq_handler(callback: IrqFn) {
78 unsafe {
79 IRQ_CALLBACKS.push(callback);
80 }
81}
82
83pub fn usb_configure_codes(vid: u16, pid: u16) {
86 let descriptors = usb_get_descriptors();
87 descriptors.set_codes(vid, pid);
88}
89
90pub fn usb_get_queuehead(endpoint: usize, tx: bool) -> &'static mut UsbEndpointQueueHead {
95 unsafe {
96 let index = match tx {
97 true => endpoint * 2 + 1,
98 false => endpoint * 2,
99 };
100
101 return &mut ENDPOINT_HEADERS[index];
102 }
103}
104
105pub fn usb_start_clock() {
108 loop {
109 let pll_usb1_status = read_word(PLL1_USB1_ADDR);
110 if (pll_usb1_status & (0x1 << 13)) == 0 {
111 assign(PLL1_USB1_ADDR_SET, 0x1 << 13); continue;
114 }
115
116 if (pll_usb1_status & (0x1 << 12)) == 0 {
117 assign(PLL1_USB1_ADDR_SET, 0x1 << 12); continue;
120 }
121
122 if (pll_usb1_status & (0x1 << 16)) > 0 {
123 continue;
125 }
126
127 if (pll_usb1_status & (0x1 << 31)) == 0 {
128 assign(PLL1_USB1_ADDR_CLR, 0x1 << 31); continue;
131 }
132
133 if (pll_usb1_status & (0x1 << 6)) == 0 {
134 assign(0x400D_9038, 0x1 << 30);
136 assign(PLL1_USB1_ADDR_SET, 0x1 << 6); continue;
139 }
140
141 break;
142 }
143
144 assign(0x400D_8000 + 0x120, 0xF << 8 | 6 << 4 | 1);
145 assign(0x400F_C000 + 0x80, read_word(0x400F_C000 + 0x80) | 0x1);
147 assign(USB + 0x160, 0x0404);
149}
150
151pub fn usb_initialize() {
155 usb_initialize_descriptors();
157
158 assign(USBPHY1_CTRL_SET, 1 << 31);
161 usb_cmd(read_word(USBCMD) | 2);
162 while (read_word(USBCMD) & 0x2) > 0 {
163 assembly!("nop");
164 }
165
166 irq_clear_pending();
167
168 assign(USBPHY1_CTRL_CLR, 1 << 31);
169 wait_exact_ns(MS_TO_NANO * 25);
170 assign(USBPHY1_CTRL_CLR, 1 << 30);
171 assign(USBPHY1_PWD, 0);
172
173 usb_set_mode(UsbMode::DEVICE);
176 endpoint0_initialize();
177
178 assign(USBINTR, 0x143);
179
180 irq_attach(Irq::Usb1, handle_usb_irq);
181 irq_priority(Irq::Usb1, 32);
182 irq_enable(Irq::Usb1);
183
184 usb_cmd(1); }
186
187pub fn usb_set_mode(mode: UsbMode) {
189 match mode {
190 UsbMode::DEVICE => {
191 assign(USBMODE, 0x2 | (0x1 << 3));
193 }
194 }
195}
196
197fn waitfor(addr: u32) {
199 while read_word(addr) > 0 {
200 assembly!("nop");
201 }
202}
203
204pub fn usb_irq_clear(value: u32) {
206 assign(USBSTS, value);
207}
208
209fn endpoint0_initialize() {
211 unsafe {
212 let epaddr = &ENDPOINT_HEADERS[0] as *const UsbEndpointQueueHead as u32;
213
214 zero(epaddr, 4096);
216
217 ENDPOINT_HEADERS[0].config |= (64 << 16) | (1 << 15); ENDPOINT_HEADERS[1].config |= 64 << 16; assign(ENDPTLISTADDR, epaddr);
223 }
224}
225
226pub fn usb_cmd(val: u32) {
228 assign(USBCMD, val);
229}
230
231pub fn usb_is_highspeed() -> bool {
233 return unsafe { HIGHSPEED };
234}
235
236fn configure_ep(qh: &mut UsbEndpointQueueHead, config: u32, cb: Option<TransferCallbackFn>) {
238 qh.config = config;
239 qh.next = 1;
240
241 if cb.is_some() {
242 qh.callback = cb.unwrap();
243 } else {
244 qh.callback = noop;
245 }
246}
247
248fn run_callbacks(qh: &mut UsbEndpointQueueHead) {
249 let mut transfer_addr = qh.first_transfer;
250 while transfer_addr > 1 {
251 let transfer = unsafe {
253 (transfer_addr as *const UsbEndpointTransferDescriptor)
254 .as_ref()
255 .unwrap()
256 };
257
258 if (transfer.status & 0x80) > 0 {
260 qh.first_transfer = transfer_addr;
261 break;
262 }
263
264 if transfer.next == 1 {
266 qh.first_transfer = 0;
268 qh.last_transfer = 0;
269 } else {
270 transfer_addr = transfer.next;
271 }
272
273 qh.callback.call((transfer,));
275
276 if transfer.next == 1 {
278 break;
279 }
280 }
281}
282
283pub fn usb_setup_endpoint(
285 index: usize,
286 tx_config: Option<EndpointConfig>,
287 rx_config: Option<EndpointConfig>,
288) {
289 let tx_qh = usb_get_queuehead(index, true);
290 let rx_qh = usb_get_queuehead(index, false);
291 let ep_control_addr = USB + 0x1C0 + (index as u32) * 4;
292
293 let isochornous = 1;
294 let bulk = 2;
295 let interrupt = 3;
296 let tx_enable_bit = 1 << 23;
297 let rx_enable_bit = 1 << 7;
298
299 if tx_config.is_some() {
300 let config = tx_config.unwrap();
301
302 let mut config_bits = (config.size as u32) << 16;
303 if config.zlt {
304 config_bits |= 1 << 29;
305 }
306
307 configure_ep(tx_qh, config_bits, config.callback);
308 match config.endpoint_type {
309 EndpointType::ISOCHRONOUS => {
310 assign(
311 ep_control_addr,
312 read_word(ep_control_addr) | (isochornous << 18) | tx_enable_bit,
313 );
314 }
315 EndpointType::BULK => {
316 assign(
317 ep_control_addr,
318 read_word(ep_control_addr) | (bulk << 18) | tx_enable_bit,
319 );
320 }
321 EndpointType::INTERRUPT => {
322 assign(
323 ep_control_addr,
324 read_word(ep_control_addr) | (interrupt << 18) | tx_enable_bit,
325 );
326 }
327 }
328 } else {
329 assign(ep_control_addr, read_word(ep_control_addr) | (bulk << 18));
331 }
332
333 if rx_config.is_some() {
334 let config = rx_config.unwrap();
335
336 let mut config_bits = (config.size as u32) << 16;
337 if config.zlt {
338 config_bits |= 1 << 29;
339 }
340
341 configure_ep(rx_qh, config_bits, config.callback);
342 match config.endpoint_type {
343 EndpointType::ISOCHRONOUS => {
344 assign(
345 ep_control_addr,
346 read_word(ep_control_addr) | (isochornous << 2) | rx_enable_bit,
347 );
348 }
349 EndpointType::BULK => {
350 assign(
351 ep_control_addr,
352 read_word(ep_control_addr) | (bulk << 2) | rx_enable_bit,
353 );
354 }
355 EndpointType::INTERRUPT => {
356 assign(
357 ep_control_addr,
358 read_word(ep_control_addr) | (interrupt << 2) | rx_enable_bit,
359 );
360 }
361 }
362 } else {
363 assign(ep_control_addr, read_word(ep_control_addr) | (bulk << 2));
365 }
366}
367
368pub fn usb_prepare_transfer(
375 transfer_queue: &mut UsbEndpointTransferDescriptor,
376 addr: u32,
377 len: u32,
378 notify: bool,
379) -> bool {
380 if (transfer_queue.status & 0x80) == 0 {
381 transfer_queue.next = 1;
382 transfer_queue.status = (len << 16) | (1 << 7);
383 transfer_queue.pointer0 = addr;
384 transfer_queue.pointer1 = addr + 4096;
385 transfer_queue.pointer2 = addr + 8192;
386 transfer_queue.pointer3 = addr + 12288;
387 transfer_queue.pointer4 = addr + 16384;
388
389 if notify {
390 transfer_queue.status |= 1 << 15;
391 }
392
393 return true;
394 }
395
396 return false;
398}
399
400pub fn usb_receive(endpoint: usize, transfer: &mut UsbEndpointTransferDescriptor) {
403 schedule_transfer(endpoint as u32, false, transfer);
404}
405
406pub fn usb_transmit(endpoint: usize, transfer: &mut UsbEndpointTransferDescriptor) {
409 schedule_transfer(endpoint as u32, true, transfer);
410}
411
412fn schedule_transfer(ep: u32, tx: bool, transfer: &mut UsbEndpointTransferDescriptor) {
413 let qh = usb_get_queuehead(ep as usize, tx);
414 let mask = match tx {
415 true => 1 << (ep + 16),
416 false => 1 << ep,
417 };
418
419 loop {
420 if qh.last_transfer > 1 {
422 let last = qh.get_last_transfer();
423
424 last.next = (transfer as *const UsbEndpointTransferDescriptor) as u32;
426
427 if (read_word(ENDPTPRIME) & mask) > 0 {
429 break;
430 }
431
432 let mut status;
433 loop {
434 assign(USBCMD, read_word(USBCMD) | (1 << 14));
436 status = read_word(ENDPTSTAT) & mask;
438 let atdtw = read_word(USBCMD) & (1 << 14);
440 if atdtw > 0 {
443 break;
444 } else {
445 assembly!("nop");
446 }
447 }
448
449 assign(USBCMD, read_word(USBCMD) & !(1 << 14));
451
452 if status > 0 {
454 break;
455 }
456 }
457
458 qh.next = (transfer as *const UsbEndpointTransferDescriptor) as u32;
460 qh.status = 0;
461
462 usb_prime_endpoint(ep, tx);
463 qh.set_first_transfer(transfer);
464 break;
465 }
466
467 qh.set_last_transfer(transfer);
468}
469
470fn usb_prime_endpoint(index: u32, tx: bool) {
471 let mask = match tx {
472 true => 1 << (16 + index),
473 false => 1 << index,
474 };
475
476 assign(ENDPTPRIME, mask);
477
478 loop {
479 let prime = read_word(ENDPTPRIME) & mask;
480 let stat = read_word(ENDPTSTAT) & mask;
481
482 if prime == 0 && stat != 0 {
483 return;
485 } else if prime == 0 && stat == 0 {
486 return;
488 } else {
489 assembly!("nop");
490 }
491 }
492}
493
494fn endpoint0_setup(packet: SetupPacket) {
495 for callback in unsafe { CONFIGURATION_CALLBACKS.into_iter() } {
496 callback(packet);
497 }
498
499 match packet.bm_request_and_type {
500 0x681 | 0x680 => {
501 let descriptors = usb_get_descriptors();
503 match descriptors.get_bytes(packet.w_value, packet.w_index) {
504 Some(bytes) => {
505 let mut byte_length = bytes.size();
506 if byte_length > packet.w_length as usize {
507 byte_length = packet.w_length as usize;
508 }
509
510 endpoint0_transmit(bytes, byte_length, false);
511 return;
512 }
513 None => {}
514 }
515 }
516 0x500 => {
517 endpoint0_receive(0, 0, false);
519 assign(DEVICEADDR, ((packet.w_value as u32) << 25) | (1 << 24));
520 return;
521 }
522 0x900 => {
523 unsafe {
525 CONFIGURATION = packet.w_value;
526 }
527
528 endpoint0_receive(0, 0, false);
529 return;
530 }
531 0x880 => {
532 }
534 0x80 => {
535 }
537 0x82 => {
538 }
540 0x302 => {
541 }
543 0x102 => {
544 }
546 0x2021 => {
547 if packet.w_length != 7 {
549 assign(ENDPTCTRL0, (1 << 16) | 1); return;
552 }
553
554 endpoint0_receive(unsafe { ENDPOINT0_BUFFER.as_ptr() } as u32, 7, true);
555 return;
556 }
557 0x2221 => {
558 endpoint0_receive(0, 0, false);
560 return;
561 }
562 0x2321 => {
563 endpoint0_receive(0, 0, false);
565 return;
566 }
567 _ => {}
568 }
569
570 assign(ENDPTCTRL0, (1 << 16) | 1); }
572
573fn endpoint0_transmit(vec: Vector<u8>, byte_length: usize, notify: bool) {
574 let len = byte_length as u32;
576 let usb_descriptor_buffer_addr = unsafe { USB_DESCRIPTOR_BUFFER.as_ptr() } as u32;
577 arm_dcache_delete(usb_descriptor_buffer_addr, len);
578 let mut i = 0;
579 for byte in vec.into_iter() {
580 unsafe {
581 USB_DESCRIPTOR_BUFFER.bytes[i] = byte;
582 }
583
584 i += 1;
585 }
586
587 if len > 0 {
588 unsafe {
589 ENDPOINT0_TRANSFER_DATA.next = 1;
590 ENDPOINT0_TRANSFER_DATA.status = (len << 16) | (1 << 7);
591
592 let addr = USB_DESCRIPTOR_BUFFER.as_ptr() as u32;
593 let endpoint0_transfer_data_addr =
594 &ENDPOINT0_TRANSFER_DATA as *const UsbEndpointTransferDescriptor as u32;
595
596 ENDPOINT0_TRANSFER_DATA.pointer0 = addr;
597 ENDPOINT0_TRANSFER_DATA.pointer1 = addr + 4096;
598 ENDPOINT0_TRANSFER_DATA.pointer2 = addr + 8192;
599 ENDPOINT0_TRANSFER_DATA.pointer3 = addr + 12288;
600 ENDPOINT0_TRANSFER_DATA.pointer4 = addr + 16384;
601
602 ENDPOINT_HEADERS[1].next = endpoint0_transfer_data_addr;
603 ENDPOINT_HEADERS[1].status = 0;
604 }
605
606 usb_prime_endpoint(0, true);
607 }
608
609 unsafe {
610 ENDPOINT0_TRANSFER_ACK.next = 1;
611 match notify {
612 true => {
613 ENDPOINT0_TRANSFER_ACK.status = (1 << 7) | (1 << 15);
614 }
615 false => {
616 ENDPOINT0_TRANSFER_ACK.status = 1 << 7;
617 }
618 }
619 ENDPOINT0_TRANSFER_ACK.pointer0 = 0;
620 ENDPOINT_HEADERS[0].next =
621 (&ENDPOINT0_TRANSFER_ACK as *const UsbEndpointTransferDescriptor) as u32;
622 ENDPOINT_HEADERS[0].status = 0;
623 }
624
625 usb_prime_endpoint(0, false);
626}
627
628fn endpoint0_receive(addr: u32, len: u32, notify: bool) {
629 if len > 0 {
630 unsafe {
631 ENDPOINT0_TRANSFER_DATA.next = 1;
632 ENDPOINT0_TRANSFER_DATA.status = (len << 16) | (1 << 7);
633 ENDPOINT0_TRANSFER_DATA.pointer0 = addr;
634 ENDPOINT0_TRANSFER_DATA.pointer1 = addr + 4096;
635 ENDPOINT0_TRANSFER_DATA.pointer2 = addr + 8192;
636 ENDPOINT0_TRANSFER_DATA.pointer3 = addr + 12288;
637 ENDPOINT0_TRANSFER_DATA.pointer4 = addr + 16384;
638 let endpoint0_transfer_data_addr =
639 (&ENDPOINT0_TRANSFER_DATA as *const UsbEndpointTransferDescriptor) as u32;
640
641 ENDPOINT_HEADERS[0].next = endpoint0_transfer_data_addr;
642 ENDPOINT_HEADERS[0].status = 0;
643 }
644
645 usb_prime_endpoint(0, false);
646 }
647
648 unsafe {
649 ENDPOINT0_TRANSFER_ACK.next = 1;
650 match notify {
651 true => {
652 ENDPOINT0_TRANSFER_ACK.status = (1 << 7) | (1 << 15);
653 }
654 false => {
655 ENDPOINT0_TRANSFER_ACK.status = 1 << 7;
656 }
657 }
658 ENDPOINT0_TRANSFER_ACK.pointer0 = 0;
659 ENDPOINT_HEADERS[1].next =
660 (&ENDPOINT0_TRANSFER_ACK as *const UsbEndpointTransferDescriptor) as u32;
661 ENDPOINT_HEADERS[1].status = 0;
662 }
663
664 if notify {
665 unsafe {
666 ENDPOINT0_NOTIFY_MASK = 1 << 16;
667 }
668 }
669
670 assign(ENDPTCOMPLETE, 1 | (1 << 16));
671 usb_prime_endpoint(0, true);
672}
673
674fn handle_usb_irq() {
675 irq_disable(Irq::Usb1);
676
677 let irq_status = read_word(USBSTS);
678 assembly!("nop"); usb_irq_clear(irq_status);
680
681 if (irq_status & HCH) > 0 {}
682
683 if (irq_status & PCI) > 0 {
684 let port_status = read_word(PORTSC1);
686 if port_status & (0x1 << 9) > 0 {
687 unsafe {
688 HIGHSPEED = true;
689 }
690 } else {
691 unsafe {
692 HIGHSPEED = false;
693 }
694 }
695
696 if (port_status & 1) > 0 {
697 }
699 }
700
701 if (irq_status & SEI) > 0 {
702 }
704
705 if (irq_status & USBERRINT) > 0 {
706 }
708
709 if (irq_status & SLI) > 0 {
710 }
712
713 if (irq_status & URI) > 0 {
714 assign(ENDPTSTAT, read_word(ENDPTSTAT));
716 assign(ENDPTCOMPLETE, read_word(ENDPTCOMPLETE));
717
718 waitfor(ENDPTPRIME);
720
721 assign(ENDPTFLUSH, 0xFFFF_FFFF);
723
724 let port_status = read_word(PORTSC1);
726 if (port_status & (1 << 8)) == 0 {
727 } else {
729 }
731 }
732
733 if (irq_status & USBINT) > 0 {
734 let mut setup_status = read_word(ENDPTSETUPSTAT);
735 while setup_status > 0 {
736 assign(ENDPTSETUPSTAT, setup_status);
738
739 let mut setup_packet;
741
742 loop {
743 assign(USBCMD, read_word(USBCMD) | (1 << 13));
745
746 unsafe {
748 setup_packet = SetupPacket::from_dwords(
749 ENDPOINT_HEADERS[0].setup0,
750 ENDPOINT_HEADERS[0].setup1,
751 );
752 }
753
754 if (read_word(USBCMD) & (1 << 13)) > 0 {
756 break;
757 }
758 }
759
760 assign(USBCMD, read_word(USBCMD) & !(1 << 13));
762
763 assign(ENDPTFLUSH, (1 << 16) | 1);
765
766 waitfor(ENDPTFLUSH);
768
769 if (read_word(ENDPTSTAT) & ((1 << 16) | 1)) > 0 {
770 }
773
774 endpoint0_setup(setup_packet);
776
777 setup_status = read_word(ENDPTSETUPSTAT);
779 }
780
781 let complete_status = read_word(ENDPTCOMPLETE);
782
783 unsafe {
784 if (complete_status & ENDPOINT0_NOTIFY_MASK) > 0 {
785 ENDPOINT0_NOTIFY_MASK = 0;
786 endpoint0_complete();
787 }
788 }
789
790 if complete_status > 0 {
791 assign(ENDPTCOMPLETE, complete_status);
792
793 for idx in 1..MAX_ENDPOINTS {
795 let mask = 1 << (16 + idx);
796 if (complete_status & mask) > 0 {
797 run_callbacks(usb_get_queuehead(idx, true));
798 }
799 }
800
801 for idx in 1..MAX_ENDPOINTS {
803 let mask = 1 << idx;
804 if (complete_status & mask) > 0 {
805 run_callbacks(usb_get_queuehead(idx, false));
806 }
807 }
808 }
809 }
810
811 unsafe {
812 for other_irq_handler in IRQ_CALLBACKS.into_iter() {
813 other_irq_handler(irq_status);
814 }
815 }
816
817 irq_enable(Irq::Usb1);
818}
819
820fn endpoint0_complete() {
821 let buffer = unsafe { ENDPOINT0_BUFFER.bytes };
826 let mut _bitrate = 0;
827
828 for i in 0..4 {
829 _bitrate |= (buffer[i] as u64) << (i * 8);
830 }
831}
832
833fn noop(_packet: &UsbEndpointTransferDescriptor) {}