Skip to content

Commit

Permalink
Added NXP IFC NOR Flash erase/write.
Browse files Browse the repository at this point in the history
  • Loading branch information
dgarske committed Oct 2, 2023
1 parent 3f1aa2b commit f5b3e50
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 86 deletions.
4 changes: 2 additions & 2 deletions config/examples/nxp-t1024.config
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion docs/Targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 |
| ----------------- | ---------- | ------------------- |
Expand Down
6 changes: 3 additions & 3 deletions hal/nxp_p1021.c
Original file line number Diff line number Diff line change
Expand Up @@ -935,15 +935,15 @@ 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);

/* 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) {
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions hal/nxp_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__
Expand Down
174 changes: 112 additions & 62 deletions hal/nxp_t1024.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,38 +22,39 @@
#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
#define USE_ERRATA_DDRA008109
#define USE_ERRATA_DDRA009663
#define USE_ERRATA_DDRA009942

/* Foward declarations */
#if defined(ENABLE_DDR) && defined(TEST_DDR)
static int test_ddr(void);
#endif
Expand All @@ -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
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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<xfer; i+=(FLASH_CFI_WIDTH/8)) {
#if FLASH_CFI_WIDTH == 16
FLASH_IO16_WRITE(sector, offset + i, *((uint16_t*)&data[pos + i]));
#else
FLASH_IO8_WRITE(sector, offset + i, data[pos + i]);
#endif
}

/* poll for DQ7 program completion */
while ((FLASH_IO8_READ(sector, 0) & FLASH_STATUS_DONE) == 0);

address += xfer;
len -= xfer;
pos += xfer;
}
return 0;
}

int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
int hal_flash_erase(uint32_t address, int len)
{
(void)address;
(void)len;
/* TODO: Implement NOR flash erase using IFC */
uint32_t sector;

/* adjust for flash base */
if (address >= 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)
{

}
Expand Down Expand Up @@ -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 */
Expand Down
2 changes: 1 addition & 1 deletion hal/nxp_t2080.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Loading

0 comments on commit f5b3e50

Please sign in to comment.