gonzui


Format: Advanced Search

tkernel_2/monitor/hwdepend/tef_em1d/src/reset.Sbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      reset.S
   17:  *
   18:  *       EM1-D512: initial setting after a reset.
   19:  */
   20: 
   21: #define _in_asm_source_
   22: 
   23: #include <machine.h>
   24: #include <tk/sysdef.h>
   25: #include <arm/em1d512.h>
   26: #include <sys/sysinfo.h>
   27: 
   28: #include "setup_em1d512.h"
   29: 
   30: /*
   31:  * macro for setting up registers
   32:  */
   33: .macro out_w reg, val
   34:   .ifnes "\val", ""     // when val is empty, do nothing.
   35:         ldr    r0, =\reg
   36:         ldr    r1, =\val
   37:         str    r1, [r0]
   38:   .endif
   39: .endm
   40: 
   41: .macro setup_param      // r0: address of parameter string.
   42: 0:                      // * r0, r2, and r3 are going to be clobbered.
   43:         ldmia  r0!, {r2, r3}
   44:         cmp    r2, #0
   45:         strne  r3, [r2]
   46:         bne    0b
   47: .endm
   48: 
   49: .macro  wait_nsec        // r0: wait time (nsec)
   50:                         // * Assume one step is 4 ns @ (500MHz)
   51:         lsr    r0, r0, #2
   52: 0:
   53:         subs   r0, r0, #1
   54:         bne    0b
   55: .endm
   56: 
   57: /*
   58:  * memory barrier macros
   59:  */
   60: .macro _mov reg, val
   61:   .ifnes "\reg", "\val"
   62:         mov    \reg, \val
   63:   .endif
   64: .endm
   65: .macro .ISB reg, val=#0
   66:         _mov   \reg, \val
   67:         mcr    p15, 0, \reg, cr7, c5, 4
   68: .endm
   69: .macro .DSB reg, val=#0
   70:         _mov   \reg, \val
   71:         mcr    p15, 0, \reg, cr7, c10, 4
   72: .endm
   73: .macro .DMB reg, val=#0
   74:         _mov   \reg, \val
   75:         mcr    p15, 0, \reg, cr7, c10, 5
   76: .endm
   77: 
   78: /*----------------------------------------------------------------------
   79:         T-Monitor boot processing
   80: ----------------------------------------------------------------------*/
   81:         .section .startup, "ax"
   82:         .balign        4
   83:         .globl startup_entry
   84:         .type  startup_entry, %function
   85:         .org   0x00000000
   86: startup_entry:
   87: // SVC mode, FIQ/IRQ interrupt disabled
   88:         mov    r0, #(PSR_SVC | PSR_I | PSR_F)
   89:         msr    cpsr_fsxc, r0
   90: 
   91: // use On-Chip SRAM as stack area
   92:         ldr    sp, =0xa0020000
   93: 
   94: // not in effect: MMU, cache (D/I), program-flow prediction, High-Vector, VIC
   95: // in effect: Force AP, TEX remap, Subpage AP
   96:         .DSB   r0
   97:         mrc    p15, 0, r0, cr1, cr0, 0
   98:         ldr    r1, =~0x01003f85
   99:         and    r0, r0, r1
  100:         ldr    r1, =0x30800000
  101:         orr    r0, r0, r1
  102:         mcr    p15, 0, r0, cr1, cr0, 0
  103: 
  104: // Setup clock divider
  105:         mov    r0, #0
  106:         ldr    r2, =CHG_L1_HOLD
  107:         str    r0, [r2]           // release data hold when L1 is off
  108:         mov    r0, #0x30000000
  109:         ldr    r2, =AUTO_FRQ_CHANGE
  110:         str    r0, [r2]           // automatic frequency change function is off
  111: 
  112: setup_clock_divider:
  113:         adr    r0, param_table0
  114:         setup_param
  115: 
  116: // Setup PLL1 (PLL3 is operating)
  117: setup_pll1:
  118:         // We assume Power ON mode: In other mode setting, we simply take it for granted that PLL has been configured already
  119:         ldr    r2, =CLK_MODE_SEL
  120:         ldr    r0, [r2]
  121:         ands   r0, r0, #0x00000f00
  122:         bne    setup_power_mode
  123: 
  124:         mov    r0, #0x79          // (default) PLL1=499.712MHz
  125:         ldr    r2, =PLL1CTRL0
  126:         str    r0, [r2]
  127:         mov    r0, #0
  128:         ldr    r2, =PLL1CTRL1
  129:         str    r0, [r2]           // PLL starts to operate
  130:         ldr    r2, =PLL_STATUS
  131: wait_pll1:
  132:         ldr    r0, [r2]           // Wait for PLL1 operation completion
  133:         ands   r0, r0, #0x00000001
  134:         beq    wait_pll1
  135: 
  136: // Setup power mode
  137: setup_power_mode:
  138:         // Transition from Power ON to Normal Mode A
  139:         mov    r0, #1
  140:         ldr    r2, =CLK_MODE_SEL
  141:         str    r0, [r2]
  142: wait_power_mode_change:
  143:         ldr    r0, [r2]
  144:         and    r0, r0, #0x00000f00
  145:         cmp    r0, #0x00000100
  146:         bne    wait_power_mode_change
  147: 
  148: // Setup PLL2 (needs to be configured in Normal Mode)
  149: setup_pll2:
  150:         mov    r0, #0xff          // PLL2 ceases to operate
  151:         ldr    r2, =PLL2CTRL1
  152:         str    r0, [r2]
  153:         ldr    r2, =PLL_STATUS
  154: wait_pll2_0:    
  155:         ldr    r0, [r2]           // Wait for PLL1 operation
  156:         ands   r0, r0, #0x00000100
  157:         bne    wait_pll2_0
  158: 
  159:         mov    r0, #0x61          // PLL2=401.408MHz
  160:         ldr    r2, =PLL2CTRL0
  161:         str    r0, [r2]
  162:         mov    r0, #0                     // PLL2 starts to operate
  163:         ldr    r2, =PLL2CTRL1
  164:         str    r0, [r2]
  165:         ldr    r2, =PLL_STATUS
  166: wait_pll2_1:    
  167:         ldr    r0, [r2]           // wait for PLL2 to stop operation.
  168:         ands   r0, r0, #0x00000100
  169:         beq    wait_pll2_1
  170: 
  171: // Setup pin multiplexer
  172: setup_pin_mux:
  173:         mov    r1, #0xff000000            // since 'adr' cannot be used, we manually make sure
  174:         ldr    r0, =Csym(GPIOConfig)      // that the code is relocatable at 16MB units boundary.
  175:         bic    r0, r0, r1
  176:         and    r1, pc, r1
  177:         orr    r0, r0, r1
  178:         setup_param
  179:         
  180: // release reset of the internal modules
  181: setup_module:
  182:         adr    r0, param_table1
  183:         setup_param
  184:         ldr    r0, =100000
  185:         wait_nsec
  186: 
  187: // supplying clock to modules.
  188: setup_clock_distribution:
  189:         adr    r0, param_table2
  190:         setup_param
  191: 
  192: // Setup Bus controller
  193: setup_bcr:
  194:         adr    r0, param_table3
  195:         setup_param
  196: 
  197: // initialization of DDR memory
  198:         bl     setup_ddr
  199: 
  200: // creation of temporary page table
  201:         ldr    r0, =PAGETBL_BASE
  202:         ldr    r1, =0x00000000
  203:         ldr    r2, =0x00000402    // Kernel/RW, Strongly-order
  204: tmptable_loop:
  205:         orr    r3, r1, r2
  206:         str    r3, [r0], #4
  207:         adds   r1, r1, #0x00100000
  208:         bne    tmptable_loop
  209: 
  210: // Mapping of FlashROM area (0x70000000 - 0x72000000 --> 0x00000000 -)
  211:         ldr    r0, =(PAGETBL_BASE + (0x700 << 2))
  212:         ldr    r1, =0x00000000
  213:         ldr    r2, =0x0000940e    // Kernel/RO, Normal WB/WA
  214: flashtable_loop:
  215:         orr    r3, r1, r2
  216:         str    r3, [r0], #4
  217:         adds   r1, r1, #0x00100000
  218:         cmp    r1, #0x02000000
  219:         bne    flashtable_loop
  220:         
  221: // initialization of CP15
  222:         ldr    r0, =0x00000004
  223:         mcr    p15, 0, r0, cr2, cr0, 2            // TTBCR
  224:         ldr    r0, =(PAGETBL_BASE + 0x09) // WB/WA, no-shared, cachable
  225:         mcr    p15, 0, r0, cr2, cr0, 1            // TTBR1
  226:         mcr    p15, 0, r0, cr2, cr0, 0            // TTBR0
  227:         ldr    r0, =EITENT_BASE
  228:         mcr    p15, 0, r0, cr12, cr0, 0   // VBAR
  229:         ldr    r0, =0x000a8aa4
  230:         mcr    p15, 0, r0, cr10, cr2, 0   // PRRR
  231:         ldr    r0, =0x44e048e0
  232:         mcr    p15, 0, r0, cr10, cr2, 1   // NMRR
  233:         ldr    r0, =0x55555555                    // All client
  234:         mcr    p15, 0, r0, cr3, cr0, 0            // Domain access
  235: 
  236: // MMU enable
  237:         .DSB   r0
  238:         mcr    p15, 0, r0, cr8, cr7, 0            // I/D TLB invalidate
  239:         mcr    p15, 0, r0, cr7, cr5, 6            // invalidate BTC
  240:         .DSB   r0
  241:         .ISB   r0
  242:         mrc    p15, 0, r0, cr1, cr0, 0
  243:         orr    r0, r0, #0x00000001
  244:         mcr    p15, 0, r0, cr1, cr0, 0
  245:         .ISB   r0
  246: 
  247: // perform reset processing
  248:         ldr    pc, =reset_entry
  249: 
  250: // initialization of DDR memory
  251: setup_ddr:
  252:         ldr    r0, =MEMCCLK270_SEL
  253:         ldr    r1, =0x00000001            // MEMCCLK270 no phase delay
  254:         str    r1, [r0]
  255: 
  256:         ldr    r0, =MEMC_DDR_CONFIGT1
  257:         ldr    r1, =0x00000006            // start auto-calibration
  258:         str    r1, [r0]
  259: calibrate_loop:
  260:         ldr    r1, [r0]
  261:         ands   r1, r1, #0x00000002       // wait for complete
  262:         beq    calibrate_loop
  263: 
  264:         ldr    r0, =MEMC_DDR_CONFIGT3
  265:         ldr    r1, [r0]           // get calibration result
  266:         ldr    r0, =MEMC_DDR_CONFIGT2
  267:         str    r1, [r0]           // apply calibrated value
  268: 
  269:         ldr    r0, =MEMCCLK270_SEL
  270:         ldr    r1, =0x00000000            // MEMCCLK270 270degree delay
  271:         str    r1, [r0]
  272: 
  273:         ldr    r0, =MEMC_DDR_CONFIGT1
  274:         ldr    r1, =0x000d0803
  275:         str    r1, [r0]
  276: 
  277:         ldr    r0, =MEMC_DDR_CONFIGF
  278:         ldr    r1, =0x00000015
  279:         str    r1, [r0]
  280: 
  281:         ldr    r0, =MEMC_DDR_CONFIGA1
  282:         ldr    r1, =0x53443203
  283:         str    r1, [r0]
  284: 
  285:         ldr    r0, =MEMC_DDR_CONFIGA2
  286:         ldr    r1, =0x28da1042
  287:         str    r1, [r0]
  288: 
  289:         ldr    r0, =MEMC_DDR_CONFIGC2
  290:         ldr    r1, =0x0000001d
  291:         str    r1, [r0]
  292: 
  293:         ldr    r0, =200000
  294:         wait_nsec
  295: 
  296:         ldr    r0, =MEMC_DDR_CONFIGC1
  297:         ldr    r1, =0x80200033
  298:         str    r1, [r0]
  299: 
  300:         ldr    r0, =MEMC_DDR_CONFIGC2
  301:         ldr    r1, =0x00000018            // CS0: memory initialize sequence
  302:         str    r1, [r0]
  303: ddr_init_loop:
  304:         ldr    r1, [r0]
  305:         ands   r1, r1, #0x00000100
  306:         beq    ddr_init_loop
  307: 
  308:         ldr    r0, =MEMC_REQSCH
  309:         ldr    r1, =0x0000001f            // memory request schedule
  310:         str    r1, [r0]
  311: 
  312:         ldr    r0, =MEMC_DDR_CONFIGC2
  313:         ldr    r1, =0x00000090            // CS0: CMD_REQ release
  314:         str    r1, [r0]
  315: 
  316:         ldr    r0, =MEMC_DDR_CONFIGR1
  317:         ldr    r1, =0x00690069            // refresh counter
  318:         str    r1, [r0]
  319: 
  320:         ldr    r0, =MEMC_DDR_CONFIGR2
  321:         ldr    r1, =0x3777011f
  322:         str    r1, [r0]
  323: 
  324:         ldr    r0, =MEMC_DDR_CONFIGR3
  325:         ldr    r1, =0x00001415
  326:         str    r1, [r0]
  327: 
  328:         bx     lr
  329: 
  330:         .pool
  331: 
  332: param_table0:
  333:         .long  NORMALA_DIV              // ACPU =PLL1/1 (499.712MHz)
  334:         .long  0x00244200               // ADSP =PLL1/1 (499.712MHz)
  335:                                         // HBUS =PLL1/3 (166.571MHz)
  336:                                         // LBUS =PLL1/6 ( 83.285MHz)
  337:                                         // FLASH=PLL1/6 ( 83.285MHz)
  338:                                         // MEMC =PLL1/3 (166.571MHz)
  339:         .long  DIVU70SCLK
  340:         .long  0x00000000               // U70_SCLK=PLL3/1 (229.376MHz)
  341:         .long  DIVU71SCLK
  342:         .long  0x00000000               // U71_SCLK=PLL3/1 (229.376MHz)
  343:         .long  DIVU72SCLK
  344:         .long  0x00000000               // U72_SCLK=PLL3/1 (229.376MHz)
  345:         .long  DIVLCDLCLK
  346:         .long  0x00000004               // LCD_LCLK=PLL2/16 (25.088MHz)
  347:         .long  DIVIICSCLK
  348:         .long  0x00530053               // IIC_SCLK=PLL3/48 (4.779MHz)
  349:         .long  DIVTIMTIN
  350:         .long  0x00000003               // Txx_TIN=PLL3/8 (28.672MHz)
  351:         .long  DIVSP0SCLK
  352:         .long  0x00000074               // SP0_SCLK=PLL3/128 (1.792MHz)
  353:         .long  TI0TIN_SEL
  354:         .long  0x00000000
  355:         .long  TI1TIN_SEL
  356:         .long  0x00000000
  357:         .long  TI2TIN_SEL
  358:         .long  0x00000000
  359:         .long  TI3TIN_SEL
  360:         .long  0x00000000
  361:         .long  TIGnTIN_SEL
  362:         .long  0x00000000
  363: 
  364:         .long  0x00000000               // (terminate)
  365:         .long  0x00000000
  366: 
  367: param_table1:
  368:         .long  RESETREQ0ENA
  369:         .long  0xffffffff
  370:         .long  RESETREQ0
  371:         .long  0xffffffe7               // Reset everything, but DSP
  372:         .long  RESETREQ0ENA
  373:         .long  0x00000000
  374:         .long  RESETREQ1ENA
  375:         .long  0xffffffff
  376:         .long  RESETREQ1
  377:         .long  0xffffffff               // Reset everything
  378:         .long  RESETREQ1ENA
  379:         .long  0x00000000
  380:         .long  RESETREQ2ENA
  381:         .long  0xffffffff
  382:         .long  RESETREQ2
  383:         .long  0xffffffff               // Reset everything
  384:         .long  RESETREQ2ENA
  385:         .long  0x00000000
  386:         .long  RESETREQ3ENA
  387:         .long  0xffffffff
  388:         .long  RESETREQ3
  389:         .long  0xffffffff               // Reset everything
  390:         .long  RESETREQ3ENA
  391:         .long  0x00000000
  392: 
  393:         .long  0x00000000               // (terminate)
  394:         .long  0x00000000
  395: 
  396: param_table2:
  397:         .long  GCLKCTRL0ENA
  398:         .long  0xffffffff
  399:         .long  GCLKCTRL0
  400:         .long  0xffffffff               // (default) module clock on
  401:         .long  GCLKCTRL0ENA
  402:         .long  0x00000000
  403:         .long  GCLKCTRL1ENA
  404:         .long  0xffffffff
  405:         .long  GCLKCTRL1
  406:         .long  0xffffffff               // (default) module clock on
  407:         .long  GCLKCTRL1ENA
  408:         .long  0x00000000
  409:         .long  GCLKCTRL2ENA
  410:         .long  0xffffffff
  411:         .long  GCLKCTRL2
  412:         .long  0xffffffff               // (default) module clock on
  413:         .long  GCLKCTRL2ENA
  414:         .long  0x00000000
  415:         .long  GCLKCTRL3ENA
  416:         .long  0xffffffff
  417:         .long  GCLKCTRL3
  418:         .long  0xffffffff               // (default) module clock on
  419:         .long  GCLKCTRL3ENA
  420:         .long  0x00000000
  421:         .long  GCLKCTRL4ENA
  422:         .long  0xffffffff
  423:         .long  GCLKCTRL4
  424:         .long  0xffffffff               // (default) module clock on
  425:         .long  GCLKCTRL4ENA
  426:         .long  0x00000000
  427:         .long  AHBCLKCTRL0
  428:         .long  0x00000000               // (default) prohibit automatic control
  429:         .long  AHBCLKCTRL1
  430:         .long  0x00000000               // (default) prohibit automatic control
  431:         .long  APBCLKCTRL0
  432:         .long  0x00000000               // (default) prohibit automatic control
  433:         .long  APBCLKCTRL1
  434:         .long  0x00000000               // (default) prohibit automatic control
  435:         .long  CLKCTRL
  436:         .long  0x00000000               // (default) prohibit automatic control
  437:         .long  CLKCTRL1
  438:         .long  0x00000000
  439: 
  440:         .long  0x00000000               // (terminate)
  441:         .long  0x00000000
  442: 
  443: param_table3:
  444:         .long  AB1_U70WAITCTRL
  445:         .long  0x00010200               // recommended value for 83MHz operation
  446:         .long  AB1_U71WAITCTRL
  447:         .long  0x00010200               // recommended value for 83MHz operation
  448:         .long  AB1_U72WAITCTRL
  449:         .long  0x00010200               // recommended value for 83MHz operation
  450:         .long  AB1_IIC2WAITCTRL
  451:         .long  0x00010300               // recommended value for 83MHz operation
  452:         .long  AB1_IICWAITCTRL
  453:         .long  0x00010300               // recommended value for 83MHz operation
  454:         .long  AB1_SDIAWAITCTRL
  455:         .long  0x00010300
  456:         .long  AB1_SDIBWAITCTRL
  457:         .long  0x00010300
  458:         .long  AB1_SDICWAITCTRL
  459:         .long  0x00010300
  460:         .long  AB1_U70READCTRL
  461:         .long  0x00000000               // (default)
  462:         .long  AB1_U71READCTRL
  463:         .long  0x00000000               // (default)
  464:         .long  AB1_U72READCTRL
  465:         .long  0x00000000               // (default)
  466:         .long  AB1_IIC2READCTRL
  467:         .long  0x00000000               // (default)
  468:         .long  AB1_IICREADCTRL
  469:         .long  0x00000000               // (default)
  470:         .long  AB1_SDIAREADCTRL
  471:         .long  0x00000000               // (default)
  472:         .long  AB1_SDIBREADCTRL
  473:         .long  0x00000000               // (default)
  474:         .long  AB1_SDICREADCTRL
  475:         .long  0x00000000               // (default)
  476: 
  477:         // memory map setup (CS0-3)
  478:         //
  479:         // 0x00000000 +----------------------------+
  480:         //            | Bank0/CS0 (not used)       |
  481:         // 0x10000000 +----------------------------+
  482:         //            | Bank1/CS1 (not used)       |
  483:         // 0x20000000 +----------------------------+
  484:         //            | Bank2/CS2 (not used)       |
  485:         // 0x28000000 +----------------------------+
  486:         //            | Bank2/CS3 (LAN controller) |
  487:         // 0x30000000 +----------------------------+
  488:         .long  AB0_CSnBASEADD(0)
  489:         .long  0x00000000
  490:         .long  AB0_CSnBITCOMP(0)
  491:         .long  0xf0000000
  492:         .long  AB0_CSnBASEADD(1)
  493:         .long  0x10000000
  494:         .long  AB0_CSnBITCOMP(1)
  495:         .long  0xf0000000
  496:         .long  AB0_CSnBASEADD(2)
  497:         .long  0x20000000
  498:         .long  AB0_CSnBITCOMP(2)
  499:         .long  0xf8000000
  500:         .long  AB0_CSnBASEADD(3)
  501:         .long  0x28000000
  502:         .long  AB0_CSnBITCOMP(3)
  503:         .long  0xf8000000
  504:         .long  AB0_FLASHCLKCTRL
  505:         .long  0x00000001               // AB0:Flash=1:2
  506: 
  507:         // set up LAN controller
  508:         // Assuming the use of 83.333 MHz (12ns/1clk), we set the following values.
  509:         //     CSint=1clk (Read+1clk=24ns, Write+2clk=36ns)
  510:         //     T0=0clk (0ns), T1=3clk(36ns), T2=2clk(24ns)
  511:         .long  AB0_CSnWAITCTRL(3)
  512:         .long  0x01020300
  513:         .long  AB0_CSnWAITCTRL_W(3)
  514:         .long  0x00020300
  515:         .long  AB0_CSnREADCTRL(3)
  516:         .long  0x00000000               // (default)
  517:         .long  AB0_CSnWAIT_MASK(3)
  518:         .long  0x00000000               // (default)
  519:         .long  AB0_CSnCONTROL(3)
  520:         .long  0x00010100               // (default)
  521:         .long  AB0_FLASHCOMSET
  522:         .long  0x00000008               // CS3 value above is reflected.
  523:         
  524:         .long  0x00000000               // (terminate)
  525:         .long  0x00000000
  526: 
  527: /*----------------------------------------------------------------------
  528:         Reset processing
  529: ----------------------------------------------------------------------*/
  530:         .text
  531:         .balign        4
  532:         .globl reset_entry
  533:         .type  reset_entry, %function
  534: reset_entry:
  535: 
  536: // SVC mode, FIQ/IRQ interrupt disabled
  537:         mov    r0, #(PSR_SVC | PSR_I | PSR_F)
  538:         msr    cpsr_fsxc, r0
  539: 
  540: // Switch to T-Monitor stack
  541:         ldr    sp, =__stack_bottom
  542: 
  543: // not in effect: cache (D/I), program-flow prediction, High-Vector, VIC
  544: // in effect: Force AP, TEX remap, Subpage AP
  545:         .DSB   r0
  546:         mrc    p15, 0, r0, cr1, cr0, 0
  547:         ldr    r1, =~0x01003f84
  548:         and    r0, r0, r1
  549:         ldr    r1, =0x30800000
  550:         orr    r0, r0, r1
  551:         mcr    p15, 0, r0, cr1, cr0, 0
  552: 
  553:         .ISB   r0
  554:         mcr    p15, 0, r0, cr8, cr7, 0            // I/D TLB invalidate
  555:         .DSB   r0
  556:         bl     Csym(FlushCache)            // Clean/invalidate I/D cache
  557: 
  558: // Turn on VFP
  559:         mrc    p15, 0, r0, cr1, cr0, 2
  560:         orr    r0, r0, #0x00f00000        // VFP(CP11,CP10) enable
  561:         bic    r0, r0, #0xc0000000        // Should be Zero
  562:         mcr    p15, 0, r0, cr1, cr0, 2
  563:         .ISB   r0                        // Flush Prefetch buffer
  564: 
  565: // initialize data area
  566:         ldr    r1, =__data_org
  567:         ldr    r2, =__data_start
  568:         ldr    r3, =_edata
  569: data_loop:
  570:         ldmia  r1!, {r4-r7}     // copy in unit of 16 bytes
  571:         stmia  r2!, {r4-r7}
  572:         cmp    r2, r3
  573:         blo    data_loop
  574: 
  575: // clear bss and stack area
  576:         ldr    r2, =__bss_start
  577:         ldr    r3, =__stack_bottom
  578:         ldr    r4, =0
  579:         ldr    r5, =0
  580:         ldr    r6, =0
  581:         ldr    r7, =0
  582: bss_loop:
  583:         stmia  r2!, {r4-r7}     // clear in units of 16 bytes
  584:         cmp    r2, r3
  585:         blo    bss_loop
  586: 
  587: // reset processing
  588:         bl     procReset
  589: 
  590: // clear registers & initialize stack pointer
  591:         ldr    r7, =__stack_top   // since it is 0-cleared, why not use it.
  592: 
  593:         ldmia  r7, {r8-r12,sp,lr}^      // usr: r8-r12, sp, lr
  594: 
  595:         mov    r0, #(PSR_FIQ | PSR_I | PSR_F)
  596:         msr    cpsr_fsxc, r0
  597:         ldmia  r7, {r8-r12,sp,lr}       // fiq: r8-r12, sp, lr, spsr
  598:         msr    spsr_fsxc, lr
  599:         ldr    sp, =__stack_top + 32
  600: 
  601:         mov    r0, #(PSR_IRQ | PSR_I | PSR_F)
  602:         msr    cpsr_fsxc, r0
  603:         ldr    sp, =__stack_top + 16      // irq: sp, lr, spsr
  604:         mov    lr, #0
  605:         msr    spsr_fsxc, lr
  606: 
  607:         mov    r0, #(PSR_ABT | PSR_I | PSR_F)
  608:         msr    cpsr_fsxc, r0
  609:         ldr    sp, =__stack_top + 64      // abt: sp, lr, spsr
  610:         mov    lr, #0
  611:         msr    spsr_fsxc, lr
  612: 
  613:         mov    r0, #(PSR_UND | PSR_I | PSR_F)
  614:         msr    cpsr_fsxc, R0
  615:         ldr    sp, =__stack_top + 48      // und: sp, lr, spsr
  616:         mov    lr, #0
  617:         msr    spsr_fsxc, lr
  618: 
  619:         // clear VFP
  620:         mov    r0, #0x40000000            // EX=0,EN=1,SBZ/other flags = 0
  621:         fmxr   fpexc, r0
  622: 
  623:         mov    r1, #0x00000000            // SBZ/other flags = 0
  624:         fmxr   fpscr, r1
  625: 
  626:         fldmiad        r7, {d0-d15}           // zero clear
  627: 
  628:         // return to SVC mode
  629:         mov    r0, #(PSR_SVC | PSR_I | PSR_F)
  630:         msr    cpsr_fsxc, r0
  631: 
  632:         ldmia  r7, {r0-r7}              // r0-r7
  633: 
  634: // enter monitor by means of SVC #0 instruction (SVC mode)
  635:   resetLoop:
  636:         svc    #0
  637:         b      resetLoop            // return will cause another reset
  638: 
  639:         .pool