yet more code shaving

This commit is contained in:
R
2024-04-14 17:10:38 +01:00
parent 2acf794123
commit 878e2229e5
2 changed files with 42 additions and 38 deletions
+40 -38
View File
@@ -161,6 +161,8 @@ extern volatile uint32_t USB_EP0_IN[4];
extern volatile uint32_t USB_EP1_OUT[32]; extern volatile uint32_t USB_EP1_OUT[32];
extern volatile uint32_t USB_EP1_IN[32]; extern volatile uint32_t USB_EP1_IN[32];
extern uint32_t SCSI_XFER_CUR_LBA;
extern uint32_t SCSI_XFER_BLK_LEFT;
extern uint32_t BLOCKNUM_LO; extern uint32_t BLOCKNUM_LO;
extern uint32_t TOTBLOCKS_LO; extern uint32_t TOTBLOCKS_LO;
extern uint32_t CSWTAG_LO; extern uint32_t CSWTAG_LO;
@@ -173,8 +175,8 @@ extern uint32_t CTRL_XFER_STATE_X;
extern uint32_t CTRL_XFER_DESC_SZ; extern uint32_t CTRL_XFER_DESC_SZ;
extern uint32_t USB_SECTOR_STASH[128]; extern uint32_t USB_SECTOR_STASH[128];
#define MAX_AUTO_BOOT_BLOCKS (38 * 16 - 1) #define MAX_AUTO_BOOT_BLOCKS (36 * 16 - 1)
extern uint32_t UF2_GOT_BLOCKS[38]; extern uint32_t UF2_GOT_BLOCKS[36];
#define USB_EPTYPE_BULK 0b00 #define USB_EPTYPE_BULK 0b00
#define USB_EPTYPE_CONTROL 0b01 #define USB_EPTYPE_CONTROL 0b01
@@ -246,6 +248,12 @@ __attribute__((always_inline)) static inline void set_ep_mode(uint32_t epidx, ui
uint32_t want_stats = (stat_rx << 12) | (stat_tx) << 4; uint32_t want_stats = (stat_rx << 12) | (stat_tx) << 4;
R16_USBD_EPR[epidx] = epaddr | (eptype << 9) | xtra | (cur_stats ^ want_stats); R16_USBD_EPR[epidx] = epaddr | (eptype << 9) | xtra | (cur_stats ^ want_stats);
} }
static void set_ep0_ack_in(void) {
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0);
}
static void set_ep0_stall(void) {
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0);
}
__attribute__((always_inline)) static inline uint32_t min(uint32_t a, uint32_t b) { __attribute__((always_inline)) static inline uint32_t min(uint32_t a, uint32_t b) {
if (a <= b) if (a <= b)
@@ -377,16 +385,15 @@ __attribute__((naked)) int main(void) {
// when writing: // when writing:
// [31:16] = ignored // [31:16] = ignored
// [15:0] = blocks left // [15:0] = blocks left
uint32_t scsi_xfer_lba_blocks = 0;
UF2_GOT_BLOCKS[37] = 0; UF2_GOT_BLOCKS[35] = 0;
while (1) { while (1) {
uint32_t usb_int_status = R16_USBD_ISTR; uint32_t usb_int_status = R16_USBD_ISTR;
if (usb_int_status & (1 << 10)) { if (usb_int_status & (1 << 10)) {
// RESET // RESET
// set all to STALL, SETUP will come in nonetheless // set all to STALL, SETUP will come in nonetheless
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_DISABLED, USB_STAT_DISABLED, 0, 0); set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_DISABLED, USB_STAT_DISABLED, 0, 0);
R16_USBD_DADDR = 0x80; R16_USBD_DADDR = 0x80;
R16_USBD_CNTR = 0; R16_USBD_CNTR = 0;
@@ -410,7 +417,7 @@ __attribute__((naked)) int main(void) {
USB_EP0_IN[0] = 0; USB_EP0_IN[0] = 0;
USB_DESCS[0].count_tx = min(2, wLength); USB_DESCS[0].count_tx = min(2, wLength);
CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN; CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (bRequest_bmRequestType == 0x0102) { } else if (bRequest_bmRequestType == 0x0102) {
// CLEAR_FEATURE // CLEAR_FEATURE
// XXX how is this supposed to work? // XXX how is this supposed to work?
@@ -419,20 +426,20 @@ __attribute__((naked)) int main(void) {
uint32_t dCSWTag = CSWTAG_LO | (CSWTAG_HI << 16); uint32_t dCSWTag = CSWTAG_LO | (CSWTAG_HI << 16);
make_msc_csw(dCSWTag, 1); make_msc_csw(dCSWTag, 1);
msc_state = (msc_state & 0xffffff00) | STATE_SENT_CSW; msc_state = (msc_state & 0xffffff00) | STATE_SENT_CSW;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (wIndex == 0x01) { } else if (wIndex == 0x01) {
set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 0); set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 0);
msc_state = (msc_state & 0xffffff00) | STATE_WANT_CBW; msc_state = (msc_state & 0xffffff00) | STATE_WANT_CBW;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else { } else {
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
} }
} else if (bRequest_bmRequestType == 0x0500) { } else if (bRequest_bmRequestType == 0x0500) {
// SET_ADDRESS // SET_ADDRESS
CTRL_XFER_STATE_X = USB_EP0_OUT[1]; CTRL_XFER_STATE_X = USB_EP0_OUT[1];
CTRL_XFER_STATE = STATE_SET_ADDR; CTRL_XFER_STATE = STATE_SET_ADDR;
USB_DESCS[0].count_tx = 0; USB_DESCS[0].count_tx = 0;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (bRequest_bmRequestType == 0x0680) { } else if (bRequest_bmRequestType == 0x0680) {
// GET_DESCRIPTOR // GET_DESCRIPTOR
uint32_t wValue = USB_EP0_OUT[1]; uint32_t wValue = USB_EP0_OUT[1];
@@ -462,14 +469,14 @@ __attribute__((naked)) int main(void) {
CTRL_XFER_STATE_X = (8 << 8) | (wLength - 8); CTRL_XFER_STATE_X = (8 << 8) | (wLength - 8);
CTRL_XFER_STATE = STATE_GET_DESC; CTRL_XFER_STATE = STATE_GET_DESC;
} }
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (wValue == 0x0300) { } else if (wValue == 0x0300) {
// string LANGIDs // string LANGIDs
USB_EP0_IN[0] = 0x0304; USB_EP0_IN[0] = 0x0304;
USB_EP0_IN[1] = 0x0409; USB_EP0_IN[1] = 0x0409;
USB_DESCS[0].count_tx = min(4, wLength); USB_DESCS[0].count_tx = min(4, wLength);
CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN; CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (wValue == 0x0303) { } else if (wValue == 0x0303) {
USB_EP0_IN[0] = 0x0300 | (24 * 2 + 2); USB_EP0_IN[0] = 0x0300 | (24 * 2 + 2);
USB_EP0_IN[1] = HEXLUT[ESIG_UNIID(0) >> 4]; USB_EP0_IN[1] = HEXLUT[ESIG_UNIID(0) >> 4];
@@ -484,24 +491,22 @@ __attribute__((naked)) int main(void) {
CTRL_XFER_STATE_X = (8 << 8) | (wLength - 8); CTRL_XFER_STATE_X = (8 << 8) | (wLength - 8);
CTRL_XFER_STATE = STATE_GET_STR_SERIAL; CTRL_XFER_STATE = STATE_GET_STR_SERIAL;
} }
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else { } else {
// bad descriptor // bad descriptor
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
} }
} else if (bRequest_bmRequestType == 0x0880) { } else if (bRequest_bmRequestType == 0x0880) {
// GET_CONFIGURATION // GET_CONFIGURATION
USB_EP0_IN[0] = ACTIVE_CONFIG; USB_EP0_IN[0] = ACTIVE_CONFIG;
USB_DESCS[0].count_tx = min(1, wLength); USB_DESCS[0].count_tx = min(1, wLength);
CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN; CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else if (bRequest_bmRequestType == 0x0900) { } else if (bRequest_bmRequestType == 0x0900) {
// SET_CONFIGURATION // SET_CONFIGURATION
uint32_t wValue = USB_EP0_OUT[1]; uint32_t wValue = USB_EP0_OUT[1];
if (wValue == 0 || wValue == 1) { if (wValue == 0 || wValue == 1) {
ACTIVE_CONFIG = wValue; ACTIVE_CONFIG = wValue;
USB_DESCS[0].count_tx = 0;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0);
if (wValue) { if (wValue) {
// activate, allow OUT // activate, allow OUT
set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 1); set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_STALL, 0, 1);
@@ -510,29 +515,31 @@ __attribute__((naked)) int main(void) {
// deactivate // deactivate
set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_DISABLED, USB_STAT_DISABLED, 0, 0); set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_DISABLED, USB_STAT_DISABLED, 0, 0);
} }
USB_DESCS[0].count_tx = 0;
set_ep0_ack_in();
} else { } else {
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
} }
} else if (bRequest_bmRequestType == 0x0A81) { } else if (bRequest_bmRequestType == 0x0A81) {
// GET_INTERFACE // GET_INTERFACE
USB_EP0_IN[0] = 0; USB_EP0_IN[0] = 0;
USB_DESCS[0].count_tx = min(1, wLength); USB_DESCS[0].count_tx = min(1, wLength);
CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN; CTRL_XFER_STATE = STATE_CTRL_SIMPLE_IN;
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} else { } else {
// unknown // unknown
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
} }
} else { } else {
// back to stall for everything, expect SETUP // back to stall for everything, expect SETUP
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
} }
} else if ((ep_status & (1 << 7)) && (epidx == 0)) { } else if ((ep_status & (1 << 7)) && (epidx == 0)) {
switch (CTRL_XFER_STATE) { switch (CTRL_XFER_STATE) {
case STATE_SET_ADDR: case STATE_SET_ADDR:
R16_USBD_DADDR = 0x80 | (CTRL_XFER_STATE_X & 0x7f); R16_USBD_DADDR = 0x80 | (CTRL_XFER_STATE_X & 0x7f);
// back to stall for everything, expect SETUP // back to stall for everything, expect SETUP
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_STALL, 0, 0); set_ep0_stall();
break; break;
case STATE_GET_DESC: case STATE_GET_DESC:
case STATE_GET_STR_SERIAL: case STATE_GET_STR_SERIAL:
@@ -552,7 +559,6 @@ __attribute__((naked)) int main(void) {
for (int i = 0; i < bytes; i+=2) for (int i = 0; i < bytes; i+=2)
USB_EP0_IN[i / 2] = *((uint16_t*)(outputting_desc + byte_pos + i)); USB_EP0_IN[i / 2] = *((uint16_t*)(outputting_desc + byte_pos + i));
} else { } else {
// todo
uint32_t serial_no_pos = (byte_pos - 2) / 2; uint32_t serial_no_pos = (byte_pos - 2) / 2;
uint32_t ascii_bytes = (bytes + 1) / 2; uint32_t ascii_bytes = (bytes + 1) / 2;
if (serial_no_pos + ascii_bytes > 24) { if (serial_no_pos + ascii_bytes > 24) {
@@ -570,7 +576,7 @@ __attribute__((naked)) int main(void) {
USB_DESCS[0].count_tx = 8; USB_DESCS[0].count_tx = 8;
CTRL_XFER_STATE_X = ((byte_pos + 8) << 8) | (bytes_left - 8); CTRL_XFER_STATE_X = ((byte_pos + 8) << 8) | (bytes_left - 8);
} }
set_ep_mode(0, 0, USB_EPTYPE_CONTROL, USB_STAT_STALL, USB_STAT_ACK, 0, 0); set_ep0_ack_in();
} }
} }
break; break;
@@ -683,10 +689,11 @@ __attribute__((naked)) int main(void) {
break; break;
} }
scsi_xfer_lba_blocks = (lba << 16) | blocks; SCSI_XFER_BLK_LEFT = blocks;
if (operation_code == 0x28) { if (operation_code == 0x28) {
// READ // READ
SCSI_XFER_CUR_LBA = lba;
synthesize_block(lba, 0); synthesize_block(lba, 0);
msc_state = STATE_SEND_MORE_READ; msc_state = STATE_SEND_MORE_READ;
} else { } else {
@@ -762,7 +769,7 @@ __attribute__((naked)) int main(void) {
uint32_t blocknum = BLOCKNUM_LO; uint32_t blocknum = BLOCKNUM_LO;
uint32_t totblocks = TOTBLOCKS_LO; uint32_t totblocks = TOTBLOCKS_LO;
if (UF2_GOT_BLOCKS[37] & 0x8000) { if (UF2_GOT_BLOCKS[35] & 0x8000) {
// not first uf2 block // not first uf2 block
UF2_GOT_BLOCKS[blocknum / 16] |= 1 << (blocknum % 16); UF2_GOT_BLOCKS[blocknum / 16] |= 1 << (blocknum % 16);
} else { } else {
@@ -809,9 +816,7 @@ __attribute__((naked)) int main(void) {
} }
} }
uint32_t blocks_left = scsi_xfer_lba_blocks & 0xffff; if (SCSI_XFER_BLK_LEFT == 1) {
blocks_left--;
if (blocks_left == 0) {
uint32_t dCSWTag = CSWTAG_LO | (CSWTAG_HI << 16); uint32_t dCSWTag = CSWTAG_LO | (CSWTAG_HI << 16);
make_msc_csw(dCSWTag, 0); make_msc_csw(dCSWTag, 0);
uint32_t all_blocks = 0xffff; uint32_t all_blocks = 0xffff;
@@ -822,7 +827,7 @@ __attribute__((naked)) int main(void) {
else else
msc_state = STATE_SENT_CSW; msc_state = STATE_SENT_CSW;
} else { } else {
scsi_xfer_lba_blocks = blocks_left; SCSI_XFER_BLK_LEFT--;
set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_NAK, 0, 0); set_ep_mode(1, 1, USB_EPTYPE_BULK, USB_STAT_ACK, USB_STAT_NAK, 0, 0);
msc_state = STATE_WAITING_FOR_WRITE; msc_state = STATE_WAITING_FOR_WRITE;
} }
@@ -859,19 +864,16 @@ __attribute__((naked)) int main(void) {
case STATE_SEND_MORE_READ: case STATE_SEND_MORE_READ:
uint32_t piece = (msc_state >> 8) & 0b111; uint32_t piece = (msc_state >> 8) & 0b111;
if (piece != 7) { if (piece != 7) {
synthesize_block(scsi_xfer_lba_blocks >> 16, piece + 1); synthesize_block(SCSI_XFER_CUR_LBA, piece + 1);
msc_state += 0x100; msc_state += 0x100;
} else { } else {
uint32_t lba = scsi_xfer_lba_blocks >> 16; if (SCSI_XFER_BLK_LEFT == 1) {
uint32_t blocks_left = scsi_xfer_lba_blocks & 0xffff;
blocks_left--;
if (blocks_left == 0) {
make_msc_csw(dCSWTag, 0); make_msc_csw(dCSWTag, 0);
msc_state = STATE_SENT_CSW; msc_state = STATE_SENT_CSW;
} else { } else {
lba++; synthesize_block(SCSI_XFER_CUR_LBA + 1, 0);
synthesize_block(lba, 0); SCSI_XFER_CUR_LBA++;
scsi_xfer_lba_blocks = (lba << 16) | blocks_left; SCSI_XFER_BLK_LEFT--;
msc_state = STATE_SEND_MORE_READ; msc_state = STATE_SEND_MORE_READ;
} }
} }
+2
View File
@@ -45,6 +45,8 @@ SECTIONS
PROVIDE( UF2_GOT_BLOCKS = 0x40006140 ); PROVIDE( UF2_GOT_BLOCKS = 0x40006140 );
PROVIDE( SCSI_XFER_CUR_LBA = 0x400061d0 );
PROVIDE( SCSI_XFER_BLK_LEFT = 0x400061d4 );
PROVIDE( BLOCKNUM_LO = 0x400061d8 ); PROVIDE( BLOCKNUM_LO = 0x400061d8 );
PROVIDE( TOTBLOCKS_LO = 0x400061dc ); PROVIDE( TOTBLOCKS_LO = 0x400061dc );
PROVIDE( CSWTAG_LO = 0x400061e0 ); PROVIDE( CSWTAG_LO = 0x400061e0 );