diff --git a/hal/zynq.c b/hal/zynq.c index 9df15e893..b23610f9d 100644 --- a/hal/zynq.c +++ b/hal/zynq.c @@ -80,6 +80,9 @@ static int qspi_wait_we(QspiDev_t* dev); static int test_ext_flash(QspiDev_t* dev); #endif +/* asm function */ +extern void flush_dcache_range(unsigned long start, unsigned long stop); + #ifdef DEBUG_UART void uart_init(void) { @@ -293,9 +296,23 @@ static inline int qspi_isr_wait(uint32_t wait_mask, uint32_t wait_val) } return 0; } +#ifdef GQSPI_DMA +static inline int qspi_dmaisr_wait(uint32_t wait_mask, uint32_t wait_val) +{ + uint32_t timeout = 0; + while ((GQSPIDMA_ISR & wait_mask) == wait_val && + ++timeout < GQSPI_TIMEOUT_TRIES); + if (timeout == GQSPI_TIMEOUT_TRIES) { + return -1; + } + return 0; +} +#endif static int qspi_gen_fifo_write(uint32_t reg_genfifo) { + uint32_t reg_cfg; + /* wait until the gen FIFO is not full to write */ if (qspi_isr_wait(GQSPI_IXR_GEN_FIFO_NOT_FULL, 0)) { return GQSPI_CODE_TIMEOUT; @@ -317,6 +334,17 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz) return GQSPI_CODE_TIMEOUT; } + #if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 3 + uint32_t txSz = sz; + if (txSz > GQSPI_FIFO_WORD_SZ) + txSz = GQSPI_FIFO_WORD_SZ; + memcpy(&tmp32, data, txSz); + GQSPI_TXD = tmp32; + wolfBoot_printf("TXD=%08x\n", tmp32); + + sz -= txSz; + data += txSz; + #else /* Write data */ if (sz >= 4) { GQSPI_TXD = *(uint32_t*)data; @@ -329,23 +357,32 @@ static int gspi_fifo_tx(const uint8_t* data, uint32_t sz) GQSPI_TXD = tmp32; sz = 0; } + #endif } return GQSPI_CODE_SUCCESS; } -static int gspi_fifo_rx(uint8_t* data, uint32_t sz, uint32_t discardSz) +#ifndef GQSPI_DMA +static int gspi_fifo_rx(uint8_t* data, uint32_t sz) { uint32_t tmp32; + while (sz > 0) { /* Wait for RX FIFO not empty */ if (qspi_isr_wait(GQSPI_IXR_RX_FIFO_NOT_EMPTY, 0)) { return GQSPI_CODE_TIMEOUT; } - if (discardSz >= GQSPI_FIFO_WORD_SZ) { - tmp32 = GQSPI_RXD; /* discard */ - discardSz -= GQSPI_FIFO_WORD_SZ; - continue; - } + + #if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 3 + uint32_t rxSz = sz; + if (rxSz > GQSPI_FIFO_WORD_SZ) + rxSz = GQSPI_FIFO_WORD_SZ; + tmp32 = GQSPI_RXD; + memcpy(data, &tmp32, rxSz); + wolfBoot_printf("RXD=%08x\n", tmp32); + sz -= rxSz; + data += rxSz; + #else if (sz >= 4) { *(uint32_t*)data = GQSPI_RXD; data += 4; @@ -356,9 +393,11 @@ static int gspi_fifo_rx(uint8_t* data, uint32_t sz, uint32_t discardSz) memcpy(data, &tmp32, sz); sz = 0; } + #endif } return GQSPI_CODE_SUCCESS; } +#endif static int qspi_cs(QspiDev_t* pDev, int csAssert) { @@ -374,6 +413,33 @@ static int qspi_cs(QspiDev_t* pDev, int csAssert) return qspi_gen_fifo_write(reg_genfifo); } +static uint32_t qspi_calc_exp(uint32_t xferSz, uint32_t* reg_genfifo) +{ + uint32_t expval = 8; + *reg_genfifo &= ~(GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK); + if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) { + /* Use exponent mode */ + while (1) { + if (xferSz & (1 << expval)) { + *reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK; + *reg_genfifo |= GQSPI_GEN_FIFO_IMM(expval); /* IMM is exponent */ + xferSz = (1 << expval); + break; + } + expval++; + } + } + else { + /* Use length mode */ + *reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */ + } + return xferSz; +} + +#ifdef GQSPI_DMA +static uint8_t XALIGNED(QQSPI_DMA_ALIGN) dmatmp[GQSPI_DMA_TMPSZ]; +#endif + static int qspi_transfer(QspiDev_t* pDev, const uint8_t* cmdData, uint32_t cmdSz, const uint8_t* txData, uint32_t txSz, @@ -382,7 +448,9 @@ static int qspi_transfer(QspiDev_t* pDev, { int ret = GQSPI_CODE_SUCCESS; uint32_t reg_genfifo, xferSz; - +#ifdef GQSPI_DMA + uint8_t* dmarxptr = NULL; +#endif GQSPI_EN = 1; /* Enable device */ qspi_cs(pDev, 1); /* Select slave */ @@ -395,14 +463,14 @@ static int qspi_transfer(QspiDev_t* pDev, xferSz = cmdSz; while (ret == GQSPI_CODE_SUCCESS && cmdData && xferSz > 0) { /* Enable TX and send command inline */ - reg_genfifo |= GQSPI_GEN_FIFO_TX; reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK); + reg_genfifo |= GQSPI_GEN_FIFO_TX; reg_genfifo |= GQSPI_GEN_FIFO_IMM(*cmdData); /* IMM is data */ /* Submit general FIFO operation */ ret = qspi_gen_fifo_write(reg_genfifo); if (ret != GQSPI_CODE_SUCCESS) { - wolfBoot_printf("on line %d: error %d\n", __LINE__, ret); + wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret); break; } @@ -411,39 +479,28 @@ static int qspi_transfer(QspiDev_t* pDev, cmdData++; } - /* Set desired data mode and stripe */ + /* Set desired data mode */ reg_genfifo |= (mode & GQSPI_GEN_FIFO_MODE_MASK); - reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE); /* TX Data */ while (ret == GQSPI_CODE_SUCCESS && txData && txSz > 0) { - xferSz = txSz; - /* Enable TX */ reg_genfifo &= ~(GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK); reg_genfifo |= (GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_DATA_XFER); - - if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) { - /* Use exponent mode */ - xferSz = 256; /* 2 ^ 8 = 256 */ - reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK; - reg_genfifo |= GQSPI_GEN_FIFO_IMM(8); /* IMM is exponent */ - } - else { - reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */ - } + reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE); + xferSz = qspi_calc_exp(txSz, ®_genfifo); /* Submit general FIFO operation */ ret = qspi_gen_fifo_write(reg_genfifo); if (ret != GQSPI_CODE_SUCCESS) { - wolfBoot_printf("on line %d: error %d\n", __LINE__, ret); + wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret); } /* Fill FIFO */ ret = gspi_fifo_tx(txData, xferSz); if (ret != GQSPI_CODE_SUCCESS) { - wolfBoot_printf("on line %d: error %d\n", __LINE__, ret); + wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret); break; } @@ -454,60 +511,77 @@ static int qspi_transfer(QspiDev_t* pDev, /* Dummy operations */ if (ret == GQSPI_CODE_SUCCESS && dummySz) { - /* Send dummy clocks (Disable TX & RX) */ + /* Send dummy clocks (Disable TX & RX), do not set stripe */ reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_RX | - GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK); + GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK | + GQSPI_GEN_FIFO_STRIPE); + reg_genfifo |= GQSPI_GEN_FIFO_DATA_XFER; /* IMM is number of dummy clock cycles */ reg_genfifo |= GQSPI_GEN_FIFO_IMM(dummySz); ret = qspi_gen_fifo_write(reg_genfifo); /* Submit FIFO Dummy Op */ - - if (rxSz > 0) { - /* Convert dummy bits to bytes */ - dummySz = (dummySz + 7) / 8; - /* Adjust rxSz for dummy bytes */ - rxSz += dummySz; - /* round up by FIFO Word Size */ - rxSz = (((rxSz + GQSPI_FIFO_WORD_SZ - 1) / GQSPI_FIFO_WORD_SZ) * - GQSPI_FIFO_WORD_SZ); - } } /* RX Data */ while (ret == GQSPI_CODE_SUCCESS && rxData && rxSz > 0) { - xferSz = rxSz; - /* Enable RX */ reg_genfifo &= ~(GQSPI_GEN_FIFO_TX | GQSPI_GEN_FIFO_IMM_MASK | GQSPI_GEN_FIFO_EXP_MASK); reg_genfifo |= (GQSPI_GEN_FIFO_RX | GQSPI_GEN_FIFO_DATA_XFER); + reg_genfifo |= (pDev->stripe & GQSPI_GEN_FIFO_STRIPE); - if (xferSz > GQSPI_GEN_FIFO_IMM_MASK) { - /* Use exponent mode */ - xferSz = 256; /* 2 ^ 8 = 256 */ - reg_genfifo |= GQSPI_GEN_FIFO_EXP_MASK; - reg_genfifo |= GQSPI_GEN_FIFO_IMM(8); /* IMM is exponent */ - } - else { - reg_genfifo |= GQSPI_GEN_FIFO_IMM(xferSz); /* IMM is length */ + xferSz = rxSz; + #ifdef GQSPI_DMA + /* if xferSz or rxData is not QQSPI_DMA_ALIGN aligned use tmp */ + dmarxptr = rxData; + if ((rxSz & (QQSPI_DMA_ALIGN-1)) || + (((size_t)rxData) & (QQSPI_DMA_ALIGN-1))) { + dmarxptr = (uint8_t*)dmatmp; + /* round up */ + xferSz = ((xferSz + (QQSPI_DMA_ALIGN-1)) & ~(QQSPI_DMA_ALIGN-1)); + if (xferSz > (uint32_t)sizeof(dmatmp)) { + xferSz = (uint32_t)sizeof(dmatmp); + } } + GQSPIDMA_DST = (unsigned long)dmarxptr; + GQSPIDMA_SIZE = xferSz; + GQSPIDMA_IER = GQSPIDMA_ISR_ALL_MASK; + flush_dcache_range((unsigned long)dmarxptr, + (unsigned long)dmarxptr + xferSz); + #endif + xferSz = qspi_calc_exp(xferSz, ®_genfifo); + /* Submit general FIFO operation */ ret = qspi_gen_fifo_write(reg_genfifo); if (ret != GQSPI_CODE_SUCCESS) { - wolfBoot_printf("on line %d: error %d\n", __LINE__, ret); + wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret); break; } + #ifndef GQSPI_DMA /* Read FIFO */ - ret = gspi_fifo_rx(rxData, xferSz-dummySz, dummySz); + ret = gspi_fifo_rx(rxData, xferSz); if (ret != GQSPI_CODE_SUCCESS) { - wolfBoot_printf("on line %d: error %d\n", __LINE__, ret); + wolfBoot_printf("zynq.c:%d (error %d)\n", __LINE__, ret); } + #else + /* Wait for DMA done */ + if (qspi_dmaisr_wait(GQSPIDMA_ISR_DONE, 0)) { + return GQSPI_CODE_TIMEOUT; + } + GQSPIDMA_ISR = GQSPIDMA_ISR_DONE; + /* adjust xfer sz */ + if (xferSz > rxSz) + xferSz = rxSz; + /* copy result if not aligned */ + if (dmarxptr != rxData) { + memcpy(rxData, dmarxptr, xferSz); + } + #endif /* offset size and buffer */ rxSz -= xferSz; - rxData += (xferSz - dummySz); - dummySz = 0; /* only first RX */ + rxData += xferSz; } qspi_cs(pDev, 0); /* Deselect Slave */ @@ -524,7 +598,7 @@ static int qspi_flash_read_id(QspiDev_t* dev, uint8_t* id, uint32_t idSz) uint8_t status = 0; memset(cmd, 0, sizeof(cmd)); - cmd[0] = MULTI_IO_READ_ID_CMD; + cmd[0] = READ_ID_CMD; ret = qspi_transfer(&mDev, cmd, 1, NULL, 0, cmd, sizeof(cmd), 0, GQSPI_GEN_FIFO_MODE_SPI); @@ -775,11 +849,11 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq) /* Clear and disable interrupts */ reg_isr = GQSPI_ISR; GQSPI_ISR |= GQSPI_ISR_WR_TO_CLR_MASK; /* Clear poll timeout counter interrupt */ - reg_cfg = QSPIDMA_DST_I_STS; - QSPIDMA_DST_I_STS = reg_cfg; /* clear all active interrupts */ - QSPIDMA_DST_STS |= QSPIDMA_DST_STS_WTC; /* mark outstanding DMA's done */ + reg_cfg = GQSPIDMA_ISR; + GQSPIDMA_ISR = reg_cfg; /* clear all active interrupts */ + GQSPIDMA_STS |= GQSPIDMA_STS_WTC; /* mark outstanding DMA's done */ GQSPI_IDR = GQSPI_IXR_ALL_MASK; /* disable interrupts */ - QSPIDMA_DST_I_STS = QSPIDMA_DST_I_STS_ALL_MASK; /* disable interrupts */ + GQSPIDMA_ISR = GQSPIDMA_ISR_ALL_MASK; /* disable interrupts */ /* Reset FIFOs */ if (GQSPI_ISR & GQSPI_IXR_RX_FIFO_EMPTY) { GQSPI_FIFO_CTRL |= (GQSPI_FIFO_CTRL_RST_TX_FIFO | GQSPI_FIFO_CTRL_RST_RX_FIFO); @@ -791,10 +865,14 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq) GQSPI_EN = 0; /* Disable device */ /* Initialize clock divisor, write protect hold and start mode */ +#ifdef GQSPI_DMA + reg_cfg = GQSPI_CFG_MODE_EN_DMA; /* Use DMA Transfer Mode */ +#else reg_cfg = GQSPI_CFG_MODE_EN_IO; /* Use I/O Transfer Mode */ + reg_cfg |= GQSPI_CFG_START_GEN_FIFO; /* Auto start GFIFO cmd execution */ +#endif reg_cfg |= GQSPI_CFG_BAUD_RATE_DIV(GQSPI_CLK_DIV); /* Clock Divider */ reg_cfg |= GQSPI_CFG_WP_HOLD; /* Use WP Hold */ - reg_cfg |= GQSPI_CFG_START_GEN_FIFO; /* Start GFIFO command execution */ reg_cfg &= ~(GQSPI_CFG_CLK_POL | GQSPI_CFG_CLK_PH); /* Use POL=0,PH=0 */ GQSPI_CFG = reg_cfg; @@ -803,30 +881,31 @@ void qspi_init(uint32_t cpu_clock, uint32_t flash_freq) * the clock and data tap delays bypassed. */ IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX; GQSPI_LPBK_DLY_ADJ = 0; - QSPI_DATA_DLY_ADJ = 0; + GQSPI_DATA_DLY_ADJ = 0; #elif GQSPI_CLK_DIV >= 1 /* 300/4=75MHz */ /* At 100 MHz, the Quad-SPI controller should be in clock loopback mode * with the clock tap delay bypassed, but the data tap delay enabled. */ IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX; GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK; - QSPI_DATA_DLY_ADJ = QSPI_DATA_DLY_ADJ_USE_DATA_DLY | QSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2); + GQSPI_DATA_DLY_ADJ = (GQSPI_DATA_DLY_ADJ_USE_DATA_DLY | + GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2)); #else /* At 150 MHz, only the generic controller can be used. * The generic controller should be in clock loopback mode and the clock * tap delay enabled, but the data tap delay disabled. */ IOU_TAPDLY_BYPASS = 0; GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK; - QSPI_DATA_DLY_ADJ = 0; + GQSPI_DATA_DLY_ADJ = 0; #endif /* Initialize hardware parameters for Threshold and Interrupts */ GQSPI_TX_THRESH = 1; GQSPI_RX_THRESH = 1; - GQSPI_GF_THRESH = 16; + GQSPI_GF_THRESH = 31; /* Reset DMA */ - QSPIDMA_DST_CTRL = QSPIDMA_DST_CTRL_DEF; - QSPIDMA_DST_CTRL2 = QSPIDMA_DST_CTRL2_DEF; + GQSPIDMA_CTRL = GQSPIDMA_CTRL_DEF; + GQSPIDMA_CTRL2 = GQSPIDMA_CTRL2_DEF; /* Interrupts unmask and enable */ GQSPI_IMR = GQSPI_IXR_ALL_MASK; diff --git a/hal/zynq.h b/hal/zynq.h index 22b728560..725fcbf6c 100644 --- a/hal/zynq.h +++ b/hal/zynq.h @@ -85,18 +85,25 @@ #define GQSPI_POLL_CFG (*((volatile uint32_t*)(QSPI_BASE + 0x154))) /* poll configuration register */ #define GQSPI_P_TIMEOUT (*((volatile uint32_t*)(QSPI_BASE + 0x158))) /* poll timeout register. */ #define GQSPI_XFER_STS (*((volatile uint32_t*)(QSPI_BASE + 0x15C))) /* transfer status register. */ -#define QSPI_DATA_DLY_ADJ (*((volatile uint32_t*)(QSPI_BASE + 0x1F8))) /* adjusting the internal receive data delay for read data capturing */ +#define GQSPI_DATA_DLY_ADJ (*((volatile uint32_t*)(QSPI_BASE + 0x1F8))) /* adjusting the internal receive data delay for read data capturing */ #define GQSPI_MOD_ID (*((volatile uint32_t*)(QSPI_BASE + 0x1FC))) -#define QSPIDMA_DST_STS (*((volatile uint32_t*)(QSPI_BASE + 0x808))) -#define QSPIDMA_DST_CTRL (*((volatile uint32_t*)(QSPI_BASE + 0x80C))) -#define QSPIDMA_DST_I_STS (*((volatile uint32_t*)(QSPI_BASE + 0x814))) -#define QSPIDMA_DST_CTRL2 (*((volatile uint32_t*)(QSPI_BASE + 0x824))) +/* DMA Registers */ +#define GQSPIDMA_DST (*((volatile uint32_t*)(QSPI_BASE + 0x800))) /* Destination memory address for DMA stream -> memory data transfer */ +#define GQSPIDMA_DST_MSB (*((volatile uint32_t*)(QSPI_BASE + 0x828))) /* Destination memory address (MSBs) for DMA stream -> memory data transfer */ +#define GQSPIDMA_SIZE (*((volatile uint32_t*)(QSPI_BASE + 0x804))) /* DMA transfer payload for DMA stream -> memory data transfer */ +#define GQSPIDMA_STS (*((volatile uint32_t*)(QSPI_BASE + 0x808))) /* General DST DMA status */ +#define GQSPIDMA_CTRL (*((volatile uint32_t*)(QSPI_BASE + 0x80C))) /* General DST DMA control */ +#define GQSPIDMA_ISR (*((volatile uint32_t*)(QSPI_BASE + 0x814))) /* DST DMA interrupt status register */ +#define GQSPIDMA_IER (*((volatile uint32_t*)(QSPI_BASE + 0x818))) /* DST DMA interrupt enable */ +#define GQSPIDMA_IDR (*((volatile uint32_t*)(QSPI_BASE + 0x81C))) /* DST DMA interrupt disable */ +#define GQSPIDMA_IMR (*((volatile uint32_t*)(QSPI_BASE + 0x820))) /* DST DMA interrupt mask */ +#define GQSPIDMA_CTRL2 (*((volatile uint32_t*)(QSPI_BASE + 0x824))) /* General DST DMA control register 2 */ #define GQSPI_LPBK_DLY_ADJ_USE_LPBK (1UL << 5) #define GQSPI_LPBK_DLY_ADJ_DIV0(x) (((x) & 0x7) << 0) #define GQSPI_LPBK_DLY_ADJ_DLY1(x) (((x) & 0x3) << 3) -#define QSPI_DATA_DLY_ADJ_USE_DATA_DLY (1UL << 31) -#define QSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(x) (((x) & 0x7) << 28) +#define GQSPI_DATA_DLY_ADJ_USE_DATA_DLY (1UL << 31) +#define GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(x) (((x) & 0x7) << 28) /* GQSPI Registers */ /* GQSPI_CFG: Configuration registers */ @@ -166,15 +173,16 @@ #define GQSPI_FIFO_CTRL_RST_TX_FIFO (1UL << 1) #define GQSPI_FIFO_CTRL_RST_RX_FIFO (1UL << 2) -/* QSPIDMA_DST_CTRL */ -#define QSPIDMA_DST_CTRL_DEF 0x403FFA00UL -#define QSPIDMA_DST_CTRL2_DEF 0x081BFFF8UL +/* GQSPIDMA_CTRL */ +#define GQSPIDMA_CTRL_DEF 0x403FFA00UL +#define GQSPIDMA_CTRL2_DEF 0x081BFFF8UL -/* QSPIDMA_DST_STS */ -#define QSPIDMA_DST_STS_WTC 0xE000U +/* GQSPIDMA_STS */ +#define GQSPIDMA_STS_WTC 0xE000U -/* QSPIDMA_DST_I_STS */ -#define QSPIDMA_DST_I_STS_ALL_MASK 0xFEU +/* GQSPIDMA_ISR */ +#define GQSPIDMA_ISR_DONE 0x02 +#define GQSPIDMA_ISR_ALL_MASK 0xFEU /* QSPI Configuration (bare-metal only) */ #ifndef GQSPI_CLK_DIV @@ -182,6 +190,16 @@ #endif #define GQSPI_CS_ASSERT_CLOCKS 5 /* CS Setup Time (tCSS) - num of clock cycles foes in IMM */ #define GQSPI_FIFO_WORD_SZ 4 +#define QQSPI_DMA_ALIGN 64 /* L1 cache size */ +#ifndef GQSPI_DMA_TMPSZ + /* Use larger of WOLFBOOT_SHA_BLOCK_SIZE or IMAGE_HEADER_SIZE */ + #if defined(WOLFBOOT_SHA_BLOCK_SIZE) && \ + WOLFBOOT_SHA_BLOCK_SIZE > IMAGE_HEADER_SIZE + #define GQSPI_DMA_TMPSZ WOLFBOOT_SHA_BLOCK_SIZE + #else + #define GQSPI_DMA_TMPSZ IMAGE_HEADER_SIZE + #endif +#endif #define GQSPI_TIMEOUT_TRIES 100000 #define QSPI_FLASH_READY_TRIES 1000 @@ -196,7 +214,7 @@ #define GQPI_USE_4BYTE_ADDR 1 #endif #ifndef GQSPI_DUMMY_READ -#define GQSPI_DUMMY_READ (8*8) /* Number of dummy clock cycles for reads */ +#define GQSPI_DUMMY_READ (8) /* Number of dummy clock cycles for reads */ #endif diff --git a/include/image.h b/include/image.h index c084aa7fa..8b00a3ac0 100644 --- a/include/image.h +++ b/include/image.h @@ -74,6 +74,22 @@ int wolfBot_get_dts_size(void *dts_addr); # endif #endif +/* Helpers for memory alignment */ +#ifndef XALIGNED + #if defined(__GNUC__) || defined(__llvm__) || \ + defined(__IAR_SYSTEMS_ICC__) + #define XALIGNED(x) __attribute__ ( (aligned (x))) + #elif defined(__KEIL__) + #define XALIGNED(x) __align(x) + #elif defined(_MSC_VER) + /* disable align warning, we want alignment ! */ + #pragma warning(disable: 4324) + #define XALIGNED(x) __declspec (align (x)) + #else + #define XALIGNED(x) /* null expansion */ + #endif +#endif + #ifndef WOLFBOOT_FLAGS_INVERT #define SECT_FLAG_NEW 0x0F diff --git a/src/boot_aarch64.c b/src/boot_aarch64.c index e323dbfce..dec78f6d9 100644 --- a/src/boot_aarch64.c +++ b/src/boot_aarch64.c @@ -69,7 +69,7 @@ void boot_entry_C(void) #ifdef MMU -int __attribute((weak)) hal_dts_fixup(void* dts_addr) +int WEAKFUNCTION hal_dts_fixup(void* dts_addr) { (void)dts_addr; return 0; diff --git a/src/boot_aarch64_start.S b/src/boot_aarch64_start.S index f761331b9..4d4b57847 100644 --- a/src/boot_aarch64_start.S +++ b/src/boot_aarch64_start.S @@ -461,6 +461,34 @@ invalidatecaches_next_level: invalidatecaches_end: ret + +/* + * void flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +.global flush_dcache_range +flush_dcache_range: + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc civac, x0 /* clean & invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret + + /* * Below is the static translation page table required by MMU for Cortex-A53. * The translation table is flat mapped (input address = output address) with diff --git a/src/boot_ppc.c b/src/boot_ppc.c index b59d90893..912ae630a 100644 --- a/src/boot_ppc.c +++ b/src/boot_ppc.c @@ -101,12 +101,12 @@ void set_law(uint8_t idx, uint32_t addr_h, uint32_t addr_l, uint32_t trgt_id, (void)get32(LAWAR(idx)); } -void __attribute((weak)) hal_early_init(void) +void WEAKFUNCTION hal_early_init(void) { } #ifdef MMU -int __attribute((weak)) hal_dts_fixup(void* dts_addr) +int WEAKFUNCTION hal_dts_fixup(void* dts_addr) { (void)dts_addr; return 0; diff --git a/test-app/app_stm32h5.c b/test-app/app_stm32h5.c index b0250c771..08bd8b12f 100644 --- a/test-app/app_stm32h5.c +++ b/test-app/app_stm32h5.c @@ -33,6 +33,7 @@ #include "wolfboot/wolfboot.h" #include "keystore.h" #include "target.h" +#include "image.h" #ifdef SECURE_PKCS11 #include "wcs/user_settings.h" @@ -797,7 +798,7 @@ void _exit (int status) while (1) {} /* Make sure we hang here */ } -__attribute__((weak)) int _read(int file, char *ptr, int len) +int WEAKFUNCTION _read(int file, char *ptr, int len) { (void)file; int DataIdx;