linux/arch/m32r/kernel/head.S
<<
>>
Prefs
   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