Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * ti omap3530 SoC machine assist
3
 * arm cortex-a8 processor
4
 *
5
 * loader uses R11 as scratch.
6
 * R9 and R10 are used for `extern register' variables.
7
 *
8
 * ARM v7 arch. ref. man. §B1.3.3 that we don't need barriers
9
 * around moves to CPSR.
10
 */
11
 
12
#include "arm.s"
13
 
14
/*
15
 * MCR and MRC are counter-intuitively named.
16
 *	MCR	coproc, opcode1, Rd, CRn, CRm[, opcode2]	# arm -> coproc
17
 *	MRC	coproc, opcode1, Rd, CRn, CRm[, opcode2]	# coproc -> arm
18
 */
19
 
20
/*
21
 * Entered here from Das U-Boot or another Plan 9 kernel with MMU disabled.
22
 * Until the MMU is enabled it is OK to call functions provided
23
 * they are within ±32MiB relative and do not require any
24
 * local variables or more than one argument (i.e. there is
25
 * no stack).
26
 */
27
TEXT _start(SB), 1, $-4
28
	MOVW	$setR12(SB), R12		/* load the SB */
29
	SUB	$KZERO, R12
30
	ADD	$PHYSDRAM, R12
31
 
32
	/* SVC mode, interrupts disabled */
33
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R1
34
	MOVW	R1, CPSR
35
	BARRIERS
36
 
37
	DELAY(printloopret, 1)
38
PUTC('\r')
39
	DELAY(printloopnl, 1)
40
PUTC('\n')
41
	/*
42
	 * work around errata
43
	 */
44
	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
45
	ORR	$(CpACissue1|CpACldstissue1), R1  /* fight omap35x errata 3.1.1.9 */
46
	ORR	$CpACibe, R1			/* enable cp15 invalidate */
47
	ORR	$CpACl1pe, R1			/* enable l1 parity checking */
48
	ORR	$CpCalign, R1			/* catch alignment errors */
49
	BIC	$CpACasa, R1			/* no speculative accesses */
50
	/* go faster with fewer restrictions */
51
	BIC	$(CpACcachenopipe|CpACcp15serial|CpACcp15waitidle|CpACcp15pipeflush), R1
52
	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
53
	ISB
54
 
55
	MRC	CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
56
	ORR	$CpCl2nowralloc, R1		/* fight cortex errata 460075 */
57
	ORR	$(CpCl2ecc|CpCl2eccparity), R1
58
#ifdef TEDIUM
59
	/*
60
	 * I don't know why this clobbers the system, but I'm tired
61
	 * of arguing with this fussy processor.  To hell with it.
62
	 */
63
	MCR	CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
64
	ISB
65
#endif
66
	DELAY(printloops, 1)
67
PUTC('P')
68
	/*
69
	 * disable the MMU & caches
70
	 */
71
	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
72
	BIC	$(CpCdcache|CpCicache|CpCmmu), R1
73
	ORR	$CpCsbo, R1
74
	BIC	$CpCsbz, R1
75
	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
76
	ISB
77
 
78
	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
79
	BIC	$CpACl2en, R1			/* turn l2 cache off */
80
	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
81
	ISB
82
 
83
PUTC('l')
84
	DELAY(printloop3, 1)
85
 
86
PUTC('a')
87
	/* clear Mach */
88
	MOVW	$PADDR(MACHADDR), R4		/* address of Mach */
89
	MOVW	$0, R0
90
_machZ:
91
	MOVW	R0, (R4)
92
	ADD	$4, R4
93
	CMP.S	$PADDR(L1+L1X(0)), R4	/* end at top-level page table */
94
	BNE	_machZ
95
 
96
	/*
97
	 * set up the MMU page table
98
	 */
99
 
100
PUTC('n')
101
	/* clear all PTEs first, to provide a default */
102
//	MOVW	$PADDR(L1+L1X(0)), R4		/* address of PTE for 0 */
103
_ptenv0:
104
	ZEROPTE()
105
	CMP.S	$PADDR(L1+16*KiB), R4
106
	BNE	_ptenv0
107
 
108
	DELAY(printloop4, 2)
109
PUTC(' ')
110
	/*
111
	 * set up double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs,
112
	 * but only if KZERO and PHYSDRAM differ.
113
	 */
114
	MOVW	$PTEDRAM, R2			/* PTE bits */
115
	MOVW	$PHYSDRAM, R3			/* pa */
116
	CMP	$KZERO, R3
117
	BEQ	no2map
118
	MOVW	$PADDR(L1+L1X(PHYSDRAM)), R4  /* address of PTE for PHYSDRAM */
119
	MOVW	$DOUBLEMAPMBS, R5
120
_ptdbl:
121
	FILLPTE()
122
	SUB.S	$1, R5
123
	BNE	_ptdbl
124
no2map:
125
 
126
	/*
127
	 * back up and fill in PTEs for memory at KZERO.
128
	 * beagle has 1 bank of 256MB of SDRAM at PHYSDRAM;
129
	 * igepv2 has 1 bank of 512MB at PHYSDRAM.
130
	 * Map the maximum (512MB).
131
	 */
132
PUTC('9')
133
	MOVW	$PTEDRAM, R2			/* PTE bits */
134
	MOVW	$PHYSDRAM, R3
135
	MOVW	$PADDR(L1+L1X(KZERO)), R4	/* start with PTE for KZERO */
136
	MOVW	$512, R5			/* inner loop count (MBs) */
137
_ptekrw:					/* set PTEs */
138
	FILLPTE()
139
	SUB.S	$1, R5				/* decrement inner loop count */
140
	BNE	_ptekrw
141
 
142
	/*
143
	 * back up and fill in PTEs for MMIO
144
	 * stop somewhere after uarts
145
	 */
146
PUTC(' ')
147
	MOVW	$PTEIO, R2			/* PTE bits */
148
	MOVW	$PHYSIO, R3
149
	MOVW	$PADDR(L1+L1X(VIRTIO)), R4	/* start with PTE for VIRTIO */
150
_ptenv2:
151
	FILLPTE()
152
	CMP.S	$PADDR(L1+L1X(PHYSIOEND)), R4
153
	BNE	_ptenv2
154
 
155
	/* mmu.c sets up the trap vectors later */
156
 
157
	/*
158
	 * set up a temporary stack; avoid data & bss segments
159
	 */
160
	MOVW	$(PHYSDRAM | (128*1024*1024)), R13
161
 
162
	/* invalidate caches */
163
	BL	cachedinv(SB)
164
	MOVW	$KZERO, R0
165
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
166
	ISB
167
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
168
	BARRIERS
169
 
170
PUTC('f')
171
	/*
172
	 * turn caches on
173
	 */
174
	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
175
	ORR	$CpACl2en, R1			/* turn l2 cache on */
176
	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl
177
	BARRIERS
178
 
179
	MRC	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
180
	ORR	$(CpCdcache|CpCicache), R1
181
	MCR	CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
182
	BARRIERS
183
 
184
PUTC('r')
185
	/* set the domain access control */
186
	MOVW	$Client, R0
187
	BL	dacput(SB)
188
 
189
	DELAY(printloop5, 2)
190
PUTC('o')
191
	/* set the translation table base */
192
	MOVW	$PADDR(L1), R0
193
	BL	ttbput(SB)
194
 
195
	MOVW	$0, R0
196
	BL	pidput(SB)		/* paranoia */
197
 
198
PUTC('m')
199
	/*
200
	 * the little dance to turn the MMU on
201
	 */
202
	BL	cacheuwbinv(SB)
203
	BL	mmuinvalidate(SB)
204
	BL	mmuenable(SB)
205
 
206
PUTC(' ')
207
	/* warp the PC into the virtual map */
208
	MOVW	$KZERO, R0
209
	BL	_r15warp(SB)
210
 
211
	/*
212
	 * now running at KZERO+something!
213
	 */
214
 
215
	MOVW	$setR12(SB), R12		/* reload the SB */
216
 
217
	/*
218
	 * set up temporary stack again, in case we've just switched
219
	 * to a new register set.
220
	 */
221
	MOVW	$(KZERO|(128*1024*1024)), R13
222
 
223
	/* can now execute arbitrary C code */
224
 
225
	BL	cacheuwbinv(SB)
226
 
227
PUTC('B')
228
	MOVW	$PHYSDRAM, R3			/* pa */
229
	CMP	$KZERO, R3
230
	BEQ	no2unmap
231
	/* undo double map of PHYSDRAM, KZERO & first few MBs */
232
	MOVW	$(L1+L1X(PHYSDRAM)), R4		/* addr. of PTE for PHYSDRAM */
233
	MOVW	$0, R0
234
	MOVW	$DOUBLEMAPMBS, R5
235
_ptudbl:
236
	ZEROPTE()
237
	SUB.S	$1, R5
238
	BNE	_ptudbl
239
no2unmap:
240
	BARRIERS
241
	MOVW	$KZERO, R0
242
	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
243
	BARRIERS
244
 
245
#ifdef HIGH_SECURITY				/* i.e., not GP omap */
246
	/* hack: set `secure monitor' vector base addr for cortex */
247
//	MOVW	$HVECTORS, R0
248
	MOVW	$PADDR(L1), R0
249
	SUB	$(MACHSIZE+(2*1024)), R0
250
	MCR	CpSC, 0, R0, C(CpVECS), C(CpVECSbase), CpVECSmon
251
	ISB
252
#endif
253
 
254
	/*
255
	 * call main in C
256
	 * pass Mach to main and set up the stack in it
257
	 */
258
	MOVW	$(MACHADDR), R0			/* Mach */
259
	MOVW	R0, R13
260
	ADD	$(MACHSIZE), R13		/* stack pointer */
261
	SUB	$4, R13				/* space for link register */
262
	MOVW	R0, R10				/* m = MACHADDR */
263
PUTC('e')
264
	BL	main(SB)			/* void main(Mach*) */
265
	/*FALLTHROUGH*/
266
 
267
/*
268
 * reset the system
269
 */
270
 
271
TEXT _reset(SB), 1, $-4
272
	MOVW	$(PsrDirq|PsrDfiq|PsrMsvc), R0
273
	MOVW	R0, CPSR
274
	BARRIERS
275
 
276
	DELAY(printloopr, 2)
277
PUTC('!')
278
PUTC('r')
279
PUTC('e')
280
PUTC('s')
281
PUTC('e')
282
PUTC('t')
283
PUTC('!')
284
PUTC('\r')
285
PUTC('\n')
286
 
