-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JTAG trampoline for running HSS over JTAG
Signed-off-by: Maciej Nowak <[email protected]>
- Loading branch information
Showing
7 changed files
with
537 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# | ||
# MPFS HSS Embedded Software | ||
# | ||
# Copyright 2019-2021 Microchip Corporation. | ||
# | ||
# SPDX-License-Identifier: MIT | ||
# | ||
# Permission is hereby granted, free of charge, to any person obtaining a copy | ||
# of this software and associated documentation files (the "Software"), to | ||
# deal in the Software without restriction, including without limitation the | ||
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | ||
# sell copies of the Software, and to permit persons to whom the Software is | ||
# furnished to do so, subject to the following conditions: | ||
# | ||
# The above copyright notice and this permission notice shall be included in | ||
# all copies or substantial portions of the Software. | ||
# | ||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS | ||
# IN THE SOFTWARE. | ||
# | ||
# | ||
# Boot HSS over JTAG trampoline | ||
|
||
|
||
OBJS-jtag_trampoline = \ | ||
jtag_trampoline/jtag_trampoline_crt.o \ | ||
jtag_trampoline/jtag_trampoline_funcs.o \ | ||
baremetal/polarfire-soc-bare-metal-library/src/platform/mpfs_hal/common/mss_l2_cache.o | ||
|
||
EXTRA_OBJS-jtag_trampoline= | ||
|
||
LINKER_SCRIPT-jtag_trampoline = jtag_trampoline/jtag_trampoline.ld | ||
|
||
jtag_trampoline/jtag_trampoline_crc.o: CFLAGS=$(CFLAGS_GCCEXT) | ||
jtag_trampoline/jtag_trampoline_funcs.o: CFLAGS=$(CFLAGS_GCCEXT) | ||
|
||
$(TARGET-jtag_trampoline): LIBS:= | ||
$(TARGET-jtag_trampoline): $(OBJS-jtag_trampoline) $(BINDIR)/run-hss.cfg | ||
$(call main-build-target,jtag_trampoline) | ||
@$(ECHO) " HEX `basename $@ .elf`.hex"; | ||
$(OBJCOPY) -O ihex $(BINDIR)/$@ $(BINDIR)/`basename $@ .elf`.hex | ||
$(SIZE) $(BINDIR)/$(TARGET-jtag_trampoline) 2>/dev/null | ||
|
||
jtag_trampoline_clean: | ||
-$(RM) $(COMPRESSED_TARGET) $(OBJS-jtag_trampoline) $(BINDIR)/$(TARGET-jtag_trampoline) $(BINDIR)/`basename $(TARGET-jtag_trampoline) .elf`.sym $(BINDIR)/`basename $(TARGET-jtag_trampoline) .elf`.bin | ||
|
||
HEX_FILE-jtag_trampoline=$(BINDIR)/$(TARGET-jtag_trampoline:.elf=.hex) | ||
BIN_FILE-jtag_trampoline=$(BINDIR)/$(TARGET-jtag_trampoline:.elf=.bin) | ||
|
||
BIN_FILE-jtag_trampoline: $(TARGET-jtag_trampoline) | ||
|
||
COPY_CMD := cp | ||
|
||
ifeq ($(OS),Windows_NT) | ||
COPY_CMD := cmd /c copy | ||
endif | ||
|
||
$(BINDIR)/run-hss.cfg: jtag_trampoline/run-hss.cfg | ||
$(SHELL) -c "cp jtag_trampoline/run-hss.cfg $(BINDIR)/run-hss.cfg" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# HSS-over-JTAG | ||
During development it might be useful to run HSS in boot mode 0 and without need to write HSS executable to eNVM. HSS itself is running from L2 scratchpad but there are some initialization steps required for HSS to execute correctly. In bootmodes 1..3 that initialization is performed by `envm-wrapper`. In bootmode 0 `jtag_trampoline` with OpenOCD script can be used to achieve the same results. | ||
|
||
## Running HSS-over-JTAG | ||
1. Build HSS binaries. | ||
2. Connect debug adapter to target | ||
3. Execute OpenOCD command: `openocd -f <init script> -c "set HSS_DIR <hart-software-services>/Default" -f <hart-software-services>/Default/run-hss.cfg` | ||
4. HSS will be started | ||
|
||
|
||
## Details of operation | ||
1. `hss-jtag_trampoline.hex` is loaded into E51 DTIM and E51 ITIM memories | ||
2. Harts are resumed starting from address `0x01800000` (E51 ITIM). OpenOCD hangs on `wait_halt` command. | ||
3. HSS initialization steps are performed: L2 scratchpad configuration, clocks setups | ||
4. `ebreak` instruction is invoked. OpenOCD command `wait_halt` ends and resumes script. | ||
5. `hss-l2scratch.bin` is loaded into L2 scratchpad area. | ||
6. Harts are resumed from address `0x0A000000`. | ||
7. HSS is running |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,257 @@ | ||
/******************************************************************************* | ||
* Copyright 2019-2021 Microchip FPGA Embedded Systems Solutions. | ||
* | ||
* SPDX-License-Identifier: MIT | ||
* | ||
* MPFS HAL Embedded Software | ||
* | ||
*/ | ||
/******************************************************************************* | ||
* | ||
* file name : mpfs_lim.ld | ||
* Used when debugging code. The debugger loads the code to LIM. | ||
* | ||
* You can find details on the PolarFireSoC Memory map in the mpfs-memory-hierarchy.md | ||
* which can be found under the link below: | ||
* https://github.com/polarfire-soc/polarfire-soc-documentation | ||
* | ||
*/ | ||
|
||
OUTPUT_ARCH( "riscv" ) | ||
ENTRY(_start) | ||
|
||
/*----------------------------------------------------------------------------- | ||
|
||
-- MSS hart Reset vector | ||
|
||
The MSS reset vector for each hart is stored securely in the MPFS. | ||
The most common usage will be where the reset vector for each hart will be set | ||
to the start of the envm at address 0x2022_0100, giving 128K-256B of contiguous | ||
non-volatile storage. Normally this is where the initial boot-loader will | ||
reside. (Note: The first 256B page of envm is used for metadata associated with | ||
secure boot. When not using secure boot (mode 0,1), this area is still reserved | ||
by convention. It allows easier transition from non-secure to secure boot flow | ||
during the development process. | ||
When debugging a bare metal program that is run out of reset from envm, a linker | ||
script will be used whereby the program will run from LIM instead of envm. | ||
In this case, the reset vector in the linker script is normally set to the | ||
start of LIM, 0x0800_0000. | ||
This means you are not continually programming the envm each time you load a | ||
program and there is no limitation with break points when debugging. | ||
See the mpfs-lim.ld example linker script when runing from LIM. | ||
|
||
|
||
------------------------------------------------------------------------------*/ | ||
|
||
MEMORY | ||
{ | ||
dtim (rwx) : ORIGIN = 0x01000000, LENGTH = 8k | ||
e51_itim (rwx) : ORIGIN = 0x01800000, LENGTH = 28k | ||
scratchpad(rwx) : ORIGIN = 0x0A000000, LENGTH = 256k | ||
|
||
l2lim (rwx) : ORIGIN = 0x08000000, LENGTH = 1920k | ||
l2zerodevice (rwx) : ORIGIN = 0x0A000000, LENGTH = 512k | ||
} | ||
|
||
HEAP_SIZE = 0k; /* needs to be calculated for your application if using */ | ||
PROVIDE(STACK_SIZE_PER_HART = 4k); | ||
|
||
/* STACK_SIZE_PER_HART needs to be calculated for your */ | ||
/* application. Must be aligned */ | ||
/* Also Thread local storage (AKA hart local storage) allocated for each hart */ | ||
/* as part of the stack | ||
/* So memory map will look like once apportion in startup code: */ | ||
/* */ | ||
/* stack hart0 Actual Stack size = (STACK_SIZE_PER_HART - HLS_DEBUG_AREA_SIZE) */ | ||
/* TLS hart 0 */ | ||
/* stack hart1 */ | ||
/* TLS hart 1 */ | ||
/* etc */ | ||
/* note: HLS_DEBUG_AREA_SIZE is defined in mss_sw_config.h */ | ||
/* STACK_SIZE_PER_HART = 8k; */ | ||
|
||
/* | ||
* There is common area for shared variables, accessed from a pointer in a harts HLS | ||
*/ | ||
SIZE_OF_COMMON_HART_MEM = 128; | ||
|
||
/* | ||
* Stack size for each hart's application. | ||
* These are the stack sizes that will be allocated to each hart before starting | ||
* each hart's application function, e51(), u54_1(), u54_2(), u54_3(), u54_4(). | ||
*/ | ||
STACK_SIZE_E51_APPLICATION = 2k; | ||
|
||
|
||
SECTIONS | ||
{ | ||
PROVIDE(__dtim_start = ORIGIN(dtim)); | ||
PROVIDE(__dtim_end = ORIGIN(dtim) + LENGTH(dtim)); | ||
PROVIDE(__e51itim_start = ORIGIN(e51_itim)); | ||
PROVIDE(__e51itim_end = ORIGIN(e51_itim) + LENGTH(e51_itim)); | ||
|
||
PROVIDE(__l2lim_start = ORIGIN(l2lim)); | ||
PROVIDE(__l2lim_end = ORIGIN(l2lim) + LENGTH(l2lim)); | ||
PROVIDE(__l2_start = ORIGIN(l2zerodevice)); | ||
PROVIDE(__l2_end = ORIGIN(l2zerodevice) + LENGTH(l2zerodevice)); | ||
|
||
/* text: text code section */ | ||
|
||
.text : ALIGN(0x10) | ||
{ | ||
__text_load = LOADADDR(.text); | ||
__text_start = .; | ||
*(.entry) | ||
*(.text.init) | ||
. = ALIGN(0x10); | ||
*(.text .text.* .gnu.linkonce.t.*) | ||
*(.plt) | ||
. = ALIGN(0x10); | ||
|
||
KEEP (*crtbegin.o(.ctors)) | ||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) | ||
KEEP (*(SORT(.ctors.*))) | ||
KEEP (*crtend.o(.ctors)) | ||
KEEP (*crtbegin.o(.dtors)) | ||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) | ||
KEEP (*(SORT(.dtors.*))) | ||
KEEP (*crtend.o(.dtors)) | ||
|
||
*(.rodata .rodata.* .gnu.linkonce.r.*) | ||
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*) | ||
*(.gcc_except_table) | ||
*(.eh_frame_hdr) | ||
*(.eh_frame) | ||
|
||
KEEP (*(.init)) | ||
KEEP (*(.fini)) | ||
|
||
PROVIDE_HIDDEN (__preinit_array_start = .); | ||
KEEP (*(.preinit_array)) | ||
PROVIDE_HIDDEN (__preinit_array_end = .); | ||
PROVIDE_HIDDEN (__init_array_start = .); | ||
KEEP (*(SORT(.init_array.*))) | ||
KEEP (*(.init_array)) | ||
PROVIDE_HIDDEN (__init_array_end = .); | ||
PROVIDE_HIDDEN (__fini_array_start = .); | ||
KEEP (*(.fini_array)) | ||
KEEP (*(SORT(.fini_array.*))) | ||
PROVIDE_HIDDEN (__fini_array_end = .); | ||
|
||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) | ||
*(.srodata*) | ||
|
||
. = ALIGN(0x10); | ||
__text_end = .; | ||
. = ALIGN(0x10); | ||
} > e51_itim | ||
|
||
.l2_scratchpad : ALIGN(0x10) | ||
{ | ||
. = ALIGN (0x10); | ||
__l2_scratchpad_load = LOADADDR(.l2_scratchpad); | ||
__l2_scratchpad_start = .; | ||
__l2_scratchpad_vma_start = .; | ||
*(.l2_scratchpad) | ||
. = ALIGN(0x10); | ||
__l2_scratchpad_end = .; | ||
__l2_scratchpad_vma_end = .; | ||
} >scratchpad AT> e51_itim | ||
|
||
/* short/global data section */ | ||
.sdata : ALIGN(0x10) | ||
{ | ||
__sdata_load = LOADADDR(.sdata); | ||
__sdata_start = .; | ||
/* offset used with gp(gloabl pointer) are +/- 12 bits, so set point to middle of expected sdata range */ | ||
/* If sdata more than 4K, linker used direct addressing. Perhaps we should add check/warning to linker script if sdata is > 4k */ | ||
__global_pointer$ = . + 0x800; | ||
*(.sdata .sdata.* .gnu.linkonce.s.*) | ||
. = ALIGN(0x10); | ||
__sdata_end = .; | ||
} > dtim AT>e51_itim | ||
|
||
/* data section */ | ||
.data : ALIGN(0x10) | ||
{ | ||
__data_load = LOADADDR(.data); | ||
__data_start = .; | ||
*(.got.plt) *(.got) | ||
*(.shdata) | ||
*(.data .data.* .gnu.linkonce.d.*) | ||
. = ALIGN(0x10); | ||
__data_end = .; | ||
} > dtim AT>e51_itim | ||
|
||
/* sbss section */ | ||
.sbss : ALIGN(0x10) | ||
{ | ||
__sbss_start = .; | ||
*(.sbss .sbss.* .gnu.linkonce.sb.*) | ||
*(.scommon) | ||
. = ALIGN(0x10); | ||
__sbss_end = .; | ||
} > dtim | ||
|
||
/* sbss section */ | ||
.bss : ALIGN(0x10) | ||
{ | ||
__bss_start = .; | ||
*(.shbss) | ||
*(.bss .bss.* .gnu.linkonce.b.*) | ||
*(COMMON) | ||
. = ALIGN(0x10); | ||
__bss_end = .; | ||
} > dtim | ||
|
||
/* End of uninitialized data segment */ | ||
_end = .; | ||
|
||
.heap : ALIGN(0x10) | ||
{ | ||
__heap_start = .; | ||
. += HEAP_SIZE; | ||
__heap_end = .; | ||
. = ALIGN(0x10); | ||
_heap_end = __heap_end; | ||
} > dtim | ||
|
||
/* must be on 4k boundary- corresponds to page size */ | ||
.stack : ALIGN(0x1000) | ||
{ | ||
PROVIDE(__stack_bottom_h0$ = .); | ||
PROVIDE(__app_stack_bottom_h0 = .); | ||
. += STACK_SIZE_E51_APPLICATION; | ||
PROVIDE(__app_stack_top_h0 = .); | ||
PROVIDE(__stack_top_h0$ = .); | ||
|
||
} > dtim | ||
|
||
/* | ||
* memory shared accross harts. | ||
* The boot Hart Local Storage holds a pointer to this area for each hart if | ||
* when enabled by setting MPFS_HAL_SHARED_MEM_ENABLED define in the | ||
* mss_sw_config.h | ||
*/ | ||
.app_hart_common : /* ALIGN(0x1000) */ | ||
{ | ||
PROVIDE(__app_hart_common_start = .); | ||
. += SIZE_OF_COMMON_HART_MEM; | ||
PROVIDE(__app_hart_common_end = .); | ||
} > dtim | ||
|
||
/* | ||
* These are unused it the bootloader program but need to be preset for | ||
* compilation, as used in non-bootloader function. | ||
*/ | ||
.unused_non_bootloader : ALIGN(0x10) | ||
{ | ||
PROVIDE(__uninit_bottom$ = .); | ||
PROVIDE(__uninit_top_h$ = .); | ||
PROVIDE(__app_stack_bottom = .); | ||
PROVIDE(__app_stack_top = .); | ||
PROVIDE(__uninit_top_h$ = .); | ||
} > dtim | ||
|
||
__dtim_trampoline_end = .; | ||
} |
Oops, something went wrong.