Skip to content

Commit d76f7c3

Browse files
bugadaniMabezDev
andauthored
[WIP] Add ESP32-S3 (#8)
* include literal sections in loader linker script * Add ESP32-S3 --------- Co-authored-by: Scott Mabin <scott@mabez.dev>
1 parent 22b65fd commit d76f7c3

File tree

12 files changed

+380
-24
lines changed

12 files changed

+380
-24
lines changed

.cargo/config.toml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
[alias]
2+
esp32s3 = "build --release --features esp32s3 --target xtensa-esp32s3-none-elf"
23
esp32c2 = "build --release --features esp32c2 --target riscv32imc-unknown-none-elf"
34
esp32c3 = "build --release --features esp32c3 --target riscv32imc-unknown-none-elf"
45
esp32c6 = "build --release --features esp32c6 --target riscv32imac-unknown-none-elf"
56
esp32h2 = "build --release --features esp32h2 --target riscv32imac-unknown-none-elf"
67

7-
[target.'cfg(any(target_arch = "xtensa", target_arch = "riscv32"))']
8+
[target.'cfg(target_arch = "riscv32")']
89
rustflags = [
910
"-C", "link-arg=-Tld/loader.x",
1011
"-C", "link-args=-Map=target/esp-loader.map",
1112
"-C", "link-args=--nmagic",
1213
]
1314

15+
[target.'cfg(target_arch = "xtensa")']
16+
rustflags = [
17+
"-C", "linker=rust-lld",
18+
"-C", "link-arg=-Tld/loader.x"
19+
]
20+
1421
[unstable]
1522
build-std = [ "core" ]

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ ufmt = { version = "0.1.0", optional = true }
1313
log = ["ufmt"]
1414

1515
# targets
16+
esp32s3 = []
1617
esp32c2 = []
1718
esp32c3 = []
1819
esp32c6 = []

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ $ target-gen elf target/riscv32imc-unknown-none-elf/release/esp-flashloader outp
2222
| ------- | --------- |
2323
| esp32 | N |
2424
| esp32s2 | N |
25-
| esp32s3 | N |
25+
| esp32s3 | Y |
2626
| esp32c2 | Y |
2727
| esp32c3 | Y |
2828
| esp32c6 | Y |

build.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ use std::{env, fs};
33

44
fn main() {
55
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
6-
println!("cargo:rustc-link-search)={}", out_dir.display());
6+
println!("cargo:rustc-link-search={}", out_dir.display());
77

88
fs::copy("ld/loader.x", out_dir.join("loader.x")).unwrap();
99
println!("cargo:rerun-if-changed=ld/loader.x");
1010

11+
#[cfg(feature = "esp32s3")]
12+
let chip = "esp32s3";
1113
#[cfg(feature = "esp32c2")]
1214
let chip = "esp32c2";
1315
#[cfg(feature = "esp32c3")]

ld/esp32c3.x

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
2-
31
MEMORY {
42
/* Start 64k into the RAM region */
53
IRAM : ORIGIN = 0x40390000, LENGTH = 0x40000

ld/esp32s3.x

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
MEMORY {
2+
/* SRAM2 + 0x8400 */
3+
IRAM : ORIGIN = 0x40380400, LENGTH = 0x40000
4+
}
5+
6+
/* ROM function interface esp32s3.rom.ld for esp32s3
7+
*
8+
*
9+
* Generated from ./interface-esp32s3.yml md5sum 39c4ce259b11323b9404c192b01b712b
10+
*
11+
* Compatible with ROM where ECO version equal or greater to 0.
12+
*
13+
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
14+
*/
15+
16+
PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach );
17+
18+
/***************************************
19+
Group miniz
20+
***************************************/
21+
22+
/* Functions */
23+
mz_adler32 = 0x4000078c;
24+
mz_crc32 = 0x40000798;
25+
mz_free = 0x400007a4;
26+
tdefl_compress = 0x400007b0;
27+
tdefl_compress_buffer = 0x400007bc;
28+
tdefl_compress_mem_to_heap = 0x400007c8;
29+
tdefl_compress_mem_to_mem = 0x400007d4;
30+
tdefl_compress_mem_to_output = 0x400007e0;
31+
tdefl_get_adler32 = 0x400007ec;
32+
tdefl_get_prev_return_status = 0x400007f8;
33+
tdefl_init = 0x40000804;
34+
tdefl_write_image_to_png_file_in_memory = 0x40000810;
35+
tdefl_write_image_to_png_file_in_memory_ex = 0x4000081c;
36+
tinfl_decompress = 0x40000828;
37+
tinfl_decompress_mem_to_callback = 0x40000834;
38+
tinfl_decompress_mem_to_heap = 0x40000840;
39+
tinfl_decompress_mem_to_mem = 0x4000084c;
40+
41+
/***************************************
42+
Group opi_flash
43+
***************************************/
44+
45+
/* Functions */
46+
PROVIDE( opi_flash_set_lock_func = 0x40000870 );
47+
PROVIDE( esp_rom_spi_cmd_config = 0x4000087c );
48+
PROVIDE( esp_rom_spi_cmd_start = 0x40000888 );
49+
PROVIDE( esp_rom_opiflash_pin_config = 0x40000894 );
50+
PROVIDE( esp_rom_spi_set_op_mode = 0x400008a0 );
51+
PROVIDE( esp_rom_opiflash_mode_reset = 0x400008ac );
52+
PROVIDE( esp_rom_opiflash_exec_cmd = 0x400008b8 );
53+
PROVIDE( esp_rom_opiflash_soft_reset = 0x400008c4 );
54+
PROVIDE( esp_rom_opiflash_read_id = 0x400008d0 );
55+
PROVIDE( esp_rom_opiflash_rdsr = 0x400008dc );
56+
PROVIDE( esp_rom_opiflash_wait_idle = 0x400008e8 );
57+
PROVIDE( esp_rom_opiflash_wren = 0x400008f4 );
58+
PROVIDE( esp_rom_opiflash_erase_sector = 0x40000900 );
59+
PROVIDE( esp_rom_opiflash_erase_block_64k = 0x4000090c );
60+
PROVIDE( esp_rom_opiflash_erase_area = 0x40000918 );
61+
PROVIDE( esp_rom_opiflash_read = 0x40000924 );
62+
PROVIDE( esp_rom_opiflash_write = 0x40000930 );
63+
PROVIDE( esp_rom_spi_set_dtr_swap_mode = 0x4000093c );
64+
PROVIDE( esp_rom_opiflash_exit_continuous_read_mode = 0x40000948 );
65+
PROVIDE( esp_rom_opiflash_legacy_driver_init = 0x40000954 );
66+
PROVIDE( esp_rom_opiflash_read_raw = 0x4004d9d4);
67+
68+
/***************************************
69+
Group spiflash_legacy
70+
***************************************/
71+
72+
/* Functions */
73+
PROVIDE( esp_rom_spiflash_wait_idle = 0x40000960 );
74+
PROVIDE( esp_rom_spiflash_write_encrypted = 0x4000096c );
75+
PROVIDE( esp_rom_spiflash_write_encrypted_dest = 0x40000978 );
76+
PROVIDE( esp_rom_spiflash_write_encrypted_enable = 0x40000984 );
77+
PROVIDE( esp_rom_spiflash_write_encrypted_disable = 0x40000990 );
78+
PROVIDE( esp_rom_spiflash_erase_chip = 0x4000099c );
79+
PROVIDE( _esp_rom_spiflash_erase_sector = 0x400009a8 );
80+
PROVIDE( _esp_rom_spiflash_erase_block = 0x400009b4 );
81+
PROVIDE( _esp_rom_spiflash_write = 0x400009c0 );
82+
PROVIDE( _esp_rom_spiflash_read = 0x400009cc );
83+
PROVIDE( _esp_rom_spiflash_unlock = 0x400009d8 );
84+
PROVIDE( _SPIEraseArea = 0x400009e4 );
85+
PROVIDE( _SPI_write_enable = 0x400009f0 );
86+
PROVIDE( esp_rom_spiflash_erase_sector = 0x400009fc );
87+
PROVIDE( esp_rom_spiflash_erase_block = 0x40000a08 );
88+
PROVIDE( esp_rom_spiflash_write = 0x40000a14 );
89+
PROVIDE( esp_rom_spiflash_read = 0x40000a20 );
90+
PROVIDE( esp_rom_spiflash_unlock = 0x40000a2c );
91+
PROVIDE( SPIEraseArea = 0x40000a38 );
92+
PROVIDE( SPI_write_enable = 0x40000a44 );
93+
PROVIDE( esp_rom_spiflash_config_param = 0x40000a50 );
94+
PROVIDE( esp_rom_spiflash_read_user_cmd = 0x40000a5c );
95+
PROVIDE( esp_rom_spiflash_select_qio_pins = 0x40000a68 );
96+
PROVIDE( esp_rom_spi_flash_auto_sus_res = 0x40000a74 );
97+
PROVIDE( esp_rom_spi_flash_send_resume = 0x40000a80 );
98+
PROVIDE( esp_rom_spi_flash_update_id = 0x40000a8c );
99+
PROVIDE( esp_rom_spiflash_config_clk = 0x40000a98 );
100+
PROVIDE( esp_rom_spiflash_config_readmode = 0x40000aa4 );
101+
PROVIDE( esp_rom_spiflash_read_status = 0x40000ab0 );
102+
PROVIDE( esp_rom_spiflash_read_statushigh = 0x40000abc );
103+
PROVIDE( esp_rom_spiflash_write_status = 0x40000ac8 );
104+
PROVIDE( esp_rom_opiflash_cache_mode_config = 0x40000ad4 );
105+
PROVIDE( esp_rom_spiflash_auto_wait_idle = 0x40000ae0 );
106+
PROVIDE( spi_flash_attach = 0x40000aec );
107+
PROVIDE( spi_flash_get_chip_size = 0x40000af8 );
108+
PROVIDE( spi_flash_guard_set = 0x40000b04 );
109+
PROVIDE( spi_flash_guard_get = 0x40000b10 );
110+
PROVIDE( spi_flash_write_config_set = 0x40000b1c );
111+
PROVIDE( spi_flash_write_config_get = 0x40000b28 );
112+
PROVIDE( spi_flash_safe_write_address_func_set = 0x40000b34 );
113+
PROVIDE( spi_flash_unlock = 0x40000b40 );
114+
PROVIDE( spi_flash_erase_range = 0x40000b4c );
115+
PROVIDE( spi_flash_erase_sector = 0x40000b58 );
116+
PROVIDE( spi_flash_write = 0x40000b64 );
117+
PROVIDE( spi_flash_read = 0x40000b70 );
118+
PROVIDE( spi_flash_write_encrypted = 0x40000b7c );
119+
PROVIDE( spi_flash_read_encrypted = 0x40000b88 );
120+
PROVIDE( spi_flash_mmap_os_func_set = 0x40000b94 );
121+
PROVIDE( spi_flash_mmap_page_num_init = 0x40000ba0 );
122+
PROVIDE( spi_flash_mmap = 0x40000bac );
123+
PROVIDE( spi_flash_mmap_pages = 0x40000bb8 );
124+
PROVIDE( spi_flash_munmap = 0x40000bc4 );
125+
PROVIDE( spi_flash_mmap_dump = 0x40000bd0 );
126+
PROVIDE( spi_flash_check_and_flush_cache = 0x40000bdc );
127+
PROVIDE( spi_flash_mmap_get_free_pages = 0x40000be8 );
128+
PROVIDE( spi_flash_cache2phys = 0x40000bf4 );
129+
PROVIDE( spi_flash_phys2cache = 0x40000c00 );
130+
PROVIDE( spi_flash_disable_cache = 0x40000c0c );
131+
PROVIDE( spi_flash_restore_cache = 0x40000c18 );
132+
PROVIDE( spi_flash_cache_enabled = 0x40000c24 );
133+
PROVIDE( spi_flash_enable_cache = 0x40000c30 );
134+
PROVIDE( spi_cache_mode_switch = 0x40000c3c );
135+
PROVIDE( spi_common_set_dummy_output = 0x40000c48 );
136+
PROVIDE( spi_common_set_flash_cs_timing = 0x40000c54 );
137+
PROVIDE( esp_rom_spi_set_address_bit_len = 0x40000c60 );
138+
PROVIDE( esp_enable_cache_flash_wrap = 0x40000c6c );
139+
PROVIDE( SPILock = 0x40000c78 );
140+
PROVIDE( SPIMasterReadModeCnfig = 0x40000c84 );
141+
PROVIDE( SPI_Common_Command = 0x40000c90 );
142+
PROVIDE( SPI_WakeUp = 0x40000c9c );
143+
PROVIDE( SPI_block_erase = 0x40000ca8 );
144+
PROVIDE( SPI_chip_erase = 0x40000cb4 );
145+
PROVIDE( SPI_init = 0x40000cc0 );
146+
PROVIDE( SPI_page_program = 0x40000ccc );
147+
PROVIDE( SPI_read_data = 0x40000cd8 );
148+
PROVIDE( SPI_sector_erase = 0x40000ce4 );
149+
PROVIDE( SelectSpiFunction = 0x40000cf0 );
150+
PROVIDE( SetSpiDrvs = 0x40000cfc );
151+
PROVIDE( Wait_SPI_Idle = 0x40000d08 );
152+
PROVIDE( spi_dummy_len_fix = 0x40000d14 );
153+
PROVIDE( Disable_QMode = 0x40000d20 );
154+
PROVIDE( Enable_QMode = 0x40000d2c );
155+
156+
157+
/* Functions */
158+
ets_efuse_get_spiconfig = 0x40001f74;

ld/loader.x

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,15 @@ SECTIONS {
1313
* KEEP statement here.
1414
*/
1515

16-
KEEP(*(.text))
17-
KEEP(*(.text.*))
16+
KEEP(*(.literal))
17+
KEEP(*(.literal.*))
1818

1919
KEEP(*(.rodata))
2020
KEEP(*(.rodata.*))
2121

22+
KEEP(*(.text))
23+
KEEP(*(.text.*))
24+
2225
KEEP(*(.srodata .srodata.*))
2326

2427
*(.data .data.*)

src/api.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// Setup the device for the flashing process.
2+
#[no_mangle]
3+
pub unsafe extern "C" fn Init(adr: u32, clk: u32, fnc: u32) -> i32 {
4+
crate::Init_impl(adr, clk, fnc)
5+
}
6+
7+
/// Erase the sector at the given address in flash
8+
///
9+
/// Returns 0 on success, 1 on failure.
10+
#[no_mangle]
11+
pub unsafe extern "C" fn EraseSector(adr: u32) -> i32 {
12+
crate::EraseSector_impl(adr)
13+
}
14+
15+
#[no_mangle]
16+
pub unsafe extern "C" fn EraseChip() -> i32 {
17+
crate::EraseChip_impl()
18+
}
19+
20+
#[no_mangle]
21+
pub unsafe extern "C" fn ProgramPage(adr: u32, sz: u32, buf: *const u8) -> i32 {
22+
crate::ProgramPage_impl(adr, sz, buf)
23+
}
24+
25+
#[no_mangle]
26+
pub unsafe extern "C" fn UnInit(fnc: u32) -> i32 {
27+
crate::UnInit_impl(fnc)
28+
}

src/api_xtensa.rs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
use core::arch::asm;
2+
3+
// Probe-rs doesn't know how to call a function on the Xtensa architecture. Due to the windowed
4+
// ABI, just jumping to the function address won't work. Instead, we need to use a call<N>
5+
// instruction, which will set up the window increment and then jump to the function address.
6+
7+
#[cfg(feature = "esp32s3")]
8+
#[no_mangle]
9+
// End of SRAM1 - DATA_CACHE_SIZE
10+
static STACK_PTR: u32 = 0x3FCD_0000;
11+
12+
/// Setup the device for the flashing process.
13+
#[no_mangle]
14+
#[naked]
15+
pub unsafe extern "C" fn Init(adr: u32, clk: u32, fnc: u32) -> i32 {
16+
asm!(
17+
"
18+
.global Init_impl
19+
l32r a1, STACK_PTR
20+
mov.n a6, a2
21+
mov.n a7, a3
22+
mov.n a8, a4
23+
call4 Init_impl
24+
mov.n a2, a6
25+
",
26+
options(noreturn)
27+
)
28+
}
29+
30+
/// Erase the sector at the given address in flash
31+
///
32+
/// Returns 0 on success, 1 on failure.
33+
#[no_mangle]
34+
#[naked]
35+
pub unsafe extern "C" fn EraseSector(adr: u32) -> i32 {
36+
asm!(
37+
"
38+
.global EraseSector_impl
39+
l32r a1, STACK_PTR
40+
mov.n a6, a2
41+
call4 EraseSector_impl
42+
mov.n a2, a6
43+
",
44+
options(noreturn)
45+
)
46+
}
47+
48+
#[no_mangle]
49+
#[naked]
50+
pub unsafe extern "C" fn EraseChip() -> i32 {
51+
asm!(
52+
"
53+
.global EraseChip_impl
54+
l32r a1, STACK_PTR
55+
call4 EraseChip_impl
56+
mov.n a2, a6
57+
",
58+
options(noreturn)
59+
)
60+
}
61+
62+
#[no_mangle]
63+
#[naked]
64+
pub unsafe extern "C" fn ProgramPage(adr: u32, sz: u32, buf: *const u8) -> i32 {
65+
asm!(
66+
"
67+
.global ProgramPage_impl
68+
l32r a1, STACK_PTR
69+
mov.n a6, a2
70+
mov.n a7, a3
71+
mov.n a8, a4
72+
call4 ProgramPage_impl
73+
mov.n a2, a6
74+
",
75+
options(noreturn)
76+
)
77+
}
78+
79+
#[no_mangle]
80+
#[naked]
81+
pub unsafe extern "C" fn UnInit(fnc: u32) -> i32 {
82+
asm!(
83+
"
84+
.global UnInit_impl
85+
l32r a1, STACK_PTR
86+
mov.n a6, a2
87+
call4 UnInit_impl
88+
mov.n a2, a6
89+
",
90+
options(noreturn)
91+
)
92+
}

0 commit comments

Comments
 (0)