Merge "Merge remote-tracking branch 'origin/core'"

This commit is contained in:
Anas Nashif 2017-02-15 04:33:25 +00:00
commit 15a6598691
137 changed files with 14962 additions and 39 deletions

3
.gitignore vendored
View file

@ -31,3 +31,6 @@ scripts/grub
doc/reference/kconfig/CONFIG_* doc/reference/kconfig/CONFIG_*
doc/reference/kconfig/index.rst doc/reference/kconfig/index.rst
tags tags
.project
.cproject
.xxproject

2
Kbuild
View file

@ -90,7 +90,7 @@ define rule_cc_o_c_1
$(call echo-cmd,cc_o_c_1) $(cmd_cc_o_c_1); $(call echo-cmd,cc_o_c_1) $(cmd_cc_o_c_1);
endef endef
cmd_cc_o_c_1 = $(CC) $(KBUILD_CFLAGS) $(ZEPHYRINCLUDE) -c -o $@ $< cmd_cc_o_c_1 = $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(ZEPHYRINCLUDE) -c -o $@ $<
arch/$(ARCH)/core/offsets/offsets.o: arch/$(ARCH)/core/offsets/offsets.c $(KCONFIG_CONFIG) \ arch/$(ARCH)/core/offsets/offsets.o: arch/$(ARCH)/core/offsets/offsets.c $(KCONFIG_CONFIG) \
include/generated/generated_dts_board.h include/generated/generated_dts_board.h

View file

@ -376,7 +376,6 @@ ZEPHYRINCLUDE = \
KBUILD_CPPFLAGS := -DKERNEL -D__ZEPHYR__=1 KBUILD_CPPFLAGS := -DKERNEL -D__ZEPHYR__=1
KBUILD_CFLAGS := -c -g -std=c99 \ KBUILD_CFLAGS := -c -g -std=c99 \
-fno-asynchronous-unwind-tables \
-Wall \ -Wall \
-Wformat \ -Wformat \
-Wformat-security \ -Wformat-security \
@ -595,6 +594,12 @@ drivers-y := drivers/
ARCH = $(subst $(DQUOTE),,$(CONFIG_ARCH)) ARCH = $(subst $(DQUOTE),,$(CONFIG_ARCH))
export ARCH export ARCH
ifeq ($(CONFIG_DEBUG),y)
KBUILD_CFLAGS += -Og
else
KBUILD_CFLAGS += -Os
endif
ifdef ZEPHYR_GCC_VARIANT ifdef ZEPHYR_GCC_VARIANT
include $(srctree)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT) include $(srctree)/scripts/Makefile.toolchain.$(ZEPHYR_GCC_VARIANT)
else else
@ -632,11 +637,8 @@ KBUILD_CFLAGS += $(call cc-option,-fno-reorder-blocks,) \
$(call cc-option,-fno-partial-inlining) $(call cc-option,-fno-partial-inlining)
endif endif
ifeq ($(CONFIG_DEBUG),y) # Some GCC variants don't support these
KBUILD_CFLAGS += -Og KBUILD_CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,)
else
KBUILD_CFLAGS += -Os
endif
ifeq ($(CONFIG_STACK_CANARIES),y) ifeq ($(CONFIG_STACK_CANARIES),y)
KBUILD_CFLAGS += $(call cc-option,-fstack-protector-all,) KBUILD_CFLAGS += $(call cc-option,-fstack-protector-all,)
@ -683,8 +685,10 @@ else
# Use make W=1 to enable this warning (see scripts/Makefile.build) # Use make W=1 to enable this warning (see scripts/Makefile.build)
KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable) KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
KBUILD_CFLAGS += $(call cc-option,-fno-reorder-functions) KBUILD_CFLAGS += $(call cc-option,-fno-reorder-functions)
ifneq (${ZEPHYR_GCC_VARIANT},xcc)
KBUILD_CFLAGS += $(call cc-option,-fno-defer-pop) KBUILD_CFLAGS += $(call cc-option,-fno-defer-pop)
endif endif
endif
# We trigger additional mismatches with less inlining # We trigger additional mismatches with less inlining
ifdef CONFIG_DEBUG_SECTION_MISMATCH ifdef CONFIG_DEBUG_SECTION_MISMATCH

View file

@ -3,6 +3,7 @@
# #
# Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2014-2015 Wind River Systems, Inc.
# Copyright (c) 2015 Intel Corporation # Copyright (c) 2015 Intel Corporation
# Copyright (c) 2016 Cadence Design Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -29,6 +30,9 @@ config NIOS2
config RISCV32 config RISCV32
bool "RISCV32 architecture" bool "RISCV32 architecture"
config XTENSA
bool "Xtensa architecture"
endchoice endchoice
# #

12
arch/xtensa/Kbuild Normal file
View file

@ -0,0 +1,12 @@
subdir-ccflags-y +=-I$(srctree)/include/drivers
subdir-ccflags-y +=-I$(srctree)/drivers
subdir-asflags-y := ${subdir-ccflags-y}
ifneq ($(SOC_FAMILY),)
obj-y += soc/$(SOC_FAMILY)/
else
obj-y += soc/$(SOC_PATH)/
endif
obj-y += core/
obj-y += core/startup/

81
arch/xtensa/Kconfig Normal file
View file

@ -0,0 +1,81 @@
# Kconfig - XTENSA architecture configuration options
#
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
choice
prompt "XTENSA core Selection"
default sample_controller
depends on XTENSA
source "arch/xtensa/soc/Kconfig.cores"
endchoice
menu "XTENSA Options"
depends on XTENSA
config ARCH
default "xtensa"
config SYS_CLOCK_HW_CYCLES_PER_SEC
int
prompt "Hardware clock cycles per second, 2000000 for ISS"
default 2000000
range 1000000 1000000000
help
This option specifies hardware clock.
config XTENSA_NO_IPC
bool "Core has no IPC support"
select ATOMIC_OPERATIONS_C
default n
help
Uncheck this if you core does not implment "SCOMPARE1" register and "s32c1i"
isntruction.
config SW_ISR_TABLE
bool
prompt "Enable software interrupt handler table"
default y
help
Enable an interrupt handler table implemented in software. This
table, unlike ISRs connected directly in the vector table, allow
a parameter to be passed to the interrupt handlers. Also, invoking
the exeception/interrupt exit stub is automatically done.
This has to be enabled for dynamically connecting interrupt handlers
at runtime (SW_ISR_TABLE_DYNAMIC).
config IRQ_OFFLOAD
bool "Enable IRQ offload"
default n
help
Enable irq_offload() API which allows functions to be synchronously
run in interrupt context. Uses one entry in the IDT. Mainly useful
for test cases.
config SW_ISR_TABLE_DYNAMIC
bool
prompt "Allow installing interrupt handlers at runtime"
depends on SW_ISR_TABLE
default n
help
This option enables irq_connect_dynamic(). It moves the ISR table to
SRAM so that it is writable. This has the side-effect of removing
write-protection on the ISR table.
menu "Specific core configuration"
config IRQ_OFFLOAD_INTNUM
int
prompt "IRQ offload SW interrupt index"
help
The index of the software interrupt to be used for IRQ offload.
Please note that in order for IRQ offload to work correctly the selected
interrupt shall have its priority shall not exceed XCHAL_EXCM_LEVEL.
source "arch/xtensa/soc/*/Kconfig"
endmenu
endmenu

41
arch/xtensa/Makefile Normal file
View file

@ -0,0 +1,41 @@
SOC_PATH=${XTENSA_CORE}
export SOC_PATH
flagBoardType=
ifeq ($(CONFIG_BOARD_XTENSA),y)
flagBoardType= -DXT_BOARD
endif
ifeq ($(CONFIG_SIMULATOR_XTENSA),y)
flagBoardType= -DXT_SIMULATOR
endif
# XCC emits an annoying warning if this is used even though the
# $(call cc-option,) test in toplevel Makefile passes.
KBUILD_CFLAGS := $(filter-out -fno-omit-frame-pointer, \
${KBUILD_CFLAGS})
# Put functions and data in their own binary sections so that ld can
# garbage collect them
KBUILD_CFLAGS += $(call cc-option,-ffunction-sections,) \
$(call cc-option,-fdata-sections,)
KBUILD_AFLAGS += $(flagBoardType)
KBUILD_CFLAGS += -DPROC_$(XTENSA_CORE) \
-DCONFIG_$(XTENSA_CORE) \
$(flagBoardType) \
$(call cc-option,-fms-extensions,)
include $(srctree)/arch/$(ARCH)/core/Makefile
include $(srctree)/arch/$(ARCH)/soc/$(SOC_PATH)/Makefile
cflags-$(CONFIG_LTO) += $(call cc-option,-flto,)
KBUILD_CFLAGS += $(cflags-y)
KBUILD_CXXFLAGS += $(cflags-y)
QEMU_CPU_TYPE_xtensa ?= unsupported
QEMU_FLAGS_xtensa = -cpu $(QEMU_CPU_TYPE_xtensa) \
-machine sim -semihosting -nographic
QEMU_xtensa = qemu-system-xtensa
export QEMU_FLAGS_xtensa QEMU_xtensa

18
arch/xtensa/core/Makefile Normal file
View file

@ -0,0 +1,18 @@
ccflags-y += -I$(srctree)/kernel/unified/include
asflags-y += -I$(srctree)/kernel/unified/include --longcalls
ifdef CONFIG_ATOMIC_OPERATIONS_C
# Use C routines from kernel/nanokernel/atomic.c
obj-atomic=
else
# Use our own routines implmented in assembly
obj-atomic=atomic.o
endif
obj-y = ${obj-atomic} cpu_idle.o fatal.o \
swap.o thread.o xt_zephyr.o xtensa_context.o xtensa_intr_asm.o \
xtensa_intr.o xtensa_vectors.o irq_manage.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
obj-$(CONFIG_SIMULATOR_XTENSA) += crt1-sim.o
obj-$(CONFIG_BOARD_XTENSA) += crt1-boards.o
# Keep this last so that vague linking works
obj-y += sw_isr_table.o

405
arch/xtensa/core/atomic.S Normal file
View file

@ -0,0 +1,405 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa_context.h>
/**
*
* @brief Atomically clear a memory location
*
* This routine atomically clears the contents of <target> and returns the old
* value that was in <target>.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_clear
* (
* atomic_t *target /@ memory location to clear @/
* )
*/
.global atomic_clear
.type atomic_clear,@function
.align 4
atomic_clear:
ENTRY(48)
movi a4, 0
.L_LoopClear:
l32ai a3, a2, 0
wsr a3, scompare1
s32c1i a4, a2, 0
bne a3, a4, .L_LoopClear
mov a2, a3
RET(48)
/**
*
* @brief Atomically set a memory location
*
* This routine atomically sets the contents of <target> to <value> and returns
* the old value that was in <target>.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_set
* (
* atomic_t *target, /@ memory location to set @/
* atomic_val_t value /@ set with this value @/
* )
*
*/
.global atomic_set
.type atomic_set,@function
.align 4
atomic_set:
ENTRY(48)
.L_LoopSet:
l32ai a4, a2, 0
wsr a4, scompare1
s32c1i a3, a2, 0
bne a3, a4, .L_LoopSet
mov a2, a3
RET(48)
/**
*
* @brief Get the value of a shared memory atomically
*
* This routine atomically retrieves the value in *target
*
* long atomic_get
* (
* atomic_t * target /@ address of atom to be retrieved @/
* )
*
* @return value read from address target.
*
*/
.global atomic_get
.type atomic_get,@function
.align 4
atomic_get:
ENTRY(48)
l32ai a2, a2, 0
RET(48)
/**
*
* @brief Atomically increment a memory location
*
* This routine atomically increments the value in <target>. The operation is
* done using unsigned integer arithmetic. Various CPU architectures may
* impose restrictions with regards to the alignment and cache attributes of
* the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_inc
* (
* atomic_t *target, /@ memory location to increment @/
* )
*
*/
.global atomic_inc
.type atomic_inc,@function
.align 4
atomic_inc:
ENTRY(48)
.L_LoopInc:
l32ai a3, a2, 0
wsr a3, scompare1
addi a4, a3, 1
s32c1i a4, a2, 0
bne a3, a4, .L_LoopInc
mov a2, a3
RET(48)
/**
*
* @brief Atomically add a value to a memory location
*
* This routine atomically adds the contents of <target> and <value>, placing
* the result in <target>. The operation is done using signed integer
* arithmetic. Various CPU architectures may impose restrictions with regards
* to the alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_add
* (
* atomic_t *target, /@ memory location to add to @/
* atomic_val_t value /@ value to add @/
* )
*/
.global atomic_add
.type atomic_add,@function
.align 4
atomic_add:
ENTRY(48)
.L_LoopAdd:
l32ai a4, a2, 0
wsr a4, scompare1
add a5, a3, a4
s32c1i a5, a2, 0
bne a5, a4, .L_LoopAdd
mov a2, a5
RET(48)
/**
*
* @brief Atomically decrement a memory location
*
* This routine atomically decrements the value in <target>. The operation is
* done using unsigned integer arithmetic. Various CPU architectures may impose
* restrictions with regards to the alignment and cache attributes of the
* atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_dec
* (
* atomic_t *target, /@ memory location to decrement @/
* )
*
*/
.global atomic_dec
.type atomic_dec,@function
.align 4
atomic_dec:
ENTRY(48)
.L_LoopDec:
l32ai a3, a2, 0
wsr a3, scompare1
addi a4, a3, -1
s32c1i a4, a2, 0
bne a3, a4, .L_LoopDec
mov a2, a3
RET(48)
/**
*
* @brief Atomically subtract a value from a memory location
*
* This routine atomically subtracts <value> from the contents of <target>,
* placing the result in <target>. The operation is done using signed integer
* arithmetic. Various CPU architectures may impose restrictions with regards to
* the alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_sub
* (
* atomic_t *target, /@ memory location to subtract from @/
* atomic_val_t value /@ value to subtract @/
* )
*
*/
.global atomic_sub
.type atomic_sub,@function
.align 4
atomic_sub:
ENTRY(48)
.L_LoopSub:
l32ai a4, a2, 0
wsr a4, scompare1
sub a5, a4, a3
s32c1i a5, a2, 0
bne a5, a4, .L_LoopSub
mov a2, a5
RET(48)
/**
*
* @brief Atomically perform a bitwise NAND on a memory location
*
* This routine atomically performs a bitwise NAND operation of the contents of
* <target> and <value>, placing the result in <target>.
* Various CPU architectures may impose restrictions with regards to the
* alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_nand
* (
* atomic_t *target, /@ memory location to NAND @/
* atomic_val_t value /@ NAND with this value @/
* )
*
*/
.global atomic_nand
.type atomic_nand,@function
.align 4
atomic_nand:
ENTRY(48)
.L_LoopNand:
l32ai a4, a2, 0
wsr a4, scompare1
and a5, a3, a4
neg a5, a5
addi a5, a5, -1
s32c1i a5, a2, 0
bne a5, a4, .L_LoopNand
mov a2, a4
RET(48)
/**
*
* @brief Atomically perform a bitwise AND on a memory location
*
* This routine atomically performs a bitwise AND operation of the contents of
* <target> and <value>, placing the result in <target>.
* Various CPU architectures may impose restrictions with regards to the
* alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_and
* (
* atomic_t *target, /@ memory location to AND @/
* atomic_val_t value /@ AND with this value @/
* )
*
*/
.global atomic_and
.type atomic_and,@function
.align 4
atomic_and:
ENTRY(48)
.L_LoopAnd:
l32ai a4, a2, 0
wsr a4, scompare1
and a5, a3, a4
s32c1i a5, a2, 0
bne a5, a4, .L_LoopAnd
mov a2, a4
RET(48)
/**
*
* @brief Atomically perform a bitwise OR on memory location
*
* This routine atomically performs a bitwise OR operation of the contents of
* <target> and <value>, placing the result in <target>.
* Various CPU architectures may impose restrictions with regards to the
* alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_or
* (
* atomic_t *target, /@ memory location to OR @/
* atomic_val_t value /@ OR with this value @/
* )
*
*/
.global atomic_or
.type atomic_or,@function
.align 4
atomic_or:
ENTRY(48)
.L_LoopOr:
l32ai a4, a2, 0
wsr a4, scompare1
or a5, a3, a4
s32c1i a5, a2, 0
bne a4, a5, .L_LoopOr
mov a2, a4
RET(48)
/**
*
* @brief Atomically perform a bitwise XOR on a memory location
*
* This routine atomically performs a bitwise XOR operation of the contents of
* <target> and <value>, placing the result in <target>.
* Various CPU architectures may impose restrictions with regards to the
* alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return Contents of <target> before the atomic operation
*
* atomic_val_t atomic_xor
* (
* atomic_t *target, /@ memory location to XOR @/
* atomic_val_t value /@ XOR with this value @/
* )
*
*/
.global atomic_xor
.type atomic_xor,@function
.align 4
atomic_xor:
ENTRY(48)
.L_LoopXor:
l32ai a4, a2, 0
wsr a4, scompare1
xor a5, a3, a4
s32c1i a5, a2, 0
bne a5, a4, .L_LoopXor
mov a2, a4
RET(48)
/**
*
* @brief Atomically compare-and-swap the contents of a memory location
*
* This routine performs an atomic compare-and-swap. testing that the contents
* of <target> contains <oldValue>, and if it does, setting the value of
* <target> to <newValue>. Various CPU architectures may impose restrictions
* with regards to the alignment and cache attributes of the atomic_t type.
*
* This routine can be used from both task and interrupt level.
*
* @return 1 if the swap is actually executed, 0 otherwise.
*
* int atomic_cas
* (
* atomic_t *target, /@ memory location to compare-and-swap @/
* atomic_val_t oldValue, /@ compare to this value @/
* atomic_val_t newValue, /@ swap with this value @/
* )
*
*/
.global atomic_cas
.type atomic_cas,@function
.align 4
atomic_cas:
ENTRY(48)
.L_LoopCas:
l32ai a5, a2, 0
beq a5, a3, 1f
movi a2, 0
j 2f
1:
wsr a5, scompare1
s32c1i a4, a2, 0
bne a3, a5, .L_LoopCas
movi a2, 1
2:
RET(48)

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/tie/xt_core.h>
#include <xtensa/tie/xt_interrupt.h>
#include <logging/kernel_event_logger.h>
/*
* @brief Put the CPU in low-power mode
*
* This function always exits with interrupts unlocked.
*
* void k_cpu_idle(void)
*/
void k_cpu_idle(void)
{
#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
_sys_k_event_logger_enter_sleep();
#endif
XT_WAITI(0);
}
/*
* @brief Put the CPU in low-power mode, entered with IRQs locked
*
* This function exits with interrupts restored to <key>.
*
* void nano_cpu_atomic_idle(unsigned int key)
*/
void k_cpu_atomic_idle(unsigned int key)
{
#ifdef CONFIG_KERNEL_EVENT_LOGGER_SLEEP
_sys_k_event_logger_enter_sleep();
#endif
XT_WAITI(0);
XT_WSR_PS(key);
XT_RSYNC();
}

View file

@ -0,0 +1,271 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* For most hardware / boards, this code sets up the C calling context
* (setting up stack, PS, and clearing BSS) and jumps to __clibrary_start
* which sets up the C library, calls constructors and registers destructors,
* and calls main().
*
* Control arrives here at _start from the reset vector or from crt0-app.S.
*/
#include <xtensa/coreasm.h>
#include "xtos-internal.h"
/* Exports */
.global _start
/*
* Imports
* __clibrary_init from C library (eg. newlib or uclibc)
* exit from C library
* main from user application
* board_init board-specific (uart/mingloss/tinygloss.c)
* xthal_dcache_all_writeback from HAL library
* __stack from linker script (see LSP Ref Manual)
* _bss_table_start from linker script (see LSP Ref Manual)
* _bss_table_end from linker script (see LSP Ref Manual)
*/
.type main, @function
/* Macros to abstract away ABI differences */
#if __XTENSA_CALL0_ABI__
# define CALL call0
# define CALLX callx0
# define ARG1 a2 /* 1st outgoing call argument */
# define ARG2 a3 /* 2nd outgoing call argument */
# define ARG3 a4 /* 3rd outgoing call argument */
# define ARG4 a5 /* 4th outgoing call argument */
# define ARG5 a6 /* 5th outgoing call argument */
#else
# define CALL call4
# define CALLX callx4
# define ARG1 a6 /* 1st outgoing call argument */
# define ARG2 a7 /* 2nd outgoing call argument */
# define ARG3 a8 /* 3rd outgoing call argument */
# define ARG4 a9 /* 4th outgoing call argument */
# define ARG5 a10 /* 5th outgoing call argument */
#endif
/**************************************************************************/
.text
.align 4
_start:
/*
* _start is typically NOT at the beginning of the text segment --
* it is always called from either the reset vector or other code
* that does equivalent initialization (such as crt0-app.S).
*
* Assumptions on entry to _start:
* - low (level-one) and medium priority interrupts are disabled
* via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
* be zeroed, to potentially enable them, before calling main)
* - C calling context not initialized:
* - PS not initialized
* - SP not initialized
* - the following are initialized:
* - LITBASE, cache attributes, WindowBase, WindowStart,
* CPENABLE, FP's FCR and FSR, EXCSAVE[n]
* Keep a0 zero. It is used to initialize a few things.
* It is also the return address, where zero indicates
* that the frame used by _start is the bottommost frame.
*/
/* not needed for Xtensa TX */
#if !XCHAL_HAVE_HALT || !XCHAL_HAVE_BOOTLOADER
movi a0, 0 /* keep this register zero. */
#endif
#if XTOS_RESET_UNNEEDED && !XCHAL_HAVE_HALT
#include "reset-unneeded.S"
#endif
/*
* Initialize the stack pointer.
* See the "ABI and Software Conventions" chapter in the
* Xtensa ISA Reference manual for details.
*
* NOTE: Because the _start routine does not use any memory in its
* stack frame, and because all of its CALL instructions use a
* window size of 4 (or zero), the stack frame for _start can be empty.
*/
movi sp, __stack
/*
* Now that sp (a1) is set, we can set PS as per the application (user
* vector mode, enable interrupts, enable window exceptions if
* applicable).
*/
#if XCHAL_HAVE_EXCEPTIONS
# ifdef __XTENSA_CALL0_ABI__
/* PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM
# else
/* PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM|PS_WOE
# endif
wsr a3, PS
rsync
#endif
/*
* Do any initialization that affects the memory map, such as
* setting up TLB entries, that needs to be done before we can
* successfully clear BSS (e.g. if some BSS segments are in
* remapped areas).
*
* NOTE: This hook works where the reset vector does not unpack
* segments (see "ROM packing" in the LSP manual), or where
* unpacking of segments is not affected by memory remapping.
* If ROM unpacking is affected, TLB setup must be done in
* assembler from the reset vector.
*
* The __memmap_init() routine can be a C function, however it
* does not have BSS initialized! In particular, __memmap_init()
* cannot set BSS variables, i.e. uninitialized global variables
* (they'll be wiped out by the following BSS clear), nor can it
* assume they are yet initialized to zero.
*
* The __memmap_init() function is optional. It is marked as a
* weak symbol, so that it gets valued zero if not defined.
*/
.weak __memmap_init
movi a4, __memmap_init
beqz a4, 1f
CALLX a4
1:
#if !XCHAL_HAVE_BOOTLOADER /* boot loader takes care of zeroing BSS */
# ifdef __XTENSA_CALL0_ABI__
/* Clear a0 again as possible CALLX to __memmap_init changed it. */
movi a0, 0
# endif
/*
* Clear the BSS (uninitialized data) segments.
* This code supports multiple zeroed sections (*.bss).
*
* Register allocation:
* a0 = 0
* a6 = pointer to start of table, and through table
* a7 = pointer to end of table
* a8 = start address of bytes to be zeroed
* a9 = end address of bytes to be zeroed
* a10 = length of bytes to be zeroed
*/
movi a6, _bss_table_start
movi a7, _bss_table_end
bgeu a6, a7, .L3zte
.L0zte: l32i a8, a6, 0 /* get start address, assumed multiple of 4 */
l32i a9, a6, 4 /* get end address, assumed multiple of 4 */
addi a6, a6, 8 /* next entry */
sub a10, a9, a8 /* a10 = length, assumed a multiple of 4 */
bbci.l a10, 2, .L1zte
s32i a0, a8, 0 /* clear 4 bytes to make len multiple of 8 */
addi a8, a8, 4
.L1zte: bbci.l a10, 3, .L2zte
s32i a0, a8, 0 /* clear 8 bytes to make len multiple of 16 */
s32i a0, a8, 4
addi a8, a8, 8
.L2zte: srli a10, a10, 4 /* len is now multiple of 16, divide by 16 */
floopnez a10, clearzte
s32i a0, a8, 0 /* clear 16 bytes at a time... */
s32i a0, a8, 4
s32i a0, a8, 8
s32i a0, a8, 12
addi a8, a8, 16
floopend a10, clearzte
bltu a6, a7, .L0zte /* loop until end of table of *.bss sections */
.L3zte:
#endif
/*
* We can now call C code, the C calling environment has been
* initialized.
*
* From this point on, we use ABI-specific macros to refer to
* registers a0 .. a15 (ARG#).
*/
#if XCHAL_HAVE_HALT
/*
* Assume minimalist environment for memory-constrained TX cores.
* No C library or board initialization, no parameters passed to main
* (assume declared as "void main(void)") and no call to exit().
*/
CALL main
halt
#else /* !HALT */
.type board_init, @function
.type __clibrary_init, @function
.type exit, @function
/* Initialize the board (eg. UART, etc). */
CALL board_init
/*
* Call __clibrary_init to initialize the C library:
*
* void __clibrary_init(int argc, char ** argv, char ** environ,
* void(*init_func)(void), void(*fini_func)(void));
* Pass an empty argv array, with an empty string as the program name
*/
movi ARG1, _start_argc /* argc address */
movi ARG2, _start_argv /* argv = ["", 0] */
movi ARG3, _start_envp /* envp = [0] */
movi ARG4, _init /* function that calls constructors */
movi ARG5, _fini /* function that calls destructors */
l32i ARG1, ARG1, 0 /* argc = 1 */
CALL __clibrary_init
/* Call: int main(int argc, char ** argv, char ** environ); */
movi ARG1, _start_argc /* argc address */
movi ARG2, _start_argv /* argv = ["", 0] */
movi ARG3, _start_envp /* envp = [0] */
l32i ARG1, ARG1, 0 /* argc = 1 */
CALL main
/* The return value is the same register as the first
* outgoing argument.
*/
CALL exit /* exit with main's return value */
/* Does not return here. */
.data
/*
* Mark argc/argv/envp parameters as weak so that an external
* object file can override them.
*/
.weak _start_argc, _start_argv, _start_envp
.align 4
_start_argv:
.word _start_null /* empty program name */
_start_null:
_start_envp:
/* end of argv array, empty string, empty environ */
.word 0
_start_argc:
.word 1 /* one argument (program name) */
.text
#endif /* !HALT */
.size _start, . - _start

246
arch/xtensa/core/crt1-sim.S Normal file
View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* For the Xtensa simulator target, this code sets up the C calling context
* and calls main() (via __clibrary_start).
* Control arrives here at _start from the reset vector or from crt0-app.S.
*/
#include <xtensa/simboard.h>
#include <xtensa/simcall.h>
#include <xtensa/coreasm.h>
/* Exports */
.global _start
.global __start
/*
* Imports
* __clibrary_init from C library (eg. newlib or uclibc)
* exit from C library
* main from user application
* __stack from linker script (see LSP Ref Manual)
*/
.type __clibrary_init, @function
.type _Cstart, @function
.type exit, @function
/* Macros to abstract away ABI differences */
#if __XTENSA_CALL0_ABI__
# define CALL call0
# define CALLX callx0
# define ARG1 a2 /* 1st outgoing call argument */
# define ARG2 a3 /* 2nd outgoing call argument */
# define ARG3 a4 /* 3rd outgoing call argument */
# define ARG4 a5 /* 4th outgoing call argument */
# define ARG5 a6 /* 5th outgoing call argument */
#else
# define CALL call4
# define CALLX callx4
# define ARG1 a6 /* 1st outgoing call argument */
# define ARG2 a7 /* 2nd outgoing call argument */
# define ARG3 a8 /* 3rd outgoing call argument */
# define ARG4 a9 /* 4th outgoing call argument */
# define ARG5 a10 /* 5th outgoing call argument */
#endif
.data
.weak _start_envp /* allow overriding */
.align 4
_start_envp: .word 0 /* empty environ */
.text
.align 4
_start:
__start:
/*
* _start is typically NOT at the beginning of the text segment --
* it is always called from either the reset vector or other code
* that does equivalent initialization (such as crt0-app.S).
*
* Assumptions on entry to _start:
* - low (level-one) and medium priority interrupts are disabled
* via PS.INTLEVEL and/or INTENABLE (PS.INTLEVEL is expected to
* be zeroed, to potentially enable them, before calling main)
* - C calling context not initialized:
* - PS not initialized
* - SP not initialized
* - the following are initialized:
* - LITBASE, cache attributes, WindowBase, WindowStart,
* CPENABLE, FP's FCR and FSR, EXCSAVE[n]
* Keep a0 zero. It is used to initialize a few things.
* It is also the return address, where zero indicates
* that the frame used by _start is the bottommost frame.
*
*/
movi a0, 0 /* keep this register zero. */
#if XTOS_RESET_UNNEEDED
#include "reset-unneeded.S"
#endif
/*
* Initialize the stack pointer.
* See the "ABI and Software Conventions" chapter in the
* Xtensa ISA Reference manual for details.
*
* NOTE: Because the _start routine does not use any memory in its
* stack frame, and because all of its CALL instructions use a
* window size of 4, the stack frame for _start can be empty.
*/
movi sp, __stack
/*
* reserve stack space for
* - argv array
* - argument strings
*/
movi a2, SYS_iss_argv_size
simcall /* returns size of argv[] + its strings in a2 */
#if XCHAL_HAVE_PIF
/*
* The stack only needs 16-byte alignment. However, here we round up
* the argv size further to 128 byte multiples so that in most cases,
* variations in argv[0]'s path do not result in different stack
* allocation. Otherwise, such variations can impact execution timing
* (eg. due to cache effects etc) for the same code and data. If we
* have a PIF, it's more likely the extra required space is okay.
*/
addi a2, a2, 127
srli a2, a2, 7
slli a2, a2, 7
#else
/* Keep stack 16-byte aligned. */
addi a2, a2, 15
srli a2, a2, 4
slli a2, a2, 4
#endif
/*
* No need to use MOVSP because we have no caller (we're the
* base caller); in fact it's better not to use MOVSP in this
* context, to avoid unnecessary ALLOCA exceptions and copying
* from undefined memory:
* sub a3, sp, a2
* movsp sp, a3
*/
sub sp, sp, a2
/*
* Now that sp (a1) is set, we can set PS as per the application (user
* vector mode, enable interrupts, enable window exceptions if
* applicable).
*/
#if XCHAL_HAVE_EXCEPTIONS
# ifdef __XTENSA_CALL0_ABI__
/* PS.WOE = 0, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM
# else
/* PS.WOE = 1, PS.UM = 1, PS.EXCM = 0, PS.INTLEVEL = 0 */
movi a3, PS_UM|PS_WOE
# endif
wsr a3, PS
rsync
#endif
/*
* Do any initialization that affects the memory map, such as
* setting up TLB entries, that needs to be done before we can
* successfully clear BSS (e.g. if some BSS segments are in
* remapped areas).
*
* NOTE: This hook works where the reset vector does not unpack
* segments (see "ROM packing" in the LSP manual), or where
* unpacking of segments is not affected by memory remapping.
* If ROM unpacking is affected, TLB setup must be done in
* assembler from the reset vector.
*
* The __memmap_init() routine can be a C function, however it
* does not have BSS initialized! In particular, __memmap_init()
* cannot set BSS variables, i.e. uninitialized global variables
* (they'll be wiped out by the following BSS clear), nor can it
* assume they are yet initialized to zero.
*
* The __memmap_init() function is optional. It is marked as a
* weak symbol, so that it gets valued zero if not defined.
*/
.weak __memmap_init
movi a4, __memmap_init
beqz a4, 1f
CALLX a4
1:
/* The new ISS simcall only appeared after RB-2007.2: */
#if !XCHAL_HAVE_BOOTLOADER && \
(XCHAL_HW_MAX_VERSION > XTENSA_HWVERSION_RB_2007_2)
/* pre-LX2 cores only */
/*
* Clear the BSS (uninitialized data) segments.
* This code supports multiple zeroed sections (*.bss).
* For speed, we clear memory using an ISS simcall
* (see crt1-boards.S for more generic BSS clearing code).
*/
movi a6, _bss_table_start
movi a7, _bss_table_end
bgeu a6, a7, .Lnobss
.Lbssloop:
movi a2, SYS_memset
l32i a3, a6, 0 /* arg1 = fill start address */
movi a4, 0 /* arg2 = fill pattern */
l32i a5, a6, 4 /* get end address */
addi a6, a6, 8 /* next bss table entry */
sub a5, a5, a3 /* arg3 = fill size in bytes */
simcall /* memset(a3,a4,a5) */
bltu a6, a7, .Lbssloop /* loop until end of bss table */
.Lnobss:
#endif
/*
* Call __clibrary_init to initialize the C library:
*
* void __clibrary_init(int argc, char ** argv, char ** environ,
* void(*init_func)(void), void(*fini_func)(void));
*/
/* Get argv with the arguments from the ISS */
mov a3, sp /* tell simcall where to write argv[] */
movi a2, SYS_iss_set_argv
simcall /* write argv[] array at a3 */
movi a2, SYS_iss_argc
simcall /* put argc in a2 */
/* Call: int _Cstart(); */
CALL _Cstart
/* The return value is the same register as the first outgoing
* argument.
*/
CALL exit
/* Does not return here. */
.size _start, . - _start
/*
* Local Variables:
* mode:fundamental
* comment-start: "/* "
* comment-start-skip: "/* *"
* End:
*/