287
	/* turn the caches off */
288
	BL	cacheuwbinv(SB)
289
 
290
	MRC	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
291
	BIC	$(CpCicache|CpCdcache|CpCalign), R0
292
	ORR	$CpCsw, R0			/* enable SWP */
293
	MCR	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
294
	BARRIERS
295
 
296
	/* redo double map of PHYSDRAM, KZERO & first few MBs */
297
	MOVW	$PTEDRAM, R2			/* PTE bits */
298
	MOVW	$PHYSDRAM, R3			/* pa */
299
	MOVW	$(L1+L1X(PHYSDRAM)), R4		/* address of PHYSDRAM's PTE */
300
	MOVW	$DOUBLEMAPMBS, R5
301
_ptrdbl:
302
	FILLPTE()
303
	SUB.S	$1, R5
304
	BNE	_ptrdbl
305
 
306
	MOVW	$PHYSDRAM, R0
307
	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
308
	BARRIERS
309
 
310
	/* turn the MMU off */
311
	MOVW	$PHYSDRAM, R0
312
	BL	_r15warp(SB)
313
	BL	mmuinvalidate(SB)
314
	BL	mmudisable(SB)
315
 
316
	/* set new reset vector */
317
	MOVW	$HVECTORS, R2
318
	MOVW	$0xe59ff018, R3			/* MOVW 0x18(R15), R15 */
319
	MOVW	R3, (R2)
320
	BARRIERS
321
 
322
//	MOVW	$PHYSFLASH, R3			/* TODO */
323
//	MOVW	R3, 0x20(R2)			/* where $0xe59ff018 jumps to */
324
 
325
	/* ...and jump to it */
326
//	MOVW	R2, R15				/* software reboot */
327
_limbo:						/* should not get here... */
328
	BL	idlehands(SB)
329
	B	_limbo				/* ... and can't get out */
330
	BL	_div(SB)			/* hack to load _div, etc. */
331
 
332
TEXT _r15warp(SB), 1, $-4
333
	BIC	$KSEGM, R14			/* link reg, will become PC */
334
	ORR	R0, R14
335
	BIC	$KSEGM, R13			/* SP too */
336
	ORR	R0, R13
337
	RET
338
 
