GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2007 - 2013 Tensilica, Inc.
|
||||
# (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
|
||||
|
||||
obj-y = cpu.o exceptions.o
|
||||
extra-y = start.o
|
||||
@@ -0,0 +1,54 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2008 - 2013 Tensilica Inc.
|
||||
* (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CPU specific code
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <vsprintf.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <asm/cache.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/misc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
gd_t *gd __attribute__((section(".data")));
|
||||
|
||||
#if defined(CONFIG_DISPLAY_CPUINFO)
|
||||
/*
|
||||
* Print information about the CPU.
|
||||
*/
|
||||
|
||||
int print_cpuinfo(void)
|
||||
{
|
||||
char buf[120], mhz[8];
|
||||
uint32_t id0, id1;
|
||||
|
||||
asm volatile ("rsr %0, 176\n"
|
||||
"rsr %1, 208\n"
|
||||
: "=r"(id0), "=r"(id1));
|
||||
|
||||
sprintf(buf, "CPU: Xtensa %s (id: %08x:%08x) at %s MHz\n",
|
||||
XCHAL_CORE_ID, id0, id1, strmhz(mhz, gd->cpu_clk));
|
||||
puts(buf);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dram_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2008 - 2013 Tensilica Inc.
|
||||
* (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Exception handling.
|
||||
* We currently don't handle any exception and force a reset.
|
||||
* (Note that alloca is a special case and handled in start.S)
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <irq_func.h>
|
||||
#include <asm/string.h>
|
||||
#include <asm/regs.h>
|
||||
|
||||
typedef void (*handler_t)(struct pt_regs *);
|
||||
|
||||
void unhandled_exception(struct pt_regs *regs)
|
||||
{
|
||||
printf("Unhandled Exception: EXCCAUSE = %ld, EXCVADDR = %lx, pc = %lx\n",
|
||||
regs->exccause, regs->excvaddr, regs->pc);
|
||||
panic("*** PANIC\n");
|
||||
}
|
||||
|
||||
handler_t exc_table[EXCCAUSE_LAST] = {
|
||||
[0 ... EXCCAUSE_LAST-1] = unhandled_exception,
|
||||
};
|
||||
|
||||
int interrupt_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void enable_interrupts(void)
|
||||
{
|
||||
}
|
||||
|
||||
int disable_interrupts(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,676 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2008 - 2013 Tensilica Inc.
|
||||
* (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/asmmacro.h>
|
||||
#include <asm/cacheasm.h>
|
||||
#include <asm/regs.h>
|
||||
#include <asm/arch/tie.h>
|
||||
#include <asm-offsets.h>
|
||||
|
||||
/*
|
||||
* Offsets into the the pt_regs struture.
|
||||
* Make sure these always match with the structure defined in ptrace.h!
|
||||
*/
|
||||
|
||||
#define PT_PC 0
|
||||
#define PT_PS 4
|
||||
#define PT_DEPC 8
|
||||
#define PT_EXCCAUSE 12
|
||||
#define PT_EXCVADDR 16
|
||||
#define PT_DEBUGCAUSE 20
|
||||
#define PT_WMASK 24
|
||||
#define PT_LBEG 28
|
||||
#define PT_LEND 32
|
||||
#define PT_LCOUNT 36
|
||||
#define PT_SAR 40
|
||||
#define PT_WINDOWBASE 44
|
||||
#define PT_WINDOWSTART 48
|
||||
#define PT_SYSCALL 52
|
||||
#define PT_ICOUNTLEVEL 56
|
||||
#define PT_RESERVED 60
|
||||
#define PT_AREG 64
|
||||
#define PT_SIZE (64 + 64)
|
||||
|
||||
/*
|
||||
* Cache attributes are different for full MMU and region protection.
|
||||
*/
|
||||
|
||||
#if XCHAL_HAVE_PTP_MMU
|
||||
#define CA_WRITEBACK (0x7)
|
||||
#else
|
||||
#define CA_WRITEBACK (0x4)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Reset vector.
|
||||
* Only a trampoline to jump to _start
|
||||
* (Note that we have to mark the section writable as the section contains
|
||||
* a relocatable literal)
|
||||
*/
|
||||
|
||||
.section .ResetVector.text, "awx"
|
||||
.global _ResetVector
|
||||
_ResetVector:
|
||||
|
||||
j 1f
|
||||
.align 4
|
||||
2: .long _start
|
||||
1: l32r a2, 2b
|
||||
jx a2
|
||||
|
||||
|
||||
/*
|
||||
* Processor initialization. We still run in rom space.
|
||||
*
|
||||
* NOTE: Running in ROM
|
||||
* For Xtensa, we currently don't allow to run some code from ROM but
|
||||
* unpack the data immediately to memory. This requires, for example,
|
||||
* that DDR has been set up before running U-Boot. (See also comments
|
||||
* inline for ways to change it)
|
||||
*/
|
||||
|
||||
.section .reset.text, "ax"
|
||||
.global _start
|
||||
.align 4
|
||||
_start:
|
||||
/* Keep a0 = 0 for various initializations */
|
||||
|
||||
movi a0, 0
|
||||
|
||||
/*
|
||||
* For full MMU cores, put page table at unmapped virtual address.
|
||||
* This ensures that accesses outside the static maps result
|
||||
* in miss exceptions rather than random behaviour.
|
||||
*/
|
||||
|
||||
#if XCHAL_HAVE_PTP_MMU
|
||||
wsr a0, PTEVADDR
|
||||
#endif
|
||||
|
||||
/* Disable dbreak debug exceptions */
|
||||
|
||||
#if XCHAL_HAVE_DEBUG && XCHAL_NUM_DBREAK > 0
|
||||
.set _index, 0
|
||||
.rept XCHAL_NUM_DBREAK
|
||||
wsr a0, DBREAKC + _index
|
||||
.set _index, _index + 1
|
||||
.endr
|
||||
#endif
|
||||
|
||||
/* Reset windowbase and windowstart */
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
movi a3, 1
|
||||
wsr a3, windowstart
|
||||
wsr a0, windowbase
|
||||
rsync
|
||||
movi a0, 0 /* windowbase might have changed */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Vecbase in bitstream may differ from header files
|
||||
* set or check it.
|
||||
*/
|
||||
|
||||
#if XCHAL_HAVE_VECBASE
|
||||
movi a3, XCHAL_VECBASE_RESET_VADDR /* VECBASE reset value */
|
||||
wsr a3, VECBASE
|
||||
#endif
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
/* Disable loops */
|
||||
|
||||
wsr a0, LCOUNT
|
||||
#endif
|
||||
|
||||
/* Set PS.WOE = 0, PS.EXCM = 0 (for loop), PS.INTLEVEL = EXCM level */
|
||||
|
||||
#if XCHAL_HAVE_XEA1
|
||||
movi a2, 1
|
||||
#else
|
||||
movi a2, XCHAL_EXCM_LEVEL
|
||||
#endif
|
||||
wsr a2, PS
|
||||
rsync
|
||||
|
||||
/* Unlock and invalidate caches */
|
||||
|
||||
___unlock_dcache_all a2, a3
|
||||
___invalidate_dcache_all a2, a3
|
||||
___unlock_icache_all a2, a3
|
||||
___invalidate_icache_all a2, a3
|
||||
|
||||
isync
|
||||
|
||||
/* Unpack data sections */
|
||||
|
||||
movi a2, __reloc_table_start
|
||||
movi a3, __reloc_table_end
|
||||
|
||||
1: beq a2, a3, 3f # no more entries?
|
||||
l32i a4, a2, 0 # start destination (in RAM)
|
||||
l32i a5, a2, 4 # end destination (in RAM)
|
||||
l32i a6, a2, 8 # start source (in ROM)
|
||||
addi a2, a2, 12 # next entry
|
||||
beq a4, a5, 1b # skip, empty entry
|
||||
beq a4, a6, 1b # skip, source and destination are the same
|
||||
|
||||
/* If there's memory protection option with 512MB TLB regions and
|
||||
* cache attributes in TLB entries and caching is not inhibited,
|
||||
* enable data/instruction cache for relocated image.
|
||||
*/
|
||||
#if XCHAL_HAVE_SPANNING_WAY && \
|
||||
!(CONFIG_IS_ENABLED(SYS_DCACHE_OFF) && \
|
||||
CONFIG_IS_ENABLED(SYS_ICACHE_OFF))
|
||||
srli a7, a4, 29
|
||||
slli a7, a7, 29
|
||||
addi a7, a7, XCHAL_SPANNING_WAY
|
||||
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
|
||||
rdtlb1 a8, a7
|
||||
srli a8, a8, 4
|
||||
slli a8, a8, 4
|
||||
addi a8, a8, CA_WRITEBACK
|
||||
wdtlb a8, a7
|
||||
#endif
|
||||
#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF)
|
||||
ritlb1 a8, a7
|
||||
srli a8, a8, 4
|
||||
slli a8, a8, 4
|
||||
addi a8, a8, CA_WRITEBACK
|
||||
witlb a8, a7
|
||||
#endif
|
||||
isync
|
||||
#endif
|
||||
|
||||
2: l32i a7, a6, 0
|
||||
addi a6, a6, 4
|
||||
s32i a7, a4, 0
|
||||
addi a4, a4, 4
|
||||
bltu a4, a5, 2b
|
||||
j 1b
|
||||
|
||||
3: /* All code and initalized data segments have been copied */
|
||||
|
||||
/* Setup PS, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */
|
||||
|
||||
#if __XTENSA_CALL0_ABI__
|
||||
movi a2, XCHAL_EXCM_LEVEL
|
||||
#else
|
||||
movi a2, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL
|
||||
#endif
|
||||
wsr a2, PS
|
||||
rsync
|
||||
|
||||
/* Writeback */
|
||||
|
||||
___flush_dcache_all a2, a3
|
||||
|
||||
#ifdef __XTENSA_WINDOWED_ABI__
|
||||
/*
|
||||
* In windowed ABI caller and call target need to be within the same
|
||||
* gigabyte. Put the rest of the code into the text segment and jump
|
||||
* there.
|
||||
*/
|
||||
|
||||
movi a4, .Lboard_init_code
|
||||
jx a4
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.Lboard_init_code:
|
||||
#endif
|
||||
|
||||
movi a0, 0
|
||||
movi sp, (XTENSA_SYS_TEXT_ADDR - 16) & 0xfffffff0
|
||||
|
||||
#ifdef CONFIG_DEBUG_UART
|
||||
movi a4, debug_uart_init
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
callx0 a4
|
||||
#else
|
||||
callx4 a4
|
||||
#endif
|
||||
#endif
|
||||
|
||||
movi a4, board_init_f_alloc_reserve
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
mov a2, sp
|
||||
callx0 a4
|
||||
mov sp, a2
|
||||
#else
|
||||
mov a6, sp
|
||||
callx4 a4
|
||||
movsp sp, a6
|
||||
#endif
|
||||
|
||||
movi a4, board_init_f_init_reserve
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
callx0 a4
|
||||
#else
|
||||
callx4 a4
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Call board initialization routine (never returns).
|
||||
*/
|
||||
|
||||
movi a4, board_init_f
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
movi a2, 0
|
||||
callx0 a4
|
||||
#else
|
||||
movi a6, 0
|
||||
callx4 a4
|
||||
#endif
|
||||
/* Never Returns */
|
||||
ill
|
||||
|
||||
/*
|
||||
* void relocate_code (addr_sp, gd, addr_moni)
|
||||
*
|
||||
* This "function" does not return, instead it continues in RAM
|
||||
* after relocating the monitor code.
|
||||
*
|
||||
* a2 = addr_sp
|
||||
* a3 = gd
|
||||
* a4 = destination address
|
||||
*/
|
||||
.text
|
||||
.globl relocate_code
|
||||
.align 4
|
||||
relocate_code:
|
||||
abi_entry
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
mov a1, a2
|
||||
mov a2, a3
|
||||
mov a3, a4
|
||||
movi a0, board_init_r
|
||||
callx0 a0
|
||||
#else
|
||||
/* We can't movsp here, because the chain of stack frames may cross
|
||||
* the now reserved memory. We need to toss all window frames except
|
||||
* the current, create new pristine stack frame and start from scratch.
|
||||
*/
|
||||
rsr a0, windowbase
|
||||
ssl a0
|
||||
movi a0, 1
|
||||
sll a0, a0
|
||||
wsr a0, windowstart
|
||||
rsync
|
||||
|
||||
movi a0, 0
|
||||
|
||||
/* Reserve 16-byte save area */
|
||||
addi sp, a2, -16
|
||||
mov a6, a3
|
||||
mov a7, a4
|
||||
movi a4, board_init_r
|
||||
callx4 a4
|
||||
#endif
|
||||
ill
|
||||
|
||||
#if XCHAL_HAVE_EXCEPTIONS
|
||||
|
||||
/*
|
||||
* Exception vectors.
|
||||
*
|
||||
* Various notes:
|
||||
* - We currently don't use the user exception vector (PS.UM is always 0),
|
||||
* but do define such a vector, just in case. They both jump to the
|
||||
* same exception handler, though.
|
||||
* - We currently only save the bare minimum number of registers:
|
||||
* a0...a15, sar, loop-registers, exception register (epc1, excvaddr,
|
||||
* exccause, depc)
|
||||
* - WINDOWSTART is only saved to identify if registers have been spilled
|
||||
* to the wrong stack (exception stack) while executing the exception
|
||||
* handler.
|
||||
*/
|
||||
|
||||
.section .KernelExceptionVector.text, "ax"
|
||||
.global _KernelExceptionVector
|
||||
_KernelExceptionVector:
|
||||
|
||||
wsr a2, EXCSAVE1
|
||||
movi a2, ExceptionHandler
|
||||
jx a2
|
||||
|
||||
.section .UserExceptionVector.text, "ax"
|
||||
.global _UserExceptionVector
|
||||
_UserExceptionVector:
|
||||
|
||||
wsr a2, EXCSAVE1
|
||||
movi a2, ExceptionHandler
|
||||
jx a2
|
||||
|
||||
#if !XCHAL_HAVE_XEA1
|
||||
.section .DoubleExceptionVector.text, "ax"
|
||||
.global _DoubleExceptionVector
|
||||
_DoubleExceptionVector:
|
||||
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
wsr a0, EXCSAVE1
|
||||
movi a0, hang # report and ask user to reset board
|
||||
callx0 a0
|
||||
#else
|
||||
wsr a4, EXCSAVE1
|
||||
movi a4, hang # report and ask user to reset board
|
||||
callx4 a4
|
||||
#endif
|
||||
#endif
|
||||
/* Does not return here */
|
||||
|
||||
|
||||
.text
|
||||
.align 4
|
||||
ExceptionHandler:
|
||||
|
||||
rsr a2, EXCCAUSE # find handler
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
/* Special case for alloca handler */
|
||||
|
||||
bnei a2, 5, 1f # jump if not alloca exception
|
||||
|
||||
addi a1, a1, -16 - 4 # create a small stack frame
|
||||
s32i a3, a1, 0 # and save a3 (a2 still in excsave1)
|
||||
movi a2, fast_alloca_exception
|
||||
jx a2 # jump to fast_alloca_exception
|
||||
#endif
|
||||
/* All other exceptions go here: */
|
||||
|
||||
/* Create ptrace stack and save a0...a3 */
|
||||
|
||||
1: addi a2, a1, - PT_SIZE - 16
|
||||
s32i a0, a2, PT_AREG + 0 * 4
|
||||
s32i a1, a2, PT_AREG + 1 * 4
|
||||
s32i a3, a2, PT_AREG + 3 * 4
|
||||
rsr a3, EXCSAVE1
|
||||
s32i a3, a2, PT_AREG + 2 * 4
|
||||
mov a1, a2
|
||||
|
||||
/* Save remaining AR registers */
|
||||
|
||||
s32i a4, a1, PT_AREG + 4 * 4
|
||||
s32i a5, a1, PT_AREG + 5 * 4
|
||||
s32i a6, a1, PT_AREG + 6 * 4
|
||||
s32i a7, a1, PT_AREG + 7 * 4
|
||||
s32i a8, a1, PT_AREG + 8 * 4
|
||||
s32i a9, a1, PT_AREG + 9 * 4
|
||||
s32i a10, a1, PT_AREG + 10 * 4
|
||||
s32i a11, a1, PT_AREG + 11 * 4
|
||||
s32i a12, a1, PT_AREG + 12 * 4
|
||||
s32i a13, a1, PT_AREG + 13 * 4
|
||||
s32i a14, a1, PT_AREG + 14 * 4
|
||||
s32i a15, a1, PT_AREG + 15 * 4
|
||||
|
||||
/* Save SRs */
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
rsr a2, WINDOWSTART
|
||||
s32i a2, a1, PT_WINDOWSTART
|
||||
#endif
|
||||
|
||||
rsr a2, SAR
|
||||
rsr a3, EPC1
|
||||
rsr a4, EXCVADDR
|
||||
s32i a2, a1, PT_SAR
|
||||
s32i a3, a1, PT_PC
|
||||
s32i a4, a1, PT_EXCVADDR
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
movi a2, 0
|
||||
rsr a3, LBEG
|
||||
xsr a2, LCOUNT
|
||||
s32i a3, a1, PT_LBEG
|
||||
rsr a3, LEND
|
||||
s32i a2, a1, PT_LCOUNT
|
||||
s32i a3, a1, PT_LEND
|
||||
#endif
|
||||
|
||||
/* Set up C environment and call registered handler */
|
||||
/* Setup stack, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */
|
||||
|
||||
rsr a2, EXCCAUSE
|
||||
#if XCHAL_HAVE_XEA1
|
||||
movi a3, (1<<PS_WOE_BIT) | 1
|
||||
#elif __XTENSA_CALL0_ABI__
|
||||
movi a3, XCHAL_EXCM_LEVEL
|
||||
#else
|
||||
movi a3, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL
|
||||
#endif
|
||||
xsr a3, PS
|
||||
rsync
|
||||
s32i a2, a1, PT_EXCCAUSE
|
||||
s32i a3, a1, PT_PS
|
||||
|
||||
movi a0, exc_table
|
||||
addx4 a0, a2, a0
|
||||
l32i a0, a0, 0
|
||||
#ifdef __XTENSA_CALL0_ABI__
|
||||
mov a2, a1 # Provide stack frame as only argument
|
||||
callx0 a0
|
||||
l32i a3, a1, PT_PS
|
||||
#else
|
||||
mov a6, a1 # Provide stack frame as only argument
|
||||
callx4 a0
|
||||
#endif
|
||||
|
||||
/* Restore PS and go to exception mode (PS.EXCM=1) */
|
||||
|
||||
wsr a3, PS
|
||||
|
||||
/* Restore SR registers */
|
||||
|
||||
#if XCHAL_HAVE_LOOPS
|
||||
l32i a2, a1, PT_LBEG
|
||||
l32i a3, a1, PT_LEND
|
||||
l32i a4, a1, PT_LCOUNT
|
||||
wsr a2, LBEG
|
||||
wsr a3, LEND
|
||||
wsr a4, LCOUNT
|
||||
#endif
|
||||
|
||||
l32i a2, a1, PT_SAR
|
||||
l32i a3, a1, PT_PC
|
||||
wsr a2, SAR
|
||||
wsr a3, EPC1
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
/* Do we need to simulate a MOVSP? */
|
||||
|
||||
l32i a2, a1, PT_WINDOWSTART
|
||||
addi a3, a2, -1
|
||||
and a2, a2, a3
|
||||
beqz a2, 1f # Skip if regs were spilled before exc.
|
||||
|
||||
rsr a2, WINDOWSTART
|
||||
addi a3, a2, -1
|
||||
and a2, a2, a3
|
||||
bnez a2, 1f # Skip if registers aren't spilled now
|
||||
|
||||
addi a2, a1, -16
|
||||
l32i a4, a2, 0
|
||||
l32i a5, a2, 4
|
||||
s32i a4, a1, PT_SIZE + 0
|
||||
s32i a5, a1, PT_SIZE + 4
|
||||
l32i a4, a2, 8
|
||||
l32i a5, a2, 12
|
||||
s32i a4, a1, PT_SIZE + 8
|
||||
s32i a5, a1, PT_SIZE + 12
|
||||
#endif
|
||||
|
||||
/* Restore address register */
|
||||
|
||||
1: l32i a15, a1, PT_AREG + 15 * 4
|
||||
l32i a14, a1, PT_AREG + 14 * 4
|
||||
l32i a13, a1, PT_AREG + 13 * 4
|
||||
l32i a12, a1, PT_AREG + 12 * 4
|
||||
l32i a11, a1, PT_AREG + 11 * 4
|
||||
l32i a10, a1, PT_AREG + 10 * 4
|
||||
l32i a9, a1, PT_AREG + 9 * 4
|
||||
l32i a8, a1, PT_AREG + 8 * 4
|
||||
l32i a7, a1, PT_AREG + 7 * 4
|
||||
l32i a6, a1, PT_AREG + 6 * 4
|
||||
l32i a5, a1, PT_AREG + 5 * 4
|
||||
l32i a4, a1, PT_AREG + 4 * 4
|
||||
l32i a3, a1, PT_AREG + 3 * 4
|
||||
l32i a2, a1, PT_AREG + 2 * 4
|
||||
l32i a0, a1, PT_AREG + 0 * 4
|
||||
|
||||
l32i a1, a1, PT_AREG + 1 * 4 # Remove ptrace stack frame
|
||||
|
||||
rfe
|
||||
|
||||
#endif /* XCHAL_HAVE_EXCEPTIONS */
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
|
||||
/*
|
||||
* Window overflow and underflow handlers.
|
||||
* The handlers must be 64 bytes apart, first starting with the underflow
|
||||
* handlers underflow-4 to underflow-12, then the overflow handlers
|
||||
* overflow-4 to overflow-12.
|
||||
*
|
||||
* Note: We rerun the underflow handlers if we hit an exception, so
|
||||
* we try to access any page that would cause a page fault early.
|
||||
*/
|
||||
|
||||
.section .WindowVectors.text, "ax"
|
||||
|
||||
/* 4-Register Window Overflow Vector (Handler) */
|
||||
|
||||
.align 64
|
||||
.global _WindowOverflow4
|
||||
_WindowOverflow4:
|
||||
s32e a0, a5, -16
|
||||
s32e a1, a5, -12
|
||||
s32e a2, a5, -8
|
||||
s32e a3, a5, -4
|
||||
rfwo
|
||||
|
||||
|
||||
/* 4-Register Window Underflow Vector (Handler) */
|
||||
|
||||
.align 64
|
||||
.global _WindowUnderflow4
|
||||
_WindowUnderflow4:
|
||||
l32e a0, a5, -16
|
||||
l32e a1, a5, -12
|
||||
l32e a2, a5, -8
|
||||
l32e a3, a5, -4
|
||||
rfwu
|
||||
|
||||
/*
|
||||
* a0: a0
|
||||
* a1: new stack pointer = a1 - 16 - 4
|
||||
* a2: available, saved in excsave1
|
||||
* a3: available, saved on stack *a1
|
||||
*/
|
||||
|
||||
/* 15*/ .byte 0xff
|
||||
|
||||
fast_alloca_exception: /* must be at _WindowUnderflow4 + 16 */
|
||||
|
||||
/* 16*/ rsr a2, PS
|
||||
/* 19*/ rsr a3, WINDOWBASE
|
||||
/* 22*/ extui a2, a2, PS_OWB_SHIFT, PS_OWB_SHIFT
|
||||
/* 25*/ xor a2, a2, a3
|
||||
/* 28*/ rsr a3, PS
|
||||
/* 31*/ slli a2, a2, PS_OWB_SHIFT
|
||||
/* 34*/ xor a2, a3, a2
|
||||
/* 37*/ wsr a2, PS
|
||||
|
||||
/* 40*/ _l32i a3, a1, 0
|
||||
/* 43*/ addi a1, a1, 16 + 4
|
||||
/* 46*/ rsr a2, EXCSAVE1
|
||||
|
||||
/* 49*/ rotw -1
|
||||
/* 52*/ _bbci.l a4, 31, _WindowUnderflow4 /* 0x: call4 */
|
||||
/* 55*/ rotw -1
|
||||
/* 58*/ _bbci.l a8, 30, _WindowUnderflow8 /* 10: call8 */
|
||||
/* 61*/ _j __WindowUnderflow12 /* 11: call12 */
|
||||
/* 64*/
|
||||
|
||||
/* 8-Register Window Overflow Vector (Handler) */
|
||||
|
||||
.align 64
|
||||
.global _WindowOverflow8
|
||||
_WindowOverflow8:
|
||||
s32e a0, a9, -16
|
||||
l32e a0, a1, -12
|
||||
s32e a2, a9, -8
|
||||
s32e a1, a9, -12
|
||||
s32e a3, a9, -4
|
||||
s32e a4, a0, -32
|
||||
s32e a5, a0, -28
|
||||
s32e a6, a0, -24
|
||||
s32e a7, a0, -20
|
||||
rfwo
|
||||
|
||||
/* 8-Register Window Underflow Vector (Handler) */
|
||||
|
||||
.align 64
|
||||
.global _WindowUnderflow8
|
||||
_WindowUnderflow8:
|
||||
l32e a1, a9, -12
|
||||
l32e a0, a9, -16
|
||||
l32e a7, a1, -12
|
||||
l32e a2, a9, -8
|
||||
l32e a4, a7, -32
|
||||
l32e a3, a9, -4
|
||||
l32e a5, a7, -28
|
||||
l32e a6, a7, -24
|
||||
l32e a7, a7, -20
|
||||
rfwu
|
||||
|
||||
/* 12-Register Window Overflow Vector (Handler) */
|
||||
|
||||
.align 64
|
||||
.global _WindowOverflow12
|
||||
_WindowOverflow12:
|
||||
s32e a0, a13, -16
|
||||
l32e a0, a1, -12
|
||||
s32e a1, a13, -12
|
||||
s32e a2, a13, -8
|
||||
s32e a3, a13, -4
|
||||
s32e a4, a0, -48
|
||||
s32e a5, a0, -44
|
||||
s32e a6, a0, -40
|
||||
s32e a7, a0, -36
|
||||
s32e a8, a0, -32
|
||||
s32e a9, a0, -28
|
||||
s32e a10, a0, -24
|
||||
s32e a11, a0, -20
|
||||
rfwo
|
||||
|
||||
/* 12-Register Window Underflow Vector (Handler) */
|
||||
|
||||
.org _WindowOverflow12 + 64 - 3
|
||||
__WindowUnderflow12:
|
||||
rotw -1
|
||||
.global _WindowUnderflow12
|
||||
_WindowUnderflow12:
|
||||
l32e a1, a13, -12
|
||||
l32e a0, a13, -16
|
||||
l32e a11, a1, -12
|
||||
l32e a2, a13, -8
|
||||
l32e a4, a11, -48
|
||||
l32e a8, a11, -32
|
||||
l32e a3, a13, -4
|
||||
l32e a5, a11, -44
|
||||
l32e a6, a11, -40
|
||||
l32e a7, a11, -36
|
||||
l32e a9, a11, -28
|
||||
l32e a10, a11, -24
|
||||
l32e a11, a11, -20
|
||||
rfwu
|
||||
|
||||
#endif /* XCHAL_HAVE_WINDOWED */
|
||||
@@ -0,0 +1,115 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* (C) Copyright 2008 - 2013 Tensilica, Inc.
|
||||
* (C) Copyright 2014 - 2016 Cadence Design Systems Inc.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <asm/ldscript.h>
|
||||
#include <asm/arch/core.h>
|
||||
#include <asm/addrspace.h>
|
||||
#include <asm-offsets.h>
|
||||
|
||||
OUTPUT_ARCH(xtensa)
|
||||
ENTRY(_start)
|
||||
|
||||
/*
|
||||
* U-Boot resets from SYSROM and unpacks itself from a ROM store to RAM.
|
||||
* The reset vector is usually near the base of SYSROM and has room
|
||||
* above it for the ROM store into which the rest of U-Boot is packed.
|
||||
* The ROM store also needs to be above any other vectors that are in ROM.
|
||||
* If a core has its vectors near the top of ROM, this must be edited.
|
||||
*
|
||||
* Note that to run C code out of ROM, the processor would have to support
|
||||
* 'relocatable' exception vectors and provide a scratch memory for the
|
||||
* initial stack. Not all Xtensa processor configurations support that, so
|
||||
* we can simplify the boot process and unpack U-Boot to RAM immediately.
|
||||
* This, however, requires that memory have been initialized throug some
|
||||
* other means (serial ROM, for example) or are initialized early (requiring
|
||||
* an assembler function. See start.S for more details)
|
||||
*/
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = + SIZEOF_HEADERS;
|
||||
SECTION_ResetVector(XCHAL_RESET_VECTOR_VADDR, LMA_EQ_VMA)
|
||||
|
||||
.reloc_table ALIGN(4) : FOLLOWING(.ResetVector.text)
|
||||
{
|
||||
__reloc_table_start = ABSOLUTE(.);
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
RELOCATE2(WindowVectors,text);
|
||||
#endif
|
||||
RELOCATE2(KernelExceptionVector,literal);
|
||||
RELOCATE2(KernelExceptionVector,text);
|
||||
RELOCATE2(UserExceptionVector,literal);
|
||||
RELOCATE2(UserExceptionVector,text);
|
||||
RELOCATE2(DoubleExceptionVector,literal);
|
||||
RELOCATE2(DoubleExceptionVector,text);
|
||||
RELOCATE1(text);
|
||||
RELOCATE1(rodata);
|
||||
RELOCATE1(data);
|
||||
RELOCATE1(u_boot_list);
|
||||
__reloc_table_end = ABSOLUTE(.);
|
||||
}
|
||||
|
||||
#if XCHAL_HAVE_WINDOWED
|
||||
SECTION_VECTOR(WindowVectors,text,XCHAL_WINDOW_VECTORS_VADDR,
|
||||
FOLLOWING(.reloc_table))
|
||||
SECTION_VECTOR(KernelExceptionVector,literal,XCHAL_KERNEL_VECTOR_VADDR-8,
|
||||
FOLLOWING(.WindowVectors.text))
|
||||
#else
|
||||
SECTION_VECTOR(KernelExceptionVector,literal,XCHAL_KERNEL_VECTOR_VADDR-8,
|
||||
FOLLOWING(.reloc_table))
|
||||
#endif
|
||||
SECTION_VECTOR(KernelExceptionVector,text,XCHAL_KERNEL_VECTOR_VADDR,
|
||||
FOLLOWING(.KernelExceptionVector.literal))
|
||||
SECTION_VECTOR(UserExceptionVector,literal,XCHAL_USER_VECTOR_VADDR-8,
|
||||
FOLLOWING(.KernelExceptionVector.text))
|
||||
SECTION_VECTOR(UserExceptionVector,text,XCHAL_USER_VECTOR_VADDR,
|
||||
FOLLOWING(.UserExceptionVector.literal))
|
||||
SECTION_VECTOR(DoubleExceptionVector,literal,XCHAL_DOUBLEEXC_VECTOR_VADDR-8,
|
||||
FOLLOWING(.UserExceptionVector.text))
|
||||
SECTION_VECTOR(DoubleExceptionVector,text,XCHAL_DOUBLEEXC_VECTOR_VADDR,
|
||||
FOLLOWING(.DoubleExceptionVector.literal))
|
||||
|
||||
__monitor_start = XTENSA_SYS_TEXT_ADDR;
|
||||
|
||||
SECTION_text(XTENSA_SYS_TEXT_ADDR, FOLLOWING(.DoubleExceptionVector.text))
|
||||
SECTION_rodata(ALIGN(16), FOLLOWING(.text))
|
||||
SECTION_u_boot_list(ALIGN(16), FOLLOWING(.rodata))
|
||||
SECTION_data(ALIGN(16), FOLLOWING(.u_boot_list))
|
||||
|
||||
__reloc_end = .;
|
||||
__init_end = .;
|
||||
|
||||
SECTION_bss(__init_end (OVERLAY),)
|
||||
|
||||
__monitor_end = .;
|
||||
|
||||
/*
|
||||
* On many Xtensa boards a region of RAM may be mapped to the ROM address
|
||||
* space to facilitate on-chip-debug, and U-Boot must fit with that region.
|
||||
* The config variables CONFIG_SYS_MONITOR_* define the region.
|
||||
* If U-Boot extends beyond this region it will appear discontiguous in the
|
||||
* address space and is in danger of overwriting itself during unpacking
|
||||
* ("relocation").
|
||||
* This causes U-Boot to crash in a way that is difficult to debug. On some
|
||||
* boards (such as xtav60) the region is small enough that U-Boot will not
|
||||
* fit if compiled entirely with -O0 (a common scenario). To avoid a lengthy
|
||||
* debugging session when this happens, ensure a link-time error occurs.
|
||||
*
|
||||
*/
|
||||
|
||||
ASSERT(__monitor_end - __monitor_start <= CONFIG_SYS_MONITOR_LEN,
|
||||
"U-Boot ROM image is too large. Check optimization level.")
|
||||
|
||||
SECTION_xtensa
|
||||
SECTION_debug
|
||||
|
||||
/DISCARD/ : { *(.dynstr*) }
|
||||
/DISCARD/ : { *(.hash*) }
|
||||
/DISCARD/ : { *(.interp) }
|
||||
/DISCARD/ : { *(.got*) }
|
||||
/DISCARD/ : { *(.dynsym) }
|
||||
}
|
||||
Reference in New Issue
Block a user