Skip to content

Commit fa523a5

Browse files
committed
make sure usb buffer occupies whole cache line when DCACHE is enabled for msc,cdc,hid
HIL enable device DMA for p4
1 parent 2571889 commit fa523a5

File tree

10 files changed

+105
-103
lines changed

10 files changed

+105
-103
lines changed

hw/bsp/espressif/boards/espressif_p4_function_ev/board.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* in the Software without restriction, including without limitation the rights
99
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1010
* copies of the Software, and to permit persons to whom the Software is
11-
* furnished to do so, subject to the following conditions:
11+
* furnished to do so, subject to the following conditions:aaaaa
1212
*
1313
* The above copyright notice and this permission notice shall be included in
1414
* all copies or substantial portions of the Software.
@@ -33,7 +33,7 @@
3333

3434
// #define NEOPIXEL_PIN 48
3535

36-
#define BUTTON_PIN 0
36+
#define BUTTON_PIN 35
3737
#define BUTTON_STATE_ACTIVE 0
3838

3939
// For CI hardware test, to test both device and host on the same HS port with help of

src/class/cdc/cdc_device.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,14 @@ typedef struct {
6969
OSAL_MUTEX_DEF(tx_ff_mutex);
7070

7171
// Endpoint Transfer buffer
72-
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
73-
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
72+
union {
73+
CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_CDC_EP_BUFSIZE];
74+
TUD_DCACHE_PADDING;
75+
};
76+
union {
77+
CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_CDC_EP_BUFSIZE];
78+
TUD_DCACHE_PADDING;
79+
};
7480
} cdcd_interface_t;
7581

7682
#define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, wanted_char)

src/class/hid/hid_device.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,18 @@ typedef struct {
5353
// Note: HID descriptor may be not available from application after enumeration
5454
tusb_hid_descriptor_hid_t const *hid_descriptor;
5555

56-
uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE];
57-
CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE];
58-
CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE];
56+
union {
57+
CFG_TUD_MEM_ALIGN uint8_t ctrl_buf[CFG_TUD_HID_EP_BUFSIZE];
58+
TUD_DCACHE_PADDING;
59+
};
60+
union {
61+
CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_HID_EP_BUFSIZE];
62+
TUD_DCACHE_PADDING;
63+
};
64+
union {
65+
CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_HID_EP_BUFSIZE];
66+
TUD_DCACHE_PADDING;
67+
};
5968
} hidd_interface_t;
6069

6170
CFG_TUD_MEM_SECTION tu_static hidd_interface_t _hidd_itf[CFG_TUD_HID];

src/class/msc/msc_device.c

Lines changed: 54 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,27 @@
4444
//--------------------------------------------------------------------+
4545
// MACRO CONSTANT TYPEDEF
4646
//--------------------------------------------------------------------+
47-
enum
48-
{
47+
enum {
4948
MSC_STAGE_CMD = 0,
5049
MSC_STAGE_DATA,
5150
MSC_STAGE_STATUS,
5251
MSC_STAGE_STATUS_SENT,
5352
MSC_STAGE_NEED_RESET,
5453
};
5554

56-
typedef struct
57-
{
58-
// TODO optimize alignment
59-
CFG_TUSB_MEM_ALIGN msc_cbw_t cbw;
60-
CFG_TUSB_MEM_ALIGN msc_csw_t csw;
55+
typedef struct {
56+
union {
57+
CFG_TUD_MEM_ALIGN msc_cbw_t cbw;
58+
TUD_DCACHE_PADDING;
59+
};
60+
union {
61+
CFG_TUD_MEM_ALIGN msc_csw_t csw;
62+
TUD_DCACHE_PADDING;
63+
};
64+
union {
65+
CFG_TUD_MEM_ALIGN uint8_t ep_buf[CFG_TUD_MSC_EP_BUFSIZE];
66+
TUD_DCACHE_PADDING;
67+
};
6168

6269
uint8_t itf_num;
6370
uint8_t ep_in;
@@ -74,8 +81,7 @@ typedef struct
7481
uint8_t add_sense_qualifier;
7582
}mscd_interface_t;
7683

77-
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static mscd_interface_t _mscd_itf;
78-
CFG_TUD_MEM_SECTION CFG_TUSB_MEM_ALIGN tu_static uint8_t _mscd_buf[CFG_TUD_MSC_EP_BUFSIZE];
84+
CFG_TUD_MEM_SECTION CFG_TUD_MEM_ALIGN static mscd_interface_t _mscd_itf;
7985

8086
//--------------------------------------------------------------------+
8187
// INTERNAL OBJECT & FUNCTION DECLARATION
@@ -86,28 +92,24 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
8692
static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc);
8793
static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint32_t xferred_bytes);
8894

