Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic HPM6300 support #15

Merged
merged 3 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions HPMicro.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,43 @@ variants:
- core0
flash_algorithms:
- flash-algo-hpm5300
- name: HPM6360
cores:
- name: core0
type: riscv
core_access_options: !Riscv {}
memory_map:
- !Ram
name: ILM0
range:
start: 0x0
end: 0x20000
cores:
- core0
- !Ram
name: DLM0
range:
start: 0x00080000
end: 0x000a0000
cores:
- core0
- !Ram
name: AXI_SRAM
range:
start: 0x01080000
end: 0x01100000
cores:
- core0
- !Nvm
name: XPI0
range:
start: 0x80000000
end: 0x90000000
is_boot_memory: true
cores:
- core0
flash_algorithms:
- flash-algo-hpm6300
- name: HPM6E80
cores:
- name: core0
Expand Down Expand Up @@ -137,3 +174,27 @@ flash_algorithms:
address: 0x0
cores:
- core0
- name: flash-algo-hpm6300
description: A flash algorithm under test
default: true
instructions: EwEB3CMuESIjLIEiIyqRIiMoISO3BQAABUV9Fo1GI4KlSGN41gy3FQD0A6AFgH1WI6DFgAOgBYEjqMWAI6KlkGgAEwYAEIFFlwAAAOeA4C4jLgEQIywBEDcF+fwFBSMmoRAdRSMooRAjKgEQNwUCIAMlRfF0RdHCNwUE82wAcAI3CQTzgpYqhCnpskQjAAEEDAgIEhMGwA+XAAAA54AAFmgMbAJRRpcAAADngCAVNwUAACMmlTaTBMU2E4VEAAwSEwYAEZcAAADngEATI6okETcFAACFRSMCtUgihYMgwSMDJIEjgyRBIwMpASMTAQEkgoCXAAAA54BADZcAAADngMAOtwUAAAPGRUgFRQHGAUUjggVIgoC3BQAAg8VFSJ3BtwUCIIOlRfGcUZnPtwUAABOGxTYDJ0YRtwYAgKmOkUU6hYKHBUWCgJcAAADngOAJtwYAAAPHRkgFyy6ItwUCIIOlRfEDo4UCYwIDArKGtwUAABOGxTaDJ0YRNwcAgCmPkUU+hcKHAoMFRYKAlwAAAOeAoAU3BQAAA0VFSBnNNwUCIAMlRfFcTZnLNwUAABMGxTYDJUYRkUWChwVFgoCXAAAA54CAAkERBsYixAAIlwAAAOeAgAJBEQbGIsQACJcAAADngID+QREGxiLEAAiXAAAA54CA/gGgQREGxiLEAAiyQCJEQQEXAwAAZwCDAEERBsYixAAIwUZja9YGswagQBP4NgCzAwUBYwwIAKqHroYDxwYAI4DnAIUHhQbj6nf+s4gFATMIBkGTcsj/k/U4ALOGUwChwWNZUASTlTgAE/OFAZP3yP+QQ7MFsEAT/oUBkQeYQzNWZgCzFccB0Y0joLMAkQORBzqG4+XT/jGoqoYN4g2oY1pQAMaFkEEjoMMAkQORBePr0/6zhVgAE3Y4ABHKNpYDxwUAI4DmAIUGhQXj6sb+skAiREEBgoBBEQbGIsQACMFGY2TWBLMGoECNijMH1QCZxqqHI4C3AIUH4+3n/hWOk3fG/7MG9wBjXvAAE/j1D7cHAQGThxcQswf4AhzDEQfjbtf+DYoB5gmoqoYZxjaWI4C2AIUG4+3G/rJAIkRBAYKAQREGxiLEAAiyQCJEQQEXAwAAZwCD+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
load_address: 0x20
pc_init: 0x0
pc_uninit: 0x102
pc_program_page: 0x150
pc_erase_sector: 0x116
pc_erase_all: 0x194
data_section_offset: 0x464
flash_properties:
address_range:
start: 0x80000000
end: 0x90000000
page_size: 0x1000
erased_byte_value: 0xff
program_page_timeout: 1000
erase_sector_timeout: 2000
sectors:
- size: 0x1000
address: 0x0
cores:
- core0
30 changes: 30 additions & 0 deletions examples/hpm6300evk/.cargo/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[build]
target = "riscv32imafc-unknown-none-elf"

