GK SDK 源码库: XMIPCLinuxV100R005C00SPC030 (kernel/tools/open_source excluded)

This commit is contained in:
lai
2026-09-06 03:52:57 +08:00
commit b1928b41c0
21813 changed files with 4413081 additions and 0 deletions
@@ -0,0 +1,9 @@
if TARGET_NSIM
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "nsim"
endif
@@ -0,0 +1,8 @@
- BOARD
M: Alexey Brodkin <abrodkin@synopsys.com>
S: Maintained
F: include/configs/nsim.h
F: configs/nsim_700_defconfig
F: configs/nsim_700be_defconfig
F: configs/nsim_hs38_defconfig
F: configs/nsim_hs38be_defconfig
@@ -0,0 +1,12 @@
if TARGET_AXS101 || TARGET_AXS103
config SYS_BOARD
default "axs10x"
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "axs10x"
endif
@@ -0,0 +1,7 @@
AXS10X BOARD
M: Alexey Brodkin <abrodkin@synopsys.com>
S: Maintained
F: board/synopsys/axs10x/
F: include/configs/axs10x.h
F: configs/axs101_defconfig
F: configs/axs103_defconfig
@@ -0,0 +1,5 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2013-2016 Synopsys, Inc. All rights reserved.
obj-y += axs10x.o
@@ -0,0 +1,91 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
*/
#include <common.h>
#include <cpu_func.h>
#include <dwmmc.h>
#include <malloc.h>
#include <asm/arcregs.h>
#include "axs10x.h"
DECLARE_GLOBAL_DATA_PTR;
#define AXS_MB_CREG 0xE0011000
int board_early_init_f(void)
{
if (readl((void __iomem *)AXS_MB_CREG + 0x234) & (1 << 28))
gd->board_type = AXS_MB_V3;
else
gd->board_type = AXS_MB_V2;
return 0;
}
#ifdef CONFIG_ISA_ARCV2
void board_jump_and_run(ulong entry, int zero, int arch, uint params)
{
void (*kernel_entry)(int zero, int arch, uint params);
kernel_entry = (void (*)(int, int, uint))entry;
smp_set_core_boot_addr(entry, -1);
smp_kick_all_cpus();
kernel_entry(zero, arch, params);
}
#define RESET_VECTOR_ADDR 0x0
void smp_set_core_boot_addr(unsigned long addr, int corenr)
{
/* All cores have reset vector pointing to 0 */
writel(addr, (void __iomem *)RESET_VECTOR_ADDR);
/* Make sure other cores see written value in memory */
flush_dcache_all();
}
void smp_kick_all_cpus(void)
{
/* CPU start CREG */
#define AXC003_CREG_CPU_START 0xF0001400
/* Bits positions in CPU start CREG */
#define BITS_START 0
#define BITS_START_MODE 4
#define BITS_CORE_SEL 9
/*
* In axs103 v1.1 START bits semantics has changed quite a bit.
* We used to have a generic START bit for all cores selected by CORE_SEL mask.
* But now we don't touch CORE_SEL at all because we have a dedicated START bit
* for each core:
* bit 0: Core 0 (master)
* bit 1: Core 1 (slave)
*/
#define BITS_START_CORE1 1
#define ARCVER_HS38_3_0 0x53
int core_family = read_aux_reg(ARC_AUX_IDENTITY) & 0xff;
int cmd = readl((void __iomem *)AXC003_CREG_CPU_START);
if (core_family < ARCVER_HS38_3_0) {
cmd |= (1 << BITS_CORE_SEL) | (1 << BITS_START);
cmd &= ~(1 << BITS_START_MODE);
} else {
cmd |= (1 << BITS_START_CORE1);
}
writel(cmd, (void __iomem *)AXC003_CREG_CPU_START);
}
#endif
int checkboard(void)
{
printf("Board: ARC Software Development Platform AXS%s\n",
is_isa_arcv2() ? "103" : "101");
return 0;
};
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2015 Synopsys, Inc. All rights reserved.
*/
#ifndef _BOARD_SYNOPSYS_AXS10X_H
#define _BOARD_SYNOPSYS_AXS10X_H
enum {
AXS_MB_V2,
AXS_MB_V3
};
#endif /* _BOARD_SYNOPSYS_AXS10X_H */
@@ -0,0 +1,23 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
bsp-generate: u-boot u-boot.bin
ifdef CONFIG_ISA_ARCV2
$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-axs.py \
--header-type v2 \
--arc-id 0x53 \
--spi-flash-offset 0x200000 \
--image $(srctree)/u-boot.bin \
--elf $(srctree)/u-boot
else
$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-axs.py \
--header-type v1 \
--arc-id 0x434 \
--spi-flash-offset 0x0 \
--image $(srctree)/u-boot.bin \
--elf $(srctree)/u-boot
endif
$(Q)tools/mkimage -T script -C none -n 'uboot update script' \
-d $(srctree)/u-boot-update.txt \
$(srctree)/u-boot-update.img &> /dev/null
@@ -0,0 +1,176 @@
#!/usr/bin/env python3
#we can use binascii instead of zlib
import os, getopt, sys, zlib
from elftools.elf.elffile import ELFFile
def usage(exit_code):
print("typical usage:")
print("AXS101:")
print(sys.argv[0] + \
" --header-type v1 --arc-id 0x434 --spi-flash-offset 0x0 --image u-boot.bin --elf u-boot")
print("AXS103:")
print(sys.argv[0] + \
" --header-type v2 --arc-id 0x53 --spi-flash-offset 0x200000 --image u-boot.bin --elf u-boot")
sys.exit(exit_code)
def elf_get_entry(filename):
with open(filename, 'rb') as f:
elffile = ELFFile(f)
return elffile.header['e_entry']
def calc_check_sum(filename):
# Calculate u-boot image check_sum: it is sum of all u-boot binary bytes
with open(filename, "rb") as file:
ba = bytearray(file.read())
return sum(ba) & 0xFF
def arg_verify(uboot_bin_filename, uboot_elf_filename, header_type):
if not os.path.isfile(uboot_bin_filename):
print("uboot bin file not exists: " + uboot_bin_filename)
sys.exit(2)
if not os.path.isfile(uboot_elf_filename):
print("uboot elf file not exists: " + uboot_elf_filename)
sys.exit(2)
if header_type not in ("v1", "v2"):
print("unknown header type: " + header_type)
print("choose between 'v1' (most likely AXS101) and 'v2' (most likely AXS103)")
sys.exit(2)
def main():
try:
opts, args = getopt.getopt(sys.argv[1:],
"ht:a:s:i:l:e:",
["help", "header-type=", "arc-id=", "spi-flash-offset=", "image=", "elf="])
except getopt.GetoptError as err:
print(err)
usage(2)
# default filenames
uboot_elf_filename = "u-boot"
uboot_bin_filename = "u-boot.bin"
headerised_filename = "u-boot.head"
uboot_scrypt_file = "u-boot-update.txt"
# default values
spi_flash_offset = 0x200000
header_type = "v2"
arc_id = 0x53
# initial header values: place where preloader will store u-boot binary,
# should be equal to CONFIG_SYS_TEXT_BASE
image_copy_adr = 0x81000000
# initial constant header values, do not change these values
magic1 = 0xdeadbeafaf # big endian byte order
magic2 = [ # big endian byte order
0x20202a2020202020202020202a20202020207c5c2e20202020202e2f7c20202020207c2d,
0x2e5c2020202f2e2d7c20202020205c2020602d2d2d6020202f20202020202f205f202020,
0x205f20205c20202020207c205f60712070205f207c2020202020272e5f3d2f205c3d5f2e,
0x272020202020202020605c202f60202020202020202020202020206f2020202020202020]
for opt, arg in opts:
if opt in ('-h', "--help"): usage(0)
if opt in ('-t', "--header-type"): header_type = arg
if opt in ('-a', "--arc-id"): arc_id = int(arg, 16)
if opt in ('-s', "--spi-flash-offset"): spi_flash_offset = int(arg, 16)
if opt in ('-i', "--image"): uboot_bin_filename = arg
if opt in ('-e', "--elf"): uboot_elf_filename = arg
arg_verify(uboot_bin_filename, uboot_elf_filename, header_type)
uboot_img_size = os.path.getsize(uboot_bin_filename)
jump_address = elf_get_entry(uboot_elf_filename)
check_sum = calc_check_sum(uboot_bin_filename)
# Calculate header adresses depend on header type
if header_type == "v2":
image_copy_adr -= 0x4
uboot_img_size += 0x4
# we append image so we need to append checksum
jmpchk_sum = sum(jump_address.to_bytes(4, byteorder='big'))
check_sum = (check_sum + jmpchk_sum) & 0xFF
imade_jump_append = True
else:
imade_jump_append = False
# write header to file
with open(headerised_filename, "wb") as file:
file.write(arc_id.to_bytes(2, byteorder='little'))
file.write(uboot_img_size.to_bytes(4, byteorder='little'))
file.write(check_sum.to_bytes(1, byteorder='little'))
file.write(image_copy_adr.to_bytes(4, byteorder='little'))
file.write(magic1.to_bytes(5, byteorder='big'))
for i in range(16): file.write(0x00.to_bytes(1, byteorder='little'))
for byte in magic2: file.write(byte.to_bytes(36, byteorder='big'))
for i in range(224 - len(magic2) * 36):
file.write(0x00.to_bytes(1, byteorder='little'))
if imade_jump_append:
file.write(jump_address.to_bytes(4, byteorder='little'))
# append u-boot image to header
with open(headerised_filename, "ab") as fo:
with open(uboot_bin_filename,'rb') as fi:
fo.write(fi.read())
# calc u-boot headerised image CRC32 (will be used by uboot update
# command for check)
headerised_image_crc = ""
with open(headerised_filename, "rb") as fi:
headerised_image_crc = hex(zlib.crc32(fi.read()) & 0xffffffff)
load_addr = 0x81000000
crc_store_adr = load_addr - 0x8
crc_calc_adr = crc_store_adr - 0x4
load_size = os.path.getsize(headerised_filename)
crc_calc_cmd = \
"crc32 " + hex(load_addr) + " " + hex(load_size) + " " + hex(crc_calc_adr)
crc_check_cmd = \
"mw.l " + hex(crc_store_adr) + " " + headerised_image_crc + " && " + \
crc_calc_cmd + " && " + \
"cmp.l " + hex(crc_store_adr) + " " + hex(crc_calc_adr) + " 1"
# make errase size to be allighned by 64K
if load_size & 0xFFFF == 0:
errase_size = load_size
else:
errase_size = load_size - (load_size & 0xFFFF) + 0x10000
# Hack to handle n25*** flash protect ops weirdness:
# protect unlock return fail status is region is already unlock (entire or
# partially). Same for lock ops.
# As there is no possibility to check current flash status pretend
# unlock & lock always success.
sf_unlock_cmd = \
"if sf protect unlock 0x0 0x4000000 ; then true ; else true ; fi"
sf_lock_cmd = \
"if sf protect lock 0x0 0x4000000 ; then true ; else true ; fi"
# u-bood CMD to load u-bood with header to SPI flash
sf_load_image_cmd = \
"fatload mmc 0:1 " + hex(load_addr) + " " + headerised_filename + " && " + \
"sf probe 0:0 && " + \
sf_unlock_cmd + " && " + \
"sf erase " + hex(spi_flash_offset) + " " + hex(errase_size) + " && " + \
"sf write " + hex(load_addr) + " " + hex(spi_flash_offset) + " " + hex(load_size) + " && " + \
sf_lock_cmd
update_uboot_cmd = sf_load_image_cmd + " && echo \"u-boot update: OK\""
with open(uboot_scrypt_file, "wb") as fo:
fo.write(update_uboot_cmd.encode('ascii'))
if __name__ == "__main__":
try:
main()
except Exception as err:
print(err)
sys.exit(2)
@@ -0,0 +1,12 @@
if TARGET_EMSDP
config SYS_BOARD
default "emsdp"
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "emsdp"
endif
@@ -0,0 +1,6 @@
EM DEVELOPMENT KIT BOARD
M: Alexey Brodkin <abrodkin@synopsys.com>
S: Maintained
F: arch/arc/dts/emsdp.dts
F: board/synopsys/emsdp/
F: configs/emsdp_defconfig
@@ -0,0 +1,7 @@
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += emsdp.o
@@ -0,0 +1,83 @@
================================================================================
Useful notes on bulding and using of U-Boot on
ARC EM Software Development Platform (AKA EMSDP)
================================================================================
BOARD OVERVIEW
The DesignWare ARC EM Software Development Platform is FPGA-bases platform
for rapid software development on the ARC EM family of processors.
Since this board is based on FPGA it's possible to load and use different
versions of ARC EM CPUs. U-Boot is built to be run on the simplest
possible configuration which means the same one binary will work on more
advanced configurations as well.
The board has the following features useful for U-Boot:
* On-board 2-channel FTDI TTL-to-USB converter
- The first channel is used for serial debug port (which makes it possible
to use a serial connection on pretty much any host machine be it
Windows, Linux or Mac).
On Linux machine typucally FTDI serial port would be /dev/ttyUSB0.
There's no HW flow-control and baud-rate is 115200.
- The second channel is used for built-in Digilent USB JTAG probe.
That means no extra hardware is required to access ARC core from a
debugger on development host. Both proprietary MetaWare debugger and
open source OpenOCD + GDB client are supported.
- Also with help of this FTDI chip it is possible to reset entire
board with help of a special `rff-ftdi-reset` utility, see:
https://github.com/foss-for-synopsys-dwc-arc-processors/rff-ftdi-reset
* Micro SD-card slot
- U-Boot expects to see the very first partition on the card formatted as
FAT file-system and uses it for keeping its environment in `uboot.env`
file. Note uboot.env is not just a text file but it is auto-generated
file created by U-Boot on invocation of `saveenv` command.
It contains a checksum which makes this saved environment invalid in
case of maual modification.
- There might be more useful files on that first FAT partition like
user applications, data files etc.
* 256 KiB of "ROM"
- This so-called "ROM" is a part of FPGA image and even though it
might be unlocked for writes its initial content will be restored
on the next power-on.
BUILDING U-BOOT
1. Configure U-Boot:
------------------------->8----------------------
make emsdp_defconfig
------------------------->8----------------------
2. To build Elf file (for example to be used with host debugger via JTAG
connection to the target board):
------------------------->8----------------------
make mdbtrick
------------------------->8----------------------
This will produce `u-boot` Elf file.
3. To build binary image to be put in "ROM":
------------------------->8----------------------
make u-boot.bin
------------------------->8----------------------
EXECUTING U-BOOT
1. The EMSDP board is supposed to auto-start U-Boot image stored in ROM on
power-on. For that make sure VCCIO DIP-switches are all in "off" state.
2. Though it is possible to load U-Boot as a simple Elf file via JTAG right
in "ROM" and start it from the debugger. One important note here we first
need to enable writes into "ROM" by writing 1 to 0xf0001000.
2.1. In case of proprietary MetaWare debugger run:
------------------------->8----------------------
mdb -digilent -OK -preloadexec="eval *(int*)0xf0001000=0" u-boot
------------------------->8----------------------
@@ -0,0 +1,2 @@
PLATFORM_CPPFLAGS += -mlittle-endian -mnorm -mswap -mmpy-option=3 \
-mbarrel-shifter -mfpu=fpuda_all -mcode-density
@@ -0,0 +1,153 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
*/
#include <common.h>
#include <dwmmc.h>
#include <malloc.h>
#include <asm/arcregs.h>
DECLARE_GLOBAL_DATA_PTR;
#define ARC_PERIPHERAL_BASE 0xF0000000
#define CGU_ARC_FMEAS_ARC (void *)(ARC_PERIPHERAL_BASE + 0x84)
#define CGU_ARC_FMEAS_ARC_START BIT(31)
#define CGU_ARC_FMEAS_ARC_DONE BIT(30)
#define CGU_ARC_FMEAS_ARC_CNT_MASK GENMASK(14, 0)
#define CGU_ARC_FMEAS_ARC_RCNT_OFFSET 0
#define CGU_ARC_FMEAS_ARC_FCNT_OFFSET 15
#define SDIO_BASE (void *)(ARC_PERIPHERAL_BASE + 0x10000)
int mach_cpu_init(void)
{
int rcnt, fcnt;
u32 data;
/* Start frequency measurement */
writel(CGU_ARC_FMEAS_ARC_START, CGU_ARC_FMEAS_ARC);
/* Poll DONE bit */
do {
data = readl(CGU_ARC_FMEAS_ARC);
} while (!(data & CGU_ARC_FMEAS_ARC_DONE));
/* Amount of reference 100 MHz clocks */
rcnt = ((data >> CGU_ARC_FMEAS_ARC_RCNT_OFFSET) &
CGU_ARC_FMEAS_ARC_CNT_MASK);
/* Amount of CPU clocks */
fcnt = ((data >> CGU_ARC_FMEAS_ARC_FCNT_OFFSET) &
CGU_ARC_FMEAS_ARC_CNT_MASK);
gd->cpu_clk = ((100 * fcnt) / rcnt) * 1000000;
return 0;
}
int board_early_init_r(void)
{
#define EMSDP_PSRAM_BASE 0xf2001000
#define PSRAM_FLASH_CONFIG_REG_0 (void *)(EMSDP_PSRAM_BASE + 0x10)
#define PSRAM_FLASH_CONFIG_REG_1 (void *)(EMSDP_PSRAM_BASE + 0x14)
#define CRE_ENABLE BIT(31)
#define CRE_DRIVE_CMD BIT(6)
#define PSRAM_RCR_DPD BIT(1)
#define PSRAM_RCR_PAGE_MODE BIT(7)
/*
* PSRAM_FLASH_CONFIG_REG_x[30:15] to the address lines[16:1] of flash,
* thus "<< 1".
*/
#define PSRAM_RCR_SETUP ((PSRAM_RCR_DPD | PSRAM_RCR_PAGE_MODE) << 1)
// Switch PSRAM controller to command mode
writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_0);
// Program Refresh Configuration Register (RCR) for BANK0
writew(0, (void *)(0x10000000 + PSRAM_RCR_SETUP));
// Switch PSRAM controller back to memory mode
writel(0, PSRAM_FLASH_CONFIG_REG_0);
// Switch PSRAM controller to command mode
writel(CRE_ENABLE | CRE_DRIVE_CMD, PSRAM_FLASH_CONFIG_REG_1);
// Program Refresh Configuration Register (RCR) for BANK1
writew(0, (void *)(0x10800000 + PSRAM_RCR_SETUP));
// Switch PSRAM controller back to memory mode
writel(0, PSRAM_FLASH_CONFIG_REG_1);
printf("PSRAM initialized.\n");
return 0;
}
#define CREG_BASE 0xF0001000
#define CREG_BOOT (void *)(CREG_BASE + 0x0FF0)
#define CREG_IP_SW_RESET (void *)(CREG_BASE + 0x0FF0)
#define CREG_IP_VERSION (void *)(CREG_BASE + 0x0FF8)
/* Bits in CREG_BOOT register */
#define CREG_BOOT_WP_BIT BIT(8)
void reset_cpu(ulong addr)
{
writel(1, CREG_IP_SW_RESET);
while (1)
; /* loop forever till reset */
}
static int do_emsdp_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
u32 creg_boot = readl(CREG_BOOT);
if (!strcmp(argv[1], "unlock"))
creg_boot &= ~CREG_BOOT_WP_BIT;
else if (!strcmp(argv[1], "lock"))
creg_boot |= CREG_BOOT_WP_BIT;
else
return CMD_RET_USAGE;
writel(creg_boot, CREG_BOOT);
return CMD_RET_SUCCESS;
}
cmd_tbl_t cmd_emsdp[] = {
U_BOOT_CMD_MKENT(rom, 2, 0, do_emsdp_rom, "", ""),
};
static int do_emsdp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
cmd_tbl_t *c;
c = find_cmd_tbl(argv[1], cmd_emsdp, ARRAY_SIZE(cmd_emsdp));
/* Strip off leading 'emsdp' command */
argc--;
argv++;
if (c == NULL || argc > c->maxargs)
return CMD_RET_USAGE;
return c->cmd(cmdtp, flag, argc, argv);
}
U_BOOT_CMD(
emsdp, CONFIG_SYS_MAXARGS, 0, do_emsdp,
"Synopsys EMSDP specific commands",
"rom unlock - Unlock non-volatile memory for writing\n"
"emsdp rom lock - Lock non-volatile memory to prevent writing\n"
);
int checkboard(void)
{
int version = readl(CREG_IP_VERSION);
printf("Board: ARC EM Software Development Platform v%d.%d\n",
(version >> 16) & 0xff, version & 0xff);
return 0;
};
@@ -0,0 +1,12 @@
if TARGET_HSDK
config SYS_BOARD
default "hsdk"
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "hsdk"
endif
@@ -0,0 +1,5 @@
HSDK BOARD
M: Eugeniy Paltsev <paltsev@synopsys.com>
S: Maintained
F: board/synopsys/hsdk/
F: configs/hsdk_defconfig
@@ -0,0 +1,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2017 Synopsys, Inc. All rights reserved.
obj-y += hsdk.o
obj-y += env-lib.o
obj-y += clk-lib.o
@@ -0,0 +1,128 @@
================================================================================
Useful notes on bulding and using of U-Boot on ARC HS Development Kit (AKA HSDK)
================================================================================
BOARD OVERVIEW
The DesignWare ARC HS Development Kit is a ready-to-use platform for rapid
software development on the ARC HS3x family of processors.
For more information please visit:
https://www.synopsys.com/dw/ipdir.php?ds=arc-hs-development-kit
User guide is availalble here:
https://github.com/foss-for-synopsys-dwc-arc-processors/ARC-Development-Systems-Forum/wiki/docs/ARC_HSDK_User_Guide.pdf
It has the following features useful for U-Boot:
* On-board 2-channel FTDI TTL-to-USB converter
- The first channel is used for serial debug port (which makes it possible
to use a serial connection on pretty much any host machine be it
Windows, Linux or Mac).
On Linux machine typucally FTDI serial port would be /dev/ttyUSB0.
There's no HW flow-control and baud-rate is 115200.
- The second channel is used for built-in Digilent USB JTAG probe.
That means no extra hardware is required to access ARC core from a
debugger on development host. Both proprietary MetaWare debugger and
open source OpenOCD + GDB client are supported.
- Also with help of this FTDI chip it is possible to reset entire
board with help of a special `rff-ftdi-reset` utility, see:
https://github.com/foss-for-synopsys-dwc-arc-processors/rff-ftdi-reset
* Micro SD-card slot
- U-Boot expects to see the very first partition on the card formatted as
FAT file-system and uses it for keeping its environment in `uboot.env`
file. Note uboot.env is not just a text file but it is auto-generated
file created by U-Boot on invocation of `saveenv` command.
It contains a checksum which makes this saved environment invalid in
case of maual modification.
- There might be more useful files on that first FAT partition like
Linux kernl image in form of uImage (with or without built-in
initramfs), device tree blob (.dtb) etc.
- Except FAT partition there might be others following the first FAT one
like Ext file-system with rootfs etc.
* 1 Gb Ethernet socket
- U-Boot might get payload from TFTP server. This might be uImage, rootfs
image and anything else.
* 2 MiB of SPI-flash
- SPI-flahs is used as a storage for image of an application auto-executed
by bootROM on power-on. Typically U-Boot gets programmed there but
there might be other uses. But note bootROM expects to find a special
header preceeding application image itself so before flashing anything
make sure required image is prepended. In case of U-Boot this is done
by invocation of `headerize-hsdk.py` with `make bsp-generate` command.
BUILDING U-BOOT
1. Configure U-Boot:
------------------------->8----------------------
make hsdk_defconfig
------------------------->8----------------------
2. To build Elf file (for example to be used with host debugger via JTAG
connection to the target board):
------------------------->8----------------------
make mdbtrick
------------------------->8----------------------
This will produce `u-boot` Elf file.
3. To build artifacts required for U-Boot update in n-board SPI-flash:
------------------------->8----------------------
make bsp-generate
------------------------->8----------------------
This will produce `u-boot.head` and `u-boot-update.scr` which should
be put on the first FAT partition of micro SD-card to be inserted in the
HSDK board.
Note that Python3 script is used for generation of a header, thus
to get that done it's required to have Python3 with "pyelftools" installed.
"pyelftools" could be installed with help of "pip" even w/o root rights:
------------------------->8----------------------
python3 -m pip install --user pyelftools
------------------------->8----------------------
EXECUTING U-BOOT
1. The HSDK board is supposed to auto-start U-Boot image stored in on-board
SPI-flash on power-on. For that make sure DIP-switches in the corner of
the board are in their default positions: BIM in 1:off, 2:on state
while both BMC and BCS should be in 1:on, 2:on state.
2. Though it is possible to load U-Boot as a simple Elf file via JTAG right
in DDR and start it from the debugger.
2.1. In case of proprietary MetaWare debugger run:
------------------------->8----------------------
mdb -digilent -run -cl u-boot
------------------------->8----------------------
UPDATION U-BOOT IMAGE IN ON-BOARD SPI-FLASH
1. Create `u-boot.head` and `u-boot-update.scr` as discribed above with
`make bsp-generate` command.
2. Copy `u-boot.head` and `u-boot-update.scr` to the first FAT partition
of micro SD-card.
3. Connect USB cable from the HSDK board to the developemnt host and
fire-up serial terminal.
3. Insert prepared micro SD-card in the HSDK board, press reset button
and stop auto-execution of existing `bootcmd` pressing any key in serial
terminal and enter the following command:
------------------------->8----------------------
mmc rescan && fatload mmc 0:1 ${loadaddr} u-boot-update.scr && source ${loadaddr}
------------------------->8----------------------
Wait before you see "u-boot update: OK" message.
4. Press RESET button and enjoy updated U-Boot version.
@@ -0,0 +1,74 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
#include <clk.h>
#include <dm/device.h>
#include "clk-lib.h"
#define HZ_IN_MHZ 1000000
#define ceil(x, y) ({ ulong __x = (x), __y = (y); (__x + __y - 1) / __y; })
int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl)
{
int ret;
ulong mhz_rate, priv_rate;
struct clk clk;
/* Dummy fmeas device, just to be able to use standard clk_* api */
struct udevice fmeas = {
.name = "clk-fmeas",
.node = ofnode_path("/clk-fmeas"),
};
ret = clk_get_by_name(&fmeas, name, &clk);
if (ret) {
pr_err("clock '%s' not found, err=%d\n", name, ret);
return ret;
}
if (ctl & CLK_ON) {
ret = clk_enable(&clk);
if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
return ret;
}
if ((ctl & CLK_SET) && rate) {
priv_rate = ctl & CLK_MHZ ? (*rate) * HZ_IN_MHZ : *rate;
ret = clk_set_rate(&clk, priv_rate);
if (ret)
return ret;
}
if (ctl & CLK_OFF) {
ret = clk_disable(&clk);
if (ret) {
pr_err("clock '%s' can't be disabled, err=%d\n", name, ret);
return ret;
}
}
priv_rate = clk_get_rate(&clk);
clk_free(&clk);
mhz_rate = ceil(priv_rate, HZ_IN_MHZ);
if (ctl & CLK_MHZ)
priv_rate = mhz_rate;
if ((ctl & CLK_GET) && rate)
*rate = priv_rate;
if ((ctl & CLK_PRINT) && (ctl & CLK_MHZ))
printf("HSDK: clock '%s' rate %lu MHz\n", name, priv_rate);
else if (ctl & CLK_PRINT)
printf("HSDK: clock '%s' rate %lu Hz\n", name, priv_rate);
else
debug("HSDK: clock '%s' rate %lu MHz\n", name, mhz_rate);
return 0;
}
@@ -0,0 +1,37 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
#ifndef __BOARD_CLK_LIB_H
#define __BOARD_CLK_LIB_H
#include <common.h>
enum clk_ctl_ops {
CLK_SET = BIT(0), /* set frequency */
CLK_GET = BIT(1), /* get frequency */
CLK_ON = BIT(2), /* enable clock */
CLK_OFF = BIT(3), /* disable clock */
CLK_PRINT = BIT(4), /* print frequency */
CLK_MHZ = BIT(5) /* all values in MHZ instead of HZ */
};
/*
* Depending on the clk_ctl_ops enable / disable /
* set clock rate from 'rate' argument / read clock to 'rate' argument /
* print clock rate. If CLK_MHZ flag set in clk_ctl_ops 'rate' is in MHz,
* otherwise - in Hz.
*
* This function expects "clk-fmeas" node in device tree:
* / {
* clk-fmeas {
* clocks = <&cpu_pll>, <&sys_pll>;
* clock-names = "cpu-pll", "sys-pll";
* };
* };
*/
int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl);
#endif /* __BOARD_CLK_LIB_H */
@@ -0,0 +1,11 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
bsp-generate: u-boot u-boot.bin
$(Q)python3 $(srctree)/board/$(BOARDDIR)/headerize-hsdk.py \
--arc-id 0x52 --image $(srctree)/u-boot.bin \
--elf $(srctree)/u-boot
$(Q)tools/mkimage -T script -C none -n 'uboot update script' \
-d $(srctree)/u-boot-update.txt \
$(srctree)/u-boot-update.scr &> /dev/null
@@ -0,0 +1,302 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
#include "env-lib.h"
#include <env.h>
#define MAX_CMD_LEN 25
static void env_clear_common(u32 index, const struct env_map_common *map)
{
map[index].val->val = 0;
map[index].val->set = false;
}
static int env_read_common(u32 index, const struct env_map_common *map)
{
u32 val;
if (!env_get_yesno(map[index].env_name)) {
if (map[index].type == ENV_HEX) {
val = (u32)env_get_hex(map[index].env_name, 0);
debug("ENV: %s: = %#x\n", map[index].env_name, val);
} else {
val = (u32)env_get_ulong(map[index].env_name, 10, 0);
debug("ENV: %s: = %d\n", map[index].env_name, val);
}
map[index].val->val = val;
map[index].val->set = true;
}
return 0;
}
static void env_clear_core(u32 index, const struct env_map_percpu *map)
{
for (u32 i = 0; i < NR_CPUS; i++) {
(*map[index].val)[i].val = 0;
(*map[index].val)[i].set = false;
}
}
static int env_read_core(u32 index, const struct env_map_percpu *map)
{
u32 val;
char command[MAX_CMD_LEN];
for (u32 i = 0; i < NR_CPUS; i++) {
sprintf(command, "%s_%u", map[index].env_name, i);
if (!env_get_yesno(command)) {
if (map[index].type == ENV_HEX) {
val = (u32)env_get_hex(command, 0);
debug("ENV: %s: = %#x\n", command, val);
} else {
val = (u32)env_get_ulong(command, 10, 0);
debug("ENV: %s: = %d\n", command, val);
}
(*map[index].val)[i].val = val;
(*map[index].val)[i].set = true;
}
}
return 0;
}
static int env_validate_common(u32 index, const struct env_map_common *map)
{
u32 value = map[index].val->val;
bool set = map[index].val->set;
u32 min = map[index].min;
u32 max = map[index].max;
/* Check if environment is mandatory */
if (map[index].mandatory && !set) {
pr_err("Variable \'%s\' is mandatory, but it is not defined\n",
map[index].env_name);
return -EINVAL;
}
/* Check environment boundary */
if (set && (value < min || value > max)) {
if (map[index].type == ENV_HEX)
pr_err("Variable \'%s\' must be between %#x and %#x\n",
map[index].env_name, min, max);
else
pr_err("Variable \'%s\' must be between %u and %u\n",
map[index].env_name, min, max);
return -EINVAL;
}
return 0;
}
static int env_validate_core(u32 index, const struct env_map_percpu *map,
bool (*cpu_used)(u32))
{
u32 value;
bool set;
bool mandatory = map[index].mandatory;
u32 min, max;
for (u32 i = 0; i < NR_CPUS; i++) {
set = (*map[index].val)[i].set;
value = (*map[index].val)[i].val;
/* Check if environment is mandatory */
if (cpu_used(i) && mandatory && !set) {
pr_err("CPU %u is used, but \'%s_%u\' is not defined\n",
i, map[index].env_name, i);
return -EINVAL;
}
min = map[index].min[i];
max = map[index].max[i];
/* Check environment boundary */
if (set && (value < min || value > max)) {
if (map[index].type == ENV_HEX)
pr_err("Variable \'%s_%u\' must be between %#x and %#x\n",
map[index].env_name, i, min, max);
else
pr_err("Variable \'%s_%u\' must be between %d and %d\n",
map[index].env_name, i, min, max);
return -EINVAL;
}
}
return 0;
}
void envs_cleanup_core(const struct env_map_percpu *map)
{
/* Cleanup env struct first */
for (u32 i = 0; map[i].env_name; i++)
env_clear_core(i, map);
}
void envs_cleanup_common(const struct env_map_common *map)
{
/* Cleanup env struct first */
for (u32 i = 0; map[i].env_name; i++)
env_clear_common(i, map);
}
int envs_read_common(const struct env_map_common *map)
{
int ret;
for (u32 i = 0; map[i].env_name; i++) {
ret = env_read_common(i, map);
if (ret)
return ret;
}
return 0;
}
int envs_validate_common(const struct env_map_common *map)
{
int ret;
for (u32 i = 0; map[i].env_name; i++) {
ret = env_validate_common(i, map);
if (ret)
return ret;
}
return 0;
}
int envs_read_validate_common(const struct env_map_common *map)
{
int ret;
envs_cleanup_common(map);
ret = envs_read_common(map);
if (ret)
return ret;
ret = envs_validate_common(map);
if (ret)
return ret;
return 0;
}
int envs_read_validate_core(const struct env_map_percpu *map,
bool (*cpu_used)(u32))
{
int ret;
envs_cleanup_core(map);
for (u32 i = 0; map[i].env_name; i++) {
ret = env_read_core(i, map);
if (ret)
return ret;
}
for (u32 i = 0; map[i].env_name; i++) {
ret = env_validate_core(i, map, cpu_used);
if (ret)
return ret;
}
return 0;
}
int envs_process_and_validate(const struct env_map_common *common,
const struct env_map_percpu *core,
bool (*cpu_used)(u32))
{
int ret;
ret = envs_read_validate_common(common);
if (ret)
return ret;
ret = envs_read_validate_core(core, cpu_used);
if (ret)
return ret;
return 0;
}
static int args_envs_read_search(const struct env_map_common *map,
int argc, char *const argv[])
{
for (int i = 0; map[i].env_name; i++) {
if (!strcmp(argv[0], map[i].env_name))
return i;
}
pr_err("Unexpected argument '%s', can't parse\n", argv[0]);
return -ENOENT;
}
static int arg_read_set(const struct env_map_common *map, u32 i, int argc,
char *const argv[])
{
char *endp = argv[1];
if (map[i].type == ENV_HEX)
map[i].val->val = simple_strtoul(argv[1], &endp, 16);
else
map[i].val->val = simple_strtoul(argv[1], &endp, 10);
map[i].val->set = true;
if (*endp == '\0')
return 0;
pr_err("Unexpected argument '%s', can't parse\n", argv[1]);
map[i].val->set = false;
return -EINVAL;
}
int args_envs_enumerate(const struct env_map_common *map, int enum_by,
int argc, char *const argv[])
{
u32 i;
if (argc % enum_by) {
pr_err("unexpected argument number: %d\n", argc);
return -EINVAL;
}
while (argc > 0) {
i = args_envs_read_search(map, argc, argv);
if (i < 0)
return i;
debug("ARG: found '%s' with index %d\n", map[i].env_name, i);
if (i < 0) {
pr_err("unknown arg: %s\n", argv[0]);
return -EINVAL;
}
if (arg_read_set(map, i, argc, argv))
return -EINVAL;
debug("ARG: value.s '%s' == %#x\n", argv[1], map[i].val->val);
argc -= enum_by;
argv += enum_by;
}
return 0;
}
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
* Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
*/
#ifndef __BOARD_ENV_LIB_H
#define __BOARD_ENV_LIB_H
#include <common.h>
#include <config.h>
#include <linux/kernel.h>
enum env_type {
ENV_DEC,
ENV_HEX
};
typedef struct {
u32 val;
bool set;
} u32_env;
struct env_map_common {
const char *const env_name;
enum env_type type;
bool mandatory;
u32 min;
u32 max;
u32_env *val;
};
struct env_map_percpu {
const char *const env_name;
enum env_type type;
bool mandatory;
u32 min[NR_CPUS];
u32 max[NR_CPUS];
u32_env (*val)[NR_CPUS];
};
void envs_cleanup_common(const struct env_map_common *map);
int envs_read_common(const struct env_map_common *map);
int envs_validate_common(const struct env_map_common *map);
int envs_read_validate_common(const struct env_map_common *map);
void envs_cleanup_core(const struct env_map_percpu *map);
int envs_read_validate_core(const struct env_map_percpu *map,
bool (*cpu_used)(u32));
int envs_process_and_validate(const struct env_map_common *common,
const struct env_map_percpu *core,
bool (*cpu_used)(u32));
int args_envs_enumerate(const struct env_map_common *map,
int enum_by, int argc, char *const argv[]);
#endif /* __BOARD_ENV_LIB_H */
@@ -0,0 +1,149 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
# Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
import os, getopt, sys, zlib
from elftools.elf.elffile import ELFFile
def usage(exit_code):
print("usage:")
print(sys.argv[0] + " --arc-id 0x52 --image u-boot.bin --elf u-boot")
sys.exit(exit_code)
def elf_get_entry(filename):
with open(filename, 'rb') as f:
elffile = ELFFile(f)
return elffile.header['e_entry']
def calc_check_sum(filename):
# u-boot.head check_sum for preloader - it is sum of all u-boot binary bytes
with open(filename, "rb") as file:
ba = bytearray(file.read())
return sum(ba) & 0xFF
def arg_verify(uboot_bin_filename, uboot_elf_filename, arc_id):
if arc_id not in [0x52, 0x53]:
print("unknown ARC ID: " + hex(arc_id))
sys.exit(2)
if not os.path.isfile(uboot_bin_filename):
print("uboot bin file not exists: " + uboot_bin_filename)
sys.exit(2)
if not os.path.isfile(uboot_elf_filename):
print("uboot elf file not exists: " + uboot_elf_filename)
sys.exit(2)
def main():
try:
opts, args = getopt.getopt(sys.argv[1:],
"ha:i:l:e:", ["help", "arc-id=", "image=", "elf="])
except getopt.GetoptError as err:
print(err)
usage(2)
# default filenames
uboot_elf_filename = "u-boot"
uboot_bin_filename = "u-boot.bin"
headerised_filename = "u-boot.head"
uboot_scrypt_file = "u-boot-update.txt"
# initial header values: place where preloader will store u-boot binary,
# should be equal to CONFIG_SYS_TEXT_BASE
image_copy_adr = 0x81000000
# initial constant header values, do not change these values
arc_id = 0x52 # 0x52 for 1st HSDK release (hardcoded in RTL)
magic1 = 0xdeadbeafaf # big endian byte order
flash_address = 0x0
flash_type = 0x0 # 0 - SPI flash, 1 - NOR flash
magic2 = [ # big endian byte order
0x20202a2020202020202020202a20202020207c5c2e20202020202e2f7c20202020207c2d,
0x2e5c2020202f2e2d7c20202020205c2020602d2d2d6020202f20202020202f205f202020,
0x205f20205c20202020207c205f60712070205f207c2020202020272e5f3d2f205c3d5f2e,
0x272020202020202020605c202f60202020202020202020202020206f2020202020202020]
for opt, arg in opts:
if opt in ('-h', "--help"): usage(0)
if opt in ('-a', "--arc-id"): arc_id = int(arg, 16)
if opt in ('-i', "--image"): uboot_bin_filename = arg
if opt in ('-e', "--elf"): uboot_elf_filename = arg
arg_verify(uboot_bin_filename, uboot_elf_filename, arc_id)
uboot_img_size = os.path.getsize(uboot_bin_filename)
jump_address = elf_get_entry(uboot_elf_filename)
check_sum = calc_check_sum(uboot_bin_filename)
# write header to file
with open(headerised_filename, "wb") as file:
file.write(arc_id.to_bytes(2, byteorder='little'))
file.write(uboot_img_size.to_bytes(4, byteorder='little'))
file.write(check_sum.to_bytes(1, byteorder='little'))
file.write(image_copy_adr.to_bytes(4, byteorder='little'))
file.write(magic1.to_bytes(5, byteorder='big'))
file.write(jump_address.to_bytes(4, byteorder='little'))
for i in range(12): file.write(0xFF.to_bytes(1, byteorder='little'))
for byte in magic2: file.write(byte.to_bytes(36, byteorder='big'))
for i in range(208 - len(magic2) * 36):
file.write(0xFF.to_bytes(1, byteorder='little'))
file.write(flash_address.to_bytes(4, byteorder='little'))
for i in range(11): file.write(0xFF.to_bytes(1, byteorder='little'))
file.write(flash_type.to_bytes(1, byteorder='little'))
# append u-boot image to header
with open(headerised_filename, "ab") as fo:
with open(uboot_bin_filename,'rb') as fi:
fo.write(fi.read())
# calc u-boot headerized image CRC32 (will be used by uboot update
# command for check)
headerised_image_crc = ""
with open(headerised_filename, "rb") as fi:
headerised_image_crc = hex(zlib.crc32(fi.read()) & 0xffffffff)
load_addr = 0x81000000
crc_store_adr = load_addr - 0x8
crc_calc_adr = crc_store_adr - 0x4
load_size = os.path.getsize(headerised_filename)
crc_calc_cmd = \
"crc32 " + hex(load_addr) + " " + hex(load_size) + " " + hex(crc_calc_adr)
crc_check_cmd = \
"mw.l " + hex(crc_store_adr) + " " + headerised_image_crc + " && " + \
crc_calc_cmd + " && " + \
"cmp.l " + hex(crc_store_adr) + " " + hex(crc_calc_adr) + " 1"
# make errase size to be allighned by 64K
if load_size & 0xFFFF == 0:
errase_size = load_size
else:
errase_size = load_size - (load_size & 0xFFFF) + 0x10000
# u-bood CMD to load u-bood with header to SPI flash
sf_load_image_cmd = \
"fatload mmc 0:1 " + hex(load_addr) + " " + headerised_filename + " && " + \
"sf probe 0:0 && " + \
crc_check_cmd + " && " + \
"sf protect unlock 0x0 " + hex(errase_size) + " && " + \
"sf erase 0x0 " + hex(errase_size) + " && " + \
"sf write " + hex(load_addr) + " 0x0 " + hex(load_size) + " && " + \
"sf protect lock 0x0 " + hex(errase_size)
update_uboot_cmd = sf_load_image_cmd + " && echo \"u-boot update: OK\""
with open(uboot_scrypt_file, "wb") as fo:
fo.write(update_uboot_cmd.encode('ascii'))
if __name__ == "__main__":
try:
main()
except Exception as err:
print(err)
sys.exit(2)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,12 @@
if TARGET_IOT_DEVKIT
config SYS_BOARD
default "iot_devkit"
config SYS_VENDOR
default "synopsys"
config SYS_CONFIG_NAME
default "iot_devkit"
endif
@@ -0,0 +1,5 @@
IOT DEVKIT BOARD
M: Alexey Brodkin <abrodkin@synopsys.com>
S: Maintained
F: board/synopsys/iot_devkit/
F: configs/iot_devkit_defconfig
@@ -0,0 +1,7 @@
#
# Copyright (C) 2018 Synopsys, Inc. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += iot_devkit.o
@@ -0,0 +1,145 @@
================================================================================
Useful notes on bulding and using of U-Boot on
ARC IoT Development Kit (AKA IoTDK)
================================================================================
BOARD OVERVIEW
The DesignWare ARC IoT Development Kit is a versatile platform that includes
the necessary hardware and software to accelerate software development and
debugging of sensor fusion, voice recognition and face detection designs.
The ARC IoT Development Kit includes a silicon implementation of the
ARC Data Fusion IP Subsystem running at 144 MHz on SMIC's
55-nm ultra-low power process, and a rich set of peripherals commonly used
in IoT designs such as USB, UART, SPI, I2C, PWM, SDIO and ADCs.
The board is shipped with pre-installed U-Boot in non-volatile memory
(eFlash) so on power-on user sees U-Boot start header and command line
prompt which might be used for U-Boot environment fine-tuning, manual
loading and execution of user application binaries etc.
The board has the following features useful for U-Boot:
* On-board 2-channel FTDI TTL-to-USB converter
- The first channel is used for serial debug port (which makes it possible
to use a serial connection on pretty much any host machine be it
Windows, Linux or Mac).
On Linux machine typucally FTDI serial port would be /dev/ttyUSB0.
There's no HW flow-control and baud-rate is 115200.
- The second channel is used for built-in Digilent USB JTAG probe.
That means no extra hardware is required to access ARC core from a
debugger on development host. Both proprietary MetaWare debugger and
open source OpenOCD + GDB client are supported.
- Also with help of this FTDI chip it is possible to reset entire
board with help of a special `rff-ftdi-reset` utility, see:
https://github.com/foss-for-synopsys-dwc-arc-processors/rff-ftdi-reset
* Micro SD-card slot
- U-Boot expects to see the very first partition on the card formatted as
FAT file-system and uses it for keeping its environment in `uboot.env`
file. Note uboot.env is not just a text file but it is auto-generated
file created by U-Boot on invocation of `saveenv` command.
It contains a checksum which makes this saved environment invalid in
case of maual modification.
- There might be more useful files on that first FAT partition like
user applications, data files etc.
* USB OTG connector
- U-Boot may access USB mass-storage devices attached to this connector.
Note only FAT file-system is supported. It might be used for storing
user application binaries as well as micro SD-card mentioned above.
* The following memories are avaialble on the board:
- eFlash: 256 KiB @ 0x0000_0000
A non-volatile memory from which ARC core may execute code directly.
Still is is not direcly writable, thus this is not an ordinary RAM.
- ICCM: 256 KiB @ 0x2000_0000
Instruction Closely Coupled Memory - fast on-chip memory primary used
for code being executed, still data could be placed in this memory too.
In that sense it's just a general purpose RAM.
- SRAM: 128 KiB @ 0x3000_0000
On-chip SRAM. From user perspective is the same as ICCM above.
- DCCM: 128 KiB @ 0x8000_0000
Data Closely Coupled Memory is similar to ICCM with a major difference -
ARC core cannot execute code from DCCM. So this is very special RAM
only suitable for data.
BUILDING U-BOOT
1. Configure U-Boot:
------------------------->8----------------------
make iot_devkit_defconfig
------------------------->8----------------------
2. To build Elf file (for example to be used with host debugger via JTAG
connection to the target board):
------------------------->8----------------------
make mdbtrick
------------------------->8----------------------
This will produce `u-boot` Elf file.
3. To build binary image to be put in "ROM":
------------------------->8----------------------
make u-boot.bin
------------------------->8----------------------
EXECUTING U-BOOT
1. The IoTDK board is supposed to auto-start U-Boot image stored in eFlash on
power-on. Note it's possible to update that image - follow instructions in
user's manual.
2. Though it is possible to load and start U-Boot as a simple Elf file
via JTAG right in ICCM. For that it's required to re-configure U-Boot
so it gets linked to ICCM address 0x2000_0000 (remember eFlash is not
direcly writable).
Run U-Boot's configuration utility with "make menuconfig", go to
"Boot images" and change "Text Base" from default 0x00000000 to
0x20000000. Exit & save new configuration. Now run "make mdbtrick" to
build new Elf.
2.1. In case of proprietary MetaWare debugger run:
------------------------->8----------------------
mdb -digilent u-boot
------------------------->8----------------------
USING U-BOOT
Note due to limited memory size it's supposed that user will run binary
images of their applications instead of loading Elf files.
1. To load and start application binary from micro SD-card execute
the following commands in U-Boot's shell:
------------------------->8----------------------
fatload mmc 0 0x20000000 yourapp.bin
go 0x20000000
------------------------->8----------------------
2. To load and start application binary from USB mass-storage device execute
the following commands in U-Boot's shell:
------------------------->8----------------------
usb start
fatload usb 0x20000000 yourapp.bin
go 0x20000000
------------------------->8----------------------
3. To have a sequence of commands executed on U-Boot start put those
commands in "bootcmd" with semicolon between them.
For example to get (1) done automatically:
------------------------->8----------------------
setenv bootcmd fatload mmc 0 0x20000000 yourapp.bin\; go 0x20000000
saveenv
------------------------->8----------------------
4. To reboot the board just run:
------------------------->8----------------------
reset
------------------------->8----------------------
@@ -0,0 +1,2 @@
PLATFORM_CPPFLAGS += -mlittle-endian -mcode-density -mdiv-rem -mswap -mnorm -mmpy-option=6 -mbarrel-shifter
LDSCRIPT = $(srctree)/board/synopsys/iot_devkit/u-boot.lds
@@ -0,0 +1,159 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
*/
#include <common.h>
#include <malloc.h>
#include <dwmmc.h>
#include <linux/libfdt.h>
#include <fdtdec.h>
#include <asm/arcregs.h>
DECLARE_GLOBAL_DATA_PTR;
#define SYSCON_BASE 0xf000a000
#define AHBCKDIV (void *)(SYSCON_BASE + 0x04)
#define APBCKDIV (void *)(SYSCON_BASE + 0x08)
#define APBCKEN (void *)(SYSCON_BASE + 0x0C)
#define RESET_REG (void *)(SYSCON_BASE + 0x18)
#define CLKSEL (void *)(SYSCON_BASE + 0x24)
#define CLKSTAT (void *)(SYSCON_BASE + 0x28)
#define PLLCON (void *)(SYSCON_BASE + 0x2C)
#define APBCKSEL (void *)(SYSCON_BASE + 0x30)
#define AHBCKEN (void *)(SYSCON_BASE + 0x34)
#define USBPHY_PLL (void *)(SYSCON_BASE + 0x78)
#define USBCFG (void *)(SYSCON_BASE + 0x7c)
#define PLL_MASK_0 0xffcfffff
#define PLL_MASK_1 0xffcfff00
#define PLL_MASK_2 0xfbcfff00
#define CLKSEL_DEFAULT 0x5a690000
static int set_cpu_freq(unsigned int clk)
{
clk /= 1000000;
/* Set clk to ext Xtal (LSN value 0) */
writel(CLKSEL_DEFAULT, CLKSEL);
switch (clk) {
case 16:
/* Bypass mode */
return 0;
case 50:
writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
/* pll_off=1, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
writel((readl(PLLCON) & PLL_MASK_1) | 0x300191, PLLCON);
/* pll_off=0, M=25, N=1, OD=3, PLL_OUT_CLK=50M */
writel((readl(PLLCON) & PLL_MASK_2) | 0x300191, PLLCON);
break;
case 72:
writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
/* pll_off=1, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
writel((readl(PLLCON) & PLL_MASK_1) | 0x200121, PLLCON);
/* pll_off=0, M=18, N=1, OD=2, PLL_OUT_CLK=72M */
writel((readl(PLLCON) & PLL_MASK_2) | 0x200121, PLLCON);
break;
case 100:
writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
/* pll_off=1,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
writel((readl(PLLCON) & PLL_MASK_1) | 0x200191, PLLCON);
/* pll_off=0,M=25, N=1, OD=2, PLL_OUT_CLK=100M */
writel((readl(PLLCON) & PLL_MASK_2) | 0x200191, PLLCON);
break;
case 136:
writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
/* pll_off=1, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
writel((readl(PLLCON) & PLL_MASK_1) | 0x100111, PLLCON);
/* pll_off=0, M=17, N=1, OD=1, PLL_OUT_CLK=136M */
writel((readl(PLLCON) & PLL_MASK_2) | 0x100111, PLLCON);
break;
case 144:
writel(readl(PLLCON) & PLL_MASK_0, PLLCON);
/* pll_off=1, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
writel((readl(PLLCON) & PLL_MASK_1) | 0x100121, PLLCON);
/* pll_off=0, M=18, N=1, OD=1, PLL_OUT_CLK=144M */
writel((readl(PLLCON) & PLL_MASK_2) | 0x100121, PLLCON);
break;
default:
return -EINVAL;
}
while (!(readl(CLKSTAT) & 0x4))
;
/* Set clk from PLL on bus (LSN = 1) */
writel(CLKSEL_DEFAULT | BIT(0), CLKSEL);
return 0;
}
extern u8 __rom_end[];
extern u8 __ram_start[];
extern u8 __ram_end[];
/*
* Use mach_cpu_init() for .data section copy as board_early_init_f() will be
* too late: initf_dm() will use a value of "av_" variable from not yet
* initialized (by copy) area.
*/
int mach_cpu_init(void)
{
int offset;
/* Don't relocate U-Boot */
gd->flags |= GD_FLG_SKIP_RELOC;
/* Copy data from ROM to RAM */
u8 *src = __rom_end;
u8 *dst = __ram_start;
while (dst < __ram_end)
*dst++ = *src++;
/* Enable debug uart */
#define DEBUG_UART_BASE 0x80014000
#define DEBUG_UART_DLF_OFFSET 0xc0
write_aux_reg(DEBUG_UART_BASE + DEBUG_UART_DLF_OFFSET, 1);
offset = fdt_path_offset(gd->fdt_blob, "/cpu_card/core_clk");
if (offset < 0)
return offset;
gd->cpu_clk = fdtdec_get_int(gd->fdt_blob, offset, "clock-frequency", 0);
if (!gd->cpu_clk)
return -EINVAL;
/* If CPU freq > 100 MHz, divide eFLASH clock by 2 */
if (gd->cpu_clk > 100000000) {
u32 reg = readl(AHBCKDIV);
reg &= ~(0xF << 8);
reg |= 2 << 8;
writel(reg, AHBCKDIV);
}
return set_cpu_freq(gd->cpu_clk);
}
#define IOTDK_RESET_SEQ 0x55AA6699
void reset_cpu(ulong addr)
{
writel(IOTDK_RESET_SEQ, RESET_REG);
}
int checkboard(void)
{
puts("Board: Synopsys IoT Development Kit\n");
return 0;
};
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2018 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
MEMORY {
ROM : ORIGIN = ROM_BASE, LENGTH = ROM_SIZE
RAM : ORIGIN = RAM_DATA_BASE, LENGTH = RAM_DATA_SIZE
}
OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc")
OUTPUT_ARCH(arc)
ENTRY(_start)
SECTIONS
{
. = CONFIG_SYS_MONITOR_BASE;
__image_copy_start = .;
.ivt :
{
__ivt_start = .;
KEEP(*(.ivt));
__ivt_end = .;
} > ROM
. = ALIGN(1024);
.text : {
__text_start = .;
arch/arc/lib/start.o (.text*)
*(.text*)
__text_end = .;
} > ROM
. = ALIGN(4);
.rodata : {
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
} > ROM
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
/* Mark RAM's LMA */
. = ALIGN(4);
__rom_end = .;
} > ROM
.data : {
/* Mark RAM's VMA */
. = ALIGN(4);
/*
* Everything between __ram_start and __ram_start will be
* copied from ROM to RAM in board_early_init_f().
*/
__ram_start = .;
*(.data*)
__ram_end = .;
} > RAM AT > ROM
.bss : {
. = ALIGN(1024);
__bss_start = .;
*(.bss*)
__bss_end = .;
} > RAM
/* Keep relocation-related symbols to make linker happy */
__rel_dyn_start = .;
__rel_dyn_end = .;
__image_copy_end = .;
__init_end = .;
}