]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/omap/l.s
kernel: remove Ipifc.mbps, unused.
[plan9front.git] / sys / src / 9 / omap / l.s
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 WAVE('\r')
39         DELAY(printloopnl, 1)
40 WAVE('\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 WAVE('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 WAVE('l')
84         DELAY(printloop3, 1)
85
86 WAVE('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 WAVE('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 WAVE(' ')
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 WAVE('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 WAVE(' ')
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 WAVE('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 WAVE('r')
185         /* set the domain access control */
186         MOVW    $Client, R0
187         BL      dacput(SB)
188
189         DELAY(printloop5, 2)
190 WAVE('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 WAVE('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 WAVE(' ')
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 WAVE('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 WAVE('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 WAVE('!')
278 WAVE('r')
279 WAVE('e')
280 WAVE('s')
281 WAVE('e')
282 WAVE('t')
283 WAVE('!')
284 WAVE('\r')
285 WAVE('\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"