242
arch/xtensa/core/fatal.c Normal file
View file

@ -0,0 +1,242 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <kernel.h>
#include <arch/cpu.h>
#include <kernel_structs.h>
#include <inttypes.h>
#include <kernel_arch_data.h>
#include <misc/printk.h>
#include <xtensa/specreg.h>
const NANO_ESF _default_esf = {
{0xdeaddead}, /* sp */
0xdeaddead, /* pc */
};
/* Need to do this as a macro since regnum must be an immediate value */
#define get_sreg(regnum_p) ({ \
unsigned int retval; \
__asm__ volatile( \
"rsr %[retval], %[regnum]\n\t" \
: [retval] "=r" (retval) \
: [regnum] "i" (regnum_p)); \
retval; \
})
/**
*
* @brief Nanokernel fatal error handler
*
* This routine is called when fatal error conditions are detected by software
* and is responsible only for reporting the error. Once reported, it then
* invokes the user provided routine _SysFatalErrorHandler() which is
* responsible for implementing the error handling policy.
*
* The caller is expected to always provide a usable ESF. In the event that the
* fatal error does not have a hardware generated ESF, the caller should either
* create its own or use a pointer to the global default ESF <_default_esf>.
*
* @param reason the reason that the handler was called
* @param pEsf pointer to the exception stack frame
*
* @return This function does not return.
*/
FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf)
{
switch (reason) {
case _NANO_ERR_HW_EXCEPTION:
case _NANO_ERR_RESERVED_IRQ:
break;
case _NANO_ERR_INVALID_TASK_EXIT:
printk("***** Invalid Exit Software Error! *****\n");
break;
#if defined(CONFIG_STACK_CANARIES)
case _NANO_ERR_STACK_CHK_FAIL:
printk("***** Stack Check Fail! *****\n");
break;
#endif /* CONFIG_STACK_CANARIES */
case _NANO_ERR_ALLOCATION_FAIL:
printk("**** Kernel Allocation Failure! ****\n");
break;
default:
printk("**** Unknown Fatal Error %d! ****\n", reason);
break;
}
printk("Current thread ID = %p\n"
"Faulting instruction address = 0x%x\n",
k_current_get(),
pEsf->pc);
/*
* Now that the error has been reported, call the user implemented
* policy
* to respond to the error. The decisions as to what responses are
* appropriate to the various errors are something the customer must
* decide.
*/
_SysFatalErrorHandler(reason, pEsf);
}
#ifdef CONFIG_PRINTK
static char *cause_str(unsigned int cause_code)
{
switch (cause_code) {
case 0:
return "illegal instruction";
case 1:
return "syscall";
case 2:
return "instr fetch error";
case 3:
return "load/store error";
case 4:
return "level-1 interrupt";
case 5:
return "alloca";
case 6:
return "divide by zero";
case 8:
return "privileged";
case 9:
return "load/store alignment";
case 12:
return "instr PIF data error";
case 13:
return "load/store PIF data error";
case 14:
return "instr PIF addr error";
case 15:
return "load/store PIF addr error";
case 16:
return "instr TLB miss";
case 17:
return "instr TLB multi hit";
case 18:
return "instr fetch privilege";
case 20:
return "inst fetch prohibited";
case 24:
return "load/store TLB miss";
case 25:
return "load/store TLB multi hit";
case 26:
return "load/store privilege";
case 28:
return "load prohibited";
case 29:
return "store prohibited";
case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39:
return "coprocessor disabled";
default:
return "unknown/reserved";
}
}
#endif
static inline unsigned int get_bits(int offset, int num_bits, unsigned int val)
{
int mask;
mask = (1 << num_bits) - 1;
val = val >> offset;
return val & mask;
}
static void dump_exc_state(void)
{
#ifdef CONFIG_PRINTK
unsigned int cause, ps;
cause = get_sreg(EXCCAUSE);
ps = get_sreg(PS);
printk("Exception cause %d (%s):\n"
" EPC1 : 0x%08x EXCSAVE1 : 0x%08x EXCVADDR : 0x%08x\n",
cause, cause_str(cause), get_sreg(EPC_1),
get_sreg(EXCSAVE_1), get_sreg(EXCVADDR));
printk("Program state (PS):\n"
" INTLEVEL : %02d EXCM : %d UM : %d RING : %d WOE : %d\n",
get_bits(0, 4, ps), get_bits(4, 1, ps), get_bits(5, 1, ps),
get_bits(6, 2, ps), get_bits(18, 1, ps));
#ifndef __XTENSA_CALL0_ABI__
printk(" OWB : %02d CALLINC : %d\n",
get_bits(8, 4, ps), get_bits(16, 2, ps));
#endif
#endif /* CONFIG_PRINTK */
}
FUNC_NORETURN void FatalErrorHandler(void)
{
printk("*** Unhandled exception ****\n");
dump_exc_state();
_NanoFatalErrorHandler(_NANO_ERR_HW_EXCEPTION, &_default_esf);
}
FUNC_NORETURN void ReservedInterruptHandler(unsigned int intNo)
{
printk("*** Reserved Interrupt ***\n");
dump_exc_state();
printk("INTENABLE = 0x%x\n"
"INTERRUPT = 0x%x (%d)\n",
get_sreg(INTENABLE), (1 << intNo), intNo);
_NanoFatalErrorHandler(_NANO_ERR_RESERVED_IRQ, &_default_esf);
}
/* Implemented in Xtensa HAL */
extern FUNC_NORETURN void exit(int exit_code);
/**
*
* @brief Fatal error handler
*
* This routine implements the corrective action to be taken when the system
* detects a fatal error.
*
* This sample implementation attempts to abort the current thread and allow
* the system to continue executing, which may permit the system to continue
* functioning with degraded capabilities.
*
* System designers may wish to enhance or substitute this sample
* implementation to take other actions, such as logging error (or debug)
* information to a persistent repository and/or rebooting the system.
*
* @param reason the fatal error reason
* @param pEsf pointer to exception stack frame
*
* @return N/A
*/
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf)
{
ARG_UNUSED(reason);
ARG_UNUSED(pEsf);
#if !defined(CONFIG_SIMPLE_FATAL_ERROR_HANDLER)
if (k_is_in_isr() || _is_thread_essential()) {
printk("Fatal fault in %s! Spinning...\n",
k_is_in_isr() ? "ISR" : "essential thread");
#ifdef XT_SIMULATOR
exit(255 - reason);
#else
for (;;)
; /* spin forever */
#endif
}
printk("Fatal fault in thread %p! Aborting.\n", _current);
k_thread_abort(_current);
#else
for (;;) {
k_cpu_idle();
}
#endif
CODE_UNREACHABLE;
}

View file

@ -0,0 +1,38 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <stdio.h>
#include <xtensa_api.h>
#include <kernel_arch_data.h>
#include <misc/__assert.h>
/*
* @internal
*
* @brief Set an interrupt's priority
*
* The priority is verified if ASSERT_ON is enabled.
*
* The priority is verified if ASSERT_ON is enabled. The maximum number of
* priority levels is a little complex, as there are some hardware priority
* levels which are reserved: three for various types of exceptions, and
* possibly one additional to support zero latency interrupts.
*
* Valid values are from 1 to 6. Interrupts of priority 1 are not masked when
* interrupts are locked system-wide, so care must be taken when using them.
* ISR installed with priority 0 interrupts cannot make kernel calls.
*
* @return N/A
*/
void _irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
__ASSERT(prio < XCHAL_EXCM_LEVEL + 1,
"invalid priority %d! values must be less than %d\n",
prio, XCHAL_EXCM_LEVEL + 1);
/* TODO: Write code to set priority if this is ever possible on
* Xtensa
*/
}

View file

@ -0,0 +1,39 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <nanokernel.h>
#include <irq_offload.h>
#include <arch/xtensa/arch.h>
#include <xtensa_api.h>
/*
* Xtensa core should support software interrupt in order to allow using
* irq_offload feature
*/
static irq_offload_routine_t offload_routine;
static void *offload_param;
/* Called by ISR dispatcher */
void _irq_do_offload(void *unused)
{
ARG_UNUSED(unused);
offload_routine(offload_param);
}
void irq_offload(irq_offload_routine_t routine, void *parameter)
{
IRQ_CONNECT(CONFIG_IRQ_OFFLOAD_INTNUM, XCHAL_EXCM_LEVEL,
_irq_do_offload, NULL, 0);
_arch_irq_disable(CONFIG_IRQ_OFFLOAD_INTNUM);
offload_routine = routine;
offload_param = parameter;
_xt_set_intset(1 << CONFIG_IRQ_OFFLOAD_INTNUM);
/*
* Enable the software interrupt, in case it is disabled, so that IRQ
* offload is serviced.
*/
_arch_irq_enable(CONFIG_IRQ_OFFLOAD_INTNUM);
}

View file

@ -0,0 +1 @@
obj-y = offsets.o

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2013-2014 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Xtensa kernel structure member offset definition file
*
* This module is responsible for the generation of the absolute symbols whose
* value represents the member offsets for various Xtensa nanokernel
* structures.
*
* All of the absolute symbols defined by this module will be present in the
* final microkernel or nanokernel ELF image (due to the linker's reference to
* the _OffsetAbsSyms symbol).
*
* INTERNAL
* It is NOT necessary to define the offset for every member of a structure.
* Typically, only those members that are accessed by assembly language routines
* are defined; however, it doesn't hurt to define all fields for the sake of
* completeness.
*/
#include <gen_offset.h> /* located in kernel/arch/common/include */
/* list of headers that define whose structure offsets will be generated */
#include <kernel_structs.h>
#include <kernel_offsets.h>
/* Xtensa-specific TCS structure member offsets */
GEN_OFFSET_SYM(_callee_saved_t, topOfStack);
GEN_OFFSET_SYM(_callee_saved_t, retval);
GEN_OFFSET_SYM(_thread_arch_t, preempCoprocReg);
#if XCHAL_CP_NUM > 0
GEN_OFFSET_SYM(tPreempCoprocReg, cpStack);
#endif
/* Xtensa-specific _thread_arch_t structure member offsets */
GEN_OFFSET_SYM(_thread_arch_t, flags);
#ifdef CONFIG_THREAD_CUSTOM_DATA
GEN_OFFSET_SYM(_thread_arch_t, custom_data);
#endif
/* Xtensa-specific ESF structure member offsets */
GEN_OFFSET_SYM(__esf_t, sp);
GEN_OFFSET_SYM(__esf_t, pc);
/* size of the entire __esf_t structure */
GEN_ABSOLUTE_SYM(____esf_t_SIZEOF, sizeof(__esf_t));
/* size of the entire preempt registers structure */
GEN_ABSOLUTE_SYM(__tPreempt_SIZEOF, sizeof(_caller_saved_t));
/* size of the struct tcs structure without save area for coproc regs */
GEN_ABSOLUTE_SYM(_K_THREAD_NO_FLOAT_SIZEOF,
sizeof(struct k_thread) - sizeof(tCoopCoprocReg) -
sizeof(tPreempCoprocReg));
GEN_ABS_SYM_END

View file

@ -0,0 +1,2 @@
asflags-y := -c -xassembler-with-cpp $(XTENSA_INCLUDE) $(flagBoardType) -mtext-section-literals --longcalls
obj-y = reset-vector.o

View file

@ -0,0 +1,695 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/coreasm.h>
#include <xtensa/corebits.h>
#include <xtensa/cacheasm.h>
#include <xtensa/cacheattrasm.h>
#include <xtensa/xtensa-xer.h>
#include <xtensa/xdm-regs.h>
#include <xtensa/config/specreg.h>
#include <xtensa/config/system.h> /* for XSHAL_USE_ABSOLUTE_LITERALS only */
#include <xtensa/xtruntime-core-state.h>
/*
* The following reset vector avoids initializing certain registers already
* initialized by processor reset. But it does initialize some of them
* anyway, for minimal support of warm restart (restarting in software by
* jumping to the reset vector rather than asserting hardware reset).
*/
.begin literal_prefix .ResetVector
.section .ResetVector.text, "ax"
.align 4
.global _ResetVector
_ResetVector:
#if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE
/*
* NOTE:
*
* IMPORTANT: If you move the _ResetHandler portion to a section
* other than .ResetVector.text that is outside the range of
* the reset vector's 'j' instruction, the _ResetHandler symbol
* and a more elaborate j/movi/jx sequence are needed in
* .ResetVector.text to dispatch to the new location.
*/
j _ResetHandler
.size _ResetVector, . - _ResetVector
#if XCHAL_HAVE_HALT
/*
* Xtensa TX: reset vector segment is only 4 bytes, so must place the
* unpacker code elsewhere in the memory that contains the reset
* vector.
*/
#if XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTRAM0_VADDR
.section .iram0.text, "ax"
#elif XCHAL_RESET_VECTOR_VADDR == XCHAL_INSTROM0_VADDR
.section .irom0.text, "ax"
#elif XCHAL_RESET_VECTOR_VADDR == XCHAL_URAM0_VADDR
.section .uram0.text, "ax"
#else
#warning "Xtensa TX reset vector not at start of iram0, irom0, or uram0 -- ROMing LSPs may not work"
.text
#endif
#endif /* XCHAL_HAVE_HALT */
.extern __memctl_default
.align 4
/* tells the assembler/linker to place literals here */
.literal_position
.align 4
.global _ResetHandler
_ResetHandler:
#endif
#if !XCHAL_HAVE_HALT
/*
* Even if the processor supports the non-PC-relative L32R option,
* it will always start up in PC-relative mode. We take advantage of
* this, and use PC-relative mode at least until we're sure the .lit4
* section is in place (which is sometimes only after unpacking).
*/
.begin no-absolute-literals
/*
* If we have dynamic cache way support, init the caches as soon
* as we can, which is now. Except, if we are waking up from a
* PSO event, then we need to do this slightly later.
*/
#if XCHAL_HAVE_ICACHE_DYN_WAYS || XCHAL_HAVE_DCACHE_DYN_WAYS
# if XCHAL_HAVE_PSO_CDM && !XCHAL_HAVE_PSO_FULL_RETENTION
/* Do this later on in the code -- see below */
# else
movi a0, __memctl_default
wsr a0, MEMCTL
# endif
#endif
/*
* If we have PSO support, then we must check for a warm start with
* caches left powered on. If the caches had been left powered on,
* we must restore the state of MEMCTL to the saved state if any.
* Note that MEMCTL may not be present depending on config.
*/
#if XCHAL_HAVE_PSO_CDM && !XCHAL_HAVE_PSO_FULL_RETENTION
/* Read PWRSTAT */
movi a2, XDM_MISC_PWRSTAT
/* Save area address - retained for later */
movi a3, _xtos_pso_savearea
/* Signature for compare - retained for later */
movi a5, CORE_STATE_SIGNATURE
/* PWRSTAT value - retained for later */
rer a7, a2
/* Now bottom 2 bits are core wakeup and cache power lost */
extui a4, a7, 1, 2
/* a4==1 means PSO wakeup, caches did not lose power */
bnei a4, 1, .Lcold_start
/* Load save area signature field */
l32i a4, a3, CS_SA_signature
sub a4, a4, a5
/* If signature mismatch then do cold start */
bnez a4, .Lcold_start
#if XCHAL_USE_MEMCTL
/* Load saved MEMCTL value */
l32i a4, a3, CS_SA_memctl
movi a0, ~MEMCTL_INV_EN
/* Clear invalidate bit */
and a0, a4, a0
wsr a0, MEMCTL
#endif
j .Lwarm_start
.Lcold_start:
#if XCHAL_HAVE_ICACHE_DYN_WAYS || XCHAL_HAVE_DCACHE_DYN_WAYS
/*
* Enable and invalidate all ways of both caches. If there is no
* dynamic way support then this write will have no effect.
*/
movi a0, __memctl_default
wsr a0, MEMCTL
#endif
.Lwarm_start:
#endif
/* a0 is always 0 in this code, used to initialize lots of things */
movi a0, 0
/* technically this should be under !FULL_RESET, assuming hard reset */
#if XCHAL_HAVE_INTERRUPTS
/* make sure that interrupts are shut off (*before* we lower
* PS.INTLEVEL and PS.EXCM!)
*/
wsr a0, INTENABLE
#endif
#if !XCHAL_HAVE_FULL_RESET
/* pre-LX2 cores only */
#if XCHAL_HAVE_CCOUNT && (XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0)
/* not really necessary, but nice; best done very early */
wsr a0, CCOUNT
#endif
/*
* For full MMU configs, put page table at an unmapped virtual address.
* This ensures that accesses outside the static maps result
* in miss exceptions rather than random behaviour.
* Assumes XCHAL_SEG_MAPPABLE_VADDR == 0 (true in released MMU).
*/
#if XCHAL_ITLB_ARF_WAYS > 0 || XCHAL_DTLB_ARF_WAYS > 0
wsr a0, PTEVADDR
#endif
/*
* Debug initialization
*
* NOTE: DBREAKCn must be initialized before the combination of these
* two things: any load/store, and a lowering of PS.INTLEVEL below
* DEBUG_LEVEL. The processor already resets IBREAKENABLE
* appropriately.
*/
#if XCHAL_HAVE_DEBUG
#if XCHAL_NUM_DBREAK
#if XCHAL_NUM_DBREAK >= 2
wsr a0, DBREAKC1
#endif
wsr a0, DBREAKC0
dsync /* wait for WSRs to DBREAKCn to complete */
#endif /* XCHAL_NUM_DBREAK */
/* pre-LX cores only */
# if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RA_2004_1
/*
* Starting in Xtensa LX, ICOUNTLEVEL resets to zero (not 15), so no
* need to initialize it. Prior to that we do, otherwise we get an
* ICOUNT exception, 2^32 instructions after reset.
*/
/* are we being debugged? (detected by ICOUNTLEVEL not 15, or dropped
* below 12)
*/
rsr a2, ICOUNTLEVEL
/* if so, avoid initializing ICOUNTLEVEL which drops single-steps
* through here
* */
bltui a2, 12, 1f
/* avoid ICOUNT exceptions */
wsr a0, ICOUNTLEVEL
/* wait for WSR to ICOUNTLEVEL to complete */
isync
1:
#endif
#endif /* XCHAL_HAVE_DEBUG */
#endif /* !XCHAL_HAVE_FULL_RESET */
#if XCHAL_HAVE_ABSOLUTE_LITERALS
/* Technically, this only needs to be done under !FULL_RESET,
* assuming hard reset:
*/
wsr a0, LITBASE
rsync
#endif
#if XCHAL_HAVE_PSO_CDM && ! XCHAL_HAVE_PSO_FULL_RETENTION
/*
* If we're powering up from a temporary power shut-off (PSO),
* restore state saved just prior to shut-off. Note that the
* MEMCTL register was already restored earlier, and as a side
* effect, registers a3, a5, a7 are now preloaded with values
* that we will use here.
* a3 - pointer to save area base address (_xtos_pso_savearea)
* a5 - saved state signature (CORE_STATE_SIGNATURE)
* a7 - contents of PWRSTAT register
*/
/* load save area signature */
l32i a4, a3, CS_SA_signature
/* compare signature with expected one */
sub a4, a4, a5
# if XTOS_PSO_TEST
/* pretend PSO warm start with warm caches */
movi a7, PWRSTAT_WAKEUP_RESET
# endif
/* wakeup from PSO? (branch if not) */
bbci.l a7, PWRSTAT_WAKEUP_RESET_SHIFT, 1f
/* Yes, wakeup from PSO. Check whether state was properly saved.
* speculatively clear PSO-wakeup bit */
addi a5, a7, - PWRSTAT_WAKEUP_RESET
/* if state not saved (corrupted?), mark as cold start */
movnez a7, a5, a4
/* if state not saved, just continue with reset */
bnez a4, 1f
/* Wakeup from PSO with good signature. Now check cache status:
* if caches warm, restore now */
bbci.l a7, PWRSTAT_CACHES_LOST_POWER_SHIFT, .Lpso_restore
/* Caches got shutoff. Continue reset, we'll end up initializing
* caches, and check again later for PSO.
*/
# if XCHAL_HAVE_PRID && XCHAL_HAVE_S32C1I
j .Ldonesync /* skip reset sync, only done for cold start */
# endif
1: /* Cold start. (Not PSO wakeup.) Proceed with normal full reset. */
#endif
#if XCHAL_HAVE_PRID && XCHAL_HAVE_S32C1I
/* Core 0 initializes the XMP synchronization variable, if present.
* This operation needs to happen as early as possible in the startup
* sequence so that the other cores can be released from reset.
*/
.weak _ResetSync
movi a2, _ResetSync /* address of sync variable */
rsr.prid a3 /* core and multiprocessor ID */
extui a3, a3, 0, 8 /* extract core ID (FIXME: need proper
* constants for PRID bits to extract) */
beqz a2, .Ldonesync /* skip if no sync variable */
bnez a3, .Ldonesync /* only do this on core 0 */
s32i a0, a2, 0 /* clear sync variable */
.Ldonesync:
#endif
#if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MP_RUNSTALL
/* On core 0, this releases other cores. On other cores this has no
* effect, because runstall control is unconnected
*/
movi a2, XER_MPSCORE
wer a0, a2
#endif
/*
* For processors with relocatable vectors, apply any alternate
* vector base given to xt-genldscripts, which sets the
* _memmap_vecbase_reset symbol accordingly.
*/
#if XCHAL_HAVE_VECBASE
/* note: absolute symbol, not a ptr */
movi a2, _memmap_vecbase_reset
wsr a2, vecbase
#endif
/* have ATOMCTL ? */
#if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0)
#if XCHAL_DCACHE_IS_COHERENT
/* MX -- internal for writeback, RCW otherwise */
movi a3, 0x25
#else
/* non-MX -- always RCW */
movi a3, 0x15
#endif /* XCHAL_DCACHE_IS_COHERENT */
wsr a3, ATOMCTL
#endif
#if XCHAL_HAVE_INTERRUPTS && XCHAL_HAVE_DEBUG
/* lower PS.INTLEVEL here to make reset vector easier to debug */
rsil a2, 1
#endif
/* If either of the caches does not have dynamic way support, then
* use the old (slow) method to init them. If the cache is absent
* the macros will expand to empty.
*/
#if ! XCHAL_HAVE_ICACHE_DYN_WAYS
icache_reset a2, a3
#endif
#if ! XCHAL_HAVE_DCACHE_DYN_WAYS
dcache_reset a2, a3
#endif
#if XCHAL_HAVE_PSO_CDM && ! XCHAL_HAVE_PSO_FULL_RETENTION
/* Here, a7 still contains status from the power status register,
* or zero if signature check failed.
*/
/* wakeup from PSO with good signature? */
bbci.l a7, PWRSTAT_WAKEUP_RESET_SHIFT, .Lcoldstart
/* Yes, wakeup from PSO. Caches had been powered down, now are
* initialized.
*/
.Lpso_restore:
/* Assume memory still initialized, so all code still unpacked etc.
* So we can just jump/call to relevant state restore code (wherever
* located).
*/
/* make shutoff routine return zero */
movi a2, 0
movi a3, _xtos_pso_savearea
/* Here, as below for _start, call0 is used as an unlimited-range
* jump.
*/
call0 _xtos_core_restore_nw
/* (does not return) */
.Lcoldstart:
#endif
#if XCHAL_HAVE_PREFETCH
/* Enable cache prefetch if present. */
movi a2, XCHAL_CACHE_PREFCTL_DEFAULT
wsr a2, PREFCTL
#endif
/*
* Now setup the memory attributes. On some cores this "enables"
* caches. We do this ahead of unpacking, so it can proceed more
* efficiently.
*
* The _memmap_cacheattr_reset symbol's value (address) is defined by
* the LSP's linker script, as generated by xt-genldscripts. If
* defines 4-bit attributes for eight 512MB regions.
*
* (NOTE: for cores with the older MMU v1 or v2, or without any
* memory protection mechanism, the following code has no effect.)
*/
#if XCHAL_HAVE_MPU
/* If there's an empty background map, setup foreground maps to mimic
* region protection:
*/
# if XCHAL_MPU_ENTRIES >= 8 && XCHAL_MPU_BACKGROUND_ENTRIES <= 2
.pushsection .rodata, "a"
.global _xtos_mpu_attribs
.align 4
_xtos_mpu_attribs:
/* Illegal (---) */
.word 0x00006000+XCHAL_MPU_ENTRIES-8
/* Writeback (rwx Cacheable Non-shareable wb rd-alloc wr-alloc) */
.word 0x000F7700+XCHAL_MPU_ENTRIES-8
/* WBNA (rwx Cacheable Non-shareable wb rd-alloc) */
.word 0x000D5700+XCHAL_MPU_ENTRIES-8
/* Writethru (rwx Cacheable Non-shareable wt rd-alloc) */
.word 0x000C4700+XCHAL_MPU_ENTRIES-8
/* Bypass (rwx Device non-interruptible system-shareable) */
.word 0x00006700+XCHAL_MPU_ENTRIES-8
.popsection
/*
* We assume reset state: all MPU entries zeroed and disabled.
* Otherwise we'd need a loop to zero everything.
*/
/* note: absolute symbol, not a ptr */
movi a2, _memmap_cacheattr_reset
movi a3, _xtos_mpu_attribs
movi a4, 0x20000000 /* 512 MB delta */
movi a6, 8
movi a7, 1 /* MPU entry vaddr 0, with valid bit set */
movi a9, 0 /* cacheadrdis value */
/* enable everything temporarily while MPU updates */
wsr.cacheadrdis a9
/* Write eight MPU entries, from the last one going backwards
* (entries n-1 thru n-8)
*/
2: extui a8, a2, 28, 4 /* get next attribute nibble (msb first) */
extui a5, a8, 0, 2 /* lower two bit indicate whether cached */
slli a9, a9, 1 /* add a bit to cacheadrdis... */
addi a10, a9, 1 /* set that new bit if... */
moveqz a9, a10, a5 /* ... that region is non-cacheable */
addx4 a5, a8, a3 /* index into _xtos_mpu_attribs table */
addi a8, a8, -5 /* make valid attrib indices negative */
movgez a5, a3, a8 /* if not valid attrib, use Illegal */
l32i a5, a5, 0 /* load access rights, memtype from table
* entry
*/
slli a2, a2, 4
sub a7, a7, a4 /* next 512MB region (last to first) */
addi a6, a6, -1
add a5, a5, a6 /* add the index */
wptlb a5, a7 /* write the MPU entry */
bnez a6, 2b /* loop until done */
# else
/* default value of CACHEADRDIS for bgnd map */
movi a9, XCHAL_MPU_BG_CACHEADRDIS
# endif
wsr.cacheadrdis a9 /* update cacheadrdis */
#elif XCHAL_HAVE_CACHEATTR || XCHAL_HAVE_MIMIC_CACHEATTR \
|| XCHAL_HAVE_XLT_CACHEATTR \
|| (XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY)
/* note: absolute symbol, not a ptr */
movi a2, _memmap_cacheattr_reset
/* set CACHEATTR from a2 (clobbers a3-a8) */
cacheattr_set
#endif
/* Now that caches are initialized, cache coherency can be enabled. */
#if XCHAL_DCACHE_IS_COHERENT
# if XCHAL_HAVE_EXTERN_REGS && XCHAL_HAVE_MX && \
(XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RE_2012_0)
/* Opt into coherence for MX (for backward compatibility / testing). */
movi a3, 1
movi a2, XER_CCON
wer a3, a2
# endif
#endif
/* Enable zero-overhead loop instr buffer, and snoop responses, if
* configured. If HW erratum 453 fix is to be applied, then don't
* enable loop instr buffer.
*/
#if XCHAL_USE_MEMCTL && XCHAL_SNOOP_LB_MEMCTL_DEFAULT
movi a3, XCHAL_SNOOP_LB_MEMCTL_DEFAULT
rsr a2, MEMCTL
or a2, a2, a3
wsr a2, MEMCTL
#endif
/* Caches are all up and running, clear PWRCTL.ShutProcOffOnPWait. */
#if XCHAL_HAVE_PSO_CDM
movi a2, XDM_MISC_PWRCTL
movi a4, ~PWRCTL_CORE_SHUTOFF
rer a3, a2
and a3, a3, a4
wer a3, a2
#endif
#endif /* !XCHAL_HAVE_HALT */
/*
* Unpack code and data (eg. copy ROMed segments to RAM, vectors into
* their proper location, etc).
*/
#if defined(XTOS_UNPACK)
movi a2, _rom_store_table
beqz a2, unpackdone
unpack: l32i a3, a2, 0 /* start vaddr */
l32i a4, a2, 4 /* end vaddr */
l32i a5, a2, 8 /* store vaddr */
addi a2, a2, 12
bgeu a3, a4, upnext /* skip unless start < end */
uploop: l32i a6, a5, 0
addi a5, a5, 4
s32i a6, a3, 0
addi a3, a3, 4
bltu a3, a4, uploop
j unpack
upnext: bnez a3, unpack
bnez a5, unpack
#endif /* XTOS_UNPACK */
unpackdone:
#if defined(XTOS_UNPACK) || defined(XTOS_MP)
/*
* If writeback caches are configured and enabled, unpacked data must
* be written out to memory before trying to execute it:
*/
dcache_writeback_all a2, a3, a4, 0
/* ensure data written back is visible to i-fetch */
icache_sync a2
/*
* Note: no need to invalidate the i-cache after the above, because
* we already invalidated it further above and did not execute
* anything within unpacked regions afterwards. [Strictly speaking,
* if an unpacked region follows this code very closely, it's possible
* for cache-ahead to have cached a bit of that unpacked region, so in
* the future we may need to invalidate the entire i-cache here again
* anyway.]
*/
#endif
#if !XCHAL_HAVE_HALT /* skip for TX */
/*
* Now that we know the .lit4 section is present (if got unpacked)
* (and if absolute literals are used), initialize LITBASE to use it.
*/
#if XCHAL_HAVE_ABSOLUTE_LITERALS && XSHAL_USE_ABSOLUTE_LITERALS
/*
* Switch from PC-relative to absolute (litbase-relative) L32R mode.
* Set LITBASE to 256 kB beyond the start of the literals in .lit4
* (aligns to the nearest 4 kB boundary, LITBASE does not have bits
* 1..11) and set the enable bit (_lit4_start is assumed 4-byte
* aligned).
*/
movi a2, _lit4_start + 0x40001
wsr a2, LITBASE
rsync
#endif /* have and use absolute literals */
/* we can now start using absolute literals */
.end no-absolute-literals
/* Technically, this only needs to be done pre-LX2, assuming hard
* reset:
*/
# if XCHAL_HAVE_WINDOWED && defined(__XTENSA_WINDOWED_ABI__)
/* Windowed register init, so we can call windowed code (eg. C code). */
movi a1, 1
wsr a1, WINDOWSTART
/*
* The processor always clears WINDOWBASE at reset, so no need to
* clear it here. It resets WINDOWSTART to 1 starting with LX2.0/X7.0
* (RB-2006.0). However, assuming hard reset is not yet always
* practical, so do this anyway:
*/
wsr a0, WINDOWBASE
rsync
movi a0, 0 /* possibly a different a0, clear it */
# endif
/* only pre-LX2 needs this */
#if XCHAL_HW_MIN_VERSION < XTENSA_HWVERSION_RB_2006_0
/* Coprocessor option initialization */
# if XCHAL_HAVE_CP
/*
* To allow creating new coprocessors using TC that are not known
* at GUI build time without having to explicitly enable them,
* all CPENABLE bits must be set, even though they may not always
* correspond to a coprocessor.
*/
movi a2, 0xFF /* enable *all* bits, to allow dynamic TIE */
wsr a2, CPENABLE
# endif
/*
* Floating point coprocessor option initialization (at least
* rounding mode, so that floating point ops give predictable results)
*/
# if XCHAL_HAVE_FP && !XCHAL_HAVE_VECTORFPU2005
/* floating-point control register (user register number) */
# define FCR 232
/* floating-point status register (user register number) */
# define FSR 233
/* wait for WSR to CPENABLE to complete before accessing FP coproc
* state
*/
rsync
wur a0, FCR /* clear FCR (default rounding mode, round-nearest) */
wur a0, FSR /* clear FSR */
# endif
#endif /* pre-LX2 */
/*
* Initialize memory error handler address.
* Putting this address in a register allows multiple instances of
* the same configured core (with separate program images but shared
* code memory, thus forcing memory error vector to be shared given
* it is not VECBASE relative) to have the same memory error vector,
* yet each have their own handler and associated data save area.
*/
#if XCHAL_HAVE_MEM_ECC_PARITY
movi a4, _MemErrorHandler
wsr a4, MESAVE
#endif
/*
* Initialize medium and high priority interrupt dispatchers:
*/
#if HAVE_XSR
/* For asm macros; works for positive a,b smaller than 1000: */
# define GREATERTHAN(a,b) (((b)-(a)) & ~0xFFF)
# ifndef XCHAL_DEBUGLEVEL /* debug option not selected? */
# define XCHAL_DEBUGLEVEL 99 /* bogus value outside 2..6 */
# endif
.macro init_vector level
.if GREATERTHAN(XCHAL_NUM_INTLEVELS+1,\level)
.if XCHAL_DEBUGLEVEL-\level
.weak _Level&level&FromVector
movi a4, _Level&level&FromVector
wsr a4, EXCSAVE+\level
.if GREATERTHAN(\level,XCHAL_EXCM_LEVEL)
movi a5, _Pri_&level&_HandlerAddress
s32i a4, a5, 0
/* If user provides their own handler, that handler might
* not provide its own _Pri_<n>_HandlerAddress variable for
* linking handlers. In that case, the reference below
* would pull in the XTOS handler anyway, causing a conflict.
* To avoid that, provide a weak version of it here:
*/
.pushsection .data, "aw"
.global _Pri_&level&_HandlerAddress
.weak _Pri_&level&_HandlerAddress
.align 4
_Pri_&level&_HandlerAddress: .space 4
.popsection
.endif
.endif
.endif
.endm
init_vector 2
init_vector 3
init_vector 4
init_vector 5
init_vector 6
#endif /*HAVE_XSR*/
/*
* Complete reset initialization outside the vector, to avoid
* requiring a vector that is larger than necessary. This 2nd-stage
* startup code sets up the C Run-Time (CRT) and calls main().
*
* Here we use call0 not because we expect any return, but because the
* assembler/linker dynamically sizes call0 as needed (with
* -mlongcalls) which it doesn't with j or jx. Note: This needs to
* be call0 regardless of the selected ABI.
*/
call0 _start /* jump to _start (in crt1-*.S) */
/* does not return */
#else /* XCHAL_HAVE_HALT */
j _start /* jump to _start (in crt1-*.S) */
/* (TX has max 64kB IRAM, so J always in range) */
/* Paranoia -- double-check requirements / assumptions of this Xtensa
* TX code:
*/
# if !defined(__XTENSA_CALL0_ABI__) || !XCHAL_HAVE_FULL_RESET \
|| XCHAL_HAVE_INTERRUPTS || XCHAL_HAVE_CCOUNT \
|| XCHAL_DTLB_ARF_WAYS || XCHAL_HAVE_DEBUG \
|| XCHAL_HAVE_S32C1I || XCHAL_HAVE_ABSOLUTE_LITERALS \
|| XCHAL_DCACHE_SIZE || XCHAL_ICACHE_SIZE || XCHAL_HAVE_PIF \
|| XCHAL_HAVE_WINDOWED
# error "Halt architecture (Xtensa TX) requires: call0 ABI, all flops reset, no exceptions or interrupts, no TLBs, no debug, no S32C1I, no LITBASE, no cache, no PIF, no windowed regs"
# endif
#endif /* XCHAL_HAVE_HALT */
#if (!XCHAL_HAVE_HALT || defined(XTOS_UNPACK)) && XCHAL_HAVE_IMEM_LOADSTORE
.size _ResetHandler, . - _ResetHandler
#else
.size _ResetVector, . - _ResetVector
#endif
.text
.global xthals_hw_configid0, xthals_hw_configid1
.global xthals_release_major, xthals_release_minor
.end literal_prefix

View file

@ -0,0 +1,59 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief ISR table for static ISR declarations for XTENSA
*
* Software ISR table for XTENSA
*/
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <xtensa/config/core.h>
/*
* Xtensa assembly code uses xt_unhandled_interrupt for default IRQ handler.
*/
#define _irq_spurious xt_unhandled_interrupt
/*
* enable preprocessor features, such
* as %expr - evaluate the expression and use it as a string
*/
.altmacro
/*
* Define an ISR table entry
* Define symbol as weak and give the section .gnu.linkonce.d
* prefix. This allows linker overload the symbol and the
* whole section by the one defined by a device driver
*/
.macro _isr_table_entry_declare index
WDATA(_isr_irq\index)
.section .gnu.linkonce.d.isr_irq\index
_isr_irq\index: .word 0xABAD1DEA, _irq_spurious
.endm
/*
* Declare the ISR table
*/
.macro _isr_table_declare from, to
counter = \from
.rept (\to - \from)
_isr_table_entry_declare %counter
counter = counter + 1
.endr
.endm
GTEXT(_irq_spurious)
GDATA(_sw_isr_table)
.section .isr_irq0
.align
_sw_isr_table:
_isr_table_declare 0 XCHAL_NUM_INTERRUPTS

96
arch/xtensa/core/swap.S Normal file
View file

@ -0,0 +1,96 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief kernel swapper code for Xtensa
*
* This module implements the _Swap() routine for the Xtensa architecture.
*/
#include <xtensa_context.h>
#include <kernel_arch_data.h>
#include <offsets_short.h>
.extern _kernel
/* unsigned int _Swap (unsigned int basepri); */
.globl _Swap
.type _Swap,@function
.align 4
_Swap:
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, -XT_SOL_FRMSZ
#else
entry sp, XT_SOL_FRMSZ
#endif
s32i a0, sp, XT_SOL_pc
s32i a2, sp, XT_SOL_ps
#ifdef __XTENSA_CALL0_ABI__
s32i a12, sp, XT_SOL_a12 /* save callee-saved registers */
s32i a13, sp, XT_SOL_a13
s32i a14, sp, XT_SOL_a14
s32i a15, sp, XT_SOL_a15
#else
/* Spill register windows. Calling xthal_window_spill() causes extra
* spills and reloads, so we will set things up to call the _nw version
* instead to save cycles.
*/
/* spills a4-a7 if needed */
movi a6, ~(PS_WOE_MASK|PS_INTLEVEL_MASK)
and a2, a2, a6 /* clear WOE, INTLEVEL */
addi a2, a2, XCHAL_EXCM_LEVEL /* set INTLEVEL */
wsr a2, PS
rsync
call0 xthal_window_spill_nw
l32i a2, sp, XT_SOL_ps /* restore PS */
addi a2, a2, XCHAL_EXCM_LEVEL
wsr a2, PS
#endif
#if XCHAL_CP_NUM > 0
/* Save coprocessor callee-saved state (if any). At this point CPENABLE
* should still reflect which CPs were in use (enabled).
*/
call0 _xt_coproc_savecs
#endif
movi a2, _kernel
movi a3, 0
l32i a4, a2, KERNEL_OFFSET(current) /* a4 := _kernel->current */
s32i a3, sp, XT_SOL_exit /* 0 to flag as solicited frame */
s32i sp, a4, THREAD_OFFSET(sp) /* current->arch.topOfStack := sp */
/*
* Set _Swap()'s default return code to -EAGAIN. This eliminates the
* need for the timeout code to set it itself.
*/
movi a3, -11 /* a3 := -EAGAIN. TODO: Use a macro here insted of 11 */
s32i a3, a4, THREAD_OFFSET(retval) /* current->arch.retval := -EAGAIN */
#if XCHAL_CP_NUM > 0
/* Clear CPENABLE, also in task's co-processor state save area. */
movi a3, 0
/* a4 := current->arch.preempCoprocReg.cpStack */
l32i a4, a4, THREAD_OFFSET(cpStack)
wsr a3, CPENABLE
beqz a4, 1f
s16i a3, a4, XT_CPENABLE /* clear saved cpenable */
1:
#endif
#ifdef CONFIG_KERNEL_EVENT_LOGGER_CONTEXT_SWITCH
/* Register the context switch */
#ifdef __XTENSA_CALL0_ABI__
call0 _sys_k_event_logger_context_switch
#else
call4 _sys_k_event_logger_context_switch
#endif
#endif
/* _thread := _kernel.ready_q.cache */
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
/*
* Swap threads if any is to be swapped in.
*/
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
/* Never reaches here. */

179
arch/xtensa/core/thread.c Normal file
View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifdef CONFIG_INIT_STACKS
#include <string.h>
#endif /* CONFIG_INIT_STACKS */
#ifdef CONFIG_DEBUG
#include <misc/printk.h>
#endif
#include <kernel_structs.h>
#include <wait_q.h>
#include <xtensa_config.h>
extern void _xt_user_exit(void);
#if CONFIG_MICROKERNEL
extern FUNC_NORETURN void _TaskAbort(void);
#endif
extern void fiber_abort(void);
#if defined(CONFIG_THREAD_MONITOR)
#define THREAD_MONITOR_INIT(tcs) _thread_monitor_init(tcs)
#else
#define THREAD_MONITOR_INIT(tcs) \
do {/* do nothing */ \
} while ((0))
#endif
#if defined(CONFIG_THREAD_MONITOR)
/**
*
* @brief Initialize thread monitoring support
*
* Currently only inserts the new thread in the list of active threads.
*
* @return N/A
*/
static inline void _thread_monitor_init(struct tcs *tcs)
{
unsigned int key;
/*
* Add the newly initialized thread to head of the list of threads.
* This singly linked list of threads maintains ALL the threads in the
* system:
* both tasks and fibers regardless of whether they are runnable.
*/
key = irq_lock();
tcs->next_thread = _nanokernel.threads;
_nanokernel.threads = tcs;
irq_unlock(key);
}
#endif /* CONFIG_THREAD_MONITOR */
/*
* @brief Initialize a new thread from its stack space
*
* The control structure (TCS) is put at the lower address of the stack. An
* initial context, to be "restored" by __return_from_coop(), is put at
* the other end of the stack, and thus reusable by the stack when not
* needed anymore.
*
* The initial context is a basic stack frame that contains arguments for
* _thread_entry() return address, that points at _thread_entry()
* and status register.
*
* <options> is currently unused.
*
* @param pStackmem the pointer to aligned stack memory
* @param stackSize the stack size in bytes
* @param pEntry thread entry point routine
* @param p1 first param to entry point
* @param p2 second param to entry point
* @param p3 third param to entry point
* @param fiber prio, -1 for task
* @param options is unused (saved for future expansion)
*
* @return N/A
*/
void _new_thread(char *pStack, size_t stackSize,
void (*pEntry)(void *, void *, void *),
void *p1, void *p2, void *p3,
int prio, unsigned int options)
{
/* Align stack end to maximum alignment requirement. */
char *stackEnd = (char *)ROUND_DOWN(pStack + stackSize,
(XCHAL_TOTAL_SA_ALIGN < 16 ? 16 : XCHAL_TOTAL_SA_ALIGN));
/* TCS is located at top of stack while frames are located at end
* of it
*/
struct tcs *tcs = (struct tcs *)(pStack);
#if XCHAL_CP_NUM > 0
uint32_t *cpSA;
#endif
#ifdef CONFIG_DEBUG
printk("\nstackPtr = %p, stackSize = %d\n", pStack, stackSize);
printk("stackEnd = %p\n", stackEnd);
#endif
#ifdef CONFIG_INIT_STACKS
memset(pStack, 0xaa, stackSize);
#endif
#if XCHAL_CP_NUM > 0
/* Coprocessor's stack is allocated just after the TCS */
tcs->arch.preempCoprocReg.cpStack = pStack + sizeof(struct k_thread);
cpSA = (uint32_t *)(tcs->arch.preempCoprocReg.cpStack + XT_CP_ASA);
/* Coprocessor's save area alignment is at leat 16 bytes */
*cpSA = ROUND_UP(cpSA + 1,
(XCHAL_TOTAL_SA_ALIGN < 16 ? 16 : XCHAL_TOTAL_SA_ALIGN));
#ifdef CONFIG_DEBUG
printk("cpStack = %p\n", tcs->arch.preempCoprocReg.cpStack);
printk("cpAsa = %p\n",
*(void **)(tcs->arch.preempCoprocReg.cpStack + XT_CP_ASA));
#endif
#endif
/* Thread's first frame alignment is granted as both operands are
* aligned
*/
XtExcFrame *pInitCtx =
(XtExcFrame *)(stackEnd - (XT_XTRA_SIZE - XT_CP_SIZE));
#ifdef CONFIG_DEBUG
printk("pInitCtx = %p\n", pInitCtx);
#endif
/* Explicitly initialize certain saved registers */
/* task entrypoint */
pInitCtx->pc = (uint32_t)_thread_entry;
/* physical top of stack frame */
pInitCtx->a1 = (uint32_t)pInitCtx + XT_STK_FRMSZ;
/* user exception exit dispatcher */
pInitCtx->exit = (uint32_t)_xt_user_exit;
/* Set initial PS to int level 0, EXCM disabled, user mode.
* Also set entry point argument arg.
*/
#ifdef __XTENSA_CALL0_ABI__
pInitCtx->a2 = (uint32_t)pEntry;
pInitCtx->a3 = (uint32_t)p1;
pInitCtx->a4 = (uint32_t)p2;
pInitCtx->a5 = (uint32_t)p3;
pInitCtx->ps = PS_UM | PS_EXCM;
#else
/* For windowed ABI set also WOE and CALLINC
* (pretend task is 'call4')
*/
pInitCtx->a6 = (uint32_t)pEntry;
pInitCtx->a7 = (uint32_t)p1;
pInitCtx->a8 = (uint32_t)p2;
pInitCtx->a9 = (uint32_t)p3;
pInitCtx->ps = PS_UM | PS_EXCM | PS_WOE | PS_CALLINC(1);
#endif
tcs->callee_saved.topOfStack = pInitCtx;
tcs->arch.flags = 0;
_init_thread_base(&tcs->base, prio, _THREAD_PRESTART, options);
/* static threads overwrite it afterwards with real value */
tcs->init_data = NULL;
tcs->fn_abort = NULL;
#ifdef CONFIG_THREAD_CUSTOM_DATA
/* Initialize custom data field (value is opaque to kernel) */
tcs->custom_data = NULL;
#endif
#ifdef CONFIG_THREAD_MONITOR
/*
* In debug mode tcs->entry give direct access to the thread entry
* and the corresponding parameters.
*/
tcs->entry = (struct __thread_entry *)(pInitCtx);
#endif
/* initial values in all other registers/TCS entries are irrelevant */
THREAD_MONITOR_INIT(tcs);
}

View file

@ -0,0 +1,388 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa_context.h>
#include <xtensa_timer.h>
#include <offsets_short.h>
#include <kernel_structs.h>
.extern _interrupt_stack
.extern _kernel
#ifdef CONFIG_SYS_CLOCK_EXISTS
.extern _timer_int_handler
#endif
.set _interrupt_stack_top, _interrupt_stack + CONFIG_ISR_STACK_SIZE
/*
* _zxt_dispatch(_kernel_t *_kernel, _thread_t *_thread)
* At this point, the a2 register contains the '&_kernel' and the
* thread to be swapped in (&_thread) is in a3.
*/
.text
.globl _zxt_dispatch
.type _zxt_dispatch,@function
.align 4
_zxt_dispatch:
/* Updated current thread: _kernel.current := _kernel.ready_q.cache */
s32i a3, a2, KERNEL_OFFSET(current) /* _kernel.current := _thread */
l32i sp, a3, THREAD_OFFSET(sp) /* sp := _thread->topOfStack; */
/* Determine the type of stack frame. */
l32i a2, sp, XT_STK_exit /* exit dispatcher or solicited flag */
bnez a2, .L_frxt_dispatch_stk
.L_frxt_dispatch_sol:
/* Solicited stack frame. Restore retval from _Swap */
l32i a2, a3, THREAD_OFFSET(retval)
l32i a3, sp, XT_SOL_ps
#ifdef __XTENSA_CALL0_ABI__
l32i a12, sp, XT_SOL_a12
l32i a13, sp, XT_SOL_a13
l32i a14, sp, XT_SOL_a14
l32i a15, sp, XT_SOL_a15
#endif
l32i a0, sp, XT_SOL_pc
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE is complete (should be, it was cleared on
* entry).
*/
rsync
#endif
/* As soons as PS is restored, interrupts can happen. No need to sync
* PS.
*/
wsr a3, PS
#ifdef __XTENSA_CALL0_ABI__
addi sp, sp, XT_SOL_FRMSZ
ret
#else
retw
#endif
.L_frxt_dispatch_stk:
#if XCHAL_CP_NUM > 0
/* Restore CPENABLE from task's co-processor save area. */
l32i a2, a3, THREAD_OFFSET(cpStack)
l16ui a3, a2, XT_CPENABLE
wsr a3, CPENABLE
#endif
/*
* Interrupt stack frame.
* Restore full context and return to exit dispatcher.
*/
call0 _xt_context_restore
/* In Call0 ABI, restore callee-saved regs (A12, A13 already
* restored).
*/
#ifdef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_a14
l32i a15, sp, XT_STK_a15
#endif
#if XCHAL_CP_NUM > 0
/* Ensure wsr.CPENABLE has completed. */
rsync
#endif
/*
* Must return via the exit dispatcher corresponding to the entrypoint
* from which this was called. Interruptee's A0, A1, PS, PC are
* restored and the interrupt stack frame is deallocated in the exit
* dispatcher.
*/
l32i a0, sp, XT_STK_exit
ret
/*
* _zxt_int_enter
* void _zxt_int_enter(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_ENTER function for
* freeRTOS. Saves the rest of the interrupt context (not already saved).
* May only be called from assembly code by the 'call0' instruction, with
* interrupts disabled.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*/
.globl _zxt_int_enter
.type _zxt_int_enter,@function
.align 4
_zxt_int_enter:
/* Save a12-13 in the stack frame as required by _xt_context_save. */
s32i a12, a1, XT_STK_a12
s32i a13, a1, XT_STK_a13
/* Save return address in a safe place (free a0). */
mov a12, a0
/* Save the rest of the interrupted context (preserves A12-13). */
call0 _xt_context_save
/*
* Save interrupted task's SP in TCB only if not nesting. Manage
* nesting directly rather than call the generic IntEnter() (in
* windowed ABI we can't call a C function here anyway because PS.EXCM
* is still set).
*/
movi a2, _kernel /* a2 := _kernel */
l32i a3, a2, KERNEL_OFFSET(nested) /* a3 := _kernel->nested */
addi a3, a3, 1 /* increment nesting count */
s32i a3, a2, KERNEL_OFFSET(nested) /* save nesting count */
bnei a3, 1, .Lnested /* !=0 before incr, so nested */
l32i a3, a2, KERNEL_OFFSET(current)/* a3 := _kernel->current */
s32i a1, a3, THREAD_OFFSET(sp) /* save SP to Current top of stack */
movi a1, _interrupt_stack_top /* a1 = top of intr stack */
.Lnested:
1:
mov a0, a12 /* restore return addr and return */
ret
/*
* _zxt_int_exit
* void _zxt_int_exit(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_INT_EXIT function for
* Zephyr. If required, calls vPortYieldFromInt() to perform task context
* switching, restore the (possibly) new task's context, and return to the exit
* dispatcher saved in the task's stack frame at XT_STK_EXIT. May only be
* called from assembly code by the 'call0' instruction. Does not return to
* caller. See the description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*/
.globl _zxt_int_exit
.type _zxt_int_exit,@function
.align 4
_zxt_int_exit:
rsil a0, XCHAL_EXCM_LEVEL /* lock out interrupts */
movi a2, _kernel
l32i a3, a2, KERNEL_OFFSET(nested) /* _kernel->nested */
addi a3, a3, -1 /* decrement nesting count */
s32i a3, a2, KERNEL_OFFSET(nested) /* save nesting count */
bnez a3, .Lnesting /* !=0 after decr so still nested */
/*
* When using call0 ABI callee-saved registers a12-15 need to be saved
* before enabling preemption. They were already saved by
* _zxt_int_enter().
*/
#ifdef __XTENSA_CALL0_ABI__
s32i a14, a1, XT_STK_a14
s32i a15, a1, XT_STK_a15
#endif
#if XCHAL_CP_NUM > 0
l32i a3, a2, KERNEL_OFFSET(current) /* _thread := _kernel->current */
l32i a4, a3, THREAD_OFFSET(cpStack)
rsr a5, CPENABLE
s16i a5, a4, XT_CPENABLE /* cp_state->cpenable = CPENABLE; */
movi a3, 0
wsr a3, CPENABLE /* disable all co-processors */
#endif
l32i a3, a2, KERNEL_OFFSET(current) /* _thread := _kernel.current */
/*
* Non-preemptible thread ? Do not schedule (see explanation of
* preempt field in kernel_struct.h).
*/
movi a4, _NON_PREEMPT_THRESHOLD
l16ui a5, a3, THREAD_OFFSET(preempt)
bgeu a5, a4, .noReschedule
/* _thread := _kernel.ready_q.cache */
l32i a3, a2, KERNEL_OFFSET(ready_q_cache)
.noReschedule:
/*
* Swap threads if any is to be swapped in.
*/
call0 _zxt_dispatch /* (_kernel@a2, _thread@a3) */
/* Never returns here. */
.Lnesting:
/*
* We come here only if there was no context switch, that is if this
* is a nested interrupt, or the interrupted task was not preempted.
* In either case there's no need to load the SP.
*/
/* Restore full context from interrupt stack frame */
call0 _xt_context_restore
/*
* Must return via the exit dispatcher corresponding to the entrypoint
* from which this was called. Interruptee's A0, A1, PS, PC are
* restored and the interrupt stack frame is deallocated in the exit
* dispatcher.
*/
l32i a0, sp, XT_STK_exit
ret
/*
* _zxt_timer_int
* void _zxt_timer_int(void)
*
* Implements Xtensa RTOS porting layer's XT_RTOS_TIMER_INT function. Called
* every timer interrupt. Manages the tick timer and calls
* xPortSysTickHandler() every tick. See the detailed description of the
* XT_RTOS_ENTER macro in xtensa_rtos.h. Callable from C. Implemented in
* assmebly code for performance.
*
*/
.globl _zxt_timer_int
.type _zxt_timer_int,@function
.align 4
_zxt_timer_int:
/*
* Xtensa timers work by comparing a cycle counter with a preset value.
* Once the match occurs an interrupt is generated, and the handler has
* to set a new cycle count into the comparator. To avoid clock drift
* due to interrupt latency, the new cycle count is computed from the
* old, not the time the interrupt was serviced. However if a timer
* interrupt is ever serviced more than one tick late, it is necessary
* to process multiple ticks until the new cycle count is in the
* future, otherwise the next timer interrupt would not occur until
* after the cycle counter had wrapped (2^32 cycles later).
*
* do {
* ticks++;
* old_ccompare = read_ccompare_i();
* write_ccompare_i( old_ccompare + divisor );
* service one tick;
* diff = read_ccount() - old_ccompare;
* } while ( diff > divisor );
*/
ENTRY(16)
.L_xt_timer_int_catchup:
#ifdef CONFIG_SYS_CLOCK_EXISTS
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
/* Update the timer comparator for the next tick. */
#ifdef XT_CLOCK_FREQ
movi a2, XT_TICK_DIVISOR /* a2 = comparator increment */
#else
movi a3, _xt_tick_divisor
l32i a2, a3, 0 /* a2 = comparator increment */
#endif
rsr a3, XT_CCOMPARE /* a3 = old comparator value */
add a4, a3, a2 /* a4 = new comparator value */
wsr a4, XT_CCOMPARE /* update comp. and clear interrupt */
esync
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
#ifdef __XTENSA_CALL0_ABI__
/* Preserve a2 and a3 across C calls. */
s32i a2, sp, 4
s32i a3, sp, 8
/* TODO: movi a2, _xt_interrupt_table */
movi a3, _timer_int_handler
/* TODO: l32i a2, a2, 0 */
callx0 a3
/* Restore a2 and a3. */
l32i a2, sp, 4
l32i a3, sp, 8
#else
/* TODO: movi a6, _xt_interrupt_table */
movi a7, _timer_int_handler
/* TODO: l32i a6, a6, 0 */
callx4 a7
#endif
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
/* Check if we need to process more ticks to catch up. */
esync /* ensure comparator update complete */
rsr a4, CCOUNT /* a4 = cycle count */
sub a4, a4, a3 /* diff = ccount - old comparator */
blt a2, a4, .L_xt_timer_int_catchup /* repeat while diff > divisor */
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
#endif
RET(16)
/*
* _zxt_tick_timer_init
* void _zxt_tick_timer_init(void)
*
* Initialize timer and timer interrupt handler (_xt_tick_divisor_init() has
* already been been called).
* Callable from C (obeys ABI conventions on entry).
*
*/
.globl _zxt_tick_timer_init
.type _zxt_tick_timer_init,@function
.align 4
_zxt_tick_timer_init:
ENTRY(48)
#ifdef CONFIG_SYS_CLOCK_EXISTS
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
/* Set up the periodic tick timer (assume enough time to complete
* init).
*/
#ifdef XT_CLOCK_FREQ
movi a3, XT_TICK_DIVISOR
#else
movi a2, _xt_tick_divisor
l32i a3, a2, 0
#endif
rsr a2, CCOUNT /* current cycle count */
add a2, a2, a3 /* time of first timer interrupt */
wsr a2, XT_CCOMPARE /* set the comparator */
/*
Enable the timer interrupt at the device level. Don't write directly
to the INTENABLE register because it may be virtualized.
*/
#ifdef __XTENSA_CALL0_ABI__
movi a2, XT_TIMER_INTEN
call0 _xt_ints_on
#else
movi a6, XT_TIMER_INTEN
call4 _xt_ints_on
#endif
#endif
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
RET(48)
/*
* _zxt_task_coproc_state
* void _zxt_task_coproc_state(void)
*
* Implements the Xtensa RTOS porting layer's XT_RTOS_CP_STATE function.
*
* May only be called when a task is running, not within an interrupt handler
* (returns 0 in that case).
* May only be called from assembly code by the 'call0' instruction.
* Does NOT obey ABI conventions.
* Returns in A15 a pointer to the base of the co-processor state save area
* for the current task.
* See the detailed description of the XT_RTOS_ENTER macro in xtensa_rtos.h.
*
*/
#if XCHAL_CP_NUM > 0
.globl _zxt_task_coproc_state
.type _zxt_task_coproc_state,@function
.align 4
_zxt_task_coproc_state:
movi a2, _kernel
l32i a15, a2, KERNEL_OFFSET(nested)
bnez a15, 1f
l32i a2, a2, KERNEL_OFFSET(current)
beqz a2, 1f
l32i a15, a2, THREAD_OFFSET(cpStack)
ret
1: movi a15, 0
2: ret
#endif /* XCHAL_CP_NUM > 0 */

View file

