mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-04-11 16:37:45 -04:00
DM320: Re-write of crt0.S and update to app linker script.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29224 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
02dbde7097
commit
9241210050
2 changed files with 384 additions and 173 deletions
|
|
@ -1,6 +1,6 @@
|
|||
#include "config.h"
|
||||
|
||||
ENTRY(start)
|
||||
ENTRY(_start)
|
||||
|
||||
OUTPUT_FORMAT(elf32-littlearm)
|
||||
OUTPUT_ARCH(arm)
|
||||
|
|
@ -16,7 +16,7 @@ STARTUP(target/arm/tms320dm320/crt0.o)
|
|||
|
||||
#define LCD_FUDGE LCD_NATIVE_WIDTH%32
|
||||
|
||||
#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
|
||||
#define LCD_BUFFER_SIZE ((LCD_NATIVE_WIDTH+LCD_FUDGE)*LCD_NATIVE_HEIGHT*2)
|
||||
|
||||
/* must be 16Kb (0x4000) aligned */
|
||||
#define TTB_SIZE 0x4000
|
||||
|
|
@ -30,112 +30,144 @@ STARTUP(target/arm/tms320dm320/crt0.o)
|
|||
#define DRAMSIZE (MEMORYSIZE * 0x100000)
|
||||
|
||||
#define DRAMORIG 0x00900000
|
||||
#define IRAMORIG 0x00000000
|
||||
#define IRAMSIZE 0x4000
|
||||
|
||||
#define FLASHORIG 0x00100000
|
||||
#define FLASHSIZE 0x00800000
|
||||
|
||||
#define ITCMORIG 0x00000000
|
||||
#define ITCMSIZE 0x4000
|
||||
|
||||
#define DTCMORIG 0x00020000
|
||||
#define DTCMSIZE 0x4000
|
||||
|
||||
PRO_STACK_SIZE = 0x2000;
|
||||
IRQ_STACK_SIZE = 0x600;
|
||||
FIQ_STACK_SIZE = 0x400;
|
||||
|
||||
/* End of the audio buffer, where the codec buffer starts */
|
||||
#define ENDAUDIOADDR (DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
|
||||
#define ENDAUDIOADDR \
|
||||
(DRAMORIG + DRAMSIZE - PLUGIN_BUFFER_SIZE - CODEC_SIZE - LCD_TTB_AREA)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE
|
||||
IRAM : ORIGIN = IRAMORIG, LENGTH = IRAMSIZE
|
||||
ITCM : ORIGIN = ITCMORIG, LENGTH = ITCMSIZE
|
||||
DTCM : ORIGIN = DTCMORIG, LENGTH = DTCMSIZE
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
/* Set up variables needed for memory initialization */
|
||||
_sdram_start = DRAMORIG;
|
||||
_sdram_sizem = ((_endsdram - _sdram_start) / 0x100000);
|
||||
|
||||
_flash_start = FLASHORIG;
|
||||
_flash_sizem = (FLASHSIZE / 0x100000);
|
||||
|
||||
/* crt0.S initialization */
|
||||
.init :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
loadaddress = .;
|
||||
*(.init)
|
||||
} > DRAM
|
||||
|
||||
.vectors ITCMORIG :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
_vectorsstart = .;
|
||||
*(.vectors);
|
||||
_vectorsend = .;
|
||||
} > ITCM AT> DRAM
|
||||
|
||||
_vectorscopy = LOADADDR(.vectors);
|
||||
|
||||
.text :
|
||||
{
|
||||
loadaddress = .;
|
||||
_loadaddress = .;
|
||||
*(.init.text)
|
||||
*(.text*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
. = ALIGN(0x4);
|
||||
*(.text*)
|
||||
} > DRAM
|
||||
|
||||
/* Thumb interworking sections - for some reason LD dies even if these
|
||||
* sections are empty.
|
||||
*/
|
||||
.glue :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
*(.glue_7) /* ARM calling Thumb */
|
||||
*(.glue_7t) /* Thumb calling ARM */
|
||||
} > DRAM
|
||||
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata) /* problems without this, dunno why */
|
||||
*(.rodata*)
|
||||
. = ALIGN(0x4);
|
||||
*(.rodata*)
|
||||
} > DRAM
|
||||
|
||||
.data :
|
||||
{
|
||||
*(.data*)
|
||||
. = ALIGN(0x4);
|
||||
*(.data*)
|
||||
} > DRAM
|
||||
|
||||
/DISCARD/ :
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
*(.eh_frame)
|
||||
}
|
||||
|
||||
.vectors IRAMORIG :
|
||||
{
|
||||
_vectorsstart = .;
|
||||
*(.vectors);
|
||||
_vectorsend = .;
|
||||
} > IRAM AT> DRAM
|
||||
|
||||
_vectorscopy = LOADADDR(.vectors);
|
||||
. = ALIGN(0x4);
|
||||
_bss_start = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
_bss_end = .;
|
||||
} > DRAM
|
||||
|
||||
.iram :
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
_iramstart = .;
|
||||
*(.icode)
|
||||
*(.irodata*)
|
||||
*(.irodata)
|
||||
*(.idata)
|
||||
. = ALIGN(0x4);
|
||||
_iramend = .;
|
||||
} > IRAM AT> DRAM
|
||||
} > ITCM AT> DRAM
|
||||
|
||||
_iramcopy = LOADADDR(.iram);
|
||||
|
||||
.ibss (NOLOAD) :
|
||||
|
||||
.ibss DTCMORIG + _iramend (NOLOAD) :
|
||||
{
|
||||
_iedata = .;
|
||||
. = ALIGN(0x4);
|
||||
_ibss_start = .;
|
||||
*(.ibss)
|
||||
. = ALIGN(0x4);
|
||||
_iend = .;
|
||||
} > IRAM
|
||||
_ibss_end = .;
|
||||
} > DTCM
|
||||
|
||||
.stack (NOLOAD) :
|
||||
/* Program stack space */
|
||||
.pro_stack (NOLOAD):
|
||||
{
|
||||
*(.stack)
|
||||
stackbegin = .;
|
||||
. += 0x2000;
|
||||
stackend = .;
|
||||
} > IRAM
|
||||
|
||||
.irqstack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
. += 0x400;
|
||||
irq_stack = .;
|
||||
} > IRAM
|
||||
|
||||
.fiqstack (NOLOAD) :
|
||||
{
|
||||
*(.stack)
|
||||
. += 0x400;
|
||||
fiq_stack = .;
|
||||
} > IRAM
|
||||
|
||||
/* This overwrites the iram (in ram), so make sure that the iram is copied
|
||||
* out in crt0.s before the bss section and the rest are used.
|
||||
*/
|
||||
.bss (NOLOAD) :
|
||||
{
|
||||
. = ADDR(.data) + SIZEOF(.data);
|
||||
_edata = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(0x4);
|
||||
_end = .;
|
||||
} > DRAM
|
||||
*(.stack)
|
||||
stackbegin = .; /* Variable for thread.c */
|
||||
_pro_stack_end = .;
|
||||
. += PRO_STACK_SIZE;
|
||||
_pro_stack_start = .;
|
||||
stackend = .; /* Variable for tread.c */
|
||||
} > DTCM
|
||||
|
||||
/* IRQ stack space */
|
||||
.irq_stack (NOLOAD):
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
_irq_stack_end = .;
|
||||
. += IRQ_STACK_SIZE;
|
||||
_irq_stack_start = .;
|
||||
} > DTCM
|
||||
|
||||
/* FIQ stack space */
|
||||
.fiq_stack (NOLOAD):
|
||||
{
|
||||
. = ALIGN(0x4);
|
||||
_fiq_stack_end = .;
|
||||
. += FIQ_STACK_SIZE;
|
||||
_fiq_stack_start = .;
|
||||
} > DTCM
|
||||
|
||||
.audiobuf (NOLOAD) :
|
||||
{
|
||||
|
|
@ -160,6 +192,8 @@ SECTIONS
|
|||
. += PLUGIN_BUFFER_SIZE;
|
||||
} > DRAM
|
||||
|
||||
_endsdram = .;
|
||||
|
||||
.ttbtable (NOLOAD) :
|
||||
{
|
||||
. = ALIGN (0x4000);
|
||||
|
|
|
|||
|
|
@ -7,12 +7,7 @@
|
|||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||
*
|
||||
* Arm bootloader and startup code based on startup.s from the iPodLinux loader
|
||||
*
|
||||
* Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org)
|
||||
* Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org>
|
||||
* Copyright (C) 2010 by Karl Kurbjun
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
|
@ -26,25 +21,83 @@
|
|||
#include "config.h"
|
||||
#include "cpu.h"
|
||||
|
||||
.section .init.text,"ax",%progbits
|
||||
#define CACHE_NONE 0
|
||||
#define CACHE_ALL 0x0C
|
||||
#define BUFFERED 0x04
|
||||
|
||||
.global start
|
||||
start:
|
||||
msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
|
||||
#define LONG_VECTORS 1
|
||||
|
||||
#ifndef CREATIVE_ZVx
|
||||
/* Copy exception handler code to address 0 */
|
||||
ldr r2, =_vectorsstart
|
||||
ldr r3, =_vectorsend
|
||||
ldr r4, =_vectorscopy
|
||||
1:
|
||||
cmp r3, r2
|
||||
ldrhi r5, [r4], #4
|
||||
strhi r5, [r2], #4
|
||||
bhi 1b
|
||||
/******************************************************************************
|
||||
* vectors: *
|
||||
* This is the ARM vector table *
|
||||
* Long call exception handlers are used for simplicity between flash *
|
||||
* bootloader and SDRAM main-application. These need to be copied to address *
|
||||
* 0x0 at start. *
|
||||
******************************************************************************/
|
||||
.section .vectors,"ax"
|
||||
.code 32
|
||||
|
||||
.global _vectors
|
||||
@entry:
|
||||
_vectors:
|
||||
|
||||
#if defined(SHORT_VECTORS) /* Use relative branch vectors (64 MB limit) */
|
||||
b _start /* Reset Vector */
|
||||
b _undefined_instruction /* Undefined instruction */
|
||||
b _software_interrupt /* Software Vector */
|
||||
b _prefetch_abort /* Prefetch Abort */
|
||||
b _data_abort /* Data Abort */
|
||||
b _dead_loop /* Reserved/Unused */
|
||||
b irq_handler /* IRQ vector */
|
||||
b fiq_handler /* FIQ vector */
|
||||
#else
|
||||
#if defined(LONG_VECTORS)
|
||||
/* Load the PC with the word values stored below */
|
||||
ldr pc, [pc, #0x18] /* Reset */
|
||||
ldr pc, [pc, #0x18] /* Undefined instruction */
|
||||
ldr pc, [pc, #0x18] /* Software interrupt */
|
||||
ldr pc, [pc, #0x18] /* Prefetch Abort */
|
||||
ldr pc, [pc, #0x18] /* Data Abort */
|
||||
ldr pc, [pc, #0x18] /* Reserved/Unused */
|
||||
ldr pc, [pc, #0x18] /* IRQ */
|
||||
ldr pc, [pc, #0x18] /* FIQ */
|
||||
|
||||
/* Addresses of the handlers */
|
||||
.word _start
|
||||
.word _undefined_instruction
|
||||
.word _software_interrupt
|
||||
.word _prefetch_abort
|
||||
.word _data_abort
|
||||
.word _dead_loop
|
||||
.word irq_handler
|
||||
.word fiq_handler
|
||||
#else
|
||||
#error Vector type undefined
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Disable data and instruction cache, high vectors (at 0xffff0000 instead of 0x00000000) */
|
||||
/******************************************************************************
|
||||
* _start: *
|
||||
* This is the main entry point to the program *
|
||||
******************************************************************************/
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
.align 0x04
|
||||
.global _start
|
||||
_start:
|
||||
/* Go into supervisor state with IRQ's disabled.
|
||||
* This register is described in section "A2.5 Program status registers"
|
||||
* of the "ARM Architecture Reference Manual".
|
||||
*/
|
||||
msr cpsr, #0xd3
|
||||
|
||||
/* Disable all the fancy stuff */
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/* Disable data and instruction cache, high vectors (at 0xffff0000 instead
|
||||
* of 0x00000000)
|
||||
*/
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
/* clear bits 13, 9:8 (--VI --RS) */
|
||||
bic r0, r0, #0x00003300
|
||||
|
|
@ -54,112 +107,236 @@ start:
|
|||
orr r0, r0, #0x00000002
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
#if !defined(STUB)
|
||||
/* Zero out IBSS */
|
||||
ldr r2, =_iedata
|
||||
ldr r3, =_iend
|
||||
mov r4, #0
|
||||
1:
|
||||
cmp r3, r2
|
||||
strhi r4, [r2], #4
|
||||
bhi 1b
|
||||
/* Add a few cycles of delay before continuing due to system requirements */
|
||||
mov r0, #0x20
|
||||
bl _delay_cycles
|
||||
|
||||
#ifndef CREATIVE_ZVx
|
||||
/* Copy the IRAM */
|
||||
ldr r2, =_iramcopy
|
||||
ldr r3, =_iramstart
|
||||
ldr r4, =_iramend
|
||||
1:
|
||||
cmp r4, r3
|
||||
ldrhi r5, [r2], #4
|
||||
strhi r5, [r3], #4
|
||||
bhi 1b
|
||||
#if defined(BOOTLOADER)
|
||||
bl _init_board
|
||||
#endif
|
||||
#endif /* !STUB */
|
||||
|
||||
/* Copy exception handler code to address 0 */
|
||||
ldr r0, =_vectorscopy
|
||||
ldr r1, =_vectorsstart
|
||||
ldr r2, =_vectorsend
|
||||
bl _copy_section
|
||||
|
||||
/* Initialise bss section to zero */
|
||||
ldr r2, =_edata
|
||||
ldr r3, =_end
|
||||
mov r4, #0
|
||||
bsszero:
|
||||
cmp r3, r2
|
||||
strhi r4, [r2], #4
|
||||
bhi bsszero
|
||||
/* Add some delay time to make sure JTAG can be accessed cleanly */
|
||||
mov r0, #0x100000
|
||||
bl _delay_cycles
|
||||
|
||||
/* Set up some stack and munge it with 0xdeadbeef */
|
||||
ldr sp, =stackend
|
||||
mov r3, sp
|
||||
ldr r2, =stackbegin
|
||||
ldr r4, =0xdeadbeef
|
||||
stackmunge:
|
||||
cmp r3, r2
|
||||
strhi r4, [r2], #4
|
||||
bhi stackmunge
|
||||
#if defined(BOOTLOADER)
|
||||
/* Copy the DRAM */
|
||||
ldr r0, =_dramcopy
|
||||
ldr r1, =_dramstart
|
||||
ldr r2, =_dramend
|
||||
bl _copy_section
|
||||
#endif
|
||||
|
||||
/* Set up stack for IRQ mode */
|
||||
msr cpsr_c, #0xd2 /* IRQ disabled, FIQ enabled */
|
||||
ldr sp, =irq_stack
|
||||
/* Set up stack for FIQ mode */
|
||||
msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */
|
||||
ldr sp, =fiq_stack
|
||||
/* Zero out the IBSS */
|
||||
mov r0, #0
|
||||
ldr r1, =_ibss_start
|
||||
ldr r2, =_ibss_end
|
||||
bl _init_section
|
||||
|
||||
/* Let abort and undefined modes use IRQ stack */
|
||||
msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */
|
||||
ldr sp, =irq_stack
|
||||
msr cpsr_c, #0xdb /* IRQ/FIQ disabled */
|
||||
ldr sp, =irq_stack
|
||||
/* Copy the IRAM */
|
||||
ldr r0, =_iramcopy
|
||||
ldr r1, =_iramstart
|
||||
ldr r2, =_iramend
|
||||
bl _copy_section
|
||||
|
||||
/* Switch to supervisor mode (no IRQ) */
|
||||
msr cpsr_c, #0xd3
|
||||
ldr sp, =stackend
|
||||
/* Zero out the BSS */
|
||||
mov r0, #0
|
||||
ldr r1, =_bss_start
|
||||
ldr r2, =_bss_end
|
||||
bl _init_section
|
||||
|
||||
start_loc:
|
||||
bl main
|
||||
/* main() should never return */
|
||||
/* Initialize fiq stack */
|
||||
ldr r0, =0xDEADBEEF
|
||||
ldr r1, =_fiq_stack_end /* Stack counts backwards, so end is first*/
|
||||
ldr r2, =_fiq_stack_start
|
||||
bl _init_section
|
||||
|
||||
/* Exception handlers. Will be copied to address 0 after memory remapping */
|
||||
.section .vectors,"aw"
|
||||
b start
|
||||
b undef_instr_handler
|
||||
b software_int_handler
|
||||
b prefetch_abort_handler
|
||||
b data_abort_handler
|
||||
b reserved_handler
|
||||
b irq_handler
|
||||
b fiq_handler
|
||||
msr cpsr_c, #0xd1 /* Go into fiq state */
|
||||
ldr sp, =_fiq_stack_start /* set the fiq stack pointer */
|
||||
|
||||
.text
|
||||
/* Initialize irq stack */
|
||||
ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */
|
||||
ldr r1, =_irq_stack_end /* Stack counts backwards, so end is first*/
|
||||
ldr r2, =_irq_stack_start
|
||||
bl _init_section
|
||||
|
||||
/* All illegal exceptions call into UIE with exception address as first
|
||||
parameter. This is calculated differently depending on which exception
|
||||
we're in. Second parameter is exception number, used for a string lookup
|
||||
in UIE.
|
||||
msr cpsr_c, #0xd2 /* Go into irq state */
|
||||
ldr sp, =_irq_stack_start /* set the irq stack pointer */
|
||||
|
||||
/* This should not be needed, but set the stack location for abort and
|
||||
* undefined to at least a known stack location (IRQ)
|
||||
*/
|
||||
msr cpsr_c, #0xd7 /* Go into abort state */
|
||||
ldr sp, =_irq_stack_start /* set the stack pointer */
|
||||
|
||||
msr cpsr_c, #0xdb /* Go into undefined state */
|
||||
ldr sp, =_irq_stack_start /* set the stack pointer */
|
||||
|
||||
/* Initialize program stack */
|
||||
msr cpsr_c, #0xd3 /* Go into supervisor state */
|
||||
ldr r0, =0xDEADBEEF /* Can be taken out; left for clarity */
|
||||
ldr r1, =_pro_stack_end /* Stack counts backwards, so end is first*/
|
||||
ldr r2, =_pro_stack_start
|
||||
bl _init_section
|
||||
|
||||
ldr sp, =_pro_stack_start /* set the supervisor stack pointer */
|
||||
|
||||
/* MMU initialization */
|
||||
bl ttb_init
|
||||
|
||||
/* Make sure everything is mapped on itself */
|
||||
ldr r0, =0x0
|
||||
ldr r1, =0x0
|
||||
ldr r2, =0x1000
|
||||
mov r3, #CACHE_NONE
|
||||
bl map_section
|
||||
|
||||
/* Enable caching for FLASH */
|
||||
ldr r0, =_flash_start
|
||||
ldr r1, =_flash_start
|
||||
ldr r2, =_flash_sizem
|
||||
mov r3, #CACHE_ALL
|
||||
bl map_section
|
||||
|
||||
/* Enable caching for RAM */
|
||||
ldr r0, =_sdram_start
|
||||
ldr r1, =_sdram_start
|
||||
ldr r2, =_sdram_sizem
|
||||
mov r3, #CACHE_ALL
|
||||
bl map_section
|
||||
|
||||
bl enable_mmu
|
||||
|
||||
/* Initial setup is complete, go into main */
|
||||
ldr pc, =main
|
||||
|
||||
/* If main returns go into an infinite loop */
|
||||
b _dead_loop
|
||||
|
||||
/* Constants go here (from _start - .ltorg): */
|
||||
.ltorg
|
||||
|
||||
/******************************************************************************
|
||||
* _init_section: *
|
||||
* This function initializes a section with the 32-bit value specified. *
|
||||
******************************************************************************/
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
.align 0x04
|
||||
.global _init_section
|
||||
.type _init_section, %function
|
||||
/* r0 = init value
|
||||
* r1 = start location
|
||||
* r2 = end location
|
||||
*/
|
||||
undef_instr_handler:
|
||||
|
||||
/* This function will not run if end is less than or equal to start */
|
||||
_init_section:
|
||||
cmp r2, r1
|
||||
strhi r0, [r1], #4 /* store and increment start location */
|
||||
bhi _init_section
|
||||
bx lr
|
||||
.ltorg
|
||||
.size _init_section, .-_init_section
|
||||
|
||||
/******************************************************************************
|
||||
* _copy_section: *
|
||||
* This function copies a section to a new location *
|
||||
******************************************************************************/
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
.align 0x04
|
||||
.global _copy_section
|
||||
.type _copy_section, %function
|
||||
/* r0 = source address
|
||||
* r1 = destination start address
|
||||
* r2 = destination end address
|
||||
*
|
||||
* r3 is a scratch register
|
||||
*/
|
||||
|
||||
_copy_section:
|
||||
cmp r2, r1
|
||||
ldrhi r3, [r0], #4
|
||||
strhi r3, [r1], #4
|
||||
bhi _copy_section
|
||||
bx lr
|
||||
.ltorg
|
||||
.size _copy_section, .-_copy_section
|
||||
|
||||
/******************************************************************************
|
||||
* _delay_cycles: *
|
||||
* This function delays for the specified number of cycles *
|
||||
******************************************************************************/
|
||||
.section .init, "ax"
|
||||
.code 32
|
||||
.align 0x04
|
||||
.global _delay_cycles
|
||||
.type _delay_cycles, %function
|
||||
/* r0 = number of cycles to delay */
|
||||
|
||||
/* If r0 is zero it will be the maximum length delay */
|
||||
_delay_cycles:
|
||||
subs r0, r0, #1
|
||||
bne _delay_cycles
|
||||
bx lr
|
||||
.ltorg
|
||||
.size _delay_cycles, .-_delay_cycles
|
||||
|
||||
/******************************************************************************
|
||||
* Unused exception vectors. These call the UIE function. *
|
||||
* Arguements are: *
|
||||
* r0: PC of exception *
|
||||
* r1: Exception number. *
|
||||
* Exception numbers are as defined: *
|
||||
* 0: Undefined Instruction *
|
||||
* 1: Prefetch Abort *
|
||||
* 2: Data Abort *
|
||||
* The exceptions return operations are documented in section A2.6 of the *
|
||||
* ARM Architecture Reference Manual. *
|
||||
******************************************************************************/
|
||||
|
||||
/* A2.6.3: Undefined Instruction Exception - LR=PC of next instruction */
|
||||
_undefined_instruction:
|
||||
sub r0, lr, #4
|
||||
mov r1, #0
|
||||
b UIE
|
||||
bl UIE
|
||||
|
||||
/* We run supervisor mode most of the time, and should never see a software
|
||||
exception being thrown. Perhaps make it illegal and call UIE?
|
||||
/* A2.6.4: Software Interrupt exception - These should not happen in Rockbox,
|
||||
* but for now leave this as a placeholder and continue with the program.
|
||||
* LR=PC of next instruction.
|
||||
*/
|
||||
software_int_handler:
|
||||
reserved_handler:
|
||||
movs pc, lr
|
||||
_software_interrupt:
|
||||
mov pc, lr
|
||||
|
||||
prefetch_abort_handler:
|
||||
/* A2.6.5 Prefetch Abort - This is also the BKPT instruction since this is a
|
||||
* v5 target. Pass it on to UIE since it is not currently used.
|
||||
*/
|
||||
_prefetch_abort:
|
||||
sub r0, lr, #4
|
||||
mov r1, #1
|
||||
b UIE
|
||||
bl UIE
|
||||
|
||||
data_abort_handler:
|
||||
/* A2.6.6 Data Abort - There was a memory abort, can return after fixing cause
|
||||
* with the LR address.
|
||||
*/
|
||||
_data_abort:
|
||||
sub r0, lr, #8
|
||||
mov r1, #2
|
||||
b UIE
|
||||
bl UIE
|
||||
|
||||
#ifdef STUB
|
||||
UIE:
|
||||
b UIE
|
||||
#endif
|
||||
/******************************************************************************
|
||||
* _dead_loop: Something really unexpected happened (like a reserved *
|
||||
* exception). Just hang. *
|
||||
******************************************************************************/
|
||||
_dead_loop:
|
||||
b _dead_loop
|
||||
|
||||
.ltorg
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue