1/* 2 * nvidia tegra 2 machine assist, definitions 3 * dual-core cortex-a9 processor 4 * 5 * R9 and R10 are used for `extern register' variables. 6 * R11 is used by the loader as a temporary, so avoid it. 7 */ 8 9#include "mem.h" 10#include "arm.h" 11 12#undef B /* B is for 'botch' */ 13 14#define KADDR(pa) (KZERO | ((pa) & ~KSEGM)) 15#define PADDR(va) (PHYSDRAM | ((va) & ~KSEGM)) 16 17#define L1X(va) (((((va))>>20) & 0x0fff)<<2) 18 19#define MACHADDR (L1-MACHSIZE) /* only room for cpu0's */ 20 21/* L1 pte values */ 22#define PTEDRAM (Dom0|L1AP(Krw)|Section|L1ptedramattrs) 23#define PTEIO (Dom0|L1AP(Krw)|Section) 24 25#define DOUBLEMAPMBS 512 /* megabytes of low dram to double-map */ 26 27/* steps on R0 */ 28#define DELAY(label, mloops) \ 29 MOVW $((mloops)*1000000), R0; \ 30label: \ 31 SUB.S $1, R0; \ 32 BNE label 33 34/* print a byte on the serial console; clobbers R0 & R6; needs R12 (SB) set */ 35#define PUTC(c) \ 36 BARRIERS; \ 37 MOVW $(c), R0; \ 38 MOVW $PHYSCONS, R6; \ 39 MOVW R0, (R6); \ 40 BARRIERS 41 42/* 43 * new instructions 44 */ 45 46#define SMC WORD $0xe1600070 /* low 4-bits are call # (trustzone) */ 47/* flush branch-target cache */ 48#define FLBTC MTCP CpSC, 0, PC, C(CpCACHE), C(CpCACHEinvi), CpCACHEflushbtc 49/* flush one entry of the branch-target cache, va in R0 (cortex) */ 50#define FLBTSE MTCP CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEflushbtse 51 52/* arm v7 arch defines these */ 53#define DSB WORD $0xf57ff04f /* data synch. barrier; last f = SY */ 54#define DMB WORD $0xf57ff05f /* data mem. barrier; last f = SY */ 55#define ISB WORD $0xf57ff06f /* instr. sync. barrier; last f = SY */ 56 57#define WFI WORD $0xe320f003 /* wait for interrupt */ 58#define NOOP WORD $0xe320f000 59 60#define CLZ(s, d) WORD $(0xe16f0f10 | (d) << 12 | (s)) /* count leading 0s */ 61 62#define SETEND(o) WORD $(0xf1010000 | (o) << 9) /* o==0, little-endian */ 63 64#define CPSIE WORD $0xf1080080 /* intr enable: zeroes I bit */ 65#define CPSID WORD $0xf10c00c0 /* intr disable: sets I,F bits */ 66#define CPSAE WORD $0xf1080100 /* async abt enable: zeroes A bit */ 67#define CPSMODE(m) WORD $(0xf1020000 | (m)) /* switch to mode m (PsrM*) */ 68 69#define CLREX WORD $0xf57ff01f 70 71/* floating point */ 72#define VMRS(fp, cpu) WORD $(0xeef00a10 | (fp)<<16 | (cpu)<<12) /* FP → arm */ 73#define VMSR(cpu, fp) WORD $(0xeee00a10 | (fp)<<16 | (cpu)<<12) /* arm → FP */ 74 75/* 76 * a popular code sequence used to write a pte for va is: 77 * 78 * MOVW R(n), TTB[LnX(va)] 79 * // clean the cache line 80 * DSB 81 * // invalidate tlb entry for va 82 * FLBTC 83 * DSB 84 * PFF (now ISB) 85 */ 86#define BARRIERS FLBTC; DSB; ISB 87 88/* 89 * invoked with PTE bits in R2, pa in R3, PTE pointed to by R4. 90 * fill PTE pointed to by R4 and increment R4 past it. 91 * increment R3 by a MB. clobbers R1. 92 */ 93#define FILLPTE() \ 94 ORR R3, R2, R1; /* pte bits in R2, pa in R3 */ \ 95 MOVW R1, (R4); \ 96 ADD $4, R4; /* bump PTE address */ \ 97 ADD $MiB, R3; /* bump pa */ \ 98 99/* zero PTE pointed to by R4 and increment R4 past it. assumes R0 is 0. */ 100#define ZEROPTE() \ 101 MOVW R0, (R4); \ 102 ADD $4, R4; /* bump PTE address */ 103 104/* 105 * set kernel SB for zero segment (instead of usual KZERO segment). 106 * NB: the next line puts rubbish in R12: 107 * MOVW $setR12-KZERO(SB), R12 108 */ 109#define SETZSB \ 110 MOVW $setR12(SB), R12; /* load kernel's SB */ \ 111 SUB $KZERO, R12; \ 112 ADD $PHYSDRAM, R12 113 114/* 115 * note that 5a's RFE is not the v6/7 arch. instruction (0xf8900a00), 116 * which loads CPSR from the word after the PC at (R13), but rather 117 * the pre-v6 simulation `MOVM.IA.S.W (R13), [R15]' (0xe8fd8000 since 118 * MOVM is LDM in this case), which loads CPSR not from memory but 119 * from SPSR due to `.S'. 120 */ 121#define RFEV7(r) WORD $(0xf8900a00 | (r) << 16) 122#define RFEV7W(r) WORD $(0xf8900a00 | (r) << 16 | 0x00200000) /* RFE.W */ 123#define RFEV7DB(r) WORD $(0xf9100a00 | (r) << 16) /* RFE.DB */ 124#define RFEV7DBW(r) WORD $(0xf9100a00 | (r) << 16 | 0x00200000) /* RFE.DB.W */ 125 126#define CKPSR(psr, tmp, bad) 127#define CKCPSR(psrtmp, tmp, bad) 128 129/* return with cpu id in r and condition codes set from "r == 0" */ 130#define CPUID(r) \ 131 MFCP CpSC, 0, r, C(CpID), C(CpIDidct), CpIDmpid; \ 132 AND.S $(MAXMACH-1), r /* mask out non-cpu-id bits */ 133