soc: intel_adsp: Generalize bootloader
Move bootloader to soc/xtensa/intel_adsp making it available for other boards. Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
This commit is contained in:
parent
35c4838425
commit
d6a33ef467
12 changed files with 36 additions and 8 deletions
|
@ -7,3 +7,5 @@ zephyr_library_sources(soc.c)
|
|||
zephyr_library_sources(main_entry.S)
|
||||
|
||||
zephyr_library_sources_ifdef(CONFIG_SMP soc_mp.c)
|
||||
|
||||
add_subdirectory(common)
|
||||
|
|
20
soc/xtensa/intel_apl_adsp/bootloader.cmake
Normal file
20
soc/xtensa/intel_apl_adsp/bootloader.cmake
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Copyright (c) 2019 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_subdirectory(${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/bootloader ${build_dir})
|
||||
|
||||
add_custom_target(
|
||||
process_elf ALL
|
||||
DEPENDS base_module
|
||||
DEPENDS ${ZEPHYR_FINAL_EXECUTABLE}
|
||||
COMMAND ${CMAKE_OBJCOPY} --dump-section .data=mod-apl.bin ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/libbase_module.a
|
||||
COMMAND ${CMAKE_OBJCOPY} --add-section .module=mod-apl.bin --set-section-flags .module=load,readonly ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf.mod
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
process_bootloader ALL
|
||||
DEPENDS bootloader boot_module
|
||||
COMMAND ${CMAKE_OBJCOPY} --dump-section .data=mod-boot.bin ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/libboot_module.a
|
||||
COMMAND ${CMAKE_OBJCOPY} --add-section .module=mod-boot.bin --set-section-flags .module=load,readonly ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/bootloader.elf ${CMAKE_BINARY_DIR}/zephyr/bootloader.elf.mod
|
||||
)
|
6
soc/xtensa/intel_apl_adsp/common/CMakeLists.txt
Normal file
6
soc/xtensa/intel_apl_adsp/common/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Intel CAVS SoC family CMake file
|
||||
#
|
||||
# Copyright (c) 2020 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
include(bootloader.cmake)
|
30
soc/xtensa/intel_apl_adsp/common/bootloader.cmake
Normal file
30
soc/xtensa/intel_apl_adsp/common/bootloader.cmake
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Copyright (c) 2019 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set(SOC_FAMILY intel_apl_adsp)
|
||||
|
||||
if(EXISTS ${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/bootloader/CMakeLists.txt)
|
||||
if(USING_OUT_OF_TREE_BOARD)
|
||||
set(build_dir boards/${ARCH}/${BOARD}/bootloader)
|
||||
else()
|
||||
unset(build_dir)
|
||||
endif()
|
||||
|
||||
add_subdirectory(${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/bootloader ${build_dir})
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
process_elf ALL
|
||||
DEPENDS base_module
|
||||
DEPENDS ${ZEPHYR_FINAL_EXECUTABLE}
|
||||
COMMAND ${CMAKE_OBJCOPY} --dump-section .data=mod-apl.bin ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/libbase_module.a
|
||||
COMMAND ${CMAKE_OBJCOPY} --add-section .module=mod-apl.bin --set-section-flags .module=load,readonly ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf ${CMAKE_BINARY_DIR}/zephyr/zephyr.elf.mod
|
||||
)
|
||||
|
||||
add_custom_target(
|
||||
process_bootloader ALL
|
||||
DEPENDS bootloader boot_module
|
||||
COMMAND ${CMAKE_OBJCOPY} --dump-section .data=mod-boot.bin ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/libboot_module.a
|
||||
COMMAND ${CMAKE_OBJCOPY} --add-section .module=mod-boot.bin --set-section-flags .module=load,readonly ${CMAKE_BINARY_DIR}/zephyr/soc/xtensa/${SOC_FAMILY}/common/bootloader/bootloader.elf ${CMAKE_BINARY_DIR}/zephyr/bootloader.elf.mod
|
||||
)
|
47
soc/xtensa/intel_apl_adsp/common/bootloader/CMakeLists.txt
Normal file
47
soc/xtensa/intel_apl_adsp/common/bootloader/CMakeLists.txt
Normal file
|
@ -0,0 +1,47 @@
|
|||
# Copyright (c) 2019 Intel Corporation
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
add_library(base_module base_module.c)
|
||||
target_include_directories(base_module PUBLIC
|
||||
${SOC_DIR}/${ARCH}/${SOC_PATH}/include
|
||||
)
|
||||
|
||||
add_library(boot_module boot_module.c)
|
||||
target_include_directories(boot_module PUBLIC
|
||||
${SOC_DIR}/${ARCH}/${SOC_PATH}/include
|
||||
)
|
||||
|
||||
add_executable(bootloader
|
||||
boot_entry.S
|
||||
${ARCH_DIR}/${ARCH}/core/startup/memctl_default.S
|
||||
${ARCH_DIR}/${ARCH}/core/startup/memerror-vector.S
|
||||
${ARCH_DIR}/${ARCH}/core/startup/reset-vector.S
|
||||
boot_loader.c
|
||||
start_address.S
|
||||
)
|
||||
|
||||
add_dependencies(bootloader ${SYSCALL_LIST_H_TARGET})
|
||||
|
||||
set(zephyr_sdk $ENV{ZEPHYR_SDK_INSTALL_DIR})
|
||||
|
||||
target_include_directories(bootloader PUBLIC
|
||||
./
|
||||
${ZEPHYR_BASE}/include
|
||||
${TOOLCHAIN_INCLUDES}
|
||||
${SOC_DIR}/${ARCH}/${SOC_PATH}/
|
||||
${SOC_DIR}/${ARCH}/${SOC_PATH}/include
|
||||
)
|
||||
|
||||
set_source_files_properties(boot_entry.S PROPERTIES COMPILE_FLAGS -DASSEMBLY)
|
||||
set_source_files_properties(${ARCH_DIR}/${ARCH}/core/startup/reset-vector.S PROPERTIES COMPILE_FLAGS -DBOOTLOADER)
|
||||
|
||||
target_compile_options(bootloader PUBLIC -fno-inline-functions -mlongcalls -mtext-section-literals -imacros${CMAKE_BINARY_DIR}/zephyr/include/generated/autoconf.h)
|
||||
|
||||
target_link_libraries(bootloader PUBLIC -Wl,--no-check-sections -ucall_user_start -Wl,-static -nostdlib)
|
||||
target_link_libraries(bootloader PRIVATE -lhal -L${zephyr_sdk}/xtensa/intel_apl_adsp/xtensa-zephyr-elf/lib)
|
||||
target_link_libraries(bootloader PRIVATE -T${SOC_DIR}/${ARCH}/${SOC_FAMILY}/common/bootloader/boot_ldr.x)
|
||||
|
||||
if(CONFIG_XTENSA_HAL)
|
||||
target_link_libraries(bootloader PRIVATE XTENSA_HAL)
|
||||
endif()
|
32
soc/xtensa/intel_apl_adsp/common/bootloader/base_module.c
Normal file
32
soc/xtensa/intel_apl_adsp/common/bootloader/base_module.c
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright(c) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "manifest.h"
|
||||
#include <platform/memory.h>
|
||||
|
||||
/*
|
||||
* Each module has an entry in the FW manifest header. This is NOT part of
|
||||
* the SOF executable image but is inserted by object copy as a ELF section
|
||||
* for parsing by rimage (to genrate the manifest).
|
||||
*/
|
||||
struct sof_man_module_manifest apl_manifest = {
|
||||
.module = {
|
||||
.name = "BASEFW",
|
||||
.uuid = {0x2e, 0x9e, 0x86, 0xfc, 0xf8, 0x45, 0x45, 0x40,
|
||||
0xa4, 0x16, 0x89, 0x88, 0x0a, 0xe3, 0x20, 0xa9},
|
||||
.entry_point = SOF_TEXT_START,
|
||||
.type = {
|
||||
.load_type = SOF_MAN_MOD_TYPE_MODULE,
|
||||
.domain_ll = 1,
|
||||
},
|
||||
.affinity_mask = 3,
|
||||
},
|
||||
};
|
||||
|
||||
/* not used, but stops linker complaining */
|
||||
int _start;
|
223
soc/xtensa/intel_apl_adsp/common/bootloader/boot_entry.S
Normal file
223
soc/xtensa/intel_apl_adsp/common/bootloader/boot_entry.S
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright(c) 2016 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
* Entry point from ROM - assumes :-
|
||||
*
|
||||
* 1) C runtime environment is initialized by ROM.
|
||||
* 2) Stack is in first HPSRAM bank.
|
||||
*/
|
||||
|
||||
#include <platform/shim.h>
|
||||
#include <platform/platform.h>
|
||||
#include <xtensa/corebits.h>
|
||||
#include <xtensa/config/core-isa.h>
|
||||
|
||||
.type boot_master_core, @function
|
||||
|
||||
.begin literal_prefix .boot_entry
|
||||
.section .boot_entry.text, "ax"
|
||||
|
||||
.align 4
|
||||
.global boot_entry
|
||||
|
||||
boot_entry:
|
||||
entry a1, 48
|
||||
j boot_init
|
||||
|
||||
.align 4
|
||||
.literal_position
|
||||
#if defined(PLATFORM_RESET_MHE_AT_BOOT)
|
||||
l2_mecs:
|
||||
.word SHIM_L2_MECS
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DISABLE_L2CACHE_AT_BOOT)
|
||||
l2_cache_pref:
|
||||
.word SHIM_L2_PREF_CFG
|
||||
#endif
|
||||
|
||||
sof_stack_base:
|
||||
.word SOF_STACK_BASE
|
||||
|
||||
wnd0_base:
|
||||
.word DMWBA(0)
|
||||
|
||||
wnd0_size:
|
||||
.word DMWLO(0)
|
||||
|
||||
wnd0_base_val:
|
||||
.word HP_SRAM_WIN0_BASE | DMWBA_READONLY | DMWBA_ENABLE
|
||||
|
||||
wnd0_size_val:
|
||||
.word HP_SRAM_WIN0_SIZE | 0x7
|
||||
|
||||
wnd0_status_address:
|
||||
.word HP_SRAM_WIN0_BASE
|
||||
|
||||
wnd0_error_address:
|
||||
.word HP_SRAM_WIN0_BASE | 0x4
|
||||
|
||||
#if defined(PLATFORM_MEM_INIT_AT_BOOT)
|
||||
shim_ldoctl_address:
|
||||
.word SHIM_BASE + SHIM_LDOCTL
|
||||
|
||||
ldoctl_hpsram_ldo_on:
|
||||
.word SHIM_LDOCTL_HPSRAM_LDO_ON
|
||||
|
||||
ldoctl_hpsram_ldo_bypass:
|
||||
.word SHIM_LDOCTL_HPSRAM_LDO_BYPASS
|
||||
|
||||
hspgctl0_address:
|
||||
.word HSPGCTL0
|
||||
|
||||
hsrmctl0_address:
|
||||
.word HSRMCTL0
|
||||
|
||||
hspgctl1_address:
|
||||
.word HSPGCTL1
|
||||
|
||||
hsrmctl1_address:
|
||||
.word HSRMCTL1
|
||||
|
||||
hspgists0_address:
|
||||
.word HSPGISTS0
|
||||
|
||||
hspgists1_address:
|
||||
.word HSPGISTS1
|
||||
#endif
|
||||
|
||||
fw_loaded_status_value:
|
||||
.word 0x00000005
|
||||
|
||||
fw_no_errors_value:
|
||||
.word 0x00000000
|
||||
|
||||
boot_init:
|
||||
.align 4
|
||||
#if defined(PLATFORM_DISABLE_L2CACHE_AT_BOOT)
|
||||
l32r a3, l2_cache_pref
|
||||
movi a5, 0
|
||||
s32i a5, a3, 0
|
||||
memw
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_RESET_MHE_AT_BOOT)
|
||||
/* reset memory hole */
|
||||
l32r a3, l2_mecs
|
||||
movi a5, 0
|
||||
s32i a5, a3, 0
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_MEM_INIT_AT_BOOT)
|
||||
/* turn on memory _before_ stack reprogramming */
|
||||
|
||||
l32r a3, ldoctl_hpsram_ldo_on
|
||||
l32r a5, shim_ldoctl_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
|
||||
/* delay for 256 iterations before touching pwr regs */
|
||||
movi a2, 256
|
||||
1: addi.n a2, a2, -1
|
||||
bnez a2, 1b
|
||||
|
||||
movi a3, 0
|
||||
l32r a5, hspgctl0_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
|
||||
l32r a5, hsrmctl0_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
|
||||
l32r a5, hspgctl1_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
|
||||
l32r a5, hsrmctl1_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
|
||||
/* wait for status of first bank group */
|
||||
l32r a5, hspgists0_address
|
||||
2:
|
||||
l32i a3, a5, 0
|
||||
bnez a3, 2b
|
||||
|
||||
/* wait for status of second bank group */
|
||||
l32r a5, hspgists1_address
|
||||
3:
|
||||
l32i a3, a5, 0
|
||||
bnez a3, 3b
|
||||
|
||||
/* delay for 256 iterations before touching pwr regs */
|
||||
movi a2, 256
|
||||
4: addi.n a2, a2, -1
|
||||
bnez a2, 4b
|
||||
|
||||
l32r a3, ldoctl_hpsram_ldo_bypass
|
||||
l32r a5, shim_ldoctl_address
|
||||
s32i a3, a5, 0
|
||||
memw
|
||||
#endif
|
||||
|
||||
/* reprogram stack to the area defined by main FW */
|
||||
l32r a3, sof_stack_base
|
||||
mov sp, a3
|
||||
|
||||
/* set status register to 0x00000005 in wnd0 */
|
||||
l32r a3, fw_loaded_status_value
|
||||
l32r a5, wnd0_status_address
|
||||
s32i a3, a5, 0
|
||||
|
||||
/* set error register to 0x00 in wnd0 */
|
||||
l32r a3, fw_no_errors_value
|
||||
l32r a5, wnd0_error_address
|
||||
s32i a3, a5, 0
|
||||
|
||||
/* realloc memory window0 to
|
||||
continue reporting boot progress */
|
||||
l32r a3, wnd0_size
|
||||
l32r a5, wnd0_size_val
|
||||
s32i a5, a3, 0
|
||||
memw
|
||||
l32r a3, wnd0_base
|
||||
l32r a5, wnd0_base_val
|
||||
s32i a5, a3, 0
|
||||
memw
|
||||
|
||||
#if (XCHAL_DCACHE_IS_COHERENT || XCHAL_LOOP_BUFFER_SIZE) && \
|
||||
XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RE_2012_0
|
||||
/* Enable zero-overhead loop instr buffer,
|
||||
and snoop responses, if configured. */
|
||||
movi a3, (MEMCTL_SNOOP_EN | MEMCTL_L0IBUF_EN)
|
||||
rsr a2, MEMCTL
|
||||
or a2, a2, a3
|
||||
wsr a2, MEMCTL
|
||||
#endif
|
||||
|
||||
/* determine core we are running on */
|
||||
rsr.prid a2
|
||||
movi a3, PLATFORM_MASTER_CORE_ID
|
||||
beq a2, a3, 1f
|
||||
|
||||
/* no core should get here */
|
||||
j dead
|
||||
|
||||
1:
|
||||
/* we are primary core so boot it */
|
||||
call8 boot_master_core
|
||||
|
||||
dead:
|
||||
/* should never get here - we are dead */
|
||||
j dead
|
||||
|
||||
.size boot_entry, . - boot_entry
|
||||
|
||||
.end literal_prefix
|
210
soc/xtensa/intel_apl_adsp/common/bootloader/boot_ldr.x
Normal file
210
soc/xtensa/intel_apl_adsp/common/bootloader/boot_ldr.x
Normal file
|
@ -0,0 +1,210 @@
|
|||
OUTPUT_ARCH(xtensa)
|
||||
PROVIDE(__memctl_default = 0x00000000);
|
||||
PROVIDE(_MemErrorHandler = 0x00000000);
|
||||
MEMORY
|
||||
{
|
||||
boot_entry_text :
|
||||
org = 0xB000A000,
|
||||
len = 0x86
|
||||
boot_entry_lit :
|
||||
org = (0xB000A000 + 0x86),
|
||||
len = 0x70
|
||||
sof_text :
|
||||
org = ((0xB000A000 + 0x86) + 0x70),
|
||||
len = 0x1C00,
|
||||
sof_data :
|
||||
org = 0xB0002000,
|
||||
len = 0x1000
|
||||
sof_bss_data :
|
||||
org = 0xB0100000,
|
||||
len = 0x10000
|
||||
sof_stack :
|
||||
org = 0xBE000000,
|
||||
len = (1 * 0x1000)
|
||||
wnd0 :
|
||||
org = ((((((0xBE000000 + 0x8000) + 0x2000) + 0x800) + 0x800) + 0x1000) + 0x2000),
|
||||
len = (0x1000 + 0x1000)
|
||||
}
|
||||
PHDRS
|
||||
{
|
||||
boot_entry_text_phdr PT_LOAD;
|
||||
boot_entry_lit_phdr PT_LOAD;
|
||||
sof_text_phdr PT_LOAD;
|
||||
sof_data_phdr PT_LOAD;
|
||||
sof_bss_data_phdr PT_LOAD;
|
||||
sof_stack_phdr PT_LOAD;
|
||||
wnd0_phdr PT_LOAD;
|
||||
}
|
||||
ENTRY(boot_entry)
|
||||
EXTERN(reset_vector)
|
||||
SECTIONS
|
||||
{
|
||||
.boot_entry.text : ALIGN(4)
|
||||
{
|
||||
_boot_entry_text_start = ABSOLUTE(.);
|
||||
KEEP (*(.boot_entry.text))
|
||||
_boot_entry_text_end = ABSOLUTE(.);
|
||||
} >boot_entry_text :boot_entry_text_phdr
|
||||
.boot_entry.literal : ALIGN(4)
|
||||
{
|
||||
_boot_entry_literal_start = ABSOLUTE(.);
|
||||
*(.boot_entry.literal)
|
||||
*(.literal .literal.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
_boot_entry_literal_end = ABSOLUTE(.);
|
||||
} >boot_entry_lit :boot_entry_lit_phdr
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
KEEP(*(.init))
|
||||
*( .text .text.*)
|
||||
*(.fini.literal)
|
||||
KEEP(*(.fini))
|
||||
*(.gnu.version)
|
||||
KEEP (*(.ResetVector.text))
|
||||
KEEP (*(.ResetHandler.text))
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >sof_text :sof_text_phdr
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
KEEP (*(.xt_except_table))
|
||||
KEEP (*(.gcc_except_table))
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
KEEP (*(.eh_frame))
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4);
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
_bss_table_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} >sof_data :sof_data_phdr
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
KEEP(*(.gnu.linkonce.d.*personality*))
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
KEEP(*(.jcr))
|
||||
_data_end = ABSOLUTE(.);
|
||||
} >sof_data :sof_data_phdr
|
||||
.lit4 : ALIGN(4)
|
||||
{
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
} >sof_data :sof_data_phdr
|
||||
.bss (NOLOAD) : ALIGN(8)
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
} >sof_bss_data :sof_bss_data_phdr
|
||||
_man = 0x1234567;
|
||||
PROVIDE(_memmap_vecbase_reset = (((((((0xBE000000 + 0x8000) + 0x2000) + 0x800) + 0x800) + 0x1000) + 0x2000) + (0x1000 + 0x1000)));
|
||||
_memmap_cacheattr_wbna_trapnull = 0xFF42FFF2;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wbna_trapnull);
|
||||
__stack = 0xBE000000 + (1 * 0x1000);
|
||||
__wnd0 = ((((((0xBE000000 + 0x8000) + 0x2000) + 0x800) + 0x800) + 0x1000) + 0x2000);
|
||||
__wnd0_size = (0x1000 + 0x1000);
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
.debug_ranges 0 : { *(.debug_ranges) }
|
||||
.xtensa.info 0 : { *(.xtensa.info) }
|
||||
.xt.insn 0 :
|
||||
{
|
||||
KEEP (*(.xt.insn))
|
||||
KEEP (*(.gnu.linkonce.x.*))
|
||||
}
|
||||
.xt.prop 0 :
|
||||
{
|
||||
KEEP (*(.xt.prop))
|
||||
KEEP (*(.xt.prop.*))
|
||||
KEEP (*(.gnu.linkonce.prop.*))
|
||||
}
|
||||
.xt.lit 0 :
|
||||
{
|
||||
KEEP (*(.xt.lit))
|
||||
KEEP (*(.xt.lit.*))
|
||||
KEEP (*(.gnu.linkonce.p.*))
|
||||
}
|
||||
.xt.profile_range 0 :
|
||||
{
|
||||
KEEP (*(.xt.profile_range))
|
||||
KEEP (*(.gnu.linkonce.profile_range.*))
|
||||
}
|
||||
.xt.profile_ranges 0 :
|
||||
{
|
||||
KEEP (*(.xt.profile_ranges))
|
||||
KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
|
||||
}
|
||||
.xt.profile_files 0 :
|
||||
{
|
||||
KEEP (*(.xt.profile_files))
|
||||
KEEP (*(.gnu.linkonce.xt.profile_files.*))
|
||||
}
|
||||
}
|
166
soc/xtensa/intel_apl_adsp/common/bootloader/boot_loader.c
Normal file
166
soc/xtensa/intel_apl_adsp/common/bootloader/boot_loader.c
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright(c) 2016 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <platform/platform.h>
|
||||
#include <platform/memory.h>
|
||||
#include <soc.h>
|
||||
#include "manifest.h"
|
||||
|
||||
#define MANIFEST_BASE IMR_BOOT_LDR_MANIFEST_BASE
|
||||
|
||||
extern void __start(void);
|
||||
|
||||
static inline void idelay(int n)
|
||||
{
|
||||
while (n--) {
|
||||
__asm__ volatile("nop");
|
||||
}
|
||||
}
|
||||
|
||||
/* memcopy used by boot loader */
|
||||
static inline void bmemcpy(void *dest, void *src, size_t bytes)
|
||||
{
|
||||
uint32_t *d = dest;
|
||||
uint32_t *s = src;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (bytes >> 2); i++)
|
||||
d[i] = s[i];
|
||||
|
||||
SOC_DCACHE_FLUSH(dest, bytes);
|
||||
}
|
||||
|
||||
/* bzero used by bootloader */
|
||||
static inline void bbzero(void *dest, size_t bytes)
|
||||
{
|
||||
uint32_t *d = dest;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < (bytes >> 2); i++)
|
||||
d[i] = 0;
|
||||
|
||||
SOC_DCACHE_FLUSH(dest, bytes);
|
||||
}
|
||||
|
||||
static void parse_module(struct sof_man_fw_header *hdr,
|
||||
struct sof_man_module *mod)
|
||||
{
|
||||
int i;
|
||||
uint32_t bias;
|
||||
|
||||
/* each module has 3 segments */
|
||||
for (i = 0; i < 3; i++) {
|
||||
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_PARSE_SEGMENT + i); */
|
||||
switch (mod->segment[i].flags.r.type) {
|
||||
case SOF_MAN_SEGMENT_TEXT:
|
||||
case SOF_MAN_SEGMENT_DATA:
|
||||
bias = (mod->segment[i].file_offset -
|
||||
SOF_MAN_ELF_TEXT_OFFSET);
|
||||
|
||||
/* copy from IMR to SRAM */
|
||||
bmemcpy((void *)mod->segment[i].v_base_addr,
|
||||
(void *)((int)hdr + bias),
|
||||
mod->segment[i].flags.r.length *
|
||||
HOST_PAGE_SIZE);
|
||||
break;
|
||||
case SOF_MAN_SEGMENT_BSS:
|
||||
/* copy from IMR to SRAM */
|
||||
bbzero((void *)mod->segment[i].v_base_addr,
|
||||
mod->segment[i].flags.r.length *
|
||||
HOST_PAGE_SIZE);
|
||||
break;
|
||||
default:
|
||||
/* ignore */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define MAN_SKIP_ENTRIES 1
|
||||
|
||||
/* parse FW manifest and copy modules */
|
||||
static void parse_manifest(void)
|
||||
{
|
||||
struct sof_man_fw_desc *desc =
|
||||
(struct sof_man_fw_desc *)MANIFEST_BASE;
|
||||
struct sof_man_fw_header *hdr = &desc->header;
|
||||
struct sof_man_module *mod;
|
||||
int i;
|
||||
|
||||
/* copy module to SRAM - skip bootloader module */
|
||||
for (i = MAN_SKIP_ENTRIES; i < hdr->num_module_entries; i++) {
|
||||
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_PARSE_MODULE + i); */
|
||||
mod = (void *)((uintptr_t)desc + SOF_MAN_MODULE_OFFSET(i));
|
||||
parse_module(hdr, mod);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t lp_sram_init(void)
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t lspgctl_value;
|
||||
uint32_t timeout_counter, delay_count = 256;
|
||||
|
||||
timeout_counter = delay_count;
|
||||
|
||||
shim_write(SHIM_LDOCTL, SHIM_LDOCTL_LPSRAM_LDO_ON);
|
||||
|
||||
/* add some delay before writing power registers */
|
||||
idelay(delay_count);
|
||||
|
||||
lspgctl_value = shim_read(LSPGCTL);
|
||||
shim_write(LSPGCTL, lspgctl_value & ~LPSRAM_MASK(0));
|
||||
|
||||
/* add some delay before checking the status */
|
||||
idelay(delay_count);
|
||||
|
||||
/* query the power status of first part of LP memory */
|
||||
/* to check whether it has been powered up. A few */
|
||||
/* cycles are needed for it to be powered up */
|
||||
status = io_reg_read(LSPGISTS);
|
||||
while (status) {
|
||||
if (!timeout_counter--) {
|
||||
/* platform_panic(SOF_IPC_PANIC_MEM); */
|
||||
break;
|
||||
}
|
||||
idelay(delay_count);
|
||||
status = io_reg_read(LSPGISTS);
|
||||
}
|
||||
|
||||
shim_write(SHIM_LDOCTL, SHIM_LDOCTL_LPSRAM_LDO_BYPASS);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* boot master core */
|
||||
void boot_master_core(void)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
/* TODO: platform trace should write to HW IPC regs on CNL */
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_ENTRY); */
|
||||
|
||||
/* init the LPSRAM */
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_LPSRAM); */
|
||||
|
||||
result = lp_sram_init();
|
||||
if (result < 0) {
|
||||
/* platform_panic(SOF_IPC_PANIC_MEM); */
|
||||
return;
|
||||
}
|
||||
|
||||
/* parse manifest and copy modules */
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_MANIFEST); */
|
||||
parse_manifest();
|
||||
|
||||
/* now call SOF entry */
|
||||
/* platform_trace_point(TRACE_BOOT_LDR_JUMP); */
|
||||
__start();
|
||||
}
|
34
soc/xtensa/intel_apl_adsp/common/bootloader/boot_module.c
Normal file
34
soc/xtensa/intel_apl_adsp/common/bootloader/boot_module.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright(c) 2018 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Marcin Maka <marcin.maka@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include "manifest.h"
|
||||
#include <platform/memory.h>
|
||||
|
||||
/*
|
||||
* Each module has an entry in the FW manifest header. This is NOT part of
|
||||
* the SOF executable image but is inserted by object copy as a ELF section
|
||||
* for parsing by rimage (to generate the manifest).
|
||||
*/
|
||||
struct sof_man_module_manifest apl_bootldr_manifest = {
|
||||
.module = {
|
||||
.name = "BRNGUP",
|
||||
.uuid = {
|
||||
0xcc, 0x48, 0x7b, 0x0d, 0xa9, 0x1e, 0x0a, 0x47,
|
||||
0xa8, 0xc1, 0x53, 0x34, 0x24, 0x52, 0x8a, 0x17
|
||||
},
|
||||
.entry_point = IMR_BOOT_LDR_TEXT_ENTRY_BASE,
|
||||
.type = {
|
||||
.load_type = SOF_MAN_MOD_TYPE_MODULE,
|
||||
.domain_ll = 1,
|
||||
},
|
||||
.affinity_mask = 3,
|
||||
},
|
||||
};
|
||||
|
||||
/* not used, but stops linker complaining */
|
||||
int _start;
|
199
soc/xtensa/intel_apl_adsp/common/bootloader/manifest.h
Normal file
199
soc/xtensa/intel_apl_adsp/common/bootloader/manifest.h
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright(c) 2017 Intel Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __INCLUDE_UAPI_USER_MANIFEST_H__
|
||||
#define __INCLUDE_UAPI_USER_MANIFEST_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* start offset for base FW module */
|
||||
#define SOF_MAN_ELF_TEXT_OFFSET 0x2000
|
||||
|
||||
/* FW Extended Manifest Header id = $AE1 */
|
||||
#define SOF_MAN_EXT_HEADER_MAGIC 0x31454124
|
||||
|
||||
/* module type load type */
|
||||
#define SOF_MAN_MOD_TYPE_BUILTIN 0
|
||||
#define SOF_MAN_MOD_TYPE_MODULE 1
|
||||
|
||||
struct sof_man_module_type {
|
||||
uint32_t load_type:4; /* SOF_MAN_MOD_TYPE_ */
|
||||
uint32_t auto_start:1;
|
||||
uint32_t domain_ll:1;
|
||||
uint32_t domain_dp:1;
|
||||
uint32_t rsvd_:25;
|
||||
};
|
||||
|
||||
/* segment flags.type */
|
||||
#define SOF_MAN_SEGMENT_TEXT 0
|
||||
#define SOF_MAN_SEGMENT_RODATA 1
|
||||
#define SOF_MAN_SEGMENT_DATA 1
|
||||
#define SOF_MAN_SEGMENT_BSS 2
|
||||
#define SOF_MAN_SEGMENT_EMPTY 15
|
||||
|
||||
union sof_man_segment_flags {
|
||||
uint32_t ul;
|
||||
struct {
|
||||
uint32_t contents:1;
|
||||
uint32_t alloc:1;
|
||||
uint32_t load:1;
|
||||
uint32_t readonly:1;
|
||||
uint32_t code:1;
|
||||
uint32_t data:1;
|
||||
uint32_t _rsvd0:2;
|
||||
uint32_t type:4; /* MAN_SEGMENT_ */
|
||||
uint32_t _rsvd1:4;
|
||||
uint32_t length:16; /* of segment in pages */
|
||||
} r;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Module segment descriptor. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_segment_desc {
|
||||
union sof_man_segment_flags flags;
|
||||
uint32_t v_base_addr;
|
||||
uint32_t file_offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* The firmware binary can be split into several modules.
|
||||
*/
|
||||
|
||||
#define SOF_MAN_MOD_ID_LEN 4
|
||||
#define SOF_MAN_MOD_NAME_LEN 8
|
||||
#define SOF_MAN_MOD_SHA256_LEN 32
|
||||
#define SOF_MAN_MOD_ID {'$', 'A', 'M', 'E'}
|
||||
|
||||
/*
|
||||
* Each module has an entry in the FW header. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_module {
|
||||
uint8_t struct_id[SOF_MAN_MOD_ID_LEN]; /* SOF_MAN_MOD_ID */
|
||||
uint8_t name[SOF_MAN_MOD_NAME_LEN];
|
||||
uint8_t uuid[16];
|
||||
struct sof_man_module_type type;
|
||||
uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
|
||||
uint32_t entry_point;
|
||||
uint16_t cfg_offset;
|
||||
uint16_t cfg_count;
|
||||
uint32_t affinity_mask;
|
||||
uint16_t instance_max_count; /* max number of instances */
|
||||
uint16_t instance_bss_size; /* instance (pages) */
|
||||
struct sof_man_segment_desc segment[3];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Each module has a configuration in the FW header. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_mod_config {
|
||||
uint32_t par[4]; /* module parameters */
|
||||
uint32_t is_pages; /* actual size of instance .bss (pages) */
|
||||
uint32_t cps; /* cycles per second */
|
||||
uint32_t ibs; /* input buffer size (bytes) */
|
||||
uint32_t obs; /* output buffer size (bytes) */
|
||||
uint32_t module_flags; /* flags, reserved for future use */
|
||||
uint32_t cpc; /* cycles per single run */
|
||||
uint32_t obls; /* output block size, reserved for future use */
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* FW Manifest Header
|
||||
*/
|
||||
|
||||
#define SOF_MAN_FW_HDR_FW_NAME_LEN 8
|
||||
#define SOF_MAN_FW_HDR_ID {'$', 'A', 'M', '1'}
|
||||
#define SOF_MAN_FW_HDR_NAME "ADSPFW"
|
||||
#define SOF_MAN_FW_HDR_FLAGS 0x0
|
||||
#define SOF_MAN_FW_HDR_FEATURES 0x1ff
|
||||
|
||||
/*
|
||||
* The firmware has a standard header that is checked by the ROM on firmware
|
||||
* loading. preload_page_count is used by DMA code loader and is entire
|
||||
* image size on CNL. i.e. CNL: total size of the binary’s .text and .rodata
|
||||
* Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_fw_header {
|
||||
uint8_t header_id[4];
|
||||
uint32_t header_len;
|
||||
uint8_t name[SOF_MAN_FW_HDR_FW_NAME_LEN];
|
||||
/* number of pages of preloaded image loaded by driver */
|
||||
uint32_t preload_page_count;
|
||||
uint32_t fw_image_flags;
|
||||
uint32_t feature_mask;
|
||||
uint16_t major_version;
|
||||
uint16_t minor_version;
|
||||
uint16_t hotfix_version;
|
||||
uint16_t build_version;
|
||||
uint32_t num_module_entries;
|
||||
uint32_t hw_buf_base_addr;
|
||||
uint32_t hw_buf_length;
|
||||
/* target address for binary loading as offset in IMR
|
||||
* must be == base offset
|
||||
*/
|
||||
uint32_t load_offset;
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Firmware manifest descriptor. This can contain N modules and N module
|
||||
* configs. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_fw_desc {
|
||||
struct sof_man_fw_header header;
|
||||
|
||||
/* Warning - hack for module arrays. For some unknown reason the we
|
||||
* have a variable size array of struct man_module followed by a
|
||||
* variable size array of struct mod_config. These should have been
|
||||
* merged into a variable array of a parent structure. We have to hack
|
||||
* around this in many places....
|
||||
*
|
||||
* struct sof_man_module man_module[];
|
||||
* struct sof_man_mod_config mod_config[];
|
||||
*/
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Component Descriptor. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_component_desc {
|
||||
uint32_t reserved[2]; /* all 0 */
|
||||
uint32_t version;
|
||||
uint8_t hash[SOF_MAN_MOD_SHA256_LEN];
|
||||
uint32_t base_offset;
|
||||
uint32_t limit_offset;
|
||||
uint32_t attributes[4];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Audio DSP extended metadata. Used by ROM - Immutable.
|
||||
*/
|
||||
struct sof_man_adsp_meta_file_ext {
|
||||
uint32_t ext_type; /* always 17 for ADSP extension */
|
||||
uint32_t ext_len;
|
||||
uint32_t imr_type;
|
||||
uint8_t reserved[16]; /* all 0 */
|
||||
struct sof_man_component_desc comp_desc[1];
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Module Manifest for rimage module metadata. Not used by ROM.
|
||||
*/
|
||||
struct sof_man_module_manifest {
|
||||
struct sof_man_module module;
|
||||
uint32_t text_size;
|
||||
};
|
||||
|
||||
/*
|
||||
* Module offset in manifest.
|
||||
*/
|
||||
#define SOF_MAN_MODULE_OFFSET(index) \
|
||||
(sizeof(struct sof_man_fw_header) + \
|
||||
(index) * sizeof(struct sof_man_module))
|
||||
|
||||
#endif
|
11
soc/xtensa/intel_apl_adsp/common/bootloader/start_address.S
Normal file
11
soc/xtensa/intel_apl_adsp/common/bootloader/start_address.S
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Intel Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <platform/memory.h>
|
||||
|
||||
.global _start
|
||||
.equ _start, SOF_TEXT_BASE
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue