Initial support for NXP LS1028A. Booting into OCRAM app. Updates to ARMv8 startup.

pull/525/head
David Garske 2024-07-31 15:57:13 -07:00 committed by Daniele Lacamera
parent 34bb4f651c
commit d007c9af08
17 changed files with 2803 additions and 41 deletions

17
arch.mk
View File

@ -72,6 +72,23 @@ ifeq ($(ARCH),AARCH64)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_arm64.o
endif
ifeq ($(TARGET),nxp_ls1028a)
ARCH_FLAGS=-mcpu=cortex-a72+crypto -mstrict-align -march=armv8-a+crypto -mtune=cortex-a72
CFLAGS+=$(ARCH_FLAGS) -DCORTEX_A72 -DTARGET_LS1028A -DWOLFSSL_ARMASM -DWC_HASH_DATA_ALIGNMENT=8
#LDFLAGS+=-Wl,--as-needed -D"__WOLFBOOT"
CFLAGS +=-ffunction-sections -fdata-sections
LDFLAGS+=-Wl,--gc-sections
WOLFCRYPT_OBJS += lib/wolfssl/wolfcrypt/src/port/arm/armv8-sha256.o \
lib/wolfssl/wolfcrypt/src/port/arm/armv8-aes.o
ifeq ($(DEBUG_UART),0)
CFLAGS+=-fno-builtin-printf
endif
SPI_TARGET=nxp
endif
endif
## ARM Cortex-M

View File

@ -0,0 +1,65 @@
ARCH=AARCH64
TARGET=nxp_ls1028a
SIGN?=ECC256
HASH?=SHA256
DEBUG?=1
DEBUG_UART?=1
VTOR?=0
CORTEX_M0?=0
NO_ASM?=0
EXT_FLASH?=1
SPI_FLASH?=0
## Force app to be copied into ram
NO_XIP?=1
UART_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=0
WOLFBOOT_VERSION?=0
V?=0
NO_MPU?=0
SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
PKA?=0
WOLFTPM=1
MEASURED_BOOT?=0
MEASURED_PCR_A?=3
WOLFBOOT_TPM_KEYSTORE?=1
WOLFBOOT_TPM_KEYSTORE_NV_INDEX?=25166336
WOLFBOOT_TPM_POLICY_NV_INDEX?=25166337
WOLFBOOT_TPM_PCR_INDEX?=16
# NOR Base Address
ARCH_FLASH_OFFSET?=0x20000000
# Flash Sector Size (128 KB)
WOLFBOOT_SECTOR_SIZE=0x20000
# wolfBoot start address
WOLFBOOT_ORIGIN=0x20020000
# wolfBoot partition size
BOOTLOADER_PARTITION_SIZE=0x20000
# Application Partition size
WOLFBOOT_PARTITION_SIZE?=0x20000
# Location in Flash for Application Partition
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20040000
# Load Partition to RAM Address
WOLFBOOT_LOAD_ADDRESS?=0x18020100
# Location in Flash for Update Partition
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x20060000
# Location of temporary sector used during updates
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x20080000
# DTS (Device Tree)
WOLFBOOT_LOAD_DTS_ADDRESS?=0x80000000
WOLFBOOT_DTS_BOOT_ADDRESS?=0x20F00000
WOLFBOOT_DTS_UPDATE_ADDRESS?=0x20F00000

View File

@ -0,0 +1,55 @@
ARCH=AARCH64
TARGET=nxp_ls1028a
SIGN?=ECC256
HASH?=SHA256
DEBUG?=1
DEBUG_UART?=1
VTOR?=0
CORTEX_M0?=0
NO_ASM?=0
EXT_FLASH?=1
SPI_FLASH?=0
## Force app to be copied into ram
NO_XIP?=1
UART_FLASH?=0
ALLOW_DOWNGRADE?=0
NVM_FLASH_WRITEONCE?=0
WOLFBOOT_VERSION?=0
V?=0
NO_MPU?=0
SPMATH?=1
RAM_CODE?=0
DUALBANK_SWAP?=0
PKA?=0
# NOR Base Address
ARCH_FLASH_OFFSET?=0x20000000
# Flash Sector Size (128 KB)
WOLFBOOT_SECTOR_SIZE=0x20000
# wolfBoot start address
WOLFBOOT_ORIGIN=0x20020000
# wolfBoot partition size
BOOTLOADER_PARTITION_SIZE=0x20000
# Application Partition size
WOLFBOOT_PARTITION_SIZE?=0x20000
# Location in Flash for Application Partition
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20040000
# Load Partition to RAM Address
WOLFBOOT_LOAD_ADDRESS?=0x18020100
# Location in Flash for Update Partition
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x20060000
# Location of temporary sector used during updates
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x20080000
# DTS (Device Tree)
WOLFBOOT_LOAD_DTS_ADDRESS?=0x80000000
WOLFBOOT_DTS_BOOT_ADDRESS?=0x20F00000
WOLFBOOT_DTS_UPDATE_ADDRESS?=0x20F00000

View File

