start.S revision 1.2
1/* $NetBSD: start.S,v 1.2 2008/01/25 23:18:59 chris 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 109 /* flush ID cache */ 110 mov r0, #0 111 cmp r14, #0 112 mcreq 15, 0, r0, c7, c0, 0 /* flush v3 ID cache */ 113 mcrne 15, 0, r0, c7, c7, 0 /* flush v4 ID cache */ 114 115 /* drain write buffer (v4) */ 116 mov r0, #0 117 cmp r14, #0 118 mcrne 15, 0, r0, c7, c10, 4 /* drain WB (v4) */ 119 120 /* flush TLB */ 121 mcr 15, 0, r0, c5, c0, 0 /* flush TLB for v3 and v4 */ 122 123 /* set new TLB address */ 124 mov r0, r11 125 mcr 15, 0, r0, c2, c0, 0 /* write TLB address */ 126 127 /* Switch on MMU, IDCache and WB and keep on running on flat translated memory */ 128 orr r0, r13, #CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_32BP_ENABLE 129 orr r0, r0, #CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_MMU_ENABLE 130 mcr 15, 0, r0, c1, c0, 0 /* write register !!! */ 131 mov r0, r0 /* flat */ 132 mov r0, r0 /* flat */ 133 /* not flat anymore but we just continue */ 134 135 /* call the kernel! */ 136 mov r0, r8 /* saved configuration structure */ 137 mov pc, r12 /* entry point ..... bye bye! */ 138 139relocate_code_end: 140 b relocate_code_end 141 142/* ----------------------------------------------------------------------- */ 143 144 145/* we are not expected to ever return from here */ 146ENTRY(start_kernel) 147 /* 148 entry conditions : 149 - on RISC OS page tables in usr26 mode on virtual space 150 - r0 relocation code page (V) 151 - r1 relocation pv offset 152 - r2 configuration structure 153 - r3 relocation table (P) 154 - r4 L1 page descriptor (P) 155 - r5 kernel entry point 156 */ 157 mov ip, sp 158 stmfd sp!, {r4-r9, fp, ip, lr, pc} 159 sub fp, ip, #4 160 161 /* get stuff out of the calling frame */ 162 ldr r4, [ip, #0] 163 ldr r5, [ip, #4] 164 165 /* relocate the relocation routine to the given page */ 166 adr r6, relocate_code 167 ldr r7, Lnbpp 168 mov r8, r0 169relocate_code_loop: 170 ldr r9, [r6], #4 171 str r9, [r8], #4 172 subs r7, r7, #4 173 bne relocate_code_loop 174 175 /* we messed up the data cache : lets read a 64 or 128 kb <-- GROSS */ 176 mov r7, #128*1024 177 mov r6, #0x8000 /* start of RISCOS application area */ 178flush_ID_cache_try: 179 ldr r9, [r6], #4 180 subs r7, r7, #4 181 bne flush_ID_cache_try 182 183 /* enter sub26 mode */ 184 swi OS_EnterOS 185 186 /* go to sup32 mode with ICQ and FIQ disabled */ 187 mrs r6, cpsr 188 bic r6, r6, #PSR_MODE /* clear processor mode */ 189 orr r6, r6, #(I32_bit | F32_bit) /* disable ICQ + FIQ */ 190 orr r6, r6, #PSR_SVC32_MODE /* go to 32 bit supervisor mode */ 191 msr cpsr, r6 192 mov r0, r0 /* nops ... just in case */ 193 mov r0, r0 194 195 /* set up info */ 196 mov r9, r0 /* save relocated page address */ 197 mov r7, #relocate_code_physical_restart - relocate_code /* get offset */ 198 add r1, r0, r1 /* get physical address */ 199 add r1, r1, r7 /* add offset */ 200 mov r0, r2 /* put configuration structure in r0 */ 201 mov r2, r3 /* relocation table */ 202 mov r3, r4 /* L1 page discriptor */ 203 mov r4, r5 /* kernel entry point */ 204 205 mov pc, r9 /* jump to page addr == relocate_code */ 206 207emergency_exit: 208 ldmdb fp, {r4-r9, fp, sp, pc} 209 210Lnbpp: 211 .word nbpp 212Lvideomem_start_ro: 213 .word videomem_start_ro 214 215