/*
*	External functions defined by the library
*/

	.globl		BX_IRQ_Entry		// IRQ handler

/*
*	External functions defined by you
*/

	.globl		fatal_error			// Error (UND and ABT) exception
	.globl		fast_irq			// Fast IRQ handler
	.globl		supervisor			// Supervisor instruction handler
	.globl		sys_boot			// C routine to boot the system

/*
*	Exception vector table in FLASH
*	This table is in its own section, which must be
*	placed at 0 by the linker. We don't have to align,
*	because we *know* that it is aligned (being at 0).
*/

	.section	.vectors,"ax",%progbits
	.code		32					// Indicate that it's ARM code
	b		reset					// Reset
	b		fatal_error				// Undefined instruction (UND)
	b		supervisor				// Supervisor call (SVI)
	b		fatal_error				// Instruction prefetch abort (ABT)
	b		fatal_error				// Data access abort (ABT)
	.word	0						// Unused by the ARM7TDMI core
	b		BX_IRQ_Entry			// Interrupt (IRQ)
	b		fast_irq				// Fast interrupt (FIQ)

/*
*	Reset code. It could go into the code segment or can
*	reside in the .vectors segment. We choose the latter.
*/

reset:
	msr		cpsr,#0xd7				// Set ABT mode
	ldr		sp,err_stk				// Set the ABT stack
	msr		cpsr,#0xdb				// Set UND mode
	ldr		sp,err_stk				// Set the UND stack
	msr		cpsr,#0xd3				// Set SVI mode
	ldr		sp,svi_stk				// Set the SVI stack
	msr		cpsr,#0xd1				// Set FIQ mode
	ldr		sp,fiq_stk				// Set the FIQ stack
	msr		cpsr,#0xd2				// Set IRQ mode
	ldr		sp,irq_stk				// Set the IRQ stack
	ldr		r0,sysinit				// Get boot code address
	bx		r0						// Start it (in IRQ mode)

/*
*	Addresses of various objects
*/

irq_stk:	.word	istack
err_stk:	.word	estack
fiq_stk:	.word	fstack
svi_stk:	.word	sstack
sysinit:	.word	sys_boot

/*
*	Stacks for everything except system mode.
*	Of course if you do not use fast interrupts and supervisor mode
*	and if an abort or undefined instruction is a fatal error, from
*	which system reset is the way out, then you don't need that many
*	stacks and you can set them all to point to the interrupt stack.
*
*	Note that we put the stacks into their own segment, not into the
*	bss. That's because we will clear the bss to 0 and it would be
*	most unhealthy to zero the stack we're currently running on...
*/

	.section	.stacks,"aw",%nobits
	.align	2
	.space	1024					// 1 KB interrupt stack
istack:
	.space	512						// 1/2 KB fatal error handling stack
estack:
	.space	512						// 1/2 KB fast interrupt stack
fstack:
	.space	512						// 1/2 KB supervisor stack
sstack:

	.end