@ -0,0 +1,609 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/* XTENSA CONTEXT SAVE AND RESTORE ROUTINES
*
* Low-level Call0 functions for handling generic context save and restore of
* registers not specifically addressed by the interrupt vectors and handlers.
* Those registers (not handled by these functions) are PC, PS, A0, A1 (SP).
* Except for the calls to RTOS functions, this code is generic to Xtensa.
*
* Note that in Call0 ABI, interrupt handlers are expected to preserve the
* callee-save regs (A12-A15), which is always the case if the handlers are
* coded in C. However A12, A13 are made available as scratch registers for
* interrupt dispatch code, so are presumed saved anyway, and are always
* restored even in Call0 ABI. Only A14, A15 are truly handled as callee-save
* regs.
*
* Because Xtensa is a configurable architecture, this port supports all user
* generated configurations (except restrictions stated in the release notes).
* This is accomplished by conditional compilation using macros and functions
* defined in the Xtensa HAL (hardware adaptation layer) for your
* configuration. Only the processor state included in your configuration is
* saved and restored, including any processor state added by user
* configuration options or TIE.
*/
/* Warn nicely if this file gets named with a lowercase .s instead of .S: */
#define NOERROR #
NOERROR: .error "C preprocessor needed for this file: make sure its filename\
ends in uppercase .S, or use xt-xcc's -x assembler-with-cpp option."
#include "xtensa_rtos.h"
#ifdef XT_USE_OVLY
#include <xtensa/overlay_os_asm.h>
#endif
.text
/*
* _xt_context_save
*
* !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
*
* Saves all Xtensa processor state except PC, PS, A0, A1 (SP), A12, A13, in
* the interrupt stack frame defined in xtensa_rtos.h. Its counterpart is
* _xt_context_restore (which also restores A12, A13).
*
* Caller is expected to have saved PC, PS, A0, A1 (SP), A12, A13 in the frame.
* This function preserves A12 & A13 in order to provide the caller with 2
* scratch regs that need not be saved over the call to this function. The
* choice of which 2 regs to provide is governed by xthal_window_spill_nw and
* xthal_save_extra_nw, to avoid moving data more than necessary. Caller can
* assign regs accordingly.
*
* Entry Conditions:
* A0 = Return address in caller.
* A1 = Stack pointer of interrupted thread or handler ("interruptee").
* Original A12, A13 have already been saved in the interrupt stack frame.
* Other processor state except PC, PS, A0, A1 (SP), A12, A13, is as at the
* point of interruption.
* If windowed ABI, PS.EXCM = 1 (exceptions disabled).
*
* Exit conditions:
* A0 = Return address in caller.
* A1 = Stack pointer of interrupted thread or handler ("interruptee").
* A12, A13 as at entry (preserved).
* If windowed ABI, PS.EXCM = 1 (exceptions disabled).
*/
.global _xt_context_save
.type _xt_context_save,@function
.align 4
_xt_context_save:
s32i a2, sp, XT_STK_a2
s32i a3, sp, XT_STK_a3
s32i a4, sp, XT_STK_a4
s32i a5, sp, XT_STK_a5
s32i a6, sp, XT_STK_a6
s32i a7, sp, XT_STK_a7
s32i a8, sp, XT_STK_a8
s32i a9, sp, XT_STK_a9
s32i a10, sp, XT_STK_a10
s32i a11, sp, XT_STK_a11
/* Call0 ABI callee-saved regs a12-15 do not need to be saved here. a12-13
* are the caller's responsibility so it can use them as scratch. So only
* need to save a14-a15 here for Windowed ABI (not Call0).
*/
#ifndef __XTENSA_CALL0_ABI__
s32i a14, sp, XT_STK_a14
s32i a15, sp, XT_STK_a15
#endif
rsr a3, SAR
s32i a3, sp, XT_STK_sar
#if XCHAL_HAVE_LOOPS
rsr a3, LBEG
s32i a3, sp, XT_STK_lbeg
rsr a3, LEND
s32i a3, sp, XT_STK_lend
rsr a3, LCOUNT
s32i a3, sp, XT_STK_lcount
#endif
#if XT_USE_SWPRI
/* Save virtual priority mask */
movi a3, _xt_vpri_mask
l32i a3, a3, 0
s32i a3, sp, XT_STK_VPRI
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a9, a0 /* preserve ret addr */
#endif
#ifndef __XTENSA_CALL0_ABI__
/* To spill the reg windows, temp. need pre-interrupt stack ptr and a4-15.
* Need to save a9,12,13 temporarily (in frame temps) and recover
* originals. Interrupts need to be disabled below XCHAL_EXCM_LEVEL and
* window overflow and underflow exceptions disabled (assured by PS.EXCM ==
* 1).
*/
s32i a12, sp, XT_STK_tmp0 /* temp. save stuff in stack frame */
s32i a13, sp, XT_STK_tmp1
s32i a9, sp, XT_STK_tmp2
/* Save the overlay state if we are supporting overlays. Since we just
* saved three registers, we can conveniently use them here. Note that as
* of now, overlays only work for windowed calling ABI.
*/
#ifdef XT_USE_OVLY
l32i a9, sp, XT_STK_PC /* recover saved PC */
_xt_overlay_get_state a9, a12, a13
s32i a9, sp, XT_STK_OVLY /* save overlay state */
#endif
l32i a12, sp, XT_STK_a12 /* recover original a9,12,13 */
l32i a13, sp, XT_STK_a13
l32i a9, sp, XT_STK_a9
addi sp, sp, XT_STK_FRMSZ /* restore the interruptee's SP */
call0 xthal_window_spill_nw /* preserves only a4,5,8,9,12,13 */
addi sp, sp, -XT_STK_FRMSZ
l32i a12, sp, XT_STK_tmp0 /* recover stuff from stack frame */
l32i a13, sp, XT_STK_tmp1
l32i a9, sp, XT_STK_tmp2
#endif
#if XCHAL_EXTRA_SA_SIZE > 0
/* NOTE: Normally the xthal_save_extra_nw macro only affects address
* registers a2-a5. It is theoretically possible for Xtensa processor
* designers to write TIE that causes more address registers to be
* affected, but it is generally unlikely. If that ever happens, more
* registers need to be saved/restored around this macro invocation. Here
* we assume a9,12,13 are preserved. Future Xtensa tools releases might
* limit the regs that can be affected.
*/
addi a2, sp, XT_STK_EXTRA /* where to save it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_save_extra_nw /* destroys a0,2,3,4,5 */
#endif
#if XCHAL_EXTRA_SA_SIZE > 0 || !defined(__XTENSA_CALL0_ABI__)
mov a0, a9 /* retrieve ret addr */
#endif
ret
/*_xt_context_restore
*
* !! MUST BE CALLED ONLY BY 'CALL0' INSTRUCTION !!
*
* Restores all Xtensa processor state except PC, PS, A0, A1 (SP) (and in Call0
* ABI, A14, A15 which are preserved by all interrupt handlers) from an
* interrupt stack frame defined in xtensa_rtos.h. Its counterpart is
* _xt_context_save (whose caller saved A12, A13).
*
* Caller is responsible to restore PC, PS, A0, A1 (SP).
*
* Entry Conditions:
* A0 = Return address in caller.
* A1 = Stack pointer of interrupted thread or handler ("interruptee").
*
* Exit conditions:
* A0 = Return address in caller.
* A1 = Stack pointer of interrupted thread or handler ("interruptee").
* Other processor state except PC, PS, A0, A1 (SP), is as at the point
* of interruption.
*/
.global _xt_context_restore
.type _xt_context_restore,@function
.align 4
_xt_context_restore:
#if XCHAL_EXTRA_SA_SIZE > 0
/* NOTE: Normally the xthal_restore_extra_nw macro only affects address
* registers a2-a5. It is theoretically possible for Xtensa processor
* designers to write TIE that causes more address registers to be
* affected, but it is generally unlikely. If that ever happens, more
* registers need to be saved/restored around this macro invocation. Here
* we only assume a13 is preserved. Future Xtensa tools releases might
* limit the regs that can be affected.
*/
mov a13, a0 /* preserve ret addr */
addi a2, sp, XT_STK_EXTRA /* where to find it */
# if XCHAL_EXTRA_SA_ALIGN > 16
movi a3, -XCHAL_EXTRA_SA_ALIGN
and a2, a2, a3 /* align dynamically >16 bytes */
# endif
call0 xthal_restore_extra_nw /* destroys a0,2,3,4,5 */
mov a0, a13 /* retrieve ret addr */
#endif
#if XCHAL_HAVE_LOOPS
l32i a2, sp, XT_STK_lbeg
l32i a3, sp, XT_STK_lend
wsr a2, LBEG
l32i a2, sp, XT_STK_lcount
wsr a3, LEND
wsr a2, LCOUNT
#endif
#ifdef XT_USE_OVLY
/* If we are using overlays, this is a good spot to check if we need to
* restore an overlay for the incoming task. Here we have a bunch of
* registers to spare. Note that this step is going to use a few bytes of
* storage below SP (SP-20 to SP-32) if an overlay is going to be
* restored.
*/
l32i a2, sp, XT_STK_pc /* retrieve PC */
l32i a3, sp, XT_STK_ps /* retrieve PS */
l32i a4, sp, XT_STK_ovly /* retrieve overlay state */
l32i a5, sp, XT_STK_a1 /* retrieve stack ptr */
_xt_overlay_check_map a2, a3, a4, a5, a6
s32i a2, sp, XT_STK_pc /* save updated PC */
s32i a3, sp, XT_STK_ps /* save updated PS */
#endif
#ifdef XT_USE_SWPRI
/* Restore virtual interrupt priority and interrupt enable */
movi a3, _xt_intdata
l32i a4, a3, 0 /* a4 = _xt_intenable */
l32i a5, sp, XT_STK_VPRI /* a5 = saved _xt_vpri_mask */
and a4, a4, a5
wsr a4, INTENABLE /* update INTENABLE */
s32i a5, a3, 4 /* restore _xt_vpri_mask */
#endif
l32i a3, sp, XT_STK_sar
l32i a2, sp, XT_STK_a2
wsr a3, SAR
l32i a3, sp, XT_STK_a3
l32i a4, sp, XT_STK_a4
l32i a5, sp, XT_STK_a5
l32i a6, sp, XT_STK_a6
l32i a7, sp, XT_STK_a7
l32i a8, sp, XT_STK_a8
l32i a9, sp, XT_STK_a9
l32i a10, sp, XT_STK_a10
l32i a11, sp, XT_STK_a11
/*
* Call0 ABI callee-saved regs a12-15 do not need to be restored here.
* However a12-13 were saved for scratch before XT_RTOS_INT_ENTER(),
* so need to be restored anyway, despite being callee-saved in Call0.
*/
l32i a12, sp, XT_STK_a12
l32i a13, sp, XT_STK_a13
#ifndef __XTENSA_CALL0_ABI__
l32i a14, sp, XT_STK_a14
l32i a15, sp, XT_STK_a15
#endif
ret
/* _xt_coproc_init
*
* Initializes global co-processor management data, setting all co-processors
* to "unowned". Leaves CPENABLE as it found it (does NOT clear it).
*
* Called during initialization of the RTOS, before any threads run.
*
* This may be called from normal Xtensa single-threaded application code which
* might use co-processors. The Xtensa run-time initialization enables all
* co-processors. They must remain enabled here, else a co-processor exception
* might occur outside of a thread, which the exception handler doesn't expect.
*
* Entry Conditions:
* Xtensa single-threaded run-time environment is in effect.
* No thread is yet running.
*
* Exit conditions:
* None.
*
* Obeys ABI conventions per prototype:
* void _xt_coproc_init(void)
*/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_init
.type _xt_coproc_init,@function
.align 4
_xt_coproc_init:
ENTRY0
/* Initialize thread co-processor ownerships to 0 (unowned). */
movi a2, _xt_coproc_owner_sa /* a2 = base of owner array */
addi a3, a2, XCHAL_CP_MAX << 2 /* a3 = top+1 of owner array */
movi a4, 0 /* a4 = 0 (unowned) */
1: s32i a4, a2, 0
addi a2, a2, 4
bltu a2, a3, 1b
RET0
#endif
/* _xt_coproc_release
*
* Releases any and all co-processors owned by a given thread. The thread is
* identified by it's co-processor state save area defined in xtensa_context.h
*
* Must be called before a thread's co-proc save area is deleted to avoid
* memory corruption when the exception handler tries to save the state.
* May be called when a thread terminates or completes but does not delete
* the co-proc save area, to avoid the exception handler having to save the
* thread's co-proc state before another thread can use it (optimization).
*
* Entry Conditions:
* A2 = Pointer to base of co-processor state save area.
*
* Exit conditions:
* None.
*
* Obeys ABI conventions per prototype:
* void _xt_coproc_release(void * coproc_sa_base)
*/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_release
.type _xt_coproc_release,@function
.align 4
_xt_coproc_release:
ENTRY0 /* a2 = base of save area */
movi a3, _xt_coproc_owner_sa /* a3 = base of owner array */
addi a4, a3, XCHAL_CP_MAX << 2 /* a4 = top+1 of owner array */
movi a5, 0 /* a5 = 0 (unowned) */
rsil a6, XCHAL_EXCM_LEVEL /* lock interrupts */
1: l32i a7, a3, 0 /* a7 = owner at a3 */
bne a2, a7, 2f /* if (coproc_sa_base == owner) */
s32i a5, a3, 0 /* owner = unowned */
2: addi a3, a3, 1<<2 /* a3 = next entry in owner array */
bltu a3, a4, 1b /* repeat until end of array */
3: wsr a6, PS /* restore interrupts */
RET0
#endif
/* _xt_coproc_savecs
*
* If there is a current thread and it has a coprocessor state save area, then
* save all callee-saved state into this area. This function is called from the
* solicited context switch handler. It calls a system-specific function to get
* the coprocessor save area base address.
*
* Entry conditions:
* - The thread being switched out is still the current thread.
* - CPENABLE state reflects which coprocessors are active.
* - Registers have been saved/spilled already.
*
* Exit conditions:
* - All necessary CP callee-saved state has been saved.
* - Registers a2-a7, a13-a15 have been trashed.
*
* Must be called from assembly code only, using CALL0.
*/
#if XCHAL_CP_NUM > 0
.extern _xt_coproc_sa_offset /* external reference */
.global _xt_coproc_savecs
.type _xt_coproc_savecs,@function
.align 4
_xt_coproc_savecs:
/* At entry, CPENABLE should be showing which CPs are enabled. */
rsr a2, CPENABLE /* a2 = which CPs are enabled */
beqz a2, .Ldone /* quick exit if none */
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone /* if none then nothing to do */
s16i a2, a15, XT_CP_CS_ST /* save mask of CPs being stored */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_store a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone:
ret
#endif
/*
* _xt_coproc_restorecs
*
* Restore any callee-saved coprocessor state for the incoming thread.
* This function is called from coprocessor exception handling, when giving
* ownership to a thread that solicited a context switch earlier. It calls a
* system-specific function to get the coprocessor save area base address.
*
* Entry conditions:
* - The incoming thread is set as the current thread.
* - CPENABLE is set up correctly for all required coprocessors.
* - a2 = mask of coprocessors to be restored.
*
* Exit conditions:
* - All necessary CP callee-saved state has been restored.
* - CPENABLE - unchanged.
* - Registers a2-a7, a13-a15 have been trashed.
*
* Must be called from assembly code only, using CALL0.
*/
#if XCHAL_CP_NUM > 0
.global _xt_coproc_restorecs
.type _xt_coproc_restorecs,@function
.align 4
_xt_coproc_restorecs:
mov a14, a0 /* save return address */
call0 XT_RTOS_CP_STATE /* get address of CP save area */
mov a0, a14 /* restore return address */
beqz a15, .Ldone2 /* if none then nothing to do */
l16ui a3, a15, XT_CP_CS_ST /* a3 = which CPs have been saved */
xor a3, a3, a2 /* clear the ones being restored */
s32i a3, a15, XT_CP_CS_ST /* update saved CP mask */
movi a13, _xt_coproc_sa_offset /* array of CP save offsets */
l32i a15, a15, XT_CP_ASA /* a15 = base of aligned save area */
#if XCHAL_CP0_SA_SIZE
bbci.l a2, 0, 2f /* CP 0 not enabled */
l32i a14, a13, 0 /* a14 = _xt_coproc_sa_offset[0] */
add a3, a14, a15 /* a3 = save area for CP 0 */
xchal_cp0_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP1_SA_SIZE
bbci.l a2, 1, 2f /* CP 1 not enabled */
l32i a14, a13, 4 /* a14 = _xt_coproc_sa_offset[1] */
add a3, a14, a15 /* a3 = save area for CP 1 */
xchal_cp1_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP2_SA_SIZE
bbci.l a2, 2, 2f
l32i a14, a13, 8
add a3, a14, a15
xchal_cp2_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP3_SA_SIZE
bbci.l a2, 3, 2f
l32i a14, a13, 12
add a3, a14, a15
xchal_cp3_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP4_SA_SIZE
bbci.l a2, 4, 2f
l32i a14, a13, 16
add a3, a14, a15
xchal_cp4_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP5_SA_SIZE
bbci.l a2, 5, 2f
l32i a14, a13, 20
add a3, a14, a15
xchal_cp5_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP6_SA_SIZE
bbci.l a2, 6, 2f
l32i a14, a13, 24
add a3, a14, a15
xchal_cp6_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
#if XCHAL_CP7_SA_SIZE
bbci.l a2, 7, 2f
l32i a14, a13, 28
add a3, a14, a15
xchal_cp7_load a3, a4, a5, a6, a7 continue=0 ofs=-1 \
select=XTHAL_SAS_TIE|XTHAL_SAS_NOCC|XTHAL_SAS_CALE alloc=XTHAL_SAS_ALL
2:
#endif
.Ldone2:
ret
#endif

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Xtensa-specific interrupt and exception functions for RTOS ports.
* Also see xtensa_intr_asm.S.
*/
#include <stdlib.h>
#include <xtensa/config/core.h>
#include "xtensa_rtos.h"
#include "xtensa_api.h"
#include <kernel_structs.h>
#if XCHAL_HAVE_EXCEPTIONS
/* Handler table is in xtensa_intr_asm.S */
extern xt_exc_handler _xt_exception_table[XCHAL_EXCCAUSE_NUM];
/*
* Default handler for unhandled exceptions.
*/
void xt_unhandled_exception(XtExcFrame *frame)
{
FatalErrorHandler();
CODE_UNREACHABLE;
}
/*
* This function registers a handler for the specified exception.
* The function returns the address of the previous handler.
* On error, it returns 0.
*/
xt_exc_handler _xt_set_exception_handler(int n, xt_exc_handler f)
{
xt_exc_handler old;
if (n < 0 || n >= XCHAL_EXCCAUSE_NUM)
return 0; /* invalid exception number */
old = _xt_exception_table[n];
if (f) {
_xt_exception_table[n] = f;
} else {
_xt_exception_table[n] = &xt_unhandled_exception;
}
return ((old == &xt_unhandled_exception) ? 0 : old);
}
#endif
#if XCHAL_HAVE_INTERRUPTS
/*
* Default handler for unhandled interrupts.
*/
void xt_unhandled_interrupt(void *arg)
{
ReservedInterruptHandler((unsigned int)arg);
CODE_UNREACHABLE;
}
#endif /* XCHAL_HAVE_INTERRUPTS */

View file

@ -0,0 +1,140 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/******************************************************************************
Xtensa interrupt handling data and assembly routines.
Also see xtensa_intr.c and xtensa_vectors.S.
******************************************************************************/
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include "xtensa_rtos.h"
#include "xtensa_context.h"
#if XCHAL_HAVE_INTERRUPTS
/*
-------------------------------------------------------------------------------
INTENABLE virtualization information.
-------------------------------------------------------------------------------
*/
.data
.global _xt_intdata
.align 8
_xt_intdata:
.global _xt_intenable
.type _xt_intenable,@object
.size _xt_intenable,4
.global _xt_vpri_mask
.type _xt_vpri_mask,@object
.size _xt_vpri_mask,4
_xt_intenable: .word 0 /* Virtual INTENABLE */
_xt_vpri_mask: .word 0xFFFFFFFF /* Virtual priority mask */
#endif /* XCHAL_HAVE_INTERRUPTS */
#if XCHAL_HAVE_EXCEPTIONS
/*
-------------------------------------------------------------------------------
Table of C-callable exception handlers for each exception. Note that not all
slots will be active, because some exceptions (e.g. coprocessor exceptions)
are always handled by the OS and cannot be hooked by user handlers.
-------------------------------------------------------------------------------
*/
.data
.global _xt_exception_table
.align 4
_xt_exception_table:
.rept XCHAL_EXCCAUSE_NUM
.word xt_unhandled_exception /* handler address */
.endr
#endif
/*
-------------------------------------------------------------------------------
unsigned int _xt_ints_on ( unsigned int mask )
Enables a set of interrupts. Does not simply set INTENABLE directly, but
computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global _xt_ints_on
.type _xt_ints_on,@function
_xt_ints_on:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
s32i a5, a4, 0 /* _xt_intenable |= mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* Return zero */
#endif
RET0
.size _xt_ints_on, . - _xt_ints_on
/*
-------------------------------------------------------------------------------
unsigned int _xt_ints_off ( unsigned int mask )
Disables a set of interrupts. Does not simply set INTENABLE directly,
but computes it as a function of the current virtual priority.
Can be called from interrupt handlers.
-------------------------------------------------------------------------------
*/
.text
.align 4
.global _xt_ints_off
.type _xt_ints_off,@function
_xt_ints_off:
ENTRY0
#if XCHAL_HAVE_INTERRUPTS
movi a3, 0
movi a4, _xt_intdata
xsr a3, INTENABLE /* Disables all interrupts */
rsync
l32i a3, a4, 0 /* a3 = _xt_intenable */
l32i a6, a4, 4 /* a6 = _xt_vpri_mask */
or a5, a3, a2 /* a5 = _xt_intenable | mask */
xor a5, a5, a2 /* a5 = _xt_intenable & ~mask */
s32i a5, a4, 0 /* _xt_intenable &= ~mask */
and a5, a5, a6 /* a5 = _xt_intenable & _xt_vpri_mask */
wsr a5, INTENABLE /* Reenable interrupts */
mov a2, a3 /* Previous mask */
#else
movi a2, 0 /* return zero */
#endif
RET0
.size _xt_ints_off, . - _xt_ints_off

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,195 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Private kernel definitions (XTENSA)
*
* This file contains private kernel structures definitions and various
* other definitions for the XTENSA processors family architecture.
*
* This file is also included by assembly language files which must #define
* _ASMLANGUAGE before including this header file. Note that kernel
* assembly source files obtains structure offset values via "absolute symbols"
* in the offsets.o module.
*/
#ifndef _kernel_arch_data__h_
#define _kernel_arch_data__h_
#ifdef __cplusplus
extern "C" {
#endif
#include <toolchain.h>
#include <sections.h>
#include <arch/cpu.h>
#include <xtensa_context.h>
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
#include <kernel.h> /* public kernel API */
#include <nano_internal.h>
#include <stdint.h>
#include <misc/dlist.h>
#include <misc/util.h>
/* Bitmask definitions for the struct k_thread->flags bit field */
/* executing context is interrupt handler */
#define INT_ACTIVE (1 << 1)
/* executing context is exception handler */
#define EXC_ACTIVE (1 << 2)
/* thread uses floating point unit */
#define USE_FP 0x010
/*
* The following structure defines the set of 'volatile' integer registers.
* These registers need not be preserved by a called C function. Given that
* they are not preserved across function calls, they must be save/restored
* (along with the struct _caller_saved) when a preemptive context switch
* occurs.
*/
struct _caller_saved {
/*
* The volatile registers area not included in the definition of
* 'tPreempReg' since the interrupt stubs (_IntEnt/_IntExit)
* and exception stubs (_ExcEnt/_ExcEnter) use the stack to save and
* restore the values of these registers in order to support interrupt
* nesting. The stubs do _not_ copy the saved values from the stack
* into the TCS.
*/
};
typedef struct _caller_saved _caller_saved_t;
/*
* The following structure defines the set of 'non-volatile' integer registers.
* These registers must be preserved by a called C function. These are the
* only registers that need to be saved/restored when a cooperative context
* switch occurs.
*/
struct _callee_saved {
/*
* The following registers are considered non-volatile, i.e.
* callee-saved, but their values are pushed onto the stack rather than
* stored in the TCS structure:
*/
uint32_t retval; /* a2 */
XtExcFrame *topOfStack; /* a1 = sp */
};
typedef struct _callee_saved _callee_saved_t;
typedef struct __esf __esf_t;
/*
* The following structure defines the set of 'non-volatile' x87 FPU/MMX/SSE
* registers. These registers must be preserved by a called C function.
* These are the only registers that need to be saved/restored when a
* cooperative context switch occurs.
*/
typedef struct s_coopCoprocReg {
/*
* This structure intentionally left blank. Coprocessor's registers are
* all 'volatile' and saved using the lazy context switch mechanism.
*/
} tCoopCoprocReg;
/*
* The following structure defines the set of 'volatile' x87 FPU/MMX/SSE
* registers. These registers need not be preserved by a called C function.
* Given that they are not preserved across function calls, they must be
* save/restored (along with s_coopCoprocReg) when a preemptive context switch
* occurs.
*/
typedef struct s_preempCoprocReg {
/*
* This structure intentionally left blank, as for now coprocessor's
* stack is positioned at top of the stack.
*/
#if XCHAL_CP_NUM > 0
char *cpStack;
#endif
} tPreempCoprocReg;
/*
* The thread control stucture definition. It contains the
* various fields to manage a _single_ thread. The TCS will be aligned
* to the appropriate architecture specific boundary via the
* _new_thread() call.
*/
struct _thread_arch {
/*
* See the above flag definitions above for valid bit settings. This
* field must remain near the start of struct tcs, specifically before
* any #ifdef'ed fields since the host tools currently use a fixed
* offset to read the 'flags' field.
*/
uint32_t flags;
#ifdef CONFIG_THREAD_CUSTOM_DATA
void *custom_data; /* available for custom use */
#endif
#if defined(CONFIG_THREAD_MONITOR)
/* thread entry and parameters description */
struct __thread_entry *entry;
/* next item in list of ALL fiber+tasks */
struct tcs *next_thread;
#endif
#ifdef CONFIG_ERRNO
int errno_var;
#endif
/*
* The location of all floating point related structures/fields MUST be
* located at the end of struct tcs. This way only the fibers/tasks
* that actually utilize non-integer capabilities need to account for
* the increased memory required for storing FP state when sizing
* stacks.
*
* Given that stacks "grow down" on Xtensa, and the TCS is located at
* the start of a thread's "workspace" memory, the stacks of
* fibers/tasks that do not utilize floating point instruction can
* effectively consume the memory occupied by the 'tCoopCoprocReg'
* and 'tPreempCoprocReg' structures without ill effect.
*
* TODO: Move Xtensa coprocessor's stack here to get rid of extra
* indirection
*/
/* non-volatile coprocessor's register storage */
tCoopCoprocReg coopCoprocReg;
/* volatile coprocessor's register storage */
tPreempCoprocReg preempCoprocReg;
};
typedef struct _thread_arch _thread_arch_t;
struct _kernel_arch {
#if defined(CONFIG_DEBUG_INFO)
NANO_ISF *isf; /* ptr to interrupt stack frame */
#endif
};
typedef struct _kernel_arch _kernel_arch_t;
#endif /*! _ASMLANGUAGE && ! __ASSEMBLER__ */
/* stacks */
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
#ifdef __cplusplus
}
#endif
#endif /* _kernel_arch_data__h_ */

View file

@ -0,0 +1,94 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/* this file is only meant to be included by kernel_structs.h */
#ifndef _kernel_arch_func__h_
#define _kernel_arch_func__h_
#ifndef _ASMLANGUAGE
#ifdef __cplusplus
extern "C" {
#endif
/* stack alignment related macros: STACK_ALIGN_SIZE is defined above */
#define STACK_ROUND_UP(x) ROUND_UP(x, STACK_ALIGN_SIZE)
#define STACK_ROUND_DOWN(x) ROUND_DOWN(x, STACK_ALIGN_SIZE)
extern void FatalErrorHandler(void);
extern void ReservedInterruptHandler(unsigned int intNo);
/* Defined in xtensa_context.S */
extern void _xt_coproc_init(void);
/**
*
* @brief Performs architecture-specific initialization
*
* This routine performs architecture-specific initialization of the
* nanokernel. Trivial stuff is done inline; more complex initialization is
* done via function calls.
*
* @return N/A
*/
static ALWAYS_INLINE void nanoArchInit(void)
{
_kernel.nested = 0;
#if XCHAL_CP_NUM > 0
/* Initialize co-processor management for tasks.
* Leave CPENABLE alone.
*/
_xt_coproc_init();
#endif
}
/**
*
* @brief Set the return value for the specified fiber (inline)
*
* @param fiber pointer to fiber
* @param value value to set as return value
*
* The register used to store the return value from a function call invocation
* is set to <value>. It is assumed that the specified <fiber> is pending, and
* thus the fibers context is stored in its TCS.
*
* @return N/A
*/
static ALWAYS_INLINE void
_set_thread_return_value(struct k_thread *thread, unsigned int value)
{
thread->callee_saved.retval = value;
}
extern void nano_cpu_atomic_idle(unsigned int imask);
/*
* _IntLibInit() is called from the non-arch specific nanokernel function,
* _nano_init(). The IA-32 nanokernel does not require any special
* initialization of the interrupt subsystem. However, we still need to
* provide an _IntLibInit() of some sort to prevent build errors.
*/
static inline void _IntLibInit(void)
{
}
FUNC_NORETURN void _NanoFatalErrorHandler(unsigned int reason,
const NANO_ESF *pEsf);
#include <stddef.h> /* For size_t */
#ifdef __cplusplus
}
#endif
#define _is_in_isr() (_kernel.nested != 0)
#endif /* _ASMLANGUAGE */
#endif /* _kernel_arch_func__h_ */

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Kernel event logger support for Xtensa
*/
#ifndef __KERNEL_EVENT_LOGGER_ARCH_H__
#define __KERNEL_EVENT_LOGGER_ARCH_H__
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get the identification of the current interrupt.
*
* This routine obtain the key of the interrupt that is currently processed
* if it is called from a ISR context.
*
* @return The key of the interrupt that is currently being processed.
*/
static inline int _sys_current_irq_key_get(void)
{
return 0;
}
#ifdef __cplusplus
}
#endif
#endif /* __KERNEL_EVENT_LOGGER_ARCH_H__ */

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2016 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef _offsets_short_arch__h_
#define _offsets_short_arch__h_
#include <offsets.h>
/* kernel */
#define KERNEL_OFFSET(field) _kernel_offset_to_##field
#define _kernel_offset_to_flags \
(___kernel_t_arch_OFFSET + ___kernel_arch_t_flags_OFFSET)
/* end - kernel */
/* threads */
#define THREAD_OFFSET(field) _thread_offset_to_##field
#define _thread_offset_to_sp \
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_topOfStack_OFFSET)
#define _thread_offset_to_retval \
(___thread_t_callee_saved_OFFSET + ___callee_saved_t_retval_OFFSET)
#define _thread_offset_to_coopCoprocReg \
(___thread_t_arch_OFFSET + ___thread_arch_t_coopCoprocReg_OFFSET)
#define _thread_offset_to_preempCoprocReg \
(___thread_t_arch_OFFSET + ___thread_arch_t_preempCoprocReg_OFFSET)
#define _thread_offset_to_cpStack \
(_thread_offset_to_preempCoprocReg + __tPreempCoprocReg_cpStack_OFFSET)
/* end - threads */
#endif /* _offsets_short_arch__h_ */

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief XTENSA nanokernel declarations to start a task
*
* XTENSA-specific parts of start_task().
*
* Currently empty, only here for abstraction.
*/
#ifndef _START_TASK_ARCH__H_
#define _START_TASK_ARCH__H_
#include <toolchain.h>
#include <sections.h>
#include <micro_private.h>
#include <kernel_structs.h>
#include <microkernel/task.h>
#ifdef __cplusplus
extern "C" {
#endif
#define _START_TASK_ARCH(task, opt_ptr) \
do {/* nothing */ \
} while ((0))
#ifdef __cplusplus
}
#endif
#endif /* _START_TASK_ARCH__H_ */

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __XTENSA_API_H__
#define __XTENSA_API_H__
#include <xtensa/hal.h>
#include "xtensa_rtos.h"
#include "xtensa_context.h"
/* Typedef for C-callable interrupt handler function */
typedef void (*xt_handler)(void *);
/* Typedef for C-callable exception handler function */
typedef void (*xt_exc_handler)(XtExcFrame *);
/*
* Call this function to set a handler for the specified exception.
*
* n - Exception number (type) f - Handler function address,
* NULL to uninstall handler.
*
* The handler will be passed a pointer to the exception frame, which is created
* on the stack of the thread that caused the exception.
*
* If the handler returns, the thread context will be restored and the faulting
* instruction will be retried. Any values in the exception frame that are
* modified by the handler will be restored as part of the context. For details
* of the exception frame structure see xtensa_context.h.
*
* FIXME: Remove this API entirely
*/
extern xt_exc_handler _xt_set_exception_handler(int n, xt_exc_handler f);
/*
* Call this function to enable the specified interrupts.
*
* mask - Bit mask of interrupts to be enabled.
*/
extern void _xt_ints_on(unsigned int mask);
/*
* Call this function to disable the specified interrupts.
*
* mask - Bit mask of interrupts to be disabled.
*/
extern void _xt_ints_off(unsigned int mask);
/*
* Call this function to set the specified (s/w) interrupt.
*/
static inline void _xt_set_intset(unsigned int arg)
{
xthal_set_intset(arg);
}
/* Call this function to clear the specified (s/w or edge-triggered)
* interrupt.
*/
static inline void _xt_set_intclear(unsigned int arg)
{
xthal_set_intclear(arg);
}
#endif /* __XTENSA_API_H__ */

View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef XTENSA_CONFIG_H
#define XTENSA_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <xtensa/hal.h>
#include <xtensa/config/core.h>
#include <xtensa/config/system.h> /* required for XSHAL_CLIB */
#include "xtensa_context.h"
/*
* STACK REQUIREMENTS
*
* This section defines the minimum stack size, and the extra space required to
* be allocated for saving coprocessor state and/or C library state information
* (if thread safety is enabled for the C library). The sizes are in bytes.
*
* Stack sizes for individual tasks should be derived from these minima based
* on the maximum call depth of the task and the maximum level of interrupt
* nesting. A minimum stack size is defined by XT_STACK_MIN_SIZE. This minimum
* is based on the requirement for a task that calls nothing else but can be
* interrupted. This assumes that interrupt handlers do not call more than a
* few levels deep. If this is not true, i.e. one or more interrupt handlers
* make deep calls then the minimum must be increased.
*
* If the Xtensa processor configuration includes coprocessors, then space is
* allocated to save the coprocessor state on the stack.
*
* If thread safety is enabled for the C runtime library,
* (XT_USE_THREAD_SAFE_CLIB is defined) then space is allocated to save the C
* library context in the TCB.
*
* Allocating insufficient stack space is a common source of hard-to-find
* errors. During development, it is best to enable the FreeRTOS stack
* checking features.
*
* Usage:
*
* XT_USE_THREAD_SAFE_CLIB -- Define this to a nonzero value to enable
* thread-safe use of the C library. This will require extra stack space to be
* allocated for tasks that use the C library reentrant functions. See below
* for more information.
*
* NOTE: The Xtensa toolchain supports multiple C libraries and not all of them
* support thread safety. Check your core configuration to see which C library
* was chosen for your system.
*
* XT_STACK_MIN_SIZE -- The minimum stack size for any task. It is
* recommended that you do not use a stack smaller than this for any task. In
* case you want to use stacks smaller than this size, you must verify that the
* smaller size(s) will work under all operating conditions.
*
* XT_STACK_EXTRA -- The amount of extra stack space to allocate for a
* task that does not make C library reentrant calls. Add this to the amount of
* stack space required by the task itself.
*
* XT_STACK_EXTRA_CLIB -- The amount of space to allocate for C library
* state.
*/
/* Extra space required for interrupt/exception hooks. */
#ifdef XT_INTEXC_HOOKS
#ifdef __XTENSA_CALL0_ABI__
#define STK_INTEXC_EXTRA 0x200
#else
#define STK_INTEXC_EXTRA 0x180
#endif
#else
#define STK_INTEXC_EXTRA 0
#endif
/* Check C library thread safety support and compute size of C library save
* area.
*/
#if XT_USE_THREAD_SAFE_CLIB > 0u
#if XSHAL_CLIB == XTHAL_CLIB_XCLIB
#define XT_HAVE_THREAD_SAFE_CLIB 0
#error "Thread-safe operation is not yet supported for the XCLIB C library."
#elif XSHAL_CLIB == XTHAL_CLIB_NEWLIB
#define XT_HAVE_THREAD_SAFE_CLIB 1
#if !defined __ASSEMBLER__
#include <sys/reent.h>
#define XT_CLIB_CONTEXT_AREA_SIZE ((sizeof(struct _reent) + 15) + (-16))
#define XT_CLIB_GLOBAL_PTR _impure_ptr
#endif
#else
#define XT_HAVE_THREAD_SAFE_CLIB 0
#error "The selected C runtime library is not thread safe."
#endif
#else
#define XT_CLIB_CONTEXT_AREA_SIZE 0
#endif
/* Extra size -- interrupt frame plus coprocessor save area plus hook space.
*
* NOTE: Make sure XT_INTEXC_HOOKS is undefined unless you really need the
* hooks.
*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x10 + XT_CP_SIZE)
#else
#define XT_XTRA_SIZE (XT_STK_FRMSZ + STK_INTEXC_EXTRA + 0x20 + XT_CP_SIZE)
#endif
/*
* Space allocated for user code -- function calls and local variables.
*
* NOTE: This number can be adjusted to suit your needs. You must verify that
* the amount of space you reserve is adequate for the worst-case conditions in
* your application. NOTE: The windowed ABI requires more stack, since space
* has to be reserved for spilling register windows.
*/
#ifdef __XTENSA_CALL0_ABI__
#define XT_USER_SIZE 0x200
#else
#define XT_USER_SIZE 0x400
#endif
/* Minimum recommended stack size. */
#define XT_STACK_MIN_SIZE \
((XT_XTRA_SIZE + XT_USER_SIZE) / sizeof(unsigned char))
/* OS overhead with and without C library thread context. */
#define XT_STACK_EXTRA (XT_XTRA_SIZE)
#define XT_STACK_EXTRA_CLIB (XT_XTRA_SIZE + XT_CLIB_CONTEXT_AREA_SIZE)
#ifdef __cplusplus
}
#endif
#endif /* XTENSA_CONFIG_H */

View file

