/*
 * Copyright (c) 2018 Renesas Electronics Corporation. All rights reserved.
 */


#define	DRAM_BASE		(0x40000000)
#define	SYSRAM_BASE		(0xE6300000)
#define	DTCM_BASE		(0xEB020000)

#define	STACK_BASE_ABT		(DTCM_BASE | 0x7080)
#define	STACK_BASE_UND		(DTCM_BASE | 0x7100)
#define	STACK_BASE_FIQ		(DTCM_BASE | 0x7180)
#define	STACK_BASE_IRQ		(DTCM_BASE | 0x7200)
#define	STACK_BASE_SVC		(DTCM_BASE | 0x8000)


	.global	Vector
	.global	Start
	.local	rtos_stacks

/*****************************************************************************
 *	Vector table
 *****************************************************************************/
	.align	5

Vector:
	b	Start				/* Reset */
	b	Undef				/* Undefined Instruction */
	b	SWI				/* Supervisor Call */
	b	PAbort				/* Prefetch Abort */
	b	DAbort				/* Data Abort */
	nop					/* Not used */
	b	IRQ				/* IRQ interrupt */
	b	FIQ				/* FIQ interrupt */


/*****************************************************************************
 *	Reset Hander
 *****************************************************************************/
Start:
	/* initialize registers*/
	mov	r0,  #0
	mov	r1,  #0
	mov	r2,  #0
	mov	r3,  #0
	mov	r4,  #0
	mov	r5,  #0
	mov	r6,  #0
	mov	r7,  #0
	mov	r8,  #0
	mov	r9,  #0
	mov	r10, #0
	mov	r11, #0
	mov	r12, #0
	mov	lr,  #0

	/* CR7_CONFIGURE_MPU */
;# region 0: all memory with r/w access for everyone
    MOV     r0,#0
    MCR     p15,0,r0,c6,c2,0                         ;# region number
    MOV     r0,#0x0                                  ;# base address
    MCR     p15,0,r0,c6,c1,0                         ;# D-side base addr
    MCR     p15,0,r0,c6,c1,1                         ;# I-side base addr
    MOV     r0,#0x3E|0x1   ;# 4GB, all memory
    MCR     p15,0,r0,c6,c1,2                         ;# D-side size & enable
    MCR     p15,0,r0,c6,c1,3                         ;# I-side size & enable
    LDR     r0,=(0x300|0x00B|0x004)         ;# 0x00B
    MCR     p15,0,r0,c6,c1,4                         ;# D-side access control
    MCR     p15,0,r0,c6,c1,5                         ;# I-side access control

;# region 1: Peripheral (0xE0000000~0xFFFFFFFF)
    MOV     r0,#1
    MCR     p15,0,r0,c6,c2,0                         ;# region number
    MOV     r0,#0xE0000000                           ;# base address
    MCR     p15,0,r0,c6,c1,0                         ;# D-side base addr
    MCR     p15,0,r0,c6,c1,1                         ;# I-side base addr
    MOV     r0,#0x38 | 0x1 ;# 512MB, all memory
    MCR     p15,0,r0,c6,c1,2                         ;# D-side size & enable
    MCR     p15,0,r0,c6,c1,3                         ;# I-side size & enable
    LDR     r0,=0x300|0x001|0x004          ;# 0x001
    MCR     p15,0,r0,c6,c1,4                         ;# D-side access control
    MCR     p15,0,r0,c6,c1,5                         ;# I-side access control

;# region 2: SecureRAM (0xEB200000)
    MOV     r0,#2
    MCR     p15,0,r0,c6,c2,0                         ;# region number
;#    LDR     r0, =0xE6300000                          ;# base address
    LDR     r0, =0xEB200000                          ;# base address
    MCR     p15,0,r0,c6,c1,0                         ;# D-side base addr
    MCR     p15,0,r0,c6,c1,1                         ;# I-side base addr
;#    MOV     r0,#REGION_SIZE_512KB | 0x1 ; 512KB, all memory
    MOV     r0,#0x26 | 0x1 ;# 1MB, all memory
    MCR     p15,0,r0,c6,c1,2                         ;# D-side size & enable
    MCR     p15,0,r0,c6,c1,3                         ;# I-side size & enable
    LDR     r0,=0x300 | 0x00B | 0x004         ;# 0x00B
    MCR     p15,0,r0,c6,c1,4                         ;# D-side access control
    MCR     p15,0,r0,c6,c1,5                         ;# I-side access control

