From: Zoltan HERPAI Date: Sun, 26 Jan 2020 22:46:18 +0000 (+0100) Subject: uboot-hifiveu: add bootloader package for HiFive Ux40 boards X-Git-Url: http://git.lede-project.org./?a=commitdiff_plain;h=2f0c33de2f53e010c85f07581a8733686bad2955;p=openwrt%2Fstaging%2Fwigyori.git uboot-hifiveu: add bootloader package for HiFive Ux40 boards Signed-off-by: Zoltan HERPAI --- diff --git a/package/boot/uboot-hifiveu/Makefile b/package/boot/uboot-hifiveu/Makefile new file mode 100644 index 0000000000..3295853bd6 --- /dev/null +++ b/package/boot/uboot-hifiveu/Makefile @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2021 OpenWrt.org +# + +include $(TOPDIR)/rules.mk +include $(INCLUDE_DIR)/kernel.mk + +PKG_RELEASE:=1 +PKG_VERSION:=2021.07 + +PKG_HASH:=312b7eeae44581d1362c3a3f02c28d806647756c82ba8c72241c7cdbe68ba77e + +include $(INCLUDE_DIR)/u-boot.mk +include $(INCLUDE_DIR)/package.mk + +define U-Boot/Default + BUILD_TARGET:=hifiveu + BUILD_DEVICES=$(1) + UBOOT_IMAGE:=u-boot.itb + DTS_DIR:=arch/riscv/dts + UENV:=default + DEFAULT:=y +endef + +define U-Boot/sifive_unleashed + NAME:=SiFive Unleashed + OPENSBI:=generic + DEPENDS:=+opensbi_generic + UBOOT_DTS:=hifive-unleashed-a00.dtb + BUILD_DEVICES:=sifive_unleashed +endef + +define U-Boot/sifive_unmatched + NAME:=SiFive Unmatched + OPENSBI:=generic + DEPENDS:=+opensbi_generic + UBOOT_DTS:=hifive-unmatched-a00.dtb + BUILD_DEVICES:=sifive_unmatched +endef + +UBOOT_TARGETS := \ + sifive_unleashed \ + sifive_unmatched + +UBOOT_MAKE_FLAGS += \ + OPENSBI=$(STAGING_DIR_IMAGE)/fw_dynamic-${OPENSBI}.bin + +define Build/InstallDev + $(INSTALL_DIR) $(STAGING_DIR_IMAGE) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(UBOOT_IMAGE) $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE) + $(INSTALL_BIN) $(PKG_BUILD_DIR)/spl/u-boot-spl.bin $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-$(UBOOT_IMAGE)-spl + $(INSTALL_BIN) $(PKG_BUILD_DIR)/$(DTS_DIR)/$(UBOOT_DTS) $(STAGING_DIR_IMAGE)/$(UBOOT_DTS) + + mkimage -C none -A arm -T script -d uEnv-$(UENV).txt \ + $(STAGING_DIR_IMAGE)/$(BUILD_DEVICES)-boot.scr +endef + +$(eval $(call BuildPackage/U-Boot)) diff --git a/package/boot/uboot-hifiveu/patches/0001-riscv-sifive-unleashed-support-compressed-images.patch b/package/boot/uboot-hifiveu/patches/0001-riscv-sifive-unleashed-support-compressed-images.patch new file mode 100644 index 0000000000..6db22f9aa7 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0001-riscv-sifive-unleashed-support-compressed-images.patch @@ -0,0 +1,30 @@ +From 351fbd6208739d1a94fc11b2aa60d8a02d2f675a Mon Sep 17 00:00:00 2001 +From: David Abdurachmanov +Date: Mon, 13 Sep 2021 03:09:05 -0700 +Subject: [PATCH 01/16] riscv: sifive: unleashed: support compressed images + +Define kernel_comp_addr_r and kernel_comp_size to allow support for compressed +Image files for booti command. Note that we leave 128MiB for ramdisk and set +compressed kernel size for 64MiB. + +Signed-off-by: David Abdurachmanov +--- + include/configs/sifive-unleashed.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/configs/sifive-unleashed.h b/include/configs/sifive-unleashed.h +index 0d69d1c..5acce36 100644 +--- a/include/configs/sifive-unleashed.h ++++ b/include/configs/sifive-unleashed.h +@@ -71,6 +71,8 @@ + "script_size_f=0x1000\0" \ + "pxefile_addr_r=0x88200000\0" \ + "ramdisk_addr_r=0x88300000\0" \ ++ "kernel_comp_addr_r=0x90300000\0" \ ++ "kernel_comp_size=0x4000000\0" \ + "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0002-drivers-clk-sifive-fu740-prci-replace-pciaux-with-pc.patch b/package/boot/uboot-hifiveu/patches/0002-drivers-clk-sifive-fu740-prci-replace-pciaux-with-pc.patch new file mode 100644 index 0000000000..8178f10c67 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0002-drivers-clk-sifive-fu740-prci-replace-pciaux-with-pc.patch @@ -0,0 +1,51 @@ +From a3a717668b8158c555490921722c04ea6c07bf1a Mon Sep 17 00:00:00 2001 +From: Green Wan +Date: Mon, 28 Jun 2021 19:13:08 +0800 +Subject: [PATCH 02/16] drivers: clk: sifive: fu740-prci: replace 'pciaux' with + 'pcieaux' + +Replace 'pciaux' with 'pcieaux', including name string and function +prefix. The old name string, 'pciaux', might cause an error if PCIe +driver is changed to use clk_get_by_name() with 'pcieaux' to get +clock. + +Signed-off-by: Green Wan +Reviewed-by: Leo Yu-Chi Liang +--- + drivers/clk/sifive/fu740-prci.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/sifive/fu740-prci.c b/drivers/clk/sifive/fu740-prci.c +index 9a642c1..b025050 100644 +--- a/drivers/clk/sifive/fu740-prci.c ++++ b/drivers/clk/sifive/fu740-prci.c +@@ -20,7 +20,7 @@ + #include "sifive-prci.h" + #include + +-int sifive_prci_fu740_pciauxclk_enable(struct __prci_clock *pc, bool enable) ++int sifive_prci_fu740_pcieauxclk_enable(struct __prci_clock *pc, bool enable) + { + struct __prci_wrpll_data *pwd = pc->pwd; + struct __prci_data *pd = pc->pd; +@@ -98,7 +98,7 @@ static const struct __prci_clock_ops sifive_fu740_prci_hfpclkplldiv_clk_ops = { + }; + + static const struct __prci_clock_ops sifive_fu740_prci_pcieaux_clk_ops = { +- .enable_clk = sifive_prci_fu740_pciauxclk_enable, ++ .enable_clk = sifive_prci_fu740_pcieauxclk_enable, + }; + + /* List of clock controls provided by the PRCI */ +@@ -150,7 +150,7 @@ struct __prci_clock __prci_init_clocks_fu740[] = { + .ops = &sifive_fu740_prci_hfpclkplldiv_clk_ops, + }, + [PRCI_CLK_PCIEAUX] { +- .name = "pciaux", ++ .name = "pcieaux", + .parent_name = "", + .ops = &sifive_fu740_prci_pcieaux_clk_ops, + .pwd = &__prci_pcieaux_data, +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0003-board-sifive-unmatched-add-initial-support-for-a-pla.patch b/package/boot/uboot-hifiveu/patches/0003-board-sifive-unmatched-add-initial-support-for-a-pla.patch new file mode 100644 index 0000000000..348861ecea --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0003-board-sifive-unmatched-add-initial-support-for-a-pla.patch @@ -0,0 +1,601 @@ +From 3b4e1fd666cc156bf6d56da60d62dc063f75b7c4 Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Wed, 30 Jun 2021 23:23:45 +0800 +Subject: [PATCH 03/16] board: sifive: unmatched: add initial support for a + platform ID EEPROM + +Add initial support for the PCB description EEPROM for SiFive HiFive +Unmatched boards. + +This implementation is refactored based on Paul Walmsley's porting and +adopt the suggestions from David Abdurachmanov. + +Signed-off-by: Paul Walmsley +Signed-off-by: David Abdurachmanov +Signed-off-by: Zong Li +Reviewed-by: Leo Yu-Chi Liang +--- + board/sifive/unmatched/Makefile | 1 + + .../sifive/unmatched/hifive-platform-i2c-eeprom.c | 542 +++++++++++++++++++++ + include/configs/sifive-unmatched.h | 6 + + 3 files changed, 549 insertions(+) + create mode 100644 board/sifive/unmatched/hifive-platform-i2c-eeprom.c + +diff --git a/board/sifive/unmatched/Makefile b/board/sifive/unmatched/Makefile +index 6308c80..e00b330 100644 +--- a/board/sifive/unmatched/Makefile ++++ b/board/sifive/unmatched/Makefile +@@ -3,6 +3,7 @@ + # Copyright (c) 2020-2021 SiFive, Inc + + obj-y += unmatched.o ++obj-$(CONFIG_ID_EEPROM) += hifive-platform-i2c-eeprom.o + + ifdef CONFIG_SPL_BUILD + obj-y += spl.o +diff --git a/board/sifive/unmatched/hifive-platform-i2c-eeprom.c b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +new file mode 100644 +index 0000000..9a62d32 +--- /dev/null ++++ b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +@@ -0,0 +1,542 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 SiFive, Inc. ++ * ++ * Based on board/freescale/common/sys_eeprom.c: ++ * Copyright 2006, 2008-2009, 2011 Freescale Semiconductor ++ * York Sun (yorksun@freescale.com) ++ * Haiying Wang (haiying.wang@freescale.com) ++ * Timur Tabi (timur@freescale.com) ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef CONFIG_SYS_EEPROM_BUS_NUM ++#error Requires CONFIG_SYS_EEPROM_BUS_NUM to be defined ++#endif ++ ++#define FORMAT_VERSION 0x1 ++ ++/* Options for the manuf_test_status field */ ++#define SIFIVE_MANUF_TEST_STATUS_UNKNOWN 0 ++#define SIFIVE_MANUF_TEST_STATUS_PASS 1 ++#define SIFIVE_MANUF_TEST_STATUS_FAIL 2 ++ ++/* ++ * BYTES_PER_EEPROM_PAGE: the AT24C02 datasheet says that data can ++ * only be written in page mode, which means 8 bytes at a time ++ */ ++#define BYTES_PER_EEPROM_PAGE 8 ++ ++/* ++ * EEPROM_WRITE_DELAY_MS: the AT24C02 datasheet says it takes up to ++ * 5ms to complete a given write ++ */ ++#define EEPROM_WRITE_DELAY_MS 5000 ++ ++/* ++ * MAGIC_NUMBER_BYTES: number of bytes used by the magic number ++ */ ++#define MAGIC_NUMBER_BYTES 4 ++ ++/* ++ * SERIAL_NUMBER_BYTES: number of bytes used by the board serial ++ * number ++ */ ++#define SERIAL_NUMBER_BYTES 16 ++ ++/* ++ * MAC_ADDR_BYTES: number of bytes used by the Ethernet MAC address ++ */ ++#define MAC_ADDR_BYTES 6 ++ ++/* ++ * MAC_ADDR_STRLEN: length of mac address string ++ */ ++#define MAC_ADDR_STRLEN 17 ++ ++/* ++ * SiFive OUI. Registration Date is 2018-02-15 ++ */ ++#define SIFIVE_OUI_PREFIX "70:B3:D5:92:F" ++ ++/** ++ * static eeprom: EEPROM layout for the SiFive platform I2C format ++ */ ++static struct __attribute__ ((__packed__)) sifive_eeprom { ++ u8 magic[MAGIC_NUMBER_BYTES]; ++ u8 format_ver; ++ u16 product_id; ++ u8 pcb_revision; ++ u8 bom_revision; ++ u8 bom_variant; ++ u8 serial[SERIAL_NUMBER_BYTES]; ++ u8 manuf_test_status; ++ u8 mac_addr[MAC_ADDR_BYTES]; ++ u32 crc; ++} e; ++ ++struct sifive_product { ++ u16 id; ++ const char *name; ++}; ++ ++/* Set to 1 if we've read EEPROM into memory */ ++static int has_been_read; ++ ++/* Magic number at the first four bytes of EEPROM */ ++static const unsigned char magic[MAGIC_NUMBER_BYTES] = { 0xf1, 0x5e, 0x50, 0x45 }; ++ ++/* Does the magic number match that of a SiFive EEPROM? */ ++static inline int is_match_magic(void) ++{ ++ return (memcmp(&e.magic, &magic, MAGIC_NUMBER_BYTES) == 0); ++} ++ ++/* Calculate the current CRC */ ++static inline u32 calculate_crc32(void) ++{ ++ return crc32(0, (void *)&e, sizeof(struct sifive_eeprom) - sizeof(e.crc)); ++} ++ ++/* This function should be called after each update to the EEPROM structure */ ++static inline void update_crc(void) ++{ ++ e.crc = calculate_crc32(); ++} ++ ++static struct sifive_product sifive_products[] = { ++ { 0, "Unknown"}, ++ { 2, "HiFive Unmatched" }, ++}; ++ ++/** ++ * dump_raw_eeprom - display the raw contents of the EEPROM ++ */ ++static void dump_raw_eeprom(void) ++{ ++ unsigned int i; ++ ++ printf("EEPROM dump: (0x%lx bytes)\n", sizeof(e)); ++ for (i = 0; i < sizeof(e); i++) { ++ if ((i % 16) == 0) ++ printf("%02X: ", i); ++ printf("%02X ", ((u8 *)&e)[i]); ++ if (((i % 16) == 15) || (i == sizeof(e) - 1)) ++ printf("\n"); ++ } ++} ++ ++/** ++ * show_eeprom - display the contents of the EEPROM ++ */ ++static void show_eeprom(void) ++{ ++ unsigned int i; ++ u32 crc; ++ const char *product_name = "Unknown"; ++ char board_serial[SERIAL_NUMBER_BYTES + 1] = { 0 }; ++ ++ if (!is_match_magic()) { ++ printf("Not a SiFive HiFive EEPROM data format - magic bytes don't match\n"); ++ dump_raw_eeprom(); ++ return; ++ }; ++ ++ snprintf(board_serial, sizeof(board_serial), "%s", e.serial); ++ ++ for (i = 0; i < ARRAY_SIZE(sifive_products); i++) { ++ if (sifive_products[i].id == e.product_id) { ++ product_name = sifive_products[i].name; ++ break; ++ } ++ }; ++ ++ printf("SiFive PCB EEPROM format v%u\n", e.format_ver); ++ printf("Product ID: %04hx (%s)\n", e.product_id, product_name); ++ printf("PCB revision: %x\n", e.pcb_revision); ++ printf("BOM revision: %c\n", e.bom_revision); ++ printf("BOM variant: %x\n", e.bom_variant); ++ printf("Serial number: %s\n", board_serial); ++ printf("Ethernet MAC address: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ e.mac_addr[0], e.mac_addr[1], e.mac_addr[2], ++ e.mac_addr[3], e.mac_addr[4], e.mac_addr[5]); ++ ++ crc = calculate_crc32(); ++ if (crc == e.crc) { ++ printf("CRC: %08x\n", e.crc); ++ } else { ++ printf("CRC: %08x (should be %08x)\n", e.crc, crc); ++ dump_raw_eeprom(); ++ } ++} ++ ++/** ++ * read_eeprom() - read the EEPROM into memory, if it hasn't been read already ++ */ ++static int read_eeprom(void) ++{ ++ int ret; ++ struct udevice *dev; ++ ++ if (has_been_read) ++ return 0; ++ ++ ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, ++ CONFIG_SYS_I2C_EEPROM_ADDR, ++ 1, ++ &dev); ++ if (!ret) ++ dm_i2c_read(dev, 0, (void *)&e, ++ sizeof(struct sifive_eeprom)); ++ ++ show_eeprom(); ++ ++ has_been_read = (ret == 0) ? 1 : 0; ++ ++ return ret; ++} ++ ++/** ++ * prog_eeprom() - write the EEPROM from memory ++ */ ++static int prog_eeprom(void) ++{ ++ int ret = 0; ++ unsigned int i; ++ void *p; ++ ++ if (!is_match_magic()) { ++ printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n"); ++ return 0; ++ } ++ ++ for (i = 0, p = &e; i < sizeof(e); ++ i += BYTES_PER_EEPROM_PAGE, p += BYTES_PER_EEPROM_PAGE) { ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, ++ CONFIG_SYS_I2C_EEPROM_ADDR, ++ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, ++ &dev); ++ if (!ret) ++ ret = dm_i2c_write(dev, i, p, ++ min((int)(sizeof(e) - i), ++ BYTES_PER_EEPROM_PAGE)); ++ ++ if (ret) ++ break; ++ ++ udelay(EEPROM_WRITE_DELAY_MS); ++ } ++ ++ if (!ret) { ++ /* Verify the write by reading back the EEPROM and comparing */ ++ struct sifive_eeprom e2; ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, ++ CONFIG_SYS_I2C_EEPROM_ADDR, ++ CONFIG_SYS_I2C_EEPROM_ADDR_LEN, ++ &dev); ++ if (!ret) ++ ret = dm_i2c_read(dev, 0, (void *)&e2, sizeof(e2)); ++ if (!ret && memcmp(&e, &e2, sizeof(e))) ++ ret = -1; ++ } ++ ++ if (ret) { ++ printf("Programming failed.\n"); ++ has_been_read = 0; ++ return -1; ++ } ++ ++ printf("Programming passed.\n"); ++ return 0; ++} ++ ++/** ++ * set_mac_address() - stores a MAC address into the local EEPROM copy ++ * ++ * This function takes a pointer to MAC address string ++ * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number), ++ * stores it in the MAC address field of the EEPROM local copy, and ++ * updates the local copy of the CRC. ++ */ ++static void set_mac_address(char *string) ++{ ++ unsigned int i; ++ ++ if (strncasecmp(SIFIVE_OUI_PREFIX, string, 13)) { ++ printf("The MAC address doesn't match SiFive OUI %s\n", ++ SIFIVE_OUI_PREFIX); ++ return; ++ } ++ ++ for (i = 0; *string && (i < MAC_ADDR_BYTES); i++) { ++ e.mac_addr[i] = simple_strtoul(string, &string, 16); ++ if (*string == ':') ++ string++; ++ } ++ ++ update_crc(); ++} ++ ++/** ++ * set_manuf_test_status() - stores a test status byte into the in-memory copy ++ * ++ * Takes a pointer to a manufacturing test status string ("unknown", ++ * "pass", "fail") and stores the corresponding numeric ID to the ++ * manuf_test_status field of the EEPROM local copy, and updates the ++ * CRC of the local copy. ++ */ ++static void set_manuf_test_status(char *string) ++{ ++ if (!strcasecmp(string, "unknown")) { ++ e.manuf_test_status = SIFIVE_MANUF_TEST_STATUS_UNKNOWN; ++ } else if (!strcasecmp(string, "pass")) { ++ e.manuf_test_status = SIFIVE_MANUF_TEST_STATUS_PASS; ++ } else if (!strcasecmp(string, "fail")) { ++ e.manuf_test_status = SIFIVE_MANUF_TEST_STATUS_FAIL; ++ } else { ++ printf("Usage: mac manuf_test_status (unknown|pass|fail)\n"); ++ return; ++ } ++ ++ update_crc(); ++} ++ ++/** ++ * set_pcb_revision() - stores a SiFive PCB revision into the local EEPROM copy ++ * ++ * Takes a pointer to a string representing the numeric PCB revision in ++ * decimal ("0" - "255"), stores it in the pcb_revision field of the ++ * EEPROM local copy, and updates the CRC of the local copy. ++ */ ++static void set_pcb_revision(char *string) ++{ ++ unsigned long p; ++ ++ p = simple_strtoul(string, &string, 10); ++ if (p > U8_MAX) { ++ printf("%s must not be greater than %d\n", "PCB revision", ++ U8_MAX); ++ return; ++ } ++ ++ e.pcb_revision = p; ++ ++ update_crc(); ++} ++ ++/** ++ * set_bom_revision() - stores a SiFive BOM revision into the local EEPROM copy ++ * ++ * Takes a pointer to a uppercase ASCII character representing the BOM ++ * revision ("A" - "Z"), stores it in the bom_revision field of the ++ * EEPROM local copy, and updates the CRC of the local copy. ++ */ ++static void set_bom_revision(char *string) ++{ ++ if (string[0] < 'A' || string[0] > 'Z') { ++ printf("BOM revision must be an uppercase letter between A and Z\n"); ++ return; ++ } ++ ++ e.bom_revision = string[0]; ++ ++ update_crc(); ++} ++ ++/** ++ * set_bom_variant() - stores a SiFive BOM variant into the local EEPROM copy ++ * ++ * Takes a pointer to a string representing the numeric BOM variant in ++ * decimal ("0" - "255"), stores it in the bom_variant field of the ++ * EEPROM local copy, and updates the CRC of the local copy. ++ */ ++static void set_bom_variant(char *string) ++{ ++ unsigned long p; ++ ++ p = simple_strtoul(string, &string, 10); ++ if (p > U8_MAX) { ++ printf("%s must not be greater than %d\n", "BOM variant", ++ U8_MAX); ++ return; ++ } ++ ++ e.bom_variant = p; ++ ++ update_crc(); ++} ++ ++/** ++ * set_product_id() - stores a SiFive product ID into the local EEPROM copy ++ * ++ * Takes a pointer to a string representing the numeric product ID in ++ * decimal ("0" - "65535"), stores it in the product ID field of the ++ * EEPROM local copy, and updates the CRC of the local copy. ++ */ ++static void set_product_id(char *string) ++{ ++ unsigned long p; ++ ++ p = simple_strtoul(string, &string, 10); ++ if (p > U16_MAX) { ++ printf("%s must not be greater than %d\n", "Product ID", ++ U16_MAX); ++ return; ++ } ++ ++ e.product_id = p; ++ ++ update_crc(); ++} ++ ++/** ++ * set_serial_number() - set the PCB serial number in the in-memory copy ++ * ++ * Set the board serial number in the in-memory EEPROM copy from the supplied ++ * string argument, and update the CRC. ++ */ ++static void set_serial_number(char *string) ++{ ++ if (strlen(string) > SERIAL_NUMBER_BYTES) { ++ printf("Serial number must not be greater than 16 bytes\n"); ++ return; ++ } ++ ++ memset(e.serial, 0, sizeof(e.serial)); ++ strncpy((char *)e.serial, string, sizeof(e.serial)); ++ update_crc(); ++} ++ ++/** ++ * init_local_copy() - initialize the in-memory EEPROM copy ++ * ++ * Initialize the in-memory EEPROM copy with the magic number. Must ++ * be done when preparing to initialize a blank EEPROM, or overwrite ++ * one with a corrupted magic number. ++ */ ++static void init_local_copy(void) ++{ ++ memset(&e, 0, sizeof(e)); ++ memcpy(e.magic, magic, sizeof(e.magic)); ++ e.format_ver = FORMAT_VERSION; ++ update_crc(); ++} ++ ++int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ char *cmd; ++ ++ if (argc == 1) { ++ show_eeprom(); ++ return 0; ++ } ++ ++ if (argc > 3) ++ return cmd_usage(cmdtp); ++ ++ cmd = argv[1]; ++ ++ /* Commands with no argument */ ++ if (!strcmp(cmd, "read_eeprom")) { ++ read_eeprom(); ++ return 0; ++ } else if (!strcmp(cmd, "initialize")) { ++ init_local_copy(); ++ return 0; ++ } else if (!strcmp(cmd, "write_eeprom")) { ++ prog_eeprom(); ++ return 0; ++ } ++ ++ if (argc != 3) ++ return cmd_usage(cmdtp); ++ ++ if (!is_match_magic()) { ++ printf("Please read the EEPROM ('read_eeprom') and/or initialize the EEPROM ('initialize') first.\n"); ++ return 0; ++ } ++ ++ if (!strcmp(cmd, "serial_number")) { ++ set_serial_number(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "manuf_test_status")) { ++ set_manuf_test_status(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "mac_address")) { ++ set_mac_address(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "pcb_revision")) { ++ set_pcb_revision(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "bom_variant")) { ++ set_bom_variant(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "bom_revision")) { ++ set_bom_revision(argv[2]); ++ return 0; ++ } else if (!strcmp(cmd, "product_id")) { ++ set_product_id(argv[2]); ++ return 0; ++ } ++ ++ return cmd_usage(cmdtp); ++} ++ ++/** ++ * mac_read_from_eeprom() - read the MAC address from EEPROM ++ * ++ * This function reads the MAC address from EEPROM and sets the ++ * appropriate environment variables for each one read. ++ * ++ * The environment variables are only set if they haven't been set already. ++ * This ensures that any user-saved variables are never overwritten. ++ * ++ * This function must be called after relocation. ++ */ ++int mac_read_from_eeprom(void) ++{ ++ u32 crc; ++ char board_serial[SERIAL_NUMBER_BYTES + 1] = { 0 }; ++ ++ puts("EEPROM: "); ++ ++ if (read_eeprom()) { ++ printf("Read failed.\n"); ++ return 0; ++ } ++ ++ if (!is_match_magic()) { ++ printf("Invalid ID (%02x %02x %02x %02x)\n", ++ e.magic[0], e.magic[1], e.magic[2], e.magic[3]); ++ dump_raw_eeprom(); ++ return 0; ++ } ++ ++ crc = calculate_crc32(); ++ if (crc != e.crc) { ++ printf("CRC mismatch (%08x != %08x)\n", crc, e.crc); ++ dump_raw_eeprom(); ++ return 0; ++ } ++ ++ eth_env_set_enetaddr("ethaddr", e.mac_addr); ++ ++ if (!env_get("serial#")) { ++ snprintf(board_serial, sizeof(board_serial), "%s", e.serial); ++ env_set("serial#", board_serial); ++ } ++ ++ return 0; ++} +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index 4fad69b..9e1859c 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -80,4 +80,10 @@ + "fdt addr ${fdtcontroladdr};" + #endif /* CONFIG_SPL_BUILD */ + ++#define CONFIG_SYS_EEPROM_BUS_NUM 0 ++#define CONFIG_SYS_I2C_EEPROM_ADDR 0x54 ++#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 0x1 ++ ++#define CONFIG_ID_EEPROM ++ + #endif /* __SIFIVE_UNMATCHED_H */ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0004-riscv-sifive-fu740-kconfig-Enable-support-for-Openco.patch b/package/boot/uboot-hifiveu/patches/0004-riscv-sifive-fu740-kconfig-Enable-support-for-Openco.patch new file mode 100644 index 0000000000..7f21f3ea92 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0004-riscv-sifive-fu740-kconfig-Enable-support-for-Openco.patch @@ -0,0 +1,39 @@ +From feb5ac0bc029c8199bc29ab5b2ddf66eaa533843 Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Wed, 30 Jun 2021 23:23:46 +0800 +Subject: [PATCH 04/16] riscv: sifive: fu740: kconfig: Enable support for + Opencores I2C controller + +Enable the Opencores I2C controller on FU740 + +Signed-off-by: Zong Li +Reviewed-by: Leo Yu-Chi Liang +--- + arch/riscv/cpu/fu740/Kconfig | 2 ++ + board/sifive/unmatched/Kconfig | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/arch/riscv/cpu/fu740/Kconfig b/arch/riscv/cpu/fu740/Kconfig +index 3a5f6e4..1dc052b 100644 +--- a/arch/riscv/cpu/fu740/Kconfig ++++ b/arch/riscv/cpu/fu740/Kconfig +@@ -35,3 +35,5 @@ config SIFIVE_FU740 + imply SIFIVE_OTP + imply DM_PWM + imply PWM_SIFIVE ++ imply DM_I2C ++ imply SYS_I2C_OCORES +diff --git a/board/sifive/unmatched/Kconfig b/board/sifive/unmatched/Kconfig +index 88b5883..fb2c1fb 100644 +--- a/board/sifive/unmatched/Kconfig ++++ b/board/sifive/unmatched/Kconfig +@@ -47,5 +47,6 @@ config BOARD_SPECIFIC_OPTIONS # dummy + imply PHY_MSCC + imply SYSRESET + imply SYSRESET_GPIO ++ imply CMD_I2C + + endif +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0005-riscv-sifive-fu740-Support-i2c-in-spl.patch b/package/boot/uboot-hifiveu/patches/0005-riscv-sifive-fu740-Support-i2c-in-spl.patch new file mode 100644 index 0000000000..88f0f09c61 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0005-riscv-sifive-fu740-Support-i2c-in-spl.patch @@ -0,0 +1,42 @@ +From bda688c4b0cda4bd20ccf1d771f1f4285a9adf27 Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Wed, 30 Jun 2021 23:23:47 +0800 +Subject: [PATCH 05/16] riscv: sifive: fu740: Support i2c in spl + +Enable SPL_I2C_SUPPORT for fu740, and add 'u-boot,dm-spl' property in +i2c node. + +Signed-off-by: Zong Li +Reviewed-by: Leo Yu-Chi Liang +--- + arch/riscv/cpu/fu740/Kconfig | 1 + + arch/riscv/dts/fu740-c000-u-boot.dtsi | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/arch/riscv/cpu/fu740/Kconfig b/arch/riscv/cpu/fu740/Kconfig +index 1dc052b..8e54310 100644 +--- a/arch/riscv/cpu/fu740/Kconfig ++++ b/arch/riscv/cpu/fu740/Kconfig +@@ -37,3 +37,4 @@ config SIFIVE_FU740 + imply PWM_SIFIVE + imply DM_I2C + imply SYS_I2C_OCORES ++ imply SPL_I2C_SUPPORT +diff --git a/arch/riscv/dts/fu740-c000-u-boot.dtsi b/arch/riscv/dts/fu740-c000-u-boot.dtsi +index a5d0688..a6f7a08 100644 +--- a/arch/riscv/dts/fu740-c000-u-boot.dtsi ++++ b/arch/riscv/dts/fu740-c000-u-boot.dtsi +@@ -95,6 +95,10 @@ + u-boot,dm-spl; + }; + ++&i2c0 { ++ u-boot,dm-spl; ++}; ++ + ð0 { + assigned-clocks = <&prci PRCI_CLK_GEMGXLPLL>; + assigned-clock-rates = <125125000>; +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0006-board-sifive-Add-an-interface-to-get-PCB-revision.patch b/package/boot/uboot-hifiveu/patches/0006-board-sifive-Add-an-interface-to-get-PCB-revision.patch new file mode 100644 index 0000000000..2ea374016e --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0006-board-sifive-Add-an-interface-to-get-PCB-revision.patch @@ -0,0 +1,81 @@ +From cdecb59564d7b2f2f0a53a41e6933f63badb2def Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Wed, 30 Jun 2021 23:23:48 +0800 +Subject: [PATCH 06/16] board: sifive: Add an interface to get PCB revision + +There are different DDR parameter settings for different board +revisions. Add a new interface to get the PCB revision to determine +which DT should be selected at runtime. + +Signed-off-by: Zong Li +Reviewed-by: Leo Yu-Chi Liang +--- + arch/riscv/include/asm/arch-fu740/eeprom.h | 15 ++++++++++ + .../sifive/unmatched/hifive-platform-i2c-eeprom.c | 32 ++++++++++++++++++++++ + 2 files changed, 47 insertions(+) + create mode 100644 arch/riscv/include/asm/arch-fu740/eeprom.h + +diff --git a/arch/riscv/include/asm/arch-fu740/eeprom.h b/arch/riscv/include/asm/arch-fu740/eeprom.h +new file mode 100644 +index 0000000..0e1220e +--- /dev/null ++++ b/arch/riscv/include/asm/arch-fu740/eeprom.h +@@ -0,0 +1,15 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (C) 2021 SiFive, Inc. ++ * ++ * Zong Li ++ */ ++ ++#ifndef _ASM_RISCV_EEPROM_H ++#define _ASM_RISCV_EEPROM_H ++ ++#define PCB_REVISION_REV3 0x3 ++ ++u8 get_pcb_revision_from_eeprom(void); ++ ++#endif /* _ASM_RISCV_EEPROM_H */ +diff --git a/board/sifive/unmatched/hifive-platform-i2c-eeprom.c b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +index 9a62d32..a2151f1 100644 +--- a/board/sifive/unmatched/hifive-platform-i2c-eeprom.c ++++ b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +@@ -540,3 +540,35 @@ int mac_read_from_eeprom(void) + + return 0; + } ++ ++/** ++ * get_pcb_revision_from_eeprom - get the PCB revision ++ * ++ * Read the EEPROM to determine the board revision. ++ * ++ * This function is called before relocation, so we need to read a private ++ * copy of the EEPROM into a local variable on the stack. ++ */ ++u8 get_pcb_revision_from_eeprom(void) ++{ ++ struct __attribute__ ((__packed__)) board_eeprom { ++ u8 magic[MAGIC_NUMBER_BYTES]; ++ u8 format_ver; ++ u16 product_id; ++ u8 pcb_revision; ++ } be; ++ ++ int ret; ++ struct udevice *dev; ++ ++ ret = i2c_get_chip_for_busnum(CONFIG_SYS_EEPROM_BUS_NUM, ++ CONFIG_SYS_I2C_EEPROM_ADDR, ++ 1, ++ &dev); ++ ++ if (!ret) ++ dm_i2c_read(dev, 0, (void *)&be, ++ sizeof(struct board_eeprom)); ++ ++ return be.pcb_revision; ++} +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0007-board-sifive-remove-the-command-for-setting-serial-n.patch b/package/boot/uboot-hifiveu/patches/0007-board-sifive-remove-the-command-for-setting-serial-n.patch new file mode 100644 index 0000000000..bd37bed1f8 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0007-board-sifive-remove-the-command-for-setting-serial-n.patch @@ -0,0 +1,60 @@ +From e6b25cf93a9255a5c167ffab7a6e87c272a2b07d Mon Sep 17 00:00:00 2001 +From: Zong Li +Date: Fri, 9 Jul 2021 16:26:35 +0800 +Subject: [PATCH 07/16] board: sifive: remove the command for setting serial + number + +We wouldn't like to allow user to change the serial number, so remove +the command for changing serial number in EEPROM. + +Signed-off-by: Zong Li +Suggested-by: David Abdurachmanov +Reviewed-by: Leo Yu-Chi Liang +--- + .../sifive/unmatched/hifive-platform-i2c-eeprom.c | 23 +--------------------- + 1 file changed, 1 insertion(+), 22 deletions(-) + +diff --git a/board/sifive/unmatched/hifive-platform-i2c-eeprom.c b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +index a2151f1..ad2f315 100644 +--- a/board/sifive/unmatched/hifive-platform-i2c-eeprom.c ++++ b/board/sifive/unmatched/hifive-platform-i2c-eeprom.c +@@ -402,24 +402,6 @@ static void set_product_id(char *string) + } + + /** +- * set_serial_number() - set the PCB serial number in the in-memory copy +- * +- * Set the board serial number in the in-memory EEPROM copy from the supplied +- * string argument, and update the CRC. +- */ +-static void set_serial_number(char *string) +-{ +- if (strlen(string) > SERIAL_NUMBER_BYTES) { +- printf("Serial number must not be greater than 16 bytes\n"); +- return; +- } +- +- memset(e.serial, 0, sizeof(e.serial)); +- strncpy((char *)e.serial, string, sizeof(e.serial)); +- update_crc(); +-} +- +-/** + * init_local_copy() - initialize the in-memory EEPROM copy + * + * Initialize the in-memory EEPROM copy with the magic number. Must +@@ -468,10 +450,7 @@ int do_mac(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) + return 0; + } + +- if (!strcmp(cmd, "serial_number")) { +- set_serial_number(argv[2]); +- return 0; +- } else if (!strcmp(cmd, "manuf_test_status")) { ++ if (!strcmp(cmd, "manuf_test_status")) { + set_manuf_test_status(argv[2]); + return 0; + } else if (!strcmp(cmd, "mac_address")) { +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0008-board-sifive-unmatched-refine-GEMGXL-initialized-fun.patch b/package/boot/uboot-hifiveu/patches/0008-board-sifive-unmatched-refine-GEMGXL-initialized-fun.patch new file mode 100644 index 0000000000..00a8a403dc --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0008-board-sifive-unmatched-refine-GEMGXL-initialized-fun.patch @@ -0,0 +1,105 @@ +From 5f26d71202f37d77ecf74da2ce7e4c3a3f4d48d3 Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Thu, 8 Jul 2021 09:08:20 +0800 +Subject: [PATCH 08/16] board: sifive: unmatched: refine GEMGXL initialized + function in SPL + +Create a new function spl_reset_device_by_gpio to reset the device +whose reset pin is connected to the GPIO. Then, using this function +to initialize GEMGXL. + +Signed-off-by: Vincent Chen +--- + board/sifive/unmatched/spl.c | 58 +++++++++++++++++++++++++++++--------------- + 1 file changed, 39 insertions(+), 19 deletions(-) + +diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c +index 5e1333b..b598f9f 100644 +--- a/board/sifive/unmatched/spl.c ++++ b/board/sifive/unmatched/spl.c +@@ -22,43 +22,63 @@ + #define MODE_SELECT_SD 0xb + #define MODE_SELECT_MASK GENMASK(3, 0) + +-int spl_board_init_f(void) ++static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width) + { + int ret; + +- ret = spl_soc_init(); ++ ret = gpio_request(pin, label); + if (ret) { +- debug("HiFive Unmatched FU740 SPL init failed: %d\n", ret); ++ debug("%s gpio request failed: %d\n", label, ret); ++ return ret; ++ } ++ ++ ret = gpio_direction_output(pin, 1); ++ if (ret) { ++ debug("%s gpio direction set failed: %d\n", label, ret); + return ret; + } + ++ udelay(1); ++ ++ gpio_set_value(pin, 0); ++ udelay(low_width); ++ gpio_set_value(pin, 1); ++ ++ return ret; ++} ++ ++static inline int spl_gemgxl_init(void) ++{ ++ int ret; + /* + * GEMGXL init VSC8541 PHY reset sequence; + * leave pull-down active for 2ms + */ + udelay(2000); +- ret = gpio_request(GEM_PHY_RESET, "gem_phy_reset"); ++ ret = spl_reset_device_by_gpio("gem_phy_reset", GEM_PHY_RESET, 1); ++ mdelay(15); ++ ++ return ret; ++} ++ ++int spl_board_init_f(void) ++{ ++ int ret; ++ ++ ret = spl_soc_init(); + if (ret) { +- debug("gem_phy_reset gpio request failed: %d\n", ret); +- return ret; ++ debug("HiFive Unmatched FU740 SPL init failed: %d\n", ret); ++ goto end; + } + +- /* Set GPIO 12 (PHY NRESET) */ +- ret = gpio_direction_output(GEM_PHY_RESET, 1); ++ ret = spl_gemgxl_init(); + if (ret) { +- debug("gem_phy_reset gpio direction set failed: %d\n", ret); +- return ret; ++ debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret); ++ goto end; + } + +- udelay(1); +- +- /* Reset PHY again to enter unmanaged mode */ +- gpio_set_value(GEM_PHY_RESET, 0); +- udelay(1); +- gpio_set_value(GEM_PHY_RESET, 1); +- mdelay(15); +- +- return 0; ++end: ++ return ret; + } + + u32 spl_boot_device(void) +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0009-board-sifive-unmatched-reset-USB-hub-PCIe-USB-bridge.patch b/package/boot/uboot-hifiveu/patches/0009-board-sifive-unmatched-reset-USB-hub-PCIe-USB-bridge.patch new file mode 100644 index 0000000000..6a82840019 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0009-board-sifive-unmatched-reset-USB-hub-PCIe-USB-bridge.patch @@ -0,0 +1,78 @@ +From 01f3996f6f3ad9b7d26bc7620af44aa063bd01b1 Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Thu, 8 Jul 2021 09:08:21 +0800 +Subject: [PATCH 09/16] board: sifive: unmatched: reset USB hub, PCIe-USB + bridge, and ULPI device in SPL + +Ensure USB hub, PCIe-USB bridge, and ULPI device to be reset +even if the rebooting is without power-cycling. + +Signed-off-by: Vincent Chen +--- + board/sifive/unmatched/spl.c | 36 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 36 insertions(+) + +diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c +index b598f9f..d566327 100644 +--- a/board/sifive/unmatched/spl.c ++++ b/board/sifive/unmatched/spl.c +@@ -16,6 +16,9 @@ + #include + #include + ++#define UBRDG_RESET SIFIVE_GENERIC_GPIO_NR(0, 7) ++#define ULPI_RESET SIFIVE_GENERIC_GPIO_NR(0, 9) ++#define UHUB_RESET SIFIVE_GENERIC_GPIO_NR(0, 11) + #define GEM_PHY_RESET SIFIVE_GENERIC_GPIO_NR(0, 12) + + #define MODE_SELECT_REG 0x1000 +@@ -61,6 +64,21 @@ static inline int spl_gemgxl_init(void) + return ret; + } + ++static inline int spl_usb_pcie_bridge_init(void) ++{ ++ return spl_reset_device_by_gpio("usb_pcie_bridge_reset", UBRDG_RESET, 3000); ++} ++ ++static inline int spl_usb_hub_init(void) ++{ ++ return spl_reset_device_by_gpio("usb_hub_reset", UHUB_RESET, 100); ++} ++ ++static inline int spl_ulpi_init(void) ++{ ++ return spl_reset_device_by_gpio("ulpi_reset", ULPI_RESET, 1); ++} ++ + int spl_board_init_f(void) + { + int ret; +@@ -77,6 +95,24 @@ int spl_board_init_f(void) + goto end; + } + ++ ret = spl_usb_pcie_bridge_init(); ++ if (ret) { ++ debug("USB Bridge (ASM1042A) init failed: %d\n", ret); ++ goto end; ++ } ++ ++ ret = spl_usb_hub_init(); ++ if (ret) { ++ debug("USB Hub (ASM1074) init failed: %d\n", ret); ++ goto end; ++ } ++ ++ ret = spl_ulpi_init(); ++ if (ret) { ++ debug("USB 2.0 PHY (USB3320C) init failed: %d\n", ret); ++ goto end; ++ } ++ + end: + return ret; + } +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0010-board-sifive-spl-Initialized-the-PWM-setting-in-the-.patch b/package/boot/uboot-hifiveu/patches/0010-board-sifive-spl-Initialized-the-PWM-setting-in-the-.patch new file mode 100644 index 0000000000..53eae73887 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0010-board-sifive-spl-Initialized-the-PWM-setting-in-the-.patch @@ -0,0 +1,89 @@ +From ac71430a203ae7073d92c5f3026f0863e6b7e22b Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Fri, 26 Mar 2021 13:58:59 +0800 +Subject: [PATCH 10/16] board: sifive: spl: Initialized the PWM setting in the + SPL stage + +LEDs and multiple fans can be controlled by SPL. This patch ensures +that all fans have been enabled in the SPL stage. In addition, the +LED's color will be set to yellow. +--- + board/sifive/unmatched/spl.c | 2 ++ + board/sifive/unmatched/unmatched.c | 48 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 50 insertions(+) + +diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c +index d566327..3c3b22d 100644 +--- a/board/sifive/unmatched/spl.c ++++ b/board/sifive/unmatched/spl.c +@@ -89,6 +89,8 @@ int spl_board_init_f(void) + goto end; + } + ++ pwm_device_init(); ++ + ret = spl_gemgxl_init(); + if (ret) { + debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret); +diff --git a/board/sifive/unmatched/unmatched.c b/board/sifive/unmatched/unmatched.c +index 6d60559..9924da9 100644 +--- a/board/sifive/unmatched/unmatched.c ++++ b/board/sifive/unmatched/unmatched.c +@@ -9,6 +9,54 @@ + #include + #include + #include ++#include ++#include ++ ++struct pwm_sifive_regs { ++ unsigned int cfg; /* PWM configuration register */ ++ unsigned int pad0; /* Reserved */ ++ unsigned int cnt; /* PWM count register */ ++ unsigned int pad1; /* Reserved */ ++ unsigned int pwms; /* Scaled PWM count register */ ++ unsigned int pad2; /* Reserved */ ++ unsigned int pad3; /* Reserved */ ++ unsigned int pad4; /* Reserved */ ++ unsigned int cmp0; /* PWM 0 compare register */ ++ unsigned int cmp1; /* PWM 1 compare register */ ++ unsigned int cmp2; /* PWM 2 compare register */ ++ unsigned int cmp3; /* PWM 3 compare register */ ++}; ++ ++#define PWM0_BASE 0x10020000 ++#define PWM1_BASE 0x10021000 ++#define PWM_CFG_INIT 0x1000 ++#define PWM_CMP_ENABLE_VAL 0x0 ++#define PWM_CMP_DISABLE_VAL 0xffff ++ ++void pwm_device_init(void) ++{ ++ struct pwm_sifive_regs *pwm0, *pwm1; ++ pwm0 = (struct pwm_sifive_regs *)PWM0_BASE; ++ pwm1 = (struct pwm_sifive_regs *)PWM1_BASE; ++ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0); ++ /* Set the 3-color PWM LEDs to yellow in SPL */ ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1); ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2); ++ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3); ++ writel(PWM_CFG_INIT, (void *)&pwm0->cfg); ++ ++ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3); ++ /* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */ ++ /* The SoC fan(J21) on the rev3 board cannot be controled by PWM_COMP0, ++ so here sets the initial value of PWM_COMP0 as DISABLE */ ++ if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3) ++ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1); ++ else ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1); ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2); ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3); ++ writel(PWM_CFG_INIT, (void *)&pwm1->cfg); ++} + + int board_init(void) + { +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0011-board-sifive-Set-LED-s-color-to-purple-in-the-U-boot.patch b/package/boot/uboot-hifiveu/patches/0011-board-sifive-Set-LED-s-color-to-purple-in-the-U-boot.patch new file mode 100644 index 0000000000..110eeee7cb --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0011-board-sifive-Set-LED-s-color-to-purple-in-the-U-boot.patch @@ -0,0 +1,59 @@ +From d2753e049b571796bb7e9290c7740c772122a3b1 Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Fri, 26 Mar 2021 14:10:02 +0800 +Subject: [PATCH 11/16] board: sifive: Set LED's color to purple in the U-boot + stage + +Set LED's color to purple in the U-boot stage. Because there are still +some functions to be executed before board_early_init_f(), it means +the LED's is not changed to purple instantly when entering the U-boot +stage. +--- + board/sifive/unmatched/unmatched.c | 14 ++++++++++++++ + configs/sifive_unmatched_defconfig | 1 + + 2 files changed, 15 insertions(+) + +diff --git a/board/sifive/unmatched/unmatched.c b/board/sifive/unmatched/unmatched.c +index 9924da9..5183f7f 100644 +--- a/board/sifive/unmatched/unmatched.c ++++ b/board/sifive/unmatched/unmatched.c +@@ -38,6 +38,7 @@ void pwm_device_init(void) + struct pwm_sifive_regs *pwm0, *pwm1; + pwm0 = (struct pwm_sifive_regs *)PWM0_BASE; + pwm1 = (struct pwm_sifive_regs *)PWM1_BASE; ++#ifdef CONFIG_SPL_BUILD + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0); + /* Set the 3-color PWM LEDs to yellow in SPL */ + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1); +@@ -56,6 +57,19 @@ void pwm_device_init(void) + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2); + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3); + writel(PWM_CFG_INIT, (void *)&pwm1->cfg); ++#else ++ /* Set the 3-color PWM LEDs to purple in U-boot */ ++ writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp1); ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2); ++ writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp3); ++#endif ++ ++} ++ ++int board_early_init_f(void) ++{ ++ pwm_device_init(); ++ return 0; + } + + int board_init(void) +diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig +index 4c26504..cf08955 100644 +--- a/configs/sifive_unmatched_defconfig ++++ b/configs/sifive_unmatched_defconfig +@@ -40,3 +40,4 @@ CONFIG_USB=y + CONFIG_DM_USB=y + CONFIG_USB_XHCI_HCD=y + CONFIG_USB_XHCI_PCI=y ++CONFIG_BOARD_EARLY_INIT_F=y +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0012-board-sifive-Set-LED-s-color-to-blue-before-jumping-.patch b/package/boot/uboot-hifiveu/patches/0012-board-sifive-Set-LED-s-color-to-blue-before-jumping-.patch new file mode 100644 index 0000000000..360c0b3c65 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0012-board-sifive-Set-LED-s-color-to-blue-before-jumping-.patch @@ -0,0 +1,35 @@ +From 0c0bc1969d89e9b8425641436db706cfac57cf45 Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Fri, 26 Mar 2021 14:07:58 +0800 +Subject: [PATCH 12/16] board: sifive: Set LED's color to blue before jumping + to Linux + +The LED's color wil be changed from purple to blue before executing +the sysboot command. Because the sysboot command includes the image loading +from the boot partition, It means the LED's color is blue when executing +"Retrieving file: /Image.gz". +--- + include/configs/sifive-unmatched.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index 9e1859c..fd93e89 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -73,7 +73,12 @@ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ + "partitions=" PARTS_DEFAULT "\0" \ +- BOOTENV ++ "setled_blue=mw.l 0x10020024 0x0000ffff; mw.l 0x10020028 0x0000ffff; mw.l 0x1002002c 0x0\0" \ ++ BOOTENV \ ++ "boot_extlinux=" \ ++ "run setled_blue; " \ ++ "sysboot ${devtype} ${devnum}:${distro_bootpart} any " \ ++ "${scriptaddr} ${prefix}${boot_syslinux_conf};\0" + + #define CONFIG_PREBOOT \ + "setenv fdt_addr ${fdtcontroladdr};" \ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0013-board-sifive-spl-Set-remote-thermal-of-TMP451-to-85-.patch b/package/boot/uboot-hifiveu/patches/0013-board-sifive-spl-Set-remote-thermal-of-TMP451-to-85-.patch new file mode 100644 index 0000000000..d4a2dc4ab1 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0013-board-sifive-spl-Set-remote-thermal-of-TMP451-to-85-.patch @@ -0,0 +1,128 @@ +From 6265d23e2f9fdc0e33074a28d52a894b6be2b19d Mon Sep 17 00:00:00 2001 +From: Vincent Chen +Date: Mon, 17 May 2021 16:21:13 +0800 +Subject: [PATCH 13/16] board: sifive: spl: Set remote thermal of TMP451 to 85 + deg C for the unmatched board + +For TMP451 on the unmatched board, the default value of the remote thermal +threshold is 108 deg C. This commit initilizes it to 85 deg C at SPL. + +Signed-off-by: Vincent Chen +--- + board/sifive/unmatched/spl.c | 29 +++++++++++++++++++++++++++++ + drivers/misc/Kconfig | 10 ++++++++++ + include/configs/sifive-unmatched.h | 3 +++ + scripts/config_whitelist.txt | 1 + + 4 files changed, 43 insertions(+) + +diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c +index 3c3b22d..7d59ca0 100644 +--- a/board/sifive/unmatched/spl.c ++++ b/board/sifive/unmatched/spl.c +@@ -10,6 +10,8 @@ + #include + #include + #include ++#include ++#include + #include + #include + #include +@@ -25,6 +27,27 @@ + #define MODE_SELECT_SD 0xb + #define MODE_SELECT_MASK GENMASK(3, 0) + ++#define TMP451_REMOTE_THERM_LIMIT_REG_OFFSET 0x19 ++#define TMP451_RETMOE_THERM_LIMIT_INIT_VALUE 0x55 ++ ++static inline int init_tmp451_remote_therm_limit(void) ++{ ++ struct udevice *dev; ++ unsigned char r_therm_limit = TMP451_RETMOE_THERM_LIMIT_INIT_VALUE; ++ int ret; ++ ++ ret = i2c_get_chip_for_busnum(CONFIG_SYS_TMP451_BUS_NUM, ++ CONFIG_SYS_I2C_TMP451_ADDR, ++ CONFIG_SYS_I2C_TMP451_ADDR_LEN, ++ &dev); ++ ++ if (!ret) ++ ret = dm_i2c_write(dev, TMP451_REMOTE_THERM_LIMIT_REG_OFFSET, ++ &r_therm_limit, ++ sizeof(unsigned char)); ++ return ret; ++} ++ + static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width) + { + int ret; +@@ -91,6 +114,12 @@ int spl_board_init_f(void) + + pwm_device_init(); + ++ ret = init_tmp451_remote_therm_limit(); ++ if (ret) { ++ debug("TMP451 remote THERM limit init failed: %d\n", ret); ++ goto end; ++ } ++ + ret = spl_gemgxl_init(); + if (ret) { + debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret); +diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig +index 997b713..2878313 100644 +--- a/drivers/misc/Kconfig ++++ b/drivers/misc/Kconfig +@@ -404,6 +404,10 @@ config SYS_I2C_EEPROM_ADDR + hex "Chip address of the EEPROM device" + default 0 + ++config SYS_I2C_TMP451_ADDR ++ hex "Chip address of the TMP451 device" ++ default 0 ++ + config SYS_I2C_EEPROM_BUS + int "I2C bus of the EEPROM device." + default 0 +@@ -429,6 +433,12 @@ config SYS_I2C_EEPROM_ADDR_LEN + help + Note: This is NOT the chip address length! + ++config SYS_I2C_TMP451_ADDR_LEN ++ int "Length in bytes of the TMP451 memory array address" ++ default 1 ++ help ++ Note: This is NOT the chip address length! ++ + config SYS_I2C_EEPROM_ADDR_OVERFLOW + hex "EEPROM Address Overflow" + default 0 +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index fd93e89..f75cf9b 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -88,6 +88,9 @@ + #define CONFIG_SYS_EEPROM_BUS_NUM 0 + #define CONFIG_SYS_I2C_EEPROM_ADDR 0x54 + #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 0x1 ++#define CONFIG_SYS_TMP451_BUS_NUM 0 ++#define CONFIG_SYS_I2C_TMP451_ADDR 0x4c ++#define CONFIG_SYS_I2C_TMP451_ADDR_LEN 0x1 + + #define CONFIG_ID_EEPROM + +diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt +index 3dbcc04..a0005fe 100644 +--- a/scripts/config_whitelist.txt ++++ b/scripts/config_whitelist.txt +@@ -3550,6 +3550,7 @@ CONFIG_SYS_TIMER_COUNTER + CONFIG_SYS_TIMER_COUNTS_DOWN + CONFIG_SYS_TIMER_PRESCALER + CONFIG_SYS_TIMER_RATE ++CONFIG_SYS_TMP451_BUS_NUM + CONFIG_SYS_TMPVIRT + CONFIG_SYS_TMRINTR_MASK + CONFIG_SYS_TMRINTR_NO +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0014-riscv-sifive-Set-default-fdtfile-names.patch b/package/boot/uboot-hifiveu/patches/0014-riscv-sifive-Set-default-fdtfile-names.patch new file mode 100644 index 0000000000..278efd5439 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0014-riscv-sifive-Set-default-fdtfile-names.patch @@ -0,0 +1,77 @@ +From 78cd21523e6c83d42a3e3c8bf01a84b9850b2a5f Mon Sep 17 00:00:00 2001 +From: Dimitri John Ledkov +Date: Wed, 14 Jul 2021 09:19:48 -0700 +Subject: [PATCH 14/16] riscv: sifive: Set default fdtfile names + +Set default fdtfile names for unleashed and unmatched boards, as used +in the upstream Linux kernel. This allows sysboot command to find and +load appropriate dtb for the matching kernel from universal stock +Ubuntu RISC-V rootfs images based on fdtdir setting in extlinux.conf. + +Signed-off-by: Dimitri John Ledkov +Reviewed-by: Leo Yu-Chi Liang +Reviewed-by: Bin Meng +cc: Paul Walmsley +cc: Palmer Dabbelt +cc: Anup Patel +cc: Atish Patra +cc: Pragnesh Patel +cc: Green Wan +--- + configs/sifive_unleashed_defconfig | 1 + + configs/sifive_unmatched_defconfig | 1 + + include/configs/sifive-unleashed.h | 1 + + include/configs/sifive-unmatched.h | 1 + + 4 files changed, 4 insertions(+) + +diff --git a/configs/sifive_unleashed_defconfig b/configs/sifive_unleashed_defconfig +index 5bf40ce..d665c8f 100644 +--- a/configs/sifive_unleashed_defconfig ++++ b/configs/sifive_unleashed_defconfig +@@ -14,6 +14,7 @@ CONFIG_RISCV_SMODE=y + CONFIG_DISTRO_DEFAULTS=y + CONFIG_FIT=y + CONFIG_SPL_LOAD_FIT_ADDRESS=0x84000000 ++CONFIG_DEFAULT_FDT_FILE="sifive/hifive-unleashed-a00.dtb" + CONFIG_DISPLAY_CPUINFO=y + CONFIG_DISPLAY_BOARDINFO=y + CONFIG_MISC_INIT_R=y +diff --git a/configs/sifive_unmatched_defconfig b/configs/sifive_unmatched_defconfig +index cf08955..bdf90ec 100644 +--- a/configs/sifive_unmatched_defconfig ++++ b/configs/sifive_unmatched_defconfig +@@ -14,6 +14,7 @@ CONFIG_RISCV_SMODE=y + CONFIG_DISTRO_DEFAULTS=y + CONFIG_FIT=y + CONFIG_SPL_LOAD_FIT_ADDRESS=0x84000000 ++CONFIG_DEFAULT_FDT_FILE="sifive/hifive-unmatched-a00.dtb" + CONFIG_DISPLAY_CPUINFO=y + CONFIG_DISPLAY_BOARDINFO=y + CONFIG_DISPLAY_BOARDINFO_LATE=y +diff --git a/include/configs/sifive-unleashed.h b/include/configs/sifive-unleashed.h +index 5acce36..db0ebaf 100644 +--- a/include/configs/sifive-unleashed.h ++++ b/include/configs/sifive-unleashed.h +@@ -77,6 +77,7 @@ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ + "partitions=" PARTS_DEFAULT "\0" \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ + BOOTENV \ + BOOTENV_SF + +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index f75cf9b..7157295 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -73,6 +73,7 @@ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ + "type_guid_gpt_system=" TYPE_GUID_SYSTEM "\0" \ + "partitions=" PARTS_DEFAULT "\0" \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ + "setled_blue=mw.l 0x10020024 0x0000ffff; mw.l 0x10020028 0x0000ffff; mw.l 0x1002002c 0x0\0" \ + BOOTENV \ + "boot_extlinux=" \ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0015-riscv-sifive-unmatched-leave-128MiB-for-ramdisk.patch b/package/boot/uboot-hifiveu/patches/0015-riscv-sifive-unmatched-leave-128MiB-for-ramdisk.patch new file mode 100644 index 0000000000..514dff5466 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0015-riscv-sifive-unmatched-leave-128MiB-for-ramdisk.patch @@ -0,0 +1,29 @@ +From 5f543ecf0d976d139de1bea274f4ea7759e4d932 Mon Sep 17 00:00:00 2001 +From: David Abdurachmanov +Date: Mon, 13 Sep 2021 03:15:35 -0700 +Subject: [PATCH 15/16] riscv: sifive: unmatched: leave 128MiB for ramdisk + +The current configuration only allows 125MiB, but the max allowed size should +be 128MiB. + +Signed-off-by: David Abdurachmanov +--- + include/configs/sifive-unmatched.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index 7157295..7254e06 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -67,7 +67,7 @@ + "scriptaddr=0x88100000\0" \ + "pxefile_addr_r=0x88200000\0" \ + "ramdisk_addr_r=0x88300000\0" \ +- "kernel_comp_addr_r=0x90000000\0" \ ++ "kernel_comp_addr_r=0x90300000\0" \ + "kernel_comp_size=0x4000000\0" \ + "type_guid_gpt_loader1=" TYPE_GUID_LOADER1 "\0" \ + "type_guid_gpt_loader2=" TYPE_GUID_LOADER2 "\0" \ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/0016-riscv-sifive-unmatched-disable-FDT-and-initrd-reloca.patch b/package/boot/uboot-hifiveu/patches/0016-riscv-sifive-unmatched-disable-FDT-and-initrd-reloca.patch new file mode 100644 index 0000000000..4c7e1715cf --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/0016-riscv-sifive-unmatched-disable-FDT-and-initrd-reloca.patch @@ -0,0 +1,35 @@ +From 1998aacd5faef21c665fa7b4771aeb9193bfd247 Mon Sep 17 00:00:00 2001 +From: David Abdurachmanov +Date: Mon, 13 Sep 2021 03:22:32 -0700 +Subject: [PATCH 16/16] riscv: sifive: unmatched: disable FDT and initrd + relocation + +Same as on SiFive Unleashed we need to disable fdt and initrd relocation. Tom +Rini mentined 18 days ago that it's most likely due to RISC-V lacking +`arch_lmb_reserve` implementation. + +The patch seems to be submitted now: +[PATCH 09/12] lmb: riscv: Add arch_lmb_reserve() +https://lists.denx.de/pipermail/u-boot/2021-September/460333.html + +Signed-off-by: David Abdurachmanov +--- + include/configs/sifive-unmatched.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/configs/sifive-unmatched.h b/include/configs/sifive-unmatched.h +index 7254e06..3b72304 100644 +--- a/include/configs/sifive-unmatched.h ++++ b/include/configs/sifive-unmatched.h +@@ -62,6 +62,8 @@ + "name=system,size=-,bootable,type=${type_guid_gpt_system};" + + #define CONFIG_EXTRA_ENV_SETTINGS \ ++ "fdt_high=0xffffffffffffffff\0" \ ++ "initrd_high=0xffffffffffffffff\0" \ + "kernel_addr_r=0x84000000\0" \ + "fdt_addr_r=0x88000000\0" \ + "scriptaddr=0x88100000\0" \ +-- +2.7.4 + diff --git a/package/boot/uboot-hifiveu/patches/100-mkimage-check-environment-for-dtc-binary-location.patch b/package/boot/uboot-hifiveu/patches/100-mkimage-check-environment-for-dtc-binary-location.patch new file mode 100644 index 0000000000..482aa1a369 --- /dev/null +++ b/package/boot/uboot-hifiveu/patches/100-mkimage-check-environment-for-dtc-binary-location.patch @@ -0,0 +1,35 @@ +From 637800493945ffed2f454756300437a4ec86e3b1 Mon Sep 17 00:00:00 2001 +From: Hauke Mehrtens +Date: Wed, 19 Jul 2017 22:23:15 +0200 +Subject: mkimage: check environment for dtc binary location + +Currently mkimage assumes the dtc binary is in the path and fails +otherwise. This patch makes it check the DTC environment variable first +for the dtc binary and then fall back to the default path. This makes +it possible to call the u-boot build with make DTC=... and build a fit +image with the dtc binary not being the the default path. + +Signed-off-by: Hauke Mehrtens +Cc: Simon Glass +--- + tools/fit_image.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/tools/fit_image.c ++++ b/tools/fit_image.c +@@ -726,9 +726,14 @@ static int fit_handle_file(struct image_ + } + *cmd = '\0'; + } else if (params->datafile) { ++ const char* dtc = getenv("DTC"); ++ ++ if (!dtc) ++ dtc = MKIMAGE_DTC; ++ + /* dtc -I dts -O dtb -p 500 -o tmpfile datafile */ + snprintf(cmd, sizeof(cmd), "%s %s -o \"%s\" \"%s\"", +- MKIMAGE_DTC, params->dtc, tmpfile, params->datafile); ++ dtc, params->dtc, tmpfile, params->datafile); + debug("Trying to execute \"%s\"\n", cmd); + } else { + snprintf(cmd, sizeof(cmd), "cp \"%s\" \"%s\"", diff --git a/package/boot/uboot-hifiveu/uEnv-default.txt b/package/boot/uboot-hifiveu/uEnv-default.txt new file mode 100644 index 0000000000..01dc51f85d --- /dev/null +++ b/package/boot/uboot-hifiveu/uEnv-default.txt @@ -0,0 +1,4 @@ +setenv loadkernel fatload mmc 0:3 \$kernel_addr_r uImage +setenv bootargs console=ttySIF0,115200 earlycon=sbi root=/dev/mmcblk0p4 rootwait +setenv uenvcmd run loadkernel \&\& bootm \$kernel_addr_r +run uenvcmd