[target.riscv32imafc-unknown-none-elf]
# runner = 'riscv64-unknown-elf-gdb -x ../../openocd.gdb'
runner = "probe-rs run --chip HPM6360 --protocol jtag --chip-description-path ../../HPMicro.yaml"

rustflags = [
# +zba,+zbb,+zbc,+zbs are not available
# Linker scripts:
"-C",
"link-arg=-Tmemory.x",
"-C",
"link-arg=-Tdevice.x", # __VECTORED_INTERRUPTS
"-C",
"link-arg=-Tlink-fixed.x",
"-C",
"link-arg=-Tdefmt.x",
"-C",
"link-arg=-nmagic",

# "--emit", "obj",
# "--emit", "asm",
]

[unstable]
build-std = ["core"]

[env]
DEFMT_LOG = "info"
24 changes: 24 additions & 0 deletions examples/hpm6300evk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "hpm6300evk"
version = "0.1.0"
edition = "2021"

[dependencies]
defmt = "0.3.8"
defmt-rtt = "0.4.1"
embedded-hal = "1.0.0"
hpm-metapac = { path = "../../../hpm-data/build/hpm-metapac", features = [
"hpm6360",
"memory-x",
"rt",
] }
panic-halt = "0.2.0"
riscv = { version = "0.11.1", features = ["critical-section-single-hart"] }
riscv-rt = { version = "0.12.2", features = ["single-hart"] }


[profile.release]
strip = false # symbols are not flashed to the microcontroller, so don't strip them.
lto = true
opt-level = "z" # Optimize for size.
debug = 2
225 changes: 225 additions & 0 deletions examples/hpm6300evk/link-fixed.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/* Temp fix for https://github.com/rust-embedded/riscv/issues/196 */

/* # Developer notes

- Symbols that start with a double underscore (__) are considered "private"

- Symbols that start with a single underscore (_) are considered "semi-public"; they can be
overridden in a user linker script, but should not be referred from user code (e.g. `extern "C" {
static mut _heap_size }`).

- `EXTERN` forces the linker to keep a symbol in the final binary. We use this to make sure a
symbol if not dropped if it appears in or near the front of the linker arguments and "it's not
needed" by any of the preceding objects (linker arguments)

- `PROVIDE` is used to provide default values that can be overridden by a user linker script

- In this linker script, you may find symbols that look like `${...}` (e.g., `4`).
These are wildcards used by the `build.rs` script to adapt to different target particularities.
Check `build.rs` for more details about these symbols.

- On alignment: it's important for correctness that the VMA boundaries of both .bss and .data *and*
the LMA of .data are all `4`-byte aligned. These alignments are assumed by the RAM
initialization routine. There's also a second benefit: `4`-byte aligned boundaries
means that you won't see "Address (..) is out of bounds" in the disassembly produced by `objdump`.
*/

PROVIDE(_stext = ORIGIN(REGION_TEXT));
PROVIDE(_stack_start = ORIGIN(REGION_STACK) + LENGTH(REGION_STACK));
PROVIDE(_max_hart_id = 0);
PROVIDE(_hart_stack_size = 2K);
PROVIDE(_heap_size = 0);

PROVIDE(InstructionMisaligned = ExceptionHandler);
PROVIDE(InstructionFault = ExceptionHandler);
PROVIDE(IllegalInstruction = ExceptionHandler);
PROVIDE(Breakpoint = ExceptionHandler);
PROVIDE(LoadMisaligned = ExceptionHandler);
PROVIDE(LoadFault = ExceptionHandler);
PROVIDE(StoreMisaligned = ExceptionHandler);
PROVIDE(StoreFault = ExceptionHandler);;
PROVIDE(UserEnvCall = ExceptionHandler);
PROVIDE(SupervisorEnvCall = ExceptionHandler);
PROVIDE(MachineEnvCall = ExceptionHandler);
PROVIDE(InstructionPageFault = ExceptionHandler);
PROVIDE(LoadPageFault = ExceptionHandler);
PROVIDE(StorePageFault = ExceptionHandler);

PROVIDE(SupervisorSoft = DefaultHandler);
PROVIDE(MachineSoft = DefaultHandler);
PROVIDE(SupervisorTimer = DefaultHandler);
PROVIDE(MachineTimer = DefaultHandler);
PROVIDE(SupervisorExternal = DefaultHandler);
PROVIDE(MachineExternal = DefaultHandler);

PROVIDE(DefaultHandler = DefaultInterruptHandler);
PROVIDE(ExceptionHandler = DefaultExceptionHandler);

/* # Pre-initialization function */
/* If the user overrides this using the `#[pre_init]` attribute or by creating a `__pre_init` function,
then the function this points to will be called before the RAM is initialized. */
PROVIDE(__pre_init = default_pre_init);

/* A PAC/HAL defined routine that should initialize custom interrupt controller if needed. */
PROVIDE(_setup_interrupts = default_setup_interrupts);

/* # Multi-processing hook function
fn _mp_hook() -> bool;

This function is called from all the harts and must return true only for one hart,
which will perform memory initialization. For other harts it must return false
and implement wake-up in platform-dependent way (e.g. after waiting for a user interrupt).
*/
PROVIDE(_mp_hook = default_mp_hook);

/* # Start trap function override
By default uses the riscv crates default trap handler
but by providing the `_start_trap` symbol external crates can override.
*/
PROVIDE(_start_trap = default_start_trap);

SECTIONS
{
.text.dummy (NOLOAD) :
{
/* This section is intended to make _stext address work */
. = ABSOLUTE(_stext);
} > REGION_TEXT

.text _stext :
{
/* Put reset handler first in .text section so it ends up as the entry */
/* point of the program. */
KEEP(*(.init));
KEEP(*(.init.rust));
. = ALIGN(4);
*(.trap);
*(.trap.rust);
*(.text.abort);
*(.text .text.*);
} > REGION_TEXT

/* Fast code section */
.fast : ALIGN(4)
{
_sifast = LOADADDR(.fast);
_sfast = .;
*(.fast)
*(.fast.*)
. = ALIGN(4);
PROVIDE(_efast= .); /* No idea why `PROVIDE` is needed here */
} > REGION_FASTTEXT AT > REGION_RODATA

.rodata : ALIGN(4)
{
*(.srodata .srodata.*);
*(.rodata .rodata.*);

/* 4-byte align the end (VMA) of this section.
This is required by LLD to ensure the LMA of the following .data
section will have the correct alignment. */
. = ALIGN(4);
} > REGION_RODATA

.data : ALIGN(4)
{
_sidata = LOADADDR(.data);
_sdata = .;
/* Must be called __global_pointer$ for linker relaxations to work. */
PROVIDE(__global_pointer$ = . + 0x800);
*(.sdata .sdata.* .sdata2 .sdata2.*);
*(.data .data.*);
. = ALIGN(4);
_edata = .;
} > REGION_DATA AT > REGION_RODATA

.bss (NOLOAD) : ALIGN(4)
{
_sbss = .;
*(.sbss .sbss.* .bss .bss.*);
. = ALIGN(4);
_ebss = .;
} > REGION_BSS

/* fictitious region that represents the memory available for the heap */
.heap (NOLOAD) :
{
_sheap = .;
. += _heap_size;
. = ALIGN(4);
_eheap = .;
} > REGION_HEAP

/* fictitious region that represents the memory available for the stack */
.stack (NOLOAD) :
{
_estack = .;
. = ABSOLUTE(_stack_start);
_sstack = .;
} > REGION_STACK

/* fake output .got section */
/* Dynamic relocations are unsupported. This section is only used to detect
relocatable code in the input files and raise an error if relocatable code
is found */
.got (INFO) :
{
KEEP(*(.got .got.*));
}

/*.eh_frame (INFO) : { KEEP(*(.eh_frame)) }
.eh_frame_hdr (INFO) : { *(.eh_frame_hdr) }*/
.eh_frame : { KEEP(*(.eh_frame)) } > REGION_TEXT
.eh_frame_hdr : { *(.eh_frame_hdr) } > REGION_TEXT
}

