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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
/*
* mpcsa_start.S
* Copyright (c) 2007, S. Kantoluoto <sami.kantoluoto@iki.fi>
* All rights reserved.
*
* Based on vx115_vep_start.S
* Copyright (c) 2007, J. Sevy <jsevy@cs.drexel.edu>
*
* Based on g42xxeb_start.S
* Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
* Written by Hiroyuki Bessho for Genetec Corporation.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of Genetec Corporation may not be used to endorse or
* promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <machine/asm.h>
#include <arm/armreg.h>
#include "assym.h"
RCSID("$NetBSD: mpcsa_start.S,v 1.3 2011/01/31 06:28:04 matt Exp $")
#ifndef FLASH_START
#define FLASH_START 0x10020000
#endif
#ifndef SDRAM_START
#define SDRAM_START 0x20000000
#endif
#define MODBASE 0x20200000
/*
* CPWAIT -- Canonical method to wait for CP15 update.
* NOTE: Clobbers the specified temp reg.
* copied from arm/arm/cpufunc_asm_xscale.S
* XXX: better be in a common header file.
*/
#define CPWAIT_BRANCH \
sub pc, pc, #4
#define CPWAIT(tmp) \
mrc p15, 0, tmp, c2, c0, 0 /* arbitrary read of CP15 */ ;\
mov tmp, tmp /* wait for it to complete */ ;\
CPWAIT_BRANCH /* branch to next insn */
/*
* Kernel start routine for MPCSA board.
* This code is executed from Flash when the bootloader jumps to it.
*/
.text
.global _C_LABEL(mpcsa_start)
_C_LABEL(mpcsa_start):
/* make sure we're in supervisor mode */
mov r0,sp
msr CPSR_c,#I32_bit | F32_bit | PSR_SVC32_MODE
mov sp,r0
/* move code to RAM */
ldr r1, Lcopy_size
adr r0, _C_LABEL(mpcsa_start)
add r1, r1, #3
mov r1, r1, LSR #2 /* get size of code in words */
mov r2, #SDRAM_START
add r2, r2, #0x200000 /* code placed 2MB above kernel base */
mov r4, r2
/* copy kernel to RAM */
5: ldr r3, [r0], #4
subs r1, r1, #1
str r3, [r2], #4
bhi 5b
/* jump to RAM */
ldr r0, Lstart_off
add pc, r4, r0
Lcopy_size: .word _edata-_C_LABEL(mpcsa_start)
Lstart_off: .word mpcsa_start_ram-_C_LABEL(mpcsa_start)
mpcsa_start_ram:
/*
* Kernel is loaded in SDRAM (0x20200000), and is expected to run
* in VA 0xc0200000.
*/
/* build page table from scratch */
ldr r0, Lstartup_pagetable
adr r4, mmu_init_table
b 3f
2:
str r3, [r0, r2]
add r2, r2, #4
add r3, r3, #(L1_S_SIZE)
adds r1, r1, #-1
bhi 2b
3:
ldmia r4!, {r1,r2,r3} /* # of sections, PA|attr, VA */
cmp r1, #0
bne 2b
mcr p15, 0, r0, c2, c0, 0 /* Set TTB */
mcr p15, 0, r0, c8, c7, 0 /* Flush TLB */
/* Set the Domain Access register. Very important! */
mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
mcr p15, 0, r0, c3, c0, 0
/* Enable MMU */
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #CPU_CONTROL_MMU_ENABLE
mcr p15, 0, r0, c1, c0, 0
CPWAIT(r0)
/* Jump to kernel code in TRUE VA */
adr r0, Lstart
ldr pc, [r0]
Lstart:
.word start
#define MMU_INIT(va,pa,n_sec,attr) \
.word n_sec ;\
.word 4*((va)>>L1_S_SHIFT) ;\
.word (pa) | (attr)
#define STARTUP_PAGETABLE_ADDR 0x20100000 + 0x4000
Lstartup_pagetable:
.word STARTUP_PAGETABLE_ADDR
mmu_init_table:
/* fill all table VA==PA */
MMU_INIT(0x00000000, 0x00000000, 1<<(32-L1_S_SHIFT), L1_TYPE_S|L1_S_AP_KRW)
/* map in peripheral space */
MMU_INIT(0xfff00000, 0xfff00000, 1, L1_TYPE_S|L1_S_AP_KRW)
/* map SDRAM VA==PA, WT cacheable */
MMU_INIT(0x20100000, 0x20100000, 63, L1_TYPE_S|L1_S_C|L1_S_AP_KRW)
/* map VA 0xc0000000..0xc0efffff to PA 0x20100000..0x23ffffff */
MMU_INIT(0xc0000000, 0x20000000, 63, L1_TYPE_S|L1_S_C|L1_S_AP_KRW)
.word 0 /* end of table */
.align 7
jme_module_header:
.word 0xe990510e /* magic number */
.string "NetBSD/mpcsa\0\0\0" /* module name */
.short 0 /* build flags */
.short 0 /* flags */
.word 0 /* version */
.word 0 /* compile / link timestamp */
.word MODBASE /* pointer to init routine */
.word MODBASE /* start address */
.word (_edata-(_C_LABEL(mpcsa_start))) /* length of module */
.word (jme_module_header-_C_LABEL(mpcsa_start)+MODBASE) /* back pointer to module struct*/
.word 0 /* data pointer (ignored but SBZ)*/
.word 0 /* data length (ignored but SBZ)*/
.word 0x20200000 /* alternate address */
.word 0 /* reserved, SBZ */
jme_kmodule_header:
.word 0xe000301e /* magic number */
.string "JME kernel\0\0\0\0\0" /* module name */
.short 0 /* build flags */
.short 0 /* flags */
.word 0 /* version */
.word 0 /* compile / link timestamp */
.word MODBASE /* pointer to init routine */
.word MODBASE /* start address */
.word (_edata-(_C_LABEL(mpcsa_start))) /* length of module */
.word (jme_kmodule_header-_C_LABEL(mpcsa_start)+MODBASE) /* back pointer to module struct*/
.word 0 /* data pointer (ignored but SBZ)*/
.word 0 /* data length (ignored but SBZ)*/
.word 0x20200000 /* alternate address */
.word 0 /* reserved, SBZ */
|