@ -0,0 +1,314 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* XTENSA CONTEXT FRAMES AND MACROS FOR RTOS ASSEMBLER SOURCES
*
* This header contains definitions and macros for use primarily by Xtensa RTOS
* assembly coded source files. It includes and uses the Xtensa hardware
* abstraction layer (HAL) to deal with config specifics. It may also be
* included in C source files.
*
* Supports only Xtensa Exception Architecture 2 (XEA2). XEA1 not supported.
*
* NOTE: The Xtensa architecture requires stack pointer alignment to 16 bytes.
*/
#ifndef XTENSA_CONTEXT_H
#define XTENSA_CONTEXT_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/config/tie.h>
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/xtruntime-frames.h>
/* Align a value up to nearest n-byte boundary, where n is a power of 2. */
#define ALIGNUP(n, val) (((val) + (n)-1) & -(n))
/*
* INTERRUPT/EXCEPTION STACK FRAME FOR A THREAD OR NESTED INTERRUPT
*
* A stack frame of this structure is allocated for any interrupt or exception.
* It goes on the current stack. If the RTOS has a system stack for handling
* interrupts, every thread stack must allow space for just one interrupt stack
* frame, then nested interrupt stack frames go on the system stack.
*
* The frame includes basic registers (explicit) and "extra" registers
* introduced by user TIE or the use of the MAC16 option in the user's Xtensa
* config. The frame size is minimized by omitting regs not applicable to
* user's config.
*
* For Windowed ABI, this stack frame includes the interruptee's base save
* area, another base save area to manage gcc nested functions, and a little
* temporary space to help manage the spilling of the register windows.
*/
STRUCT_BEGIN
STRUCT_FIELD(long, 4, XT_STK_, exit) /* exit point for dispatch */
STRUCT_FIELD(long, 4, XT_STK_, pc) /* return PC */
STRUCT_FIELD(long, 4, XT_STK_, ps) /* return PS */
STRUCT_FIELD(long, 4, XT_STK_, a0)
STRUCT_FIELD(long, 4, XT_STK_, a1) /* stack pointer before irq */
STRUCT_FIELD(long, 4, XT_STK_, a2)
STRUCT_FIELD(long, 4, XT_STK_, a3)
STRUCT_FIELD(long, 4, XT_STK_, a4)
STRUCT_FIELD(long, 4, XT_STK_, a5)
STRUCT_FIELD(long, 4, XT_STK_, a6)
STRUCT_FIELD(long, 4, XT_STK_, a7)
STRUCT_FIELD(long, 4, XT_STK_, a8)
STRUCT_FIELD(long, 4, XT_STK_, a9)
STRUCT_FIELD(long, 4, XT_STK_, a10)
STRUCT_FIELD(long, 4, XT_STK_, a11)
STRUCT_FIELD(long, 4, XT_STK_, a12)
STRUCT_FIELD(long, 4, XT_STK_, a13)
STRUCT_FIELD(long, 4, XT_STK_, a14)
STRUCT_FIELD(long, 4, XT_STK_, a15)
STRUCT_FIELD(long, 4, XT_STK_, sar)
STRUCT_FIELD(long, 4, XT_STK_, exccause)
STRUCT_FIELD(long, 4, XT_STK_, excvaddr)
#if XCHAL_HAVE_LOOPS
STRUCT_FIELD(long, 4, XT_STK_, lbeg)
STRUCT_FIELD(long, 4, XT_STK_, lend)
STRUCT_FIELD(long, 4, XT_STK_, lcount)
#endif
#ifndef __XTENSA_CALL0_ABI__
/* Temporary space for saving stuff during window spill */
STRUCT_FIELD(long, 4, XT_STK_, tmp0)
STRUCT_FIELD(long, 4, XT_STK_, tmp1)
STRUCT_FIELD(long, 4, XT_STK_, tmp2)
#endif
#ifdef XT_USE_SWPRI
/* Storage for virtual priority mask */
STRUCT_FIELD(long, 4, XT_STK_, vpri)
#endif
#ifdef XT_USE_OVLY
/* Storage for overlay state */
STRUCT_FIELD(long, 4, XT_STK_, ovly)
#endif
STRUCT_END(XtExcFrame)
#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__)
#define XT_STK_NEXT1 XtExcFrameSize
#else
#define XT_STK_NEXT1 sizeof(XtExcFrame)
#endif
/* Allocate extra storage if needed */
#if XCHAL_EXTRA_SA_SIZE != 0
#if XCHAL_EXTRA_SA_ALIGN <= 16
#define XT_STK_EXTRA ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1)
#else
/* If need more alignment than stack, add space for dynamic alignment */
#define XT_STK_EXTRA (ALIGNUP(XCHAL_EXTRA_SA_ALIGN, XT_STK_NEXT1) \
+ XCHAL_EXTRA_SA_ALIGN)
#endif
#define XT_STK_NEXT2 (XT_STK_EXTRA + XCHAL_EXTRA_SA_SIZE)
#else
#define XT_STK_NEXT2 XT_STK_NEXT1
#endif
/*
* This is the frame size. Add space for 4 registers (interruptee's base save
* area) and some space for gcc nested functions if any.
*/
#define XT_STK_FRMSZ (ALIGNUP(0x10, XT_STK_NEXT2) + 0x20)
/*
* SOLICITED STACK FRAME FOR A THREAD
*
* A stack frame of this structure is allocated whenever a thread enters the
* RTOS kernel intentionally (and synchronously) to submit to thread
* scheduling. It goes on the current thread's stack.
*
* The solicited frame only includes registers that are required to be
* preserved by the callee according to the compiler's ABI conventions, some
* space to save the return address for returning to the caller, and the
* caller's PS register. For Windowed ABI, this stack frame includes the
* caller's base save area.
*
* Note on XT_SOL_EXIT field:
*
* It is necessary to distinguish a solicited from an interrupt stack frame.
* This field corresponds to XT_STK_EXIT in the interrupt stack frame and is
* always at the same offset (0). It can be written with a code (usually 0) to
* distinguish a solicted frame from an interrupt frame. An RTOS port may opt
* to ignore this field if it has another way of distinguishing frames.
*/
STRUCT_BEGIN
STRUCT_FIELD(long, 4, XT_SOL_, exit)
STRUCT_FIELD(long, 4, XT_SOL_, pc)
STRUCT_FIELD(long, 4, XT_SOL_, ps)
STRUCT_FIELD(long, 4, XT_SOL_, next)
#ifdef __XTENSA_CALL0_ABI__
STRUCT_FIELD(long, 4, XT_SOL_, a12) /* should be on 16-byte alignment */
STRUCT_FIELD(long, 4, XT_SOL_, a13)
STRUCT_FIELD(long, 4, XT_SOL_, a14)
STRUCT_FIELD(long, 4, XT_SOL_, a15)
#else
STRUCT_FIELD(long, 4, XT_SOL_, a0) /* should be on 16-byte alignment */
STRUCT_FIELD(long, 4, XT_SOL_, a1)
STRUCT_FIELD(long, 4, XT_SOL_, a2)
STRUCT_FIELD(long, 4, XT_SOL_, a3)
#endif
STRUCT_END(XtSolFrame)
/* Size of solicited stack frame */
#define XT_SOL_FRMSZ ALIGNUP(0x10, XtSolFrameSize)
/*
* CO-PROCESSOR STATE SAVE AREA FOR A THREAD
*
* The RTOS must provide an area per thread to save the state of co-processors
* when that thread does not have control. Co-processors are context-switched
* lazily (on demand) only when a new thread uses a co-processor instruction,
* otherwise a thread retains ownership of the co-processor even when it loses
* control of the processor. An Xtensa co-processor exception is triggered when
* any co-processor instruction is executed by a thread that is not the owner,
* and the context switch of that co-processor is then peformed by the handler.
* Ownership represents which thread's state is currently in the co-processor.
*
* Co-processors may not be used by interrupt or exception handlers. If a
* co-processor instruction is executed by an interrupt or exception handler,
* the co-processor exception handler will trigger a kernel panic and freeze.
* This restriction is introduced to reduce the overhead of saving and
* restoring co-processor state (which can be quite large) and in particular
* remove that overhead from interrupt handlers.
*
* The co-processor state save area may be in any convenient per-thread
* location such as in the thread control block or above the thread stack area.
* It need not be in the interrupt stack frame since interrupts don't use
* co-processors.
*
* Along with the save area for each co-processor, two bitmasks with flags per
* co-processor (laid out as in the CPENABLE reg) help manage context-switching
* co-processors as efficiently as possible:
*
* XT_CPENABLE
*
* The contents of a non-running thread's CPENABLE register. It represents the
* co-processors owned (and whose state is still needed) by the thread. When a
* thread is preempted, its CPENABLE is saved here. When a thread solicits a
* context-swtich, its CPENABLE is cleared - the compiler has saved the
* (caller-saved) co-proc state if it needs to. When a non-running thread
* loses ownership of a CP, its bit is cleared. When a thread runs, it's
* XT_CPENABLE is loaded into the CPENABLE reg. Avoids co-processor exceptions
* when no change of ownership is needed.
*
* XT_CPSTORED
*
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
* Indicates whether the state of each co-processor is saved in the state save
* area. When a thread enters the kernel, only the state of co-procs still
* enabled in CPENABLE is saved. When the co-processor exception handler
* assigns ownership of a co-processor to a thread, it restores the saved state
* only if this bit is set, and clears this bit.
*
* XT_CP_CS_ST
*
* A bitmask with the same layout as CPENABLE, a bit per co-processor.
* Indicates whether callee-saved state is saved in the state save area.
* Callee-saved state is saved by itself on a solicited context switch, and
* restored when needed by the coprocessor exception handler. Unsolicited
* switches will cause the entire coprocessor to be saved when necessary.
*
* XT_CP_ASA
*
* Pointer to the aligned save area. Allows it to be aligned more than the
* overall save area (which might only be stack-aligned or TCB-aligned).
* Especially relevant for Xtensa cores configured with a very large data path
* that requires alignment greater than 16 bytes (ABI stack alignment).
*/
#if XCHAL_CP_NUM > 0
/* Offsets of each coprocessor save area within the 'aligned save area': */
#define XT_CP0_SA 0
#define XT_CP1_SA ALIGNUP(XCHAL_CP1_SA_ALIGN, XT_CP0_SA + XCHAL_CP0_SA_SIZE)
#define XT_CP2_SA ALIGNUP(XCHAL_CP2_SA_ALIGN, XT_CP1_SA + XCHAL_CP1_SA_SIZE)
#define XT_CP3_SA ALIGNUP(XCHAL_CP3_SA_ALIGN, XT_CP2_SA + XCHAL_CP2_SA_SIZE)
#define XT_CP4_SA ALIGNUP(XCHAL_CP4_SA_ALIGN, XT_CP3_SA + XCHAL_CP3_SA_SIZE)
#define XT_CP5_SA ALIGNUP(XCHAL_CP5_SA_ALIGN, XT_CP4_SA + XCHAL_CP4_SA_SIZE)
#define XT_CP6_SA ALIGNUP(XCHAL_CP6_SA_ALIGN, XT_CP5_SA + XCHAL_CP5_SA_SIZE)
#define XT_CP7_SA ALIGNUP(XCHAL_CP7_SA_ALIGN, XT_CP6_SA + XCHAL_CP6_SA_SIZE)
#define XT_CP_SA_SIZE ALIGNUP(16, XT_CP7_SA + XCHAL_CP7_SA_SIZE)
/* Offsets within the overall save area: */
/* (2 bytes) coprocessors active for this thread */
#define XT_CPENABLE 0
/* (2 bytes) coprocessors saved for this thread */
#define XT_CPSTORED 2
/* (2 bytes) coprocessor callee-saved regs stored for this thread */
#define XT_CP_CS_ST 4
/* (4 bytes) ptr to aligned save area */
#define XT_CP_ASA 8
/* Overall size allows for dynamic alignment: */
#define XT_CP_SIZE ALIGNUP(XCHAL_TOTAL_SA_ALIGN, 12 + XT_CP_SA_SIZE)
#else
#define XT_CP_SIZE 0
#endif
/*
* MACROS TO HANDLE ABI SPECIFICS OF FUNCTION ENTRY AND RETURN
*
* Convenient where the frame size requirements are the same for both ABIs.
* ENTRY(sz), RET(sz) are for framed functions (have locals or make calls).
* ENTRY0, RET0 are for frameless functions (no locals, no calls).
*
* where size = size of stack frame in bytes (must be >0 and aligned to 16).
* For framed functions the frame is created and the return address saved at
* base of frame (Call0 ABI) or as determined by hardware (Windowed ABI). For
* frameless functions, there is no frame and return address remains in
* a0.
*
* Note: Because CPP macros expand to a single line, macros requiring
* multi-line expansions are implemented as assembler macros.
*/
#ifdef __ASSEMBLER__
#ifdef __XTENSA_CALL0_ABI__
/* Call0 */
#define ENTRY(sz) entry1 sz
.macro entry1 size=0x10
addi sp, sp, -\size
s32i a0, sp, 0
.endm
#define ENTRY0
#define RET(sz) ret1 sz
.macro ret1 size=0x10
l32i a0, sp, 0
addi sp, sp, \size
ret
.endm
#define RET0 ret
#else
/* Windowed */
#define ENTRY(sz) entry sp, sz
#define ENTRY0 entry sp, 0x10
#define RET(sz) retw
#define RET0 retw
#endif /* __XTENSA_CALL0_ABI__ */
#endif /* __ASSEMBLER__ */
#endif /* XTENSA_CONTEXT_H */

View file

@ -0,0 +1,202 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* RTOS-SPECIFIC INFORMATION FOR XTENSA RTOS ASSEMBLER SOURCES
* (FreeRTOS Port)
*
* This header is the primary glue between generic Xtensa RTOS support
* sources and a specific RTOS port for Xtensa. It contains definitions
* and macros for use primarily by Xtensa assembly coded source files.
*
* Macros in this header map callouts from generic Xtensa files to specific
* RTOS functions. It may also be included in C source files.
*
* Xtensa RTOS ports support all RTOS-compatible configurations of the Xtensa
* architecture, using the Xtensa hardware abstraction layer (HAL) to deal
* with configuration specifics.
*
* Should be included by all Xtensa generic and RTOS port-specific sources.
*/
#ifndef XTENSA_RTOS_H
#define XTENSA_RTOS_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#else
#include <xtensa/config/core.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include <xtensa/simcall.h>
/*
* Convert FreeRTOSConfig definitions to XTENSA definitions.
* However these can still be overridden from the command line.
*/
#ifndef XT_SIMULATOR
#if CONFIG_SIMULATOR_XTENSA
#define XT_SIMULATOR 1 /* Simulator mode */
#endif
#endif
#ifndef XT_BOARD
#if CONFIG_BOARD_XTENSA
#define XT_BOARD 1 /* Board mode */
#endif
#endif
#ifndef XT_TIMER_INDEX
#if defined configXT_TIMER_INDEX
/* Index of hardware timer to be used */
#define XT_TIMER_INDEX configXT_TIMER_INDEX
#endif
#endif
#ifndef XT_INTEXC_HOOKS
#if configXT_INTEXC_HOOKS
#define XT_INTEXC_HOOKS 1 /* Enables exception hooks */
#endif
#endif
#if (!XT_SIMULATOR) && (!XT_BOARD)
#error Either XT_SIMULATOR or XT_BOARD must be defined.
#endif
/*
* Name of RTOS (for messages).
*/
#define XT_RTOS_NAME Zephyr
/*
* Define for enabling RTOS specific code. Enable only one of below lines.
*/
#define XT_RTOS_IS_ZEPHYR_OS 1
#undef XT_RTOS_IS_FREE_RTOS
/*
* Check some Xtensa configuration requirements and report error if not met.
* Error messages can be customize to the RTOS port.
*/
#if !XCHAL_HAVE_XEA2
#error "Zephyr/Xtensa requires XEA2 (exception architecture 2)."
#endif
/*
* RTOS CALLOUT MACROS MAPPED TO RTOS PORT-SPECIFIC FUNCTIONS.
*
* Define callout macros used in generic Xtensa code to interact with the RTOS.
* The macros are simply the function names for use in calls from assembler
* code.
* Some of these functions may call back to generic functions in
* xtensa_context.h .
*/
/*
* Inform RTOS of entry into an interrupt handler that will affect it.
* Allows RTOS to manage switch to any system stack and count nesting level.
* Called after minimal context has been saved, with interrupts disabled.
* RTOS port can call0 _xt_context_save to save the rest of the context.
* May only be called from assembly code by the 'call0' instruction.
*/
#define XT_RTOS_INT_ENTER _zxt_int_enter
/*
* Inform RTOS of completion of an interrupt handler, and give control to
* RTOS to perform thread/task scheduling, switch back from any system stack
* and restore the context, and return to the exit dispatcher saved in the
* stack frame at XT_STK_EXIT. RTOS port can call0 _xt_context_restore
* to save the context saved in XT_RTOS_INT_ENTER via _xt_context_save,
* leaving only a minimal part of the context to be restored by the exit
* dispatcher. This function does not return to the place it was called from.
* May only be called from assembly code by the 'call0' instruction.
*/
#define XT_RTOS_INT_EXIT _zxt_int_exit
/*
* Inform RTOS of the occurrence of a tick timer interrupt.
* If RTOS has no tick timer, leave XT_RTOS_TIMER_INT undefined.
* May be coded in or called from C or assembly, per ABI conventions.
* RTOS may optionally define XT_TICK_PER_SEC in its own way (eg. macro).
*/
#define XT_RTOS_TIMER_INT _zxt_timer_int
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
/*
* Return in a15 the base address of the co-processor state save area for the
* thread that triggered a co-processor exception, or 0 if no thread was
* running. The state save area is structured as defined in xtensa_context.h
* and has size XT_CP_SIZE. Co-processor instructions should only be used in
* thread code, never in interrupt handlers or the RTOS kernel. May only be
* called from assembly code and by the 'call0' instruction. A result of 0
* indicates an unrecoverable error.
*
* The implementation may use only a2-4, a15 (all other regs must be
* preserved).
*/
#define XT_RTOS_CP_STATE _zxt_task_coproc_state
/*
* HOOKS TO DYNAMICALLY INSTALL INTERRUPT AND EXCEPTION HANDLERS PER LEVEL.
*
* This Xtensa RTOS port provides hooks for dynamically installing exception
* and interrupt handlers to facilitate automated testing where each test case
* can install its own handler for user exceptions and each interrupt priority
* (level). This consists of an array of function pointers indexed by interrupt
* priority, with index 0 being the user exception handler hook. Each entry in
* the array is initially 0, and may be replaced by a function pointer of type
* XT_INTEXC_HOOK. A handler may be uninstalled by installing 0.
*
* The handler for low and medium priority obeys ABI conventions so may be
* coded in C. For the exception handler, the cause is the contents of the
* EXCCAUSE reg, and the result is -1 if handled, else the cause (still needs
* handling). For interrupt handlers, the cause is a mask of pending enabled
* interrupts at that level, and the result is the same mask with the bits for
* the handled interrupts cleared (those not cleared still need handling). This
* allows a test case to either pre-handle or override the default handling for
* the exception or interrupt level (see xtensa_vectors.S).
*
* High priority handlers (including NMI) must be coded in assembly, are always
* called by 'call0' regardless of ABI, must preserve all registers except a0,
* and must not use or modify the interrupted stack. The hook argument 'cause'
* is not passed and the result is ignored, so as not to burden the caller
* with saving and restoring a2 (it assumes only one interrupt per level - see
* the discussion in high priority interrupts in xtensa_vectors.S). The handler
* therefore should be coded to prototype 'void h(void)' even though it plugs
* into an array of handlers of prototype 'unsigned h(unsigned)'.
*
* To enable interrupt/exception hooks, compile the RTOS with
* '-DXT_INTEXC_HOOKS'.
*/
#define XT_INTEXC_HOOK_NUM (1 + XCHAL_NUM_INTLEVELS + XCHAL_HAVE_NMI)
#ifndef __ASSEMBLER__
typedef unsigned int (*XT_INTEXC_HOOK)(unsigned int cause);
extern volatile XT_INTEXC_HOOK _xt_intexc_hooks[XT_INTEXC_HOOK_NUM];
#endif
/*
* CONVENIENCE INCLUSIONS.
*
* Ensures RTOS specific files need only include this one Xtensa-generic
* header. These headers are included last so they can use the RTOS
* definitions above.
*/
#include "xtensa_context.h"
#ifdef XT_RTOS_TIMER_INT
#include "xtensa_timer.h"
#endif
#endif /* XTENSA_RTOS_H */

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/*
* XTENSA INFORMATION FOR RTOS TICK TIMER AND CLOCK FREQUENCY
*
* This header contains definitions and macros for use primarily by Xtensa
* RTOS assembly coded source files. It includes and uses the Xtensa hardware
* abstraction layer (HAL) to deal with config specifics. It may also be
* included in C source files.
*
* User may edit to modify timer selection and to specify clock frequency and
* tick duration to match timer interrupt to the real-time tick duration.
*
* If the RTOS has no timer interrupt, then there is no tick timer and the
* clock frequency is irrelevant, so all of these macros are left undefined
* and the Xtensa core configuration need not have a timer.
*/
#ifndef XTENSA_TIMER_H
#define XTENSA_TIMER_H
#ifdef __ASSEMBLER__
#include <xtensa/coreasm.h>
#endif
#include <xtensa/corebits.h>
#include <xtensa/config/system.h>
#include "xtensa_rtos.h" /* in case this wasn't included directly */
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
/*
* Select timer to use for periodic tick, and determine its interrupt number
* and priority. User may specify a timer by defining XT_TIMER_INDEX with -D,
* in which case its validity is checked (it must exist in this core and must
* not be on a high priority interrupt - an error will be reported in invalid).
* Otherwise select the first low or medium priority interrupt timer available.
*/
#if XCHAL_NUM_TIMERS == 0
#error "This Xtensa configuration is unsupported, it has no timers."
#endif /* XCHAL_NUM_TIMERS */
#ifndef XT_TIMER_INDEX
#if XCHAL_TIMER3_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER3_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 3
#endif
#endif
#if XCHAL_TIMER2_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER2_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 2
#endif
#endif
#if XCHAL_TIMER1_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER1_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 1
#endif
#endif
#if XCHAL_TIMER0_INTERRUPT != XTHAL_TIMER_UNCONFIGURED
#if XCHAL_INT_LEVEL(XCHAL_TIMER0_INTERRUPT) <= XCHAL_EXCM_LEVEL
#undef XT_TIMER_INDEX
#define XT_TIMER_INDEX 0
#endif
#endif
#endif
#ifndef XT_TIMER_INDEX
#error "There is no suitable timer in this Xtensa configuration."
#endif
#define XT_CCOMPARE ((CCOMPARE) + (XT_TIMER_INDEX))
#define XT_TIMER_INTNUM XCHAL_TIMER_INTERRUPT(XT_TIMER_INDEX)
#if XT_TIMER_INTNUM == XTHAL_TIMER_UNCONFIGURED
#error "The timer selected by XT_TIMER_INDEX does not exist in this core."
#endif
#else /* Case of an external timer which is not emulated by internal timer */
#define XT_TIMER_INTNUM CONFIG_XTENSA_TIMER_IRQ
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
#if CONFIG_XTENSA_INTERNAL_TIMER
#define XT_TIMER_INTPRI XCHAL_INT_LEVEL(XT_TIMER_INTNUM)
#else
#define XT_TIMER_INTPRI CONFIG_XTENSA_TIMER_IRQ_PRIORITY
#endif /* CONFIG_XTENSA_INTERNAL_TIMER */
#if XT_TIMER_INTPRI > XCHAL_EXCM_LEVEL
#error "The timer interrupt cannot be high priority (use medium or low)."
#endif
#define XT_TIMER_INTEN (1 << (XT_TIMER_INTNUM))
/*
* Set processor clock frequency, used to determine clock divisor for timer
* tick. User should BE SURE TO ADJUST THIS for the Xtensa platform being
* used. If using a supported board via the board-independent API defined in
* xtbsp.h, this may be left undefined and frequency and tick divisor will be
* computed and cached during run-time initialization.
*
* NOTE ON SIMULATOR: Under the Xtensa instruction set simulator, the frequency
* can only be estimated because it depends on the speed of the host and the
* version of the simulator. Also because it runs much slower than hardware,
* it is not possible to achieve real-time performance for most applications
* under the simulator. A frequency too low does not allow enough time between
* timer interrupts, starving threads. To obtain a more convenient but
* non-real-time tick duration on the simulator, compile with xt-xcc option
* "-DXT_SIMULATOR". Adjust this frequency to taste (it's not real-time
* anyway!).
*/
#if defined(XT_SIMULATOR) && !defined(XT_CLOCK_FREQ)
#define XT_CLOCK_FREQ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC
#endif
#if !defined(XT_CLOCK_FREQ) && !defined(XT_BOARD)
#error "XT_CLOCK_FREQ must be defined for the target platform."
#endif
/*
* Default number of timer "ticks" per second (default 100 for 10ms tick).
* RTOS may define this in its own way (if applicable) in xtensa_rtos.h.
* User may redefine this to an optimal value for the application, either by
* editing this here or in xtensa_rtos.h, or compiling with xt-xcc option
* "-DXT_TICK_PER_SEC=<value>" where <value> is a suitable number.
*/
#ifndef XT_TICK_PER_SEC
#define XT_TICK_PER_SEC CONFIG_SYS_CLOCK_TICKS_PER_SEC
#endif
/*
* Derivation of clock divisor for timer tick and interrupt (one per tick).
*/
#ifdef XT_CLOCK_FREQ
#define XT_TICK_DIVISOR (XT_CLOCK_FREQ / XT_TICK_PER_SEC)
#endif
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
#ifndef __ASSEMBLER__
extern unsigned int _xt_tick_divisor;
extern void _xt_tick_divisor_init(void);
#endif
#endif // Internal/External timer
#endif /* XTENSA_TIMER_H */

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if D_108mini
config IRQ_OFFLOAD_INTNUM
default 7
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,606 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram1_0_seg : org = 0x3FFC0000, len = 0x20000
dram0_0_seg : org = 0x3FFE0000, len = 0x20000
iram0_0_seg : org = 0x40000000, len = 0x178
iram0_1_seg : org = 0x40000178, len = 0x8
iram0_2_seg : org = 0x40000180, len = 0x38
iram0_3_seg : org = 0x400001B8, len = 0x8
iram0_4_seg : org = 0x400001C0, len = 0x38
iram0_5_seg : org = 0x400001F8, len = 0x8
iram0_6_seg : org = 0x40000200, len = 0x38
iram0_7_seg : org = 0x40000238, len = 0x8
iram0_8_seg : org = 0x40000240, len = 0x38
iram0_9_seg : org = 0x40000278, len = 0x8
iram0_10_seg : org = 0x40000280, len = 0x38
iram0_11_seg : org = 0x400002B8, len = 0x8
iram0_12_seg : org = 0x400002C0, len = 0x38
iram0_13_seg : org = 0x400002F8, len = 0x8
iram0_14_seg : org = 0x40000300, len = 0x38
iram0_15_seg : org = 0x40000338, len = 0x8
iram0_16_seg : org = 0x40000340, len = 0x38
iram0_17_seg : org = 0x40000378, len = 0x48
iram0_18_seg : org = 0x400003C0, len = 0x40
iram0_19_seg : org = 0x40000400, len = 0x1FC00
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0xFFFD00
sram0_seg : org = 0x60000000, len = 0x4000000
}
PHDRS
{
dram1_0_phdr PT_LOAD;
dram1_0_bss_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
iram0_1_phdr PT_LOAD;
iram0_2_phdr PT_LOAD;
iram0_3_phdr PT_LOAD;
iram0_4_phdr PT_LOAD;
iram0_5_phdr PT_LOAD;
iram0_6_phdr PT_LOAD;
iram0_7_phdr PT_LOAD;
iram0_8_phdr PT_LOAD;
iram0_9_phdr PT_LOAD;
iram0_10_phdr PT_LOAD;
iram0_11_phdr PT_LOAD;
iram0_12_phdr PT_LOAD;
iram0_13_phdr PT_LOAD;
iram0_14_phdr PT_LOAD;
iram0_15_phdr PT_LOAD;
iram0_16_phdr PT_LOAD;
iram0_17_phdr PT_LOAD;
iram0_18_phdr PT_LOAD;
iram0_19_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram0_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram1_start = 0x3ffc0000;
_memmap_mem_dram1_end = 0x3ffe0000;
_memmap_mem_dram0_start = 0x3ffe0000;
_memmap_mem_dram0_end = 0x40000000;
_memmap_mem_iram0_start = 0x40000000;
_memmap_mem_iram0_end = 0x40020000;
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_dram1_0_start = 0x3ffc0000;
_memmap_seg_dram1_0_max = 0x3ffe0000;
_memmap_seg_dram0_0_start = 0x3ffe0000;
_memmap_seg_dram0_0_max = 0x40000000;
_memmap_seg_iram0_0_start = 0x40000000;
_memmap_seg_iram0_0_max = 0x40000178;
_memmap_seg_iram0_1_start = 0x40000178;
_memmap_seg_iram0_1_max = 0x40000180;
_memmap_seg_iram0_2_start = 0x40000180;
_memmap_seg_iram0_2_max = 0x400001b8;
_memmap_seg_iram0_3_start = 0x400001b8;
_memmap_seg_iram0_3_max = 0x400001c0;
_memmap_seg_iram0_4_start = 0x400001c0;
_memmap_seg_iram0_4_max = 0x400001f8;
_memmap_seg_iram0_5_start = 0x400001f8;
_memmap_seg_iram0_5_max = 0x40000200;
_memmap_seg_iram0_6_start = 0x40000200;
_memmap_seg_iram0_6_max = 0x40000238;
_memmap_seg_iram0_7_start = 0x40000238;
_memmap_seg_iram0_7_max = 0x40000240;
_memmap_seg_iram0_8_start = 0x40000240;
_memmap_seg_iram0_8_max = 0x40000278;
_memmap_seg_iram0_9_start = 0x40000278;
_memmap_seg_iram0_9_max = 0x40000280;
_memmap_seg_iram0_10_start = 0x40000280;
_memmap_seg_iram0_10_max = 0x400002b8;
_memmap_seg_iram0_11_start = 0x400002b8;
_memmap_seg_iram0_11_max = 0x400002c0;
_memmap_seg_iram0_12_start = 0x400002c0;
_memmap_seg_iram0_12_max = 0x400002f8;
_memmap_seg_iram0_13_start = 0x400002f8;
_memmap_seg_iram0_13_max = 0x40000300;
_memmap_seg_iram0_14_start = 0x40000300;
_memmap_seg_iram0_14_max = 0x40000338;
_memmap_seg_iram0_15_start = 0x40000338;
_memmap_seg_iram0_15_max = 0x40000340;
_memmap_seg_iram0_16_start = 0x40000340;
_memmap_seg_iram0_16_max = 0x40000378;
_memmap_seg_iram0_17_start = 0x40000378;
_memmap_seg_iram0_17_max = 0x400003c0;
_memmap_seg_iram0_18_start = 0x400003c0;
_memmap_seg_iram0_18_max = 0x40000400;
_memmap_seg_iram0_19_start = 0x40000400;
_memmap_seg_iram0_19_max = 0x40020000;
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x40000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001110;
_memmap_cacheattr_wt_base = 0x00001110;
_memmap_cacheattr_bp_base = 0x00002220;
_memmap_cacheattr_unused_mask = 0xFFFF000F;
_memmap_cacheattr_wb_trapnull = 0x2222111F;
_memmap_cacheattr_wba_trapnull = 0x2222111F;
_memmap_cacheattr_wbna_trapnull = 0x2222111F;
_memmap_cacheattr_wt_trapnull = 0x2222111F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF111F;
_memmap_cacheattr_wt_strict = 0xFFFF111F;
_memmap_cacheattr_bp_strict = 0xFFFF222F;
_memmap_cacheattr_wb_allvalid = 0x22221112;
_memmap_cacheattr_wt_allvalid = 0x22221112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram1.rodata : ALIGN(4)
{
_dram1_rodata_start = ABSOLUTE(.);
*(.dram1.rodata)
_dram1_rodata_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.literal : ALIGN(4)
{
_dram1_literal_start = ABSOLUTE(.);
*(.dram1.literal)
_dram1_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.data : ALIGN(4)
{
_dram1_data_start = ABSOLUTE(.);
*(.dram1.data)
_dram1_data_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram1_bss_start = ABSOLUTE(.);
*(.dram1.bss)
. = ALIGN (8);
_dram1_bss_end = ABSOLUTE(.);
_memmap_seg_dram1_0_end = ALIGN(0x8);
} >dram1_0_seg :dram1_0_bss_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_1_end = ALIGN(0x8);
} >iram0_1_seg :iram0_1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_2_end = ALIGN(0x8);
} >iram0_2_seg :iram0_2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_3_end = ALIGN(0x8);
} >iram0_3_seg :iram0_3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_4_end = ALIGN(0x8);
} >iram0_4_seg :iram0_4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_5_end = ALIGN(0x8);
} >iram0_5_seg :iram0_5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_6_end = ALIGN(0x8);
} >iram0_6_seg :iram0_6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_7_end = ALIGN(0x8);
} >iram0_7_seg :iram0_7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_8_end = ALIGN(0x8);
} >iram0_8_seg :iram0_8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_9_end = ALIGN(0x8);
} >iram0_9_seg :iram0_9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_10_end = ALIGN(0x8);
} >iram0_10_seg :iram0_10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_11_end = ALIGN(0x8);
} >iram0_11_seg :iram0_11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_12_end = ALIGN(0x8);
} >iram0_12_seg :iram0_12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_13_end = ALIGN(0x8);
} >iram0_13_seg :iram0_13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_14_end = ALIGN(0x8);
} >iram0_14_seg :iram0_14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_15_end = ALIGN(0x8);
} >iram0_15_seg :iram0_15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_16_end = ALIGN(0x8);
} >iram0_16_seg :iram0_16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_17_end = ALIGN(0x8);
} >iram0_17_seg :iram0_17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_18_end = ALIGN(0x8);
} >iram0_18_seg :iram0_18_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_19_end = ALIGN(0x8);
} >iram0_19_seg :iram0_19_phdr
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram1_bss_start)
LONG(_dram1_bss_end)
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram0_seg :sram0_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram0_seg :sram0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_bss_phdr
__stack = 0x64000000;
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram0_seg :sram0_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if D_212GP
config IRQ_OFFLOAD_INTNUM
default 7
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,612 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dport0_0_seg : org = 0x3FFC0000, len = 0x20000
dram0_0_seg : org = 0x3FFE0000, len = 0x20000
iram0_0_seg : org = 0x40000000, len = 0x20000
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0xFFFD00
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x8
sram2_seg : org = 0x60000180, len = 0x38
sram3_seg : org = 0x600001B8, len = 0x8
sram4_seg : org = 0x600001C0, len = 0x38
sram5_seg : org = 0x600001F8, len = 0x8
sram6_seg : org = 0x60000200, len = 0x38
sram7_seg : org = 0x60000238, len = 0x8
sram8_seg : org = 0x60000240, len = 0x38
sram9_seg : org = 0x60000278, len = 0x8
sram10_seg : org = 0x60000280, len = 0x38
sram11_seg : org = 0x600002B8, len = 0x8
sram12_seg : org = 0x600002C0, len = 0x38
sram13_seg : org = 0x600002F8, len = 0x8
sram14_seg : org = 0x60000300, len = 0x38
sram15_seg : org = 0x60000338, len = 0x8
sram16_seg : org = 0x60000340, len = 0x38
sram17_seg : org = 0x60000378, len = 0x48
sram18_seg : org = 0x600003C0, len = 0x40
sram19_seg : org = 0x60000400, len = 0x3FFFC00
}
PHDRS
{
dport0_0_phdr PT_LOAD;
dport0_0_bss_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram14_phdr PT_LOAD;
sram15_phdr PT_LOAD;
sram16_phdr PT_LOAD;
sram17_phdr PT_LOAD;
sram18_phdr PT_LOAD;
sram19_phdr PT_LOAD;
sram19_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dport0_start = 0x3ffc0000;
_memmap_mem_dport0_end = 0x3ffe0000;
_memmap_mem_dram0_start = 0x3ffe0000;
_memmap_mem_dram0_end = 0x40000000;
_memmap_mem_iram0_start = 0x40000000;
_memmap_mem_iram0_end = 0x40020000;
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_dport0_0_start = 0x3ffc0000;
_memmap_seg_dport0_0_max = 0x3ffe0000;
_memmap_seg_dram0_0_start = 0x3ffe0000;
_memmap_seg_dram0_0_max = 0x40000000;
_memmap_seg_iram0_0_start = 0x40000000;
_memmap_seg_iram0_0_max = 0x40020000;
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x60000180;
_memmap_seg_sram2_start = 0x60000180;
_memmap_seg_sram2_max = 0x600001b8;
_memmap_seg_sram3_start = 0x600001b8;
_memmap_seg_sram3_max = 0x600001c0;
_memmap_seg_sram4_start = 0x600001c0;
_memmap_seg_sram4_max = 0x600001f8;
_memmap_seg_sram5_start = 0x600001f8;
_memmap_seg_sram5_max = 0x60000200;
_memmap_seg_sram6_start = 0x60000200;
_memmap_seg_sram6_max = 0x60000238;
_memmap_seg_sram7_start = 0x60000238;
_memmap_seg_sram7_max = 0x60000240;
_memmap_seg_sram8_start = 0x60000240;
_memmap_seg_sram8_max = 0x60000278;
_memmap_seg_sram9_start = 0x60000278;
_memmap_seg_sram9_max = 0x60000280;
_memmap_seg_sram10_start = 0x60000280;
_memmap_seg_sram10_max = 0x600002b8;
_memmap_seg_sram11_start = 0x600002b8;
_memmap_seg_sram11_max = 0x600002c0;
_memmap_seg_sram12_start = 0x600002c0;
_memmap_seg_sram12_max = 0x600002f8;
_memmap_seg_sram13_start = 0x600002f8;
_memmap_seg_sram13_max = 0x60000300;
_memmap_seg_sram14_start = 0x60000300;
_memmap_seg_sram14_max = 0x60000338;
_memmap_seg_sram15_start = 0x60000338;
_memmap_seg_sram15_max = 0x60000340;
_memmap_seg_sram16_start = 0x60000340;
_memmap_seg_sram16_max = 0x60000378;
_memmap_seg_sram17_start = 0x60000378;
_memmap_seg_sram17_max = 0x600003c0;
_memmap_seg_sram18_start = 0x600003c0;
_memmap_seg_sram18_max = 0x60000400;
_memmap_seg_sram19_start = 0x60000400;
_memmap_seg_sram19_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00004440;
_memmap_cacheattr_wt_base = 0x00001110;
_memmap_cacheattr_bp_base = 0x00002220;
_memmap_cacheattr_unused_mask = 0xFFFF000F;
_memmap_cacheattr_wb_trapnull = 0x2222444F;
_memmap_cacheattr_wba_trapnull = 0x2222444F;
_memmap_cacheattr_wbna_trapnull = 0x2222555F;
_memmap_cacheattr_wt_trapnull = 0x2222111F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF444F;
_memmap_cacheattr_wt_strict = 0xFFFF111F;
_memmap_cacheattr_bp_strict = 0xFFFF222F;
_memmap_cacheattr_wb_allvalid = 0x22224442;
_memmap_cacheattr_wt_allvalid = 0x22221112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dport0.rodata : ALIGN(4)
{
_dport0_rodata_start = ABSOLUTE(.);
*(.dport0.rodata)
*(.dport.rodata)
_dport0_rodata_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.dport0.literal : ALIGN(4)
{
_dport0_literal_start = ABSOLUTE(.);
*(.dport0.literal)
*(.dport.literal)
_dport0_literal_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.dport0.data : ALIGN(4)
{
_dport0_data_start = ABSOLUTE(.);
*(.dport0.data)
*(.dport.data)
_dport0_data_end = ABSOLUTE(.);
} >dport0_0_seg :dport0_0_phdr
.dport0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dport0_bss_start = ABSOLUTE(.);
*(.dport0.bss)
. = ALIGN (8);
_dport0_bss_end = ABSOLUTE(.);
_memmap_seg_dport0_0_end = ALIGN(0x8);
} >dport0_0_seg :dport0_0_bss_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
*(.dram.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
*(.dram.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
*(.dram.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram14_end = ALIGN(0x8);
} >sram14_seg :sram14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram15_end = ALIGN(0x8);
} >sram15_seg :sram15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram16_end = ALIGN(0x8);
} >sram16_seg :sram16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram17_end = ALIGN(0x8);
} >sram17_seg :sram17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram18_end = ALIGN(0x8);
} >sram18_seg :sram18_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dport0_bss_start)
LONG(_dport0_bss_end)
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram19_seg :sram19_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram19_seg :sram19_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram19_end = ALIGN(0x8);
} >sram19_seg :sram19_bss_phdr
__stack = 0x64000000;
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram19_seg :sram19_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if D_233L
config IRQ_OFFLOAD_INTNUM
default 7
endif

