1/* 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 5 * 6 * arch/sh5/kernel/head.S 7 * 8 * Copyright (C) 2000, 2001 Paolo Alberelli 9 * 10 * 11 * benedict.gaster@superh.com: 2nd May 2002 12 * Moved definition of empty_zero_page to its own section allowing 13 * it to be placed at an absolute address known at load time. 14 * 15 * lethal@linux-sh.org: 9th May 2003 16 * Kill off GLOBAL_NAME() usage. 17 */ 18 19#include <linux/config.h> 20 21#include <asm/page.h> 22#include <asm/mmu_context.h> 23#include <asm/cache.h> 24#include <asm/tlb.h> 25#include <asm/processor.h> 26#include <asm/registers.h> 27 28/* 29 * MMU defines: TLB boundaries. 30 */ 31 32#define MMUIR_FIRST ITLB_FIXED 33#define MMUIR_END ITLB_LAST_VAR_UNRESTRICTED+TLB_STEP 34#define MMUIR_STEP TLB_STEP 35 36#define MMUDR_FIRST DTLB_FIXED 37#define MMUDR_END DTLB_LAST_VAR_UNRESTRICTED+TLB_STEP 38#define MMUDR_STEP TLB_STEP 39 40/* Safety check : CONFIG_CACHED_MEMORY_OFFSET has to be a multiple of 512Mb */ 41#if (CONFIG_CACHED_MEMORY_OFFSET & ((1UL<<29)-1)) 42#error "CONFIG_CACHED_MEMORY_OFFSET must be a multiple of 512Mb" 43#endif 44 45/* 46 * MMU defines: Fixed TLBs. 47 */ 48/* Deal safely with the case where the base of RAM is not 512Mb aligned */ 49 50#define ALIGN_512M_MASK (0xffffffffe0000000) 51#define ALIGNED_EFFECTIVE ((CONFIG_CACHED_MEMORY_OFFSET + CONFIG_MEMORY_START) & ALIGN_512M_MASK) 52#define ALIGNED_PHYSICAL (CONFIG_MEMORY_START & ALIGN_512M_MASK) 53 54#define MMUIR_TEXT_H (0x0000000000000003 | ALIGNED_EFFECTIVE) 55 /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ 56 57#define MMUIR_TEXT_L (0x000000000000009a | ALIGNED_PHYSICAL) 58 /* 512 Mb, Cacheable, Write-back, execute, Not User, Ph. Add. */ 59 60#define MMUDR_CACHED_H 0x0000000000000003 | ALIGNED_EFFECTIVE 61 /* Enabled, Shared, ASID 0, Eff. Add. 0xA0000000 */ 62#define MMUDR_CACHED_L 0x000000000000015a | ALIGNED_PHYSICAL 63 /* 512 Mb, Cacheable, Write-back, read/write, Not User, Ph. Add. */ 64 65#ifdef CONFIG_ICACHE_DISABLED 66#define ICCR0_INIT_VAL ICCR0_OFF /* ICACHE off */ 67#else 68#define ICCR0_INIT_VAL ICCR0_ON | ICCR0_ICI /* ICE + ICI */ 69#endif 70#define ICCR1_INIT_VAL ICCR1_NOLOCK /* No locking */ 71 72#if defined (CONFIG_DCACHE_DISABLED) 73#define OCCR0_INIT_VAL OCCR0_OFF /* D-cache: off */ 74#elif defined (CONFIG_DCACHE_WRITE_THROUGH) 75#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WT /* D-cache: on, */ 76 /* WT, invalidate */ 77#elif defined (CONFIG_DCACHE_WRITE_BACK) 78#define OCCR0_INIT_VAL OCCR0_ON | OCCR0_OCI | OCCR0_WB /* D-cache: on, */ 79 /* WB, invalidate */ 80#else 81#error preprocessor flag CONFIG_DCACHE_... not recognized! 82#endif 83 84#define OCCR1_INIT_VAL OCCR1_NOLOCK /* No locking */ 85 86 .section .empty_zero_page, "aw" 87 .global empty_zero_page 88 89empty_zero_page: 90 .long 1 /* MOUNT_ROOT_RDONLY */ 91 .long 0 /* RAMDISK_FLAGS */ 92 .long 0x0200 /* ORIG_ROOT_DEV */ 93 .long 1 /* LOADER_TYPE */ 94 .long 0x00360000 /* INITRD_START */ 95 .long 0x000a0000 /* INITRD_SIZE */ 96 .long 0 97 98 .text 99 .balign 4096,0,4096 100 101 .section .data, "aw" 102 .balign PAGE_SIZE 103 104 .section .data, "aw" 105 .balign PAGE_SIZE 106 107 .global swapper_pg_dir 108swapper_pg_dir: 109 .space PAGE_SIZE, 0 110 111 .global empty_bad_page 112empty_bad_page: 113 .space PAGE_SIZE, 0 114 115 .global empty_bad_pte_table 116empty_bad_pte_table: 117 .space PAGE_SIZE, 0 118 119variables: 120 .global fpu_in_use 121fpu_in_use: .quad 0 122 123 124 .section .text, "ax" 125 .balign L1_CACHE_BYTES 126/* 127 * Condition at the entry of __stext: 128 * . Reset state: 129 * . SR.FD = 1 (FPU disabled) 130 * . SR.BL = 1 (Exceptions disabled) 131 * . SR.MD = 1 (Privileged Mode) 132 * . SR.MMU = 0 (MMU Disabled) 133 * . SR.CD = 0 (CTC User Visible) 134 * . SR.IMASK = Undefined (Interrupt Mask) 135 * 136 * Operations supposed to be performed by __stext: 137 * . prevent speculative fetch onto device memory while MMU is off 138 * . reflect as much as possible SH5 ABI (r15, r26, r27, r18) 139 * . first, save CPU state and set it to something harmless 140 * . any CPU detection and/or endianness settings (?) 141 * . initialize EMI/LMI (but not TMU/RTC/INTC/SCIF): TBD 142 * . set initial TLB entries for cached and uncached regions 143 * (no fine granularity paging) 144 * . set initial cache state 145 * . enable MMU and caches 146 * . set CPU to a consistent state 147 * . registers (including stack pointer and current/KCR0) 148 * . NOT expecting to set Exception handling nor VBR/RESVEC/DCR 149 * at this stage. This is all to later Linux initialization steps. 150 * . initialize FPU 151 * . clear BSS 152 * . jump into start_kernel() 153 * . be prepared to hopeless start_kernel() returns. 154 * 155 */ 156 .global _stext 157_stext: 158 /* 159 * Prevent speculative fetch on device memory due to 160 * uninitialized target registers. 161 */ 162 ptabs/u ZERO, t0 163 ptabs/u ZERO, t1 164 ptabs/u ZERO, t2 165 ptabs/u ZERO, t3 166 ptabs/u ZERO, t4 167 ptabs/u ZERO, t5 168 ptabs/u ZERO, t6 169 ptabs/u ZERO, t7 170 synci 171 172 /* 173 * Set variable/constant pointers according to SH5 ABI. 174 */ 175 _loada constants, GCDT 176 177 _loada variables, GVDT 178 179 /* 180 * Read/Set CPU state. After this block: 181 * r29 = Initial SR 182 */ 183 getcon SR, r29 184 movi SR_HARMLESS, r20 185 putcon r20, SR 186 187 /* 188 * Initialize EMI/LMI. To Be Done. 189 */ 190 191 /* 192 * CPU detection and/or endianness settings (?). To Be Done. 193 * Pure PIC code here, please ! Just save state into r30. 194 * After this block: 195 * r30 = CPU type/Platform Endianness 196 */ 197 198 /* 199 * Set initial TLB entries for cached and uncached regions. 200 * Note: PTA/BLINK is PIC code, PTABS/BLINK isn't ! 201 */ 202 /* Clear ITLBs */ 203 _ptar clear_ITLB, t1 204 movi MMUIR_FIRST, r21 205 movi MMUIR_END, r22 206clear_ITLB: 207 putcfg r21, 0, ZERO /* Clear MMUIR[n].PTEH.V */ 208 addi r21, MMUIR_STEP, r21 209 bne r21, r22, t1 210 211 /* Clear DTLBs */ 212 _ptar clear_DTLB, t1 213 movi MMUDR_FIRST, r21 214 movi MMUDR_END, r22 215clear_DTLB: 216 putcfg r21, 0, ZERO /* Clear MMUDR[n].PTEH.V */ 217 addi r21, MMUDR_STEP, r21 218 bne r21, r22, t1 219 220 /* Map one big (512Mb) page for ITLB */ 221 movi MMUIR_FIRST, r21 222 movi MMUIR_TEXT_L, r22 /* PTEL first */ 223 add.l r22, r63, r22 /* Sign extend */ 224 putcfg r21, 1, r22 /* Set MMUIR[0].PTEL */ 225 movi MMUIR_TEXT_H, r22 /* PTEH last */ 226 add.l r22, r63, r22 /* Sign extend */ 227 putcfg r21, 0, r22 /* Set MMUIR[0].PTEH */ 228 229 /* Map one big CACHED (512Mb) page for DTLB */ 230 movi MMUDR_FIRST, r21 231 movi MMUDR_CACHED_L, r22 /* PTEL first */ 232 add.l r22, r63, r22 /* Sign extend */ 233 putcfg r21, 1, r22 /* Set MMUDR[0].PTEL */ 234 movi MMUDR_CACHED_H, r22 /* PTEH last */ 235 add.l r22, r63, r22 /* Sign extend */ 236 putcfg r21, 0, r22 /* Set MMUDR[0].PTEH */ 237 238 /* 239 * Set cache behaviours. 240 */ 241 /* ICache */ 242 movi ICCR_BASE, r21 243 movi ICCR0_INIT_VAL, r22 244 movi ICCR1_INIT_VAL, r23 245 putcfg r21, ICCR_REG0, r22 246 putcfg r21, ICCR_REG1, r23 247 248 /* OCache */ 249 movi OCCR_BASE, r21 250 movi OCCR0_INIT_VAL, r22 251 movi OCCR1_INIT_VAL, r23 252 putcfg r21, OCCR_REG0, r22 253 putcfg r21, OCCR_REG1, r23 254 255 256 /* 257 * Enable Caches and MMU. Do the first non-PIC jump. 258 * Now head.S global variables, constants and externs 259 * can be used. 260 */ 261 getcon SR, r21 262 movi SR_ENABLE_MMU, r22 263 or r21, r22, r21 264 putcon r21, SSR 265 _loada hyperspace, r22 266 ori r22, 1, r22 /* Make it SHmedia, not required but..*/ 267 putcon r22, SPC 268 synco 269 rte /* And now go into the hyperspace ... */ 270hyperspace: /* ... that's the next instruction ! */ 271 272 /* 273 * Set CPU to a consistent state. 274 * r31 = FPU support flag 275 * t0/t7 in use. Others give a chance to loop somewhere safe 276 */ 277 _loada start_kernel, r32 278 ori r32, 1, r32 279 280 ptabs r32, t0 /* r32 = _start_kernel address */ 281 _ptaru hopeless, t1 282 _ptaru hopeless, t2 283 _ptaru hopeless, t3 284 _ptaru hopeless, t4 285 _ptaru hopeless, t5 286 _ptaru hopeless, t6 287 _ptar hopeless, t7 288 gettr t1, r28 /* r28 = hopeless address */ 289 290 /* Set initial stack pointer */ 291 _loada init_task_union, SP 292 putcon SP, KCR0 /* Set current to init_task */ 293 movi THREAD_SIZE, r22 /* Point to the end */ 294 add SP, r22, SP 295 296 /* 297 * Initialize FPU. 298 * Keep FPU flag in r31. After this block: 299 * r31 = FPU flag 300 */ 301 addi GVDT, fpu_in_use - variables, r31 /* Temporary */ 302 303#ifndef CONFIG_NOFPU_SUPPORT 304 getcon SR, r21 305 movi SR_ENABLE_FPU, r22 306 and r21, r22, r22 307 putcon r22, SR /* Try to enable */ 308 getcon SR, r22 309 xor r21, r22, r21 310 shlri r21, 15, r21 /* Supposedly 0/1 */ 311 st.q r31, 0 , r21 /* Set fpu_in_use */ 312#else 313 movi 0, r21 314 st.q r31, 0 , r21 /* Set fpu_in_use */ 315#endif 316 or r21, ZERO, r31 /* Set FPU flag at last */ 317 318 /* 319 * Clear bss 320 */ 321 _ptar clear_quad, t1 322 _loada __bss_start, r22 323 _loada _end, r23 324clear_quad: 325 st.q r22, 0, ZERO 326 addi r22, 8, r22 327 bne r22, r23, t1 /* Both quad aligned, see vmlinux.lds.S */ 328 _ptaru hopeless, t1 329 330 /* Say bye to head.S but be prepared to wrongly get back ... */ 331 blink t0, LINK 332 333 /* If we ever get back here through LINK/t1-t7 */ 334 _ptaru hopeless, t7 335 336hopeless: 337 /* 338 * Something's badly wrong here. Loop endlessly, 339 * there's nothing more we can do about it. 340 * 341 * Note on hopeless: it can be jumped into invariably 342 * before or after jumping into hyperspace. The only 343 * requirement is to be PIC called (PTA) before and 344 * any way (PTA/PTABS) after. According to Virtual 345 * to Physical mapping a simulator/emulator can easily 346 * tell where we came here from just looking at hopeless 347 * (PC) address. 348 * 349 * For debugging purposes: 350 * (r28) hopeless/loop address 351 * (r29) Original SR 352 * (r30) CPU type/Platform endianness 353 * (r31) FPU Support 354 * (r32) _start_kernel address 355 */ 356 blink t7, ZERO 357 358 359 .balign L1_CACHE_BYTES 360constants: 361dummyc: .quad 0 362 363