mirror of
https://github.com/esp-rs/esp-hal.git
synced 2025-09-28 04:40:52 +00:00
Add direct-boot support for ESP32-S3 (#107)
* Add direct-boot support for ESP32-S3 * Make sure to use correct alignments * Only enable naked_functions and asm_experimental_arch when direct-boot feature is selected
This commit is contained in:
parent
147d8de988
commit
9fa1d1ecdb
@ -29,6 +29,7 @@ embedded-hal = { version = "0.2", features = ["unproven"] }
|
||||
embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.8" }
|
||||
xtensa-lx = { version = "0.7", features = ["esp32s3"] }
|
||||
xtensa-lx-rt = { version = "0.12", features = ["esp32s3"], optional = true }
|
||||
r0 = { version = "1.0.0", optional = true }
|
||||
|
||||
[dependencies.esp-hal-common]
|
||||
path = "../esp-hal-common"
|
||||
@ -43,6 +44,7 @@ esp-println = { version = "0.2.0", features = ["esp32s3"] }
|
||||
|
||||
[features]
|
||||
default = ["rt"]
|
||||
direct-boot = ["r0"]
|
||||
eh1 = ["esp-hal-common/eh1"]
|
||||
rt = ["xtensa-lx-rt/esp32s3"]
|
||||
ufmt = ["esp-hal-common/ufmt"]
|
||||
|
@ -1,5 +1,6 @@
|
||||
use std::{env, fs::File, io::Write, path::PathBuf};
|
||||
|
||||
#[cfg(not(feature = "direct-boot"))]
|
||||
fn main() {
|
||||
// Put the linker script somewhere the linker can find it
|
||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
@ -34,3 +35,39 @@ fn main() {
|
||||
// instead of when any part of the source code changes.
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
}
|
||||
|
||||
#[cfg(feature = "direct-boot")]
|
||||
fn main() {
|
||||
// Put the linker script somewhere the linker can find it
|
||||
let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
|
||||
File::create(out.join("memory.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("ld/db-memory.x"))
|
||||
.unwrap();
|
||||
|
||||
File::create(out.join("alias.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("ld/rom.x"))
|
||||
.unwrap();
|
||||
|
||||
File::create(out.join("hal-defaults.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("ld/hal-defaults.x"))
|
||||
.unwrap();
|
||||
|
||||
File::create(out.join("esp32s3.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("ld/db-esp32s3.x"))
|
||||
.unwrap();
|
||||
|
||||
File::create(out.join("linkall.x"))
|
||||
.unwrap()
|
||||
.write_all(include_bytes!("ld/linkall.x"))
|
||||
.unwrap();
|
||||
|
||||
println!("cargo:rustc-link-search={}", out.display());
|
||||
|
||||
// Only re-run the build script when memory.x is changed,
|
||||
// instead of when any part of the source code changes.
|
||||
println!("cargo:rerun-if-changed=memory.x");
|
||||
}
|
||||
|
300
esp32s3-hal/ld/db-esp32s3.x
Normal file
300
esp32s3-hal/ld/db-esp32s3.x
Normal file
@ -0,0 +1,300 @@
|
||||
/* before memory.x to allow override */
|
||||
ENTRY(Reset)
|
||||
|
||||
INCLUDE memory.x
|
||||
|
||||
/* map generic regions to output sections */
|
||||
INCLUDE "alias.x"
|
||||
|
||||
_external_ram_start = ABSOLUTE(ORIGIN(psram_seg));
|
||||
_external_ram_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
||||
|
||||
_heap_end = ABSOLUTE(ORIGIN(dram_seg))+LENGTH(dram_seg)+LENGTH(reserved_for_boot_seg) - 2*STACK_SIZE;
|
||||
_text_heap_end = ABSOLUTE(ORIGIN(iram_seg)+LENGTH(iram_seg));
|
||||
_external_heap_end = ABSOLUTE(ORIGIN(psram_seg)+LENGTH(psram_seg));
|
||||
|
||||
_stack_start_cpu1 = _heap_end;
|
||||
_stack_end_cpu1 = _stack_start_cpu1 + STACK_SIZE;
|
||||
_stack_start_cpu0 = _stack_end_cpu1;
|
||||
_stack_end_cpu0 = _stack_start_cpu0 + STACK_SIZE;
|
||||
|
||||
EXTERN(DefaultHandler);
|
||||
|
||||
INCLUDE "device.x"
|
||||
|
||||
/* after memory.x to allow override */
|
||||
PROVIDE(__pre_init = DefaultPreInit);
|
||||
PROVIDE(__zero_bss = default_mem_hook);
|
||||
PROVIDE(__init_data = default_mem_hook);
|
||||
|
||||
/*INCLUDE exception.x*/
|
||||
/* exception vector for the ESP32, requiring high priority interrupts and register window support */
|
||||
|
||||
/* high level exception/interrupt routines, which can be override with Rust functions */
|
||||
PROVIDE(__exception = __default_exception);
|
||||
PROVIDE(__user_exception = __default_user_exception);
|
||||
PROVIDE(__double_exception = __default_double_exception);
|
||||
PROVIDE(__level_1_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_2_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_3_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_4_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_5_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_6_interrupt = __default_interrupt);
|
||||
PROVIDE(__level_7_interrupt = __default_interrupt);
|
||||
|
||||
/* low level exception/interrupt, which must be overridden using naked functions */
|
||||
PROVIDE(__naked_user_exception = __default_naked_exception);
|
||||
PROVIDE(__naked_kernel_exception = __default_naked_exception);
|
||||
PROVIDE(__naked_double_exception = __default_naked_double_exception);
|
||||
PROVIDE(__naked_level_2_interrupt = __default_naked_level_2_interrupt);
|
||||
PROVIDE(__naked_level_3_interrupt = __default_naked_level_3_interrupt);
|
||||
PROVIDE(__naked_level_4_interrupt = __default_naked_level_4_interrupt);
|
||||
PROVIDE(__naked_level_5_interrupt = __default_naked_level_5_interrupt);
|
||||
PROVIDE(__naked_level_6_interrupt = __default_naked_level_6_interrupt);
|
||||
PROVIDE(__naked_level_7_interrupt = __default_naked_level_7_interrupt);
|
||||
|
||||
/* needed to force inclusion of the vectors */
|
||||
EXTERN(__default_exception);
|
||||
EXTERN(__default_double_exception);
|
||||
EXTERN(__default_interrupt);
|
||||
|
||||
EXTERN(__default_naked_exception);
|
||||
EXTERN(__default_naked_double_exception);
|
||||
EXTERN(__default_naked_level_2_interrupt);
|
||||
EXTERN(__default_naked_level_3_interrupt);
|
||||
EXTERN(__default_naked_level_4_interrupt);
|
||||
EXTERN(__default_naked_level_5_interrupt);
|
||||
EXTERN(__default_naked_level_6_interrupt);
|
||||
EXTERN(__default_naked_level_7_interrupt);
|
||||
|
||||
SECTIONS {
|
||||
.pre_header (NOLOAD) : AT(0)
|
||||
{
|
||||
. = . + 0x400;
|
||||
}
|
||||
|
||||
.header ORIGIN(ROTEXT) : AT(0x400)
|
||||
{
|
||||
LONG(0xaedb041d)
|
||||
LONG(0xaedb041d)
|
||||
}
|
||||
|
||||
.text ORIGIN(ROTEXT) + 0x408 : AT(0x408)
|
||||
{
|
||||
_stext = .;
|
||||
. = ALIGN (4);
|
||||
_text_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
KEEP(*(.init));
|
||||
*(.literal .text .literal.* .text.*)
|
||||
. = ALIGN (4);
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
}
|
||||
_text_size = _etext - _stext;
|
||||
|
||||
.rodata ORIGIN(RODATA) + 0x408 + _text_size : AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header))
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.rodata .rodata.*)
|
||||
. = ALIGN (4);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
.rwtext ORIGIN(RWTEXT) + 0x408 + _text_size + SIZEOF(.rodata) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata))
|
||||
{
|
||||
_irwtext = ORIGIN(RODATA) + 0x408 + _text_size + SIZEOF(.rodata);
|
||||
_srwtext = .;
|
||||
|
||||
. = ALIGN (4);
|
||||
|
||||
. = ALIGN(0x1000);
|
||||
_init_start = ABSOLUTE(.);
|
||||
KEEP(*(.WindowOverflow4.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.WindowUnderflow4.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.WindowOverflow8.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.WindowUnderflow8.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.WindowOverflow12.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.WindowUnderflow12.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.Level2InterruptVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.Level3InterruptVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.Level4InterruptVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.Level5InterruptVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.DebugExceptionVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.NMIExceptionVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.KernelExceptionVector.text));
|
||||
. = ALIGN(64);
|
||||
KEEP(*(.UserExceptionVector.text));
|
||||
. = ALIGN(128);
|
||||
KEEP(*(.DoubleExceptionVector.text));
|
||||
. = ALIGN(0x400);
|
||||
|
||||
_init_end = ABSOLUTE(.);
|
||||
|
||||
*(.rwtext.literal .rwtext .rwtext.literal.* .rwtext.*)
|
||||
|
||||
. = ALIGN (4);
|
||||
_erwtext = .;
|
||||
}
|
||||
|
||||
.data ORIGIN(RWDATA) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext))
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.data .data.*)
|
||||
. = ALIGN (4);
|
||||
_data_end = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
|
||||
/* LMA of .data */
|
||||
_sidata = ORIGIN(RODATA) + _text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext);
|
||||
|
||||
.bss (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
_bss_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
*(.bss .bss.* COMMON)
|
||||
. = ALIGN (4);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
} > RWDATA
|
||||
|
||||
.noinit (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.noinit .noinit.*)
|
||||
. = ALIGN (4);
|
||||
} > RWDATA
|
||||
|
||||
.rtc_fast.text ORIGIN(rtc_fast_iram_seg) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_text_start = ABSOLUTE(.);
|
||||
*(.rtc_fast.literal .rtc_fast.text .rtc_fast.literal.* .rtc_fast.text.*)
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_text_end = ABSOLUTE(.);
|
||||
}
|
||||
_irtc_fast_text = ORIGIN(RODATA) + _text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext);
|
||||
|
||||
.rtc_fast.data ORIGIN(rtc_fast_dram_seg) + SIZEOF(.rtc_fast.text) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) + SIZEOF(.rtc_fast.text) )
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_data_start = ABSOLUTE(.);
|
||||
*(.rtc_fast.data .rtc_fast.data.*)
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_data_end = ABSOLUTE(.);
|
||||
}
|
||||
_irtc_fast_data = ORIGIN(RODATA) + _text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) + SIZEOF(.rtc_fast.text);
|
||||
|
||||
.rtc_fast.bss ORIGIN(rtc_fast_dram_seg) + SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) (NOLOAD) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) +
|
||||
SIZEOF(.rwtext) + SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_fast_bss_start = ABSOLUTE(.);
|
||||
*(.rtc_fast.bss .rtc_fast.bss.*)
|
||||
. = ALIGN (4);
|
||||
_rtc_fast_bss_end = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
.rtc_fast.noinit ORIGIN(rtc_fast_dram_seg) + SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss) (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc_fast.noinit .rtc_fast.noinit.*)
|
||||
. = ALIGN (4);
|
||||
}
|
||||
|
||||
.rtc_slow.text ORIGIN(rtc_slow_seg) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) +
|
||||
SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_text_start = ABSOLUTE(.);
|
||||
*(.rtc_slow.literal .rtc_slow.text .rtc_slow.literal.* .rtc_slow.text.*)
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_text_end = ABSOLUTE(.);
|
||||
}
|
||||
_irtc_slow_text = ORIGIN(RODATA) + _text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) +
|
||||
SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss);
|
||||
|
||||
.rtc_slow.data ORIGIN(rtc_slow_seg) + SIZEOF(.rtc_slow.text) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) +
|
||||
SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss) + SIZEOF(.rtc_slow.text))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_data_start = ABSOLUTE(.);
|
||||
*(.rtc_slow.data .rtc_slow.data.*)
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_data_end = ABSOLUTE(.);
|
||||
}
|
||||
_irtc_slow_data = ORIGIN(RODATA) + _text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) +
|
||||
SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss) + SIZEOF(.rtc_slow.text);
|
||||
|
||||
.rtc_slow.bss ORIGIN(rtc_slow_seg) + SIZEOF(.rtc_slow.text) + SIZEOF(.rtc_slow.data) (NOLOAD) :
|
||||
AT(_text_size + SIZEOF(.header) + SIZEOF(.pre_header) + SIZEOF(.rodata) + SIZEOF(.rwtext) +
|
||||
SIZEOF(.rtc_fast.text) + SIZEOF(.rtc_fast.data) + SIZEOF(.rtc_fast.bss) + SIZEOF(.rtc_slow.text) + SIZEOF(.rtc_slow.data))
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_rtc_slow_bss_start = ABSOLUTE(.);
|
||||
*(.rtc_slow.bss .rtc_slow.bss.*)
|
||||
. = ALIGN (4);
|
||||
_rtc_slow_bss_end = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
.rtc_slow.noinit ORIGIN(rtc_slow_seg) + SIZEOF(.rtc_slow.text) + SIZEOF(.rtc_slow.data) + SIZEOF(.rtc_slow.bss) (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc_slow.noinit .rtc_slow.noinit.*)
|
||||
. = ALIGN (4);
|
||||
}
|
||||
|
||||
.external.data :
|
||||
{
|
||||
_external_data_start = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
*(.external.data .external.data.*)
|
||||
. = ALIGN (4);
|
||||
_external_data_end = ABSOLUTE(.);
|
||||
} > psram_seg AT > RODATA
|
||||
|
||||
.external.bss (NOLOAD) :
|
||||
{
|
||||
_external_bss_start = ABSOLUTE(.);
|
||||
. = ALIGN(4);
|
||||
*(.external.bss .external.bss.*)
|
||||
. = ALIGN (4);
|
||||
_external_bss_end = ABSOLUTE(.);
|
||||
} > psram_seg
|
||||
|
||||
.external.noinit (NOLOAD) :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.external.noinit .external.noinit.*)
|
||||
. = ALIGN (4);
|
||||
} > psram_seg
|
||||
|
||||
/* must be last segment using psram_seg */
|
||||
.external_heap_start (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (4);
|
||||
_external_heap_start = ABSOLUTE(.);
|
||||
. = ALIGN (4);
|
||||
} > psram_seg
|
||||
}
|
44
esp32s3-hal/ld/db-memory.x
Normal file
44
esp32s3-hal/ld/db-memory.x
Normal file
@ -0,0 +1,44 @@
|
||||
/* override entry point */
|
||||
ENTRY(ESP32Reset)
|
||||
|
||||
/* reserved at the start of DRAM */
|
||||
RESERVE_DRAM = 0x8000;
|
||||
|
||||
/* reserved at the start of the RTC memories for use by the ULP processor */
|
||||
RESERVE_RTC_FAST = 0;
|
||||
RESERVE_RTC_SLOW = 0;
|
||||
|
||||
/* define stack size for both cores */
|
||||
STACK_SIZE = 8k;
|
||||
|
||||
/* Specify main memory areas */
|
||||
MEMORY
|
||||
{
|
||||
iram_seg ( RX ) : ORIGIN = 0x40370400 + RESERVE_DRAM, len = 328k - 0x400
|
||||
|
||||
dram_seg ( RW ) : ORIGIN = 0x3FC80000 + RESERVE_DRAM, len = 328k - RESERVE_DRAM
|
||||
reserved_for_boot_seg : ORIGIN = 0x3FFDC200, len = 144k /* ???? SRAM1; reserved for static ROM usage; can be used for heap */
|
||||
|
||||
/* external flash
|
||||
The 0x20 offset is a convenience for the app binary image generation.
|
||||
Flash cache has 64KB pages. The .bin file which is flashed to the chip
|
||||
has a 0x18 byte file header, and each segment has a 0x08 byte segment
|
||||
header. Setting this offset makes it simple to meet the flash cache MMU's
|
||||
constraint that (paddr % 64KB == vaddr % 64KB).)
|
||||
*/
|
||||
irom_seg ( RX ) : ORIGIN = 0x42000000, len = 4M
|
||||
drom_seg ( R ) : ORIGIN = 0x3C000000, len = 4M
|
||||
|
||||
|
||||
/* RTC fast memory (executable). Persists over deep sleep. Only for core 0 (PRO_CPU) */
|
||||
rtc_fast_iram_seg(RWX) : ORIGIN = 0x600fe000, len = 8k
|
||||
|
||||
/* RTC fast memory (same block as above), viewed from data bus. Only for core 0 (PRO_CPU) */
|
||||
rtc_fast_dram_seg(RW) : ORIGIN = 0x600fe000 + RESERVE_RTC_FAST, len = 8k - RESERVE_RTC_FAST
|
||||
|
||||
/* RTC slow memory (data accessible). Persists over deep sleep. */
|
||||
rtc_slow_seg(RW) : ORIGIN = 0x50000000 + RESERVE_RTC_SLOW, len = 8k - RESERVE_RTC_SLOW
|
||||
|
||||
/* external memory, including data and text */
|
||||
psram_seg(RWX) : ORIGIN = 0x3F500000, len = 0xA80000 /* ??? */
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
#![no_std]
|
||||
#![cfg_attr(feature = "direct-boot", feature(naked_functions))]
|
||||
#![cfg_attr(feature = "direct-boot", feature(asm_experimental_arch))]
|
||||
|
||||
pub use embedded_hal as ehal;
|
||||
pub use esp_hal_common::{
|
||||
@ -34,6 +36,118 @@ pub mod gpio;
|
||||
#[no_mangle]
|
||||
extern "C" fn DefaultHandler(_level: u32, _interrupt: pac::Interrupt) {}
|
||||
|
||||
#[cfg(all(feature = "rt", feature = "direct-boot"))]
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
#[link_section = ".init"]
|
||||
#[naked]
|
||||
unsafe extern "C" fn init() {
|
||||
core::arch::asm!("call0 startup_direct_boot", options(noreturn));
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "rt", feature = "direct-boot"))]
|
||||
#[doc(hidden)]
|
||||
#[no_mangle]
|
||||
pub unsafe fn startup_direct_boot() -> ! {
|
||||
// These symbols are from `memory.x`
|
||||
extern "C" {
|
||||
static mut _rtc_fast_bss_start: u32;
|
||||
static mut _rtc_fast_bss_end: u32;
|
||||
|
||||
static mut _rtc_slow_bss_start: u32;
|
||||
static mut _rtc_slow_bss_end: u32;
|
||||
|
||||
// Boundaries of the .rtc_fast.text section
|
||||
static mut _rtc_fast_text_start: u32;
|
||||
static mut _rtc_fast_text_end: u32;
|
||||
static mut _irtc_fast_text: u32;
|
||||
|
||||
// Boundaries of the .rtc_fast.data section
|
||||
static mut _rtc_fast_data_start: u32;
|
||||
static mut _rtc_fast_data_end: u32;
|
||||
static mut _irtc_fast_data: u32;
|
||||
|
||||
// Boundaries of the .rtc_slow.text section
|
||||
static mut _rtc_slow_text_start: u32;
|
||||
static mut _rtc_slow_text_end: u32;
|
||||
static mut _irtc_slow_text: u32;
|
||||
|
||||
// Boundaries of the .rtc_slow.data section
|
||||
static mut _rtc_slow_data_start: u32;
|
||||
static mut _rtc_slow_data_end: u32;
|
||||
static mut _irtc_slow_data: u32;
|
||||
|
||||
static mut _stack_end_cpu0: u32;
|
||||
}
|
||||
|
||||
// set stack pointer to end of memory: no need to retain stack up to this point
|
||||
xtensa_lx::set_stack_pointer(&mut _stack_end_cpu0);
|
||||
|
||||
// copy rtc data from flash to destinations
|
||||
r0::init_data(
|
||||
&mut _rtc_fast_data_start,
|
||||
&mut _rtc_fast_data_end,
|
||||
&_irtc_fast_data,
|
||||
);
|
||||
|
||||
r0::init_data(
|
||||
&mut _rtc_fast_text_start,
|
||||
&mut _rtc_fast_text_end,
|
||||
&_irtc_fast_text,
|
||||
);
|
||||
|
||||
r0::init_data(
|
||||
&mut _rtc_slow_data_start,
|
||||
&mut _rtc_slow_data_end,
|
||||
&_irtc_slow_data,
|
||||
);
|
||||
|
||||
r0::init_data(
|
||||
&mut _rtc_slow_text_start,
|
||||
&mut _rtc_slow_text_end,
|
||||
&_irtc_slow_text,
|
||||
);
|
||||
|
||||
// Initialize RTC RAM
|
||||
xtensa_lx_rt::zero_bss(&mut _rtc_fast_bss_start, &mut _rtc_fast_bss_end);
|
||||
xtensa_lx_rt::zero_bss(&mut _rtc_slow_bss_start, &mut _rtc_slow_bss_end);
|
||||
|
||||
// first of all copy rwtext
|
||||
extern "C" {
|
||||
// Boundaries of the .iram section
|
||||
static mut _srwtext: u32;
|
||||
static mut _erwtext: u32;
|
||||
static mut _irwtext: u32;
|
||||
}
|
||||
r0::init_data(&mut _srwtext, &mut _erwtext, &_irwtext);
|
||||
|
||||
// do some configurations for compatability with the 2nd stage bootloader
|
||||
// this is a workaround and ideally we should deal with these settings in other
|
||||
// places
|
||||
(&*crate::pac::TIMG0::PTR)
|
||||
.int_ena_timers
|
||||
.modify(|_, w| w.t0_int_ena().set_bit().t1_int_ena().set_bit());
|
||||
(&*crate::pac::TIMG1::PTR)
|
||||
.int_ena_timers
|
||||
.modify(|_, w| w.t0_int_ena().set_bit().t1_int_ena().set_bit());
|
||||
|
||||
(&*crate::pac::RTC_CNTL::PTR)
|
||||
.swd_wprotect
|
||||
.write(|w| w.bits(0x8f1d312a));
|
||||
(&*crate::pac::RTC_CNTL::PTR)
|
||||
.swd_conf
|
||||
.modify(|_, w| w.swd_disable().set_bit());
|
||||
(&*crate::pac::RTC_CNTL::PTR)
|
||||
.swd_wprotect
|
||||
.write(|w| w.bits(0));
|
||||
|
||||
(&*crate::pac::SYSTEM::PTR)
|
||||
.sysclk_conf
|
||||
.modify(|_, w| w.soc_clk_sel().bits(1));
|
||||
|
||||
xtensa_lx_rt::Reset();
|
||||
}
|
||||
|
||||
#[cfg(feature = "rt")]
|
||||
#[doc(hidden)]
|
||||
#[link_section = ".rwtext"]
|
||||
@ -107,7 +221,13 @@ pub unsafe extern "C" fn ESP32Reset() -> ! {
|
||||
#[no_mangle]
|
||||
#[rustfmt::skip]
|
||||
pub extern "Rust" fn __init_data() -> bool {
|
||||
false
|
||||
#[cfg(feature = "direct-boot")]
|
||||
let res = true;
|
||||
|
||||
#[cfg(not(feature = "direct-boot"))]
|
||||
let res = false;
|
||||
|
||||
res
|
||||
}
|
||||
|
||||
fn gpio_intr_enable(int_enable: bool, nmi_enable: bool) -> u8 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user