From f5b3e50e6c7d3701d33ce482959cc9540cf8c822 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 2 Oct 2023 16:24:11 -0700 Subject: [PATCH] Added NXP IFC NOR Flash erase/write. --- config/examples/nxp-t1024.config | 4 +- docs/Targets.md | 2 +- hal/nxp_p1021.c | 6 +- hal/nxp_ppc.h | 6 +- hal/nxp_t1024.c | 174 ++++++++++++++++++++----------- hal/nxp_t2080.c | 2 +- src/boot_ppc.c | 29 +++--- 7 files changed, 137 insertions(+), 86 deletions(-) diff --git a/config/examples/nxp-t1024.config b/config/examples/nxp-t1024.config index 211ead7a4..895f9f5b7 100644 --- a/config/examples/nxp-t1024.config +++ b/config/examples/nxp-t1024.config @@ -29,8 +29,8 @@ DEBUG_ELF=0 # NOR Base Address ARCH_FLASH_OFFSET?=0xEC000000 -# Flash Sector Size -WOLFBOOT_SECTOR_SIZE=0x10000 +# Flash Sector Size (128KB) +WOLFBOOT_SECTOR_SIZE=0x20000 # wolfBoot start address WOLFBOOT_ORIGIN=0xEFF40000 diff --git a/docs/Targets.md b/docs/Targets.md index 2fd3519a8..6a0b0e5d9 100644 --- a/docs/Targets.md +++ b/docs/Targets.md @@ -1265,7 +1265,7 @@ Reset Configuration Word (RCW): Flash is NOR on IFC CS0 (0x0_EC00_0000) 64MB (default). -Default NOR Flash Memory Layout (64MB): +Default NOR Flash Memory Layout (64MB) (128KB block, 1K page) | Description | Address | Size | | ----------------- | ---------- | ------------------- | diff --git a/hal/nxp_p1021.c b/hal/nxp_p1021.c index 7796a30a1..2cba23bc6 100644 --- a/hal/nxp_p1021.c +++ b/hal/nxp_p1021.c @@ -935,7 +935,7 @@ static void hal_ddr_init(void) /* 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"); + __asm__ __volatile__("sync;isync"); /* busy wait for ~500us */ udelay(500); @@ -943,7 +943,7 @@ static void hal_ddr_init(void) /* 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"); + __asm__ __volatile__("sync;isync"); /* Wait for data initialization to complete */ while (get32(DDR_SDRAM_CFG_2) & DDR_SDRAM_CFG_2_D_INIT) { @@ -1438,7 +1438,7 @@ static void hal_mp_up(uint32_t bootpg) bpcr = get32(ECM_EEBPCR); bpcr |= ECM_EEBPCR_CPU_EN(up); set32(ECM_EEBPCR, bpcr); - asm volatile("sync; isync; msync"); + __asm__ __volatile__("sync; isync; msync"); /* wait for other core to start */ cpu_up_mask = (1 << whoami); diff --git a/hal/nxp_ppc.h b/hal/nxp_ppc.h index 15f756d3e..4ad66c196 100644 --- a/hal/nxp_ppc.h +++ b/hal/nxp_ppc.h @@ -545,13 +545,13 @@ #define WC_STRINGIFY(str) _WC_STRINGIFY_L2(str) #endif -#define mtspr(rn, v) asm volatile("mtspr " WC_STRINGIFY(rn) ",%0" : : "r" (v)) +#define mtspr(rn, v) __asm__ __volatile__("mtspr " WC_STRINGIFY(rn) ",%0" : : "r" (v)) #define mfmsr() ({ \ unsigned int rval; \ - asm volatile("mfmsr %0" : "=r" (rval)); rval; \ + __asm__ __volatile__("mfmsr %0" : "=r" (rval)); rval; \ }) -#define mtmsr(v) asm volatile("mtmsr %0" : : "r" (v)) +#define mtmsr(v) __asm__ __volatile__("mtmsr %0" : : "r" (v)) #ifndef __ASSEMBLER__ diff --git a/hal/nxp_t1024.c b/hal/nxp_t1024.c index 95e7f2d55..52896441a 100644 --- a/hal/nxp_t1024.c +++ b/hal/nxp_t1024.c @@ -22,31 +22,31 @@ #include "target.h" #include "printf.h" #include "string.h" -#include "image.h" /* for RAMFUNCTION */ +#include "hal.h" #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_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 + + /* Tests */ + #if 1 + //#define TEST_DDR + //#define TEST_FLASH + //#define TEST_TPM + #endif #endif #define USE_ERRATA_DDRA008378 @@ -54,6 +54,7 @@ #define USE_ERRATA_DDRA009663 #define USE_ERRATA_DDRA009942 +/* Foward declarations */ #if defined(ENABLE_DDR) && defined(TEST_DDR) static int test_ddr(void); #endif @@ -64,6 +65,8 @@ static int test_flash(void); static int test_tpm(void); #endif +static void hal_flash_unlock_sector(uint32_t sector); + #ifdef ENABLE_ESPI #include "spi_drv.h" /* for transfer flags */ #endif @@ -321,7 +324,6 @@ enum ifc_amask_sizes { IFC_AMASK_4GB = 0x0000, }; - /* NOR Flash */ #define FLASH_BANK_SIZE (64*1024*1024) #define FLASH_PAGE_SIZE (1024) /* program buffer */ @@ -380,6 +382,16 @@ enum ifc_amask_sizes { #define AMD_STATUS_TOGGLE 0x40 #define AMD_STATUS_ERROR 0x20 +/* Flash IO Helpers */ +#if FLASH_CFI_WIDTH == 16 +#define FLASH_IO8_WRITE(sec, n, val) *((volatile uint16_t*)(FLASH_BASE_ADDR + (FLASH_SECTOR_SIZE * (sec)) + ((n) * 2))) = (((val) << 8) | (val)) +#define FLASH_IO16_WRITE(sec, n, val) *((volatile uint16_t*)(FLASH_BASE_ADDR + (FLASH_SECTOR_SIZE * (sec)) + ((n) * 2))) = (val) +#define FLASH_IO8_READ(sec, n) (uint8_t)(*((volatile uint16_t*)(FLASH_BASE_ADDR + (FLASH_SECTOR_SIZE * (sec)) + ((n) * 2)))) +#else +#define FLASH_IO8_WRITE(sec, n, val) *((volatile uint8_t*)(FLASH_BASE_ADDR + (FLASH_SECTOR_SIZE * (sec)) + (n))) = (val) +#define FLASH_IO8_READ(sec, n) *((volatile uint8_t*)(FLASH_BASE_ADDR + (FLASH_SECTOR_SIZE * (sec)) + (n))) +#endif + /* CPLD */ #define CPLD_BASE 0xFFDF0000 @@ -774,51 +786,30 @@ void uart_write(const char* buf, uint32_t sz) } #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) +#if defined(ENABLE_IFC) && !defined(BUILD_LOADER_STAGE1) +static int 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); + hal_flash_unlock_sector(0); + FLASH_IO8_WRITE(0, 0x555, FLASH_CMD_READ_ID); udelay(1000); - for (i=0; i<(int)sizeof(manfid); i++) { - manfid[i] = FLASH_IO8_READ(i); - } + manfid[0] = FLASH_IO8_READ(0, 0); /* Manufacture Code */ + manfid[1] = FLASH_IO8_READ(0, 1); /* Device Code 1 */ + manfid[2] = FLASH_IO8_READ(0, 14); /* Device Code 2 */ + manfid[3] = FLASH_IO8_READ(0, 15); /* Device Code 3 */ - /* Leave READ CFI */ - FLASH_IO8_WRITE(0, AMD_CMD_RESET); + /* Exit read info */ + FLASH_IO8_WRITE(0, 0, AMD_CMD_RESET); udelay(1); - wolfBoot_printf("Flash ID: 0x%x 0x%x 0x%x 0x%x\n", + wolfBoot_printf("Flash: Mfg 0x%x, Device Code 0x%x/0x%x/0x%x\n", manfid[0], manfid[1], manfid[2], manfid[3]); -#endif /* ENABLE_IFC */ + return 0; } -#endif /* BUILD_LOADER_STAGE1 */ +#endif /* ENABLE_IFC && !BUILD_LOADER_STAGE1 */ static void hal_flash_init(void) { @@ -941,16 +932,16 @@ static void hal_ddr_init(void) /* 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"); + __asm__ __volatile__("sync;isync"); /* busy wait for ~500us */ udelay(500); - asm volatile("sync;isync"); + __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"); + __asm__ __volatile__("sync;isync"); #ifdef USE_ERRATA_DDRA008378 /* Errata A-008378: training in DDR4 mode */ @@ -1331,7 +1322,7 @@ static void hal_mp_up(uint32_t bootpg) /* Release the CPU core(s) */ set32(DCFG_BRR, all_cores); - asm volatile("sync; isync; msync"); + __asm__ __volatile__("sync; isync; msync"); /* wait for other core to start */ while (timeout) { @@ -1447,29 +1438,86 @@ void hal_init(void) #endif } -int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len) +int 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 */ + uint32_t pos, i, sector, offset, xfer; + + /* adjust for flash base */ + if (address >= FLASH_BASE_ADDR) + address -= FLASH_BASE_ADDR; + + pos = 0; + while (len > 0) { + /* dertermine sector address */ + sector = (address / FLASH_SECTOR_SIZE); + offset = address - (sector * FLASH_SECTOR_SIZE); + offset /= (FLASH_CFI_WIDTH/8); + xfer = len; + if (xfer > FLASH_PAGE_SIZE) + xfer = FLASH_PAGE_SIZE; + xfer /= (FLASH_CFI_WIDTH/8); + + hal_flash_unlock_sector(sector); + FLASH_IO8_WRITE(sector, offset, AMD_CMD_WRITE_TO_BUFFER); + FLASH_IO8_WRITE(sector, offset, xfer); + + for (i=0; i= FLASH_BASE_ADDR) + address -= FLASH_BASE_ADDR; + + while (len > 0) { + /* dertermine sector address */ + sector = (address / FLASH_SECTOR_SIZE); + + hal_flash_unlock_sector(sector); + FLASH_IO8_WRITE(sector, 0x555, AMD_CMD_ERASE_START); + hal_flash_unlock_sector(sector); + FLASH_IO8_WRITE(sector, 0, AMD_CMD_ERASE_SECTOR); + + /* poll for DQ7 erase completion */ + while ((FLASH_IO8_READ(sector, 0) & FLASH_STATUS_DONE) == 0); + + address += FLASH_SECTOR_SIZE; + len -= FLASH_SECTOR_SIZE; + } return 0; } -void RAMFUNCTION hal_flash_unlock(void) +static void hal_flash_unlock_sector(uint32_t sector) { + /* Unlock sequence */ + FLASH_IO8_WRITE(sector, 0x555, AMD_CMD_UNLOCK_START); + FLASH_IO8_WRITE(sector, 0x2AA, AMD_CMD_UNLOCK_ACK); +} +void hal_flash_unlock(void) +{ + hal_flash_unlock_sector(0); } -void RAMFUNCTION hal_flash_lock(void) +void hal_flash_lock(void) { } @@ -1535,17 +1583,19 @@ static int test_ddr(void) #if defined(ENABLE_IFC) && defined(TEST_FLASH) #ifndef TEST_ADDRESS -#define TEST_ADDRESS (2 * 0x100000) /* 2MB */ + /* 0xEC100000 (1MB offset) */ + #define TEST_ADDRESS (FLASH_BASE_ADDR + (1 * 0x100000)) #endif + /* #define TEST_FLASH_READONLY */ -static uint32_t pageData[WOLFBOOT_SECTOR_SIZE/4]; /* force 32-bit alignment */ +static uint32_t pageData[WOLFBOOT_SECTOR_SIZE/sizeof(uint32_t)]; /* force 32-bit alignment */ static int test_flash(void) { int ret; uint32_t i; - uint8_t* pagePtr = (uint8_t*)FLASH_BASE_ADDR + TEST_ADDRESS; + uint8_t* pagePtr = (uint8_t*)TEST_ADDRESS; #ifndef TEST_FLASH_READONLY /* Erase sector */ diff --git a/hal/nxp_t2080.c b/hal/nxp_t2080.c index dc344474d..adbdb302f 100644 --- a/hal/nxp_t2080.c +++ b/hal/nxp_t2080.c @@ -443,7 +443,7 @@ static void hal_ddr_init(void) /* Enable controller */ DDR_SDRAM_CFG |= DDR_SDRAM_CFG_MEM_EN; - asm volatile("sync;isync"); + __asm__ __volatile__("sync;isync"); /* Wait for data initialization is complete */ while ((DDR_SDRAM_CFG_2 & DDR_SDRAM_CFG_2_D_INIT)); diff --git a/src/boot_ppc.c b/src/boot_ppc.c index 6440daf80..1df610556 100644 --- a/src/boot_ppc.c +++ b/src/boot_ppc.c @@ -43,7 +43,7 @@ void write_tlb(uint32_t mas0, uint32_t mas1, uint32_t mas2, uint32_t mas3, mtspr(MAS2, mas2); mtspr(MAS3, mas3); mtspr(MAS7, mas7); - asm volatile("isync;msync;tlbwe;isync"); + __asm__ __volatile__("isync;msync;tlbwe;isync"); } void set_tlb(uint8_t tlb, uint8_t esel, uint32_t epn, uint32_t rpn, @@ -85,15 +85,16 @@ void invalidate_tlb(int tlb) void set_law(uint8_t idx, uint32_t addr_h, uint32_t addr_l, uint32_t trgt_id, uint32_t law_sz, int reset) { - if (reset) + if (reset) { set32(LAWAR(idx), 0); /* reset */ - #ifdef CORE_E500 - (void)addr_h; /* not used */ - set32(LAWBAR(idx), addr_l >> 12); - #else - set32(LAWBARH(idx), addr_h); - set32(LAWBARL(idx), addr_l); - #endif + } +#ifdef CORE_E500 + (void)addr_h; /* not used */ + set32(LAWBAR(idx), addr_l >> 12); +#else + set32(LAWBARH(idx), addr_h); + set32(LAWBARL(idx), addr_l); +#endif set32(LAWAR(idx), LAWAR_ENABLE | LAWAR_TRGT_ID(trgt_id) | law_sz); /* Read back so that we sync the writes */ @@ -143,18 +144,18 @@ void flush_cache(uint32_t start_addr, uint32_t size) for (addr = start; (addr <= end) && (addr >= start); addr += CACHE_LINE_SIZE) { - asm volatile("dcbst 0,%0" : : "r" (addr) : "memory"); + __asm__ __volatile__("dcbst 0,%0" : : "r" (addr) : "memory"); } /* wait for all dcbst to complete on bus */ - asm volatile("sync" : : : "memory"); + __asm__ __volatile__("sync" : : : "memory"); for (addr = start; (addr <= end) && (addr >= start); addr += CACHE_LINE_SIZE) { - asm volatile("icbi 0,%0" : : "r" (addr) : "memory"); + __asm__ __volatile__("icbi 0,%0" : : "r" (addr) : "memory"); } - asm volatile("sync" : : : "memory"); + __asm__ __volatile__("sync" : : : "memory"); /* flush prefetch queue */ - asm volatile("isync" : : : "memory"); + __asm__ __volatile__("isync" : : : "memory"); } #endif