From bb7a0ef8015ebb1901680ef698319c3a2c35bd60 Mon Sep 17 00:00:00 2001 From: Guillaume Endignoux <guillaumee@google.com> Date: Wed, 11 Mar 2020 17:04:05 +0100 Subject: [PATCH] Sync patches with upstream Tock. --- patches/tock/01-persistent-storage.patch | 4 +- patches/tock/02-usb.patch | 181 +----- patches/tock/04-increase-rom-nordic.patch | 24 - patches/tock/05-usb-cancel.patch | 747 ---------------------- third_party/tock | 2 +- 5 files changed, 26 insertions(+), 932 deletions(-) delete mode 100644 patches/tock/04-increase-rom-nordic.patch delete mode 100644 patches/tock/05-usb-cancel.patch diff --git a/patches/tock/01-persistent-storage.patch b/patches/tock/01-persistent-storage.patch index ecfb0b0..57880c6 100644 --- a/patches/tock/01-persistent-storage.patch +++ b/patches/tock/01-persistent-storage.patch @@ -286,10 +286,10 @@ index 5abd2d84..5a726fdb 100644 + } +} diff --git a/kernel/src/callback.rs b/kernel/src/callback.rs -index ece4a443..9a1afc84 100644 +index c812e0bf..bd1613b3 100644 --- a/kernel/src/callback.rs +++ b/kernel/src/callback.rs -@@ -52,6 +52,31 @@ impl AppId { +@@ -130,6 +130,31 @@ impl AppId { (start, end) }) } diff --git a/patches/tock/02-usb.patch b/patches/tock/02-usb.patch index a75a5b3..55f807b 100644 --- a/patches/tock/02-usb.patch +++ b/patches/tock/02-usb.patch @@ -124,11 +124,11 @@ index 105f7120..535e5cd8 100644 ipc: kernel::ipc::IPC::new(board_kernel, &memory_allocation_capability), nvmc: nvmc, diff --git a/capsules/src/driver.rs b/capsules/src/driver.rs -index 9305e6a7..40466f44 100644 +index bfc06429..5858d352 100644 --- a/capsules/src/driver.rs +++ b/capsules/src/driver.rs -@@ -24,6 +24,7 @@ pub enum NUM { - Spi = 0x20001, +@@ -25,6 +25,7 @@ pub enum NUM { + I2cMaster = 0x20003, UsbUser = 0x20005, I2cMasterSlave = 0x20006, + UsbCtap = 0x20009, @@ -509,10 +509,10 @@ index 00000000..da3d16d8 +} diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs new file mode 100644 -index 00000000..fdf7263a +index 00000000..4b1916cf --- /dev/null +++ b/capsules/src/usb/usbc_ctap_hid.rs -@@ -0,0 +1,352 @@ +@@ -0,0 +1,359 @@ +//! A USB HID client of the USB hardware interface + +use super::descriptors::Buffer64; @@ -603,8 +603,9 @@ index 00000000..fdf7263a +pub struct ClientCtapHID<'a, 'b, C: 'a> { + client_ctrl: ClientCtrl<'a, 'static, C>, + -+ // A 64-byte buffer for the endpoint -+ buffer: Buffer64, ++ // 64-byte buffers for the endpoint ++ in_buffer: Buffer64, ++ out_buffer: Buffer64, + + // Interaction with the client + client: OptionalCell<&'b dyn CtapUsbClient>, @@ -648,7 +649,8 @@ index 00000000..fdf7263a + LANGUAGES, + STRINGS, + ), -+ buffer: Default::default(), ++ in_buffer: Default::default(), ++ out_buffer: Default::default(), + client: OptionalCell::empty(), + tx_packet: OptionalCell::empty(), + pending_in: Cell::new(false), @@ -702,7 +704,7 @@ index 00000000..fdf7263a + fn send_packet_to_client(&'a self) -> bool { + // Copy the packet into a buffer to send to the client. + let mut buf: [u8; 64] = [0; 64]; -+ for (i, x) in self.buffer.buf.iter().enumerate() { ++ for (i, x) in self.out_buffer.buf.iter().enumerate() { + buf[i] = x.get(); + } + @@ -735,11 +737,7 @@ index 00000000..fdf7263a + + fn cancel_in_transaction(&'a self) -> bool { + self.tx_packet.take(); -+ let result = self.pending_in.take(); -+ if result { -+ self.controller().endpoint_cancel_in(1); -+ } -+ result ++ self.pending_in.take() + } + + fn cancel_out_transaction(&'a self) -> bool { @@ -758,7 +756,10 @@ index 00000000..fdf7263a + self.client_ctrl.enable(); + + // Set up the interrupt in-out endpoint -+ self.controller().endpoint_set_buffer(1, &self.buffer.buf); ++ self.controller() ++ .endpoint_set_in_buffer(1, &self.in_buffer.buf); ++ self.controller() ++ .endpoint_set_out_buffer(1, &self.out_buffer.buf); + self.controller() + .endpoint_in_out_enable(TransferType::Interrupt, 1); + } @@ -808,7 +809,7 @@ index 00000000..fdf7263a + } + + if let Some(packet) = self.tx_packet.take() { -+ let buf = &self.buffer.buf; ++ let buf = &self.in_buffer.buf; + for i in 0..64 { + buf[i].set(packet[i]); + } @@ -861,149 +862,13 @@ index 00000000..fdf7263a + panic!("Unexpected tx_packet while a packet was being transmitted."); + } + self.pending_in.set(false); ++ ++ // Clear any pending packet on the receiving side. ++ // It's up to the client to handle the transmitted packet and decide if they want to ++ // receive another packet. ++ self.cancel_out_transaction(); ++ + // Notify the client + self.client.map(|client| client.packet_transmitted()); + } +} -diff --git a/chips/nrf52/src/usbd.rs b/chips/nrf52/src/usbd.rs -index 8ddb5895..8c1992cc 100644 ---- a/chips/nrf52/src/usbd.rs -+++ b/chips/nrf52/src/usbd.rs -@@ -1499,7 +1499,23 @@ impl<'a> Usbd<'a> { - if epdatastatus.is_set(status_epin(endpoint)) { - let (transfer_type, direction, state) = - self.descriptors[endpoint].state.get().bulk_state(); -- assert_eq!(state, BulkState::InData); -+ match state { -+ BulkState::InData => { -+ // Totally expected state. Nothing to do. -+ } -+ BulkState::Init => { -+ internal_warn!( -+ "Received a stale epdata IN in an unexpected state: {:?}", -+ state -+ ); -+ } -+ BulkState::OutDelay -+ | BulkState::OutData -+ | BulkState::OutDma -+ | BulkState::InDma => { -+ internal_err!("Unexpected state: {:?}", state); -+ } -+ } - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, - direction, -@@ -1677,7 +1693,7 @@ impl<'a> Usbd<'a> { - } - - fn transmit_in(&self, endpoint: usize) { -- debug_info!("transmit_in({})", endpoint); -+ debug_events!("transmit_in({})", endpoint); - let regs = &*self.registers; - - self.client.map(|client| { -@@ -1717,7 +1733,7 @@ impl<'a> Usbd<'a> { - } - - fn transmit_out(&self, endpoint: usize) { -- debug_info!("transmit_out({})", endpoint); -+ debug_events!("transmit_out({})", endpoint); - - let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); - // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event. -@@ -1882,11 +1898,13 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - } - - fn endpoint_resume_in(&self, endpoint: usize) { -+ debug_events!("endpoint_resume_in({})", endpoint); -+ - let (_, direction, _) = self.descriptors[endpoint].state.get().bulk_state(); - assert!(direction.has_in()); - - if self.dma_pending.get() { -- debug_info!("requesting resume_in[{}]", endpoint); -+ debug_events!("requesting resume_in[{}]", endpoint); - // A DMA is already pending. Schedule the resume for later. - self.descriptors[endpoint].request_transmit_in.set(true); - } else { -@@ -1896,6 +1914,8 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - } - - fn endpoint_resume_out(&self, endpoint: usize) { -+ debug_events!("endpoint_resume_out({})", endpoint); -+ - let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); - assert!(direction.has_out()); - -@@ -1914,7 +1934,7 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - // happened in the meantime. This pending transaction will now - // continue in transmit_out(). - if self.dma_pending.get() { -- debug_info!("requesting resume_out[{}]", endpoint); -+ debug_events!("requesting resume_out[{}]", endpoint); - // A DMA is already pending. Schedule the resume for later. - self.descriptors[endpoint].request_transmit_out.set(true); - } else { -@@ -1927,6 +1947,20 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - } - } - } -+ -+ fn endpoint_cancel_in(&self, endpoint: usize) { -+ debug_events!("endpoint_cancel_in({})", endpoint); -+ -+ let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); -+ assert!(direction.has_in()); -+ assert_eq!(state, BulkState::InData); -+ -+ self.descriptors[endpoint].state.set(EndpointState::Bulk( -+ transfer_type, -+ direction, -+ BulkState::Init, -+ )); -+ } - } - - fn status_epin(ep: usize) -> Field<u32, EndpointStatus::Register> { -diff --git a/chips/nrf52840/src/lib.rs b/chips/nrf52840/src/lib.rs -index 9d58a705..942d0288 100644 ---- a/chips/nrf52840/src/lib.rs -+++ b/chips/nrf52840/src/lib.rs -@@ -2,7 +2,7 @@ - - pub use nrf52::{ - acomp, adc, aes, ble_radio, clock, constants, crt1, ficr, i2c, ieee802154_radio, init, nvmc, -- pinmux, ppi, pwm, rtc, spi, temperature, timer, trng, uart, uicr, -+ pinmux, ppi, pwm, rtc, spi, temperature, timer, trng, uart, uicr, usbd, - }; - pub mod chip; - pub mod gpio; -diff --git a/chips/sam4l/src/usbc/mod.rs b/chips/sam4l/src/usbc/mod.rs -index 35f3bb7c..28a0b9f9 100644 ---- a/chips/sam4l/src/usbc/mod.rs -+++ b/chips/sam4l/src/usbc/mod.rs -@@ -1547,6 +1547,10 @@ impl hil::usb::UsbController<'a> for Usbc<'a> { - requests.resume_out = true; - self.requests[endpoint].set(requests); - } -+ -+ fn endpoint_cancel_in(&self, _endpoint: usize) { -+ unimplemented!() -+ } - } - - /// Static state to manage the USBC -diff --git a/kernel/src/hil/usb.rs b/kernel/src/hil/usb.rs -index 846f5e93..64610fa5 100644 ---- a/kernel/src/hil/usb.rs -+++ b/kernel/src/hil/usb.rs -@@ -27,6 +27,8 @@ pub trait UsbController<'a> { - fn endpoint_resume_in(&self, endpoint: usize); - - fn endpoint_resume_out(&self, endpoint: usize); -+ -+ fn endpoint_cancel_in(&self, endpoint: usize); - } - - #[derive(Clone, Copy, Debug)] diff --git a/patches/tock/04-increase-rom-nordic.patch b/patches/tock/04-increase-rom-nordic.patch deleted file mode 100644 index 83948f8..0000000 --- a/patches/tock/04-increase-rom-nordic.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/boards/nordic/nrf52840_dongle/layout.ld b/boards/nordic/nrf52840_dongle/layout.ld -index 657b0d26..f86b2321 100644 ---- a/boards/nordic/nrf52840_dongle/layout.ld -+++ b/boards/nordic/nrf52840_dongle/layout.ld -@@ -1,6 +1,6 @@ - MEMORY - { -- rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K -+ rom (rx) : ORIGIN = 0x00000000, LENGTH = 192K - prog (rx) : ORIGIN = 0x00030000, LENGTH = 832K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K - } -diff --git a/boards/nordic/nrf52840dk/layout.ld b/boards/nordic/nrf52840dk/layout.ld -index 657b0d26..f86b2321 100644 ---- a/boards/nordic/nrf52840dk/layout.ld -+++ b/boards/nordic/nrf52840dk/layout.ld -@@ -1,6 +1,6 @@ - MEMORY - { -- rom (rx) : ORIGIN = 0x00000000, LENGTH = 128K -+ rom (rx) : ORIGIN = 0x00000000, LENGTH = 192K - prog (rx) : ORIGIN = 0x00030000, LENGTH = 832K - ram (rwx) : ORIGIN = 0x20000000, LENGTH = 256K - } diff --git a/patches/tock/05-usb-cancel.patch b/patches/tock/05-usb-cancel.patch deleted file mode 100644 index f853971..0000000 --- a/patches/tock/05-usb-cancel.patch +++ /dev/null @@ -1,747 +0,0 @@ -diff --git a/capsules/src/usb/usbc_client.rs b/capsules/src/usb/usbc_client.rs -index b0678c23..9fb43781 100644 ---- a/capsules/src/usb/usbc_client.rs -+++ b/capsules/src/usb/usbc_client.rs -@@ -115,11 +115,11 @@ impl<'a, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for Client<'a, C> - self.client_ctrl.enable(); - - // Set up a bulk-in endpoint for debugging -- self.controller().endpoint_set_buffer(1, self.buffer(1)); -+ self.controller().endpoint_set_in_buffer(1, self.buffer(1)); - self.controller().endpoint_in_enable(TransferType::Bulk, 1); - - // Set up a bulk-out endpoint for debugging -- self.controller().endpoint_set_buffer(2, self.buffer(2)); -+ self.controller().endpoint_set_out_buffer(2, self.buffer(2)); - self.controller().endpoint_out_enable(TransferType::Bulk, 2); - } - -diff --git a/capsules/src/usb/usbc_client_ctrl.rs b/capsules/src/usb/usbc_client_ctrl.rs -index 2aaca0cc..5f9b253c 100644 ---- a/capsules/src/usb/usbc_client_ctrl.rs -+++ b/capsules/src/usb/usbc_client_ctrl.rs -@@ -201,7 +201,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtrl<'a, 'b, C> { - pub fn enable(&'a self) { - // Set up the default control endpoint - self.controller -- .endpoint_set_buffer(0, &self.ctrl_buffer.buf); -+ .endpoint_set_ctrl_buffer(&self.ctrl_buffer.buf); - self.controller - .enable_as_device(hil::usb::DeviceSpeed::Full); // must be Full for Bulk transfers - self.controller -diff --git a/capsules/src/usb/usbc_ctap_hid.rs b/capsules/src/usb/usbc_ctap_hid.rs -index fdf7263a..4b1916cf 100644 ---- a/capsules/src/usb/usbc_ctap_hid.rs -+++ b/capsules/src/usb/usbc_ctap_hid.rs -@@ -88,8 +88,9 @@ static HID: HIDDescriptor<'static> = HIDDescriptor { - pub struct ClientCtapHID<'a, 'b, C: 'a> { - client_ctrl: ClientCtrl<'a, 'static, C>, - -- // A 64-byte buffer for the endpoint -- buffer: Buffer64, -+ // 64-byte buffers for the endpoint -+ in_buffer: Buffer64, -+ out_buffer: Buffer64, - - // Interaction with the client - client: OptionalCell<&'b dyn CtapUsbClient>, -@@ -133,7 +134,8 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { - LANGUAGES, - STRINGS, - ), -- buffer: Default::default(), -+ in_buffer: Default::default(), -+ out_buffer: Default::default(), - client: OptionalCell::empty(), - tx_packet: OptionalCell::empty(), - pending_in: Cell::new(false), -@@ -187,7 +189,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { - fn send_packet_to_client(&'a self) -> bool { - // Copy the packet into a buffer to send to the client. - let mut buf: [u8; 64] = [0; 64]; -- for (i, x) in self.buffer.buf.iter().enumerate() { -+ for (i, x) in self.out_buffer.buf.iter().enumerate() { - buf[i] = x.get(); - } - -@@ -220,11 +222,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> ClientCtapHID<'a, 'b, C> { - - fn cancel_in_transaction(&'a self) -> bool { - self.tx_packet.take(); -- let result = self.pending_in.take(); -- if result { -- self.controller().endpoint_cancel_in(1); -- } -- result -+ self.pending_in.take() - } - - fn cancel_out_transaction(&'a self) -> bool { -@@ -243,7 +241,10 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap - self.client_ctrl.enable(); - - // Set up the interrupt in-out endpoint -- self.controller().endpoint_set_buffer(1, &self.buffer.buf); -+ self.controller() -+ .endpoint_set_in_buffer(1, &self.in_buffer.buf); -+ self.controller() -+ .endpoint_set_out_buffer(1, &self.out_buffer.buf); - self.controller() - .endpoint_in_out_enable(TransferType::Interrupt, 1); - } -@@ -293,7 +294,7 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap - } - - if let Some(packet) = self.tx_packet.take() { -- let buf = &self.buffer.buf; -+ let buf = &self.in_buffer.buf; - for i in 0..64 { - buf[i].set(packet[i]); - } -@@ -346,6 +347,12 @@ impl<'a, 'b, C: hil::usb::UsbController<'a>> hil::usb::Client<'a> for ClientCtap - panic!("Unexpected tx_packet while a packet was being transmitted."); - } - self.pending_in.set(false); -+ -+ // Clear any pending packet on the receiving side. -+ // It's up to the client to handle the transmitted packet and decide if they want to -+ // receive another packet. -+ self.cancel_out_transaction(); -+ - // Notify the client - self.client.map(|client| client.packet_transmitted()); - } -diff --git a/chips/nrf52/src/usbd.rs b/chips/nrf52/src/usbd.rs -index 8c1992cc..972871d0 100644 ---- a/chips/nrf52/src/usbd.rs -+++ b/chips/nrf52/src/usbd.rs -@@ -623,7 +623,7 @@ pub enum UsbState { - pub enum EndpointState { - Disabled, - Ctrl(CtrlState), -- Bulk(TransferType, EndpointDirection, BulkState), -+ Bulk(TransferType, Option<BulkInState>, Option<BulkOutState>), - } - - impl EndpointState { -@@ -634,10 +634,10 @@ impl EndpointState { - } - } - -- fn bulk_state(self) -> (TransferType, EndpointDirection, BulkState) { -+ fn bulk_state(self) -> (TransferType, Option<BulkInState>, Option<BulkOutState>) { - match self { -- EndpointState::Bulk(transfer_type, direction, state) => { -- (transfer_type, direction, state) -+ EndpointState::Bulk(transfer_type, in_state, out_state) => { -+ (transfer_type, in_state, out_state) - } - _ => panic!("Expected EndpointState::Bulk"), - } -@@ -651,31 +651,18 @@ pub enum CtrlState { - ReadStatus, - } - --#[derive(Copy, Clone, Debug)] --pub enum EndpointDirection { -- In, -- Out, -- InOut, --} -- --impl EndpointDirection { -- fn has_in(&self) -> bool { -- match self { -- EndpointDirection::In | EndpointDirection::InOut => true, -- EndpointDirection::Out => false, -- } -- } -- -- fn has_out(&self) -> bool { -- match self { -- EndpointDirection::Out | EndpointDirection::InOut => true, -- EndpointDirection::In => false, -- } -- } -+#[derive(Copy, Clone, PartialEq, Debug)] -+pub enum BulkInState { -+ // The endpoint is ready to perform transactions. -+ Init, -+ // There is a pending DMA transfer on this IN endpoint. -+ InDma, -+ // There is a pending IN packet transfer on this endpoint. -+ InData, - } - - #[derive(Copy, Clone, PartialEq, Debug)] --pub enum BulkState { -+pub enum BulkOutState { - // The endpoint is ready to perform transactions. - Init, - // There is a pending OUT packet in this endpoint's buffer, to be read by -@@ -685,14 +672,11 @@ pub enum BulkState { - OutData, - // There is a pending DMA transfer on this OUT endpoint. - OutDma, -- // There is a pending DMA transfer on this IN endpoint. -- InDma, -- // There is a pending IN packet transfer on this endpoint. -- InData, - } - - pub struct Endpoint<'a> { -- slice: OptionalCell<&'a [VolatileCell<u8>]>, -+ slice_in: OptionalCell<&'a [VolatileCell<u8>]>, -+ slice_out: OptionalCell<&'a [VolatileCell<u8>]>, - state: Cell<EndpointState>, - // The USB controller can only process one DMA transfer at a time (over all endpoints). The - // request_transmit_* bits allow to queue transfers until the DMA becomes available again. -@@ -705,7 +689,8 @@ pub struct Endpoint<'a> { - impl Endpoint<'_> { - const fn new() -> Self { - Endpoint { -- slice: OptionalCell::empty(), -+ slice_in: OptionalCell::empty(), -+ slice_out: OptionalCell::empty(), - state: Cell::new(EndpointState::Disabled), - request_transmit_in: Cell::new(false), - request_transmit_out: Cell::new(false), -@@ -914,18 +899,12 @@ impl<'a> Usbd<'a> { - chip_revision.get() - ); - } -- Some(ChipRevision::REV::Value::REVC) => { -+ Some(ChipRevision::REV::Value::REVC) | Some(ChipRevision::REV::Value::REVD) => { - debug_info!( - "Your chip is NRF52840 revision {}. The USB stack was tested on your chip :)", - chip_revision.get() - ); - } -- Some(ChipRevision::REV::Value::REVD) => { -- internal_warn!( -- "Your chip is NRF52840 revision {}. Although this USB implementation should be compatible, your chip hasn't been tested.", -- chip_revision.get() -- ); -- } - None => { - internal_warn!( - "Your chip is NRF52840 revision {} (unknown revision). Although this USB implementation should be compatible, your chip hasn't been tested.", -@@ -1026,7 +1005,7 @@ impl<'a> Usbd<'a> { - }); - self.descriptors[endpoint].state.set(match endpoint { - 0 => EndpointState::Ctrl(CtrlState::Init), -- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::In, BulkState::Init), -+ 1..=7 => EndpointState::Bulk(transfer_type, Some(BulkInState::Init), None), - 8 => unimplemented!("isochronous endpoint"), - _ => unreachable!("unexisting endpoint"), - }); -@@ -1064,7 +1043,7 @@ impl<'a> Usbd<'a> { - }); - self.descriptors[endpoint].state.set(match endpoint { - 0 => EndpointState::Ctrl(CtrlState::Init), -- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::Out, BulkState::Init), -+ 1..=7 => EndpointState::Bulk(transfer_type, None, Some(BulkOutState::Init)), - 8 => unimplemented!("isochronous endpoint"), - _ => unreachable!("unexisting endpoint"), - }); -@@ -1114,7 +1093,11 @@ impl<'a> Usbd<'a> { - }); - self.descriptors[endpoint].state.set(match endpoint { - 0 => EndpointState::Ctrl(CtrlState::Init), -- 1..=7 => EndpointState::Bulk(transfer_type, EndpointDirection::InOut, BulkState::Init), -+ 1..=7 => EndpointState::Bulk( -+ transfer_type, -+ Some(BulkInState::Init), -+ Some(BulkOutState::Init), -+ ), - 8 => unimplemented!("isochronous endpoint"), - _ => unreachable!("unexisting endpoint"), - }); -@@ -1304,13 +1287,13 @@ impl<'a> Usbd<'a> { - match desc.state.get() { - EndpointState::Disabled => {} - EndpointState::Ctrl(_) => desc.state.set(EndpointState::Ctrl(CtrlState::Init)), -- EndpointState::Bulk(transfer_type, direction, _) => { -+ EndpointState::Bulk(transfer_type, in_state, out_state) => { - desc.state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::Init, -+ in_state.map(|_| BulkInState::Init), -+ out_state.map(|_| BulkOutState::Init), - )); -- if direction.has_out() { -+ if out_state.is_some() { - // Accept incoming OUT packets. - regs.size_epout[ep].set(0); - } -@@ -1347,13 +1330,13 @@ impl<'a> Usbd<'a> { - match endpoint { - 0 => {} - 1..=7 => { -- let (transfer_type, direction, state) = -+ let (transfer_type, in_state, out_state) = - self.descriptors[endpoint].state.get().bulk_state(); -- assert_eq!(state, BulkState::InDma); -+ assert_eq!(in_state, Some(BulkInState::InDma)); - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::InData, -+ Some(BulkInState::InData), -+ out_state, - )); - } - 8 => unimplemented!("isochronous endpoint"), -@@ -1405,25 +1388,25 @@ impl<'a> Usbd<'a> { - 1..=7 => { - // Notify the client about the new packet. - let packet_bytes = regs.size_epout[endpoint].get(); -- let (transfer_type, direction, state) = -+ let (transfer_type, in_state, out_state) = - self.descriptors[endpoint].state.get().bulk_state(); -- assert_eq!(state, BulkState::OutDma); -+ assert_eq!(out_state, Some(BulkOutState::OutDma)); - -- self.debug_packet("out", packet_bytes as usize, endpoint); -+ self.debug_out_packet(packet_bytes as usize, endpoint); - - self.client.map(|client| { - let result = client.packet_out(transfer_type, endpoint, packet_bytes); - debug_packets!("packet_out => {:?}", result); -- let newstate = match result { -+ let new_out_state = match result { - hil::usb::OutResult::Ok => { - // Indicate that the endpoint is ready to receive data again. - regs.size_epout[endpoint].set(0); -- BulkState::Init -+ BulkOutState::Init - } - - hil::usb::OutResult::Delay => { - // We can't send the packet now. Wait for a resume_out call from the client. -- BulkState::OutDelay -+ BulkOutState::OutDelay - } - - hil::usb::OutResult::Error => { -@@ -1432,13 +1415,13 @@ impl<'a> Usbd<'a> { - + EndpointStall::IO::Out - + EndpointStall::STALL::Stall, - ); -- BulkState::Init -+ BulkOutState::Init - } - }; - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- newstate, -+ in_state, -+ Some(new_out_state), - )); - }); - } -@@ -1497,29 +1480,27 @@ impl<'a> Usbd<'a> { - // Endpoint 8 (isochronous) doesn't receive any EPDATA event. - for endpoint in 1..NUM_ENDPOINTS { - if epdatastatus.is_set(status_epin(endpoint)) { -- let (transfer_type, direction, state) = -+ let (transfer_type, in_state, out_state) = - self.descriptors[endpoint].state.get().bulk_state(); -- match state { -- BulkState::InData => { -+ assert!(in_state.is_some()); -+ match in_state.unwrap() { -+ BulkInState::InData => { - // Totally expected state. Nothing to do. - } -- BulkState::Init => { -+ BulkInState::Init => { - internal_warn!( - "Received a stale epdata IN in an unexpected state: {:?}", -- state -+ in_state - ); - } -- BulkState::OutDelay -- | BulkState::OutData -- | BulkState::OutDma -- | BulkState::InDma => { -- internal_err!("Unexpected state: {:?}", state); -+ BulkInState::InDma => { -+ internal_err!("Unexpected state: {:?}", in_state); - } - } - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::Init, -+ Some(BulkInState::Init), -+ out_state, - )); - self.client - .map(|client| client.packet_transmitted(endpoint)); -@@ -1530,28 +1511,26 @@ impl<'a> Usbd<'a> { - // Endpoint 8 (isochronous) doesn't receive any EPDATA event. - for ep in 1..NUM_ENDPOINTS { - if epdatastatus.is_set(status_epout(ep)) { -- let (transfer_type, direction, state) = -+ let (transfer_type, in_state, out_state) = - self.descriptors[ep].state.get().bulk_state(); -- match state { -- BulkState::Init => { -+ assert!(out_state.is_some()); -+ match out_state.unwrap() { -+ BulkOutState::Init => { - // The endpoint is ready to receive data. Request a transmit_out. - self.descriptors[ep].request_transmit_out.set(true); - } -- BulkState::OutDelay => { -+ BulkOutState::OutDelay => { - // The endpoint will be resumed later by the client application with transmit_out(). - } -- BulkState::OutData -- | BulkState::OutDma -- | BulkState::InDma -- | BulkState::InData => { -- internal_err!("Unexpected state: {:?}", state); -+ BulkOutState::OutData | BulkOutState::OutDma => { -+ internal_err!("Unexpected state: {:?}", out_state); - } - } - // Indicate that the endpoint now has data available. - self.descriptors[ep].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::OutData, -+ in_state, -+ Some(BulkOutState::OutData), - )); - } - } -@@ -1564,8 +1543,8 @@ impl<'a> Usbd<'a> { - let state = self.descriptors[endpoint].state.get().ctrl_state(); - match state { - CtrlState::Init => { -- let ep_buf = &self.descriptors[endpoint].slice; -- let ep_buf = ep_buf.expect("No slice set for this descriptor"); -+ let ep_buf = &self.descriptors[endpoint].slice_out; -+ let ep_buf = ep_buf.expect("No OUT slice set for this descriptor"); - if ep_buf.len() < 8 { - panic!("EP0 DMA buffer length < 8"); - } -@@ -1697,21 +1676,21 @@ impl<'a> Usbd<'a> { - let regs = &*self.registers; - - self.client.map(|client| { -- let (transfer_type, direction, state) = -+ let (transfer_type, in_state, out_state) = - self.descriptors[endpoint].state.get().bulk_state(); -- assert_eq!(state, BulkState::Init); -+ assert_eq!(in_state, Some(BulkInState::Init)); - - let result = client.packet_in(transfer_type, endpoint); - debug_packets!("packet_in => {:?}", result); -- let newstate = match result { -+ let new_in_state = match result { - hil::usb::InResult::Packet(size) => { - self.start_dma_in(endpoint, size); -- BulkState::InDma -+ BulkInState::InDma - } - - hil::usb::InResult::Delay => { - // No packet to send now. Wait for a resume call from the client. -- BulkState::Init -+ BulkInState::Init - } - - hil::usb::InResult::Error => { -@@ -1720,14 +1699,14 @@ impl<'a> Usbd<'a> { - + EndpointStall::IO::In - + EndpointStall::STALL::Stall, - ); -- BulkState::Init -+ BulkInState::Init - } - }; - - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- newstate, -+ Some(new_in_state), -+ out_state, - )); - }); - } -@@ -1735,15 +1714,16 @@ impl<'a> Usbd<'a> { - fn transmit_out(&self, endpoint: usize) { - debug_events!("transmit_out({})", endpoint); - -- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); -+ let (transfer_type, in_state, out_state) = -+ self.descriptors[endpoint].state.get().bulk_state(); - // Starting the DMA can only happen in the OutData state, i.e. after an EPDATA event. -- assert_eq!(state, BulkState::OutData); -+ assert_eq!(out_state, Some(BulkOutState::OutData)); - self.start_dma_out(endpoint); - - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::OutDma, -+ in_state, -+ Some(BulkOutState::OutDma), - )); - } - -@@ -1751,9 +1731,9 @@ impl<'a> Usbd<'a> { - let regs = &*self.registers; - - let slice = self.descriptors[endpoint] -- .slice -- .expect("No slice set for this descriptor"); -- self.debug_packet("in", size, endpoint); -+ .slice_in -+ .expect("No IN slice set for this descriptor"); -+ self.debug_in_packet(size, endpoint); - - // Start DMA transfer - self.set_pending_dma(); -@@ -1766,8 +1746,8 @@ impl<'a> Usbd<'a> { - let regs = &*self.registers; - - let slice = self.descriptors[endpoint] -- .slice -- .expect("No slice set for this descriptor"); -+ .slice_out -+ .expect("No OUT slice set for this descriptor"); - - // Start DMA transfer - self.set_pending_dma(); -@@ -1777,10 +1757,27 @@ impl<'a> Usbd<'a> { - } - - // Debug-only function -- fn debug_packet(&self, _title: &str, size: usize, endpoint: usize) { -+ fn debug_in_packet(&self, size: usize, endpoint: usize) { -+ let slice = self.descriptors[endpoint] -+ .slice_in -+ .expect("No IN slice set for this descriptor"); -+ if size > slice.len() { -+ panic!("Packet is too large: {}", size); -+ } -+ -+ let mut packet_hex = [0; 128]; -+ packet_to_hex(slice, &mut packet_hex); -+ debug_packets!( -+ "in={}", -+ core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap() -+ ); -+ } -+ -+ // Debug-only function -+ fn debug_out_packet(&self, size: usize, endpoint: usize) { - let slice = self.descriptors[endpoint] -- .slice -- .expect("No slice set for this descriptor"); -+ .slice_out -+ .expect("No OUT slice set for this descriptor"); - if size > slice.len() { - panic!("Packet is too large: {}", size); - } -@@ -1788,8 +1785,7 @@ impl<'a> Usbd<'a> { - let mut packet_hex = [0; 128]; - packet_to_hex(slice, &mut packet_hex); - debug_packets!( -- "{}={}", -- _title, -+ "out={}", - core::str::from_utf8(&packet_hex[..(2 * size)]).unwrap() - ); - } -@@ -1807,17 +1803,41 @@ impl<'a> power::PowerClient for Usbd<'a> { - } - - impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { -- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { -+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) { -+ if buf.len() < 8 { -+ panic!("Endpoint buffer must be at least 8 bytes"); -+ } -+ if !buf.len().is_power_of_two() { -+ panic!("Buffer size must be a power of 2"); -+ } -+ self.descriptors[0].slice_in.set(buf); -+ self.descriptors[0].slice_out.set(buf); -+ } -+ -+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { -+ if buf.len() < 8 { -+ panic!("Endpoint buffer must be at least 8 bytes"); -+ } -+ if !buf.len().is_power_of_two() { -+ panic!("Buffer size must be a power of 2"); -+ } -+ if endpoint == 0 || endpoint >= NUM_ENDPOINTS { -+ panic!("Endpoint number is invalid"); -+ } -+ self.descriptors[endpoint].slice_in.set(buf); -+ } -+ -+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { - if buf.len() < 8 { - panic!("Endpoint buffer must be at least 8 bytes"); - } - if !buf.len().is_power_of_two() { - panic!("Buffer size must be a power of 2"); - } -- if endpoint >= NUM_ENDPOINTS { -- panic!("Endpoint number is too high"); -+ if endpoint == 0 || endpoint >= NUM_ENDPOINTS { -+ panic!("Endpoint number is invalid"); - } -- self.descriptors[endpoint].slice.set(buf); -+ self.descriptors[endpoint].slice_out.set(buf); - } - - fn enable_as_device(&self, speed: hil::usb::DeviceSpeed) { -@@ -1900,8 +1920,8 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - fn endpoint_resume_in(&self, endpoint: usize) { - debug_events!("endpoint_resume_in({})", endpoint); - -- let (_, direction, _) = self.descriptors[endpoint].state.get().bulk_state(); -- assert!(direction.has_in()); -+ let (_, in_state, _) = self.descriptors[endpoint].state.get().bulk_state(); -+ assert!(in_state.is_some()); - - if self.dma_pending.get() { - debug_events!("requesting resume_in[{}]", endpoint); -@@ -1916,20 +1936,21 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - fn endpoint_resume_out(&self, endpoint: usize) { - debug_events!("endpoint_resume_out({})", endpoint); - -- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); -- assert!(direction.has_out()); -+ let (transfer_type, in_state, out_state) = -+ self.descriptors[endpoint].state.get().bulk_state(); -+ assert!(out_state.is_some()); - -- match state { -- BulkState::OutDelay => { -+ match out_state.unwrap() { -+ BulkOutState::OutDelay => { - // The endpoint has now finished processing the last ENDEPOUT. No EPDATA event - // happened in the meantime, so the state is now back to Init. - self.descriptors[endpoint].state.set(EndpointState::Bulk( - transfer_type, -- direction, -- BulkState::Init, -+ in_state, -+ Some(BulkOutState::Init), - )); - } -- BulkState::OutData => { -+ BulkOutState::OutData => { - // Although the client reported a delay before, an EPDATA event has - // happened in the meantime. This pending transaction will now - // continue in transmit_out(). -@@ -1942,25 +1963,11 @@ impl<'a> hil::usb::UsbController<'a> for Usbd<'a> { - self.transmit_out(endpoint); - } - } -- BulkState::Init | BulkState::OutDma | BulkState::InDma | BulkState::InData => { -- internal_err!("Unexpected state: {:?}", state); -+ BulkOutState::Init | BulkOutState::OutDma => { -+ internal_err!("Unexpected state: {:?}", out_state); - } - } - } -- -- fn endpoint_cancel_in(&self, endpoint: usize) { -- debug_events!("endpoint_cancel_in({})", endpoint); -- -- let (transfer_type, direction, state) = self.descriptors[endpoint].state.get().bulk_state(); -- assert!(direction.has_in()); -- assert_eq!(state, BulkState::InData); -- -- self.descriptors[endpoint].state.set(EndpointState::Bulk( -- transfer_type, -- direction, -- BulkState::Init, -- )); -- } - } - - fn status_epin(ep: usize) -> Field<u32, EndpointStatus::Register> { -diff --git a/chips/sam4l/src/usbc/mod.rs b/chips/sam4l/src/usbc/mod.rs -index 28a0b9f9..ab5b636f 100644 ---- a/chips/sam4l/src/usbc/mod.rs -+++ b/chips/sam4l/src/usbc/mod.rs -@@ -1438,11 +1438,28 @@ fn endpoint_enable_interrupts(endpoint: usize, mask: FieldValue<u32, EndpointCon - } - - impl hil::usb::UsbController<'a> for Usbc<'a> { -- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { -+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]) { - if buf.len() != 8 { - client_err!("Bad endpoint buffer size"); - } - -+ self._endpoint_bank_set_buffer(EndpointIndex::new(0), BankIndex::Bank0, buf); -+ } -+ -+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { -+ if buf.len() != 8 { -+ client_err!("Bad endpoint buffer size"); -+ } -+ -+ self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf); -+ } -+ -+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]) { -+ if buf.len() != 8 { -+ client_err!("Bad endpoint buffer size"); -+ } -+ -+ // XXX: when implementing in_out endpoints, this should probably set a different slice than endpoint_set_in_buffer. - self._endpoint_bank_set_buffer(EndpointIndex::new(endpoint), BankIndex::Bank0, buf); - } - -@@ -1547,10 +1564,6 @@ impl hil::usb::UsbController<'a> for Usbc<'a> { - requests.resume_out = true; - self.requests[endpoint].set(requests); - } -- -- fn endpoint_cancel_in(&self, _endpoint: usize) { -- unimplemented!() -- } - } - - /// Static state to manage the USBC -diff --git a/kernel/src/hil/usb.rs b/kernel/src/hil/usb.rs -index 64610fa5..a114b30d 100644 ---- a/kernel/src/hil/usb.rs -+++ b/kernel/src/hil/usb.rs -@@ -5,7 +5,9 @@ use crate::common::cells::VolatileCell; - /// USB controller interface - pub trait UsbController<'a> { - // Should be called before `enable_as_device()` -- fn endpoint_set_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]); -+ fn endpoint_set_ctrl_buffer(&self, buf: &'a [VolatileCell<u8>]); -+ fn endpoint_set_in_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]); -+ fn endpoint_set_out_buffer(&self, endpoint: usize, buf: &'a [VolatileCell<u8>]); - - // Must be called before `attach()` - fn enable_as_device(&self, speed: DeviceSpeed); -@@ -27,8 +29,6 @@ pub trait UsbController<'a> { - fn endpoint_resume_in(&self, endpoint: usize); - - fn endpoint_resume_out(&self, endpoint: usize); -- -- fn endpoint_cancel_in(&self, endpoint: usize); - } - - #[derive(Clone, Copy, Debug)] diff --git a/third_party/tock b/third_party/tock index fbc863f..7e47e6f 160000 --- a/third_party/tock +++ b/third_party/tock @@ -1 +1 @@ -Subproject commit fbc863faf0c9615537ee52dcdccdfcb9204d2467 +Subproject commit 7e47e6f1a9b279b6458edeb0fa24af381f5a1572 -- GitLab