leon.h 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * Copyright (C) 2004 Konrad Eisele (eiselekd@web.de,konrad@gaisler.com) Gaisler Research
  3. * Copyright (C) 2004 Stefan Holst (mail@s-holst.de) Uni-Stuttgart
  4. * Copyright (C) 2009 Daniel Hellstrom (daniel@gaisler.com) Aeroflex Gaisler AB
  5. * Copyright (C) 2009 Konrad Eisele (konrad@gaisler.com) Aeroflex Gaisler AB
  6. */
  7. #ifndef LEON_H_INCLUDE
  8. #define LEON_H_INCLUDE
  9. #ifdef CONFIG_SPARC_LEON
  10. /* mmu register access, ASI_LEON_MMUREGS */
  11. #define LEON_CNR_CTRL 0x000
  12. #define LEON_CNR_CTXP 0x100
  13. #define LEON_CNR_CTX 0x200
  14. #define LEON_CNR_F 0x300
  15. #define LEON_CNR_FADDR 0x400
  16. #define LEON_CNR_CTX_NCTX 256 /*number of MMU ctx */
  17. #define LEON_CNR_CTRL_TLBDIS 0x80000000
  18. #define LEON_MMUTLB_ENT_MAX 64
  19. /*
  20. * diagnostic access from mmutlb.vhd:
  21. * 0: pte address
  22. * 4: pte
  23. * 8: additional flags
  24. */
  25. #define LEON_DIAGF_LVL 0x3
  26. #define LEON_DIAGF_WR 0x8
  27. #define LEON_DIAGF_WR_SHIFT 3
  28. #define LEON_DIAGF_HIT 0x10
  29. #define LEON_DIAGF_HIT_SHIFT 4
  30. #define LEON_DIAGF_CTX 0x1fe0
  31. #define LEON_DIAGF_CTX_SHIFT 5
  32. #define LEON_DIAGF_VALID 0x2000
  33. #define LEON_DIAGF_VALID_SHIFT 13
  34. /* irq masks */
  35. #define LEON_HARD_INT(x) (1 << (x)) /* irq 0-15 */
  36. #define LEON_IRQMASK_R 0x0000fffe /* bit 15- 1 of lregs.irqmask */
  37. #define LEON_IRQPRIO_R 0xfffe0000 /* bit 31-17 of lregs.irqmask */
  38. #define LEON_MCFG2_SRAMDIS 0x00002000
  39. #define LEON_MCFG2_SDRAMEN 0x00004000
  40. #define LEON_MCFG2_SRAMBANKSZ 0x00001e00 /* [12-9] */
  41. #define LEON_MCFG2_SRAMBANKSZ_SHIFT 9
  42. #define LEON_MCFG2_SDRAMBANKSZ 0x03800000 /* [25-23] */
  43. #define LEON_MCFG2_SDRAMBANKSZ_SHIFT 23
  44. #define LEON_TCNT0_MASK 0x7fffff
  45. #define ASI_LEON3_SYSCTRL 0x02
  46. #define ASI_LEON3_SYSCTRL_ICFG 0x08
  47. #define ASI_LEON3_SYSCTRL_DCFG 0x0c
  48. #define ASI_LEON3_SYSCTRL_CFG_SNOOPING (1 << 27)
  49. #define ASI_LEON3_SYSCTRL_CFG_SSIZE(c) (1 << ((c >> 20) & 0xf))
  50. #ifndef __ASSEMBLY__
  51. /* do a virtual address read without cache */
  52. static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
  53. {
  54. unsigned long retval;
  55. __asm__ __volatile__("lda [%1] %2, %0\n\t" :
  56. "=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
  57. return retval;
  58. }
  59. /* do a physical address bypass write, i.e. for 0x80000000 */
  60. static inline void leon_store_reg(unsigned long paddr, unsigned long value)
  61. {
  62. __asm__ __volatile__("sta %0, [%1] %2\n\t" : : "r"(value), "r"(paddr),
  63. "i"(ASI_LEON_BYPASS) : "memory");
  64. }
  65. /* do a physical address bypass load, i.e. for 0x80000000 */
  66. static inline unsigned long leon_load_reg(unsigned long paddr)
  67. {
  68. unsigned long retval;
  69. __asm__ __volatile__("lda [%1] %2, %0\n\t" :
  70. "=r"(retval) : "r"(paddr), "i"(ASI_LEON_BYPASS));
  71. return retval;
  72. }
  73. static inline void leon_srmmu_disabletlb(void)
  74. {
  75. unsigned int retval;
  76. __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
  77. "i"(ASI_LEON_MMUREGS));
  78. retval |= LEON_CNR_CTRL_TLBDIS;
  79. __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
  80. "i"(ASI_LEON_MMUREGS) : "memory");
  81. }
  82. static inline void leon_srmmu_enabletlb(void)
  83. {
  84. unsigned int retval;
  85. __asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
  86. "i"(ASI_LEON_MMUREGS));
  87. retval = retval & ~LEON_CNR_CTRL_TLBDIS;
  88. __asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
  89. "i"(ASI_LEON_MMUREGS) : "memory");
  90. }
  91. /* macro access for leon_load_reg() and leon_store_reg() */
  92. #define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
  93. #define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
  94. #define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
  95. #define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
  96. #define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
  97. #define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
  98. #define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
  99. #define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
  100. #define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
  101. #define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))
  102. /* macro access for leon_readnobuffer_reg() */
  103. #define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))
  104. extern void leon_init(void);
  105. extern void leon_switch_mm(void);
  106. extern void leon_init_IRQ(void);
  107. extern unsigned long last_valid_pfn;
  108. static inline unsigned long sparc_leon3_get_dcachecfg(void)
  109. {
  110. unsigned int retval;
  111. __asm__ __volatile__("lda [%1] %2, %0\n\t" :
  112. "=r"(retval) :
  113. "r"(ASI_LEON3_SYSCTRL_DCFG),
  114. "i"(ASI_LEON3_SYSCTRL));
  115. return retval;
  116. }
  117. /* enable snooping */
  118. static inline void sparc_leon3_enable_snooping(void)
  119. {
  120. __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
  121. "set 0x800000, %%l2\n\t"
  122. "or %%l2, %%l1, %%l2\n\t"
  123. "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
  124. };
  125. static inline int sparc_leon3_snooping_enabled(void)
  126. {
  127. u32 cctrl;
  128. __asm__ __volatile__("lda [%%g0] 2, %0\n\t" : "=r"(cctrl));
  129. return (cctrl >> 23) & 1;
  130. };
  131. static inline void sparc_leon3_disable_cache(void)
  132. {
  133. __asm__ __volatile__ ("lda [%%g0] 2, %%l1\n\t"
  134. "set 0x00000f, %%l2\n\t"
  135. "andn %%l2, %%l1, %%l2\n\t"
  136. "sta %%l2, [%%g0] 2\n\t" : : : "l1", "l2");
  137. };
  138. static inline unsigned long sparc_leon3_asr17(void)
  139. {
  140. u32 asr17;
  141. __asm__ __volatile__ ("rd %%asr17, %0\n\t" : "=r"(asr17));
  142. return asr17;
  143. };
  144. static inline int sparc_leon3_cpuid(void)
  145. {
  146. return sparc_leon3_asr17() >> 28;
  147. }
  148. #endif /*!__ASSEMBLY__*/
  149. #ifdef CONFIG_SMP
  150. # define LEON3_IRQ_IPI_DEFAULT 13
  151. # define LEON3_IRQ_TICKER (leon3_ticker_irq)
  152. # define LEON3_IRQ_CROSS_CALL 15
  153. #endif
  154. #if defined(PAGE_SIZE_LEON_8K)
  155. #define LEON_PAGE_SIZE_LEON 1
  156. #elif defined(PAGE_SIZE_LEON_16K)
  157. #define LEON_PAGE_SIZE_LEON 2)
  158. #else
  159. #define LEON_PAGE_SIZE_LEON 0
  160. #endif
  161. #if LEON_PAGE_SIZE_LEON == 0
  162. /* [ 8, 6, 6 ] + 12 */
  163. #define LEON_PGD_SH 24
  164. #define LEON_PGD_M 0xff
  165. #define LEON_PMD_SH 18
  166. #define LEON_PMD_SH_V (LEON_PGD_SH-2)
  167. #define LEON_PMD_M 0x3f
  168. #define LEON_PTE_SH 12
  169. #define LEON_PTE_M 0x3f
  170. #elif LEON_PAGE_SIZE_LEON == 1
  171. /* [ 7, 6, 6 ] + 13 */
  172. #define LEON_PGD_SH 25
  173. #define LEON_PGD_M 0x7f
  174. #define LEON_PMD_SH 19
  175. #define LEON_PMD_SH_V (LEON_PGD_SH-1)
  176. #define LEON_PMD_M 0x3f
  177. #define LEON_PTE_SH 13
  178. #define LEON_PTE_M 0x3f
  179. #elif LEON_PAGE_SIZE_LEON == 2
  180. /* [ 6, 6, 6 ] + 14 */
  181. #define LEON_PGD_SH 26
  182. #define LEON_PGD_M 0x3f
  183. #define LEON_PMD_SH 20
  184. #define LEON_PMD_SH_V (LEON_PGD_SH-0)
  185. #define LEON_PMD_M 0x3f
  186. #define LEON_PTE_SH 14
  187. #define LEON_PTE_M 0x3f
  188. #elif LEON_PAGE_SIZE_LEON == 3
  189. /* [ 4, 7, 6 ] + 15 */
  190. #define LEON_PGD_SH 28
  191. #define LEON_PGD_M 0x0f
  192. #define LEON_PMD_SH 21
  193. #define LEON_PMD_SH_V (LEON_PGD_SH-0)
  194. #define LEON_PMD_M 0x7f
  195. #define LEON_PTE_SH 15
  196. #define LEON_PTE_M 0x3f
  197. #else
  198. #error cannot determine LEON_PAGE_SIZE_LEON
  199. #endif
  200. #define PAGE_MIN_SHIFT (12)
  201. #define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)
  202. #define LEON3_XCCR_SETS_MASK 0x07000000UL
  203. #define LEON3_XCCR_SSIZE_MASK 0x00f00000UL
  204. #define LEON2_CCR_DSETS_MASK 0x03000000UL
  205. #define LEON2_CFG_SSIZE_MASK 0x00007000UL
  206. #ifndef __ASSEMBLY__
  207. struct vm_area_struct;
  208. extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
  209. extern void leon_flush_icache_all(void);
  210. extern void leon_flush_dcache_all(void);
  211. extern void leon_flush_cache_all(void);
  212. extern void leon_flush_tlb_all(void);
  213. extern int leon_flush_during_switch;
  214. extern int leon_flush_needed(void);
  215. extern void leon_flush_pcache_all(struct vm_area_struct *vma, unsigned long page);
  216. /* struct that hold LEON3 cache configuration registers */
  217. struct leon3_cacheregs {
  218. unsigned long ccr; /* 0x00 - Cache Control Register */
  219. unsigned long iccr; /* 0x08 - Instruction Cache Configuration Register */
  220. unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
  221. };
  222. /* struct that hold LEON2 cache configuration register
  223. * & configuration register
  224. */
  225. struct leon2_cacheregs {
  226. unsigned long ccr, cfg;
  227. };
  228. #ifdef __KERNEL__
  229. #include <linux/interrupt.h>
  230. struct device_node;
  231. extern unsigned int leon_build_device_irq(unsigned int real_irq,
  232. irq_flow_handler_t flow_handler,
  233. const char *name, int do_ack);
  234. extern void leon_update_virq_handling(unsigned int virq,
  235. irq_flow_handler_t flow_handler,
  236. const char *name, int do_ack);
  237. extern void leon_init_timers(void);
  238. extern void leon_trans_init(struct device_node *dp);
  239. extern void leon_node_init(struct device_node *dp, struct device_node ***nextp);
  240. extern void init_leon(void);
  241. extern void poke_leonsparc(void);
  242. extern void leon3_getCacheRegs(struct leon3_cacheregs *regs);
  243. extern int leon3_ticker_irq;
  244. #ifdef CONFIG_SMP
  245. extern int leon_smp_nrcpus(void);
  246. extern void leon_clear_profile_irq(int cpu);
  247. extern void leon_smp_done(void);
  248. extern void leon_boot_cpus(void);
  249. extern int leon_boot_one_cpu(int i);
  250. void leon_init_smp(void);
  251. extern void cpu_idle(void);
  252. extern void init_IRQ(void);
  253. extern void cpu_panic(void);
  254. extern int __leon_processor_id(void);
  255. void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
  256. extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);
  257. extern unsigned int real_irq_entry[];
  258. extern unsigned int smpleon_ipi[];
  259. extern unsigned int patchme_maybe_smp_msg[];
  260. extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
  261. extern unsigned int linux_trap_ipi15_sun4m[];
  262. extern int leon_ipi_irq;
  263. #endif /* CONFIG_SMP */
  264. #endif /* __KERNEL__ */
  265. #endif /* __ASSEMBLY__ */
  266. /* macros used in leon_mm.c */
  267. #define PFN(x) ((x) >> PAGE_SHIFT)
  268. #define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
  269. #define _SRMMU_PTE_PMASK_LEON 0xffffffff
  270. #else /* defined(CONFIG_SPARC_LEON) */
  271. /* nop definitions for !LEON case */
  272. #define leon_init() do {} while (0)
  273. #define leon_switch_mm() do {} while (0)
  274. #define leon_init_IRQ() do {} while (0)
  275. #define init_leon() do {} while (0)
  276. #define leon_smp_done() do {} while (0)
  277. #define leon_boot_cpus() do {} while (0)
  278. #define leon_boot_one_cpu(i) 1
  279. #define leon_init_smp() do {} while (0)
  280. #endif /* !defined(CONFIG_SPARC_LEON) */
  281. #endif