mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 01:06:50 +02:00
Reduce patch sections space of DATEL platform (#108)
This commit is contained in:
@@ -15,9 +15,13 @@ public:
|
|||||||
{
|
{
|
||||||
return new DatelReadSpiBytePatchCode(patchHeap);
|
return new DatelReadSpiBytePatchCode(patchHeap);
|
||||||
});
|
});
|
||||||
|
auto cycleSpi = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
|
{
|
||||||
|
return new DatelCycleSpiPatchCode(patchHeap);
|
||||||
|
});
|
||||||
auto sendSdio = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
auto sendSdio = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
{
|
{
|
||||||
return new DatelSendSdioCommandPatchCode(patchHeap, spi);
|
return new DatelSendSdioCommandPatchCode(patchHeap, spi, cycleSpi);
|
||||||
});
|
});
|
||||||
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
{
|
{
|
||||||
@@ -32,9 +36,13 @@ public:
|
|||||||
{
|
{
|
||||||
return new DatelReadSpiBytePatchCode(patchHeap);
|
return new DatelReadSpiBytePatchCode(patchHeap);
|
||||||
});
|
});
|
||||||
|
auto cycleSpi = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
|
{
|
||||||
|
return new DatelCycleSpiPatchCode(patchHeap);
|
||||||
|
});
|
||||||
auto sendSdio = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
auto sendSdio = patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
{
|
{
|
||||||
return new DatelSendSdioCommandPatchCode(patchHeap, spi);
|
return new DatelSendSdioCommandPatchCode(patchHeap, spi, cycleSpi);
|
||||||
});
|
});
|
||||||
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
return patchCodeCollection.GetOrAddSharedPatchCode([&]
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "patches/PatchCode.h"
|
#include "patches/PatchCode.h"
|
||||||
|
|
||||||
DEFINE_SECTION_SYMBOLS(datel_read_spi);
|
DEFINE_SECTION_SYMBOLS(datel_read_spi);
|
||||||
|
DEFINE_SECTION_SYMBOLS(datel_cycle_spi);
|
||||||
DEFINE_SECTION_SYMBOLS(datel_spi_send);
|
DEFINE_SECTION_SYMBOLS(datel_spi_send);
|
||||||
|
|
||||||
extern "C" u8 datel_readSpiByte();
|
extern "C" u8 datel_readSpiByte();
|
||||||
@@ -11,11 +12,14 @@ extern "C" u16 datel_readSpiShort();
|
|||||||
extern "C" u8 datel_readSpiByteTimeout();
|
extern "C" u8 datel_readSpiByteTimeout();
|
||||||
extern "C" bool datel_waitSpiByteTimeout();
|
extern "C" bool datel_waitSpiByteTimeout();
|
||||||
|
|
||||||
|
extern "C" void datel_cycleSpi();
|
||||||
|
|
||||||
extern "C" u8 datel_spiSendSDIOCommandR0(u32 arg, u8 cmd);
|
extern "C" u8 datel_spiSendSDIOCommandR0(u32 arg, u8 cmd);
|
||||||
extern "C" u8 datel_spiSendSDIOCommand(u32 arg, u8 cmd, int extraBytes);
|
extern "C" u8 datel_spiSendSDIOCommand(u32 arg, u8 cmd, int extraBytes);
|
||||||
|
|
||||||
extern u32 datel_spiSendSDIOCommandR0_ReadWriteSpiByte;
|
extern u32 datel_spiSendSDIOCommandR0_CycleSpi;
|
||||||
extern u32 datel_spiSendSDIOCommandR0_ReadSpiByteTimeout;
|
extern u32 datel_spiSendSDIOCommandR0_ReadSpiByteTimeout;
|
||||||
|
extern u32 datel_spiSendSDIOCommandR0_ReadWriteSpiByte;
|
||||||
|
|
||||||
class DatelReadSpiBytePatchCode : public PatchCode
|
class DatelReadSpiBytePatchCode : public PatchCode
|
||||||
{
|
{
|
||||||
@@ -49,14 +53,29 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DatelCycleSpiPatchCode : public PatchCode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit DatelCycleSpiPatchCode(PatchHeap& patchHeap)
|
||||||
|
: PatchCode(SECTION_START(datel_cycle_spi), SECTION_SIZE(datel_cycle_spi), patchHeap) { }
|
||||||
|
|
||||||
|
const void* GetCycleSpiFunction() const
|
||||||
|
{
|
||||||
|
return GetAddressAtTarget((void*)datel_cycleSpi);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class DatelSendSdioCommandPatchCode : public PatchCode
|
class DatelSendSdioCommandPatchCode : public PatchCode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DatelSendSdioCommandPatchCode(PatchHeap& patchHeap, const DatelReadSpiBytePatchCode* datelReadSpiBytePatchCode)
|
DatelSendSdioCommandPatchCode(PatchHeap& patchHeap,
|
||||||
|
const DatelReadSpiBytePatchCode* datelReadSpiBytePatchCode,
|
||||||
|
const DatelCycleSpiPatchCode* datelCycleSpiPatchCode)
|
||||||
: PatchCode(SECTION_START(datel_spi_send), SECTION_SIZE(datel_spi_send), patchHeap)
|
: PatchCode(SECTION_START(datel_spi_send), SECTION_SIZE(datel_spi_send), patchHeap)
|
||||||
{
|
{
|
||||||
datel_spiSendSDIOCommandR0_ReadWriteSpiByte = (u32)datelReadSpiBytePatchCode->GetReadWriteSpiByteFunction();
|
datel_spiSendSDIOCommandR0_CycleSpi = (u32)datelCycleSpiPatchCode->GetCycleSpiFunction();
|
||||||
datel_spiSendSDIOCommandR0_ReadSpiByteTimeout = (u32)datelReadSpiBytePatchCode->GetReadSpiByteTimeoutFunction();
|
datel_spiSendSDIOCommandR0_ReadSpiByteTimeout = (u32)datelReadSpiBytePatchCode->GetReadSpiByteTimeoutFunction();
|
||||||
|
datel_spiSendSDIOCommandR0_ReadWriteSpiByte = (u32)datelReadSpiBytePatchCode->GetReadWriteSpiByteFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* GetSpiSendSDIOCommandR0Function() const
|
const void* GetSpiSendSDIOCommandR0Function() const
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ BEGIN_ASM_FUNC datel_readSpiByte
|
|||||||
movs r0, 0xFF
|
movs r0, 0xFF
|
||||||
@u8 datel_readWriteSpiByte(u8);
|
@u8 datel_readWriteSpiByte(u8);
|
||||||
BEGIN_ASM_FUNC datel_readWriteSpiByte
|
BEGIN_ASM_FUNC datel_readWriteSpiByte
|
||||||
push {r1-r3, lr}
|
push {r1-r3}
|
||||||
ldr r3, =REG_MCCNT0
|
ldr r3, =REG_MCCNT0
|
||||||
@ Wait if there's a transfer in progress (can happen if the random byte sent by the cycle spi function is still on its way)
|
@ Wait if there's a transfer in progress (can happen if the random byte sent by the cycle spi function is still on its way)
|
||||||
1:
|
1:
|
||||||
@@ -27,7 +27,8 @@ BEGIN_ASM_FUNC datel_readWriteSpiByte
|
|||||||
@uppper half always 0
|
@uppper half always 0
|
||||||
ldrh r0, [r3, #2]
|
ldrh r0, [r3, #2]
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
pop {r1-r3, pc}
|
pop {r1-r3}
|
||||||
|
mov pc,lr
|
||||||
|
|
||||||
@u16 datel_readWriteSpiShort();
|
@u16 datel_readWriteSpiShort();
|
||||||
BEGIN_ASM_FUNC datel_readSpiShort
|
BEGIN_ASM_FUNC datel_readSpiShort
|
||||||
@@ -53,12 +54,13 @@ BEGIN_ASM_FUNC datel_readSpiByteTimeout
|
|||||||
subs r4, r4, #1
|
subs r4, r4, #1
|
||||||
bne 1b
|
bne 1b
|
||||||
1:
|
1:
|
||||||
pop {r1-r4, pc}
|
pop {r1-r4,pc}
|
||||||
|
|
||||||
@bool datel_waitSpiByteTimeout();
|
@bool datel_waitSpiByteTimeout();
|
||||||
BEGIN_ASM_FUNC datel_waitSpiByteTimeout
|
BEGIN_ASM_FUNC datel_waitSpiByteTimeout
|
||||||
push {r1-r4, lr}
|
push {r1-r4}
|
||||||
@ use a timeout of 0x1000 instead of 0xFFFF, easier to setup
|
push {lr}
|
||||||
|
@ use a timeout of 0x10000 instead of 0xFFFF, easier to setup
|
||||||
@ ldr r2, =DATEL_SD_WRITE_TIMEOUT_LEN
|
@ ldr r2, =DATEL_SD_WRITE_TIMEOUT_LEN
|
||||||
movs r2, #1
|
movs r2, #1
|
||||||
lsls r2, #16
|
lsls r2, #16
|
||||||
@@ -69,15 +71,19 @@ BEGIN_ASM_FUNC datel_waitSpiByteTimeout
|
|||||||
bne 1b
|
bne 1b
|
||||||
|
|
||||||
movs r0, #0
|
movs r0, #0
|
||||||
pop {r1-r4, pc}
|
b end
|
||||||
|
|
||||||
1:
|
1:
|
||||||
movs r0, #1
|
movs r0, #1
|
||||||
pop {r1-r4, pc}
|
end:
|
||||||
|
pop {r1}
|
||||||
|
mov lr,r1
|
||||||
|
pop {r1-r4}
|
||||||
|
mov pc,lr
|
||||||
|
|
||||||
.section "datel_spi_send", "ax"
|
.section "datel_cycle_spi", "ax"
|
||||||
@void datel_cycleSpi();
|
@void datel_cycleSpi();
|
||||||
datel_cycleSpi:
|
BEGIN_ASM_FUNC datel_cycleSpi
|
||||||
push {r0-r5, lr}
|
push {r0-r5, lr}
|
||||||
adr r0, datel_cycleSpi_data
|
adr r0, datel_cycleSpi_data
|
||||||
ldm r0!, {r1,r3,r4}
|
ldm r0!, {r1,r3,r4}
|
||||||
@@ -106,7 +112,14 @@ datel_sendNtrCommandF2:
|
|||||||
beq datel_sendNtrCommandF2
|
beq datel_sendNtrCommandF2
|
||||||
|
|
||||||
pop {r0-r5, pc}
|
pop {r0-r5, pc}
|
||||||
|
.balign 4
|
||||||
|
.pool
|
||||||
|
datel_cycleSpi_data:
|
||||||
|
.word REG_MCCNT0
|
||||||
|
.word 0x00FFA040 @ MCCNT0_MODE_SPI | MCCNT0_SPI_HOLD_CS | MCCNT0_ENABLE in lower 16 bit, 0xFF in upper 16
|
||||||
|
.word 0xA07F6000 @ MCCNT1_RESET_OFF | MCCNT1_CMD_SCRAMBLE | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_LATENCY2(0x3F)
|
||||||
|
|
||||||
|
.section "datel_spi_send", "ax"
|
||||||
@ NOTE!!!: This function needs to set r0 last with mov or something similar so that it updates the zero flags
|
@ NOTE!!!: This function needs to set r0 last with mov or something similar so that it updates the zero flags
|
||||||
@u8 datel_spiSendSDIOCommandR0(u32 arg, u8 cmd);
|
@u8 datel_spiSendSDIOCommandR0(u32 arg, u8 cmd);
|
||||||
BEGIN_ASM_FUNC datel_spiSendSDIOCommandR0
|
BEGIN_ASM_FUNC datel_spiSendSDIOCommandR0
|
||||||
@@ -115,12 +128,14 @@ BEGIN_ASM_FUNC datel_spiSendSDIOCommandR0
|
|||||||
BEGIN_ASM_FUNC datel_spiSendSDIOCommand
|
BEGIN_ASM_FUNC datel_spiSendSDIOCommand
|
||||||
push {r0-r7, lr}
|
push {r0-r7, lr}
|
||||||
|
|
||||||
bl datel_cycleSpi
|
ldr r3, datel_spiSendSDIOCommandR0_CycleSpi
|
||||||
|
@ branch to datel_cycleSpi
|
||||||
|
bl datel_spiSendSDIOCommandR0_InterworkR3
|
||||||
|
|
||||||
adr r4, datel_spiSendSDIOCommandR0_ReadSpiByteTimeout
|
adr r3, datel_spiSendSDIOCommandR0_ReadSpiByteTimeout
|
||||||
@ r3 contains ReadSpiByteTimeout
|
@ r3 contains ReadSpiByteTimeout
|
||||||
@ r7 contains ReadWriteSpiByte
|
@ r7 contains ReadWriteSpiByte
|
||||||
ldm r4!, {r3,r7}
|
ldm r3, {r3,r7}
|
||||||
|
|
||||||
@ we use the cmd and arg directly from the stack
|
@ we use the cmd and arg directly from the stack
|
||||||
@ r0 is on top, r1 is right below, we read the command id as the last byte pushed of r1,
|
@ r0 is on top, r1 is right below, we read the command id as the last byte pushed of r1,
|
||||||
@@ -157,7 +172,9 @@ BEGIN_ASM_FUNC datel_spiSendSDIOCommand
|
|||||||
bcc datel_spiSendSDIOCommandR0_Interwork
|
bcc datel_spiSendSDIOCommandR0_Interwork
|
||||||
movs r0, r6
|
movs r0, r6
|
||||||
pop {r1}
|
pop {r1}
|
||||||
pop {r1-r7, pc}
|
pop {r1-r7}
|
||||||
|
pop {r2}
|
||||||
|
mov pc,r2
|
||||||
|
|
||||||
datel_spiSendSDIOCommandR0_Interwork:
|
datel_spiSendSDIOCommandR0_Interwork:
|
||||||
bx r7
|
bx r7
|
||||||
@@ -165,10 +182,9 @@ datel_spiSendSDIOCommandR0_InterworkR3:
|
|||||||
bx r3
|
bx r3
|
||||||
.balign 4
|
.balign 4
|
||||||
.pool
|
.pool
|
||||||
datel_cycleSpi_data:
|
.global datel_spiSendSDIOCommandR0_CycleSpi
|
||||||
.word REG_MCCNT0
|
datel_spiSendSDIOCommandR0_CycleSpi:
|
||||||
.word 0x00FFA040 @ MCCNT0_MODE_SPI | MCCNT0_SPI_HOLD_CS | MCCNT0_ENABLE in lower 16 bit, 0xFF in upper 16
|
.word 0
|
||||||
.word 0xA07F6000 @ MCCNT1_RESET_OFF | MCCNT1_CMD_SCRAMBLE | MCCNT1_READ_DATA_DESCRAMBLE | MCCNT1_CLOCK_SCRAMBLER | MCCNT1_LATENCY2(0x3F)
|
|
||||||
.global datel_spiSendSDIOCommandR0_ReadSpiByteTimeout
|
.global datel_spiSendSDIOCommandR0_ReadSpiByteTimeout
|
||||||
datel_spiSendSDIOCommandR0_ReadSpiByteTimeout:
|
datel_spiSendSDIOCommandR0_ReadSpiByteTimeout:
|
||||||
.word 0
|
.word 0
|
||||||
|
|||||||
@@ -29,7 +29,10 @@ datel_writeSectorSdhcLabel:
|
|||||||
movs r1, DATEL_SDIO_CMD25_WRITE_MULTIPLE_BLOCK
|
movs r1, DATEL_SDIO_CMD25_WRITE_MULTIPLE_BLOCK
|
||||||
movs r2, #1
|
movs r2, #1
|
||||||
ldr r7, datel_SDWriteMultipleSector_SpiSendSDIOCommand
|
ldr r7, datel_SDWriteMultipleSector_SpiSendSDIOCommand
|
||||||
bl datel_SDWriteMultipleSector_Interwork
|
|
||||||
|
@ call datel_readSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r7
|
||||||
bne CMD25_not_ok
|
bne CMD25_not_ok
|
||||||
|
|
||||||
@ r6 contains datel_SDWriteMultipleSector_WaitSpiByteTimeout
|
@ r6 contains datel_SDWriteMultipleSector_WaitSpiByteTimeout
|
||||||
@@ -49,11 +52,15 @@ write_next_sector:
|
|||||||
@ Send start token
|
@ Send start token
|
||||||
movs r0, DATEL_SPI_MULTI_BLOCK_WRITE_TOKEN
|
movs r0, DATEL_SPI_MULTI_BLOCK_WRITE_TOKEN
|
||||||
|
|
||||||
bl datel_SDWriteMultipleSector_InterworkR1 @ call datel_readWriteSpiByte
|
@ call datel_readWriteSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r1
|
||||||
|
|
||||||
write_next_byte:
|
write_next_byte:
|
||||||
ldrb r0, [r4, r5]
|
ldrb r0, [r4, r5]
|
||||||
bl datel_SDWriteMultipleSector_InterworkR1 @ call datel_readWriteSpiByte
|
@ call datel_readWriteSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r1
|
||||||
|
|
||||||
adds r5, #1
|
adds r5, #1
|
||||||
@ Shifting left by 0x17 will set the Zero flag if the number that was shifted is a multiple
|
@ Shifting left by 0x17 will set the Zero flag if the number that was shifted is a multiple
|
||||||
@@ -61,11 +68,17 @@ write_next_byte:
|
|||||||
lsls r0, r5, #0x17
|
lsls r0, r5, #0x17
|
||||||
bne write_next_byte
|
bne write_next_byte
|
||||||
|
|
||||||
@ write dummy crc
|
@ write dummy crc (ignore result)
|
||||||
bl datel_SDWriteMultipleSector_Interwork @ call datel_readSpiByte
|
@ call datel_readSpiByte
|
||||||
bl datel_SDWriteMultipleSector_Interwork @ call datel_readSpiByte
|
mov lr,pc
|
||||||
|
mov pc,r7
|
||||||
|
@ call datel_readSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r7
|
||||||
|
|
||||||
bl datel_SDWriteMultipleSector_Interwork @ call datel_readSpiByte
|
@ call datel_readSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r7
|
||||||
|
|
||||||
@ we check if the lower nibble is equal to DATEL_SD_WRITE_OK
|
@ we check if the lower nibble is equal to DATEL_SD_WRITE_OK
|
||||||
subs r0, DATEL_SD_WRITE_OK
|
subs r0, DATEL_SD_WRITE_OK
|
||||||
@@ -73,7 +86,9 @@ write_next_byte:
|
|||||||
bne write_command_failed
|
bne write_command_failed
|
||||||
|
|
||||||
@ Wait for card to write data
|
@ Wait for card to write data
|
||||||
bl datel_SDWriteMultipleSector_InterworkR6 @ call datel_waitSpiByteTimeout
|
@ call datel_waitSpiByteTimeout
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r6
|
||||||
beq sector_write_timeout_expired
|
beq sector_write_timeout_expired
|
||||||
|
|
||||||
@ r3 holds the total number of bytes to write
|
@ r3 holds the total number of bytes to write
|
||||||
@@ -82,13 +97,21 @@ write_next_byte:
|
|||||||
|
|
||||||
@ send stop token
|
@ send stop token
|
||||||
movs r0, DATEL_SPI_END_MULTI_BLOCK_WRITE
|
movs r0, DATEL_SPI_END_MULTI_BLOCK_WRITE
|
||||||
bl datel_SDWriteMultipleSector_InterworkR1 @ call datel_readWriteSpiByte
|
|
||||||
|
@ call datel_readWriteSpiByte
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r1
|
||||||
|
|
||||||
@ send 1 byte clock
|
@ send 1 byte clock
|
||||||
bl datel_SDWriteMultipleSector_Interwork @ call datel_readSpiByte
|
|
||||||
|
@ call datel_readSpiByte
|
||||||
bl datel_SDWriteMultipleSector_InterworkR6 @ call datel_waitSpiByteTimeout
|
mov lr,pc
|
||||||
|
mov pc,r7
|
||||||
|
|
||||||
|
@ call datel_waitSpiByteTimeout
|
||||||
|
mov lr,pc
|
||||||
|
mov pc,r6
|
||||||
|
|
||||||
@ pop {r1-r7, pc}
|
@ pop {r1-r7, pc}
|
||||||
|
|
||||||
CMD25_not_ok:
|
CMD25_not_ok:
|
||||||
@@ -97,12 +120,6 @@ sector_write_timeout_expired:
|
|||||||
@ movs r0, #0
|
@ movs r0, #0
|
||||||
pop {r1-r7, pc}
|
pop {r1-r7, pc}
|
||||||
|
|
||||||
datel_SDWriteMultipleSector_Interwork:
|
|
||||||
bx r7
|
|
||||||
datel_SDWriteMultipleSector_InterworkR6:
|
|
||||||
bx r6
|
|
||||||
datel_SDWriteMultipleSector_InterworkR1:
|
|
||||||
bx r1
|
|
||||||
.balign 4
|
.balign 4
|
||||||
.pool
|
.pool
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user