1; $NetBSD: arm.asm,v 1.8 2008/05/03 23:49:14 martin Exp $ 2; 3; Copyright (c) 2001 The NetBSD Foundation, Inc. 4; All rights reserved. 5; 6; This code is derived from software contributed to The NetBSD Foundation 7; by UCHIYAMA Yasushi. 8; 9; Redistribution and use in source and binary forms, with or without 10; modification, are permitted provided that the following conditions 11; are met: 12; 1. Redistributions of source code must retain the above copyright 13; notice, this list of conditions and the following disclaimer. 14; 2. Redistributions in binary form must reproduce the above copyright 15; notice, this list of conditions and the following disclaimer in the 16; documentation and/or other materials provided with the distribution. 17; 18; THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21; PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22; BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28; POSSIBILITY OF SUCH DAMAGE. 29; 30 31; 32;armasm.exe $(InputPath) 33;arm.obj 34; 35 ; dummy buffer for WritebackDCache 36 EXPORT |dcachebuf| [DATA] 37 AREA |.data|, DATA 38|dcachebuf| 39 % 8192 ; D-cache size 40 41 AREA |.text|, CODE, PIC 42 43 ; 44 ; Operation mode ops. 45 ; 46 EXPORT |SetSVCMode| 47|SetSVCMode| PROC 48 mrs r0, cpsr 49 bic r0, r0, #0x1f 50 orr r0, r0, #0x13 51 msr cpsr, r0 52 mov pc, lr 53 ENDP ; |SetSVCMode| 54 EXPORT |SetSystemMode| 55|SetSystemMode| PROC 56 mrs r0, cpsr 57 orr r0, r0, #0x1f 58 msr cpsr, r0 59 mov pc, lr 60 ENDP ; |SetSystemMode| 61 62 ; 63 ; Interrupt ops. 64 ; 65 EXPORT |DI| 66|DI| PROC 67 mrs r0, cpsr 68 orr r0, r0, #0xc0 69 msr cpsr, r0 70 mov pc, lr 71 ENDP ; |DI| 72 EXPORT |EI| 73|EI| PROC 74 mrs r0, cpsr 75 bic r0, r0, #0xc0 76 msr cpsr, r0 77 mov pc, lr 78 ENDP ; |EI| 79 80 ; 81 ; Cache ops. 82 ; 83 EXPORT |InvalidateICache| 84|InvalidateICache| PROC 85 ; c7 (CRn) Cache Control Register 86 ; c5, 0 (CRm, opcode_2) Flush I 87 ; r0 (Rd) ignored 88 mcr p15, 0, r0, c7, c5, 0 89 mov pc, lr 90 ENDP ; |InvalidateICache| 91 92 EXPORT |WritebackDCache| 93|WritebackDCache| PROC 94 ldr r0, [pc, #16] ; dcachebuf 95 add r1, r0, #8192 ; cache-size is 8Kbyte. 96|wbdc1| 97 ldr r2, [r0], #32 ; line-size is 32byte. 98 teq r1, r0 99 bne |wbdc1| 100 mov pc, lr 101 DCD |dcachebuf| 102 ENDP ; |WritebackDCache| 103 104 EXPORT |InvalidateDCache| 105|InvalidateDCache| PROC 106 ; c7 (CRn) Cache Control Register 107 ; c6, 0 (CRm, opcode_2) Flush D 108 ; r0 (Rd) ignored 109 mcr p15, 0, r0, c7, c6, 0 110 mov pc, lr 111 ENDP ; |InvalidateDCache| 112 113 EXPORT |WritebackInvalidateDCache| 114|WritebackInvalidateDCache| PROC 115 ldr r0, [pc, #20] ; dcachebuf 116 add r1, r0, #8192 117|wbidc1| 118 ldr r2, [r0], #32 119 teq r1, r0 120 bne |wbidc1| 121 mcr p15, 0, r0, c7, c6, 0 122 mov pc, lr 123 DCD |dcachebuf| 124 ENDP ; |WritebackInvalidateDCache| 125 126 ; 127 ; WriteBuffer ops 128 ; 129 EXPORT |WritebufferFlush| 130|WritebufferFlush| PROC 131 ; c7 (CRn) Cache Control Register 132 ; c10, 4(CRm, opcode_2) Flush D 133 ; r0 (Rd) ignored 134 mcr p15, 0, r0, c7, c10, 4 135 mov pc, lr 136 ENDP ; |WritebufferFlush| 137 138 ; 139 ; TLB ops. 140 ; 141 EXPORT |FlushIDTLB| 142|FlushIDTLB| PROC 143 mcr p15, 0, r0, c8, c7, 0 144 mov pc, lr 145 ENDP ; |FlushIDTLB| 146 147 EXPORT |FlushITLB| 148|FlushITLB| PROC 149 mcr p15, 0, r0, c8, c5, 0 150 mov pc, lr 151 ENDP ; |FlushITLB| 152 153 EXPORT |FlushDTLB| 154|FlushDTLB| PROC 155 mcr p15, 0, r0, c8, c6, 0 156 mov pc, lr 157 ENDP ; |FlushITLB| 158 159 EXPORT |FlushDTLBS| 160|FlushDTLBS| PROC 161 mcr p15, 0, r0, c8, c6, 1 162 mov pc, lr 163 ENDP ; |FlushITLBS| 164 165 ; 166 ; CurrentProgramStatusRegister access. 167 ; 168 EXPORT |GetCPSR| 169|GetCPSR| PROC 170 mrs r0, cpsr 171 mov pc, lr 172 ENDP ; |GetCPSR| 173 174 EXPORT |SetCPSR| 175|SetCPSR| PROC 176 msr cpsr, r0 177 mov pc, lr 178 ENDP ; |SetCPSR| 179 180 ; 181 ; SA-1100 Coprocessor15 access. 182 ; 183; Reg0 ID (R) 184 EXPORT |GetCop15Reg0| 185|GetCop15Reg0| PROC 186 mrc p15, 0, r0, c0, c0, 0 187 ; 0x4401a119 (44|01 = version 4|A11 = SA1100|9 = E stepping) 188 mov pc, lr 189 ENDP ; |GetCop15Reg0| 190 191; Reg1 Control (R/W) 192 EXPORT |GetCop15Reg1| 193|GetCop15Reg1| PROC 194 mrc p15, 0, r0, c1, c0, 0 195 ; 0xc007327f (||...........|||..||..|..|||||||) 196 ; 0 (1)MMU enabled 197 ; 1 (1)Address fault enabled 198 ; 2 (1)D-cache enabled 199 ; 3 (1)Write-buffer enabled 200 ; 7 (0)little-endian 201 ; 8 (0)MMU protection (System) 202 ; 9 (1)MMU protection (ROM) 203 ; 12 (1)I-cache enabled 204 ; 13 (1)Base address of interrupt vector is 0xffff0000 205 mov pc, lr 206 ENDP ; |GetCop15Reg1| 207 EXPORT |SetCop15Reg1| 208|SetCop15Reg1| PROC 209 mcr p15, 0, r0, c1, c0, 0 210 nop 211 nop 212 nop 213 mov pc, lr 214 ENDP ; |SetCop15Reg1| 215 216; Reg2 Translation table base (R/W) 217 EXPORT |GetCop15Reg2| 218|GetCop15Reg2| PROC 219 mrc p15, 0, r0, c2, c0, 0 220 mov pc, lr 221 ENDP ; |GetCop15Reg2| 222 EXPORT |SetCop15Reg2| 223|SetCop15Reg2| PROC 224 mcr p15, 0, r0, c2, c0, 0 225 mov pc, lr 226 ENDP ; |SetCop15Reg2| 227 228; Reg3 Domain access control (R/W) 229 EXPORT |GetCop15Reg3| 230|GetCop15Reg3| PROC 231 mrc p15, 0, r0, c3, c0, 0 232 mov pc, lr 233 ENDP ; |GetCop15Reg3| 234 EXPORT |SetCop15Reg3| 235|SetCop15Reg3| PROC 236 mcr p15, 0, r0, c3, c0, 0 237 mov pc, lr 238 ENDP ; |SetCop15Reg3| 239 240; Reg5 Fault status (R/W) 241 EXPORT |GetCop15Reg5| 242|GetCop15Reg5| PROC 243 mrc p15, 0, r0, c5, c0, 0 244 mov pc, lr 245 ENDP ; |GetCop15Reg5| 246 247; Reg6 Fault address (R/W) 248 EXPORT |GetCop15Reg6| 249|GetCop15Reg6| PROC 250 mrc p15, 0, r0, c6, c0, 0 251 mov pc, lr 252 ENDP ; |GetCop15Reg6| 253 254; Reg7 Cache operations (W) 255 ; -> Cache ops 256; Reg8 TLB operations (Flush) (W) 257 ; -> TLB ops 258; Reg9 Read buffer operations (W) 259; Reg13 Process ID (R/W) 260 EXPORT |GetCop15Reg13| 261|GetCop15Reg13| PROC 262 mrc p15, 0, r0, c13, c0, 0 263 mov pc, lr 264 ENDP ; |GetCop15Reg13| 265 EXPORT |SetCop15Reg13| 266|SetCop15Reg13| PROC 267 mcr p15, 0, r0, c13, c0, 0 268 mov pc, lr 269 ENDP ; |SetCop15Reg13| 270 271; Reg14 Breakpoint (R/W) 272 EXPORT |GetCop15Reg14| 273|GetCop15Reg14| PROC 274 mrc p15, 0, r0, c14, c0, 0 275 mov pc, lr 276 ENDP ; |GetCop15Reg14| 277; Reg15 Test, clock, and idle (W) 278 279 ; FlatJump (kaddr_t bootinfo, kaddr_t pvec, kaddr_t stack 280 ; kaddr_t jump) 281 ; bootinfo boot information block address. 282 ; pvec page vector of kernel. 283 ; stack physical address of stack 284 ; jump physical address of boot function 285 ; *** MMU and pipeline behavier are SA-1100 specific. *** 286 EXPORT |FlatJump| 287|FlatJump| PROC 288 ; disable interrupt 289 mrs r4, cpsr 290 orr r4, r4, #0xc0 291 msr cpsr, r4 292 ; disable MMU, I/D-Cache, Writebuffer. 293 ; interrupt vector address is 0xffff0000 294 ; 32bit exception handler/address range. 295 ldr r4, [pc, #24] 296 ; Disable WB/Cache/MMU 297 mcr p15, 0, r4, c1, c0, 0 298 ; Invalidate I/D-cache. 299 mcr p15, 0, r4, c7, c7, 0 ; Fetch translated fetch 300 ; Invalidate TLB entries. 301 mcr p15, 0, r4, c8, c7, 0 ; Fetch translated decode 302 ; jump to kernel entry physical address. 303 mov pc, r3 ; Fetch translated execute 304 ; NOTREACHED 305 nop ; Fetch nontranslated cache access 306 nop ; Fetch nontranslated writeback 307 mov pc, lr ; Fetch nontranslated 308 DCD 0x00002030 309 ENDP ; |FlatJump| 310; 311; UART test 312; 313 ; boot_func (uint32_t mapaddr, uint32_t bootinfo, uint32_t flags) 314 ; 315 EXPORT |boot_func| 316|boot_func| PROC 317 nop ; Cop15 hazard 318 nop ; Cop15 hazard 319 nop ; Cop15 hazard 320 mov sp, r2 ; set bootloader stack 321; mov r4, r0 322; mov r5, r1 323; bl colorbar 324; mov r0, r4 325; mov r1, r5 326 bl boot 327 nop ; NOTREACHED 328 nop 329 ENDP ; |boot_func| 330 331 EXPORT |colorbar| 332|colorbar| PROC 333 stmfd sp!, {r4-r7, lr} 334 adr r4, |$FBADDR| 335 ldr r4, [r4] 336 337 mov r7, #8 338 add r0, r0, r7 339|color_loop| 340 mov r6, r0 341 and r6, r6, #7 342 orr r6, r6, r6, LSL #8 343 orr r6, r6, r6, LSL #16 344 add r5, r4, #0x9600 345|fb_loop| 346 str r6, [r4], #4 347 cmp r4, r5 348 blt |fb_loop| 349 350 subs r7, r7, #1 351 bne |color_loop| 352 353 ldmfd sp!, {r4-r7, pc} 354|$FBADDR| 355 DCD 0xc0003000 ; use WindowsCE default. 356 ENDP ; |colorbar| 357 358 EXPORT |boot| 359|boot| PROC 360; 361; UART test code 362; 363; ; print boot_info address (r0) and page_vector start address (r1). 364; mov r4, r0 365; mov r5, r1 366; mov r0, #'I' 367; bl btputc 368; mov r0, r4 369; bl hexdump 370; mov r0, #'P' 371; bl btputc 372; mov r0, r5 373; bl hexdump 374; mov r7, r4 375; mov r2, r5 ; start 376 377 mov r7, r0 ; if enabled above debug print, remove this. 378 mov r2, r1 ; if enabled above debug print, remove this. 379|page_loop| 380 mvn r0, #0 ; ~0 381 cmp r2, r0 382 beq |page_end| ; if (next == ~0) goto page_end 383 384 mov r1, r2 ; p = next 385 ldr r2, [r1] ; next 386 ldr r3, [r1, #4] ; src 387 ldr r4, [r1, #8] ; dst 388 ldr r5, [r1, #12] ; sz 389 390 cmp r3, r0 391 add r6, r4, r5 ; end address 392 bne |page_memcpy4| ; if (src != ~0) goto page_memcpy4 393 394 mov r0, #0 395|page_memset| ; memset (dst, 0, sz) uncached. 396 str r0, [r4], #4 397 cmp r4, r6 398 blt |page_memset| 399 b |page_loop| 400 401|page_memcpy4| ; memcpy (dst, src, sz) uncached. 402 ldr r0, [r3], #4 403 ldr r5, [r3], #4 404 str r0, [r4], #4 405 cmp r4, r6 406 strlt r5, [r4], #4 407 cmplt r4, r6 408 blt |page_memcpy4| 409 410 b |page_loop| 411|page_end| 412 ; 413 ; jump to kernel 414 ; 415; mov r0, #'E' 416; bl btputc 417; ldr r0, [r7] 418; bl hexdump 419; ldr r0, [r7] 420; ldr r0, [r0] 421; bl hexdump 422 423 ; set stack pointer 424 mov r5, #4096 425 add r6, r6, #8192 426 sub r5, r5, #1 427 bic sp, r6, r5 428 429 ; set bootargs 430 ldr r4, [r7] 431 ldr r0, [r7, #4] 432 ldr r1, [r7, #8] 433 ldr r2, [r7, #12] 434 mov pc, r4 435 ; NOTREACHED 436 437|infinite_loop| 438 nop 439 nop 440 nop 441 nop 442 nop 443 b |infinite_loop| 444 ENDP ; |boot| 445 446|btputc| PROC 447 adr r1, |$UARTTXBSY| 448 ldr r1, [r1] 449|btputc_busy| 450 ldr r2, [r1] 451 and r2, r2, #1 452 cmp r2, #1 453 beq |btputc_busy| 454 adr r1, |$UARTTXADR| 455 ldr r1, [r1] 456 str r0, [r1] 457 mov pc, lr 458 ENDP ;|btputc| 459 460|hexdump| PROC 461 stmfd sp!, {r4-r5, lr} 462 mov r4, r0 463 mov r0, #0x30 464 bl btputc 465 mov r0, #0x78 466 bl btputc 467 mov r0, r4 468 ; Transmit register address 469 adr r1, |$UARTTXADR| 470 ldr r1, [r1] 471 ; Transmit busy register address 472 adr r2, |$UARTTXBSY| 473 ldr r2, [r2] 474 mov r5, #8 475|hex_loop| 476 mov r3, r0, LSR #28 477 cmp r3, #9 478 addgt r3, r3, #0x41 - 10 479 addle r3, r3, #0x30 480|hex_busyloop| 481 ldr r4, [r2] 482 and r4, r4, #1 483 cmp r4, #1 484 beq |hex_busyloop| 485 str r3, [r1] 486 mov r0, r0, LSL #4 487 subs r5, r5, #1 488 bne |hex_loop| 489 mov r0, #0x0d 490 bl btputc 491 mov r0, #0x0a 492 bl btputc 493 ldmfd sp!, {r4-r5, pc} 494 ENDP ;|hexdump| 495 496|$UARTTXADR| 497 DCD 0x80050014 498|$UARTTXBSY| 499 DCD 0x80050020 500 501 EXPORT |boot_func_end| [ DATA ] 502|boot_func_end| DCD 0x0 503 504 END 505