/* Do not exceed this mark in the error messages above | */
ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");

ASSERT(ORIGIN(REGION_RODATA) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_RODATA must be 4-byte aligned");

ASSERT(ORIGIN(REGION_DATA) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_DATA must be 4-byte aligned");

ASSERT(ORIGIN(REGION_HEAP) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_HEAP must be 4-byte aligned");

ASSERT(ORIGIN(REGION_TEXT) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_TEXT must be 4-byte aligned");

ASSERT(ORIGIN(REGION_STACK) % 4 == 0, "
ERROR(riscv-rt): the start of the REGION_STACK must be 4-byte aligned");

ASSERT(_stext % 4 == 0, "
ERROR(riscv-rt): `_stext` must be 4-byte aligned");

ASSERT(_sdata % 4 == 0 && _edata % 4 == 0, "
BUG(riscv-rt): .data is not 4-byte aligned");

ASSERT(_sidata % 4 == 0, "
BUG(riscv-rt): the LMA of .data is not 4-byte aligned");

ASSERT(_sbss % 4 == 0 && _ebss % 4 == 0, "
BUG(riscv-rt): .bss is not 4-byte aligned");

ASSERT(_sheap % 4 == 0, "
BUG(riscv-rt): start of .heap is not 4-byte aligned");

ASSERT(_stext + SIZEOF(.text) < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "
ERROR(riscv-rt): The .text section must be placed inside the REGION_TEXT region.
Set _stext to an address smaller than 'ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT)'");

ASSERT(SIZEOF(.stack) > (_max_hart_id + 1) * _hart_stack_size, "
ERROR(riscv-rt): .stack section is too small for allocating stacks for all the harts.
Consider changing `_max_hart_id` or `_hart_stack_size`.");

ASSERT(SIZEOF(.got) == 0, "
.got section detected in the input files. Dynamic relocations are not
supported. If you are linking to C code compiled using the `gcc` crate
then modify your build script to compile the C code _without_ the
-fPIC flag. See the documentation of the `gcc::Config.fpic` method for
details.");

/* Do not exceed this mark in the error messages above | */
35 changes: 35 additions & 0 deletions examples/hpm6300evk/memory-ram.x
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
MEMORY
{
ILM0 : ORIGIN = 0x00000000, LENGTH = 128K
DLM0 : ORIGIN = 0x00080000, LENGTH = 128K /* data local memory */

AXI_SRAM : ORIGIN = 0x01200000, LENGTH = 512K
AHB_SRAM : ORIGIN = 0xF0300000, LENGTH = 32K
}
REGION_ALIAS("REGION_TEXT", ILM0);
REGION_ALIAS("REGION_RODATA", ILM0);
REGION_ALIAS("REGION_DATA", DLM0);
REGION_ALIAS("REGION_BSS", DLM0)
REGION_ALIAS("REGION_HEAP", DLM0);
REGION_ALIAS("REGION_STACK", DLM0);
REGION_ALIAS("REGION_FASTTEXT", ILM0);


/*
SECTIONS
{
.fast : ALIGN(4)
{
. = ALIGN(8);
__fast_load_addr__ = LOADADDR(.fast);
__fast_start_addr__ = .;
PROVIDE(__ramfunc_start__ = .);
*(.fast)
*(.fast.*)
. = ALIGN(8);
PROVIDE(__ramfunc_end__ = .);
__fast_end_addr__ = .;
} > ILM
}

*/
Loading
Loading