arm.s 4.0 KB

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