1/* 2 * linux/arch/m32r/boot/compressed/head.S 3 * 4 * Copyright (c) 2001-2003 Hiroyuki Kondo, Hirokazu Takata, 5 * Hitoshi Yamamoto, Takeo Takahashi 6 * Copyright (c) 2004 Hirokazu Takata 7 */ 8 9 .text 10#include <linux/linkage.h> 11#include <asm/addrspace.h> 12#include <asm/page.h> 13#include <asm/assembler.h> 14 15 /* 16 * This code can be loaded anywhere, as long as output will not 17 * overlap it. 18 * 19 * NOTE: This head.S should *NOT* be compiled with -fpic. 20 * 21 */ 22 23 .global startup 24 .global __bss_start, _ebss, end, zimage_data, zimage_len 25 __ALIGN 26startup: 27 ldi r0, #0x0000 /* SPI, disable EI */ 28 mvtc r0, psw 29 30 ldi r12, #-8 31 bl 1f 32 .fillinsn 331: 34 seth r1, #high(CONFIG_MEMORY_START + 0x00400000) /* Start address */ 35 add r12, r14 /* Real address */ 36 sub r12, r1 /* difference */ 37 38 .global got_len 39 seth r3, #high(_GLOBAL_OFFSET_TABLE_+8) 40 or3 r3, r3, #low(_GLOBAL_OFFSET_TABLE_+12) 41 add r3, r14 42 43 /* Update the contents of global offset table */ 44 ldi r1, #low(got_len) 45 srli r1, #2 46 beqz r1, 2f 47 .fillinsn 481: 49 ld r2, @r3 50 add r2, r12 51 st r2, @r3 52 addi r3, #4 53 addi r1, #-1 54 bnez r1, 1b 55 .fillinsn 562: 57 /* XXX: resolve plt */ 58 59/* 60 * Clear BSS first so that there are no surprises... 61 */ 62#ifdef CONFIG_ISA_DUAL_ISSUE 63 seth r2, #high(__bss_start) 64 or3 r2, r2, #low(__bss_start) 65 add r2, r12 66 seth r3, #high(_ebss) 67 or3 r3, r3, #low(_ebss) 68 add r3, r12 69 sub r3, r2 70 71 ; R4 = BSS size in longwords (rounded down) 72 mv r4, r3 || ldi r1, #0 73 srli r4, #4 || addi r2, #-4 74 beqz r4, .Lendloop1 75.Lloop1: 76#ifndef CONFIG_CHIP_M32310 77 ; Touch memory for the no-write-allocating cache. 78 ld r0, @(4,r2) 79#endif 80 st r1, @+r2 || addi r4, #-1 81 st r1, @+r2 82 st r1, @+r2 83 st r1, @+r2 || cmpeq r1, r4 ; R4 = 0? 84 bnc .Lloop1 85.Lendloop1: 86 and3 r4, r3, #15 87 addi r2, #4 88 beqz r4, .Lendloop2 89.Lloop2: 90 stb r1, @r2 || addi r4, #-1 91 addi r2, #1 92 bnez r4, .Lloop2 93.Lendloop2: 94 95#else /* not CONFIG_ISA_DUAL_ISSUE */ 96 seth r2, #high(__bss_start) 97 or3 r2, r2, #low(__bss_start) 98 add r2, r12 99 seth r3, #high(_ebss) 100 or3 r3, r3, #low(_ebss) 101 add r3, r12 102 sub r3, r2 103 mv r4, r3 104 srli r4, #2 ; R4 = BSS size in longwords (rounded down) 105 ldi r1, #0 ; clear R1 for longwords store 106 addi r2, #-4 ; account for pre-inc store 107 beqz r4, .Lendloop1 ; any more to go? 108.Lloop1: 109 st r1, @+r2 ; yep, zero out another longword 110 addi r4, #-1 ; decrement count 111 bnez r4, .Lloop1 ; go do some more 112.Lendloop1: 113 114#endif /* not CONFIG_ISA_DUAL_ISSUE */ 115 116 seth r1, #high(end) 117 or3 r1, r1, #low(end) 118 add r1, r12 119 mv sp, r1 120 121/* 122 * decompress the kernel 123 */ 124 mv r0, sp 125 srli r0, 31 /* MMU is ON or OFF */ 126 seth r1, #high(zimage_data) 127 or3 r1, r1, #low(zimage_data) 128 add r1, r12 129 seth r2, #high(zimage_len) 130 or3 r2, r2, #low(zimage_len) 131 mv r3, sp 132 133 bl decompress_kernel 134 135#if defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_VDEC2) 136 /* Cache flush */ 137 ldi r0, -1 138 ldi r1, 0xd0 ; invalidate i-cache, copy back d-cache 139 stb r1, @r0 140#elif defined(CONFIG_CHIP_M32102) 141 /* Cache flush */ 142 ldi r0, -2 143 ldi r1, 0x0100 ; invalidate 144 stb r1, @r0 145#elif defined(CONFIG_CHIP_M32104) 146 /* Cache flush */ 147 ldi r0, -2 148 ldi r1, 0x0700 ; invalidate i-cache, copy back d-cache 149 sth r1, @r0 150#else 151#error "put your cache flush function, please" 152#endif 153 154 mv r0, sp 155 srli r0, 31 /* MMU is ON or OFF */ 156 slli r0, 31 157 or3 r0, r0, #0x2000 158 seth r1, #high(CONFIG_MEMORY_START) 159 or r0, r1 160 jmp r0 161 162 .balign 512 163fake_headers_as_bzImage: 164 .short 0 165 .ascii "HdrS" 166 .short 0x0202 167 .short 0 168 .short 0 169 .byte 0x00, 0x10 170 .short 0 171 .byte 0 172 .byte 1 173 .byte 0x00, 0x80 174 .long 0 175 .long 0 176 177