Author: wmb Date: Fri May 20 01:22:54 2011 New Revision: 2207 URL: http://tracker.coreboot.org/trac/openfirmware/changeset/2207
Log: OLPC XO-1.75 - Halved OFW startup time, mostly by doing the inflation on the P4J processor with caches on.
Added: cpu/arm/olpc/initmmu.fth cpu/arm/olpc/resetvec.bth Modified: cpu/arm/mmp2/mmuon.fth cpu/arm/olpc/1.75/addrs.fth cpu/arm/olpc/1.75/config.fth cpu/arm/olpc/1.75/devices.fth cpu/arm/olpc/1.75/fw-version.fth cpu/arm/olpc/1.75/fw.bth cpu/arm/olpc/1.75/olpc.bth cpu/arm/scc.fth
Modified: cpu/arm/mmp2/mmuon.fth ============================================================================== --- cpu/arm/mmp2/mmuon.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/mmp2/mmuon.fth Fri May 20 01:22:54 2011 (r2207) @@ -67,6 +67,7 @@ c;
: go-fast + control@ 1 and if exit then \ Don't do this if MMU is already on setup-sections start-mmu dcache-on
Modified: cpu/arm/olpc/1.75/addrs.fth ============================================================================== --- cpu/arm/olpc/1.75/addrs.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/addrs.fth Fri May 20 01:22:54 2011 (r2207) @@ -36,7 +36,8 @@
h# 0020.0000 constant /fw-ram
-h# 0110.0000 constant def-load-base +\ h# 0110.0000 constant def-load-base +h# 0800.0000 constant def-load-base
\ The heap starts at RAMtop, which on this system is "fw-pa /fw-ram +"
@@ -44,3 +45,7 @@ heap-size constant initial-heap-size
h# 40.0000 constant page-table-pa + +\ RAM address where the Security Processor code places the subset of the dropin module +\ image that it copies out of SPI FLASH. +h# 900.0000 constant 'dropins \ Must agree with 'compressed in cforth/src/app/arm-xo-1.75/
Modified: cpu/arm/olpc/1.75/config.fth ============================================================================== --- cpu/arm/olpc/1.75/config.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/config.fth Fri May 20 01:22:54 2011 (r2207) @@ -3,6 +3,7 @@ create debug-startup create olpc create trust-ec-keyboard +create use-null-nvram
fload ${BP}/cpu/arm/olpc/1.75/addrs.fth fload ${BP}/cpu/arm/mmp2/hwaddrs.fth
Modified: cpu/arm/olpc/1.75/devices.fth ============================================================================== --- cpu/arm/olpc/1.75/devices.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/devices.fth Fri May 20 01:22:54 2011 (r2207) @@ -39,6 +39,36 @@ ; warning on
+[ifdef] use-null-nvram +\ For not storing configuration variable changes across reboots ... +\ This is useful for "turnkey" systems where configurability would +\ increase support costs. + +fload ${BP}/cpu/x86/pc/nullnv.fth +stand-init: Null-NVRAM + " /null-nvram" open-dev to nvram-node + ['] init-config-vars catch drop +; +[then] + +[ifdef] use-flash-nvram +\ For configuration variables stored in a sector of the boot FLASH ... + +\ Create a node below the top-level FLASH node to access the portion +\ containing the configuration variables. +0 0 " d0000" " /flash" begin-package + " nvram" device-name + + h# 10000 constant /device + fload ${BP}/dev/subrange.fth +end-package + +stand-init: NVRAM + " /nvram" open-dev to nvram-node + ['] init-config-vars catch drop +; +[then] + \ Create a pseudo-device that presents the dropin modules as a filesystem. fload ${BP}/ofw/fs/dropinfs.fth
@@ -186,9 +216,10 @@ fload ${BP}/dev/video/common/rectangle16.fth \ Rectangular graphics
: display-on - init-xo-display \ Turns on DCON +\ init-xo-display \ Turns on DCON + smb-init + fb-pa hdisp vdisp * >bytes h# ffffffff lfill init-lcd - fb-pa hdisp vdisp * >bytes h# ff fill ; : map-frame-buffer ( -- ) fb-pa to frame-buffer-adr
Modified: cpu/arm/olpc/1.75/fw-version.fth ============================================================================== --- cpu/arm/olpc/1.75/fw-version.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/fw-version.fth Fri May 20 01:22:54 2011 (r2207) @@ -1,4 +1,5 @@ \ The overall firmware revision macro: FW_MAJOR A -macro: FW_MINOR 13 +macro: FW_MINOR 13h +
Modified: cpu/arm/olpc/1.75/fw.bth ============================================================================== --- cpu/arm/olpc/1.75/fw.bth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/fw.bth Fri May 20 01:22:54 2011 (r2207) @@ -70,11 +70,12 @@ ukey? if ukey upc ascii I = if true unloop exit then then - 1 ms + d# 1000 us \ 1000 us is more precise than 1 ms, which is often close to 2 ms loop false ;
+: rotate-button? ( -- flag ) d# 15 gpio-pin@ 0= ; warning @ warning off : init \ initial-heap add-memory @@ -83,7 +84,8 @@ standalone? if disable-interrupts d# 1000 - i-key-wait if +\ i-key-wait if + rotate-button? if protect-fw ." Interacting" cr hex interact then @@ -225,13 +227,19 @@ ; : cmos! ( data index -- ) h# 38 mod 8 + " rtc!" clock-node @ ( data index adr len ih ) - ['] $call-method if 2drop 3drop then + ['] $call-method catch if 2drop 3drop then ; code halt ( -- ) wfi c; fload ${BP}/cpu/x86/pc/olpc/sound.fth fload ${BP}/cpu/x86/pc/olpc/guardrtc.fth fload ${BP}/cpu/x86/pc/olpc/security.fth
+stand-init: xid + 0 cmos@ dup 1+ 0 cmos! ( n ) + d# 24 lshift ( new-xid ) + " dev /obp-tftp to rpc-xid dend" evaluate +; + : pre-setup-for-linux ( -- ) [ ' linux-pre-hook behavior compile, ] \ Chain to old behavior sound-end @@ -268,7 +276,7 @@ \needs ramdisk " " d# 128 config-string ramdisk " " ' boot-file set-config-string-default \ Let the boot script set the cmdline
-3 config-int auto-boot-countdown +2 config-int auto-boot-countdown
\ Eliminate 4 second delay in install console for the case where \ there is no keyboard. The delay is unnecessary because the screen
Modified: cpu/arm/olpc/1.75/olpc.bth ============================================================================== --- cpu/arm/olpc/1.75/olpc.bth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/olpc/1.75/olpc.bth Fri May 20 01:22:54 2011 (r2207) @@ -2,6 +2,7 @@
command: &builder &this in: ${BP}/cpu/arm/olpc/1.75/build/fw.img +in: ${BP}/cpu/arm/olpc/1.75/build/resetvec.img in: sd8686.bin in: verify.img in: ${BP}/dev/usb2/device/hub/build/hub.fc @@ -66,6 +67,7 @@ " ${BP}/cpu/arm/build/inflate.bin" " inflate" $add-dropin " fw.img" " firmware" $add-deflated-dropin \ " fw.img" " firmware" $add-dropin + " resetvec.img" " reset" $add-dropin
\ " ${BP}/dev/usb2/hcd/ehci/build/ehci.fc" " class0c0320" $add-deflated-dropin " ${BP}/dev/usb2/device/hub/build/hub.fc" " usb,class9" $add-deflated-dropin
Added: cpu/arm/olpc/initmmu.fth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/arm/olpc/initmmu.fth Fri May 20 01:22:54 2011 (r2207) @@ -0,0 +1,272 @@ +\ See license at end of file +purpose: Setup the initial virtual address map + +[ifdef] notdef +\ Synchronizes the instruction and data caches over the indicated +\ address range, thus allowing the execution of instructions that +\ have recently been written to memory. +label sync-cache-range \ r0: adr, r1: len + begin + mcr p15, 0, r0, cr7, cr10, 1 \ clean D$ line + mcr p15, 0, r0, cr7, cr5, 1 \ invalidate I$ line + add r0, r0, #32 \ Advance to next line + subs r1, r1, #32 + 0<= until + mov pc, lr +end-code + +\ Forces data in the cache within the indicated address range +\ into memory. +label clean-dcache-range \ r0: adr, r1: len + begin + mcr p15, 0, r0, cr7, cr10, 1 \ clean D$ line + add r0, r0, #32 \ Advance to next line + subs r1, r1, #32 + 0<= until + mov pc, lr +end-code +[then] + +\ Turn on the caches +label caches-on + + \ Invalidate the entire L1 data cache by looping over all sets and ways + mov r0,#0 \ Start with set/way 0 of L1 cache + begin + \ In this unrolled loop, the number of iterations (8) and the increment + \ value (0x20000000) depend on fact that this cache has 8 ways. + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way - will wrap to 0 + + inc r0,#32 \ Next set + ands r1,r0,#0xfe0 \ Mask set bits - depends on #sets=128 + 0= until + + \ Invalidate the entire L2 cache by looping over all sets and ways + mov r0,#2 \ Start with set/way 0 of L2 cache + begin + \ In this unrolled loop, the number of iterations (8) and the increment + \ value (0x20000000) depend on fact that this cache has 8 ways. + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr6, 2 \ Invalidate D$ line by set/index + inc r0,#0x20000000 \ Next way - will wrap to 0 + + inc r0,#32 \ Next set + set r2,#0xffe0 \ Mask for set field for L2 cache - depends on #sets=2048 + ands r1,r0,r2 \ Mask set bits + 0= until + + mcr p15, 0, r0, cr7, cr5, 0 \ Invalidate entire I$ + + mcr p15, 0, r0, cr7, cr5, 6 \ Flush branch target cache + + mrc p15,0,r0,cr1,cr0,0 \ Read control register + orr r0,r0,#0x1000 \ ICache on + orr r0,r0,#0x0800 \ Branch prediction on + orr r0,r0,#0x0004 \ DCache on + mcr p15,0,r0,cr1,cr0,0 \ Write control register with new bits + + mrc p15,0,r0,cr1,cr0,1 \ Read aux control register + orr r0,r0,#0x0002 \ L2 Cache on + mcr p15,0,r0,cr1,cr0,1 \ Write control register with new bits + + mov pc, lr +end-code + +\ Synchronizes the instruction and data caches, thus allowing the +\ execution of instructions that have recently been written to memory. +\ This version, which operates on the entire cache, is more efficient +\ than an address-range version when the range is larger than the +\ L1 cache size. +label sync-caches \ No args or returns, kills r0 and r1 + + \ Clean (push the data out to a higher level) the entire L1 data cache + \ by looping over all sets and ways + mov r0,#0 \ Start with set/way 0 of L1 cache + begin + \ In this unrolled loop, the number of iterations (8) and the increment + \ value (0x20000000) depend on fact that this cache has 8 ways. + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way + mcr p15, 0, r0, cr7, cr10, 2 \ clean D$ line by set/index + inc r0,#0x20000000 \ Next way - will wrap to 0 + + inc r0,#32 \ Next set + ands r1,r0,#0xfe0 \ Mask set bits - depends on #sets=128 + 0= until + + mcr p15, 0, r0, cr7, cr5, 0 \ Invalidate entire I$ + mov pc, lr +end-code + +\ Insert zeros into the code stream until a cache line boundary is reached +\ This must be enclosed with "ahead .. then" to branch around the zeros. +: cache-align ( -- ) + begin + here [ also assembler ] asm-base [ previous ] - h# 1f and + while + 0 l, + repeat +; + +\ Turn on the MMU +label enable-mmu ( -- ) + mvn r2, #0 \ Set domains for Manager access - all domains su + mcr p15,0,r2,3,0,0 \ Update register 3 in CP15 - domain access control + + \ Enable the MMU + mrc p15, 0, r2, 1, 0, 0 \ Read current settings in control reg + mov r2, r2, LSL #18 \ Upper 18-bits must be written as zero, + mov r2, r2, LSR #18 \ ... clear them now. + + orr r2, r2, 0x200 \ Set the ROM Protection bit + bic r2, r2, 0x100 \ Clear the System Protection bit + orr r2, r2, 0x001 \ Set the MMU bit + + \ Align following code to a cache line boundary + ahead + cache-align + then + + mcr p15, 0, r2, cr1, cr0, 0 \ Go Virtual + mrc p15, 0, r2, cr2, cr0, 0 \ Ensure that the write completes + mov r2, r2 \ before continuing + sub pc, pc, #4 + + mov pc, lr +end-code + +\ Map sections virtual=physical within the given address range, using +\ the given protection/cacheability mode. pt-adr is the page table base address. +label map-sections-v=p ( r0: pt-adr, r1: adr, r2: len, r3: mode -- ) + begin + add r4, r1, r3 \ PA+mode + str r4, [r0, r1, lsr #18] + + inc r1, #0x100000 + decs r2, #0x100000 + 0<= until + + mov pc, lr +end-code + +\ Initial the section table, setting up mappings for the platform-specific +\ address ranges that the firmware uses. +\ Destroys: r0-r4 +label init-map ( r0: section-table -- ) + mov r10,lr + + mcr p15,0,r0,cr2,cr0,0 \ Set table base address + + \ Clear the entire section table for starters + mov r2, #0x1000 \ Section# + mov r3, #0 \ Invalid section entry + begin + subs r2, r2, #1 \ Decrement section number + str r3, [r0, r2, lsl #2] \ Invalidate section entry + 0= until + + mov r1,0 \ Address of low memory + set r2,`dma-base #` \ Size of low memory - up to dma-base + set r3,#0xc0e \ Cache and write bufferable + bl `map-sections-v=p` + + set r1,`dma-base #` \ Address of DMA area + set r2,`dma-size #` \ Size of DMA area + set r3,#0xc02 \ No caching or write buffering + bl `map-sections-v=p` + + set r1,`fw-pa #` \ Address of Firmware region + set r2,`/fw-ram #` \ Size of firmware region + set r3,#0xc0e \ Write bufferable + bl `map-sections-v=p` + + set r1,`fb-pa #` \ Address - Frame buffer + set r2,`fb-size #` \ Size of frame buffer + set r3,#0xc06 \ Write bufferable + bl `map-sections-v=p` + + set r1,#0xd1000000 \ Address of SRAM + set r2,#0x00300000 \ Size of SRAM + set r3,#0xc02 \ No caching or write buffering + bl `map-sections-v=p` + + set r1,#0xd4000000 \ Address of I/O + set r2,#0x00400000 \ Size of I/O region + set r3,#0xc02 \ No caching or write buffering + bl `map-sections-v=p` + + set r1,#0xe0000000 \ Address of Audio SRAM + set r2,#0x00100000 \ Size of audio SRAM + set r3,#0xc02 \ No caching or write buffering + bl `map-sections-v=p` + +\ The cache is not on yet +\ set r1,#0x4000 \ Size of section table +\ bl `clean-dcache-range` + + mov pc, r10 +end-code + +\ LICENSE_BEGIN +\ Copyright (c) 2011 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Added: cpu/arm/olpc/resetvec.bth ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ cpu/arm/olpc/resetvec.bth Fri May 20 01:22:54 2011 (r2207) @@ -0,0 +1,262 @@ +\ See license at end of file +purpose: Low-level startup code + +command: &builder &this +build-now + +\ create debug-reset + +\needs start-assembling fload ${BP}/cpu/arm/asmtools.fth +\needs write-dropin fload ${BP}/forth/lib/mkdropin.fth + +fload ${BP}/cpu/arm/olpc/1.75/config.fth + +hex + +also forth definitions +: c$, ( adr len -- ) + 1+ here swap note-string dup allot move 4 (align) +; +previous definitions + +also arm-assembler definitions +: $find-dropin, ( adr len -- ) + 2>r + " mov r0,pc" evaluate \ Get address of string + " ahead" evaluate \ Skip string + 2r> c$, \ Place string + " then" evaluate + " bl `find-dropin`" evaluate \ and call find routine +; +previous definitions + +/fw-ram h# 2.0000 - constant workspace-offset \ Offset of inflater workspace within destination RAM +/fw-ram constant stack-offset \ Offset of top of inflater stack within destination RAM + +start-assembling + +label my-entry +\ **** This is the primary entry point; it will contain a branch instruction +\ that skips a few subroutines and lands at the startup sequence. That +\ branch instruction is patched in below. The entry point for this module +\ is in turn reached from a branch instruction at the beginning of the ROM, +\ which is created by the file arch/dna/resetvec.bth + 0 , \ To be patched later +end-code + +\ This subroutine is used by the startup code. +\ It compares two null-terminated strings, returning zero if they match. +\ Destroys: r2, r3 +label strcmp ( r0: str1 r1: str2 -- r0: 0 if match, nonzero if mismatch ) + begin + ldrb r2,[r0],#1 + ldrb r3,[r1],#1 + cmp r2,r3 + <> if + sub r0,r3,r2 + mov pc,lr + then + + cmp r2,#0 + = until + mov r0,#0 + mov pc,lr +end-code + +\ This subroutine is used by the startup code. +\ It searches the ROM for a dropin module whose name field matches the +\ null-terminated string that is passed in r0. +\ Destroys: r1-6 +label find-dropin ( r0: module-name-ptr -- r0: address|-1 ) + mov r6,lr \ r6: return address + mov r5,r0 \ r5: module name + + \ Compute address of first dropin (the one containing this code) +\ sub r4,pc,`here asm-base - h# 20 + 8 + #` \ r4: module pointer + set r4,`'dropins #` + + begin + ldr r1,[r4] + set r2,#0x444d424f \ 'OBMD' in little-endian + cmp r1,r2 + = while + mov r0,r5 + add r1,r4,#16 + bl `strcmp` + cmp r0,#0 + = if \ It the strings match, we found the dropin + mov r0,r4 + mov pc,r6 + then + ldr r0,[r4,#4] \ Length of dropin image + eor r1,r0,r0, ror #16 \ Byte reverse r0 + bic r1,r1,#0xff0000 \ using the tricky sequence + mov r0,r0,ror #8 \ shown in the ARM Programming Techniques + eor r0,r0,r1,lsr #8 \ manual + + add r0,r0,r4 \ Added to base address of previous dropin + add r0,r0,#35 \ Plus length of header (32) + roundup (3) + bic r4,r0,#3 \ Aligned to 4-byte boundary = new dropin addr + repeat + + mvn r0,#0 \ No more dropins; return -1 to indicate failure + mov pc,r6 +end-code + +\ This subroutine is used by the startup code. +\ It copies n (r2) bytes of memory from src (r1) to dst (r0) +\ Destroys: r0-r3 +label memcpy ( r0: dst r1: src r2: n -- r0: dst ) + ahead begin + ldr r3,[r1],#4 + str r3,[r0],#4 + but then + subs r2,r2,#4 + 0< until + + mov pc,lr +end-code + +\ Load some additional subroutines that are used by the startup code +fload ${BP}/cpu/arm/olpc/initmmu.fth \ Setup the initial virtual address map + +\ **** This is the main-line code for the initial startup sequence. +\ It is reached from a branch instruction (which will be patched in later) +\ at the beginning of this module. + +label startup + +\ Place a branch instruction to this location at the entry address +\ (i.e. the beginning) of this module +here my-entry put-branch + +[ifdef] notdef + \ Locate and execute the dropin module named "start". + \ That module's job is to initialize the core logic and memory controller + \ at least to the point that memory works, and to size the memory. + \ It returns in r0 the physical address just past the end of the last + \ bank of memory. Near the beginning of the last megabyte of memory, + \ it stores bitmasks describing which memory banks are populated. + + " start" $find-dropin, \ Assemble call to find-dropin with literal arg + + add r0,r0,#32 \ Skip dropin header + mov lr,pc \ Set return address + mov pc,r0 \ Execute the dropin +[then] + + \ Setup the page (section) table and turn on the MMU and caches + set r0,`page-table-pa #` + bl `init-map` \ Setup the initial virtual address map + bl `enable-mmu` \ Turn on the MMU + bl `caches-on` \ Turn on the caches + + \ Now we are running with the MMU and caches on, thus going faster + + \ Locate the dropin module named "firmware". + + " firmware" $find-dropin, \ Assemble call to find-dropin with literal arg + + ldr r1,[r0,#12] \ Get the module's "expanded size" field, + cmp r1,#0 \ which will be non0 if the module's compressed + <> if + \ The firmware dropin is compressed, so we find the inflater + \ and use it to inflate the firmware into RAM + mov r11,r0 \ Save address of firmware dropin + + + \ Locate the "inflate" module. + " inflate" $find-dropin, \ Assemble call to find-dropin with literal arg + + add r4,r0,#32 \ r1: Base address of inflater code + + \ Execute the inflater, giving it the address of the compressed firmware + \ module, the address where the inflated firmware should be placed, and + \ the address of some RAM the inflater can use for scratch variables. + + set r0,`fw-virt-base workspace-offset + #` \ Scratch RAM for inflater + mov r1,#0 \ No-header flag (false) + set r2,`fw-virt-base #` \ Firmware RAM address + add r3,r11,#32 \ Address of compressed bits of firmware dropin + + set sp,`fw-virt-base stack-offset + #` \ Stack for inflater + +[ifdef] notdef + \ Simple recipe for debug output to serial port + set r11, #0xd4018000 + begin + ldr r10,[r11,0x14] + ands r10,r10,#0x20 + 0<> until + set r10, #0x43 \ C + str r10, [r11] +[then] + + mov lr,pc + mov pc,r4 \ Inflate the firmware + + else + \ The firmware dropin isn't compressed, so we just copy it to RAM + + ldr r2,[r0,#4] \ Length of image + + eor r1,r2,r2, ror #16 \ Byte reverse r2 using the + bic r1,r1,#0xff0000 \ tricky sequence shown in the + mov r2,r2,ror #8 \ ARM Programming Techniques + eor r2,r2,r1,lsr #8 \ manual + + add r1,r0,#32 \ src: Skip dropin header + + set r0,`fw-virt-base #` \ dst: Firmware RAM address + bl `memcpy` \ Copy the firmware + then + + \ Synchronize the instruction and data caches so the firmware code can + \ be executed. + bl `sync-caches` \ Push Forth dictionary to memory + +[ifdef] notdef + " nanoforth" $find-dropin, \ Assemble call to find-dropin with literal arg + + add r0,r0,#32 \ Skip dropin header + mov lr,pc \ Set return address + mov pc,r0 \ Execute the dropin +[then] + + \ Jump to the RAM firmware image + set r4, `fw-virt-base #` \ RAM start address + mov pc, r4 + + \ Notreached, in theory + begin again +end-code + +end-assembling + +writing resetvec.img +asm-base here over - ofd @ fputs +ofd @ fclose + +\ LICENSE_BEGIN +\ Copyright (c) 2011 FirmWorks +\ +\ Permission is hereby granted, free of charge, to any person obtaining +\ a copy of this software and associated documentation files (the +\ "Software"), to deal in the Software without restriction, including +\ without limitation the rights to use, copy, modify, merge, publish, +\ distribute, sublicense, and/or sell copies of the Software, and to +\ permit persons to whom the Software is furnished to do so, subject to +\ the following conditions: +\ +\ The above copyright notice and this permission notice shall be +\ included in all copies or substantial portions of the Software. +\ +\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +\ +\ LICENSE_END
Modified: cpu/arm/scc.fth ============================================================================== --- cpu/arm/scc.fth Fri May 20 01:15:27 2011 (r2206) +++ cpu/arm/scc.fth Fri May 20 01:22:54 2011 (r2207) @@ -6,6 +6,7 @@ code cache-type@ ( -- n ) psh tos,sp mrc p15,0,tos,cr0,cr0,1 c; code tlb-type@ ( -- n ) psh tos,sp mrc p15,0,tos,cr0,cr0,3 c; code control@ ( -- n ) psh tos,sp mrc p15,0,tos,cr1,cr0,0 c; +code aux-control@ ( -- n ) psh tos,sp mrc p15,0,tos,cr1,cr0,1 c; code ttbase@ ( -- n ) psh tos,sp mrc p15,0,tos,cr2,cr0,0 c; code ttbase0@ ( -- n ) psh tos,sp mrc p15,0,tos,cr2,cr0,0 c; code ttbase1@ ( -- n ) psh tos,sp mrc p15,0,tos,cr2,cr1,0 c; @@ -18,6 +19,7 @@ code i-fault-address@ ( -- n ) psh tos,sp mrc p15,0,tos,cr6,cr2,0 c;
code control! ( n -- ) mcr p15,0,tos,cr1,cr0,0 pop tos,sp c; +code aux-control! ( n -- ) mcr p15,0,tos,cr1,cr0,1 pop tos,sp c; code ttbase! ( n -- ) mcr p15,0,tos,cr2,cr0,0 pop tos,sp c; code ttbase0! ( n -- ) mcr p15,0,tos,cr2,cr0,0 pop tos,sp c; code ttbase1! ( n -- ) mcr p15,0,tos,cr2,cr1,0 pop tos,sp c; @@ -162,8 +164,13 @@ \ operation, so it uses the Open Firmware nomenclature. defer flush-cache ' noop to flush-cache
+[ifdef] notdef : l2cache-on ( -- ) flush-l2$ control@ h# 0400.0000 or control! ; : l2cache-off ( -- ) clean-l2$ control@ h# 0400.0000 invert and control! ; +[else] +: l2cache-on ( -- ) flush-l2$ aux-control@ 2 or aux-control! ; +: l2cache-off ( -- ) clean-l2$ aux-control@ 2 invert and aux-control! ; +[then]
: bpu-on ( -- ) flush-bt$ control@ h# 0800 or control! ; : bpu-off ( -- ) control@ h# 0800 invert and control! ;