@ -16,6 +16,7 @@ This README describes configuration of supported targets.
* [NXP iMX-RT](#nxp-imx-rt)
* [NXP Kinetis](#nxp-kinetis)
* [NXP LPC54xxx](#nxp-lpc54xxx)
* [NXP LS1028A](#nxp-ls1028a)
* [NXP MCXA153](#nxp-mcxa153)
* [NXP P1021 PPC](#nxp-qoriq-p1021-ppc)
* [NXP T1024 PPC](#nxp-qoriq-t1024-ppc)
@ -1073,6 +1074,97 @@ arm-none-eabi-gdb wolfboot.elf -ex "target remote localhost:3333"
```
## NXP LS1028A
The LS1028A is a AARCH64 armv8-a Cortex-A72 processor. Support has been tested with the NXP LS1028ARDB.
Example configurations for this target are provided in:
* NXP LS1028A: [/config/examples/nxp-ls1028a.config](/config/examples/nxp-ls1028a.config).
* NXP LS1028A with TPM: [/config/examples/nxp-ls1028a-tpm.config](/config/examples/nxp-ls1028a-tpm.config).
### Building wolfBoot for NXP LS1028A
1. Download `aarch64-none-elf-` toolchain.
2. Copy the example `nxp-ls1028a.cofig` file to root directory and rename to `.config`
3. Build keytools and wolfboot
```
cp ./config/examples/nxp-ls1028a.config .config
make distclean
make keytools
make
```
This should output 3 binary files, `wolfboot.bin`, `image_v1_signed.bin` and `factory.bin`
- `wolfboot.bin` is the wolfboot binary
- `image_v1_signed.bin` is the signed application image and by default is `test-app/app_nxp_ls1028a`
- `factory.bin` is the two binaries merged together
### Hardware Setup LS1028ARDB
DIP Switch Configuraiton for XSPI_NOR_BOOT:
```
SW2 : 0xF8 = 11111000 SW3 : 0x70 = 01110000 SW5 : 0x20 = 00100000
Where '1' = UP/ON
```
UART Configuraiton:
```
Baud Rate: 115200
Data Bits: 8
Parity: None
Stop Bits: 1
Flow Control: None
Specify device type - PC16552D
Configured for UART1 DB9 Connector
```
### Programming NXP LS1028A
Programming requires three components:
1. RCW binary - Distribured by NXP at `https://github.com/nxp-qoriq/qoriq-rcw-bin` or can be generated using `https://github.com/nxp-qoriq/rcw/tree/master/ls1028ardb/R_SQPP_0x85bb` (tested with `rcw_1300.bin`)
2. woflBoot
3. Application - Test app found in `test-app/app_nxp_ls1028a.c`
Once you have all components, you can use a lauterbach or CW to flash NOR flash. You must flash RCW, wolfboot and singed_image. `factory.bin` can be used which is wolfboot and the signed image merged. You will need to build a signed image for every update to the application code, which can be done by using keytools in `tools/keytools/sign` see `docs/Signing.md` for more details
and to sign a custom image.
```
Usage: tools/keytools/sign [options] image key version
```
#### Lauterbach Flashing and Debugging
1. Launch lauterbach and open the demo script `debug_wolfboot.cmm`.
2. Open any desired debug windows.
3. Hit the play button on the demo script.
4. It should pop up with a code window and at the reset startpoint. (May requrie a reset or power cycle)
```
./t32/bin/macosx64/t32marm-qt
Open Script > debug_wolfboot.cmm
```
You can modify the Lauterbach NOR flash demo or use `debug_wolfboot.cmm` script, just make sure the flash offset for
the RCW is `0x0` and the address offset for wolboot is `0x1000`.
#### Other Tools
1. Make sure the memory addresses are alinged with the `.config` file.
2. Note the important NOR flash addresses in the defualt config are as follows.
3. RCW location is offset `0x0` or `0x20000000` memory mapped.
4. Wolfboot location is offset `0x1000` or `0x20001000` where wolfboot starts.
5. Application location is offset `0x20000` or `0x20020000` where application code goes.
6. Update location is offset `0x40000` or `0x20040000` where the new or updated applciaiton goes.
7. Load Location is `0x18020100` which is OCRAM or where the applciaiton code is loaded if using RAM loading from
8. DTS Location is
9. Update memory locations as neeeded.
## Cortex-A53 / Raspberry PI 3 (experimental)
Tested using `https://github.com/raspberrypi/linux` on Ubuntu 20

View File

@ -39,7 +39,7 @@ To enable measured boot add `MEASURED_BOOT=1` setting in your wolfBoot config.
It is also necessary to select the PCR (index) where the measurement will be stored.
Selection is made using the `MEASURED_BOOT_PCR_A=[index]` setting. Add this
Selection is made using the `MEASURED_PCR_A=[index]` setting. Add this
setting in your wolfBoot config and replace `[index]` with a number between
0 and 23. Below you will find guidelines for selecting a PCR index.

View File

@ -0,0 +1,111 @@
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_vector_table)
MEMORY
{
/*The flash address range on LS1028A RDB is 0x20000000 - 0x23FFFFFF.*/
FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@
/* DDR4 - 2GB */
DRAM (rwx) : ORIGIN = 0x80001000 , LENGTH = 0xBFFFFFFF
/* OCRAM 128K for startup RAM */
OCRAM (rwx) : ORIGIN = 0x18000000, LENGTH = 128K
}
SECTIONS
{
PROVIDE (_DDR_ADDRESS = 0x80001000);
PROVIDE (_OCRAM_ADDRESS = 0x18000000);
PROVIDE (_FLASH_ADDRESS = @WOLFBOOT_ORIGIN@);
PROVIDE (_CORE_NUMBER = 0);
PROVIDE (_MEMORY_SIZE = LENGTH(OCRAM));
PROVIDE (_FLASH_SIZE = LENGTH(FLASH));
PROVIDE (STACK_SIZE = 20K);
.boot :
{
PROVIDE(_vector_table = .);
._vector_table = .;
. = ALIGN(0x800);
KEEP(*(.vector_table))
KEEP(*(.boot*))
} > OCRAM
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.text :
{
_start_text = .;
*(.text*)
*(.note.*)
. = ALIGN(8);
_end_text = .;
} > OCRAM
.rodata :
{
_rodata_start = .;
*(.rodata)
*(.rodata.*)
. = ALIGN(8);
_rodata_end = .;
} > OCRAM
PROVIDE(_stored_data = .);
.data :
{
_start_data = .;
KEEP(*(.data .data.* .gnu.linkonce.d.*))
. = ALIGN(8);
KEEP(*(.ramcode))
. = ALIGN(8);
_end_data = .;
} > OCRAM
.bss :
{
_start_bss = .;
__bss_start__ = .;
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > OCRAM
. = ALIGN(16);
.stack :
{
_start_stack = .;
. = . + STACK_SIZE;
_end_stack = .;
} > OCRAM
PROVIDE(_stack_base = .);
}

879
hal/nxp_ls1028a.c 100644
View File

@ -0,0 +1,879 @@
/* ls1028a.c
*
* Copyright (C) 2024 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 <stdint.h>
#include <string.h>
#include <target.h>
#include "image.h"
#include "printf.h"
#ifndef ARCH_AARCH64
# error "wolfBoot ls1028a HAL: wrong architecture selected. Please compile with ARCH=AARCH64."
#endif
#include "nxp_ls1028a.h"
/* HAL options */
#define ENABLE_DDR
#define BAUD_RATE 115200
#define UART_SEL 0 /* select UART 0 or 1 */
void hal_flash_init(void);
void switch_el3_to_el2(void);
extern void mmu_enable(void);
#ifdef DEBUG_UART
void uart_init(void)
{
/* calc divisor for UART
* example config values:
* clock_div, baud, base_clk 163 115200 400000000
* +0.5 to round up
*/
uint32_t div = (((SYS_CLK / 2.0) / (16 * BAUD_RATE)) + 0.5);
while (!(UART_LSR(UART_SEL) & UART_LSR_TEMT));
/* set ier, fcr, mcr */
UART_IER(UART_SEL) = 0;
UART_FCR(UART_SEL) = (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN);
/* enable baud rate access (DLAB=1) - divisor latch access bit*/
UART_LCR(UART_SEL) = (UART_LCR_DLAB | UART_LCR_WLS);
/* set divisor */
UART_DLB(UART_SEL) = (div & 0xff);
UART_DMB(UART_SEL) = ((div>>8) & 0xff);
/* disable rate access (DLAB=0) */
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 (!(UART_LSR(UART_SEL) & UART_LSR_THRE));
UART_THR(UART_SEL) = '\r';
}
while (!(UART_LSR(UART_SEL) & UART_LSR_THRE));
UART_THR(UART_SEL) = c;
}
}
#endif /* DEBUG_UART */
/* SPI interface */
/* Clear and halt the SPI controller*/
static void spi_close(unsigned int sel)
{
/* Halt, flush and set as master */
SPI_MCR(sel) = SPI_MCR_MASTER_HALT;
}
/*Clear the SPI controller and setup as a running master*/
static void spi_open(unsigned int sel)
{
spi_close(sel);
/* Setup CTAR0 */
SPI_CTAR0(sel) = SPI_CTAR_8_00MODE_8DIV;
/* Enable as master */
SPI_MCR(sel) = SPI_MCR_MASTER_RUNNING;
}
static int spi_can_rx(unsigned int sel)
{
return !!(SPI_SR(sel) & SPI_SR_RXCTR);
}
static unsigned char spi_pop_rx(unsigned int sel)
{
return SPI_POPR(sel) & 0xFF;
}
static void spi_flush_rx(unsigned int sel)
{
unsigned char rx_data;
while (spi_can_rx(sel)) {
rx_data = spi_pop_rx(sel);
}
(void) rx_data;
}
static int spi_can_tx(unsigned int sel)
{
return !!(SPI_SR(sel) & SPI_SR_TFFF);
}
static void spi_push_tx(unsigned int sel, unsigned int pcs, unsigned char data,
int last)
{
SPI_PUSHR(sel) = (last ? SPI_PUSHR_LAST : SPI_PUSHR_CONT)
| SPI_PUSHR_PCS(pcs) | data;
}
/* Perform a SPI transaction. Set cont!=0 to not let CS go low after this*/
static void spi_transaction(unsigned int sel, unsigned int pcs,
const unsigned char *out, unsigned char *in, unsigned int size,
int cont)
{
unsigned int tx_count = size;
unsigned int rx_count = size;
int last = 0;
unsigned char rx_data = 0;
unsigned char tx_data = 0;
/* XXX No parameter validation */
/* Flush RX FIFO */
spi_flush_rx(sel);
/* Nothing to do? */
if (!size)
return;
while (rx_count > 0) {
/* Try to push TX data */
while ((tx_count > 0) && ((rx_count - tx_count) < SPI_FIFO_DEPTH)
&& spi_can_tx(sel)) {
if (out) {
tx_data = *out;
out++;
}
tx_count--;
last = (!cont && !tx_count);
spi_push_tx(sel, pcs, tx_data, last);
}
/* Try to pop RX data */
while ((rx_count > 0) && spi_can_rx(sel)) {
rx_data = spi_pop_rx(sel);
if (in) {
*in = rx_data;
in++;
}
rx_count--;
}
}
}
/*#define TPM_TEST*/
#ifdef TPM_TEST
void read_tpm_id()
{
/*Read 4 bytes from offset D40F00. Assumes 0 wait state on TPM*/
unsigned char out[8] = { 0x83, 0xD4, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00 };
unsigned char in[8] = { 0 };
unsigned char in2[8] = { 0 };
unsigned int counter;
/*LS1028A SPI to the MikroBus uses SPI3 (sel is 2) and CS 0*/
#ifndef SPI_SEL_TPM
#define SPI_SEL_TPM 2
#endif
#ifndef SPI_CS_TPM
#define SPI_CS_TPM 0
#endif
spi_open(SPI_SEL_TPM);
/* Single transaction */
spi_transaction(SPI_SEL_TPM, SPI_CS_TPM, out, in, sizeof(out), 0);
/* Use individual transactions with cont set */
for (counter = 0; counter < (sizeof(out) - 1); counter++) {
spi_transaction(SPI_SEL_TPM, SPI_CS_TPM, &out[counter], &in2[counter], 1,
1);
}
spi_transaction(SPI_SEL_TPM, SPI_CS_TPM, &out[counter], &in2[counter], 1, 0);
spi_close(SPI_SEL_TPM);
(void) in;
(void) in2;
}
#endif
/* Exposed functions */
extern void nxp_ls1028a_spi_init(unsigned int sel);
extern int nxp_ls1028a_spi_xfer(unsigned int sel, unsigned int cs,
const unsigned char *out, unsigned char *in,
unsigned int size, int cont);
extern void nxp_ls1028a_spi_deinit(unsigned int sel);
void nxp_ls1028a_spi_init(unsigned int sel)
{
/* TODO Expose more configuration options */
spi_open(sel);
}
int nxp_ls1028a_spi_xfer(unsigned int sel, unsigned int cs,
const unsigned char *out, unsigned char *in,
unsigned int size, int cont)
{
/*TODO Make spi_transaction actually return errors */
spi_transaction(sel, cs, out, in, size, cont);
return 0;
}
void nxp_ls1028a_spi_deinit(unsigned int sel)
{
spi_close(sel);
}
void hal_delay_us(uint32_t us) {
uint64_t delay = (uint64_t)SYS_CLK * us / 1000000;
volatile uint32_t i = 0;
for (i = 0; i < delay; i++) {
asm volatile("nop");
}
}
/* Fixed addresses */
static const void* kernel_addr = (void*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
static const void* update_addr = (void*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
void* hal_get_primary_address(void)
{
return (void*)kernel_addr;
}
void* hal_get_update_address(void)
{
return (void*)update_addr;
}
void* hal_get_dts_address(void)
{
return (void*)WOLFBOOT_LOAD_DTS_ADDRESS;
}
void* hal_get_dts_update_address(void)
{
return (void*)NULL;
}
void erratum_err050568(void)
{
/* Use IP bus only if systembus PLL is 300MHz (Dont use 300MHz) */
}
/* Application on Serial NOR Flash device 18.6.3 */
void xspi_init(void)
{
/* Configure module control register */
XSPI_MCR0 = XSPI_MCR0_CFG;
XSPI_MCR1 = XSPI_MCR1_CFG;
XSPI_MCR2 = XSPI_MCR2_CFG;
/* Clear RX/TX fifos */
XSPI_IPRXFCR = XSPI_IPRXFCR_CFG; /* Note: RX/TX Water Mark can be set here default is 64bit */
XSPI_IPTXFCR = XSPI_IPTXFCR_CFG; /* Increase size to reduce transfer requests */
/* Configure AHB bus control register (AHBCR) and AHB RX Buffer control register (AHBRXBUFxCR0) */
XSPI_AHBCR = XSPI_AHBCR_CFG;
XSPI_AHBRXBUFnCR0(0) = XSPI_AHBRXBUF0CR_CFG;
XSPI_AHBRXBUFnCR0(1) = XSPI_AHBRXBUF1CR_CFG;
XSPI_AHBRXBUFnCR0(2) = XSPI_AHBRXBUF2CR_CFG;
XSPI_AHBRXBUFnCR0(3) = XSPI_AHBRXBUF3CR_CFG;
XSPI_AHBRXBUFnCR0(4) = XSPI_AHBRXBUF4CR_CFG;
XSPI_AHBRXBUFnCR0(5) = XSPI_AHBRXBUF5CR_CFG;
XSPI_AHBRXBUFnCR0(6) = XSPI_AHBRXBUF6CR_CFG;
XSPI_AHBRXBUFnCR0(7) = XSPI_AHBRXBUF7CR_CFG;
/* Configure Flash control registers (FLSHxCR0,FLSHxCR1,FLSHxCR2) */
XSPI_FLSHA1CR0 = XSPI_FLSHA1CR0_CFG;
XSPI_FLSHA2CR0 = XSPI_FLSHA2CR0_CFG;
XSPI_FLSHB1CR0 = XSPI_FLSHB1CR0_CFG;
XSPI_FLSHB2CR0 = XSPI_FLSHB2CR0_CFG;
XSPI_FLSHA1CR1 = XSPI_FLSHA1CR1_CFG;
XSPI_FLSHA2CR1 = XSPI_FLSHA2CR1_CFG;
XSPI_FLSHB1CR1 = XSPI_FLSHB1CR1_CFG;
XSPI_FLSHB2CR1 = XSPI_FLSHB2CR1_CFG;
XSPI_FLSHA1CR2 = XSPI_FLSHA1CR2_CFG;
XSPI_FLSHA2CR2 = XSPI_FLSHA2CR2_CFG;
XSPI_FLSHB1CR2 = XSPI_FLSHB1CR2_CFG;
XSPI_FLSHB2CR2 = XSPI_FLSHB2CR2_CFG;
/* Configure DLL control register (DLLxCR) according to sample clock source selection */
XSPI_DLLACR = XSPI_DLLACR_CFG;
XSPI_DLLBCR = XSPI_DLLBCR_CFG;
}
void xspi_lut_lock(void)
{
XSPI_LUTKEY = LUT_KEY;
XSPI_LUT_LOCK()
}
void xspi_lut_unlock(void)
{
XSPI_LUTKEY = LUT_KEY;
XSPI_LUT_UNLOCK()
}
void hal_flash_init(void)
{
xspi_lut_unlock();
xspi_init();
/* Fast Read */
XSPI_LUT(LUT_INDEX_READ) = XSPI_LUT_SEQ(RADDR_SDR, LUT_PAD_SINGLE, LUT_OP_ADDR3B, CMD_SDR, LUT_PAD_SINGLE, LUT_OP_READ3B);
XSPI_LUT(1) = XSPI_LUT_SEQ(STOP, LUT_PAD_SINGLE, 0x0, READ_SDR, LUT_PAD_SINGLE, 0x04);
XSPI_LUT(2) = 0x0;
XSPI_LUT(3) = 0x0;
/* Write Enable */
XSPI_LUT(LUT_INDEX_WRITE_EN) = XSPI_LUT_SEQ(STOP, LUT_PAD_SINGLE, 0x0, CMD_SDR, LUT_PAD_SINGLE, LUT_OP_WE);
XSPI_LUT(5) = 0x0;
XSPI_LUT(6) = 0x0;
XSPI_LUT(7) = 0x0;
/* Erase */
XSPI_LUT(LUT_INDEX_SE) = XSPI_LUT_SEQ(RADDR_SDR, LUT_PAD_SINGLE, LUT_OP_ADDR3B, CMD_SDR, LUT_PAD_SINGLE, LUT_OP_SE);
XSPI_LUT(9) = 0x0;
XSPI_LUT(10) = 0x0;
XSPI_LUT(11) = 0x0;
/* Subsector 4k Erase */
XSPI_LUT(LUT_INDEX_SSE4K) = XSPI_LUT_SEQ(RADDR_SDR, LUT_PAD_SINGLE, LUT_OP_ADDR3B, CMD_SDR, LUT_PAD_SINGLE, LUT_OP_SE_4K);
XSPI_LUT(13) = 0x0;
XSPI_LUT(14) = 0x0;
XSPI_LUT(15) = 0x0;
/* Page Program */
XSPI_LUT(LUT_INDEX_PP) = XSPI_LUT_SEQ(RADDR_SDR, LUT_PAD_SINGLE, LUT_OP_ADDR3B, CMD_SDR, LUT_PAD(1), LUT_OP_PP);
XSPI_LUT(17) = XSPI_LUT_SEQ(STOP, LUT_PAD_SINGLE, 0x0, WRITE_SDR, LUT_PAD_SINGLE, 0x1);
XSPI_LUT(18) = 0x0;
XSPI_LUT(19) = 0x0;
/* Read Flag Status Regsiter */
XSPI_LUT(LUT_INDEX_RDSR) = XSPI_LUT_SEQ(READ_SDR, LUT_PAD_SINGLE, LUT_OP_1BYTE, CMD_SDR, LUT_PAD_SINGLE, LUT_OP_RDSR);
XSPI_LUT(21) = 0x0;
XSPI_LUT(22) = 0x0;
XSPI_LUT(23) = 0x0;
xspi_lut_lock();
}
/* Called from boot_aarch64_start.S */
void hal_ddr_init(void)
{
#ifdef ENABLE_DDR
uint64_t counter = 0;
DDR_DDRCDR_1 = DDR_DDRCDR_1_VAL;
DDR_SDRAM_CLK_CNTL = DDR_SDRAM_CLK_CNTL_VAL;
/* Setup DDR CS (chip select) bounds */
DDR_CS_BNDS(0) = DDR_CS0_BNDS_VAL;
DDR_CS_BNDS(1) = DDR_CS1_BNDS_VAL;
DDR_CS_BNDS(2) = DDR_CS2_BNDS_VAL;
DDR_CS_BNDS(3) = DDR_CS3_BNDS_VAL;
/* DDR SDRAM timing configuration */
DDR_TIMING_CFG_0 = DDR_TIMING_CFG_0_VAL;
DDR_TIMING_CFG_1 = DDR_TIMING_CFG_1_VAL;
DDR_TIMING_CFG_2 = DDR_TIMING_CFG_2_VAL;
DDR_TIMING_CFG_3 = DDR_TIMING_CFG_3_VAL;
DDR_TIMING_CFG_4 = DDR_TIMING_CFG_4_VAL;
DDR_TIMING_CFG_5 = DDR_TIMING_CFG_5_VAL;
DDR_TIMING_CFG_6 = DDR_TIMING_CFG_6_VAL;
DDR_TIMING_CFG_7 = DDR_TIMING_CFG_7_VAL;
DDR_TIMING_CFG_8 = DDR_TIMING_CFG_8_VAL;
DDR_ZQ_CNTL = DDR_ZQ_CNTL_VAL;
DDR_DQ_MAP_0 = DDR_DQ_MAP_0_VAL;
DDR_DQ_MAP_1 = DDR_DQ_MAP_1_VAL;
DDR_DQ_MAP_2 = DDR_DQ_MAP_2_VAL;
DDR_DQ_MAP_3 = DDR_DQ_MAP_3_VAL;
/* DDR SDRAM mode configuration */
DDR_SDRAM_CFG_3 = DDR_SDRAM_CFG_3_VAL;
DDR_SDRAM_MODE = DDR_SDRAM_MODE_VAL;
DDR_SDRAM_MODE_2 = DDR_SDRAM_MODE_2_VAL;
DDR_SDRAM_MODE_3 = DDR_SDRAM_MODE_3_VAL;
DDR_SDRAM_MODE_4 = DDR_SDRAM_MODE_4_VAL;
DDR_SDRAM_MODE_5 = DDR_SDRAM_MODE_5_VAL;
DDR_SDRAM_MODE_6 = DDR_SDRAM_MODE_6_VAL;
DDR_SDRAM_MODE_7 = DDR_SDRAM_MODE_7_VAL;
DDR_SDRAM_MODE_8 = DDR_SDRAM_MODE_8_VAL;
DDR_SDRAM_MODE_9 = DDR_SDRAM_MODE_9_VAL;
DDR_SDRAM_MODE_10 = DDR_SDRAM_MODE_10_VAL;
DDR_SDRAM_MODE_11 = DDR_SDRAM_MODE_11_VAL;
DDR_SDRAM_MODE_12 = DDR_SDRAM_MODE_12_VAL;
DDR_SDRAM_MODE_13 = DDR_SDRAM_MODE_13_VAL;
DDR_SDRAM_MODE_14 = DDR_SDRAM_MODE_14_VAL;
DDR_SDRAM_MODE_15 = DDR_SDRAM_MODE_15_VAL;
DDR_SDRAM_MODE_16 = DDR_SDRAM_MODE_16_VAL;
DDR_SDRAM_MD_CNTL = DDR_SDRAM_MD_CNTL_VAL;
/* DDR Configuration */
DDR_SDRAM_INTERVAL = DDR_SDRAM_INTERVAL_VAL;
DDR_DATA_INIT = DDR_DATA_INIT_VAL;
DDR_WRLVL_CNTL = DDR_WRLVL_CNTL_VAL;
DDR_WRLVL_CNTL_2 = DDR_WRLVL_CNTL_2_VAL;
DDR_WRLVL_CNTL_3 = DDR_WRLVL_CNTL_3_VAL;
DDR_SR_CNTR = 0;
DDR_SDRAM_RCW_1 = DDR_SDRAM_RCW_1_VAL;
DDR_SDRAM_RCW_2 = DDR_SDRAM_RCW_2_VAL;
DDR_SDRAM_RCW_3 = DDR_SDRAM_RCW_3_VAL;
DDR_SDRAM_RCW_4 = DDR_SDRAM_RCW_4_VAL;
DDR_SDRAM_RCW_5 = DDR_SDRAM_RCW_5_VAL;
DDR_SDRAM_RCW_6 = DDR_SDRAM_RCW_6_VAL;
DDR_DDRCDR_2 = DDR_DDRCDR_2_VAL;
DDR_SDRAM_CFG_2 = DDR_SDRAM_CFG_2_VAL;
DDR_INIT_ADDR = 0;
DDR_INIT_EXT_ADDR = 0;
DDR_ERR_DISABLE = 0;
DDR_ERR_INT_EN = DDR_ERR_INT_EN_VAL;
DDR_DDRDSR_1 = DDR_DDRDSR_1_VAL;
DDR_DDRDSR_2 = DDR_DDRDSR_2_VAL;
DDR_ERR_SBE = DDR_ERR_SBE_VAL;
DDR_CS_CONFIG(0) = DDR_CS0_CONFIG_VAL;
DDR_CS_CONFIG(1) = DDR_CS1_CONFIG_VAL;
DDR_CS_CONFIG(2) = DDR_CS2_CONFIG_VAL;
DDR_CS_CONFIG(3) = DDR_CS3_CONFIG_VAL;
/* Set values, but do not enable the DDR yet */
DDR_SDRAM_CFG = (DDR_SDRAM_CFG_VAL & ~DDR_SDRAM_CFG_MEM_EN);
hal_delay_us(500);
asm volatile("isb");
/* Enable controller */
DDR_SDRAM_CFG &= ~(DDR_SDRAM_CFG_BI);
DDR_SDRAM_CFG |= DDR_SDRAM_CFG_MEM_EN;
asm volatile("isb");
/* Wait for data initialization is complete */
while ((DDR_SDRAM_CFG_2 & DDR_SDRAM_CFG2_D_INIT)) {
counter++;
}
(void)counter;
#endif
}
void hal_flash_unlock(void) {}
void hal_flash_lock(void) {}
void ext_flash_lock(void) {}
void ext_flash_unlock(void) {}
void xspi_writereg(uint32_t* addr, uint32_t val)
{
*(volatile uint32_t *)(addr) = val;
}
void xspi_write_en(uint32_t addr)
{
XSPI_IPTXFCR = XSPI_IPRCFCR_FLUSH;
XSPI_IPCR0 = addr;
XSPI_IPCR1 = XSPI_ISEQID(LUT_INDEX_WRITE_EN) | 1;
XSPI_IPCMD_START();
while(!(XSPI_INTR & XSPI_IPCMDDONE));
XSPI_INTR |= XSPI_IPCMDDONE;
}
void xspi_read_sr(uint8_t* rxbuf, uint32_t addr, uint32_t len)
{
uint32_t data = 0;
/* Read IP CR regsiter */
uint32_t rxfcr = XSPI_IPRXFCR;
/* Flush RX fifo */
rxfcr = rxfcr | XSPI_IPRCFCR_FLUSH;
XSPI_IPTXFCR = rxfcr;
/* Trigger read SR command */
XSPI_IPCR0 = addr;
XSPI_IPCR1 = XSPI_ISEQID(LUT_INDEX_RDSR) | len;
XSPI_IPCMD_START();
while(!(XSPI_INTR & XSPI_IPCMDDONE));
XSPI_INTR |= XSPI_IPCMDDONE;
data = XSPI_RFD(0);
memcpy(rxbuf, &data, len);
XSPI_IPRXFCR = XSPI_IPRCFCR_FLUSH;
XSPI_INTR = XSPI_IPRXWA;
XSPI_INTR = XSPI_IPCMDDONE;
}
void xspi_sw_reset(void)
{
XSPI_SWRESET();
while (XSPI_MCR0 & XSPI_SW_RESET);
}
void xspi_flash_write(uintptr_t address, const uint8_t *data, uint32_t len)
{
uint32_t size = 0;
uint32_t tx_data = 0;
uint32_t size_wm = 0;
uint32_t loop_cnt = 0;
uint32_t remaining, rem_size = 0;
uint32_t i = 0, j = 0;
while (len) {
size = len > XSPI_IP_BUF_SIZE ? XSPI_IP_BUF_SIZE : len;
XSPI_IPCR0 = address;
loop_cnt = size / XSPI_IP_WM_SIZE;
/* Fill TX fifos */
for (i = 0; i < loop_cnt; i++) {
/* Wait for TX fifo ready */
while (!(XSPI_INTR & XSPI_INTR_IPTXWE_MASK));
for(j = 0; j < XSPI_IP_WM_SIZE; j+=4) {
memcpy(&tx_data, data++, 4);
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
}
/* Reset fifo */
XSPI_INTR = XSPI_INTR_IPTXWE_MASK;
}
remaining = size % XSPI_IP_WM_SIZE;
/* Write remaining data for non aligned data */
if (remaining) {
/* Wait for fifo Empty */
while(!(XSPI_INTR & XSPI_INTR_IPTXWE_MASK));
for(j = 0; j < remaining; j+=4) {
tx_data = 0;
rem_size = (remaining < 4) ? remaining : 4;
memcpy(&tx_data, data++, rem_size);
xspi_writereg((uint32_t*)XSPI_TFD_BASE + j, tx_data);
}
/* Reset fifo */
XSPI_INTR = XSPI_INTR_IPTXWE_MASK;
}
XSPI_IPCR1 = XSPI_ISEQID(LUT_INDEX_PP) | size;
XSPI_IPCMD_START();
/* Wait command done */
while (!(XSPI_INTR & XSPI_IPCMDDONE))
/* Flush fifo, set done flag */
XSPI_IPTXFCR = XSPI_IPRCFCR_FLUSH;
XSPI_INTR = XSPI_IPCMDDONE;
len -= size;
address += size;
}
}
void xspi_flash_sec_erase(uintptr_t address)
{
XSPI_IPCR0 = address;
XSPI_IPCR1 = XSPI_ISEQID(LUT_INDEX_SE) | FLASH_ERASE_SIZE;
XSPI_IPCMD_START();
while(!(XSPI_INTR & XSPI_IPCMDDONE));
XSPI_INTR &= ~XSPI_IPCMDDONE;
}
int hal_flash_write(uintptr_t address, const uint8_t *data, int len)
{
xspi_write_en(address);
xspi_flash_write(address, data, len);
return len;
}
int hal_flash_erase(uintptr_t address, int len)
{
uint32_t num_sectors = 0;
uint32_t i = 0;
uint8_t status[4] = {0, 0, 0, 0};
num_sectors = len / FLASH_ERASE_SIZE;
num_sectors += (len % FLASH_ERASE_SIZE) ? 1 : 0;
for (i = 0; i < num_sectors; i++) {
xspi_write_en(address + i * FLASH_ERASE_SIZE);
xspi_flash_sec_erase(address + i * FLASH_ERASE_SIZE);
while (!(status[0] & FLASH_READY_MSK)) {
xspi_read_sr(status, 0, 1);
}
}
xspi_sw_reset();
return len;
}
int ext_flash_write(uintptr_t address, const uint8_t *data, int len)
{
xspi_write_en(address);
xspi_flash_write(address, data, len);
return len;
}
int ext_flash_read(uintptr_t address, uint8_t *data, int len)
{
address = address & MASK_32BIT;
memcpy(data, (void*)address, len);
return len;
}
int ext_flash_erase(uintptr_t address, int len)
{
uint32_t num_sectors = 0;
uint32_t i = 0;
uint8_t status[4] = {0, 0, 0, 0};
num_sectors = len / FLASH_ERASE_SIZE;
num_sectors += (len % FLASH_ERASE_SIZE) ? 1 : 0;
for (i = 0; i < num_sectors; i++) {
xspi_write_en(address + i * FLASH_ERASE_SIZE);
xspi_flash_sec_erase(address + i * FLASH_ERASE_SIZE);
while (!(status[0] & FLASH_READY_MSK)) {
xspi_read_sr(status, 0, 1);
}
}
xspi_sw_reset();
return len;
}
void hal_prepare_boot(void)
{
#if 0
/* TODO: EL2 */
switch_el3_to_el2();
#endif
}
#ifdef TEST_HW_DDR
static int test_hw_ddr(void)
{
int status = 0;
uint64_t counter = 0;
DDR_MTPn(0) = 0xffffffff;
DDR_MTPn(1) = 0x00000001;
DDR_MTPn(2) = 0x00000002;
DDR_MTPn(3) = 0x00000003;
DDR_MTPn(4) = 0x00000004;
DDR_MTPn(5) = 0x00000005;
DDR_MTPn(6) = 0xcccccccc;
DDR_MTPn(7) = 0xbbbbbbbb;
DDR_MTPn(8) = 0xaaaaaaaa;
DDR_MTPn(9) = 0xffffffff;
DDR_MTCR = DDR_MEM_TEST_EN;
while (DDR_MTCR & DDR_MEM_TEST_EN)
counter++;
if (DDR_ERR_SBE & 0xffff || DDR_ERR_DETECT) {
status = -1;
wolfBoot_printf("DDR ECC error\n");
}
if (DDR_MTCR & DDR_MEM_TEST_FAIL) {
status = -1;
wolfBoot_printf("DDR self-test failed\n");
} else {
status = 0;
wolfBoot_printf("DDR self-test passed\n");
}
return status;
}
#endif /* TEST_HW_DDR */
#ifdef TEST_DDR
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_SIZE/4];
memset(tmp, 0, sizeof(tmp));
/* test write to DDR */
for (i = 0; i < TEST_DDR_SIZE/4; i++) {
ptr[i] = (uint32_t)i;
}
/* test read from DDR */
for (i = 0; i < TEST_DDR_SIZE/4; i++) {
tmp[i] = ptr[i];
}
/* compare results */
for (i = 0; i < TEST_DDR_SIZE/4; i++) {
if (tmp[i] != (uint32_t)i) {
ret = -1;
break;
}
}
return ret;
}
#endif /* TEST_DDR */
#ifdef TEST_EXT_FLASH
#define TEST_ADDRESS 0x20012000
static int test_flash(void)
{
int ret;
uint32_t i;
uint8_t pageData[FLASH_PAGE_SIZE];
/* Erase sector */
ret = ext_flash_erase(TEST_ADDRESS, WOLFBOOT_SECTOR_SIZE);
wolfBoot_printf("Erase Sector: Ret %d\n", ret);
/* Write Pages */
for (i=0; i<sizeof(pageData); i++) {
pageData[i] = (i & 0xff);
}
ret = ext_flash_write(TEST_ADDRESS, pageData, sizeof(pageData));
wolfBoot_printf("Write Page: Ret %d\n", ret);
/* Read page */
memset(pageData, 0, sizeof(pageData));
ret = ext_flash_read(TEST_ADDRESS, pageData, sizeof(pageData));
wolfBoot_printf("Read Page: Ret %d\n", ret);
wolfBoot_printf("Checking...\n");
/* Check data */
for (i=0; i<sizeof(pageData); i++) {
wolfBoot_printf("check[%3d] %02x\n", i, pageData[i]);
if (pageData[i] != (i & 0xff)) {
wolfBoot_printf("Check Data @ %d failed\n", i);
return -i;
}
}
wolfBoot_printf("Flash Test Passed\n");
return ret;
}
#endif /* TEST_EXT_FLASH */
/* Function to set MMU MAIR memory attributes base on index */
void set_memory_attribute(uint32_t attr_idx, uint64_t mair_value)
{
uint64_t mair = 0;
asm volatile("mrs %0, mair_el3" : "=r"(mair));
mair &= ~(0xffUL << (attr_idx * 8));
mair |= (mair_value << (attr_idx * 8));
asm volatile("msr mair_el3, %0" : : "r"(mair));
}
void hal_init_tzpc(void)
{
TZDECPROT0_SET = 0xff; //0x86;
TZDECPROT1_SET = 0xff; //0x00;
TZPCR0SIZE = 0x00; //0x200;
/* Enable TZASC to allow secure read/write access to the DDR */
/* Really, we are allowing the full Region 0 to be R/W in secure world */
TZASC_ACTION = TZASC_ACTION_ENABLE_DECERR;
TZASC_REGION_ATTRIBUTES_0 = TZASC_REGION_ATTRIBUTES_ALLOW_SECRW;
TZASC_GATE_KEEPER = TZASC_GATE_KEEPER_REQUEST_OPEN;
}
void hal_init(void)
{
volatile uint32_t counter=0xFFFFul; /* used for delay */
#ifdef DEBUG_UART
uint32_t fw;
uart_init();
wolfBoot_printf("wolfBoot Init\n");
#endif
hal_init_tzpc();
hal_flash_init();
wolfBoot_printf("Flash init done\n");
#ifdef TEST_EXT_FLASH
test_flash();
#endif
#ifdef TPM_TEST
read_tpm_id();
wolfBoot_printf("TPM test done\n");
#endif
hal_ddr_init();
wolfBoot_printf("DDR init done\n");
#ifdef TEST_HW_DDR
test_hw_ddr();
#endif
while (counter--);
wolfBoot_printf("Delay is done\n");
#if TEST_DDR
if (test_ddr() == -1) {
wolfBoot_printf("DDR R/W test failed\n");
}
else {
wolfBoot_printf("DDR R/W test passed\n");
}
#endif
#if 0
/* TODO: MMU enable? */
mmu_enable();
wolfBoot_printf("MMU init done\n");
#endif
}

767
hal/nxp_ls1028a.h 100644
View File

@ -0,0 +1,767 @@
/* nxp_ls1028a.h
*
* Copyright (C) 2024 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
*/
#ifndef NXP_LS1028A_H
#define NXP_LS1028A_H
/* Expose AA64 defines */
#define AA64_TARGET_EL 2 /* Boot to EL2 hypervisor */
#define AA64_CNTFRQ ARMGT_CLK /* ARM Global Generic Timer */
#define AA64GIC_VERSION 3 /* GIC-500 in v3 mode */
#define AA64GICV3_GICD_BASE GICD_BASE
#define AA64GICV3_GITS_BASE GITS_BASE
#define AA64GICV3_GITST_BASE GITST_BASE
/* LS1028A Reference Manual Rev 0 12/2019 */
/* LS1028A Memory Map 0GB - 4GB Table 1 */
#define BOOTROM_BASE (0x00000000ul) /* Boot ROM */
#define BOOTROM_SIZE (64ul*1024) /* 64kB */
#define CCSR_BASE (0x01000000ul) /* CCSR register space */
#define CCSR_SIZE (240ul*1024*1024) /* 240MB */
#define OCRAM_BASE (0x18000000ul) /* On-Chip RAM */
#define OCRAM_SIZE (256ul*1024) /* 256kB */
#define CSSTM_BASE (0x19000000ul) /* CoreSight STM */
#define CSSTM_SIZE (16ul*1024*1024) /* 16MB */
#define XSPIWIN1_BASE (0x20000000ul) /* FlexSPI window 1 */
#define XSPIWIN1_SIZE (256ul*1024*1024) /* 256MB */
#define DDRWIN1_BASE (0x80000000ul) /* DRAM window 1 */
#define DDRWIN1_SIZE (2048ul*1024*1024) /* 2GB */
/* LS1028A Memory Map 4GB - 576GB Table 1*/
#define ECAMCFG_BASE (0x01F0000000ull) /* ECAM Config space */
#define ECAMREG_BASE (0x01F0800000ull) /* ECAM Register space */
#define ECAMRCIE_BASE (0x01F8000000ull) /* ECAM RCIE */
#define XSPIWIN2_BASE (0x0401000000ull) /* FlexSPI window 2 */
#define XSPIWIN2_SIZE (0x00F0000000ull) /* 3840MB */
#define DCSR_BASE (0x0700000000ull) /* DCSR */
#define DDRWIN2_BASE (0x2080000000ull) /* DDR window 2 */
#define DDRWIN2_SIZE (0x1F80000000ull) /* 126GB */
#define DDRWIN3_BASE (0x6000000000ull) /* DDR window 3 */
#define DDRWIN3_SIZE (0x2000000000ull) /* 126GB */
#define PCIE1_BASE (0x8000000000ull) /* PCIE 1 */
#define PCIE1_SIZE (0x0800000000ull) /* 32GB */
#define PCIE2_BASE (0x8800000000ull) /* PCIE 2 */
#define PCIE2_SIZE (0x0800000000ull) /* 32GB */
/* LS1028A CCSR Memory Map Table 2 */
#define DDRC_BASE (0x01080000ul) /* DDR Controller */
#define TZASC_BASE (0x01100000ul) /* Trust Zone ASC for DDR */
#define CGUCGA_BASE (0x01300000ul) /* Clock Generation Unit - CGA */
#define CGUP_BASE (0x01360000ul) /* Platform CGU */
#define CGUPTZ_BASE (0x01368000ul) /* Secure Platform CGU */
#define CLOCK_BASE (0x01370000ul) /* Clocking */
#define CGUD_BASE (0x01380000ul) /* DDR CGU */
#define DDRPHY1_BASE (0x01400000ul) /* DDR PHY for DDRC 1 */
#define DCFG_BASE (0x01E00000ul) /* Privileged Device Config */
#define PMU_BASE (0x01E30000ul) /* Power Management Unit */
#define RESET_BASE (0x01E60000ul) /* Reset */
#define SFP_BASE (0x01E80000ul) /* Security Fuse Processor */
#define SFPTZ_BASE (0x01E88000ul) /* TrustZone SFP */
#define SECMON_BASE (0x01E90000ul) /* Security Monitor */
#define SERDES_BASE (0x01EA0000ul) /* SerDes */
#define SERVP_BASE (0x01F00000ul) /* Service Processor */
#define ISC_BASE (0x01F70000ul) /* Interrupt Sampling Control */
#define TMU_BASE (0x01F80000ul) /* Thermal Monitor Unit */
#define VOLT_BASE (0x01F90000ul) /* Voltage Sense */
#define SCFG_BASE (0x01FC0000ul) /* Supplemental Configuration */
#define PINC_BASE (0x01FF0000ul) /* Pin Control */
#define I2C0_BASE (0x02000000ul) /* I2C 1 */
#define I2C_STRIDE (0x10000ul) /* For I2C 1-8 */
#define I2C_COUNT (8)
#define I2C_BASE(_n) (I2C0_BASE + ((_n) % I2C_COUNT) * I2C_STRIDE)
#define XSPIC_BASE (0x020C0000ul) /* FlexSPI */
#define SPI0_BASE (0x02100000ul) /* SPI 1 */
#define SPI_STRIDE (0x10000ul) /* For SPI 1-3 */
#define SPI_COUNT (3)
#define SPI_BASE(_n) (SPI0_BASE + ((_n) % SPI_COUNT) * SPI_STRIDE)
#define ESDHC0_BASE (0x02140000ul) /* eSDHC 1 */
#define ESDHC_STRIDE (0x10000ul) /* For eSDHC 1-2 */
#define ESDHC_COUNT (2)
#define ESDHC_BASE(_n) (ESDHC0_BASE + ((_n) % ESDHC_COUNT) * ESDHC_STRIDE)
#define CANBUS0_BASE (0x02180000ul) /* CAN 1 */
#define CANBUS_STRIDE (0x10000ul) /* For CAN 1-2 */
#define CANBUS_COUNT (8)
#define CANBUS_BASE(_n) (CANBUS0_BASE + ((_n) % CANBUS_COUNT) * CANBUS_STRIDE)
#define DUART0_BASE (0x021C0500ul) /* DUART 1 */
#define DUART_STRIDE (0x100ul) /* For DUART 1-2 */
#define DUART_COUNT (2)
#define DUART_BASE(_n) (DUART0_BASE + ((_n) % DUART_COUNT) * DUART_STRIDE)
#define OCTZPC_BASE (0x02200000ul) /* OCRAM TZPC */
#define LPUART0_BASE (0x02260000ul) /* LPUART 1 */
#define LPUART_STRIDE (0x10000ul) /* For LPUART 1-6 */
#define LPUART_COUNT (6)
#define LPUART_BASE(_n) (LPUART0_BASE + ((_n) % LPUART_COUNT) * LPUART_STRIDE)
#define EDMA_BASE (0x022C0000ul) /* eDMA */
#define EDMAMX0_BASE (0x022D0000ul) /* eDMA Channel Mux 1 */
#define EDMAMX_STRIDE (0x10000ul) /* For EDMAMX 1-2 */
#define EDMAMX_COUNT (2)
#define EDMAMX_BASE(_n) (EDMAMX0_BASE + ((_n) % EDMAMX_COUNT) * EDMAMX_STRIDE)
#define GPIO0_BASE (0x02300000ul) /* GPIO 1 */
#define GPIO_STRIDE (0x10000ul) /* For GPIO 1-3 */
#define GPIO_COUNT (3)
#define GPIO_BASE(_n) (GPIO0_BASE + ((_n) % GPIO_COUNT) * GPIO_STRIDE)
#define TZWDT_BASE (0x023C0000ul) /* Trust Zone Watchdog Timer */
#define GGRT_BASE (0x023D0000ul) /* Global Generic Reference Timer */
#define GGRTC_BASE (0x023E0000ul) /* GGRT Control */
#define GGRTS_BASE (0x023F0000ul) /* GGRT Status */
#define FLEXT0_BASE (0x02800000ul) /* Flex Timer 1 */
#define FLEXT_STRIDE (0x10000ul) /* For Flex Timer 1-8 */
#define FLEXT_COUNT (8)
#define FLEXT_BASE(_n) (FLEXT0_BASE + ((_n) % FLEXT_COUNT) * FLEXT_STRIDE)
#define USB0_BASE (0x03100000ul) /* USB 1 */
#define USB_STRIDE (0x10000ul) /* For USB 1-2 */
#define USB_COUNT (2)
#define USB_BASE(_n) (USB0_BASE + ((_n) % USB_COUNT) * USB_STRIDE)
#define SATA_BASE (0x03200000ul) /* SATA */
#define PCIE_COUNT (2)
#define PCIEPF0_BASE (0x03400000ul) /* PCI Express PF0 1 */
#define PCIELT0_BASE (0x03480000ul) /* PCIE Controller LUT 1 */
#define PCIEPC0_BASE (0x034C0000ul) /* PCIE Controller PF0 Controls 1 */
#define PCIEPF_STRIDE (0x10000ul) /* For PCIE PF0 1-2 */
#define PCIELT_STRIDE (0x10000ul) /* For PCIE LUT 1-2 */
#define PCIEPC_STRIDE (0x10000ul) /* For PCIE PF0 Controls 1-2 */
#define PCIEPF_BASE(_n) (PCIEPF0_BASE + ((_n) % PCIE_COUNT) * PCIEPF_STRIDE)
#define PCIELT_BASE(_n) (PCIELT0_BASE + ((_n) % PCIE_COUNT) * PCIELT_STRIDE)
#define PCIEPC_BASE(_n) (PCIEPC0_BASE + ((_n) % PCIE_COUNT) * PCIEPC_STRIDE)
#define CCI400_BASE (0x04090000ul) /* CCI-400 Configuration */
#define MMUGR0_BASE (0x05000000ul) /* MMU-500 Global Register Space 0 */
#define MMUGR1_BASE (0x05010000ul) /* MMU-500 Global Register Space 1 */
#define MMUGID_BASE (0x05020000ul) /* MMU-500 Implementation Defined */
#define MMUPM_BASE (0x05030000ul) /* MMU-500 Performance Monitor */
#define MMUSSD_BASE (0x05050000ul) /* MMU-500 Security State */
#define MMUTCB0_BASE (0x05400000ul) /* MMU Translation Context Bank 0 */
#define MMUTCB_STRIDE (0x10000ul) /* For MMUTCB 0-63 */
#define MMUTCB_COUNT (64)
#define MMUTCB_BASE(_n) (MMUTCB0_BASE + ((_n) % MMUTCB_COUNT) * MMUTCB_STRIDE)
#define GICD_BASE (0x06000000ul) /* GIC-500 GICD */
#define GITS_BASE (0x06020000ul) /* GIC-500 GITS Control */
#define GITST_BASE (0x06030000ul) /* GIC-500 GITS Translation */
#define CPU0RD_BASE (0x06040000ul) /* CPU0 control, Locality Perif Int*/
#define CPU0SGI_BASE (0x06050000ul) /* CPU0 SW Gen Int, Priv Perif Int */
#define CPU1RD_BASE (0x06060000ul) /* CPU1 control, physical LPIs */
#define CPU1SGI_BASE (0x06070000ul) /* CPU1 SGIs, PPIs */
#define SEC_BASE (0x08000000ul) /* General Purpose SEC Block */
#define QDMACONF_BASE (0x08380000ul) /* qDMA Configuration */
#define QDMAMGMT_BASE (0x08390000ul) /* qDMA Management */
#define QDMASA_BASE (0x083A0000ul) /* qDMA Standalone */
#define CPU0WDT_BASE (0x0C000000ul) /* Core 0 WDT */
#define CPU1WDT_BASE (0x0C010000ul) /* Core 1 WDT */
#define LCD_BASE (0x0F080000ul) /* LCD Controller */
#define GPU_BASE (0x0F0C0000ul) /* GPU */
#define SAI0_BASE (0x0F100000ul) /* Synchronous Audio Interface 1 */
#define SAI_STRIDE (0x10000ul) /* For SAI 1-6 */
#define SAI_COUNT (6)
#define SAI_BASE(_n) (SAI0_BASE + ((_n) % SAI_COUNT) * SAI_STRIDE)
#define MMPLL_BASE (0x0F1F0000ul) /* Multimedia PLL 1 */
#define EDPPHY_BASE (0x0F200000ul) /* Display PHY and PHY Controller */
/* Alternate SMMU names */
#define SMMU_GR0_BASE MMUGR0_BASE
#define SMMU_GR1_BASE MMUGR1_BASE
#define SMMU_GID_BASE MMUGID_BASE
#define SMMU_PM_BASE MMUPM_BASE
#define SMMU_SSD_BASE MMUSSD_BASE
#define SMMU_TOP MMUTCB0_BASE
#define SMMU_GLOBAL_TOP MMUTCB0_BASE
#define SMMU_CB_BASE MMUTCB0_BASE
/* Clocking */
#define SYSTEM_CLK (100000000ul) /* System clock fixed 100MHz */
#define ARMGT_CLK (SYSTEM_CLK / 4) /* ARM Generic Timer fixed 1/4 */
/* Platform CLK = SYSTEM_CLK * RCW[SYS_PLL_RAT] which is usually 4
*
* Peripherals using Platform CLK:
* OCRAM, eSDHC, CCI-400, TZC-400, SecMon, SEC, TSN L2Switch, PCIe, GIC-500,
* ENETC, GPU, RCPM, SATA, qDMA
*
* Peripherals using Platform CLK / 2:
* LPUART, Service Proc, GPIO, SPI, FTM, FlexSPI (APB), DUART, TMU, WDOG, TZPC,
* SAI, USB, CAN
*
* Peripherals using Platform CLK / 4:
* I2C
*/
#define SYS_CLK (400000000) /* Sysclock = 400Mhz set by RCW */
#define FLASH_FREQ (100000000) /* Flash clock = 100Mhz */
#define NOR_BASE (0x20000000)
/* TZC-400 CoreLink Trust Zone Address Space Controller for DDR RM 32.2*/
#define TZASC_BUILD_CONFIG *((volatile uint32_t*)(TZASC_BASE + 0x0))
#define TZASC_ACTION *((volatile uint32_t*)(TZASC_BASE + 0x4))
#define TZASC_GATE_KEEPER *((volatile uint32_t*)(TZASC_BASE + 0x8))
#define TZASC_SPECULATION_CTRL *((volatile uint32_t*)(TZASC_BASE + 0xC))
#define TZASC_INT_STATUS *((volatile uint32_t*)(TZASC_BASE + 0x10))
#define TZASC_INT_CLEAR *((volatile uint32_t*)(TZASC_BASE + 0x14))
#define TZASC_FAIL_ADDRESS_LOW *((volatile uint32_t*)(TZASC_BASE + 0x20))
#define TZASC_FAIL_ADDRESS_HIGH *((volatile uint32_t*)(TZASC_BASE + 0x24))
#define TZASC_FAIL_CONTROL *((volatile uint32_t*)(TZASC_BASE + 0x28))
#define TZASC_REGION_BASE_LOW_0 *((volatile uint32_t*)(TZASC_BASE + 0x100))
#define TZASC_REGION_BASE_HIGH_0 *((volatile uint32_t*)(TZASC_BASE + 0x104))
#define TZASC_REGION_TOP_LOW_0 *((volatile uint32_t*)(TZASC_BASE + 0x108))
#define TZASC_REGION_TOP_HIGH_0 *((volatile uint32_t*)(TZASC_BASE + 0x10C))
#define TZASC_REGION_ATTRIBUTES_0 *((volatile uint32_t*)(TZASC_BASE + 0x110))
#define TZASC_ACTION_ENABLE_DECERR 0x1 /* RM 32.4.3 */
#define TZASC_GATE_KEEPER_REQUEST_OPEN 0x1 /* RM 32.4.3 */
#define TZASC_REGION_ATTRIBUTES_ALLOW_SECRW 0xC0000001 /* RM 32.4.15 */
/* TZPC Trust Zone Protection Controller for OCRAM RM 32.6 */
#define TZPC_OCRAM (0x2200000)
#define TZPCR0SIZE *((volatile uint32_t*)(TZPC_OCRAM + 0x0))
#define TZDECPROT0_STAT *((volatile uint32_t*)(TZPC_OCRAM + 0x800))
#define TZDECPROT0_SET *((volatile uint32_t*)(TZPC_OCRAM + 0x804))
#define TZDECPROT0_CLR *((volatile uint32_t*)(TZPC_OCRAM + 0x808))
#define TZDECPROT1_STAT *((volatile uint32_t*)(TZPC_OCRAM + 0x80C))
#define TZDECPROT1_SET *((volatile uint32_t*)(TZPC_OCRAM + 0x810))
#define TZDECPROT1_CLR *((volatile uint32_t*)(TZPC_OCRAM + 0x814))
#define TZPCPERIPHID0 *((volatile uint32_t*)(TZPC_OCRAM + 0xFE0))
#define TZPCPERIPHID1 *((volatile uint32_t*)(TZPC_OCRAM + 0xFE4))
#define TZPCPERIPHID2 *((volatile uint32_t*)(TZPC_OCRAM + 0xFE8))
#define TZPCPERIPHID3 *((volatile uint32_t*)(TZPC_OCRAM + 0xFEC))
#define TZPCPCELLID0 *((volatile uint32_t*)(TZPC_OCRAM + 0xFF0))
#define TZPCPCELLID1 *((volatile uint32_t*)(TZPC_OCRAM + 0xFF4))
#define TZPCPCELLID2 *((volatile uint32_t*)(TZPC_OCRAM + 0xFF8))
#define TZPCPCELLID3 *((volatile uint32_t*)(TZPC_OCRAM + 0xFFC))
#define TZWT_BASE (0x23C0000)
/* LS1028A PC16552D Dual UART */
#define UART_BASE(n) (0x21C0500 + (n * 100))
#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_FCR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_IIR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_LCR(n) *((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_LSR(n) *((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */
#define UART_SCR(n) *((volatile uint8_t*)(UART_BASE(n) + 7)) /* scratch 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 */
/* LS1028 XSPI Flex SPI Memory map - RM 18.7.2.1 */
#define XSPI_BASE (0x20C0000UL)
#define XSPI_MCRn(x) *((volatile uint32_t*)(XSPI_BASE + (x * 0x4))) /* Module Control Register */
#define XSPI_MCR0 *((volatile uint32_t*)(XSPI_BASE + 0x0)) /* Module Control Register */
#define XSPI_MCR1 *((volatile uint32_t*)(XSPI_BASE + 0x4)) /* Module Control Register */
#define XSPI_MCR2 *((volatile uint32_t*)(XSPI_BASE + 0x8)) /* Module Control Register */
#define XSPI_AHBCR *((volatile uint32_t*)(XSPI_BASE + 0xC)) /* Bus Control Register */
#define XSPI_INTEN *((volatile uint32_t*)(XSPI_BASE + 0x10)) /* Interrupt Enable Register */
#define XSPI_INTR *((volatile uint32_t*)(XSPI_BASE + 0x14)) /* Interrupt Register */
#define XSPI_LUTKEY *((volatile uint32_t*)(XSPI_BASE + 0x18)) /* LUT Key Register */
#define XSPI_LUTCR *((volatile uint32_t*)(XSPI_BASE + 0x1C)) /* LUT Control Register */
#define XSPI_AHBRXBUFnCR0(x) *((volatile uint32_t*)(XSPI_BASE + 0x20 + (x * 0x4))) /* AHB RX Buffer Control Register */
#define XSPI_FLSHA1CR0 *((volatile uint32_t*)(XSPI_BASE + 0x60)) /* Flash A1 Control Register */
#define XSPI_FLSHA2CR0 *((volatile uint32_t*)(XSPI_BASE + 0x64)) /* Flash A2 Control Register */
#define XSPI_FLSHB1CR0 *((volatile uint32_t*)(XSPI_BASE + 0x68)) /* Flash B1 Control Register */
#define XSPI_FLSHB2CR0 *((volatile uint32_t*)(XSPI_BASE + 0x6C)) /* Flash B2 Control Register */
#define XSPI_FLSHA1CR1 *((volatile uint32_t*)(XSPI_BASE + 0x70)) /* Flash A1 Control Register */
#define XSPI_FLSHA2CR1 *((volatile uint32_t*)(XSPI_BASE + 0x74)) /* Flash A2 Control Register */
#define XSPI_FLSHB1CR1 *((volatile uint32_t*)(XSPI_BASE + 0x78)) /* Flash B1 Control Register */
#define XSPI_FLSHB2CR1 *((volatile uint32_t*)(XSPI_BASE + 0x7C)) /* Flash B2 Control Register */
#define XSPI_FLSHA1CR2 *((volatile uint32_t*)(XSPI_BASE + 0x80)) /* Flash A1 Control Register */
#define XSPI_FLSHA2CR2 *((volatile uint32_t*)(XSPI_BASE + 0x84)) /* Flash A2 Control Register */
#define XSPI_FLSHB1CR2 *((volatile uint32_t*)(XSPI_BASE + 0x88)) /* Flash B1 Control Register */
#define XSPI_FLSHB2CR2 *((volatile uint32_t*)(XSPI_BASE + 0x8C)) /* Flash B2 Control Register */
#define XSPI_FLSHCR4 *((volatile uint32_t*)(XSPI_BASE + 0x94)) /* Flash A1 Control Register */
#define XSPI_IPCR0 *((volatile uint32_t*)(XSPI_BASE + 0xA0)) /* IP Control Register 0 */
#define XSPI_IPCR1 *((volatile uint32_t*)(XSPI_BASE + 0xA4)) /* IP Control Register 1 */
#define XSPI_IPCMD *((volatile uint32_t*)(XSPI_BASE + 0xB0)) /* IP Command Register */
#define XSPI_DLPR *((volatile uint32_t*)(XSPI_BASE + 0xB4)) /* Data Lean Pattern Register */
#define XSPI_IPRXFCR *((volatile uint32_t*)(XSPI_BASE + 0xB8)) /* IPC RX FIFO Control Register */
#define XSPI_IPTXFCR *((volatile uint32_t*)(XSPI_BASE + 0xBC)) /* IPC TX FIFO Control Register */
#define XSPI_DLLACR *((volatile uint32_t*)(XSPI_BASE + 0xC0)) /* DLLA Control Register */
#define XSPI_DLLBCR *((volatile uint32_t*)(XSPI_BASE + 0xC4)) /* DLLB Control Register */
#define XSPI_STS0 *((volatile uint32_t*)(XSPI_BASE + 0xE0)) /* Status Register 0 */
#define XSPI_STS1 *((volatile uint32_t*)(XSPI_BASE + 0xE4)) /* Status Register 1 */
#define XSPI_STS2 *((volatile uint32_t*)(XSPI_BASE + 0xE8)) /* Status Register 2 */
#define XSPI_AHBSPNDST *((volatile uint32_t*)(XSPI_BASE + 0xEC)) /* AHB Suspend Status Register */
#define XSPI_IPRXFSTS *((volatile uint32_t*)(XSPI_BASE + 0xF0)) /* IPC RX FIFO Status Register */
#define XSPI_IPTXFSTS *((volatile uint32_t*)(XSPI_BASE + 0xF4)) /* IPC TX FIFO Status Register */
#define XSPI_RFD(x) *((volatile uint32_t*)(XSPI_BASE + 0x100 + (x * 0x4))) /* RX FIFO Data Register */
#define XSPI_TFD_BASE (XSPI_BASE + 0x180) /* TX FIFO Data Register Base Address */
#define XSPI_TFD(x) *((volatile uint32_t*)(XSPI_BASE + 0x180 + (x * 0x4))) /* TX FIFO Data Register */
#define XSPI_LUT(x) *((volatile uint32_t*)(XSPI_BASE + 0x200 + (x * 0x4))) /* LUT Register */
#define XSPI_SFAR XSPI_IPCR0 /* Serial Flash Address Register determined by AHB burst address */
/* XSPI register instructions */
#define XSPI_SWRESET() XSPI_MCRn(0) |= 0x1; /* XSPI Software Reset */
#define XSPI_ENTER_STOP() XSPI_MCRn(0) |= 0x1 << 1; /* XSPI Module Disable */
#define XSPI_EXIT_STOP() XSPI_MCRn(0) |= 0x0 << 1; /* XSPI Module Enable */
#define XSPI_LUT_LOCK() XSPI_LUTCR = 0x1; /* XSPI LUT Lock */
#define XSPI_LUT_UNLOCK() XSPI_LUTCR = 0x2; /* XSPI LUT Unlock */
#define XSPI_ISEQID(x) (x << 16) /* Sequence Index In LUT */
#define XSPI_ISEQNUM(x) (x << 24) /* Number of Sequences to Execute ISEQNUM+1 */
#define XSPI_IPAREN() (0x1 << 31) /* Peripheral Chip Select Enable */
#define XSPI_IDATSZ(x) (x << 0) /* Number of Data Bytes to Send */
#define XSPI_IPCMD_START() (XSPI_IPCMD = 0x1) /* Start IP Command */
#define XSPI_IPCMDDONE (0x1)
#define XSPI_IPRXWA (0x1 << 5)
#define XSPI_IPRCFCR_FLUSH (0x1)
#define XSPI_IP_BUF_SIZE (256)
#define XSPI_IP_WM_SIZE (8)
#define XSPI_INTR_IPTXWE_MASK (0x1 << 6)
#define XSPI_SW_RESET (0x1)
/* XSPI Parameters */
#define XSPI_MAX_BANKS (8)
#define XSPI_MAX_LUT_ENTRIES (64)
#define XSPI_FIFO_DEPTH (32)
#define XSPI_FIFO_SIZE (XSPI_FIFO_DEPTH * 4)
/* IPRXFCR Masks*/
#define XSPI_IPRXFCR_RXWMRK_MASK(x) (x << 2) /* XSPI RX Watermark */
#define XSPI_IPRXFCR_RXDMAEN_MASK (0x1 << 1) /* XSPI RX DMA Enable */
#define XSPI_IPRXFCR_CLRIPRXF_MASK (0x1 << 0) /* XSPI Clear RX FIFO */
/* MCR Masks */
#define XSPI_MCR_SWRESET_MASK (0x1) /* XSPI Software Reset */
#define XSPI_MCR_MDIS_MASK (0x1 << 1) /* XSPI Module Disable */
#define XSPI_MCR_RXCLKSRC_MASK (0x3 << 4) /* XSPI RX Clock Source */
#define XSPI_MCR_ARDFEN_MASK (0x1 << 6) /* XSPI AHB RX FIFO DMA Enable */
#define XSPI_MCR_ATDFEN_MASK (0x1 << 7) /* XSPI AHB TX FIFO DMA Enable */
#define XSPI_MCR_SERCLKDIV_MASK (0x7 << 8) /* XSPI Serial Clock Divider */
#define XSPI_MCR_HSEN_MASK (0x1 << 11) /* XSPI Half Speed Serial Clock Enable */
#define XSPI_MCR_DOZEEN_MASK (0x1 << 12) /* XSPI Doze Enable */
#define XSPI_MCR_COMBINATIONEN_MASK (0x1 << 13) /* XSPI Combination Mode Enable */
#define XSPI_MCR_SCKFREERUNEN_MASK (0x1 << 14) /* XSPI Serial Clock Free Run Enable */
#define XSPI_MCR_LEARNEN_MASK (0x1 << 15) /* XSPI Learn Mode Enable */
/* XSPI Init */
/*#define XSPI_MCR0_CFG 0xFFFF80C0*/
#define XSPI_MCR0_CFG 0xFFFF0000
#define XSPI_MCR1_CFG 0xFFFFFFFF
#define XSPI_MCR2_CFG 0x200081F7
#define XSPI_INTEN_CFG 0x00000061
#define XSPI_AHBCR_CFG 0x00000038
#define XSPI_AHBRXBUF0CR_CFG 0x80000100
#define XSPI_AHBRXBUF1CR_CFG 0x80010100
#define XSPI_AHBRXBUF2CR_CFG 0x80020100
#define XSPI_AHBRXBUF3CR_CFG 0x80030100
#define XSPI_AHBRXBUF4CR_CFG 0x80040100
#define XSPI_AHBRXBUF5CR_CFG 0x80050100
#define XSPI_AHBRXBUF6CR_CFG 0x80060100
#define XSPI_AHBRXBUF7CR_CFG 0x80070100
/* Flash Size */
#define XSPI_FLSHA1CR0_CFG 0x80000
#define XSPI_FLSHA2CR0_CFG 0x80000
#define XSPI_FLSHB1CR0_CFG 0x80000
#define XSPI_FLSHB2CR0_CFG 0x80000
/* XSPI Timing */
#define XSPI_FLSHA1CR1_CFG 0x00000063
#define XSPI_FLSHA2CR1_CFG 0x00000063
#define XSPI_FLSHB1CR1_CFG 0x00000063
#define XSPI_FLSHB2CR1_CFG 0x00000063
#define XSPI_FLSHA1CR2_CFG 0x00000C00
#define XSPI_FLSHA2CR2_CFG 0x00000C00
#define XSPI_FLSHB1CR2_CFG 0x00000C00
#define XSPI_FLSHB2CR2_CFG 0x00000C00
#define XSPI_IPRXFCR_CFG 0x00000001
#define XSPI_IPTXFCR_CFG 0x00000001
#define XSPI_DLLACR_CFG 0x100
#define XSPI_DLLBCR_CFG 0x100
#define XSPI_AHB_UPDATE 0x20
/* Initalize LUT for NOR flash
* MT35XU02GCBA1G12-0SIT ES
* 256 MB, PBGA24 x1/x8 SPI serial NOR flash memory
* Supports 166 MHz SDR speed and 200 MHz DDR speed
* Powers up in x1 mode and can be switched to x8 mode
* All padding is x1 mode or (1)
*/
/* NOR Flash parameters */
#define FLASH_BANK_SIZE (256 * 1024 * 1024) /* 256MB total size */
#define FLASH_PAGE_SIZE (256) /* program size */
#define FLASH_ERASE_SIZE (128 * 1024) /* erase sector size */
#define FLASH_SECTOR_CNT (FLASH_BANK_SIZE / FLASH_ERASE_SIZE)
#define FLASH_ERASE_TOUT 60000 /* Flash Erase Timeout (ms) */
#define FLASH_WRITE_TOUT 500 /* Flash Write Timeout (ms) */
#define FLASH_READY_MSK (0x1 << 0)
#define MASK_32BIT 0xffffffff
/* LUT register helper */
#define XSPI_LUT_SEQ(code1, pad1, op1, code0, pad0, op0) \
(((code1) << 26) | ((pad1) << 24) | ((op1) << 16) | \
(code0) << 10 | ((pad0) << 8) | (op0))
/* FlexSPI Look up Table defines */
#define LUT_KEY 0x5AF05AF0
/* Calculate the number of PAD bits for LUT register*/
#define LUT_PAD(x) (x - 1)
#define LUT_PAD_SINGLE LUT_PAD(1)
#define LUT_PAD_OCTAl LUT_PAD(4)
#define CMD_SDR 0x01
#define CMD_DDR 0x21
#define RADDR_SDR 0x02
#define RADDR_DDR 0x22
#define CADDR_SDR 0x03
#define CADDR_DDR 0x23
#define MODE1_SDR 0x04
#define MODE1_DDR 0x24
#define MODE2_SDR 0x05
#define MODE2_DDR 0x25
#define MODE4_SDR 0x06
#define MODE4_DDR 0x26
#define MODE8_SDR 0x07
#define MODE8_DDR 0x27
#define WRITE_SDR 0x08
#define WRITE_DDR 0x28
#define READ_SDR 0x09
#define READ_DDR 0x29
#define LEARN_SDR 0x0A
#define LEARN_DDR 0x2A
#define DATSZ_SDR 0x0B
#define DATSZ_DDR 0x2B
#define DUMMY_SDR 0x0C
#define DUMMY_DDR 0x2C
#define DUMMY_RWDS_SDR 0x0D
#define DUMMY_RWDS_DDR 0x2D
#define JMP_ON_CS 0x1F
#define STOP 0
/* MT35XU02GCBA1G12 Operation definitions */
#define LUT_OP_WE 0x06 /* Write Enable */
#define LUT_OP_WD 0x04 /* Write Disable */
#define LUT_OP_WNVCR 0xB1 /* Write Non-Volatile Configuration Register */
#define LUT_OP_CLSFR 0x50 /* Clear Status Flag Register */
#define LUT_OP_WSR 0x01 /* Write Status Register */
#define LUT_OP_RSR 0x05 /* Read Status Register */
#define LUT_OP_RID 0x9F /* Read ID */
#define LUT_OP_PP 0x02 /* Page Program */
#define LUT_OP_PP4B 0x12 /* Page Program */
#define LUT_OP_FPP 0x82 /* Fast Page Program */
#define LUT_OP_SE 0xD8 /* Sector Erase */
#define LUT_OP_SE_4K 0x20 /* 4K Sector Erase */
#define LUT_OP_SE_4K4B 0x21 /* 4K Sector Erase */
#define LUT_OP_SE_32K 0x52 /* 32K Sector Erase */
#define LUT_OP_SE_32K4B 0x5C /* 32K Sector Erase */
#define LUT_OP_4SE 0xDC /* 4 byte Sector Erase */
#define LUT_OP_CE 0xC4 /* Chip Erase */
#define LUT_OP_READ3B 0x03 /* Read */
#define LUT_OP_READ4B 0x13 /* Read */
#define LUT_OP_FAST_READ 0x0B /* Fast Read */
#define LUT_OP_FAST_READ4B 0x0C /* Fast Read */
#define LUT_OP_OCTAL_READ 0x8B /* Octal Read */
#define LUT_OP_ADDR3B 0x18 /* 3 byte address */
#define LUT_OP_ADDR4B 0x20 /* 4 byte address */
#define LUT_OP_RDSR 0x05 /* Read Status Register */
#define LUT_OP_1BYTE 0x01 /* 1 byte */
#define LUT_INDEX_READ 0
#define LUT_INDEX_WRITE_EN 4
#define LUT_INDEX_SE 8
#define LUT_INDEX_SSE4K 12
#define LUT_INDEX_PP 16
#define LUT_INDEX_RDSR 20
/* MT40A1G8SA-075:E --> DDR4: static, 1GB, 1600 MHz (1.6 GT/s) */
#define DDR_ADDRESS 0x80000000
#define DDR_FREQ 1600
#define DDR_SIZE (2 * 1024 * 1024 * 1024)
#define DDR_N_RANKS 1
#define DDR_RANK_DENS 0x100000000
#define DDR_SDRAM_WIDTH 32
#define DDR_EC_SDRAM_W 0
#define DDR_N_ROW_ADDR 15
#define DDR_N_COL_ADDR 10
#define DDR_N_BANKS 2
#define DDR_EDC_CONFIG 2
#define DDR_BURSTL_MASK 0x0c
#define DDR_TCKMIN_X_PS 750
#define DDR_TCMMAX_PS 1900
#define DDR_CASLAT_X 0x0001FFE00
#define DDR_TAA_PS 13500
#define DDR_TRCD_PS 13500
#define DDR_TRP_PS 13500
#define DDR_TRAS_PS 32000
#define DDR_TRC_PS 45500
#define DDR_TWR_PS 15000
#define DDR_TRFC1_PS 350000
#define DDR_TRFC2_PS 260000
#define DDR_TRFC4_PS 160000
#define DDR_TFAW_PS 21000
#define DDR_TRFC_PS 260000
#define DDR_TRRDS_PS 3000
#define DDR_TRRDL_PS 4900
#define DDR_TCCDL_PS 5000
#define DDR_REF_RATE_PS 7800000
#define DDR_CS0_BNDS_VAL 0x000000FF
#define DDR_CS1_BNDS_VAL 0x00000000
#define DDR_CS2_BNDS_VAL 0x00000000
#define DDR_CS3_BNDS_VAL 0x00000000
#define DDR_CS0_CONFIG_VAL 0x80040422
#define DDR_CS1_CONFIG_VAL 0x00000000
#define DDR_CS2_CONFIG_VAL 0x00000000
#define DDR_CS3_CONFIG_VAL 0x00000000
#define DDR_TIMING_CFG_3_VAL 0x01111000
#define DDR_TIMING_CFG_0_VAL 0x91550018
#define DDR_TIMING_CFG_1_VAL 0xBAB40C42
#define DDR_TIMING_CFG_2_VAL 0x0048C111
#define DDR_SDRAM_CFG_VAL 0xE50C0004
#define DDR_SDRAM_CFG_2_VAL 0x00401110
#define DDR_SDRAM_MODE_VAL 0x03010210
#define DDR_SDRAM_MODE_2_VAL 0x00000000
#define DDR_SDRAM_MD_CNTL_VAL 0x0600041F
#define DDR_SDRAM_INTERVAL_VAL 0x18600618
#define DDR_DATA_INIT_VAL 0xDEADBEEF
#define DDR_SDRAM_CLK_CNTL_VAL 0x02000000
#define DDR_INIT_ADDR_VAL 0x00000000
#define DDR_INIT_EXT_ADDR_VAL 0x00000000
#define DDR_TIMING_CFG_4_VAL 0x00000002
#define DDR_TIMING_CFG_5_VAL 0x03401400
#define DDR_TIMING_CFG_6_VAL 0x00000000
#define DDR_TIMING_CFG_7_VAL 0x23300000
#define DDR_ZQ_CNTL_VAL 0x8A090705
#define DDR_WRLVL_CNTL_VAL 0x8675F605
#define DDR_SR_CNTL_VAL 0x00000000
#define DDR_SDRAM_RCW_1_VAL 0x00000000
#define DDR_SDRAM_RCW_2_VAL 0x00000000
#define DDR_WRLVL_CNTL_2_VAL 0x06070700
#define DDR_WRLVL_CNTL_3_VAL 0x00000008
#define DDR_SDRAM_RCW_3_VAL 0x00000000
#define DDR_SDRAM_RCW_4_VAL 0x00000000
#define DDR_SDRAM_RCW_5_VAL 0x00000000
#define DDR_SDRAM_RCW_6_VAL 0x00000000
#define DDR_SDRAM_MODE_3_VAL 0x00010210
#define DDR_SDRAM_MODE_4_VAL 0x00000000
#define DDR_SDRAM_MODE_5_VAL 0x00010210
#define DDR_SDRAM_MODE_6_VAL 0x00000000
#define DDR_SDRAM_MODE_7_VAL 0x00010210
#define DDR_SDRAM_MODE_8_VAL 0x00000000
#define DDR_SDRAM_MODE_9_VAL 0x00000500
#define DDR_SDRAM_MODE_10_VAL 0x04000000
#define DDR_SDRAM_MODE_11_VAL 0x00000400
#define DDR_SDRAM_MODE_12_VAL 0x04000000
#define DDR_SDRAM_MODE_13_VAL 0x00000400
#define DDR_SDRAM_MODE_14_VAL 0x04000000
#define DDR_SDRAM_MODE_15_VAL 0x00000400
#define DDR_SDRAM_MODE_16_VAL 0x04000000
#define DDR_TIMING_CFG_8_VAL 0x02114600
#define DDR_SDRAM_CFG_3_VAL 0x00000000
#define DDR_DQ_MAP_0_VAL 0x5b65b658
#define DDR_DQ_MAP_1_VAL 0xd96d8000
#define DDR_DQ_MAP_2_VAL 0x00000000
#define DDR_DQ_MAP_3_VAL 0x01600000
#define DDR_DDRDSR_1_VAL 0x00000000
#define DDR_DDRDSR_2_VAL 0x00000000
#define DDR_DDRCDR_1_VAL 0x80040000
#define DDR_DDRCDR_2_VAL 0x0000A181
#define DDR_ERR_INT_EN_VAL 0x00000000
#define DDR_ERR_SBE_VAL 0x00000000
/* 12.4 DDR Memory Map */
#define DDR_BASE (0x1080000)
#define DDR_PHY_BASE (0x1400000)
#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_TIMING_CFG_3 *((volatile uint32_t*)(DDR_BASE + 0x100)) /* DDR SDRAM timing configuration 3 */
#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_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_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_DATA_INIT *((volatile uint32_t*)(DDR_BASE + 0x128)) /* DDR training initialization value */
#define DDR_SDRAM_CLK_CNTL *((volatile uint32_t*)(DDR_BASE + 0x130)) /* DDR SDRAM clock control */
#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_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_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_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_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_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_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_MODE_11 *((volatile uint32_t*)(DDR_BASE + 0x228)) /* DDR SDRAM mode configuration 11 */
#define DDR_SDRAM_MODE_12 *((volatile uint32_t*)(DDR_BASE + 0x22C)) /* DDR SDRAM mode configuration 12 */
#define DDR_SDRAM_MODE_13 *((volatile uint32_t*)(DDR_BASE + 0x230)) /* DDR SDRAM mode configuration 13 */
#define DDR_SDRAM_MODE_14 *((volatile uint32_t*)(DDR_BASE + 0x234)) /* DDR SDRAM mode configuration 14 */
#define DDR_SDRAM_MODE_15 *((volatile uint32_t*)(DDR_BASE + 0x238)) /* DDR SDRAM mode configuration 15 */
#define DDR_SDRAM_MODE_16 *((volatile uint32_t*)(DDR_BASE + 0x23C)) /* DDR SDRAM mode configuration 16 */
#define DDR_TIMING_CFG_8 *((volatile uint32_t*)(DDR_BASE + 0x250)) /* DDR SDRAM timing configuration 8 */
#define DDR_SDRAM_CFG_3 *((volatile uint32_t*)(DDR_BASE + 0x260)) /* DDR SDRAM configuration 3 */
#define DDR_DQ_MAP_0 *((volatile uint32_t*)(DDR_BASE + 0x400)) /* DDR DQ Map 0 */
#define DDR_DQ_MAP_1 *((volatile uint32_t*)(DDR_BASE + 0x404)) /* DDR DQ Map 1 */
#define DDR_DQ_MAP_2 *((volatile uint32_t*)(DDR_BASE + 0x408)) /* DDR DQ Map 2 */
#define DDR_DQ_MAP_3 *((volatile uint32_t*)(DDR_BASE + 0x40C)) /* DDR DQ Map 3 */
#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_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_MTCR *((volatile uint32_t*)(DDR_BASE + 0xD00)) /* Memory Test Control Register */
#define DDR_MTPn(n) *((volatile uint32_t*)(DDR_BASE + 0xD20 + (n) * 4)) /* Memory Test Pattern Register */
#define DDR_MTP0 *((volatile uint32_t*)(DDR_BASE + 0xD20)) /* Memory Test Pattern Register 0 */
#define DDR_MT_ST_ADDR *((volatile uint32_t*)(DDR_BASE + 0xD64)) /* Memory Test Start Address */
#define DDR_MT_END_ADDR *((volatile uint32_t*)(DDR_BASE + 0xD6C)) /* Memory Test End Address */
#define DDR_ERR_DETECT *((volatile uint32_t*)(DDR_BASE + 0xE40)) /* Memory error detect */
#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_CFG_MEM_EN 0x80000000 /* SDRAM interface logic is enabled */
#define DDR_SDRAM_CFG_BI 0x00000001
#define DDR_SDRAM_CFG2_D_INIT 0x00000010 /* data initialization in progress */
#define DDR_MEM_TEST_EN 0x80000000 /* Memory test enable */
#define DDR_MEM_TEST_FAIL 0x00000001 /* Memory test fail */
#define TEST_DDR_SIZE 1024 * 5
#define TEST_DDR_OFFSET 0x10000000
/* MMU Access permission and shareability
Device mem encoding 0b0000dd00
dd = 00, 01, 10, 11
Nomral Mem encoding 0bxxxxiiii
xxxx = 00RW, 0100, 01RW, 10RW, 11RW, where RW = Outer Read/Write policy
iiii = 00RW, 0100, 01RW, 10RW, 11RW, where RW = Inner Read/Write policy
R or W is 0 for No alloc, 1 for alloc
*/
#define ATTR_SH_IS (0x3 << 8) /* Inner Shareable */
#define ATTR_SH_OS (0x2 << 8) /* Outer Shareable */
#define ATTR_UXN (0x1 << 54) /* EL0 cannot execute */
#define ATTR_PXN (0x1 << 53) /* EL1 cannot execute */
#define ATTR_AF (0x1 << 10) /* Access Flag */
#define ATTR_AP_RW_PL1 (0x1 << 6) /* EL1 Read-Write */
#define ATTR_AP_RW_PL0 (0x0 << 6) /* EL0 Read-Write */
#define ATTR_AP_RO_PL1 (0x5 << 6) /* EL1 Read-Only */
#define ATTR_AP_RO_PL0 (0x4 << 6) /* EL0 Read-Only */
#define ATTR_NS (0x1 << 5) /* Non-secure */
#define ATTR_AP_RW (ATTR_AP_RW_PL1 | ATTR_AP_RW_PL0)
/* Memory attribute MAIR reg cfg */
#define ATTR_IDX_NORMAL_MEM 0
#define MAIR_ATTR_NORMAL_MEM 0xFF /* Normal, Write-Back, Read-Write-Allocate */
#define ATTR_IDX_DEVICE_MEM 1
#define MAIR_ATTR_DEVICE_MEM 0x04 /* Device-nGnRnE */
#define ATTRIBUTE_DEVICE (ATTR_IDX_DEVICE_MEM << 2) | ATTR_AP_RW | ATTR_SH_IS
#define ATTRIBUTE_NORMAL_MEM (ATTR_IDX_NORMAL_MEM << 2) | ATTR_AP_RW | ATTR_SH_IS
/* SPI interface */
#define SPI_MCR(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x000))
#define SPI_TCR(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x008))
#define SPI_CTAR0(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x00C))
#define SPI_CTAR1(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x010))
#define SPI_SR(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x02C))
#define SPI_RSER(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x030))
#define SPI_PUSHR(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x034))
#define SPI_POPR(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x038))
#define SPI_TXFR0(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x03C))
#define SPI_TXFR1(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x040))
#define SPI_TXFR2(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x044))
#define SPI_TXFR3(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x048))
#define SPI_RXFR0(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x07C))
#define SPI_RXFR1(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x080))
#define SPI_RXFR2(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x084))
#define SPI_RXFR3(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x088))
#define SPI_CTARE0(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x11C))
#define SPI_CTARE1(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x120))
#define SPI_SREX(_n) *((volatile unsigned int*)(SPI_BASE(_n)+0x13C))
/* Configuration is a simple, 8-bit frame that is expected to be
* accessed with single byte transactions.
*/
/* MCR config */
/* Master, no frz, inactive CS high, flush FIFO, halt */
#define SPI_MCR_MASTER_HALT 0x80010301ul
/* Master, no frz, inactive CS high, running */
#define SPI_MCR_MASTER_RUNNING 0x80010000ul
/* CTAR config*/
/* no double baud, 8-bit frame, mode 00, MSB, default delays
* PBR=2, BR=32 for total divisor 64
* 200MHz platform clock yields 3.125MHz SPI clk */
#define SPI_CTAR_8_00MODE_64DIV 0x38000005
/* no double baud, 8-bit frame, mode 00, MSB, default delays
* PBR=2, BR=4 for total divisor 8
* 200MHz platform clock yields 25MHz SPI clk */
#define SPI_CTAR_8_00MODE_8DIV 0x38000001
/* SPI has TX/RX FIFO with limited depth, overwrite on overflow */
#define SPI_FIFO_DEPTH 4
/* CMD/DATA FIFO entry*/
/* no keep pcs asserted, use CTAR0, not EOQ, no clear TC, no parity*/
#define SPI_PUSHR_LAST 0x00000000
/* keep pcs asserted, use CTAR0, not EOQ, no clear TC, no parity*/
#define SPI_PUSHR_CONT 0x80000000
/* CS selection (0-3). Not all SPI interfaces have 4 CS's */
#define SPI_PUSHR_PCS_SHIFT (16)
#define SPI_PUSHR_PCS(_n) ((1ul<<(_n)) << SPI_PUSHR_PCS_SHIFT)
/* Status register bits*/
#define SPI_SR_TCF (1ul << 31)
#define SPI_SR_TFFF (1ul << 25)
#define SPI_SR_RXCTR (0xFul << 4)
#endif /* !NXP_LS1028A_H */

111
hal/nxp_ls1028a.ld 100644
View File

@ -0,0 +1,111 @@
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_vector_table)
MEMORY
{
/*The flash address range on LS1028A RDB is 0x20000000 - 0x23FFFFFF.*/
FLASH (rx) : ORIGIN = @WOLFBOOT_ORIGIN@, LENGTH = @BOOTLOADER_PARTITION_SIZE@
/* DDR4 - 2GB */
DRAM (rwx) : ORIGIN = 0x80001000 , LENGTH = 0xBFFFFFFF
/* OCRAM 256K for startup RAM */
OCRAM (rwx) : ORIGIN = 0x18000000, LENGTH = 256K
}
SECTIONS
{
PROVIDE (_DDR_ADDRESS = 0x80001000);
PROVIDE (_OCRAM_ADDRESS = 0x18000000);
PROVIDE (_FLASH_ADDRESS = @WOLFBOOT_ORIGIN@);
PROVIDE (_CORE_NUMBER = 0);
PROVIDE (_MEMORY_SIZE = LENGTH(OCRAM));
PROVIDE (_FLASH_SIZE = LENGTH(FLASH));
PROVIDE (STACK_SIZE = 64K);
.boot :
{
PROVIDE(_vector_table = .);
._vector_table = .;
. = ALIGN(0x800);
KEEP(*(.vector_table))
KEEP(*(.boot*))
} > FLASH
/* Read-only sections, merged into text segment: */
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.init : { *(.rela.init) }
.rela.fini : { *(.rela.fini) }
.rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
.rela.data.rel.ro : { *(.rela.data.rel.ro .rela.data.rel.ro.* .rela.gnu.linkonce.d.rel.ro.*) }
.rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
.rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
.rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
.rela.ctors : { *(.rela.ctors) }
.rela.dtors : { *(.rela.dtors) }
.rela.got : { *(.rela.got) }
.rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
.text :
{
_start_text = .;
*(.text*)
*(.note.*)
. = ALIGN(8);
_end_text = .;
} > FLASH
.rodata :
{
_rodata_start = .;
*(.rodata)
*(.rodata.*)
. = ALIGN(8);
_rodata_end = .;
} > FLASH
PROVIDE(_stored_data = .);
.data :
{
_start_data = .;
KEEP(*(.data .data.* .gnu.linkonce.d.*))
. = ALIGN(8);
KEEP(*(.ramcode))
. = ALIGN(8);
_end_data = .;
} > OCRAM AT > FLASH
.bss :
{
_start_bss = .;
__bss_start__ = .;
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > OCRAM
. = ALIGN(16);
.stack :
{
_start_stack = .;
. = . + STACK_SIZE;
_end_stack = .;
} > OCRAM
PROVIDE(_stack_base = .);
}

View File

@ -34,15 +34,29 @@ extern void hal_espi_init(uint32_t cs, uint32_t clock_hz, uint32_t mode);
extern int hal_espi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int flags);
extern void hal_espi_deinit(void);
#if defined(TARGET_nxp_ls1028a)
/* Functions from hal/nxp_ls1028a.c */
extern void nxp_ls1028a_spi_init(unsigned int sel);
extern int nxp_ls1028a_spi_xfer(unsigned int sel, unsigned int cs,
const unsigned char *out, unsigned char *in,
unsigned int size, int cont);
extern void nxp_ls1028a_spi_deinit(unsigned int sel);
#endif
#include <wolftpm/tpm2_types.h>
static int initialized = 0;
void spi_init(int polarity, int phase)
{
static int initialized = 0;
if (!initialized) {
initialized++;
#if defined(TARGET_nxp_p1021) || defined(TARGET_nxp_t1024)
hal_espi_init(SPI_CS_TPM, TPM2_SPI_MAX_HZ, (polarity | (phase << 1)));
#elif defined(TARGET_nxp_ls1028a)
nxp_ls1028a_spi_init(SPI_SEL_TPM);
#endif
}
(void)polarity;
(void)phase;
@ -50,12 +64,26 @@ void spi_init(int polarity, int phase)
void spi_release(void)
{
hal_espi_deinit();
if (initialized) {
initialized--;
#if defined(TARGET_nxp_p1021) || defined(TARGET_nxp_t1024)
hal_espi_deinit();
#elif defined(TARGET_nxp_ls1028a)
nxp_ls1028a_spi_deinit(SPI_SEL_TPM);
#endif
}
}
int spi_xfer(int cs, const uint8_t* tx, uint8_t* rx, uint32_t sz, int flags)
{
#if defined(TARGET_nxp_p1021) || defined(TARGET_nxp_t1024)
return hal_espi_xfer(cs, tx, rx, sz, flags);
#elif defined(TARGET_nxp_ls1028a)
return nxp_ls1028a_spi_xfer(SPI_SEL_TPM, cs, tx, rx, sz, flags);
#endif
}
#endif /* WOLFBOOT_TPM */
#endif /* TARGET_ */

View File

@ -29,4 +29,17 @@
#endif
#endif
#if defined(TARGET_nxp_ls1028a)
/* LS1028A SPI to the MikroBus uses SPI3 (sel is 2) and CS 0 */
#ifndef SPI_SEL_TPM
#define SPI_SEL_TPM 2
#endif
#ifndef SPI_CS_TPM
#define SPI_CS_TPM 0
#endif
#endif
#endif /* !SPI_DRV_NXP_H_INCLUDED */

View File

@ -59,7 +59,8 @@
#include "hal/spi/spi_drv_nrf5340.h"
#endif
#if defined(TARGET_nxp_p1021) || defined(TARGET_nxp_t1024)
#if defined(TARGET_nxp_p1021) || defined(TARGET_nxp_t1024) || \
defined(TARGET_nxp_ls1028a)
#include "hal/spi/spi_drv_nxp.h"
#endif

View File

@ -25,17 +25,20 @@
#include "loader.h"
#include "wolfboot/wolfboot.h"
/* Linker exported variables */
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;
static volatile unsigned int cpu_id;
extern unsigned int *END_STACK;
extern unsigned int _stored_data;
extern unsigned int _start_data;
extern unsigned int _end_data;
extern void main(void);
extern void gicv2_init_secure(void);
void boot_entry_C(void)
{
register unsigned int *dst;
register unsigned int *dst, *src;
/* Initialize the BSS section to 0 */
dst = &__bss_start__;
while (dst < (unsigned int *)&__bss_end__) {
@ -43,6 +46,17 @@ void boot_entry_C(void)
dst++;
}
/* Copy data section from flash to RAM if necessary */
src = (unsigned int*)&_stored_data;
dst = (unsigned int*)&_start_data;
if(src!=dst) {
while (dst < (unsigned int *)&_end_data) {
*dst = *src;
dst++;
src++;
}
}
/* Run wolfboot! */
main();
}

View File

@ -20,65 +20,230 @@
*/
#define GICD_BASE 0xF9010000
/* Include target-specific defines here to override any AA64 defaults */
#if defined(TARGET_LS1028A)
#include "../hal/nxp_ls1028a.h"
#endif
/* AARCH64 default configurations */
#if !defined(AA64_TARGET_EL)
#define AA64_TARGET_EL 2
#endif
#if !defined(AA64GIC_VERSION)
#define AA64GIC_VERSION 2
#endif
#if (AA64GIC_VERSION==2)
#if !defined(AA64GICV2_GICD_BASE)
#define AA64GICV2_GICD_BASE 0xF9010000
#endif
#if !defined(AA64_GICC_BASE)
#define AA64GICV2_GICC_BASE 0xF9020000
#endif
#endif
/* CURRENT_EL ARMv8 Current Exception Level Register */
#define CURRENT_EL_MASK (0x3 << 2) /* Current EL */
#define CURRENT_EL_EL0 0x0
#define CURRENT_EL_EL1 0x4
#define CURRENT_EL_EL2 0x8
#define CURRENT_EL_EL3 0xC
/* ID_AA64PFR0_EL1 ARMv8 Processor Feature Register 0*/
#define ID_AA64PFRO_EL3_MASK (0xF<<12) /* EL3 is implemented: 0x0000 no */
/* 0x1000 AA64, 0x2000 AA64+AA32 */
#define ID_AA64PFRO_EL2_MASK (0xF<<8) /* EL2 is implemented: 0x000 no */
/* 0x100 AA64, 0x200 AA64+AA32 */
#define ID_AA64PFRO_EL1_MASK (0xF<<4) /* EL1 is implemented: */
/* 0x10 AA64, 0x20 AA64+AA32 */
#define ID_AA64PFRO_EL0_MASK (0xF<<0) /* EL0 is implemented: */
/* 0x1 AA64, 0x2 AA64+AA32 */
#define ID_AA64PFRO_FGT_MASK (0xFull<<56) /* Fine Grained Traps: */
/* 0x0 no, !0x0: yes */
/* GICv2 Register Offsets */
#define GICD_CTLR 0x0000
#define GICD_TYPER 0x0004
#define GICD_SGIR 0x0F00
#define GICD_IGROUPRn 0x0080
#define GICC_BASE 0xF9020000
#define GICC_PMR 0x0004
#ifndef USE_BUILTIN_STARTUP
.section ".boot"
/* This is the entry function. If this is the start of a cold boot, the CPU
* will be at the highest exception level (EL) and the CPU must be configured
* for each of the levels down to the target EL: either EL2 for a hypervisor
* or EL1 for a standard OS.
*
* Configuration only enables secure EL3 and forces all lower levels NS.
*
* AA64_TARGET_EL: 1 or 2
* AA64_GICVERSION: 0- no external GIC, 2: GICv2, 3: GICv3
* AA64_ENABLE_EL3_SMC: Enable SMC call handling in EL3
* AA64_ENABLE_EL3_PM: Enable handling of power management (TWE, TWI)
*/
.section ".boot", "ax"
.global _vector_table
_vector_table:
mov x21, x0 // read ATAG/FDT address
/* If we are booted as a Linux direct boot, then X0 will have FDT */
mov x21, x0 /* save ATAG/FDT address */
4: ldr x1, =_vector_table // get start of .text in x1
// Read current EL
mrs x0, CurrentEL
and x0, x0, #0x0C
// EL == 3?
cmp x0, #12
/* Get highest EL implemented in this CPU */
bl aa64_get_highest_el
mov x19, x0 /* save highest EL in x19 */
/* Get current EL */
bl aa64_get_current_el
mov x20, x0 /* save current EL in x20 */
cmp x19, x20 /* EL is at highest? */
bne 3f
bl aa64_setup_el_highest
3: cmp x20, #0x3 /* at EL3? */
bne 2f
3: mrs x2, scr_el3
orr x2, x2, 0x0F // scr_el3 |= NS|IRQ|FIQ|EA
msr scr_el3, x2
bl aa64_setup_el3
msr cptr_el3, xzr // enable FP/SIMD
// EL == 1?
2: cmp x0, #4
2: cmp x20, #0x1 /* EL == 1? */
beq 1f
// EL == 2?
mov x2, #3 << 20
msr cptr_el2, x2 /* Enable FP/SIMD */
/* EL2 Setup */
mov x2, #3 << 20
msr cptr_el2, x2 /* Disable FP/SIMD traps for EL2 */
b 0f
1: mov x0, #3 << 20
msr cpacr_el1, x0 // Enable FP/SIMD for EL1
/* EL1 Setup */
1: mov x0, #3 << 20
msr cpacr_el1, x0 /* Disable FP/SIMD traps for EL1 */
msr sp_el1, x1
/* Suspend slave CPUs */
0: mrs x3, mpidr_el1 // read MPIDR_EL1
and x3, x3, #3 // CPUID = MPIDR_EL1 & 0x03
cbz x3, 8f // if 0, branch forward
7: wfi // infinite sleep
b 7b
/* Suspend slave CPUs */
0: mrs x3, mpidr_el1 /* read MPIDR_EL1 */
and x3, x3, #3 /* CPUID = MPIDR_EL1 & 0x03 */
cbz x3, 8f /* if 0, branch forward */
7: wfi /* infinite sleep */
b 7b
8: mov sp, x1 // set stack pointer
bl boot_entry_C // boot_entry_C never returns
b 7b // go to sleep anyhow in case.
8: ldr x1, =_vector_table /* ??? get start of .text in x1 */
mov sp, x1 /* XXX set stack pointer */
#ifdef CORTEX_A72
bl init_A72
#endif
bl boot_entry_C /* boot_entry_C never returns */
b 7b /* go to sleep anyhow in case. */
#endif /* USE_BUILTIN_STARTUP */
/* Return the highest EL implemented on this CPU in x0
* No stack usage. No clobbers. */
.global aa64_get_highest_el
.type aa64_get_highest_el, @function
aa64_get_highest_el:
mrs x0, ID_AA64PFR0_EL1
tst x0, ID_AA64PFR0_EL3_MASK
cbz 2f /* Highest is not EL3? */
mov x0, #0x3
ret
2: tst x0, ID_AA64PFR0_EL2_MASK
cbz 1f /* Highest is not EL2? */
mov x0, #0x2
ret
1: mov x0, #0x1 /* Highest is EL1 */
ret
/* Return the current EL on this CPU in x0
* No stack usage. No clobbers. */
.global aa64_get_current_el
.type aa64_get_current_el, @function
aa64_get_current_el:
mrs x0, CURRENT_EL
tst x0, CURRENT_EL3_MASK
cbz 2f /* Current is not EL3? */
mov x0, #0x3
ret
2: tst x0, CURRENT_EL2_MASK
cbz 1f /* Current is not EL2? */
mov x0, #0x2
ret
1: tst x0, CURRENT_EL1_MASK
cbz 0f /* Current is not EL1? */
mov x0, #0x1
ret
0: mov x0, #0x0 /* Current is EL0 */
ret
/* Perform chip setup when at the highest EL
* No stack. Clobbers: x0 */
.global aa64_setup_el_highest
.type aa64_setup_el_highest, @function
aa64_setup_el_highest
#if defined(AA64_CNTFRQ)
/* Set the counter-timer frequency to AA64_CNTFRQ*/
mov x0, AA64_CNTFRQ
msr cntfrq_el0, x0
#endif
ret
/* Perform chip setup when at the EL3
* No stack. Clobbers: x0 */
.global aa64_setup_el3
.type aa64_setup_el3, @function
aa64_setup_el3
mrs x0, scr_el3 /* Get Secure Config Reg scr_el3 */
bic x0, x0, #(1 << 18) /* EEL2 Disable Secure EL2 */
#if !defined (AA64_ENABLE_EL3_PM)
bic x0, x0, #(1 << 13) /* TWE Disable trap WFE to EL3 */
bic x0, x0, #(1 << 12) /* TWI Disable trap WFI to EL3 */
#else
orr x0, x0, #(1 << 13) /* TWE Enable trap WFE to EL3 */
orr x0, x0, #(1 << 12) /* TWI Enable trap WFI to EL3 */
#endif
orr x0, x0, #(1 << 11) /* ST Disable trap SEL1 acc CNTPS to EL3 */
orr x0, x0, #(1 << 10) /* RW Next lower level is AArch64 */
orr x0, x0, #(1 << 9) /* SIF Disable Sec Ins Fetch from NS mem */
#if defined(AA64_TARGET_EL) && (AA64_TARGET_EL==2)
orr x0, x0, #(1 << 8) /* HCE Enable Hypervisor Call HVC */
#else
bic x0, x0, #(1 << 8) /* HCE Disable Hypervisor Call HVC */
#endif
#if !defined(AA64_ENABLE_EL3_SMC)
orr x0, x0, #(1 << 7) /* SMD Disable Secure Monitor Call SMC */
#else
bic x0, x0, #(1 << 7) /* SMD Enable Secure Monitor Call SMC */
#endif
bic x0, x0, #(1 << 3) /* EA Disable EA and SError to EL3 */
bic x0, x0, #(1 << 2) /* FIQ Disable FIQ to EL3 */
bic x0, x0, #(1 << 1) /* IRQ Disable IRQ to EL3 */
orr x0, x0, #(1 << 0) /* NS EL0, EL1, and EL2 are NS */
msr scr_el3, x0 /* Set scr_el3 */
mrs x0, cptr_el3 /* Get EL3 Feature Trap Reg CPTR_EL3 */
bic x0, x0, #(1 << 31) /* TCPAC Disable config traps to EL3 */
bic x0, x0, #(1 << 30) /* TAM Disable AM traps to EL3 */
bic x0, x0, #(1 << 20) /* TTA Disable trace traps to EL3 */
bic x0, x0, #(1 << 12) /* ESM Disable SVCR traps to EL3 */
bic x0, x0, #(1 << 10) /* TFP Disable FP/SIMD traps to EL3 */
bic x0, x0, #(1 << 20) /* EZ Disable ZCR traps to EL3 */
msr cptr_el3, x0 /* Set cptr_el3 */
#if defined(AA64_TARGET_EL) && (AA64_TARGET_EL==2)
orr x0, x0, #(1 << 8) /* HCE Enable Hypervisor Call HVC */
#else
bic x0, x0, #(1 << 8) /* HCE Disable Hypervisor Call HVC */
#endif
ret
/* Initialize GIC 400 (GICv2) */
.global gicv2_init_secure
gicv2_init_secure:
ldr x0, =GICD_BASE
ldr x0, =AA64_GICD_BASE
mov w9, #0x3 /* EnableGrp0 | EnableGrp1 */
str w9, [x0, GICD_CTLR] /* Secure GICD_CTLR */
ldr w9, [x0, GICD_TYPER]
@ -91,7 +256,7 @@ gicv2_init_secure:
sub w10, w10, #0x1
cbnz w10, 0b
ldr x1, =GICC_BASE /* GICC_CTLR */
ldr x1, =AA64_GICC_BASE /* GICC_CTLR */
mov w0, #3 /* EnableGrp0 | EnableGrp1 */
str w0, [x1]
@ -99,3 +264,272 @@ gicv2_init_secure:
str w0, [x1, #4] /* GICC_PMR */
1:
ret
.global invalidate_ivac
invalidate_ivac:
ldr x0, =_OCRAM_ADDRESS
ldr x1, =_MEMORY_SIZE
add x1, x1, x0
mrs x2, ctr_el0
ubfx x4, x2, #16, #4
mov x3, #4
lsl x3, x3, x4
sub x4, x3, #1
bic x4, x0, x4
inval_loop:
dc ivac, x4
add x4, x4, x3
cmp x4, x1
blt inval_loop
dsb sy
ret
.global disable_mmu
disable_mmu:
mrs x0, sctlr_el3
bic x0, x0, x1
msr sctlr_el3, x0
isb
dsb sy
ret
.global switch_el3_to_el2
switch_el3_to_el2:
mov x0, #0x531
msr scr_el3, x0
msr cptr_el3, xzr /* Disable el3 traps */
mov x0, #0x33ff
msr cptr_el2, x0 /* Disable el2 traps */
mrs x0, sctlr_el2
mov x1, #(1 << 0) | (1 << 2) | (1 << 12)
bic x0, x0, x1
msr sctlr_el2, x0
mrs x0, sctlr_el3
bic x0, x0, x1
msr sctlr_el3, x0
bl invalidate_ivac
ldp x29, x30, [sp]
mrs x0, vbar_el3
msr vbar_el2, x0
mov x0, #0x3c9
msr spsr_el3, x0
msr elr_el3, x30
ret
.global cortex_a72_erratta
cortex_a72_erratta:
/* Initalization code for NXP LS1028a (A72) */
.global init_A72
init_A72:
ldr x1, =_vector_table_el3 /* Initalize vec table */
msr vbar_el3, x1
el3_state:
mrs x0, scr_el3 /* Get scr_el3 */
bic x0, x0, #(1 << 18) /* EEL2 Disable Secure EL2 */
#if !defined (AA64_ENABLE_EL3_PM)
bic x0, x0, #(1 << 13) /* TWE Disable trap WFE to EL3 */
bic x0, x0, #(1 << 12) /* TWI Disable trap WFI to EL3 */
#else
orr x0, x0, #(1 << 13) /* TWE Enable trap WFE to EL3 */
orr x0, x0, #(1 << 12) /* TWI Enable trap WFI to EL3 */
#endif
orr x0, x0, #(1 << 11) /* ST Disable trap SEL1 access CNTPS to EL3 */
orr x0, x0, #(1 << 10) /* RW Next lower level is AArch64 */
orr x0, x0, #(1 << 9) /* SIF Disable secure ins. fetches from NS */
#if defined(AA64_TARGET_EL) && (AA64_TARGET_EL==2)
orr x0, x0, #(1 << 8) /* HCE Enable Hypervisor Call HVC */
#else
bic x0, x0, #(1 << 8) /* HCE Disable Hypervisor Call HVC */
#endif
#if !defined(AA64_ENABLE_EL3_SMC)
orr x0, x0, #(1 << 7) /* SMD Disable Secure Monitor Call SMC */
#else
bic x0, x0, #(1 << 7) /* SMD Enable Secure Monitor Call SMC */
#endif
orr x0, x0, #(1 << 3) /* EA Enable EA and SError to EL3 for now */
orr x0, x0, #(1 << 2) /* FIQ Enable FIQ to EL3 for now */
orr x0, x0, #(1 << 1) /* IRQ Enable IRQ to EL3 for now */
orr x0, x0, #(1 << 0) /* NS EL0, EL1, and EL2 are NS */
msr scr_el3, x0 /* Set scr_el3 */
mrs x0, sctlr_el3 /* sctlr_el3 config */
bic x0, x0, #(1 << 19) /* Disable EL3 translation XN */
bic x0, x0, #(1 << 12) /* Disable I cache */
bic x0, x0, #(1 << 3) /* Disable SP Alignment check */
bic x0, x0, #(1 << 2) /* Disable D cache */
bic x0, x0, #(1 << 1) /* Disable Alignment check */
bic x0, x0, #(1 << 0) /* Disable MMU */
msr sctlr_el3, x0
isb
invalidate_cache:
msr csselr_el1, x0
mrs x4, ccsidr_el1 /* read cache size */
and x1, x4, #0x7
and x1, x1, #0x4 /* cache line size */
ldr x3, =0x7ff
and x2, x3, x4, lsr #13 /* number of cache sets */
ldr x3, =0x3ff
and x3, x3, x4, lsr #3 /* cache associativity number */
clz w4, w3
mov x5, #0
way_loop:
mov x6, #0
set_loop:
lsl x7, x5, x4
orr x7, x0, x7
lsl x8, x6, x1
orr x7, x7, x8
dc cisw, x7 /* invalidate cache */
add x6, x6, #1
cmp x6, x2
ble set_loop /* loop until all sets are invalidated */
add x5, x5, #1
cmp x5, x3
ble way_loop /* loop until all ways are invalidated */
msr cptr_el3, xzr
init_stack:
ldr x0, =_stack_base /* Set and align stack */
sub x0, x0, #16
and x0, x0, #-16
mov sp, x0
ldr x1, =STACK_SIZE
msr sp_el2, x0
msr sp_el1, x0
msr sp_el0, x0
mov x29, 0 /* Setup an initial dummy frame with saved fp=0 and saved lr=0 */
stp x29, x29, [sp, #-16]!
mov x29, sp
bl invalidate_ivac
b boot_entry_C
.global mmu_enable
mmu_enable:
tlbi alle3 /* Invalidate table entries */
dsb sy
isb
/* Set tcr reg */
ldr x0, =0x0
orr x0, x0, #24 /* Size of the memory region */
orr x0, x0, #(1 << 17) /* PS 40 bit */
orr x0, x0, #(1 << 16) /* TG0 4KB */
orr x0, x0, #(2 << 12) /* SH0 Outer Shareable */
orr x0, x0, #(1 << 10) /* normal outer WBWA cacheable */
orr x0, x0, #(1 << 8) /* normal inner WBWA cacheable */
msr tcr_el3, x0
ldr x1, =0x44E048E000098AA4 //0xFF440C0400
msr mair_el3, x1
ldr x0, =ttb0_base
msr ttbr0_el3, x0
mrs x0, S3_1_c15_c2_1
orr x0, x0, #(1 << 6) /* Must set SPMEN */
msr S3_1_c15_c2_1, x0
isb
/* Set sctlr reg */
mrs x0, sctlr_el3
orr x1, x0, #(1 << 12) /* I - instruction cache enable */
orr x1, x0, #(1 << 2) /* C - data & unified cache enable */
orr x1, x0, #(1 << 0) /* M - MMU enable */
msr sctlr_el3, x1
dsb sy
isb
ret
/* Exception Vector Table EL3 */
.balign 0x800
.global _vector_table_el3
_vector_table_el3:
el3_sp0_sync:
eret
.balign 0x80
el3_sp0_irq:
eret
.balign 0x80
el3_spi_fiq:
eret
.balign 0x80
el3_sp0_serror:
eret
.balign 0x80
el3_spx_sync:
eret
.balign 0x80
el3_spx_irq:
eret
.balign 0x80
el3_spx_fiq:
eret
.balign 0x80
el3_spx_serror:
eret
.balign 0x80
lower_el3_aarch64_sync:
eret
.balign 0x80
lower_el3_aarch64_irq:
eret
.balign 0x80
lower_el3_aarch64_fiq:
eret
.balign 0x80
lower_el3_aarch64_serror:
eret
/* Memory Table Macros */
.macro PUT_64BIT_WORD high, low
.word \low
.word \high
.endm
.macro TABLE_ENTRY PA, attributes
PUT_64BIT_WORD \attributes, \PA + 0x3
.endm
.macro BLOCK_1GB PA, attr_hi, attr_lo
PUT_64BIT_WORD \attr_hi, ((\PA) & 0xc0000000) | \attr_lo | 0x1
.endm
.macro BLOCK_2MB PA, attr_hi, attr_lo
PUT_64BIT_WORD \attr_hi, ((\PA) & 0xffe00000) | \attr_lo | 0x1
.endm
/* Note: In EL3/2 has direct physical to virutal mapping */
.align 12
.global ttb0_base
ttb0_base:
TABLE_ENTRY level1_pagetable, 0
BLOCK_1GB 0x80000000, 0, 0x740
BLOCK_1GB 0xC0000000, 0, 0x740
.align 12
.global level1_pagetable
level1_pagetable:
.set ADDR, 0x0
.rept 0x200
BLOCK_2MB (ADDR << 20), 0, 0x74c
.set ADDR, ADDR + 2
.endr

View File

@ -0,0 +1,55 @@
MEMORY
{
FLASH (rx) : ORIGIN = @WOLFBOOT_TEST_APP_ADDRESS@, LENGTH = 256K
DRAM (rwx) : ORIGIN = 0x80001000 , LENGTH = 0xBFFFFFFF
OCRAM (rwx) : ORIGIN = 0x18020100, LENGTH = 128K
}
ENTRY(main);
SECTIONS
{
.text :
{
_start_text = .;
KEEP(*(.boot*))
*(.text*)
*(.rodata*)
*(.note.*)
. = ALIGN(4);
_end_text = .;
} > OCRAM
.edidx :
{
. = ALIGN(4);
*(.ARM.exidx*)
} > OCRAM
PROVIDE(_stored_data = .);
.data :
{
_start_data = .;
KEEP(*(.data*))
. = ALIGN(4);
KEEP(*(.ramcode))
. = ALIGN(4);
_end_data = .;
} > OCRAM
.bss (NOLOAD) :
{
_start_bss = .;
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_end_bss = .;
__bss_end__ = .;
_end = .;
} > OCRAM
. = ALIGN(4);
}
END_STACK = _start_text;

View File

@ -427,6 +427,10 @@ ifeq ($(TARGET),x86_fsp_qemu)
LDFLAGS=
endif
ifeq ($(TARGET),nxp_ls1028a)
LSCRIPT_TEMPLATE:=AARCH64-ls1028a.ld
endif
CFLAGS+=-I../lib/wolfssl
ifeq ($(WOLFHSM_CLIENT),1)

View File

@ -0,0 +1,116 @@
/* app_nxp_ls1028a.c
*
* Copyright (C) 2024 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 <stdint.h>
#include "wolfboot/wolfboot.h"
/* P1021 */
#define CCSRBAR (0x1000000)
#define SYS_CLK (400000000)
/* P1021 PC16552D Dual UART */
#define BAUD_RATE 115200
#define UART_SEL 0 /* select UART 0 or 1 */
#define UART_BASE(n) (0x21C0500 + (n * 100))
#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_FCR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* FIFO control register */
#define UART_IIR(n) *((volatile uint8_t*)(UART_BASE(n) + 2)) /* interrupt ID register */
#define UART_LCR(n) *((volatile uint8_t*)(UART_BASE(n) + 3)) /* line control register */
#define UART_LSR(n) *((volatile uint8_t*)(UART_BASE(n) + 5)) /* line status register */
#define UART_SCR(n) *((volatile uint8_t*)(UART_BASE(n) + 7)) /* scratch 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 */
static void uart_init(void)
{
/* calc divisor for UART
* example config values:
* clock_div, baud, base_clk 163 115200 300000000
* +0.5 to round up
*/
uint32_t div = (((SYS_CLK / 2.0) / (16 * BAUD_RATE)) + 0.5);
while (!(UART_LSR(UART_SEL) & UART_LSR_TEMT))
;
/* set ier, fcr, mcr */
UART_IER(UART_SEL) = 0;
UART_FCR(UART_SEL) = (UART_FCR_TFR | UART_FCR_RFR | UART_FCR_FEN);
/* enable baud rate access (DLAB=1) - divisor latch access bit*/
UART_LCR(UART_SEL) = (UART_LCR_DLAB | UART_LCR_WLS);
/* set divisor */
UART_DLB(UART_SEL) = (div & 0xff);
UART_DMB(UART_SEL) = ((div >> 8) & 0xff);
/* disable rate access (DLAB=0) */
UART_LCR(UART_SEL) = (UART_LCR_WLS);
}
static 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++];
}
}
static const char* hex_lut = "0123456789abcdef";
__attribute__((section(".boot")))
void main(void)
{
int i = 0;
int j = 0;
int k = 0;
char snum[8];
uint32_t bootver;
uint32_t updv;
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);
}
}