···33VERSION = 2026
44PATCHLEVEL = 01
55SUBLEVEL =
66-EXTRAVERSION = -rc3
66+EXTRAVERSION = -rc4
77NAME =
8899# *DOCUMENTATION*
···14971497# override the address back to make u-boot-elf.srec
14981498# compatible with the recovery tools.
14991499OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x50000000
15001500+endif
15011501+15021502+ifeq ($(CONFIG_POSITION_INDEPENDENT)$(CONFIG_RCAR_GEN5),yy)
15031503+# The flash_writer tool and previous recovery tools
15041504+# require the SREC load address to be 0x8e30_0000 .
15051505+# The PIE U-Boot build sets the address to 0x0, so
15061506+# override the address back to make u-boot-elf.srec
15071507+# compatible with the recovery tools.
15081508+OBJCOPYFLAGS_u-boot-elf.srec += --change-addresses=0x8e300000
15001509endif
1501151015021511u-boot-elf.srec: u-boot.elf FORCE
+5-5
arch/arm/config.mk
···58585959# Only test once
6060ifeq ($(CONFIG_$(PHASE_)SYS_THUMB_BUILD),y)
6161-archprepare: checkthumb checkgcc6
6161+archprepare: checkthumb checkgcc10
62626363checkthumb:
6464 @if test "$(call cc-name)" = "gcc" -a \
···6969 false; \
7070 fi
7171else
7272-archprepare: checkgcc6
7272+archprepare: checkgcc10
7373endif
74747575-checkgcc6:
7575+checkgcc10:
7676 @if test "$(call cc-name)" = "gcc" -a \
7777- "$(call cc-version)" -lt "0600"; then \
7878- echo '*** Your GCC is older than 6.0 and is not supported'; \
7777+ "$(call cc-version)" -lt "1000"; then \
7878+ echo '*** Your GCC is older than 10.0 and is not supported'; \
7979 false; \
8080 fi
8181
···217217static struct socfpga_sdr_ctrl *sdr_ctrl =
218218 (struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS;
219219220220+void socfpga_sdram_apply_static_cfg(void)
221221+{
222222+ const u32 applymask = 0x8;
223223+ u32 val = readl(&sdr_ctrl->static_cfg) | applymask;
224224+225225+ /*
226226+ * SDRAM staticcfg register specific:
227227+ * When applying the register setting, the CPU must not access
228228+ * SDRAM. Luckily for us, we can use i-cache here to help us
229229+ * circumvent the SDRAM access issue. The idea is to make sure
230230+ * that the code is in one full i-cache line by branching past
231231+ * it and back. Once it is in the i-cache, we execute the core
232232+ * of the code and apply the register settings.
233233+ *
234234+ * The code below uses 7 instructions, while the Cortex-A9 has
235235+ * 32-byte cachelines, thus the limit is 8 instructions total.
236236+ */
237237+ asm volatile(".align 5 \n"
238238+ " b 2f \n"
239239+ "1: str %0, [%1] \n"
240240+ " dsb \n"
241241+ " isb \n"
242242+ " b 3f \n"
243243+ "2: b 1b \n"
244244+ "3: nop \n"
245245+ : : "r"(val), "r"(&sdr_ctrl->static_cfg) : "memory", "cc");
246246+}
247247+220248void do_bridge_reset(int enable, unsigned int mask)
221249{
222250 int i;
···234262 writel(iswgrp_handoff[2],
235263 socfpga_get_sysmgr_addr() +
236264 SYSMGR_GEN5_FPGAINFGRP_MODULE);
237237- writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
265265+ if (iswgrp_handoff[3]) {
266266+ writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst);
267267+ socfpga_sdram_apply_static_cfg();
268268+ }
238269 writel(iswgrp_handoff[0],
239270 socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
240271 writel(iswgrp_handoff[1], &nic301_regs->remap);
···246277 writel(0, socfpga_get_sysmgr_addr() +
247278 SYSMGR_GEN5_FPGAINFGRP_MODULE);
248279 writel(0, &sdr_ctrl->fpgaport_rst);
280280+ socfpga_sdram_apply_static_cfg();
249281 writel(0x7, socfpga_get_rstmgr_addr() + RSTMGR_GEN5_BRGMODRST);
250282 writel(1, &nic301_regs->remap);
251283 }
···16161717 /* The firmware provided ATAG/FDT address can be found in r2/x0 */
1818#ifdef CONFIG_ARM64
1919- adr x8, fw_dtb_pointer
1919+ adrp x8, fw_dtb_pointer
2020+ add x8, x8, #:lo12:fw_dtb_pointer
2021 str x0, [x8]
2122#else
2223 ldr r8, =fw_dtb_pointer
+25-8
board/raspberrypi/rpi/rpi.c
···33 * (C) Copyright 2012-2016 Stephen Warren
44 */
5566+#define LOG_CATEGORY LOGC_BOARD
77+68#include <config.h>
79#include <dm.h>
810#include <env.h>
···332334#ifdef CONFIG_OF_BOARD
333335int dram_init_banksize(void)
334336{
337337+ phys_addr_t total_size = 0;
338338+ int i;
335339 int ret;
336340337341 ret = fdtdec_setup_memory_banksize();
338342 if (ret)
339343 return ret;
340344341341- return fdtdec_setup_mem_size_base();
345345+ ret = fdtdec_setup_mem_size_base();
346346+ if (ret)
347347+ return ret;
348348+349349+ /* Update gd->ram_size to reflect total RAM across all banks */
350350+ for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
351351+ if (gd->bd->bi_dram[i].size == 0)
352352+ break;
353353+ total_size += gd->bd->bi_dram[i].size;
354354+ }
355355+ gd->ram_size = total_size;
356356+357357+ return 0;
342358}
343359#endif
344360···354370}
355371356372/*
357357- * If the firmware provided a valid FDT at boot time, let's expose it in
358358- * ${fdt_addr} so it may be passed unmodified to the kernel.
373373+ * Allow U-Boot to use its control FDT with extlinux if one is not provided.
374374+ * This will then go through the usual fixups that U-Boot does, before being
375375+ * handed off to Linux
359376 */
360377static void set_fdt_addr(void)
361378{
362362- if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC)
363363- return;
364364-365365- env_set_hex("fdt_addr", fw_dtb_pointer);
379379+ env_set_hex("fdt_addr", (ulong)gd->fdt_blob);
366380}
367381368382/*
···608622{
609623 int node;
610624611611- update_fdt_from_fw(blob, (void *)fw_dtb_pointer);
625625+ if (blob == gd->fdt_blob)
626626+ log_debug("Same FDT: nothing to do\n");
627627+ else
628628+ update_fdt_from_fw(blob, (void *)gd->fdt_blob);
612629613630 if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) {
614631 node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer");
···1111#include <linux/arm-smccc.h>
1212#include "fw.h"
13131414-#define LDFW_RAW_PART "ldfw"
1515-#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
1414+#define LDFW_RAW_PART "ldfw"
1515+#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin"
1616+#define LDFW_MAGIC 0x10adab1e
1717+1818+/* SMC command for providing LDFW to EL3 monitor */
1919+#define SMC_CMD_LOAD_LDFW -0x500
2020+/* SMC command for loading some binary over USB */
2121+#define SMC_CMD_LOAD_IMAGE_BY_USB -0x512
16221717-#define LDFW_MAGIC 0x10adab1e
1818-#define SMC_CMD_LOAD_LDFW -0x500
1919-#define SDM_HW_RESET_STATUS 0x1230
2020-#define SDM_SW_RESET_STATUS 0x1231
2121-#define SB_ERROR_PREFIX 0xfdaa0000
2323+/* Error codes for SMC_CMD_LOAD_LDFW */
2424+#define SDM_HW_RESET_STATUS 0x1230
2525+#define SDM_SW_RESET_STATUS 0x1231
2626+#define SB_ERROR_PREFIX 0xfdaa0000
22272328struct ldfw_header {
2429 u32 magic;
···9499}
9510096101/**
9797- * load_ldfw - Load the loadable firmware (LDFW)
102102+ * load_image_usb - Load some binary over USB during USB boot
103103+ * @type: Image type
104104+ * @addr: Memory address where the image should be downloaded to
105105+ * @size: Image size
106106+ *
107107+ * Return: 0 on success or a negative value on error.
108108+ */
109109+int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size)
110110+{
111111+ struct arm_smccc_res res;
112112+113113+ arm_smccc_smc(SMC_CMD_LOAD_IMAGE_BY_USB, (u64)type, addr, size,
114114+ 0, 0, 0, 0, &res);
115115+ if (res.a0)
116116+ return -EIO;
117117+118118+ return 0;
119119+}
120120+121121+/**
122122+ * load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device
98123 * @ifname: Interface name of the block device to load the firmware from
99124 * @dev: Device number
100125 * @part: Partition number
···102127 *
103128 * Return: 0 on success or a negative value on error.
104129 */
105105-int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr)
130130+int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr)
131131+{
132132+ void *buf = (void *)addr;
133133+ int err;
134134+135135+ /* First try to read LDFW from EFI partition, then from the raw one */
136136+ err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf);
137137+ if (err)
138138+ return read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
139139+140140+ return 0;
141141+}
142142+143143+/**
144144+ * init_ldfw - Provide the LDFW (loaded to RAM) to EL3 monitor to make use of it
145145+ * @addr: Memory address where LDFW resides
146146+ *
147147+ * EL3 monitor will copy the LDFW from the provided Normal World memory @addr to
148148+ * Secure World location, and start using it.
149149+ *
150150+ * Return: 0 on success or a negative value on error.
151151+ */
152152+int init_ldfw(phys_addr_t addr)
106153{
107154 struct ldfw_header *hdr;
108155 struct arm_smccc_res res;
109109- void *buf = (void *)addr;
110156 u64 size = 0;
111157 int err, i;
112158113113- /* First try to read LDFW from EFI partition, then from the raw one */
114114- err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf);
115115- if (err) {
116116- err = read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf);
117117- if (err)
118118- return err;
119119- }
120120-121159 /* Validate LDFW by magic number in its header */
122122- hdr = buf;
160160+ hdr = (struct ldfw_header *)addr;
123161 if (hdr->magic != LDFW_MAGIC) {
124162 debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__);
125163 return -EINVAL;
+9-1
board/samsung/e850-96/fw.h
···991010#include <asm/types.h>
11111212-int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr);
1212+/* Image types for downloading over USB */
1313+enum usb_dn_image {
1414+ USB_DN_IMAGE_LDFW = 1, /* Loadable Firmware */
1515+ USB_DN_IMAGE_SP = 2, /* Secure Payload (tzsw.img) */
1616+};
1717+1818+int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size);
1919+int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr);
2020+int init_ldfw(phys_addr_t addr);
13211422#endif /* __E850_96_FW_H */
···88#include <env.h>
99#include <init.h>
1010#include <net.h>
1111-#include <status_led.h>
1111+#include <led.h>
1212#include <asm/arch/reset_manager.h>
1313#include <asm/global_data.h>
1414#include <asm/io.h>
···2424int board_late_init(void)
2525{
2626 const unsigned int usb_nrst_gpio = 35;
2727+ struct udevice *dev;
2728 int ret;
28292929- status_led_set(1, CONFIG_LED_STATUS_ON);
3030- status_led_set(2, CONFIG_LED_STATUS_ON);
3030+ ret = led_get_by_label("status_1", &dev);
3131+ if (!ret)
3232+ led_set_state(dev, LEDST_ON);
3333+3434+ ret = led_get_by_label("status_2", &dev);
3535+ if (!ret)
3636+ led_set_state(dev, LEDST_ON);
31373238 /* Address of boot parameters for ATAG (if ATAG is used) */
3339 gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100;
+1-1
board/ti/am335x/board.c
···429429{
430430 int sil_rev, mpu_vdd;
431431432432- if (!IS_ENABLED(CONFIG_DM_PMIC_TPS65910))
432432+ if (!IS_ENABLED(CONFIG_SPL_POWER_TPS65910))
433433 return;
434434435435 /*
···2727#include <fdtdec.h>
2828#include <version.h>
2929#include <video.h>
3030+#include <smbios.h>
30313132DECLARE_GLOBAL_DATA_PTR;
3233···333334 int nodeoffset;
334335 int err;
335336 const char *str; /* used to set string properties */
337337+ ulong smbiosaddr; /* SMBIOS table address */
336338337339 err = fdt_check_header(fdt);
338340 if (err < 0) {
···385387 printf("WARNING: could not set u-boot,version %s.\n",
386388 fdt_strerror(err));
387389 return err;
390390+ }
391391+392392+ if (CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)) {
393393+ /* Inject SMBIOS address when we have a valid address.
394394+ * This is useful for systems using booti/bootm instead of bootefi.
395395+ * Failure to set this property is non-fatal, we only generate a
396396+ * warning.
397397+ */
398398+ smbiosaddr = gd_smbios_start();
399399+ if (smbiosaddr) {
400400+ err = fdt_setprop_u64(fdt, nodeoffset, "smbios3-entrypoint",
401401+ smbiosaddr);
402402+ if (err < 0) {
403403+ printf("WARNING: could not set smbios3-entrypoint %s.\n",
404404+ fdt_strerror(err));
405405+ }
406406+ }
388407 }
389408390409 return fdt_fixup_stdout(fdt, nodeoffset);
+4
cmd/extension_board.c
···9999 int i = 0;
100100101101 extension_list = extension_get_list();
102102+ if (!extension_list) {
103103+ printf("No extension device\n");
104104+ return CMD_RET_FAILURE;
105105+ }
102106 if (!alist_get_ptr(extension_list, 0)) {
103107 printf("No extension registered - Please run \"extension scan\"\n");
104108 return CMD_RET_SUCCESS;
···11+#include <configs/renesas_rcar64.config>
22+33+CONFIG_ARCH_CPU_INIT=y
44+CONFIG_SYS_LOAD_ADDR=0x9E600000
55+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
66+CONFIG_USE_BOOTARGS=y
77+CONFIG_USE_BOOTCOMMAND=y
88+99+CONFIG_BOOTARGS="root=/dev/nfs rw nfsroot=192.168.0.1:/export/rfs ip=192.168.0.20"
1010+CONFIG_CMD_MMC=y
1111+CONFIG_DM_ETH_PHY=y
1212+# CONFIG_MMC_HS200_SUPPORT is not set
1313+# CONFIG_MMC_IO_VOLTAGE is not set
1414+# CONFIG_MMC_UHS_SUPPORT is not set
1515+CONFIG_PHY_R8A78000_ETHERNET_PCS=y
1616+CONFIG_PHY_R8A78000_MP_PHY=y
1717+CONFIG_PHY_TI_DP83869=y
1818+# CONFIG_PSCI_RESET is not set
1919+CONFIG_RENESAS_ETHER_SWITCH=y
2020+CONFIG_RENESAS_SDHI=y
2121+CONFIG_SPI_FLASH_SPANSION=y
2222+# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
2323+CONFIG_SYS_I2C_RCAR_I2C=y
+2
configs/socfpga_agilex5_defconfig
···7070# CONFIG_ISO_PARTITION is not set
7171# CONFIG_EFI_PARTITION is not set
7272CONFIG_OF_LIST=""
7373+CONFIG_ENV_IS_IN_FAT=y
7374CONFIG_ENV_IS_IN_UBI=y
7575+CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
7476CONFIG_ENV_UBI_PART="root"
7577CONFIG_ENV_UBI_VOLUME="env"
7678CONFIG_ENV_RELOC_GD_ENV_ADDR=y
+5-3
configs/socfpga_cyclone5_defconfig
···1212CONFIG_SPL_STACK=0x0
1313CONFIG_SPL_TEXT_BASE=0xFFFF0000
1414CONFIG_TARGET_SOCFPGA_CYCLONE5_SOCDK=y
1515+CONFIG_SPL_FS_FAT=y
1616+# CONFIG_SPL_SPI is not set
1517CONFIG_TIMESTAMP=y
1618CONFIG_FIT=y
1719CONFIG_DISTRO_DEFAULTS=y
1818-# CONFIG_USE_BOOTCOMMAND is not set
2020+CONFIG_BOOTCOMMAND="run fatscript;bridge enable; run distro_bootcmd"
1921CONFIG_DEFAULT_FDT_FILE="socfpga_cyclone5_socdk.dtb"
2022CONFIG_SYS_CONSOLE_IS_IN_ENV=y
2123CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE=y
···2729CONFIG_SPL_NO_BSS_LIMIT=y
2830# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
2931CONFIG_SPL_HAVE_INIT_STACK=y
3030-CONFIG_SPL_SPI_LOAD=y
3131-CONFIG_SYS_SPI_U_BOOT_OFFS=0x40000
3232+# CONFIG_SPL_SYS_MMCSD_RAW_MODE is not set
3233CONFIG_SYS_MAXARGS=32
3334CONFIG_CMD_ASKENV=y
3435CONFIG_CMD_GREPENV=y
···7980CONFIG_USB_GADGET_DOWNLOAD=y
8081# CONFIG_SPL_WDT is not set
8182CONFIG_SYS_TIMER_COUNTS_DOWN=y
8383+# CONFIG_TOOLS_MKEFICAPSULE is not set
···11+.. SPDX-License-Identifier: GPL-2.0+
22+.. sectionauthor:: Kaustabh Chakraborty <kauschluss@disroot.org>
33+44+Samsung Exynos Generic ARMv8 Boards (for mobile devices)
55+========================================================
66+77+Overview
88+--------
99+This document describes how to build and run U-Boot for Samsung Exynos generic
1010+boards. Boards are expected to boot with a primary bootloader, such as S-BOOT or
1111+S-LK, which hands off control to U-Boot. Presently, only ARMv8 devices are
1212+supported.
1313+1414+The U-Boot image is built with all device tree blobs packed in a single FIT
1515+image. During boot, it uses simple heuristics to detect the target board, and
1616+subsequently the appropriate FDT is selected.
1717+1818+Installation
1919+------------
2020+Building
2121+^^^^^^^^
2222+If a cross-compiler is required, install it and set it up like so:
2323+2424+.. prompt:: bash $
2525+2626+ export CROSS_COMPILE=aarch64-linux-gnu-
2727+2828+Then, run the following commands to build U-Boot:
2929+3030+.. prompt:: bash $
3131+3232+ make O=.output exynos-mobile_defconfig
3333+ make O=.output -j$(nproc)
3434+3535+If successful, the U-Boot binary will be present in ``.output/u-boot.bin``.
3636+3737+Preparation and Flashing
3838+^^^^^^^^^^^^^^^^^^^^^^^^
3939+Since U-Boot supports multiple boards, and devices have different requirements,
4040+this step will vary depending on your target.
4141+4242+.. toctree::
4343+ :maxdepth: 1
4444+4545+ exynos-mobile/exynos7870
+85
doc/board/samsung/exynos-mobile/exynos7870.rst
···11+.. SPDX-License-Identifier: GPL-2.0+
22+.. sectionauthor:: Kaustabh Chakraborty <kauschluss@disroot.org>
33+44+Samsung Exynos 7870 Boards
55+==========================
66+77+Preparation
88+-----------
99+Create the following device tree (named ``stub.dts``)
1010+1111+.. code-block:: devicetree
1212+1313+ /dts-v1/;
1414+1515+ / {
1616+ compatible = "samsung,exynos7870";
1717+ #address-cells = <2>;
1818+ #size-cells = <1>;
1919+2020+ model_info-chip = <7870>;
2121+ model_info-hw_rev = <0>;
2222+ model_info-hw_rev_end = <255>;
2323+2424+ chosen {
2525+ };
2626+2727+ memory@80000000 {
2828+ device_type = "memory";
2929+ reg = <0x0 0x80000000 0x0>;
3030+ };
3131+3232+ memory@100000000 {
3333+ device_type = "memory";
3434+ reg = <0x1 0x00000000 0x0>;
3535+ };
3636+ };
3737+3838+The chosen node and memory ranges are populated by S-BOOT. A certain device
3939+model may have multiple variants, with differing amounts of RAM and storage. The
4040+RAM capacity information is graciously provided by S-BOOT's device tree
4141+overlays.
4242+4343+Compile it to a device tree blob, then pack it in the QCDT format [1]_ using
4444+``dtbTool-exynos`` [2]_ by issuing the following commands:
4545+4646+.. prompt:: bash $
4747+4848+ dtc -I dts -O dtb -o stub.dtb stub.dts
4949+ dtbTool-exynos -o stub-dt.img stub.dtb
5050+5151+Finally, use ``mkbootimg`` by osm0sis [3]_ to generate the boot image:
5252+5353+.. prompt:: bash $
5454+5555+ mkbootimg -o u-boot.img \
5656+ --kernel .output/u-boot.bin \
5757+ --dt stub-dt.img
5858+5959+Offsets are not provided to ``mkbootimg`` as S-BOOT ignores them.
6060+6161+Flashing
6262+--------
6363+If flashing for the first time, it must be done via Samsung's Download (Odin)
6464+mode. Heimdall [4]_ can be used for flashing, like so:
6565+6666+.. prompt:: bash $
6767+6868+ heimdall flash --BOOT u-boot.img
6969+7070+However, if U-Boot is already installed, you may also use its fastboot interface
7171+for flashing. Boot into the boot menu by holding the volume down key. Enable
7272+fastboot mode from there, connect the device to your host, then run:
7373+7474+.. prompt:: bash $
7575+7676+ fastboot flash boot u-boot.img
7777+7878+To flash an OS image in internal storage, fastboot is a reliable option.
7979+8080+References
8181+----------
8282+.. [1] https://wiki.postmarketos.org/wiki/QCDT
8383+.. [2] https://github.com/dsankouski/dtbtool-exynos
8484+.. [3] https://github.com/osm0sis/mkbootimg
8585+.. [4] https://git.sr.ht/~grimler/Heimdall
···125125Boot
126126----
127127128128-Output:
128128+Output::
129129130130-.. code-block:: console
130130+ U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100)
131131+ SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
132132+ Changed A53 CPU frequency to 1250000000Hz (U grade) in DT
133133+ SPL initial stack usage: 17080 bytes
134134+ Trying to boot from MMC1
135135+ Authentication passed
136136+ Authentication passed
137137+ Authentication passed
138138+ Loading Environment from nowhere... OK
139139+ init_env from device 9 not supported!
140140+ Authentication passed
141141+ Authentication passed
142142+ Starting ATF on ARM64 core...
131143132132-U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:46:57 +0100)
133133-SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
134134-Changed A53 CPU frequency to 1250000000Hz (U grade) in DT
135135-SPL initial stack usage: 17080 bytes
136136-Trying to boot from MMC1
137137-Authentication passed
138138-Authentication passed
139139-Authentication passed
140140-Loading Environment from nowhere... OK
141141-init_env from device 9 not supported!
142142-Authentication passed
143143-Authentication passed
144144-Starting ATF on ARM64 core...
144144+ NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096
145145+ NOTICE: BL31: Built : 10:57:58, May 9 2025
146146+ I/TC:
147147+ I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64
148148+ I/TC: WARNING: This OP-TEE configuration might be insecure!
149149+ I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
150150+ I/TC: Primary CPU initializing
151151+ I/TC: GIC redistributor base address not provided
152152+ I/TC: Assuming default GIC group status and modifier
153153+ I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
154154+ I/TC: Activated SA2UL device
155155+ I/TC: Enabled firewalls for SA2UL TRNG device
156156+ I/TC: SA2UL TRNG initialized
157157+ I/TC: SA2UL Drivers initialized
158158+ I/TC: HUK Initialized
159159+ I/TC: Primary CPU switching to normal world boot
145160146146-NOTICE: BL31: v2.12.0(release):v2.12.0-1106-g4301798db096
147147-NOTICE: BL31: Built : 10:57:58, May 9 2025
148148-I/TC:
149149-I/TC: OP-TEE version: 4.6.0-18-g76d920d354df (gcc version 12.3.1 20230626 (Arm GNU Toolchain 12.3.Rel1 (Build arm-12.35))) #4 Tue May 6 19:48:13 UTC 2025 aarch64
150150-I/TC: WARNING: This OP-TEE configuration might be insecure!
151151-I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
152152-I/TC: Primary CPU initializing
153153-I/TC: GIC redistributor base address not provided
154154-I/TC: Assuming default GIC group status and modifier
155155-I/TC: SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
156156-I/TC: Activated SA2UL device
157157-I/TC: Enabled firewalls for SA2UL TRNG device
158158-I/TC: SA2UL TRNG initialized
159159-I/TC: SA2UL Drivers initialized
160160-I/TC: HUK Initialized
161161-I/TC: Primary CPU switching to normal world boot
161161+ U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
162162+ SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
163163+ SPL initial stack usage: 1760 bytes
164164+ HW CFG: 0x00
165165+ Trying to boot from MMC1
166166+ Authentication passed
167167+ Authentication passed
162168163163-U-Boot SPL 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
164164-SYSFW ABI: 4.0 (firmware rev 0x000b '11.0.7--v11.00.07 (Fancy Rat)')
165165-SPL initial stack usage: 1760 bytes
166166-HW CFG: 0x00
167167-Trying to boot from MMC1
168168-Authentication passed
169169-Authentication passed
170169171171-172172-U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
173173-174174-SoC: AM62PX SR1.0 HS-FS
175175-DRAM: 2 GiB
176176-Core: 147 devices, 31 uclasses, devicetree: separate
177177-MMC: mmc@fa10000: 0, mmc@fa00000: 1
178178-Loading Environment from MMC... Reading from MMC(0)... OK
179179-In: serial@2800000
180180-Out: serial@2800000
181181-Err: serial@2800000
182182-Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A
183183-Serial#: 15664919
184184-Carrier: Toradex Dahlia V1.1D, Serial# 11287149
185185-am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2
186186-Setting variant to wifi
187187-Net:
188188-Warning: ethernet@8000000port@1 MAC addresses don't match:
189189-Address in ROM is 58:a1:5f:b8:93:f9
190190-Address in environment is 00:14:2d:ef:07:17
191191-eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7
192192-am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed
170170+ U-Boot 2025.04-00006-g51dc98d36470 (May 12 2025 - 15:47:54 +0100)
171171+172172+ SoC: AM62PX SR1.0 HS-FS
173173+ DRAM: 2 GiB
174174+ Core: 147 devices, 31 uclasses, devicetree: separate
175175+ MMC: mmc@fa10000: 0, mmc@fa00000: 1
176176+ Loading Environment from MMC... Reading from MMC(0)... OK
177177+ In: serial@2800000
178178+ Out: serial@2800000
179179+ Err: serial@2800000
180180+ Model: Toradex 0099 Verdin AM62P Quad 2GB WB IT V1.0A
181181+ Serial#: 15664919
182182+ Carrier: Toradex Dahlia V1.1D, Serial# 11287149
183183+ am65_cpsw_nuss ethernet@8000000: K3 CPSW: nuss_ver: 0x6BA01903 cpsw_ver: 0x6BA81903 ale_ver: 0x00290105 Ports:2
184184+ Setting variant to wifi
185185+ Net:
186186+ Warning: ethernet@8000000port@1 MAC addresses don't match:
187187+ Address in ROM is 58:a1:5f:b8:93:f9
188188+ Address in environment is 00:14:2d:ef:07:17
189189+ eth0: ethernet@8000000port@1 [PRIME]Could not get PHY for mdio@f00: addr 7
190190+ am65_cpsw_nuss_port ethernet@8000000port@2: phy_connect() failed
193191194194-Hit any key to stop autoboot: 0
195195-Verdin AM62P #
196196-192192+ Hit any key to stop autoboot: 0
193193+ Verdin AM62P #
+9-7
doc/develop/pytest/usage.rst
···315315316316The following environment variables are set when running hook scripts:
317317318318-- ``UBOOT_BOARD_TYPE`` the board type being tested.
319319-- ``UBOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none
318318+- ``U_BOOT_BOARD_TYPE`` the board type being tested.
319319+- ``U_BOOT_BOARD_TYPE_EXTRA`` the 2nd board type being tested, if applicable.
320320+- ``U_BOOT_BOARD_IDENTITY`` the board identity being tested, or ``na`` if none
320321 was specified.
321321-- ``UBOOT_SOURCE_DIR`` the U-Boot source directory.
322322-- ``UBOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory.
323323-- ``UBOOT_BUILD_DIR`` the U-Boot build directory.
324324-- ``UBOOT_RESULT_DIR`` the test result directory.
325325-- ``UBOOT_PERSISTENT_DATA_DIR`` the test persistent data directory.
322322+- ``U_BOOT_SOURCE_DIR`` the U-Boot source directory.
323323+- ``U_BOOT_TEST_PY_DIR`` the full path to ``test/py/`` in the source directory.
324324+- ``U_BOOT_BUILD_DIR`` the U-Boot build directory.
325325+- ``U_BOOT_BUILD_DIR_EXTRA`` the 2nd U-Boot build directory, if applicable.
326326+- ``U_BOOT_RESULT_DIR`` the test result directory.
327327+- ``U_BOOT_PERSISTENT_DATA_DIR`` the test persistent data directory.
326328327329u-boot-test-console
328330'''''''''''''''''''
+1-1
doc/develop/release_cycle.rst
···77777878* U-Boot |next_ver|-rc3 was released on Mon 24 November 2025.
79798080-.. * U-Boot |next_ver|-rc4 was released on Mon 08 December 2025.
8080+* U-Boot |next_ver|-rc4 was released on Mon 08 December 2025.
81818282.. * U-Boot |next_ver|-rc5 was released on Tue 22 December 2025.
8383
+1
doc/learn/index.rst
···66.. toctree::
77 :maxdepth: 1
8899+ logo
910 talks
+20
doc/learn/logo.rst
···11+.. SPDX-License-Identifier: GPL-2.0-or-later
22+33+U-Boot logo
44+===========
55+66+The project uses the logos below.
77+88+Logo with text
99+--------------
1010+1111+.. image:: ../../tools/logos/u-boot_logo_with_text.svg
1212+ :width: 10em
1313+ :alt: U-Boot logo with text
1414+1515+Logo without text
1616+-----------------
1717+1818+.. image:: ../../tools/logos/u-boot_logo.svg
1919+ :width: 10em
2020+ :alt: U-Boot logo without text
···594594 if (!clk_valid(clk))
595595 return 0;
596596 ops = clk_dev_ops(clk->dev);
597597+ clk_get_priv(clk, &clkp);
597598598599 /* Try to find parents which can set rate */
599600 while (!ops->set_rate) {
600601 struct clk *parent;
601602602602- if (!(clk->flags & CLK_SET_RATE_PARENT))
603603+ if (!(clkp->flags & CLK_SET_RATE_PARENT))
603604 return -ENOSYS;
604605605606 parent = clk_get_parent(clk);
···608609609610 clk = parent;
610611 ops = clk_dev_ops(clk->dev);
612612+ clk_get_priv(clk, &clkp);
611613 }
612614613613- /* get private clock struct used for cache */
614614- clk_get_priv(clk, &clkp);
615615 /* Clean up cached rates for us and all child clocks */
616616 clk_clean_rate_cache(clkp);
617617
+7
drivers/clk/exynos/Kconfig
···1515 This enables common clock driver support for platforms based
1616 on Samsung Exynos7420 SoC.
17171818+config CLK_EXYNOS7870
1919+ bool "Clock driver for Samsung's Exynos7870 SoC"
2020+ select CLK_CCF
2121+ help
2222+ This enables common clock driver support for platforms based
2323+ on Samsung Exynos7870 SoC.
2424+1825config CLK_EXYNOS850
1926 bool "Clock driver for Samsung's Exynos850 SoC"
2027 select CLK_CCF
···99#ifndef __EXYNOS_CLK_H
1010#define __EXYNOS_CLK_H
11111212+#include <clk.h>
1213#include <errno.h>
1314#include <linux/clk-provider.h>
1415#include "clk-pll.h"
1616+1717+int samsung_clk_request(struct clk *clk);
15181619#define _SAMSUNG_CLK_OPS(_name, _cmu) \
1720static int _name##_of_xlate(struct clk *clk, \
···3740 .enable = ccf_clk_enable, \
3841 .disable = ccf_clk_disable, \
3942 .of_xlate = _name##_of_xlate, \
4343+ .request = samsung_clk_request, \
4044}
41454246/**
···5761 * Keeps a range of 256 available clocks for every CMU.
5862 */
5963#define SAMSUNG_TO_CLK_ID(_cmu, _id) (((_cmu) << 8) | ((_id) & 0xff))
6464+6565+/**
6666+ * struct samsung_fixed_rate_clock - information about fixed-rate clock
6767+ * @id: platform specific id of the clock
6868+ * @name: name of this fixed-rate clock
6969+ * @fixed_rate: fixed clock rate of this clock
7070+ */
7171+struct samsung_fixed_rate_clock {
7272+ unsigned int id;
7373+ const char *name;
7474+ unsigned long fixed_rate;
7575+};
7676+7777+#define FRATE(_id, cname, frate) \
7878+ { \
7979+ .id = _id, \
8080+ .name = cname, \
8181+ .fixed_rate = frate, \
8282+ }
8383+8484+/**
8585+ * struct samsung_fixed_factor_clock - information about fixed-factor clock
8686+ * @id: platform specific id of the clock
8787+ * @name: name of this fixed-factor clock
8888+ * @parent_name: parent clock name
8989+ * @mult: fixed multiplication factor
9090+ * @div: fixed division factor
9191+ * @flags: optional fixed-factor clock flags
9292+ */
9393+struct samsung_fixed_factor_clock {
9494+ unsigned int id;
9595+ const char *name;
9696+ const char *parent_name;
9797+ unsigned long mult;
9898+ unsigned long div;
9999+ unsigned long flags;
100100+};
101101+102102+#define FFACTOR(_id, cname, pname, m, d, f) \
103103+ { \
104104+ .id = _id, \
105105+ .name = cname, \
106106+ .parent_name = pname, \
107107+ .mult = m, \
108108+ .div = d, \
109109+ .flags = f, \
110110+ }
6011161112/**
62113 * struct samsung_mux_clock - information about mux clock
···206257 }
207258208259enum samsung_clock_type {
260260+ S_CLK_FRATE,
261261+ S_CLK_FFACTOR,
209262 S_CLK_MUX,
210263 S_CLK_DIV,
211264 S_CLK_GATE,
+4
drivers/clk/renesas/Makefile
···2626obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
2727obj-$(CONFIG_CLK_RZG2L) += rzg2l-cpg.o
2828obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
2929+3030+# Temporary stub clock used for SCP compatibility.
3131+# This is going to be removed once SCP solidifies.
3232+obj-$(CONFIG_R8A78000) += compound-clock.o
···154154 help
155155 Support for the Designware APB GPIO driver.
156156157157+config SPL_DWAPB_GPIO
158158+ bool "DWAPB GPIO driver in SPL"
159159+ depends on SPL_DM_GPIO
160160+ help
161161+ Support for the Designware APB GPIO driver in SPL.
162162+163163+ If unsure, say N.
164164+157165config AT91_GPIO
158166 bool "AT91 PIO GPIO driver"
159167 depends on ARCH_AT91
···6666 Select this driver if your platform has support for this hardware
6767 block.
68686969+config RCAR_MFIS_MBOX
7070+ bool "Renesas MFIS Multifunctional Interface mailbox driver"
7171+ depends on DM_MAILBOX && ARCH_RENESAS
7272+ help
7373+ This enables support for the Renesas MFIS mailbox module, which
7474+ provides an interface between the different CPU Cores, such as AP
7575+ System Core domain and the Realtime Core domain, SCP Core domain
7676+ and AP System Core domain or Realtime Core domain and AP System
7777+ Core domain or Realtime Core domain.
7878+6979config ZYNQMP_IPI
7080 bool "Xilinx ZynqMP IPI controller support"
7181 depends on DM_MAILBOX && (ARCH_ZYNQMP || ARCH_VERSAL || ARCH_VERSAL_NET || ARCH_VERSAL2)
···180180 This option is used to enable Versal OSPI DMA operations which
181181 are used for ospi flash read using cadence qspi controller.
182182183183+config CADENCE_XSPI
184184+ bool "Cadence XSPI driver (Experimental feature)"
185185+ help
186186+ Important: this feature is experimental so far and tested only
187187+ on simulated environment.
188188+189189+ Enable the Cadence eXpanded Serial Periheral Interface (xSPI) flash
190190+ driver. This driver can be used to access the SPI NOR flash on
191191+ platforms embedding this Cadence IP core up to 8 bit wide bus.
192192+ xSPI flash controller IP offers three work mode, Auto Command (ACMD)
193193+ work mode, Software Triggered Instruction Generator (STIG) work mode
194194+ and Direct work mode. This flash controller able to coomunicate
195195+ with Flash Memory Devices supporting JESD216 and JESD251 stadards
196196+ by using the Auto Command work mode.
197197+183198config CF_SPI
184199 bool "ColdFire SPI driver"
185200 depends on M68K
···271271272272config USB_EHCI_PCI
273273 bool "Support for PCI-based EHCI USB controller"
274274+ depends on PCI
274275 default y if X86
275276 help
276277 Enables support for the PCI-based EHCI controller.
···3939/* Boot modes are selectable and should be defined in the board env before including */
4040#if defined(USE_NFS)
4141// rootpath is set by CONFIG_ROOTPATH
4242-nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}${rootpath},tcp,nfsvers=3 ${adi_bootargs}
4242+nfsargs=setenv bootargs root=/dev/nfs rw nfsroot=${serverip}:${rootpath},tcp,nfsvers=3 ${adi_bootargs}
4343nfsboot=run init_ethernet;
4444 tftp ${loadaddr} ${tftp_dir_prefix}${imagefile};
4545 run nfsargs;
+7-27
lib/efi_loader/efi_capsule.c
···857857 struct efi_device_path *file_dp;
858858 efi_status_t ret;
859859860860- size = 0;
861861- ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
862862- NULL, &size, NULL, NULL);
863863- if (ret == EFI_BUFFER_TOO_SMALL) {
864864- buf = malloc(size);
865865- if (!buf)
866866- return EFI_OUT_OF_RESOURCES;
867867- ret = efi_get_variable_int(boot_var, &efi_global_variable_guid,
868868- NULL, &size, buf, NULL);
869869- }
870870- if (ret != EFI_SUCCESS)
871871- return ret;
860860+ buf = efi_get_var(boot_var, &efi_global_variable_guid, &size);
861861+ if (!buf)
862862+ return EFI_NOT_FOUND;
872863873864 efi_deserialize_load_option(&lo, buf, &size);
874865···960951961952skip:
962953 /* find active boot device in BootOrder */
963963- size = 0;
964964- ret = efi_get_variable_int(u"BootOrder", &efi_global_variable_guid,
965965- NULL, &size, NULL, NULL);
966966- if (ret == EFI_BUFFER_TOO_SMALL) {
967967- boot_order = malloc(size);
968968- if (!boot_order) {
969969- ret = EFI_OUT_OF_RESOURCES;
970970- goto out;
971971- }
972972-973973- ret = efi_get_variable_int(u"BootOrder",
974974- &efi_global_variable_guid,
975975- NULL, &size, boot_order, NULL);
954954+ boot_order = efi_get_var(u"BootOrder", &efi_global_variable_guid, &size);
955955+ if (!boot_order) {
956956+ ret = EFI_NOT_FOUND;
957957+ goto out;
976958 }
977977- if (ret != EFI_SUCCESS)
978978- goto out;
979959980960 /* check in higher order */
981961 num = size / sizeof(u16);
···11-// SPDX-License-Identifier: GPL-2.1+
11+// SPDX-License-Identifier: GPL-2.0+
22/*
33 * Copyright (C) 2021 Sean Anderson <seanga2@gmail.com>
44 * Copyright (C) 2011-2021 Free Software Foundation, Inc.
+3-2
tools/binman/control.py
···99import glob
1010try:
1111 import importlib.resources as importlib_resources
1212-except ImportError: # pragma: no cover
1313- # for Python 3.6
1212+ # for Python 3.6, 3.7 and 3.8
1313+ importlib_resources.files
1414+except (ImportError, AttributeError): # pragma: no cover
1415 import importlib_resources
1516import os
1617import re
+100
tools/cv_bsp_generator/cv_bsp_generator.py
···11+#! /usr/bin/env python
22+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
33+"""
44+Bsp preloader header file generator
55+66+Process the handoff files from Quartus and convert them to headers
77+usable by U-Boot. Includes the qts filter.sh capability to generate
88+correct format for headers to be used for mainline Uboot on FPGA,
99+namely Cyclone V & Arria V.
1010+1111+Copyright (C) 2022 Intel Corporation <www.intel.com>
1212+1313+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1414+"""
1515+import glob
1616+import optparse
1717+import os
1818+import shutil
1919+import emif
2020+import hps
2121+import iocsr
2222+import renderer
2323+import model
2424+import collections
2525+import sys
2626+2727+def printUsage():
2828+ """ usage string """
2929+ print ("Usage:\n\t%s\n" % ("sys.argv[0], --input_dir=<path to iswinfo directory> --output_dir=<path store output files>"))
3030+ exit(1)
3131+3232+def verifyInputDir(dir):
3333+ """ check if the input directory exists """
3434+ if not os.path.isdir(dir):
3535+ print ("There is no such directory '%s'!\n" % (dir))
3636+ exit(1)
3737+3838+def verifyOutputDir(dir):
3939+ """ check if the output directory exists """
4040+ if not os.path.isdir(dir):
4141+ os.makedirs(dir)
4242+4343+if __name__ == '__main__':
4444+ # Do some rudimentary command line processing until it is proven we need something
4545+ # heavier, such as argparse (preferred, but 2.7+ only) or optparse
4646+4747+ inputDir = '.'
4848+ outputDir = '.'
4949+5050+ progVersion = '%prog 1.0'
5151+ progDesc = 'Generate board-specific files for the preloader'
5252+ optParser = optparse.OptionParser(version=progVersion, description=progDesc)
5353+ optParser.add_option('-i', '--input-dir', action='store', type='string', dest='inputDir', default='.',
5454+ help='input-dir is usually the iswinfo directory')
5555+ optParser.add_option('-o', '--output-dir', action='store', type='string', dest='outputDir', default='.',
5656+ help='output-dir is usually the directory containing the preloader source')
5757+5858+ (options, args) = optParser.parse_args()
5959+6060+ for arg in args:
6161+ print ("***WARNING: I don't understand '%s', so I am ignoring it\n" % (arg))
6262+6363+ inputDir = options.inputDir
6464+ verifyInputDir(inputDir)
6565+ outputDir = options.outputDir
6666+6767+ verifyOutputDir(outputDir)
6868+6969+ emif = emif.EMIFGrokker(inputDir, outputDir, 'emif.xml')
7070+ hps = hps.HPSGrokker(inputDir, outputDir)
7171+7272+ pllConfigH = outputDir + "/" + "pll_config.h"
7373+ print ("Generating file: " + pllConfigH)
7474+ hpsModel = model.hps.create(inputDir + "/" + "hps.xml")
7575+ emifModel = model.emif.create(inputDir +"/" + "emif.xml")
7676+7777+ content=str(renderer.pll_config_h(hpsModel, emifModel))
7878+ f = open(pllConfigH, "w")
7979+ f.write(content)
8080+ f.close()
8181+8282+ # For all the .hiof files, make a iocsr_config.[h|c]
8383+ # Only support single hiof file currently
8484+ hiof_list = glob.glob(inputDir + os.sep + "*.hiof")
8585+ if len(hiof_list) < 1:
8686+ print ("***Error: No .hiof files found in input!")
8787+8888+ elif len(hiof_list) > 1:
8989+ print ("***Error: We don't handle more than one .hiof file yet")
9090+ print (" Only the last .hiof file in the list will be converted")
9191+ print (" hiof files found:")
9292+ for f in hiof_list:
9393+ print (" " + f)
9494+9595+ for hiof_file_path in hiof_list:
9696+ hiof_file = os.path.basename(hiof_file_path)
9797+ # Avoid IOCSRGrokker having to parse hps.xml to determine
9898+ # device family for output file name, instead we'll just
9999+ # get it from HPSGrokker
100100+ iocsr = iocsr.IOCSRGrokker(hps.getDeviceFamily(), inputDir, outputDir, hiof_file)
+243
tools/cv_bsp_generator/doc.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+Generic document construction classes.
44+55+These classes are templates for creating documents that are not bound
66+to a specific usage or data model.
77+88+Copyright (C) 2022 Intel Corporation <www.intel.com>
99+1010+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1111+"""
1212+1313+class document(object):
1414+ """
1515+ An abstract document class which does not dictate
1616+ how a document should be constructed or manipulated.
1717+1818+ It's sole purpose is to describe the entire document
1919+ in smaller units
2020+ """
2121+2222+ class entry(object):
2323+ """
2424+ An entry is the smallest unit
2525+ """
2626+2727+ def __init__(self, parent):
2828+ """ entry initialization """
2929+ if parent != None:
3030+ parent.add(self)
3131+3232+ class block(entry):
3333+ """
3434+ A block is the smallest collection unit
3535+ consists of entries and blocks.
3636+ """
3737+3838+ def __init__(self, parent):
3939+ """ block initialization """
4040+ super(document.block, self).__init__(parent)
4141+ self.entries = []
4242+4343+ def add(self, entry):
4444+ """ add entry to block """
4545+ self.entries.append(entry)
4646+4747+4848+ def __init__(self):
4949+ """ document initialization """
5050+ self.entries = []
5151+5252+ def add(self, entry):
5353+ """ add entry to entry list """
5454+ self.entries.append(entry)
5555+5656+5757+class text(document):
5858+ """
5959+ A simple text document implementation
6060+ """
6161+6262+ class string(document.entry):
6363+ """
6464+ The smallest unit of a text file is a string
6565+ """
6666+6767+ def __init__(self, parent, stringString=None):
6868+ """ string initialization """
6969+ super(text.string, self).__init__(parent)
7070+ self.stringString = stringString
7171+7272+ def __str__(self):
7373+ """ convert None to empty string """
7474+ if (self.stringString != None):
7575+ return self.stringString
7676+ else:
7777+ return ""
7878+7979+8080+ class line(string):
8181+ """
8282+ A line is a string with EOL character
8383+ """
8484+8585+ def __str__(self):
8686+ """ convert string with newline """
8787+ return super(text.line, self).__str__() + "\n"
8888+8989+ class block(document.block):
9090+ """
9191+ A block of text which can be made up of
9292+ strings or lines
9393+ """
9494+9595+ def __str__(self):
9696+ """ concatenate strings or lines """
9797+ blockString = ""
9898+9999+ for entry in self.entries:
100100+ blockString += str(entry)
101101+102102+ return blockString
103103+104104+105105+ def __str__(self):
106106+ """ concatenate strings or lines """
107107+ textString = ""
108108+109109+ for entry in self.entries:
110110+ textString += str(entry)
111111+112112+ return textString
113113+114114+115115+class c_source(text):
116116+ """
117117+ A simple C header document implementation
118118+ """
119119+120120+ class define(text.string):
121121+ """
122122+ C header define
123123+ """
124124+125125+ def __init__(self, parent, id, token=None):
126126+ """ c header constructor initialization """
127127+ super(c_source.define, self).__init__(parent, id)
128128+ self.token = token
129129+130130+ def __str__(self):
131131+ """ c header to strings """
132132+ defineString = "#define" + " " + super(c_source.define, self).__str__()
133133+134134+ if self.token != None:
135135+ defineString += " " + self.token
136136+137137+ defineString += "\n"
138138+139139+ return defineString
140140+141141+ class comment_string(text.string):
142142+ """
143143+ C header comment
144144+ """
145145+146146+ def __str__(self):
147147+ """ c comment """
148148+ return "/*" + " " + super(c_source.comment_string, self).__str__() + " " + "*/"
149149+150150+ class comment_line(comment_string):
151151+ """
152152+ C header comment with newline
153153+ """
154154+155155+ def __str__(self):
156156+ """ c comment with newline """
157157+ return super(c_source.comment_line, self).__str__() + "\n"
158158+159159+ class block(text.block):
160160+ """
161161+ A simple C block string implementation
162162+ """
163163+164164+ def __init__(self, parent, prologue=None, epilogue=None):
165165+ """ ifdef block string implementation """
166166+ super(c_source.block, self).__init__(parent)
167167+168168+ self.prologue = None
169169+ self.epilogue = None
170170+171171+ if prologue != None:
172172+ self.prologue = prologue
173173+174174+ if epilogue != None:
175175+ self.epilogue = epilogue
176176+177177+ def __str__(self):
178178+ """ convert ifdef to string """
179179+ blockString = ""
180180+181181+ if self.prologue != None:
182182+ blockString += str(self.prologue)
183183+184184+ blockString += super(c_source.block, self).__str__()
185185+186186+ if self.epilogue != None:
187187+ blockString += str(self.epilogue)
188188+189189+ return blockString
190190+191191+ class comment_block(block):
192192+ """
193193+ A simple C header block comment implementation
194194+ """
195195+196196+ def __init__(self, parent, comments):
197197+ """ block comment initialization """
198198+ super(c_source.comment_block, self).__init__(parent, "/*\n", " */\n")
199199+ for comment in comments.split("\n"):
200200+ self.add(comment)
201201+202202+ def add(self, entry):
203203+ """ add line to block comment """
204204+ super(c_source.block, self).add(" * " + entry + "\n")
205205+206206+ class ifndef_block(block):
207207+ """
208208+ A simple C header ifndef implementation
209209+ """
210210+211211+ def __init__(self, parent, id):
212212+ """ ifndef block initialization """
213213+ prologue = text.line(None, "#ifndef" + " " + id)
214214+ epilogue = text.block(None)
215215+ text.string(epilogue, "#endif")
216216+ text.string(epilogue, " ")
217217+ c_source.comment_line(epilogue, id)
218218+ super(c_source.ifndef_block, self).__init__(parent, prologue, epilogue)
219219+220220+221221+class generated_c_source(c_source):
222222+ """
223223+ Caller to generate c format files using the helper classes
224224+ """
225225+226226+ def __init__(self, filename):
227227+ """ Generate c header file with license, copyright, comment,
228228+ ifdef block
229229+ """
230230+ super(generated_c_source, self).__init__()
231231+232232+ self.entries.append(c_source.comment_line(None, "SPDX-License-Identifier: BSD-3-Clause"))
233233+ self.entries.append(c_source.comment_block(None, "Copyright (C) 2022 Intel Corporation <www.intel.com>"))
234234+ self.entries.append(c_source.comment_block(None, "Altera SoCFPGA Clock and PLL configuration"))
235235+ self.entries.append(text.line(None))
236236+237237+ self.body = c_source.ifndef_block(None, filename)
238238+ self.body.add(c_source.define(None, filename))
239239+ self.entries.append(self.body)
240240+241241+ def add(self, entry):
242242+ """ add content to be written into c header file """
243243+ self.body.add(entry)
+424
tools/cv_bsp_generator/emif.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+SDRAM header file generator
44+55+Process the handoff files from Quartus and convert them to headers
66+usable by U-Boot.
77+88+Copyright (C) 2022 Intel Corporation <www.intel.com>
99+1010+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1111+"""
1212+1313+import os
1414+import re
1515+import xml.dom.minidom
1616+import streamer
1717+import xmlgrok
1818+1919+class EMIFGrokker(object):
2020+ """ parse an emif.xml input and translate to various
2121+ outputs
2222+ """
2323+ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
2424+ TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src'
2525+ SDRAM_FILE_HEADER = '/*\n' + ' * Altera SoCFPGA SDRAM configuration\n' + ' *\n' + ' */\n\n'
2626+ SDRAM_SENTINEL = '__SOCFPGA_SDRAM_CONFIG_H__'
2727+ SDRAM_MATCH = r'#define (CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE|CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT|CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN|CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW|CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT|CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES|CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES|CFG_HPS_SDR_CTRLCFG_DRAMODT_READ|CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS|CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS|CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH|CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN|CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK|CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL|CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA|CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH|CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP|CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP|CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP|CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP|CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR|CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN|CFG_HPS_SDR_CTRLCFG_FPGAPORTRST|CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE|CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC|CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14|CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46|CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0|CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32|CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0|CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4|CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32|CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64|RW_MGR_ACTIVATE_0_AND_1|RW_MGR_ACTIVATE_0_AND_1_WAIT1|RW_MGR_ACTIVATE_0_AND_1_WAIT2|RW_MGR_ACTIVATE_1|RW_MGR_CLEAR_DQS_ENABLE|RW_MGR_EMR_OCD_ENABLE|RW_MGR_EMR|RW_MGR_EMR2|RW_MGR_EMR3|RW_MGR_GUARANTEED_READ|RW_MGR_GUARANTEED_READ_CONT|RW_MGR_GUARANTEED_WRITE|RW_MGR_GUARANTEED_WRITE_WAIT0|RW_MGR_GUARANTEED_WRITE_WAIT1|RW_MGR_GUARANTEED_WRITE_WAIT2|RW_MGR_GUARANTEED_WRITE_WAIT3|RW_MGR_IDLE|RW_MGR_IDLE_LOOP1|RW_MGR_IDLE_LOOP2|RW_MGR_INIT_RESET_0_CKE_0|RW_MGR_INIT_RESET_1_CKE_0|RW_MGR_INIT_CKE_0|RW_MGR_LFSR_WR_RD_BANK_0|RW_MGR_LFSR_WR_RD_BANK_0_DATA|RW_MGR_LFSR_WR_RD_BANK_0_DQS|RW_MGR_LFSR_WR_RD_BANK_0_NOP|RW_MGR_LFSR_WR_RD_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_BANK_0_WL_1|RW_MGR_LFSR_WR_RD_DM_BANK_0|RW_MGR_LFSR_WR_RD_DM_BANK_0_DATA|RW_MGR_LFSR_WR_RD_DM_BANK_0_DQS|RW_MGR_LFSR_WR_RD_DM_BANK_0_NOP|RW_MGR_LFSR_WR_RD_DM_BANK_0_WAIT|RW_MGR_LFSR_WR_RD_DM_BANK_0_WL_1|RW_MGR_MR_CALIB|RW_MGR_MR_USER|RW_MGR_MR_DLL_RESET|RW_MGR_MRS0_DLL_RESET|RW_MGR_MRS0_DLL_RESET_MIRR|RW_MGR_MRS0_USER|RW_MGR_MRS0_USER_MIRR|RW_MGR_MRS1|RW_MGR_MRS1_MIRR|RW_MGR_MRS2|RW_MGR_MRS2_MIRR|RW_MGR_MRS3|RW_MGR_MRS3_MIRR|RW_MGR_NOP|RW_MGR_PRECHARGE_ALL|RW_MGR_READ_B2B|RW_MGR_READ_B2B_WAIT1|RW_MGR_READ_B2B_WAIT2|RW_MGR_REFRESH|RW_MGR_REFRESH_ALL|RW_MGR_RETURN|RW_MGR_SGLE_READ|RW_MGR_ZQCL|RW_MGR_TRUE_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_ADDRESS_MIRRORING|RW_MGR_MEM_DATA_MASK_WIDTH|RW_MGR_MEM_DATA_WIDTH|RW_MGR_MEM_DQ_PER_READ_DQS|RW_MGR_MEM_DQ_PER_WRITE_DQS|RW_MGR_MEM_IF_READ_DQS_WIDTH|RW_MGR_MEM_IF_WRITE_DQS_WIDTH|RW_MGR_MEM_NUMBER_OF_CS_PER_DIMM|RW_MGR_MEM_NUMBER_OF_RANKS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_READ_DQS|RW_MGR_MEM_VIRTUAL_GROUPS_PER_WRITE_DQS|IO_DELAY_PER_DCHAIN_TAP|IO_DELAY_PER_DQS_EN_DCHAIN_TAP|IO_DELAY_PER_OPA_TAP|IO_DLL_CHAIN_LENGTH|IO_DQDQS_OUT_PHASE_MAX|IO_DQS_EN_DELAY_MAX|IO_DQS_EN_DELAY_OFFSET|IO_DQS_EN_PHASE_MAX|IO_DQS_IN_DELAY_MAX|IO_DQS_IN_RESERVE|IO_DQS_OUT_RESERVE|IO_IO_IN_DELAY_MAX|IO_IO_OUT1_DELAY_MAX|IO_IO_OUT2_DELAY_MAX|IO_SHIFT_DQS_EN_WHEN_SHIFT_DQS|AFI_RATE_RATIO|AFI_CLK_FREQ|CALIB_LFIFO_OFFSET|CALIB_VFIFO_OFFSET|ENABLE_SUPER_QUICK_CALIBRATION|MAX_LATENCY_COUNT_WIDTH|READ_VALID_FIFO_SIZE|REG_FILE_INIT_SEQ_SIGNATURE|TINIT_CNTR0_VAL|TINIT_CNTR1_VAL|TINIT_CNTR2_VAL|TRESET_CNTR0_VAL|TRESET_CNTR1_VAL|TRESET_CNTR2_VAL|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC|CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP)\s+'
2828+2929+ SDRAM_CONFIG_H_FILENAME = "sdram_config.h"
3030+3131+ sdramHTemplate = ""
3232+ seqAutoTemplate = ""
3333+ seqDefinesTemplate = ""
3434+ seqAutoAcTemplate = ""
3535+ seqAutoInstTemplate = ""
3636+ seqAutoTemplateList = []
3737+ seqDefinesTemplateList = []
3838+ seqAutoAcTemplateList = []
3939+ seqAutoInstTemplateList = []
4040+4141+ def __init__(self, inputDir, outputDir, emifFileName='emif.xml', hpsFileName='hps.xml'):
4242+ """ EMIFGrokker initialization """
4343+ self.inputDir = inputDir
4444+ self.outputDir = outputDir
4545+4646+ sdramDir = self.outputDir
4747+ if not os.path.isdir(sdramDir):
4848+ os.makedirs(sdramDir)
4949+5050+ self.emifFileName = inputDir + os.sep + emifFileName
5151+ self.hpsFileName = inputDir + os.sep + hpsFileName
5252+ self.emifDom = xml.dom.minidom.parse(self.emifFileName)
5353+ self.hpsDom = xml.dom.minidom.parse(self.hpsFileName)
5454+ self.sequencerDefinesStream = None
5555+ self.seqAutoFileName = inputDir + os.sep + "sequencer_auto.h"
5656+ self.seqDefinesFileName = inputDir + os.sep + "sequencer_defines.h"
5757+ self.seqAutoACFileName = inputDir + os.sep + "sequencer_auto_ac_init.c"
5858+ self.seqAutoInstFileName = inputDir + os.sep + "sequencer_auto_inst_init.c"
5959+6060+ self.createFilesFromEMIF()
6161+6262+ def openSeqFiles(self):
6363+ """ files to retrieve values to written to sdram_config.h """
6464+ self.seq_auto_fd = open(self.seqAutoFileName, "r")
6565+ self.seq_defines_fd = open(self.seqDefinesFileName, "r")
6666+ self.seq_auto_ac_fd = open(self.seqAutoACFileName, "r")
6767+ self.seq_auto_inst_fd = open(self.seqAutoInstFileName, "r")
6868+6969+ def closeSeqFiles(self):
7070+ """ close files """
7171+ self.seq_auto_fd.close()
7272+ self.seq_defines_fd.close()
7373+ self.seq_auto_ac_fd.close()
7474+ self.seq_auto_inst_fd.close()
7575+7676+ def processSeqAuto(self):
7777+ """ process sequencer files to retrieve variable. Regex match is from
7878+ qts-filter.sh
7979+ """
8080+ # replace underscore & bracket in sequencer_auto.h define
8181+ for line in self.seq_auto_fd.readlines():
8282+ if re.match(".*__RW_MGR_", line) and not re.match(".*ac_", line) and not re.match(".*CONTENT_", line):
8383+ line = re.sub("__RW_MGR", "RW_MGR", line)
8484+ if re.match(self.SDRAM_MATCH, line):
8585+ self.seqAutoTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line))
8686+ self.seqAutoTemplateList.sort()
8787+ self.seqAutoTemplate = ''.join([item for item in self.seqAutoTemplateList])
8888+8989+ # replace underscore & bracket in sequencer_defines.h define
9090+ for line in self.seq_defines_fd.readlines():
9191+ if re.match("^#define (\w+_)", line):
9292+ line = re.sub("__", "", line)
9393+ if re.match(self.SDRAM_MATCH, line):
9494+ self.seqDefinesTemplateList.append(re.sub(r' (\w+)(\s+)(\d+)', r' \1\t\3', line))
9595+ self.seqDefinesTemplateList.sort()
9696+ self.seqDefinesTemplate = ''.join([item for item in self.seqDefinesTemplateList])
9797+9898+ arrayMatchStart = 0
9999+ # replace const variable declaration in sequencer_auto_ac_init.c
100100+ for line in self.seq_auto_ac_fd.readlines():
101101+ if re.match("^const.*\[", line) or arrayMatchStart:
102102+ if arrayMatchStart == 0:
103103+ line = line.strip() + " "
104104+ arrayMatchStart = 1
105105+ if re.match("};", line):
106106+ arrayMatchStart = 0
107107+ self.seqAutoAcTemplateList.append("};")
108108+ continue
109109+ line = re.sub("alt_u32", "u32", line)
110110+ self.seqAutoAcTemplateList.append(re.sub("\[.*\]", "[]", line))
111111+ self.seqAutoAcTemplate = ''.join([item for item in self.seqAutoAcTemplateList])
112112+113113+ arrayMatchStart = 0
114114+ # replace const variable declaration in sequencer_auto_inst_init.c
115115+ for line in self.seq_auto_inst_fd.readlines():
116116+ if re.match("^const.*\[", line) or arrayMatchStart:
117117+ if arrayMatchStart == 0:
118118+ line = line.strip() + " "
119119+ arrayMatchStart = 1
120120+ if re.match("};", line):
121121+ arrayMatchStart = 0
122122+ self.seqAutoInstTemplateList.append("};")
123123+ continue
124124+ line = re.sub("alt_u32", "u32", line)
125125+ self.seqAutoInstTemplateList.append(re.sub("\[.*\]", "[]", line))
126126+ self.seqAutoInstTemplate = ''.join([item for item in self.seqAutoInstTemplateList])
127127+128128+ def handleSettingNode(self, settingNode):
129129+ """ create define string from variable name and value """
130130+ if settingNode.hasAttribute('name') and settingNode.hasAttribute('value'):
131131+ name = settingNode.getAttribute('name')
132132+ value = settingNode.getAttribute('value')
133133+ self.sequencerDefinesStream.write("#define " + name + ' ' + '(' + value + ')' + '\n')
134134+135135+ def updateTemplate(self, name, value):
136136+ """ update sdram template """
137137+ pattern = "${" + name + "}"
138138+ self.sdramHTemplate = self.sdramHTemplate.replace(pattern, value)
139139+140140+ def handleEMIFControllerNode(self, node):
141141+ """ retrieve values from emif.xml for controller node """
142142+ derivedNoDmPins = 0
143143+ derivedCtrlWidth = 0
144144+ derivedEccEn = 0
145145+ derivedEccCorrEn = 0
146146+147147+ self.mem_if_rd_to_wr_turnaround_oct = 0
148148+149149+ node = xmlgrok.firstElementChild(node)
150150+ while node != None:
151151+ name = node.getAttribute('name')
152152+ value = node.getAttribute('value')
153153+154154+ if value == "true":
155155+ value = "1"
156156+ elif value == "false":
157157+ value = "0"
158158+159159+ self.updateTemplate(name, value)
160160+161161+ if name == "MEM_IF_DM_PINS_EN":
162162+ if value == "1":
163163+ derivedNoDmPins = 0
164164+ else:
165165+ derivedNoDmPins = 1
166166+167167+ if name == "MEM_DQ_WIDTH":
168168+ if value == "8":
169169+ derivedCtrlWidth = 0
170170+ derivedEccEn = 0
171171+ derivedEccCorrEn = 0
172172+ elif value == "16":
173173+ derivedCtrlWidth = 1
174174+ derivedEccEn = 0
175175+ derivedEccCorrEn = 0
176176+ elif value == "24":
177177+ derivedCtrlWidth = 1
178178+ derivedEccEn = 1
179179+ derivedEccCorrEn = 1
180180+ elif value == "32":
181181+ derivedCtrlWidth = 2
182182+ derivedEccEn = 0
183183+ derivedEccCorrEn = 0
184184+ elif value == "40":
185185+ derivedCtrlWidth = 2
186186+ derivedEccEn = 1
187187+ derivedEccCorrEn = 1
188188+189189+ if name == "MEM_IF_RD_TO_WR_TURNAROUND_OCT":
190190+ self.mem_if_rd_to_wr_turnaround_oct = int(value)
191191+192192+ node = xmlgrok.nextElementSibling(node)
193193+194194+ self.updateTemplate("DERIVED_NODMPINS", str(derivedNoDmPins))
195195+ self.updateTemplate("DERIVED_CTRLWIDTH", str(derivedCtrlWidth))
196196+ self.updateTemplate("DERIVED_ECCEN", str(derivedEccEn))
197197+ self.updateTemplate("DERIVED_ECCCORREN", str(derivedEccCorrEn))
198198+199199+ def handleEMIFPllNode(self, node):
200200+ """ retrieve values for pll node """
201201+ node = xmlgrok.firstElementChild(node)
202202+ while node != None:
203203+ name = node.getAttribute('name')
204204+ value = node.getAttribute('value')
205205+206206+ self.updateTemplate(name, value)
207207+208208+ node = xmlgrok.nextElementSibling(node)
209209+210210+ def handleEMIFSequencerNode(self, node):
211211+ """ retrieve values for sequencer node """
212212+ derivedMemtype = 0
213213+ derivedSelfrfshexit = 0
214214+215215+ self.afi_rate_ratio = 0
216216+217217+ node = xmlgrok.firstElementChild(node)
218218+ while node != None:
219219+ name = node.getAttribute('name')
220220+ value = node.getAttribute('value')
221221+222222+ self.updateTemplate(name, value)
223223+224224+ if value.isdigit():
225225+ intValue = int(value)
226226+ else:
227227+ intValue = 0
228228+229229+ if name == "DDR2" and intValue != 0:
230230+ derivedMemtype = 1
231231+ derivedSelfrfshexit = 200
232232+ elif name == "DDR3" and intValue != 0:
233233+ derivedMemtype = 2
234234+ derivedSelfrfshexit = 512
235235+ elif name == "LPDDR1" and intValue != 0:
236236+ derivedMemtype = 3
237237+ derivedSelfrfshexit = 200
238238+ elif name == "LPDDR2" and intValue != 0:
239239+ derivedMemtype = 4
240240+ derivedSelfrfshexit = 200
241241+ elif name == "AFI_RATE_RATIO" and intValue != 0:
242242+ self.afi_rate_ratio = intValue
243243+244244+ node = xmlgrok.nextElementSibling(node)
245245+246246+ self.updateTemplate("DERIVED_MEMTYPE", str(derivedMemtype))
247247+ self.updateTemplate("DERIVED_SELFRFSHEXIT", str(derivedSelfrfshexit))
248248+249249+250250+ def handleHpsFpgaInterfaces(self, node):
251251+ """ retrieve values for fpga interface """
252252+ node = xmlgrok.firstElementChild(node)
253253+254254+ while node != None:
255255+ name = node.getAttribute('name')
256256+ value = node.getAttribute('value')
257257+258258+ self.updateTemplate(name, value)
259259+260260+ node = xmlgrok.nextElementSibling(node)
261261+262262+263263+ def createFilesFromEMIF(self):
264264+ """ create sdram_config.h with the template and value read from xml.
265265+ Different sequencer files are written to individual section, with
266266+ comment at the start.
267267+ """
268268+ self.sdramHTemplate ="""\
269269+#define CFG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR 0x5A56A
270270+#define CFG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP 0xB00088
271271+#define CFG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH 0x44555
272272+#define CFG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP 0x2C011000
273273+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER ${ADDR_ORDER}
274274+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN ${USE_HPS_DQS_TRACKING}
275275+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN ${DERIVED_ECCCORREN}
276276+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN ${DERIVED_ECCEN}
277277+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL ${MEM_BURST_LENGTH}
278278+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE ${DERIVED_MEMTYPE}
279279+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS ${DERIVED_NODMPINS}
280280+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN 1
281281+#define CFG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT 10
282282+#define CFG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH ${DERIVED_CTRLWIDTH}
283283+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS ${MEM_IF_BANKADDR_WIDTH}
284284+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS ${MEM_IF_COL_ADDR_WIDTH}
285285+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS ${DEVICE_DEPTH}
286286+#define CFG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS ${MEM_IF_ROW_ADDR_WIDTH}
287287+#define CFG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH 8
288288+#define CFG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH ${MEM_DQ_WIDTH}
289289+#define CFG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN 0
290290+#define CFG_HPS_SDR_CTRLCFG_DRAMODT_READ ${CFG_READ_ODT_CHIP}
291291+#define CFG_HPS_SDR_CTRLCFG_DRAMODT_WRITE ${CFG_WRITE_ODT_CHIP}
292292+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL 0
293293+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL ${MEM_TCL}
294294+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL ${MEM_WTCL_INT}
295295+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW ${MEM_TFAW}
296296+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC ${MEM_TRFC}
297297+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD ${MEM_TRRD}
298298+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD ${MEM_TRCD}
299299+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI ${MEM_TREFI}
300300+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP ${MEM_TRP}
301301+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR ${MEM_TWR}
302302+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR ${MEM_TWTR}
303303+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD 4
304304+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD ${MEM_TMRD_CK}
305305+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS ${MEM_TRAS}
306306+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC ${MEM_TRC}
307307+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP ${MEM_TRTP}
308308+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT 3
309309+#define CFG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT ${DERIVED_SELFRFSHEXIT}
310310+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR ${DERIVED_CLK_RD_TO_WR}
311311+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_BC ${DERIVED_CLK_RD_TO_WR}
312312+#define CFG_HPS_SDR_CTRLCFG_EXTRATIME1_CFG_EXTRA_CTL_CLK_RD_TO_WR_DIFF_CHIP ${DERIVED_CLK_RD_TO_WR}
313313+#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC 0
314314+#define CFG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE 0
315315+#define CFG_HPS_SDR_CTRLCFG_FPGAPORTRST ${F2SDRAM_RESET_PORT_USED}
316316+#define CFG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK 3
317317+#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES 0
318318+#define CFG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES 8
319319+#define CFG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 0x20820820
320320+#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 0x8208208
321321+#define CFG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 0
322322+#define CFG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 0x41041041
323323+#define CFG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 0x410410
324324+#define CFG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY 0x0
325325+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 0x01010101
326326+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 0x01010101
327327+#define CFG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 0x0101
328328+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 0x21084210
329329+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 0x10441
330330+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 0x78
331331+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 0x0
332332+#define CFG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 0x0
333333+#define CFG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0 0x200
334334+#define CFG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN 0
335335+#define CFG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP 0x760210
336336+#define CFG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL 2
337337+#define CFG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA 0
338338+#define CFG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP 0x980543
339339+"""
340340+341341+ # Get a list of all nodes with the emif element name
342342+ emifNodeList = self.emifDom.getElementsByTagName('emif')
343343+ if len(emifNodeList) > 1:
344344+ print ("*** WARNING:" + "Multiple emif Elements found in %s!" % self.emifFileName)
345345+ # For each of the emif element nodes, go through the child list
346346+ # Note that currently there is only one emif Element
347347+ # but this code will handle more than one emif node
348348+ # In the future, multiple emif nodes may need additional code
349349+ # to combine settings from the multiple emif Elements
350350+ for emifNode in emifNodeList:
351351+ # Currently, there are only 3 children of the emif Element:
352352+ # sequencer, controller, and pll
353353+ # but this is left open-ended for future additions to the
354354+ # specification for the emif.xml
355355+ childNode = xmlgrok.firstElementChild(emifNode)
356356+ while childNode != None:
357357+358358+ if childNode.nodeName == 'controller':
359359+ self.handleEMIFControllerNode(childNode)
360360+ elif childNode.nodeName == 'sequencer':
361361+ self.handleEMIFSequencerNode(childNode)
362362+ elif childNode.nodeName == 'pll':
363363+ self.handleEMIFPllNode(childNode)
364364+365365+ childNode = xmlgrok.nextElementSibling(childNode)
366366+367367+ data_rate_ratio = 2
368368+ dwidth_ratio = self.afi_rate_ratio * data_rate_ratio
369369+ if dwidth_ratio == 0:
370370+ derivedClkRdToWr = 0
371371+ else:
372372+ derivedClkRdToWr = (self.mem_if_rd_to_wr_turnaround_oct / (dwidth_ratio / 2))
373373+374374+ if (self.mem_if_rd_to_wr_turnaround_oct % (dwidth_ratio / 2)) > 0:
375375+ derivedClkRdToWr += 1
376376+377377+ self.updateTemplate("DERIVED_CLK_RD_TO_WR", str(int(derivedClkRdToWr)))
378378+379379+ # MPFE information are stored in hps.xml despite we generate
380380+ # them into sdram_config, so let's load hps.xml
381381+ hpsNodeList = self.hpsDom.getElementsByTagName('hps')
382382+383383+ for hpsNode in hpsNodeList:
384384+385385+ childNode = xmlgrok.firstElementChild(hpsNode)
386386+387387+ while childNode != None:
388388+ # MPFE info is part of fpga_interfaces
389389+ if childNode.nodeName == 'fpga_interfaces':
390390+ self.handleHpsFpgaInterfaces(childNode)
391391+392392+ childNode = xmlgrok.nextElementSibling(childNode)
393393+394394+ self.sequencerDefinesStream = streamer.Streamer(self.outputDir + os.sep + EMIFGrokker.SDRAM_CONFIG_H_FILENAME, 'w')
395395+ self.sequencerDefinesStream.open()
396396+ self.sequencerDefinesStream.writeLicenseHeader()
397397+ self.sequencerDefinesStream.write(EMIFGrokker.SDRAM_FILE_HEADER)
398398+ ret = self.sequencerDefinesStream.writeSentinelStart(EMIFGrokker.SDRAM_SENTINEL)
399399+ if ret == -1:
400400+ print("Empty header written. Exiting.")
401401+ self.sequencerDefinesStream.write("/* SDRAM configuration */\n")
402402+ self.sequencerDefinesStream.write(self.sdramHTemplate)
403403+ self.openSeqFiles()
404404+ self.processSeqAuto()
405405+406406+ self.sequencerDefinesStream.write("\n")
407407+ self.sequencerDefinesStream.write("/* Sequencer auto configuration */\n")
408408+ self.sequencerDefinesStream.write(self.seqAutoTemplate)
409409+ self.sequencerDefinesStream.write("\n")
410410+ self.sequencerDefinesStream.write("/* Sequencer defines configuration */\n")
411411+ self.sequencerDefinesStream.write(self.seqDefinesTemplate)
412412+ self.sequencerDefinesStream.write("\n")
413413+ self.sequencerDefinesStream.write("/* Sequencer ac_rom_init configuration */\n")
414414+ self.sequencerDefinesStream.write(self.seqAutoAcTemplate)
415415+ self.sequencerDefinesStream.write("\n\n")
416416+ self.sequencerDefinesStream.write("/* Sequencer inst_rom_init configuration */\n")
417417+ self.sequencerDefinesStream.write(self.seqAutoInstTemplate)
418418+ self.sequencerDefinesStream.write("\n")
419419+420420+ ret = self.sequencerDefinesStream.writeSentinelEnd(EMIFGrokker.SDRAM_SENTINEL)
421421+ if ret == -1:
422422+ print("Empty header written. Exiting.")
423423+ self.sequencerDefinesStream.close()
424424+ self.closeSeqFiles()
+571
tools/cv_bsp_generator/hps.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+Pinmux header file generator
44+55+Process the hps.xml from Quartus and convert them to headers
66+usable by U-Boot.
77+88+Copyright (C) 2022 Intel Corporation <www.intel.com>
99+1010+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1111+"""
1212+import os
1313+import re
1414+import streamer
1515+import xmlgrok
1616+import xml.dom.minidom
1717+import collections
1818+import io
1919+from io import StringIO
2020+2121+class CompatStringIO(io.StringIO):
2222+ def write(self, s):
2323+ if hasattr(s, 'decode'):
2424+ # Use unicode for python2 to keep compatible
2525+ return int(super(CompatStringIO, self).write(s.decode('utf-8')))
2626+ else:
2727+ return super(CompatStringIO, self).write(s)
2828+ def getvalue(self):
2929+ return str(super(CompatStringIO, self).getvalue())
3030+3131+class HPSGrokker(object):
3232+3333+ SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
3434+ TEMPLATE_DIR = os.path.dirname(SCRIPT_DIR) + '/src'
3535+3636+ MAKEFILE_FILENAME = "Makefile"
3737+ makefileTemplate = ""
3838+ RESET_CONFIG_H_FILENAME = "reset_config.h"
3939+ resetConfigHTemplate = ""
4040+4141+ # If no device family is specified, assume Cyclone V.
4242+ derivedDeviceFamily = "cyclone5"
4343+4444+ # Assume FPGA DMA 0-7 are not in use by default
4545+ # Note: there appears to be a weird mismatch between sopcinfo
4646+ # value vs hps.xml value of DMA_Enable of string_list hw.tcl
4747+ # type, where sopcinfo uses comma as separator e.g.
4848+ # "No,No,No,..." while hps.xml uses space as separator.
4949+ dmaEnable = "No No No No No No No No"
5050+5151+ def __init__(self, inputDir, outputDir, hpsFileName='hps.xml'):
5252+ """ HPSGrokker initialization """
5353+ self.inputDir = inputDir
5454+ self.outputDir = outputDir
5555+ self.hpsInFileName = inputDir + os.sep + hpsFileName
5656+ self.dom = xml.dom.minidom.parse(self.hpsInFileName)
5757+ self.peripheralStream = None
5858+ self.pinmuxConfigBuffer = None
5959+ self.pinmuxHeaderBuffer = None
6060+ self.pinmuxHeaderFile = None
6161+ self.pinmuxArraySize = 0
6262+ self.config_hps_ = "CFG_HPS_"
6363+ self.clockStream = None
6464+ self.pinmux_regs = self.get_default_pinmux_regs()
6565+ self.pinmux_configs = self.get_default_pinmux_configs()
6666+ self.pinmux_config_h = None
6767+6868+ self.createFilesFromHPS()
6969+7070+ def get_default_pinmux_regs(self):
7171+ """ Set default pinmux values """
7272+ p = collections.OrderedDict()
7373+7474+ p['EMACIO0'] = 0
7575+ p['EMACIO1'] = 0
7676+ p['EMACIO2'] = 0
7777+ p['EMACIO3'] = 0
7878+ p['EMACIO4'] = 0
7979+ p['EMACIO5'] = 0
8080+ p['EMACIO6'] = 0
8181+ p['EMACIO7'] = 0
8282+ p['EMACIO8'] = 0
8383+ p['EMACIO9'] = 0
8484+ p['EMACIO10'] = 0
8585+ p['EMACIO11'] = 0
8686+ p['EMACIO12'] = 0
8787+ p['EMACIO13'] = 0
8888+ p['EMACIO14'] = 0
8989+ p['EMACIO15'] = 0
9090+ p['EMACIO16'] = 0
9191+ p['EMACIO17'] = 0
9292+ p['EMACIO18'] = 0
9393+ p['EMACIO19'] = 0
9494+ p['FLASHIO0'] = 0
9595+ p['FLASHIO1'] = 0
9696+ p['FLASHIO2'] = 0
9797+ p['FLASHIO3'] = 0
9898+ p['FLASHIO4'] = 0
9999+ p['FLASHIO5'] = 0
100100+ p['FLASHIO6'] = 0
101101+ p['FLASHIO7'] = 0
102102+ p['FLASHIO8'] = 0
103103+ p['FLASHIO9'] = 0
104104+ p['FLASHIO10'] = 0
105105+ p['FLASHIO11'] = 0
106106+ p['GENERALIO0'] = 0
107107+ p['GENERALIO1'] = 0
108108+ p['GENERALIO2'] = 0
109109+ p['GENERALIO3'] = 0
110110+ p['GENERALIO4'] = 0
111111+ p['GENERALIO5'] = 0
112112+ p['GENERALIO6'] = 0
113113+ p['GENERALIO7'] = 0
114114+ p['GENERALIO8'] = 0
115115+ p['GENERALIO9'] = 0
116116+ p['GENERALIO10'] = 0
117117+ p['GENERALIO11'] = 0
118118+ p['GENERALIO12'] = 0
119119+ p['GENERALIO13'] = 0
120120+ p['GENERALIO14'] = 0
121121+ p['GENERALIO15'] = 0
122122+ p['GENERALIO16'] = 0
123123+ p['GENERALIO17'] = 0
124124+ p['GENERALIO18'] = 0
125125+ p['GENERALIO19'] = 0
126126+ p['GENERALIO20'] = 0
127127+ p['GENERALIO21'] = 0
128128+ p['GENERALIO22'] = 0
129129+ p['GENERALIO23'] = 0
130130+ p['GENERALIO24'] = 0
131131+ p['GENERALIO25'] = 0
132132+ p['GENERALIO26'] = 0
133133+ p['GENERALIO27'] = 0
134134+ p['GENERALIO28'] = 0
135135+ p['GENERALIO29'] = 0
136136+ p['GENERALIO30'] = 0
137137+ p['GENERALIO31'] = 0
138138+ p['MIXED1IO0'] = 0
139139+ p['MIXED1IO1'] = 0
140140+ p['MIXED1IO2'] = 0
141141+ p['MIXED1IO3'] = 0
142142+ p['MIXED1IO4'] = 0
143143+ p['MIXED1IO5'] = 0
144144+ p['MIXED1IO6'] = 0
145145+ p['MIXED1IO7'] = 0
146146+ p['MIXED1IO8'] = 0
147147+ p['MIXED1IO9'] = 0
148148+ p['MIXED1IO10'] = 0
149149+ p['MIXED1IO11'] = 0
150150+ p['MIXED1IO12'] = 0
151151+ p['MIXED1IO13'] = 0
152152+ p['MIXED1IO14'] = 0
153153+ p['MIXED1IO15'] = 0
154154+ p['MIXED1IO16'] = 0
155155+ p['MIXED1IO17'] = 0
156156+ p['MIXED1IO18'] = 0
157157+ p['MIXED1IO19'] = 0
158158+ p['MIXED1IO20'] = 0
159159+ p['MIXED1IO21'] = 0
160160+ p['MIXED2IO0'] = 0
161161+ p['MIXED2IO1'] = 0
162162+ p['MIXED2IO2'] = 0
163163+ p['MIXED2IO3'] = 0
164164+ p['MIXED2IO4'] = 0
165165+ p['MIXED2IO5'] = 0
166166+ p['MIXED2IO6'] = 0
167167+ p['MIXED2IO7'] = 0
168168+ p['GPLINMUX48'] = 0
169169+ p['GPLINMUX49'] = 0
170170+ p['GPLINMUX50'] = 0
171171+ p['GPLINMUX51'] = 0
172172+ p['GPLINMUX52'] = 0
173173+ p['GPLINMUX53'] = 0
174174+ p['GPLINMUX54'] = 0
175175+ p['GPLINMUX55'] = 0
176176+ p['GPLINMUX56'] = 0
177177+ p['GPLINMUX57'] = 0
178178+ p['GPLINMUX58'] = 0
179179+ p['GPLINMUX59'] = 0
180180+ p['GPLINMUX60'] = 0
181181+ p['GPLINMUX61'] = 0
182182+ p['GPLINMUX62'] = 0
183183+ p['GPLINMUX63'] = 0
184184+ p['GPLINMUX64'] = 0
185185+ p['GPLINMUX65'] = 0
186186+ p['GPLINMUX66'] = 0
187187+ p['GPLINMUX67'] = 0
188188+ p['GPLINMUX68'] = 0
189189+ p['GPLINMUX69'] = 0
190190+ p['GPLINMUX70'] = 0
191191+ p['GPLMUX0'] = 1
192192+ p['GPLMUX1'] = 1
193193+ p['GPLMUX2'] = 1
194194+ p['GPLMUX3'] = 1
195195+ p['GPLMUX4'] = 1
196196+ p['GPLMUX5'] = 1
197197+ p['GPLMUX6'] = 1
198198+ p['GPLMUX7'] = 1
199199+ p['GPLMUX8'] = 1
200200+ p['GPLMUX9'] = 1
201201+ p['GPLMUX10'] = 1
202202+ p['GPLMUX11'] = 1
203203+ p['GPLMUX12'] = 1
204204+ p['GPLMUX13'] = 1
205205+ p['GPLMUX14'] = 1
206206+ p['GPLMUX15'] = 1
207207+ p['GPLMUX16'] = 1
208208+ p['GPLMUX17'] = 1
209209+ p['GPLMUX18'] = 1
210210+ p['GPLMUX19'] = 1
211211+ p['GPLMUX20'] = 1
212212+ p['GPLMUX21'] = 1
213213+ p['GPLMUX22'] = 1
214214+ p['GPLMUX23'] = 1
215215+ p['GPLMUX24'] = 1
216216+ p['GPLMUX25'] = 1
217217+ p['GPLMUX26'] = 1
218218+ p['GPLMUX27'] = 1
219219+ p['GPLMUX28'] = 1
220220+ p['GPLMUX29'] = 1
221221+ p['GPLMUX30'] = 1
222222+ p['GPLMUX31'] = 1
223223+ p['GPLMUX32'] = 1
224224+ p['GPLMUX33'] = 1
225225+ p['GPLMUX34'] = 1
226226+ p['GPLMUX35'] = 1
227227+ p['GPLMUX36'] = 1
228228+ p['GPLMUX37'] = 1
229229+ p['GPLMUX38'] = 1
230230+ p['GPLMUX39'] = 1
231231+ p['GPLMUX40'] = 1
232232+ p['GPLMUX41'] = 1
233233+ p['GPLMUX42'] = 1
234234+ p['GPLMUX43'] = 1
235235+ p['GPLMUX44'] = 1
236236+ p['GPLMUX45'] = 1
237237+ p['GPLMUX46'] = 1
238238+ p['GPLMUX47'] = 1
239239+ p['GPLMUX48'] = 1
240240+ p['GPLMUX49'] = 1
241241+ p['GPLMUX50'] = 1
242242+ p['GPLMUX51'] = 1
243243+ p['GPLMUX52'] = 1
244244+ p['GPLMUX53'] = 1
245245+ p['GPLMUX54'] = 1
246246+ p['GPLMUX55'] = 1
247247+ p['GPLMUX56'] = 1
248248+ p['GPLMUX57'] = 1
249249+ p['GPLMUX58'] = 1
250250+ p['GPLMUX59'] = 1
251251+ p['GPLMUX60'] = 1
252252+ p['GPLMUX61'] = 1
253253+ p['GPLMUX62'] = 1
254254+ p['GPLMUX63'] = 1
255255+ p['GPLMUX64'] = 1
256256+ p['GPLMUX65'] = 1
257257+ p['GPLMUX66'] = 1
258258+ p['GPLMUX67'] = 1
259259+ p['GPLMUX68'] = 1
260260+ p['GPLMUX69'] = 1
261261+ p['GPLMUX70'] = 1
262262+ p['NANDUSEFPGA'] = 0
263263+ p['UART0USEFPGA'] = 0
264264+ p['RGMII1USEFPGA'] = 0
265265+ p['SPIS0USEFPGA'] = 0
266266+ p['CAN0USEFPGA'] = 0
267267+ p['I2C0USEFPGA'] = 0
268268+ p['SDMMCUSEFPGA'] = 0
269269+ p['QSPIUSEFPGA'] = 0
270270+ p['SPIS1USEFPGA'] = 0
271271+ p['RGMII0USEFPGA'] = 0
272272+ p['UART1USEFPGA'] = 0
273273+ p['CAN1USEFPGA'] = 0
274274+ p['USB1USEFPGA'] = 0
275275+ p['I2C3USEFPGA'] = 0
276276+ p['I2C2USEFPGA'] = 0
277277+ p['I2C1USEFPGA'] = 0
278278+ p['SPIM1USEFPGA'] = 0
279279+ p['USB0USEFPGA'] = 0
280280+ p['SPIM0USEFPGA'] = 0
281281+282282+ return p
283283+284284+285285+ def get_default_pinmux_configs(self):
286286+ """ Get default pinmux values """
287287+ p = collections.OrderedDict()
288288+289289+ p['rgmii0'] = { 'name': 'CFG_HPS_EMAC0', 'used': 0 }
290290+ p['rgmii1'] = { 'name': 'CFG_HPS_EMAC1', 'used': 0 }
291291+ p['usb0'] = { 'name': 'CFG_HPS_USB0', 'used': 0 }
292292+ p['usb1'] = { 'name': 'CFG_HPS_USB1', 'used': 0 }
293293+ p['nand'] = { 'name': 'CFG_HPS_NAND', 'used': 0 }
294294+ p['sdmmc'] = { 'name': 'CFG_HPS_SDMMC', 'used': 0 }
295295+ p['CFG_HPS_SDMMC_BUSWIDTH'] = { 'name': 'CFG_HPS_SDMMC_BUSWIDTH', 'used': 0 }
296296+ p['qspi'] = { 'name': 'CFG_HPS_QSPI', 'used': 0 }
297297+ p['CFG_HPS_QSPI_CS3'] = { 'name': 'CFG_HPS_QSPI_CS3', 'used': 0 }
298298+ p['CFG_HPS_QSPI_CS2'] = { 'name': 'CFG_HPS_QSPI_CS2', 'used': 0 }
299299+ p['CFG_HPS_QSPI_CS1'] = { 'name': 'CFG_HPS_QSPI_CS1', 'used': 0 }
300300+ p['CFG_HPS_QSPI_CS0'] = { 'name': 'CFG_HPS_QSPI_CS0', 'used': 0 }
301301+ p['uart0'] = { 'name': 'CFG_HPS_UART0', 'used': 0 }
302302+ p['CFG_HPS_UART0_TX'] = { 'name': 'CFG_HPS_UART0_TX', 'used': 0 }
303303+ p['CFG_HPS_UART0_CTS'] = { 'name': 'CFG_HPS_UART0_CTS', 'used': 0 }
304304+ p['CFG_HPS_UART0_RTS'] = { 'name': 'CFG_HPS_UART0_RTS', 'used': 0 }
305305+ p['CFG_HPS_UART0_RX'] = { 'name': 'CFG_HPS_UART0_RX', 'used': 0 }
306306+ p['uart1'] = { 'name': 'CFG_HPS_UART1', 'used': 0 }
307307+ p['CFG_HPS_UART1_TX'] = { 'name': 'CFG_HPS_UART1_TX', 'used': 0 }
308308+ p['CFG_HPS_UART1_CTS'] = { 'name': 'CFG_HPS_UART1_CTS', 'used': 0 }
309309+ p['CFG_HPS_UART1_RTS'] = { 'name': 'CFG_HPS_UART1_RTS', 'used': 0 }
310310+ p['CFG_HPS_UART1_RX'] = { 'name': 'CFG_HPS_UART1_RX', 'used': 0 }
311311+ p['trace'] = { 'name': 'CFG_HPS_TRACE', 'used': 0 }
312312+ p['i2c0'] = { 'name': 'CFG_HPS_I2C0', 'used': 0 }
313313+ p['i2c1'] = { 'name': 'CFG_HPS_I2C1', 'used': 0 }
314314+ p['i2c2'] = { 'name': 'CFG_HPS_I2C2', 'used': 0 }
315315+ p['i2c3'] = { 'name': 'CFG_HPS_I2C3', 'used': 0 }
316316+ p['spim0'] = { 'name': 'CFG_HPS_SPIM0', 'used': 0 }
317317+ p['spim1'] = { 'name': 'CFG_HPS_SPIM1', 'used': 0 }
318318+ p['spis0'] = { 'name': 'CFG_HPS_SPIS0', 'used': 0 }
319319+ p['spis1'] = { 'name': 'CFG_HPS_SPIS1', 'used': 0 }
320320+ p['can0'] = { 'name': 'CFG_HPS_CAN0', 'used': 0 }
321321+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
322322+323323+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
324324+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
325325+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
326326+ p['can1'] = { 'name': 'CFG_HPS_CAN1', 'used': 0 }
327327+328328+ return p
329329+330330+ def updateTemplate(self, name, value):
331331+ """ Update Makefile & reset_config.h """
332332+ pattern = "${" + name + "}"
333333+ self.makefileTemplate = self.makefileTemplate.replace(pattern, value)
334334+ self.resetConfigHTemplate = self.resetConfigHTemplate.replace(pattern, value)
335335+336336+ def romanToInteger(self, roman):
337337+ """
338338+ Convert roman numerals to integer
339339+ Since we only support I,V,X, the
340340+ supported range is 1-39
341341+ """
342342+ table = { 'I':1 , 'V':5, 'X':10 }
343343+344344+ literals = list(roman)
345345+346346+ value = 0
347347+ i = 0
348348+349349+ while(i < (len(literals) - 1)):
350350+ current = table[literals[i]]
351351+ next = table[literals[i + 1]]
352352+ if (current < next):
353353+ value += (next - current)
354354+ i += 2
355355+ else:
356356+ value += current
357357+ i += 1
358358+359359+ if (i < (len(literals))):
360360+ value += table[literals[i]]
361361+362362+ return value
363363+364364+ def getDeviceFamily(self):
365365+ """ Get device family """
366366+ return self.derivedDeviceFamily
367367+368368+ def getDeviceFamilyName(self, deviceFamily):
369369+ """ Get device family name """
370370+ p = re.compile('^(\w+)\s+(\w+)$')
371371+ m = p.match(deviceFamily)
372372+ return m.group(1).lower() + str(self.romanToInteger(m.group(2)))
373373+374374+ def handleHPSSystemNode(self, systemNode):
375375+ """ handleHPSPeripheralsNode(peripheralsNode)
376376+ peripheralsNode is a peripherals element node in hps.xml
377377+ peripheralsNode is a list of peripheralNodes
378378+ """
379379+ configNode = xmlgrok.firstElementChild(systemNode)
380380+ while configNode != None:
381381+382382+ name = configNode.getAttribute('name')
383383+ value = configNode.getAttribute('value')
384384+385385+ self.updateTemplate(name, value)
386386+387387+ if name == "DEVICE_FAMILY":
388388+ self.derivedDeviceFamily = self.getDeviceFamilyName(value)
389389+390390+ if name == "DMA_Enable":
391391+ self.dmaEnable = value
392392+393393+ configNode = xmlgrok.nextElementSibling(configNode)
394394+395395+ def handleHPSPeripheralNode(self, peripheralNode):
396396+ """ This node of the hps.xml may contain a name, value pair
397397+ We need to:
398398+ emit a #define for the peripheral for is 'used' state
399399+ emit a #define for that pair, if it is marked 'used'
400400+ """
401401+ peripheralNode = xmlgrok.firstElementChild(peripheralNode)
402402+403403+ while peripheralNode != None:
404404+ if peripheralNode.hasAttribute('name') and peripheralNode.hasAttribute('used'):
405405+ newLine = "\n"
406406+ name = peripheralNode.getAttribute('name')
407407+ used = peripheralNode.getAttribute('used')
408408+409409+ if used == 'true' or used == True:
410410+ used = 1
411411+ elif used == 'false' or used == False:
412412+ used = 0
413413+414414+ configs = collections.OrderedDict()
415415+416416+ configNode = xmlgrok.firstElementChild(peripheralNode)
417417+ while configNode != None:
418418+ config_define_name = configNode.getAttribute('name')
419419+ config_define_value = configNode.getAttribute('value')
420420+ configs[config_define_name] = config_define_value
421421+ configNode = xmlgrok.nextElementSibling(configNode)
422422+ if configNode == None:
423423+ newLine += newLine
424424+ self.pinmuxConfigBuffer.write("#define " + str(config_define_name) + ' ' + '(' + str(config_define_value) + ')' + newLine)
425425+426426+ entry = self.pinmux_configs[name]
427427+ define_name = entry['name']
428428+429429+ if (len(configs) > 0):
430430+ self.pinmux_configs[name] = { 'name': define_name, 'used': used, 'configs': configs }
431431+ else:
432432+ self.pinmux_configs[name] = { 'name': define_name, 'used': used }
433433+434434+ # skip the parent peripheral node
435435+ # since only need to define child config node(s)
436436+ peripheralNode = xmlgrok.nextElementSibling(peripheralNode)
437437+438438+ def handleHPSPinmuxNode(self, pinmuxNode):
439439+ """ For a pinmuxNode, we may emit a #define for the name, value pair
440440+ """
441441+ if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
442442+ self.pinmuxArraySize += 1
443443+ name = pinmuxNode.getAttribute('name')
444444+ value = pinmuxNode.getAttribute('value')
445445+446446+ def handleHPSPinmuxesNode(self, pinmuxesNode):
447447+ """ PinmuxesNode is a list of pinmuxNodes
448448+ """
449449+ self.pinmuxHeaderBuffer.write(str("const u8 sys_mgr_init_table[] = {\n"))
450450+451451+ pinmuxNode = xmlgrok.firstElementChild(pinmuxesNode)
452452+ while pinmuxNode != None:
453453+ if pinmuxNode.hasAttribute('name') and pinmuxNode.hasAttribute('value'):
454454+ self.pinmuxArraySize += 1
455455+ name = pinmuxNode.getAttribute('name')
456456+ value = pinmuxNode.getAttribute('value')
457457+ self.pinmux_regs[name] = value
458458+ pinmuxNode = xmlgrok.nextElementSibling(pinmuxNode)
459459+460460+ reg_count = 0
461461+ pinmux_regs_count = len(self.pinmux_regs)
462462+ for reg, value in self.pinmux_regs.items():
463463+ reg_count += 1
464464+ if reg_count < pinmux_regs_count:
465465+ self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ', /* ' + reg + ' */\n' ))
466466+ else:
467467+ self.pinmuxHeaderBuffer.write(str("\t" + str(value) + ' /* ' + reg + ' */\n' ))
468468+469469+ # Write the close of the pin MUX array in the header
470470+ self.pinmuxHeaderBuffer.write(str("};" ))
471471+472472+ def handleHPSClockNode(self, clockNode):
473473+ """ A clockNode may emit a #define for the name, frequency pair
474474+ """
475475+ if clockNode.hasAttribute('name') and clockNode.hasAttribute('frequency'):
476476+ name = clockNode.getAttribute('name')
477477+ frequency = clockNode.getAttribute('frequency')
478478+ self.clockStream.write("#define " + name + ' ' + '(' + frequency + ')' + '\n')
479479+480480+ def handleHPSClocksNode(self, clocksNode):
481481+ """ A list of clockNodes is call clocksNode
482482+ """
483483+ self.clockStream = streamer.Streamer(self.outputDir + os.sep + clocksNode.nodeName + '.h', 'w')
484484+ self.clockStream.open()
485485+ clockNode = xmlgrok.firstElementChild(clocksNode)
486486+ while clockNode != None:
487487+ self.handleHPSClockNode(clockNode)
488488+ clockNode = xmlgrok.nextElementSibling(clockNode)
489489+490490+ self.clockStream.close()
491491+492492+ def handleHpsFpgaInterfaces(self, node):
493493+ """ Update FPGA Interface registers """
494494+ node = xmlgrok.firstElementChild(node)
495495+496496+ while node != None:
497497+ name = node.getAttribute('name')
498498+ used = node.getAttribute('used')
499499+500500+ if used == 'true':
501501+ reset = 0
502502+ else:
503503+ reset = 1
504504+505505+ if name == 'F2H_AXI_SLAVE':
506506+ self.updateTemplate("DERIVED_RESET_ASSERT_FPGA2HPS", str(reset))
507507+ elif name == 'H2F_AXI_MASTER':
508508+ self.updateTemplate("DERIVED_RESET_ASSERT_HPS2FPGA", str(reset))
509509+ elif name == 'LWH2F_AXI_MASTER':
510510+ self.updateTemplate("DERIVED_RESET_ASSERT_LWHPS2FPGA", str(reset))
511511+512512+ node = xmlgrok.nextElementSibling(node)
513513+514514+ def createFilesFromHPS(self):
515515+ """ Parse xml and create pinmux_config.h """
516516+ # Unfortunately we can't determine the file name before
517517+ # parsing the XML, so let's build up the source file
518518+ # content in string buffer
519519+ self.pinmuxHeaderBuffer = CompatStringIO()
520520+ self.pinmuxConfigBuffer = CompatStringIO()
521521+522522+ # Get a list of all nodes with the hps element name
523523+ hpsNodeList = self.dom.getElementsByTagName('hps')
524524+ if len(hpsNodeList) > 1:
525525+ print ("*** WARNING:" + "Multiple hps Elements found in %s!" % self.hpsInFileName)
526526+ # For each of the hps element nodes, go through the child list
527527+ # Note that currently there is only one hps Element
528528+ # but this code will handle more than one hps node
529529+ # In the future, multiple hps nodes may need additional code
530530+ # to combine settings from the multiple hps Elements
531531+ for hpsNode in hpsNodeList:
532532+ # Currently, there are only 3 children of the hps Element:
533533+ # peripherals, pin_muxes, and clocks
534534+ # but this is left open-ended for future additions to the
535535+ # specification for the hps.xml
536536+ childNode = xmlgrok.firstElementChild(hpsNode)
537537+ while childNode != None:
538538+ if childNode.nodeName == 'pin_muxes':
539539+ self.handleHPSPinmuxesNode(childNode)
540540+ elif childNode.nodeName == 'system':
541541+ self.handleHPSSystemNode(childNode)
542542+ elif childNode.nodeName == 'fpga_interfaces':
543543+ self.handleHpsFpgaInterfaces(childNode)
544544+ elif childNode.nodeName == 'peripherals':
545545+ self.handleHPSPeripheralNode(childNode)
546546+ else:
547547+ print ("***Error:Found unexpected HPS child node:%s" % childNode.nodeName)
548548+ childNode = xmlgrok.nextElementSibling(childNode)
549549+550550+ self.updateTemplate("DERIVED_DEVICE_FAMILY", self.derivedDeviceFamily)
551551+552552+ # Now we write string buffers into files once we know the device family
553553+ self.pinmux_config_h = 'pinmux_config.h'
554554+ self.pinmux_config_src = 'pinmux_config_' + self.derivedDeviceFamily + '.c'
555555+556556+ # Create pinmux_config .h
557557+ headerDefine = "__SOCFPGA_PINMUX_CONFIG_H__"
558558+ self.pinmuxHeaderFile = streamer.Streamer(self.outputDir + os.sep + self.pinmux_config_h, 'w')
559559+ self.pinmuxHeaderFile.open()
560560+ self.pinmuxHeaderFile.writeLicenseHeader()
561561+ self.pinmuxHeaderFile.write('/*\n * Altera SoCFPGA PinMux configuration\n */\n\n')
562562+563563+ self.pinmuxHeaderFile.write("#ifndef " + headerDefine + "\n")
564564+ self.pinmuxHeaderFile.write("#define " + headerDefine + "\n\n")
565565+ self.pinmuxHeaderFile.write(self.pinmuxHeaderBuffer.getvalue())
566566+ self.pinmuxHeaderFile.write("\n#endif /* " + headerDefine + " */\n")
567567+ self.pinmuxHeaderFile.close()
568568+569569+ # Free up string buffers
570570+ self.pinmuxHeaderBuffer.close()
571571+ self.pinmuxConfigBuffer.close()
+203
tools/cv_bsp_generator/iocsr.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+IOCSR header file generator
44+55+Process the hiof file from Quartus and generate iocsr header
66+usable by U-Boot.
77+88+Copyright (C) 2022 Intel Corporation <www.intel.com>
99+1010+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1111+"""
1212+import os
1313+import struct
1414+import streamer
1515+1616+class IOCSRGrokker(object):
1717+ """ Decode the .hiof file and produce some C source code
1818+ """
1919+ IOCSR_ROOT_FILENAME = 'iocsr_config'
2020+ IOCSR_SENTINEL = '__SOCFPGA_IOCSR_CONFIG_H__'
2121+ IOCSR_FILE_EXTENSION_MAX_LEN = 6
2222+ PTAG_HPS_IOCSR_INFO = 39
2323+ PTAG_HPS_IOCSR = 40
2424+ PTAG_DEVICE_NAME = 2
2525+ PTAG_TERMINATION = 8
2626+2727+ def __init__(self, deviceFamily, inputDir, outputDir, hiofSrcFileName):
2828+ """ IOCSRGrokker Initialization """
2929+ self.deviceFamily = deviceFamily
3030+ self.inputDir = inputDir
3131+ self.outputDir = outputDir
3232+ self.hiofInFileName = hiofSrcFileName
3333+ self.iocsrFileName = self.IOCSR_ROOT_FILENAME
3434+ self.headerOut = None
3535+ self.sourceOut = None
3636+ self.createFilesFromHIOF()
3737+3838+ @staticmethod
3939+ def byteArrayToStr(bytes):
4040+ """ Convert a list of bytes into a string
4141+ """
4242+ # We don't like nulls
4343+ bytes = bytes.replace('\x00', '')
4444+ s = ''
4545+ for b in bytes:
4646+ s += b
4747+ return s
4848+4949+ @staticmethod
5050+ def getLengthData(bytes):
5151+ """
5252+ @param: bytes is a chunk of bytes that we need to decode
5353+ There will be a ptag that we may care about.
5454+ If we care about it, we will get the length of the chunk
5555+ that the ptag cares about.
5656+ @rtype: a pair, length of chunk and the chunk itself
5757+ @return: length of the ptag chunk we care about
5858+ @return: data chunk that ptag indicates we need to decode
5959+ """
6060+ blockSize = len(bytes)
6161+ i = 0
6262+ bitlength = 0
6363+ length = 0
6464+ data = []
6565+6666+ while i < blockSize:
6767+ byte = struct.unpack('B', bytes[i:i+1])[0]
6868+ i += 1
6969+7070+ if byte == 1:
7171+ bitlength = struct.unpack('I', bytes[i:i+4])[0]
7272+ i += 4
7373+ elif byte == 2:
7474+ length = struct.unpack('I', bytes[i:i+4])[0]
7575+ i += 4
7676+7777+ elif byte == 5:
7878+ j = 0
7979+ while i < blockSize:
8080+ data.append(struct.unpack('I', bytes[i:i+4])[0])
8181+ i += 4
8282+ j += 1
8383+8484+ else:
8585+ i += 4
8686+8787+ return (bitlength, data)
8888+8989+9090+ def verifyRead(self, tagWeRead, tagWeExpected):
9191+ """ verify the hiof value with tag expected """
9292+ if tagWeRead != tagWeExpected:
9393+ print ("***Error: Expected ptag of %02d, but got %02d" % (tagWeExpected, tagWeRead))
9494+9595+ def createFilesFromHIOF(self):
9696+ """ read the hiof file to create iocsr_config.h """
9797+ self.hiofStream = streamer.Streamer(self.inputDir + os.sep + self.hiofInFileName, 'rb')
9898+ self.iocsrHeaderStream = streamer.Streamer(self.outputDir + os.sep + self.iocsrFileName + '.h', 'w')
9999+ self.hiofStream.open()
100100+ self.iocsrHeaderStream.open()
101101+ self.iocsrHeaderStream.writeLicenseHeader()
102102+ self.iocsrHeaderStream.write('/*\n * Altera SoCFPGA IOCSR configuration\n */\n\n')
103103+ ret = self.iocsrHeaderStream.writeSentinelStart(IOCSRGrokker.IOCSR_SENTINEL)
104104+ if ret == -1:
105105+ print("Empty header written. Exiting.")
106106+107107+ # Read the file extension (typically .hiof)
108108+ # and the file version
109109+ self.fileExtension = self.hiofStream.readBytesAsString(IOCSRGrokker.IOCSR_FILE_EXTENSION_MAX_LEN)
110110+ self.fileVersion = self.hiofStream.readUnsignedInt()
111111+112112+ # Now read the ptags
113113+ # Device name is first
114114+ self.programmerTag = self.hiofStream.readUnsignedShort()
115115+ self.verifyRead(self.programmerTag, self.PTAG_DEVICE_NAME)
116116+ self.deviceNameLength = self.hiofStream.readUnsignedInt()
117117+ self.deviceName = self.hiofStream.readBytesAsString(self.deviceNameLength)
118118+119119+ # Basic information of the HIOF files
120120+ # This is not used by the preloader generator, but we read it and ignore the
121121+ # contents.
122122+ programmerTag = self.hiofStream.readUnsignedShort()
123123+ self.verifyRead(programmerTag, self.PTAG_HPS_IOCSR_INFO)
124124+ basicHPSIOCSRInfoLength = self.hiofStream.readUnsignedInt()
125125+ self.hiofStream.read(basicHPSIOCSRInfoLength)
126126+127127+ # Actual content of IOCSR information
128128+ self.programmerTag1 = self.hiofStream.readUnsignedShort()
129129+ self.verifyRead(self.programmerTag1, self.PTAG_HPS_IOCSR)
130130+ self.HPSIOCSRLength1 = self.hiofStream.readUnsignedInt()
131131+ self.HPSIOCSRBytes1 = self.hiofStream.read(self.HPSIOCSRLength1)
132132+ self.HPSIOCSRDataLength1, self.HPSIOCSRData1 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes1)
133133+134134+ # Actual content of IOCSR information
135135+ self.programmerTag2 = self.hiofStream.readUnsignedShort()
136136+ self.verifyRead(self.programmerTag2, self.PTAG_HPS_IOCSR)
137137+ self.HPSIOCSRLength2 = self.hiofStream.readUnsignedInt()
138138+ self.HPSIOCSRBytes2 = self.hiofStream.read(self.HPSIOCSRLength2)
139139+ self.HPSIOCSRDataLength2, self.HPSIOCSRData2 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes2)
140140+141141+ # Actual content of IOCSR information
142142+ self.programmerTag3 = self.hiofStream.readUnsignedShort()
143143+ self.verifyRead(self.programmerTag3, self.PTAG_HPS_IOCSR)
144144+ self.HPSIOCSRLength3 = self.hiofStream.readUnsignedInt()
145145+ self.HPSIOCSRBytes3 = self.hiofStream.read(self.HPSIOCSRLength3)
146146+ self.HPSIOCSRDataLength3, self.HPSIOCSRData3 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes3)
147147+148148+ # Actual content of IOCSR information
149149+ self.programmerTag4 = self.hiofStream.readUnsignedShort()
150150+ self.verifyRead(self.programmerTag4, self.PTAG_HPS_IOCSR)
151151+ self.HPSIOCSRLength4 = self.hiofStream.readUnsignedInt()
152152+ self.HPSIOCSRBytes4 = self.hiofStream.read(self.HPSIOCSRLength4)
153153+ self.HPSIOCSRDataLength4, self.HPSIOCSRData4 = IOCSRGrokker.getLengthData(self.HPSIOCSRBytes4)
154154+155155+ # Now we should see the end of the hiof input
156156+ programmerTag = self.hiofStream.readUnsignedShort()
157157+ if 8 != programmerTag:
158158+ print ("I didn't find the end of the .hiof file when I expected to!")
159159+160160+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN0_LENGTH\t' +\
161161+ str(self.HPSIOCSRDataLength1) + '\n')
162162+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN1_LENGTH\t' +\
163163+ str(self.HPSIOCSRDataLength2) + '\n')
164164+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN2_LENGTH\t' +\
165165+ str(self.HPSIOCSRDataLength3) + '\n')
166166+ self.iocsrHeaderStream.write('#define CFG_HPS_IOCSR_SCANCHAIN3_LENGTH\t' +\
167167+ str(self.HPSIOCSRDataLength4) + '\n')
168168+169169+ self.iocsrHeaderStream.write("\n")
170170+171171+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain0_table[] = {\n')
172172+ for value in self.HPSIOCSRData1:
173173+ hv = '0x%08X' % (value)
174174+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
175175+ self.iocsrHeaderStream.write('};\n')
176176+ self.iocsrHeaderStream.write('\n')
177177+178178+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain1_table[] = {\n')
179179+ for value in self.HPSIOCSRData2:
180180+ hv = '0x%08X' % (value)
181181+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
182182+ self.iocsrHeaderStream.write('};\n')
183183+ self.iocsrHeaderStream.write('\n')
184184+185185+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain2_table[] = {\n')
186186+ for value in self.HPSIOCSRData3:
187187+ hv = '0x%08X' % (value)
188188+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
189189+ self.iocsrHeaderStream.write('};\n')
190190+ self.iocsrHeaderStream.write('\n')
191191+192192+ self.iocsrHeaderStream.write('const unsigned long iocsr_scan_chain3_table[] = {\n')
193193+ for value in self.HPSIOCSRData4:
194194+ hv = '0x%08X' % (value)
195195+ self.iocsrHeaderStream.write('\t' + hv + ',\n')
196196+ self.iocsrHeaderStream.write('};\n')
197197+ self.iocsrHeaderStream.write('\n\n')
198198+199199+ ret = self.iocsrHeaderStream.writeSentinelEnd(IOCSRGrokker.IOCSR_SENTINEL)
200200+ if ret == -1:
201201+ print("Empty header written. Exiting.")
202202+203203+ self.iocsrHeaderStream.close()
+114
tools/cv_bsp_generator/model.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+Data models for XML files required for generating a preloader.
44+55+These classes encapsulate the complexities of XML DOM in order to
66+make retrieving data from XML files easier and more reliable.
77+By shielding data model deserialization from data consumers,
88+it'd be easier to switch to other formats such as JSON if required.
99+1010+There are some assumptions about how these XML files are structured
1111+such as the hierarchy of elements and ordering of attributes, these
1212+are relatively safe assumptions for as long as the XML files are
1313+always generated by HPS megawizard (isw.tcl) and are not hand-edited.
1414+1515+Copyright (C) 2022 Intel Corporation <www.intel.com>
1616+1717+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1818+"""
1919+import xml.dom.minidom
2020+2121+def getSingletonElementByTagName(parent, tagName):
2222+ """
2323+ Find tag by name and ensure that there is exactly one match
2424+ """
2525+ nodes = parent.getElementsByTagName(tagName)
2626+2727+ if len(nodes) == 0:
2828+ raise Exception("Can't find element: " + tagName)
2929+ elif len(nodes) > 1:
3030+ raise Exception("Unexpected multiple matches for singleton element: " + tagName)
3131+ else:
3232+ return nodes[0]
3333+3434+class hps(object):
3535+ """
3636+ Data model for hps.xml
3737+ """
3838+ @staticmethod
3939+ def create(file):
4040+ """ hps model """
4141+ return hps(file)
4242+4343+ def __init__(self, file):
4444+ """ hps model initialization """
4545+ self.dom = xml.dom.minidom.parse(file)
4646+4747+ try:
4848+ # Look for <hps> node
4949+ self.hpsNode = getSingletonElementByTagName(self.dom, "hps")
5050+ # Look for <hps><system> node
5151+ self.hpsSystemNode = getSingletonElementByTagName(self.hpsNode, "system")
5252+ except Exception:
5353+ raise Exception("Can't initialize from file: " + file)
5454+5555+ def getSystemConfig(self, param):
5656+ """ parse system configuration tag """
5757+ hpsSystemConfigNode = None
5858+5959+ # Look for <hps><system><config ...> nodes
6060+ for node in self.hpsSystemNode.getElementsByTagName("config"):
6161+ # assume name is the first attribute as in <config name="..." ...>
6262+ nameAttrNode = node.attributes.item(0)
6363+ if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param:
6464+ # assume value is the second attribute as in <config name="..." value="...">
6565+ valueAttrNode = node.attributes.item(1)
6666+ if valueAttrNode.nodeName == "value":
6767+ hpsSystemConfigNode = valueAttrNode
6868+ break
6969+7070+ if hpsSystemConfigNode == None:
7171+ raise ValueError("Can't find <hps><system><config> node: " + param)
7272+7373+ return hpsSystemConfigNode.nodeValue
7474+7575+class emif(object):
7676+ """
7777+ Data model for emif.xml.
7878+ """
7979+ @staticmethod
8080+ def create(file):
8181+ """ emif model """
8282+ return emif(file)
8383+8484+ def __init__(self, file):
8585+ """ emif model initialization """
8686+ self.dom = xml.dom.minidom.parse(file)
8787+8888+ try:
8989+ # Look for <emif> node
9090+ self.emifNode = getSingletonElementByTagName(self.dom, "emif")
9191+ # Look for <emif><pll> node
9292+ self.emifPllNode = getSingletonElementByTagName(self.emifNode, "pll")
9393+ except Exception:
9494+ raise Exception("Can't initialize from file: " + file)
9595+9696+ def getPllDefine(self, param):
9797+ """ parse pll define tag """
9898+ emifPllDefineNode = None
9999+100100+ # Look for <emif><pll><define ...> nodes
101101+ for node in self.emifPllNode.getElementsByTagName("define"):
102102+ nameAttrNode = node.attributes.item(0)
103103+ # assume name is the first attribute as in <define name="..." ...>
104104+ if nameAttrNode.nodeName == "name" and nameAttrNode.nodeValue == param:
105105+ # assume value is the second attribute as in <config name="..." value="...">
106106+ valueAttrNode = node.attributes.item(1)
107107+ if valueAttrNode.nodeName == "value":
108108+ emifPllDefineNode = valueAttrNode
109109+ break
110110+111111+ if emifPllDefineNode == None:
112112+ raise Exception("Can't find EMIF PLL define node: " + param)
113113+114114+ return emifPllDefineNode.nodeValue
+196
tools/cv_bsp_generator/renderer.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+Document renderer class for preloader source files
44+55+Each document renderer takes care of a full construction of
66+a specific file format using the required data model.
77+88+Copyright (C) 2022 Intel Corporation <www.intel.com>
99+1010+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
1111+"""
1212+import collections
1313+import doc
1414+1515+class pll_config_h:
1616+ """
1717+ pll_config.h renderer.
1818+ """
1919+2020+ def __init__(self, hpsModel, emifModel):
2121+ """ renderer initialization """
2222+ self.hpsModel = hpsModel
2323+ self.emifModel = emifModel
2424+ self.doc = doc.generated_c_source("__SOCFPGA_PLL_CONFIG_H__")
2525+2626+ def createContent(self):
2727+ """ add the content based on settings parsed. eventually it will be
2828+ written to pll_config.h file
2929+ """
3030+ doc.c_source.line(self.doc)
3131+ id = "CFG_HPS_DBCTRL_STAYOSC1"
3232+ valueString = self.hpsModel.getSystemConfig("dbctrl_stayosc1")
3333+ # Unfortunately hps.xml never tells us the data type of values
3434+ # attributes. Here we workaround this type of problem, often
3535+ # this is case-by-case, i.e. having to know which parameter that
3636+ # we're dealing with, hence this ugly parameter-specific
3737+ # if-statement needs here to workaround the data type inconsistency
3838+ if valueString.lower() == "true":
3939+ value = "1"
4040+ else:
4141+ value = "0"
4242+ doc.c_source.define(self.doc, id, value )
4343+ doc.c_source.line(self.doc)
4444+ self.addMainPllSettings()
4545+ doc.c_source.line(self.doc)
4646+ self.addPeriphPllSettings()
4747+ doc.c_source.line(self.doc)
4848+ self.addSdramPllSettings()
4949+ doc.c_source.line(self.doc)
5050+ self.addClockFreq()
5151+ doc.c_source.line(self.doc)
5252+ self.addAlteraSettings()
5353+ doc.c_source.line(self.doc)
5454+5555+ def addMainPllSettings(self):
5656+ """ add pll settings to the file """
5757+ paramMap = collections.OrderedDict()
5858+ paramMap["VCO_DENOM"] = "main_pll_n"
5959+ paramMap["VCO_NUMER"] = "main_pll_m"
6060+6161+ for key in paramMap.keys():
6262+ id = "CFG_HPS_MAINPLLGRP_" + key
6363+ value = self.hpsModel.getSystemConfig(paramMap[key])
6464+ doc.c_source.define(self.doc, id, value )
6565+6666+ # main_pll_c0, main_pll_c1, main_pll_c2 are fixed counters,
6767+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MPUCLK_CNT", "0")
6868+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_MAINCLK_CNT", "0")
6969+ doc.c_source.define(self.doc, "CFG_HPS_MAINPLLGRP_DBGATCLK_CNT", "0")
7070+7171+ paramMap = collections.OrderedDict()
7272+7373+ paramMap["MAINQSPICLK_CNT"] = "main_pll_c3"
7474+ paramMap["MAINNANDSDMMCCLK_CNT"] = "main_pll_c4"
7575+ paramMap["CFGS2FUSER0CLK_CNT"] = "main_pll_c5"
7676+ paramMap["MAINDIV_L3MPCLK"] = "l3_mp_clk_div"
7777+ paramMap["MAINDIV_L3SPCLK"] = "l3_sp_clk_div"
7878+ paramMap["MAINDIV_L4MPCLK"] = "l4_mp_clk_div"
7979+ paramMap["MAINDIV_L4SPCLK"] = "l4_sp_clk_div"
8080+ paramMap["DBGDIV_DBGATCLK"] = "dbg_at_clk_div"
8181+ paramMap["DBGDIV_DBGCLK"] = "dbg_clk_div"
8282+ paramMap["TRACEDIV_TRACECLK"] = "dbg_trace_clk_div"
8383+ paramMap["L4SRC_L4MP"] = "l4_mp_clk_source"
8484+ paramMap["L4SRC_L4SP"] = "l4_sp_clk_source"
8585+8686+ for key in paramMap.keys():
8787+ id = "CFG_HPS_MAINPLLGRP_" + key
8888+ value = self.hpsModel.getSystemConfig(paramMap[key])
8989+ doc.c_source.define(self.doc, id, value )
9090+9191+ def addPeriphPllSettings(self):
9292+ """ add peripheral pll settings to the file """
9393+ paramMap = collections.OrderedDict()
9494+ paramMap["VCO_DENOM"] = "periph_pll_n"
9595+ paramMap["VCO_NUMER"] = "periph_pll_m"
9696+ paramMap["VCO_PSRC"] = "periph_pll_source"
9797+ paramMap["EMAC0CLK_CNT"] = "periph_pll_c0"
9898+ paramMap["EMAC1CLK_CNT"] = "periph_pll_c1"
9999+ paramMap["PERQSPICLK_CNT"] = "periph_pll_c2"
100100+ paramMap["PERNANDSDMMCCLK_CNT"] = "periph_pll_c3"
101101+ paramMap["PERBASECLK_CNT"] = "periph_pll_c4"
102102+ paramMap["S2FUSER1CLK_CNT"] = "periph_pll_c5"
103103+ paramMap["DIV_USBCLK"] = "usb_mp_clk_div"
104104+ paramMap["DIV_SPIMCLK"] = "spi_m_clk_div"
105105+ paramMap["DIV_CAN0CLK"] = "can0_clk_div"
106106+ paramMap["DIV_CAN1CLK"] = "can1_clk_div"
107107+ paramMap["GPIODIV_GPIODBCLK"] = "gpio_db_clk_div"
108108+ paramMap["SRC_SDMMC"] = "sdmmc_clk_source"
109109+ paramMap["SRC_NAND"] = "nand_clk_source"
110110+ paramMap["SRC_QSPI"] = "qspi_clk_source"
111111+112112+ for key in paramMap.keys():
113113+ id = "CFG_HPS_PERPLLGRP_" + key
114114+ value = self.hpsModel.getSystemConfig(paramMap[key])
115115+ doc.c_source.define(self.doc, id, value )
116116+117117+ def addSdramPllSettings(self):
118118+ """ add sdram pll settings to the file """
119119+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_DIV")
120120+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_DENOM", value )
121121+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_MULT")
122122+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_NUMER", value )
123123+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_VCO_SSRC", "0")
124124+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_CNT", "1")
125125+ value = self.emifModel.getPllDefine("PLL_MEM_CLK_PHASE_DEG")
126126+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQSCLK_PHASE", value )
127127+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_CNT", "0")
128128+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDR2XDQSCLK_PHASE", "0")
129129+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_CNT", "1")
130130+ value = self.emifModel.getPllDefine("PLL_WRITE_CLK_PHASE_DEG")
131131+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_DDRDQCLK_PHASE", value )
132132+133133+ try:
134134+ value = self.hpsModel.getSystemConfig("sdram_pll_c5")
135135+ except ValueError:
136136+ value = "5"
137137+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_CNT", value )
138138+ doc.c_source.define(self.doc, "CFG_HPS_SDRPLLGRP_S2FUSER2CLK_PHASE", "0")
139139+140140+ def addClockFreq(self):
141141+ """ add clock frequency settings to the file """
142142+ paramMap = collections.OrderedDict()
143143+ paramMap["OSC1"] = "eosc1_clk_hz"
144144+ paramMap["OSC2"] = "eosc2_clk_hz"
145145+ paramMap["F2S_SDR_REF"] = "F2SCLK_SDRAMCLK_FREQ"
146146+ paramMap["F2S_PER_REF"] = "F2SCLK_PERIPHCLK_FREQ"
147147+ paramMap["MAINVCO"] = "main_pll_vco_hz"
148148+ paramMap["PERVCO"] = "periph_pll_vco_hz"
149149+150150+ for key in paramMap.keys():
151151+ id = "CFG_HPS_CLK_" + key + "_HZ"
152152+ value = self.hpsModel.getSystemConfig(paramMap[key])
153153+ doc.c_source.define(self.doc, id, value )
154154+155155+ eosc1 = int(self.hpsModel.getSystemConfig("eosc1_clk_hz"))
156156+ eosc2 = int(self.hpsModel.getSystemConfig("eosc2_clk_hz"))
157157+ m = int(self.emifModel.getPllDefine("PLL_MEM_CLK_MULT"))
158158+ n = int(self.emifModel.getPllDefine("PLL_MEM_CLK_DIV"))
159159+ vco = int(round(eosc1 * (m + 1) / (n + 1)))
160160+ doc.c_source.define(self.doc, "CFG_HPS_CLK_SDRVCO_HZ", str(vco) )
161161+162162+ paramMap = collections.OrderedDict()
163163+ paramMap["EMAC0"] = "emac0_clk_hz"
164164+ paramMap["EMAC1"] = "emac1_clk_hz"
165165+ paramMap["USBCLK"] = "usb_mp_clk_hz"
166166+ paramMap["NAND"] = "nand_clk_hz"
167167+ paramMap["SDMMC"] = "sdmmc_clk_hz"
168168+ paramMap["QSPI"] = "qspi_clk_hz"
169169+ paramMap["SPIM"] = "spi_m_clk_hz"
170170+ paramMap["CAN0"] = "can0_clk_hz"
171171+ paramMap["CAN1"] = "can1_clk_hz"
172172+ paramMap["GPIODB"] = "gpio_db_clk_hz"
173173+ paramMap["L4_MP"] = "l4_mp_clk_hz"
174174+ paramMap["L4_SP"] = "l4_sp_clk_hz"
175175+176176+ for key in paramMap.keys():
177177+ id = "CFG_HPS_CLK_" + key + "_HZ"
178178+ value = self.hpsModel.getSystemConfig(paramMap[key])
179179+ doc.c_source.define(self.doc, id, value )
180180+181181+ def addAlteraSettings(self):
182182+ """ add Altera-related settings to the file """
183183+ paramMap = collections.OrderedDict()
184184+ paramMap["MPUCLK"] = "main_pll_c0_internal"
185185+ paramMap["MAINCLK"] = "main_pll_c1_internal"
186186+ paramMap["DBGATCLK"] = "main_pll_c2_internal"
187187+188188+ for key in paramMap.keys():
189189+ id = "CFG_HPS_ALTERAGRP_" + key
190190+ value = self.hpsModel.getSystemConfig(paramMap[key])
191191+ doc.c_source.define(self.doc, id, value )
192192+193193+ def __str__(self):
194194+ """ convert to string """
195195+ self.createContent()
196196+ return str(self.doc)
+5
tools/cv_bsp_generator/requirements.txt
···11+# requirements.txt for cv_bsp_generator.py
22+# All dependencies are either standard library modules
33+# or local Python files included in this BSP tool.
44+# No external pip packages are required.
55+
+102
tools/cv_bsp_generator/streamer.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+Generate license, file header and close tag.
44+55+Copyright (C) 2022 Intel Corporation <www.intel.com>
66+77+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
88+"""
99+import os
1010+import struct
1111+import doc
1212+1313+class Streamer(object):
1414+ """ Streamer class to generate license, header, and close tag.
1515+ """
1616+ def __init__(self, fileName, mode='r'):
1717+ """ Streamer initialization """
1818+ self.fileName = fileName
1919+ self.mode = mode
2020+ self.file = None
2121+ self.sentinel = None
2222+ if '+' in mode or 'w' in mode or 'a' in mode:
2323+ self.fileMode = 'write'
2424+ else:
2525+ self.fileMode = 'read'
2626+2727+ def close(self):
2828+ """ file close """
2929+ if self.file != None:
3030+ self.file.close()
3131+ self.file = None
3232+3333+ def open(self):
3434+ """ file open """
3535+ if self.fileName != None:
3636+ if self.file == None:
3737+ if self.fileMode == 'write':
3838+ print ("Generating file: %s..." % self.fileName)
3939+ else:
4040+ print ("Reading file: %s..." % self.fileName)
4141+ self.file = open(self.fileName, self.mode)
4242+4343+ def read(self, numBytes):
4444+ """ file read number of bytes """
4545+ if self.file == None:
4646+ print ("***Error: Attempted to read from unopened file %s" \
4747+ % (self.fileName))
4848+ exit(-1)
4949+5050+ else:
5151+ return self.file.read(numBytes)
5252+5353+ def readUnsignedInt(self):
5454+ """ read unsigned integer """
5555+ return struct.unpack('I', self.read(4))[0]
5656+5757+ def readUnsignedShort(self):
5858+ """ read unsigned short """
5959+ return struct.unpack('H', self.read(2))[0]
6060+6161+ def readBytesAsString(self, numBytes):
6262+ """ Read some bytes from a binary file
6363+ and interpret the data values as a String
6464+ """
6565+ bytes = self.read(numBytes)
6666+ s = bytes.decode('utf-8')
6767+6868+ return s
6969+7070+ def write(self, str):
7171+ """ file write """
7272+ if self.file == None:
7373+ print ("***Error: Attempted to write to unopened file %s" \
7474+ % (self.fileName))
7575+ exit(-1)
7676+7777+ else:
7878+ self.file.write("%s" % str)
7979+8080+ def writeLicenseHeader(self):
8181+ """ write license & copyright """
8282+ # format the license header
8383+ licenseHeader = "/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */\n"
8484+ self.file.write("%s" % licenseHeader)
8585+ copyrightHeader = "/*\n * Copyright (C) 2022 Intel Corporation <www.intel.com>\n *\n */\n"
8686+ self.file.write("%s" % copyrightHeader)
8787+8888+ def writeSentinelStart(self, sentinel):
8989+ """ start header """
9090+ if sentinel == None:
9191+ return -1
9292+ self.sentinel = sentinel
9393+ self.file.write("%s\n%s\n\n" % (\
9494+ "#ifndef " + self.sentinel,
9595+ "#define " + self.sentinel))
9696+9797+ def writeSentinelEnd(self, sentinel):
9898+ """ end header """
9999+ if sentinel == None:
100100+ return -1
101101+ self.sentinel = sentinel
102102+ self.file.write("\n%s\n" % ("#endif /* " + self.sentinel + " */"))
+32
tools/cv_bsp_generator/xmlgrok.py
···11+# SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
22+"""
33+XML node parser
44+55+Copyright (C) 2022 Intel Corporation <www.intel.com>
66+77+Author: Lee, Kah Jing <kah.jing.lee@intel.com>
88+"""
99+import xml.dom
1010+1111+def isElementNode(XMLNode):
1212+ """ check if the node is element node """
1313+ return XMLNode.nodeType == xml.dom.Node.ELEMENT_NODE
1414+1515+def firstElementChild(XMLNode):
1616+ """ Calling firstChild on an Node of type Element often (always?)
1717+ returns a Node of Text type. How annoying! Return the first Element
1818+ child
1919+ """
2020+ child = XMLNode.firstChild
2121+ while child != None and not isElementNode(child):
2222+ child = nextElementSibling(child)
2323+ return child
2424+2525+def nextElementSibling(XMLNode):
2626+ """ nextElementSibling will return the next sibling of XMLNode that is
2727+ an Element Node Type
2828+ """
2929+ sib = XMLNode.nextSibling
3030+ while sib != None and not isElementNode(sib):
3131+ sib = sib.nextSibling
3232+ return sib