;# region 3: TCM (0xEB000000)
    MOV     r0,#3
    MCR     p15,0,r0,c6,c2,0                         ;# region number
    LDR     r0, =0xEB000000                          ;# base address
    MCR     p15,0,r0,c6,c1,0                         ;# D-side base addr
    MCR     p15,0,r0,c6,c1,1                         ;# I-side base addr
    MOV     r0,#0x1E | 0x1  ;# 64KB, all memory
    MCR     p15,0,r0,c6,c1,2                         ;# D-side size & enable
    MCR     p15,0,r0,c6,c1,3                         ;# I-side size & enable
    LDR     r0,=0x300 | 0x00B | 0x004         ;# 0x00B
    MCR     p15,0,r0,c6,c1,4                         ;# D-side access control
    MCR     p15,0,r0,c6,c1,5                         ;# I-side access control

;# region 4: SecureROM (0xEB100000)
    MOV     r0,#4
    MCR     p15,0,r0,c6,c2,0                         ;# region number
    LDR     r0, =0xEB100000                          ;# base address
    MCR     p15,0,r0,c6,c1,0                         ;# D-side base addr
    MCR     p15,0,r0,c6,c1,1                         ;# I-side base addr
    MOV     r0,#0x22 | 0x1 ;# 256KB, all memory
    MCR     p15,0,r0,c6,c1,2                         ;# D-side size & enable
    MCR     p15,0,r0,c6,c1,3                         ;# I-side size & enable
    LDR     r0,=0x300 | 0x00B | 0x004         ;# 0x00B
    MCR     p15,0,r0,c6,c1,4                         ;# D-side access control
    MCR     p15,0,r0,c6,c1,5                         ;# I-side access control

;#CR7_SET_MPU_ON
    MRC     p15, 0, r0, c1, c0, 0
    ORR     r0, r0, #0x00000001
    DSB
    MCR     p15, 0, r0, c1, c0, 0
    ISB

	LDR	PC, =STACK_INIT

STACK_INIT:
	/* stack initialize */
	ldr	r0, =__STACKS_END__

	msr	CPSR_c, #(0x17 | 0x80 | 0x40)	/* ABT */
	mov	sp, r0				/* STACK_BASE_ABT */

	msr	CPSR_c, #(0x1B | 0x80 | 0x40)	/* UND */
	sub	r0, r0, #0x80			/* STACK_BASE_UND */
	mov	sp, r0

	msr	CPSR_c, #(0x11 | 0x80 | 0x40)	/* FIQ */
	sub	r0, r0, #0x80			/* STACK_BASE_FIQ */
	mov	sp, r0

	msr	CPSR_c, #(0x12 | 0x80 | 0x40)	/* IRQ */
	sub	r0, r0, #0x80			/* STACK_BASE_IRQ */
	mov	sp, r0

	msr	CPSR_c, #(0x13 | 0x80 | 0x40)	/* SVC */
	sub	r0, r0, #0x80			/* STACK_BASE_SVC */
	mov	sp, r0


	/* Loader Main */
	BL     rtos_main

NO_BOOT:
	nop
1:
	wfe
	b	1b


/*****************************************************************************
 *	Exception Handers
 *****************************************************************************/

	/* Undefined Instruction */
Undef:
	nop
1:
	wfe
	b	1b

	/* Supervisor Call */
SWI:
	nop
1:
	wfe
	b	1b

	/* Prefetch Abort */
PAbort:
	nop
1:
	wfe
	b	1b

	/* Data Abort */
DAbort:
	nop
1:
	wfe
	b	1b

	/* IRQ interrupt */
IRQ:
	nop
1:
	wfe
	b	1b

	/* FIQ interrupt */
FIQ:
	nop
1:
	wfe
	b	1b


/*****************************************************************************
 *	Define stack
 *****************************************************************************/
	.section tzfw_normal_stacks, "aw"
	.align   6

rtos_stacks:
	.space   4 * 1024

	.end
