1/* Copyright (c) 2009, 2010, 2011, 2012 ARM Ltd.  All rights reserved.
2
3 Redistribution and use in source and binary forms, with or without
4 modification, are permitted provided that the following conditions
5 are met:
6 1. Redistributions of source code must retain the above copyright
7    notice, this list of conditions and the following disclaimer.
8 2. Redistributions in binary form must reproduce the above copyright
9    notice, this list of conditions and the following disclaimer in the
10    documentation and/or other materials provided with the distribution.
11 3. The name of the company may not be used to endorse or promote
12    products derived from this software without specific prior written
13    permission.
14
15 THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20 TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
22 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
25
26#include "newlib.h"
27#include "svc.h"
28
29/* ANSI concatenation macros.  */
30#define CONCAT(a, b) CONCAT2(a, b)
31#define CONCAT2(a, b) a ## b
32
33#ifdef __USER_LABEL_PREFIX__
34#define FUNCTION( name ) CONCAT (__USER_LABEL_PREFIX__, name)
35#else
36#error __USER_LABEL_PREFIX is not defined
37#endif
38
39
40	.text
41	.align 2
42_init_vectors:
43        /* Installs a table of exception vectors to catch and handle all
44           exceptions by terminating the process with a diagnostic.  */
45	adr	x0, vectors
46	msr	vbar_el3, x0
47	msr	vbar_el2, x0
48	msr	vbar_el1, x0
49	ret
50
51curr_sp0_sync:
52curr_sp0_irq:
53curr_sp0_fiq:
54curr_sp0_serror:
55curr_spx_sync:
56curr_spx_irq:
57curr_spx_fiq:
58curr_spx_serror:
59lower_a64_sync:
60lower_a64_irq:
61lower_a64_fiq:
62lower_a64_serror:
63lower_a32_sync:
64lower_a32_irq:
65lower_a32_fiq:
66lower_a32_serror:
67	mov	x0, 2
68	adr	x1, .LC3
69	mov	x2, 26
70	bl	FUNCTION (write)
71	mov	x0,  126
72	b	FUNCTION (exit)		/* Cannot return.  */
73.LC3:
74	.string "Terminated by exception.\n"
75
76	.macro	ventry	label
77	.align	7
78	b	\label
79	.endm
80
81	/* AArch64 Exception Model -- 3.5.5 Exception Vectors.  */
82
83	.align	12
84vectors:
85	/* Current EL with SP0.  */
86	ventry	curr_sp0_sync		/* Synchronous  */
87	ventry	curr_sp0_irq		/* Irq/vIRQ  */
88	ventry	curr_sp0_fiq		/* Fiq/vFIQ  */
89	ventry	curr_sp0_serror		/* SError/VSError  */
90
91	/* Current EL with SPx.  */
92	ventry	curr_spx_sync		/* Synchronous  */
93	ventry	curr_spx_irq		/* IRQ/vIRQ  */
94	ventry	curr_spx_fiq		/* FIQ/vFIQ  */
95	ventry	curr_spx_serror		/* SError/VSError  */
96
97	/* Lower EL using AArch64.  */
98	ventry	lower_a64_sync		/* Synchronous  */
99	ventry	lower_a64_irq		/* IRQ/vIRQ  */
100	ventry	lower_a64_fiq		/* FIQ/vFIQ  */
101	ventry	lower_a64_serror	/* SError/VSError  */
102
103	/* Lower EL using AArch32.  */
104	ventry	lower_a32_sync		/* Synchronous  */
105	ventry	lower_a32_irq		/* IRQ/vIRQ  */
106	ventry	lower_a32_fiq		/* FIQ/vFIQ  */
107	ventry	lower_a32_serror	/* SError/VSError  */
108
109
110	.text
111	.align 2
112_flat_map:
113	/* Page table setup (identity mapping).  */
114	adrp	x0, ttb
115	add	x0, x0, :lo12:ttb
116	msr	ttbr0_el3, x0
117	adr	x1, .				/* phys address */
118	bic	x1, x1, #(1 << 30) - 1		/* 1GB block alignment */
119	add	x2, x0, x1, lsr #(30 - 3)	/* offset in level 1 page
120						   table */
121	mov	x3, #0x401			/* page table attributes
122						   (AF, block) */
123	orr	x1, x1, x3
124	mov	x3, #(1 << 30)			/* 1GB block */
125	str	x1, [x2], #8			/* 1st GB */
126	add	x1, x1, x3
127	str	x1, [x2]			/* 2nd GB */
128
129	/* Setup/enable the MMU.  */
130
131	/* RES1, RES1, 40-bit PA, 39-bit VA, inner/outer cacheable WB */
132	ldr	x0, =(1 << 31) | (1 << 23) | (2 << 16) | 25 | (3 << 10) | (3 << 8)
133	msr	tcr_el3, x0
134
135	mov	x0, #0xee			/* Inner/outer cacheable WB */
136	msr	mair_el3, x0
137	isb
138
139	mrs	x0, sctlr_el3
140	ldr	x1, =0x100d			/* bits I(12) SA(3) C(2) M(0) */
141	bic	x0, x0, #(1 << 1)		/* clear bit A(1) */
142	bic	x0, x0, #(1 << 19)		/* clear WXN */
143	orr	x0, x0, x1			/* set bits */
144
145	dsb	sy
146	msr	sctlr_el3, x0
147	isb
148	ret
149
150	.data
151	.align	12
152ttb:
153	.space	4096, 0
154
155
156	.text
157	.align 2
158	.global	FUNCTION (_cpu_init_hook)
159	.type	FUNCTION (_cpu_init_hook), %function
160FUNCTION (_cpu_init_hook):
161	sub	sp, sp, #16
162	str	x30, [sp, xzr]
163	bl	_init_vectors
164	bl	_flat_map
165	ldr	x30, [sp, xzr]
166	add	sp, sp, #16
167	ret
168	.size	FUNCTION (_cpu_init_hook), .-FUNCTION (_cpu_init_hook)
169