1 1.1 kiyohara /* $NetBSD: e32boot.cpp,v 1.1 2013/04/28 12:11:27 kiyohara Exp $ */ 2 1.1 kiyohara /* 3 1.1 kiyohara * Copyright (c) 2012, 2013 KIYOHARA Takashi 4 1.1 kiyohara * All rights reserved. 5 1.1 kiyohara * 6 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 7 1.1 kiyohara * modification, are permitted provided that the following conditions 8 1.1 kiyohara * are met: 9 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 10 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 11 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 12 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 13 1.1 kiyohara * documentation and/or other materials provided with the distribution. 14 1.1 kiyohara * 15 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 1.1 kiyohara * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 1.1 kiyohara * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 1.1 kiyohara * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 1.1 kiyohara * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 1.1 kiyohara * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 1.1 kiyohara * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 1.1 kiyohara * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 1.1 kiyohara * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 1.1 kiyohara * POSSIBILITY OF SUCH DAMAGE. 26 1.1 kiyohara */ 27 1.1 kiyohara 28 1.1 kiyohara #include <e32base.h> 29 1.1 kiyohara #include <e32def.h> 30 1.1 kiyohara #include <e32std.h> 31 1.1 kiyohara 32 1.1 kiyohara #include "cpu.h" 33 1.1 kiyohara #include "e32boot.h" 34 1.1 kiyohara #include "ekern.h" 35 1.1 kiyohara #include "epoc32.h" 36 1.1 kiyohara #include "netbsd.h" 37 1.1 kiyohara 38 1.1 kiyohara 39 1.1 kiyohara class E32BootLDD : public DLogicalDevice { 40 1.1 kiyohara public: 41 1.1 kiyohara E32BootLDD(void); 42 1.1 kiyohara virtual TInt Install(void); 43 1.1 kiyohara virtual void GetCaps(TDes8 &) const; 44 1.1 kiyohara virtual DLogicalChannel *CreateL(void); 45 1.1 kiyohara }; 46 1.1 kiyohara 47 1.1 kiyohara class E32BootChannel : public DLogicalChannel { 48 1.1 kiyohara public: 49 1.1 kiyohara E32BootChannel(DLogicalDevice *); 50 1.1 kiyohara 51 1.1 kiyohara protected: 52 1.1 kiyohara virtual void DoCancel(TInt); 53 1.1 kiyohara virtual void DoRequest(TInt, TAny *, TAny *); 54 1.1 kiyohara virtual TInt DoControl(TInt, TAny *, TAny *); 55 1.1 kiyohara 56 1.1 kiyohara private: 57 1.1 kiyohara EPOC32 *epoc32; 58 1.1 kiyohara TAny *safeAddress; 59 1.1 kiyohara 60 1.1 kiyohara TInt BootNetBSD(NetBSD *, struct btinfo_common *); 61 1.1 kiyohara }; 62 1.1 kiyohara 63 1.1 kiyohara 64 1.1 kiyohara /* E32Dll() function is required by all DLLs. */ 65 1.1 kiyohara GLDEF_C TInt 66 1.1 kiyohara E32Dll(TDllReason) 67 1.1 kiyohara { 68 1.1 kiyohara 69 1.1 kiyohara return KErrNone; 70 1.1 kiyohara } 71 1.1 kiyohara 72 1.1 kiyohara EXPORT_C DLogicalDevice * 73 1.1 kiyohara CreateLogicalDevice(void) 74 1.1 kiyohara { 75 1.1 kiyohara 76 1.1 kiyohara return new E32BootLDD; 77 1.1 kiyohara } 78 1.1 kiyohara 79 1.1 kiyohara E32BootLDD::E32BootLDD(void) 80 1.1 kiyohara { 81 1.1 kiyohara /* Nothing */ 82 1.1 kiyohara } 83 1.1 kiyohara 84 1.1 kiyohara TInt 85 1.1 kiyohara E32BootLDD::Install(void) 86 1.1 kiyohara { 87 1.1 kiyohara 88 1.1 kiyohara return SetName(&E32BootName); 89 1.1 kiyohara } 90 1.1 kiyohara 91 1.1 kiyohara void 92 1.1 kiyohara E32BootLDD::GetCaps(TDes8 &aDes) const 93 1.1 kiyohara { 94 1.1 kiyohara TVersion version(0, 0, 0); /* XXXXX: What is it? Don't check? */ 95 1.1 kiyohara 96 1.1 kiyohara aDes.FillZ(aDes.MaxLength()); 97 1.1 kiyohara aDes.Copy((TUint8 *)&version, Min(aDes.MaxLength(), sizeof(version))); 98 1.1 kiyohara } 99 1.1 kiyohara 100 1.1 kiyohara DLogicalChannel * 101 1.1 kiyohara E32BootLDD::CreateL(void) 102 1.1 kiyohara { 103 1.1 kiyohara 104 1.1 kiyohara return new (ELeave) E32BootChannel(this); 105 1.1 kiyohara } 106 1.1 kiyohara 107 1.1 kiyohara 108 1.1 kiyohara E32BootChannel::E32BootChannel(DLogicalDevice *aDevice) 109 1.1 kiyohara : DLogicalChannel(aDevice) 110 1.1 kiyohara { 111 1.1 kiyohara 112 1.1 kiyohara epoc32 = new EPOC32; 113 1.1 kiyohara safeAddress = NULL; 114 1.1 kiyohara } 115 1.1 kiyohara 116 1.1 kiyohara void 117 1.1 kiyohara E32BootChannel::DoCancel(TInt aReqNo) 118 1.1 kiyohara { 119 1.1 kiyohara /* Nothing */ 120 1.1 kiyohara } 121 1.1 kiyohara 122 1.1 kiyohara void 123 1.1 kiyohara E32BootChannel::DoRequest(TInt aReqNo, TAny *a1, TAny *a2) 124 1.1 kiyohara { 125 1.1 kiyohara /* Nothing */ 126 1.1 kiyohara } 127 1.1 kiyohara 128 1.1 kiyohara TInt 129 1.1 kiyohara E32BootChannel::DoControl(TInt aFunction, TAny *a1, TAny *a2) 130 1.1 kiyohara { 131 1.1 kiyohara 132 1.1 kiyohara switch (aFunction) { 133 1.1 kiyohara case KE32BootGetProcessorID: 134 1.1 kiyohara { 135 1.1 kiyohara TInt id; 136 1.1 kiyohara 137 1.1 kiyohara __asm("mrc p15, 0, %0, c0, c0" : "=r"(id)); 138 1.1 kiyohara *(TUint *)a1 = id; 139 1.1 kiyohara break; 140 1.1 kiyohara } 141 1.1 kiyohara 142 1.1 kiyohara case KE32BootSetSafeAddress: 143 1.1 kiyohara { 144 1.1 kiyohara safeAddress = (TAny *)PAGE_ALIGN(a1); 145 1.1 kiyohara break; 146 1.1 kiyohara } 147 1.1 kiyohara 148 1.1 kiyohara case KE32BootBootNetBSD: 149 1.1 kiyohara { 150 1.1 kiyohara NetBSD *netbsd = (NetBSD *)a1; 151 1.1 kiyohara struct btinfo_common *bootinfo = (struct btinfo_common *)a2; 152 1.1 kiyohara 153 1.1 kiyohara BootNetBSD(netbsd, bootinfo); 154 1.1 kiyohara 155 1.1 kiyohara /* NOTREACHED */ 156 1.1 kiyohara 157 1.1 kiyohara break; 158 1.1 kiyohara } 159 1.1 kiyohara 160 1.1 kiyohara default: 161 1.1 kiyohara break; 162 1.1 kiyohara } 163 1.1 kiyohara return KErrNone; 164 1.1 kiyohara } 165 1.1 kiyohara 166 1.1 kiyohara TInt 167 1.1 kiyohara E32BootChannel::BootNetBSD(NetBSD *netbsd, struct btinfo_common *bootinfo) 168 1.1 kiyohara { 169 1.1 kiyohara TAny *mmu_disabled, *ttb; 170 1.1 kiyohara 171 1.1 kiyohara __asm("adr %0, mmu_disabled" : "=r"(mmu_disabled)); 172 1.1 kiyohara mmu_disabled = epoc32->GetPhysicalAddress(mmu_disabled); 173 1.1 kiyohara /* 174 1.1 kiyohara * ARMv3 can't read TTB from CP15 C1. 175 1.1 kiyohara * Also can't read Control Register. 176 1.1 kiyohara */ 177 1.1 kiyohara ttb = epoc32->GetPhysicalAddress(epoc32->GetTTB()); 178 1.1 kiyohara 179 1.1 kiyohara __asm __volatile(" \ 180 1.1 kiyohara mrs r12, cpsr; \ 181 1.1 kiyohara /* Clear PSR_MODE and Interrupts */ \ 182 1.1 kiyohara bic r12, r12, #0xdf; \ 183 1.1 kiyohara /* Disable Interrupts(IRQ/FIQ) */ \ 184 1.1 kiyohara orr r12, r12, #(3 << 6); \ 185 1.1 kiyohara /* Set SVC32 MODE */ \ 186 1.1 kiyohara orr r12, r12, #0x13; \ 187 1.1 kiyohara msr cpsr_c, r12; \ 188 1.1 kiyohara \ 189 1.1 kiyohara ldr r10, [%0, #0x0]; \ 190 1.1 kiyohara ldr sp, [%0, #0x4]; \ 191 1.1 kiyohara ldr lr, [%0, #0x8]; \ 192 1.1 kiyohara mov r12, %1; \ 193 1.1 kiyohara " :: "r"(netbsd), "r"(bootinfo)); 194 1.1 kiyohara 195 1.1 kiyohara __asm __volatile(" \ 196 1.1 kiyohara mov r7, %2; \ 197 1.1 kiyohara mov r8, %1; \ 198 1.1 kiyohara mov r9, %0; \ 199 1.1 kiyohara \ 200 1.1 kiyohara /* Set all domains to 15 */ \ 201 1.1 kiyohara mov r0, #0xffffffff; \ 202 1.1 kiyohara mcr p15, 0, r0, c3, c0; \ 203 1.1 kiyohara \ 204 1.1 kiyohara /* Disable MMU */ \ 205 1.1 kiyohara mov r0, #0x38; /* WBUF | 32BP | 32BD */ \ 206 1.1 kiyohara mcr p15, 0, r0, c1, c0, 0; \ 207 1.1 kiyohara \ 208 1.1 kiyohara mov pc, r7; \ 209 1.1 kiyohara \ 210 1.1 kiyohara mmu_disabled: \ 211 1.1 kiyohara /* \ 212 1.1 kiyohara * r8 safe address(maybe frame-buffer address)\ 213 1.1 kiyohara * r9 ttb \ 214 1.1 kiyohara * r10 buffer (netbsd) \ 215 1.1 kiyohara * r11 memory descriptor \ 216 1.1 kiyohara * r12 bootinfo \ 217 1.1 kiyohara * sp load descriptor \ 218 1.1 kiyohara * lr entry point \ 219 1.1 kiyohara */ \ 220 1.1 kiyohara /* save lr to r7 before call functions. */ \ 221 1.1 kiyohara mov r7, lr; \ 222 1.1 kiyohara \ 223 1.1 kiyohara mov r0, r8; \ 224 1.1 kiyohara mov r1, r9; \ 225 1.1 kiyohara bl vtop; \ 226 1.1 kiyohara mov r8, r0; \ 227 1.1 kiyohara \ 228 1.1 kiyohara /* \ 229 1.1 kiyohara * Copy bootinfo to safe address. \ 230 1.1 kiyohara * That addr used to framebuffer by EPOC32. \ 231 1.1 kiyohara */ \ 232 1.1 kiyohara mov r0, r12; \ 233 1.1 kiyohara mov r1, r9; \ 234 1.1 kiyohara bl vtop; \ 235 1.1 kiyohara mov r1, r0; \ 236 1.1 kiyohara mov r12, r8; \ 237 1.1 kiyohara mov r0, r8; \ 238 1.1 kiyohara mov r2, #0x400; \ 239 1.1 kiyohara bl copy; \ 240 1.1 kiyohara \ 241 1.1 kiyohara /* save lr(r7) to r8. it is no need. */ \ 242 1.1 kiyohara mov r8, r7; \ 243 1.1 kiyohara \ 244 1.1 kiyohara /* Copy loader to safe address + 0x400. */ \ 245 1.1 kiyohara add r0, r12, #0x400; \ 246 1.1 kiyohara adr r1, miniloader_start; \ 247 1.1 kiyohara adr r2, miniloader_end; \ 248 1.1 kiyohara sub r2, r2, r1; \ 249 1.1 kiyohara bl copy; \ 250 1.1 kiyohara \ 251 1.1 kiyohara /* Make load-descriptor to safe addr + 0x800. */\ 252 1.1 kiyohara mov r0, sp; \ 253 1.1 kiyohara mov r1, r9; \ 254 1.1 kiyohara bl vtop; \ 255 1.1 kiyohara mov sp, r0; \ 256 1.1 kiyohara add r4, r12, #0x800; \ 257 1.1 kiyohara \ 258 1.1 kiyohara next_section: \ 259 1.1 kiyohara ldmia sp!, {r5 - r7}; \ 260 1.1 kiyohara \ 261 1.1 kiyohara next_page: \ 262 1.1 kiyohara add r0, r10, r6; \ 263 1.1 kiyohara mov r1, r9; \ 264 1.1 kiyohara bl vtop; \ 265 1.1 kiyohara /* vtop returns set mask to r2 */ \ 266 1.1 kiyohara orr r2, r0, r2; \ 267 1.1 kiyohara add r2, r2, #1; \ 268 1.1 kiyohara sub r2, r2, r0; \ 269 1.1 kiyohara cmp r2, r7; \ 270 1.1 kiyohara movgt r2, r7; \ 271 1.1 kiyohara mov r1, r0; \ 272 1.1 kiyohara mov r0, r5; \ 273 1.1 kiyohara stmia r4!, {r0 - r2}; \ 274 1.1 kiyohara add r5, r5, r2; \ 275 1.1 kiyohara add r6, r6, r2; \ 276 1.1 kiyohara subs r7, r7, r2; \ 277 1.1 kiyohara bgt next_page; \ 278 1.1 kiyohara \ 279 1.1 kiyohara ldr r0, [sp]; \ 280 1.1 kiyohara cmp r0, #0xffffffff; \ 281 1.1 kiyohara beq fin; \ 282 1.1 kiyohara /* Pad to section align. */ \ 283 1.1 kiyohara str r5, [r4], #4; \ 284 1.1 kiyohara mov r6, #0xffffffff; \ 285 1.1 kiyohara str r6, [r4], #4; \ 286 1.1 kiyohara sub r2, r0, r5; \ 287 1.1 kiyohara str r2, [r4], #4; \ 288 1.1 kiyohara b next_section; \ 289 1.1 kiyohara \ 290 1.1 kiyohara fin: \ 291 1.1 kiyohara stmia r4, {r5 - r7}; \ 292 1.1 kiyohara add sp, r12, #0x800; \ 293 1.1 kiyohara \ 294 1.1 kiyohara /* save lr(r8) to r11. r11 is no need. */ \ 295 1.1 kiyohara mov r11, r8; \ 296 1.1 kiyohara \ 297 1.1 kiyohara /* Fixup load-descriptor by BTINFO_MEMORY. */ \ 298 1.1 kiyohara mov r10, r12; \ 299 1.1 kiyohara mov r9, sp; \ 300 1.1 kiyohara add r8, sp, #12; \ 301 1.1 kiyohara next_bootinfo: \ 302 1.1 kiyohara ldmia r10, {r0, r1}; \ 303 1.1 kiyohara cmp r1, #0; /* BTINFO_NONE */ \ 304 1.1 kiyohara beq btinfo_none; \ 305 1.1 kiyohara \ 306 1.1 kiyohara cmp r1, #2; /* BTINFO_MEMORY */ \ 307 1.1 kiyohara beq btinfo_memory; \ 308 1.1 kiyohara add r10, r10, r0; \ 309 1.1 kiyohara b next_bootinfo; \ 310 1.1 kiyohara \ 311 1.1 kiyohara btinfo_none: \ 312 1.1 kiyohara /* ENOMEM */ \ 313 1.1 kiyohara add r2, r12, #0x800; \ 314 1.1 kiyohara mov r1, #640; \ 315 1.1 kiyohara mov r0, #0x00ff0000; \ 316 1.1 kiyohara orr r0, r0, #0x00ff; \ 317 1.1 kiyohara 98: \ 318 1.1 kiyohara str r0, [r2], #4; \ 319 1.1 kiyohara subs r1, r1, #4; \ 320 1.1 kiyohara bgt 98b; \ 321 1.1 kiyohara mov r1, #640; \ 322 1.1 kiyohara mov r0, #0xff000000; \ 323 1.1 kiyohara orr r0, r0, #0xff00; \ 324 1.1 kiyohara 99: \ 325 1.1 kiyohara str r0, [r2], #4; \ 326 1.1 kiyohara subs r1, r1, #4; \ 327 1.1 kiyohara bgt 99b; \ 328 1.1 kiyohara 100: \ 329 1.1 kiyohara b 100b; \ 330 1.1 kiyohara \ 331 1.1 kiyohara btinfo_memory: \ 332 1.1 kiyohara ldmia r10!, {r4 - r7}; \ 333 1.1 kiyohara ldr r4, [r9, #0]; \ 334 1.1 kiyohara subs r4, r4, r6; \ 335 1.1 kiyohara addgt r6, r6, r4; \ 336 1.1 kiyohara subgt r7, r7, r4; \ 337 1.1 kiyohara next_desc: \ 338 1.1 kiyohara ldmia r9, {r3 - r5}; \ 339 1.1 kiyohara ldmia r8!, {r0 - r2}; \ 340 1.1 kiyohara add r3, r3, r5; \ 341 1.1 kiyohara add r4, r4, r5; \ 342 1.1 kiyohara cmp r3, r0; \ 343 1.1 kiyohara cmpeq r4, r1; \ 344 1.1 kiyohara beq join_desc; \ 345 1.1 kiyohara \ 346 1.1 kiyohara ldr r3, [r9, #0]; \ 347 1.1 kiyohara cmp r3, r6; \ 348 1.1 kiyohara strlt r6, [r9, #0]; /* Fixup */ \ 349 1.1 kiyohara cmp r5, r7; \ 350 1.1 kiyohara bgt split_desc; \ 351 1.1 kiyohara add r6, r6, r5; \ 352 1.1 kiyohara sub r7, r7, r5; \ 353 1.1 kiyohara add r9, r9, #12; \ 354 1.1 kiyohara stmia r9, {r0 - r2}; \ 355 1.1 kiyohara cmp r0, #0xffffffff; \ 356 1.1 kiyohara beq fixuped; \ 357 1.1 kiyohara b next_desc; \ 358 1.1 kiyohara \ 359 1.1 kiyohara join_desc: /* Join r8 descriptor to r9. */ \ 360 1.1 kiyohara add r5, r5, r2; \ 361 1.1 kiyohara str r5, [r9, #8]; \ 362 1.1 kiyohara b next_desc; \ 363 1.1 kiyohara \ 364 1.1 kiyohara split_desc: /* Split r9 descriptor. */ \ 365 1.1 kiyohara ldr r3, [r9, #0]; \ 366 1.1 kiyohara ldr r4, [r9, #4]; \ 367 1.1 kiyohara str r7, [r9, #8]; \ 368 1.1 kiyohara \ 369 1.1 kiyohara sub r6, r5, r7; \ 370 1.1 kiyohara add r5, r4, r7; \ 371 1.1 kiyohara add r4, r3, r7; \ 372 1.1 kiyohara sub r8, r8, #12; /* Back to prev desc */ \ 373 1.1 kiyohara add r9, r9, #12;/* Point to splited desc */ \ 374 1.1 kiyohara \ 375 1.1 kiyohara cmp r8, r9; \ 376 1.1 kiyohara bne 2f; \ 377 1.1 kiyohara add r0, r8, #12; \ 378 1.1 kiyohara mov r1, r8; \ 379 1.1 kiyohara mov r2, #0; \ 380 1.1 kiyohara 1: \ 381 1.1 kiyohara ldr r3, [r8, r2]; \ 382 1.1 kiyohara add r2, r2, #12; \ 383 1.1 kiyohara cmp r3, #0xffffffff; \ 384 1.1 kiyohara bne 1b; \ 385 1.1 kiyohara bl copy; \ 386 1.1 kiyohara add r8, r8, #12; /* Point to moved desc */ \ 387 1.1 kiyohara 2: \ 388 1.1 kiyohara stmia r9, {r4 - r6}; \ 389 1.1 kiyohara b next_bootinfo; \ 390 1.1 kiyohara \ 391 1.1 kiyohara fixuped: \ 392 1.1 kiyohara /* Jump to miniloader. Our LR is entry-point! */\ 393 1.1 kiyohara add pc, r12, #0x400; \ 394 1.1 kiyohara \ 395 1.1 kiyohara vtop: \ 396 1.1 kiyohara /* \ 397 1.1 kiyohara * paddr vtop(vaddr, ttb) \ 398 1.1 kiyohara */ \ 399 1.1 kiyohara bic r2, r0, #0x000f0000; /* L1_ADDR_BITS */ \ 400 1.1 kiyohara bic r2, r2, #0x0000ff00; /* L1_ADDR_BITS */ \ 401 1.1 kiyohara bic r2, r2, #0x000000ff; /* L1_ADDR_BITS */ \ 402 1.1 kiyohara mov r2, r2, lsr #(20 - 2); \ 403 1.1 kiyohara ldr r1, [r1, r2]; \ 404 1.1 kiyohara and r3, r1, #0x3; /* L1_TYPE_MASK */ \ 405 1.1 kiyohara cmp r3, #0; \ 406 1.1 kiyohara bne valid; \ 407 1.1 kiyohara \ 408 1.1 kiyohara invalid: \ 409 1.1 kiyohara mov r0, #-1; \ 410 1.1 kiyohara mov pc, lr; \ 411 1.1 kiyohara \ 412 1.1 kiyohara valid: \ 413 1.1 kiyohara cmp r3, #0x2; \ 414 1.1 kiyohara bgt 3f; \ 415 1.1 kiyohara beq 2f; \ 416 1.1 kiyohara \ 417 1.1 kiyohara 1: /* Coarse L2 */ \ 418 1.1 kiyohara mov r2, #10; \ 419 1.1 kiyohara b l2; \ 420 1.1 kiyohara \ 421 1.1 kiyohara 2: /* Section */ \ 422 1.1 kiyohara mov r2, #0xff000000; /* L1_S_ADDR_MASK */\ 423 1.1 kiyohara add r2, r2, #0x00f00000;/* L1_S_ADDR_MASK */\ 424 1.1 kiyohara mvn r2, r2; \ 425 1.1 kiyohara bic r3, r1, r2; \ 426 1.1 kiyohara and r0, r0, r2; \ 427 1.1 kiyohara orr r0, r3, r0; \ 428 1.1 kiyohara mov pc, lr; \ 429 1.1 kiyohara \ 430 1.1 kiyohara 3: /* Fine L2 */ \ 431 1.1 kiyohara mov r2, #12; \ 432 1.1 kiyohara l2: \ 433 1.1 kiyohara mov r3, #1; \ 434 1.1 kiyohara mov r3, r3, lsl r2; \ 435 1.1 kiyohara sub r3, r3, #1; \ 436 1.1 kiyohara bic r1, r1, r3; /* L2 table */ \ 437 1.1 kiyohara mov r3, r0, lsl #12; \ 438 1.1 kiyohara mov r3, r3, lsr #12; \ 439 1.1 kiyohara sub r2, r2, #22; \ 440 1.1 kiyohara rsb r2, r2, #0; \ 441 1.1 kiyohara mov r3, r3, lsr r2; /* index for L2 */ \ 442 1.1 kiyohara ldr r1, [r1, r3, lsl #2]; \ 443 1.1 kiyohara and r3, r1, #0x3; /* L2_TYPE_MASK */ \ 444 1.1 kiyohara cmp r3, #0; \ 445 1.1 kiyohara beq invalid; \ 446 1.1 kiyohara cmp r3, #2; \ 447 1.1 kiyohara movlt r2, #16; /* L2_L_SHIFT */ \ 448 1.1 kiyohara moveq r2, #12; /* L2_S_SHIFT */ \ 449 1.1 kiyohara movgt r2, #10; /* L2_T_SHIFT */ \ 450 1.1 kiyohara mov r3, #1; \ 451 1.1 kiyohara mov r2, r3, lsl r2; \ 452 1.1 kiyohara sub r2, r2, #1; \ 453 1.1 kiyohara bic r3, r1, r2; \ 454 1.1 kiyohara and r0, r0, r2; \ 455 1.1 kiyohara orr r0, r3, r0; \ 456 1.1 kiyohara mov pc, lr; \ 457 1.1 kiyohara \ 458 1.1 kiyohara miniloader_start: \ 459 1.1 kiyohara b miniloader; \ 460 1.1 kiyohara \ 461 1.1 kiyohara copy: \ 462 1.1 kiyohara /* \ 463 1.1 kiyohara * void copy(dest, src, len) \ 464 1.1 kiyohara */ \ 465 1.1 kiyohara cmp r0, r1; \ 466 1.1 kiyohara bgt rcopy; \ 467 1.1 kiyohara lcopy: \ 468 1.1 kiyohara ldr r3, [r1], #4; \ 469 1.1 kiyohara str r3, [r0], #4; \ 470 1.1 kiyohara subs r2, r2, #4; \ 471 1.1 kiyohara bgt lcopy; \ 472 1.1 kiyohara mov pc, lr; \ 473 1.1 kiyohara rcopy: \ 474 1.1 kiyohara subs r2, r2, #4; \ 475 1.1 kiyohara ldr r3, [r1, r2]; \ 476 1.1 kiyohara str r3, [r0, r2]; \ 477 1.1 kiyohara bgt rcopy; \ 478 1.1 kiyohara mov pc, lr; \ 479 1.1 kiyohara \ 480 1.1 kiyohara \ 481 1.1 kiyohara miniloader: \ 482 1.1 kiyohara /* \ 483 1.1 kiyohara * r11 entry-point \ 484 1.1 kiyohara * r12 bootinfo \ 485 1.1 kiyohara * sp load-descriptor \ 486 1.1 kiyohara */ \ 487 1.1 kiyohara load: \ 488 1.1 kiyohara ldmia sp!, {r0 - r2}; \ 489 1.1 kiyohara cmp r0, #0xffffffff; \ 490 1.1 kiyohara beq end; \ 491 1.1 kiyohara cmp r1, #0xffffffff;/* Skip section align */\ 492 1.1 kiyohara blne copy; /* or copy */ \ 493 1.1 kiyohara b load; \ 494 1.1 kiyohara \ 495 1.1 kiyohara end: \ 496 1.1 kiyohara mov r0, r12; \ 497 1.1 kiyohara mov pc, r11; \ 498 1.1 kiyohara nop; \ 499 1.1 kiyohara nop; \ 500 1.1 kiyohara miniloader_end: \ 501 1.1 kiyohara \ 502 1.1 kiyohara " 503 1.1 kiyohara ::"r"(ttb), 504 1.1 kiyohara "r"(safeAddress), 505 1.1 kiyohara "r"(mmu_disabled) 506 1.1 kiyohara ); 507 1.1 kiyohara 508 1.1 kiyohara /* NOTREACHED */ 509 1.1 kiyohara 510 1.1 kiyohara return -1; 511 1.1 kiyohara } 512