123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376 |
- /*
- * Copyright (C) 2012, Freescale Semiconductor, Inc. All Rights Reserved
- * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
- * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
- * Freescale Semiconductor, Inc.
- */
- /*!
- * @file plat_startup.inc
- * @brief This file contains start-up DCD.
- *
- * @ingroup diag_init
- */
- /* *INDENT-OFF* */
- #ifndef _PLAT_STARTUP_H_
- #define _PLAT_STARTUP_H_
- #include "soc_memory_map.h"
- #define IMAGE_ENTRY_ADDR 0x80000000
- #define IMAGE_SIZE 4*1024*1024
- #define L2CC_REG1_CTRL 0x00A02100
- #define L2CC_INV_REG 0x00A0277C
- #define L2CC_TAG_RAM_CTRL 0x00A02108
- #define L2CC_DAT_RAM_CTRL 0x00A0210C
- #define L2CC_PREFETCH_CTRL 0x00A02F60
- #define ROM_API_TABLE_BASE_ADDR (0x00000180)
- #define ROM_API_HWCNFG_SETUP_OFFSET (0x08)
- #define PLATFORM_INIT plat_dcd_startup
- #define ASM_REG32_WR(i, addr, val) \
- ldr r0, =addr; \
- ldr r1, =val; \
- str r1, [r0];
- // image starts at 0x00907000
- //flash header & DCD @ 0x400
- .macro plat_dcd_startup
- b startup
- .org 0x400
- /* First IVT to copy the plugin that initializes the system into OCRAM */
- ivt_header: .long 0x402000D1 //Tag=0xD1, Len=0x0020, Ver=0x40
- app_code_jump_v: .long 0x00907458 // Plugin entry point, address after the second IVT table
- reserv1: .long 0x0
- dcd_ptr: .long 0x0
- boot_data_ptr: .long 0x00907420
- self_ptr: .long 0x00907400
- app_code_csf: .long 0x0 // reserve 4K for csf
- reserv2: .long 0x0
- boot_data: .long 0x00907000
- image_len: .long 16*1024
- plugin: .long 0x1 // Enable plugin flag
- /* Second IVT to give entry point into the bootloader copied to DDR */
- ivt2_header: .long 0x402000D1 //Tag=0xD1, Len=0x0020, Ver=0x40
- app2_code_jump_v: .long startup // Entry point for the bootloader
- reserv3: .long 0x0
- dcd2_ptr: .long 0x0
- boot_data2_ptr: .long boot_data2
- self_ptr2: .long ivt2_header
- app_code_csf2: .long 0x0 // reserve 4K for csf
- reserv4: .long 0x0
- boot_data2: .long IMAGE_ENTRY_ADDR
- image_len2: .long IMAGE_SIZE
- plugin2: .long 0x0
- // Here starts the plugin code
- plugin_start:
- // Save the return address and the function arguments
- push {r0-r4, lr}
- #if defined(EVB) || defined(SABRE_LITE)
- ASM_REG32_WR(0, 0x020bc000, 0x30)
- ASM_REG32_WR(0, 0x020c4068, 0xffffffff)
- ASM_REG32_WR(0, 0x020c406c, 0xffffffff)
- ASM_REG32_WR(0, 0x020c4070, 0xffffffff)
- ASM_REG32_WR(0, 0x020c4074, 0xffffffff)
- ASM_REG32_WR(0, 0x020c4078, 0xffffffff)
- ASM_REG32_WR(0, 0x020c407c, 0xffffffff)
- ASM_REG32_WR(0, 0x020c4080, 0xffffffff)
- ASM_REG32_WR(0, 0x020c4084, 0xffffffff)
- ASM_REG32_WR(0, 0x020E04B4, 0x000C0000)
- ASM_REG32_WR(0, 0x020E04AC, 0x00000000)
- ASM_REG32_WR(0, 0x020E027C, 0x00000030)
- ASM_REG32_WR(0, 0x020E0250, 0x00000030)
- ASM_REG32_WR(0, 0x020E024C, 0x00000030)
- ASM_REG32_WR(0, 0x020E0490, 0x00000030)
- ASM_REG32_WR(0, 0x020E0288, 0x00000030)
- ASM_REG32_WR(0, 0x020E0270, 0x00000000)
- ASM_REG32_WR(0, 0x020E0260, 0x00000030)
- ASM_REG32_WR(0, 0x020E0264, 0x00000030)
- ASM_REG32_WR(0, 0x020E04A0, 0x00000030)
- ASM_REG32_WR(0, 0x020E0494, 0x00020000)
- ASM_REG32_WR(0, 0x020E0280, 0x00000030)
- ASM_REG32_WR(0, 0x020E0284, 0x00000030)
- ASM_REG32_WR(0, 0x020E04B0, 0x00020000)
- ASM_REG32_WR(0, 0x020E0498, 0x00000030)
- ASM_REG32_WR(0, 0x020E04A4, 0x00000030)
- ASM_REG32_WR(0, 0x020E0244, 0x00000030)
- ASM_REG32_WR(0, 0x020E0248, 0x00000030)
- ASM_REG32_WR(0, 0x021B001C, 0x00008000)
- ASM_REG32_WR(0, 0x021B0800, 0xA1390003)
- ASM_REG32_WR(0, 0x021B080C, 0x001b001E)
- ASM_REG32_WR(0, 0x021B083C, 0x42400240)
- ASM_REG32_WR(0, 0x021B0848, 0x00003A3E)
- ASM_REG32_WR(0, 0x021B0850, 0x00003230)
- ASM_REG32_WR(0, 0x021B081C, 0x33333333)
- ASM_REG32_WR(0, 0x021B0820, 0x33333333)
- ASM_REG32_WR(0, 0x021B082C, 0xf3333333)
- ASM_REG32_WR(0, 0x021B0830, 0xf3333333)
- ASM_REG32_WR(0, 0x021B08C0, 0x00922012)
- ASM_REG32_WR(0, 0x021B08b8, 0x00000800)
- ASM_REG32_WR(0, 0x021B0004, 0x0002002D)
- ASM_REG32_WR(0, 0x021B0008, 0x1B333000)
- ASM_REG32_WR(0, 0x021B000C, 0x676B54B3)
- ASM_REG32_WR(0, 0x021B0010, 0xB68E0A83)
- ASM_REG32_WR(0, 0x021B0014, 0x01FF00DB)
- ASM_REG32_WR(0, 0x021B0018, 0x00211740)
- ASM_REG32_WR(0, 0x021B001C, 0x00008000)
- ASM_REG32_WR(0, 0x021B002C, 0x000026D2)
- ASM_REG32_WR(0, 0x021B0030, 0x006C1023)
- ASM_REG32_WR(0, 0x021B0040, 0x0000005F)
- ASM_REG32_WR(0, 0x021B0000, 0x85180000)
- ASM_REG32_WR(0, 0x021B001C, 0x02008032)
- ASM_REG32_WR(0, 0x021B001C, 0x00008033)
- ASM_REG32_WR(0, 0x021B001C, 0x00048031)
- ASM_REG32_WR(0, 0x021B001C, 0x15208030)
- ASM_REG32_WR(0, 0x021B001C, 0x04008040)
- ASM_REG32_WR(0, 0x021B0020, 0x00000800)
- ASM_REG32_WR(0, 0x021B0818, 0x00000227)
- ASM_REG32_WR(0, 0x021B0004, 0x0002552D)
- ASM_REG32_WR(0, 0x021B0404, 0x00011006)
- ASM_REG32_WR(0, 0x021B001C, 0x00000000)
- #else
- #error "Please add the DDR initialization code for this board, unless you can make sure the existing code can be shared."
- #endif
- read_obds:
- /********************
- The following is to fill in those arguments for this ROM function
- pu_irom_hwcnfg_setup(void **start, size_t *bytes, const void *boot_data)
- This function is used to copy data from the storage media into DDR.
- start - Initial (possibly partial) image load address on entry. Final image load address on exit.
- bytes - Initial (possibly partial) image size on entry. Final image size on exit.
- boot_data - Initial @ref ivt Boot Data load address.
- */
- adr r0, DDR_DEST_ADDR
- adr r1, COPY_SIZE
- adr r2, BOOT_DATA
- /*
- * check the _pu_irom_api_table for the address
- */
- before_calling_rom___pu_irom_hwcnfg_setup:
- //mov r4, #0x2000
- //add r4, r4, #0xed
- //blx r4 // This address might change in future ROM versions.
- ldr r3, =ROM_API_TABLE_BASE_ADDR /* Address of rom_api_table is 0xc0 */
- ldr r4, [r3, #ROM_API_HWCNFG_SETUP_OFFSET] /* hwcnfg setup function address is 3rd entry in the api table address 0xc8 */
- blx r4 /* call into ROM function */
- after_calling_rom___pu_irom_hwcnfg_setup:
- /* SDRAM has been setup, binary image has been copied to SDRAM */
- b startup // Jump to our code directly
- DDR_DEST_ADDR: .word IMAGE_ENTRY_ADDR
- COPY_SIZE: .word IMAGE_SIZE
- BOOT_DATA: .word IMAGE_ENTRY_ADDR
- .word IMAGE_SIZE //real data to be copied by the pu_irom_hwcnfg_setup()
- .word 0
- .endm //plat_dcd_startup
- // #define PLATFORM_ASM_STARTUP platform_asm_startup
- .macro platform_asm_startup
- config_L2_cache:
- disable_L2_cache
- init_aips_start:
- init_aips
- init_reloc_start:
- /* Check if need to copy image to Redboot ROM space */
- ldr r0, =0xFFFFF000
- and r0, r0, pc
- ldr r1, =IMAGE_ENTRY_ADDR
- cmp r0, r1
- beq skip_SDRAM_copy
- add r2, r0, #IMAGE_SIZE
- 1: ldmia r0!, {r3-r10}
- stmia r1!, {r3-r10}
- cmp r0, r2
- ble 1b
- /* Jump to SDRAM */
- ldr r1, =0xFFFF
- and r0, pc, r1 /* offset of pc */
- ldr r1, =(IMAGE_ENTRY_ADDR + 0x8)
- add pc, r0, r1
- nop
- nop
- nop
- nop
- skip_SDRAM_copy:
- .endm //platform_asm_startup
- /* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
- .macro init_aips
- /*
- * Set all MPROTx to be non-bufferable, trusted for R/W,
- * not forced to user-mode.
- */
- ldr r0, =AIPS_TZ1_BASE_ADDR
- ldr r1, =0x77777777
- str r1, [r0, #0x00]
- str r1, [r0, #0x04]
- ldr r0, =AIPS_TZ2_BASE_ADDR
- str r1, [r0, #0x00]
- str r1, [r0, #0x04]
- .endm /* init_aips */
- .macro clean_L1_DCache
- mov r0, #0
- mcr p15, 2, r0, c0, c0, 0 // select DCache
- mrc p15, 1, r0, c0, c0, 0 // read CCSIDR
- mov r0, r0, ASR #13
- ldr r3, =0x3FFF
- and r0, r0, r3
- cmp r0, #0x7F
- moveq r6, #0x1000 // 4KB * 4way = 16KB
- beq clean_and_invalidate_L1_dcache
- cmp r0, #0xFF
- moveq r6, #0x2000 // 32KB
- beq clean_and_invalidate_L1_dcache
- movne r6, #0x4000 // 64KB
- clean_and_invalidate_L1_dcache:
- mov r2, #0x00000000
- mov r3, #0x40000000
- mov r4, #0x80000000
- mov r5, #0xC0000000
- clean_and_invalidate_L1_dcache_byset:
- mcr p15, 0, r2, c7, c14, 2 //clean and invalidate dcache on way 0
- mcr p15, 0, r3, c7, c14, 2 //clean and invalidate dcache on way 1
- mcr p15, 0, r4, c7, c14, 2 //clean and invalidate dcache on way 2
- mcr p15, 0, r5, c7, c14, 2 //clean and invalidate dcache on way 3
- add r2, r2, #0x20
- add r3, r3, #0x20
- add r4, r4, #0x20
- add r5, r5, #0x20
-
- cmp r2, r6
- bne clean_and_invalidate_L1_dcache_byset
-
- .endm
- .macro enable_L1_cache
- mov r0, #0
- mcr p15, 0, r0, c7, c5, 6 // invalidate BTAC
- mcr p15, 0, r0, c7, c5, 0 // invalidate icache
-
- mov r0, #0
- mcr p15, 2, r0, c0, c0, 0 // select DCache
- mrc p15, 1, r0, c0, c0, 0 // read CCSIDR
- mov r0, r0, ASR #13
- ldr r3, =0x3FFF
- and r0, r0, r3
- cmp r0, #0x7F
- moveq r6, #0x1000 // 4KB * 4way = 16KB
- beq invalidate_dcache
- cmp r0, #0xFF
- moveq r6, #0x2000 // 32KB
- beq invalidate_dcache
- movne r6, #0x4000 // 64KB
- invalidate_dcache:
- mov r2, #0x00000000
- mov r3, #0x40000000
- mov r4, #0x80000000
- mov r5, #0xC0000000
- invalidate_dcache_byset:
- mcr p15, 0, r2, c7, c6, 2 //invalidate dcache on way 0
- mcr p15, 0, r3, c7, c6, 2 //invalidate dcache on way 1
- mcr p15, 0, r4, c7, c6, 2 //invalidate dcache on way 2
- mcr p15, 0, r5, c7, c6, 2 //invalidate dcache on way 3
- add r2, r2, #0x20
- add r3, r3, #0x20
- add r4, r4, #0x20
- add r5, r5, #0x20
-
- cmp r2, r6
- bne invalidate_dcache_byset
-
- ldr r0, =0x00930000 //where to store the TLB page table
- mcr p15, 0, r0, c2, c0, 0
- ldr r0, =0x55555555
- mcr p15, 0, r0, c3, c0, 0
-
- mrc p15, 0, r0, c1, c0, 0 // read CP15 register 1 into r0
- orr r0, r0, #(0x1<<12) // enable I Cache
- orr r0, r0, #(0x1<<11) // turn on BP
- orr r0, r0, #(0x1<<2) // enable D Cache
- /*Attention: If you want to enable MMU, must set up the TLB tables first!!*/
- bic r0, r0, #(0x1<<0) // disable MMU
- mcr p15, 0, r0, c1, c0, 0 // write CP15 register 1
- .endm
- .macro disable_L1_cache
- mrc p15, 0, r0, c1, c0, 0
- bic r0, r0, #(0x1<<12)
- bic r0, r0, #(0x1<<11)
- bic r0, r0, #(0x1<<2)
- bic r0, r0, #(0x1<<0)
- mcr p15, 0, r0, c1, c0, 0
- .endm
- .macro disable_L1_DCache
- mrc p15, 0, r0, c1, c0, 0
- ands r0, r0, #(0x1<<11) //check if L1 DCache has been disabled
- beq disable_L1_DCache_done
- bic r0, r0, #(0x1<<11)
- bic r0, r0, #(0x1<<0) //disable MMU
- mcr p15, 0, r0, c1, c0, 0
- clean_L1_DCache
- disable_L1_DCache_done:
- .endm
- .macro enable_L2_cache
- /* set latency: 4x cycles read, 2x cycles write, (3x cycles setup)*/
- ldr r1,= L2CC_TAG_RAM_CTRL
- ldr r0,=0x0132
- str r0,[r1]
- ldr r1, =L2CC_DAT_RAM_CTRL
- ldr r0,=0x0132
- str r0,[r1]
-
- /* invalidate L2Cache by way */
- ldr r1, =L2CC_INV_REG
- ldr r0, =0xffff
- str r0,[r1]
- l2cc_inv_done:
- ldr r2,[r1]
- mov r0,#0x0
- cmp r2,r0
- bne l2cc_inv_done
-
- /* turn on l2 cache */
- ldr r1, =L2CC_REG1_CTRL
- mov r0,#1
- str r0,[r1]
- .endm
- .macro disable_L2_cache
- ldr r1, =L2CC_REG1_CTRL
- mov r0,#0
- str r0,[r1]
- .endm
- #endif //_PLAT_STARTUP_H_
|