mirror of https://github.com/wolfSSL/wolfBoot.git
Initial support for NXP LS1028A. Booting into OCRAM app. Updates to ARMv8 startup.
parent
34bb4f651c
commit
d007c9af08
17
arch.mk
17
arch.mk
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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 = .);
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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 */
|
|
@ -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 = .);
|
||||
}
|
|
@ -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_ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue