Skip to content

Commit

Permalink
Added flattened device tree (FDT) support. Setting required FDT field…
Browse files Browse the repository at this point in the history
…s per ePAPR 1.1.
  • Loading branch information
dgarske committed Nov 14, 2023
1 parent 5000fc7 commit 0f0f8ca
Show file tree
Hide file tree
Showing 8 changed files with 853 additions and 33 deletions.
3 changes: 3 additions & 0 deletions arch.mk
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ ifeq ($(TARGET),nxp_t1024)
LDFLAGS+=-Wl,--hash-style=both # generate both sysv and gnu symbol hash table
LDFLAGS+=-Wl,--as-needed # remove weak functions not used
OBJS+=src/boot_ppc_mp.o # support for spin table
OBJS+=src/fdt.o
UPDATE_OBJS:=src/update_ram.o
ifeq ($(SPMATH),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
Expand All @@ -445,6 +446,7 @@ ifeq ($(TARGET),nxp_t2080)
LDFLAGS+=-Wl,--hash-style=both # generate both sysv and gnu symbol hash table
LDFLAGS+=-Wl,--as-needed # remove weak functions not used
UPDATE_OBJS:=src/update_ram.o
OBJS+=src/fdt.o
ifeq ($(SPMATH),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
Expand Down Expand Up @@ -750,6 +752,7 @@ BOOT_IMG?=test-app/image.bin
## Update mechanism
ifeq ($(ARCH),AARCH64)
CFLAGS+=-DMMU -DWOLFBOOT_DUALBOOT
OBJS+=src/fdt.o
UPDATE_OBJS:=src/update_ram.o
endif
ifeq ($(DUALBANK_SWAP),1)
Expand Down
6 changes: 6 additions & 0 deletions hal/nxp_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
#define CCSRBAR_SIZE BOOKE_PAGESZ_1M

#define ENABLE_DDR
#ifndef DDR_SIZE
#define DDR_SIZE (512UL * 1024UL * 1024UL)
#endif

/* Memory used for transferring blocks to/from NAND.
* Maps to eLBC FCM internal 8KB region (by hardware) */
Expand Down Expand Up @@ -87,7 +89,9 @@
#endif

#define ENABLE_DDR
#ifndef DDR_SIZE
#define DDR_SIZE (2048ULL * 1024ULL * 1024ULL)
#endif

#define FLASH_BASE_ADDR 0xEC000000UL
#define FLASH_BASE_PHYS_HIGH 0xFULL
Expand Down Expand Up @@ -125,7 +129,9 @@
#define ENABLE_INTERRUPTS

#define ENABLE_DDR
#ifndef DDR_SIZE
#define DDR_SIZE (8192UL * 1024UL * 1024UL)
#endif

#define FLASH_BASE_ADDR 0xE8000000UL
#define FLASH_BASE_PHYS_HIGH 0x0ULL
Expand Down
125 changes: 114 additions & 11 deletions hal/nxp_t1024.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "string.h"
#include "hal.h"
#include "nxp_ppc.h"
#include "fdt.h"

/* Tested on T1024E Rev 1.0, e5500 core 2.1, PVR 8024_1021 and SVR 8548_0010 */
/* IFC: CS0 NOR, CS1 MRAM, CS2 CPLD, CS3, MPU CPLD */
Expand Down Expand Up @@ -119,6 +120,7 @@ static void hal_flash_unlock_sector(uint32_t sector);

/* QUICC Engine */
#define QE_MAX_RISC 1
#define QE_MURAM_SIZE (24 * 1024)

/* QE microcode/firmware address */
#ifndef QE_FW_ADDR
Expand Down Expand Up @@ -152,6 +154,8 @@ static void hal_flash_unlock_sector(uint32_t sector);
#define QE_RSP_TIBCR(n, i) ((volatile uint32_t*)(QE_RSP + ((n) * 0x100) + (i)))
#define QE_RSP_ECCR(n) ((volatile uint32_t*)(QE_RSP + ((n) * 0x100) + 0xF0))

#define QE_MURAM (QE_ENGINE_BASE + 0x110000UL) /* 24KB */

#define QE_IRAM_IADD_AIE 0x80000000 /* Auto Increment Enable */
#define QE_IRAM_IADD_BADDR 0x00080000 /* Base Address */
#define QE_IRAM_READY 0x80000000
Expand Down Expand Up @@ -234,7 +238,7 @@ static void hal_flash_unlock_sector(uint32_t sector);
#endif

#define FMAN_BASE (CCSRBAR + 0x400000)
//#define QE_CEPIER ((volatile uint32_t*)(FMAN_BASE + 0x00CUL))




Expand Down Expand Up @@ -619,22 +623,31 @@ enum ifc_amask_sizes {


#ifdef ENABLE_BUS_CLK_CALC
static uint32_t hal_get_bus_clk(void)
static uint32_t hal_get_plat_clk(void)
{
/* compute bus clock (system input * ratio) */
uint32_t plat_clk, bus_clk;
/* compute platform clock (system input * ratio) */
uint32_t plat_clk;
uint32_t plat_ratio = get32(CLOCKING_PLLPGSR); /* see SYS_PLL_RAT in RCW */
/* mask and shift by 1 to get platform ratio */
plat_ratio = ((plat_ratio & 0x3E) >> 1); /* default is 4 (4:1) */
plat_clk = SYS_CLK * plat_ratio;
bus_clk = plat_clk / 2;
return plat_clk;
}

static uint32_t hal_get_bus_clk(void)
{
/* compute bus clock (platform clock / 2) */
uint32_t bus_clk = hal_get_plat_clk() / 2;
return bus_clk;
}
#else
#define hal_get_bus_clk() (uint32_t)((SYS_CLK * 4) / 2)
#define hal_get_plat_clk() (uint32_t)(SYS_CLK * 4)
#define hal_get_bus_clk() (uint32_t)(hal_get_plat_clk() / 2)
#endif

#define DELAY_US ((hal_get_bus_clk() / 16) / 1000000)
#define TIMEBASE_CLK_DIV 16
#define TIMEBASE_HZ (hal_get_plat_clk() / TIMEBASE_CLK_DIV)
#define DELAY_US (TIMEBASE_HZ / 1000000)
static void udelay(uint32_t delay_us)
{
wait_ticks(delay_us * DELAY_US);
Expand Down Expand Up @@ -1330,7 +1343,7 @@ static int hal_qe_init(void)
set32(QE_SDMA_SDAQMR, 0);

/* Allocate 2KB temporary buffer for sdma */
sdma_base = 0;
sdma_base = 0; /* offset in QE_MURAM */
set32(QE_SDMA_SDEBCR, sdma_base & QE_SDEBCR_BA_MASK);

/* Clear sdma status */
Expand Down Expand Up @@ -1370,6 +1383,10 @@ extern uint32_t _mp_page_start;
extern uint32_t _spin_table;
extern uint32_t _bootpg_addr;

#define SPIN_TABLE_ADDR() ((uint8_t*)(BOOT_ROM_ADDR + \
((uint32_t)&_spin_table - (uint32_t)&_mp_page_start)))


/* Startup additional cores with spin table and synchronize the timebase */
static void hal_mp_up(uint32_t bootpg)
{
Expand All @@ -1382,8 +1399,7 @@ static void hal_mp_up(uint32_t bootpg)
active_cores = (1 << whoami); /* current running cores */

/* Calculate location of spin table in BPTR */
spin_table_addr = (uint8_t*)(BOOT_ROM_ADDR +
((uint32_t)&_spin_table - (uint32_t)&_mp_page_start));
spin_table_addr = SPIN_TABLE_ADDR();

wolfBoot_printf("MP: Starting core 2 (spin table %p)\n",
spin_table_addr);
Expand Down Expand Up @@ -1670,7 +1686,94 @@ void* hal_get_dts_address(void)
{
return (void*)WOLFBOOT_DTS_BOOT_ADDRESS;
}
#endif

int hal_dts_fixup(void* dts_addr)
{
#ifndef BUILD_LOADER_STAGE1
struct fdt_header *fdt = (struct fdt_header *)dts_addr;
int off;
uint32_t *reg;

/* display FTD information */
wolfBoot_printf("FDT: Version %d, Size %d\n",
fdt_version(fdt), fdt_totalsize(fdt));

/* expand total size */
fdt->totalsize += 1024; /* expand by 1KB */
wolfBoot_printf("FDT: Expanded (1KB) to %d bytes\n", fdt->totalsize);

/* fixup the memory region - single bank */
off = fdt_find_devtype(fdt, -1, "memory");
if (off != -FDT_ERR_NOTFOUND) {
/* build addr/size as 64-bit */
uint8_t ranges[sizeof(uint64_t) * 2], *p = ranges;
*(uint64_t*)p = cpu_to_fdt64(DDR_ADDRESS);
p += sizeof(uint64_t);
*(uint64_t*)p = cpu_to_fdt64(DDR_SIZE);
p += sizeof(uint64_t);
fdt_setprop(fdt, off, "reg", ranges, (int)(p - ranges));
wolfBoot_printf("FDT: Set memory, start=0x%x, size=0x%x\n",
DDR_ADDRESS, (uint32_t)DDR_SIZE);
}

/* fixup CPU status and, release address and enable method */
off = fdt_find_devtype(fdt, -1, "cpu");
while (off != -FDT_ERR_NOTFOUND) {
int core;
uintptr_t core_spin_table;

reg = (uint32_t*)fdt_getprop(fdt, off, "reg", 0);
if (reg == NULL || *reg >= CPU_NUMCORES)
break;
core = *reg;

/* calculate location of spin table for core */
core_spin_table = (uintptr_t)(SPIN_TABLE_ADDR() +
(core * ENTRY_SIZE) + ENTRY_ADDR_LOWER);

fdt_fixup_str(fdt, off, "cpu", "status", (core == 0) ? "okay" : "disabled");
fdt_fixup_val(fdt, off, "cpu", "spin-table", (uint32_t)core_spin_table);
fdt_fixup_str(fdt, off, "cpu", "enable-method", "spin-table");
fdt_fixup_val(fdt, off, "cpu", "timebase-frequency", TIMEBASE_HZ);
fdt_fixup_val(fdt, off, "cpu", "clock-frequency", hal_get_plat_clk());
fdt_fixup_val(fdt, off, "cpu", "bus-frequency", hal_get_plat_clk());

off = fdt_find_devtype(fdt, off, "cpu");
}

/* fixup the soc clock */
off = fdt_find_devtype(fdt, -1, "soc");
if (off != -FDT_ERR_NOTFOUND) {
fdt_fixup_val(fdt, off, "soc", "bus-frequency", hal_get_plat_clk());
}

/* fixup the serial clocks */
off = fdt_find_devtype(fdt, -1, "serial");
while (off != -FDT_ERR_NOTFOUND) {
fdt_fixup_val(fdt, off, "serial", "clock-frequency", hal_get_bus_clk());
off = fdt_find_devtype(fdt, off, "serial");
}

/* fixup the QE bridge and bus blocks */
off = fdt_find_devtype(fdt, -1, "qe");
if (off != -FDT_ERR_NOTFOUND) {
fdt_fixup_val(fdt, off, "qe", "clock-frequency", hal_get_bus_clk());
fdt_fixup_val(fdt, off, "qe", "bus-frequency", hal_get_bus_clk());
fdt_fixup_val(fdt, off, "qe", "brg-frequency", hal_get_bus_clk()/2);
}

/* mpic clock */
off = fdt_find_devtype(fdt, -1, "open-pic");
if (off != -FDT_ERR_NOTFOUND) {
fdt_fixup_val(fdt, off, "open-pic", "clock-frequency", hal_get_bus_clk());
}


#endif /* !BUILD_LOADER_STAGE1 */
return 0;
}
#endif /* MMU */


#if defined(ENABLE_DDR) && defined(TEST_DDR)

Expand Down
138 changes: 138 additions & 0 deletions include/fdt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* fdt.h
*
* Functions to help with flattened device tree (DTB) parsing
*
*
* Copyright (C) 2023 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
*/

/* Based on work from "libfdt" by David Gibson */

#ifndef FDT_H
#define FDT_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

#ifdef BIG_ENDIAN_ORDER
#define FDT_MAGIC 0xD00DFEEDUL
#else
#define FDT_MAGIC 0xEDFE0DD0UL
#endif
#define FDT_SW_MAGIC (~FDT_MAGIC)

struct fdt_header {
uint32_t magic;
uint32_t totalsize;
uint32_t off_dt_struct;
uint32_t off_dt_strings;
uint32_t off_mem_rsvmap;
uint32_t version;
uint32_t last_comp_version;
uint32_t boot_cpuid_phys;
uint32_t size_dt_strings;
uint32_t size_dt_struct;
};

struct fdt_reserve_entry {
uint64_t address;
uint64_t size;
};

struct fdt_prop {
uint32_t len;
uint32_t nameoff;
};

struct fdt_node_header {
uint32_t tag;
char name[0];
};

struct fdt_property {
uint32_t tag;
uint32_t len;
uint32_t nameoff;
char data[0];
};

#define FDT_TAGSIZE sizeof(uint32_t)
#define FDT_ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
#define FDT_TAGALIGN(x) (FDT_ALIGN((x), FDT_TAGSIZE))

#define FDT_BEGIN_NODE 0x00000001UL
#define FDT_END_NODE 0x00000002UL
#define FDT_PROP 0x00000003UL
#define FDT_NOP 0x00000004UL
#define FDT_END 0x00000009UL

#define FDT_ERR_NOTFOUND 1
#define FDT_ERR_NOSPACE 3
#define FDT_ERR_BADOFFSET 4
#define FDT_ERR_TRUNCATED 8
#define FDT_ERR_BADVERSION 10
#define FDT_ERR_BADSTRUCTURE 11
#define FDT_ERR_INTERNAL 13


uint32_t cpu_to_fdt32(uint32_t x);
uint64_t cpu_to_fdt64(uint64_t x);
uint32_t fdt32_to_cpu(uint32_t x);
uint64_t fdt64_to_cpu(uint64_t x);

int fdt_next_node(const void *fdt, int offset, int *depth);
const void *fdt_getprop(const void *fdt, int nodeoffset, const char *name, int *lenp);
int fdt_setprop(void *fdt, int nodeoffset, const char *name, const void *val, int len);

int fdt_fixup_str(void* fdt, int off, const char* node, const char* name, const char* str);
int fdt_fixup_val(void* fdt, int off, const char* node, const char* name, uint32_t val);
int fdt_find_devtype(void* fdt, int startoff, const char* node);

#define fdt_get_header(fdt, field) (fdt32_to_cpu(((const struct fdt_header *)(fdt))->field))
#define fdt_magic(fdt) (fdt_get_header(fdt, magic))
#define fdt_totalsize(fdt) (fdt_get_header(fdt, totalsize))
#define fdt_off_dt_struct(fdt) (fdt_get_header(fdt, off_dt_struct))
#define fdt_off_dt_strings(fdt) (fdt_get_header(fdt, off_dt_strings))
#define fdt_off_mem_rsvmap(fdt) (fdt_get_header(fdt, off_mem_rsvmap))
#define fdt_version(fdt) (fdt_get_header(fdt, version))
#define fdt_last_comp_version(fdt) (fdt_get_header(fdt, last_comp_version))
#define fdt_boot_cpuid_phys(fdt) (fdt_get_header(fdt, boot_cpuid_phys))
#define fdt_size_dt_strings(fdt) (fdt_get_header(fdt, size_dt_strings))
#define fdt_size_dt_struct(fdt) (fdt_get_header(fdt, size_dt_struct))

#define fdt_set_header(fdt, field, val) (((struct fdt_header *)fdt)->field = cpu_to_fdt32(val))
#define fdt_set_magic(fdt, val) (fdt_set_header(fdt, magic, (val)))
#define fdt_set_totalsize(fdt, val) (fdt_set_header(fdt, totalsize, (val)))
#define fdt_set_off_dt_struct(fdt, val) (fdt_set_header(fdt, off_dt_struct, (val)))
#define fdt_set_off_dt_strings(fdt, val) (fdt_set_header(fdt, off_dt_strings, (val)))
#define fdt_set_off_mem_rsvmap(fdt, val) (fdt_set_header(fdt, off_mem_rsvmap, (val)))
#define fdt_set_version(fdt, val) (fdt_set_header(fdt, version, (val)))
#define fdt_set_last_comp_version(fdt, val) (fdt_set_header(fdt, last_comp_version, (val)))
#define fdt_set_boot_cpuid_phys(fdt, val) (fdt_set_header(fdt, boot_cpuid_phys, (val)))
#define fdt_set_size_dt_strings(fdt, val) (fdt_set_header(fdt, size_dt_strings, (val)))
#define fdt_set_size_dt_struct(fdt, val) (fdt_set_header(fdt, size_dt_struct, (val)))

#ifdef __cplusplus
}
#endif

#endif /* !FDT_H */
Loading

0 comments on commit 0f0f8ca

Please sign in to comment.