mirror of https://github.com/wolfSSL/wolfBoot.git
Peer review fixes + ZynqMP robustness improvements
hal/zynq.c:
- Route IOU_TAPDLY_BYPASS writes through pmu_request at EL<=2 in the
<=40 MHz and <=100 MHz branches (previously only done at <=150 MHz);
the register is equally unwritable from EL2/EL1 at lower clocks.
- Add qspi_flash_reset() (RESET_ENABLE 0x66 + RESET_MEMORY 0x99),
called per chip in qspi_init so the flash starts from a known state
regardless of what FSBL/BootROM left behind (XIP, 4-byte addr,
auto-boot).
- Drop unused 'reg' in csu_aes and 'ms' in csu_init so
-Werror=unused-variable builds (OPTIMIZATION_LEVEL=0 / DEBUG=1) pass.
hal/zynq.ld:
- Move wolfBoot ORIGIN from 0x08000000 to 0x10000000. Large FIT images
(kernel load=0x00200000, payload >~126 MB) would sweep across
0x08000000 at handoff and overwrite wolfBoot's own code.
tools/scripts/zcu102/zcu102-ca53-qspi.cmm:
- Rewrite against the Lauterbach TRACE32 ZCU102 QSPI demo: PREPAREONLY
entry mode, single/dual toggle, READ_ID_TEST, separate flash dialogs
for BOOT.BIN (offset 0) and test-app/image_v1_signed.bin.
- Document the ~128 MB TRACE32 temp-memory ceiling on FLASHFILE.Create:
larger files must be split externally and loaded in chunks.
pull/765/head
parent
75439c7a87
commit
cbaecdd5d8
|
|
@ -84,8 +84,12 @@ CFLAGS_EXTRA+=-DBOOT_PART_A=1
|
|||
CFLAGS_EXTRA+=-DBOOT_PART_B=2
|
||||
|
||||
# Disk read chunk size for firmware loading (update_disk.c). 512KB gives the
|
||||
# best throughput (~1.4s for 32MB). The SDMA engine handles boundary crossings
|
||||
# every 4KB (SDHCI_DMA_THRESHOLD default) within each 512KB chunk.
|
||||
# best throughput (~1.4s for 32MB). The SDMA engine handles SDMA buffer
|
||||
# boundary crossings within each 512KB chunk; this boundary is 4KB by default
|
||||
# (auto-derived from SDHCI_DMA_THRESHOLD). To reduce boundary IRQs, override
|
||||
# SDHCI_DMA_BUFF_BOUNDARY independently using the raw register value so the
|
||||
# override is safe to use in preprocessor #if expressions, e.g.:
|
||||
# CFLAGS_EXTRA+=-DSDHCI_DMA_BUFF_BOUNDARY=0x7000 # 512KB (SDHCI_SRS01_DMA_BUFF_512KB)
|
||||
CFLAGS_EXTRA+=-DDISK_BLOCK_SIZE=0x80000
|
||||
|
||||
# Linux rootfs is on partition 4. Device naming depends on whether both
|
||||
|
|
@ -99,8 +103,8 @@ CFLAGS_EXTRA+=-DLINUX_BOOTARGS_ROOT=\"/dev/mmcblk0p4\"
|
|||
# ============================================================================
|
||||
# Boot Memory Layout
|
||||
# ============================================================================
|
||||
# wolfBoot runs from DDR at 0x8000000 (same as U-Boot, loaded via BL31)
|
||||
WOLFBOOT_ORIGIN=0x8000000
|
||||
# wolfBoot runs from DDR at 0x10000000 (loaded by BL31; see hal/zynq.ld).
|
||||
WOLFBOOT_ORIGIN=0x10000000
|
||||
|
||||
# Load Partition to RAM Address (Linux kernel loads here)
|
||||
WOLFBOOT_LOAD_ADDRESS?=0x10000000
|
||||
|
|
|
|||
|
|
@ -3223,7 +3223,7 @@ qemu-system-aarch64 -machine xlnx-zcu102 -cpu cortex-a53 -serial stdio -display
|
|||
|
||||
Use `config/examples/zynqmp_sdcard.config`. This uses the Arasan SDHCI controller (SD1 - external SD card slot on ZCU102) and an **MBR** partitioned SD card.
|
||||
|
||||
wolfBoot unconditionally flushes the EL2 D-cache/I-cache and disables the EL2 MMU before handoff (see `el2_flush_and_disable_mmu` in `src/boot_aarch64_start.S`), satisfying the ARM64 Linux boot protocol with no extra config flag required.
|
||||
On the direct-jump handoff path, wolfBoot flushes the EL2 D-cache/I-cache and disables the EL2 MMU via `el2_flush_and_disable_mmu` in `src/boot_aarch64_start.S` when `BOOT_EL1` is not enabled and the current exception level is EL2. The ERET-to-EL1 handoff path is different, so this cleanup is not unconditional.
|
||||
|
||||
**Partition layout**
|
||||
| Partition | Name | Size | Type | Contents |
|
||||
|
|
@ -3329,8 +3329,11 @@ The ZynqMP uses an Arasan SDHCI v3.0 controller. Key considerations:
|
|||
level. `SDHCI_FORCE_CARD_DETECT` is set in the config since FSBL already booted from
|
||||
the same SD card.
|
||||
- **`DISK_BLOCK_SIZE`**: Controls the firmware read chunk size in `update_disk.c` (default
|
||||
64KB). This determines the per-read size passed to the SDHCI driver. Must be less than
|
||||
the SDMA buffer boundary (4KB with the default threshold).
|
||||
64KB). This determines the per-read size passed to the SDHCI driver. It does not need
|
||||
to be smaller than `SDHCI_DMA_BUFF_BOUNDARY`; if a read crosses one or more SDMA buffer
|
||||
boundaries, the SDHCI driver handles that via the normal SDMA boundary interrupt path.
|
||||
In practice, this setting is a tradeoff: larger reads may trigger boundary IRQs more
|
||||
often, while smaller reads reduce crossings but increase request overhead.
|
||||
|
||||
**Debug**
|
||||
|
||||
|
|
|
|||
13
hal/versal.c
13
hal/versal.c
|
|
@ -66,7 +66,11 @@
|
|||
/* Linux kernel command line arguments */
|
||||
#ifndef LINUX_BOOTARGS
|
||||
#ifndef LINUX_BOOTARGS_ROOT
|
||||
#define LINUX_BOOTARGS_ROOT "/dev/mmcblk0p4"
|
||||
/* Default Versal SD layout: rootfs on partition 2. Configurations that use
|
||||
* the 4-partition MBR layout with OFP_A/OFP_B slots
|
||||
* (boot / OFP_A / OFP_B / rootfs, e.g. config/examples/zynqmp_sdcard.config)
|
||||
* should override LINUX_BOOTARGS_ROOT to "/dev/mmcblk0p4". */
|
||||
#define LINUX_BOOTARGS_ROOT "/dev/mmcblk0p2"
|
||||
#endif
|
||||
|
||||
#define LINUX_BOOTARGS \
|
||||
|
|
@ -1275,10 +1279,11 @@ int hal_dts_fixup(void* dts_addr)
|
|||
/* Expand total size to allow adding/modifying properties */
|
||||
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 512);
|
||||
|
||||
/* Find /chosen node */
|
||||
/* Find /chosen node; create it only if genuinely missing. Any other
|
||||
* negative return (malformed FDT, etc.) is surfaced directly rather
|
||||
* than masked by a follow-on fdt_add_subnode() failure. */
|
||||
off = fdt_find_node_offset(fdt, -1, "chosen");
|
||||
if (off < 0) {
|
||||
/* Create /chosen node if it doesn't exist */
|
||||
if (off == -FDT_ERR_NOTFOUND) {
|
||||
off = fdt_add_subnode(fdt, 0, "chosen");
|
||||
}
|
||||
|
||||
|
|
|
|||
94
hal/zynq.c
94
hal/zynq.c
|
|
@ -504,7 +504,6 @@ static int csu_dma_config(int ch, int doSwap)
|
|||
int csu_aes(int enc, const uint8_t* iv, const uint8_t* in, uint8_t* out, uint32_t sz)
|
||||
{
|
||||
int ret;
|
||||
uint32_t reg;
|
||||
|
||||
/* Flush data cache for variables used */
|
||||
flush_dcache_range((unsigned long)iv, (unsigned long)iv + AES_GCM_TAG_SZ);
|
||||
|
|
@ -601,7 +600,6 @@ int csu_init(void)
|
|||
#endif
|
||||
uint32_t reg1 = pmu_mmio_read(CSU_IDCODE);
|
||||
uint32_t reg2 = pmu_mmio_read(CSU_VERSION);
|
||||
uint64_t ms;
|
||||
|
||||
wolfBoot_printf("CSU ID 0x%08x, Ver 0x%08x\n",
|
||||
reg1, reg2 & CSU_VERSION_MASK);
|
||||
|
|
@ -1361,6 +1359,39 @@ static int qspi_exit_4byte_addr(QspiDev_t* dev)
|
|||
}
|
||||
#endif
|
||||
|
||||
/* Soft-reset the flash to a known idle state.
|
||||
* FSBL / BootROM may leave the flash in an unexpected mode (XIP enabled,
|
||||
* 4-byte addr set, auto-boot probing, etc.). Issue RESET_ENABLE (0x66) +
|
||||
* RESET_MEMORY (0x99) to bring it back to defaults before first transaction.
|
||||
* Per Micron MT25Q datasheet: t_SHSL2 ~ 40 us max after RESET_MEMORY. */
|
||||
static int qspi_flash_reset(QspiDev_t* dev)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cmd[4]; /* size multiple of uint32_t */
|
||||
|
||||
memset(cmd, 0, sizeof(cmd));
|
||||
cmd[0] = RESET_ENABLE_CMD;
|
||||
/* Reset commands are always issued in single-SPI mode regardless of
|
||||
* dev->mode: the flash's current bus mode is unknown at reset time, and
|
||||
* the single-SPI opcode is the universal-compatible form. */
|
||||
ret = qspi_transfer(dev, cmd, 1, NULL, 0, NULL, 0, 0,
|
||||
GQSPI_GEN_FIFO_MODE_SPI);
|
||||
#if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 2
|
||||
wolfBoot_printf("Flash Reset Enable: Ret %d\n", ret);
|
||||
#endif
|
||||
if (ret == GQSPI_CODE_SUCCESS) {
|
||||
cmd[0] = RESET_MEMORY_CMD;
|
||||
ret = qspi_transfer(dev, cmd, 1, NULL, 0, NULL, 0, 0,
|
||||
GQSPI_GEN_FIFO_MODE_SPI);
|
||||
#if defined(DEBUG_ZYNQ) && DEBUG_ZYNQ >= 2
|
||||
wolfBoot_printf("Flash Reset Memory: Ret %d\n", ret);
|
||||
#endif
|
||||
}
|
||||
/* Allow flash time to complete the reset and become ready. */
|
||||
hal_delay_ms(1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* QSPI functions */
|
||||
void qspi_init(void)
|
||||
{
|
||||
|
|
@ -1444,13 +1475,29 @@ void qspi_init(void)
|
|||
#if (GQSPI_CLK_REF / (2 << GQSPI_CLK_DIV)) <= 40000000 /* 40MHz */
|
||||
/* At <40 MHz, the Quad-SPI controller should be in non-loopback mode with
|
||||
* the clock and data tap delays bypassed. */
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
/* IOU_TAPDLY_BYPASS is not writable from EL2/EL1 without going through PMU. */
|
||||
if (current_el() <= 2) {
|
||||
pmu_request(PM_MMIO_WRITE, IOU_TAPDLY_BYPASS_ADDR,
|
||||
IOU_TAPDLY_BYPASS_LQSPI_RX, IOU_TAPDLY_BYPASS_LQSPI_RX,
|
||||
0, NULL);
|
||||
}
|
||||
else {
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
}
|
||||
GQSPI_LPBK_DLY_ADJ = 0;
|
||||
GQSPI_DATA_DLY_ADJ = 0;
|
||||
#elif (GQSPI_CLK_REF / (2 << GQSPI_CLK_DIV)) <= 100000000 /* 100MHz */
|
||||
/* At <100 MHz, the Quad-SPI controller should be in clock loopback mode
|
||||
* with the clock tap delay bypassed, but the data tap delay enabled. */
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
/* IOU_TAPDLY_BYPASS is not writable from EL2/EL1 without going through PMU. */
|
||||
if (current_el() <= 2) {
|
||||
pmu_request(PM_MMIO_WRITE, IOU_TAPDLY_BYPASS_ADDR,
|
||||
IOU_TAPDLY_BYPASS_LQSPI_RX, IOU_TAPDLY_BYPASS_LQSPI_RX,
|
||||
0, NULL);
|
||||
}
|
||||
else {
|
||||
IOU_TAPDLY_BYPASS |= IOU_TAPDLY_BYPASS_LQSPI_RX;
|
||||
}
|
||||
GQSPI_LPBK_DLY_ADJ = GQSPI_LPBK_DLY_ADJ_USE_LPBK;
|
||||
GQSPI_DATA_DLY_ADJ = (GQSPI_DATA_DLY_ADJ_USE_DATA_DLY |
|
||||
GQSPI_DATA_DLY_ADJ_DATA_DLY_ADJ(2));
|
||||
|
|
@ -1485,6 +1532,19 @@ void qspi_init(void)
|
|||
(void)reg_cfg;
|
||||
(void)reg_isr;
|
||||
|
||||
/* Issue flash soft reset so we start from a known state regardless of
|
||||
* whatever mode FSBL/BootROM left the device in. Send to each chip in
|
||||
* dual-parallel configurations by targeting both chip selects. */
|
||||
mDev.mode = GQSPI_GEN_FIFO_MODE_SPI;
|
||||
mDev.bus = GQSPI_GEN_FIFO_BUS_LOW;
|
||||
mDev.cs = GQSPI_GEN_FIFO_CS_LOWER;
|
||||
(void)qspi_flash_reset(&mDev);
|
||||
#if GQPI_USE_DUAL_PARALLEL == 1
|
||||
mDev.bus = GQSPI_GEN_FIFO_BUS_UP;
|
||||
mDev.cs = GQSPI_GEN_FIFO_CS_UPPER;
|
||||
(void)qspi_flash_reset(&mDev);
|
||||
#endif
|
||||
|
||||
/* ------ Flash Read ID (retry) ------ */
|
||||
timeout = 0;
|
||||
while (++timeout < QSPI_FLASH_READY_TRIES) {
|
||||
|
|
@ -1577,6 +1637,10 @@ void hal_init(void)
|
|||
wolfBoot_printf(bootMsg);
|
||||
wolfBoot_printf("Current EL: %d\n", current_el());
|
||||
|
||||
#ifndef WOLFBOOT_REPRODUCIBLE_BUILD
|
||||
wolfBoot_printf("Build: %s %s\n", __DATE__, __TIME__);
|
||||
#endif
|
||||
|
||||
#if defined(EXT_FLASH) && (EXT_FLASH == 1)
|
||||
qspi_init();
|
||||
#endif
|
||||
|
|
@ -1809,15 +1873,28 @@ void RAMFUNCTION ext_flash_unlock(void)
|
|||
|
||||
}
|
||||
|
||||
/* The following helpers (hal_get_timer_us, hal_get_dts_address, hal_dts_fixup)
|
||||
* are only compiled into the wolfBoot binary. The test-app build also links
|
||||
* hal/zynq.o but must not pull in FDT/MMU-specific code, so __WOLFBOOT gates
|
||||
* these symbols out of that build. */
|
||||
#if defined(MMU) && defined(__WOLFBOOT)
|
||||
/* Fallback timer frequency if CNTFRQ_EL0 is not configured (e.g. boot path
|
||||
* that did not run ATF/BL31). ZynqMP system counter is 100 MHz. */
|
||||
#ifndef ZYNQMP_TIMER_CLK_FREQ
|
||||
#define ZYNQMP_TIMER_CLK_FREQ 100000000ULL
|
||||
#endif
|
||||
|
||||
/* Get current time in microseconds using ARMv8 generic timer */
|
||||
uint64_t hal_get_timer_us(void)
|
||||
{
|
||||
uint64_t count, freq;
|
||||
__asm__ volatile("mrs %0, CNTPCT_EL0" : "=r"(count));
|
||||
__asm__ volatile("mrs %0, CNTFRQ_EL0" : "=r"(freq));
|
||||
/* Fall back to a known frequency rather than returning 0, so udelay()
|
||||
* callers that spin on hal_get_timer_us() advancing remain monotonic
|
||||
* (matches hal/versal.c). */
|
||||
if (freq == 0)
|
||||
return 0;
|
||||
freq = ZYNQMP_TIMER_CLK_FREQ;
|
||||
/* Use __uint128_t to avoid overflow of (count * 1e6) at long uptimes
|
||||
* (would overflow uint64_t after ~51h at 100MHz). */
|
||||
return (uint64_t)(((__uint128_t)count * 1000000ULL) / freq);
|
||||
|
|
@ -1856,10 +1933,11 @@ int hal_dts_fixup(void* dts_addr)
|
|||
* the pattern used in hal/versal.c:hal_dts_fixup. */
|
||||
fdt_set_totalsize(fdt, fdt_totalsize(fdt) + 512);
|
||||
|
||||
/* Find /chosen node */
|
||||
/* Find /chosen node; create it only if genuinely missing. Any other
|
||||
* negative return (malformed FDT, etc.) is surfaced directly rather
|
||||
* than masked by a follow-on fdt_add_subnode() failure. */
|
||||
off = fdt_find_node_offset(fdt, -1, "chosen");
|
||||
if (off < 0) {
|
||||
/* Create /chosen node if it doesn't exist */
|
||||
if (off == -FDT_ERR_NOTFOUND) {
|
||||
off = fdt_add_subnode(fdt, 0, "chosen");
|
||||
}
|
||||
if (off < 0) {
|
||||
|
|
|
|||
17
hal/zynq.ld
17
hal/zynq.ld
|
|
@ -13,10 +13,21 @@ MEMORY
|
|||
{
|
||||
/* psu_ddr_0_MEM_0 : ORIGIN = 0x0, LENGTH = 0x80000000 */
|
||||
/* wolfBoot DDR location (2MB reserved):
|
||||
* Loaded by FSBL/BL31 to DDR at 0x8000000 (128MB)
|
||||
* Same address used for both QSPI and SD card boot
|
||||
* Loaded by FSBL/BL31 to DDR at 0x10000000 (256MB). Must be above
|
||||
* the OS kernel load region: for FIT images whose "load" address is
|
||||
* 0x00200000 (typical for AArch64 kernels) and whose payload
|
||||
* approaches or exceeds ~126MB, the kernel memcpy into 0x00200000..
|
||||
* sweeps across 0x08000000 and would clobber wolfBoot if linked
|
||||
* there. Same address used for QSPI and SD card boot.
|
||||
*
|
||||
* WOLFBOOT_LOAD_ADDRESS (signed-image staging base) also defaults to
|
||||
* 0x10000000 on the SD-card config. The overlap with wolfBoot's own
|
||||
* 2MB text region is safe because wolfBoot completes the verify and
|
||||
* jump sequence from I-cache; the I-cache is only invalidated inside
|
||||
* el2_flush_and_disable_mmu, immediately before control transfers to
|
||||
* the loaded kernel (which no longer needs wolfBoot's .text).
|
||||
*/
|
||||
psu_ddr_0_MEM_0 : ORIGIN = 0x8000000, LENGTH = 0x200000
|
||||
psu_ddr_0_MEM_0 : ORIGIN = 0x10000000, LENGTH = 0x200000
|
||||
psu_ddr_1_MEM_0 : ORIGIN = 0x800000000, LENGTH = 0x80000000
|
||||
psu_ocm_ram_0_MEM_0 : ORIGIN = 0xFFFC0000, LENGTH = 0x40000
|
||||
psu_qspi_linear_0_MEM_0 : ORIGIN = 0xC0000000, LENGTH = 0x20000000
|
||||
|
|
|
|||
|
|
@ -57,7 +57,13 @@
|
|||
#define DISK_TEST_BLOCK_ADDR 149504 /* ~76MB offset */
|
||||
#endif
|
||||
|
||||
/* Auto-select DMA buffer boundary based on threshold */
|
||||
/* DMA buffer boundary: how often the SDMA engine pauses to refresh its
|
||||
* address pointer (handled by sdhci_irq_handler() via SDHCI_SRS12_DMAINT).
|
||||
* This is a throughput knob and is independent of SDHCI_DMA_THRESHOLD
|
||||
* (which controls when to switch from PIO to SDMA). Override in target
|
||||
* .config to match the largest expected single transfer for fewer
|
||||
* boundary IRQs; otherwise auto-select based on the threshold. */
|
||||
#ifndef SDHCI_DMA_BUFF_BOUNDARY
|
||||
#if (SDHCI_DMA_THRESHOLD > (256U * 1024U))
|
||||
#define SDHCI_DMA_BUFF_BOUNDARY SDHCI_SRS01_DMA_BUFF_512KB
|
||||
#if (SDHCI_DMA_THRESHOLD != (512U * 1024U))
|
||||
|
|
@ -99,6 +105,7 @@
|
|||
#warning "SDHCI_DMA_THRESHOLD rounded up to 4KB (minimum)"
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !SDHCI_DMA_BUFF_BOUNDARY */
|
||||
|
||||
/* Timeouts */
|
||||
#ifndef SDHCI_INIT_TIMEOUT_US
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#include "hal/versal.h"
|
||||
#elif defined(TARGET_zynq)
|
||||
#include "hal/zynq.h"
|
||||
#elif defined(TARGET_ls1028a)
|
||||
#elif defined(TARGET_nxp_ls1028a)
|
||||
#include "hal/nxp_ls1028a.h"
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1362,7 +1362,7 @@ el2_to_el1_boot:
|
|||
* at EL2, so instruction fetch keeps working after SCTLR_EL2.M is
|
||||
* cleared.
|
||||
*
|
||||
* AAPCS64: clobbers x0-x11; x30 (LR) is preserved because the
|
||||
* AAPCS64: clobbers x0-x7, x9-x11; x30 (LR) is preserved because the
|
||||
* set/way loop body does not touch it.
|
||||
*/
|
||||
#if defined(EL2_HYPERVISOR) && EL2_HYPERVISOR == 1
|
||||
|
|
|
|||
|
|
@ -18,8 +18,10 @@
|
|||
; 3. wolfBoot runs from DDR (0x7FF00000)
|
||||
; ------------------------------------------------------------------------------
|
||||
|
||||
; Base directory for wolfBoot build output (adjust to match your build path)
|
||||
&basedir="/home/davidgarske/GitHub/wolfboot-alt"
|
||||
; Base directory for wolfBoot build output. "." means the TRACE32 current
|
||||
; working directory - set this to your wolfBoot checkout path if running
|
||||
; TRACE32 from elsewhere (e.g. "C:/src/wolfBoot" or "/home/user/wolfBoot").
|
||||
&basedir="."
|
||||
|
||||
PRINT "========================================"
|
||||
PRINT "T1040 wolfBoot Debug Session"
|
||||
|
|
|
|||
|
|
@ -25,11 +25,15 @@
|
|||
; 0xEFFFC000: Stage 1 loader (16 KB, includes reset vector)
|
||||
; ------------------------------------------------------------------------------
|
||||
|
||||
; Base directory for wolfBoot build output (adjust to match your build path)
|
||||
&basedir="/home/davidgarske/GitHub/wolfboot-alt"
|
||||
; Base directory for wolfBoot build output. "." means the TRACE32 current
|
||||
; working directory - set this to your wolfBoot checkout path if running
|
||||
; TRACE32 from elsewhere (e.g. "C:/src/wolfBoot" or "/home/user/wolfBoot").
|
||||
&basedir="."
|
||||
|
||||
; Persistent backup directory (survives make clean)
|
||||
&backupdir="/home/davidgarske/Projects/NXP/t1040rdb"
|
||||
; Persistent backup directory (survives make clean). Leave as "." to keep
|
||||
; artifacts alongside the build tree, or point elsewhere to preserve
|
||||
; signed/backup images across source cleans.
|
||||
&backupdir="."
|
||||
|
||||
; FLASH Number of banks
|
||||
; The JS28F00AM29EWHA is a single 128MB NOR chip. CPLD virtual banking
|
||||
|
|
|
|||
|
|
@ -1,225 +1,241 @@
|
|||
; Zynq UltraScale+ ZCU102 Quad SPI FLASH Programming Script
|
||||
;
|
||||
; S(D)RAM : 0xFFFC1000
|
||||
; Generic Quad-SPI Controller base: 0xFF0F0000
|
||||
; FLASH: MT25QU512 (Micron)
|
||||
;
|
||||
; Based on Lauterbach TRACE32 ZCU102 QSPI demo scripts.
|
||||
|
||||
LOCAL &arg1
|
||||
ENTRY &arg1
|
||||
&arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY"
|
||||
&dualqspi=1 ; dual(1) or single(0)
|
||||
|
||||
; Adjust to your TRACE32 installation path
|
||||
LOCAL &pdd
|
||||
&pdd="C:/T32/demo/arm"
|
||||
|
||||
SYStem.RESet
|
||||
SYStem.CPU ZYNQ-ULTRASCALE+-APU
|
||||
SYStem.MemAccess DAP
|
||||
CORE.ASSIGN 1.
|
||||
ETM.OFF
|
||||
Trace.DISable
|
||||
|
||||
; <temporarily switch to BOOTMODE=JTAG>
|
||||
; this sequence forces the SoC to use BOOTMODE=JTAG
|
||||
; a SRST is issued using the debug logic
|
||||
; we use the first A53 for flash programming
|
||||
SYStem.Option ResBreak OFF
|
||||
SYStem.Option EnReset OFF
|
||||
SYStem.Option TRST OFF
|
||||
DO &pdd/hardware/zynq_ultrascale/scripts/zynq-ultrascale_reset.cmm OVERRIDE_BOOTMODE=0x0
|
||||
SYStem.Mode Prepare
|
||||
DO &pdd/hardware/zynq_ultrascale/scripts/zynq-ultrascale_kick_bootcore.cmm "A53_X64"
|
||||
SYStem.Mode.Attach
|
||||
Break.direct
|
||||
; </temporarily switch to BOOTMODE=JTAG>
|
||||
|
||||
SYStem.JtagClock CTCK 24MHz
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; peripheral initializations
|
||||
|
||||
//Pin muxing MIO configuration MIO[0:12]
|
||||
|
||||
Data.Set A:0xFF5E0068 %LE %Long 0x01010c00 ;QSPI_REF_CTRL
|
||||
|
||||
&addr=0xFF180000
|
||||
RePeaT 13.
|
||||
(
|
||||
Data.Set A:&addr %LE %Long 0x2
|
||||
&addr=&addr+0x4
|
||||
)
|
||||
|
||||
Data.Set A:0xFF180204 %LE %Long 0x2240000
|
||||
|
||||
Data.Set A:0xFF5E0238 %Long 0x17FFFE
|
||||
|
||||
IF &dualqspi==1
|
||||
GOSUB READ_ID_TEST_DUAL
|
||||
ELSE
|
||||
GOSUB READ_ID_TEST
|
||||
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ; Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ; thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ; thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ; Interrupt status register
|
||||
|
||||
Data.Set A:0xFF0F014C %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
;The flash dualport works only under the non-secure mode for the ZYNQ-ULTRASCALE+
|
||||
SYStem.MemAccess DAP
|
||||
Register.Set NS 1.
|
||||
Register.Set M 0x5 ;EL1h
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; Flash Declaration
|
||||
|
||||
Break.RESet
|
||||
|
||||
FLASHFILE.RESet
|
||||
FLASHFILE.CONFIG 0xFF0F0000
|
||||
|
||||
IF &dualqspi==1
|
||||
FLASHFILE.TARGET 0xFFFC1000++0x2FFF E:0xFFFC4000++0x27FF &pdd/flash/word/spiw4b64_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
|
||||
ELSE
|
||||
FLASHFILE.TARGET 0xFFFC1000++0x2FFF E:0xFFFC4000++0x27FF &pdd/flash/byte/spi4b64fs_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
|
||||
|
||||
FLASHFILE.GETID
|
||||
|
||||
//End of the test prepareonly
|
||||
IF "&arg1"=="PREPAREONLY"
|
||||
ENDDO
|
||||
|
||||
; Save Whole Flash
|
||||
;FLASHFILE.SAVE "flash_dump.bin" 0x0++0x1FFFFFFF
|
||||
|
||||
FLASHFILE.Create 0x0--0x1FFFFFFF 0x20000 Byte
|
||||
|
||||
; Flash BOOT.BIN (wolfBoot) at offset 0x0
|
||||
DIALOG.YESNO "Flash wolfBoot BOOT.BIN now?"
|
||||
ENTRY &programnow
|
||||
if &programnow
|
||||
(
|
||||
FLASHFILE.ReProgram ALL
|
||||
FLASHFILE.Load "BOOT.BIN" 0x0
|
||||
FLASHFILE.ReProgram off
|
||||
)
|
||||
|
||||
; Flash signed application image at partition offset
|
||||
DIALOG.YESNO "Flash signed application image now?"
|
||||
ENTRY &programnow
|
||||
if &programnow
|
||||
(
|
||||
FLASHFILE.ReProgram ALL
|
||||
FLASHFILE.Load "test-app/image_v1_signed.bin" 0x7000000
|
||||
FLASHFILE.ReProgram off
|
||||
)
|
||||
|
||||
ENDDO
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; Subroutines
|
||||
|
||||
READ_ID_TEST:
|
||||
(
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ;Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ;Interrupt status register
|
||||
|
||||
;read A:0xFF0F0100 -> 0x0
|
||||
|
||||
Data.Set A:0xFF0f014c %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
&dat_xfer=0x1<<8.
|
||||
&spimode=0x1<<10.
|
||||
&cs_lower=0x1<<12.
|
||||
&cs_upper=0x1<<13.
|
||||
&bus_lower=0x1<<14.
|
||||
&bus_upper=0x2<<14.
|
||||
&bus_both=0x3<<14.
|
||||
&transmit=0x1<<16.
|
||||
&receive=0x1<<17.
|
||||
&stripe=0x1<<18.
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x1 ;spi enable register , cs low
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x9f ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (dummy)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (manufacture id)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (device id)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x0 ;spi disable, cs high
|
||||
|
||||
RETURN
|
||||
)
|
||||
|
||||
|
||||
READ_ID_TEST_DUAL:
|
||||
(
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ;Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ;Interrupt status register
|
||||
|
||||
;read A:0xFF0F0100 -> 0x0
|
||||
|
||||
Data.Set A:0xFF0f014c %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
&dat_xfer=0x1<<8.
|
||||
&spimode=0x1<<10.
|
||||
&cs_lower=0x1<<12.
|
||||
&cs_upper=0x1<<13.
|
||||
&bus_lower=0x1<<14.
|
||||
&bus_upper=0x2<<14.
|
||||
&bus_both=0x3<<14.
|
||||
&transmit=0x1<<16.
|
||||
&receive=0x1<<17.
|
||||
&stripe=0x1<<18.
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x1 ;spi enable register , cs low
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00009f9f ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x0 ;spi disable, cs high
|
||||
|
||||
RETURN
|
||||
)
|
||||
; Zynq UltraScale+ ZCU102 Quad SPI FLASH Programming Script
|
||||
;
|
||||
; S(D)RAM : 0xFFFC1000
|
||||
; Generic Quad-SPI Controller base: 0xFF0F0000
|
||||
; FLASH: MT25QU512 (Micron)
|
||||
;
|
||||
; Based on Lauterbach TRACE32 ZCU102 QSPI demo scripts.
|
||||
|
||||
LOCAL &arg1
|
||||
ENTRY &arg1
|
||||
&arg1=STRing.UPpeR("&arg1") // for example "PREPAREONLY"
|
||||
&dualqspi=1 ; dual(1) or single(0)
|
||||
|
||||
; TRACE32 demo scripts directory.
|
||||
; "~~" is the TRACE32 installation path - expands to the correct location
|
||||
; on Windows (e.g. C:/T32), Linux (e.g. /opt/t32), and macOS automatically,
|
||||
; so no per-platform edit is needed. Override only if the demo scripts live
|
||||
; somewhere non-standard:
|
||||
; &pdd="C:/T32/demo/arm" ; Windows default install
|
||||
; &pdd="/opt/t32/demo/arm" ; Linux default install
|
||||
LOCAL &pdd
|
||||
&pdd="~~/demo/arm"
|
||||
|
||||
SYStem.RESet
|
||||
SYStem.CPU ZYNQ-ULTRASCALE+-APU
|
||||
SYStem.MemAccess DAP
|
||||
CORE.ASSIGN 1.
|
||||
ETM.OFF
|
||||
Trace.DISable
|
||||
|
||||
; <temporarily switch to BOOTMODE=JTAG>
|
||||
; this sequence forces the SoC to use BOOTMODE=JTAG
|
||||
; a SRST is issued using the debug logic
|
||||
; we use the first A53 for flash programming
|
||||
SYStem.Option ResBreak OFF
|
||||
SYStem.Option EnReset OFF
|
||||
SYStem.Option TRST OFF
|
||||
DO &pdd/hardware/zynq_ultrascale/scripts/zynq-ultrascale_reset.cmm OVERRIDE_BOOTMODE=0x0
|
||||
SYStem.Mode Prepare
|
||||
DO &pdd/hardware/zynq_ultrascale/scripts/zynq-ultrascale_kick_bootcore.cmm "A53_X64"
|
||||
SYStem.Mode.Attach
|
||||
Break.direct
|
||||
; </temporarily switch to BOOTMODE=JTAG>
|
||||
|
||||
SYStem.JtagClock CTCK 24MHz
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; peripheral initializations
|
||||
|
||||
//Pin muxing MIO configuration MIO[0:12]
|
||||
|
||||
Data.Set A:0xFF5E0068 %LE %Long 0x01010c00 ;QSPI_REF_CTRL
|
||||
|
||||
&addr=0xFF180000
|
||||
RePeaT 13.
|
||||
(
|
||||
Data.Set A:&addr %LE %Long 0x2
|
||||
&addr=&addr+0x4
|
||||
)
|
||||
|
||||
Data.Set A:0xFF180204 %LE %Long 0x2240000
|
||||
|
||||
Data.Set A:0xFF5E0238 %Long 0x17FFFE
|
||||
|
||||
IF &dualqspi==1
|
||||
GOSUB READ_ID_TEST_DUAL
|
||||
ELSE
|
||||
GOSUB READ_ID_TEST
|
||||
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ; Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ; thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ; thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ; Interrupt status register
|
||||
|
||||
Data.Set A:0xFF0F014C %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
;The flash dualport works only under the non-secure mode for the ZYNQ-ULTRASCALE+
|
||||
SYStem.MemAccess DAP
|
||||
Register.Set NS 1.
|
||||
Register.Set M 0x5 ;EL1h
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; Flash Declaration
|
||||
|
||||
Break.RESet
|
||||
|
||||
FLASHFILE.RESet
|
||||
FLASHFILE.CONFIG 0xFF0F0000
|
||||
|
||||
IF &dualqspi==1
|
||||
FLASHFILE.TARGET 0xFFFC1000++0x2FFF E:0xFFFC4000++0x27FF &pdd/flash/word/spiw4b64_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
|
||||
ELSE
|
||||
FLASHFILE.TARGET 0xFFFC1000++0x2FFF E:0xFFFC4000++0x27FF &pdd/flash/byte/spi4b64fs_zynqultra.bin /KEEP /STACKSIZE 0x400 /DUALPORT
|
||||
|
||||
FLASHFILE.GETID
|
||||
|
||||
//End of the test prepareonly
|
||||
IF "&arg1"=="PREPAREONLY"
|
||||
ENDDO
|
||||
|
||||
; Save Whole Flash
|
||||
;FLASHFILE.SAVE "flash_dump.bin" 0x0++0x1FFFFFFF
|
||||
|
||||
FLASHFILE.Create 0x0--0x1FFFFFFF 0x20000 Byte
|
||||
|
||||
; NOTE ON LARGE IMAGES (>~100 MB):
|
||||
; FLASHFILE.Load buffers the full source file into TRACE32 temporary memory
|
||||
; before any programming. Many installations cap that pool at ~128 MB, so a
|
||||
; single Load of a file larger than ~100 MB will fail with
|
||||
; "FATAL ERROR: out of temporary memory"
|
||||
; Workaround: split the source externally (e.g. `dd bs=1M count=N` and
|
||||
; `dd bs=1M skip=N`) and issue each Load in its own
|
||||
; FLASHFILE.ReProgram ALL / off bracket (the temp pool is released between
|
||||
; brackets - a single bracket spanning multiple large Loads still exhausts
|
||||
; memory on the second Load).
|
||||
|
||||
; Flash BOOT.BIN (wolfBoot) at offset 0x0
|
||||
DIALOG.YESNO "Flash wolfBoot BOOT.BIN now?"
|
||||
ENTRY &programnow
|
||||
if &programnow
|
||||
(
|
||||
FLASHFILE.ReProgram ALL
|
||||
FLASHFILE.Load "BOOT.BIN" 0x0
|
||||
FLASHFILE.ReProgram off
|
||||
)
|
||||
|
||||
; Flash signed application image at partition offset
|
||||
DIALOG.YESNO "Flash signed application image now?"
|
||||
ENTRY &programnow
|
||||
if &programnow
|
||||
(
|
||||
FLASHFILE.ReProgram ALL
|
||||
FLASHFILE.Load "test-app/image_v1_signed.bin" 0x7000000
|
||||
FLASHFILE.ReProgram off
|
||||
)
|
||||
|
||||
ENDDO
|
||||
|
||||
; --------------------------------------------------------------------------------
|
||||
; Subroutines
|
||||
|
||||
READ_ID_TEST:
|
||||
(
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ;Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ;Interrupt status register
|
||||
|
||||
;read A:0xFF0F0100 -> 0x0
|
||||
|
||||
Data.Set A:0xFF0f014c %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
&dat_xfer=0x1<<8.
|
||||
&spimode=0x1<<10.
|
||||
&cs_lower=0x1<<12.
|
||||
&cs_upper=0x1<<13.
|
||||
&bus_lower=0x1<<14.
|
||||
&bus_upper=0x2<<14.
|
||||
&bus_both=0x3<<14.
|
||||
&transmit=0x1<<16.
|
||||
&receive=0x1<<17.
|
||||
&stripe=0x1<<18.
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x1 ;spi enable register , cs low
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x9f ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (dummy)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (manufacture id)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120) " (device id)"
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &transmit|&receive|&bus_lower|&cs_lower|&spimode|&dat_xfer|0x1
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x0 ;spi disable, cs high
|
||||
|
||||
RETURN
|
||||
)
|
||||
|
||||
READ_ID_TEST_DUAL:
|
||||
(
|
||||
Data.Set A:0xFF0F0144 %LE %Long 1 ;enable GQSPI_SEL
|
||||
Data.Set A:0xFF0F010C %Long 0x0FBE ;Interrupt disable register
|
||||
Data.Set A:0xFF0F0128 %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F012C %Long 0x01 ;thres hold
|
||||
Data.Set A:0xFF0F0104 %Long 0x0FBE ;Interrupt status register
|
||||
|
||||
;read A:0xFF0F0100 -> 0x0
|
||||
|
||||
Data.Set A:0xFF0f014c %Long 0x7 ; reset tx fifo and gen_fifo..
|
||||
WAIT 100.ms
|
||||
|
||||
Data.Set A:0xFF0F0100 %Long 0x00080010 ;Config register, clk speed control[5:3] , mode==00 [31:30] I/O mode
|
||||
|
||||
&dat_xfer=0x1<<8.
|
||||
&spimode=0x1<<10.
|
||||
&cs_lower=0x1<<12.
|
||||
&cs_upper=0x1<<13.
|
||||
&bus_lower=0x1<<14.
|
||||
&bus_upper=0x2<<14.
|
||||
&bus_both=0x3<<14.
|
||||
&transmit=0x1<<16.
|
||||
&receive=0x1<<17.
|
||||
&stripe=0x1<<18.
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x1 ;spi enable register , cs low
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00009f9f ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F011C %Long 0x00000000 ; tx, data transfer
|
||||
Data.Set A:0xFF0F0140 %Long &stripe|&transmit|&receive|&bus_both|&cs_lower|&cs_upper|&spimode|&dat_xfer|0x4 ; tx,4 byte data transfer
|
||||
PRINT "read 0x" Data.Long(A:0xff0f0120)
|
||||
|
||||
Data.Set A:0xFF0F0114 %Long 0x0 ;spi disable, cs high
|
||||
|
||||
RETURN
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ Trace.DISable
|
|||
|
||||
SYStem.Mode Prepare
|
||||
;GOSUB DisableWatchdog
|
||||
;DO "C:/T32/demo/arm/hardware/zynq_ultrascale/scripts/zynq-ultrascale_kick_bootcore.cmm" A53_X64
|
||||
; "~~" expands to the TRACE32 install dir on any host OS (Windows/Linux/macOS):
|
||||
;DO "~~/demo/arm/hardware/zynq_ultrascale/scripts/zynq-ultrascale_kick_bootcore.cmm" A53_X64
|
||||
|
||||
SYStem.Mode.Attach
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue