Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/mn10300/kernel/head.S
10817 views
1
/* Boot entry point for MN10300 kernel
2
*
3
* Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4
* Written by David Howells ([email protected])
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public Licence
8
* as published by the Free Software Foundation; either version
9
* 2 of the Licence, or (at your option) any later version.
10
*/
11
12
#include <linux/init.h>
13
#include <linux/threads.h>
14
#include <linux/linkage.h>
15
#include <linux/serial_reg.h>
16
#include <asm/thread_info.h>
17
#include <asm/page.h>
18
#include <asm/pgtable.h>
19
#include <asm/frame.inc>
20
#include <asm/param.h>
21
#include <unit/serial.h>
22
#ifdef CONFIG_SMP
23
#include <asm/smp.h>
24
#include <asm/intctl-regs.h>
25
#include <asm/cpu-regs.h>
26
#include <proc/smp-regs.h>
27
#endif /* CONFIG_SMP */
28
29
__HEAD
30
31
###############################################################################
32
#
33
# bootloader entry point
34
#
35
###############################################################################
36
.globl _start
37
.type _start,@function
38
_start:
39
#ifdef CONFIG_SMP
40
#
41
# If this is a secondary CPU (AP), then deal with that elsewhere
42
#
43
mov (CPUID),d3
44
and CPUID_MASK,d3
45
bne startup_secondary
46
47
#
48
# We're dealing with the primary CPU (BP) here, then.
49
# Keep BP's D0,D1,D2 register for boot check.
50
#
51
52
# Set up the Boot IPI for each secondary CPU
53
mov 0x1,a0
54
loop_set_secondary_icr:
55
mov a0,a1
56
asl CROSS_ICR_CPU_SHIFT,a1
57
add CROSS_GxICR(SMP_BOOT_IRQ,0),a1
58
movhu (a1),d3
59
or GxICR_ENABLE|GxICR_LEVEL_0,d3
60
movhu d3,(a1)
61
movhu (a1),d3 # flush
62
inc a0
63
cmp NR_CPUS,a0
64
bne loop_set_secondary_icr
65
#endif /* CONFIG_SMP */
66
67
# save commandline pointer
68
mov d0,a3
69
70
# preload the PGD pointer register
71
mov swapper_pg_dir,d0
72
mov d0,(PTBR)
73
clr d0
74
movbu d0,(PIDR)
75
76
# turn on the TLBs
77
mov MMUCTR_IIV|MMUCTR_DIV,d0
78
mov d0,(MMUCTR)
79
#ifdef CONFIG_AM34_2
80
mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
81
#else
82
mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
83
#endif
84
mov d0,(MMUCTR)
85
86
# turn on AM33v2 exception handling mode and set the trap table base
87
movhu (CPUP),d0
88
or CPUP_EXM_AM33V2,d0
89
movhu d0,(CPUP)
90
mov CONFIG_INTERRUPT_VECTOR_BASE,d0
91
mov d0,(TBR)
92
93
# invalidate and enable both of the caches
94
#ifdef CONFIG_SMP
95
mov ECHCTR,a0
96
clr d0
97
mov d0,(a0)
98
#endif
99
mov CHCTR,a0
100
clr d0
101
movhu d0,(a0) # turn off first
102
mov CHCTR_ICINV|CHCTR_DCINV,d0
103
movhu d0,(a0)
104
setlb
105
mov (a0),d0
106
btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy
107
lne
108
109
#ifdef CONFIG_MN10300_CACHE_ENABLED
110
#ifdef CONFIG_MN10300_CACHE_WBACK
111
#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
112
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
113
#else
114
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
115
#endif /* NOWRALLOC */
116
#else
117
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
118
#endif /* WBACK */
119
movhu d0,(a0) # enable
120
#endif /* ENABLED */
121
122
# turn on RTS on the debug serial port if applicable
123
#ifdef CONFIG_MN10300_UNIT_ASB2305
124
bset UART_MCR_RTS,(ASB2305_DEBUG_MCR)
125
#endif
126
127
# clear the BSS area
128
mov __bss_start,a0
129
mov __bss_stop,a1
130
clr d0
131
bssclear:
132
cmp a1,a0
133
bge bssclear_end
134
mov d0,(a0)
135
inc4 a0
136
bra bssclear
137
bssclear_end:
138
139
# retrieve the parameters (including command line) before we overwrite
140
# them
141
cmp 0xabadcafe,d1
142
bne __no_parameters
143
144
__copy_parameters:
145
mov redboot_command_line,a0
146
mov a0,a1
147
add COMMAND_LINE_SIZE,a1
148
1:
149
movbu (a3),d0
150
inc a3
151
movbu d0,(a0)
152
inc a0
153
cmp a1,a0
154
blt 1b
155
156
mov redboot_platform_name,a0
157
mov a0,a1
158
add COMMAND_LINE_SIZE,a1
159
mov d2,a3
160
1:
161
movbu (a3),d0
162
inc a3
163
movbu d0,(a0)
164
inc a0
165
cmp a1,a0
166
blt 1b
167
168
__no_parameters:
169
170
# set up the registers with recognisable rubbish in them
171
mov init_thread_union+THREAD_SIZE-12,sp
172
173
mov 0xea01eaea,d0
174
mov d0,(4,sp) # EPSW save area
175
mov 0xea02eaea,d0
176
mov d0,(8,sp) # PC save area
177
178
mov 0xeb0060ed,d0
179
mov d0,mdr
180
mov 0xeb0061ed,d0
181
mov d0,mdrq
182
mov 0xeb0062ed,d0
183
mov d0,mcrh
184
mov 0xeb0063ed,d0
185
mov d0,mcrl
186
mov 0xeb0064ed,d0
187
mov d0,mcvf
188
mov 0xed0065ed,a3
189
mov a3,usp
190
191
mov 0xed00e0ed,e0
192
mov 0xed00e1ed,e1
193
mov 0xed00e2ed,e2
194
mov 0xed00e3ed,e3
195
mov 0xed00e4ed,e4
196
mov 0xed00e5ed,e5
197
mov 0xed00e6ed,e6
198
mov 0xed00e7ed,e7
199
200
mov 0xed00d0ed,d0
201
mov 0xed00d1ed,d1
202
mov 0xed00d2ed,d2
203
mov 0xed00d3ed,d3
204
mov 0xed00a0ed,a0
205
mov 0xed00a1ed,a1
206
mov 0xed00a2ed,a2
207
mov 0,a3
208
209
# set up the initial kernel stack
210
SAVE_ALL
211
mov 0xffffffff,d0
212
mov d0,(REG_ORIG_D0,fp)
213
214
# put different recognisable rubbish in the regs
215
mov 0xfb0060ed,d0
216
mov d0,mdr
217
mov 0xfb0061ed,d0
218
mov d0,mdrq
219
mov 0xfb0062ed,d0
220
mov d0,mcrh
221
mov 0xfb0063ed,d0
222
mov d0,mcrl
223
mov 0xfb0064ed,d0
224
mov d0,mcvf
225
mov 0xfd0065ed,a0
226
mov a0,usp
227
228
mov 0xfd00e0ed,e0
229
mov 0xfd00e1ed,e1
230
mov 0xfd00e2ed,e2
231
mov 0xfd00e3ed,e3
232
mov 0xfd00e4ed,e4
233
mov 0xfd00e5ed,e5
234
mov 0xfd00e6ed,e6
235
mov 0xfd00e7ed,e7
236
237
mov 0xfd00d0ed,d0
238
mov 0xfd00d1ed,d1
239
mov 0xfd00d2ed,d2
240
mov 0xfd00d3ed,d3
241
mov 0xfd00a0ed,a0
242
mov 0xfd00a1ed,a1
243
mov 0xfd00a2ed,a2
244
245
# we may be holding current in E2
246
#ifdef CONFIG_MN10300_CURRENT_IN_E2
247
mov init_task,e2
248
#endif
249
250
# initialise the processor and the unit
251
call processor_init[],0
252
call unit_init[],0
253
254
#ifdef CONFIG_SMP
255
# mark the primary CPU in cpu_boot_map
256
mov cpu_boot_map,a0
257
mov 0x1,d0
258
mov d0,(a0)
259
260
# signal each secondary CPU to begin booting
261
mov 0x1,d2 # CPU ID
262
263
loop_request_boot_secondary:
264
mov d2,a0
265
# send SMP_BOOT_IPI to secondary CPU
266
asl CROSS_ICR_CPU_SHIFT,a0
267
add CROSS_GxICR(SMP_BOOT_IRQ,0),a0
268
movhu (a0),d0
269
or GxICR_REQUEST|GxICR_DETECT,d0
270
movhu d0,(a0)
271
movhu (a0),d0 # flush
272
273
# wait up to 100ms for AP's IPI to be received
274
clr d3
275
wait_on_secondary_boot:
276
mov DELAY_TIME_BOOT_IPI,d0
277
call __delay[],0
278
inc d3
279
mov cpu_boot_map,a0
280
mov (a0),d0
281
lsr d2,d0
282
btst 0x1,d0
283
bne 1f
284
cmp TIME_OUT_COUNT_BOOT_IPI,d3
285
bne wait_on_secondary_boot
286
1:
287
inc d2
288
cmp NR_CPUS,d2
289
bne loop_request_boot_secondary
290
#endif /* CONFIG_SMP */
291
292
#ifdef CONFIG_GDBSTUB
293
call gdbstub_init[],0
294
295
#ifdef CONFIG_GDBSTUB_IMMEDIATE
296
.globl __gdbstub_pause
297
__gdbstub_pause:
298
bra __gdbstub_pause
299
#endif
300
#endif
301
302
jmp start_kernel
303
.size _start,.-_start
304
305
###############################################################################
306
#
307
# Secondary CPU boot point
308
#
309
###############################################################################
310
#ifdef CONFIG_SMP
311
startup_secondary:
312
# preload the PGD pointer register
313
mov swapper_pg_dir,d0
314
mov d0,(PTBR)
315
clr d0
316
movbu d0,(PIDR)
317
318
# turn on the TLBs
319
mov MMUCTR_IIV|MMUCTR_DIV,d0
320
mov d0,(MMUCTR)
321
#ifdef CONFIG_AM34_2
322
mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE|MMUCTR_WTE,d0
323
#else
324
mov MMUCTR_ITE|MMUCTR_DTE|MMUCTR_CE,d0
325
#endif
326
mov d0,(MMUCTR)
327
328
# turn on AM33v2 exception handling mode and set the trap table base
329
movhu (CPUP),d0
330
or CPUP_EXM_AM33V2,d0
331
movhu d0,(CPUP)
332
333
# set the interrupt vector table
334
mov CONFIG_INTERRUPT_VECTOR_BASE,d0
335
mov d0,(TBR)
336
337
# invalidate and enable both of the caches
338
mov ECHCTR,a0
339
clr d0
340
mov d0,(a0)
341
mov CHCTR,a0
342
clr d0
343
movhu d0,(a0) # turn off first
344
mov CHCTR_ICINV|CHCTR_DCINV,d0
345
movhu d0,(a0)
346
setlb
347
mov (a0),d0
348
btst CHCTR_ICBUSY|CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
349
lne
350
351
#ifdef CONFIG_MN10300_CACHE_ENABLED
352
#ifdef CONFIG_MN10300_CACHE_WBACK
353
#ifndef CONFIG_MN10300_CACHE_WBACK_NOWRALLOC
354
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK,d0
355
#else
356
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRBACK|CHCTR_DCALMD,d0
357
#endif /* !NOWRALLOC */
358
#else
359
mov CHCTR_ICEN|CHCTR_DCEN|CHCTR_DCWTMD_WRTHROUGH,d0
360
#endif /* WBACK */
361
movhu d0,(a0) # enable
362
#endif /* ENABLED */
363
364
# Clear the boot IPI interrupt for this CPU
365
movhu (GxICR(SMP_BOOT_IRQ)),d0
366
and ~GxICR_REQUEST,d0
367
movhu d0,(GxICR(SMP_BOOT_IRQ))
368
movhu (GxICR(SMP_BOOT_IRQ)),d0 # flush
369
370
/* get stack */
371
mov CONFIG_INTERRUPT_VECTOR_BASE + CONFIG_BOOT_STACK_OFFSET,a0
372
mov (CPUID),d0
373
and CPUID_MASK,d0
374
mulu CONFIG_BOOT_STACK_SIZE,d0
375
sub d0,a0
376
mov a0,sp
377
378
# init interrupt for AP
379
call smp_prepare_cpu_init[],0
380
381
# mark this secondary CPU in cpu_boot_map
382
mov (CPUID),d0
383
mov 0x1,d1
384
asl d0,d1
385
mov cpu_boot_map,a0
386
bset d1,(a0)
387
388
or EPSW_IE|EPSW_IM_1,epsw # permit level 0 interrupts
389
nop
390
nop
391
#ifdef CONFIG_MN10300_CACHE_WBACK
392
# flush the local cache if it's in writeback mode
393
call mn10300_local_dcache_flush_inv[],0
394
setlb
395
mov (CHCTR),d0
396
btst CHCTR_DCBUSY,d0 # wait till not busy (use CPU loop buffer)
397
lne
398
#endif
399
400
# now sleep waiting for further instructions
401
secondary_sleep:
402
mov CPUM_SLEEP,d0
403
movhu d0,(CPUM)
404
nop
405
nop
406
bra secondary_sleep
407
.size startup_secondary,.-startup_secondary
408
#endif /* CONFIG_SMP */
409
410
###############################################################################
411
#
412
#
413
#
414
###############################################################################
415
ENTRY(__head_end)
416
417
/*
418
* This is initialized to disallow all access to the low 2G region
419
* - the high 2G region is managed directly by the MMU
420
* - range 0x70000000-0x7C000000 are initialised for use by VMALLOC
421
*/
422
.section .bss
423
.balign PAGE_SIZE
424
ENTRY(swapper_pg_dir)
425
.space PTRS_PER_PGD*4
426
427
/*
428
* The page tables are initialized to only 8MB here - the final page
429
* tables are set up later depending on memory size.
430
*/
431
432
.balign PAGE_SIZE
433
ENTRY(empty_zero_page)
434
.space PAGE_SIZE
435
436
.balign PAGE_SIZE
437
ENTRY(empty_bad_page)
438
.space PAGE_SIZE
439
440
.balign PAGE_SIZE
441
ENTRY(empty_bad_pte_table)
442
.space PAGE_SIZE
443
444
.balign PAGE_SIZE
445
ENTRY(large_page_table)
446
.space PAGE_SIZE
447
448
.balign PAGE_SIZE
449
ENTRY(kernel_vmalloc_ptes)
450
.space ((VMALLOC_END-VMALLOC_START)/PAGE_SIZE)*4
451
452