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