[feat] add boot2_copy_self

This commit is contained in:
zhji 2025-04-19 21:07:29 +08:00
parent f40cd252ef
commit ec54eb19e3
4 changed files with 105 additions and 1 deletions

50
driver/inc/reg/ssi_reg.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef __HARDWARE_SSI_REG_H__
#define __HARDWARE_SSI_REG_H__
#include "reg.h"
typedef struct {
io_rw_32 ctrlr0;
io_rw_32 ctrlr1;
io_rw_32 ssienr;
io_rw_32 mwcr;
io_rw_32 ser;
io_rw_32 baudr;
io_rw_32 txftlr;
io_rw_32 rxftlr;
io_rw_32 txflr;
io_rw_32 rxflr;
io_rw_32 sr;
io_rw_32 imr;
io_rw_32 isr;
io_rw_32 risr;
io_rw_32 txoicr;
io_rw_32 rxoicr;
io_rw_32 rxuicr;
io_rw_32 msticr;
io_rw_32 icr;
io_rw_32 dmacr;
io_rw_32 dmatdlr;
io_rw_32 dmardlr;
io_rw_32 idr;
io_rw_32 ssi_version_id;
io_rw_32 dr0;
uint32_t _pad[(0xf0 - 0x60) / 4 - 1];
io_rw_32 rx_sample_dly;
io_rw_32 spi_ctrlr0;
io_rw_32 txd_drive_edge;
} ssi_hw_t;
#define ssi_hw ((ssi_hw_t *const)XIP_SSI_BASE)
#define ssi_hw_set ((ssi_hw_t *const)hw_set_alias_untyped(ssi_hw))
#define ssi_hw_clear ((ssi_hw_t *const)hw_clear_alias_untyped(ssi_hw))
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* __HARDWARE_SSI_REG_H__ */

View File

@ -34,6 +34,7 @@ SECTIONS
.text :
{
. = ALIGN(4);
_boot2_copy_self_start_addr = .;
*(.text*)
. = ALIGN(4);
} >RAM AT > FLASH :text
@ -52,6 +53,8 @@ SECTIONS
. = ALIGN(4);
} >RAM AT > FLASH :data
_boot2_copy_self_end_addr = .;
.bss (NOLOAD) :
{
. = ALIGN(4);

View File

@ -11,6 +11,7 @@ boot2_pre:
msr msp, r0
bl boot2_copy_self
bl main
b .
.word 0x11223344
.word 0xabcdef58

View File

@ -1,6 +1,56 @@
#include "gpio.h"
#include "ssi_reg.h"
void __attribute__((section(".text.boot2_pre"))) boot2_copy_self(void)
{
return;
#define BOOT2_FLASHCMD_READ_DATA (0x03)
#define BOOT2_FLASH_OFFSET (256)
extern uint32_t _boot2_copy_self_start_addr;
extern uint32_t _boot2_copy_self_end_addr;
io_rw_32 *reg;
uint32_t cmd;
uint32_t length, tx_count, rx_count, rx_skip;
uint8_t *copy_to_addr;
uint8_t rxbyte;
/* force QSPI_CS low level as selected */
reg = (io_rw_32 *)(IO_QSPI_BASE + GPIO_QSPI_CS_CTRL_OFFSET);
*reg = GPIO_OVER_OUT_FORCE_LOW << GPIO_OVER_OUT_POS;
/* send command and length */
cmd = (BOOT2_FLASHCMD_READ_DATA << 24) | BOOT2_FLASH_OFFSET;
for (int i = 0; i < 4; ++i) {
ssi_hw->dr0 = cmd >> 24;
cmd <<= 8;
}
/* init parameter */
length = (uint32_t)&_boot2_copy_self_end_addr - (uint32_t)&_boot2_copy_self_start_addr;
tx_count = length;
rx_count = length;
rx_skip = 4;
copy_to_addr = (uint8_t *)&_boot2_copy_self_start_addr;
/* copy data from flash to ram */
while (tx_count || rx_skip || rx_count) {
uint32_t tx_level = ssi_hw->txflr;
uint32_t rx_level = ssi_hw->rxflr;
if (tx_count && tx_level + rx_level < 14) {
ssi_hw->dr0 = 0;
tx_count--;
}
if (rx_level) {
rxbyte = ssi_hw->dr0;
if (rx_skip) {
rx_skip--;
} else {
*copy_to_addr++ = rxbyte;
rx_count--;
}
}
}
/* force QSPI_CS high level as disselected */
*reg = GPIO_OVER_OUT_FORCE_HIGH << GPIO_OVER_OUT_POS;
}
int main(void)