1/* 2 * linux/arch/m32r/kernel/head.S 3 * 4 * M32R startup code. 5 * 6 * Copyright (c) 2001, 2002 Hiroyuki Kondo, Hirokazu Takata, 7 * Hitoshi Yamamoto 8 */ 9 10#include <linux/init.h> 11__INIT 12__INITDATA 13 14 .text 15#include <linux/linkage.h> 16#include <asm/segment.h> 17#include <asm/page.h> 18#include <asm/pgtable.h> 19#include <asm/assembler.h> 20#include <asm/m32r.h> 21#include <asm/mmu_context.h> 22 23/* 24 * References to members of the boot_cpu_data structure. 25 */ 26__HEAD 27 .global start_kernel 28 .global __bss_start 29 .global _end 30ENTRY(stext) 31ENTRY(_stext) 32 /* Setup up the stack pointer */ 33 LDIMM (r0, spi_stack_top) 34 LDIMM (r1, spu_stack_top) 35 mvtc r0, spi 36 mvtc r1, spu 37 38 /* Initilalize PSW */ 39 ldi r0, #0x0000 /* use SPI, disable EI */ 40 mvtc r0, psw 41 42 /* Set up the stack pointer */ 43 LDIMM (r0, stack_start) 44 ld r0, @r0 45 mvtc r0, spi 46 47/* 48 * Clear BSS first so that there are no surprises... 49 */ 50#ifdef CONFIG_ISA_DUAL_ISSUE 51 52 LDIMM (r2, __bss_start) 53 LDIMM (r3, _end) 54 sub r3, r2 ; BSS size in bytes 55 ; R4 = BSS size in longwords (rounded down) 56 mv r4, r3 || ldi r1, #0 57 srli r4, #4 || addi r2, #-4 58 beqz r4, .Lendloop1 59.Lloop1: 60#ifndef CONFIG_CHIP_M32310 61 ; Touch memory for the no-write-allocating cache. 62 ld r0, @(4,r2) 63#endif 64 st r1, @+r2 || addi r4, #-1 65 st r1, @+r2 66 st r1, @+r2 67 st r1, @+r2 || cmpeq r1, r4 ; R4 = 0? 68 bnc .Lloop1 69.Lendloop1: 70 and3 r4, r3, #15 71 addi r2, #4 72 beqz r4, .Lendloop2 73.Lloop2: 74 stb r1, @r2 || addi r4, #-1 75 addi r2, #1 76 bnez r4, .Lloop2 77.Lendloop2: 78 79#else /* not CONFIG_ISA_DUAL_ISSUE */ 80 81 LDIMM (r2, __bss_start) 82 LDIMM (r3, _end) 83 sub r3, r2 ; BSS size in bytes 84 mv r4, r3 85 srli r4, #2 ; R4 = BSS size in longwords (rounded down) 86 ldi r1, #0 ; clear R1 for longwords store 87 addi r2, #-4 ; account for pre-inc store 88 beqz r4, .Lendloop1 ; any more to go? 89.Lloop1: 90 st r1, @+r2 ; yep, zero out another longword 91 addi r4, #-1 ; decrement count 92 bnez r4, .Lloop1 ; go do some more 93.Lendloop1: 94 and3 r4, r3, #3 ; get no. of remaining BSS bytes to clear 95 addi r2, #4 ; account for pre-inc store 96 beqz r4, .Lendloop2 ; any more to go? 97.Lloop2: 98 stb r1, @r2 ; yep, zero out another byte 99 addi r2, #1 ; bump address 100 addi r4, #-1 ; decrement count 101 bnez r4, .Lloop2 ; go do some more 102.Lendloop2: 103 104#endif /* not CONFIG_ISA_DUAL_ISSUE */ 105 106#if 0 /* M32R_FIXME */ 107/* 108 * Copy data segment from ROM to RAM. 109 */ 110 .global ROM_D, TOP_DATA, END_DATA 111 112 LDIMM (r1, ROM_D) 113 LDIMM (r2, TOP_DATA) 114 LDIMM (r3, END_DATA) 115 addi r2, #-4 116 addi r3, #-4 117loop1: 118 ld r0, @r1+ 119 st r0, @+r2 120 cmp r2, r3 121 bc loop1 122#endif /* 0 */ 123 124/* Jump to kernel */ 125 LDIMM (r2, start_kernel) 126 jl r2 127 .fillinsn 1281: 129 bra 1b ; main should never return here, but 130 ; just in case, we know what happens. 131 132#ifdef CONFIG_SMP 133/* 134 * AP startup routine 135 */ 136 .global eit_vector 137ENTRY(startup_AP) 138;; setup EVB 139 LDIMM (r4, eit_vector) 140 mvtc r4, cr5 141 142;; enable MMU 143 LDIMM (r2, init_tlb) 144 jl r2 145 seth r4, #high(MATM) 146 or3 r4, r4, #low(MATM) 147 ldi r5, #0x01 148 st r5, @r4 ; Set MATM Reg(T bit ON) 149 ld r6, @r4 ; MATM Check 150 LDIMM (r5, 1f) 151 jmp r5 ; enable MMU 152 nop 153 .fillinsn 1541: 155;; ISN check 156 ld r6, @r4 ; MATM Check 157 seth r4, #high(M32R_ICU_ISTS_ADDR) 158 or3 r4, r4, #low(M32R_ICU_ISTS_ADDR) 159 ld r5, @r4 ; Read ISTSi reg. 160 mv r6, r5 161 slli r5, #13 ; PIML check 162 srli r5, #13 ; 163 seth r4, #high(M32R_ICU_IMASK_ADDR) 164 or3 r4, r4, #low(M32R_ICU_IMASK_ADDR) 165 st r5, @r4 ; Write IMASKi reg. 166 slli r6, #4 ; ISN check 167 srli r6, #26 ; 168 seth r4, #high(M32R_IRQ_IPI5) 169 or3 r4, r4, #low(M32R_IRQ_IPI5) 170 bne r4, r6, 2f ; if (ISN != CPU_BOOT_IPI) goto sleep; 171 172;; check cpu_bootout_map and set cpu_bootin_map 173 LDIMM (r4, cpu_bootout_map) 174 ld r4, @r4 175 seth r5, #high(M32R_CPUID_PORTL) 176 or3 r5, r5, #low(M32R_CPUID_PORTL) 177 ld r5, @r5 178 ldi r6, #1 179 sll r6, r5 180 and r4, r6 181 beqz r4, 2f 182 LDIMM (r4, cpu_bootin_map) 183 ld r5, @r4 184 or r5, r6 185 st r6, @r4 186 187;; clear PSW 188 ldi r4, #0 189 mvtc r4, psw 190 191;; setup SPI 192 LDIMM (r4, stack_start) 193 ld r4, @r4 194 mvtc r4, spi 195 196;; setup BPC (start_secondary) 197 LDIMM (r4, start_secondary) 198 mvtc r4, bpc 199 200 rte ; goto startup_secondary 201 nop 202 nop 203 204 .fillinsn 2052: 206 ;; disable MMU 207 seth r4, #high(MATM) 208 or3 r4, r4, #low(MATM) 209 ldi r5, #0 210 st r5, @r4 ; Set MATM Reg(T bit OFF) 211 ld r6, @r4 ; MATM Check 212 LDIMM (r4, 3f) 213 seth r5, #high(__PAGE_OFFSET) 214 or3 r5, r5, #low(__PAGE_OFFSET) 215 not r5, r5 216 and r4, r5 217 jmp r4 ; disable MMU 218 nop 219 .fillinsn 2203: 221 ;; SLEEP and wait IPI 222 LDIMM (r4, AP_loop) 223 seth r5, #high(__PAGE_OFFSET) 224 or3 r5, r5, #low(__PAGE_OFFSET) 225 not r5, r5 226 and r4, r5 227 jmp r4 228 nop 229 nop 230#endif /* CONFIG_SMP */ 231 232 .text 233ENTRY(stack_start) 234 .long init_thread_union+8192 235 .long __KERNEL_DS 236 237/* 238 * This is initialized to create a identity-mapping at 0-4M (for bootup 239 * purposes) and another mapping of the 0-4M area at virtual address 240 * PAGE_OFFSET. 241 */ 242 .text 243 244#define MOUNT_ROOT_RDONLY 1 245#define RAMDISK_FLAGS 0 ; 1024KB 246#define ORIG_ROOT_DEV 0x0100 ; /dev/ram0 (major:01, minor:00) 247#define LOADER_TYPE 1 ; (??? - non-zero value seems 248 ; to be needed to boot from initrd) 249 250#define COMMAND_LINE "" 251 252 .section .empty_zero_page, "aw" 253ENTRY(empty_zero_page) 254 .long MOUNT_ROOT_RDONLY /* offset: +0x00 */ 255 .long RAMDISK_FLAGS 256 .long ORIG_ROOT_DEV 257 .long LOADER_TYPE 258 .long 0 /* INITRD_START */ /* +0x10 */ 259 .long 0 /* INITRD_SIZE */ 260 .long 0 /* CPU_CLOCK */ 261 .long 0 /* BUS_CLOCK */ 262 .long 0 /* TIMER_DIVIDE */ /* +0x20 */ 263 .balign 256,0 264 .asciz COMMAND_LINE 265 .byte 0 266 .balign 4096,0,4096 267 268/*------------------------------------------------------------------------ 269 * Stack area 270 */ 271 .section .init.data, "aw" 272 ALIGN 273 .global spi_stack_top 274 .zero 1024 275spi_stack_top: 276 277 .section .init.data, "aw" 278 ALIGN 279 .global spu_stack_top 280 .zero 1024 281spu_stack_top: 282 283 .end 284