89-
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir)
90-
{
95+
TU_ATTR_ALWAYS_INLINE static inline bool is_data_in(uint8_t dir) {
9196
return tu_bit_test(dir, 7);
9297
}
9398

94-
static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc)
95-
{
99+
static inline bool send_csw(uint8_t rhport, mscd_interface_t* p_msc) {
96100
// Data residue is always = host expect - actual transferred
97101
p_msc->csw.data_residue = p_msc->cbw.total_bytes - p_msc->xferred_len;
98102

99103
p_msc->stage = MSC_STAGE_STATUS_SENT;
100104
return usbd_edpt_xfer(rhport, p_msc->ep_in , (uint8_t*) &p_msc->csw, sizeof(msc_csw_t));
101105
}
102106

103-
static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc)
104-
{
107+
static inline bool prepare_cbw(uint8_t rhport, mscd_interface_t* p_msc) {
105108
p_msc->stage = MSC_STAGE_CMD;
106109
return usbd_edpt_xfer(rhport, p_msc->ep_out, (uint8_t*) &p_msc->cbw, sizeof(msc_cbw_t));
107110
}
108111

109-
static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status)
110-
{
112+
static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status) {
111113
msc_cbw_t const * p_cbw = &p_msc->cbw;
112114
msc_csw_t * p_csw = &p_msc->csw;
113115

@@ -116,39 +118,34 @@ static void fail_scsi_op(uint8_t rhport, mscd_interface_t* p_msc, uint8_t status
116118
p_msc->stage = MSC_STAGE_STATUS;
117119

118120
// failed but sense key is not set: default to Illegal Request
119-
if ( p_msc->sense_key == 0 ) tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
121+
if (p_msc->sense_key == 0) {
122+
tud_msc_set_sense(p_cbw->lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
123+
}
120124

121125
// If there is data stage and not yet complete, stall it
122-
if ( p_cbw->total_bytes && p_csw->data_residue )
123-
{
124-
if ( is_data_in(p_cbw->dir) )
125-
{
126+
if (p_cbw->total_bytes && p_csw->data_residue) {
127+
if (is_data_in(p_cbw->dir)) {
126128
usbd_edpt_stall(rhport, p_msc->ep_in);
127-
}
128-
else
129-
{
129+
} else {
130130
usbd_edpt_stall(rhport, p_msc->ep_out);
131131
}
132132
}
133133
}
134134

135-
static inline uint32_t rdwr10_get_lba(uint8_t const command[])
136-
{
135+
static inline uint32_t rdwr10_get_lba(uint8_t const command[]) {
137136
// use offsetof to avoid pointer to the odd/unaligned address
138137
uint32_t const lba = tu_unaligned_read32(command + offsetof(scsi_write10_t, lba));
139138

140139
// lba is in Big Endian
141140
return tu_ntohl(lba);
142141
}
143142

144-
static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw)
145-
{
143+
static inline uint16_t rdwr10_get_blockcount(msc_cbw_t const* cbw) {
146144
uint16_t const block_count = tu_unaligned_read16(cbw->command + offsetof(scsi_write10_t, block_count));
147145
return tu_ntohs(block_count);
148146
}
149147

150-
static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw)
151-
{
148+
static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw) {
152149
// first extract block count in the command
153150
uint16_t const block_count = rdwr10_get_blockcount(cbw);
154151

@@ -158,40 +155,28 @@ static inline uint16_t rdwr10_get_blocksize(msc_cbw_t const* cbw)
158155
return (uint16_t) (cbw->total_bytes / block_count);
159156
}
160157

161-
uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
162-
{
158+
uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw) {
163159
uint8_t status = MSC_CSW_STATUS_PASSED;
164160
uint16_t const block_count = rdwr10_get_blockcount(cbw);
165161

166-
if ( cbw->total_bytes == 0 )
167-
{
168-
if ( block_count )
169-
{
162+
if (cbw->total_bytes == 0) {
163+
if (block_count) {
170164
TU_LOG_DRV(" SCSI case 2 (Hn < Di) or case 3 (Hn < Do) \r\n");
171165
status = MSC_CSW_STATUS_PHASE_ERROR;
172-
}else
173-
{
166+
} else {
174167
// no data transfer, only exist in complaint test suite
175168
}
176-
}else
177-
{
178-
if ( SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir) )
179-
{
169+
} else {
170+
if (SCSI_CMD_READ_10 == cbw->command[0] && !is_data_in(cbw->dir)) {
180171
TU_LOG_DRV(" SCSI case 10 (Ho <> Di)\r\n");
181172
status = MSC_CSW_STATUS_PHASE_ERROR;
182-
}
183-
else if ( SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir) )
184-
{
173+
} else if (SCSI_CMD_WRITE_10 == cbw->command[0] && is_data_in(cbw->dir)) {
185174
TU_LOG_DRV(" SCSI case 8 (Hi <> Do)\r\n");
186175
status = MSC_CSW_STATUS_PHASE_ERROR;
187-
}
188-
else if ( 0 == block_count )
189-
{
176+
} else if (0 == block_count) {
190177
TU_LOG_DRV(" SCSI case 4 Hi > Dn (READ10) or case 9 Ho > Dn (WRITE10) \r\n");
191-
status = MSC_CSW_STATUS_FAILED;
192-
}
193-
else if ( cbw->total_bytes / block_count == 0 )
194-
{
178+
status = MSC_CSW_STATUS_FAILED;
179+
} else if (cbw->total_bytes / block_count == 0) {
195180
TU_LOG_DRV(" Computed block size = 0. SCSI case 7 Hi < Di (READ10) or case 13 Ho < Do (WRIT10)\r\n");
196181
status = MSC_CSW_STATUS_PHASE_ERROR;
197182
}
@@ -205,8 +190,7 @@ uint8_t rdwr10_validate_cmd(msc_cbw_t const* cbw)
205190
//--------------------------------------------------------------------+
206191
#if CFG_TUSB_DEBUG >= CFG_TUD_MSC_LOG_LEVEL
207192

208-
TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
209-
{
193+
TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] = {
210194
{ .key = SCSI_CMD_TEST_UNIT_READY , .data = "Test Unit Ready" },
211195
{ .key = SCSI_CMD_INQUIRY , .data = "Inquiry" },
212196
{ .key = SCSI_CMD_MODE_SELECT_6 , .data = "Mode_Select 6" },
@@ -220,8 +204,7 @@ TU_ATTR_UNUSED tu_static tu_lookup_entry_t const _msc_scsi_cmd_lookup[] =
220204
{ .key = SCSI_CMD_WRITE_10 , .data = "Write10" }
221205
};
222206

223-
TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table =
224-
{
207+
TU_ATTR_UNUSED tu_static tu_lookup_table_t const _msc_scsi_cmd_table = {
225208
.count = TU_ARRAY_SIZE(_msc_scsi_cmd_lookup),
226209
.items = _msc_scsi_cmd_lookup
227210
};
@@ -462,25 +445,25 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
462445
// 2. IN & Zero: Process if is built-in, else Invoke app callback. Skip DATA if zero length
463446
if ( (p_cbw->total_bytes > 0 ) && !is_data_in(p_cbw->dir) )
464447
{
465-
if (p_cbw->total_bytes > sizeof(_mscd_buf))
448+
if (p_cbw->total_bytes > CFG_TUD_MSC_EP_BUFSIZE)
466449
{
467450
TU_LOG_DRV(" SCSI reject non READ10/WRITE10 with large data\r\n");
468451
fail_scsi_op(rhport, p_msc, MSC_CSW_STATUS_FAILED);
469452
}else
470453
{
471454
// Didn't check for case 9 (Ho > Dn), which requires examining scsi command first
472455
// but it is OK to just receive data then responded with failed status
473-
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, (uint16_t) p_msc->total_len) );
456+
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, p_msc->ep_buf, (uint16_t) p_msc->total_len) );
474457
}
475458
}else
476459
{
477460
// First process if it is a built-in commands
478-
int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, _mscd_buf, sizeof(_mscd_buf));
461+
int32_t resplen = proc_builtin_scsi(p_cbw->lun, p_cbw->command, p_msc->ep_buf, CFG_TUD_MSC_EP_BUFSIZE);
479462

480463
// Invoke user callback if not built-in
481464
if ( (resplen < 0) && (p_msc->sense_key == 0) )
482465
{
483-
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
466+
resplen = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, p_msc->ep_buf, (uint16_t) p_msc->total_len);
484467
}
485468

486469
if ( resplen < 0 )
@@ -513,7 +496,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
513496
{
514497
// cannot return more than host expect
515498
p_msc->total_len = tu_min32((uint32_t) resplen, p_cbw->total_bytes);
516-
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) p_msc->total_len) );
499+
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, p_msc->ep_buf, (uint16_t) p_msc->total_len) );
517500
}
518501
}
519502
}
@@ -522,7 +505,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
522505

