From b3e2fb9ddda922c02f34cf61c171f967052956a1 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 29 Sep 2023 13:35:21 -0700 Subject: [PATCH] NXP T1024 wolfBoot support: * Added DDR4 w/ECC. * Added L2 and L2 CPC SRAM support * Added platform SRAM 160KB support * Added support for core timers (timebase) and platform clock. * Added IFC driver with erase/write * Added stage 1 loader to relocate wolfBoot to DDR * Added CPLD, QUICC, FMAN and MP drivers * Added eSPI driver for TPM. * Added hal_early_init instead of calling ddr_init directly. * Fixes for device tree (DTB) loading with update_ram and PPC boot. * Fixes for relocating CCSRBAR to upper. * Fixes for interrupt offsets. --- .github/workflows/test-configs.yml | 6 + Makefile | 3 + arch.mk | 25 +- config/examples/nxp-t1024.config | 67 ++ config/examples/nxp-t2080.config | 10 +- docs/Targets.md | 87 ++ hal/nxp_p1021.c | 46 +- hal/nxp_ppc.c | 23 + hal/nxp_ppc.h | 241 ++++- hal/nxp_t1024.c | 1614 ++++++++++++++++++++++++++++ hal/nxp_t1024.ld | 90 ++ hal/nxp_t1024_stage1.ld | 109 ++ hal/nxp_t2080.c | 81 +- hal/nxp_t2080.ld | 1 + hal/spi/spi_drv_stm32.h | 28 +- hal/zynq.c | 2 +- include/image.h | 2 +- include/spi_drv.h | 9 +- options.mk | 4 + src/boot_ppc.c | 38 +- src/boot_ppc_mp.S | 14 +- src/boot_ppc_start.S | 258 +++-- src/elf.c | 5 +- src/image.c | 16 +- src/update_ram.c | 56 +- stage1/Makefile | 6 +- stage1/loader_stage1.c | 17 +- test-app/app_nxp_t1024.c | 51 + 28 files changed, 2581 insertions(+), 328 deletions(-) create mode 100644 config/examples/nxp-t1024.config create mode 100644 hal/nxp_ppc.c create mode 100644 hal/nxp_t1024.c create mode 100644 hal/nxp_t1024.ld create mode 100644 hal/nxp_t1024_stage1.ld create mode 100644 test-app/app_nxp_t1024.c diff --git a/.github/workflows/test-configs.yml b/.github/workflows/test-configs.yml index 18c7aa29..ec19c92b 100644 --- a/.github/workflows/test-configs.yml +++ b/.github/workflows/test-configs.yml @@ -76,6 +76,12 @@ jobs: arch: ppc config-file: ./config/examples/nxp-p1021.config + nxp_t1024_test: + uses: ./.github/workflows/test-build.yml + with: + arch: ppc + config-file: ./config/examples/nxp-t1024.config + nxp_t2080_68ppc2_test: uses: ./.github/workflows/test-build.yml with: diff --git a/Makefile b/Makefile index f7ad8a09..e773fd06 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,9 @@ endif ifeq ($(TARGET),nxp_p1021) MAIN_TARGET:=factory_wstage1.bin endif +ifeq ($(TARGET),nxp_t1024) + MAIN_TARGET:=factory_wstage1.bin +endif ASFLAGS:=$(CFLAGS) BOOTLOADER_PARTITION_SIZE?=$$(( $(WOLFBOOT_PARTITION_BOOT_ADDRESS) - $(ARCH_FLASH_OFFSET))) diff --git a/arch.mk b/arch.mk index d64d314f..16f2c346 100644 --- a/arch.mk +++ b/arch.mk @@ -412,9 +412,30 @@ ifeq ($(ARCH),ARM_BE) endif endif +ifeq ($(TARGET),nxp_t1024) + # Power PC big endian + ARCH_FLAGS=-mhard-float -mcpu=e5500 + CFLAGS+=$(ARCH_FLAGS) -DBIG_ENDIAN_ORDER + CFLAGS+=-DMMU -DWOLFBOOT_DUALBOOT + CFLAGS+=-pipe # use pipes instead of temp files + CFLAGS+=-feliminate-unused-debug-types + LDFLAGS+=$(ARCH_FLAGS) + LDFLAGS+=-Wl,--hash-style=both # generate both sysv and gnu symbol hash table + LDFLAGS+=-Wl,--as-needed # remove weak functions not used + OBJS+=src/boot_ppc_mp.o # support for spin table + UPDATE_OBJS:=src/update_ram.o + ifeq ($(SPMATH),1) + MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o + else + # Use the SP math all assembly accelerations + CFLAGS+=-DWOLFSSL_SP_PPC + endif + SPI_TARGET=nxp +endif + ifeq ($(TARGET),nxp_t2080) # Power PC big endian - ARCH_FLAGS=-m32 -mhard-float -mcpu=e6500 + ARCH_FLAGS=-mhard-float -mcpu=e6500 CFLAGS+=$(ARCH_FLAGS) -DBIG_ENDIAN_ORDER CFLAGS+=-DMMU -DWOLFBOOT_DUALBOOT CFLAGS+=-pipe # use pipes instead of temp files @@ -440,8 +461,8 @@ ifeq ($(TARGET),nxp_p1021) CFLAGS+=-pipe # use pipes instead of temp files LDFLAGS+=$(ARCH_FLAGS) LDFLAGS+=-Wl,--as-needed # remove weak functions not used + OBJS+=src/boot_ppc_mp.o # support for spin table UPDATE_OBJS:=src/update_ram.o - UPDATE_OBJS+=src/boot_ppc_mp.o # Use PPC stdlib for memcpy, etc. #CFLAGS+=-DWOLFBOOT_USE_STDLIBC diff --git a/config/examples/nxp-t1024.config b/config/examples/nxp-t1024.config new file mode 100644 index 00000000..211ead7a --- /dev/null +++ b/config/examples/nxp-t1024.config @@ -0,0 +1,67 @@ +# NXP QorIQ T1024 (2 core) + +ARCH=PPC +TARGET=nxp_t1024 +SIGN?=ECC384 +HASH?=SHA384 +IMAGE_HEADER_SIZE?=512 +DEBUG?=0 +DEBUG_UART?=1 +VTOR?=1 +CORTEX_M0?=0 +NO_ASM?=0 +EXT_FLASH?=0 +SPI_FLASH?=0 +NO_XIP?=0 +UART_FLASH?=0 +ALLOW_DOWNGRADE?=0 +NVM_FLASH_WRITEONCE?=0 +WOLFBOOT_VERSION?=0 +NO_MPU?=0 +SPMATH?=0 +SPMATHALL?=1 +RAM_CODE?=0 +DUALBANK_SWAP?=0 +WOLFTPM?=0 +ELF?=1 +DEBUG_ELF=0 + +# NOR Base Address +ARCH_FLASH_OFFSET?=0xEC000000 + +# Flash Sector Size +WOLFBOOT_SECTOR_SIZE=0x10000 + +# wolfBoot start address +WOLFBOOT_ORIGIN=0xEFF40000 +# wolfBoot partition size (custom) +BOOTLOADER_PARTITION_SIZE=0xC0000 + +# Application Partition Size +WOLFBOOT_PARTITION_SIZE?=0x01E00000 +# Location in Flash for Application Partition +WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xEE000000 +# Load Partition to RAM Address +WOLFBOOT_LOAD_ADDRESS?=0x70000000 + +# Location in Flash for Update Partition +WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0xEC200000 + +# Location of temporary sector used during updates +WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xEC0F0000 + +# Stage 1 loader settings (16KB) +WOLFBOOT_STAGE1_SIZE=0x4000 +# Location in Flash for stage 1 loader (XIP from boot ROM) +WOLFBOOT_STAGE1_FLASH_ADDR=0xEFFFC000 +# Address in RAM to load wolfBoot (end of DDR at 2GB-1MB) +WOLFBOOT_STAGE1_LOAD_ADDR=0x7FF00000 + +# DTS (Device Tree) +WOLFBOOT_DTS_BOOT_ADDRESS?=0xEC020000 +WOLFBOOT_DTS_UPDATE_ADDRESS?=0xEC040000 +# DTS Load to RAM Address +WOLFBOOT_LOAD_DTS_ADDRESS?=0x7F100000 + +# Load to RAM before hash and verify +CFLAGS_EXTRA+=-DWOLFBOOT_USE_RAMBOOT diff --git a/config/examples/nxp-t2080.config b/config/examples/nxp-t2080.config index 10d04d34..fb12a390 100644 --- a/config/examples/nxp-t2080.config +++ b/config/examples/nxp-t2080.config @@ -30,7 +30,13 @@ ARCH_FLASH_OFFSET?=0xEFFF0000 BOOTLOADER_PARTITION_SIZE=0x10000 WOLFBOOT_PARTITION_BOOT_ADDRESS?=0xEFFD0000 +WOLFBOOT_LOAD_ADDRESS?=0x19000 WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0xEFFB0000 + +# Location of temporary sector used during updates WOLFBOOT_PARTITION_SWAP_ADDRESS?=0xEFFA0000 -WOLFBOOT_LOAD_ADDRESS?=0x200000 -WOLFBOOT_LOAD_DTS_ADDRESS?=0x40000 + +# DTS (Device Tree) +WOLFBOOT_DTS_BOOT_ADDRESS?=0xE8040000 +WOLFBOOT_DTS_UPDATE_ADDRESS?=0xE8050000 +WOLFBOOT_LOAD_DTS_ADDRESS?=0x200000 diff --git a/docs/Targets.md b/docs/Targets.md index 82aabb4b..2fd3519a 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -11,6 +11,7 @@ This README describes configuration of supported targets. * [NXP iMX-RT](#nxp-imx-rt) * [NXP Kinetis](#nxp-kinetis) * [NXP P1021 PPC](#nxp-qoriq-p1021-ppc) +* [NXP T1024 PPC](#nxp-qoriq-t1024-ppc) * [NXP T2080 PPC](#nxp-qoriq-t2080-ppc) * [Qemu x86-64 UEFI](#qemu-x86-64-uefi) * [SiFive HiFive1 RISC-V](#sifive-hifive1-risc-v) @@ -1245,6 +1246,92 @@ make factory_wstage1.bin ``` +## NXP QorIQ T1024 PPC + +The NXP QorIQ T1024 is a two core 64-bit PPC e5500 based processor at 1400MHz. Each core has 256KB L2 cache. + +Board: T1024RDB +Board rev: 0x3031 +CPLD ver: 0x42 + +T1024E, Version: 1.0, (0x8548_0010) +e5500, Version: 2.1, (0x8024_1021) + +Reset Configuration Word (RCW): +00000000: 0810000e 00000000 00000000 00000000 +00000010: 2d800003 40408812 fc027000 21000000 +00000020: 00000000 00000000 60000000 00036800 +00000030: 00000100 484a5808 00000000 00000006 + +Flash is NOR on IFC CS0 (0x0_EC00_0000) 64MB (default). + +Default NOR Flash Memory Layout (64MB): + +| Description | Address | Size | +| ----------------- | ---------- | ------------------- | +| RCW | 0xEC000000 | 0x00020000 (128 KB) | +| Primary (FDT) | 0xEC020000 | 0x00020000 (128 KB) | +| Update (FDT) | 0xEC040000 | 0x00020000 (128 KB) | +| Free | 0xEC060000 | 0x00090000 (576 KB) | +| Swap Sector | 0xEC0F0000 | 0x00010000 ( 64 KB) | +| Free | 0xEC100000 | 0x00100000 ( 1 MB) | +| Update (OS) | 0xEC200000 | 0x01E00000 ( 30 MB) | +| Application (OS) | 0xEE000000 | 0x01E00000 ( 30 MB) | +| QUICC | 0xEFE00000 | 0x00100000 ( 1 MB) | +| DPAA (FMAN) | 0xEFF00000 | 0x00020000 (128 KB) | +| wolfBoot | 0xEFF40000 | 0x000BC000 (752 KB) | +| wolfBoot Stage 1 | 0xEFFFC000 | 0x00004000 ( 16 KB) | + +QE: uploading microcode 'Microcode for T1024 r1.0' version 0.0.1 + +DDR4 2GB + +### Building wolfBoot for NXP T1024 PPC + +By default wolfBoot will use `powerpc-linux-gnu-` cross-compiler prefix. These tools can be installed with the Debian package `gcc-powerpc-linux-gnu` (`sudo apt install gcc-powerpc-linux-gnu`). + +The `make` creates a `factory_stage1.bin` image that can be programmed at `0xEC000000` + +``` +cp ./config/examples/nxp-t1024.config .config +make clean +make keytools +make +``` + +Or each `make` component can be manually built using: + +``` +make stage1 +make wolfboot.elf +make test-app/image_v1_signed.bin +``` + +If getting errors with keystore then you can reset things using `make distclean`. + +### Signing Custom application + +``` +./tools/keytools/sign --ecc384 --sha384 custom.elf wolfboot_signing_private_key.der 1 +``` + +### Assembly of custom firmware image + +``` +./tools/bin-assemble/bin-assemble factory_custom.bin \ + 0xEC000000 RCW_CTS.bin \ + 0xEC020000 custom.dtb \ + 0xEE000000 custom_v1_signed.bin \ + 0xEFE00000 iram_Type_A_T1024_r1.0.bin \ + 0xEFF00000 fsl_fman_ucode_t1024_r1.0_108_4_5.bin \ + 0xEFF40000 wolfboot.bin \ + 0xEFFFC000 stage1/loader_stage1.bin +``` + +Flash factory_custom.bin to NOR base 0xEC00_0000 + + + ## NXP QorIQ T2080 PPC The NXP QorIQ T2080 is a PPC e6500 based processor (four cores). Support has been tested with the NAII 68PPC2. diff --git a/hal/nxp_p1021.c b/hal/nxp_p1021.c index 2ab9c119..d9709628 100644 --- a/hal/nxp_p1021.c +++ b/hal/nxp_p1021.c @@ -419,7 +419,6 @@ enum elbc_amask_sizes { #define DDR_SDRAM_MODE ((volatile uint32_t*)(DDR_BASE + 0x118)) /* DDR SDRAM mode configuration */ #define DDR_SDRAM_MODE_2 ((volatile uint32_t*)(DDR_BASE + 0x11C)) /* DDR SDRAM mode configuration 2 */ #define DDR_SDRAM_MD_CNTL ((volatile uint32_t*)(DDR_BASE + 0x120)) /* DDR SDRAM mode control */ -#define DDR_SDRAM_INTERVAL ((volatile uint32_t*)(DDR_BASE + 0x124)) /* DDR SDRAM interval configuration */ #define DDR_SDRAM_CLK_CNTL ((volatile uint32_t*)(DDR_BASE + 0x130)) /* DDR SDRAM clock control */ #define DDR_SDRAM_CFG_MEM_EN 0x80000000 /* SDRAM interface logic is enabled */ @@ -482,7 +481,6 @@ enum elbc_amask_sizes { #define ESPI_CSMODE_CSAFT(x) (((x) & 0xF) << 8) /* CS assertion time in bits after frame end */ #define ESPI_CSMODE_CSCG(x) (((x) & 0xF) << 3) /* Clock gaps between transmitted frames according to this size */ - #ifdef ENABLE_ELBC static volatile uint8_t* flash_buf; @@ -492,33 +490,31 @@ static uint32_t flash_idx; int ext_flash_read(uintptr_t address, uint8_t *data, int len); #endif +/* generic share NXP QorIQ driver code */ +#include "nxp_ppc.c" + /* local functions */ +#ifdef ENABLE_BUS_CLK_CALC static uint32_t hal_get_bus_clk(void) { + /* compute bus clock (system input 66MHz * ratio) */ uint32_t bus_clk; -#ifdef ENABLE_BUS_CLK_CALC - /* compute bus clock (system input 66MHz * ratio */ uint32_t plat_ratio = get32(GUTS_PORPLLSR); /* mask and shift by 1 to get platform ratio */ plat_ratio = ((plat_ratio & 0x3E) >> 1); bus_clk = SYS_CLK * plat_ratio; return bus_clk; +} #else - return (uint32_t)(SYS_CLK * 6); /* can also be 8 */ +#define hal_get_bus_clk() (uint32_t)(SYS_CLK * 6) #endif -} -#if defined(ENABLE_ESPI) || defined(ENABLE_DDR) -#ifdef BUILD_LOADER_STAGE1 -static -#endif -void udelay(unsigned long delay_us) +#define DELAY_US (hal_get_bus_clk() / 1000000) +static void udelay(uint32_t delay_us) { - delay_us *= (hal_get_bus_clk() / 1000000); - wait_ticks(delay_us); + wait_ticks(delay_us * DELAY_US); } -#endif /* ---- eSPI Driver ---- */ #ifdef ENABLE_ESPI @@ -903,7 +899,7 @@ static int hal_flash_init(void) return ret; } -void hal_ddr_init(void) +static void hal_ddr_init(void) { #ifdef ENABLE_DDR uint32_t reg; @@ -968,6 +964,12 @@ void hal_ddr_init(void) #endif /* ENABLE_DDR */ } +void hal_early_init(void) +{ + hal_ddr_init(); +} + + #ifdef ENABLE_PCIE #define CONFIG_SYS_PCIE1_MEM_PHYS 0xc0000000 #define CONFIG_SYS_PCIE1_IO_PHYS 0xffc20000 @@ -987,18 +989,18 @@ static int hal_pcie_init(void) set_law(3, CONFIG_SYS_PCIE2_IO_PHYS, LAW_TRGT_PCIE2, LAW_SIZE_64KB), /* Map TLB for PCIe */ - set_tlb(1, 2, CONFIG_SYS_PCIE2_MEM_VIRT, CONFIG_SYS_PCIE2_MEM_PHYS, + set_tlb(1, 2, CONFIG_SYS_PCIE2_MEM_VIRT, CONFIG_SYS_PCIE2_MEM_PHYS, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256M, 1); set_tlb(1, 3, (CONFIG_SYS_PCIE2_MEM_VIRT + 0x10000000), - (CONFIG_SYS_PCIE2_MEM_PHYS + 0x10000000), + (CONFIG_SYS_PCIE2_MEM_PHYS + 0x10000000), 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256M, 1); - set_tlb(1, 4, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, + set_tlb(1, 4, CONFIG_SYS_PCIE1_MEM_VIRT, CONFIG_SYS_PCIE1_MEM_PHYS, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256M, 1); set_tlb(1, 5, (CONFIG_SYS_PCIE1_MEM_VIRT + 0x10000000), - (CONFIG_SYS_PCIE1_MEM_PHYS + 0x10000000), + (CONFIG_SYS_PCIE1_MEM_PHYS + 0x10000000), 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256M, 1); - set_tlb(1, 6, CONFIG_SYS_PCIE2_IO_VIRT, CONFIG_SYS_PCIE2_IO_PHYS, + set_tlb(1, 6, CONFIG_SYS_PCIE2_IO_VIRT, CONFIG_SYS_PCIE2_IO_PHYS, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256K, 1); return 0; } @@ -1011,7 +1013,7 @@ static int hal_cpld_init(void) /* Setup Local Access Window (LAW) for CPLD/BCSR */ set_law(5, BCSR_BASE, LAW_TRGT_ELBC, LAW_SIZE_256KB); /* Setup TLB MMU (Translation Lookaside Buffer) for CPLD/BCSR */ - set_tlb(1, 8, BCSR_BASE, BCSR_BASE, MAS3_SX | MAS3_SW | MAS3_SR, + set_tlb(1, 8, BCSR_BASE, BCSR_BASE, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_256K, 1); /* setup eLBC for CPLD (CS1), 8-bit */ @@ -1504,7 +1506,7 @@ static void hal_mp_init(void) /* map reset page to bootpg so we can copy code there */ disable_tlb1(i_tlb); - set_tlb(1, i_tlb, BOOT_ROM_ADDR, bootpg, /* tlb, epn, rpn */ + set_tlb(1, i_tlb, BOOT_ROM_ADDR, bootpg, 0, /* tlb, epn, rpn */ MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I, /* perms, wimge */ 0, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */ diff --git a/hal/nxp_ppc.c b/hal/nxp_ppc.c new file mode 100644 index 00000000..fae59422 --- /dev/null +++ b/hal/nxp_ppc.c @@ -0,0 +1,23 @@ +/* nxp_ppc.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +/* This file gets directly included from nxp_ targets. + * This file contains shared driver code for all NXP QorIQ platforms */ diff --git a/hal/nxp_ppc.h b/hal/nxp_ppc.h index 6c452c04..76f9743f 100644 --- a/hal/nxp_ppc.h +++ b/hal/nxp_ppc.h @@ -26,6 +26,7 @@ /* NXP P1021 */ #define CPU_NUMCORES 2 #define CORE_E500 + #define LAW_MAX_ENTRIES 12 #define CCSRBAR_DEF (0xFF700000) /* P1021RM 4.3 default base */ #define CCSRBAR_SIZE BOOKE_PAGESZ_1M @@ -40,8 +41,13 @@ /* First stage loader features */ #define ENABLE_L2_CACHE - #define L2SRAM_ADDR (0xF8F80000) /* L2 as SRAM */ - #define L2SRAM_SIZE (256 * 1024) + #define L2SRAM_ADDR (0xF8F80000) /* L2 as SRAM */ + #define L2SRAM_SIZE (256 * 1024) + + #define INITIAL_SRAM_ADDR L2SRAM_ADDR + #define INITIAL_SRAM_LAW_SZ LAW_SIZE_256KB + #define INITIAL_SRAM_LAW_TRGT LAW_TRGT_ELBC + #define INITIAL_SRAM_BOOKE_SZ BOOKE_PAGESZ_256K #else /* For wolfBoot features */ #define ENABLE_L1_CACHE @@ -53,28 +59,72 @@ #define ENABLE_INTERRUPTS #endif +#elif defined(PLATFORM_nxp_t1024) + /* NXP T1024 */ + #define CPU_NUMCORES 2 + #define CORE_E5500 + #define LAW_MAX_ENTRIES 16 + + #define CCSRBAR_DEF (0xFE000000) /* T1024RM 4.4.1 default base */ + #define CCSRBAR_SIZE BOOKE_PAGESZ_16M + + #define INITIAL_SRAM_ADDR 0xFDFC0000 + #define INITIAL_SRAM_LAW_SZ LAW_SIZE_256KB + #define INITIAL_SRAM_LAW_TRGT LAW_TRGT_PSRAM + #define INITIAL_SRAM_BOOKE_SZ BOOKE_PAGESZ_256K + + #define ENABLE_L1_CACHE + #define ENABLE_INTERRUPTS + + #ifdef BUILD_LOADER_STAGE1 + #define ENABLE_L2_CACHE /* setup and enable L2 in first stage only */ + #else + /* relocate to 64-bit 0xF_ */ + #define CCSRBAR_PHYS_HIGH 0xFULL + #define CCSRBAR_PHYS (CCSRBAR_PHYS_HIGH + CCSRBAR_DEF) + #endif + + #define ENABLE_DDR + + #define FLASH_BASE_ADDR 0xEC000000 + #define FLASH_BASE_PHYS_HIGH 0xFULL + #define FLASH_LAW_SIZE LAW_SIZE_64MB + #define FLASH_TLB_PAGESZ BOOKE_PAGESZ_64M + + #define USE_LONG_JUMP + #elif defined(PLATFORM_nxp_t2080) /* NXP T0280 */ #define CPU_NUMCORES 4 #define CORE_E6500 + #define LAW_MAX_ENTRIES 32 - #define CCSRBAR_DEF (0xFE000000) /* T2080RM 4.3.1 default base - 0xFF000000 */ + #define CCSRBAR_DEF (0xFE000000) /* T2080RM 4.3.1 default base */ #define CCSRBAR_SIZE BOOKE_PAGESZ_16M /* relocate to 64-bit 0xE_ */ - //#define CCSRBAR_PHYS_HIGH 0xE + //#define CCSRBAR_PHYS_HIGH 0xEULL //#define CCSRBAR_PHYS (CCSRBAR_PHYS_HIGH + CCSRBAR_DEF) #define ENABLE_L1_CACHE #define ENABLE_L2_CACHE + #define L2SRAM_ADDR (0xF8F80000) /* L2 as SRAM */ #define L2SRAM_SIZE (256 * 1024) + + #define INITIAL_SRAM_ADDR L2SRAM_ADDR + #define INITIAL_SRAM_LAW_SZ LAW_SIZE_256KB + #define INITIAL_SRAM_LAW_TRGT LAW_TRGT_DDR_1 + #define INITIAL_SRAM_BOOKE_SZ BOOKE_PAGESZ_256K + #define ENABLE_INTERRUPTS #define ENABLE_DDR - #define FLASH_BASE_ADDR 0xE8000000 - #define FLASH_BASE_PHYS_HIGH 0x0 + #define FLASH_BASE_ADDR 0xE8000000 + #define FLASH_BASE_PHYS_HIGH 0x0ULL + #define FLASH_LAW_SIZE LAW_SIZE_128MB + #define FLASH_TLB_PAGESZ BOOKE_PAGESZ_128M #define USE_LONG_JUMP #else @@ -118,9 +168,9 @@ #define L1_CACHE_SZ (32 * 1024) #endif -#ifdef CORE_E500 - /* PowerPC e500 */ - /* EREF: 7.5.3.2 - TLB Entry Page Size */ +#if defined(CORE_E500) || defined(CORE_E5500) + /* E500CORERM: 2.12.5.2 MAS Register 1 (MAS1) + * E5500RM: 2.16.6.2 MAS Register 1 (MAS1) */ #define BOOKE_PAGESZ_4K 1 #define BOOKE_PAGESZ_16K 2 #define BOOKE_PAGESZ_64K 3 @@ -135,6 +185,37 @@ #define MAS1_TSIZE_MASK 0x00000F00 #define MAS1_TSIZE(x) (((x) << 8) & MAS1_TSIZE_MASK) +#elif defined(CORE_E6500) + /* E6500RM: 2.13.10.2 MMU Assist 1 (MAS1) + * EREF 2.0: 6.5.3.2 - TLB Entry Page Size */ + #define BOOKE_PAGESZ_4K 2 + #define BOOKE_PAGESZ_8K 3 + #define BOOKE_PAGESZ_16K 4 + #define BOOKE_PAGESZ_32K 5 + #define BOOKE_PAGESZ_64K 6 + #define BOOKE_PAGESZ_128K 7 + #define BOOKE_PAGESZ_256K 8 + #define BOOKE_PAGESZ_512K 9 + #define BOOKE_PAGESZ_1M 10 + #define BOOKE_PAGESZ_2M 11 + #define BOOKE_PAGESZ_4M 12 + #define BOOKE_PAGESZ_8M 13 + #define BOOKE_PAGESZ_16M 14 + #define BOOKE_PAGESZ_32M 15 + #define BOOKE_PAGESZ_64M 16 + #define BOOKE_PAGESZ_128M 17 + #define BOOKE_PAGESZ_256M 18 + #define BOOKE_PAGESZ_512M 19 + #define BOOKE_PAGESZ_1G 20 + #define BOOKE_PAGESZ_2G 21 + #define BOOKE_PAGESZ_4G 22 + + #define MAS1_TSIZE_MASK 0x00000F80 + #define MAS1_TSIZE(x) (((x) << 7) & MAS1_TSIZE_MASK) +#endif + +#ifdef CORE_E500 + /* PowerPC e500 */ #define CACHE_LINE_SHIFT 5 /* 32 bytes per L1 cache line */ @@ -179,44 +260,45 @@ #define LAW_SIZE_32GB 0x22 -#elif defined(CORE_E6500) - /* PowerPC e6500 */ +#elif defined(CORE_E6500) || defined(CORE_E5500) + /* PowerPC e5500/e6500 */ /* CoreNet on-chip interface between the core cluster and rest of SoC */ #define USE_CORENET_INTERFACE - - /* EREF 2.0: 6.5.3.2 - TLB Entry Page Size */ - #define BOOKE_PAGESZ_4K 2 - #define BOOKE_PAGESZ_8K 3 - #define BOOKE_PAGESZ_16K 4 - #define BOOKE_PAGESZ_32K 5 - #define BOOKE_PAGESZ_64K 6 - #define BOOKE_PAGESZ_128K 7 - #define BOOKE_PAGESZ_256K 8 - #define BOOKE_PAGESZ_512K 9 - #define BOOKE_PAGESZ_1M 10 - #define BOOKE_PAGESZ_2M 11 - #define BOOKE_PAGESZ_4M 12 - #define BOOKE_PAGESZ_8M 13 - #define BOOKE_PAGESZ_16M 14 - #define BOOKE_PAGESZ_32M 15 - #define BOOKE_PAGESZ_64M 16 - #define BOOKE_PAGESZ_128M 17 - #define BOOKE_PAGESZ_256M 18 - #define BOOKE_PAGESZ_512M 19 - #define BOOKE_PAGESZ_1G 20 - #define BOOKE_PAGESZ_2G 21 - #define BOOKE_PAGESZ_4G 22 - - #define MAS1_TSIZE_MASK 0x00000F80 - #define MAS1_TSIZE(x) (((x) << 7) & MAS1_TSIZE_MASK) + #define HAS_EMBEDDED_HYPERVISOR /* E.HV Supported */ #define CACHE_LINE_SHIFT 6 /* 64 bytes per L1 cache line */ /* CoreNet Platform Cache Base */ - #define CPC_BASE (CCSRBAR + 0x10000) + #define CPC_BASE (CCSRBAR + 0x10000) + /* 8.2 CoreNet Platform Cache (CPC) Memory Map */ + #define CPCCSR0 (0x000) + #define CPCSRCR1 (0x100) + #define CPCSRCR0 (0x104) + #define CPCHDBCR0 (0xF00) - /* T2080 LAW - Local Access Window (Memory Map) - RM 2.4 */ + #define CPCCSR0_CPCE (0x80000000 >> 0) + #define CPCCSR0_CPCPE (0x80000000 >> 1) + #define CPCCSR0_CPCFI (0x80000000 >> 10) + #define CPCCSR0_CPCLFC (0x80000000 >> 21) + #define CPCCSR0_SRAM_ENABLE (CPCCSR0_CPCE | CPCCSR0_CPCPE) + + #ifdef CORE_E6500 + #define CPCSRCR0_SRAMSZ_64 (0x1 << 1) /* ways 14-15 */ + #define CPCSRCR0_SRAMSZ_256 (0x3 << 1) /* ways 8-15 */ + #define CPCSRCR0_SRAMSZ_512 (0x4 << 1) /* ways 0-15 */ + #else /* CORE E5500 */ + #define CPCSRCR0_SRAMSZ_64 (0x1 << 1) /* ways 6-7 */ + #define CPCSRCR0_SRAMSZ_128 (0x2 << 1) /* ways 4-7 */ + #define CPCSRCR0_SRAMSZ_256 (0x3 << 1) /* ways 0-7 */ + #endif + #define CPCSRCR0_SRAMEN (0x1) + + #define CPCHDBCR0_SPEC_DIS (0x80000000 >> 4) + + #define CORENET_DCSR_SZ_1G 0x3 + + /* T1024/T2080 LAW - Local Access Window (Memory Map) - RM 2.4 */ #define LAWBAR_BASE(n) (0xC00 + (n * 0x10)) #define LAWBARH(n) *((volatile uint32_t*)(CCSRBAR + LAWBAR_BASE(n) + 0x0)) #define LAWBARL(n) *((volatile uint32_t*)(CCSRBAR + LAWBAR_BASE(n) + 0x4)) @@ -225,13 +307,20 @@ #define LAWAR_ENABLE (1<<31) #define LAWAR_TRGT_ID(id) (id<<20) - /* T2080 Global Source/Target ID Assignments - RM Table 2-1 */ - #define LAW_TRGT_DDR_1 0x10 - #define LAW_TRGT_BMAN 0x18 /* Buffer Manager (BMan) (control) */ - #define LAW_TRGT_CORENET 0x1E + /* T1024/T2080 Global Source/Target ID Assignments - RM Table 2-1 */ + #define LAW_TRGT_PCIE1 0x00 + #define LAW_TRGT_PCIE2 0x01 + #define LAW_TRGT_PCIE3 0x02 + #define LAW_TRGT_DDR_1 0x10 /* Memory Complex 1 */ + #define LAW_TRGT_DDR_2 0x11 + #define LAW_TRGT_BMAN 0x18 /* Buffer Manager (control) */ + #define LAW_TRGT_DCSR 0x1D /* debug facilities */ + #define LAW_TRGT_CORENET 0x1E /* CCSR */ #define LAW_TRGT_IFC 0x1F /* Integrated Flash Controller */ + #define LAW_TRGT_QMAN 0x3C /* Queue Manager (control) */ + #define LAW_TRGT_PSRAM 0x4A /* 160 KB Platform SRAM */ - /* T2080 2.4.3 - size is equal to 2^(enum + 1) */ + /* T1024/T2080 2.4.3 - size is equal to 2^(enum + 1) */ #define LAW_SIZE_4KB 0x0B #define LAW_SIZE_8KB 0x0C #define LAW_SIZE_16KB 0x0D @@ -261,7 +350,6 @@ #define LAW_SIZE_256GB 0x25 #define LAW_SIZE_512GB 0x26 #define LAW_SIZE_1TB 0x27 - #endif #ifndef CACHE_LINE_SIZE @@ -271,6 +359,7 @@ /* MMU Assist Registers * E6500RM 2.13.10 + * E5500RM 2.16.6 * E500CORERM 2.12.5 */ #define MAS0 0x270 @@ -279,6 +368,7 @@ #define MAS3 0x273 #define MAS6 0x276 #define MAS7 0x3B0 +#define MAS8 0x155 #define MMUCSR0 0x3F4 /* MMU control and status register 0 */ #define MAS0_TLBSEL_MSK 0x30000000 @@ -319,14 +409,45 @@ /* L1 Cache */ -#define L1CFG0 0x203 /* L1 Cache Configuration Register 0 */ -#define L1CSR0 0x3F2 /* L1 Data */ -#define L1CSR1 0x3F3 /* L1 Instruction */ +#define L1CFG0 0x203 /* L1 Cache Configuration Register 0 */ +#define L1CSR2 0x25E /* L1 Data Cache Control and Status Register 2 */ +#define L1CSR0 0x3F2 /* L1 Data */ +#define L1CSR1 0x3F3 /* L1 Instruction */ + #define L1CSR_CPE 0x00010000 /* cache parity enable */ #define L1CSR_CLFC 0x00000100 /* cache lock bits flash clear */ #define L1CSR_CFI 0x00000002 /* cache flash invalidate */ #define L1CSR_CE 0x00000001 /* cache enable */ +/* L2 Cache */ +#if defined(CORE_E6500) + /* MMRs */ + #define L2CSR0 0x000 /* L2 Cache Control and Status 0 */ + #define L2CSR1 0x004 /* L2 Cache Control and Status 1 */ + #define L2CFG0 0x008 /* L2 Cache Configuration */ +#else + /* SPR */ + #define L2CFG0 0x207 /* L2 Cache Configuration Register 0 */ + #define L2CSR0 0x3F9 /* L2 Data Cache Control and Status Register 0 */ + #define L2CSR1 0x3FA /* L2 Data Cache Control and Status Register 1 */ +#endif + +#define L2CSR0_L2FI 0x00200000 /* L2 Cache Flash Invalidate */ +#define L2CSR0_L2FL 0x00000800 /* L2 Cache Flush */ +#define L2CSR0_L2LFC 0x00000400 /* L2 Cache Lock Flash Clear */ +#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ +#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ + +#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ +#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ +#define L2CSR0_L2WP 0x1c000000 /* L2 I/D Way Partioning */ +#define L2CSR0_L2CM 0x03000000 /* L2 Cache Coherency Mode */ +#define L2CSR0_L2FI 0x00200000 /* L2 Cache Flash Invalidate */ +#define L2CSR0_L2IO 0x00100000 /* L2 Cache Instruction Only */ +#define L2CSR0_L2DO 0x00010000 /* L2 Cache Data Only */ +#define L2CSR0_L2REP 0x00003000 /* L2 Line Replacement Algo */ + + #define SCCSRBAR 0x3FE /* Shifted CCSRBAR */ #define SPRN_DBSR 0x130 /* Debug Status Register */ @@ -361,10 +482,10 @@ #define IVPR 0x03F /* Interrupt Vector Prefix Register */ /* Guest Interrupt Vectors */ -#define GIVOR2 (0x1B8) -#define GIVOR3 (0x1B9) -#define GIVOR4 (0x1BA) -#define GIVOR8 (0x1BB) +#define GIVOR2 (0x1B8) +#define GIVOR3 (0x1B9) +#define GIVOR4 (0x1BA) +#define GIVOR8 (0x1BB) #define GIVOR13 (0x1BC) #define GIVOR14 (0x1BD) #define GIVOR35 (0x1D1) @@ -376,6 +497,7 @@ #define MSR_IS (1<<5) /* Book E Instruction address space */ #define MSR_DE (1<<9) /* Debug Exception Enable */ #define MSR_ME (1<<12) /* Machine check enable */ +#define MSR_EE (1<<15) /* External Interrupt enable */ #define MSR_CE (1<<17) /* Critical interrupt enable */ #define MSR_PR (1<<14) /* User mode (problem state) */ @@ -412,8 +534,7 @@ (((epn) & MAS2_EPN) | (wimge)) #define BOOKE_MAS3(rpn, user, perms) \ (((rpn) & MAS3_RPN) | (user) | (perms)) -#define BOOKE_MAS7(rpn) \ - (((unsigned long long)(rpn) >> 32) & MAS7_RPN) +#define BOOKE_MAS7(urpn) (urpn) /* Stringification */ #ifndef WC_STRINGIFY @@ -429,6 +550,7 @@ }) #define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) + #ifndef __ASSEMBLER__ /* The data barrier / coherency safe functions for reading and writing */ @@ -474,7 +596,7 @@ static inline void set16(volatile unsigned short *addr, int val) ); } -static inline unsigned int get32(const volatile unsigned *addr) +static inline unsigned int get32(const volatile unsigned int *addr) { unsigned int ret; __asm__ __volatile__( @@ -486,7 +608,7 @@ static inline unsigned int get32(const volatile unsigned *addr) ); return ret; } -static inline void set32(volatile unsigned *addr, unsigned int val) +static inline void set32(volatile unsigned int *addr, unsigned int val) { __asm__ __volatile__( "sync;" @@ -496,8 +618,9 @@ static inline void set32(volatile unsigned *addr, unsigned int val) } /* C version in boot_ppc.c */ -extern void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint64_t rpn, - uint8_t perms, uint8_t wimge, uint8_t ts, uint8_t tsize, uint8_t iprot); +extern void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint32_t rpn, + uint32_t urpn, uint8_t perms, uint8_t wimge, uint8_t ts, uint8_t tsize, + uint8_t iprot); extern void disable_tlb1(uint8_t esel); extern void flush_cache(uint32_t start_addr, uint32_t size); @@ -506,7 +629,7 @@ extern void uart_init(void); /* from boot_ppc_start.S */ extern unsigned long long get_ticks(void); -extern void wait_ticks(unsigned long); +extern void wait_ticks(unsigned long long); extern unsigned long get_pc(void); extern void relocate_code(uint32_t *dest, uint32_t *src, uint32_t length); extern void invalidate_dcache(void); diff --git a/hal/nxp_t1024.c b/hal/nxp_t1024.c new file mode 100644 index 00000000..9c430eb6 --- /dev/null +++ b/hal/nxp_t1024.c @@ -0,0 +1,1614 @@ +/* nxp_t1024.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +#include +#include "target.h" +#include "printf.h" +#include "string.h" +#include "image.h" /* for RAMFUNCTION */ +#include "nxp_ppc.h" + +/* Tested on T1024E Rev 1.0, e5500 core 2.1, PVR 8024_1021 and SVR 8548_0010 */ +/* IFC: CS0 NOR, CS1 MRAM, CS2 CPLD, CS3, MPU CPLD */ +/* DDR: DDR4 w/ECC (5 chips MT40A256M16GE-083EIT) - SPD on I2C1 at Addr 0x51 */ + +/* Tests */ +#if 1 + //#define TEST_DDR + //#define TEST_FLASH + //#define TEST_TPM +#endif + +#define ENABLE_DDR +#define ENABLE_BUS_CLK_CALC +#define ENABLE_IFC +#ifndef BUILD_LOADER_STAGE1 + #define ENABLE_CPLD + #define ENABLE_QE /* QUICC Engine */ + //#define ENABLE_FMAN + //#define ENABLE_MP /* multi-core support */ + #if defined(WOLFBOOT_TPM) || defined(TEST_TPM) + #define ENABLE_ESPI /* SPI for TPM */ + #endif +#endif + +#define USE_ERRATA_DDRA008378 +#define USE_ERRATA_DDRA008109 +#define USE_ERRATA_DDRA009663 +#define USE_ERRATA_DDRA009942 + +#if defined(ENABLE_DDR) && defined(TEST_DDR) +static int test_ddr(void); +#endif +#if defined(ENABLE_IFC) && defined(TEST_FLASH) +static int test_flash(void); +#endif +#if defined(ENABLE_ESPI) && defined(TEST_TPM) +static int test_tpm(void); +#endif + +#ifdef ENABLE_ESPI +#include "spi_drv.h" /* for transfer flags */ +#endif + +/* T1024 */ +#define SYS_CLK (100000000) /* 100MHz */ + +/* Boot page translation register - T1024RM 4.5.9 */ +#define LCC_BSTRH ((volatile uint32_t*)(CCSRBAR + 0x20)) /* Boot space translation register high */ +#define LCC_BSTRL ((volatile uint32_t*)(CCSRBAR + 0x24)) /* Boot space translation register low */ +#define LCC_BSTAR ((volatile uint32_t*)(CCSRBAR + 0x28)) /* Boot space translation attribute register */ +#define LCC_BSTAR_EN 0x80000000 +#define LCC_BSTAR_LAWTRGT(n) ((n) << 20) +#define LCC_BSTAR_LAWSZ(n) ((n) & 0x3F) + +/* DCFG (Device Configuration/Pin Control) T1024RM 7.3 */ +#define DCFG_BASE (CCSRBAR + 0xE0000) +#define DCFG_PVR ((volatile uint32_t*)(DCFG_BASE + 0xA0UL)) +#define DCFG_SVR ((volatile uint32_t*)(DCFG_BASE + 0xA4UL)) +#define DCFG_DEVDISR1 ((volatile uint32_t*)(DCFG_BASE + 0x70UL)) /* Device disable register */ +#define DCFG_DEVDISR2 ((volatile uint32_t*)(DCFG_BASE + 0x74UL)) /* Device disable register */ +#define DCFG_DEVDISR3 ((volatile uint32_t*)(DCFG_BASE + 0x78UL)) /* Device disable register */ +#define DCFG_DEVDISR4 ((volatile uint32_t*)(DCFG_BASE + 0x7CUL)) /* Device disable register */ +#define DCFG_DEVDISR5 ((volatile uint32_t*)(DCFG_BASE + 0x80UL)) /* Device disable register */ +#define DCFG_COREDISR ((volatile uint32_t*)(DCFG_BASE + 0x94UL)) /* Core Enable/Disable */ +#define DCFG_BRR ((volatile uint32_t*)(DCFG_BASE + 0xE4UL)) /* Boot Release Register (DCFG_CCSR_BRR) */ +#define DCFG_DCSR ((volatile uint32_t*)(DCFG_BASE + 0x704UL)) /* Debug configuration and status */ + +/* T1024RM: 4.6.5 */ +#define CLOCKING_BASE (CCSRBAR + 0xE1000) +#define CLOCKING_PLLPGSR ((volatile uint32_t*)(CLOCKING_BASE + 0xC00UL)) /* Platform PLL general status register */ + +#define RCPM_BASE (CCSRBAR + 0xE2000) +#define RCPM_PCTBENR ((volatile uint32_t*)(RCPM_BASE + 0x1A0)) /* Physical Core Time Base Enable Bit 0=Core 0 */ +#define RCPM_PCTBCKSELR ((volatile uint32_t*)(RCPM_BASE + 0x1A4)) /* Physical Core Time Base Clock Select 0=Platform Clock/16, 1=RTC */ +#define RCPM_TBCLKDIVR ((volatile uint32_t*)(RCPM_BASE + 0x1A8)) /* Time Base Clock Divider 0=1/16, 1=1/8, 2=1/24, 3=1/32 */ + +/* MPIC - T1024RM 24.3 */ +#define PIC_BASE (CCSRBAR + 0x40000) +#define PIC_WHOAMI ((volatile uint32_t*)(PIC_BASE + 0x0090UL)) /* Returns the ID of the processor core reading this register */ +#define PIC_GCR ((volatile uint32_t*)(PIC_BASE + 0x1020UL)) /* Global configuration register (controls PIC operating mode) */ +#define PIC_GCR_RST 0x80000000 +#define PIC_GCR_M 0x20000000 + + +/* QUICC Engine */ +#define QE_MAX_RISC 1 + +/* QE microcode/firmware address */ +#ifndef QE_FW_ADDR +#define QE_FW_ADDR 0xEFE00000 /* location in NOR flash */ +#endif + +#define QE_BASE (CCSRBAR + 0xF000) +#define QE_CEPIER ((volatile uint32_t*)(QE_BASE + 0x00CUL)) +#define QE_CEPIMR ((volatile uint32_t*)(QE_BASE + 0x010UL)) +#define QE_CEPICR ((volatile uint32_t*)(QE_BASE + 0x014UL)) + +#define QE_ENGINE_BASE (CCSRBAR + 0x80000) +#define QE_IRAM (QE_ENGINE_BASE + 0x000UL) /* Instruction RAM registers */ +#define QE_IRAM_IADD ((volatile uint32_t*)(QE_IRAM + 0x000UL)) +#define QE_IRAM_IDATA ((volatile uint32_t*)(QE_IRAM + 0x004UL)) +#define QE_IRAM_IREADY ((volatile uint32_t*)(QE_IRAM + 0x00CUL)) + +#define QE_CP (QE_ENGINE_BASE + 0x100UL) /* Configuration register */ +#define QE_CP_CECR ((volatile uint32_t*)(QE_CP + 0x00)) /* command register */ +#define QE_CP_CECDR ((volatile uint32_t*)(QE_CP + 0x08)) /* data register */ +#define QE_CP_CERCR ((volatile uint16_t*)(QE_CP + 0x38)) /* RAM control register */ + +#define QE_SDMA (QE_ENGINE_BASE + 0x4000UL) /* Serial DMA */ +#define QE_SDMA_SDSR ((volatile uint32_t*)(QE_SDMA + 0x00)) +#define QE_SDMA_SDMR ((volatile uint32_t*)(QE_SDMA + 0x04)) +#define QE_SDMA_SDAQR ((volatile uint32_t*)(QE_SDMA + 0x38)) +#define QE_SDMA_SDAQMR ((volatile uint32_t*)(QE_SDMA + 0x3C)) +#define QE_SDMA_SDEBCR ((volatile uint32_t*)(QE_SDMA + 0x44)) + +#define QE_RSP (QE_ENGINE_BASE + 0x4100UL) /* Special Registers */ +#define QE_RSP_TIBCR(n, i) ((volatile uint32_t*)(QE_RSP + ((n) * 0x100) + (i))) +#define QE_RSP_ECCR(n) ((volatile uint32_t*)(QE_RSP + ((n) * 0x100) + 0xF0)) + +#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */ +#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */ +#define QE_IRAM_READY 0x80000000 + +#define QE_CP_CERCR_CIR 0x0800 /* Common instruction RAM */ + +#define QE_CR_FLG 0x00010000 +#define QE_CR_PROTOCOL_SHIFT 6 + +#define QE_SDMR_GLB_1_MSK 0x80000000 +#define QE_SDMR_CEN_SHIFT 13 +#define QE_SDEBCR_BA_MASK 0x01FFFFFF + +/* QE Commands */ +#define QE_RESET 0x80000000 + + +/* T1024RM 10.5.1: Queue Manager (QMan): + * - QMan block base address: 31_8000h + * - 512 frame queue (FQ) cache + * - 2-Kbyte SFDRs + * - 256 congestion groups + */ + +/* T1024RM 10.5.2: Buffer Manager (BMan): + * - BMan block base address: 31_A000h + * - 64 buffer pools + */ + +/* T1024RM 10.5.4: Security and Encryption Engine (SEC) + * - SEC block base address: 30_0000h + * - 2.5 Gbps SEC processing at 400 MHz + * - Cryptographic Hardware Accelerators (CHAs) include: + * - PKHA + * - DESA + * - AESA + * - MDHA + * - RNG4 + * - AFHA + */ + +/* T1024RM 10.5.3: Frame Manager (FMan): + * - FMan block base address: 40_0000h + * - Four multirate Ethernet MACs, for configuration options refer to SerDes Protocols + * - Block base addresses are as follows: + * - FM1 mEMAC1: 4E_0000h + * - FM1 mEMAC2: 4E_2000h + * - FM1 mEMAC3: 4E_4000h + * - FM1 mEMAC4: 4E_6000h + * - mEMAC PortIDs (RX/TX): + * - mEMAC1: 08h/28h + * - mEMAC2: 09h/29h + * - mEMAC3: 0Ah/2Ah + * - mEMAC4: 0Bh/2Bh + * - Supports 1 host command and 3 offline ports: + * - Host command: 02h + * - Offline port 3: 03h + * - Offline port 4: 04h + * - Offline port 5: 05h + * - FM1 Dedicated MDIO1: 4F_C000h + * - FM1 Dedicated MDIO2: 4F_D000h + * - One FMan Controller complexes + * - 192-Kbyte internal FMan memory + * - 32-Kbyte FMan Controller configuration data + * - Up to 32 Keygen schemes + * - Up to 8 Policer profiles + * - Up to 32 entries in FMan DMA command queue + * - Up to 64 TNUMs + * - Up to 1 FMan debug flows + */ + +#define FMAN_COUNT 1 + +#ifndef FMAN_FW_ADDR +#define FMAN_FW_ADDR 0xEFF00000 /* location in NOR flash */ +#endif + +#define FMAN_BASE (CCSRBAR + 0x400000) +//#define QE_CEPIER ((volatile uint32_t*)(FMAN_BASE + 0x00CUL)) + + + +/* T1024 PC16552D Dual UART */ +#define BAUD_RATE 115200 +#define UART_SEL 0 /* select UART 0 or 1 */ + +#define UART_BASE(n) (CCSRBAR + 0x11C500 + (n * 0x1000)) + +#define UART_RBR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* receiver buffer register */ +#define UART_THR(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* transmitter holding register */ +#define UART_IER(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* interrupt enable register */ +#define UART_IIR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */ +#define UART_FCR(n) ((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */ +#define UART_LCR(n) ((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */ +#define UART_MCR(n) ((volatile uint8_t*)(UART_BASE(n) + 4)) /* modem control register */ +#define UART_LSR(n) ((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */ + +/* enabled when UART_LCR_DLAB set */ +#define UART_DLB(n) ((volatile uint8_t*)(UART_BASE(n) + 0)) /* divisor least significant byte register */ +#define UART_DMB(n) ((volatile uint8_t*)(UART_BASE(n) + 1)) /* divisor most significant byte register */ + +#define UART_FCR_TFR (0x04) /* Transmitter FIFO reset */ +#define UART_FCR_RFR (0x02) /* Receiver FIFO reset */ +#define UART_FCR_FEN (0x01) /* FIFO enable */ +#define UART_LCR_DLAB (0x80) /* Divisor latch access bit */ +#define UART_LCR_WLS (0x03) /* Word length select: 8-bits */ +#define UART_LSR_TEMT (0x40) /* Transmitter empty */ +#define UART_LSR_THRE (0x20) /* Transmitter holding register empty */ + + +/* T1024 IFC (Integrated Flash Controller) - RM 23.1 */ +#define IFC_BASE (CCSRBAR + 0x00124000) +#define IFC_MAX_BANKS 8 + +#define IFC_CSPR_EXT(n) ((volatile uint32_t*)(IFC_BASE + 0x000C + (n * 0xC))) /* Extended Base Address */ +#define IFC_CSPR(n) ((volatile uint32_t*)(IFC_BASE + 0x0010 + (n * 0xC))) /* Chip-select Property */ +#define IFC_AMASK(n) ((volatile uint32_t*)(IFC_BASE + 0x00A0 + (n * 0xC))) +#define IFC_CSOR(n) ((volatile uint32_t*)(IFC_BASE + 0x0130 + (n * 0xC))) +#define IFC_CSOR_EXT(n) ((volatile uint32_t*)(IFC_BASE + 0x0134 + (n * 0xC))) +#define IFC_FTIM0(n) ((volatile uint32_t*)(IFC_BASE + 0x01C0 + (n * 0x30))) +#define IFC_FTIM1(n) ((volatile uint32_t*)(IFC_BASE + 0x01C4 + (n * 0x30))) +#define IFC_FTIM2(n) ((volatile uint32_t*)(IFC_BASE + 0x01C8 + (n * 0x30))) +#define IFC_FTIM3(n) ((volatile uint32_t*)(IFC_BASE + 0x01CC + (n * 0x30))) + +#define IFC_CSPR_PHYS_ADDR(x) (((uint32_t)x) & 0xFFFFFF00) /* Physical base address */ +#define IFC_CSPR_PORT_SIZE_8 0x00000080 /* Port Size 8 */ +#define IFC_CSPR_PORT_SIZE_16 0x00000100 /* Port Size 16 */ +#define IFC_CSPR_WP 0x00000040 /* Write Protect */ +#define IFC_CSPR_MSEL_NOR 0x00000000 /* Mode Select - NOR */ +#define IFC_CSPR_MSEL_NAND 0x00000002 /* Mode Select - NAND */ +#define IFC_CSPR_MSEL_GPCM 0x00000004 /* Mode Select - GPCM (General-purpose chip-select machine) */ +#define IFC_CSPR_V 0x00000001 /* Bank Valid */ + +/* NOR Timings (IFC clocks) */ +#define IFC_FTIM0_NOR_TACSE(n) (((n) & 0x0F) << 28) /* After address hold cycle */ +#define IFC_FTIM0_NOR_TEADC(n) (((n) & 0x3F) << 16) /* External latch address delay cycles */ +#define IFC_FTIM0_NOR_TAVDS(n) (((n) & 0x3F) << 8) /* Delay between CS assertion */ +#define IFC_FTIM0_NOR_TEAHC(n) (((n) & 0x3F) << 0) /* External latch address hold cycles */ +#define IFC_FTIM1_NOR_TACO(n) (((n) & 0xFF) << 24) /* CS assertion to output enable */ +#define IFC_FTIM1_NOR_TRAD(n) (((n) & 0x3F) << 8) /* read access delay */ +#define IFC_FTIM1_NOR_TSEQ(n) (((n) & 0x3F) << 0) /* sequential read access delay */ +#define IFC_FTIM2_NOR_TCS(n) (((n) & 0x0F) << 24) /* Chip-select assertion setup time */ +#define IFC_FTIM2_NOR_TCH(n) (((n) & 0x0F) << 18) /* Chip-select hold time */ +#define IFC_FTIM2_NOR_TWPH(n) (((n) & 0x3F) << 10) /* Chip-select hold time */ +#define IFC_FTIM2_NOR_TWP(n) (((n) & 0xFF) << 0) /* Write enable pulse width */ + +/* GPCM Timings (IFC clocks) */ +#define IFC_FTIM0_GPCM_TACSE(n) (((n) & 0x0F) << 28) /* After address hold cycle */ +#define IFC_FTIM0_GPCM_TEADC(n) (((n) & 0x3F) << 16) /* External latch address delay cycles */ +#define IFC_FTIM0_GPCM_TEAHC(n) (((n) & 0x3F) << 0) /* External latch address hold cycles */ +#define IFC_FTIM1_GPCM_TACO(n) (((n) & 0xFF) << 24) /* CS assertion to output enable */ +#define IFC_FTIM1_GPCM_TRAD(n) (((n) & 0x3F) << 8) /* read access delay */ +#define IFC_FTIM2_GPCM_TCS(n) (((n) & 0x0F) << 24) /* Chip-select assertion setup time */ +#define IFC_FTIM2_GPCM_TCH(n) (((n) & 0x0F) << 18) /* Chip-select hold time */ +#define IFC_FTIM2_GPCM_TWP(n) (((n) & 0xFF) << 0) /* Write enable pulse width */ + +/* IFC AMASK - RM Table 13-3 - Count of MSB minus 1 */ +enum ifc_amask_sizes { + IFC_AMASK_64KB = 0xFFFF, + IFC_AMASK_128KB = 0xFFFE, + IFC_AMASK_256KB = 0xFFFC, + IFC_AMASK_512KB = 0xFFF8, + IFC_AMASK_1MB = 0xFFF0, + IFC_AMASK_2MB = 0xFFE0, + IFC_AMASK_4MB = 0xFFC0, + IFC_AMASK_8MB = 0xFF80, + IFC_AMASK_16MB = 0xFF00, + IFC_AMASK_32MB = 0xFE00, + IFC_AMASK_64MB = 0xFC00, + IFC_AMASK_128MB = 0xF800, + IFC_AMASK_256MB = 0xF000, + IFC_AMASK_512MB = 0xE000, + IFC_AMASK_1GB = 0xC000, + IFC_AMASK_2GB = 0x8000, + IFC_AMASK_4GB = 0x0000, +}; + + +/* NOR Flash */ +#define FLASH_BANK_SIZE (64*1024*1024) +#define FLASH_PAGE_SIZE (1024) /* program buffer */ +#define FLASH_SECTOR_SIZE (128*1024) +#define FLASH_SECTORS (FLASH_BANK_SIZE / FLASH_SECTOR_SIZE) +#define FLASH_CFI_WIDTH 16 /* 8 or 16 */ + +#define FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */ +#define FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */ + +/* Intel CFI */ +#define FLASH_CMD_CFI 0x98 +#define FLASH_CMD_READ_ID 0x90 +#define FLASH_CMD_RESET 0xFF +#define FLASH_CMD_BLOCK_ERASE 0x20 +#define FLASH_CMD_ERASE_CONFIRM 0xD0 +#define FLASH_CMD_WRITE 0x40 +#define FLASH_CMD_PROTECT 0x60 +#define FLASH_CMD_SETUP 0x60 +#define FLASH_CMD_SET_CR_CONFIRM 0x03 +#define FLASH_CMD_PROTECT_SET 0x01 +#define FLASH_CMD_PROTECT_CLEAR 0xD0 +#define FLASH_CMD_CLEAR_STATUS 0x50 +#define FLASH_CMD_READ_STATUS 0x70 +#define FLASH_CMD_WRITE_TO_BUFFER 0xE8 +#define FLASH_CMD_WRITE_BUFFER_PROG 0xE9 +#define FLASH_CMD_WRITE_BUFFER_CONFIRM 0xD0 + +#define FLASH_STATUS_DONE 0x80 +#define FLASH_STATUS_ESS 0x40 +#define FLASH_STATUS_ECLBS 0x20 +#define FLASH_STATUS_PSLBS 0x10 +#define FLASH_STATUS_VPENS 0x08 +#define FLASH_STATUS_PSS 0x04 +#define FLASH_STATUS_DPS 0x02 +#define FLASH_STATUS_R 0x01 +#define FLASH_STATUS_PROTECT 0x01 + +/* AMD CFI */ +#define AMD_CMD_RESET 0xF0 +#define AMD_CMD_WRITE 0xA0 +#define AMD_CMD_ERASE_START 0x80 +#define AMD_CMD_ERASE_SECTOR 0x30 +#define AMD_CMD_UNLOCK_START 0xAA +#define AMD_CMD_UNLOCK_ACK 0x55 +#define AMD_CMD_WRITE_TO_BUFFER 0x25 +#define AMD_CMD_WRITE_BUFFER_CONFIRM 0x29 +#define AMD_CMD_SET_PPB_ENTRY 0xC0 +#define AMD_CMD_SET_PPB_EXIT_BC1 0x90 +#define AMD_CMD_SET_PPB_EXIT_BC2 0x00 +#define AMD_CMD_PPB_UNLOCK_BC1 0x80 +#define AMD_CMD_PPB_UNLOCK_BC2 0x30 +#define AMD_CMD_PPB_LOCK_BC1 0xA0 +#define AMD_CMD_PPB_LOCK_BC2 0x00 + +#define AMD_STATUS_TOGGLE 0x40 +#define AMD_STATUS_ERROR 0x20 + + +/* CPLD */ +#define CPLD_BASE 0xFFDF0000 +#define CPLD_BASE_PHYS_HIGH 0xFULL + +#define CPLD_VER 0x00 /* CPLD Major Revision Register */ +#define CPLD_VER_SUB 0x01 /* CPLD Minor Revision Register */ +#define HW_VER 0x02 /* Hardware Revision Register */ +#define SW_VER 0x03 /* Software Revision register */ +#define RESET_CTL1 0x10 /* Reset control Register1 */ +#define RESET_CTL2 0x11 /* Reset control Register2 */ +#define INT_STATUS 0x12 /* Interrupt status Register */ +#define FLASH_CSR 0x13 /* Flash control and status register */ +#define FAN_CTL_STATUS 0x14 /* Fan control and status register */ +#define LED_CTL_STATUS 0x15 /* LED control and status register */ +#define SFP_CTL_STATUS 0x16 /* SFP control and status register */ +#define MISC_CTL_STATUS 0x17 /* Miscellanies ctrl & status register*/ +#define BOOT_OVERRIDE 0x18 /* Boot override register */ +#define BOOT_CONFIG1 0x19 /* Boot config override register*/ +#define BOOT_CONFIG2 0x1A /* Boot config override register*/ + +#define CPLD_LBMAP_MASK 0x3F +#define CPLD_BANK_SEL_MASK 0x07 +#define CPLD_BANK_OVERRIDE 0x40 +#define CPLD_LBMAP_ALTBANK 0x44 /* BANK OR | BANK 4 */ +#define CPLD_LBMAP_DFLTBANK 0x40 /* BANK OR | BANK 0 */ +#define CPLD_LBMAP_RESET 0xFF +#define CPLD_LBMAP_SHIFT 0x03 +#define CPLD_BOOT_SEL 0x80 + +#define CPLD_PCIE_SGMII_MUX 0x80 +#define CPLD_OVERRIDE_BOOT_EN 0x01 +#define CPLD_OVERRIDE_MUX_EN 0x02 /* PCIE/2.5G-SGMII mux override enable */ + +#define CPLD_DATA(n) ((volatile uint8_t*)(CPLD_BASE + n)) + + +/* DDR4 - 2GB */ +/* 1600 MT/s (64-bit, CL=12, ECC on) */ +#define DDR_SIZE (2048ULL * 1024ULL * 1024ULL) + +#define DDR_CS0_BNDS_VAL 0x0000007F +#define DDR_CS1_BNDS_VAL 0x008000BF +#define DDR_CS2_BNDS_VAL 0x0100013F +#define DDR_CS3_BNDS_VAL 0x0140017F +#define DDR_CS0_CONFIG_VAL 0x80010312 +#define DDR_CS1_CONFIG_VAL 0x00000202 +#define DDR_CS2_CONFIG_VAL 0x00000202 +#define DDR_CS3_CONFIG_VAL 0x00010202 +#define DDR_CS_CONFIG_2_VAL 0x00000000 + +#define DDR_TIMING_CFG_0_VAL 0x8055000C +#define DDR_TIMING_CFG_1_VAL 0x2E268E44 +#define DDR_TIMING_CFG_2_VAL 0x0049111C +#define DDR_TIMING_CFG_3_VAL 0x114C1000 + +#define DDR_TIMING_CFG_4_VAL 0x00220001 +#define DDR_TIMING_CFG_5_VAL 0x05401400 +#define DDR_TIMING_CFG_8_VAL 0x03115800 + +#define DDR_SDRAM_MODE_VAL 0x01010215 +#define DDR_SDRAM_MODE_2_VAL 0x00000000 +#define DDR_SDRAM_MODE_9_VAL 0x00000500 /* Extended SDRAM mode 5 */ +#define DDR_SDRAM_MODE_10_VAL 0x04000000 /* Extended SDRAM mode 7 */ +#define DDR_SDRAM_MODE_3_8_VAL 0x00000000 +#define DDR_SDRAM_MD_CNTL_VAL 0x03001000 + +#define DDR_SDRAM_CFG_VAL 0xE5200000 /* DDR4 w/ECC */ +#define DDR_SDRAM_CFG_2_VAL 0x00401050 + +#define DDR_SDRAM_INTERVAL_VAL 0x18600618 +#define DDR_DATA_INIT_VAL 0xDEADBEEF +#define DDR_SDRAM_CLK_CNTL_VAL 0x02400000 +#define DDR_ZQ_CNTL_VAL 0x8A090705 + +#define DDR_WRLVL_CNTL_VAL 0x8675F606 +#define DDR_WRLVL_CNTL_2_VAL 0x06070709 +#define DDR_WRLVL_CNTL_3_VAL 0x09090908 + +#define DDR_SDRAM_RCW_1_VAL 0x00000000 +#define DDR_SDRAM_RCW_2_VAL 0x00000000 + +#define DDR_DDRCDR_1_VAL 0x80080000 +#define DDR_DDRCDR_2_VAL 0x00000000 + +#define DDR_ERR_INT_EN_VAL 0x0000001D +#define DDR_ERR_SBE_VAL 0x00000000 + + +/* 12.4 DDR Memory Map */ +#define DDR_BASE (CCSRBAR + 0x8000) + +#define DDR_CS_BNDS(n) ((volatile uint32_t*)(DDR_BASE + 0x000 + (n * 8))) /* Chip select n memory bounds */ +#define DDR_CS_CONFIG(n) ((volatile uint32_t*)(DDR_BASE + 0x080 + (n * 4))) /* Chip select n configuration */ +#define DDR_CS_CONFIG_2(n) ((volatile uint32_t*)(DDR_BASE + 0x0C0 + (n * 4))) /* Chip select n configuration 2 */ +#define DDR_SDRAM_CFG ((volatile uint32_t*)(DDR_BASE + 0x110)) /* DDR SDRAM control configuration */ +#define DDR_SDRAM_CFG_2 ((volatile uint32_t*)(DDR_BASE + 0x114)) /* DDR SDRAM control configuration 2 */ +#define DDR_SDRAM_CFG_3 ((volatile uint32_t*)(DDR_BASE + 0x260)) /* DDR SDRAM control configuration 3 */ +#define DDR_SDRAM_INTERVAL ((volatile uint32_t*)(DDR_BASE + 0x124)) /* DDR SDRAM interval configuration */ +#define DDR_INIT_ADDR ((volatile uint32_t*)(DDR_BASE + 0x148)) /* DDR training initialization address */ +#define DDR_INIT_EXT_ADDR ((volatile uint32_t*)(DDR_BASE + 0x14C)) /* DDR training initialization extended address */ +#define DDR_DATA_INIT ((volatile uint32_t*)(DDR_BASE + 0x128)) /* DDR training initialization value */ +#define DDR_TIMING_CFG_0 ((volatile uint32_t*)(DDR_BASE + 0x104)) /* DDR SDRAM timing configuration 0 */ +#define DDR_TIMING_CFG_1 ((volatile uint32_t*)(DDR_BASE + 0x108)) /* DDR SDRAM timing configuration 1 */ +#define DDR_TIMING_CFG_2 ((volatile uint32_t*)(DDR_BASE + 0x10C)) /* DDR SDRAM timing configuration 2 */ +#define DDR_TIMING_CFG_3 ((volatile uint32_t*)(DDR_BASE + 0x100)) /* DDR SDRAM timing configuration 3 */ +#define DDR_TIMING_CFG_4 ((volatile uint32_t*)(DDR_BASE + 0x160)) /* DDR SDRAM timing configuration 4 */ +#define DDR_TIMING_CFG_5 ((volatile uint32_t*)(DDR_BASE + 0x164)) /* DDR SDRAM timing configuration 5 */ +#define DDR_TIMING_CFG_6 ((volatile uint32_t*)(DDR_BASE + 0x168)) /* DDR SDRAM timing configuration 6 */ +#define DDR_TIMING_CFG_7 ((volatile uint32_t*)(DDR_BASE + 0x16C)) /* DDR SDRAM timing configuration 7 */ +#define DDR_TIMING_CFG_8 ((volatile uint32_t*)(DDR_BASE + 0x250)) /* DDR SDRAM timing configuration 8 */ +#define DDR_ZQ_CNTL ((volatile uint32_t*)(DDR_BASE + 0x170)) /* DDR ZQ calibration control */ +#define DDR_WRLVL_CNTL ((volatile uint32_t*)(DDR_BASE + 0x174)) /* DDR write leveling control */ +#define DDR_WRLVL_CNTL_2 ((volatile uint32_t*)(DDR_BASE + 0x190)) /* DDR write leveling control 2 */ +#define DDR_WRLVL_CNTL_3 ((volatile uint32_t*)(DDR_BASE + 0x194)) /* DDR write leveling control 3 */ +#define DDR_SR_CNTR ((volatile uint32_t*)(DDR_BASE + 0x17C)) /* DDR Self Refresh Counter */ +#define DDR_SDRAM_RCW_1 ((volatile uint32_t*)(DDR_BASE + 0x180)) /* DDR Register Control Word 1 */ +#define DDR_SDRAM_RCW_2 ((volatile uint32_t*)(DDR_BASE + 0x184)) /* DDR Register Control Word 2 */ +#define DDR_SDRAM_RCW_3 ((volatile uint32_t*)(DDR_BASE + 0x1A0)) /* DDR Register Control Word 3 */ +#define DDR_SDRAM_RCW_4 ((volatile uint32_t*)(DDR_BASE + 0x1A4)) /* DDR Register Control Word 4 */ +#define DDR_SDRAM_RCW_5 ((volatile uint32_t*)(DDR_BASE + 0x1A8)) /* DDR Register Control Word 5 */ +#define DDR_SDRAM_RCW_6 ((volatile uint32_t*)(DDR_BASE + 0x1AC)) /* DDR Register Control Word 6 */ +#define DDR_DDRCDR_1 ((volatile uint32_t*)(DDR_BASE + 0xB28)) /* DDR Control Driver Register 1 */ +#define DDR_DDRCDR_2 ((volatile uint32_t*)(DDR_BASE + 0xB2C)) /* DDR Control Driver Register 2 */ +#define DDR_DDRDSR_1 ((volatile uint32_t*)(DDR_BASE + 0xB20)) /* DDR Debug Status Register 1 */ +#define DDR_DDRDSR_2 ((volatile uint32_t*)(DDR_BASE + 0xB24)) /* DDR Debug Status Register 2 */ +#define DDR_ERR_DISABLE ((volatile uint32_t*)(DDR_BASE + 0xE44)) /* Memory error disable */ +#define DDR_ERR_INT_EN ((volatile uint32_t*)(DDR_BASE + 0xE48)) /* Memory error interrupt enable */ +#define DDR_ERR_SBE ((volatile uint32_t*)(DDR_BASE + 0xE58)) /* Single-Bit ECC memory error management */ +#define DDR_SDRAM_MODE ((volatile uint32_t*)(DDR_BASE + 0x118)) /* DDR SDRAM mode configuration */ +#define DDR_SDRAM_MODE_2 ((volatile uint32_t*)(DDR_BASE + 0x11C)) /* DDR SDRAM mode configuration 2 */ +#define DDR_SDRAM_MODE_3 ((volatile uint32_t*)(DDR_BASE + 0x200)) /* DDR SDRAM mode configuration 3 */ +#define DDR_SDRAM_MODE_4 ((volatile uint32_t*)(DDR_BASE + 0x204)) /* DDR SDRAM mode configuration 4 */ +#define DDR_SDRAM_MODE_5 ((volatile uint32_t*)(DDR_BASE + 0x208)) /* DDR SDRAM mode configuration 5 */ +#define DDR_SDRAM_MODE_6 ((volatile uint32_t*)(DDR_BASE + 0x20C)) /* DDR SDRAM mode configuration 6 */ +#define DDR_SDRAM_MODE_7 ((volatile uint32_t*)(DDR_BASE + 0x210)) /* DDR SDRAM mode configuration 7 */ +#define DDR_SDRAM_MODE_8 ((volatile uint32_t*)(DDR_BASE + 0x214)) /* DDR SDRAM mode configuration 8 */ +#define DDR_SDRAM_MODE_9 ((volatile uint32_t*)(DDR_BASE + 0x220)) /* DDR SDRAM mode configuration 9 */ +#define DDR_SDRAM_MODE_10 ((volatile uint32_t*)(DDR_BASE + 0x224)) /* DDR SDRAM mode configuration 10 */ +#define DDR_SDRAM_MD_CNTL ((volatile uint32_t*)(DDR_BASE + 0x120)) /* DDR SDRAM mode control */ +#define DDR_SDRAM_CLK_CNTL ((volatile uint32_t*)(DDR_BASE + 0x130)) /* DDR SDRAM clock control */ + +#define DDR_DEBUG_9 ((volatile uint32_t*)(DDR_BASE + 0xF20)) +#define DDR_DEBUG_10 ((volatile uint32_t*)(DDR_BASE + 0xF24)) +#define DDR_DEBUG_11 ((volatile uint32_t*)(DDR_BASE + 0xF28)) +#define DDR_DEBUG_12 ((volatile uint32_t*)(DDR_BASE + 0xF2C)) +#define DDR_DEBUG_13 ((volatile uint32_t*)(DDR_BASE + 0xF30)) +#define DDR_DEBUG_14 ((volatile uint32_t*)(DDR_BASE + 0xF34)) +#define DDR_DEBUG_19 ((volatile uint32_t*)(DDR_BASE + 0xF48)) +#define DDR_DEBUG_29 ((volatile uint32_t*)(DDR_BASE + 0xF70)) + +#define DDR_SDRAM_CFG_MEM_EN 0x80000000 /* SDRAM interface logic is enabled */ +#define DDR_SDRAM_CFG_ECC_EN 0x20000000 +#define DDR_SDRAM_CFG_32_BE 0x00080000 +#define DDR_SDRAM_CFG_2_D_INIT 0x00000010 /* data initialization in progress */ +#define DDR_SDRAM_CFG_HSE 0x00000008 +#define DDR_SDRAM_CFG_BI 0x00000001 /* Bypass initialization */ +#define DDR_SDRAM_CFG_SDRAM_TYPE_MASK 0x07000000 +#define DDR_SDRAM_CFG_SDRAM_TYPE(n) (((n) & 0x7) << 24) +#define DDR_SDRAM_TYPE_DDR4 5 +#define DDR_SDRAM_INTERVAL_BSTOPRE 0x3FFF + + +/* eSPI */ +#define ESPI_MAX_CS_NUM 4 +#define ESPI_MAX_RX_LEN (1 << 16) +#define ESPI_FIFO_WORD 4 + +#define ESPI_BASE (CCSRBAR + 0x7000) +#define ESPI_SPMODE ((volatile uint32_t*)(ESPI_BASE + 0x00)) /* controls eSPI general operation mode */ +#define ESPI_SPIE ((volatile uint32_t*)(ESPI_BASE + 0x04)) /* controls interrupts and report events */ +#define ESPI_SPIM ((volatile uint32_t*)(ESPI_BASE + 0x08)) /* enables/masks interrupts */ +#define ESPI_SPCOM ((volatile uint32_t*)(ESPI_BASE + 0x0C)) /* command frame information */ +#define ESPI_SPITF ((volatile uint32_t*)(ESPI_BASE + 0x10)) /* transmit FIFO access register (32-bit) */ +#define ESPI_SPIRF ((volatile uint32_t*)(ESPI_BASE + 0x14)) /* read-only receive data register (32-bit) */ +#define ESPI_SPITF8 ((volatile uint8_t*)( ESPI_BASE + 0x10)) /* transmit FIFO access register (8-bit) */ +#define ESPI_SPIRF8 ((volatile uint8_t*)( ESPI_BASE + 0x14)) /* read-only receive data register (8-bit) */ +#define ESPI_SPCSMODE(x) ((volatile uint32_t*)(ESPI_BASE + 0x20 + ((cs) * 4))) /* controls master operation with chip select 0-3 */ + +#define ESPI_SPMODE_EN (0x80000000) /* Enable eSPI */ +#define ESPI_SPMODE_TXTHR(x) ((x) << 8) /* Tx FIFO threshold (1-32) */ +#define ESPI_SPMODE_RXTHR(x) ((x) << 0) /* Rx FIFO threshold (0-31) */ + +#define ESPI_SPCOM_CS(x) ((x) << 30) /* Chip select-chip select for which transaction is destined */ +#define ESPI_SPCOM_RXSKIP(x) ((x) << 16) /* Number of characters skipped for reception from frame start */ +#define ESPI_SPCOM_TRANLEN(x) (((x) - 1) << 0) /* Transaction length */ + +#define ESPI_SPIE_TXE (1 << 15) /* transmit empty */ +#define ESPI_SPIE_DON (1 << 14) /* Last character was transmitted */ +#define ESPI_SPIE_RXT (1 << 13) /* Rx FIFO has more than RXTHR bytes */ +#define ESPI_SPIE_RNE (1 << 9) /* receive not empty */ +#define ESPI_SPIE_TNF (1 << 8) /* transmit not full */ +#define ESPI_SPIE_RXCNT(n) (((n) >> 24) & 0x3F) /* The current number of full Rx FIFO bytes */ + +#define ESPI_CSMODE_CI 0x80000000 /* Inactive high */ +#define ESPI_CSMODE_CP 0x40000000 /* Begin edge clock */ +#define ESPI_CSMODE_REV 0x20000000 /* MSB first */ +#define ESPI_CSMODE_DIV16 0x10000000 /* divide system clock by 16 */ +#define ESPI_CSMODE_PM(x) (((x) & 0xF) << 24) /* presale modulus select */ +#define ESPI_CSMODE_POL 0x00100000 /* asserted low */ +#define ESPI_CSMODE_LEN(x) ((((x) - 1) & 0xF) << 16) /* Character length in bits per character */ +#define ESPI_CSMODE_CSBEF(x) (((x) & 0xF) << 12) /* CS assertion time in bits before frame start */ +#define ESPI_CSMODE_CSAFT(x) (((x) & 0xF) << 8) /* CS assertion time in bits after frame end */ +#define ESPI_CSMODE_CSCG(x) (((x) & 0xF) << 3) /* Clock gaps between transmitted frames according to this size */ + + +/* generic share NXP QorIQ driver code */ +#include "nxp_ppc.c" + + +#ifdef ENABLE_BUS_CLK_CALC +static uint32_t hal_get_bus_clk(void) +{ + /* compute bus clock (system input * ratio) */ + uint32_t plat_clk, bus_clk; + uint32_t plat_ratio = get32(CLOCKING_PLLPGSR); /* see SYS_PLL_RAT in RCW */ + /* mask and shift by 1 to get platform ratio */ + plat_ratio = ((plat_ratio & 0x3E) >> 1); /* default is 4 (4:1) */ + plat_clk = SYS_CLK * plat_ratio; + bus_clk = plat_clk / 2; + return bus_clk; +} +#else +#define hal_get_bus_clk() (uint32_t)((SYS_CLK * 4) / 2) +#endif + +#define DELAY_US ((hal_get_bus_clk() / 16) / 1000000) +static void udelay(uint32_t delay_us) +{ + wait_ticks(delay_us * DELAY_US); +} + +static void set_law(uint8_t idx, uint32_t addr_h, uint32_t addr_l, + uint32_t trgt_id, uint32_t law_sz) +{ + LAWAR(idx) = 0; /* reset */ + LAWBARH(idx) = addr_h; + LAWBARL(idx) = addr_l; + LAWAR(idx) = (LAWAR_ENABLE | LAWAR_TRGT_ID(trgt_id) | law_sz); + + /* Read back so that we sync the writes */ + (void)LAWAR(idx); +} + +static void law_init(void) +{ + /* Buffer Manager (BMan) (control) - probably not required */ + set_law(3, 0xF, 0xF4000000, LAW_TRGT_BMAN, LAW_SIZE_32MB); +} + + +/* ---- eSPI Driver ---- */ +#ifdef ENABLE_ESPI +void hal_espi_init(uint32_t cs, uint32_t clock_hz, uint32_t mode) +{ + uint32_t spibrg = hal_get_bus_clk() / 2, pm, csmode; + + /* Enable eSPI with TX threadshold 4 and RX threshold 3 */ + set32(ESPI_SPMODE, (ESPI_SPMODE_EN | ESPI_SPMODE_TXTHR(4) | + ESPI_SPMODE_RXTHR(3))); + + set32(ESPI_SPIE, 0xffffffff); /* Clear all eSPI events */ + set32(ESPI_SPIM, 0x00000000); /* Mask all eSPI interrupts */ + + csmode = (ESPI_CSMODE_REV | ESPI_CSMODE_POL | ESPI_CSMODE_LEN(8) | + ESPI_CSMODE_CSBEF(0) | ESPI_CSMODE_CSAFT(0) | ESPI_CSMODE_CSCG(1)); + + /* calculate clock divisor */ + if (spibrg / clock_hz > 16) { + csmode |= ESPI_CSMODE_DIV16; + pm = (spibrg / (clock_hz * 16)); + } + else { + pm = (spibrg / (clock_hz)); + } + if (pm > 0) + pm--; + + csmode |= ESPI_CSMODE_PM(pm); + + if (mode & 1) + csmode |= ESPI_CSMODE_CP; + if (mode & 2) + csmode |= ESPI_CSMODE_CI; + + /* configure CS */ + set32(ESPI_SPCSMODE(cs), csmode); +} + +int hal_espi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, + int flags) +{ + uint32_t mosi, miso, xfer, event; + +#ifdef DEBUG_ESPI + wolfBoot_printf("CS %d, Sz %d, Flags %x\n", cs, sz, flags); +#endif + + if (sz > 0) { + /* assert CS - use max length and control CS with mode enable toggle */ + set32(ESPI_SPCOM, ESPI_SPCOM_CS(cs) | ESPI_SPCOM_TRANLEN(0x10000)); + set32(ESPI_SPIE, 0xffffffff); /* Clear all eSPI events */ + } + while (sz > 0) { + xfer = ESPI_FIFO_WORD; + if (xfer > sz) + xfer = sz; + + /* Transfer 4 or 1 */ + if (xfer == ESPI_FIFO_WORD) { + set32(ESPI_SPITF, *((uint32_t*)tx)); + } + else { + xfer = 1; + set8(ESPI_SPITF8, *((uint8_t*)tx)); + } + + /* wait till TX fifo is empty or done */ + while (1) { + event = get32(ESPI_SPIE); + if (event & (ESPI_SPIE_TXE | ESPI_SPIE_DON)) { + /* clear events */ + set32(ESPI_SPIE, (ESPI_SPIE_TXE | ESPI_SPIE_DON)); + break; + } + } + + /* wait till RX has enough data */ + while (1) { + event = get32(ESPI_SPIE); + if ((event & ESPI_SPIE_RNE) == 0) + continue; + #if defined(DEBUG_ESPI) && DEBUG_ESPI > 1 + wolfBoot_printf("event %x\n", event); + #endif + if (ESPI_SPIE_RXCNT(event) >= xfer) + break; + } + if (xfer == ESPI_FIFO_WORD) { + *((uint32_t*)rx) = get32(ESPI_SPIRF); + } + else { + *((uint8_t*)rx) = get8(ESPI_SPIRF8); + } + +#ifdef DEBUG_ESPI + wolfBoot_printf("MOSI %x, MISO %x\n", + *((uint32_t*)tx), *((uint32_t*)rx)); +#endif + tx += xfer; + rx += xfer; + sz -= xfer; + } + + if (!(flags & SPI_XFER_FLAG_CONTINUE)) { + /* toggle ESPI_SPMODE_EN - to deassert CS */ + set32(ESPI_SPMODE, get32(ESPI_SPMODE) & ~ESPI_SPMODE_EN); + set32(ESPI_SPMODE, get32(ESPI_SPMODE) | ESPI_SPMODE_EN); + } + + return 0; +} +void hal_espi_deinit(void) +{ + /* do nothing */ +} +#endif /* ENABLE_ESPI */ + +#ifdef DEBUG_UART +void uart_init(void) +{ + /* calc divisor for UART + * baud rate = CCSRBAR frequency รท (16 x [UDMB||UDLB]) + */ + /* compute UART divisor - round up */ + uint32_t div = (hal_get_bus_clk() + (16/2 * BAUD_RATE)) / (16 * BAUD_RATE); + + while (!(get8(UART_LSR(UART_SEL)) & UART_LSR_TEMT)) + ; + + /* set ier, fcr, mcr */ + set8(UART_IER(UART_SEL), 0); + set8(UART_FCR(UART_SEL), (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN)); + + /* enable baud rate access (DLAB=1) - divisor latch access bit*/ + set8(UART_LCR(UART_SEL), (UART_LCR_DLAB | UART_LCR_WLS)); + /* set divisor */ + set8(UART_DLB(UART_SEL), (div & 0xff)); + set8(UART_DMB(UART_SEL), ((div>>8) & 0xff)); + /* disable rate access (DLAB=0) */ + set8(UART_LCR(UART_SEL), (UART_LCR_WLS)); +} + +void uart_write(const char* buf, uint32_t sz) +{ + uint32_t pos = 0; + while (sz-- > 0) { + char c = buf[pos++]; + if (c == '\n') { /* handle CRLF */ + while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0); + set8(UART_THR(UART_SEL), '\r'); + } + while ((get8(UART_LSR(UART_SEL)) & UART_LSR_THRE) == 0); + set8(UART_THR(UART_SEL), c); + } +} +#endif /* DEBUG_UART */ + +#if FLASH_CFI_WIDTH == 16 +#define FLASH_IO8_WRITE(n, val) *((volatile uint16_t*)(FLASH_BASE_ADDR + (n))) = (((val) << 8) | (val)) +#define FLASH_IO8_READ(n) (uint8_t)(*((volatile uint16_t*)(FLASH_BASE_ADDR + (n))) >> 8) +#else +#define FLASH_IO8_WRITE(n, val) *((volatile uint8_t*)(FLASH_BASE_ADDR + (n))) = (val) +#define FLASH_IO8_READ(n) *((volatile uint8_t*)(FLASH_BASE_ADDR + (n))) +#endif + +#ifndef BUILD_LOADER_STAGE1 +static int RAMFUNCTION hal_flash_getid(void) +{ +#ifdef ENABLE_IFC + int i; + uint8_t manfid[4]; + + /* Get Manufacture ID */ + +#if 0 + /* Unlock sequence */ + FLASH_IO8_WRITE(0xAAA, AMD_CMD_UNLOCK_START); + FLASH_IO8_WRITE(0x555, AMD_CMD_UNLOCK_ACK); +#endif + + /* Reset */ + //FLASH_IO8_WRITE(0, AMD_CMD_RESET); + //udelay(1); + + /* Read CFI */ + FLASH_IO8_WRITE(0xAAA, FLASH_CMD_CFI); + udelay(1000); + + for (i=0; i<(int)sizeof(manfid); i++) { + manfid[i] = FLASH_IO8_READ(i); + } + + /* Leave READ CFI */ + FLASH_IO8_WRITE(0, AMD_CMD_RESET); + udelay(1); + + wolfBoot_printf("Flash ID: 0x%x 0x%x 0x%x 0x%x\n", + manfid[0], manfid[1], manfid[2], manfid[3]); +#endif /* ENABLE_IFC */ + return 0; +} +#endif /* BUILD_LOADER_STAGE1 */ + +static void hal_flash_init(void) +{ +#ifdef ENABLE_IFC + /* IFC - NOR Flash */ + /* LAW is already set in boot_ppc_start.S:flash_law */ + + /* NOR IFC Flash Timing Parameters */ + set32(IFC_FTIM0(0), (IFC_FTIM0_NOR_TACSE(4) | + IFC_FTIM0_NOR_TEADC(5) | + IFC_FTIM0_NOR_TEAHC(5))); + set32(IFC_FTIM1(0), (IFC_FTIM1_NOR_TACO(53) | + IFC_FTIM1_NOR_TRAD(26) | + IFC_FTIM1_NOR_TSEQ(19))); + set32(IFC_FTIM2(0), (IFC_FTIM2_NOR_TCS(4) | + IFC_FTIM2_NOR_TCH(4) | + IFC_FTIM2_NOR_TWPH(14) | + IFC_FTIM2_NOR_TWP(28))); + set32(IFC_FTIM3(0), 0); + /* NOR IFC Definitions (CS0) */ + set32(IFC_CSPR_EXT(0), FLASH_BASE_PHYS_HIGH); + set32(IFC_CSPR(0), (IFC_CSPR_PHYS_ADDR(FLASH_BASE_ADDR) | + #if FLASH_CFI_WIDTH == 16 + IFC_CSPR_PORT_SIZE_16 | + #else + IFC_CSPR_PORT_SIZE_8 | + #endif + IFC_CSPR_MSEL_NOR | + IFC_CSPR_V)); + set32(IFC_AMASK(0), IFC_AMASK_64MB); + set32(IFC_CSOR(0), 0x0000000C); /* TRHZ (80 clocks for read enable high) */ + + #ifndef BUILD_LOADER_STAGE1 + hal_flash_getid(); + #endif +#endif /* ENABLE_IFC */ +} + +static void hal_ddr_init(void) +{ +#ifdef ENABLE_DDR + uint32_t reg; + + /* If DDR is already enabled then just return */ + if (get32(DDR_SDRAM_CFG) & DDR_SDRAM_CFG_MEM_EN) { + return; + } + + /* Map LAW for DDR */ + set_law(15, 0, DDR_ADDRESS, LAW_TRGT_DDR_1, LAW_SIZE_2GB); + + /* Set early for clock / pin */ + set32(DDR_SDRAM_CLK_CNTL, DDR_SDRAM_CLK_CNTL_VAL); + + /* Setup DDR CS (chip select) bounds */ + set32(DDR_CS_BNDS(0), DDR_CS0_BNDS_VAL); + set32(DDR_CS_CONFIG(0), DDR_CS0_CONFIG_VAL); + set32(DDR_CS_CONFIG_2(0), DDR_CS_CONFIG_2_VAL); + set32(DDR_CS_BNDS(1), DDR_CS1_BNDS_VAL); + set32(DDR_CS_CONFIG(1), DDR_CS1_CONFIG_VAL); + set32(DDR_CS_CONFIG_2(1), DDR_CS_CONFIG_2_VAL); + set32(DDR_CS_BNDS(2), DDR_CS2_BNDS_VAL); + set32(DDR_CS_CONFIG(2), DDR_CS2_CONFIG_VAL); + set32(DDR_CS_CONFIG_2(2), DDR_CS_CONFIG_2_VAL); + set32(DDR_CS_BNDS(3), DDR_CS3_BNDS_VAL); + set32(DDR_CS_CONFIG(3), DDR_CS3_CONFIG_VAL); + set32(DDR_CS_CONFIG_2(3), DDR_CS_CONFIG_2_VAL); + + /* DDR SDRAM timing configuration */ + set32(DDR_TIMING_CFG_3, DDR_TIMING_CFG_3_VAL); + set32(DDR_TIMING_CFG_0, DDR_TIMING_CFG_0_VAL); + set32(DDR_TIMING_CFG_1, DDR_TIMING_CFG_1_VAL); + set32(DDR_TIMING_CFG_2, DDR_TIMING_CFG_2_VAL); + set32(DDR_TIMING_CFG_4, DDR_TIMING_CFG_4_VAL); + set32(DDR_TIMING_CFG_5, DDR_TIMING_CFG_5_VAL); + set32(DDR_TIMING_CFG_8, DDR_TIMING_CFG_8_VAL); + + set32(DDR_ZQ_CNTL, DDR_ZQ_CNTL_VAL); + set32(DDR_SDRAM_CFG_3, 0); + + /* DDR SDRAM mode configuration */ + set32(DDR_SDRAM_MODE, DDR_SDRAM_MODE_VAL); + set32(DDR_SDRAM_MODE_2, DDR_SDRAM_MODE_2_VAL); + set32(DDR_SDRAM_MODE_3, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_4, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_5, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_6, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_7, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_8, DDR_SDRAM_MODE_3_8_VAL); + set32(DDR_SDRAM_MODE_9, DDR_SDRAM_MODE_9_VAL); + set32(DDR_SDRAM_MODE_10, DDR_SDRAM_MODE_10_VAL); + set32(DDR_SDRAM_MD_CNTL, DDR_SDRAM_MD_CNTL_VAL); + + /* DDR Configuration */ +#ifdef USE_ERRATA_DDRA009663 + /* Errata A-009663 - DRAM VRef training (do not set precharge interval till after enable) */ + set32(DDR_SDRAM_INTERVAL, DDR_SDRAM_INTERVAL_VAL & ~DDR_SDRAM_INTERVAL_BSTOPRE); +#else + set32(DDR_SDRAM_INTERVAL, DDR_SDRAM_INTERVAL_VAL); +#endif + set32(DDR_DATA_INIT, DDR_DATA_INIT_VAL); + set32(DDR_WRLVL_CNTL, DDR_WRLVL_CNTL_VAL); + set32(DDR_WRLVL_CNTL_2, DDR_WRLVL_CNTL_2_VAL); + set32(DDR_WRLVL_CNTL_3, DDR_WRLVL_CNTL_3_VAL); + set32(DDR_SR_CNTR, 0); + set32(DDR_SDRAM_RCW_1, 0); + set32(DDR_SDRAM_RCW_2, 0); + set32(DDR_SDRAM_RCW_3, 0); + set32(DDR_SDRAM_RCW_4, 0); + set32(DDR_SDRAM_RCW_5, 0); + set32(DDR_SDRAM_RCW_6, 0); + set32(DDR_DDRCDR_1, DDR_DDRCDR_1_VAL); + set32(DDR_SDRAM_CFG_2, DDR_SDRAM_CFG_2_VAL); + set32(DDR_INIT_ADDR, 0); + set32(DDR_INIT_EXT_ADDR, 0); + set32(DDR_DDRCDR_2, DDR_DDRCDR_2_VAL); + set32(DDR_ERR_DISABLE, 0); + set32(DDR_ERR_INT_EN, DDR_ERR_INT_EN_VAL); + set32(DDR_ERR_SBE, DDR_ERR_SBE_VAL); + + /* Set values, but do not enable the DDR yet */ + set32(DDR_SDRAM_CFG, DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN); + asm volatile("sync;isync"); + + /* busy wait for ~500us */ + udelay(500); + asm volatile("sync;isync"); + + /* Enable controller */ + reg = get32(DDR_SDRAM_CFG) & ~DDR_SDRAM_CFG_BI; + set32(DDR_SDRAM_CFG, reg | DDR_SDRAM_CFG_MEM_EN); + asm volatile("sync;isync"); + +#ifdef USE_ERRATA_DDRA008378 + /* Errata A-008378: training in DDR4 mode */ + /* write to DEBUG_29[8:11] a value of 4'b1001 before controller is enabled */ + reg = get32(DDR_DEBUG_29); + reg |= (0x9 << 20); + set32(DDR_DEBUG_29, reg); +#endif +#ifdef USE_ERRATA_DDRA008109 + /* Errata A-008109: Memory controller could fail to complete initialization */ + reg = get32(DDR_SDRAM_CFG_2); + reg |= 0x800; /* set DDR_SLOW */ + set32(DDR_SDRAM_CFG_2, reg); + reg = get32(DDR_DEBUG_19); + reg |= 0x2; + set32(DDR_DEBUG_19, reg); + set32(DDR_DEBUG_29, 0x30000000); +#endif +#ifdef USE_ERRATA_DDRA009942 + /* Errata A-009942: DDR controller can train to non-optimal setting */ + reg = get32(DDR_DEBUG_29); + reg &= ~0xFF0FFF00; + reg |= 0x0070006F; /* CPO calculated */ + set32(DDR_DEBUG_29, reg); +#endif + + /* Wait for data initialization to complete */ + while (get32(DDR_SDRAM_CFG_2) & DDR_SDRAM_CFG_2_D_INIT) { + /* busy wait loop - throttle polling */ + udelay(10000); + } + +#ifdef USE_ERRATA_DDRA009663 + /* Errata A-009663 - Write real precharge interval */ + set32(DDR_SDRAM_INTERVAL, DDR_SDRAM_INTERVAL_VAL); +#endif + + /* DDR - TBL=1, Entry 12/13 */ + set_tlb(1, 12, DDR_ADDRESS, DDR_ADDRESS, 0, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, + 0, BOOKE_PAGESZ_1G, 1); + set_tlb(1, 13, DDR_ADDRESS + 0x40000000, DDR_ADDRESS + 0x40000000, 0, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, + 0, BOOKE_PAGESZ_1G, 1); +#endif +} + + +void hal_early_init(void) +{ + /* enable timebase on core 0 */ + set32(RCPM_PCTBENR, (1 << 0)); + + /* invalidate the CPC before DDR gets enabled */ + set32((volatile uint32_t*)(CPC_BASE + CPCCSR0), + (CPCCSR0_CPCFI | CPCCSR0_CPCLFC)); + while (get32((volatile uint32_t*)(CPC_BASE + CPCCSR0)) & + (CPCCSR0_CPCFI | CPCCSR0_CPCLFC)); + + /* set DCSRCR space = 1G */ + set32(DCFG_DCSR, (get32(DCFG_DCSR) | CORENET_DCSR_SZ_1G)); + get32(DCFG_DCSR); /* read again */ + + /* disable devices */ + set32(DCFG_DEVDISR1, + ((1 << 19) | /* Disable USB1 */ + (1 << 18) | /* Disable USB2 */ + (1 << 15) | /* SATA1 */ + (1 << 2) /* DIU (LCD) */ + )); + + hal_ddr_init(); +} + +static void hal_cpld_init(void) +{ +#ifdef ENABLE_CPLD + #ifdef DEBUG + uint32_t fw; + #endif + /* CPLD IFC Timing Parameters */ + set32(IFC_FTIM0(2), (IFC_FTIM0_GPCM_TACSE(14) | + IFC_FTIM0_GPCM_TEADC(14) | + IFC_FTIM0_GPCM_TEAHC(14))); + set32(IFC_FTIM1(2), (IFC_FTIM1_GPCM_TACO(14) | + IFC_FTIM1_GPCM_TRAD(31))); + set32(IFC_FTIM2(2), (IFC_FTIM2_GPCM_TCS(14) | + IFC_FTIM2_GPCM_TCH(8) | + IFC_FTIM2_GPCM_TWP(31))); + set32(IFC_FTIM3(2), 0); + + /* CPLD IFC Definitions (CS2) */ + set32(IFC_CSPR_EXT(2), CPLD_BASE_PHYS_HIGH); + set32(IFC_CSPR(2), (IFC_CSPR_PHYS_ADDR(CPLD_BASE) | + IFC_CSPR_PORT_SIZE_8 | + IFC_CSPR_MSEL_GPCM | + IFC_CSPR_V)); + set32(IFC_AMASK(2), IFC_AMASK_64KB); + set32(IFC_CSOR(2), 0); + + /* IFC - CPLD */ + set_law(2, CPLD_BASE_PHYS_HIGH, CPLD_BASE, + LAW_TRGT_IFC, LAW_SIZE_4KB); + + /* CPLD - TBL=1, Entry 11 */ + set_tlb(1, 11, CPLD_BASE, CPLD_BASE, CPLD_BASE_PHYS_HIGH, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, + 0, BOOKE_PAGESZ_4K, 1); + +#ifdef DEBUG + fw = get8(CPLD_DATA(HW_VER)); + wolfBoot_printf("CPLD HW Rev: 0x%x\n", fw); + fw = get8(CPLD_DATA(SW_VER)); + wolfBoot_printf("CPLD SW Rev: 0x%x\n", fw); +#endif +#endif /* ENABLE_CPLD */ +} + + +/* QE Microcode */ +#if defined(ENABLE_QE) || defined(ENABLE_FMAN) + +/* Structure packing */ +#if (defined(__IAR_SYSTEMS_ICC__) && (__IAR_SYSTEMS_ICC__ > 8)) || \ + defined(__GNUC__) + #define QE_PACKED __attribute__ ((packed)) +#else + #define QE_PACKED +#endif + +/* QE based on work from Shlomi Gridish and Dave Liu at Freescale/NXP */ + +struct qe_header { + uint32_t length; /* Length of the entire structure, in bytes */ + uint8_t magic[3]; /* Set to { 'Q', 'E', 'F' } */ + uint8_t version; /* Version of this layout. First ver is '1' */ +} QE_PACKED; + +struct qe_soc { + uint16_t model; /* The SOC model */ + uint8_t major; /* The SOC revision major */ + uint8_t minor; /* The SOC revision minor */ +} QE_PACKED; + +struct qe_microcode { + uint8_t id[32]; /* Null-terminated identifier */ + uint32_t traps[16]; /* Trap addresses, 0 == ignore */ + uint32_t eccr; /* The value for the ECCR register */ + uint32_t iram_offset; /* Offset into I-RAM for the code */ + uint32_t count; /* Number of 32-bit words of the code */ + uint32_t code_offset; /* Offset of the actual microcode */ + uint8_t major; /* The microcode version major */ + uint8_t minor; /* The microcode version minor */ + uint8_t revision; /* The microcode version revision */ + uint8_t padding; /* Reserved, for alignment */ + uint8_t reserved[4]; /* Reserved, for future expansion */ +} QE_PACKED; + +struct qe_firmware { + struct qe_header header; + uint8_t id[62]; /* Null-terminated identifier string */ + uint8_t split; /* 0 = shared I-RAM, 1 = split I-RAM */ + uint8_t count; /* Number of microcode[] structures */ + struct qe_soc soc; + uint8_t padding[4]; /* Reserved, for alignment */ + uint64_t extended_modes; /* Extended modes */ + uint32_t vtraps[8]; /* Virtual trap addresses */ + uint8_t reserved[4]; /* Reserved, for future expansion */ + struct qe_microcode microcode[1]; + /* All microcode binaries should be located here */ + /* CRC32 should be located here, after the microcode binaries */ +} QE_PACKED; + +static void qe_upload_microcode(const struct qe_firmware *firmware, + const struct qe_microcode *ucode) +{ + const uint32_t *code = (void*)firmware + ucode->code_offset; + unsigned int i; + + wolfBoot_printf("QE: uploading '%s' version %u.%u.%u\n", + ucode->id, ucode->major, ucode->minor, ucode->revision); + + /* Use auto-increment */ + set32(QE_IRAM_IADD, ucode->iram_offset | + QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR); + + /* Copy 32-bits at a time to iRAM */ + for (i = 0; i < ucode->count; i++) { + set32(QE_IRAM_IDATA, code[i]); + } +} + +/* Upload a microcode to the I-RAM at a specific address */ +static int qe_upload_firmware(const struct qe_firmware *firmware) +{ + unsigned int i, j; + uint32_t crc; + size_t calc_size = sizeof(struct qe_firmware); + size_t length; + const struct qe_header *hdr; + + hdr = &firmware->header; + length = hdr->length; + + /* Check the magic */ + if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') || + (hdr->magic[2] != 'F')) { + wolfBoot_printf("QE firmware header invalid!\n"); + return -1; + } + + /* Check the version */ + if (hdr->version != 1) { + wolfBoot_printf("QE version %d unsupported!\n", hdr->version); + return -1; + } + + /* Validate some of the fields */ + if ((firmware->count < 1) || (firmware->count > QE_MAX_RISC)) { + wolfBoot_printf("QE count %d invalid!\n", firmware->count); + return -1; + } + + /* Validate the length and check if there's a CRC */ + calc_size += (firmware->count - 1) * sizeof(struct qe_microcode); + for (i = 0; i < firmware->count; i++) { + /* For situations where the second RISC uses the same microcode + * as the first, the 'code_offset' and 'count' fields will be + * zero, so it's okay to add those. */ + calc_size += sizeof(uint32_t) * firmware->microcode[i].count; + } + + /* Validate the length */ + if (length != calc_size + sizeof(uint32_t)) { + wolfBoot_printf("QE length %d invalid!\n", length); + return -1; + } + +#ifdef ENABLE_QE_CRC32 + /* Validate the CRC */ + crc = *(uint32_t *)((void *)firmware + calc_size); + if (crc != (crc32(-1, (const void *) firmware, calc_size) ^ -1)) { + wolfBoot_printf("QE firmware CRC is invalid\n"); + return -1; + } +#endif + + /* Use common instruction RAM if not split (default is split) */ + if (!firmware->split) { + set16(QE_CP_CERCR, get16(QE_CP_CERCR) | QE_CP_CERCR_CIR); + } + + wolfBoot_printf("QE: Length %d, Count %d\n", length, firmware->count); + + /* Loop through each microcode. */ + for (i = 0; i < firmware->count; i++) { + const struct qe_microcode *ucode = &firmware->microcode[i]; + uint32_t trapCount = 0; + + /* Upload a microcode if it's present */ + if (ucode->code_offset) { + qe_upload_microcode(firmware, ucode); + } + + /* Program the traps for this processor (max 16) */ + for (j = 0; j < 16; j++) { + uint32_t trap = ucode->traps[j]; + if (trap) { + trapCount++; + set32(QE_RSP_TIBCR(i, j), trap); + } + } + + /* Enable traps */ + set32(QE_RSP_ECCR(i), ucode->eccr); + wolfBoot_printf("QE: Traps %d\n", trapCount); + } + + return 0; +} + +#endif + +/* ---- QUICC Engine Driver ---- */ +#ifdef ENABLE_QE + +static void qe_issue_cmd(uint32_t cmd, uint32_t sbc, uint8_t mcn, + uint32_t cmd_data) +{ + set32(QE_CP_CECDR, cmd_data); + set32(QE_CP_CECR, + sbc | /* sub block code */ + QE_CR_FLG | /* flag: set by software, cleared by hardware */ + ((uint32_t)mcn << QE_CR_PROTOCOL_SHIFT) | /* MCC/QMC channel number */ + cmd /* opcode (reset sets 0x8000_0000) */ + ); + + /* Wait for the command semaphore flag to clear */ + while (get32(QE_CP_CECR) & QE_CR_FLG); +} + +static int hal_qe_init(void) +{ + int ret; + uint32_t sdma_base; + + /* Upload microcode to IRAM */ + ret = qe_upload_firmware((const struct qe_firmware *)QE_FW_ADDR); + if (ret == 0) { + /* enable the microcode in IRAM */ + set32(QE_IRAM_IREADY, QE_IRAM_READY); + + /* Serial DMA */ + /* All of DMA transaction in bus 1 */ + set32(QE_SDMA_SDAQR, 0); + set32(QE_SDMA_SDAQMR, 0); + + /* Allocate 2KB temporary buffer for sdma */ + sdma_base = 0; + set32(QE_SDMA_SDEBCR, sdma_base & QE_SDEBCR_BA_MASK); + + /* Clear sdma status */ + set32(QE_SDMA_SDSR, 0x03000000); + + /* Enable global mode on bus 1, and 2KB buffer size */ + set32(QE_SDMA_SDMR, QE_SDMR_GLB_1_MSK | (0x3 << QE_SDMR_CEN_SHIFT)); + + /* Reset QUICC Engine */ + qe_issue_cmd(QE_RESET, 0, 0, 0); + } + + return ret; +} +#endif /* ENABLE_QUICC */ + +#ifdef ENABLE_FMAN +static int hal_fman_init(void) +{ + int ret; + + /* Upload microcode to IRAM */ + ret = qe_upload_firmware((const struct qe_firmware *)FMAN_FW_ADDR); + if (ret == 0) { + + } + return ret; +} +#endif /* ENABLE_FMAN */ + + +/* SMP Multi-Processor Driver */ +#ifdef ENABLE_MP + +/* from boot_ppc_core.S */ +extern uint32_t _mp_page_start; +extern uint32_t _spin_table; +extern uint32_t _bootpg_addr; + +/* Startup additional cores with spin table and synchronize the timebase */ +static void hal_mp_up(uint32_t bootpg) +{ + uint32_t all_cores, active_cores, whoami, bpcr; + uint8_t *spin_table_addr; + int timeout = 50, i; + + whoami = get32(PIC_WHOAMI); /* Get current running core number */ + all_cores = ((1 << CPU_NUMCORES) - 1); /* mask of all cores */ + active_cores = (1 << whoami); /* current running cores */ + + /* Calculate location of spin table in BPTR */ + spin_table_addr = (uint8_t*)(BOOT_ROM_ADDR + + ((uint32_t)&_spin_table - (uint32_t)&_mp_page_start)); + + wolfBoot_printf("MP: Starting core 2 (spin table %p)\n", + spin_table_addr); + + /* Set the boot page translation reigster */ + set32(LCC_BSTRL, bootpg); + set32(LCC_BSTAR, (LCC_BSTAR_EN | + LCC_BSTAR_LAWTRGT(LAW_TRGT_IFC) | + LAW_SIZE_4KB)); + (void)get32(LCC_BSTAR); /* read back to sync */ + + /* Enable time base on current core only */ + set32(RCPM_PCTBENR, (1 << whoami)); + + /* Release the CPU core(s) */ + set32(DCFG_BRR, all_cores); + asm volatile("sync; isync; msync"); + + /* wait for other core to start */ + while (timeout) { + for (i = 0; i < CPU_NUMCORES; i++) { + uint32_t* entry = (uint32_t*)(spin_table_addr + + (i * ENTRY_SIZE) + ENTRY_ADDR_LOWER); + if (*entry) { + active_cores |= (1 << i); + } + } + if ((active_cores & all_cores) == all_cores) { + break; + } + + udelay(100); + timeout--; + } + + if (timeout == 0) { + wolfBoot_printf("MP: Timeout enabling additional cores!\n"); + } + + /* Disable all timebases */ + set32(RCPM_PCTBENR, 0); + + /* Reset our timebase */ + mtspr(SPRN_TBWU, 0); + mtspr(SPRN_TBWL, 0); + + /* Enable timebase for all cores */ + set32(RCPM_PCTBENR, all_cores); +} + +static void hal_mp_init(void) +{ + uint32_t *fixup = (uint32_t*)&_mp_page_start; + size_t bootpg; + int i_tlb = 0; /* always 0 */ + size_t i; + const uint32_t *s; + uint32_t *d; + + /* Assign virtual boot page at end of DDR */ + bootpg = DDR_ADDRESS + DDR_SIZE - BOOT_ROM_SIZE; + + /* Store the boot page address for use by additional CPU cores */ + _bootpg_addr = bootpg; + + /* map reset page to bootpg so we can copy code there */ + disable_tlb1(i_tlb); + set_tlb(1, i_tlb, BOOT_ROM_ADDR, bootpg, 0, /* tlb, epn, rpn, urpn */ + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, /* perms, wimge */ + 0, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */ + + /* copy startup code to virtually mapped boot address */ + /* do not use memcpy due to compiler array bounds report (not valid) */ + s = (const uint32_t*)fixup; + d = (uint32_t*)BOOT_ROM_ADDR; + for (i = 0; i < BOOT_ROM_SIZE/4; i++) { + d[i] = s[i]; + } + + /* start core and wait for it to be enabled */ + hal_mp_up(bootpg); +} +#endif /* ENABLE_MP */ + + + +void hal_init(void) +{ + law_init(); + +#ifdef DEBUG_UART + uart_init(); + uart_write("wolfBoot HAL Init\n", 18); +#endif + + hal_flash_init(); + hal_cpld_init(); + +#ifdef ENABLE_QE + if (hal_qe_init() != 0) { + wolfBoot_printf("QE: Engine init failed!\n"); + } +#endif +#ifdef ENABLE_FMAN + if (hal_fman_init() != 0) { + wolfBoot_printf("FMAN: init failed!\n"); + } +#endif +#ifdef ENABLE_MP + hal_mp_init(); +#endif + + /* Hardware Tests */ +#if defined(ENABLE_DDR) && defined(TEST_DDR) + if (test_ddr() != 0) { + wolfBoot_printf("DDR Test Failed!\n"); + } +#endif + +#if defined(ENABLE_IFC) && defined(TEST_FLASH) + if (test_flash() != 0) { + wolfBoot_printf("Flash Test Failed!\n"); + } +#endif + +#if defined(ENABLE_ESPI) && defined(TEST_TPM) + if (test_tpm() != 0) { + wolfBoot_printf("TPM Test Failed!\n"); + } +#endif +} + +int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +{ + (void)address; + (void)data; + (void)len; + /* TODO: Implement NOR flash write using IFC */ + return 0; +} + +int RAMFUNCTION hal_flash_erase(uint32_t address, int len) +{ + (void)address; + (void)len; + /* TODO: Implement NOR flash erase using IFC */ + return 0; +} + +void RAMFUNCTION hal_flash_unlock(void) +{ + +} + +void RAMFUNCTION hal_flash_lock(void) +{ + +} + +void hal_prepare_boot(void) +{ + +} + +#ifdef MMU +void* hal_get_dts_address(void) +{ + return (void*)WOLFBOOT_DTS_BOOT_ADDRESS; +} +#endif + +#if defined(ENABLE_DDR) && defined(TEST_DDR) + +#ifndef TEST_DDR_OFFSET +#define TEST_DDR_OFFSET (2 * 1024 * 1024) +#endif +#ifndef TEST_DDR_TOTAL_SIZE +#define TEST_DDR_TOTAL_SIZE (2 * 1024) +#endif +#ifndef TEST_DDR_CHUNK_SIZE +#define TEST_DDR_CHUNK_SIZE 1024 +#endif + +static int test_ddr(void) +{ + int ret = 0; + int i; + uint32_t *ptr = (uint32_t*)(DDR_ADDRESS + TEST_DDR_OFFSET); + uint32_t tmp[TEST_DDR_CHUNK_SIZE/4]; + uint32_t total = 0; + + while (total < TEST_DDR_TOTAL_SIZE) { + /* test write to DDR */ + for (i=0; i DRAM + . = ALIGN(4); + + /* entry point branch offset to _reset */ + .reset : + { + KEEP(*(.reset)) + } > DRAM + . = ALIGN(4); + + .text : + { + _start_vector = .; + KEEP(*(.isr_vector)) + . = ALIGN(256); + _start_text = .; + *(.text*) + *(.rodata*) + *(.sdata*) + } > DRAM + + /* Read-only sections, merged into text segment: */ + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_r : { *(.gnu.version_r) } + .gnu.hash : { *(.gnu.hash) } + .rela.dyn : { *(.rela.dyn) } + + _stored_data = .; + + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(4); + KEEP(*(.ramcode)) + . = ALIGN(4); + _end_data = .; + } > DRAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + __bss_end__ = .; + . = ALIGN(16); + _end = .; + } > DRAM + +} + +PROVIDE(_start_heap = _end); + +/* If relocated to DDR already then use stack end from DDR */ +/* If debugging and DDR is not ready, use L1 or L2 */ +PROVIDE(_end_stack = _end + HEAP_SIZE + STACK_SIZE ); +/* PROVIDE(_end_stack = ORIGIN(L2RAM) + (LENGTH(L2RAM)) ); */ diff --git a/hal/nxp_t1024_stage1.ld b/hal/nxp_t1024_stage1.ld new file mode 100644 index 00000000..5a03c142 --- /dev/null +++ b/hal/nxp_t1024_stage1.ld @@ -0,0 +1,109 @@ +OUTPUT_ARCH( "powerpc" ) + +ENTRY( _reset ) + +/* Boot ROM out of reset mapped to 0xEFFFF000 */ +BASE_ADDR = @WOLFBOOT_STAGE1_FLASH_ADDR@; + +LOADER_STAGE1_SIZE = @WOLFBOOT_STAGE1_SIZE@; + +/* Boot initialization code */ +BOOTSTRAP_TLB = 0xEFFFF000; + +/* Entry point where RCW directs code to execute from */ +BOOTSTRAP_ENTRY = 0xEFFFFFFC; + +MEMORY +{ + /* Boot Location */ + FLASH (rx) : ORIGIN = BASE_ADDR, LENGTH = LOADER_STAGE1_SIZE + + /* L1 SRAM - 16KB */ + L1RAM (rwx) : ORIGIN = 0xF8F80000, LENGTH = 0x4000 + + /* L2 SRAM - 160KB */ + L2RAM (rwx) : ORIGIN = 0xFDFC0000, LENGTH = 0x28000 + + /* DDR - 2GB: Start at 16MB to avoid using 0x0 (NULL) addresses */ + DRAM (rwx) : ORIGIN = 0x1000000, LENGTH = 0x7FFFFFFF - 0x1000000 +} + +SECTIONS +{ + /* boot code boot_ppc_start.S for _reset */ + .boot BOOTSTRAP_TLB : + { + KEEP(*(.boot)) + } = 0xFFFC + . = ALIGN(4); + + /* entry point branch offset to _reset */ + .reset BOOTSTRAP_ENTRY : + { + KEEP(*(.reset)) + } = 0x4 + . = ALIGN(4); + + .text : + { + _start_vector = .; + KEEP(*(.isr_vector)) + . = ALIGN(256); + _start_text = .; + *(.text*) + *(.rodata*) + *(.sdata*) + } > FLASH + + /* Read-only sections, merged into text segment: */ + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .gnu.version : { *(.gnu.version) } + .gnu.version_r : { *(.gnu.version_r) } + .gnu.hash : { *(.gnu.hash) } + .rela.dyn : { *(.rela.dyn) } + + + .reloc : + { + _GOT2_TABLE_ = .; + *(.got2) + _FIXUP_TABLE_ = .; + *(.fixup) + } > FLASH + __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2; + __fixup_entries = (. - _FIXUP_TABLE_) >> 2; + + __init_end = .; + . = ALIGN(8); + _stored_data = .; + + .data : AT (_stored_data) + { + _start_data = .; + KEEP(*(.data*)) + . = ALIGN(4); + KEEP(*(.ramcode)) + . = ALIGN(4); + _end_data = .; + } > DRAM + + .bss (NOLOAD) : + { + _start_bss = .; + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(4); + _end_bss = .; + __bss_end__ = .; + . = ALIGN(16); + _end = .; + } > DRAM + +} + +PROVIDE(_start_heap = ORIGIN(L2RAM)); +PROVIDE(_end_stack = ORIGIN(L2RAM) + (LENGTH(L2RAM)) ); diff --git a/hal/nxp_t2080.c b/hal/nxp_t2080.c index bdbd0f20..0c3b6ccc 100644 --- a/hal/nxp_t2080.c +++ b/hal/nxp_t2080.c @@ -21,13 +21,13 @@ #include #include "target.h" #include "printf.h" - +#include "image.h" /* for RAMFUNCTION */ #include "nxp_ppc.h" /* Tested on T2080E Rev 1.1, e6500 core 2.0, PVR 8040_0120 and SVR 8538_0011 */ /* T2080 */ -#define SYS_CLK (600000000) +#define SYS_CLK (600000000) /* 100MHz PLL with 6:1 = 600 MHz */ /* T2080 PC16552D Dual UART */ #define BAUD_RATE 115200 @@ -56,7 +56,6 @@ #define UART_LSR_TEMT (0x40) /* Transmitter empty */ #define UART_LSR_THRE (0x20) /* Transmitter holding register empty */ -#define GET_PHYS_HIGH(addr) (((uint64_t)(addr)) >> 32) /* T2080 IFC (Integrated Flash Controller) - RM 13.3 */ #define IFC_BASE (CCSRBAR + 0x00124000) @@ -128,7 +127,6 @@ enum ifc_amask_sizes { /* NOR Flash */ #define FLASH_BASE 0xE8000000 -#define FLASH_BASE_PHYS (0xF00000000ULL | FLASH_BASE) #define FLASH_BANK_SIZE (128*1024*1024) #define FLASH_PAGE_SIZE (1024) /* program buffer */ @@ -146,7 +144,7 @@ enum ifc_amask_sizes { #endif /* CPLD */ #define CPLD_BASE 0xFFDF0000 -#define CPLD_BASE_PHYS (0xF00000000ULL | CPLD_BASE) +#define CPLD_BASE_PHYS_HIGH 0xFULL #define CPLD_SPARE 0x00 #define CPLD_SATA_MUX_SEL 0x02 @@ -250,7 +248,6 @@ enum ifc_amask_sizes { /* 12.4 DDR Memory Map */ #define DDR_BASE (CCSRBAR + 0x8000) -#define DDR_BASE_PHYS (0xF00000000ULL | DDR_BASE) #define DDR_CS_BNDS(n) *((volatile uint32_t*)(DDR_BASE + 0x000 + (n * 8))) /* Chip select n memory bounds */ #define DDR_CS_CONFIG(n) *((volatile uint32_t*)(DDR_BASE + 0x080 + (n * 4))) /* Chip select n configuration */ @@ -291,11 +288,14 @@ enum ifc_amask_sizes { #define DDR_SDRAM_MODE_7 *((volatile uint32_t*)(DDR_BASE + 0x210)) /* DDR SDRAM mode configuration 7 */ #define DDR_SDRAM_MODE_8 *((volatile uint32_t*)(DDR_BASE + 0x214)) /* DDR SDRAM mode configuration 8 */ #define DDR_SDRAM_MD_CNTL *((volatile uint32_t*)(DDR_BASE + 0x120)) /* DDR SDRAM mode control */ -#define DDR_SDRAM_INTERVAL *((volatile uint32_t*)(DDR_BASE + 0x124)) /* DDR SDRAM interval configuration */ #define DDR_SDRAM_CLK_CNTL *((volatile uint32_t*)(DDR_BASE + 0x130)) /* DDR SDRAM clock control */ #define DDR_SDRAM_CFG_MEM_EN 0x80000000 /* SDRAM interface logic is enabled */ -#define DDR_SDRAM_CFG2_D_INIT 0x00000010 /* data initialization in progress */ +#define DDR_SDRAM_CFG_2_D_INIT 0x00000010 /* data initialization in progress */ + + +/* generic share NXP QorIQ driver code */ +#include "nxp_ppc.c" #ifdef DEBUG_UART @@ -328,33 +328,40 @@ void uart_write(const char* buf, uint32_t sz) { uint32_t pos = 0; while (sz-- > 0) { - while (!(UART_LSR(UART_SEL) & UART_LSR_THRE)) - ; - UART_THR(UART_SEL) = buf[pos++]; + char c = buf[pos++]; + if (c == '\n') { /* handle CRLF */ + while ((UART_LSR(UART_SEL) & UART_LSR_THRE) == 0); + UART_THR(UART_SEL) = '\r'; + } + while ((UART_LSR(UART_SEL) & UART_LSR_THRE) == 0); + UART_THR(UART_SEL) = c; } } #endif /* DEBUG_UART */ +static void set_law(uint8_t idx, uint32_t addr_h, uint32_t addr_l, + uint32_t trgt_id, uint32_t law_sz) +{ + LAWAR(idx) = 0; /* reset */ + LAWBARH(idx) = addr_h; + LAWBARL(idx) = addr_l; + LAWAR(idx) = (LAWAR_ENABLE | LAWAR_TRGT_ID(trgt_id) | law_sz); + + /* Read back so that we sync the writes */ + (void)LAWAR(idx); +} + void law_init(void) { /* Buffer Manager (BMan) (control) - probably not required */ - LAWAR(3) = 0; /* reset */ - LAWBARH(3) = 0xF; - LAWBARL(3) = 0xF4000000; - LAWAR(3) = LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_BMAN) | LAW_SIZE_32MB; + set_law(3, 0xF, 0xF4000000, LAW_TRGT_BMAN, LAW_SIZE_32MB); } static void hal_flash_init(void) { - /* Set up LAW to map IFC(flash) to 0xf_e800_0000 - * This must be in place along with TLB before switching back to AS/TS=0 - */ - /* IFC - NOR Flash */ - LAWAR(1) = 0; /* reset */ - LAWBARH(1) = GET_PHYS_HIGH(FLASH_BASE_PHYS); - LAWBARL(1) = FLASH_BASE; - LAWAR(1) = LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_IFC) | LAW_SIZE_128MB; + /* LAW is also set in boot_ppc_start.S:flash_law */ + set_law(1, FLASH_BASE_PHYS_HIGH, FLASH_BASE, LAW_TRGT_IFC, LAW_SIZE_128MB); /* NOR IFC Flash Timing Parameters */ IFC_FTIM0(0) = (IFC_FTIM0_NOR_TACSE(4) | \ @@ -378,7 +385,7 @@ static void hal_flash_init(void) IFC_CSOR(0) = 0x0000000C; /* TRHZ (80 clocks for read enable high) */ } -void hal_ddr_init(void) +static void hal_ddr_init(void) { #ifdef ENABLE_DDR /* If DDR is already enabled then just return */ @@ -449,21 +456,23 @@ void hal_ddr_init(void) asm volatile("sync;isync"); /* Map LAW for DDR */ - LAWAR (4) = 0; /* reset */ - LAWBARH(4) = 0; - LAWBARL(4) = 0x0000000; - LAWAR (4) = LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_DDR_1) | LAW_SIZE_8GB; + set_law(4, 0, 0, LAW_TRGT_DDR_1, LAW_SIZE_2GB); /* Wait for data initialization is complete */ - while ((DDR_SDRAM_CFG_2 & DDR_SDRAM_CFG2_D_INIT)); + while ((DDR_SDRAM_CFG_2 & DDR_SDRAM_CFG_2_D_INIT)); /* DDR - TBL=1, Entry 19 */ - set_tlb(1, 19, DDR_ADDRESS, 0, + set_tlb(1, 19, DDR_ADDRESS, DDR_ADDRESS, 0, MAS3_SX | MAS3_SW | MAS3_SR, 0, 0, BOOKE_PAGESZ_2G, 1); #endif } +void hal_early_init(void) +{ + hal_ddr_init(); +} + static void hal_cpld_init(void) { #ifdef ENABLE_CPLD @@ -479,7 +488,7 @@ static void hal_cpld_init(void) IFC_FTIM3(3) = 0; /* CPLD IFC Definitions (CS3) */ - IFC_CSPR_EXT(3) = (0xF); + IFC_CSPR_EXT(3) = CPLD_BASE_PHYS_HIGH; IFC_CSPR(3) = (IFC_CSPR_PHYS_ADDR(CPLD_BASE) | IFC_CSPR_PORT_SIZE_16 | IFC_CSPR_MSEL_GPCM | @@ -488,13 +497,11 @@ static void hal_cpld_init(void) IFC_CSOR(3) = 0; /* IFC - CPLD */ - LAWAR (2) = 0; /* reset */ - LAWBARH(2) = GET_PHYS_HIGH(CPLD_BASE_PHYS); - LAWBARL(2) = CPLD_BASE; - LAWAR (2) = LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_IFC) | LAW_SIZE_4KB; + set_law(2, CPLD_BASE_PHYS_HIGH, CPLD_BASE, + LAW_TRGT_IFC, LAW_SIZE_4KB); /* CPLD - TBL=1, Entry 17 */ - set_tlb(1, 17, CPLD_BASE, CPLD_BASE_PHYS, + set_tlb(1, 17, CPLD_BASE, CPLD_BASE, CPLD_BASE_PHYS_HIGH, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_4K, 1); #endif @@ -587,6 +594,6 @@ void hal_prepare_boot(void) #ifdef MMU void* hal_get_dts_address(void) { - return (void*)WOLFBOOT_LOAD_DTS_ADDRESS; + return (void*)WOLFBOOT_DTS_BOOT_ADDRESS; } #endif diff --git a/hal/nxp_t2080.ld b/hal/nxp_t2080.ld index 47089974..3ee1be3f 100644 --- a/hal/nxp_t2080.ld +++ b/hal/nxp_t2080.ld @@ -40,6 +40,7 @@ SECTIONS { _start_vector = .; KEEP(*(.isr_vector)) + . = ALIGN(256); *(.text*) *(.rodata*) *(.sdata*) diff --git a/hal/spi/spi_drv_stm32.h b/hal/spi/spi_drv_stm32.h index 2393d0df..c28b10e5 100644 --- a/hal/spi/spi_drv_stm32.h +++ b/hal/spi/spi_drv_stm32.h @@ -333,7 +333,7 @@ #define SPI1_BASE (0x40013000) /* SPI1 base address */ #endif -#define SPI1_APB2_CLOCK_ER_VAL (1 << 12) +#define SPI1_APB2_CLOCK_ER_VAL (1 << 12) #define SPI1_CR1 (*(volatile uint32_t *)(SPI1_BASE)) #define SPI1_CR2 (*(volatile uint32_t *)(SPI1_BASE + 0x04)) @@ -342,21 +342,21 @@ #define SPI_CR1_CLOCK_PHASE (1 << 0) #define SPI_CR1_CLOCK_POLARITY (1 << 1) -#define SPI_CR1_MASTER (1 << 2) -#define SPI_CR1_BAUDRATE (0x07 << 3) -#define SPI_CR1_SPI_EN (1 << 6) -#define SPI_CR1_LSBFIRST (1 << 7) -#define SPI_CR1_SSI (1 << 8) -#define SPI_CR1_SSM (1 << 9) +#define SPI_CR1_MASTER (1 << 2) +#define SPI_CR1_BAUDRATE (0x07 << 3) +#define SPI_CR1_SPI_EN (1 << 6) +#define SPI_CR1_LSBFIRST (1 << 7) +#define SPI_CR1_SSI (1 << 8) +#define SPI_CR1_SSM (1 << 9) #define SPI_CR1_16BIT_FORMAT (1 << 11) -#define SPI_CR1_TX_CRC_NEXT (1 << 12) -#define SPI_CR1_HW_CRC_EN (1 << 13) -#define SPI_CR1_BIDIOE (1 << 14) -#define SPI_CR2_SSOE (1 << 2) +#define SPI_CR1_TX_CRC_NEXT (1 << 12) +#define SPI_CR1_HW_CRC_EN (1 << 13) +#define SPI_CR1_BIDIOE (1 << 14) +#define SPI_CR2_SSOE (1 << 2) -#define SPI_SR_RX_NOTEMPTY (1 << 0) -#define SPI_SR_TX_EMPTY (1 << 1) -#define SPI_SR_BUSY (1 << 7) +#define SPI_SR_RX_NOTEMPTY (1 << 0) +#define SPI_SR_TX_EMPTY (1 << 1) +#define SPI_SR_BUSY (1 << 7) /* GPIO */ diff --git a/hal/zynq.c b/hal/zynq.c index 665a3cf2..ea332393 100644 --- a/hal/zynq.c +++ b/hal/zynq.c @@ -1330,7 +1330,7 @@ void RAMFUNCTION ext_flash_unlock(void) #ifdef MMU void* hal_get_dts_address(void) { - return (void*)WOLFBOOT_LOAD_DTS_ADDRESS; + return (void*)WOLFBOOT_DTS_BOOT_ADDRESS; } #endif diff --git a/include/image.h b/include/image.h index 65a8cedb..dfade4b9 100644 --- a/include/image.h +++ b/include/image.h @@ -668,7 +668,7 @@ static inline int wb_flash_write_verify_word(struct wolfBoot_image *img, #define UBOOT_IMG_HDR_SZ 64 /* --- Flattened Device Tree Blob */ -#define UBOOT_FDT_MAGIC 0xEDFE0DD0UL +#define UBOOT_FDT_MAGIC 0xEDFE0DD0UL #ifndef EXT_ENCRYPTED #define WOLFBOOT_MAX_SPACE (WOLFBOOT_PARTITION_SIZE - \ diff --git a/include/spi_drv.h b/include/spi_drv.h index 37c958c2..4ccd58cc 100644 --- a/include/spi_drv.h +++ b/include/spi_drv.h @@ -32,6 +32,11 @@ #include #include "image.h" +/* SPI transfer flags */ +#define SPI_XFER_FLAG_NONE 0x0 +#define SPI_XFER_FLAG_CONTINUE 0x1 /* keep CS asserted */ + + #if defined(SPI_FLASH) || defined(WOLFBOOT_TPM) || defined(QSPI_FLASH) || \ defined(OCTOSPI_FLASH) @@ -64,10 +69,6 @@ uint8_t spi_read(void); #endif #ifdef WOLFBOOT_TPM -/* SPI transfer flags */ -#define SPI_XFER_FLAG_NONE 0x0 -#define SPI_XFER_FLAG_CONTINUE 0x1 /* keep CS asserted */ - /* Perform a SPI transaction. * Set flags == SPI_XFER_FLAG_CONTINUE to keep CS asserted after transfer. */ int spi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int flags); diff --git a/options.mk b/options.mk index ffbf51a2..d66bb371 100644 --- a/options.mk +++ b/options.mk @@ -639,6 +639,10 @@ endif ifeq ($(ELF),1) CFLAGS+=-DWOLFBOOT_ELF OBJS += src/elf.o + + ifneq ($(DEBUG_ELF),) + CFLAGS+=-DDEBUG_ELF=$(DEBUG_ELF) + endif endif ifeq ($(MULTIBOOT2),1) diff --git a/src/boot_ppc.c b/src/boot_ppc.c index 0a60d8e7..f965a842 100644 --- a/src/boot_ppc.c +++ b/src/boot_ppc.c @@ -33,7 +33,7 @@ extern unsigned int _start_data; extern unsigned int _end_data; extern void main(void); -extern void hal_ddr_init(void); +extern void hal_early_init(void); void write_tlb(uint32_t mas0, uint32_t mas1, uint32_t mas2, uint32_t mas3, uint32_t mas7) @@ -46,9 +46,9 @@ void write_tlb(uint32_t mas0, uint32_t mas1, uint32_t mas2, uint32_t mas3, asm volatile("isync;msync;tlbwe;isync"); } -void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint64_t rpn, - uint8_t perms, uint8_t wimge, - uint8_t ts, uint8_t tsize, uint8_t iprot) +void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint32_t rpn, + uint32_t urpn, uint8_t perms, uint8_t wimge, uint8_t ts, uint8_t tsize, + uint8_t iprot) { uint32_t _mas0, _mas1, _mas2, _mas3, _mas7; @@ -56,7 +56,7 @@ void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint64_t rpn, _mas1 = BOOKE_MAS1(1, iprot, 0, ts, tsize); _mas2 = BOOKE_MAS2(epn, wimge); _mas3 = BOOKE_MAS3(rpn, 0, perms); - _mas7 = BOOKE_MAS7(rpn); + _mas7 = BOOKE_MAS7(urpn); write_tlb(_mas0, _mas1, _mas2, _mas3, _mas7); } @@ -82,7 +82,7 @@ void invalidate_tlb(int tlb) mtspr(MMUCSR0, 0x2); } -void __attribute((weak)) hal_ddr_init(void) +void __attribute((weak)) hal_early_init(void) { } @@ -91,7 +91,7 @@ void boot_entry_C(void) { register unsigned int *dst, *src, *end; - hal_ddr_init(); + hal_early_init(); /* Copy the .data section from flash to RAM */ src = (unsigned int*)&_stored_data; @@ -149,11 +149,9 @@ void do_boot(const uint32_t *app_offset) #ifndef BUILD_LOADER_STAGE1 uint32_t msr; #endif - -#ifdef MMU - /* TODO: Determine if the dts_offset needs passed as argument */ - (void)dts_offset; -#endif + typedef void (*boot_entry)(uintptr_t r3, uintptr_t r4, uintptr_t r5, uintptr_t r6, + uintptr_t r7, uintptr_t r8, uintptr_t r9); + boot_entry entry = (boot_entry)app_offset; #ifndef BUILD_LOADER_STAGE1 /* invalidate cache */ @@ -165,8 +163,20 @@ void do_boot(const uint32_t *app_offset) mtmsr(msr); #endif - /* do branch unconditionally */ - asm volatile("mtlr %0; blr":: "r"(app_offset)); + /* ePAPR (Embedded Power Architecture Platform Requirements) + * https://elinux.org/images/c/cf/Power_ePAPR_APPROVED_v1.1.pdf + */ + entry( + #ifdef MMU + (uintptr_t)dts_offset, /* r3 = dts address */ + #else + 0, + #endif + 0, 0, + EPAPR_MAGIC, /* r6 = ePAPR magic */ + WOLFBOOT_PARTITION_SIZE, /* r7 = Size of Initial Mapped Area (IMA) */ + 0, 0 + ); } void arch_reboot(void) {} diff --git a/src/boot_ppc_mp.S b/src/boot_ppc_mp.S index 598c7235..2eb09978 100644 --- a/src/boot_ppc_mp.S +++ b/src/boot_ppc_mp.S @@ -30,7 +30,7 @@ #ifndef INTVEC_ADDR /* workaround to use isr_empty for all interrupts, for real IRQ's adjust the * offset and define additional interrupts at those offsets */ -#define INTVEC_ADDR(n) (BOOT_ROM_SIZE + (n * 0x0)) +#define INTVEC_ADDR(n) isr_empty@l #endif /* Additional cores (mp) assembly code for core minimum startup and spin table. @@ -40,12 +40,12 @@ .align 12 _mp_page_start: /* Time base, MAS7 and machine check pin enable */ - lis r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@h + lis r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@h ori r0, r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@l mtspr SPRN_HID0, r0 /* enable branch prediction */ - lis r0, (BUCSR_ENABLE)@h + lis r0, (BUCSR_ENABLE)@h ori r0, r0, (BUCSR_ENABLE)@l mtspr SPRN_BUCSR, r0 @@ -55,7 +55,7 @@ _mp_page_start: mttbu r3 /* Enable/invalidate the I-Cache */ - lis r2, (L1CSR_CFI|L1CSR_CLFC)@h + lis r2, (L1CSR_CFI|L1CSR_CLFC)@h ori r2, r2, (L1CSR_CFI|L1CSR_CLFC)@l mtspr L1CSR1, r2 1: @@ -63,7 +63,7 @@ _mp_page_start: and. r1, r3, r2 bne 1b - lis r3, (L1CSR_CPE|L1CSR_CE)@h + lis r3, (L1CSR_CPE|L1CSR_CE)@h ori r3, r3, (L1CSR_CPE|L1CSR_CE)@l mtspr L1CSR1,r3 isync @@ -81,7 +81,7 @@ _mp_page_start: and. r1, r3, r2 bne 1b - lis r3, (L1CSR_CPE|L1CSR_CE)@h + lis r3, (L1CSR_CPE|L1CSR_CE)@h ori r3, r3, (L1CSR_CPE|L1CSR_CE)@l mtspr L1CSR0, r3 isync @@ -91,7 +91,7 @@ _mp_page_start: beq 2b /* Get our PIR to figure out our table entry */ - lis r3, TORESET(_spin_table)@h + lis r3, TORESET(_spin_table)@h ori r3, r3, TORESET(_spin_table)@l /* Determine base address for the core (use r10) */ diff --git a/src/boot_ppc_start.S b/src/boot_ppc_start.S index f6fd9401..74a7ea5e 100644 --- a/src/boot_ppc_start.S +++ b/src/boot_ppc_start.S @@ -77,8 +77,8 @@ All TLBs for boot will be in TLB1 and supervisor mode (not user) .global isr_empty .global _end_stack -/* NXP P1021 First stage loader requires GOT for PIC and relocation */ -#if defined(PLATFORM_nxp_p1021) && defined(BUILD_LOADER_STAGE1) +/* First stage loader requires GOT for PIC and relocation */ +#if defined(NO_XIP) && defined(BUILD_LOADER_STAGE1) #define USE_GOT #endif @@ -113,7 +113,7 @@ GOT_ENTRY(__init_end) #ifndef INTVEC_ADDR /* workaround to use isr_empty for all interrupts, for real IRQ's adjust the * offset and define additional interrupts at those offsets */ -#define INTVEC_ADDR(n) (BOOT_ROM_SIZE + (n * 0x0)) +#define INTVEC_ADDR(n) isr_empty@l #endif @@ -144,20 +144,22 @@ reset_exceptions: mttbl r0 /* prevent FIT and WDT exceptions */ mttbu r0 mtspr SPRN_TSR, r1 /* clear all timer exception status */ -#ifdef PLATFORM_nxp_p1021 mtspr SPRN_TCR, r0 /* disable all timers */ -#endif mtspr SPRN_ESR, r0 /* clear exception syndrome register */ mtspr SPRN_MCSR, r0 /* clear machine check syndrome register */ mtxer r0 /* clear integer exception register */ +#if defined(CORE_E5500) || defined(CORE_E6500) + mtspr MAS8, r0 /* clear MAS8 used with Embedded Hypervisor */ +#endif + hardware_reg: /* Time base, MAS7 and machine check pin enable */ - lis r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@h + lis r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@h ori r0, r0, (HID0_EMCP | HID0_TBEN | HID0_ENMAS7)@l mtspr SPRN_HID0, r0 -#if defined(PLATFORM_nxp_p1021) && !defined(BUILD_LOADER_STAGE1) +#if defined(CORE_E500) && !defined(BUILD_LOADER_STAGE1) /* Set addr streaming & broadcast * and optimized sync instruction (if rev 5.0 or greater) */ li r0, (HID1_ASTME | HID1_ABE)@l @@ -172,15 +174,17 @@ hardware_reg: #ifndef BUILD_LOADER_STAGE1 branch_prediction: /* enable branch prediction */ - lis r0, (BUCSR_ENABLE)@h + lis r0, (BUCSR_ENABLE)@h ori r0, r0, (BUCSR_ENABLE)@l mtspr SPRN_BUCSR, r0 #endif startup_init: + /* Invalidate L1 instruction and data cache */ - bl invalidate_icache; - bl invalidate_dcache; + li r0, L1CSR_CFI + mtspr L1CSR1, r0 + mtspr L1CSR0, r0 /* Clear debug status register - read and write */ mfspr r1, SPRN_DBSR @@ -264,7 +268,7 @@ setup_interrupts: /* Setup interrupt vectors */ lis r1, (_start_vector)@h - mtspr IVPR, r1 + mtspr IVPR, r1 /* set the 48-bit high-order prefix address */ #ifdef ENABLE_INTERRUPTS li r1, INTVEC_ADDR(0) @@ -304,9 +308,9 @@ setup_interrupts: #if CCSRBAR_DEF != CCSRBAR_PHYS /* Use R8 = new, R9 = old virtual */ - lis r8, CCSRBAR@h + lis r8, CCSRBAR@h ori r8, r8, CCSRBAR@l - lis r9, (CCSRBAR + 0x1000)@h + lis r9, (CCSRBAR + 0x1000)@h ori r9, r9, (CCSRBAR + 0x1000)@l create_temp_ccsr: @@ -340,13 +344,13 @@ infinite_debug_loop: ccsr_temp_law: /* CCSR - LAW0 (Temp CoreNet 4K) */ #define CCSR_TEMP_LAW (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_CORENET) | LAW_SIZE_4KB) - lis r0, CCSRBAR_PHYS_HIGH@h + lis r0, CCSRBAR_PHYS_HIGH@h ori r0, r0, CCSRBAR_PHYS_HIGH@l - lis r1, CCSRBAR_DEF@h + lis r1, CCSRBAR_DEF@h ori r1, r1, CCSRBAR_DEF@l - lis r2, CCSR_TEMP_LAW@h + lis r2, CCSR_TEMP_LAW@h ori r2, r2, CCSR_TEMP_LAW@l - stw r0, LAWBAR_BASE(0)(r9) /* LAWBARH */ + stw r0, LAWBAR_BASE(0)(r9) /* LAWBARH */ stw r1, LAWBAR_BASE(0)+4(r9) /* LAWBARL */ sync stw r2, LAWBAR_BASE(0)+8(r9) /* LAWAR */ @@ -359,12 +363,12 @@ read_old_ccsr: isync write_new_ccsrbar: - lis r0, CCSRBAR_PHYS_HIGH@h + lis r0, CCSRBAR_PHYS_HIGH@h ori r0, r0, CCSRBAR_PHYS_HIGH@l - lis r1, CCSRBAR@h + lis r1, CCSRBAR@h ori r1, r1, CCSRBAR@l #define CCSRAR_C 0x80000000 /* Commit */ - lis r2, CCSRAR_C@h + lis r2, CCSRAR_C@h ori r2, r2, CCSRAR_C@l stw r0, 0(r9) /* CCSRBARH */ sync @@ -381,7 +385,7 @@ write_new_ccsrbar: lwz r0, 0(r9) isync /* write new CCSBAR */ - lis r0, (CCSRBAR_PHYS_HIGH << 20) | (CCSRBAR >> 12)@h + lis r0, (CCSRBAR_PHYS_HIGH << 20) | (CCSRBAR >> 12)@h ori r0, r0, (CCSRBAR_PHYS_HIGH << 20) | (CCSRBAR >> 12)@l stw r0, 0(r9) sync @@ -413,21 +417,21 @@ boot_page: ccsr_tlb: /* CCSRBAR: TLB 1, Entry 1, Supervisor R/W, IG, TS=0, 1M/16M, IPROT */ set_tlb(1, 1, - CCSRBAR, CCSRBAR, 0, + CCSRBAR, CCSRBAR, CCSRBAR_PHYS_HIGH, MAS3_SX | MAS3_SR | MAS3_SW, MAS2_I | MAS2_G, 0, CCSRBAR_SIZE, 1, r3); -#ifdef CORE_E6500 +#if defined(CORE_E5500) || defined(CORE_E6500) ccsr_law: /* CCSR - LAW0 (CoreNet 16MB) */ #define CCSR_LAW (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_CORENET) | LAW_SIZE_16MB) - lis r9, CCSRBAR + LAWBAR_BASE(0)@h + lis r9, CCSRBAR + LAWBAR_BASE(0)@h ori r9, r9, CCSRBAR + LAWBAR_BASE(0)@l - lis r0, CCSRBAR_PHYS_HIGH@h + lis r0, CCSRBAR_PHYS_HIGH@h ori r0, r0, CCSRBAR_PHYS_HIGH@l - lis r1, CCSRBAR@h + lis r1, CCSRBAR@h ori r1, r1, CCSRBAR@l - lis r2, CCSR_LAW@h + lis r2, CCSR_LAW@h ori r2, r2, CCSR_LAW@l stw r0, 0(r9) /* LAWBARH */ stw r1, 4(r9) /* LAWBARL */ @@ -435,21 +439,21 @@ ccsr_law: stw r2, 8(r9) /* LAWAR */ lwz r2, 8(r9) /* read back LAWAR (per 2.3.2 Configuring Local Access Windows) */ isync -#endif /* CORE_E6500 */ +#endif /* CORE_E5500 || CORE_E6500 */ #ifdef FLASH_BASE_ADDR -#ifdef CORE_E6500 - /* Memory Mapped NOR Flash (128MB) at 0xE8000000 */ +#if defined(CORE_E5500) || defined(CORE_E6500) + /* Memory Mapped NOR Flash (64/128MB) at 0xEC000000/0xE8000000 */ flash_law: - /* FLASH - LAW1 (IFC 128MB) */ - #define FLASH_LAW (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_IFC) | LAW_SIZE_128MB) - lis r9, CCSRBAR + LAWBAR_BASE(1)@h + /* FLASH - LAW1 (IFC 64/128MB) */ + #define FLASH_LAW (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_IFC) | FLASH_LAW_SIZE) + lis r9, CCSRBAR + LAWBAR_BASE(1)@h ori r9, r9, CCSRBAR + LAWBAR_BASE(1)@l - lis r0, FLASH_BASE_PHYS_HIGH@h + lis r0, FLASH_BASE_PHYS_HIGH@h ori r0, r0, FLASH_BASE_PHYS_HIGH@l - lis r1, FLASH_BASE_ADDR@h + lis r1, FLASH_BASE_ADDR@h ori r1, r1, FLASH_BASE_ADDR@l - lis r2, FLASH_LAW@h + lis r2, FLASH_LAW@h ori r2, r2, FLASH_LAW@l stw r0, 0(r9) /* LAWBARH */ stw r1, 4(r9) /* LAWBARL */ @@ -458,11 +462,12 @@ flash_law: lwz r2, 8(r9) /* read back LAWAR (per 2.3.2 Configuring Local Access Windows) */ isync flash_tlb: - /* Flash: TLB 1, Entry 7, Super X/R, W, TS=0, 128M, IPROT */ + /* Flash: TLB 1, Entry 7, Super X/R/W, W, TS=0, 64/128M, IPROT */ + /* Write is required for Write/Erase using CFI commands to base */ set_tlb(1, 7, FLASH_BASE_ADDR, FLASH_BASE_ADDR, FLASH_BASE_PHYS_HIGH, - MAS3_SX | MAS3_SR, MAS2_W, 0, - BOOKE_PAGESZ_128M, 1, r3); + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_W | MAS2_G, 0, + FLASH_TLB_PAGESZ, 1, r3); #else flash_tlb: /* For TS/AS=1 map boot ROM */ @@ -471,13 +476,14 @@ flash_tlb: FLASH_BASE_ADDR, FLASH_BASE_ADDR, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, 0, BOOKE_PAGESZ_1M, 1, r3); -#endif /* CORE_E6500 */ +#endif /* CORE_E5500 || CORE_E6500 */ #endif /* FLASH_BASE_ADDR */ -#ifdef ENABLE_DDR +/* Enable use of the DDR if available (like 2nd stage) */ +#if defined(CORE_E500) && defined(ENABLE_DDR) #ifdef BUILD_LOADER_STAGE1 /* use cache inhibited for first stage loader to avoid - * L1 cache as SRAM issues */ + * L1 cache as SRAM issues */ #define DDR_WING (MAS2_I | MAS2_G) #else #define DDR_WING (MAS2_G) @@ -492,22 +498,21 @@ flash_tlb: DDR_ADDRESS + (256*1024*1024), DDR_ADDRESS + (256*1024*1024), 0, MAS3_SX | MAS3_SW | MAS3_SR, DDR_WING, 0, BOOKE_PAGESZ_256M, 0, r3); -#endif +#endif /* CORE_E500 && ENABLE_DDR */ -#ifdef ENABLE_L2_CACHE -#ifdef CORE_E6500 /* --- L2 E6500 --- */ -#ifdef L2SRAM_ADDR -l2_sram_law: - /* L2 SRAM - LAW2 (DDR 256KB) */ - #define L2SRAM_LAW \ - (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_DDR_1) | LAW_SIZE_256KB) - lis r9, CCSRBAR + LAWBAR_BASE(2)@h +#ifdef INITIAL_SRAM_ADDR +init_sram_law: + /* Intial SRAM LAW 2 */ + #define INITIAL_SRAM_LAW (LAWAR_ENABLE | \ + LAWAR_TRGT_ID(INITIAL_SRAM_LAW_TRGT) | \ + INITIAL_SRAM_LAW_SZ) + lis r9, CCSRBAR + LAWBAR_BASE(2)@h ori r9, r9, CCSRBAR + LAWBAR_BASE(2)@l - li r0, 0 - lis r1, L2SRAM_ADDR@h - ori r1, r1, L2SRAM_ADDR@l - lis r2, L2SRAM_LAW@h - ori r2, r2, L2SRAM_LAW@l + li r0, 0 /* UPPER=0 */ + lis r1, INITIAL_SRAM_ADDR@h + ori r1, r1, INITIAL_SRAM_ADDR@l + lis r2, INITIAL_SRAM_LAW@h + ori r2, r2, INITIAL_SRAM_LAW@l stw r0, 0(r9) /* LAWBARH */ stw r1, 4(r9) /* LAWBARL */ sync @@ -515,36 +520,23 @@ l2_sram_law: lwz r2, 8(r9) /* read back LAWAR (per 2.3.2 Configuring Local Access Windows) */ isync -l2_sram_tlb: - /* L2 0xFEC20000: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, 256KB, IPROT */ +init_sram_tlb: + /* Inital SRAM: TLB 1, Entry 9, Supervisor X/R/W, M, TS=0, IPROT */ set_tlb(1, 9, - L2SRAM_ADDR, L2SRAM_ADDR, 0, + INITIAL_SRAM_ADDR, INITIAL_SRAM_ADDR, 0, MAS3_SX | MAS3_SW | MAS3_SR, MAS2_M, 0, - BOOKE_PAGESZ_256K, 1, r3); + INITIAL_SRAM_BOOKE_SZ, 1, r3); +#endif +#ifdef ENABLE_L2_CACHE + +#if defined(CORE_E5500) || defined(CORE_E6500) /* --- L2 E5500/E6500 --- */ +#ifdef L2SRAM_ADDR l2_setup_sram: - /* 8.2 CoreNet Platform Cache (CPC) Memory Map */ - #define CPCCSR0 (0x000) - #define CPCSRCR1 (0x100) - #define CPCSRCR0 (0x104) - #define CPCHDBCR0 (0xF00) - - #define CPCCSR0_CPCE (0x80000000 >> 0) - #define CPCCSR0_CPCPE (0x80000000 >> 1) - #define CPCCSR0_CPCFI (0x80000000 >> 10) - #define CPCCSR0_CPCLFC (0x80000000 >> 21) - #define CPCCSR0_SRAM_ENABLE (CPCCSR0_CPCE | CPCCSR0_CPCPE) - - #define CPCSRCR0_SRAMSZ_64 (0x1 << 1) /* ways 14-15 */ - #define CPCSRCR0_SRAMSZ_256 (0x3 << 1) /* ways 8-15 */ - #define CPCSRCR0_SRAMSZ_512 (0x4 << 1) /* ways 0-15 */ - #define CPCSRCR0_SRAMEN (0x1) - - #define CPCHDBCR0_SPEC_DIS (0x80000000 >> 4) - - /* T2080RM: 8.4.2.2 Enabling the CPC after Power-On Reset */ + /* T2080RM: 8.4.2.2 or T1024RM 13.4.2.2 + * Enabling the CPC after Power-On Reset */ /* R1 = CPC base */ - lis r1, CPC_BASE@h + lis r1, CPC_BASE@h ori r1, r1, CPC_BASE@l /* Set CPC SRAM control register */ @@ -552,7 +544,7 @@ l2_setup_sram: li r0, 0 stw r0, CPCSRCR1(r1) /* SRAM low address */ - lis r0, L2SRAM_ADDR@h + lis r0, L2SRAM_ADDR@h ori r0, r0, L2SRAM_ADDR@l /* Enable SRAM and set size (must match L2SRAM_SIZE) */ ori r0, r0, (CPCSRCR0_SRAMSZ_256 | CPCSRCR0_SRAMEN) @@ -564,35 +556,27 @@ l2_setup_sram: isync stw r0, CPCCSR0(r1) mbar -#endif /* L2SRAM_ADDR */ /* Disable speculation */ lwz r0, CPCHDBCR0(r1) oris r0, r0, CPCHDBCR0_SPEC_DIS@h stw r0, CPCHDBCR0(r1) +#endif /* L2SRAM_ADDR */ +#if defined(CORE_E6500) /* --- L2 E6500 --- */ l2_setup_cache: /* L2 Cache Control - E6500CORERM 2.2.3 Memory-mapped registers (MMRs) */ #define L2_CLUSTER_BASE(n) (CCSRBAR + 0xC20000 + (n * 0x40000)) - #define L2CSR0 (0x000) /* L2 Cache Control and Status 0 */ - #define L2CSR1 (0x004) /* L2 Cache Control and Status 1 */ - #define L2CFG0 (0x008) /* L2 Cache Configuration */ #define L2PID(n) (0x200 + (n * 0x10)) /* L2 Cache Partitioning ID */ #define L2PIR(n) (0x208 + (n * 0x10)) /* L2 Cache Partitioning Allocation */ #define L2PWR(n) (0x20C + (n * 0x10)) /* L2 Cache Partitioning Way */ - #define L2CSR0_L2FI 0x00200000 /* L2 Cache Flash Invalidate */ - #define L2CSR0_L2FL 0x00000800 /* L2 Cache Flush */ - #define L2CSR0_L2LFC 0x00000400 /* L2 Cache Lock Flash Clear */ - #define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ - #define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ - /* E6500CORERM: 11.7 L2 cache state */ /* R5 = L2 cluster 1 base */ - lis r5, L2_CLUSTER_BASE(0)@h + lis r5, L2_CLUSTER_BASE(0)@h ori r5, r5, L2_CLUSTER_BASE(0)@l /* Invalidate and clear locks */ - lis r1, (L2CSR0_L2FI | L2CSR0_L2LFC)@h + lis r1, (L2CSR0_L2FI | L2CSR0_L2LFC)@h ori r1, r1, (L2CSR0_L2FI | L2CSR0_L2LFC)@l sync stw r1, L2CSR0(r5) @@ -604,6 +588,10 @@ l2_poll_invclear: bne l2_poll_invclear isync + /* set stash id to (coreID) * 2 + 32 + L2 (1) */ + li r4, (32 + 1) + stw r4, L2CSR1(r5) + /* enable L2 with parity */ sync isync @@ -611,37 +599,43 @@ l2_poll_invclear: stw r4, L2CSR0(r5) isync - /* set stash id = 32 */ - li r4, 32 - stw r4, L2CSR1(r5) +#elif defined(CORE_E5500) /* --- L2 E5500 --- */ +l2_setup_cache: + /* L2 Cache Control - E5500RM 2.15 L2 Cache Registers */ + #define L2_BASE (CCSRBAR + 0x20000) -#elif defined(CORE_E500) /* --- L2 E500 --- */ - -#ifdef L2SRAM_ADDR -l2_sram_law: - /* L2 SRAM - LAW2 (eLBC 256KB) */ - #define L2SRAM_LAW \ - (LAWAR_ENABLE | LAWAR_TRGT_ID(LAW_TRGT_ELBC) | LAW_SIZE_256KB) - lis r9, CCSRBAR + LAWBAR_BASE(2)@h - ori r9, r9, CCSRBAR + LAWBAR_BASE(2)@l - lis r1, L2SRAM_ADDR@h - ori r1, r1, L2SRAM_ADDR@l - lis r2, L2SRAM_LAW@h - ori r2, r2, L2SRAM_LAW@l - stw r1, 0(r9) /* LAWBAR */ + /* Invalidate and clear locks */ + lis r1, (L2CSR0_L2FI | L2CSR0_L2LFC)@h + ori r1, r1, (L2CSR0_L2FI | L2CSR0_L2LFC)@l sync - stw r2, 8(r9) /* LAWAR */ - lwz r2, 8(r9) /* read back LAWAR */ + isync + mtspr L2CSR0, r1 isync -l2_sram_tlb: - /* L2 0xF8F80000: TLB 1, Entry 9, Supervisor X/R/W, G, TS=0, 256KB, IPROT */ - set_tlb(1, 9, - L2SRAM_ADDR, L2SRAM_ADDR, 0, - MAS3_SX | MAS3_SW | MAS3_SR, MAS2_G, 0, - BOOKE_PAGESZ_256K, 1, r3); -#endif + /* poll till invalidate and lock bits are cleared */ +l2_poll_invclear: + mfspr r4, L2CSR0 + and. r4, r1, r4 + bne l2_poll_invclear + /* set stash id to (coreID) * 2 + 32 + L2 (1) */ + li r4, (32 + 1) + sync + isync + mtspr L2CSR1, r4 + isync + sync + + /* enable L2 with no parity */ + lis r4, (L2CSR0_L2E)@h + sync + isync + mtspr L2CSR0, r4 + isync +#endif +#endif /* CORE_E5500 || CORE_E6500 */ + +#if defined(CORE_E500) /* --- L2 E500 --- */ /* e500 - L2 Cache */ l2_setup_cache: #define L2_BASE (CCSRBAR + 0x20000) @@ -659,9 +653,9 @@ l2_setup_cache: #define L2CTL_VAL (L2CTL_EN | L2CTL_INV | L2CTL_SIZ(2)) #endif /* Configure the L2 Cache */ - lis r5, L2_BASE@h + lis r5, L2_BASE@h ori r5, r5, L2_BASE@l - lis r1, L2CTL_VAL@h + lis r1, L2CTL_VAL@h ori r1, r1, L2CTL_VAL@l msync isync @@ -675,18 +669,22 @@ l2_setup_sram: /* Set the L2SRAM base address */ mbar isync - lis r1, L2SRAM_ADDR@h + lis r1, L2SRAM_ADDR@h ori r1, r1, L2SRAM_ADDR@l stw r1, L2SRBAR0(r5) mbar #endif /* L2SRAM_ADDR */ - -#endif /* CORE_* */ +#endif /* CORE_E500 */ #endif /* ENABLE_L2_CACHE */ #ifdef ENABLE_L1_CACHE setup_l1: +#if defined(CORE_E5500) || defined(CORE_E6500) + /* set L1 stash id = 32: (coreID * 2) + 32 + L1 CT (0) */ + li r2, 32 + mtspr L1CSR2, r2 +#endif #ifndef BUILD_LOADER_STAGE1 /* L1 Instruction Cache */ bl icache_enable; @@ -716,7 +714,7 @@ l1_tlb: #ifdef CACHE_SRAM_ADDR cache_sram_init: - lis r3, CACHE_SRAM_ADDR@h + lis r3, CACHE_SRAM_ADDR@h ori r3, r3, CACHE_SRAM_ADDR@l /* read the cache size */ mfspr r2, L1CFG0 @@ -729,7 +727,7 @@ cache_sram_init_loop: /* Data cache block zero */ dcbz r0, r3 /* Data cache block touch and lock set */ -#ifdef CORE_E6500 +#if defined(CORE_E6500) dcbtls 2, r0, r3 dcbtls 0, r0, r3 #else @@ -752,13 +750,13 @@ setup_stack: stwu r0, -4(r1) stwu r0, -4(r1) /* Terminate Back chain */ stwu r1, -8(r1) /* Save back chain and move SP */ - lis r0, RESET_VECTOR@h /* Address of reset vector */ + lis r0, RESET_VECTOR@h /* Address of reset vector */ ori r0, r0, RESET_VECTOR@l stwu r1, -8(r1) /* Save back chain and move SP */ stw r0, +12(r1) /* Save return addr (underflow vect) */ /* switch back to AS/TS=0 */ - lis r3, (MSR_CE | MSR_ME | MSR_DE)@h + lis r3, (MSR_CE | MSR_ME | MSR_DE)@h ori r3, r3, (MSR_CE | MSR_ME | MSR_DE)@l mtmsr r3 isync @@ -770,7 +768,7 @@ setup_stack: #ifdef USE_LONG_JUMP /* load absolute address into "LR" and branch return to it */ /* Enables long jump in 32-bit */ - lis r3, boot_entry_C@h + lis r3, boot_entry_C@h ori r3, r3, boot_entry_C@l mtlr r3 blr diff --git a/src/elf.c b/src/elf.c index d8588238..0bf31ca9 100644 --- a/src/elf.c +++ b/src/elf.c @@ -34,8 +34,11 @@ /* support for elf parsing debug printf */ #if defined(DEBUG) || defined(ELF_PARSER) -#if DEBUG_ELF == 0 +#if defined(DEBUG_ELF) && DEBUG_ELF == 0 #undef DEBUG_ELF +#else +#undef DEBUG_ELF +#define DEBUG_ELF #endif #endif diff --git a/src/image.c b/src/image.c index 525f8202..e2ec888b 100644 --- a/src/image.c +++ b/src/image.c @@ -838,10 +838,9 @@ static uint32_t wb_reverse_word32(uint32_t x) */ int wolfBoot_get_dts_size(void *dts_addr) { - uint32_t hdr[2]; - uint32_t magic; - uint32_t size; - memcpy(hdr, dts_addr, 2 * sizeof(uint32_t)); + uint32_t hdr[2], magic, size; + + memcpy(hdr, dts_addr, sizeof(hdr)); #ifdef BIG_ENDIAN_ORDER magic = wb_reverse_word32(hdr[0]); @@ -850,10 +849,7 @@ int wolfBoot_get_dts_size(void *dts_addr) magic = hdr[0]; size = wb_reverse_word32(hdr[1]); #endif - if (magic != UBOOT_FDT_MAGIC) - return -1; - else - return (int)size; + return (magic == UBOOT_FDT_MAGIC) ? (int)size : -1; } #endif @@ -893,7 +889,9 @@ int wolfBoot_open_image(struct wolfBoot_image *img, uint8_t part) } #ifdef MMU if (part == PART_DTS_BOOT || part == PART_DTS_UPDATE) { - img->hdr = (void *)WOLFBOOT_LOAD_DTS_ADDRESS; + img->hdr = (part == PART_DTS_BOOT) ? + (void*)WOLFBOOT_DTS_BOOT_ADDRESS : + (void*)WOLFBOOT_DTS_UPDATE_ADDRESS; wolfBoot_printf("%s partition: %p\n", (part == PART_DTS_BOOT) ? "DTB boot" : "DTB update", img->hdr); if (PART_IS_EXT(img)) diff --git a/src/update_ram.c b/src/update_ram.c index 44cdb16b..0b984332 100644 --- a/src/update_ram.c +++ b/src/update_ram.c @@ -47,7 +47,7 @@ extern uint32_t dts_load_addr; #define WOLFBOOT_USE_RAMBOOT #endif -#if defined(EXT_FLASH) && defined(NO_XIP) +#ifdef WOLFBOOT_USE_RAMBOOT /* Function to load image from flash to ram */ int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst) { @@ -57,11 +57,15 @@ int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst) /* read header into RAM */ wolfBoot_printf("Loading header %d bytes to %p\n", IMAGE_HEADER_SIZE, dst); +#if defined(EXT_FLASH) && defined(NO_XIP) ret = ext_flash_read((uintptr_t)src, dst, IMAGE_HEADER_SIZE); if (ret != IMAGE_HEADER_SIZE){ wolfBoot_printf("Error reading header at %p\n", img); return -1; } +#else + memcpy(dst, src, IMAGE_HEADER_SIZE); +#endif /* check for valid header and version */ ret = wolfBoot_get_blob_version((uint8_t*)dst); @@ -76,12 +80,16 @@ int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst) /* Read the entire image into RAM */ wolfBoot_printf("Loading image %d bytes to %p\n", img_size, dst + IMAGE_HEADER_SIZE); +#if defined(EXT_FLASH) && defined(NO_XIP) ret = ext_flash_read((uintptr_t)src + IMAGE_HEADER_SIZE, dst + IMAGE_HEADER_SIZE, img_size); if (ret < 0) { wolfBoot_printf("Error reading image at %p\n", src); return -1; } +#else + memcpy(dst + IMAGE_HEADER_SIZE, src + IMAGE_HEADER_SIZE, img_size); +#endif /* mark image as no longer external */ img->not_ext = 1; @@ -133,13 +141,13 @@ void RAMFUNCTION wolfBoot_start(void) #ifdef WOLFBOOT_USE_RAMBOOT load_address = (uint32_t*)(WOLFBOOT_LOAD_ADDRESS - IMAGE_HEADER_SIZE); - #if defined(EXT_FLASH) && defined(NO_XIP) - ret = wolfBoot_ramboot(&os_image, (uint8_t*)source_address, - (uint8_t*)load_address); - #elif defined(EXT_ENCRYPTED) && defined(MMU) + #if defined(EXT_ENCRYPTED) && defined(MMU) ret = wolfBoot_ram_decrypt((uint8_t*)source_address, (uint8_t*)load_address); - #endif + #else + ret = wolfBoot_ramboot(&os_image, (uint8_t*)source_address, + (uint8_t*)load_address); + #endif if (ret != 0) { goto backup_on_failure; } @@ -159,9 +167,15 @@ void RAMFUNCTION wolfBoot_start(void) goto backup_on_failure; } else { - /* Success */ + /* Success - integrity and signature valid */ + #ifdef WOLFBOOT_LOAD_ADDRESS load_address = (uint32_t*)WOLFBOOT_LOAD_ADDRESS; - break; + #elif !defined(NO_XIP) + load_address = (uint32_t*)os_image.fw_base; + #else + #error missing WOLFBOOT_LOAD_ADDRESS or XIP + #endif + break; } backup_on_failure: @@ -179,7 +193,7 @@ backup_on_failure: wolfBoot_printf("Firmware Valid\n"); - /* First time we boot this update, set to TESTING to await + /* First time we boot this update, set to TESTING to await * confirmation from the system */ #ifdef WOLFBOOT_FIXED_PARTITIONS @@ -214,13 +228,6 @@ backup_on_failure: #pragma GCC diagnostic ignored "-Wnonnull" #endif -#ifdef WOLFBOOT_ELF - /* Load elf */ - if (elf_load_image((uint8_t*)load_address, (uintptr_t*)&load_address) != 0){ - wolfBoot_printf("Invalid elf, falling back to raw binary\n"); - } -#endif - #ifndef WOLFBOOT_USE_RAMBOOT /* if needed copy image to RAM */ wolfBoot_printf("Loading %d bytes to RAM at %p\n", os_image.fw_size, @@ -228,6 +235,13 @@ backup_on_failure: memcpy((void*)load_address, os_image.fw_base, os_image.fw_size); #endif +#ifdef WOLFBOOT_ELF + /* Load elf */ + if (elf_load_image((uint8_t*)load_address, (uintptr_t*)&load_address) != 0){ + wolfBoot_printf("Invalid elf, falling back to raw binary\n"); + } +#endif + #ifdef MMU /* Load DTS to RAM */ #ifdef EXT_FLASH @@ -252,11 +266,13 @@ backup_on_failure: /* Allow failure, continue booting */ } else { + /* relocate DTS to RAM */ + uint8_t* dts_dst = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS; dts_size = (uint32_t)ret; - wolfBoot_printf("Loading DTB (size %d) to RAM at %08lx\n", - dts_size, dts_addr); - memcpy((void*)WOLFBOOT_LOAD_DTS_ADDRESS, dts_addr, dts_size); - dts_addr = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS; + wolfBoot_printf("Loading DTB (size %d) from %p to RAM at %p\n", + dts_size, dts_addr, WOLFBOOT_LOAD_DTS_ADDRESS); + memcpy(dts_dst, dts_addr, dts_size); + dts_addr = dts_dst; } } } diff --git a/stage1/Makefile b/stage1/Makefile index 30e44c13..51591dec 100644 --- a/stage1/Makefile +++ b/stage1/Makefile @@ -100,8 +100,10 @@ CFLAGS+=\ # For printf support (disable NO_PRINTF_UART) and increase WOLFBOOT_STAGE1_SIZE ifeq ($(ARCH),PPC) CFLAGS+=-DNO_PRINTF_UART - # Use PIC (Position Independent Code) for first stage loader - CFLAGS+=-fPIC + ifeq ($(NO_XIP),1) + # Use PIC (Position Independent Code) for first stage loader + CFLAGS+=-fPIC + endif endif diff --git a/stage1/loader_stage1.c b/stage1/loader_stage1.c index 20a98a48..f58f5ba4 100644 --- a/stage1/loader_stage1.c +++ b/stage1/loader_stage1.c @@ -32,8 +32,9 @@ #include #include -#ifndef EXT_FLASH - #error The stage1 loader only supports use with external flash + +#if !defined(EXT_FLASH) && defined(NO_XIP) + #error Using first stage loader requires XIP or External Flash (EXT_FLASH) #endif #ifndef WOLFBOOT_STAGE1_SIZE @@ -73,7 +74,7 @@ int main(void) hal_init(); spi_flash_probe(); /* make sure external flash is initialized */ -#ifdef BOOT_ROM_ADDR +#if defined(NO_XIP) && defined(BOOT_ROM_ADDR) /* if this is executing from boot 4KB region (FCM buffer) it must * first be relocated to RAM before the eLBC NAND can be read */ if ((get_pc() & BOOT_ROM_ADDR) == BOOT_ROM_ADDR) { @@ -104,11 +105,21 @@ int main(void) uart_write("Loading wolfBoot to DDR\n", 24); #endif +#ifdef EXT_FLASH ret = ext_flash_read( (uintptr_t)WOLFBOOT_ORIGIN, /* flash offset */ (uint8_t*)WOLFBOOT_STAGE1_LOAD_ADDR,/* ram destination */ BOOTLOADER_PARTITION_SIZE /* boot-loader partition (entire) */ ); +#else + /* copy from flash to ram */ + memcpy32( + (uint8_t*)WOLFBOOT_STAGE1_LOAD_ADDR,/* ram destination */ + (uint8_t*)WOLFBOOT_ORIGIN, /* flash offset */ + BOOTLOADER_PARTITION_SIZE /* boot-loader partition (entire) */ + ); + ret = 0; +#endif if (ret >= 0) { wolfboot_start = (uint32_t*)WOLFBOOT_STAGE1_LOAD_ADDR; #ifdef PRINTF_ENABLED diff --git a/test-app/app_nxp_t1024.c b/test-app/app_nxp_t1024.c new file mode 100644 index 00000000..ee8455f7 --- /dev/null +++ b/test-app/app_nxp_t1024.c @@ -0,0 +1,51 @@ +/* app_nxp_t1024.c + * + * Copyright (C) 2023 wolfSSL Inc. + * + * This file is part of wolfBoot. + * + * wolfBoot is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfBoot is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ + +#include +#include "../hal/nxp_ppc.h" +#include "printf.h" + +static const char* hex_lut = "0123456789abcdef"; + +void main(void) +{ + int i = 0; + int j = 0; + int k = 0; + char snum[8]; + + uart_init(); + + uart_write("Test App\n", 9); + + /* Wait for reboot */ + while(1) { + for (j=0; j<1000000; j++) + ; + i++; + + uart_write("\r\n0x", 4); + for (k=0; k<8; k++) { + snum[7 - k] = hex_lut[(i >> 4*k) & 0xf]; + } + uart_write(snum, 8); + } +}