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 107/* Jump to kernel */ 108 LDIMM (r2, start_kernel) 109 jl r2 110 .fillinsn 1111: 112 bra 1b ; main should never return here, but 113 ; just in case, we know what happens. 114 115#ifdef CONFIG_SMP 116/* 117 * AP startup routine 118 */ 119 .global eit_vector 120ENTRY(startup_AP) 121;; setup EVB 122 LDIMM (r4, eit_vector) 123 mvtc r4, cr5 124 125;; enable MMU 126 LDIMM (r2, init_tlb) 127 jl r2 128 seth r4, #high(MATM) 129 or3 r4, r4, #low(MATM) 130 ldi r5, #0x01 131 st r5, @r4 ; Set MATM Reg(T bit ON) 132 ld r6, @r4 ; MATM Check 133 LDIMM (r5, 1f) 134 jmp r5 ; enable MMU 135 nop 136 .fillinsn 1371: 138;; ISN check 139 ld r6, @r4 ; MATM Check 140 seth r4, #high(M32R_ICU_ISTS_ADDR) 141 or3 r4, r4, #low(M32R_ICU_ISTS_ADDR) 142 ld r5, @r4 ; Read ISTSi reg. 143 mv r6, r5 144 slli r5, #13 ; PIML check 145 srli r5, #13 ; 146 seth r4, #high(M32R_ICU_IMASK_ADDR) 147 or3 r4, r4, #low(M32R_ICU_IMASK_ADDR) 148 st r5, @r4 ; Write IMASKi reg. 149 slli r6, #4 ; ISN check 150 srli r6, #26 ; 151 seth r4, #high(M32R_IRQ_IPI5) 152 or3 r4, r4, #low(M32R_IRQ_IPI5) 153 bne r4, r6, 2f ; if (ISN != CPU_BOOT_IPI) goto sleep; 154 155;; check cpu_bootout_map and set cpu_bootin_map 156 LDIMM (r4, cpu_bootout_map) 157 ld r4, @r4 158 seth r5, #high(M32R_CPUID_PORTL) 159 or3 r5, r5, #low(M32R_CPUID_PORTL) 160 ld r5, @r5 161 ldi r6, #1 162 sll r6, r5 163 and r4, r6 164 beqz r4, 2f 165 LDIMM (r4, cpu_bootin_map) 166 ld r5, @r4 167 or r5, r6 168 st r6, @r4 169 170;; clear PSW 171 ldi r4, #0 172 mvtc r4, psw 173 174;; setup SPI 175 LDIMM (r4, stack_start) 176 ld r4, @r4 177 mvtc r4, spi 178 179;; setup BPC (start_secondary) 180 LDIMM (r4, start_secondary) 181 mvtc r4, bpc 182 183 rte ; goto startup_secondary 184 nop 185 nop 186 187 .fillinsn 1882: 189 ;; disable MMU 190 seth r4, #high(MATM) 191 or3 r4, r4, #low(MATM) 192 ldi r5, #0 193 st r5, @r4 ; Set MATM Reg(T bit OFF) 194 ld r6, @r4 ; MATM Check 195 LDIMM (r4, 3f) 196 seth r5, #high(__PAGE_OFFSET) 197 or3 r5, r5, #low(__PAGE_OFFSET) 198 not r5, r5 199 and r4, r5 200 jmp r4 ; disable MMU 201 nop 202 .fillinsn 2033: 204 ;; SLEEP and wait IPI 205 LDIMM (r4, AP_loop) 206 seth r5, #high(__PAGE_OFFSET) 207 or3 r5, r5, #low(__PAGE_OFFSET) 208 not r5, r5 209 and r4, r5 210 jmp r4 211 nop 212 nop 213#endif /* CONFIG_SMP */ 214 215 .text 216ENTRY(stack_start) 217 .long init_thread_union+8192 218 .long __KERNEL_DS 219 220/* 221 * This is initialized to create a identity-mapping at 0-4M (for bootup 222 * purposes) and another mapping of the 0-4M area at virtual address 223 * PAGE_OFFSET. 224 */ 225 .text 226 227#define MOUNT_ROOT_RDONLY 1 228#define RAMDISK_FLAGS 0 ; 1024KB 229#define ORIG_ROOT_DEV 0x0100 ; /dev/ram0 (major:01, minor:00) 230#define LOADER_TYPE 1 ; (??? - non-zero value seems 231 ; to be needed to boot from initrd) 232 233#define COMMAND_LINE "" 234 235 .section .empty_zero_page, "aw" 236ENTRY(empty_zero_page) 237 .long MOUNT_ROOT_RDONLY /* offset: +0x00 */ 238 .long RAMDISK_FLAGS 239 .long ORIG_ROOT_DEV 240 .long LOADER_TYPE 241 .long 0 /* INITRD_START */ /* +0x10 */ 242 .long 0 /* INITRD_SIZE */ 243 .long 0 /* CPU_CLOCK */ 244 .long 0 /* BUS_CLOCK */ 245 .long 0 /* TIMER_DIVIDE */ /* +0x20 */ 246 .balign 256,0 247 .asciz COMMAND_LINE 248 .byte 0 249 .balign 4096,0,4096 250 251/*------------------------------------------------------------------------ 252 * Stack area 253 */ 254 .section .init.data, "aw" 255 ALIGN 256 .global spi_stack_top 257 .zero 1024 258spi_stack_top: 259 260 .section .init.data, "aw" 261 ALIGN 262 .global spu_stack_top 263 .zero 1024 264spu_stack_top: 265 266 .end 267