1/* $NetBSD: start.S,v 1.1 2002/12/28 23:57:37 reinoud Exp $ */ 2 3/* 4 * Copyright (c) 2002 Reinoud Zandijk 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30#include <machine/asm.h> 31#include <arm/armreg.h> 32#include <riscoscalls.h> 33 34 35/* ----------------------------------------------------------------------- */ 36ENTRY(relocate_code) 37 /* 38 - r0 pointer to configuration structure 39 - r1 pointer to physical restart point 40 - r2 pointer to relocation table (P) 41 - r3 pointer to physical new L1 page address (P) 42 - r4 kernel entry point 43 */ 44 45 /* save registers / move args up in register bank later */ 46 /* r8-r12 becomes r0-r4 */ 47 stmfd sp!, {r0-r4} 48 ldmfd sp!, {r8-r12} 49 50 /* 51 * determine processor architecture version. This is nessisary for the 52 * correct coprocessor instruction. 53 */ 54 mrc 15, 0, r0, c0, c0, 0 /* read CPU id in r0 */ 55 mov r3, r0 /* store in r3 */ 56 57 /* assume its ARMv4 instruction set */ 58 mov r14, #1 59 60 /* check ARM6. It needs a special mask */ 61 mov r0, #0x0000ff00 62 mov r1, #0x00000600 /* check for 0xxxxx06xx => ARM6 */ 63 and r2, r3, r0 64 cmp r2, r1 65 moveq r14, #0 /* mark v3 */ 66 67 /* newer ARM's need a different mask */ 68 mov r0, #0x0000f000 69 70 /* check for ARM7 and derivatives like the ARM 7500 and ARM 7500FE */ 71 mov r1, #0x00007000 /* check for 0xxxxx7xxx => ARM 7 */ 72 and r2, r3, r0 73 cmp r2, r1 74 moveq r14, #0 /* mark v3 */ 75 76 /* switch off MMU, IDcache and WB and branch to physical code space */ 77 cmp r14, #0 78 mrcne 15, 0, r0, c1, c0, 0 /* read processor control register if v4*/ 79 bic r0, r0, #0x3f /* clear only known bits */ 80 moveq r0, #0 /* for v3 just set to zero */ 81 orr r0, r0, #CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_32BP_ENABLE 82 mov r13, r0 /* save this control value in r13 */ 83 cmp r14, #0 84 mcr 15, 0, r0, c1, c0, 0 /* write control register! */ 85/*1*/ mcrne 15, 0, r1, c7, c5, 0 /* write zero in ARMv4 MMU disable */ 86/*2*/ mov pc, r9 /* branch to physical address */ 87 88relocate_code_physical_restart: 89 /* we are running in physical flat 1:1 space now */ 90 mov r5, r10 /* r5 = is start of relocation table */ 91 ldr r6, [r5], #4 /* r4 = number of relocated pages */ 92loop_relocate_pages: 93 ldr r2, [r5], #4 /* r2 = from address */ 94 ldr r3, [r5], #4 /* r3 = to address */ 95 ldr r7, [r5], #4 /* r7 = number of bytes to travel */ 96 mov r1, #0 /* r1 = offset in page */ 97 /* its slow ... we dont know anything about alignment here */ 98loop_one_page: 99 ldrb r0, [r2, r1] 100 strb r0, [r3, r1] 101 add r1, r1, #1 102 cmp r1, r7 /* all bytes copied? */ 103 bne loop_one_page 104 subs r6, r6, #1 105 bne loop_relocate_pages 106 107 /* OK! all is relocated... now switch over to the new L1 pages */ 108 /* disable SA110 clock switching (WHY?) */ 109 mov r0, #0 110 cmp r14, #0 111 mcrne 15, 0, r0, c15, c2, 2 112 113 /* flush ID cache */ 114 mov r0, #0 115 cmp r14, #0 116 mcreq 15, 0, r0, c7, c0, 0 /* flush v3 ID cache */ 117 mcrne 15, 0, r0, c7, c7, 0 /* flush v4 ID cache */ 118 119 /* drain write buffer (v4) */ 120 mov r0, #0 121 cmp r14, #0 122 mcrne 15, 0, r0, c7, c10, 4 /* drain WB (v4) */ 123 124 /* flush TLB */ 125 mcr 15, 0, r0, c5, c0, 0 /* flush TLB for v3 and v4 */ 126 127 /* set new TLB address */ 128 mov r0, r11 129 mcr 15, 0, r0, c2, c0, 0 /* write TLB address */ 130 131 /* Switch on MMU, IDCache and WB and keep on running on flat translated memory */ 132 orr r0, r13, #CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_32BP_ENABLE 133 orr r0, r0, #CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_MMU_ENABLE 134 mcr 15, 0, r0, c1, c0, 0 /* write register !!! */ 135 mov r0, r0 /* flat */ 136 mov r0, r0 /* flat */ 137 /* not flat anymore but we just continue */ 138 139 /* call the kernel! */ 140 mov r0, r8 /* saved configuration structure */ 141 mov pc, r12 /* entry point ..... bye bye! */ 142 143relocate_code_end: 144 b relocate_code_end 145 146/* ----------------------------------------------------------------------- */ 147 148 149/* we are not expected to ever return from here */ 150ENTRY(start_kernel) 151 /* 152 entry conditions : 153 - on RISC OS page tables in usr26 mode on virtual space 154 - r0 relocation code page (V) 155 - r1 relocation pv offset 156 - r2 configuration structure 157 - r3 relocation table (P) 158 - r4 L1 page descriptor (P) 159 - r5 kernel entry point 160 */ 161 mov ip, sp 162 stmfd sp!, {r4-r9, fp, ip, lr, pc} 163 sub fp, ip, #4 164 165 /* get stuff out of the calling frame */ 166 ldr r4, [ip, #0] 167 ldr r5, [ip, #4] 168 169 /* relocate the relocation routine to the given page */ 170 adr r6, relocate_code 171 ldr r7, Lnbpp 172 mov r8, r0 173relocate_code_loop: 174 ldr r9, [r6], #4 175 str r9, [r8], #4 176 subs r7, r7, #4 177 bne relocate_code_loop 178 179 /* we messed up the data cache : lets read a 64 or 128 kb <-- GROSS */ 180 mov r7, #128*1024 181 mov r6, #0x8000 /* start of RISCOS application area */ 182flush_ID_cache_try: 183 ldr r9, [r6], #4 184 subs r7, r7, #4 185 bne flush_ID_cache_try 186 187 /* enter sub26 mode */ 188 swi OS_EnterOS 189 190 /* go to sup32 mode with ICQ and FIQ disabled */ 191 mrs r6, cpsr 192 bic r6, r6, #PSR_MODE /* clear processor mode */ 193 orr r6, r6, #(I32_bit | F32_bit) /* disable ICQ + FIQ */ 194 orr r6, r6, #PSR_SVC32_MODE /* go to 32 bit supervisor mode */ 195 msr cpsr, r6 196 mov r0, r0 /* nops ... just in case */ 197 mov r0, r0 198 199 /* set up info */ 200 mov r9, r0 /* save relocated page address */ 201 mov r7, #relocate_code_physical_restart - relocate_code /* get offset */ 202 add r1, r0, r1 /* get physical address */ 203 add r1, r1, r7 /* add offset */ 204 mov r0, r2 /* put configuration structure in r0 */ 205 mov r2, r3 /* relocation table */ 206 mov r3, r4 /* L1 page discriptor */ 207 mov r4, r5 /* kernel entry point */ 208 209 mov pc, r9 /* jump to page addr == relocate_code */ 210 211emergency_exit: 212 ldmdb fp, {r4-r9, fp, sp, pc} 213 214Lnbpp: 215 .word nbpp 216Lvideomem_start_ro: 217 .word videomem_start_ro 218 219