Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:53

0001 /*
0002  * RTEMS generic MPC5200 BSP
0003  *
0004  * This file contains the startup assembly code.
0005  *
0006  * References: startup code for Motorola PQII ADS board.
0007  * Modified for the Motorola PQII ADS board by Andy Dachs.
0008  * Comment for the original code:
0009  *
0010  *   I have a proprietary bootloader programmed into the flash
0011  *   on the board which initialises the SDRAM prior to calling
0012  *   this function.
0013  */
0014 
0015 /*
0016  * Modified for the Motorola PQII ADS board by
0017  * Andy Dachs <a.dachs@sstl.co.uk> 23-11-00.
0018  * Surrey Satellite Technology Limited
0019  *
0020  * Based on the one by Jay Monkman (jmonkman@fracsa.com)
0021  * which in turn was based on the dlentry.s file for the Papyrus BSP,
0022  * written by:
0023  *
0024  * Author: Andrew Bray <andy@i-cubed.co.uk>
0025  * Copyright (c) 1995 by i-cubed ltd.
0026  *
0027  * To anyone who acknowledges that this file is provided "AS IS"
0028  * without any express or implied warranty:
0029  *    permission to use, copy, modify, and distribute this file
0030  *    for any purpose is hereby granted without fee, provided that
0031  *    the above copyright notice and this notice appears in all
0032  *    copies, and that the name of i-cubed limited not be used in
0033  *    advertising or publicity pertaining to distribution of the
0034  *    software without specific, written prior permission.
0035  *    i-cubed limited makes no representations about the suitability
0036  *    of this software for any purpose.
0037  *
0038  * Copyright (c) 2003 IPR Engineering
0039  * Copyright (c) 2005 embedded brains GmbH & Co. KG
0040  *
0041  * The license and distribution terms for this file may be
0042  * found in the file LICENSE in this distribution or at
0043  * http://www.rtems.org/license/LICENSE.
0044  */
0045 
0046 #include <rtems/asm.h>
0047 #include <rtems/powerpc/cache.h>
0048 #include <libcpu/powerpc-utility.h>
0049 
0050 #include <bsp.h>
0051 #include <bsp/mpc5200.h>
0052 
0053 /* Some register offsets of MPC5x00 memory map registers */
0054 .set    CS0STR,         0x04
0055 .set    CS0STP,         0x08
0056 .set    CS1STR,         0x0C
0057 .set    CS1STP,         0x10
0058 .set    SDRAMCS0,       0x34
0059 .set    SDRAMCS1,       0x38
0060 .set    BOOTSTR,        0x4C
0061 .set    BOOTSTP,        0x50
0062 .set    ADREN,          0x54
0063 .set    CSSR0,          0x58        /* Critical Interrupt SSR0 (603le only) */
0064 .set    CSSR1,          0x59        /* Critical Interrupt SSR1 (603le only) */
0065 .set    CFG,            0x20C
0066 .set    CSBOOTROM,          0x300
0067 .set    CSCONTROL,      0x318
0068 .set    CS1CONF,        0x304
0069 
0070 
0071 /* Register offsets of MPC5x00 SDRAM memory controller registers */
0072 .set    MOD,            0x100
0073 .set    CTRL,           0x104
0074 .set    CFG1,           0x108
0075 .set    CFG2,           0x10C
0076 .set    ADRSEL,         0x110
0077 .set    SDELAY,         0x190
0078 
0079 /* Register offsets of MPC5x00 GPIO registers needed */
0080 .set    GPIOPCR,        0xb00
0081 .set    GPIOWE,         0xc00
0082 .set    GPIOWOD,        0xc04
0083 .set    GPIOWDD,        0xc08
0084 .set    GPIOWDO,        0xc0c
0085 
0086 .set    GPIOSEN,        0xb04
0087 .set    GPIOSDD,        0xb0c
0088 .set    GPIOSDO,        0xb10
0089 
0090 /* Register offsets of MPC5x00 Arbiter registers */
0091 .set    ARBCFG,         0x1f40
0092 .set    ARBADRTO,       0x1f58
0093 .set    ARBDATTO,       0x1f5c
0094 .set    ARBMPREN,       0x1f64
0095 .set    ARBMPRIO,       0x1f68
0096 .set    ARBSNOOP,       0x1f70
0097 
0098 /* Some bit encodings for MGT5100 registers */
0099 .set    ADREN_BOOT_EN,      (1 << (31 - 6))
0100 .set    ADREN_CS0_EN,       (1 << (31 - 15))
0101 .set    ADREN_CS1_EN,       (1 << (31 - 14))
0102 .set    ADREN_WSE,      (1 << (31 - 31))
0103 
0104 .set    CTRL_PRECHARGE_ALL, (1 << (31 - 30))
0105 .set    CTRL_REFRESH,       (1 << (31 - 29))
0106 .set    CTRL_MODE_EN,       (1 << (31 - 0))
0107 
0108 .set    CSCONF_CE,      (1<<12)
0109 
0110 /* Some fixed values for MPC5x00 registers */
0111 .set    CSCONTROL_VAL,      0x91000000
0112 
0113 /*
0114  * The DDR_MODE bit is a read-only status and should be written as 0.
0115  *
0116  * XLB_CLK = FVCO / 4
0117  * IPB_CLK = XLB_CLK / 2
0118  * PCI_CLK = IPB_CLK
0119  */
0120 .set    CFG_VAL,        0x00000100
0121 
0122 .extern boot_card
0123 
0124 .section ".vectors", "ax"
0125     bl  start
0126     .rep 63
0127     .long 0x04000400
0128     .endr
0129 __vec2: b   __vec2
0130     .rep 63
0131     .long 0x04000400
0132     .endr
0133 __vec3: b   __vec3
0134     .rep 63
0135     .long 0x04000400
0136     .endr
0137 __vec4: b   __vec4
0138     .rep 63
0139     .long 0x04000400
0140     .endr
0141 __vec5: b   __vec5
0142     .rep 63
0143     .long 0x04000400
0144     .endr
0145 __vec6: b   __vec6
0146     .rep 63
0147     .long 0x04000400
0148     .endr
0149 __vec7: b   __vec7
0150     .rep 63
0151     .long 0x04000400
0152     .endr
0153 __vec8: b   __vec8
0154     .rep 63
0155     .long 0x04000400
0156     .endr
0157 __vec9: b   __vec9
0158     .rep 63
0159     .long 0x04000400
0160     .endr
0161 __veca: b   __veca
0162     .rep 63
0163     .long 0x04000400
0164     .endr
0165 __vecb: b   __vecb
0166     .rep 63
0167     .long 0x04000400
0168     .endr
0169 __vecc: b   __vecc
0170     .rep 63
0171     .long 0x04000400
0172     .endr
0173 __vecd: b   __vecd
0174     .rep 63
0175     .long 0x04000400
0176     .endr
0177 __vece: b   __vece
0178     .rep 63
0179     .long 0x04000400
0180     .endr
0181 __vecf: b   __vecf
0182     .rep 63+1024
0183     .long 0x04000400
0184     .endr
0185 
0186 .section ".entry"
0187 PUBLIC_VAR (start)
0188 start:
0189 /* 1st: initialization work (common for RAM/ROM startup) */
0190     mfmsr   r30
0191     SETBITS r30, r29, MSR_ME|MSR_RI
0192     CLRBITS r30, r29, MSR_EE
0193     mtmsr   r30                 /* Set RI/ME, Clr EE in MSR */
0194 
0195 #ifdef HAS_UBOOT
0196     mr  r14, r3
0197 #endif /* HAS_UBOOT */
0198 
0199 #if defined(NEED_LOW_LEVEL_INIT)
0200 /* initialize the MBAR (common RAM/ROM startup) */
0201     LWI r31, MBAR_RESET
0202     LWI r29, MBAR
0203     rlwinm  r30, r29,16,16,31
0204     stw r30, 0(r31)             /* Set the MBAR */
0205 #endif
0206 
0207     LWI r31, MBAR           /* set r31 to current MBAR */
0208     /* init GPIOPCR */
0209     lwz r29,GPIOPCR(r31)
0210     LWI r30, BSP_GPIOPCR_INITMASK
0211     not r30,r30
0212     and r29,r29,r30
0213     LWI r30, BSP_GPIOPCR_INITVAL
0214     or  r29,r29,r30
0215     stw r29, GPIOPCR(r31)
0216 
0217 /* further initialization work (common RAM/ROM startup) */
0218     bl  TLB_init            /* Initialize TLBs */
0219 
0220 
0221     bl  FID_DCache          /* Flush, inhibit and disable data cache */
0222 
0223 
0224     bl  IDUL_ICache         /* Inhibit, disable and unlock instruction cache */
0225 
0226 
0227     bl  FPU_init            /* Initialize FPU */
0228 
0229 
0230 #if defined(NEED_LOW_LEVEL_INIT)
0231     bl  SPRG_init           /* Initialize special purpose registers */
0232 #endif
0233 
0234 #if defined(NEED_LOW_LEVEL_INIT)
0235 /* detect RAM/ROM startup (common for RAM/ROM startup) */
0236     LWI     r20, bsp_rom_start      /* set the relocation offset */
0237 
0238 
0239     LWI     r30, CFG_VAL            /* get CFG register content */
0240     lwz r30, CFG(r31)           /* set CFG register */
0241 
0242 
0243 
0244     lwz r30, ADREN(r31)         /* get content of ADREN */
0245 
0246 
0247 
0248     TSTBITS r30, r29, ADREN_BOOT_EN
0249     bne skip_ROM_start          /* If BOOT_ROM is not enabled, skip further initialization */
0250 
0251 /* do some board dependent configuration (unique for ROM startup) */
0252     LWI     r30, CSCONTROL_VAL      /* get CSCONTROL register content */
0253     stw r30, CSCONTROL(r31)     /* enable internal/external bus error and master for CS */
0254 
0255 
0256 #if defined(MPC5200_BOARD_BRS5L)
0257     #define CSBOOTROM_VAL 0x0101D910
0258 #elif defined(MPC5200_BOARD_BRS6L)
0259     #define CSBOOTROM_VAL 0x0202D910
0260 #endif
0261 
0262 #ifdef CSBOOTROM_VAL
0263     LWI r30, CSBOOTROM_VAL
0264     stw r30, CSBOOTROM(r31)     /* Set CSBOOTROM */
0265 #endif
0266 
0267     /* FIXME: map BOOT ROM into final location with CS0 registers */
0268     LWI r30, bsp_rom_start
0269     rlwinm  r30, r30,17,15,31
0270     stw r30, CS0STR(r31)        /* Set CS0STR */
0271 
0272     LWI r30, bsp_rom_end - 1
0273 
0274     rlwinm  r30, r30,17,15,31
0275     stw r30, CS0STP(r31)        /* Set CS0STP */
0276 
0277     lwz r30, ADREN(r31)         /* get content of ADREN */
0278     SETBITS r30, r29, ADREN_CS0_EN
0279     stw r30, ADREN(r31)         /* enable CS0 mapping */
0280     isync
0281     /* jump to same code in final BOOT ROM location */
0282     LWI r30, reloc_in_CS0
0283     LWI r29, bsp_ram_start
0284     sub r30,r30,r29
0285     LWI r29, bsp_rom_start
0286     add r30,r30,r29
0287     mtctr   r30
0288     bctr
0289 
0290 reloc_in_CS0:
0291     /* disable CSBOOT (or map it to CS0 range) */
0292     lwz r30, ADREN(r31)         /* get content of ADREN */
0293     CLRBITS r30, r29, ADREN_BOOT_EN
0294     stw r30, ADREN(r31)         /* disable BOOT mapping */
0295 
0296     /* init SDRAM */
0297     LWI r30, bsp_ram_start
0298     ori r30, r30, 0x1a          /* size code: bank is 128MByte */
0299     stw r30, SDRAMCS0(r31)      /* Set SDRAMCS0 */
0300 
0301     LWI r30, bsp_ram_size
0302     srawi   r30, r30, 1
0303     ori r30, r30, 0x1a          /* size code: bank is 128MByte */
0304     stw r30, SDRAMCS1(r31)      /* Set SDRAMCS1 */
0305 
0306     bl  SDRAM_init          /* Initialize SDRAM controller */
0307 
0308     bl  XLB_init
0309 /* copy .text section from ROM to RAM location (unique for ROM startup) */
0310     LA  r30, bsp_section_text_start /* get start address of text section in RAM */
0311 
0312 
0313     add r30, r20, r30           /* get start address of text section in ROM (add reloc offset) */
0314 
0315 
0316     LA  r29, bsp_section_text_start /* get start address of text section in RAM */
0317 
0318 
0319     LA  r28, bsp_section_text_size  /* get size of RAM image */
0320 
0321 
0322     bl  copy_image          /* copy text section from ROM to RAM location */
0323 
0324 
0325 /* copy .data section from ROM to RAM location (unique for ROM startup) */
0326     LA  r30, bsp_section_data_start /* get start address of data section in RAM */
0327 
0328 
0329     add r30, r20, r30           /* get start address of data section in ROM (add reloc offset) */
0330 
0331 
0332     LA  r29, bsp_section_data_start /* get start address of data section in RAM */
0333 
0334 
0335     LA  r28, bsp_section_data_size      /* get size of RAM image */
0336 
0337 
0338     bl  copy_image          /* copy initialized data section from ROM to RAM location */
0339 
0340 
0341     LA  r29, remap_rom          /* get compile time address of label */
0342     mtlr    r29
0343 
0344     blrl                    /* now further execution RAM */
0345 
0346 remap_rom:
0347 /* remap BOOT ROM to CS0 (common for RAM/ROM startup) */
0348     lwz r30, CSBOOTROM(r31)     /* get content of CSBOOTROM */
0349 
0350 
0351 
0352     CLRBITS r30, r29, CSCONF_CE
0353     stw r30, CSBOOTROM(r31)     /* disable BOOT CS */
0354 
0355 
0356 
0357     lwz r30, ADREN(r31)         /* get content of ADREN */
0358 
0359 
0360 
0361     mr  r29, r30            /* move content of r30 to r29 */
0362 
0363 
0364     LWI r30, ADREN_BOOT_EN      /* mask ADREN_BOOT_EN */
0365     andc    r29,r29,r30
0366 
0367 
0368     LWI r30, ADREN_CS0_EN       /* unmask ADREN_CS0_EN */
0369     or  r29,r29,r30
0370 
0371 
0372     stw r29,ADREN(r31)          /* Simultaneous enable CS0 and disable BOOT address space */
0373 
0374 
0375 
0376     lwz r30, CSBOOTROM(r31)     /* get content of CSBOOTROM */
0377 
0378 
0379 
0380     SETBITS r30, r29, CSCONF_CE
0381     stw r30, CSBOOTROM(r31)     /* disable BOOT CS */
0382 
0383 
0384 
0385 skip_ROM_start:
0386 /* configure external DPRAM CS1 */
0387     LWI r30, 0xFFFFFB10
0388     stw r30, CS1CONF(r31)
0389 
0390 /* map external DPRAM (CS1) */
0391     LWI r30, bsp_dpram_start
0392     srawi   r30, r30, 16
0393     stw r30, CS1STR(r31)
0394 
0395     LWI r30, bsp_dpram_end
0396     srawi   r30, r30, 16
0397     stw r30, CS1STP(r31)
0398 
0399     lwz r30, ADREN(r31)         /* get content of ADREN */
0400 
0401     LWI r29, ADREN_CS1_EN       /* unmask ADREN_CS1_EN */
0402     or  r30, r30,r29
0403 
0404     stw r30, ADREN(r31)         /* enable CS1 */
0405 
0406 /* clear entire on chip SRAM (unique for ROM startup) */
0407     lis r30, (MBAR+ONCHIP_SRAM_OFFSET)@h    /* get start address of onchip SRAM */
0408     ori r30, r30,(MBAR+ONCHIP_SRAM_OFFSET)@l
0409     LWI r29, ONCHIP_SRAM_SIZE       /* get size of onchip SRAM */
0410 
0411     bl      clr_mem             /* Clear onchip SRAM */
0412 
0413 #else /* defined(NEED_LOW_LEVEL_INIT) */
0414     bl  XLB_init
0415 #endif /* defined(NEED_LOW_LEVEL_INIT) */
0416 /* clear .bss section (unique for ROM startup) */
0417     LWI r30, bsp_section_bss_start  /* get start address of bss section */
0418     LWI r29, bsp_section_bss_size   /* get size of bss section */
0419 
0420 
0421     bl      clr_mem             /* Clear the bss section */
0422 
0423 #ifdef HAS_UBOOT
0424     mr  r3, r14
0425     bl  bsp_uboot_copy_board_info
0426 #endif /* HAS_UBOOT */
0427 
0428     /*
0429      * Initialize start stack (common for RAM/ROM startup).  The stacks are
0430      * statically allocated and properly aligned.
0431      */
0432     LA  r1, _ISR_Stack_area_end
0433     subi    r1, r1, PPC_DEFAULT_CACHE_LINE_SIZE
0434     li  r0, 0
0435     stw r0, 0(r1)
0436 
0437     bl  __eabi              /* Set up EABI and SYSV environment */
0438 
0439 /* enable dynamic power management(common for RAM/ROM startup) */
0440     bl  PPC_HID0_rd         /* Get the content of HID0 */
0441 
0442     SETBITS r30, r29, HID0_DPM
0443     bl  PPC_HID0_wr         /* Set DPM in HID0 */
0444 
0445 /* clear arguments and do further init. in C (common for RAM/ROM startup) */
0446 
0447     /* Clear cmdline */
0448     xor r3, r3, r3
0449 
0450     bl      SYM (boot_card)         /* Call the first C routine */
0451 
0452 twiddle:
0453     b   twiddle             /* We don't expect to return from boot_card but if we do */
0454                         /* wait here for watchdog to kick us into hard reset     */
0455 
0456 #if defined(NEED_LOW_LEVEL_INIT)
0457 SDRAM_init:
0458     mflr    r12
0459 
0460 #if defined(MPC5200_BOARD_BRS5L)
0461       /* set GPIO_WKUP7 pin low for 66MHz buffering */
0462       /* or high for 133MHz registered buffering    */
0463     LWI r30, 0x80000000
0464 
0465     lwz r29, GPIOWE(r31)
0466     or  r29,r29,r30         /* set bit 0 in r29/GPIOWE */
0467     stw r29,GPIOWE(r31)
0468 
0469     lwz r29, GPIOWOD(r31)
0470     andc    r29,r29,r30         /* clear bit 0 in r29/GPIOWOD */
0471     stw r29,GPIOWOD(r31)
0472 
0473     lwz r29, GPIOWDO(r31)
0474     andc    r29,r29,r30         /* clear bit 0 in r29/GPIOWDO */
0475     stw r29,GPIOWDO(r31)
0476 
0477     lwz r29, GPIOWDD(r31)
0478     or  r29,r29,r30         /* set bit 0 in r29/GPIOWDD */
0479     stw r29,GPIOWDD(r31)
0480 
0481     /* activate MEM_CS1 output */
0482     lwz r29, GPIOPCR(r31)
0483     or  r29,r29,r30         /* set bit 0 in r29/GPIOPCR */
0484     stw r29,GPIOPCR(r31)
0485 
0486 #endif
0487 
0488     #define SDELAY_VAL 0x00000004
0489 
0490 #if defined(MPC5200_BOARD_BRS6L)
0491     #define CFG1_VAL 0x73722930
0492 #else
0493     /*
0494      * Single Read2Read/Write delay=0xC, Single Write2Read/Prec. delay=0x4
0495      * Read CAS latency=0x2, Active2Read delay=0x2, Prec.2active delay=0x2
0496      */
0497     #define CFG1_VAL 0xC4222600
0498 #endif
0499 
0500 #if defined(MPC5200_BOARD_BRS6L)
0501     #define CFG2_VAL 0x47770000
0502 #else
0503     /* Refr.2No-Read delay=0x06, Write latency=0x0 */
0504     /* Burst2Read Prec.delay=0x8, Burst Write delay=0x8 */
0505     /* Burst Read2Write delay=0xB, Burst length=0x7, Read Tap=0x4 */
0506     #define CFG2_VAL 0xCCC70004
0507 #endif
0508 
0509 #if defined(MPC5200_BOARD_BRS5L)
0510     /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */
0511     /* Refresh counter=0xFFFF */
0512     #define CTRL_VAL 0xD1470000
0513 #elif defined(MPC5200_BOARD_BRS6L)
0514     #define CTRL_VAL 0xF15F0F00
0515 #else
0516     /* Mode Set enabled, Clock enabled, Auto refresh enabled, Mem. data drv */
0517     /* Refresh counter=0xFFFF */
0518     #define CTRL_VAL 0xD04F0000
0519 #endif
0520 
0521 #if defined(MPC5200_BOARD_BRS6L)
0522     /* Enable DLL, normal drive strength */
0523     #define EMODE_VAL 0x40010000
0524 #endif
0525 
0526 #if defined(MPC5200_BOARD_BRS6L)
0527     /* Burst length = 8, burst type sequential, CAS latency 2.5, normal operation/reset DLL */
0528     #define MODE_VAL 0x058D0000
0529 #else
0530     /* Op.Mode=0x0, Read CAS latency=0x2, Burst length=0x3, Write strobe puls */
0531     #define MODE_VAL 0x008D0000
0532 #endif
0533 
0534 #if defined(MPC5200_BOARD_BRS6L)
0535     /* Burst length = 8, burst type sequential, CAS latency 2.5, normal operation */
0536     #define SECOND_MODE_VAL (MODE_VAL & ~0x04000000)
0537 #endif
0538 
0539     /* SDRAM initialization according to application note AN3221 */
0540 
0541     /* SDRAM controller setup */
0542 
0543     LWI r3, SDELAY_VAL
0544     stw r3, SDELAY(r31)
0545 
0546     LWI r3, CFG1_VAL
0547     stw r3, CFG1(r31)
0548 
0549     LWI r3, CFG2_VAL
0550     stw r3, CFG2(r31)
0551 
0552     LWI r11, CTRL_VAL
0553     stw r11, CTRL(r31)
0554     lwz r3, CTRL(r31)
0555 
0556     /* Perform a PRECHARGE ALL command */
0557     ori r3, r11, CTRL_PRECHARGE_ALL
0558     stw r3, CTRL(r31)
0559     lwz r3, CTRL(r31)
0560 
0561     /* Wait at least tRP time */
0562     li  r3, 15
0563     bl  ndelay
0564 
0565 #if defined(EMODE_VAL)
0566     /* Write EMODE register */
0567     LWI r3, EMODE_VAL
0568     stw r3, MOD(r31)
0569 
0570     /* Wait at least tMRD time */
0571     li  r3, 10
0572     bl  ndelay
0573 #endif
0574 
0575     /* Write MODE register */
0576     LWI r3, MODE_VAL
0577     stw r3, MOD(r31)
0578 
0579     /* Wait at least tMRD time */
0580     li  r3, 10
0581     bl  ndelay
0582 
0583     /* Perform a PRECHARGE ALL command */
0584     ori r3, r11, CTRL_PRECHARGE_ALL
0585     stw r3, CTRL(r31)
0586     lwz r3, CTRL(r31)
0587 
0588     /* Wait at least tRP time */
0589     li  r3, 15
0590     bl  ndelay
0591 
0592     /* Perform an AUTO REFRESH */
0593     ori r3, r11, CTRL_REFRESH
0594     stw r3, CTRL(r31)
0595     lwz r3, CTRL(r31)
0596 
0597     /* Wait at least tRFC time */
0598     li  r3, 70
0599     bl  ndelay
0600 
0601     /* Perform an AUTO REFRESH */
0602     ori r3, r11, CTRL_REFRESH
0603     stw r3, CTRL(r31)
0604     lwz r3, CTRL(r31)
0605 
0606     /* Wait at least tRFC time */
0607     li  r3, 70
0608     bl  ndelay
0609 
0610 #if defined(SECOND_MODE_VAL)
0611     /* Write MODE register */
0612     LWI r3, SECOND_MODE_VAL
0613     stw r3, MOD(r31)
0614 #endif
0615 
0616     /* Disable MODE register access */
0617     lis r4, CTRL_MODE_EN@h
0618     andc    r3, r11, r4
0619     stw r3, CTRL(r31)
0620     lwz r3, CTRL(r31)
0621 
0622     mtlr    r12
0623     blr
0624 
0625 copy_image:
0626     mr  r27, r28
0627     srwi    r28, r28, 2
0628     mtctr   r28
0629 
0630 
0631     slwi    r28, r28, 2
0632     sub     r27, r27, r28           /* maybe some residual bytes */
0633 
0634 
0635 copy_image_word:
0636     lswi    r28, r30, 0x04
0637 
0638     stswi   r28, r29, 0x04          /* do word copy ROM -> RAM */
0639 
0640 
0641     addi    r30, r30, 0x04          /* increment source pointer */
0642     addi    r29, r29, 0x04          /* increment destination pointer */
0643 
0644     bdnz    copy_image_word         /* decrement ctr and branch if not 0 */
0645 
0646     cmpwi   r27, 0x00           /* copy image finished ? */
0647     beq copy_image_end;
0648     mtctr   r27             /* reload counter for residual bytes */
0649 copy_image_byte:
0650     lswi    r28, r30, 0x01
0651 
0652     stswi   r28, r29, 0x01          /* do byte copy ROM -> RAM */
0653 
0654 
0655     addi    r30, r30, 0x01          /* increment source pointer */
0656     addi    r29, r29, 0x01          /* increment destination pointer */
0657 
0658     bdnz    copy_image_byte         /* decrement ctr and branch if not 0 */
0659 
0660 copy_image_end:
0661     blr
0662 #endif /* defined(NEED_LOW_LEVEL_INIT) */
0663 
0664 FID_DCache:
0665     mflr    r26
0666 
0667     bl      PPC_HID0_rd
0668     TSTBITS r30, r29, HID0_DCE
0669     bne     FID_DCache_exit         /* If data cache is switched of, skip further actions */
0670 
0671     li      r29, PPC_D_CACHE        /* 16 Kb data cache on 603e */
0672     LWI r28, bsp_section_text_start /* Load base address (begin of RAM) */
0673 
0674 FID_DCache_loop_1:
0675     lwz     r27, 0(r28)         /* Load data at address */
0676 
0677     addi    r28, r28, PPC_CACHE_ALIGNMENT   /* increment cache line address */
0678     subi    r29, r29, PPC_CACHE_ALIGNMENT   /* increment loop counter */
0679     cmpwi   r29, 0x0
0680     bne     FID_DCache_loop_1       /* Loop until cache size is reached */
0681 
0682     li      r29, PPC_D_CACHE        /* 16 Kb data cache on 603e */
0683     LWI r28, bsp_section_text_start /* Reload base address (begin of RAM) */
0684     xor r27, r27, r27
0685 FID_DCache_loop_2:
0686 
0687     dcbf    r27, r28                    /* Flush and invalidate cache */
0688 
0689     addi    r28, r28, PPC_CACHE_ALIGNMENT   /* increment cache line address */
0690     subi    r29, r29, PPC_CACHE_ALIGNMENT   /* increment loop counter */
0691     cmpwi   r29, 0x0
0692     bne     FID_DCache_loop_2       /* Loop around until cache size is reached */
0693 
0694     bl      PPC_HID0_rd         /* Read HID0 */
0695     CLRBITS r30, r29, HID0_DCE
0696     bl      PPC_HID0_wr         /* Clear DCE */
0697 
0698 FID_DCache_exit:
0699     mtlr    r26
0700     blr
0701 
0702 IDUL_ICache:
0703     mflr    r26
0704 
0705     bl      PPC_HID0_rd
0706     TSTBITS r30, r29, HID0_ICE
0707     bne     IDUL_ICache_exit        /* If instruction cache is switched of, skip further actions */
0708 
0709     CLRBITS r30, r29, HID0_ICE
0710     bl      PPC_HID0_wr             /* Disable ICE bit */
0711 
0712     SETBITS r30, r29, HID0_ICFI
0713     bl  PPC_HID0_wr         /* Invalidate instruction cache */
0714 
0715     CLRBITS r30, r29, HID0_ICFI
0716     bl  PPC_HID0_wr         /* Disable cache invalidate */
0717 
0718     CLRBITS r30, r29, HID0_ILOCK
0719     bl      PPC_HID0_wr         /* Disable instruction cache lock */
0720 
0721 IDUL_ICache_exit:
0722     mtlr    r26
0723     blr
0724 
0725 
0726 TLB_init:                   /* Initialize translation lookaside buffers (TLBs) */
0727     xor r30, r30, r30
0728     xor r29, r29, r29
0729 
0730 TLB_init_loop:
0731     tlbie   r29, 0
0732     tlbsync
0733     addi    r29, r29, 0x1000
0734     addi    r30, r30, 0x01
0735     cmpli   0, 0, r30, 0x0080
0736     bne TLB_init_loop
0737     blr
0738 
0739 FPU_init:
0740     mfmsr   r30             /* get content of MSR */
0741 
0742 
0743     SETBITS r30, r29, MSR_FP
0744     mtmsr   r30             /* enable FPU and FPU exceptions */
0745     sync
0746 
0747     lfd     f0, 0(r29)
0748     fmr     f1, f0
0749     fmr     f2, f0
0750     fmr     f3, f0
0751     fmr     f4, f0
0752     fmr     f5, f0
0753     fmr     f6, f0
0754     fmr     f7, f0
0755     fmr     f8, f0
0756     fmr     f9, f0
0757     fmr     f10, f0
0758     fmr     f11, f0
0759     fmr     f12, f0
0760     fmr     f13, f0
0761     fmr     f14, f0
0762     fmr     f15, f0
0763     fmr     f16, f0
0764     fmr     f17, f0
0765     fmr     f18, f0
0766     fmr     f19, f0
0767     fmr     f20, f0
0768     fmr     f21, f0
0769     fmr     f22, f0
0770     fmr     f23, f0
0771     fmr     f24, f0
0772     fmr     f25, f0
0773     fmr     f26, f0
0774     fmr     f27, f0
0775     fmr     f28, f0
0776     fmr     f29, f0
0777     fmr     f30, f0
0778     fmr     f31, f0
0779 
0780 
0781     mtfsfi  0, 0                /* initialize bit positons in FPSCR */
0782     mtfsfi  1, 0
0783     mtfsfi  2, 0
0784     mtfsfi  3, 0
0785     mtfsfi  4, 0
0786     mtfsfi  5, 0
0787     mtfsfi  6, 0
0788     mtfsfi  7, 0
0789 
0790     blr
0791 
0792 SPRG_init:                  /* initialize registers */
0793     xor r30, r30, r30
0794 
0795     mtspr   PPC_XER, r30
0796     mtspr   PPC_CTR, r30
0797     mtspr   DSISR, r30
0798     mtspr   PPC_DAR, r30
0799     mtspr   PPC_DEC, r30
0800     mtspr   SDR1, r30
0801     mtspr   SRR0, r30
0802     mtspr   SRR1, r30
0803     mtspr   CSSR0, r30
0804     mtspr   CSSR1, r30
0805     mtspr   SPRG0, r30
0806     mtspr   SPRG1, r30
0807     mtspr   SPRG2, r30
0808     mtspr   SPRG3, r30
0809     mtspr   SPRG4, r30
0810     mtspr   SPRG5, r30
0811     mtspr   SPRG6, r30
0812     mtspr   SPRG7, r30
0813     mtspr   PPC_EAR, r30
0814     mtspr   TBWU, r30
0815     mtspr   TBWL, r30
0816     mtspr   IBAT0U, r30
0817     mtspr   IBAT0L, r30
0818     mtspr   IBAT1U, r30
0819     mtspr   IBAT1L, r30
0820     mtspr   IBAT2U, r30
0821     mtspr   IBAT2L, r30
0822     mtspr   IBAT3U, r30
0823     mtspr   IBAT3L, r30
0824     mtspr   IBAT4U, r30
0825     mtspr   IBAT4L, r30
0826     mtspr   IBAT5U, r30
0827     mtspr   IBAT5L, r30
0828     mtspr   IBAT6U, r30
0829     mtspr   IBAT6L, r30
0830     mtspr   IBAT7U, r30
0831     mtspr   IBAT7L, r30
0832     mtspr   DBAT0U, r30
0833     mtspr   DBAT0L, r30
0834     mtspr   DBAT1U, r30
0835     mtspr   DBAT1L, r30
0836     mtspr   DBAT2U, r30
0837     mtspr   DBAT2L, r30
0838     mtspr   DBAT3U, r30
0839     mtspr   DBAT3L, r30
0840     mtspr   DBAT4U, r30
0841     mtspr   DBAT4L, r30
0842     mtspr   DBAT5U, r30
0843     mtspr   DBAT5L, r30
0844     mtspr   DBAT6U, r30
0845     mtspr   DBAT6L, r30
0846     mtspr   DBAT7U, r30
0847     mtspr   DBAT7L, r30
0848     mtspr   DMISS, r30
0849     mtspr   DCMP, r30
0850     mtspr   HASH1, r30
0851     mtspr   HASH2, r30
0852     mtspr   IMISS, r30
0853     mtspr   ICMP, r30
0854     mtspr   PPC_RPA, r30
0855     mtsr    PPC_SR0, r30
0856     mtsr    PPC_SR1, r30
0857     mtsr    PPC_SR2, r30
0858     mtsr    PPC_SR3, r30
0859     mtsr    PPC_SR4, r30
0860     mtsr    PPC_SR5, r30
0861     mtsr    PPC_SR6, r30
0862     mtsr    PPC_SR7, r30
0863     mtsr    PPC_SR8, r30
0864     mtsr    PPC_SR9, r30
0865     mtsr    PPC_SR10, r30
0866     mtsr    PPC_SR12, r30
0867     mtsr    PPC_SR13, r30
0868     mtsr    PPC_SR14, r30
0869     mtsr    PPC_SR15, r30
0870 
0871 
0872 
0873 
0874 
0875     blr
0876 
0877 PPC_HID0_rd:                    /* get HID0 content to r30 */
0878 
0879 
0880     mfspr   r30, HID0
0881 
0882     blr
0883 
0884 
0885 PPC_HID0_wr:                    /* put r30 content to HID0 */
0886 
0887 
0888     mtspr   HID0, r30
0889 
0890     blr
0891 
0892 clr_mem:
0893     mr  r28, r29
0894     srwi    r29, r29, 2
0895     mtctr   r29             /* set ctr reg */
0896 
0897 
0898     slwi    r29, r29, 2
0899     sub     r28, r28, r29           /* maybe some residual bytes */
0900     xor     r29, r29, r29
0901 
0902 
0903 clr_mem_word:
0904     stswi   r29, r30, 0x04          /* store r29 (word) to r30 memory location */
0905     addi    r30, r30, 0x04          /* increment r30 */
0906 
0907     bdnz    clr_mem_word            /* dec counter and loop */
0908 
0909 
0910     cmpwi   r28, 0x00           /* clear mem. finished ? */
0911     beq clr_mem_end;
0912     mtctr   r28             /* reload counter for residual bytes */
0913 clr_mem_byte:
0914     stswi   r29, r30, 0x01          /* store r29 (byte) to r30 memory location  */
0915     addi    r30, r30, 0x01          /* update r30 */
0916 
0917     bdnz    clr_mem_byte            /* dec counter and loop */
0918 
0919 clr_mem_end:
0920     blr                 /* return */
0921 
0922 XLB_init:
0923 /* init arbiter and stuff... */
0924     LWI r30, 0x8000a06e
0925     stw r30, ARBCFG(r31)        /* Set ARBCFG */
0926 
0927     LWI r30, 0x000000ff
0928     stw r30, ARBMPREN(r31)      /* Set ARBMPREN */
0929 
0930     LWI r30, 0x00001234
0931     stw r30, ARBMPRIO(r31)      /* Set ARBPRIO */
0932 
0933     LWI r30, 0x0000001e
0934     stw r30, ARBSNOOP(r31)      /* Set ARBSNOOP */
0935 
0936     LWI r30, 4096
0937     stw r30, ARBADRTO(r31)      /* Set ARBADRTO */
0938     stw r30, ARBDATTO(r31)      /* Set ARBDATTO */
0939 
0940     blr
0941 
0942 ndelay:
0943     /*
0944      * The maximum core frequency is 396MHz.
0945      * We have (396MHz * 1024) / 10**9 == 405.
0946      */
0947     mulli   r3, r3, 405
0948     srwi.   r3, r3, 10
0949 
0950     beqlr
0951 
0952     mtctr   r3
0953 
0954 ndelay_loop:
0955     bdnz    ndelay_loop
0956 
0957     blr