View file

@ -0,0 +1,3 @@
obj- = soc.o
QEMU_CPU_TYPE_xtensa = dc233c

View file

@ -0,0 +1,513 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
sram1_seg : org = 0x00002000, len = 0x178
sram2_seg : org = 0x00002178, len = 0x8
sram3_seg : org = 0x00002180, len = 0x38
sram4_seg : org = 0x000021B8, len = 0x8
sram5_seg : org = 0x000021C0, len = 0x38
sram6_seg : org = 0x000021F8, len = 0x8
sram7_seg : org = 0x00002200, len = 0x38
sram8_seg : org = 0x00002238, len = 0x8
sram9_seg : org = 0x00002240, len = 0x38
sram10_seg : org = 0x00002278, len = 0x8
sram11_seg : org = 0x00002280, len = 0x38
sram12_seg : org = 0x000022B8, len = 0x8
sram13_seg : org = 0x000022C0, len = 0x38
sram14_seg : org = 0x000022F8, len = 0x8
sram15_seg : org = 0x00002300, len = 0x38
sram16_seg : org = 0x00002338, len = 0x8
sram17_seg : org = 0x00002340, len = 0x38
sram18_seg : org = 0x00002378, len = 0x48
sram19_seg : org = 0x000023C0, len = 0x140
sram20_seg : org = 0x00002500, len = 0x3FFDB00
srom0_seg : org = 0xFE000000, len = 0x300
srom1_seg : org = 0xFE000300, len = 0xFFFD00
}
PHDRS
{
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram14_phdr PT_LOAD;
sram15_phdr PT_LOAD;
sram16_phdr PT_LOAD;
sram17_phdr PT_LOAD;
sram18_phdr PT_LOAD;
sram19_phdr PT_LOAD;
sram20_phdr PT_LOAD;
sram20_bss_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_sram_start = 0x4;
_memmap_mem_sram_end = 0x4000000;
_memmap_mem_srom_start = 0xfe000000;
_memmap_mem_srom_end = 0xff000000;
/* Memory segment boundary addresses: */
_memmap_seg_sram1_start = 0x2000;
_memmap_seg_sram1_max = 0x2178;
_memmap_seg_sram2_start = 0x2178;
_memmap_seg_sram2_max = 0x2180;
_memmap_seg_sram3_start = 0x2180;
_memmap_seg_sram3_max = 0x21b8;
_memmap_seg_sram4_start = 0x21b8;
_memmap_seg_sram4_max = 0x21c0;
_memmap_seg_sram5_start = 0x21c0;
_memmap_seg_sram5_max = 0x21f8;
_memmap_seg_sram6_start = 0x21f8;
_memmap_seg_sram6_max = 0x2200;
_memmap_seg_sram7_start = 0x2200;
_memmap_seg_sram7_max = 0x2238;
_memmap_seg_sram8_start = 0x2238;
_memmap_seg_sram8_max = 0x2240;
_memmap_seg_sram9_start = 0x2240;
_memmap_seg_sram9_max = 0x2278;
_memmap_seg_sram10_start = 0x2278;
_memmap_seg_sram10_max = 0x2280;
_memmap_seg_sram11_start = 0x2280;
_memmap_seg_sram11_max = 0x22b8;
_memmap_seg_sram12_start = 0x22b8;
_memmap_seg_sram12_max = 0x22c0;
_memmap_seg_sram13_start = 0x22c0;
_memmap_seg_sram13_max = 0x22f8;
_memmap_seg_sram14_start = 0x22f8;
_memmap_seg_sram14_max = 0x2300;
_memmap_seg_sram15_start = 0x2300;
_memmap_seg_sram15_max = 0x2338;
_memmap_seg_sram16_start = 0x2338;
_memmap_seg_sram16_max = 0x2340;
_memmap_seg_sram17_start = 0x2340;
_memmap_seg_sram17_max = 0x2378;
_memmap_seg_sram18_start = 0x2378;
_memmap_seg_sram18_max = 0x23c0;
_memmap_seg_sram19_start = 0x23c0;
_memmap_seg_sram19_max = 0x2500;
_memmap_seg_sram20_start = 0x2500;
_memmap_seg_sram20_max = 0x4000000;
_memmap_seg_srom0_start = 0xfe000000;
_memmap_seg_srom0_max = 0xfe000300;
_memmap_seg_srom1_start = 0xfe000300;
_memmap_seg_srom1_max = 0xff000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x2000);
PROVIDE(_memmap_reset_vector = 0xfe000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x70000007;
_memmap_cacheattr_wt_base = 0xB000000B;
_memmap_cacheattr_bp_base = 0x30000003;
_memmap_cacheattr_unused_mask = 0x0FFFFFF0;
_memmap_cacheattr_wb_trapnull = 0x73333337;
_memmap_cacheattr_wba_trapnull = 0x73333337;
_memmap_cacheattr_wbna_trapnull = 0x73333337;
_memmap_cacheattr_wt_trapnull = 0xB333333B;
_memmap_cacheattr_bp_trapnull = 0x33333333;
_memmap_cacheattr_wb_strict = 0x7CCCCCC7;
_memmap_cacheattr_wt_strict = 0xBCCCCCCB;
_memmap_cacheattr_bp_strict = 0x3CCCCCC3;
_memmap_cacheattr_wb_allvalid = 0x73333337;
_memmap_cacheattr_wt_allvalid = 0xB333333B;
_memmap_cacheattr_bp_allvalid = 0x33333333;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram14_end = ALIGN(0x8);
} >sram14_seg :sram14_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram15_end = ALIGN(0x8);
} >sram15_seg :sram15_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram16_end = ALIGN(0x8);
} >sram16_seg :sram16_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram17_end = ALIGN(0x8);
} >sram17_seg :sram17_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram18_end = ALIGN(0x8);
} >sram18_seg :sram18_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram19_end = ALIGN(0x8);
} >sram19_seg :sram19_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram20_seg :sram20_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram20_seg :sram20_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram20_seg :sram20_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram20_seg :sram20_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram20_seg :sram20_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram20_seg :sram20_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram20_seg :sram20_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram20_end = ALIGN(0x8);
} >sram20_seg :sram20_bss_phdr
__stack = 0x4000000;
_heap_sentry = 0x4000000;
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram20_seg :sram20_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,62 @@
# Kconfig - XTENSA supported cores
#
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
config cpsw4irq
bool "cpsw4irq core"
config sample_controller
bool "sample_controller core"
config sample_flix
bool "sample_flix core"
config hifi3_bd5
bool "hifi3_bd5 core"
config hifi3_bd5_call0
bool "hifi3_bd5_call0 (hifi3_bd5 core with call0 ABI and 3 additional SW IRQs)"
config tie_dev2
bool "tie_dev2 core"
config XRC_FUSION_AON_ALL_LM
bool "XRC_FUSION_AON_ALL_LM core"
config tie_dev1
bool "tie_dev1 core"
config sample_config
bool "sample_config core"
config hifiep_bd5
bool "hifiep_bd5 core"
config D_108mini
bool "D_108mini core"
config D_212GP
bool "D_212GP core"
config D_233L
bool "D_233L core"
config hifi_mini
bool "hifi_mini core"
config hifi_mini_4swIrq
bool "hifi_mini_4swIrq (hifi_mini core with 4 additional SW IRQs)"
config hifi2_std
bool "hifi2_std core"
config XRC_D2PM
bool "XRC_D2PM core"
config XRC_D2PM_5swIrq
bool "XRC_D2PM_5swIrq (XRC_D2PM core with 4 additional SW IRQs)"
config hifi4_bd7
bool "hifi4_bd7 core"

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if XRC_D2PM
config IRQ_OFFLOAD_INTNUM
default 11
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,616 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
srom0_seg : org = 0x40000000, len = 0x2E0
srom1_seg : org = 0x400002E0, len = 0xFFFD20
dram0_0_seg : org = 0x5FFA0000, len = 0x20000
dram1_0_seg : org = 0x5FFC0000, len = 0x20000
iram0_0_seg : org = 0x5FFE0000, len = 0x20000
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x4
sram2_seg : org = 0x6000017C, len = 0x1C
sram3_seg : org = 0x60000198, len = 0x4
sram4_seg : org = 0x6000019C, len = 0x1C
sram5_seg : org = 0x600001B8, len = 0x4
sram6_seg : org = 0x600001BC, len = 0x1C
sram7_seg : org = 0x600001D8, len = 0x4
sram8_seg : org = 0x600001DC, len = 0x1C
sram9_seg : org = 0x600001F8, len = 0x4
sram10_seg : org = 0x600001FC, len = 0x1C
sram11_seg : org = 0x60000218, len = 0x4
sram12_seg : org = 0x6000021C, len = 0x1C
sram13_seg : org = 0x60000238, len = 0x4
sram14_seg : org = 0x6000023C, len = 0x1C
sram15_seg : org = 0x60000258, len = 0x4
sram16_seg : org = 0x6000025C, len = 0x1C
sram17_seg : org = 0x60000278, len = 0x4
sram18_seg : org = 0x6000027C, len = 0x1C
sram19_seg : org = 0x60000298, len = 0x3FFFD68
}
PHDRS
{
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
dram1_0_phdr PT_LOAD;
dram1_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram14_phdr PT_LOAD;
sram15_phdr PT_LOAD;
sram16_phdr PT_LOAD;
sram17_phdr PT_LOAD;
sram18_phdr PT_LOAD;
sram19_phdr PT_LOAD;
sram19_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_srom_start = 0x40000000;
_memmap_mem_srom_end = 0x41000000;
_memmap_mem_dram0_start = 0x5ffa0000;
_memmap_mem_dram0_end = 0x5ffc0000;
_memmap_mem_dram1_start = 0x5ffc0000;
_memmap_mem_dram1_end = 0x5ffe0000;
_memmap_mem_iram0_start = 0x5ffe0000;
_memmap_mem_iram0_end = 0x60000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_srom0_start = 0x40000000;
_memmap_seg_srom0_max = 0x400002e0;
_memmap_seg_srom1_start = 0x400002e0;
_memmap_seg_srom1_max = 0x41000000;
_memmap_seg_dram0_0_start = 0x5ffa0000;
_memmap_seg_dram0_0_max = 0x5ffc0000;
_memmap_seg_dram1_0_start = 0x5ffc0000;
_memmap_seg_dram1_0_max = 0x5ffe0000;
_memmap_seg_iram0_0_start = 0x5ffe0000;
_memmap_seg_iram0_0_max = 0x60000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x6000017c;
_memmap_seg_sram2_start = 0x6000017c;
_memmap_seg_sram2_max = 0x60000198;
_memmap_seg_sram3_start = 0x60000198;
_memmap_seg_sram3_max = 0x6000019c;
_memmap_seg_sram4_start = 0x6000019c;
_memmap_seg_sram4_max = 0x600001b8;
_memmap_seg_sram5_start = 0x600001b8;
_memmap_seg_sram5_max = 0x600001bc;
_memmap_seg_sram6_start = 0x600001bc;
_memmap_seg_sram6_max = 0x600001d8;
_memmap_seg_sram7_start = 0x600001d8;
_memmap_seg_sram7_max = 0x600001dc;
_memmap_seg_sram8_start = 0x600001dc;
_memmap_seg_sram8_max = 0x600001f8;
_memmap_seg_sram9_start = 0x600001f8;
_memmap_seg_sram9_max = 0x600001fc;
_memmap_seg_sram10_start = 0x600001fc;
_memmap_seg_sram10_max = 0x60000218;
_memmap_seg_sram11_start = 0x60000218;
_memmap_seg_sram11_max = 0x6000021c;
_memmap_seg_sram12_start = 0x6000021c;
_memmap_seg_sram12_max = 0x60000238;
_memmap_seg_sram13_start = 0x60000238;
_memmap_seg_sram13_max = 0x6000023c;
_memmap_seg_sram14_start = 0x6000023c;
_memmap_seg_sram14_max = 0x60000258;
_memmap_seg_sram15_start = 0x60000258;
_memmap_seg_sram15_max = 0x6000025c;
_memmap_seg_sram16_start = 0x6000025c;
_memmap_seg_sram16_max = 0x60000278;
_memmap_seg_sram17_start = 0x60000278;
_memmap_seg_sram17_max = 0x6000027c;
_memmap_seg_sram18_start = 0x6000027c;
_memmap_seg_sram18_max = 0x60000298;
_memmap_seg_sram19_start = 0x60000298;
_memmap_seg_sram19_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001100;
_memmap_cacheattr_wt_base = 0x00001100;
_memmap_cacheattr_bp_base = 0x00002200;
_memmap_cacheattr_unused_mask = 0xFFFF00FF;
_memmap_cacheattr_wb_trapnull = 0x2222112F;
_memmap_cacheattr_wba_trapnull = 0x2222112F;
_memmap_cacheattr_wbna_trapnull = 0x2222112F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF11FF;
_memmap_cacheattr_wt_strict = 0xFFFF11FF;
_memmap_cacheattr_bp_strict = 0xFFFF22FF;
_memmap_cacheattr_wb_allvalid = 0x22221122;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
} >srom1_seg :srom1_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.dram1.rodata : ALIGN(4)
{
_dram1_rodata_start = ABSOLUTE(.);
*(.dram1.rodata)
_dram1_rodata_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.iram0.literal : ALIGN(4)
{
_iram0_literal_start = ABSOLUTE(.);
*(.iram0.literal)
*(.iram.literal)
*(.iram.text.literal)
_iram0_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.literal : ALIGN(4)
{
_dram1_literal_start = ABSOLUTE(.);
*(.dram1.literal)
_dram1_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.data : ALIGN(4)
{
_dram1_data_start = ABSOLUTE(.);
*(.dram1.data)
_dram1_data_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram1_bss_start = ABSOLUTE(.);
*(.dram1.bss)
. = ALIGN (8);
_dram1_bss_end = ABSOLUTE(.);
_memmap_seg_dram1_0_end = ALIGN(0x8);
} >dram1_0_seg :dram1_0_bss_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.text)
*(.iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >iram0_0_seg :iram0_0_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram14_end = ALIGN(0x8);
} >sram14_seg :sram14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram15_end = ALIGN(0x8);
} >sram15_seg :sram15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram16_end = ALIGN(0x8);
} >sram16_seg :sram16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram17_end = ALIGN(0x8);
} >sram17_seg :sram17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram18_end = ALIGN(0x8);
} >sram18_seg :sram18_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_dram1_bss_start)
LONG(_dram1_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram19_seg :sram19_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram19_seg :sram19_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram19_end = ALIGN(0x8);
} >sram19_seg :sram19_bss_phdr
PROVIDE(__stack = 0x64000000);
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram19_seg :sram19_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if XRC_D2PM_5swIrq
config IRQ_OFFLOAD_INTNUM
default 22
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,616 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
srom0_seg : org = 0x40000000, len = 0x2E0
srom1_seg : org = 0x400002E0, len = 0xFFFD20
dram0_0_seg : org = 0x5FFA0000, len = 0x20000
dram1_0_seg : org = 0x5FFC0000, len = 0x20000
iram0_0_seg : org = 0x5FFE0000, len = 0x20000
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x4
sram2_seg : org = 0x6000017C, len = 0x1C
sram3_seg : org = 0x60000198, len = 0x4
sram4_seg : org = 0x6000019C, len = 0x1C
sram5_seg : org = 0x600001B8, len = 0x4
sram6_seg : org = 0x600001BC, len = 0x1C
sram7_seg : org = 0x600001D8, len = 0x4
sram8_seg : org = 0x600001DC, len = 0x1C
sram9_seg : org = 0x600001F8, len = 0x4
sram10_seg : org = 0x600001FC, len = 0x1C
sram11_seg : org = 0x60000218, len = 0x4
sram12_seg : org = 0x6000021C, len = 0x1C
sram13_seg : org = 0x60000238, len = 0x4
sram14_seg : org = 0x6000023C, len = 0x1C
sram15_seg : org = 0x60000258, len = 0x4
sram16_seg : org = 0x6000025C, len = 0x1C
sram17_seg : org = 0x60000278, len = 0x4
sram18_seg : org = 0x6000027C, len = 0x1C
sram19_seg : org = 0x60000298, len = 0x3FFFD68
}
PHDRS
{
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
dram1_0_phdr PT_LOAD;
dram1_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram14_phdr PT_LOAD;
sram15_phdr PT_LOAD;
sram16_phdr PT_LOAD;
sram17_phdr PT_LOAD;
sram18_phdr PT_LOAD;
sram19_phdr PT_LOAD;
sram19_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_srom_start = 0x40000000;
_memmap_mem_srom_end = 0x41000000;
_memmap_mem_dram0_start = 0x5ffa0000;
_memmap_mem_dram0_end = 0x5ffc0000;
_memmap_mem_dram1_start = 0x5ffc0000;
_memmap_mem_dram1_end = 0x5ffe0000;
_memmap_mem_iram0_start = 0x5ffe0000;
_memmap_mem_iram0_end = 0x60000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_srom0_start = 0x40000000;
_memmap_seg_srom0_max = 0x400002e0;
_memmap_seg_srom1_start = 0x400002e0;
_memmap_seg_srom1_max = 0x41000000;
_memmap_seg_dram0_0_start = 0x5ffa0000;
_memmap_seg_dram0_0_max = 0x5ffc0000;
_memmap_seg_dram1_0_start = 0x5ffc0000;
_memmap_seg_dram1_0_max = 0x5ffe0000;
_memmap_seg_iram0_0_start = 0x5ffe0000;
_memmap_seg_iram0_0_max = 0x60000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x6000017c;
_memmap_seg_sram2_start = 0x6000017c;
_memmap_seg_sram2_max = 0x60000198;
_memmap_seg_sram3_start = 0x60000198;
_memmap_seg_sram3_max = 0x6000019c;
_memmap_seg_sram4_start = 0x6000019c;
_memmap_seg_sram4_max = 0x600001b8;
_memmap_seg_sram5_start = 0x600001b8;
_memmap_seg_sram5_max = 0x600001bc;
_memmap_seg_sram6_start = 0x600001bc;
_memmap_seg_sram6_max = 0x600001d8;
_memmap_seg_sram7_start = 0x600001d8;
_memmap_seg_sram7_max = 0x600001dc;
_memmap_seg_sram8_start = 0x600001dc;
_memmap_seg_sram8_max = 0x600001f8;
_memmap_seg_sram9_start = 0x600001f8;
_memmap_seg_sram9_max = 0x600001fc;
_memmap_seg_sram10_start = 0x600001fc;
_memmap_seg_sram10_max = 0x60000218;
_memmap_seg_sram11_start = 0x60000218;
_memmap_seg_sram11_max = 0x6000021c;
_memmap_seg_sram12_start = 0x6000021c;
_memmap_seg_sram12_max = 0x60000238;
_memmap_seg_sram13_start = 0x60000238;
_memmap_seg_sram13_max = 0x6000023c;
_memmap_seg_sram14_start = 0x6000023c;
_memmap_seg_sram14_max = 0x60000258;
_memmap_seg_sram15_start = 0x60000258;
_memmap_seg_sram15_max = 0x6000025c;
_memmap_seg_sram16_start = 0x6000025c;
_memmap_seg_sram16_max = 0x60000278;
_memmap_seg_sram17_start = 0x60000278;
_memmap_seg_sram17_max = 0x6000027c;
_memmap_seg_sram18_start = 0x6000027c;
_memmap_seg_sram18_max = 0x60000298;
_memmap_seg_sram19_start = 0x60000298;
_memmap_seg_sram19_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x40000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001100;
_memmap_cacheattr_wt_base = 0x00001100;
_memmap_cacheattr_bp_base = 0x00002200;
_memmap_cacheattr_unused_mask = 0xFFFF00FF;
_memmap_cacheattr_wb_trapnull = 0x2222112F;
_memmap_cacheattr_wba_trapnull = 0x2222112F;
_memmap_cacheattr_wbna_trapnull = 0x2222112F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF11FF;
_memmap_cacheattr_wt_strict = 0xFFFF11FF;
_memmap_cacheattr_bp_strict = 0xFFFF22FF;
_memmap_cacheattr_wb_allvalid = 0x22221122;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
} >srom1_seg :srom1_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.dram1.rodata : ALIGN(4)
{
_dram1_rodata_start = ABSOLUTE(.);
*(.dram1.rodata)
_dram1_rodata_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.iram0.literal : ALIGN(4)
{
_iram0_literal_start = ABSOLUTE(.);
*(.iram0.literal)
*(.iram.literal)
*(.iram.text.literal)
_iram0_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.literal : ALIGN(4)
{
_dram1_literal_start = ABSOLUTE(.);
*(.dram1.literal)
_dram1_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.data : ALIGN(4)
{
_dram1_data_start = ABSOLUTE(.);
*(.dram1.data)
_dram1_data_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram1_bss_start = ABSOLUTE(.);
*(.dram1.bss)
. = ALIGN (8);
_dram1_bss_end = ABSOLUTE(.);
_memmap_seg_dram1_0_end = ALIGN(0x8);
} >dram1_0_seg :dram1_0_bss_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.text)
*(.iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >iram0_0_seg :iram0_0_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram14_end = ALIGN(0x8);
} >sram14_seg :sram14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram15_end = ALIGN(0x8);
} >sram15_seg :sram15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram16_end = ALIGN(0x8);
} >sram16_seg :sram16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram17_end = ALIGN(0x8);
} >sram17_seg :sram17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram18_end = ALIGN(0x8);
} >sram18_seg :sram18_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_dram1_bss_start)
LONG(_dram1_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram19_seg :sram19_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram19_seg :sram19_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram19_end = ALIGN(0x8);
} >sram19_seg :sram19_bss_phdr
PROVIDE(__stack = 0x64000000);
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram19_seg :sram19_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if XRC_FUSION_AON_ALL_LM
config IRQ_OFFLOAD_INTNUM
default 13
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,445 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram0_0_seg : org = 0x3FFE0000, len = 0x20000
iram0_0_seg : org = 0x40000000, len = 0x178
iram0_2_seg : org = 0x40000180, len = 0x38
iram0_4_seg : org = 0x400001C0, len = 0x38
iram0_6_seg : org = 0x40000200, len = 0x38
iram0_8_seg : org = 0x40000280, len = 0x40
iram0_9_seg : org = 0x400002C0, len = 0x1FD40
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0xFFFD00
sram0_seg : org = 0x60000000, len = 0x4000000
}
PHDRS
{
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
iram0_1_phdr PT_LOAD;
iram0_2_phdr PT_LOAD;
iram0_3_phdr PT_LOAD;
iram0_4_phdr PT_LOAD;
iram0_5_phdr PT_LOAD;
iram0_6_phdr PT_LOAD;
iram0_7_phdr PT_LOAD;
iram0_8_phdr PT_LOAD;
iram0_9_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram0_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram0_start = 0x3ffe0000;
_memmap_mem_dram0_end = 0x40000000;
_memmap_mem_iram0_start = 0x40000000;
_memmap_mem_iram0_end = 0x40020000;
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_dram0_0_start = 0x3ffe0000;
_memmap_seg_dram0_0_max = 0x40000000;
_memmap_seg_iram0_0_start = 0x40000000;
_memmap_seg_iram0_0_max = 0x40000178;
_memmap_seg_iram0_2_start = 0x40000180;
_memmap_seg_iram0_2_max = 0x400001b8;
_memmap_seg_iram0_4_start = 0x400001c0;
_memmap_seg_iram0_4_max = 0x400001f8;
_memmap_seg_iram0_6_start = 0x40000200;
_memmap_seg_iram0_6_max = 0x40000238;
_memmap_seg_iram0_8_start = 0x40000280;
_memmap_seg_iram0_8_max = 0x400002c0;
_memmap_seg_iram0_9_start = 0x400002c0;
_memmap_seg_iram0_9_max = 0x40020000;
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x40000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001120;
_memmap_cacheattr_wt_base = 0x00001120;
_memmap_cacheattr_bp_base = 0x00002220;
_memmap_cacheattr_unused_mask = 0xFFFF000F;
_memmap_cacheattr_wb_trapnull = 0x2222112F;
_memmap_cacheattr_wba_trapnull = 0x2222112F;
_memmap_cacheattr_wbna_trapnull = 0x2222112F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF112F;
_memmap_cacheattr_wt_strict = 0xFFFF112F;
_memmap_cacheattr_bp_strict = 0xFFFF222F;
_memmap_cacheattr_wb_allvalid = 0x22221122;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
*(.dram.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.iram0.literal : ALIGN(4)
{
_iram0_literal_start = ABSOLUTE(.);
*(.iram0.literal)
*(.iram.literal)
*(.iram.text.literal)
_iram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
*(.dram.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
*(.dram.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_2_end = ALIGN(0x8);
} >iram0_2_seg :iram0_2_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_4_end = ALIGN(0x8);
} >iram0_4_seg :iram0_4_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_6_end = ALIGN(0x8);
} >iram0_6_seg :iram0_6_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_8_end = ALIGN(0x8);
} >iram0_8_seg :iram0_8_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.text)
*(.iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_9_end = ALIGN(0x8);
} >iram0_9_seg :iram0_9_phdr
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram0_seg :sram0_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram0_seg :sram0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_image_ram_end = ABSOLUTE(.);
_end = ALIGN(0x8);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_bss_phdr
PROVIDE(__stack = 0x64000000);
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram0_seg :sram0_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi2_std
config IRQ_OFFLOAD_INTNUM
default 7
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,616 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram1_0_seg : org = 0x3FFC0000, len = 0x20000
dram0_0_seg : org = 0x3FFE0000, len = 0x20000
iram0_0_seg : org = 0x40000000, len = 0x20000
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0xFFFD00
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x8
sram2_seg : org = 0x60000180, len = 0x38
sram3_seg : org = 0x600001B8, len = 0x8
sram4_seg : org = 0x600001C0, len = 0x38
sram5_seg : org = 0x600001F8, len = 0x8
sram6_seg : org = 0x60000200, len = 0x38
sram7_seg : org = 0x60000238, len = 0x8
sram8_seg : org = 0x60000240, len = 0x38
sram9_seg : org = 0x60000278, len = 0x8
sram10_seg : org = 0x60000280, len = 0x38
sram11_seg : org = 0x600002B8, len = 0x8
sram12_seg : org = 0x600002C0, len = 0x38
sram13_seg : org = 0x600002F8, len = 0x8
sram14_seg : org = 0x60000300, len = 0x38
sram15_seg : org = 0x60000338, len = 0x8
sram16_seg : org = 0x60000340, len = 0x38
sram17_seg : org = 0x60000378, len = 0x48
sram18_seg : org = 0x600003C0, len = 0x40
sram19_seg : org = 0x60000400, len = 0x3FFFC00
}
PHDRS
{
dram1_0_phdr PT_LOAD;
dram1_0_bss_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram14_phdr PT_LOAD;
sram15_phdr PT_LOAD;
sram16_phdr PT_LOAD;
sram17_phdr PT_LOAD;
sram18_phdr PT_LOAD;
sram19_phdr PT_LOAD;
sram19_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram1_start = 0x3ffc0000;
_memmap_mem_dram1_end = 0x3ffe0000;
_memmap_mem_dram0_start = 0x3ffe0000;
_memmap_mem_dram0_end = 0x40000000;
_memmap_mem_iram0_start = 0x40000000;
_memmap_mem_iram0_end = 0x40020000;
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_dram1_0_start = 0x3ffc0000;
_memmap_seg_dram1_0_max = 0x3ffe0000;
_memmap_seg_dram0_0_start = 0x3ffe0000;
_memmap_seg_dram0_0_max = 0x40000000;
_memmap_seg_iram0_0_start = 0x40000000;
_memmap_seg_iram0_0_max = 0x40020000;
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x60000180;
_memmap_seg_sram2_start = 0x60000180;
_memmap_seg_sram2_max = 0x600001b8;
_memmap_seg_sram3_start = 0x600001b8;
_memmap_seg_sram3_max = 0x600001c0;
_memmap_seg_sram4_start = 0x600001c0;
_memmap_seg_sram4_max = 0x600001f8;
_memmap_seg_sram5_start = 0x600001f8;
_memmap_seg_sram5_max = 0x60000200;
_memmap_seg_sram6_start = 0x60000200;
_memmap_seg_sram6_max = 0x60000238;
_memmap_seg_sram7_start = 0x60000238;
_memmap_seg_sram7_max = 0x60000240;
_memmap_seg_sram8_start = 0x60000240;
_memmap_seg_sram8_max = 0x60000278;
_memmap_seg_sram9_start = 0x60000278;
_memmap_seg_sram9_max = 0x60000280;
_memmap_seg_sram10_start = 0x60000280;
_memmap_seg_sram10_max = 0x600002b8;
_memmap_seg_sram11_start = 0x600002b8;
_memmap_seg_sram11_max = 0x600002c0;
_memmap_seg_sram12_start = 0x600002c0;
_memmap_seg_sram12_max = 0x600002f8;
_memmap_seg_sram13_start = 0x600002f8;
_memmap_seg_sram13_max = 0x60000300;
_memmap_seg_sram14_start = 0x60000300;
_memmap_seg_sram14_max = 0x60000338;
_memmap_seg_sram15_start = 0x60000338;
_memmap_seg_sram15_max = 0x60000340;
_memmap_seg_sram16_start = 0x60000340;
_memmap_seg_sram16_max = 0x60000378;
_memmap_seg_sram17_start = 0x60000378;
_memmap_seg_sram17_max = 0x600003c0;
_memmap_seg_sram18_start = 0x600003c0;
_memmap_seg_sram18_max = 0x60000400;
_memmap_seg_sram19_start = 0x60000400;
_memmap_seg_sram19_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00004420;
_memmap_cacheattr_wt_base = 0x00001120;
_memmap_cacheattr_bp_base = 0x00002220;
_memmap_cacheattr_unused_mask = 0xFFFF000F;
_memmap_cacheattr_wb_trapnull = 0x2222442F;
_memmap_cacheattr_wba_trapnull = 0x2222442F;
_memmap_cacheattr_wbna_trapnull = 0x2222552F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF442F;
_memmap_cacheattr_wt_strict = 0xFFFF112F;
_memmap_cacheattr_bp_strict = 0xFFFF222F;
_memmap_cacheattr_wb_allvalid = 0x22224422;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram1.rodata : ALIGN(4)
{
_dram1_rodata_start = ABSOLUTE(.);
*(.dram1.rodata)
_dram1_rodata_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.literal : ALIGN(4)
{
_dram1_literal_start = ABSOLUTE(.);
*(.dram1.literal)
_dram1_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.data : ALIGN(4)
{
_dram1_data_start = ABSOLUTE(.);
*(.dram1.data)
_dram1_data_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram1_bss_start = ABSOLUTE(.);
*(.dram1.bss)
. = ALIGN (8);
_dram1_bss_end = ABSOLUTE(.);
_memmap_seg_dram1_0_end = ALIGN(0x8);
} >dram1_0_seg :dram1_0_bss_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.iram0.literal : ALIGN(4)
{
_iram0_literal_start = ABSOLUTE(.);
*(.iram0.literal)
*(.iram.literal)
*(.iram.text.literal)
_iram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.text)
*(.iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram14_end = ALIGN(0x8);
} >sram14_seg :sram14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram15_end = ALIGN(0x8);
} >sram15_seg :sram15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram16_end = ALIGN(0x8);
} >sram16_seg :sram16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram17_end = ALIGN(0x8);
} >sram17_seg :sram17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram18_end = ALIGN(0x8);
} >sram18_seg :sram18_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram1_bss_start)
LONG(_dram1_bss_end)
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram19_seg :sram19_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram19_seg :sram19_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram19_seg :sram19_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram19_end = ALIGN(0x8);
} >sram19_seg :sram19_bss_phdr
PROVIDE(__stack = 0x64000000);
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram19_seg :sram19_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi3_bd5
config IRQ_OFFLOAD_INTNUM
default 13
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,392 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
srom0_seg : org = 0x50000000, len = 0x2E0
srom1_seg : org = 0x500002E0, len = 0xFFFD20
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x4
sram2_seg : org = 0x6000017C, len = 0x1C
sram3_seg : org = 0x60000198, len = 0x4
sram4_seg : org = 0x6000019C, len = 0x1C
sram5_seg : org = 0x600001B8, len = 0x4
sram6_seg : org = 0x600001BC, len = 0x1C
sram7_seg : org = 0x600001D8, len = 0x4
sram8_seg : org = 0x600001DC, len = 0x1C
sram9_seg : org = 0x600001F8, len = 0x3FFFE08
}
PHDRS
{
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram9_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x500002e0;
_memmap_seg_srom1_start = 0x500002e0;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x6000017c;
_memmap_seg_sram2_start = 0x6000017c;
_memmap_seg_sram2_max = 0x60000198;
_memmap_seg_sram3_start = 0x60000198;
_memmap_seg_sram3_max = 0x6000019c;
_memmap_seg_sram4_start = 0x6000019c;
_memmap_seg_sram4_max = 0x600001b8;
_memmap_seg_sram5_start = 0x600001b8;
_memmap_seg_sram5_max = 0x600001bc;
_memmap_seg_sram6_start = 0x600001bc;
_memmap_seg_sram6_max = 0x600001d8;
_memmap_seg_sram7_start = 0x600001d8;
_memmap_seg_sram7_max = 0x600001dc;
_memmap_seg_sram8_start = 0x600001dc;
_memmap_seg_sram8_max = 0x600001f8;
_memmap_seg_sram9_start = 0x600001f8;
_memmap_seg_sram9_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00004400;
_memmap_cacheattr_wt_base = 0x00001100;
_memmap_cacheattr_bp_base = 0x00002200;
_memmap_cacheattr_unused_mask = 0xFFFF00FF;
_memmap_cacheattr_wb_trapnull = 0x2222442F;
_memmap_cacheattr_wba_trapnull = 0x2222442F;
_memmap_cacheattr_wbna_trapnull = 0x2222552F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF44FF;
_memmap_cacheattr_wt_strict = 0xFFFF11FF;
_memmap_cacheattr_bp_strict = 0xFFFF22FF;
_memmap_cacheattr_wb_allvalid = 0x22224422;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram9_seg :sram9_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram9_seg :sram9_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram9_seg :sram9_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram9_seg :sram9_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_bss_phdr
__stack = 0x64000000;
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram9_seg :sram9_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi3_bd5_call0
config IRQ_OFFLOAD_INTNUM
default 13
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,392 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
srom0_seg : org = 0x50000000, len = 0x2E0
srom1_seg : org = 0x500002E0, len = 0xFFFD20
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x4
sram2_seg : org = 0x6000017C, len = 0x1C
sram3_seg : org = 0x60000198, len = 0x4
sram4_seg : org = 0x6000019C, len = 0x1C
sram5_seg : org = 0x600001B8, len = 0x4
sram6_seg : org = 0x600001BC, len = 0x1C
sram7_seg : org = 0x600001D8, len = 0x4
sram8_seg : org = 0x600001DC, len = 0x1C
sram9_seg : org = 0x600001F8, len = 0x3FFFE08
}
PHDRS
{
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram9_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x500002e0;
_memmap_seg_srom1_start = 0x500002e0;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x6000017c;
_memmap_seg_sram2_start = 0x6000017c;
_memmap_seg_sram2_max = 0x60000198;
_memmap_seg_sram3_start = 0x60000198;
_memmap_seg_sram3_max = 0x6000019c;
_memmap_seg_sram4_start = 0x6000019c;
_memmap_seg_sram4_max = 0x600001b8;
_memmap_seg_sram5_start = 0x600001b8;
_memmap_seg_sram5_max = 0x600001bc;
_memmap_seg_sram6_start = 0x600001bc;
_memmap_seg_sram6_max = 0x600001d8;
_memmap_seg_sram7_start = 0x600001d8;
_memmap_seg_sram7_max = 0x600001dc;
_memmap_seg_sram8_start = 0x600001dc;
_memmap_seg_sram8_max = 0x600001f8;
_memmap_seg_sram9_start = 0x600001f8;
_memmap_seg_sram9_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x60000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00004400;
_memmap_cacheattr_wt_base = 0x00001100;
_memmap_cacheattr_bp_base = 0x00002200;
_memmap_cacheattr_unused_mask = 0xFFFF00FF;
_memmap_cacheattr_wb_trapnull = 0x2222442F;
_memmap_cacheattr_wba_trapnull = 0x2222442F;
_memmap_cacheattr_wbna_trapnull = 0x2222552F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF44FF;
_memmap_cacheattr_wt_strict = 0xFFFF11FF;
_memmap_cacheattr_bp_strict = 0xFFFF22FF;
_memmap_cacheattr_wb_allvalid = 0x22224422;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram9_seg :sram9_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram9_seg :sram9_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram9_seg :sram9_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram9_seg :sram9_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram9_seg :sram9_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_bss_phdr
__stack = 0x64000000;
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram9_seg :sram9_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi4_bd7
config IRQ_OFFLOAD_INTNUM
default 4
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,439 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0x1FD00
sram0_seg : org = 0x60000000, len = 0x178
sram1_seg : org = 0x60000178, len = 0x8
sram2_seg : org = 0x60000180, len = 0x38
sram3_seg : org = 0x600001B8, len = 0x8
sram4_seg : org = 0x600001C0, len = 0x38
sram5_seg : org = 0x600001F8, len = 0x8
sram6_seg : org = 0x60000200, len = 0x38
sram7_seg : org = 0x60000238, len = 0x8
sram8_seg : org = 0x60000240, len = 0x38
sram9_seg : org = 0x60000278, len = 0x8
sram10_seg : org = 0x60000280, len = 0x38
sram11_seg : org = 0x600002B8, len = 0x48
sram12_seg : org = 0x60000300, len = 0x40
sram13_seg : org = 0x60000340, len = 0x3FFCC0
}
PHDRS
{
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram1_phdr PT_LOAD;
sram2_phdr PT_LOAD;
sram3_phdr PT_LOAD;
sram4_phdr PT_LOAD;
sram5_phdr PT_LOAD;
sram6_phdr PT_LOAD;
sram7_phdr PT_LOAD;
sram8_phdr PT_LOAD;
sram9_phdr PT_LOAD;
sram10_phdr PT_LOAD;
sram11_phdr PT_LOAD;
sram12_phdr PT_LOAD;
sram13_phdr PT_LOAD;
sram13_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x50020000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x60400000;
/* Memory segment boundary addresses: */
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x50020000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x60000178;
_memmap_seg_sram1_start = 0x60000178;
_memmap_seg_sram1_max = 0x60000180;
_memmap_seg_sram2_start = 0x60000180;
_memmap_seg_sram2_max = 0x600001b8;
_memmap_seg_sram3_start = 0x600001b8;
_memmap_seg_sram3_max = 0x600001c0;
_memmap_seg_sram4_start = 0x600001c0;
_memmap_seg_sram4_max = 0x600001f8;
_memmap_seg_sram5_start = 0x600001f8;
_memmap_seg_sram5_max = 0x60000200;
_memmap_seg_sram6_start = 0x60000200;
_memmap_seg_sram6_max = 0x60000238;
_memmap_seg_sram7_start = 0x60000238;
_memmap_seg_sram7_max = 0x60000240;
_memmap_seg_sram8_start = 0x60000240;
_memmap_seg_sram8_max = 0x60000278;
_memmap_seg_sram9_start = 0x60000278;
_memmap_seg_sram9_max = 0x60000280;
_memmap_seg_sram10_start = 0x60000280;
_memmap_seg_sram10_max = 0x600002b8;
_memmap_seg_sram11_start = 0x600002b8;
_memmap_seg_sram11_max = 0x60000300;
_memmap_seg_sram12_start = 0x60000300;
_memmap_seg_sram12_max = 0x60000340;
_memmap_seg_sram13_start = 0x60000340;
_memmap_seg_sram13_max = 0x60400000;
_rom_store_table = 0;
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00004400;
_memmap_cacheattr_wt_base = 0x00001100;
_memmap_cacheattr_bp_base = 0x00002200;
_memmap_cacheattr_unused_mask = 0xFFFF00FF;
_memmap_cacheattr_wb_trapnull = 0x2222442F;
_memmap_cacheattr_wba_trapnull = 0x2222442F;
_memmap_cacheattr_wbna_trapnull = 0x2222552F;
_memmap_cacheattr_wt_trapnull = 0x2222112F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF44FF;
_memmap_cacheattr_wt_strict = 0xFFFF11FF;
_memmap_cacheattr_bp_strict = 0xFFFF22FF;
_memmap_cacheattr_wb_allvalid = 0x22224422;
_memmap_cacheattr_wt_allvalid = 0x22221122;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram1_end = ALIGN(0x8);
} >sram1_seg :sram1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram2_end = ALIGN(0x8);
} >sram2_seg :sram2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram3_end = ALIGN(0x8);
} >sram3_seg :sram3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram4_end = ALIGN(0x8);
} >sram4_seg :sram4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram5_end = ALIGN(0x8);
} >sram5_seg :sram5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_sram6_end = ALIGN(0x8);
} >sram6_seg :sram6_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram7_end = ALIGN(0x8);
} >sram7_seg :sram7_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram8_end = ALIGN(0x8);
} >sram8_seg :sram8_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram9_end = ALIGN(0x8);
} >sram9_seg :sram9_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram10_end = ALIGN(0x8);
} >sram10_seg :sram10_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_sram11_end = ALIGN(0x8);
} >sram11_seg :sram11_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_sram12_end = ALIGN(0x8);
} >sram12_seg :sram12_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram13_seg :sram13_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram13_seg :sram13_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram13_seg :sram13_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram13_seg :sram13_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram13_seg :sram13_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram13_seg :sram13_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram13_seg :sram13_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram13_end = ALIGN(0x8);
} >sram13_seg :sram13_bss_phdr
__stack = 0x60400000;
_heap_sentry = 0x60400000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram13_seg :sram13_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi_mini
config IRQ_OFFLOAD_INTNUM
default 13
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,364 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram0_0_seg : org = 0x60000000, len = 0x20000
iram0_0_seg : org = 0x60020000, len = 0x2E0
iram0_1_seg : org = 0x600202E0, len = 0x4
iram0_2_seg : org = 0x600202E4, len = 0x1C
iram0_3_seg : org = 0x60020300, len = 0x4
iram0_4_seg : org = 0x60020304, len = 0x1C
iram0_5_seg : org = 0x60020320, len = 0x4
iram0_6_seg : org = 0x60020324, len = 0x1C
iram0_7_seg : org = 0x60020340, len = 0x1FCC0
}
PHDRS
{
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
iram0_1_phdr PT_LOAD;
iram0_2_phdr PT_LOAD;
iram0_3_phdr PT_LOAD;
iram0_4_phdr PT_LOAD;
iram0_5_phdr PT_LOAD;
iram0_6_phdr PT_LOAD;
iram0_7_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram0_start = 0x60000000;
_memmap_mem_dram0_end = 0x60020000;
_memmap_mem_iram0_start = 0x60020000;
_memmap_mem_iram0_end = 0x60040000;
/* Memory segment boundary addresses: */
_memmap_seg_dram0_0_start = 0x60000000;
_memmap_seg_dram0_0_max = 0x60020000;
_memmap_seg_iram0_0_start = 0x60020000;
_memmap_seg_iram0_0_max = 0x600202e0;
_memmap_seg_iram0_1_start = 0x600202e0;
_memmap_seg_iram0_1_max = 0x600202e4;
_memmap_seg_iram0_2_start = 0x600202e4;
_memmap_seg_iram0_2_max = 0x60020300;
_memmap_seg_iram0_3_start = 0x60020300;
_memmap_seg_iram0_3_max = 0x60020304;
_memmap_seg_iram0_4_start = 0x60020304;
_memmap_seg_iram0_4_max = 0x60020320;
_memmap_seg_iram0_5_start = 0x60020320;
_memmap_seg_iram0_5_max = 0x60020324;
_memmap_seg_iram0_6_start = 0x60020324;
_memmap_seg_iram0_6_max = 0x60020340;
_memmap_seg_iram0_7_start = 0x60020340;
_memmap_seg_iram0_7_max = 0x60040000;
_rom_store_table = 0;
PROVIDE(_memmap_reset_vector = 0x60020000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001000;
_memmap_cacheattr_wt_base = 0x00001000;
_memmap_cacheattr_bp_base = 0x00002000;
_memmap_cacheattr_unused_mask = 0xFFFF0FFF;
_memmap_cacheattr_wb_trapnull = 0x2222122F;
_memmap_cacheattr_wba_trapnull = 0x2222122F;
_memmap_cacheattr_wbna_trapnull = 0x2222122F;
_memmap_cacheattr_wt_trapnull = 0x2222122F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF1FFF;
_memmap_cacheattr_wt_strict = 0xFFFF1FFF;
_memmap_cacheattr_bp_strict = 0xFFFF2FFF;
_memmap_cacheattr_wb_allvalid = 0x22221222;
_memmap_cacheattr_wt_allvalid = 0x22221222;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
_image_ram_start = ABSOLUTE(.);
*(.dram0.rodata)
*(.dram.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
*(.dram.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.ResetVector.literal : ALIGN(4)
{
_ResetVector_literal_start = ABSOLUTE(.);
*(.ResetVector.literal)
_ResetVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
*(.dram.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >dram0_0_seg :dram0_0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_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)
*(.dram0.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
__stack = 0x60020000;
_heap_sentry = 0x60020000;
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_1_end = ALIGN(0x8);
} >iram0_1_seg :iram0_1_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_2_end = ALIGN(0x8);
} >iram0_2_seg :iram0_2_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_3_end = ALIGN(0x8);
} >iram0_3_seg :iram0_3_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_4_end = ALIGN(0x8);
} >iram0_4_seg :iram0_4_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_5_end = ALIGN(0x8);
} >iram0_5_seg :iram0_5_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_6_end = ALIGN(0x8);
} >iram0_6_seg :iram0_6_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
_iram0_text_end = ABSOLUTE(.);
_image_rom_end = ABSOLUTE(.);
} >iram0_7_seg :iram0_7_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >iram0_7_seg :iram0_7_phdr
_image_text_end = .;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION dram0_0_seg :dram0_0_phdr
#define ROMABLE_REGION iram0_7_seg :iram0_7_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if hifi_mini_4swIrq
config IRQ_OFFLOAD_INTNUM
default 1
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,364 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram0_0_seg : org = 0x60000000, len = 0x20000
iram0_0_seg : org = 0x60020000, len = 0x2E0
iram0_1_seg : org = 0x600202E0, len = 0x4
iram0_2_seg : org = 0x600202E4, len = 0x1C
iram0_3_seg : org = 0x60020300, len = 0x4
iram0_4_seg : org = 0x60020304, len = 0x1C
iram0_5_seg : org = 0x60020320, len = 0x4
iram0_6_seg : org = 0x60020324, len = 0x1C
iram0_7_seg : org = 0x60020340, len = 0x1FCC0
}
PHDRS
{
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
iram0_1_phdr PT_LOAD;
iram0_2_phdr PT_LOAD;
iram0_3_phdr PT_LOAD;
iram0_4_phdr PT_LOAD;
iram0_5_phdr PT_LOAD;
iram0_6_phdr PT_LOAD;
iram0_7_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram0_start = 0x60000000;
_memmap_mem_dram0_end = 0x60020000;
_memmap_mem_iram0_start = 0x60020000;
_memmap_mem_iram0_end = 0x60040000;
/* Memory segment boundary addresses: */
_memmap_seg_dram0_0_start = 0x60000000;
_memmap_seg_dram0_0_max = 0x60020000;
_memmap_seg_iram0_0_start = 0x60020000;
_memmap_seg_iram0_0_max = 0x600202e0;
_memmap_seg_iram0_1_start = 0x600202e0;
_memmap_seg_iram0_1_max = 0x600202e4;
_memmap_seg_iram0_2_start = 0x600202e4;
_memmap_seg_iram0_2_max = 0x60020300;
_memmap_seg_iram0_3_start = 0x60020300;
_memmap_seg_iram0_3_max = 0x60020304;
_memmap_seg_iram0_4_start = 0x60020304;
_memmap_seg_iram0_4_max = 0x60020320;
_memmap_seg_iram0_5_start = 0x60020320;
_memmap_seg_iram0_5_max = 0x60020324;
_memmap_seg_iram0_6_start = 0x60020324;
_memmap_seg_iram0_6_max = 0x60020340;
_memmap_seg_iram0_7_start = 0x60020340;
_memmap_seg_iram0_7_max = 0x60040000;
_rom_store_table = 0;
PROVIDE(_memmap_reset_vector = 0x60020000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001000;
_memmap_cacheattr_wt_base = 0x00001000;
_memmap_cacheattr_bp_base = 0x00002000;
_memmap_cacheattr_unused_mask = 0xFFFF0FFF;
_memmap_cacheattr_wb_trapnull = 0x2222122F;
_memmap_cacheattr_wba_trapnull = 0x2222122F;
_memmap_cacheattr_wbna_trapnull = 0x2222122F;
_memmap_cacheattr_wt_trapnull = 0x2222122F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF1FFF;
_memmap_cacheattr_wt_strict = 0xFFFF1FFF;
_memmap_cacheattr_bp_strict = 0xFFFF2FFF;
_memmap_cacheattr_wb_allvalid = 0x22221222;
_memmap_cacheattr_wt_allvalid = 0x22221222;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
_image_ram_start = ABSOLUTE(.);
*(.dram0.rodata)
*(.dram.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
*(.dram.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.ResetVector.literal : ALIGN(4)
{
_ResetVector_literal_start = ABSOLUTE(.);
*(.ResetVector.literal)
_ResetVector_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
*(.dram.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >dram0_0_seg :dram0_0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_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)
*(.dram0.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
__stack = 0x60020000;
_heap_sentry = 0x60020000;
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_1_end = ALIGN(0x8);
} >iram0_1_seg :iram0_1_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_2_end = ALIGN(0x8);
} >iram0_2_seg :iram0_2_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_3_end = ALIGN(0x8);
} >iram0_3_seg :iram0_3_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_4_end = ALIGN(0x8);
} >iram0_4_seg :iram0_4_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_5_end = ALIGN(0x8);
} >iram0_5_seg :iram0_5_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_6_end = ALIGN(0x8);
} >iram0_6_seg :iram0_6_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
_iram0_text_end = ABSOLUTE(.);
_image_rom_end = ABSOLUTE(.);
} >iram0_7_seg :iram0_7_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >iram0_7_seg :iram0_7_phdr
_image_text_end = .;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram0_0_seg :sram0_0_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Open-RnD Sp. z o.o.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if sample_controller
config IRQ_OFFLOAD_INTNUM
default 7
endif

