summaryrefslogtreecommitdiff
path: root/cpu/at32ap/start.S
blob: 4ae0b5480efceb5d6bf6fb9cd1689251dc08b3e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (C) 2005-2006 Atmel Corporation
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */
#include <config.h>
#include <asm/sysreg.h>

#ifndef PART_SPECIFIC_BOOTSTRAP
# define PART_SPECIFIC_BOOTSTRAP
#endif

#define SYSREG_MMUCR_I_OFFSET	2
#define SYSREG_MMUCR_S_OFFSET	4

#define SR_INIT (SYSREG_BIT(GM) | SYSREG_BIT(EM) | SYSREG_BIT(M0))
#define CPUCR_INIT (SYSREG_BIT(BI) | SYSREG_BIT(BE)		\
		    | SYSREG_BIT(FE) | SYSREG_BIT(RE)		\
		    | SYSREG_BIT(IBE) | SYSREG_BIT(IEE))

	.text
	.global	_start
_start:
	PART_SPECIFIC_BOOTSTRAP

	/* Reset the Status Register */
	mov	r0, lo(SR_INIT)
	orh	r0, hi(SR_INIT)
	mtsr	SYSREG_SR, r0

	/* Reset CPUCR and invalidate the BTB */
	mov	r2, CPUCR_INIT
	mtsr	SYSREG_CPUCR, r2

	/* Flush the caches */
	mov	r1, 0
	cache	r1[4], 8
	cache	r1[0], 0
	sync	0

	/* Reset the MMU to default settings */
	mov	r0, SYSREG_BIT(MMUCR_S) | SYSREG_BIT(MMUCR_I)
	mtsr	SYSREG_MMUCR, r0

	/* Internal RAM should not need any initialization.  We might
	   have to initialize external RAM here if the part doesn't
	   have internal RAM (or we may use the data cache) */

	/* Jump to cacheable segment */
	lddpc	pc, 1f

	.align	2
1:	.long	2f

2:	lddpc	sp, sp_init

	/*
	 * Relocate the data section and initialize .bss.  Everything
	 * is guaranteed to be at least doubleword aligned by the
	 * linker script.
	 */
	lddpc	r12, .Ldata_vma
	lddpc	r11, .Ldata_lma
	lddpc	r10, .Ldata_end
	sub	r10, r12
4:	ld.d	r8, r11++
	sub	r10, 8
	st.d	r12++, r8
	brne	4b

	mov	r8, 0
	mov	r9, 0
	lddpc	r10, .Lbss_end
	sub	r10, r12
4:	sub	r10, 8
	st.d	r12++, r8
	brne	4b

	/* Initialize the GOT pointer */
	lddpc	r6, got_init
3:	rsub	r6, pc
	ld.w	pc, r6[board_init_f@got]

	.align	2
	.type	sp_init,@object
sp_init:
	.long	CFG_INIT_SP_ADDR
got_init:
	.long	3b - _GLOBAL_OFFSET_TABLE_
.Ldata_lma:
	.long	__data_lma
.Ldata_vma:
	.long	_data
.Ldata_end:
	.long	_edata
.Lbss_end:
	.long	_end