2 * ti omap3530 SoC machine assist
3 * arm cortex-a8 processor
5 * loader uses R11 as scratch.
6 * R9 and R10 are used for `extern register' variables.
8 * ARM v7 arch. ref. man. §B1.3.3 that we don't need barriers
9 * around moves to CPSR.
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
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
27 TEXT _start(SB), 1, $-4
28 MOVW $setR12(SB), R12 /* load the SB */
32 /* SVC mode, interrupts disabled */
33 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
37 DELAY(printloopret, 1)
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
55 MRC CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
56 ORR $CpCl2nowralloc, R1 /* fight cortex errata 460075 */
57 ORR $(CpCl2ecc|CpCl2eccparity), R1
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.
63 MCR CpSC, 1, R1, C(CpCLD), C(CpCLDl2), CpCLDl2aux
69 * disable the MMU & caches
71 MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
72 BIC $(CpCdcache|CpCicache|CpCmmu), R1
75 MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
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
88 MOVW $PADDR(MACHADDR), R4 /* address of Mach */
93 CMP.S $PADDR(L1+L1X(0)), R4 /* end at top-level page table */
97 * set up the MMU page table
101 /* clear all PTEs first, to provide a default */
102 // MOVW $PADDR(L1+L1X(0)), R4 /* address of PTE for 0 */
105 CMP.S $PADDR(L1+16*KiB), R4
111 * set up double map of PHYSDRAM, KZERO to PHYSDRAM for first few MBs,
112 * but only if KZERO and PHYSDRAM differ.
114 MOVW $PTEDRAM, R2 /* PTE bits */
115 MOVW $PHYSDRAM, R3 /* pa */
118 MOVW $PADDR(L1+L1X(PHYSDRAM)), R4 /* address of PTE for PHYSDRAM */
119 MOVW $DOUBLEMAPMBS, R5
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).
133 MOVW $PTEDRAM, R2 /* PTE bits */
135 MOVW $PADDR(L1+L1X(KZERO)), R4 /* start with PTE for KZERO */
136 MOVW $512, R5 /* inner loop count (MBs) */
137 _ptekrw: /* set PTEs */
139 SUB.S $1, R5 /* decrement inner loop count */
143 * back up and fill in PTEs for MMIO
144 * stop somewhere after uarts
147 MOVW $PTEIO, R2 /* PTE bits */
149 MOVW $PADDR(L1+L1X(VIRTIO)), R4 /* start with PTE for VIRTIO */
152 CMP.S $PADDR(L1+L1X(PHYSIOEND)), R4
155 /* mmu.c sets up the trap vectors later */
158 * set up a temporary stack; avoid data & bss segments
160 MOVW $(PHYSDRAM | (128*1024*1024)), R13
162 /* invalidate caches */
165 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
167 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
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
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
185 /* set the domain access control */
191 /* set the translation table base */
196 BL pidput(SB) /* paranoia */
200 * the little dance to turn the MMU on
207 /* warp the PC into the virtual map */
212 * now running at KZERO+something!
215 MOVW $setR12(SB), R12 /* reload the SB */
218 * set up temporary stack again, in case we've just switched
219 * to a new register set.
221 MOVW $(KZERO|(128*1024*1024)), R13
223 /* can now execute arbitrary C code */
228 MOVW $PHYSDRAM, R3 /* pa */
231 /* undo double map of PHYSDRAM, KZERO & first few MBs */
232 MOVW $(L1+L1X(PHYSDRAM)), R4 /* addr. of PTE for PHYSDRAM */
234 MOVW $DOUBLEMAPMBS, R5
242 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
245 #ifdef HIGH_SECURITY /* i.e., not GP omap */
246 /* hack: set `secure monitor' vector base addr for cortex */
247 // MOVW $HVECTORS, R0
249 SUB $(MACHSIZE+(2*1024)), R0
250 MCR CpSC, 0, R0, C(CpVECS), C(CpVECSbase), CpVECSmon
256 * pass Mach to main and set up the stack in it
258 MOVW $(MACHADDR), R0 /* Mach */
260 ADD $(MACHSIZE), R13 /* stack pointer */
261 SUB $4, R13 /* space for link register */
262 MOVW R0, R10 /* m = MACHADDR */
264 BL main(SB) /* void main(Mach*) */
271 TEXT _reset(SB), 1, $-4
272 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0
287 /* turn the caches off */
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
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
307 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
310 /* turn the MMU off */
316 /* set new reset vector */
318 MOVW $0xe59ff018, R3 /* MOVW 0x18(R15), R15 */
322 // MOVW $PHYSFLASH, R3 /* TODO */
323 // MOVW R3, 0x20(R2) /* where $0xe59ff018 jumps to */
325 /* ...and jump to it */
326 // MOVW R2, R15 /* software reboot */
327 _limbo: /* should not get here... */
329 B _limbo /* ... and can't get out */
330 BL _div(SB) /* hack to load _div, etc. */
332 TEXT _r15warp(SB), 1, $-4
333 BIC $KSEGM, R14 /* link reg, will become PC */
335 BIC $KSEGM, R13 /* SP too */
340 * `single-element' cache operations.
341 * in arm arch v7, they operate on all cache levels, so separate
342 * l2 functions are unnecessary.
345 TEXT cachedwbse(SB), $-4 /* D writeback SE */
351 BARRIERS /* force outstanding stores to cache */
354 ADD R0, R1 /* R1 is end address */
355 BIC $(CACHELINESZ-1), R0 /* cache line start */
357 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEse
358 /* can't have a BARRIER here since it zeroes R0 */
364 TEXT cachedwbinvse(SB), $-4 /* D writeback+invalidate SE */
370 BARRIERS /* force outstanding stores to cache */
373 ADD R0, R1 /* R1 is end address */
374 BIC $(CACHELINESZ-1), R0 /* cache line start */
376 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEse
377 /* can't have a BARRIER here since it zeroes R0 */
381 _wait: /* drain write buffer */
383 /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */
384 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
387 MOVW R3, CPSR /* splx */
390 TEXT cachedinvse(SB), $-4 /* D invalidate SE */
396 BARRIERS /* force outstanding stores to cache */
399 ADD R0, R1 /* R1 is end address */
400 BIC $(CACHELINESZ-1), R0 /* cache line start */
402 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEse
403 /* can't have a BARRIER here since it zeroes R0 */
410 * enable mmu and high vectors
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
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
427 * If one of these MCR instructions crashes or hangs the machine,
428 * check your Level 1 page table (at TTB) closely.
430 TEXT mmuinvalidate(SB), $-4 /* invalidate all */
432 CPSID /* interrupts off */
435 MOVW PC, R0 /* some valid virtual address */
436 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
438 MOVW R2, CPSR /* interrupts restored */
441 TEXT mmuinvalidateaddr(SB), $-4 /* invalidate single entry */
442 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinvse
446 TEXT cpidget(SB), 1, $-4 /* main ID */
447 MRC CpSC, 0, R0, C(CpID), C(0), CpIDid
450 TEXT cpctget(SB), 1, $-4 /* cache type */
451 MRC CpSC, 0, R0, C(CpID), C(0), CpIDct
454 TEXT controlget(SB), 1, $-4 /* control */
455 MRC CpSC, 0, R0, C(CpCONTROL), C(0), CpMainctl
458 TEXT ttbget(SB), 1, $-4 /* translation table base */
459 MRC CpSC, 0, R0, C(CpTTB), C(0), CpTTB0
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 */
468 TEXT dacget(SB), 1, $-4 /* domain access control */
469 MRC CpSC, 0, R0, C(CpDAC), C(0)
472 TEXT dacput(SB), 1, $-4 /* domain access control */
473 MCR CpSC, 0, R0, C(CpDAC), C(0)
477 TEXT fsrget(SB), 1, $-4 /* data fault status */
478 MRC CpSC, 0, R0, C(CpFSR), C(0), CpDFSR
481 TEXT ifsrget(SB), 1, $-4 /* instruction fault status */
482 MRC CpSC, 0, R0, C(CpFSR), C(0), CpIFSR
485 TEXT farget(SB), 1, $-4 /* fault address */
486 MRC CpSC, 0, R0, C(CpFAR), C(0x0)
489 TEXT getpsr(SB), 1, $-4
493 TEXT getscr(SB), 1, $-4
494 MRC CpSC, 0, R0, C(CpCONTROL), C(CpCONTROLscr), CpSCRscr
497 TEXT pidget(SB), 1, $-4 /* address translation pid */
498 MRC CpSC, 0, R0, C(CpPID), C(0x0)
501 TEXT pidput(SB), 1, $-4 /* address translation pid */
502 MCR CpSC, 0, R0, C(CpPID), C(0x0)
506 TEXT splhi(SB), 1, $-4
508 CPSID /* turn off interrupts */
510 MOVW $(MACHADDR+4), R2 /* save caller pc in Mach */
514 TEXT spllo(SB), 1, $-4 /* start marker for devkprof.c */
519 TEXT splx(SB), 1, $-4
520 MOVW $(MACHADDR+0x04), R2 /* save caller pc in Mach */
524 MOVW R0, CPSR /* reset interrupt level */
525 MOVW R3, R0 /* must return old CPSR */
528 TEXT spldone(SB), 1, $0 /* end marker for devkprof.c */
531 TEXT islo(SB), 1, $-4
541 SWPW R0,(R1) /* fix: deprecated in armv7 */
545 CLZ(0, 0) /* 0 is R0 */
548 TEXT setlabel(SB), 1, $-4
549 MOVW R13, 0(R0) /* sp */
550 MOVW R14, 4(R0) /* pc */
554 TEXT gotolabel(SB), 1, $-4
555 MOVW 0(R0), R13 /* sp */
556 MOVW 4(R0), R14 /* pc */
560 TEXT getcallerpc(SB), 1, $-4
564 TEXT idlehands(SB), $-4
569 TEXT coherence(SB), $-4
573 #include "cache.v7.s"