View file

@ -0,0 +1 @@
obj- = soc.o

View file

@ -0,0 +1,606 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the Xtensa platform.
*/
MEMORY
{
dram1_0_seg : org = 0x3FFC0000, len = 0x20000
dram0_0_seg : org = 0x3FFE0000, len = 0x20000
iram0_0_seg : org = 0x40000000, len = 0x178
iram0_1_seg : org = 0x40000178, len = 0x8
iram0_2_seg : org = 0x40000180, len = 0x38
iram0_3_seg : org = 0x400001B8, len = 0x8
iram0_4_seg : org = 0x400001C0, len = 0x38
iram0_5_seg : org = 0x400001F8, len = 0x8
iram0_6_seg : org = 0x40000200, len = 0x38
iram0_7_seg : org = 0x40000238, len = 0x8
iram0_8_seg : org = 0x40000240, len = 0x38
iram0_9_seg : org = 0x40000278, len = 0x8
iram0_10_seg : org = 0x40000280, len = 0x38
iram0_11_seg : org = 0x400002B8, len = 0x8
iram0_12_seg : org = 0x400002C0, len = 0x38
iram0_13_seg : org = 0x400002F8, len = 0x8
iram0_14_seg : org = 0x40000300, len = 0x38
iram0_15_seg : org = 0x40000338, len = 0x8
iram0_16_seg : org = 0x40000340, len = 0x38
iram0_17_seg : org = 0x40000378, len = 0x48
iram0_18_seg : org = 0x400003C0, len = 0x40
iram0_19_seg : org = 0x40000400, len = 0x1FC00
srom0_seg : org = 0x50000000, len = 0x300
srom1_seg : org = 0x50000300, len = 0xFFFD00
sram0_seg : org = 0x60000000, len = 0x4000000
}
PHDRS
{
dram1_0_phdr PT_LOAD;
dram1_0_bss_phdr PT_LOAD;
dram0_0_phdr PT_LOAD;
dram0_0_bss_phdr PT_LOAD;
iram0_0_phdr PT_LOAD;
iram0_1_phdr PT_LOAD;
iram0_2_phdr PT_LOAD;
iram0_3_phdr PT_LOAD;
iram0_4_phdr PT_LOAD;
iram0_5_phdr PT_LOAD;
iram0_6_phdr PT_LOAD;
iram0_7_phdr PT_LOAD;
iram0_8_phdr PT_LOAD;
iram0_9_phdr PT_LOAD;
iram0_10_phdr PT_LOAD;
iram0_11_phdr PT_LOAD;
iram0_12_phdr PT_LOAD;
iram0_13_phdr PT_LOAD;
iram0_14_phdr PT_LOAD;
iram0_15_phdr PT_LOAD;
iram0_16_phdr PT_LOAD;
iram0_17_phdr PT_LOAD;
iram0_18_phdr PT_LOAD;
iram0_19_phdr PT_LOAD;
srom0_phdr PT_LOAD;
srom1_phdr PT_LOAD;
sram0_phdr PT_LOAD;
sram0_bss_phdr PT_LOAD;
}
/* Default entry point: */
ENTRY(_ResetVector)
/* Memory boundary addresses: */
_memmap_mem_dram1_start = 0x3ffc0000;
_memmap_mem_dram1_end = 0x3ffe0000;
_memmap_mem_dram0_start = 0x3ffe0000;
_memmap_mem_dram0_end = 0x40000000;
_memmap_mem_iram0_start = 0x40000000;
_memmap_mem_iram0_end = 0x40020000;
_memmap_mem_srom_start = 0x50000000;
_memmap_mem_srom_end = 0x51000000;
_memmap_mem_sram_start = 0x60000000;
_memmap_mem_sram_end = 0x64000000;
/* Memory segment boundary addresses: */
_memmap_seg_dram1_0_start = 0x3ffc0000;
_memmap_seg_dram1_0_max = 0x3ffe0000;
_memmap_seg_dram0_0_start = 0x3ffe0000;
_memmap_seg_dram0_0_max = 0x40000000;
_memmap_seg_iram0_0_start = 0x40000000;
_memmap_seg_iram0_0_max = 0x40000178;
_memmap_seg_iram0_1_start = 0x40000178;
_memmap_seg_iram0_1_max = 0x40000180;
_memmap_seg_iram0_2_start = 0x40000180;
_memmap_seg_iram0_2_max = 0x400001b8;
_memmap_seg_iram0_3_start = 0x400001b8;
_memmap_seg_iram0_3_max = 0x400001c0;
_memmap_seg_iram0_4_start = 0x400001c0;
_memmap_seg_iram0_4_max = 0x400001f8;
_memmap_seg_iram0_5_start = 0x400001f8;
_memmap_seg_iram0_5_max = 0x40000200;
_memmap_seg_iram0_6_start = 0x40000200;
_memmap_seg_iram0_6_max = 0x40000238;
_memmap_seg_iram0_7_start = 0x40000238;
_memmap_seg_iram0_7_max = 0x40000240;
_memmap_seg_iram0_8_start = 0x40000240;
_memmap_seg_iram0_8_max = 0x40000278;
_memmap_seg_iram0_9_start = 0x40000278;
_memmap_seg_iram0_9_max = 0x40000280;
_memmap_seg_iram0_10_start = 0x40000280;
_memmap_seg_iram0_10_max = 0x400002b8;
_memmap_seg_iram0_11_start = 0x400002b8;
_memmap_seg_iram0_11_max = 0x400002c0;
_memmap_seg_iram0_12_start = 0x400002c0;
_memmap_seg_iram0_12_max = 0x400002f8;
_memmap_seg_iram0_13_start = 0x400002f8;
_memmap_seg_iram0_13_max = 0x40000300;
_memmap_seg_iram0_14_start = 0x40000300;
_memmap_seg_iram0_14_max = 0x40000338;
_memmap_seg_iram0_15_start = 0x40000338;
_memmap_seg_iram0_15_max = 0x40000340;
_memmap_seg_iram0_16_start = 0x40000340;
_memmap_seg_iram0_16_max = 0x40000378;
_memmap_seg_iram0_17_start = 0x40000378;
_memmap_seg_iram0_17_max = 0x400003c0;
_memmap_seg_iram0_18_start = 0x400003c0;
_memmap_seg_iram0_18_max = 0x40000400;
_memmap_seg_iram0_19_start = 0x40000400;
_memmap_seg_iram0_19_max = 0x40020000;
_memmap_seg_srom0_start = 0x50000000;
_memmap_seg_srom0_max = 0x50000300;
_memmap_seg_srom1_start = 0x50000300;
_memmap_seg_srom1_max = 0x51000000;
_memmap_seg_sram0_start = 0x60000000;
_memmap_seg_sram0_max = 0x64000000;
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = 0x40000000);
PROVIDE(_memmap_reset_vector = 0x50000000);
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x00001110;
_memmap_cacheattr_wt_base = 0x00001110;
_memmap_cacheattr_bp_base = 0x00002220;
_memmap_cacheattr_unused_mask = 0xFFFF000F;
_memmap_cacheattr_wb_trapnull = 0x2222111F;
_memmap_cacheattr_wba_trapnull = 0x2222111F;
_memmap_cacheattr_wbna_trapnull = 0x2222111F;
_memmap_cacheattr_wt_trapnull = 0x2222111F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0xFFFF111F;
_memmap_cacheattr_wt_strict = 0xFFFF111F;
_memmap_cacheattr_bp_strict = 0xFFFF222F;
_memmap_cacheattr_wb_allvalid = 0x22221112;
_memmap_cacheattr_wt_allvalid = 0x22221112;
_memmap_cacheattr_bp_allvalid = 0x22222222;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
SECTIONS
{
.dram1.rodata : ALIGN(4)
{
_dram1_rodata_start = ABSOLUTE(.);
*(.dram1.rodata)
_dram1_rodata_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.literal : ALIGN(4)
{
_dram1_literal_start = ABSOLUTE(.);
*(.dram1.literal)
_dram1_literal_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.data : ALIGN(4)
{
_dram1_data_start = ABSOLUTE(.);
*(.dram1.data)
_dram1_data_end = ABSOLUTE(.);
} >dram1_0_seg :dram1_0_phdr
.dram1.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram1_bss_start = ABSOLUTE(.);
*(.dram1.bss)
. = ALIGN (8);
_dram1_bss_end = ABSOLUTE(.);
_memmap_seg_dram1_0_end = ALIGN(0x8);
} >dram1_0_seg :dram1_0_bss_phdr
.dram0.rodata : ALIGN(4)
{
_dram0_rodata_start = ABSOLUTE(.);
*(.dram0.rodata)
_dram0_rodata_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.literal : ALIGN(4)
{
_dram0_literal_start = ABSOLUTE(.);
*(.dram0.literal)
_dram0_literal_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.data : ALIGN(4)
{
_dram0_data_start = ABSOLUTE(.);
*(.dram0.data)
_dram0_data_end = ABSOLUTE(.);
} >dram0_0_seg :dram0_0_phdr
.dram0.bss (NOLOAD) : ALIGN(8)
{
. = ALIGN (8);
_dram0_bss_start = ABSOLUTE(.);
*(.dram0.bss)
. = ALIGN (8);
_dram0_bss_end = ABSOLUTE(.);
_memmap_seg_dram0_0_end = ALIGN(0x8);
} >dram0_0_seg :dram0_0_bss_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
_memmap_seg_iram0_0_end = ALIGN(0x8);
} >iram0_0_seg :iram0_0_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_1_end = ALIGN(0x8);
} >iram0_1_seg :iram0_1_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_2_end = ALIGN(0x8);
} >iram0_2_seg :iram0_2_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_3_end = ALIGN(0x8);
} >iram0_3_seg :iram0_3_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_4_end = ALIGN(0x8);
} >iram0_4_seg :iram0_4_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_5_end = ALIGN(0x8);
} >iram0_5_seg :iram0_5_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_6_end = ALIGN(0x8);
} >iram0_6_seg :iram0_6_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_7_end = ALIGN(0x8);
} >iram0_7_seg :iram0_7_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_8_end = ALIGN(0x8);
} >iram0_8_seg :iram0_8_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_9_end = ALIGN(0x8);
} >iram0_9_seg :iram0_9_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_10_end = ALIGN(0x8);
} >iram0_10_seg :iram0_10_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_11_end = ALIGN(0x8);
} >iram0_11_seg :iram0_11_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_12_end = ALIGN(0x8);
} >iram0_12_seg :iram0_12_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_13_end = ALIGN(0x8);
} >iram0_13_seg :iram0_13_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_14_end = ALIGN(0x8);
} >iram0_14_seg :iram0_14_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_15_end = ALIGN(0x8);
} >iram0_15_seg :iram0_15_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_16_end = ALIGN(0x8);
} >iram0_16_seg :iram0_16_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
_memmap_seg_iram0_17_end = ALIGN(0x8);
} >iram0_17_seg :iram0_17_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
_memmap_seg_iram0_18_end = ALIGN(0x8);
} >iram0_18_seg :iram0_18_phdr
.iram0.text : ALIGN(4)
{
_iram0_text_start = ABSOLUTE(.);
*(.iram0.literal .iram.literal .iram.text.literal .iram0.text .iram.text)
_iram0_text_end = ABSOLUTE(.);
_memmap_seg_iram0_19_end = ALIGN(0x8);
} >iram0_19_seg :iram0_19_phdr
.ResetVector.text : ALIGN(4)
{
_image_rom_start = ABSOLUTE(.);
_ResetVector_text_start = ABSOLUTE(.);
KEEP (*(.ResetVector.text))
_ResetVector_text_end = ABSOLUTE(.);
_memmap_seg_srom0_end = ALIGN(0x8);
} >srom0_seg :srom0_phdr
.srom.rodata : ALIGN(4)
{
_srom_rodata_start = ABSOLUTE(.);
*(.srom.rodata)
_srom_rodata_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.srom.text : ALIGN(4)
{
_srom_text_start = ABSOLUTE(.);
*(.srom.literal .srom.text)
_srom_text_end = ABSOLUTE(.);
_memmap_seg_srom1_end = ALIGN(0x8);
_image_rom_end = ABSOLUTE(.);
} >srom1_seg :srom1_phdr
.sram.rodata : ALIGN(4)
{
_image_ram_start = ABSOLUTE(.);
_sram_rodata_start = ABSOLUTE(.);
*(.sram.rodata)
_sram_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_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))
/* C++ constructor and destructor tables, properly ordered: */
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))
/* C++ exception handlers table: */
__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); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_dram1_bss_start)
LONG(_dram1_bss_end)
LONG(_dram0_bss_start)
LONG(_dram0_bss_end)
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.sram.text : ALIGN(4)
{
_sram_text_start = ABSOLUTE(.);
*(.sram.literal .sram.text)
_sram_text_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
_image_text_start = ALIGN(4);
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
*(.entry.text)
*(.init.literal)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
} >sram0_seg :sram0_phdr
_image_text_end = .;
.sram.data : ALIGN(4)
{
_sram_data_start = ABSOLUTE(.);
*(.sram.data)
_sram_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >sram0_seg :sram0_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
KEEP(*(.isr_irq*))
/* sections for IRQ0-9 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9])))
/* sections for IRQ10-99 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9])))
/* sections for IRQ100-999 */
KEEP(*(SORT(.gnu.linkonce.d.isr_irq[0-9][0-9][0-9])))
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
_data_end = ABSOLUTE(.);
} >sram0_seg :sram0_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)
*(.sram.bss)
. = ALIGN (8);
_bss_end = ABSOLUTE(.);
_end = ALIGN(0x8);
_image_ram_end = ABSOLUTE(.);
PROVIDE(end = ALIGN(0x8));
_stack_sentry = ALIGN(0x8);
_memmap_seg_sram0_end = ALIGN(0x8);
} >sram0_seg :sram0_bss_phdr
__stack = 0x64000000;
_heap_sentry = 0x64000000;
.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) }
.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.*))
}
.debug.xt.callgraph 0 :
{
KEEP (*(.debug.xt.callgraph .debug.xt.callgraph.* .gnu.linkonce.xt.callgraph.*))
}
#define _LINKER
#define _ASMLANGUAGE
#include <autoconf.h>
#include <sections.h>
#include <linker-defs.h>
#include <linker-tool.h>
#define RAMABLE_REGION sram0_seg :sram0_phdr
#define ROMABLE_REGION srom1_seg :srom1_phdr
#include <linker/common-rom.ld>
#include <linker/common-ram.ld>
}