523506
case MSC_STAGE_DATA:
524507
TU_LOG_DRV(" SCSI Data [Lun%u]\r\n", p_cbw->lun);
525-
//TU_LOG_MEM(MSC_DEBUG, _mscd_buf, xferred_bytes, 2);
508+
//TU_LOG_MEM(MSC_DEBUG, p_msc->ep_buf, xferred_bytes, 2);
526509

527510
if (SCSI_CMD_READ_10 == p_cbw->command[0])
528511
{
@@ -548,7 +531,7 @@ bool mscd_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t
548531
// OUT transfer, invoke callback if needed
549532
if ( !is_data_in(p_cbw->dir) )
550533
{
551-
int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, _mscd_buf, (uint16_t) p_msc->total_len);
534+
int32_t cb_result = tud_msc_scsi_cb(p_cbw->lun, p_cbw->command, p_msc->ep_buf, (uint16_t) p_msc->total_len);
552535

553536
if ( cb_result < 0 )
554537
{
@@ -861,11 +844,11 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
861844
uint32_t const lba = rdwr10_get_lba(p_cbw->command) + (p_msc->xferred_len / block_sz);
862845

863846
// remaining bytes capped at class buffer
864-
int32_t nbytes = (int32_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
847+
int32_t nbytes = (int32_t) tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes-p_msc->xferred_len);
865848

866849
// Application can consume smaller bytes
867850
uint32_t const offset = p_msc->xferred_len % block_sz;
868-
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, _mscd_buf, (uint32_t) nbytes);
851+
nbytes = tud_msc_read10_cb(p_cbw->lun, lba, offset, p_msc->ep_buf, (uint32_t) nbytes);
869852

870853
if ( nbytes < 0 )
871854
{
@@ -884,7 +867,7 @@ static void proc_read10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
884867
}
885868
else
886869
{
887-
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, _mscd_buf, (uint16_t) nbytes), );
870+
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_in, p_msc->ep_buf, (uint16_t) nbytes), );
888871
}
889872
}
890873