339
/*
340
 * `single-element' cache operations.
341
 * in arm arch v7, they operate on all cache levels, so separate
342
 * l2 functions are unnecessary.
343
 */
344
 
345
TEXT cachedwbse(SB), $-4			/* D writeback SE */
346
	MOVW	R0, R2
347
 
348
	MOVW	CPSR, R3
349
	CPSID					/* splhi */
350
 
351
	BARRIERS			/* force outstanding stores to cache */
352
	MOVW	R2, R0
353
	MOVW	4(FP), R1
354
	ADD	R0, R1				/* R1 is end address */
355
	BIC	$(CACHELINESZ-1), R0		/* cache line start */
356
_dwbse:
357
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEse
358
	/* can't have a BARRIER here since it zeroes R0 */
359
	ADD	$CACHELINESZ, R0
360
	CMP.S	R0, R1
361
	BGT	_dwbse
362
	B	_wait
363
 
364
TEXT cachedwbinvse(SB), $-4			/* D writeback+invalidate SE */
365
	MOVW	R0, R2
366
 
367
	MOVW	CPSR, R3
368
	CPSID					/* splhi */
369
 
370
	BARRIERS			/* force outstanding stores to cache */
371
	MOVW	R2, R0
372
	MOVW	4(FP), R1
373
	ADD	R0, R1				/* R1 is end address */
374
	BIC	$(CACHELINESZ-1), R0		/* cache line start */
375
_dwbinvse:
376
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
377
	/* can't have a BARRIER here since it zeroes R0 */
378
	ADD	$CACHELINESZ, R0
379
	CMP.S	R0, R1
380
	BGT	_dwbinvse
381
_wait:						/* drain write buffer */
382
	BARRIERS
383
	/* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
384
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
385
	ISB
386
 
387
	MOVW	R3, CPSR			/* splx */
388
	RET
389
 
390
TEXT cachedinvse(SB), $-4			/* D invalidate SE */
391
	MOVW	R0, R2
392
 
393
	MOVW	CPSR, R3
394
	CPSID					/* splhi */
395
 
396
	BARRIERS			/* force outstanding stores to cache */
397
	MOVW	R2, R0
398
	MOVW	4(FP), R1
399
	ADD	R0, R1				/* R1 is end address */
400
	BIC	$(CACHELINESZ-1), R0		/* cache line start */
401
_dinvse:
402
	MCR	CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
403
	/* can't have a BARRIER here since it zeroes R0 */
404
	ADD	$CACHELINESZ, R0
405
	CMP.S	R0, R1
406
	BGT	_dinvse
407
	B	_wait
408
 
409
/*
410
 *  enable mmu and high vectors
411
 */
412
TEXT mmuenable(SB), 1, $-4
413
	MRC	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
414
	ORR	$(CpChv|CpCmmu), R0
415
	MCR	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
416
	BARRIERS
417
	RET
418
 
419
TEXT mmudisable(SB), 1, $-4
420
	MRC	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
421
	BIC	$(CpChv|CpCmmu), R0
422
	MCR	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
423
	BARRIERS
424
	RET
425
 
426
/*
427
 * If one of these MCR instructions crashes or hangs the machine,
428
 * check your Level 1 page table (at TTB) closely.
429
 */
430
TEXT mmuinvalidate(SB), $-4			/* invalidate all */
431
	MOVW	CPSR, R2
432
	CPSID					/* interrupts off */
433
 
434
	BARRIERS
435
	MOVW	PC, R0				/* some valid virtual address */
436
	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
437
	BARRIERS
438
	MOVW	R2, CPSR			/* interrupts restored */
439
	RET
440
 
441
TEXT mmuinvalidateaddr(SB), $-4			/* invalidate single entry */
442
	MCR	CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
443
	BARRIERS
444
	RET
445
 
446
TEXT cpidget(SB), 1, $-4			/* main ID */
447
	MRC	CpSC, 0, R0, C(CpID), C(0), CpIDid
448
	RET
449
 
450
TEXT cpctget(SB), 1, $-4			/* cache type */
451
	MRC	CpSC, 0, R0, C(CpID), C(0), CpIDct
452
	RET
453
 
454
TEXT controlget(SB), 1, $-4			/* control */
455
	MRC	CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
456
	RET
457
 
458
TEXT ttbget(SB), 1, $-4				/* translation table base */
459
	MRC	CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