View file

@ -0,0 +1,12 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
config XTENSA_XTSC_INC
string "Xtensa XTSC extension include file"
depends on SIMULATOR_XTENSA
help
If you want to use xtsc-run with an extended core, then you can put here the
path to the include file of the extension model. This path can either be
absolute or relative to the execution directory.

View file

@ -0,0 +1,8 @@
# Kconfig - XTENSA board configuration
#
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
config SIMULATOR_XTENSA
bool "Xtensa Development ISS"
depends on XTENSA

View file

@ -0,0 +1,11 @@
# Kconfig - STM32 MINI A15 board configuration
#
# Copyright (c) 2016 Cadence Design Systems, Inc.
# SPDX-License-Identifier: Apache-2.0
if SIMULATOR_XTENSA
config BOARD
default xt-sim
endif # SIMULATOR_XTENSA

View file

@ -0,0 +1,5 @@
ccflags-y += -I$(srctree)/include/drivers
ccflags-y += -I$(srctree)/drivers
asflags-y := ${ccflags-y}
obj-y += board.o

View file

@ -0,0 +1,4 @@
# Default to xt-run but let the user override to xtsc-run if they desire
EMU_PLATFORM ?= xt-run
DEBUG_SCRIPT := xt-gdb.sh

View file

@ -0,0 +1,4 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/

View file

@ -0,0 +1,10 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __INC_BOARD_H
#define __INC_BOARD_H
#endif /* __INC_BOARD_H */

View file

@ -0,0 +1,4 @@
CONFIG_MAIN_STACK_SIZE=2048
CONFIG_XTENSA=y
CONFIG_SIMULATOR_XTENSA=y
CONFIG_CONSOLE=y

View file

@ -2,6 +2,7 @@
# #
# Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2014-2015 Wind River Systems, Inc.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -164,6 +165,22 @@ config UART_PIPE_ON_DEV_NAME
This option specifies the name of UART device to be used This option specifies the name of UART device to be used
for pipe UART. for pipe UART.
source "drivers/console/Kconfig.telnet" config XTENSA_SIM_CONSOLE
bool
prompt "Use Xtensa simulator console"
depends on SIMULATOR_XTENSA
select CONSOLE_HAS_DRIVER
default y
help
Use simulator console to print messages.
config XTENSA_CONSOLE_INIT_PRIORITY
int
prompt "Init priority"
default 60
depends on XTENSA_SIM_CONSOLE
help
Device driver initialization priority.
source "drivers/console/Kconfig.telnet"
endif endif

View file

@ -5,3 +5,4 @@ obj-$(CONFIG_IPM_CONSOLE_RECEIVER) += ipm_console_receiver.o
obj-$(CONFIG_IPM_CONSOLE_SENDER) += ipm_console_sender.o obj-$(CONFIG_IPM_CONSOLE_SENDER) += ipm_console_sender.o
obj-$(CONFIG_UART_PIPE) += uart_pipe.o obj-$(CONFIG_UART_PIPE) += uart_pipe.o
obj-$(CONFIG_TELNET_CONSOLE) += telnet_console.o obj-$(CONFIG_TELNET_CONSOLE) += telnet_console.o
obj-$(CONFIG_XTENSA_SIM_CONSOLE) += xtensa_sim_console.o

View file

@ -0,0 +1,86 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/simcall.h>
#include <device.h>
#include <init.h>
#if defined(CONFIG_PRINTK) || defined(CONFIG_STDOUT_CONSOLE)
/**
* @brief Output one character to SIMULATOR console
* @param c Character to output
* @return The character passed as input.
*/
static int console_out(int c)
{
char buf[16];
register int a2 __asm__ ("a2") = SYS_write;
register int a3 __asm__ ("a3") = 1;
register char *a4 __asm__ ("a4") = buf;
register int a5 __asm__ ("a5") = 1;
register int ret_val __asm__ ("a2");
register int ret_err __asm__ ("a3");
buf[0] = (char)c;
__asm__ ("simcall"
: "=a" (ret_val), "=a" (ret_err)
: "a" (a2), "a" (a3), "a" (a4), "a" (a5));
return c;
}
#endif
#if defined(CONFIG_STDOUT_CONSOLE)
extern void __stdout_hook_install(int (*hook)(int));
#else
#define __stdout_hook_install(x) \
do {/* nothing */ \
} while ((0))
#endif
#if defined(CONFIG_PRINTK)
extern void __printk_hook_install(int (*fn)(int));
#else
#define __printk_hook_install(x) \
do {/* nothing */ \
} while ((0))
#endif
/**
*
* @brief Install printk/stdout hook for Xtensa Simulator console output
* @return N/A
*/
void xt_sim_console_hook_install(void)
{
__stdout_hook_install(console_out);
__printk_hook_install(console_out);
}
/**
*
* @brief Initialize the console/debug port
* @return 0 if successful, otherwise failed.
*/
static int xt_sim_console_init(struct device *arg)
{
ARG_UNUSED(arg);
xt_sim_console_hook_install();
return 0;
}
/* UART consloe initializes after the UART device itself */
SYS_INIT(xt_sim_console_init,
#if defined(CONFIG_EARLY_CONSOLE)
PRE_KERNEL_1,
#else
POST_KERNEL,
#endif
CONFIG_XTENSA_CONSOLE_INIT_PRIORITY);

View file

@ -2,6 +2,7 @@
# #
# Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2014-2015 Wind River Systems, Inc.
# Copyright (c) 2016 Cadence Design Systems, Inc.
# #
# SPDX-License-Identifier: Apache-2.0 # SPDX-License-Identifier: Apache-2.0
# #
@ -164,6 +165,48 @@ config RISCV_MACHINE_TIMER
This module implements a kernel device driver for the generic RISCV machine This module implements a kernel device driver for the generic RISCV machine
timer driver. It provides the standard "system clock driver" interfaces. timer driver. It provides the standard "system clock driver" interfaces.
config XTENSA_TIMER
bool "Xtensa timer support"
depends on XTENSA
default y
help
This module implements a kernel device driver for the Xtensa processor and
provides the standard "system clock driver" interfaces.
If unchecked, no timer will be used.
If checked it will use either an internal timer (default option) or an
external timer. In that case one shall unselect XTENSA_INTERNAL_TIMER and
define XTENSA_TIMER_IRQ and XTENSA_TIMER_IRQ_PRIORITY.
config XTENSA_INTERNAL_TIMER
bool "Xtensa internal timer"
depends on XTENSA_TIMER
default y
help
This module implements a kernel device driver for the Xtensa processor
internal timer and provides the standard "system clock driver" interfaces.
If unchecked, an external timer will be used. It will rely on a tick
interrupt connected to an IRQ line. In this case one shall define
both XTENSA_TIMER_IRQ and XTENSA_TIMER_IRQ_PRIORITY.
config XTENSA_TIMER_IRQ
int "Xtensa external timer interrupt number"
depends on XTENSA_TIMER && !XTENSA_INTERNAL_TIMER
range -1 31
default -1
help
This is the number of interrupt line used by the external timer.
The special value of -1 allows using the internal timer in order to
emulate an external timer. This is generally useful for running the project on
a simulator where it is hard to emulate an external interrupt.
config XTENSA_TIMER_IRQ_PRIORITY
int "Xtensa external timer interrupt priority"
depends on XTENSA_TIMER && !XTENSA_INTERNAL_TIMER
range 1 6
default 1
help
This is the priority of interrupt line.
config SYSTEM_CLOCK_DISABLE config SYSTEM_CLOCK_DISABLE
bool "API to disable system clock" bool "API to disable system clock"
default n default n

View file

@ -5,6 +5,8 @@ obj-$(CONFIG_ALTERA_AVALON_TIMER) += altera_avalon_timer.o
obj-$(CONFIG_NRF_RTC_TIMER) += nrf_rtc_timer.o obj-$(CONFIG_NRF_RTC_TIMER) += nrf_rtc_timer.o
obj-$(CONFIG_PULPINO_TIMER) += pulpino_timer.o obj-$(CONFIG_PULPINO_TIMER) += pulpino_timer.o
obj-$(CONFIG_RISCV_MACHINE_TIMER) += riscv_machine_timer.o obj-$(CONFIG_RISCV_MACHINE_TIMER) += riscv_machine_timer.o
obj-$(CONFIG_RISCV_QEMU_TIMER) += riscv_qemu_timer.o
obj-$(CONFIG_XTENSA_TIMER) += xtensa_sys_timer.o
obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o obj-$(CONFIG_CORTEX_M_SYSTICK) += cortex_m_systick.o

View file

@ -0,0 +1,351 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#include <nanokernel.h>
#include <system_timer.h>
#include <xtensa_rtos.h>
#include <xtensa/tie/xt_timer.h>
#include <xtensa_timer.h>
#include "irq.h"
#ifdef XT_BOARD
#include <xtensa/xtbsp.h>
#endif
#include "xtensa_rtos.h"
/*
* This device driver can be also used with an extenal timer instead of
* the internal one that may simply not exist.
* The below macros are used to abstract the timer HW interface assuming that
* it allows implementing them.
* Of course depending on the HW specific requirements, part of the code may
* need to changed. We tried to identify this code and hoghlight it to users.
*
* User shall track the TODO flags and follow the instruction to adapt the code
* according to his HW.
*/
/* Abstraction macros to access the timer fire time register */
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
#define _XT_SR_CCOMPARE(op, idx) XT_##op##SR_CCOMPARE##idx
#define XT_SR_CCOMPARE(op, idx) _XT_SR_CCOMPARE(op, idx)
/* Use XT_TIMER_INDEX to select XT_CHAL macro to access CCOMPAREx register */
#define GET_TIMER_FIRE_TIME(void) XT_SR_CCOMPARE(R, XT_TIMER_INDEX)()
#define SET_TIMER_FIRE_TIME(time) XT_SR_CCOMPARE(W, XT_TIMER_INDEX)(time)
#define GET_TIMER_CURRENT_TIME(void) XT_RSR_CCOUNT()
/* Value underwich, don't program next tick but trigger it immediately. */
#define MIN_TIMER_PROG_DELAY 50
#else /* Case of an external timer which is not emulated by internal timer */
/* TODO: User who wants ot use and external timer should ensure that:
* - CONFIG_XTENSA_INTERNAL_TIMER is unset
* - CONFIG_XTENSA_TIMER_IRQ > 0
* - Macros below are correctly implemented
*/
#define GET_TIMER_FIRE_TIME(void) /* TODO: Implement this case */
#define SET_TIMER_FIRE_TIME(time) /* TODO: Implement this case */
#define GET_TIMER_CURRENT_TIME(void) /* TODO: Implement this case */
/* Value underwich, don't program next tick but trigger it immediately. */
#define MIN_TIMER_PROG_DELAY 50 /* TODO: Update this value */
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
#ifdef CONFIG_TICKLESS_IDLE
#define TIMER_MODE_PERIODIC 0 /* normal running mode */
#define TIMER_MODE_ONE_SHOT 1 /* emulated, since sysTick has 1 mode */
#define IDLE_NOT_TICKLESS 0 /* non-tickless idle mode */
#define IDLE_TICKLESS 1 /* tickless idle mode */
extern int32_t _sys_idle_elapsed_ticks;
static uint32_t __noinit cycles_per_tick;
static uint32_t __noinit max_system_ticks;
static uint32_t idle_original_ticks;
static uint32_t __noinit max_load_value;
static unsigned char timer_mode = TIMER_MODE_PERIODIC;
static unsigned char idle_mode = IDLE_NOT_TICKLESS;
static ALWAYS_INLINE void tickless_idle_init(void)
{
cycles_per_tick = sys_clock_hw_cycles_per_tick;
/* calculate the max number of ticks with this 32-bit H/W counter */
max_system_ticks = 0xffffffff / cycles_per_tick;
max_load_value = max_system_ticks * cycles_per_tick;
}
/*
* @brief Place the system timer into idle state
*
* Re-program the timer to enter into the idle state for either the given
* number of ticks or the maximum number of ticks that can be programmed
* into hardware.
*
* @return N/A
*/
void _timer_idle_enter(int32_t ticks)
{
uint32_t P; /* Programming (current) time */
uint32_t F; /* Idle timer fire time */
uint32_t f; /* Last programmed timer fire time */
if ((ticks == K_FOREVER) || (ticks > max_system_ticks)) {
/*
* The number of cycles until the timer must fire next might
* not fit in the 32-bit counter register. To work around this,
* program the counter to fire in the maximum number of ticks.
*/
idle_original_ticks = max_system_ticks - 1;
} else {
/* Leave one tick margin time to react when coming back */
idle_original_ticks = ticks - 1;
}
/* Set timer to virtual "one shot" mode. */
timer_mode = TIMER_MODE_ONE_SHOT;
idle_mode = IDLE_TICKLESS;
/*
* We're being asked to have the timer fire in "ticks" from now. To
* maintain accuracy we must account for the remaining time left in the
* timer to the next tick to fire, so that the programmed fire time
* corresponds always on a tick bondary.
*/
P = GET_TIMER_CURRENT_TIME();
f = GET_TIMER_FIRE_TIME();
/*
* Get the time of last tick. As we are entring idle mode we are sure
* that |f - P| < cycles_per_tick.
* |-------f----P---|--------|--------|----F---|--------|--------|
* |-------|----P---f--------|--------|----F---|--------|--------|
* P f-----------s--------->F
*/
if (f < P) {
f = f + cycles_per_tick;
}
F = f + idle_original_ticks * cycles_per_tick;
/* Program the timer register to fire at the right time */
SET_TIMER_FIRE_TIME(F);
}
/**
*
* @brief Handling of tickless idle when interrupted
*
* The routine, called by _sys_power_save_idle_exit, is responsible for taking
* the timer out of idle mode and generating an interrupt at the next
* tick interval. It is expected that interrupts have been disabled.
* Note that in this routine, _sys_idle_elapsed_ticks must be zero because the
* ticker has done its work and consumed all the ticks. This has to be true
* otherwise idle mode wouldn't have been entered in the first place.
*
* @return N/A
*/
void _timer_idle_exit(void)
{
uint32_t C; /* Current time (time within this function execution) */
uint32_t F; /* Idle timer programmed fire time */
uint32_t s; /* Requested idle timer sleep time */
uint32_t e; /* elapsed "Cer time" */
uint32_t r; /*reamining time to the timer to expire */
if (timer_mode == TIMER_MODE_PERIODIC) {
/*
* The timer interrupt handler is handling a completed tickless
* idle
* or this has been called by mistake; there's nothing to do
* here.
*/
return;
}
/*
* This is a tricky logic where we use the particularity of unsigned
* integers computation and overflow/underflow to check for timer expiry
* In adddition to above defined variables, let's define following ones:
* P := Programming time (time within _timer_idle_enter execution)
* M := Maximum programmable value (0xFFFFFFFF)
*
* First case:
0----fired---->P-----not fired---->F---------------fired------------M
0 P<------------s-----F M
0 P C<---r-----F M
0 C<---------P-------------r-----F M
0--------------P-------------r-----F C<----------------M
*
* Second case:
0--not fired-->F-------fired------>P--------------not-fired---------M
0--------s-----F P<-------------------------------M
0--------r-----F C<---------P--------------------------------M
0 C<---r-----F P M
0--------r-----F P C<----------------M
*
* On both case, the timer fired when and only when r >= s.
*/
F = GET_TIMER_FIRE_TIME();
s = idle_original_ticks * cycles_per_tick; /* also s = F - P; */
C = GET_TIMER_CURRENT_TIME();
r = F - C;
/*
* Announce elapsed ticks to the microkernel. Note we are guaranteed
* that the timer ISR will execute before the tick event is serviced,
* so _sys_idle_elapsed_ticks is adjusted to account for it.
*/
e = s - r; /* also e = (C > P ? C - P : C - P + M); */
_sys_idle_elapsed_ticks = e / cycles_per_tick;
if (r >= s) {
/*
* The timer expired. There is nothing to do for this use case.
* There is no need to reprogram the timer, the interrupt is
* being serviced, and the timer ISR will be called after this
* function returns.
*/
} else {
/*
* System was interrupted before the timer fires.
* Reprogram to fire on tick edge: F := C + (r % cpt).
*/
F = C + (r - _sys_idle_elapsed_ticks * cycles_per_tick);
C = GET_TIMER_CURRENT_TIME(); /* Update current time value */
if (F - C < MIN_TIMER_PROG_DELAY) {
/*
* We are too close to the next tick edge. Let's fire
* it manually and reprogram timer to fire on next one.
*/
F += cycles_per_tick;
_sys_idle_elapsed_ticks += 1;
}
SET_TIMER_FIRE_TIME(F);
}
if (_sys_idle_elapsed_ticks) {
_sys_clock_tick_announce();
}
/* Exit timer idle mode */
idle_mode = IDLE_NOT_TICKLESS;
timer_mode = TIMER_MODE_PERIODIC;
}
#endif /* CONFIG_TICKLESS_IDLE */
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
// Internal timer
extern void _zxt_tick_timer_init(void);
unsigned int _xt_tick_divisor; /* cached number of cycles per tick */
/*
* Compute and initialize at run-time the tick divisor (the number of
* processor clock cycles in an RTOS tick, used to set the tick timer).
* Called when the processor clock frequency is not known at compile-time.
*/
void _xt_tick_divisor_init(void)
{
#ifdef XT_CLOCK_FREQ
_xt_tick_divisor = (XT_CLOCK_FREQ / XT_TICK_PER_SEC);
#else
#ifdef XT_BOARD
_xt_tick_divisor = xtbsp_clock_freq_hz() / XT_TICK_PER_SEC;
#else
#error "No way to obtain processor clock frequency"
#endif /* XT_BOARD */
#endif /* XT_CLOCK_FREQ */
}
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
/**
*
* @brief System clock tick handler
*
* This routine handles the system clock periodic tick interrupt. It always
* announces one tick by pushing a TICK_EVENT event onto the microkernel stack.
*
* @return N/A
*/
void _timer_int_handler(void *params)
{
ARG_UNUSED(params);
#ifdef CONFIG_KERNEL_EVENT_LOGGER_INTERRUPT
extern void _sys_k_event_logger_interrupt(void);
_sys_k_event_logger_interrupt();
#endif
/* Announce the tick event to the microkernel. */
_sys_clock_final_tick_announce();
}
/**
*
* @brief Initialize and enable the system clock
*
* This routine is used to program the systick to deliver interrupts at the
* rate specified via the 'sys_clock_us_per_tick' global variable.
*
* @return 0
*/
int _sys_clock_driver_init(struct device *device)
{
#if CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0)
_xt_tick_divisor_init();
/* Set up periodic tick timer (assume enough time to complete init). */
_zxt_tick_timer_init();
#else /* Case of an external timer which is not emulated by internal timer */
/*
* The code below is just an example code that is provided for Xtensa
* customers as an example of how to support external timers.
* The TODOs are here to tell customer what shall be re-implemented.
* This implementation is not fake, it works with an external timer that
* is provided as a systemC example and that could be plugged by using:
* make run EMU_PLATFORM=xtsc-run.
*
*
* The address below is that of the systemC timer example, provided in
* ${ZEPHYR_BASE}/board/xt-sim/xtsc-models/external-irqs.
* Hopefully, this hard-coded address doesn't conflict with anything
* User needs for sure to rewrite this code to fit his timer.
* I do agree that this hope is unlikely to be satisfied, but users who
* don't have external timer will never hit here, and those who do, will
* for sure modify this code in order to initialize their HW.
*/
/* TODO: Implement this case: remove below code and write yours */
volatile uint32_t *p_mmio = (uint32_t *) 0xC0000000; /* start HW reg */
uint32_t interrupt = 0x00000000;
/* Start the timer: Trigger the interrupt source drivers */
*p_mmio = 0xFFFFFFFF;
*p_mmio = interrupt;
/*
* Code above is example code, it is kept here on purpose to let users
* find all code related to external timer support on the same file.
* They will have to rewrite this anyway.
*
* Code below (enabling timer IRQ) is likely to reamin as is.
*/
/* Enable the interrupt handler */
irq_enable(CONFIG_XTENSA_TIMER_IRQ);
#endif /* CONFIG_XTENSA_INTERNAL_TIMER || (CONFIG_XTENSA_TIMER_IRQ < 0) */
#if CONFIG_TICKLESS_IDLE
tickless_idle_init();
#endif
return 0;
}
/**
*
* @brief Read the platform's timer hardware
*
* This routine returns the current time in terms of timer hardware clock
* cycles.
*
* @return up counter of elapsed clock cycles
*/
uint32_t k_cycle_get_32(void)
{
return GET_TIMER_CURRENT_TIME();
}

View file

@ -19,6 +19,8 @@
#include <arch/nios2/arch.h> #include <arch/nios2/arch.h>
#elif defined(CONFIG_RISCV32) #elif defined(CONFIG_RISCV32)
#include <arch/riscv32/arch.h> #include <arch/riscv32/arch.h>
#elif defined(CONFIG_XTENSA)
#include <arch/xtensa/arch.h>
#else #else
#error "Unknown Architecture" #error "Unknown Architecture"
#endif #endif

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef XTENSA_ADDR_TYPES_H
#define XTENSA_ADDR_TYPES_H
#ifndef _ASMLANGUAGE
typedef unsigned int paddr_t;
typedef unsigned int vaddr_t;
#endif
#endif /* XTENSA_ADDR_TYPES_H */

144
include/arch/xtensa/arch.h Normal file
View file

@ -0,0 +1,144 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Xtensa specific kernel interface header
* This header contains the Xtensa specific kernel interface. It is included
* by the generic kernel interface header (include/arch/cpu.h)
*/
#ifndef _ARCH_IFACE_H
#define _ARCH_IFACE_H
#include <irq.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__)
#include "sys_io.h" /* Include from the very same folder of this file */
#include <stdint.h>
#include <sw_isr_table.h>
#include <arch/xtensa/xtensa_irq.h>
#include <xtensa/config/core.h>
/*
* XCC does not define the following macros with the expected names, but the
* file machine/endian.h from XT_LIB defines similar ones. Thus we include it
* and define the missing macros ourselves.
*/
#define __BYTE_ORDER__ XCHAL_MEMORY_ORDER
#define __ORDER_BIG_ENDIAN__ XTHAL_BIGENDIAN
#define __ORDER_LITTLE_ENDIAN__ XTHAL_LITTLEENDIAN
#define STACK_ALIGN 16
#define OCTET_TO_SIZEOFUNIT(X) (X)
#define SIZEOFUNIT_TO_OCTET(X) (X)
#define _NANO_ERR_HW_EXCEPTION (0) /* MPU/Bus/Usage fault */
#define _NANO_ERR_INVALID_TASK_EXIT (1) /* Invalid task exit */
#define _NANO_ERR_STACK_CHK_FAIL (2) /* Stack corruption detected */
#define _NANO_ERR_ALLOCATION_FAIL (3) /* Kernel Allocation Failure */
#define _NANO_ERR_RESERVED_IRQ (4) /* Reserved interrupt */
/* Xtensa GPRs are often designated by two different names */
#define sys_define_gpr_with_alias(name1, name2) union { uint32_t name1, name2; }
#include <arch/xtensa/exc.h>
/**
*
* @brief find most significant bit set in a 32-bit word
*
* This routine finds the first bit set starting from the most significant bit
* in the argument passed in and returns the index of that bit. Bits are
* numbered starting at 1 from the least significant bit. A return value of
* zero indicates that the value passed is zero.
*
* @return most significant bit set, 0 if @a op is 0
*/
static ALWAYS_INLINE unsigned int find_msb_set(uint32_t op)
{
if (!op)
return 0;
return 32 - __builtin_clz(op);
}
/**
*
* @brief find least significant bit set in a 32-bit word
*
* This routine finds the first bit set starting from the least significant bit
* in the argument passed in and returns the index of that bit. Bits are
* numbered starting at 1 from the least significant bit. A return value of
* zero indicates that the value passed is zero.
*
* @return least significant bit set, 0 if @a op is 0
*/
static ALWAYS_INLINE unsigned int find_lsb_set(uint32_t op)
{
return __builtin_ffs(op);
}
/* internal routine documented in C file, needed by IRQ_CONNECT() macro */
extern void _irq_priority_set(uint32_t irq, uint32_t prio, uint32_t flags);
/**
* Configure a static interrupt.
*
* All arguments must be computable by the compiler at build time; if this
* can't be done use irq_connect_dynamic() instead.
*
* Internally this function does a few things:
*
* 1. The enum statement has no effect but forces the compiler to only
* accept constant values for the irq_p parameter, very important as the
* numerical IRQ line is used to create a named section.
*
* 2. An instance of _isr_table_entry is created containing the ISR and its
* parameter. If you look at how _sw_isr_table is created, each entry in the
* array is in its own section named by the IRQ line number. What we are doing
* here is to override one of the default entries (which points to the
* spurious IRQ handler) with what was supplied here.
*
* 3. The priority level for the interrupt is configured by a call to
* _irq_priority_set()
*
* @param irq_p IRQ line number
* @param priority_p Interrupt priority
* @param isr_p Interrupt service routine
* @param isr_param_p ISR parameter
* @param flags_p IRQ options
*
* @return The vector assigned to this interrupt
*/
#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
({ \
enum { IRQ = irq_p }; \
static struct _isr_table_entry \
_CONCAT(_isr_irq, irq_p) \
__attribute__ ((used)) \
__attribute__ ((section(\
STRINGIFY(_CONCAT(.gnu.linkonce.d.isr_irq, irq_p)))\
)) = {isr_param_p, isr_p}; \
_irq_priority_set(irq_p, priority_p, flags_p); \
irq_p; \
})
FUNC_NORETURN void _SysFatalErrorHandler(unsigned int reason,
const NANO_ESF *esf);
#endif /* !defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__) */
#ifdef __cplusplus
}
#endif
#endif /* _ARCH_IFACE_H */

45
include/arch/xtensa/exc.h Normal file
View file

@ -0,0 +1,45 @@
/*
* Copyright (c) 2014 Wind River Systems, Inc.
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Xtensa public exception handling
*
* Xtensa-specific nanokernel exception handling interface. Included by
* arch/xtensa/arch.h.
*/
#ifndef _ARCH_XTENSA_EXC_H_
#define _ARCH_XTENSA_EXC_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _ASMLANGUAGE
#else
/**
* @brief Nanokernel Exception Stack Frame
*
* A pointer to an "exception stack frame" (ESF) is passed as an argument
* to exception handlers registered via nanoCpuExcConnect().
*/
struct __esf {
/* XXX - not finished yet */
sys_define_gpr_with_alias(a1, sp);
uint32_t pc;
};
typedef struct __esf NANO_ESF;
extern const NANO_ESF _default_esf;
#endif
#ifdef __cplusplus
}
#endif
#endif /* _ARCH_XTENSA_EXC_H_ */

View file

@ -0,0 +1,11 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef OFFSETS_H
#define OFFSETS_H
#endif /* OFFSETS_H */

View file

@ -0,0 +1,113 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef XTENSA_SYS_IO_H
#define XTENSA_SYS_IO_H
#if !defined(_ASMLANGUAGE)
#include <sys_io.h>
/* Memory mapped registers I/O functions */
static ALWAYS_INLINE uint32_t sys_read32(mem_addr_t addr)
{
return *(volatile uint32_t *)addr;
}
static ALWAYS_INLINE void sys_write32(uint32_t data, mem_addr_t addr)
{
*(volatile uint32_t *)addr = data;
}
/* Memory bit manipulation functions */
static ALWAYS_INLINE void sys_set_bit(mem_addr_t addr, unsigned int bit)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp | (1 << bit);
}
static ALWAYS_INLINE void sys_clear_bit(mem_addr_t addr, unsigned int bit)
{
uint32_t temp = *(volatile uint32_t *)addr;
*(volatile uint32_t *)addr = temp & ~(1 << bit);
}
static ALWAYS_INLINE int sys_test_bit(mem_addr_t addr, unsigned int bit)
{
int temp = *(volatile int *)addr;
return (int)(temp & (1 << bit));
}
static ALWAYS_INLINE int sys_test_and_set_bit(mem_addr_t addr, unsigned int bit)
{
int retval = (*(volatile int *)addr) & (1 << bit);
*(volatile int *)addr = (*(volatile int *)addr) | (1 << bit);
return retval;
}
static ALWAYS_INLINE
int sys_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
{
int retval = (*(volatile int *)addr) & (1 << bit);
*(volatile int *)addr = (*(volatile int *)addr) & ~(1 << bit);
return retval;
}
static ALWAYS_INLINE
void sys_bitfield_set_bit(mem_addr_t addr, unsigned int bit)
{
/* Doing memory offsets in terms of 32-bit values to prevent
* alignment issues
*/
sys_set_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
void sys_bitfield_clear_bit(mem_addr_t addr, unsigned int bit)
{
sys_clear_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_bitfield_test_bit(mem_addr_t addr, unsigned int bit)
{
return sys_test_bit(addr + ((bit >> 5) << 2), bit & 0x1F);
}
static ALWAYS_INLINE
int sys_bitfield_test_and_set_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_bitfield_test_bit(addr, bit);
sys_bitfield_set_bit(addr, bit);
return ret;
}
static ALWAYS_INLINE
int sys_bitfield_test_and_clear_bit(mem_addr_t addr, unsigned int bit)
{
int ret;
ret = sys_bitfield_test_bit(addr, bit);
sys_bitfield_clear_bit(addr, bit);
return ret;
}
#endif /* !_ASMLANGUAGE */
#endif /* XTENSA_SYS_IO_H */

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2016 Cadence Design Systems, Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef XTENSA_IRQ_H
#define XTENSA_IRQ_H
#include <xtensa_api.h>
#include <xtensa/xtruntime.h>
/**
*
* @brief Enable an interrupt line
*
* Clear possible pending interrupts on the line, and enable the interrupt
* line. After this call, the CPU will receive interrupts for the specified
* IRQ.
*
* @return N/A
*/
static ALWAYS_INLINE void _arch_irq_enable(uint32_t irq)
{
_xt_ints_on(1 << irq);
}
/**
*
* @brief Disable an interrupt line
*
* Disable an interrupt line. After this call, the CPU will stop receiving
* interrupts for the specified IRQ.
*
* @return N/A
*/
static ALWAYS_INLINE void _arch_irq_disable(uint32_t irq)
{
_xt_ints_off(1 << irq);
}
static ALWAYS_INLINE unsigned int _arch_irq_lock(void)
{
unsigned int key = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL);
return key;
}
static ALWAYS_INLINE void _arch_irq_unlock(unsigned int key)
{
XTOS_RESTORE_INTLEVEL(key);
}
#include <irq.h>
#endif /* XTENSA_IRQ_H */

View file

@ -375,7 +375,7 @@ struct _static_thread_data {
entry, p1, p2, p3, \ entry, p1, p2, p3, \
prio, options, delay, abort, groups) \ prio, options, delay, abort, groups) \
{ \ { \
.init_stack = (stack), \ {.init_stack = (stack)}, \
.init_stack_size = (stack_size), \ .init_stack_size = (stack_size), \
.init_entry = (void (*)(void *, void *, void *))entry, \ .init_entry = (void (*)(void *, void *, void *))entry, \
.init_p1 = (void *)p1, \ .init_p1 = (void *)p1, \
@ -2972,7 +2972,7 @@ __asm__(".macro _build_mem_pool name, min_size, max_size, n_max\n\t"
static void __attribute__ ((used)) __k_mem_pool_quad_block_size_define(void) static void __attribute__ ((used)) __k_mem_pool_quad_block_size_define(void)
{ {
__asm__(".globl __memory_pool_quad_block_size\n\t" __asm__(".globl __memory_pool_quad_block_size\n\t"
#ifdef CONFIG_NIOS2 #if defined(CONFIG_NIOS2) || defined(CONFIG_XTENSA)
"__memory_pool_quad_block_size = %0\n\t" "__memory_pool_quad_block_size = %0\n\t"
#else #else
"__memory_pool_quad_block_size = %c0\n\t" "__memory_pool_quad_block_size = %c0\n\t"

View file

@ -84,7 +84,7 @@ typedef int nano_context_type_t;
abort, prio, groups) \ abort, prio, groups) \
char __noinit __stack _k_thread_obj_##name[stack_size]; \ char __noinit __stack _k_thread_obj_##name[stack_size]; \
struct _static_thread_data _k_thread_data_##name __aligned(4) \ struct _static_thread_data _k_thread_data_##name __aligned(4) \
__in_section(_static_thread_data, static, name) = \ _GENERIC_SECTION(._static_thread_data.static.mdef) = \
_THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \ _THREAD_INITIALIZER(_k_thread_obj_##name, stack_size, \
entry, p1, p2, p3, prio, 0, K_FOREVER, \ entry, p1, p2, p3, prio, 0, K_FOREVER, \
abort, groups) abort, groups)

Some files were not shown because too many files have changed in this diff Show more