Explorar o código

RP2040: Fix crash when responding to WDTR request.

The RP2040 accelerated SCSI routine in refill_dmabuf() accesses data in 16-bit words for speed.
Cortex-M0 crashes on unaligned access.

Most SCSI data transfer requests are from aligned RAM buffer,
but the responses to some negotiation messages are constants from flash.
In this case the negative response to Wide Data Transfer Request was
unaligned in flash.

Added a check for buffer alignment and use the slower byte-per-byte transfer
for unaligned buffers. Because it is just a few bytes speed doesn't matter here.
Petteri Aimonen %!s(int64=3) %!d(string=hai) anos
pai
achega
ef189f0757

+ 1 - 1
lib/ZuluSCSI_platform_RP2040/scsiHostPhy.cpp

@@ -204,7 +204,7 @@ bool scsiHostRead(uint8_t *data, uint32_t count)
 {
     int parityError = 0;
 
-    if ((count & 1) == 0)
+    if ((count & 1) == 0 && ((uint32_t)data & 1) == 0)
     {
         // Even number of bytes, use accelerated routine
         scsi_accel_host_read(data, count, &parityError, &g_scsiHostPhyReset);

+ 2 - 2
lib/ZuluSCSI_platform_RP2040/scsiPhy.cpp

@@ -278,7 +278,7 @@ extern "C" void scsiStartWrite(const uint8_t* data, uint32_t count)
 {
     scsiLogDataIn(data, count);
 
-    if ((count & 1) != 0)
+    if ((count & 1) != 0 || ((uint32_t)data & 1) != 0)
     {
         // Unaligned write, do it byte-by-byte
         scsiFinishWrite();
@@ -339,7 +339,7 @@ extern "C" void scsiRead(uint8_t* data, uint32_t count, int* parityError)
 {
     *parityError = 0;
 
-    if ((count & 1) != 0)
+    if ((count & 1) != 0 || ((uint32_t)data & 1) != 0)
     {
         // Unaligned transfer, do byte by byte
         for (uint32_t i = 0; i < count; i++)