460
	RET
461
 
462
TEXT ttbput(SB), 1, $-4				/* translation table base */
463
	MCR	CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
464
	MCR	CpSC, 0, R0, C(CpTTB), C(0), CpTTB1	/* cortex has two */
465
	ISB
466
	RET
467
 
468
TEXT dacget(SB), 1, $-4				/* domain access control */
469
	MRC	CpSC, 0, R0, C(CpDAC), C(0)
470
	RET
471
 
472
TEXT dacput(SB), 1, $-4				/* domain access control */
473
	MCR	CpSC, 0, R0, C(CpDAC), C(0)
474
	ISB
475
	RET
476
 
477
TEXT fsrget(SB), 1, $-4				/* data fault status */
478
	MRC	CpSC, 0, R0, C(CpFSR), C(0), CpDFSR
479
	RET
480
 
481
TEXT ifsrget(SB), 1, $-4			/* instruction fault status */
482
	MRC	CpSC, 0, R0, C(CpFSR), C(0), CpIFSR
483
	RET
484
 
485
TEXT farget(SB), 1, $-4				/* fault address */
486
	MRC	CpSC, 0, R0, C(CpFAR), C(0x0)
487
	RET
488
 
489
TEXT getpsr(SB), 1, $-4
490
	MOVW	CPSR, R0
491
	RET
492
 
493
TEXT getscr(SB), 1, $-4
494
	MRC	CpSC, 0, R0, C(CpCONTROL), C(CpCONTROLscr), CpSCRscr
495
	RET
496
 
497
TEXT pidget(SB), 1, $-4				/* address translation pid */
498
	MRC	CpSC, 0, R0, C(CpPID), C(0x0)
499
	RET
500
 
501
TEXT pidput(SB), 1, $-4				/* address translation pid */
502
	MCR	CpSC, 0, R0, C(CpPID), C(0x0)
503
	ISB
504
	RET
505
 
506
TEXT splhi(SB), 1, $-4
507
	MOVW	CPSR, R0
508
	CPSID					/* turn off interrupts */
509
 
510
	MOVW	$(MACHADDR+4), R2		/* save caller pc in Mach */
511
	MOVW	R14, 0(R2)
512
	RET
513
 
514
TEXT spllo(SB), 1, $-4			/* start marker for devkprof.c */
515
	MOVW	CPSR, R0
516
	CPSIE
517
	RET
518
 
519
TEXT splx(SB), 1, $-4
520
	MOVW	$(MACHADDR+0x04), R2		/* save caller pc in Mach */
521
	MOVW	R14, 0(R2)
522
 
523
	MOVW	CPSR, R3
524
	MOVW	R0, CPSR			/* reset interrupt level */
525
	MOVW	R3, R0				/* must return old CPSR */
526
	RET
527
 
528
TEXT spldone(SB), 1, $0				/* end marker for devkprof.c */
529
	RET
530
 
531
TEXT islo(SB), 1, $-4
532
	MOVW	CPSR, R0
533
	AND	$(PsrDirq), R0
534
	EOR	$(PsrDirq), R0
535
	RET
536
 
537
TEXT	tas(SB), $-4
538
TEXT	_tas(SB), $-4
539
	MOVW	R0,R1
540
	MOVW	$1,R0
541
	SWPW	R0,(R1)			/* fix: deprecated in armv7 */
542
	RET
543
 
544
TEXT clz(SB), $-4
545
	CLZ(0, 0)			/* 0 is R0 */
546
	RET
547
 
548
TEXT setlabel(SB), 1, $-4
549
	MOVW	R13, 0(R0)		/* sp */
550
	MOVW	R14, 4(R0)		/* pc */
551
	MOVW	$0, R0
552
	RET
553
 
554
TEXT gotolabel(SB), 1, $-4
555
	MOVW	0(R0), R13		/* sp */
556
	MOVW	4(R0), R14		/* pc */
557
	MOVW	$1, R0
558
	RET
559
 
560
TEXT getcallerpc(SB), 1, $-4
561
	MOVW	0(R13), R0
562
	RET
563
 
564
TEXT idlehands(SB), $-4
565
	BARRIERS
566
	WFI
567
	RET
568
 
569
TEXT coherence(SB), $-4
570
	BARRIERS
571
	RET
572
 
573
#include "cache.v7.s"