@@ -908,10 +891,10 @@ static void proc_write10_cmd(uint8_t rhport, mscd_interface_t* p_msc)
908891
}
909892

910893
// remaining bytes capped at class buffer
911-
uint16_t nbytes = (uint16_t) tu_min32(sizeof(_mscd_buf), p_cbw->total_bytes-p_msc->xferred_len);
894+
uint16_t nbytes = (uint16_t) tu_min32(CFG_TUD_MSC_EP_BUFSIZE, p_cbw->total_bytes-p_msc->xferred_len);
912895

913896
// Write10 callback will be called later when usb transfer complete
914-
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, _mscd_buf, nbytes), );
897+
TU_ASSERT( usbd_edpt_xfer(rhport, p_msc->ep_out, p_msc->ep_buf, nbytes), );
915898
}
916899

917900
// process new data arrived from WRITE10
@@ -927,7 +910,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
927910

928911
// Invoke callback to consume new data
929912
uint32_t const offset = p_msc->xferred_len % block_sz;
930-
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, _mscd_buf, xferred_bytes);
913+
int32_t nbytes = tud_msc_write10_cb(p_cbw->lun, lba, offset, p_msc->ep_buf, xferred_bytes);
931914

932915
if ( nbytes < 0 )
933916
{
@@ -950,7 +933,7 @@ static void proc_write10_new_data(uint8_t rhport, mscd_interface_t* p_msc, uint3
950933
if ( nbytes > 0 )
951934
{
952935
p_msc->xferred_len += (uint16_t) nbytes;
953-
memmove(_mscd_buf, _mscd_buf+nbytes, left_over);
936+
memmove(p_msc->ep_buf, p_msc->ep_buf+nbytes, left_over);
954937
}
955938

956939
// simulate an transfer complete with adjusted parameters --> callback will be invoked with adjusted parameter

src/common/tusb_common.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@
5858
// Generate a mask with bit from high (31) to low (0) set, e.g TU_GENMASK(3, 0) = 0b1111
5959
#define TU_GENMASK(h, l) ( (UINT32_MAX << (l)) & (UINT32_MAX >> (31 - (h))) )
6060

61+
// DCache padding for variable to occupy full cache line
62+
#define TUD_DCACHE_PADDING uint8_t TU_XSTRCAT(dcache_padding_, _TU_COUNTER_)[CFG_TUD_MEM_DCACHE_ENABLE ? CFG_TUD_MEM_DCACHE_LINE_SIZE : 1]
63+
6164
//--------------------------------------------------------------------+
6265
// Includes
6366
//--------------------------------------------------------------------+

0 commit comments

Comments
 (0)