[U-Boot] [PATCH 0/8] U-Boot port to Xtensa architecture

Hi Tom,
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Preparation patches clean up OpenCores 10/100 MBit driver, enable it to be used with dedicated packet memory and with gigabit PHY. Two patches add proper xtensa bits: changes to shares files and contents of arch/xtensa. One more patch adds sample xtensa CPU configuration -- Diamond 232. One more patch adds xtfpga board family that consists of Avnet LX60, LX110 and LX200 and Xilinx ML605 and KC705 FPGA boards configured with xtensa bitstream.
The whole series is also available in the following git tree:
git://github.com/jcmvbkbc/u-boot-xtensa.git tags/xtensa-for-mainline-20140820
The port has been done mainly by Chris Zankel. I've been maintaining it internally for some time now and I'll maintain it upstream.
Chris Zankel (5): net/ethoc: support private memory configurations xtensa: add support for the xtensa processor architecture [1/2] xtensa: add support for the xtensa processor architecture [2/2] xtensa: add core information for the dc232b processor xtensa: add support for the 'xtfpga' evaluation board
Max Filippov (3): net/ethoc: fix warnings from ethoc_read/ethoc_write net/ethoc: don't advertise gigabit on the connected PHY Makefile: allow overriding '-ansi' in LDPPFLAGS
CREDITS | 5 + MAKEALL | 6 + Makefile | 4 +- arch/Kconfig | 4 + arch/xtensa/Kconfig | 29 ++ arch/xtensa/config.mk | 13 + arch/xtensa/cpu/.gitignore | 1 + arch/xtensa/cpu/Makefile | 13 + arch/xtensa/cpu/config.mk | 9 + arch/xtensa/cpu/cpu.c | 84 ++++ arch/xtensa/cpu/exceptions.c | 67 +++ arch/xtensa/cpu/start.S | 672 ++++++++++++++++++++++++++ arch/xtensa/cpu/u-boot.lds.S | 107 ++++ arch/xtensa/include/asm/addrspace.h | 43 ++ arch/xtensa/include/asm/arch-dc232b/core.h | 422 ++++++++++++++++ arch/xtensa/include/asm/arch-dc232b/tie-asm.h | 120 +++++ arch/xtensa/include/asm/arch-dc232b/tie.h | 129 +++++ arch/xtensa/include/asm/asmmacro.h | 136 ++++++ arch/xtensa/include/asm/bitops.h | 14 + arch/xtensa/include/asm/bootparam.h | 54 +++ arch/xtensa/include/asm/byteorder.h | 81 ++++ arch/xtensa/include/asm/cache.h | 20 + arch/xtensa/include/asm/cacheasm.h | 187 +++++++ arch/xtensa/include/asm/config.h | 17 + arch/xtensa/include/asm/errno.h | 1 + arch/xtensa/include/asm/global_data.h | 24 + arch/xtensa/include/asm/io.h | 148 ++++++ arch/xtensa/include/asm/ldscript.h | 220 +++++++++ arch/xtensa/include/asm/linkage.h | 4 + arch/xtensa/include/asm/misc.h | 24 + arch/xtensa/include/asm/posix_types.h | 74 +++ arch/xtensa/include/asm/processor.h | 11 + arch/xtensa/include/asm/ptrace.h | 133 +++++ arch/xtensa/include/asm/regs.h | 95 ++++ arch/xtensa/include/asm/sections.h | 15 + arch/xtensa/include/asm/string.h | 10 + arch/xtensa/include/asm/types.h | 60 +++ arch/xtensa/include/asm/u-boot.h | 43 ++ arch/xtensa/include/asm/unaligned.h | 6 + arch/xtensa/include/asm/xtensa.h | 36 ++ arch/xtensa/lib/Makefile | 9 + arch/xtensa/lib/board.c | 173 +++++++ arch/xtensa/lib/bootm.c | 202 ++++++++ arch/xtensa/lib/misc.S | 178 +++++++ arch/xtensa/lib/time.c | 111 +++++ board/cadence/xtfpga/Kconfig | 51 ++ board/cadence/xtfpga/MAINTAINERS | 6 + board/cadence/xtfpga/Makefile | 8 + board/cadence/xtfpga/README | 121 +++++ board/cadence/xtfpga/lcd.c | 88 ++++ board/cadence/xtfpga/lcd.h | 12 + board/cadence/xtfpga/xtfpga.c | 173 +++++++ common/board_r.c | 2 +- common/cmd_bdinfo.c | 22 + common/image.c | 1 + configs/xtfpga_defconfig | 3 + doc/README.xtensa | 104 ++++ drivers/net/ethoc.c | 101 +++- examples/standalone/stubs.c | 45 ++ include/configs/xtfpga.h | 305 ++++++++++++ include/image.h | 1 + include/linux/stat.h | 4 +- 62 files changed, 4855 insertions(+), 6 deletions(-) create mode 100644 arch/xtensa/Kconfig create mode 100644 arch/xtensa/config.mk create mode 100644 arch/xtensa/cpu/.gitignore create mode 100644 arch/xtensa/cpu/Makefile create mode 100644 arch/xtensa/cpu/config.mk create mode 100644 arch/xtensa/cpu/cpu.c create mode 100644 arch/xtensa/cpu/exceptions.c create mode 100644 arch/xtensa/cpu/start.S create mode 100644 arch/xtensa/cpu/u-boot.lds.S create mode 100644 arch/xtensa/include/asm/addrspace.h create mode 100644 arch/xtensa/include/asm/arch-dc232b/core.h create mode 100644 arch/xtensa/include/asm/arch-dc232b/tie-asm.h create mode 100644 arch/xtensa/include/asm/arch-dc232b/tie.h create mode 100644 arch/xtensa/include/asm/asmmacro.h create mode 100644 arch/xtensa/include/asm/bitops.h create mode 100644 arch/xtensa/include/asm/bootparam.h create mode 100644 arch/xtensa/include/asm/byteorder.h create mode 100644 arch/xtensa/include/asm/cache.h create mode 100644 arch/xtensa/include/asm/cacheasm.h create mode 100644 arch/xtensa/include/asm/config.h create mode 100644 arch/xtensa/include/asm/errno.h create mode 100644 arch/xtensa/include/asm/global_data.h create mode 100644 arch/xtensa/include/asm/io.h create mode 100644 arch/xtensa/include/asm/ldscript.h create mode 100644 arch/xtensa/include/asm/linkage.h create mode 100644 arch/xtensa/include/asm/misc.h create mode 100644 arch/xtensa/include/asm/posix_types.h create mode 100644 arch/xtensa/include/asm/processor.h create mode 100644 arch/xtensa/include/asm/ptrace.h create mode 100644 arch/xtensa/include/asm/regs.h create mode 100644 arch/xtensa/include/asm/sections.h create mode 100644 arch/xtensa/include/asm/string.h create mode 100644 arch/xtensa/include/asm/types.h create mode 100644 arch/xtensa/include/asm/u-boot.h create mode 100644 arch/xtensa/include/asm/unaligned.h create mode 100644 arch/xtensa/include/asm/xtensa.h create mode 100644 arch/xtensa/lib/Makefile create mode 100644 arch/xtensa/lib/board.c create mode 100644 arch/xtensa/lib/bootm.c create mode 100644 arch/xtensa/lib/misc.S create mode 100644 arch/xtensa/lib/time.c create mode 100644 board/cadence/xtfpga/Kconfig create mode 100644 board/cadence/xtfpga/MAINTAINERS create mode 100644 board/cadence/xtfpga/Makefile create mode 100644 board/cadence/xtfpga/README create mode 100644 board/cadence/xtfpga/lcd.c create mode 100644 board/cadence/xtfpga/lcd.h create mode 100644 board/cadence/xtfpga/xtfpga.c create mode 100644 configs/xtfpga_defconfig create mode 100644 doc/README.xtensa create mode 100644 include/configs/xtfpga.h

From: Chris Zankel chris@zankel.net
The 'ethoc' device could also be configured to have a private memory region instead of having access to the main memory. In that case, the packets must be copied into (transmit) or out of (receive) that memory.
This behavior is configured by defining CONFIG_SYS_ETHOC_BUFFER_ADDR. Make sure to have enough memory for the configured buffers (one for transmit, and 'PKTBUFSRX' for receive)
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- drivers/net/ethoc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index af06d4f..46b9bae 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -248,6 +248,9 @@ static int ethoc_init_ring(struct eth_device *dev) { struct ethoc *priv = (struct ethoc *)dev->priv; struct ethoc_bd bd; +#ifdef CONFIG_SYS_ETHOC_BUFFER_ADDR + unsigned long addr = CONFIG_SYS_ETHOC_BUFFER_ADDR; +#endif int i;
priv->cur_tx = 0; @@ -258,6 +261,10 @@ static int ethoc_init_ring(struct eth_device *dev) bd.stat = TX_BD_IRQ | TX_BD_CRC;
for (i = 0; i < priv->num_tx; i++) { +#ifdef CONFIG_SYS_ETHOC_BUFFER_ADDR + bd.addr = addr; + addr += PKTSIZE_ALIGN; +#endif if (i == priv->num_tx - 1) bd.stat |= TX_BD_WRAP;
@@ -267,7 +274,12 @@ static int ethoc_init_ring(struct eth_device *dev) bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < priv->num_rx; i++) { +#ifdef CONFIG_SYS_ETHOC_BUFFER_ADDR + bd.addr = addr; + addr += PKTSIZE_ALIGN; +#else bd.addr = (u32)NetRxPackets[i]; +#endif if (i == priv->num_rx - 1) bd.stat |= RX_BD_WRAP;
@@ -372,7 +384,12 @@ static int ethoc_rx(struct eth_device *dev, int limit) if (ethoc_update_rx_stats(&bd) == 0) { int size = bd.stat >> 16; size -= 4; /* strip the CRC */ +#ifdef CONFIG_SYS_ETHOC_BUFFER_ADDR + memcpy(NetRxPackets[0], (void *)bd.addr, size); + NetReceive(NetRxPackets[0], size); +#else NetReceive((void *)bd.addr, size); +#endif }
/* clear the buffer descriptor so it can be reused */ @@ -428,7 +445,11 @@ static int ethoc_send(struct eth_device *dev, void *packet, int length) bd.stat |= TX_BD_PAD; else bd.stat &= ~TX_BD_PAD; +#ifdef CONFIG_SYS_ETHOC_BUFFER_ADDR + memcpy((void *)bd.addr, (const void *)packet, length); +#else bd.addr = (u32)packet; +#endif
flush_dcache_range(bd.addr, bd.addr + length); bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);

There's no need to use loff_t to specify in-memory offset; size_t is smaller and is guaranteed to be sufficient to represent any memory object size.
Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- drivers/net/ethoc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 46b9bae..9362faf 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -189,12 +189,12 @@ struct ethoc_bd { u32 addr; };
-static inline u32 ethoc_read(struct eth_device *dev, loff_t offset) +static inline u32 ethoc_read(struct eth_device *dev, size_t offset) { return readl(dev->iobase + offset); }
-static inline void ethoc_write(struct eth_device *dev, loff_t offset, u32 data) +static inline void ethoc_write(struct eth_device *dev, size_t offset, u32 data) { writel(data, dev->iobase + offset); }

Introduce MDIO communication routines. Scan MDIO bus at reset to find attached PHYs and see if they support gigabit speeds. If they do check their gigabit control register: if gigabit autonegotiation is enabled clear it and reset the PHY.
This allows using OpenCores 10/100 MAC with gigabit PHY connected to gigabit network.
Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- drivers/net/ethoc.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index 9362faf..26b8842 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -290,6 +290,80 @@ static int ethoc_init_ring(struct eth_device *dev) return 0; }
+#ifdef CONFIG_SYS_ETHOC_SETUP_PHY + +static u16 ethoc_mii_read(struct eth_device *dev, u8 phy, u8 reg) +{ + ulong tmo = get_timer(0); + + ethoc_write(dev, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); + ethoc_write(dev, MIICOMMAND, MIICOMMAND_READ); + + while (get_timer(tmo) < CONFIG_SYS_HZ) { + u32 status = ethoc_read(dev, MIISTATUS); + if (!(status & MIISTATUS_BUSY)) { + u32 data = ethoc_read(dev, MIIRX_DATA); + /* reset MII command register */ + ethoc_write(dev, MIICOMMAND, 0); + return data; + } + } + return 0xffff; +} + +static void ethoc_mii_write(struct eth_device *dev, u8 phy, u8 reg, u16 v) +{ + ulong tmo = get_timer(0); + + ethoc_write(dev, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); + ethoc_write(dev, MIITX_DATA, v); + ethoc_write(dev, MIICOMMAND, MIICOMMAND_WRITE); + + while (get_timer(tmo) < CONFIG_SYS_HZ) { + u32 stat = ethoc_read(dev, MIISTATUS); + if (!(stat & MIISTATUS_BUSY)) { + /* reset MII command register */ + ethoc_write(dev, MIICOMMAND, 0); + return; + } + } +} + +static void ethoc_setup_phy(struct eth_device *dev) +{ + u8 phy; + + ethoc_write(dev, MIIMODER, 0xfe); + + for (phy = 0; phy < 32; ++phy) { + if (ethoc_mii_read(dev, phy, MII_PHYSID1) != 0xffff) { + u16 v; + + v = ethoc_mii_read(dev, phy, MII_BMSR); + if (!(v & BMSR_ESTATEN)) + continue; + + v = ethoc_mii_read(dev, phy, MII_CTRL1000); + if (!(v & (ADVERTISE_1000FULL | ADVERTISE_1000HALF))) + continue; + + ethoc_mii_write(dev, phy, MII_CTRL1000, + v & ~(ADVERTISE_1000FULL | + ADVERTISE_1000HALF)); + v = ethoc_mii_read(dev, phy, MII_BMCR); + ethoc_mii_write(dev, phy, MII_BMCR, v | BMCR_RESET); + } + } +} + +#else + +static inline void ethoc_setup_phy(struct eth_device *dev) +{ +} + +#endif + static int ethoc_reset(struct eth_device *dev) { u32 mode; @@ -311,6 +385,8 @@ static int ethoc_reset(struct eth_device *dev) ethoc_write(dev, MODER, mode); ethoc_write(dev, IPGT, 0x15);
+ ethoc_setup_phy(dev); + ethoc_ack_irq(dev, INT_MASK_ALL); ethoc_enable_rx_and_tx(dev); return 0;

xtensa linker script cannot be preprocessed with -ansi option specified, so xtensa needs a way to override it.
Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index 666d291..344492f 100644 --- a/Makefile +++ b/Makefile @@ -209,6 +209,7 @@ HOSTCXXFLAGS = -O2 ifeq ($(HOSTOS),cygwin) HOSTCFLAGS += -ansi endif +LDPPFLAGS += -ansi
# Mac OS X / Darwin's C preprocessor is Apple specific. It # generates numerous errors and warnings. We want to bypass it @@ -1121,7 +1122,7 @@ depend dep:
# --------------------------------------------------------------------------- quiet_cmd_cpp_lds = LDS $@ -cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \ +cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) \ -D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $<
u-boot.lds: $(LDSCRIPT) prepare FORCE

From: Chris Zankel chris@zankel.net
The Xtensa processor architecture is a configurable, extensible, and synthesizable 32-bit RISC processor core provided by Cadence.
This is the first part of the basic architecture port with changes to common files. The 'arch/xtensa' directory, and boards and additional drivers will be in separate commits.
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- CREDITS | 5 +++ MAKEALL | 6 +++ Makefile | 1 + common/board_r.c | 2 +- common/cmd_bdinfo.c | 22 ++++++++++ common/image.c | 1 + doc/README.xtensa | 104 ++++++++++++++++++++++++++++++++++++++++++++ examples/standalone/stubs.c | 45 +++++++++++++++++++ include/image.h | 1 + include/linux/stat.h | 4 +- 10 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 doc/README.xtensa
diff --git a/CREDITS b/CREDITS index 3e5fb7b..55ad04c 100644 --- a/CREDITS +++ b/CREDITS @@ -534,3 +534,8 @@ N: Philip Balister E: philip@opensdr.com D: Port to Lyrtech SFFSDR development board. W: www.opensdr.com + +N: Chris Zankel +E: chris@zankel.net +D: Port to Xtensa +W: www.linux-xtensa.org diff --git a/MAKEALL b/MAKEALL index 929fe88..c22e5b7 100755 --- a/MAKEALL +++ b/MAKEALL @@ -505,6 +505,12 @@ LIST_nds32="$(targets_by_arch nds32)"
LIST_arc="$(targets_by_arch arc)"
+######################################################################### +## Xtensa Systems +######################################################################### + +LIST_xtensa="$(targets_by_arch xtensa)" + #-----------------------------------------------------------------------
get_target_location() { diff --git a/Makefile b/Makefile index 344492f..e6d8abf 100644 --- a/Makefile +++ b/Makefile @@ -656,6 +656,7 @@ endif
libs-$(CONFIG_ARM) += arch/arm/cpu/ libs-$(CONFIG_PPC) += arch/powerpc/cpu/ +libs-$(CONFIG_XTENSA) += arch/xtensa/cpu/
libs-y += $(if $(BOARDDIR),board/$(BOARDDIR)/)
diff --git a/common/board_r.c b/common/board_r.c index 8e7a3ac..38c028a 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -911,7 +911,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr) int i; #endif
-#ifndef CONFIG_X86 +#if !defined(CONFIG_X86) && !defined(CONFIG_XTENSA) gd = new_gd; #endif
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 3d37a86..fea4a55 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -536,6 +536,28 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; }
+#elif defined(CONFIG_XTENSA) + +int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + bd_t *bd = gd->bd; + + print_num("boot_params", (ulong)bd->bi_boot_params); + print_num("memstart", (ulong)bd->bi_memstart); + print_lnum("memsize", (u64)bd->bi_memsize); + print_num("flashstart", (ulong)bd->bi_flashstart); + print_num("flashsize", (ulong)bd->bi_flashsize); + print_num("flashoffset", (ulong)bd->bi_flashoffset); + +#if defined(CONFIG_CMD_NET) + print_eth(0); + printf("ip_addr = %s\n", getenv("ipaddr")); +#endif + printf("baudrate = %d bps\n", gd->baudrate); + + return 0; +} + #else #error "a case for this architecture does not exist!" #endif diff --git a/common/image.c b/common/image.c index 11b3cf5..159d004 100644 --- a/common/image.c +++ b/common/image.c @@ -85,6 +85,7 @@ static const table_entry_t uimage_arch[] = { { IH_ARCH_SANDBOX, "sandbox", "Sandbox", }, { IH_ARCH_ARM64, "arm64", "AArch64", }, { IH_ARCH_ARC, "arc", "ARC", }, + { IH_ARCH_XTENSA, "xtensa", "Xtensa", }, { -1, "", "", }, };
diff --git a/doc/README.xtensa b/doc/README.xtensa new file mode 100644 index 0000000..980ab14 --- /dev/null +++ b/doc/README.xtensa @@ -0,0 +1,104 @@ +U-Boot for the Xtensa Architecture +================================== + +Xtensa Architecture and Diamond Cores +------------------------------------- + +Xtensa is a configurable processor architecture from Tensilica, Inc. +Diamond Cores are pre-configured instances available for license and +SoC cores in the same manner as ARM, MIPS, etc. + +Xtensa licensees create their own Xtensa cores with selected features +and custom instructions, registers and co-processors. The custom core +is configured with Tensilica tools and built with Tensilica's Xtensa +Processor Generator. + +There are an effectively infinite number of CPUs in the Xtensa +architecture family. It is, however, not feasible to support individual +Xtensa CPUs in U-Boot. Therefore, there is only a single 'xtensa' CPU +in the cpu tree of U-Boot. + +In the same manner as the Linux port to Xtensa, U-Boot adapts to an +individual Xtensa core configuration using a set of macros provided with +the particular core. This is part of what is known as the hardware +abstraction layer (HAL). For the purpose of U-Boot, the HAL consists only +of a few header files. These provide CPP macros that customize sources, +Makefiles, and the linker script. + + +Adding support for an additional processor configuration +-------------------------------------------------------- + +The header files for one particular processor configuration are inside +a variant specific directory located in the arch/xtensa/include/asm +directory. The name of that directory starts with 'arch-' followed by +the name for the processor configuration, for example, arch-dc233c for +the Diamond DC233 processor. + + core.h Definitions for the core itself. + +The following files are part of the overlay but not used by U-Boot. + + tie.h Co-processors and custom extensions defined + in the Tensilica Instruction Extension (TIE) + language. + tie-asm.h Assembly macros to access custom-defined registers + and states. + + +Global Data Pointer, Exported Function Stubs, and the ABI +--------------------------------------------------------- + +To support standalone applications launched with the "go" command, +U-Boot provides a jump table of entrypoints to exported functions +(grep for EXPORT_FUNC). The implementation for Xtensa depends on +which ABI (or function calling convention) is used. + +Call0 ABI is very conventional, and like most other architectures +maintains the global data pointer gd in a register. This is chosen +to be a14 because it is callee-saved (not clobbered) and has no +other special use. + +Windowed ABI presents unique difficulties with the above approach. +Because the register window rotates during a call, there is no +register that is constantly available for the global data pointer. +Therefore, a global variable is used in the same manner as i386. +Another difficulty arises from the requirement to have an 'entry' +at the beginning of a function, which rotates the register file and +reserves a stack frame. This is an integral part of the windowed ABI +implemented in hardware. It makes using a jump table to an arbitrary +(separately compiled) function a bit tricky. Use of a simple wrapper +is also very tedious due to the need to move all possible register +arguments and adjust the stack to handle arguments that cannot be +passed in registers. The most efficient approach is to have the jump +table perform the 'entry' so as to pretend it's the start of the +real function. This requires decoding the target function's 'entry' +instruction to determine the stack frame size, and adjusting the stack +pointer accordingly, then jumping into the target function just after +the 'entry'. Decoding depends on the processor's endianness so uses +the HAL. The implementation (12 instructions) is in examples/stubs.c . + + +Access to Invalid Memory Addresses +---------------------------------- + +U-Boot does not check if memory addresses given as arguments to commands +such as "md" are valid. The expectation appears to be that if the user +requests to look at invalid memory he should expect to see garbage, and +writes to invalid memory should be ignored. + +On many processors, and indeed many Xtensa configurations, this is +acceptable. However on some configurations (particularly those with an +MMU such as would be used with Linux) an exception is generated for an +invalid memory access, which results in a hang if not handled. + +U-Boot for Xtensa provides a special memory exception handler to prevent +hanging. The memory exception handler simply skips over the offending +instruction. It is called for all memory exception causes that might +be triggered by bad user input. While this is simplistic, it's better +than hanging in most cases, while keeping U-Boot small and simple. + + +------------------------------------------------------------------------------ +Chris Zankel +Ross Morley diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c index c5c025d..c26476d 100644 --- a/examples/standalone/stubs.c +++ b/examples/standalone/stubs.c @@ -223,6 +223,51 @@ gd_t *global_data; " ld r10, [r10, %1]\n" \ " j [r10]\n" \ : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r10"); +#elif defined(CONFIG_XTENSA) +/* + * Call0 ABI: Global data ptr is in a14, and a8 is clobberable scratch. + * Windowed ABI: Global data ptr is in global_data, jump table ptr is in jt. + * Jump just past 'entry' in target and adjust stack frame + * (extract stack frame size from target 'entry' instruction). + */ + +#ifdef __XTENSA_CALL0_ABI__ +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .globl " #x "\n" \ +" .align 4\n" \ +#x ":\n" \ +" l32i a8, a14, %0\n" \ +" l32i a8, a8, %1\n" \ +" jx a8\n" \ + : : "i" (offsetof(gd_t, jt)), "i" (XF_ ## x * sizeof(void *)) : "a8"); +#else + +static void **jt; +#if XCHAL_HAVE_BE +# define SFT "8" +#else +# define SFT "12" +#endif +#define EXPORT_FUNC(x) \ + asm volatile ( \ +" .extern jt\n" \ +" .globl " #x "\n" \ +" .align 4\n" \ +#x ":\n" \ +" entry sp, 16\n" \ +" l32i a8, %0, 0\n" \ +" l32i a8, a8, %1\n" \ +" l32i a9, a8, 0\n" \ +" extui a9, a9, " SFT ", 12\n" \ +" subx8 a9, a9, sp\n" \ +" movi a10, 16\n" \ +" sub a9, a10, a9\n" \ +" movsp sp, a9\n" \ +" addi a8, a8, 3\n" \ +" jx a8\n" \ + : : "r"(jt), "i" (XF_ ## x * sizeof(void *)) : "a8", "a9", "a10"); +#endif /* __XTENSA_CALL0_ABI__ */ #else /*" addi $sp, $sp, -24\n" \ " br $r16\n" */ diff --git a/include/image.h b/include/image.h index 3e8f78d..00b3fb5 100644 --- a/include/image.h +++ b/include/image.h @@ -173,6 +173,7 @@ struct lmb; #define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */ #define IH_ARCH_ARM64 22 /* ARM64 */ #define IH_ARCH_ARC 23 /* Synopsys DesignWare ARC */ +#define IH_ARCH_XTENSA 24 /* Xtensa */
/* * Image Types diff --git a/include/linux/stat.h b/include/linux/stat.h index cef6369..1af0876 100644 --- a/include/linux/stat.h +++ b/include/linux/stat.h @@ -126,7 +126,7 @@ struct stat {
#endif /* __MIPS__ */
-#if defined(__AVR32__) || defined(__SH__) +#if defined(__AVR32__) || defined(__SH__) || defined(__XTENSA__)
struct stat { unsigned long st_dev; @@ -149,7 +149,7 @@ struct stat { unsigned long __unused5; };
-#endif /* __AVR32__ || __SH__ */ +#endif /* __AVR32__ || __SH__ || __XTENSA__ */
#ifdef __cplusplus }

From: Chris Zankel chris@zankel.net
The Xtensa processor architecture is a configurable, extensible, and synthesizable 32-bit RISC processor core provided by Tensilica, inc.
This is the second part of the basic architecture port, adding the 'arch/xtensa' directory and a readme file.
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- arch/Kconfig | 4 + arch/xtensa/Kconfig | 26 ++ arch/xtensa/config.mk | 13 + arch/xtensa/cpu/.gitignore | 1 + arch/xtensa/cpu/Makefile | 13 + arch/xtensa/cpu/config.mk | 9 + arch/xtensa/cpu/cpu.c | 84 +++++ arch/xtensa/cpu/exceptions.c | 67 ++++ arch/xtensa/cpu/start.S | 672 ++++++++++++++++++++++++++++++++++ arch/xtensa/cpu/u-boot.lds.S | 107 ++++++ arch/xtensa/include/asm/addrspace.h | 43 +++ arch/xtensa/include/asm/asmmacro.h | 136 +++++++ arch/xtensa/include/asm/bitops.h | 14 + arch/xtensa/include/asm/bootparam.h | 54 +++ arch/xtensa/include/asm/byteorder.h | 81 ++++ arch/xtensa/include/asm/cache.h | 20 + arch/xtensa/include/asm/cacheasm.h | 187 ++++++++++ arch/xtensa/include/asm/config.h | 17 + arch/xtensa/include/asm/errno.h | 1 + arch/xtensa/include/asm/global_data.h | 24 ++ arch/xtensa/include/asm/io.h | 148 ++++++++ arch/xtensa/include/asm/ldscript.h | 220 +++++++++++ arch/xtensa/include/asm/linkage.h | 4 + arch/xtensa/include/asm/misc.h | 24 ++ arch/xtensa/include/asm/posix_types.h | 74 ++++ arch/xtensa/include/asm/processor.h | 11 + arch/xtensa/include/asm/ptrace.h | 133 +++++++ arch/xtensa/include/asm/regs.h | 95 +++++ arch/xtensa/include/asm/sections.h | 15 + arch/xtensa/include/asm/string.h | 10 + arch/xtensa/include/asm/types.h | 60 +++ arch/xtensa/include/asm/u-boot.h | 43 +++ arch/xtensa/include/asm/unaligned.h | 6 + arch/xtensa/include/asm/xtensa.h | 36 ++ arch/xtensa/lib/Makefile | 9 + arch/xtensa/lib/board.c | 173 +++++++++ arch/xtensa/lib/bootm.c | 202 ++++++++++ arch/xtensa/lib/misc.S | 178 +++++++++ arch/xtensa/lib/time.c | 111 ++++++ 39 files changed, 3125 insertions(+) create mode 100644 arch/xtensa/Kconfig create mode 100644 arch/xtensa/config.mk create mode 100644 arch/xtensa/cpu/.gitignore create mode 100644 arch/xtensa/cpu/Makefile create mode 100644 arch/xtensa/cpu/config.mk create mode 100644 arch/xtensa/cpu/cpu.c create mode 100644 arch/xtensa/cpu/exceptions.c create mode 100644 arch/xtensa/cpu/start.S create mode 100644 arch/xtensa/cpu/u-boot.lds.S create mode 100644 arch/xtensa/include/asm/addrspace.h create mode 100644 arch/xtensa/include/asm/asmmacro.h create mode 100644 arch/xtensa/include/asm/bitops.h create mode 100644 arch/xtensa/include/asm/bootparam.h create mode 100644 arch/xtensa/include/asm/byteorder.h create mode 100644 arch/xtensa/include/asm/cache.h create mode 100644 arch/xtensa/include/asm/cacheasm.h create mode 100644 arch/xtensa/include/asm/config.h create mode 100644 arch/xtensa/include/asm/errno.h create mode 100644 arch/xtensa/include/asm/global_data.h create mode 100644 arch/xtensa/include/asm/io.h create mode 100644 arch/xtensa/include/asm/ldscript.h create mode 100644 arch/xtensa/include/asm/linkage.h create mode 100644 arch/xtensa/include/asm/misc.h create mode 100644 arch/xtensa/include/asm/posix_types.h create mode 100644 arch/xtensa/include/asm/processor.h create mode 100644 arch/xtensa/include/asm/ptrace.h create mode 100644 arch/xtensa/include/asm/regs.h create mode 100644 arch/xtensa/include/asm/sections.h create mode 100644 arch/xtensa/include/asm/string.h create mode 100644 arch/xtensa/include/asm/types.h create mode 100644 arch/xtensa/include/asm/u-boot.h create mode 100644 arch/xtensa/include/asm/unaligned.h create mode 100644 arch/xtensa/include/asm/xtensa.h create mode 100644 arch/xtensa/lib/Makefile create mode 100644 arch/xtensa/lib/board.c create mode 100644 arch/xtensa/lib/bootm.c create mode 100644 arch/xtensa/lib/misc.S create mode 100644 arch/xtensa/lib/time.c
diff --git a/arch/Kconfig b/arch/Kconfig index 8620a4f..d19386a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -47,6 +47,9 @@ config SPARC config X86 bool "x86 architecture"
+config XTENSA + bool "Xtensa architecture" + endchoice
source "arch/arc/Kconfig" @@ -64,3 +67,4 @@ source "arch/sandbox/Kconfig" source "arch/sh/Kconfig" source "arch/sparc/Kconfig" source "arch/x86/Kconfig" +source "arch/xtensa/Kconfig" diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig new file mode 100644 index 0000000..e4e3625 --- /dev/null +++ b/arch/xtensa/Kconfig @@ -0,0 +1,26 @@ +menu "Xtensa architecture" + depends on XTENSA + +config SYS_ARCH + string + default "xtensa" + +config SYS_CPU + string "Xtensa Core Variant" + +choice + prompt "Target select" + + +endchoice + + +config HAVE_SYS_ASCDISP + bool + +config SYS_ASCDISP + bool "System LCD Display" + default y + depends on HAVE_SYS_ASCDISP + +endmenu diff --git a/arch/xtensa/config.mk b/arch/xtensa/config.mk new file mode 100644 index 0000000..a9a5e99 --- /dev/null +++ b/arch/xtensa/config.mk @@ -0,0 +1,13 @@ +# +# (C) Copyright 2007 - 2014 Tensilica, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +CROSS_COMPILE ?= xtensa-linux- +PLATFORM_CPPFLAGS += -D__XTENSA__ -mlongcalls + +CPUDIR = arch/$(ARCH)/cpu + +__HAVE_ARCH_GENERIC_BOARD := y + diff --git a/arch/xtensa/cpu/.gitignore b/arch/xtensa/cpu/.gitignore new file mode 100644 index 0000000..09f1be0 --- /dev/null +++ b/arch/xtensa/cpu/.gitignore @@ -0,0 +1 @@ +u-boot.lds diff --git a/arch/xtensa/cpu/Makefile b/arch/xtensa/cpu/Makefile new file mode 100644 index 0000000..e47af19 --- /dev/null +++ b/arch/xtensa/cpu/Makefile @@ -0,0 +1,13 @@ +# +# (C) Copyright 2007 - 2013 Tensilica, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y = cpu.o exceptions.o +extra-y = start.o + +$(obj).depend.%: %.lds.S + $(CC) -M $(CPPFLAGS) $(EXTRA_CPPFLAGS_DEP) \ + -MQ $(obj)$(basename $<) $< >$@ + diff --git a/arch/xtensa/cpu/config.mk b/arch/xtensa/cpu/config.mk new file mode 100644 index 0000000..986b1f6 --- /dev/null +++ b/arch/xtensa/cpu/config.mk @@ -0,0 +1,9 @@ +# +# (C) Copyright 2007 - 2013 Tensilica, Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +# The linker script is pre-processed by CPP to adapt to the Xtensa core. +LDSCRIPT := $(srctree)/$(CPUDIR)/u-boot.lds.S +LDPPFLAGS := -I$(srctree)/include diff --git a/arch/xtensa/cpu/cpu.c b/arch/xtensa/cpu/cpu.c new file mode 100644 index 0000000..828f029 --- /dev/null +++ b/arch/xtensa/cpu/cpu.c @@ -0,0 +1,84 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * CPU specific code + */ + +#include <common.h> +#include <command.h> +#include <linux/stringify.h> +#include <asm/cache.h> +#include <asm/string.h> +#include <asm/misc.h> + +#ifndef __XTENSA_CALL0_ABI__ +gd_t *gd; +#endif + +/* + * Print information about the CPU. + */ + +int checkcpu(void) +{ + DECLARE_GLOBAL_DATA_PTR; + char buf[120], mhz[8]; + uint32_t id0, id1; + + asm volatile ("rsr %0, 176\n" + "rsr %1, 208\n" + : "=r"(id0), "=r"(id1)); + + sprintf(buf, "CPU: Xtensa %s (id: %08x:%08x) at %s MHz\n", + XCHAL_CORE_ID, id0, id1, strmhz(mhz, gd->cpu_clk)); + puts(buf); + return 0; +} + +/* + * Implement the "reset" command. + * We need support from the board, though. + */ + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + board_reset(); + + /* Shouldn't come back! */ + printf("****** RESET FAILED ******\n"); + return 0; +} + +/* + * We currently run always with caches enabled when running for mmemory. + * Xtensa version D or later will support changing cache behavior, so + * we could implement it if necessary. + */ + +int dcache_status(void) +{ + return 1; +} + +void dcache_enable(void) +{ +} + +void dcache_disable(void) +{ +} + +void flush_cache(ulong start_addr, ulong size) +{ + __flush_invalidate_dcache_range(start_addr, size); + __invalidate_icache_range(start_addr, size); +} + +void flush_dcache_range(ulong start_addr, ulong end_addr) +{ + __flush_invalidate_dcache_range(start_addr, end_addr - start_addr); +} diff --git a/arch/xtensa/cpu/exceptions.c b/arch/xtensa/cpu/exceptions.c new file mode 100644 index 0000000..6edc6e4 --- /dev/null +++ b/arch/xtensa/cpu/exceptions.c @@ -0,0 +1,67 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica Inc. + * (C) Copyright 2014 Cadence Design Systems Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * Exception handling. + * We currently don't handle any exception and force a reset. + * (Note that alloca is a special case and handled in start.S) + */ + +#include <common.h> +#include <command.h> +#include <asm/xtensa.h> +#include <asm/string.h> +#include <asm/regs.h> + +typedef void (*handler_t)(struct pt_regs *); + +void xtensa_mem_exc_dummy(struct pt_regs *); + +void unhandled_exception(struct pt_regs *regs) +{ +#ifdef CONFIG_SYS_ASCDISP + display_printf("!! EXCCAUSE = %2ld", regs->exccause); +#endif + printf("Unhandled Exception: EXCCAUSE = %ld (pc %lx)\n", + regs->exccause, regs->pc); + udelay(10000000); /* 10s to read display message */ + panic("*** PANIC\n"); +} + +#define E(cause) EXCCAUSE_ ## cause + +handler_t exc_table[EXCCAUSE_LAST] = { + [0 ... EXCCAUSE_LAST-1] = unhandled_exception, + [EXCCAUSE_LOAD_STORE_ERROR] = xtensa_mem_exc_dummy, + [EXCCAUSE_UNALIGNED] = xtensa_mem_exc_dummy, + [EXCCAUSE_LOAD_STORE_DATA_ERROR] = xtensa_mem_exc_dummy, + [EXCCAUSE_LOAD_STORE_ADDR_ERROR] = xtensa_mem_exc_dummy, + [EXCCAUSE_FETCH_CACHE_ATTRIBUTE] = xtensa_mem_exc_dummy, + [EXCCAUSE_DTLB_MISS] = xtensa_mem_exc_dummy, + [EXCCAUSE_DTLB_MULTIHIT] = xtensa_mem_exc_dummy, + [EXCCAUSE_DTLB_PRIVILEGE] = xtensa_mem_exc_dummy, + [EXCCAUSE_DTLB_SIZE_RESTRICTION] = xtensa_mem_exc_dummy, + [EXCCAUSE_LOAD_CACHE_ATTRIBUTE] = xtensa_mem_exc_dummy, + [EXCCAUSE_STORE_CACHE_ATTRIBUTE] = xtensa_mem_exc_dummy, +}; + +#ifdef CONFIG_USE_IRQ +#error "Use of interrupts is not supported in Avnet/Xtensa ports" +#else +int interrupt_init(void) +{ + return 0; +} +void enable_interrupts(void) +{ + return; +} +int disable_interrupts(void) +{ + return 0; +} +#endif diff --git a/arch/xtensa/cpu/start.S b/arch/xtensa/cpu/start.S new file mode 100644 index 0000000..3d31c88 --- /dev/null +++ b/arch/xtensa/cpu/start.S @@ -0,0 +1,672 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/asmmacro.h> +#include <asm/regs.h> +#include <asm/arch/tie.h> +#include <asm-offsets.h> + +/* + * Offsets into the the pt_regs struture. + * Make sure these always match with the structure defined in ptrace.h! + */ + +#define PT_PC 0 +#define PT_PS 4 +#define PT_DEPC 8 +#define PT_EXCCAUSE 12 +#define PT_EXCVADDR 16 +#define PT_DEBUGCAUSE 20 +#define PT_WMASK 24 +#define PT_LBEG 28 +#define PT_LEND 32 +#define PT_LCOUNT 36 +#define PT_SAR 40 +#define PT_WINDOWBASE 44 +#define PT_WINDOWSTART 48 +#define PT_SYSCALL 52 +#define PT_ICOUNTLEVEL 56 +#define PT_RESERVED 60 +#define PT_AREG 64 +#define PT_SIZE (64 + 64) + +/* + * Reset vector. + * Only a trampoline to jump to _start + * (Note that we have to mark the section writable as the section contains + * a relocatable literal) + */ + + .section .ResetVector.text, "awx" + .global _ResetVector +_ResetVector: + + j 1f + .align 4 +2: .long _start +1: l32r a2, 2b + jx a2 + + +/* + * Processor initialization. We still run in rom space. + * + * NOTE: Running in ROM + * For Xtensa, we currently don't allow to run some code from ROM but + * unpack the data immediately to memory. This requires, for example, + * that DDR has been set up before running U-Boot. (See also comments + * inline for ways to change it) + */ + + .section .reset.text, "ax" + .global _start + .align 4 +_start: + /* Keep a0 = 0 for various initializations. */ + + movi a0, 0 + + /* + * For full MMU cores, put page table at unmapped virtual address. + * This ensures that accesses outside the static maps result + * in miss exceptions rather than random behaviour. + */ + +#if XCHAL_HAVE_TLBS + wsr a0, PTEVADDR +#endif + + /* Disable dbreak debug exceptions. */ + +#if XCHAL_HAVE_DEBUG && XCHAL_NUM_DBREAK > 0 + .set _index, 0 + .rept XCHAL_NUM_DBREAK - 1 + wsr a0, DBREAKC + _index + .set _index, _index + 1 + .endr +#endif + + /* Reset windowbase and windowstart. */ + +#if XCHAL_HAVE_WINDOWED + movi a3, 1 + wsr a3, windowstart + wsr a0, windowbase + rsync + movi a0, 0 /* windowbase might have changed */ +#endif + +# +# Vecbase in bitstream may differ from header files +# set or check it. +# + +#if XCHAL_HAVE_VECBASE + movi a3, XCHAL_VECBASE_RESET_VADDR /* VECBASE reset value */ + wsr a3, VECBASE +#endif + + /* Disable loops. */ + + wsr a0, LCOUNT + + /* Set PS.WOE = 0, PS.EXCM = 0 (for loop), PS.INTLEVEL = EXCM level */ + +#if XCHAL_HAVE_XEA1 + movi a2, 1 +#else + movi a2, XCHAL_EXCM_LEVEL +#endif + wsr a2, PS + rsync + + /* Unlock and invalidate caches. */ + + movi a2, 0 + __loopi a2, a3, XCHAL_DCACHE_SIZE, 4 << XCHAL_DCACHE_LINEWIDTH +#if XCHAL_DCACHE_LINE_LOCKABLE + diu a2, 0 << XCHAL_DCACHE_LINEWIDTH + diu a2, 1 << XCHAL_DCACHE_LINEWIDTH + diu a2, 2 << XCHAL_DCACHE_LINEWIDTH + diu a2, 3 << XCHAL_DCACHE_LINEWIDTH +#endif + dii a2, 0 << XCHAL_DCACHE_LINEWIDTH + dii a2, 1 << XCHAL_DCACHE_LINEWIDTH + dii a2, 2 << XCHAL_DCACHE_LINEWIDTH + dii a2, 3 << XCHAL_DCACHE_LINEWIDTH + __endla a2, a3, 4 << XCHAL_DCACHE_LINEWIDTH + + movi a2, 0 + __loopi a2, a3, XCHAL_ICACHE_SIZE, 4 << XCHAL_ICACHE_LINEWIDTH +#if XCHAL_ICACHE_LINE_LOCKABLE + iiu a2, 0 << XCHAL_ICACHE_LINEWIDTH + iiu a2, 1 << XCHAL_ICACHE_LINEWIDTH + iiu a2, 2 << XCHAL_ICACHE_LINEWIDTH + iiu a2, 3 << XCHAL_ICACHE_LINEWIDTH +#endif + iii a2, 0 << XCHAL_ICACHE_LINEWIDTH + iii a2, 1 << XCHAL_ICACHE_LINEWIDTH + iii a2, 2 << XCHAL_ICACHE_LINEWIDTH + iii a2, 3 << XCHAL_ICACHE_LINEWIDTH + __endla a2, a3, 4 << XCHAL_ICACHE_LINEWIDTH + + isync + +#if XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY + movi a2, XCHAL_SPANNING_WAY + movi a3, 7 + wdtlb a3, a2 + witlb a3, a2 + isync +#endif + + /* Unpack data sections. */ + + movi a2, __reloc_table_start + movi a3, __reloc_table_end + +1: beq a2, a3, 3f # no more entries? + l32i a4, a2, 0 # start destination (in RAM) + l32i a5, a2, 4 # end destination (in RAM) + l32i a6, a2, 8 # start source (in ROM) + addi a2, a2, 12 # next entry + beq a4, a5, 1b # skip, empty entry + beq a4, a6, 1b # skip, source and destination are the same + +2: l32i a7, a6, 0 + addi a6, a6, 4 + s32i a7, a4, 0 + addi a4, a4, 4 + bltu a4, a5, 2b + j 1b + +3: /* All code and initalized data segments have been copied. */ + + /* Setup PS, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */ + +#if __XTENSA_CALL0_ABI__ + movi a2, XCHAL_EXCM_LEVEL +#else + movi a2, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL +#endif + wsr a2, PS + rsync + + + /* + * Setup a small stack for some early initialization c-code. + * Also, set up a temporary GD. + * (reserve 16 bytes for the call4 stack frame) + */ + + /* Clear BSS */ + + movi a2, _bss_start + movi a3, _bss_end + + __loopt a2, a3, a4, 2 + s32i a0, a2, 0 + __endla a2, a4, 4 + + /* Writeback */ + + movi a2, 0 + __loopi a2, a3, XCHAL_DCACHE_SIZE, 4 << XCHAL_DCACHE_LINEWIDTH + diwb a2, 0 << XCHAL_DCACHE_LINEWIDTH + diwb a2, 1 << XCHAL_DCACHE_LINEWIDTH + diwb a2, 2 << XCHAL_DCACHE_LINEWIDTH + diwb a2, 3 << XCHAL_DCACHE_LINEWIDTH + __endla a2, a3, 4 << XCHAL_DCACHE_LINEWIDTH + + + /* + * Call board initialization routine (never returns). + */ + + movi a6, (CONFIG_SYS_GD_ADDR & -16) & 0xffffffff + movi a1, (CONFIG_SYS_SP_TOP & -16) & 0xffffffff + + movi a4, xtensa_board_init + +#ifdef __XTENSA_CALL0_ABI__ + mov a2, a6 + mov a3, a1 + callx0 a4 +#else + mov a7, a1 + addi a1, a1, -16 + callx4 a4 +#endif + /* Never Returns */ + ill + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * a0 = addr_sp + * a1 = gd + * a2 = destination address + */ + .text + .globl relocate_code + .align 4 +relocate_code: + entry a1, 16 + retw + +#if XCHAL_HAVE_EXCEPTIONS + +/* + * Exception vectors. + * + * Various notes: + * - We currently don't use the user exception vector (PS.UM is always 0), + * but do define such a vector, just in case. They both jump to the + * same exception handler, though. + * - We currently only save the bare minimum number of registers: + * a0...a15, sar, loop-registers, exception register (epc1, excvaddr, + * exccause, depc) + * - WINDOWSTART is only saved to identify if registers have been spilled + * to the wrong stack (exception stack) while executing the exception + * handler. + */ + + .section .KernelExceptionVector.text, "ax" + .global _KernelExceptionVector +_KernelExceptionVector: + + wsr a2, EXCSAVE1 + movi a2, ExceptionHandler + jx a2 + + .section .UserExceptionVector.text, "ax" + .global _UserExceptionVector +_UserExceptionVector: + + wsr a2, EXCSAVE1 + movi a2, ExceptionHandler + jx a2 + +#if !XCHAL_HAVE_XEA1 + .section .DoubleExceptionVector.text, "ax" + .global _DoubleExceptionVector +_DoubleExceptionVector: + +#ifdef __XTENSA_CALL0_ABI__ + wsr a0, EXCSAVE1 + movi a0, hang # report and ask user to reset board + callx0 a0 +#else + wsr a4, EXCSAVE1 + movi a4, hang # report and ask user to reset board + callx4 a4 +#endif +#endif + /* Does not return here. */ + + + .text + .align 4 +ExceptionHandler: + + rsr a2, EXCCAUSE # find handler + + /* Special case for alloca handler. */ + + bnei a2, 5, 1f # jump if not alloca exception + + addi a1, a1, -16 - 4 # create a small stack frame + s32i a3, a1, 0 # and save a3 (a2 still in excsave1) + movi a2, fast_alloca_exception + jx a2 # jump to fast_alloca_exception + + /* All other exceptions go here: */ + + /* Create ptrace stack and save a0...a3 */ + +1: addi a2, a1, - PT_SIZE - 16 + s32i a0, a2, PT_AREG + 0 * 4 + s32i a1, a2, PT_AREG + 1 * 4 + s32i a3, a2, PT_AREG + 3 * 4 + rsr a3, EXCSAVE1 + s32i a3, a2, PT_AREG + 2 * 4 + mov a1, a2 + + /* Save remaining AR registers. */ + + s32i a4, a1, PT_AREG + 4 * 4 + s32i a5, a1, PT_AREG + 5 * 4 + s32i a6, a1, PT_AREG + 6 * 4 + s32i a7, a1, PT_AREG + 7 * 4 + s32i a8, a1, PT_AREG + 8 * 4 + s32i a9, a1, PT_AREG + 9 * 4 + s32i a10, a1, PT_AREG + 10 * 4 + s32i a11, a1, PT_AREG + 11 * 4 + s32i a12, a1, PT_AREG + 12 * 4 + s32i a13, a1, PT_AREG + 13 * 4 + s32i a14, a1, PT_AREG + 14 * 4 + s32i a15, a1, PT_AREG + 15 * 4 + + /* Save SRs */ + + rsr a2, WINDOWSTART + s32i a2, a1, PT_WINDOWSTART + + rsr a2, SAR + rsr a3, EPC1 + s32i a2, a1, PT_SAR + s32i a3, a1, PT_PC + +#if XCHAL_HAVE_LOOPS + movi a2, 0 + rsr a3, LBEG + xsr a2, LCOUNT + s32i a3, a1, PT_LBEG + rsr a3, LEND + s32i a2, a1, PT_LCOUNT + s32i a3, a1, PT_LEND +#endif + + /* Set up C environment and call registered handler. */ + /* Setup stack, PS.WOE = 1, PS.EXCM = 0, PS.INTLEVEL = EXCM level. */ + + rsr a2, EXCCAUSE +#if XCHAL_HAVE_XEA1 + movi a3, (1<<PS_WOE_BIT) | 1 +#elif __XTENSA_CALL0_ABI__ + movi a3, XCHAL_EXCM_LEVEL +#else + movi a3, (1<<PS_WOE_BIT) | XCHAL_EXCM_LEVEL +#endif + xsr a3, PS + rsync + s32i a2, a1, PT_EXCCAUSE + s32i a3, a1, PT_PS + + movi a0, exc_table + addx4 a0, a2, a0 + l32i a0, a0, 0 +#ifdef __XTENSA_CALL0_ABI__ + mov a2, a1 # Provide stack frame as only argument + callx0 a0 + l32i a3, a1, PT_PS +#else + mov a6, a1 # Provide stack frame as only argument + callx4 a0 +#endif + + /* Restore PS and go to exception mode (PS.EXCM=1) */ + + wsr a3, PS + + /* Restore SR registers */ + +#if XCHAL_HAVE_LOOPS + l32i a2, a1, PT_LBEG + l32i a3, a1, PT_LEND + l32i a4, a1, PT_LCOUNT + wsr a2, LBEG + wsr a3, LEND + wsr a4, LCOUNT +#endif + + l32i a2, a1, PT_SAR + l32i a3, a1, PT_PC + wsr a2, SAR + wsr a3, EPC1 + + /* Do we need to simulate a MOVSP? */ + + l32i a2, a1, PT_WINDOWSTART + addi a3, a2, -1 + and a2, a2, a3 + beqz a2, 1f # Skip if regs were spilled before exc. + + rsr a2, WINDOWSTART + addi a3, a2, -1 + and a2, a2, a3 + bnez a2, 1f # Skip if registers aren't spilled now + + addi a2, a1, -16 + l32i a4, a2, 0 + l32i a5, a2, 4 + s32i a4, a1, PT_SIZE + 0 + s32i a5, a1, PT_SIZE + 4 + l32i a4, a2, 8 + l32i a5, a2, 12 + s32i a4, a1, PT_SIZE + 8 + s32i a5, a1, PT_SIZE + 12 + + /* Restore address register. */ + +1: l32i a15, a1, PT_AREG + 15 * 4 + l32i a14, a1, PT_AREG + 14 * 4 + l32i a13, a1, PT_AREG + 13 * 4 + l32i a12, a1, PT_AREG + 12 * 4 + l32i a11, a1, PT_AREG + 11 * 4 + l32i a10, a1, PT_AREG + 10 * 4 + l32i a9, a1, PT_AREG + 9 * 4 + l32i a8, a1, PT_AREG + 8 * 4 + l32i a7, a1, PT_AREG + 7 * 4 + l32i a6, a1, PT_AREG + 6 * 4 + l32i a5, a1, PT_AREG + 5 * 4 + l32i a4, a1, PT_AREG + 4 * 4 + l32i a3, a1, PT_AREG + 3 * 4 + l32i a2, a1, PT_AREG + 2 * 4 + l32i a0, a1, PT_AREG + 0 * 4 + + l32i a1, a1, PT_AREG + 1 * 4 # Remove ptrace stack frame + + rfe + + +/* + * Dummy memory exception handler to avoid crash/hang on load/store of + * an invalid address (such as might be requested by user "md" command). + * U-Boot currently does not provide a hook to prevent accessing invalid + * addresses nor to inform the user, so we have to try to live with it. + * Simply skip the offending instruction (don't care what load returns). + * This is ugly (and possibly dangerous in Xtensa FLIX configs), but if we + * get here we're in trouble anyway, so might as well *try* to recover. + * void xtensa_mem_exc_dummy(struct pt_regs*); + */ + /* Table of instruction sizes based on op0 field. */ + .section .rodata, "a" + .type op0_format_lengths, @object + .align 4 +op0_format_lengths: + .byte XCHAL_OP0_FORMAT_LENGTHS + + .text + .global xtensa_mem_exc_dummy + .type xtensa_mem_exc_dummy, @function + .align 4 +xtensa_mem_exc_dummy: + +#ifndef __XTENSA_CALL0_ABI__ + entry a1, 16 +#endif + + /* Decode the size of the instruction that caused the exception. */ + l32i a3, a2, PT_PC /* a3 = PC of exception */ + l8ui a4, a3, 0 /* a4 = first byte of insn */ + movi a5, op0_format_lengths /* a5 = table of instruction sizes */ + #if XCHAL_HAVE_BE + extui a4, a4, 4, 4 /* a4 = op0 = big end nibble */ + #else + extui a4, a4, 0, 4 /* a4 = op0 = little end nibble */ + #endif + add a5, a5, a4 /* index table with op0 */ + l8ui a4, a5, 0 /* a4 = instruction size */ + + /* Increment the PC past the instruction that caused the exception. */ + add a3, a3, a4 /* PC += size of insn */ + #if XCHAL_HAVE_LOOPS + l32i a4, a2, PT_LEND /* if (PC == LEND */ + bne a3, a4, 1f + l32i a4, a2, PT_LCOUNT /* && LCOUNT != 0) */ + beqz a4, 1f /* { */ + addi a4, a4, -1 /* --LCOUNT */ + l32i a3, a2, PT_LBEG /* PC = LBEG */ + s32i a4, a2, PT_LCOUNT /* } */ + #endif +1: s32i a3, a2, PT_PC /* update PC */ + +#ifdef __XTENSA_CALL0_ABI__ + ret +#else + retw +#endif + +#endif /* XCHAL_HAVE_EXCEPTIONS */ + +#if XCHAL_HAVE_WINDOWED + +/* + * Window overflow and underflow handlers. + * The handlers must be 64 bytes apart, first starting with the underflow + * handlers underflow-4 to underflow-12, then the overflow handlers + * overflow-4 to overflow-12. + * + * Note: We rerun the underflow handlers if we hit an exception, so + * we try to access any page that would cause a page fault early. + */ + + .section .WindowVectors.text, "ax" + +/* 4-Register Window Overflow Vector (Handler) */ + + .align 64 +.global _WindowOverflow4 +_WindowOverflow4: + s32e a0, a5, -16 + s32e a1, a5, -12 + s32e a2, a5, -8 + s32e a3, a5, -4 + rfwo + + +/* 4-Register Window Underflow Vector (Handler) */ + + .align 64 +.global _WindowUnderflow4 +_WindowUnderflow4: + l32e a0, a5, -16 + l32e a1, a5, -12 + l32e a2, a5, -8 + l32e a3, a5, -4 + rfwu + +/* + * a0: a0 + * a1: new stack pointer = a1 - 16 - 4 + * a2: available, saved in excsave1 + * a3: available, saved on stack *a1 + */ + +/* 15*/ .byte 0xff + +fast_alloca_exception: /* must be at _WindowUnderflow4 + 16 + +/* 16*/ rsr a2, PS +/* 19*/ rsr a3, WINDOWBASE +/* 22*/ extui a2, a2, PS_OWB_SHIFT, PS_OWB_SHIFT +/* 25*/ xor a2, a2, a3 +/* 28*/ rsr a3, PS +/* 31*/ slli a2, a2, PS_OWB_SHIFT +/* 34*/ xor a2, a3, a2 +/* 37*/ wsr a2, PS + +/* 40*/ _l32i a3, a1, 0 +/* 43*/ addi a1, a1, 16 + 4 +/* 46*/ rsr a2, EXCSAVE1 + +/* 49*/ rotw -1 +/* 52*/ _bbci.l a4, 31, _WindowUnderflow4 /* 0x: call4 */ +/* 55*/ rotw -1 +/* 58*/ _bbci.l a8, 30, _WindowUnderflow8 /* 10: call8 */ +/* 61*/ _j __WindowUnderflow12 /* 11: call12 */ +/* 64*/ + +/* 8-Register Window Overflow Vector (Handler) */ + + .align 64 +.global _WindowOverflow8 +_WindowOverflow8: + s32e a0, a9, -16 + l32e a0, a1, -12 + s32e a2, a9, -8 + s32e a1, a9, -12 + s32e a3, a9, -4 + s32e a4, a0, -32 + s32e a5, a0, -28 + s32e a6, a0, -24 + s32e a7, a0, -20 + rfwo + +/* 8-Register Window Underflow Vector (Handler) */ + + .align 64 +.global _WindowUnderflow8 +_WindowUnderflow8: + l32e a1, a9, -12 + l32e a0, a9, -16 + l32e a7, a1, -12 + l32e a2, a9, -8 + l32e a4, a7, -32 + l32e a3, a9, -4 + l32e a5, a7, -28 + l32e a6, a7, -24 + l32e a7, a7, -20 + rfwu + +/* 12-Register Window Overflow Vector (Handler) */ + + .align 64 +.global _WindowOverflow12 +_WindowOverflow12: + s32e a0, a13, -16 + l32e a0, a1, -12 + s32e a1, a13, -12 + s32e a2, a13, -8 + s32e a3, a13, -4 + s32e a4, a0, -48 + s32e a5, a0, -44 + s32e a6, a0, -40 + s32e a7, a0, -36 + s32e a8, a0, -32 + s32e a9, a0, -28 + s32e a10, a0, -24 + s32e a11, a0, -20 + rfwo + +/* 12-Register Window Underflow Vector (Handler) */ + + .org _WindowOverflow12 + 64 - 3 +__WindowUnderflow12: + rotw -1 +.global _WindowUnderflow12 +_WindowUnderflow12: + l32e a1, a13, -12 + l32e a0, a13, -16 + l32e a11, a1, -12 + l32e a2, a13, -8 + l32e a4, a11, -48 + l32e a8, a11, -32 + l32e a3, a13, -4 + l32e a5, a11, -44 + l32e a6, a11, -40 + l32e a7, a11, -36 + l32e a9, a11, -28 + l32e a10, a11, -24 + l32e a11, a11, -20 + rfwu + +#endif /* XCHAL_HAVE_WINDOWED */ diff --git a/arch/xtensa/cpu/u-boot.lds.S b/arch/xtensa/cpu/u-boot.lds.S new file mode 100644 index 0000000..ff2fe83 --- /dev/null +++ b/arch/xtensa/cpu/u-boot.lds.S @@ -0,0 +1,107 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <asm/ldscript.h> +#include <asm/arch/core.h> +#include <asm/addrspace.h> +#include <asm-offsets.h> + +OUTPUT_ARCH(xtensa) +ENTRY(_start) + +/* + * U-Boot resets from SYSROM and unpacks itself from a ROM store to RAM. + * The reset vector is usually near the base of SYSROM and has room + * above it for the ROM store into which the rest of U-Boot is packed. + * The ROM store also needs to be above any other vectors that are in ROM. + * If a core has its vectors near the top of ROM, this must be edited. + * + * Note that to run C code out of ROM, the processor would have to support + * 'relocatable' exception vectors and provide a scratch memory for the + * initial stack. Not all Xtensa processor configurations support that, so + * we can simplify the boot process and unpack U-Boot to RAM immediately. + * This, however, requires that memory have been initialized throug some + * other means (serial ROM, for example) or are initialized early (requiring + * an assembler functiont. See start.S for more details) + */ + +SECTIONS +{ + . = + SIZEOF_HEADERS; + SECTION_ResetVector(XCHAL_RESET_VECTOR_VADDR, LMA_EQ_VMA) + + .reloc_table ALIGN(4) : FOLLOWING(.ResetVector.text) + { + __reloc_table_start = ABSOLUTE(.); + RELOCATE2(WindowVectors,text); + RELOCATE2(KernelExceptionVector,literal); + RELOCATE2(KernelExceptionVector,text); + RELOCATE2(UserExceptionVector,literal); + RELOCATE2(UserExceptionVector,text); + RELOCATE2(DoubleExceptionVector,literal); + RELOCATE2(DoubleExceptionVector,text); + RELOCATE1(text); + RELOCATE1(rodata); + RELOCATE1(data); + RELOCATE1(u_boot_list); + __reloc_table_end = ABSOLUTE(.); + } + + SECTION_VECTOR(WindowVectors,text,XCHAL_WINDOW_VECTORS_VADDR, + FOLLOWING(.reloc_table)) + SECTION_VECTOR(KernelExceptionVector,literal,XCHAL_KERNEL_VECTOR_VADDR-8, + FOLLOWING(.WindowVectors.text)) + SECTION_VECTOR(KernelExceptionVector,text,XCHAL_KERNEL_VECTOR_VADDR, + FOLLOWING(.KernelExceptionVector.literal)) + SECTION_VECTOR(UserExceptionVector,literal,XCHAL_USER_VECTOR_VADDR-8, + FOLLOWING(.KernelExceptionVector.text)) + SECTION_VECTOR(UserExceptionVector,text,XCHAL_USER_VECTOR_VADDR, + FOLLOWING(.UserExceptionVector.literal)) + SECTION_VECTOR(DoubleExceptionVector,literal,XCHAL_DOUBLEEXC_VECTOR_VADDR-8, + FOLLOWING(.UserExceptionVector.text)) + SECTION_VECTOR(DoubleExceptionVector,text,XCHAL_DOUBLEEXC_VECTOR_VADDR, + FOLLOWING(.DoubleExceptionVector.literal)) + + + SECTION_text(CONFIG_SYS_TEXT_ADDR, FOLLOWING(.DoubleExceptionVector.text)) + SECTION_rodata(ALIGN(16), FOLLOWING(.text)) + SECTION_u_boot_list(ALIGN(16), FOLLOWING(.rodata)) + SECTION_data(ALIGN(16), FOLLOWING(.u_boot_list)) + + __reloc_end = .; + __init_end = .; + + SECTION_bss(__init_end (OVERLAY),) + + /* + * On many Xtensa boards a region of RAM may be mapped to the ROM address + * space to facilitate on-chip-debug, and U-Boot must fit with that region. + * The config variables CONFIG_SYS_MONITOR_* define the region. + * If U-Boot extends beyond this region it will appear discontiguous in the + * address space and is in danger of overwriting itself during unpacking + * ("relocation"). + * This causes U-Boot to crash in a way that is difficult to debug. On some + * boards (such as xtav60) the region is small enough that U-Boot will not + * fit if compiled entirely with -O0 (a common scenario). To avoid a lengthy + * debugging session when this happens, ensure a link-time error occurs. + * + */ + + __monitor_start = LOADADDR(.ResetVector.text); + __monitor_end = LOADADDR(.data) + SIZEOF(.data); + ASSERT(__monitor_end - __monitor_start <= CONFIG_SYS_MONITOR_LEN, + "U-Boot ROM image is too large. Check optimization level.") + + SECTION_xtensa + SECTION_debug + + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.hash*) } + /DISCARD/ : { *(.interp) } + /DISCARD/ : { *(.got*) } + /DISCARD/ : { *(.dynsym) } +} diff --git a/arch/xtensa/include/asm/addrspace.h b/arch/xtensa/include/asm/addrspace.h new file mode 100644 index 0000000..5e6ecd9 --- /dev/null +++ b/arch/xtensa/include/asm/addrspace.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2008-2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_ADDRSPACE_H +#define _XTENSA_ADDRSPACE_H + +#include <asm/arch/core.h> + +/* + * MMU Memory Map + * + * V2 MMU: + * IO (uncached) f0000000..ffffffff -> f000000 + * IO (cached) e0000000..efffffff -> f000000 + * MEM (uncached) d8000000..dfffffff -> 0000000 + * MEM (cached) d0000000..d7ffffff -> 0000000 + * + * V3 MMU: + * IO (uncached) f0000000..ffffffff -> f000000 + * MEM (uncached) 00000000..0fffffff -> 0000000 + * + */ + +/* Region typically starting at 0xf0000000 */ +#define CONFIG_SYS_IO_BASE 0xf0000000 + +/* + * Region typically starting at + * 0xD0000000 for V2 MMU + * and + * 0x00000000 for V3 MMU + */ +#define CONFIG_SYS_MEMORY_BASE \ + (XCHAL_VECBASE_RESET_VADDR - XCHAL_VECBASE_RESET_PADDR) + +#define IOADDR(x) (CONFIG_SYS_IO_BASE + (x)) +#define MEMADDR(x) (CONFIG_SYS_MEMORY_BASE + (x)) +#define PHYSADDR(x) ((x) - (CONFIG_SYS_MEMORY_BASE)) + +#endif /* _XTENSA_ADDRSPACE_H */ diff --git a/arch/xtensa/include/asm/asmmacro.h b/arch/xtensa/include/asm/asmmacro.h new file mode 100644 index 0000000..d8e3565 --- /dev/null +++ b/arch/xtensa/include/asm/asmmacro.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 2005 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_ASMMACRO_H +#define _XTENSA_ASMMACRO_H + +#include <asm/arch/core.h> + +/* + * Some little helpers for loops. Use zero-overhead-loops + * where applicable and if supported by the processor. + * + * __loopi ar, at, size, inc + * ar register initialized with the start address + * at scratch register used by macro + * size size immediate value + * inc increment + * + * __loops ar, as, at, inc_log2[, mask_log2][, cond][, ncond] + * ar register initialized with the start address + * as register initialized with the size + * at scratch register use by macro + * inc_log2 increment [in log2] + * mask_log2 mask [in log2] + * cond true condition (used in loop'cond') + * ncond false condition (used in b'ncond') + * + * __loop as + * restart loop. 'as' register must not have been modified! + * + * __endla ar, at, incr + * ar start address (modified) + * as scratch register used by macro + * inc increment + */ + +#if XCHAL_HAVE_LOOPS + +.macro __loopi ar, at, size, incr + movi \at, ((\size + \incr - 1) / (\incr)) + loop \at, 99f +.endm + + +.macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond + .ifgt \incr_log2 - 1 + addi \at, \as, (1 << \incr_log2) - 1 + .ifnc \mask_log2, + extui \at, \at, \incr_log2, \mask_log2 + .else + srli \at, \at, \incr_log2 + .endif + .endif + loop\cond \at, 99f +.endm + + +.macro __loopt ar, as, at, incr_log2 + sub \at, \as, \ar + .ifgt \incr_log2 - 1 + addi \at, \at, (1 << \incr_log2) - 1 + srli \at, \at, \incr_log2 + .endif + loop \at, 99f +.endm + + +.macro __loop as + loop \as, 99f +.endm + + +.macro __endl ar, as +99: +.endm + + +#else + +.macro __loopi ar, at, size, incr + movi \at, ((\size + \incr - 1) / (\incr)) + addi \at, \ar, \size +98: +.endm + + +.macro __loops ar, as, at, incr_log2, mask_log2, cond, ncond + .ifnc \mask_log2, + extui \at, \as, \incr_log2, \mask_log2 + .else + .ifnc \ncond, + srli \at, \as, \incr_log2 + .endif + .endif + .ifnc \ncond, + b\ncond \at, 99f + + .endif + .ifnc \mask_log2, + slli \at, \at, \incr_log2 + add \at, \ar, \at + .else + add \at, \ar, \as + .endif +98: +.endm + +.macro __loopt ar, as, at, incr_log2 +98: +.endm + + +.macro __loop as +98: +.endm + + +.macro __endl ar, as + bltu \ar, \as, 98b +99: +.endm + + +#endif + + +.macro __endla ar, as, incr + addi \ar, \ar, \incr + __endl \ar \as +.endm + + +#endif /* _XTENSA_ASMMACRO_H */ diff --git a/arch/xtensa/include/asm/bitops.h b/arch/xtensa/include/asm/bitops.h new file mode 100644 index 0000000..9cb84ac --- /dev/null +++ b/arch/xtensa/include/asm/bitops.h @@ -0,0 +1,14 @@ +/* + * Atomic operations that C can't guarantee us.Useful for resource counting etc. + * + * Copyright (C) 2001 - 2012 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_BITOPS_H +#define _XTENSA_BITOPS_H + +/* Use generic implementation */ + +#endif /* _XTENSA_BITOPS_H */ diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h new file mode 100644 index 0000000..dd79485 --- /dev/null +++ b/arch/xtensa/include/asm/bootparam.h @@ -0,0 +1,54 @@ +/* + * Definition of the Linux/Xtensa boot parameter structure + * + * Copyright (C) 2001 - 2009 Tensilica Inc. + * + * (Concept borrowed from the 68K port) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_BOOTPARAM_H +#define _XTENSA_BOOTPARAM_H + +#define BP_VERSION 0x0001 + +#define BP_TAG_COMMAND_LINE 0x1001 /* command line (0-terminated string)*/ +#define BP_TAG_INITRD 0x1002 /* ramdisk addr and size (bp_meminfo) */ +#define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ +#define BP_TAG_SERIAL_BAUDRATE 0x1004 /* baud rate of current console. */ +#define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ +#define BP_TAG_FDT 0x1006 /* flat device tree */ + +#define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ +#define BP_TAG_LAST 0x7E0B /* last tag */ + +#ifndef __ASSEMBLY__ + +/* All records are aligned to 4 bytes */ + +struct bp_tag { + unsigned short id; /* tag id */ + unsigned short size; /* size of this record excluding the structure*/ + unsigned long data[0]; /* data */ +}; + +#define bp_tag_next(tag) \ + ((struct bp_tag *)((unsigned long)((tag) + 1) + (tag)->size)) + +struct meminfo { + unsigned long type; + unsigned long start; + unsigned long end; +}; + +#define MEMORY_TYPE_CONVENTIONAL 0x1000 +#define MEMORY_TYPE_NONE 0x2000 + +struct sysmem_info { + int nr_banks; + struct meminfo bank[0]; +}; + +#endif +#endif diff --git a/arch/xtensa/include/asm/byteorder.h b/arch/xtensa/include/asm/byteorder.h new file mode 100644 index 0000000..485bc4b --- /dev/null +++ b/arch/xtensa/include/asm/byteorder.h @@ -0,0 +1,81 @@ +/* + * Based on Linux/Xtensa kernel version + * + * Copyright (C) 2001 - 2007 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_BYTEORDER_H +#define _XTENSA_BYTEORDER_H + +#include <asm/types.h> + +static inline __attribute__((const)) __u32 ___arch__swab32(__u32 x) +{ + __u32 res; + + /* instruction sequence from Xtensa ISA release 2/2000 */ + __asm__("ssai 8\n\t" + "srli %0, %1, 16\n\t" + "src %0, %0, %1\n\t" + "src %0, %0, %0\n\t" + "src %0, %1, %0\n" + : "=&a" (res) + : "a" (x) + ); + return res; +} + +static inline __attribute__((const)) __u16 ___arch__swab16(__u16 x) +{ + /* Given that 'short' values are signed (i.e., can be negative), + * we cannot assume that the upper 16-bits of the register are + * zero. We are careful to mask values after shifting. + */ + + /* There exists an anomaly between xt-gcc and xt-xcc. xt-gcc + * inserts an extui instruction after putting this function inline + * to ensure that it uses only the least-significant 16 bits of + * the result. xt-xcc doesn't use an extui, but assumes the + * __asm__ macro follows convention that the upper 16 bits of an + * 'unsigned short' result are still zero. This macro doesn't + * follow convention; indeed, it leaves garbage in the upport 16 + * bits of the register. + * + * Declaring the temporary variables 'res' and 'tmp' to be 32-bit + * types while the return type of the function is a 16-bit type + * forces both compilers to insert exactly one extui instruction + * (or equivalent) to mask off the upper 16 bits. + */ + + __u32 res; + __u32 tmp; + + __asm__("extui %1, %2, 8, 8\n\t" + "slli %0, %2, 8\n\t" + "or %0, %0, %1\n" + : "=&a" (res), "=&a" (tmp) + : "a" (x) + ); + + return res; +} + +#define __arch__swab32(x) ___arch__swab32(x) +#define __arch__swab16(x) ___arch__swab16(x) + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#ifdef __XTENSA_EL__ +# include <linux/byteorder/little_endian.h> +#elif defined(__XTENSA_EB__) +# include <linux/byteorder/big_endian.h> +#else +# error processor byte order undefined! +#endif + +#endif /* _XTENSA_BYTEORDER_H */ diff --git a/arch/xtensa/include/asm/cache.h b/arch/xtensa/include/asm/cache.h new file mode 100644 index 0000000..3999122 --- /dev/null +++ b/arch/xtensa/include/asm/cache.h @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2009 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _XTENSA_CACHE_H +#define _XTENSA_CACHE_H + +#include <asm/arch/core.h> + +#define ARCH_DMA_MINALIGN XCHAL_DCACHE_LINESIZE + +#ifndef __ASSEMBLY__ + +void __flush_invalidate_dcache_range(unsigned long addr, unsigned long size); +void __invalidate_icache_range(unsigned long addr, unsigned long size); + +#endif + +#endif /* _XTENSA_CACHE_H */ diff --git a/arch/xtensa/include/asm/cacheasm.h b/arch/xtensa/include/asm/cacheasm.h new file mode 100644 index 0000000..6c62cce --- /dev/null +++ b/arch/xtensa/include/asm/cacheasm.h @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2006 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_CACHEASM_H +#define _XTENSA_CACHEASM_H + +#include <asm/cache.h> +#include <asm/asmmacro.h> +#include <linux/stringify.h> + +#define PAGE_SIZE 4096 +#define DCACHE_WAY_SIZE (XCHAL_DCACHE_SIZE/XCHAL_DCACHE_WAYS) +#define ICACHE_WAY_SIZE (XCHAL_ICACHE_SIZE/XCHAL_ICACHE_WAYS) +#define DCACHE_WAY_SHIFT (XCHAL_DCACHE_SETWIDTH + XCHAL_DCACHE_LINEWIDTH) +#define ICACHE_WAY_SHIFT (XCHAL_ICACHE_SETWIDTH + XCHAL_ICACHE_LINEWIDTH) + +/* + * Define cache functions as macros here so that they can be used + * by the kernel and boot loader. We should consider moving them to a + * library that can be linked by both. + * + * Locking + * + * ___unlock_dcache_all + * ___unlock_icache_all + * + * Flush and invaldating + * + * ___flush_invalidate_dcache_{all|range|page} + * ___flush_dcache_{all|range|page} + * ___invalidate_dcache_{all|range|page} + * ___invalidate_icache_{all|range|page} + * + */ + + .macro __loop_cache_all ar at insn size line_width + + movi \ar, 0 + + __loopi \ar, \at, \size, (4 << (\line_width)) + + \insn \ar, 0 << (\line_width) + \insn \ar, 1 << (\line_width) + \insn \ar, 2 << (\line_width) + \insn \ar, 3 << (\line_width) + + __endla \ar, \at, 4 << (\line_width) + + .endm + + + .macro __loop_cache_range ar as at insn line_width + + extui \at, \ar, 0, \line_width + add \as, \as, \at + + __loops \ar, \as, \at, \line_width + \insn \ar, 0 + __endla \ar, \at, (1 << (\line_width)) + + .endm + + + .macro __loop_cache_page ar at insn line_width + + __loopi \ar, \at, PAGE_SIZE, 4 << (\line_width) + + \insn \ar, 0 << (\line_width) + \insn \ar, 1 << (\line_width) + \insn \ar, 2 << (\line_width) + \insn \ar, 3 << (\line_width) + + __endla \ar, \at, 4 << (\line_width) + + .endm + + +#if XCHAL_DCACHE_LINE_LOCKABLE + + .macro ___unlock_dcache_all ar at + + __loop_cache_all \ar \at diu XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH + + .endm + +#endif + +#if XCHAL_ICACHE_LINE_LOCKABLE + + .macro ___unlock_icache_all ar at + + __loop_cache_all \ar \at iiu XCHAL_ICACHE_SIZE XCHAL_ICACHE_LINEWIDTH + + .endm +#endif + + .macro ___flush_invalidate_dcache_all ar at + + __loop_cache_all \ar \at diwbi XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___flush_dcache_all ar at + + __loop_cache_all \ar \at diwb XCHAL_DCACHE_SIZE XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_dcache_all ar at + + __loop_cache_all \ar \at dii __stringify(DCACHE_WAY_SIZE) \ + XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_icache_all ar at + + __loop_cache_all \ar \at iii __stringify(ICACHE_WAY_SIZE) \ + XCHAL_ICACHE_LINEWIDTH + + .endm + + + + .macro ___flush_invalidate_dcache_range ar as at + + __loop_cache_range \ar \as \at dhwbi XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___flush_dcache_range ar as at + + __loop_cache_range \ar \as \at dhwb XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_dcache_range ar as at + + __loop_cache_range \ar \as \at dhi XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_icache_range ar as at + + __loop_cache_range \ar \as \at ihi XCHAL_ICACHE_LINEWIDTH + + .endm + + + + .macro ___flush_invalidate_dcache_page ar as + + __loop_cache_page \ar \as dhwbi XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___flush_dcache_page ar as + + __loop_cache_page \ar \as dhwb XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_dcache_page ar as + + __loop_cache_page \ar \as dhi XCHAL_DCACHE_LINEWIDTH + + .endm + + + .macro ___invalidate_icache_page ar as + + __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH + + .endm + +#endif /* _XTENSA_CACHEASM_H */ diff --git a/arch/xtensa/include/asm/config.h b/arch/xtensa/include/asm/config.h new file mode 100644 index 0000000..98cf7c7 --- /dev/null +++ b/arch/xtensa/include/asm/config.h @@ -0,0 +1,17 @@ +/* + * config file header + * + * Copyright (C) 2009 Tensilica Inc. + * Based on the Linux/Xtensa version of this header. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _ASM_CONFIG_H_ +#define _ASM_CONFIG_H_ + +#include <asm/arch/core.h> + +#define CONFIG_LMB + +#endif diff --git a/arch/xtensa/include/asm/errno.h b/arch/xtensa/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/xtensa/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/xtensa/include/asm/global_data.h b/arch/xtensa/include/asm/global_data.h new file mode 100644 index 0000000..3563a5e --- /dev/null +++ b/arch/xtensa/include/asm/global_data.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2007, Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_GBL_DATA_H +#define _XTENSA_GBL_DATA_H + +/* Architecture-specific global data */ + +struct arch_global_data { + unsigned long cpu_clk; +}; + +#include <asm-generic/global_data.h> + +#ifdef __XTENSA_CALL0_ABI__ +# define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd __asm__ ("a14") +#else +# define DECLARE_GLOBAL_DATA_PTR extern gd_t *gd +#endif + +#endif /* _XTENSA_GBL_DATA_H */ diff --git a/arch/xtensa/include/asm/io.h b/arch/xtensa/include/asm/io.h new file mode 100644 index 0000000..dd01063 --- /dev/null +++ b/arch/xtensa/include/asm/io.h @@ -0,0 +1,148 @@ +/* + * IO header file + * + * Copyright (C) 2001-2007 Tensilica Inc. + * Based on the Linux/Xtensa version of this header. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_IO_H +#define _XTENSA_IO_H + +#include <linux/types.h> +#include <asm/byteorder.h> + + +/* + * swap functions to change byte order from little-endian to big-endian and + * vice versa. + */ + +static inline unsigned short _swapw(unsigned short v) +{ + return (v << 8) | (v >> 8); +} + +static inline unsigned int _swapl(unsigned int v) +{ + return (v << 24) | ((v & 0xff00) << 8) | ((v >> 8) & 0xff00) | (v >> 24); +} + +static inline void iounmap(void *addr) +{ +} + +/* + * Generic I/O + */ + +#define readb(addr) \ + ({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; }) +#define readw(addr) \ + ({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; }) +#define readl(addr) \ + ({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; }) +#define writeb(b, addr) (void)((*(volatile unsigned char *)(addr)) = (b)) +#define writew(b, addr) (void)((*(volatile unsigned short *)(addr)) = (b)) +#define writel(b, addr) (void)((*(volatile unsigned int *)(addr)) = (b)) + +#define __raw_readb readb +#define __raw_readw readw +#define __raw_readl readl +#define __raw_writeb writeb +#define __raw_writew writew +#define __raw_writel writel + +/* These are the definitions for the x86 IO instructions + * inb/inw/inl/outb/outw/outl, the "string" versions + * insb/insw/insl/outsb/outsw/outsl, and the "pausing" versions + * inb_p/inw_p/... + * The macros don't do byte-swapping. + */ + +#define inb(port) readb((u8 *)((port))) +#define outb(val, port) writeb((val), (u8 *)((unsigned long)(port))) +#define inw(port) readw((u16 *)((port))) +#define outw(val, port) writew((val), (u16 *)((unsigned long)(port))) +#define inl(port) readl((u32 *)((port))) +#define outl(val, port) writel((val), (u32 *)((unsigned long)(port))) + +#define inb_p(port) inb((port)) +#define outb_p(val, port) outb((val), (port)) +#define inw_p(port) inw((port)) +#define outw_p(val, port) outw((val), (port)) +#define inl_p(port) inl((port)) +#define outl_p(val, port) outl((val), (port)) + +void insb(unsigned long port, void *dst, unsigned long count); +void insw(unsigned long port, void *dst, unsigned long count); +void insl(unsigned long port, void *dst, unsigned long count); +void outsb(unsigned long port, const void *src, unsigned long count); +void outsw(unsigned long port, const void *src, unsigned long count); +void outsl(unsigned long port, const void *src, unsigned long count); + +#define IO_SPACE_LIMIT ~0 + +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) + +/* At this point the Xtensa doesn't provide byte swap instructions */ + +#ifdef __XTENSA_EB__ +# define in_8(addr) (*(u8 *)(addr)) +# define in_le16(addr) _swapw(*(u16 *)(addr)) +# define in_le32(addr) _swapl(*(u32 *)(addr)) +# define out_8(b, addr) *(u8 *)(addr) = (b) +# define out_le16(b, addr) *(u16 *)(addr) = _swapw(b) +# define out_le32(b, addr) *(u32 *)(addr) = _swapl(b) +#elif defined(__XTENSA_EL__) +# define in_8(addr) (*(u8 *)(addr)) +# define in_le16(addr) (*(u16 *)(addr)) +# define in_le32(addr) (*(u32 *)(addr)) +# define out_8(b, addr) *(u8 *)(addr) = (b) +# define out_le16(b, addr) *(u16 *)(addr) = (b) +# define out_le32(b, addr) *(u32 *)(addr) = (b) +#else +# error processor byte order undefined! +#endif + + +/* + * Convert a physical pointer to a virtual kernel pointer for /dev/mem access + */ +#define xlate_dev_mem_ptr(p) __va(p) + +/* + * Convert a virtual cached pointer to an uncached pointer + */ +#define xlate_dev_kmem_ptr(p) p + +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +/* We are using uncached addresses, ie: 0x80000000 ... */ +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ +} + +/* + * Dummy function to keep U-Boot's cfi_flash.c driver happy. + */ +static inline void sync(void) +{ +} + +#endif /* _XTENSA_IO_H */ diff --git a/arch/xtensa/include/asm/ldscript.h b/arch/xtensa/include/asm/ldscript.h new file mode 100644 index 0000000..4d34fa6 --- /dev/null +++ b/arch/xtensa/include/asm/ldscript.h @@ -0,0 +1,220 @@ +/* + * (C) Copyright 2007 Tensilica, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_LDSCRIPT_H +#define _XTENSA_LDSCRIPT_H + +/* + * This linker script is pre-processed with CPP to avoid hard-coding + * addresses that depend on the Xtensa core configuration, because + * this FPGA board can be used with a huge variety of Xtensa cores. + */ + +#include <asm/arch/core.h> +#include <asm/addrspace.h> + +#define ALIGN_LMA 4 +#define LMA_EQ_VMA +#define FORCE_OUTPUT . = . +#define FOLLOWING(sec) \ + AT(((LOADADDR(sec) + SIZEOF(sec) + ALIGN_LMA-1)) & ~(ALIGN_LMA-1)) + +/* + * Specify an output section that will be added to the ROM store table + * (PACKED_SECTION) or one that will be resident in ROM (RESIDENT_SECTION). + * 'symname' is a base name for section boundary symbols *_start & *_end. + * 'lma' is the load address at which a section will be packed in ROM. + * 'region' is the basename identifying a memory region and program header. + * 'keep' prevents removal of empty sections (must be 'KEEP' or 'NOKEEP'). + */ + +#define RELOCATE1(_sec_) \ + LONG(_##_sec_##_start); \ + LONG(_##_sec_##_end); \ + LONG(LOADADDR(.##_sec_)); + +#define RELOCATE2(_sym_, _sec_) \ + LONG(_##_sym_##_##_sec_##_start); \ + LONG(_##_sym_##_##_sec_##_end); \ + LONG(LOADADDR(.##_sym_##.##_sec_)); + +#define SECTION_VECTOR(_sym_, _sec_, _vma_, _lma_) \ +.##_sym_##.##_sec_ _vma_ : _lma_ \ +{ \ + . = ALIGN(4); \ + _##_sym_##_##_sec_##_start = ABSOLUTE(.); \ + KEEP(*(.##_sym_##.##_sec_)) \ + _##_sym_##_##_sec_##_end = ABSOLUTE(.); \ +} + +/* In MMU configs there are two aliases of SYSROM, cached and uncached. + * For various reasons it is simpler to use the uncached mapping for load + * addresses, so ROM sections end up contiguous with the reset vector and + * we get a compact binary image. However we can gain performance by doing + * the unpacking from the cached ROM mapping. So we adjust all the load + * addresses in the ROM store table with an offset to the cached mapping, + * including the symbols referring to the ROM store table itself. + */ + +#define SECTION_ResetVector(_vma_, _lma_) \ + .ResetVector.text _vma_ : _lma_ \ + { \ + FORCE_OUTPUT; \ + KEEP(*(.ResetVector.text)); \ + KEEP(*(.reset.literal .reset.text)) \ + } + +#define SECTION_text(_vma_, _lma_) \ + .text _vma_ : _lma_ \ + { \ + _text_start = ABSOLUTE(.); \ + *(.literal .text) \ + *(.literal.* .text.* .stub) \ + *(.gnu.warning .gnu.linkonce.literal.*) \ + *(.gnu.linkonce.t.*.literal .gnu.linkonce.t.*) \ + *(.fini.literal) \ + *(.fini) \ + *(.gnu.version) \ + _text_end = ABSOLUTE(.); \ + } + +#define SECTION_rodata(_vma_, _lma_) \ + .rodata _vma_ : _lma_ \ + { \ + _rodata_start = ABSOLUTE(.); \ + *(.rodata) \ + *(.rodata.str1.4) \ + *(.gnu.linkonce.r.*) \ + *(.rodata1) \ + __XT_EXCEPTION_TABLE__ = ABSOLUTE(.); \ + *(.xt_except_table) \ + *(.gcc_except_table) \ + *(.gnu.linkonce.e.*) \ + *(.gnu.version_r) \ + . = ALIGN(16); \ + _rodata_end = ABSOLUTE(.); \ + } + +#define SECTION_u_boot_list(_vma_, _lma_) \ + .u_boot_list _vma_ : _lma_ \ + { \ + _u_boot_list_start = ABSOLUTE(.); \ + KEEP(*(SORT(.u_boot_list*))); \ + _u_boot_list_end = ABSOLUTE(.); \ + } + +#define SECTION_data(_vma_, _lma_) \ + .data _vma_ : _lma_ \ + { \ + _data_start = ABSOLUTE(.); \ + *(.data) \ + *(.data.*) \ + *(.gnu.linkonce.d.*) \ + *(.data1) \ + *(.sdata) \ + *(.sdata.*) \ + *(.gnu.linkonce.s.*) \ + *(.sdata2) \ + *(.sdata2.*) \ + *(.gnu.linkonce.s2.*) \ + *(.jcr) \ + *(.eh_frame) \ + *(.dynamic) \ + *(.gnu.version_d) \ + _data_end = ABSOLUTE(.); \ + } + +#define SECTION_lit4(_vma_, _lma_) \ + .lit4 _vma_ : _lma_ \ + { \ + _lit4_start = ABSOLUTE(.); \ + *(*.lit4) \ + *(.gnu.linkonce.lit4.*) \ + _lit4_end = ABSOLUTE(.); \ + } + +#define SECTION_bss(_vma_, _lma_) \ + .bss _vma_ : _lma_ \ + { \ + . = ALIGN(8); \ + _bss_start = ABSOLUTE(.); \ + __bss_start = ABSOLUTE(.); \ + *(.dynsbss) \ + *(.sbss) \ + *(.sbss.*) \ + *(.gnu.linkonce.sb.*) \ + *(.scommon) \ + *(.sbss2) \ + *(.sbss2.*) \ + *(.gnu.linkonce.sb2.*) \ + *(.dynbss) \ + *(.bss) \ + *(.bss.*) \ + *(.gnu.linkonce.b.*) \ + *(COMMON) \ + *(.sram.bss) \ + . = ALIGN(8); \ + _bss_end = ABSOLUTE(.); \ + __bss_end = ABSOLUTE(.); \ + _end = ALIGN(0x8); \ + PROVIDE(end = ALIGN(0x8)); \ + _stack_sentry = ALIGN(0x8); \ + } + +#define SECTION_debug \ + .debug 0 : { *(.debug) } \ + .line 0 : { *(.line) } \ + .debug_srcinfo 0 : { *(.debug_srcinfo) } \ + .debug_sfnames 0 : { *(.debug_sfnames) } \ + .debug_aranges 0 : { *(.debug_aranges) } \ + .debug_pubnames 0 : { *(.debug_pubnames) } \ + .debug_info 0 : { *(.debug_info) } \ + .debug_abbrev 0 : { *(.debug_abbrev) } \ + .debug_line 0 : { *(.debug_line) } \ + .debug_frame 0 : { *(.debug_frame) } \ + .debug_str 0 : { *(.debug_str) } \ + .debug_loc 0 : { *(.debug_loc) } \ + .debug_macinfo 0 : { *(.debug_macinfo) } \ + .debug_weaknames 0 : { *(.debug_weaknames) } \ + .debug_funcnames 0 : { *(.debug_funcnames) } \ + .debug_typenames 0 : { *(.debug_typenames) } \ + .debug_varnames 0 : { *(.debug_varnames) } + +#define SECTION_xtensa \ + .xt.insn 0 : \ + { \ + KEEP (*(.xt.insn)) \ + KEEP (*(.gnu.linkonce.x.*)) \ + } \ + .xt.prop 0 : \ + { \ + KEEP (*(.xt.prop)) \ + KEEP (*(.xt.prop.*)) \ + KEEP (*(.gnu.linkonce.prop.*)) \ + } \ + .xt.lit 0 : \ + { \ + KEEP (*(.xt.lit)) \ + KEEP (*(.xt.lit.*)) \ + KEEP (*(.gnu.linkonce.p.*)) \ + } \ + .xt.profile_range 0 : \ + { \ + KEEP (*(.xt.profile_range)) \ + KEEP (*(.gnu.linkonce.profile_range.*)) \ + } \ + .xt.profile_ranges 0 : \ + { \ + KEEP (*(.xt.profile_ranges)) \ + KEEP (*(.gnu.linkonce.xt.profile_ranges.*)) \ + } \ + .xt.profile_files 0 : \ + { \ + KEEP (*(.xt.profile_files)) \ + KEEP (*(.gnu.linkonce.xt.profile_files.*)) \ + } + +#endif /* _XTENSA_LDSCRIPT_H */ diff --git a/arch/xtensa/include/asm/linkage.h b/arch/xtensa/include/asm/linkage.h new file mode 100644 index 0000000..3f46161 --- /dev/null +++ b/arch/xtensa/include/asm/linkage.h @@ -0,0 +1,4 @@ +#ifndef __ASM_LINKAGE_H +#define __ASM_LINKAGE_H + +#endif diff --git a/arch/xtensa/include/asm/misc.h b/arch/xtensa/include/asm/misc.h new file mode 100644 index 0000000..365c5e7 --- /dev/null +++ b/arch/xtensa/include/asm/misc.h @@ -0,0 +1,24 @@ +/* + * (C) Copyright 2008, Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef _XTENSA_MISC_H +#define _XTENSA_MISC_H + +/* Defined in cpu/xtensa/u-boot.lds.S */ +void *__memory_avail_start; +void *__memory_avail_end; + +/* Used in cpu/xtensa/cpu.c */ +void board_reset(void); + +#endif /* _XTENSA_MISC_H */ diff --git a/arch/xtensa/include/asm/posix_types.h b/arch/xtensa/include/asm/posix_types.h new file mode 100644 index 0000000..821115c --- /dev/null +++ b/arch/xtensa/include/asm/posix_types.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2007, Tensilica Inc. + * + * Based on the ARM version: Copyright (C) 1996-1998 Russell King. + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _XTENSA_POSIX_TYPES_H +#define _XTENSA_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef int __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef int __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef unsigned short __kernel_old_uid_t; +typedef unsigned short __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +typedef struct { +#if defined(__KERNEL__) || defined(__USE_ALL) + int val[2]; +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */ + int __val[2]; +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */ +} __kernel_fsid_t; + +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) + +#undef __FD_SET +#define __FD_SET(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31))) + +#undef __FD_CLR +#define __FD_CLR(fd, fdsetp) \ + (((fd_set *)fdsetp)->fds_bits[fd >> 5] &= ~(1<<(fd & 31))) + +#undef __FD_ISSET +#define __FD_ISSET(fd, fdsetp) \ + ((((fd_set *)fdsetp)->fds_bits[fd >> 5] & (1<<(fd & 31))) != 0) + +#undef __FD_ZERO +#define __FD_ZERO(fdsetp) \ + (memset(fdsetp, 0, sizeof(*(fd_set *)fdsetp))) + +#endif + +#endif /* _XTENSA_POSIX_TYPES_H */ diff --git a/arch/xtensa/include/asm/processor.h b/arch/xtensa/include/asm/processor.h new file mode 100644 index 0000000..8822f80 --- /dev/null +++ b/arch/xtensa/include/asm/processor.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 1997 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_PROCESSOR_H +#define _XTENSA_PROCESSOR_H + + +#endif /* _XTENSA_PROCESSOR_H */ diff --git a/arch/xtensa/include/asm/ptrace.h b/arch/xtensa/include/asm/ptrace.h new file mode 100644 index 0000000..bb8ca61 --- /dev/null +++ b/arch/xtensa/include/asm/ptrace.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2001 - 2007 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_PTRACE_H +#define _XTENSA_PTRACE_H + +#include <compiler.h> + +/* + * Kernel stack + * + * +-----------------------+ -------- STACK_SIZE + * | register file | | + * +-----------------------+ | + * | struct pt_regs | | + * +-----------------------+ | ------ PT_REGS_OFFSET + * double : 16 bytes spill area : | ^ + * exception :- - - - - - - - - - - -: | | + * frame : struct pt_regs : | | + * :- - - - - - - - - - - -: | | + * | | | | + * | memory stack | | | + * | | | | + * ~ ~ ~ ~ + * ~ ~ ~ ~ + * | | | | + * | | | | + * +-----------------------+ | | --- STACK_BIAS + * | struct task_struct | | | ^ + * current --> +-----------------------+ | | | + * | struct thread_info | | | | + * +-----------------------+ -------- + */ + +#define KERNEL_STACK_SIZE (2 * PAGE_SIZE) + +/* Offsets for exception_handlers[] (3 x 64-entries x 4-byte tables). */ + +#define EXC_TABLE_KSTK 0x004 /* Kernel Stack */ +#define EXC_TABLE_DOUBLE_SAVE 0x008 /* Double exception save area for a0 */ +#define EXC_TABLE_FIXUP 0x00c /* Fixup handler */ +#define EXC_TABLE_PARAM 0x010 /* For passing a parameter to fixup */ +#define EXC_TABLE_SYSCALL_SAVE 0x014 /* For fast syscall handler */ +#define EXC_TABLE_FAST_USER 0x100 /* Fast user exception handler */ +#define EXC_TABLE_FAST_KERNEL 0x200 /* Fast kernel exception handler */ +#define EXC_TABLE_DEFAULT 0x300 /* Default C-Handler */ +#define EXC_TABLE_SIZE 0x400 + +/* Registers used by strace */ + +#define REG_A_BASE 0xfc000000 +#define REG_AR_BASE 0x04000000 +#define REG_PC 0x14000000 +#define REG_PS 0x080000e6 +#define REG_WB 0x08000048 +#define REG_WS 0x08000049 +#define REG_LBEG 0x08000000 +#define REG_LEND 0x08000001 +#define REG_LCOUNT 0x08000002 +#define REG_SAR 0x08000003 +#define REG_DEPC 0x080000c0 +#define REG_EXCCAUSE 0x080000e8 +#define REG_EXCVADDR 0x080000ee +#define SYSCALL_NR 0x1 + +#define AR_REGNO_TO_A_REGNO(ar, wb) (ar - wb*4) & ~(XCHAL_NUM_AREGS - 1) + +/* Other PTRACE_ values defined in <linux/ptrace.h> using values 0-9,16,17,24 */ + +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 +#define PTRACE_GETFPREGSIZE 18 + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the + * kernel stack during a system call or other kernel entry. + */ +struct pt_regs { + unsigned long pc; /* 4 */ + unsigned long ps; /* 8 */ + unsigned long depc; /* 12 */ + unsigned long exccause; /* 16 */ + unsigned long excvaddr; /* 20 */ + unsigned long debugcause; /* 24 */ + unsigned long wmask; /* 28 */ + unsigned long lbeg; /* 32 */ + unsigned long lend; /* 36 */ + unsigned long lcount; /* 40 */ + unsigned long sar; /* 44 */ + unsigned long windowbase; /* 48 */ + unsigned long windowstart; /* 52 */ + unsigned long syscall; /* 56 */ + unsigned long icountlevel; /* 60 */ + int reserved[1]; /* 64 */ + + /* Make sure the areg field is 16 bytes aligned. */ + int align[0] __aligned(16); + + /* current register frame. + * Note: The ESF for kernel exceptions ends after 16 registers! + */ + unsigned long areg[16]; /* 128 (64) */ +}; + +#ifdef __KERNEL__ + +# define task_pt_regs(tsk) ((struct pt_regs *) \ + (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) +# define user_mode(regs) (((regs)->ps & 0x00000020) != 0) +# define instruction_pointer(regs) ((regs)->pc) +void show_regs(struct pt_regs *); + +# ifndef CONFIG_SMP +# define profile_pc(regs) instruction_pointer(regs) +# endif +#endif /* __KERNEL__ */ + +#else /* __ASSEMBLY__ */ + +#ifdef __KERNEL__ +# include <asm/asm-offsets.h> +#define PT_REGS_OFFSET (KERNEL_STACK_SIZE - PT_USER_SIZE) +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* _XTENSA_PTRACE_H */ diff --git a/arch/xtensa/include/asm/regs.h b/arch/xtensa/include/asm/regs.h new file mode 100644 index 0000000..6f623ef --- /dev/null +++ b/arch/xtensa/include/asm/regs.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2006 Tensilica, Inc. All Rights Reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_REGS_H +#define _XTENSA_REGS_H + +/* Special registers. */ + +#define IBREAKA 128 +#define DBREAKA 144 +#define DBREAKC 160 + +/* Special names for read-only and write-only interrupt registers. */ + +#define INTREAD 226 +#define INTSET 226 +#define INTCLEAR 227 + +/* EXCCAUSE register fields */ + +#define EXCCAUSE_EXCCAUSE_SHIFT 0 +#define EXCCAUSE_EXCCAUSE_MASK 0x3F + +#define EXCCAUSE_ILLEGAL_INSTRUCTION 0 +#define EXCCAUSE_SYSTEM_CALL 1 +#define EXCCAUSE_INSTRUCTION_FETCH_ERROR 2 +#define EXCCAUSE_LOAD_STORE_ERROR 3 +#define EXCCAUSE_LEVEL1_INTERRUPT 4 +#define EXCCAUSE_ALLOCA 5 +#define EXCCAUSE_INTEGER_DIVIDE_BY_ZERO 6 +#define EXCCAUSE_SPECULATION 7 +#define EXCCAUSE_PRIVILEGED 8 +#define EXCCAUSE_UNALIGNED 9 +#define EXCCAUSE_INSTR_DATA_ERROR 12 +#define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 +#define EXCCAUSE_INSTR_ADDR_ERROR 14 +#define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 +#define EXCCAUSE_ITLB_MISS 16 +#define EXCCAUSE_ITLB_MULTIHIT 17 +#define EXCCAUSE_ITLB_PRIVILEGE 18 +#define EXCCAUSE_ITLB_SIZE_RESTRICTION 19 +#define EXCCAUSE_FETCH_CACHE_ATTRIBUTE 20 +#define EXCCAUSE_DTLB_MISS 24 +#define EXCCAUSE_DTLB_MULTIHIT 25 +#define EXCCAUSE_DTLB_PRIVILEGE 26 +#define EXCCAUSE_DTLB_SIZE_RESTRICTION 27 +#define EXCCAUSE_LOAD_CACHE_ATTRIBUTE 28 +#define EXCCAUSE_STORE_CACHE_ATTRIBUTE 29 +#define EXCCAUSE_COPROCESSOR0_DISABLED 32 +#define EXCCAUSE_COPROCESSOR1_DISABLED 33 +#define EXCCAUSE_COPROCESSOR2_DISABLED 34 +#define EXCCAUSE_COPROCESSOR3_DISABLED 35 +#define EXCCAUSE_COPROCESSOR4_DISABLED 36 +#define EXCCAUSE_COPROCESSOR5_DISABLED 37 +#define EXCCAUSE_COPROCESSOR6_DISABLED 38 +#define EXCCAUSE_COPROCESSOR7_DISABLED 39 +#define EXCCAUSE_LAST 63 + +/* PS register fields. */ + +#define PS_WOE_BIT 18 +#define PS_CALLINC_SHIFT 16 +#define PS_CALLINC_MASK 0x00030000 +#define PS_OWB_SHIFT 8 +#define PS_OWB_MASK 0x00000F00 +#define PS_RING_SHIFT 6 +#define PS_RING_MASK 0x000000C0 +#define PS_UM_BIT 5 +#define PS_EXCM_BIT 4 +#define PS_INTLEVEL_SHIFT 0 +#define PS_INTLEVEL_MASK 0x0000000F + +/* DBREAKCn register fields. */ + +#define DBREAKC_MASK_BIT 0 +#define DBREAKC_MASK_MASK 0x0000003F +#define DBREAKC_LOAD_BIT 30 +#define DBREAKC_LOAD_MASK 0x40000000 +#define DBREAKC_STOR_BIT 31 +#define DBREAKC_STOR_MASK 0x80000000 + +/* DEBUGCAUSE register fields. */ + +#define DEBUGCAUSE_DEBUGINT_BIT 5 /* External debug interrupt */ +#define DEBUGCAUSE_BREAKN_BIT 4 /* BREAK.N instruction */ +#define DEBUGCAUSE_BREAK_BIT 3 /* BREAK instruction */ +#define DEBUGCAUSE_DBREAK_BIT 2 /* DBREAK match */ +#define DEBUGCAUSE_IBREAK_BIT 1 /* IBREAK match */ +#define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ + +#endif /* _XTENSA_SPECREG_H */ + diff --git a/arch/xtensa/include/asm/sections.h b/arch/xtensa/include/asm/sections.h new file mode 100644 index 0000000..2430daa --- /dev/null +++ b/arch/xtensa/include/asm/sections.h @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_XTENSA_SECTIONS_H +#define __ASM_XTENSA_SECTIONS_H + +#include <asm-generic/sections.h> + +extern void *_text_start; +#define CONFIG_SYS_TEXT_BASE ((unsigned int)&_text_start) + +#endif diff --git a/arch/xtensa/include/asm/string.h b/arch/xtensa/include/asm/string.h new file mode 100644 index 0000000..65a3601 --- /dev/null +++ b/arch/xtensa/include/asm/string.h @@ -0,0 +1,10 @@ +#ifndef _XTENSA_STRING_H +#define _XTENSA_STRING_H + +/* + * Use the generic string functions in U-Boot's lib_generic. + * In the boot loader we care about compactness more than performance. + * Prototypes will be taken from <linux/string.h> + */ + +#endif /* _XTENSA_STRING_H */ diff --git a/arch/xtensa/include/asm/types.h b/arch/xtensa/include/asm/types.h new file mode 100644 index 0000000..e30f519 --- /dev/null +++ b/arch/xtensa/include/asm/types.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1997 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_TYPES_H +#define _XTENSA_TYPES_H + +typedef unsigned short umode_t; + +/* + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the + * header files exported to user space + */ + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +typedef __signed__ long long __s64; +typedef unsigned long long __u64; +#endif + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long long s64; +typedef unsigned long long u64; + +#define BITS_PER_LONG 32 + +/* Dma addresses are 32-bits wide. */ + +typedef u32 dma_addr_t; + +typedef unsigned long phys_addr_t; +typedef unsigned long phys_size_t; + + +#endif /* __KERNEL__ */ + +#endif /* _XTENSA_TYPES_H */ diff --git a/arch/xtensa/include/asm/u-boot.h b/arch/xtensa/include/asm/u-boot.h new file mode 100644 index 0000000..15fbf2e --- /dev/null +++ b/arch/xtensa/include/asm/u-boot.h @@ -0,0 +1,43 @@ +/* + * (C) Copyright 2007, Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + * + ******************************************************************** + * NOTE: This header file defines an interface to U-Boot. Including + * this (unmodified) header file in another file is considered normal + * use of U-Boot, and does *not* fall under the heading of "derived + * work". + ******************************************************************** + */ + +#ifndef _XTENSA_U_BOOT_H +#define _XTENSA_U_BOOT_H + +#ifdef CONFIG_SYS_GENERIC_BOARD +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h> +#else + +#ifndef __ASSEMBLY__ +typedef struct bd_info { + int bi_baudrate; /* serial console baudrate */ + unsigned long bi_ip_addr; /* IP Address */ + unsigned char bi_enetaddr[6]; /* Ethernet adress */ + unsigned long bi_boot_params; /* where this board expects params */ + unsigned long bi_memstart; /* start of DRAM memory VA */ + unsigned long bi_memsize; /* size of DRAM memory in bytes */ + unsigned long bi_flashstart; /* start of FLASH memory */ + unsigned long bi_flashsize; /* size of FLASH memory */ + unsigned long bi_flashoffset; /* offset to skip UBoot image */ +} bd_t; +#endif /* __ ASSEMBLY__ */ + +#endif /* CONFIG_SYS_GENERIC_BOARD */ + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_XTENSA + +int dram_init(void); + +#endif /* _XTENSA_U_BOOT_H */ diff --git a/arch/xtensa/include/asm/unaligned.h b/arch/xtensa/include/asm/unaligned.h new file mode 100644 index 0000000..536f364 --- /dev/null +++ b/arch/xtensa/include/asm/unaligned.h @@ -0,0 +1,6 @@ +#ifndef _ASM_XTENSA_UNALIGNED_H +#define _ASM_XTENSA_UNALIGNED_H + +#include <asm-generic/unaligned.h> + +#endif /* _ASM_XTENSA_UNALIGNED_H */ diff --git a/arch/xtensa/include/asm/xtensa.h b/arch/xtensa/include/asm/xtensa.h new file mode 100644 index 0000000..94b9788 --- /dev/null +++ b/arch/xtensa/include/asm/xtensa.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2007 Tensilica, Inc. + * + * A place for global definitions specific to Xtensa-based ports. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_H_ +#define _XTENSA_H_ + +#include <stdarg.h> +#include <config.h> +#include <asm/u-boot.h> + +/* Much of this is not specific to Xtensa and should move to a common header. */ + +/* Quote a macro value as a string constant. */ +#define QUOTE1(s) #s +#define QUOTE(s) QUOTE1(s) + +/* Align a value up to nearest n-byte boundary, where n is a power of 2. */ +#define ALIGNUP(n, val) (((val) + (n)-1) & -(n)) + +#ifdef CONFIG_SYS_ASCDISP +/* + * Print a formatted string to the board's ASCII character display. + * String may have embedded newlines. Starts at top left and wraps long lines. + */ +void display_printf(const char *fmt, ...); +void lcd_disp_at_pos(char *, unsigned char); +#else +#define display_printf(fmt, args) +#endif + +#endif /* _XTENSA_H_ */ diff --git a/arch/xtensa/lib/Makefile b/arch/xtensa/lib/Makefile new file mode 100644 index 0000000..6650d24 --- /dev/null +++ b/arch/xtensa/lib/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2007 - 2013 Tensilica Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-$(CONFIG_CMD_BOOTM) += bootm.o + +obj-y += misc.o time.o board.o diff --git a/arch/xtensa/lib/board.c b/arch/xtensa/lib/board.c new file mode 100644 index 0000000..53d6e40 --- /dev/null +++ b/arch/xtensa/lib/board.c @@ -0,0 +1,173 @@ +/* + * (C) Copyright 2008 - 2013, Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> +#include <common.h> +#include <stdio_dev.h> +#include <version.h> +#include <net.h> +#include <config.h> +#include <linux/stringify.h> +#include <asm/xtensa.h> +#include <asm/addrspace.h> +#include <asm/bootparam.h> + +/* Import linker-defined symbols (see u-boot.lds) */ +extern void *__monitor_start, *__monitor_end; + +void board_init_r(gd_t *id, ulong dest_addr); + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef __XTENSA_CALL0_ABI__ +gd_t *gd; +#endif + +#ifndef CONFIG_IDENT_STRING +#define CONFIG_IDENT_STRING "" +#endif + +ulong monitor_flash_len; /* size of U-Boot packed image in flash */ + +const char version_string[] = + U_BOOT_VERSION" (" __DATE__ " - " __TIME__ ")"CONFIG_IDENT_STRING; + + +/* + * Initialize baudrate settings in global and board data structures. + * This does not actually initialize the UART or set its baudrate. + * Return 0 on success (OK to continue), else non-zero (hang). + */ +static int init_baudrate(void) +{ + gd->baudrate = getenv_ulong("baudrate", 10, CONFIG_BAUDRATE); + return 0; +} + +/* + * Initialize System RAM parameters and display RAM size. + * Install dummy exception handler that ignores load/store exceptions. + * Return 0 on success (OK to continue), else non-zero (hang). + */ +static int init_sysram(void) +{ + gd->ram_size = CONFIG_SYS_MEMORY_SIZE; + gd->ram_top = CONFIG_SYS_MEMORY_TOP; + gd->relocaddr = CONFIG_SYS_TEXT_ADDR; + + gd->bd->bi_memstart = CONFIG_SYS_SDRAM_PHYS; + gd->bd->bi_memsize = CONFIG_SYS_SDRAM_SIZE; + + puts("DRAM: "); + print_size(gd->bd->bi_memsize, "\n"); + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +#ifdef CONFIG_SYS_ASCDISP +static int display_freq(void) +{ + char mhz[8]; + /* Announce our arrival and clock frequency */ + display_printf("U-Boot %5s MHz", strmhz(mhz, gd->cpu_clk)); + + return 0; +} +#else +static int display_freq(void) +{ + return 0; +} +#endif +#endif + + +/* + * Breath some life into the board... + * + * The first part of initialization is running from Flash memory; + * its main purpose is to initialize the RAM so that we + * can relocate the monitor code to RAM. + * + * All attempts to come up with a "common" initialization sequence + * that works for all boards and architectures failed: some of the + * requirements are just _too_ different. To get rid of the resulting + * mess of board dependend #ifdef'ed code we now make the whole + * initialization sequence configurable to the user. + * + * The requirements for any new initalization function is simple: it + * receives a pointer to the "global data" structure as it's only + * argument, and returns an integer return code, where 0 means + * "continue" and != 0 means "fatal error, hang the system". + */ +typedef int (init_fnc_t) (void); + +init_fnc_t *init_sequence[] = { + board_postclk_init, + env_init, + init_baudrate, + serial_init, + console_init_f, + display_options, + checkcpu, +#if defined(CONFIG_DISPLAY_CPUINFO) + display_freq, +#endif + checkboard, + misc_init_f, + init_sysram, +#ifdef CONFIG_SYS_ACDISP + acdisp +#endif + NULL, +}; + + +/* + * Initialize board. + */ + +void xtensa_board_init(ulong gd_addr) +{ + /* + * All RAM sections have been unpacked to RAM (relocated) + * and the board has been initialized. + */ + init_fnc_t **init_fnc_ptr; + bd_t *bd; + + /* Don't cross 1GB range */ + ulong memsize = CONFIG_SYS_SDRAM_SIZE; + ulong maxsize = 0x40000000 - (CONFIG_SYS_SDRAM_SIZE & 0x3fffffff); + if (memsize > maxsize) + memsize = maxsize; + + gd = (gd_t *)gd_addr; + memset(gd, 0, sizeof(gd_t)); + gd->flags = GD_FLG_RELOC; /* relocation is already done */ + + bd = (bd_t *)((ulong)gd + ((sizeof(gd_t) + 15) & -16)); + memset(bd, 0, sizeof(bd_t)); + gd->bd = bd; + + /* Reserve memory for passing linux boot parameters to kernel */ + bd->bi_boot_params = (ulong)bd + ((sizeof(bd_t) + 15) & -16); + + /* + * Perform initialization sequence, call functions enumerated above. + */ + for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { + if ((*init_fnc_ptr)() != 0) + hang(); + } + + /* the parameters gd_t *id and ulong dest_addr are unused for Xtensa */ + board_init_r(NULL, 0); + + /* NOT REACHED */ + hang(); +} diff --git a/arch/xtensa/lib/bootm.c b/arch/xtensa/lib/bootm.c new file mode 100644 index 0000000..8bd4a4e --- /dev/null +++ b/arch/xtensa/lib/bootm.c @@ -0,0 +1,202 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica Inc. + * (C) Copyright 2014 Cadence Design Systems Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <u-boot/zlib.h> +#include <asm/byteorder.h> +#include <asm/addrspace.h> +#include <asm/bootparam.h> +#include <asm/cache.h> +#include <image.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Setup boot-parameters. + */ + +static struct bp_tag *setup_first_tag(struct bp_tag *params) +{ + params->id = BP_TAG_FIRST; + params->size = sizeof(long); + *(unsigned long *)¶ms->data = BP_VERSION; + + return bp_tag_next(params); +} + +static struct bp_tag *setup_last_tag(struct bp_tag *params) +{ + params->id = BP_TAG_LAST; + params->size = 0; + + return bp_tag_next(params); +} + +static struct bp_tag *setup_memory_tag(struct bp_tag *params) +{ + struct bd_info *bd = gd->bd; + struct meminfo *mem; + + params->id = BP_TAG_MEMORY; + params->size = sizeof(struct meminfo); + mem = (struct meminfo *)params->data; + mem->type = MEMORY_TYPE_CONVENTIONAL; + mem->start = bd->bi_memstart; + mem->end = bd->bi_memstart + bd->bi_memsize; + + printf(" MEMORY: tag:0x%04x, type:0X%lx, start:0X%lx, end:0X%lx\n", + BP_TAG_MEMORY, mem->type, mem->start, mem->end); + + return bp_tag_next(params); +} + +static struct bp_tag *setup_commandline_tag(struct bp_tag *params, + char *cmdline) +{ + int len; + + if (!cmdline) + return params; + + len = strlen(cmdline); + + params->id = BP_TAG_COMMAND_LINE; + params->size = (len + 3) & -4; + strcpy((char *)params->data, cmdline); + + printf(" COMMAND_LINE: tag:0x%04x, size:%u, data:'%s'\n", + BP_TAG_COMMAND_LINE, params->size, cmdline); + + return bp_tag_next(params); +} + +static struct bp_tag *setup_ramdisk_tag(struct bp_tag *params, + unsigned long rd_start, + unsigned long rd_end) +{ + struct meminfo *mem; + + if (rd_start == rd_end) + return params; + + /* Add a single banked memory. */ + + params->id = BP_TAG_INITRD; + params->size = sizeof(struct meminfo); + + mem = (struct meminfo *)params->data; + mem->type = MEMORY_TYPE_CONVENTIONAL; + mem->start = PHYSADDR(rd_start); + mem->end = PHYSADDR(rd_end); + + printf(" INITRD: tag:0x%x, type:0X%04lx, start:0X%lx, end:0X%lx\n", + BP_TAG_INITRD, mem->type, mem->start, mem->end); + + return bp_tag_next(params); +} + +static struct bp_tag *setup_serial_tag(struct bp_tag *params) +{ + params->id = BP_TAG_SERIAL_BAUDRATE; + params->size = sizeof(unsigned long); + params->data[0] = gd->baudrate; + + printf(" SERIAL_BAUDRATE: tag:0x%04x, size:%u, baudrate:%lu\n", + BP_TAG_SERIAL_BAUDRATE, params->size, params->data[0]); + + return bp_tag_next(params); +} + +#ifdef CONFIG_OF_LIBFDT + +static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start) +{ + params->id = BP_TAG_FDT; + params->size = sizeof(unsigned long); + params->data[0] = (unsigned long)fdt_start; + + printf(" FDT: tag:0x%04x, size:%u, start:0x%lx\n", + BP_TAG_FDT, params->size, params->data[0]); + + return bp_tag_next(params); +} + +#endif + +/* + * Boot Linux. + */ + +int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) +{ + struct bp_tag *params, *params_start; + image_header_t *hdr = images->legacy_hdr_os; + ulong initrd_start, initrd_end; + char *commandline = getenv("bootargs"); + void (*kernel)(struct bp_tag *); + + if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) + return 0; + + kernel = (void *)ntohl(hdr->ih_ep); + + if (ntohl(hdr->ih_magic) != IH_MAGIC) { + printf("Magic Number:0x%x != IH_MAGIC:0x%x\n", + ntohl(hdr->ih_magic), IH_MAGIC); + } + + show_boot_progress(15); + + if (images->rd_start) { + initrd_start = images->rd_start; + initrd_end = images->rd_end; + } else { + initrd_start = 0; + initrd_end = 0; + } + + params_start = (struct bp_tag *)gd->bd->bi_boot_params; + params = params_start; + params = setup_first_tag(params); + params = setup_memory_tag(params); + params = setup_commandline_tag(params, commandline); + params = setup_serial_tag(params); + + if (initrd_start) + params = setup_ramdisk_tag(params, initrd_start, initrd_end); + +#ifdef CONFIG_OF_LIBFDT + if (images->ft_addr) + params = setup_fdt_tag(params, images->ft_addr); +#endif + + printf("\n"); + + params = setup_last_tag(params); + + show_boot_progress(15); + + printf("Transferring Control to Linux @0x%08lx ...\n\n", (ulong)kernel); + + flush_dcache_range((unsigned long)params_start, (unsigned long)params); + + /* + * _start() in vmlinux expects boot params in register a2. + * NOTE: + * Disable/delete your u-boot breakpoints before stepping into linux. + */ + asm volatile ("mov a2, %0\n\t" + "jx %1\n\t" + : : "a" (params_start), "a" (kernel) + : "a2"); + + /* Does not return */ + + return 1; +} + diff --git a/arch/xtensa/lib/misc.S b/arch/xtensa/lib/misc.S new file mode 100644 index 0000000..6fd5bb4 --- /dev/null +++ b/arch/xtensa/lib/misc.S @@ -0,0 +1,178 @@ +/* + * Miscellaneous assembly functions. + * + * Copyright (C) 2001 - 2007 Tensilica Inc. + * + * Chris Zankel chris@zankel.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ + + +#include <linux/linkage.h> +#include <asm/asmmacro.h> +#include <asm/cacheasm.h> + +/* + * void __invalidate_icache_page(ulong start) + */ + +ENTRY(__invalidate_icache_page) + + entry sp, 16 + + ___invalidate_icache_page a2 a3 + isync + + retw + +ENDPROC(__invalidate_icache_page) + +/* + * void __invalidate_dcache_page(ulong start) + */ + +ENTRY(__invalidate_dcache_page) + + entry sp, 16 + + ___invalidate_dcache_page a2 a3 + dsync + + retw + +ENDPROC(__invalidate_dcache_page) + +/* + * void __flush_invalidate_dcache_page(ulong start) + */ + +ENTRY(__flush_invalidate_dcache_page) + + entry sp, 16 + + ___flush_invalidate_dcache_page a2 a3 + + dsync + retw + +ENDPROC(__flush_invalidate_dcache_page) + +/* + * void __flush_dcache_page(ulong start) + */ + +ENTRY(__flush_dcache_page) + + entry sp, 16 + + ___flush_dcache_page a2 a3 + + dsync + retw + +ENDPROC(__flush_dcache_page) + +/* + * void __invalidate_icache_range(ulong start, ulong size) + */ + +ENTRY(__invalidate_icache_range) + + entry sp, 16 + + ___invalidate_icache_range a2 a3 a4 + isync + + retw + +ENDPROC(__invalidate_icache_range) + +/* + * void __flush_invalidate_dcache_range(ulong start, ulong size) + */ + +ENTRY(__flush_invalidate_dcache_range) + + entry sp, 16 + + ___flush_invalidate_dcache_range a2 a3 a4 + dsync + + retw + +ENDPROC(__flush_invalidate_dcache_range) + +/* + * void _flush_dcache_range(ulong start, ulong size) + */ + +ENTRY(__flush_dcache_range) + + entry sp, 16 + + ___flush_dcache_range a2 a3 a4 + dsync + + retw + +ENDPROC(__flush_dcache_range) + +/* + * void _invalidate_dcache_range(ulong start, ulong size) + */ + +ENTRY(__invalidate_dcache_range) + + entry sp, 16 + + ___invalidate_dcache_range a2 a3 a4 + + retw + +ENDPROC(__invalidate_dcache_range) + +/* + * void _invalidate_icache_all(void) + */ + +ENTRY(__invalidate_icache_all) + + entry sp, 16 + + ___invalidate_icache_all a2 a3 + isync + + retw + +ENDPROC(__invalidate_icache_all) + +/* + * void _flush_invalidate_dcache_all(void) + */ + +ENTRY(__flush_invalidate_dcache_all) + + entry sp, 16 + + ___flush_invalidate_dcache_all a2 a3 + dsync + + retw + +ENDPROC(__flush_invalidate_dcache_all) + +/* + * void _invalidate_dcache_all(void) + */ + +ENTRY(__invalidate_dcache_all) + + entry sp, 16 + + ___invalidate_dcache_all a2 a3 + dsync + + retw + +ENDPROC(__invalidate_dcache_all) diff --git a/arch/xtensa/lib/time.c b/arch/xtensa/lib/time.c new file mode 100644 index 0000000..831335b --- /dev/null +++ b/arch/xtensa/lib/time.c @@ -0,0 +1,111 @@ +/* + * (C) Copyright 2008 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/global_data.h> +#include <linux/stringify.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if XCHAL_HAVE_CCOUNT +static ulong get_ccount(void) +{ + ulong ccount; + asm volatile ("rsr %0,"__stringify(CCOUNT) : "=a" (ccount)); + return ccount; +} +#else +static ulong fake_ccount; +#define get_ccount() fake_ccount +#endif + +static void delay_cycles(unsigned cycles) +{ +#if XCHAL_HAVE_CCOUNT + unsigned expiry = get_ccount() + cycles; + while ((signed)(expiry - get_ccount()) > 0) + ; +#else +#warning "Without Xtensa timer option, timing will not be accurate." + + /* + * Approximate the cycle count by a loop iteration count. + * This is highly dependent on config and optimization. + */ + + volatile unsigned i; + for (i = cycles >> 4U; i > 0; --i) + ; + fake_ccount += cycles; +#endif +} + +/* + * Delay (busy-wait) for a number of microseconds. + */ + +void __udelay(unsigned long usec) +{ + ulong lo, hi, i; + ulong mhz = CONFIG_SYS_CLK_FREQ / 1000000; + + /* Scale to support full 32-bit usec range */ + + lo = usec & ((1<<22)-1); + hi = usec >> 22UL; + for (i = 0; i < hi; ++i) + delay_cycles(mhz << 22); + delay_cycles(mhz * lo); +} + + +/* + * Return the elapsed time (ticks) since 'base'. + */ + +ulong get_timer(ulong base) +{ + /* Don't tie up a timer; use cycle counter if available (or fake it). */ + +#if XCHAL_HAVE_CCOUNT + register ulong ccount; + __asm__ volatile ("rsr %0, CCOUNT" : "=a"(ccount)); + return ccount / (CONFIG_SYS_CLK_FREQ / CONFIG_SYS_HZ) - base; +#else + /* + * Add at least the overhead of this call (in cycles). + * Avoids hanging in case caller doesn't use udelay(). + * Note that functions that don't call udelay() (such as + * the "sleep" command) will not get a significant delay + * because there is no time reference. + */ + + fake_ccount += 20; + return fake_ccount / (CONFIG_SYS_CLK_FREQ / CONFIG_SYS_HZ) - base; +#endif +} + + +/* + * This function is derived from ARM/PowerPC code (read timebase as long long). + * On Xtensa it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from ARM/PowerPC code (timebase clock frequency). + * On Xtensa it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +}

Hi Max,
On 20 August 2014 10:42, Max Filippov jcmvbkbc@gmail.com wrote:
From: Chris Zankel chris@zankel.net
The Xtensa processor architecture is a configurable, extensible, and synthesizable 32-bit RISC processor core provided by Tensilica, inc.
This is the second part of the basic architecture port, adding the 'arch/xtensa' directory and a readme file.
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com
arch/Kconfig | 4 + arch/xtensa/Kconfig | 26 ++ arch/xtensa/config.mk | 13 + arch/xtensa/cpu/.gitignore | 1 + arch/xtensa/cpu/Makefile | 13 + arch/xtensa/cpu/config.mk | 9 + arch/xtensa/cpu/cpu.c | 84 +++++ arch/xtensa/cpu/exceptions.c | 67 ++++ arch/xtensa/cpu/start.S | 672 ++++++++++++++++++++++++++++++++++ arch/xtensa/cpu/u-boot.lds.S | 107 ++++++ arch/xtensa/include/asm/addrspace.h | 43 +++ arch/xtensa/include/asm/asmmacro.h | 136 +++++++ arch/xtensa/include/asm/bitops.h | 14 + arch/xtensa/include/asm/bootparam.h | 54 +++ arch/xtensa/include/asm/byteorder.h | 81 ++++ arch/xtensa/include/asm/cache.h | 20 + arch/xtensa/include/asm/cacheasm.h | 187 ++++++++++ arch/xtensa/include/asm/config.h | 17 + arch/xtensa/include/asm/errno.h | 1 + arch/xtensa/include/asm/global_data.h | 24 ++ arch/xtensa/include/asm/io.h | 148 ++++++++ arch/xtensa/include/asm/ldscript.h | 220 +++++++++++ arch/xtensa/include/asm/linkage.h | 4 + arch/xtensa/include/asm/misc.h | 24 ++ arch/xtensa/include/asm/posix_types.h | 74 ++++ arch/xtensa/include/asm/processor.h | 11 + arch/xtensa/include/asm/ptrace.h | 133 +++++++ arch/xtensa/include/asm/regs.h | 95 +++++ arch/xtensa/include/asm/sections.h | 15 + arch/xtensa/include/asm/string.h | 10 + arch/xtensa/include/asm/types.h | 60 +++ arch/xtensa/include/asm/u-boot.h | 43 +++ arch/xtensa/include/asm/unaligned.h | 6 + arch/xtensa/include/asm/xtensa.h | 36 ++ arch/xtensa/lib/Makefile | 9 + arch/xtensa/lib/board.c | 173 +++++++++ arch/xtensa/lib/bootm.c | 202 ++++++++++ arch/xtensa/lib/misc.S | 178 +++++++++ arch/xtensa/lib/time.c | 111 ++++++ 39 files changed, 3125 insertions(+) create mode 100644 arch/xtensa/Kconfig create mode 100644 arch/xtensa/config.mk create mode 100644 arch/xtensa/cpu/.gitignore create mode 100644 arch/xtensa/cpu/Makefile create mode 100644 arch/xtensa/cpu/config.mk create mode 100644 arch/xtensa/cpu/cpu.c create mode 100644 arch/xtensa/cpu/exceptions.c create mode 100644 arch/xtensa/cpu/start.S create mode 100644 arch/xtensa/cpu/u-boot.lds.S create mode 100644 arch/xtensa/include/asm/addrspace.h create mode 100644 arch/xtensa/include/asm/asmmacro.h create mode 100644 arch/xtensa/include/asm/bitops.h create mode 100644 arch/xtensa/include/asm/bootparam.h create mode 100644 arch/xtensa/include/asm/byteorder.h create mode 100644 arch/xtensa/include/asm/cache.h create mode 100644 arch/xtensa/include/asm/cacheasm.h create mode 100644 arch/xtensa/include/asm/config.h create mode 100644 arch/xtensa/include/asm/errno.h create mode 100644 arch/xtensa/include/asm/global_data.h create mode 100644 arch/xtensa/include/asm/io.h create mode 100644 arch/xtensa/include/asm/ldscript.h create mode 100644 arch/xtensa/include/asm/linkage.h create mode 100644 arch/xtensa/include/asm/misc.h create mode 100644 arch/xtensa/include/asm/posix_types.h create mode 100644 arch/xtensa/include/asm/processor.h create mode 100644 arch/xtensa/include/asm/ptrace.h create mode 100644 arch/xtensa/include/asm/regs.h create mode 100644 arch/xtensa/include/asm/sections.h create mode 100644 arch/xtensa/include/asm/string.h create mode 100644 arch/xtensa/include/asm/types.h create mode 100644 arch/xtensa/include/asm/u-boot.h create mode 100644 arch/xtensa/include/asm/unaligned.h create mode 100644 arch/xtensa/include/asm/xtensa.h create mode 100644 arch/xtensa/lib/Makefile create mode 100644 arch/xtensa/lib/board.c create mode 100644 arch/xtensa/lib/bootm.c create mode 100644 arch/xtensa/lib/misc.S create mode 100644 arch/xtensa/lib/time.c
This all looks quite tidy, from a brief look.
But please make sure you use generic board - CONFIG_SYS_GENERIC_BOARD. You should not need a board.c file.
Also for your do_bootm_linux() implementation, see if you can check the flags, and thus support the bootm sub-commands.
If you have a microsecond timer, you could implement timer_get_us().
Regards, Simon

Hi Simon,
On Mon, Sep 1, 2014 at 9:02 AM, Simon Glass sjg@chromium.org wrote:
Hi Max,
On 20 August 2014 10:42, Max Filippov jcmvbkbc@gmail.com wrote:
From: Chris Zankel chris@zankel.net
The Xtensa processor architecture is a configurable, extensible, and synthesizable 32-bit RISC processor core provided by Tensilica, inc.
This is the second part of the basic architecture port, adding the 'arch/xtensa' directory and a readme file.
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com
arch/Kconfig | 4 + arch/xtensa/Kconfig | 26 ++ arch/xtensa/config.mk | 13 + arch/xtensa/cpu/.gitignore | 1 + arch/xtensa/cpu/Makefile | 13 + arch/xtensa/cpu/config.mk | 9 + arch/xtensa/cpu/cpu.c | 84 +++++ arch/xtensa/cpu/exceptions.c | 67 ++++ arch/xtensa/cpu/start.S | 672 ++++++++++++++++++++++++++++++++++ arch/xtensa/cpu/u-boot.lds.S | 107 ++++++ arch/xtensa/include/asm/addrspace.h | 43 +++ arch/xtensa/include/asm/asmmacro.h | 136 +++++++ arch/xtensa/include/asm/bitops.h | 14 + arch/xtensa/include/asm/bootparam.h | 54 +++ arch/xtensa/include/asm/byteorder.h | 81 ++++ arch/xtensa/include/asm/cache.h | 20 + arch/xtensa/include/asm/cacheasm.h | 187 ++++++++++ arch/xtensa/include/asm/config.h | 17 + arch/xtensa/include/asm/errno.h | 1 + arch/xtensa/include/asm/global_data.h | 24 ++ arch/xtensa/include/asm/io.h | 148 ++++++++ arch/xtensa/include/asm/ldscript.h | 220 +++++++++++ arch/xtensa/include/asm/linkage.h | 4 + arch/xtensa/include/asm/misc.h | 24 ++ arch/xtensa/include/asm/posix_types.h | 74 ++++ arch/xtensa/include/asm/processor.h | 11 + arch/xtensa/include/asm/ptrace.h | 133 +++++++ arch/xtensa/include/asm/regs.h | 95 +++++ arch/xtensa/include/asm/sections.h | 15 + arch/xtensa/include/asm/string.h | 10 + arch/xtensa/include/asm/types.h | 60 +++ arch/xtensa/include/asm/u-boot.h | 43 +++ arch/xtensa/include/asm/unaligned.h | 6 + arch/xtensa/include/asm/xtensa.h | 36 ++ arch/xtensa/lib/Makefile | 9 + arch/xtensa/lib/board.c | 173 +++++++++ arch/xtensa/lib/bootm.c | 202 ++++++++++ arch/xtensa/lib/misc.S | 178 +++++++++ arch/xtensa/lib/time.c | 111 ++++++ 39 files changed, 3125 insertions(+) create mode 100644 arch/xtensa/Kconfig create mode 100644 arch/xtensa/config.mk create mode 100644 arch/xtensa/cpu/.gitignore create mode 100644 arch/xtensa/cpu/Makefile create mode 100644 arch/xtensa/cpu/config.mk create mode 100644 arch/xtensa/cpu/cpu.c create mode 100644 arch/xtensa/cpu/exceptions.c create mode 100644 arch/xtensa/cpu/start.S create mode 100644 arch/xtensa/cpu/u-boot.lds.S create mode 100644 arch/xtensa/include/asm/addrspace.h create mode 100644 arch/xtensa/include/asm/asmmacro.h create mode 100644 arch/xtensa/include/asm/bitops.h create mode 100644 arch/xtensa/include/asm/bootparam.h create mode 100644 arch/xtensa/include/asm/byteorder.h create mode 100644 arch/xtensa/include/asm/cache.h create mode 100644 arch/xtensa/include/asm/cacheasm.h create mode 100644 arch/xtensa/include/asm/config.h create mode 100644 arch/xtensa/include/asm/errno.h create mode 100644 arch/xtensa/include/asm/global_data.h create mode 100644 arch/xtensa/include/asm/io.h create mode 100644 arch/xtensa/include/asm/ldscript.h create mode 100644 arch/xtensa/include/asm/linkage.h create mode 100644 arch/xtensa/include/asm/misc.h create mode 100644 arch/xtensa/include/asm/posix_types.h create mode 100644 arch/xtensa/include/asm/processor.h create mode 100644 arch/xtensa/include/asm/ptrace.h create mode 100644 arch/xtensa/include/asm/regs.h create mode 100644 arch/xtensa/include/asm/sections.h create mode 100644 arch/xtensa/include/asm/string.h create mode 100644 arch/xtensa/include/asm/types.h create mode 100644 arch/xtensa/include/asm/u-boot.h create mode 100644 arch/xtensa/include/asm/unaligned.h create mode 100644 arch/xtensa/include/asm/xtensa.h create mode 100644 arch/xtensa/lib/Makefile create mode 100644 arch/xtensa/lib/board.c create mode 100644 arch/xtensa/lib/bootm.c create mode 100644 arch/xtensa/lib/misc.S create mode 100644 arch/xtensa/lib/time.c
This all looks quite tidy, from a brief look.
Thanks for your feedback.
But please make sure you use generic board - CONFIG_SYS_GENERIC_BOARD. You should not need a board.c file.
Will fix.
Also for your do_bootm_linux() implementation, see if you can check the flags, and thus support the bootm sub-commands.
Ok.
If you have a microsecond timer, you could implement timer_get_us().
Ok, will add.

From: Chris Zankel chris@zankel.net
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- arch/xtensa/include/asm/arch-dc232b/core.h | 422 ++++++++++++++++++++++++++ arch/xtensa/include/asm/arch-dc232b/tie-asm.h | 120 ++++++++ arch/xtensa/include/asm/arch-dc232b/tie.h | 129 ++++++++ 3 files changed, 671 insertions(+) create mode 100644 arch/xtensa/include/asm/arch-dc232b/core.h create mode 100644 arch/xtensa/include/asm/arch-dc232b/tie-asm.h create mode 100644 arch/xtensa/include/asm/arch-dc232b/tie.h
diff --git a/arch/xtensa/include/asm/arch-dc232b/core.h b/arch/xtensa/include/asm/arch-dc232b/core.h new file mode 100644 index 0000000..7fd1aee --- /dev/null +++ b/arch/xtensa/include/asm/arch-dc232b/core.h @@ -0,0 +1,422 @@ +/* + * Xtensa processor core configuration information. + * + * Copyright (c) 1999-2007 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_CORE_CONFIGURATION_H +#define _XTENSA_CORE_CONFIGURATION_H + + +/**************************************************************************** + Parameters Useful for Any Code, USER or PRIVILEGED + ****************************************************************************/ + +/* + * Note: Macros of the form XCHAL_HAVE_*** have a value of 1 if the option is + * configured, and a value of 0 otherwise. These macros are always defined. + */ + + +/*---------------------------------------------------------------------- + ISA + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_BE 0 /* big-endian byte ordering */ +#define XCHAL_HAVE_WINDOWED 1 /* windowed registers option */ +#define XCHAL_NUM_AREGS 32 /* num of physical addr regs */ +#define XCHAL_NUM_AREGS_LOG2 5 /* log2(XCHAL_NUM_AREGS) */ +#define XCHAL_MAX_INSTRUCTION_SIZE 3 /* max instr bytes (3..8) */ +#define XCHAL_HAVE_DEBUG 1 /* debug option */ +#define XCHAL_HAVE_DENSITY 1 /* 16-bit instructions */ +#define XCHAL_HAVE_LOOPS 1 /* zero-overhead loops */ +#define XCHAL_HAVE_NSA 1 /* NSA/NSAU instructions */ +#define XCHAL_HAVE_MINMAX 1 /* MIN/MAX instructions */ +#define XCHAL_HAVE_SEXT 1 /* SEXT instruction */ +#define XCHAL_HAVE_CLAMPS 1 /* CLAMPS instruction */ +#define XCHAL_HAVE_MUL16 1 /* MUL16S/MUL16U instructions */ +#define XCHAL_HAVE_MUL32 1 /* MULL instruction */ +#define XCHAL_HAVE_MUL32_HIGH 0 /* MULUH/MULSH instructions */ +#define XCHAL_HAVE_DIV32 1 /* QUOS/QUOU/REMS/REMU instructions */ +#define XCHAL_HAVE_L32R 1 /* L32R instruction */ +#define XCHAL_HAVE_ABSOLUTE_LITERALS 1 /* non-PC-rel (extended) L32R */ +#define XCHAL_HAVE_CONST16 0 /* CONST16 instruction */ +#define XCHAL_HAVE_ADDX 1 /* ADDX#/SUBX# instructions */ +#define XCHAL_HAVE_WIDE_BRANCHES 0 /* B*.W18 or B*.W15 instr's */ +#define XCHAL_HAVE_PREDICTED_BRANCHES 0 /* B[EQ/EQZ/NE/NEZ]T instr's */ +#define XCHAL_HAVE_CALL4AND12 1 /* (obsolete option) */ +#define XCHAL_HAVE_ABS 1 /* ABS instruction */ +/*#define XCHAL_HAVE_POPC 0*/ /* POPC instruction */ +/*#define XCHAL_HAVE_CRC 0*/ /* CRC instruction */ +#define XCHAL_HAVE_RELEASE_SYNC 1 /* L32AI/S32RI instructions */ +#define XCHAL_HAVE_S32C1I 1 /* S32C1I instruction */ +#define XCHAL_HAVE_SPECULATION 0 /* speculation */ +#define XCHAL_HAVE_FULL_RESET 1 /* all regs/state reset */ +#define XCHAL_NUM_CONTEXTS 1 /* */ +#define XCHAL_NUM_MISC_REGS 2 /* num of scratch regs (0..4) */ +#define XCHAL_HAVE_TAP_MASTER 0 /* JTAG TAP control instr's */ +#define XCHAL_HAVE_PRID 1 /* processor ID register */ +#define XCHAL_HAVE_THREADPTR 1 /* THREADPTR register */ +#define XCHAL_HAVE_BOOLEANS 0 /* boolean registers */ +#define XCHAL_HAVE_CP 1 /* CPENABLE reg (coprocessor) */ +#define XCHAL_CP_MAXCFG 8 /* max allowed cp id plus one */ +#define XCHAL_HAVE_MAC16 1 /* MAC16 package */ +#define XCHAL_HAVE_VECTORFPU2005 0 /* vector floating-point pkg */ +#define XCHAL_HAVE_FP 0 /* floating point pkg */ +#define XCHAL_HAVE_VECTRA1 0 /* Vectra I pkg */ +#define XCHAL_HAVE_VECTRALX 0 /* Vectra LX pkg */ +#define XCHAL_HAVE_HIFI2 0 /* HiFi2 Audio Engine pkg */ + + +/*---------------------------------------------------------------------- + MISC + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_WRITEBUFFER_ENTRIES 8 /* size of write buffer */ +#define XCHAL_INST_FETCH_WIDTH 4 /* instr-fetch width in bytes */ +#define XCHAL_DATA_WIDTH 4 /* data width in bytes */ +/* In T1050, applies to selected core load and store instructions (see ISA): */ +#define XCHAL_UNALIGNED_LOAD_EXCEPTION 1 /* unaligned loads cause exc. */ +#define XCHAL_UNALIGNED_STORE_EXCEPTION 1 /* unaligned stores cause exc.*/ + +#define XCHAL_SW_VERSION 701001 /* sw version of this header */ + +#define XCHAL_CORE_ID "dc232b" /* alphanum core name + (CoreID) set in the Xtensa + Processor Generator */ + +#define XCHAL_CORE_DESCRIPTION "Diamond 232L Standard Core Rev.B (LE)" +#define XCHAL_BUILD_UNIQUE_ID 0x0000BEEF /* 22-bit sw build ID */ + +/* + * These definitions describe the hardware targeted by this software. + */ +#define XCHAL_HW_CONFIGID0 0xC56307FE /* ConfigID hi 32 bits*/ +#define XCHAL_HW_CONFIGID1 0x0D40BEEF /* ConfigID lo 32 bits*/ +#define XCHAL_HW_VERSION_NAME "LX2.1.1" /* full version name */ +#define XCHAL_HW_VERSION_MAJOR 2210 /* major ver# of targeted hw */ +#define XCHAL_HW_VERSION_MINOR 1 /* minor ver# of targeted hw */ +#define XCHAL_HW_VERSION 221001 /* major*100+minor */ +#define XCHAL_HW_REL_LX2 1 +#define XCHAL_HW_REL_LX2_1 1 +#define XCHAL_HW_REL_LX2_1_1 1 +#define XCHAL_HW_CONFIGID_RELIABLE 1 +/* If software targets a *range* of hardware versions, these are the bounds: */ +#define XCHAL_HW_MIN_VERSION_MAJOR 2210 /* major v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION_MINOR 1 /* minor v of earliest tgt hw */ +#define XCHAL_HW_MIN_VERSION 221001 /* earliest targeted hw */ +#define XCHAL_HW_MAX_VERSION_MAJOR 2210 /* major v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION_MINOR 1 /* minor v of latest tgt hw */ +#define XCHAL_HW_MAX_VERSION 221001 /* latest targeted hw */ + + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_ICACHE_LINESIZE 32 /* I-cache line size in bytes */ +#define XCHAL_DCACHE_LINESIZE 32 /* D-cache line size in bytes */ +#define XCHAL_ICACHE_LINEWIDTH 5 /* log2(I line size in bytes) */ +#define XCHAL_DCACHE_LINEWIDTH 5 /* log2(D line size in bytes) */ + +#define XCHAL_ICACHE_SIZE 16384 /* I-cache size in bytes or 0 */ +#define XCHAL_DCACHE_SIZE 16384 /* D-cache size in bytes or 0 */ + +#define XCHAL_DCACHE_IS_WRITEBACK 1 /* writeback feature */ + + + + +/**************************************************************************** + Parameters Useful for PRIVILEGED (Supervisory or Non-Virtualized) Code + ****************************************************************************/ + + +#ifndef XTENSA_HAL_NON_PRIVILEGED_ONLY + +/*---------------------------------------------------------------------- + CACHE + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_PIF 1 /* any outbound PIF present */ + +/* If present, cache size in bytes == (ways * 2^(linewidth + setwidth)). */ + +/* Number of cache sets in log2(lines per way): */ +#define XCHAL_ICACHE_SETWIDTH 7 +#define XCHAL_DCACHE_SETWIDTH 7 + +/* Cache set associativity (number of ways): */ +#define XCHAL_ICACHE_WAYS 4 +#define XCHAL_DCACHE_WAYS 4 + +/* Cache features: */ +#define XCHAL_ICACHE_LINE_LOCKABLE 1 +#define XCHAL_DCACHE_LINE_LOCKABLE 1 +#define XCHAL_ICACHE_ECC_PARITY 0 +#define XCHAL_DCACHE_ECC_PARITY 0 + +/* Number of encoded cache attr bits (see <xtensa/hal.h> for decoded bits): */ +#define XCHAL_CA_BITS 4 + + +/*---------------------------------------------------------------------- + INTERNAL I/D RAM/ROMs and XLMI + ----------------------------------------------------------------------*/ + +#define XCHAL_NUM_INSTROM 0 /* number of core instr. ROMs */ +#define XCHAL_NUM_INSTRAM 0 /* number of core instr. RAMs */ +#define XCHAL_NUM_DATAROM 0 /* number of core data ROMs */ +#define XCHAL_NUM_DATARAM 0 /* number of core data RAMs */ +#define XCHAL_NUM_URAM 0 /* number of core unified RAMs*/ +#define XCHAL_NUM_XLMI 0 /* number of core XLMI ports */ + + +/*---------------------------------------------------------------------- + INTERRUPTS and TIMERS + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_INTERRUPTS 1 /* interrupt option */ +#define XCHAL_HAVE_HIGHPRI_INTERRUPTS 1 /* med/high-pri. interrupts */ +#define XCHAL_HAVE_NMI 1 /* non-maskable interrupt */ +#define XCHAL_HAVE_CCOUNT 1 /* CCOUNT reg. (timer option) */ +#define XCHAL_NUM_TIMERS 3 /* number of CCOMPAREn regs */ +#define XCHAL_NUM_INTERRUPTS 22 /* number of interrupts */ +#define XCHAL_NUM_INTERRUPTS_LOG2 5 /* ceil(log2(NUM_INTERRUPTS)) */ +#define XCHAL_NUM_EXTINTERRUPTS 17 /* num of external interrupts */ +#define XCHAL_NUM_INTLEVELS 6 /* number of interrupt levels + (not including level zero) */ +#define XCHAL_EXCM_LEVEL 3 /* level masked by PS.EXCM */ + /* (always 1 in XEA1; levels 2 .. EXCM_LEVEL are "medium priority") */ + +/* Masks of interrupts at each interrupt level: */ +#define XCHAL_INTLEVEL1_MASK 0x001F80FF +#define XCHAL_INTLEVEL2_MASK 0x00000100 +#define XCHAL_INTLEVEL3_MASK 0x00200E00 +#define XCHAL_INTLEVEL4_MASK 0x00001000 +#define XCHAL_INTLEVEL5_MASK 0x00002000 +#define XCHAL_INTLEVEL6_MASK 0x00000000 +#define XCHAL_INTLEVEL7_MASK 0x00004000 + +/* Masks of interrupts at each range 1..n of interrupt levels: */ +#define XCHAL_INTLEVEL1_ANDBELOW_MASK 0x001F80FF +#define XCHAL_INTLEVEL2_ANDBELOW_MASK 0x001F81FF +#define XCHAL_INTLEVEL3_ANDBELOW_MASK 0x003F8FFF +#define XCHAL_INTLEVEL4_ANDBELOW_MASK 0x003F9FFF +#define XCHAL_INTLEVEL5_ANDBELOW_MASK 0x003FBFFF +#define XCHAL_INTLEVEL6_ANDBELOW_MASK 0x003FBFFF +#define XCHAL_INTLEVEL7_ANDBELOW_MASK 0x003FFFFF + +/* Level of each interrupt: */ +#define XCHAL_INT0_LEVEL 1 +#define XCHAL_INT1_LEVEL 1 +#define XCHAL_INT2_LEVEL 1 +#define XCHAL_INT3_LEVEL 1 +#define XCHAL_INT4_LEVEL 1 +#define XCHAL_INT5_LEVEL 1 +#define XCHAL_INT6_LEVEL 1 +#define XCHAL_INT7_LEVEL 1 +#define XCHAL_INT8_LEVEL 2 +#define XCHAL_INT9_LEVEL 3 +#define XCHAL_INT10_LEVEL 3 +#define XCHAL_INT11_LEVEL 3 +#define XCHAL_INT12_LEVEL 4 +#define XCHAL_INT13_LEVEL 5 +#define XCHAL_INT14_LEVEL 7 +#define XCHAL_INT15_LEVEL 1 +#define XCHAL_INT16_LEVEL 1 +#define XCHAL_INT17_LEVEL 1 +#define XCHAL_INT18_LEVEL 1 +#define XCHAL_INT19_LEVEL 1 +#define XCHAL_INT20_LEVEL 1 +#define XCHAL_INT21_LEVEL 3 +#define XCHAL_DEBUGLEVEL 6 /* debug interrupt level */ +#define XCHAL_HAVE_DEBUG_EXTERN_INT 1 /* OCD external db interrupt */ +#define XCHAL_NMILEVEL 7 /* NMI "level" (for use with + EXCSAVE/EPS/EPC_n, RFI n) */ + +/* Type of each interrupt: */ +#define XCHAL_INT0_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT1_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT2_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT3_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT4_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT5_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT6_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT7_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT8_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT9_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT10_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT11_TYPE XTHAL_INTTYPE_SOFTWARE +#define XCHAL_INT12_TYPE XTHAL_INTTYPE_EXTERN_LEVEL +#define XCHAL_INT13_TYPE XTHAL_INTTYPE_TIMER +#define XCHAL_INT14_TYPE XTHAL_INTTYPE_NMI +#define XCHAL_INT15_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT16_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT17_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT18_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT19_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT20_TYPE XTHAL_INTTYPE_EXTERN_EDGE +#define XCHAL_INT21_TYPE XTHAL_INTTYPE_EXTERN_EDGE + +/* Masks of interrupts for each type of interrupt: */ +#define XCHAL_INTTYPE_MASK_UNCONFIGURED 0xFFC00000 +#define XCHAL_INTTYPE_MASK_SOFTWARE 0x00000880 +#define XCHAL_INTTYPE_MASK_EXTERN_EDGE 0x003F8000 +#define XCHAL_INTTYPE_MASK_EXTERN_LEVEL 0x0000133F +#define XCHAL_INTTYPE_MASK_TIMER 0x00002440 +#define XCHAL_INTTYPE_MASK_NMI 0x00004000 +#define XCHAL_INTTYPE_MASK_WRITE_ERROR 0x00000000 + +/* Interrupt numbers assigned to specific interrupt sources: */ +#define XCHAL_TIMER0_INTERRUPT 6 /* CCOMPARE0 */ +#define XCHAL_TIMER1_INTERRUPT 10 /* CCOMPARE1 */ +#define XCHAL_TIMER2_INTERRUPT 13 /* CCOMPARE2 */ +#define XCHAL_TIMER3_INTERRUPT XTHAL_TIMER_UNCONFIGURED +#define XCHAL_NMI_INTERRUPT 14 /* non-maskable interrupt */ + +/* Interrupt numbers for levels at which only one interrupt is configured: */ +#define XCHAL_INTLEVEL2_NUM 8 +#define XCHAL_INTLEVEL4_NUM 12 +#define XCHAL_INTLEVEL5_NUM 13 +#define XCHAL_INTLEVEL7_NUM 14 +/* (There are many interrupts each at level(s) 1, 3.) */ + + +/* + * External interrupt vectors/levels. + * These macros describe how Xtensa processor interrupt numbers + * (as numbered internally, eg. in INTERRUPT and INTENABLE registers) + * map to external BInterrupt<n> pins, for those interrupts + * configured as external (level-triggered, edge-triggered, or NMI). + * See the Xtensa processor databook for more details. + */ + +/* Core interrupt numbers mapped to each EXTERNAL interrupt number: */ +#define XCHAL_EXTINT0_NUM 0 /* (intlevel 1) */ +#define XCHAL_EXTINT1_NUM 1 /* (intlevel 1) */ +#define XCHAL_EXTINT2_NUM 2 /* (intlevel 1) */ +#define XCHAL_EXTINT3_NUM 3 /* (intlevel 1) */ +#define XCHAL_EXTINT4_NUM 4 /* (intlevel 1) */ +#define XCHAL_EXTINT5_NUM 5 /* (intlevel 1) */ +#define XCHAL_EXTINT6_NUM 8 /* (intlevel 2) */ +#define XCHAL_EXTINT7_NUM 9 /* (intlevel 3) */ +#define XCHAL_EXTINT8_NUM 12 /* (intlevel 4) */ +#define XCHAL_EXTINT9_NUM 14 /* (intlevel 7) */ +#define XCHAL_EXTINT10_NUM 15 /* (intlevel 1) */ +#define XCHAL_EXTINT11_NUM 16 /* (intlevel 1) */ +#define XCHAL_EXTINT12_NUM 17 /* (intlevel 1) */ +#define XCHAL_EXTINT13_NUM 18 /* (intlevel 1) */ +#define XCHAL_EXTINT14_NUM 19 /* (intlevel 1) */ +#define XCHAL_EXTINT15_NUM 20 /* (intlevel 1) */ +#define XCHAL_EXTINT16_NUM 21 /* (intlevel 3) */ + + +/*---------------------------------------------------------------------- + EXCEPTIONS and VECTORS + ----------------------------------------------------------------------*/ + +#define XCHAL_XEA_VERSION 2 /* Xtensa Exception Architecture + number: 1 == XEA1 (old) + 2 == XEA2 (new) + 0 == XEAX (extern) */ +#define XCHAL_HAVE_XEA1 0 /* Exception Architecture 1 */ +#define XCHAL_HAVE_XEA2 1 /* Exception Architecture 2 */ +#define XCHAL_HAVE_XEAX 0 /* External Exception Arch. */ +#define XCHAL_HAVE_EXCEPTIONS 1 /* exception option */ +#define XCHAL_HAVE_MEM_ECC_PARITY 0 /* local memory ECC/parity */ +#define XCHAL_HAVE_VECTOR_SELECT 1 /* relocatable vectors */ +#define XCHAL_HAVE_VECBASE 1 /* relocatable vectors */ +#define XCHAL_VECBASE_RESET_VADDR 0xD0000000 /* VECBASE reset value */ +#define XCHAL_VECBASE_RESET_PADDR 0x00000000 +#define XCHAL_RESET_VECBASE_OVERLAP 0 + +#define XCHAL_RESET_VECTOR0_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR0_PADDR 0xFE000000 +#define XCHAL_RESET_VECTOR1_VADDR 0xD8000500 +#define XCHAL_RESET_VECTOR1_PADDR 0x00000500 +#define XCHAL_RESET_VECTOR_VADDR 0xFE000000 +#define XCHAL_RESET_VECTOR_PADDR 0xFE000000 +#define XCHAL_USER_VECOFS 0x00000340 +#define XCHAL_USER_VECTOR_VADDR 0xD0000340 +#define XCHAL_USER_VECTOR_PADDR 0x00000340 +#define XCHAL_KERNEL_VECOFS 0x00000300 +#define XCHAL_KERNEL_VECTOR_VADDR 0xD0000300 +#define XCHAL_KERNEL_VECTOR_PADDR 0x00000300 +#define XCHAL_DOUBLEEXC_VECOFS 0x000003C0 +#define XCHAL_DOUBLEEXC_VECTOR_VADDR 0xD00003C0 +#define XCHAL_DOUBLEEXC_VECTOR_PADDR 0x000003C0 +#define XCHAL_WINDOW_OF4_VECOFS 0x00000000 +#define XCHAL_WINDOW_UF4_VECOFS 0x00000040 +#define XCHAL_WINDOW_OF8_VECOFS 0x00000080 +#define XCHAL_WINDOW_UF8_VECOFS 0x000000C0 +#define XCHAL_WINDOW_OF12_VECOFS 0x00000100 +#define XCHAL_WINDOW_UF12_VECOFS 0x00000140 +#define XCHAL_WINDOW_VECTORS_VADDR 0xD0000000 +#define XCHAL_WINDOW_VECTORS_PADDR 0x00000000 +#define XCHAL_INTLEVEL2_VECOFS 0x00000180 +#define XCHAL_INTLEVEL2_VECTOR_VADDR 0xD0000180 +#define XCHAL_INTLEVEL2_VECTOR_PADDR 0x00000180 +#define XCHAL_INTLEVEL3_VECOFS 0x000001C0 +#define XCHAL_INTLEVEL3_VECTOR_VADDR 0xD00001C0 +#define XCHAL_INTLEVEL3_VECTOR_PADDR 0x000001C0 +#define XCHAL_INTLEVEL4_VECOFS 0x00000200 +#define XCHAL_INTLEVEL4_VECTOR_VADDR 0xD0000200 +#define XCHAL_INTLEVEL4_VECTOR_PADDR 0x00000200 +#define XCHAL_INTLEVEL5_VECOFS 0x00000240 +#define XCHAL_INTLEVEL5_VECTOR_VADDR 0xD0000240 +#define XCHAL_INTLEVEL5_VECTOR_PADDR 0x00000240 +#define XCHAL_INTLEVEL6_VECOFS 0x00000280 +#define XCHAL_INTLEVEL6_VECTOR_VADDR 0xD0000280 +#define XCHAL_INTLEVEL6_VECTOR_PADDR 0x00000280 +#define XCHAL_DEBUG_VECOFS XCHAL_INTLEVEL6_VECOFS +#define XCHAL_DEBUG_VECTOR_VADDR XCHAL_INTLEVEL6_VECTOR_VADDR +#define XCHAL_DEBUG_VECTOR_PADDR XCHAL_INTLEVEL6_VECTOR_PADDR +#define XCHAL_NMI_VECOFS 0x000002C0 +#define XCHAL_NMI_VECTOR_VADDR 0xD00002C0 +#define XCHAL_NMI_VECTOR_PADDR 0x000002C0 +#define XCHAL_INTLEVEL7_VECOFS XCHAL_NMI_VECOFS +#define XCHAL_INTLEVEL7_VECTOR_VADDR XCHAL_NMI_VECTOR_VADDR +#define XCHAL_INTLEVEL7_VECTOR_PADDR XCHAL_NMI_VECTOR_PADDR + + +/*---------------------------------------------------------------------- + DEBUG + ----------------------------------------------------------------------*/ + +#define XCHAL_HAVE_OCD 1 /* OnChipDebug option */ +#define XCHAL_NUM_IBREAK 2 /* number of IBREAKn regs */ +#define XCHAL_NUM_DBREAK 2 /* number of DBREAKn regs */ +#define XCHAL_HAVE_OCD_DIR_ARRAY 1 /* faster OCD option */ + + +/*---------------------------------------------------------------------- + MMU + ----------------------------------------------------------------------*/ + +/* See core-matmap.h header file for more details. */ + +#define XCHAL_HAVE_TLBS 1 /* inverse of HAVE_CACHEATTR */ +#define XCHAL_HAVE_SPANNING_WAY 0 /* one way maps I+D 4GB vaddr */ +#define XCHAL_HAVE_IDENTITY_MAP 0 /* vaddr == paddr always */ +#define XCHAL_HAVE_CACHEATTR 0 /* CACHEATTR register present */ +#define XCHAL_HAVE_MIMIC_CACHEATTR 0 /* region protection */ +#define XCHAL_HAVE_XLT_CACHEATTR 0 /* region prot. w/translation */ +#define XCHAL_HAVE_PTP_MMU 1 /* full MMU (with page table + [autorefill] and protection) + usable for an MMU-based OS */ +/* If none of the above last 4 are set, it's a custom TLB configuration. */ +#define XCHAL_ITLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ +#define XCHAL_DTLB_ARF_ENTRIES_LOG2 2 /* log2(autorefill way size) */ + +#define XCHAL_MMU_ASID_BITS 8 /* number of bits in ASIDs */ +#define XCHAL_MMU_RINGS 4 /* number of rings (1..4) */ +#define XCHAL_MMU_RING_BITS 2 /* num of bits in RING field */ + +#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */ + + +#endif /* _XTENSA_CORE_CONFIGURATION_H */ + diff --git a/arch/xtensa/include/asm/arch-dc232b/tie-asm.h b/arch/xtensa/include/asm/arch-dc232b/tie-asm.h new file mode 100644 index 0000000..539cba3 --- /dev/null +++ b/arch/xtensa/include/asm/arch-dc232b/tie-asm.h @@ -0,0 +1,120 @@ +/* + * This header file contains assembly-language definitions (assembly + * macros, etc.) for this specific Xtensa processor's TIE extensions + * and options. It is customized to this Xtensa processor configuration. + * + * Copyright (C) 1999-2007 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_CORE_TIE_ASM_H +#define _XTENSA_CORE_TIE_ASM_H + +/* Selection parameter values for save-area save/restore macros: */ +/* Option vs. TIE: */ +#define XTHAL_SAS_TIE 0x0001 /* custom extension or coprocessor */ +#define XTHAL_SAS_OPT 0x0002 /* optional (and not a coprocessor) */ +/* Whether used automatically by compiler: */ +#define XTHAL_SAS_NOCC 0x0004 /* not used by compiler w/o special opts/code */ +#define XTHAL_SAS_CC 0x0008 /* used by compiler without special opts/code */ +/* ABI handling across function calls: */ +#define XTHAL_SAS_CALR 0x0010 /* caller-saved */ +#define XTHAL_SAS_CALE 0x0020 /* callee-saved */ +#define XTHAL_SAS_GLOB 0x0040 /* global across function calls (in thread) */ +/* Misc */ +#define XTHAL_SAS_ALL 0xFFFF /* include all default NCP contents */ + + + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_store ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-8, 4, 4 + rsr \at1, ACCLO // MAC16 accumulator + rsr \at2, ACCHI + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + s32i \at2, \ptr, .Lxchal_ofs_ + 4 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-16, 4, 4 + rsr \at1, M0 // MAC16 registers + rsr \at2, M1 + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + s32i \at2, \ptr, .Lxchal_ofs_ + 4 + rsr \at1, M2 + rsr \at2, M3 + s32i \at1, \ptr, .Lxchal_ofs_ + 8 + s32i \at2, \ptr, .Lxchal_ofs_ + 12 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 16 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rsr \at1, SCOMPARE1 // conditional store option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + rur \at1, THREADPTR // threadptr option + s32i \at1, \ptr, .Lxchal_ofs_ + 0 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_store + +/* Macro to save all non-coprocessor (extra) custom TIE and optional state + * (not including zero-overhead loop registers). + * Save area ptr (clobbered): ptr (1 byte aligned) + * Scratch regs (clobbered): at1..at4 (only first XCHAL_NCP_NUM_ATMPS needed) + */ + .macro xchal_ncp_load ptr at1 at2 at3 at4 continue=0 ofs=-1 select=XTHAL_SAS_ALL + xchal_sa_start \continue, \ofs + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-8, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + l32i \at2, \ptr, .Lxchal_ofs_ + 4 + wsr \at1, ACCLO // MAC16 accumulator + wsr \at2, ACCHI + .set .Lxchal_ofs_, .Lxchal_ofs_ + 8 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-16, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + l32i \at2, \ptr, .Lxchal_ofs_ + 4 + wsr \at1, M0 // MAC16 registers + wsr \at2, M1 + l32i \at1, \ptr, .Lxchal_ofs_ + 8 + l32i \at2, \ptr, .Lxchal_ofs_ + 12 + wsr \at1, M2 + wsr \at2, M3 + .set .Lxchal_ofs_, .Lxchal_ofs_ + 16 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_NOCC | XTHAL_SAS_CALR) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wsr \at1, SCOMPARE1 // conditional store option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .ifeq (XTHAL_SAS_OPT | XTHAL_SAS_CC | XTHAL_SAS_GLOB) & ~\select + xchal_sa_align \ptr, 0, 1024-4, 4, 4 + l32i \at1, \ptr, .Lxchal_ofs_ + 0 + wur \at1, THREADPTR // threadptr option + .set .Lxchal_ofs_, .Lxchal_ofs_ + 4 + .endif + .endm // xchal_ncp_load + + + +#define XCHAL_NCP_NUM_ATMPS 2 + + +#define XCHAL_SA_NUM_ATMPS 2 + +#endif /*_XTENSA_CORE_TIE_ASM_H*/ + diff --git a/arch/xtensa/include/asm/arch-dc232b/tie.h b/arch/xtensa/include/asm/arch-dc232b/tie.h new file mode 100644 index 0000000..2b96a9d --- /dev/null +++ b/arch/xtensa/include/asm/arch-dc232b/tie.h @@ -0,0 +1,129 @@ +/* + * This header file describes this specific Xtensa processor's TIE extensions + * that extend basic Xtensa core functionality. It is customized to this + * Xtensa processor configuration. + * + * Copyright (C) 1999-2007 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _XTENSA_CORE_TIE_H +#define _XTENSA_CORE_TIE_H + +#define XCHAL_CP_NUM 1 /* number of coprocessors */ +#define XCHAL_CP_MAX 8 /* max CP ID + 1 (0 if none) */ +#define XCHAL_CP_MASK 0x80 /* bitmask of all CPs by ID */ +#define XCHAL_CP_PORT_MASK 0x80 /* bitmask of only port CPs */ + +/* Basic parameters of each coprocessor: */ +#define XCHAL_CP7_NAME "XTIOP" +#define XCHAL_CP7_IDENT XTIOP +#define XCHAL_CP7_SA_SIZE 0 /* size of state save area */ +#define XCHAL_CP7_SA_ALIGN 1 /* min alignment of save area */ +#define XCHAL_CP_ID_XTIOP 7 /* coprocessor ID (0..7) */ + +/* Filler info for unassigned coprocessors, to simplify arrays etc: */ +#define XCHAL_CP0_SA_SIZE 0 +#define XCHAL_CP0_SA_ALIGN 1 +#define XCHAL_CP1_SA_SIZE 0 +#define XCHAL_CP1_SA_ALIGN 1 +#define XCHAL_CP2_SA_SIZE 0 +#define XCHAL_CP2_SA_ALIGN 1 +#define XCHAL_CP3_SA_SIZE 0 +#define XCHAL_CP3_SA_ALIGN 1 +#define XCHAL_CP4_SA_SIZE 0 +#define XCHAL_CP4_SA_ALIGN 1 +#define XCHAL_CP5_SA_SIZE 0 +#define XCHAL_CP5_SA_ALIGN 1 +#define XCHAL_CP6_SA_SIZE 0 +#define XCHAL_CP6_SA_ALIGN 1 + +/* Save area for non-coprocessor optional and custom (TIE) state: */ +#define XCHAL_NCP_SA_SIZE 32 +#define XCHAL_NCP_SA_ALIGN 4 + +/* Total save area for optional and custom state (NCP + CPn): */ +#define XCHAL_TOTAL_SA_SIZE 32 /* with 16-byte align padding */ +#define XCHAL_TOTAL_SA_ALIGN 4 /* actual minimum alignment */ + +/* + * Detailed contents of save areas. + * NOTE: caller must define the XCHAL_SA_REG macro (not defined here) + * before expanding the XCHAL_xxx_SA_LIST() macros. + * + * XCHAL_SA_REG(s,ccused,abikind,kind,opt,name,galign,align,asize, + * dbnum,base,regnum,bitsz,gapsz,reset,x...) + * + * s = passed from XCHAL_*_LIST(s), eg. to select how to expand + * ccused = set if used by compiler without special options or code + * abikind = 0 (caller-saved), 1 (callee-saved), or 2 (thread-global) + * kind = 0 (special reg), 1 (TIE user reg), or 2 (TIE regfile reg) + * opt = 0 (custom TIE extension or coprocessor), or 1 (optional reg) + * name = lowercase reg name (no quotes) + * galign = group byte alignment (power of 2) (galign >= align) + * align = register byte alignment (power of 2) + * asize = allocated size in bytes (asize*8 == bitsz + gapsz + padsz) + * (not including any pad bytes required to galign this or next reg) + * dbnum = unique target number f/debug (see <xtensa-libdb-macros.h>) + * base = reg shortname w/o index (or sr=special, ur=TIE user reg) + * regnum = reg index in regfile, or special/TIE-user reg number + * bitsz = number of significant bits (regfile width, or ur/sr mask bits) + * gapsz = intervening bits, if bitsz bits not stored contiguously + * (padsz = pad bits at end [TIE regfile] or at msbits [ur,sr] of asize) + * reset = register reset value (or 0 if undefined at reset) + * x = reserved for future use (0 until then) + * + * To filter out certain registers, e.g. to expand only the non-global + * registers used by the compiler, you can do something like this: + * + * #define XCHAL_SA_REG(s,ccused,p...) SELCC##ccused(p) + * #define SELCC0(p...) + * #define SELCC1(abikind,p...) SELAK##abikind(p) + * #define SELAK0(p...) REG(p) + * #define SELAK1(p...) REG(p) + * #define SELAK2(p...) + * #define REG(kind,tie,name,galn,aln,asz,csz,dbnum,base,rnum,bsz,rst,x...) \ + * ...what you want to expand... + */ + +#define XCHAL_NCP_SA_NUM 8 +#define XCHAL_NCP_SA_LIST(s) \ + XCHAL_SA_REG(s,1,0,0,1, acclo, 4, 4, 4,0x0210, sr,16 , 32,0,0,0) \ + XCHAL_SA_REG(s,1,0,0,1, acchi, 4, 4, 4,0x0211, sr,17 , 8,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m0, 4, 4, 4,0x0220, sr,32 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m1, 4, 4, 4,0x0221, sr,33 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m2, 4, 4, 4,0x0222, sr,34 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, m3, 4, 4, 4,0x0223, sr,35 , 32,0,0,0) \ + XCHAL_SA_REG(s,0,0,0,1, scompare1, 4, 4, 4,0x020C, sr,12 , 32,0,0,0) \ + XCHAL_SA_REG(s,1,2,1,1, threadptr, 4, 4, 4,0x03E7, ur,231, 32,0,0,0) + +#define XCHAL_CP0_SA_NUM 0 +#define XCHAL_CP0_SA_LIST(s) /* empty */ + +#define XCHAL_CP1_SA_NUM 0 +#define XCHAL_CP1_SA_LIST(s) /* empty */ + +#define XCHAL_CP2_SA_NUM 0 +#define XCHAL_CP2_SA_LIST(s) /* empty */ + +#define XCHAL_CP3_SA_NUM 0 +#define XCHAL_CP3_SA_LIST(s) /* empty */ + +#define XCHAL_CP4_SA_NUM 0 +#define XCHAL_CP4_SA_LIST(s) /* empty */ + +#define XCHAL_CP5_SA_NUM 0 +#define XCHAL_CP5_SA_LIST(s) /* empty */ + +#define XCHAL_CP6_SA_NUM 0 +#define XCHAL_CP6_SA_LIST(s) /* empty */ + +#define XCHAL_CP7_SA_NUM 0 +#define XCHAL_CP7_SA_LIST(s) /* empty */ + +/* Byte length of instruction from its first nibble (op0 field), per FLIX. */ +#define XCHAL_OP0_FORMAT_LENGTHS 3,3,3,3,3,3,3,3,2,2,2,2,2,2,3,3 + +#endif /*_XTENSA_CORE_TIE_H*/ +

From: Chris Zankel chris@zankel.net
The 'xtfpga' board is actually a set of FPGA evaluation boards that can be configured to run an Xtensa processor.
- Avnet Xilinx LX60 - Avnet Xilinx LX110 - Avnet Xilinx LX200 - Xilinx ML605 - Xilinx KC705
These boards share the same components (open-ethernet, ns16550 serial, lcd display, flash, etc.).
Signed-off-by: Chris Zankel chris@zankel.net Signed-off-by: Max Filippov jcmvbkbc@gmail.com --- arch/xtensa/Kconfig | 3 + board/cadence/xtfpga/Kconfig | 51 +++++++ board/cadence/xtfpga/MAINTAINERS | 6 + board/cadence/xtfpga/Makefile | 8 + board/cadence/xtfpga/README | 121 ++++++++++++++++ board/cadence/xtfpga/lcd.c | 88 +++++++++++ board/cadence/xtfpga/lcd.h | 12 ++ board/cadence/xtfpga/xtfpga.c | 173 ++++++++++++++++++++++ configs/xtfpga_defconfig | 3 + include/configs/xtfpga.h | 305 +++++++++++++++++++++++++++++++++++++++ 10 files changed, 770 insertions(+) create mode 100644 board/cadence/xtfpga/Kconfig create mode 100644 board/cadence/xtfpga/MAINTAINERS create mode 100644 board/cadence/xtfpga/Makefile create mode 100644 board/cadence/xtfpga/README create mode 100644 board/cadence/xtfpga/lcd.c create mode 100644 board/cadence/xtfpga/lcd.h create mode 100644 board/cadence/xtfpga/xtfpga.c create mode 100644 configs/xtfpga_defconfig create mode 100644 include/configs/xtfpga.h
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index e4e3625..d41949f 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -11,9 +11,12 @@ config SYS_CPU choice prompt "Target select"
+config TARGET_XTFPGA + bool "Support XTFPGA"
endchoice
+source "board/cadence/xtfpga/Kconfig"
config HAVE_SYS_ASCDISP bool diff --git a/board/cadence/xtfpga/Kconfig b/board/cadence/xtfpga/Kconfig new file mode 100644 index 0000000..1244ad7 --- /dev/null +++ b/board/cadence/xtfpga/Kconfig @@ -0,0 +1,51 @@ +if TARGET_XTFPGA + +choice + prompt "XTFPGA board type select" + +config XTFPGA_LX60 + bool "Support Avnet LX60" + select HAVE_SYS_ASCDISP +config XTFPGA_LX110 + bool "Support Avnet LX110" + select HAVE_SYS_ASCDISP +config XTFPGA_LX200 + bool "Support Avnet LX200" +config XTFPGA_ML605 + bool "Support Xilinx ML605" + select HAVE_SYS_ASCDISP +config XTFPGA_KC705 + bool "Support Xilinx KC705" + select HAVE_SYS_ASCDISP + +endchoice + +config SYS_BOARD + string + default "xtfpga" + +config SYS_VENDOR + string + default "cadence" + +config SYS_CONFIG_NAME + string + default "xtfpga" + +config SYS_SDRAM_SIZE + hex + default 0x04000000 if XTFPGA_LX60 + default 0x03000000 if XTFPGA_LX110 + default 0x06000000 if XTFPGA_LX200 + default 0x20000000 if XTFPGA_ML605 + default 0x38000000 if XTFPGA_KC705 + +config SYS_MEMORY_SIZE + hex + default 0x04000000 if XTFPGA_LX60 + default 0x03000000 if XTFPGA_LX110 + default 0x06000000 if XTFPGA_LX200 + default 0x08000000 if XTFPGA_ML605 + default 0x08000000 if XTFPGA_KC705 + +endif diff --git a/board/cadence/xtfpga/MAINTAINERS b/board/cadence/xtfpga/MAINTAINERS new file mode 100644 index 0000000..31f5257 --- /dev/null +++ b/board/cadence/xtfpga/MAINTAINERS @@ -0,0 +1,6 @@ +XTFPGA BOARD +M: Max Filippov jcmvbkbc@gmail.com +S: Maintained +F: board/cadence/xtfpga/ +F: include/configs/xtfpga.h +F: configs/xtfpga_defconfig diff --git a/board/cadence/xtfpga/Makefile b/board/cadence/xtfpga/Makefile new file mode 100644 index 0000000..c521a80 --- /dev/null +++ b/board/cadence/xtfpga/Makefile @@ -0,0 +1,8 @@ +# +# (C) Copyright 2007 - 2013, Tensilica Inc. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += ${BOARD}.o +obj-$(CONFIG_SYS_ASCDISP) += lcd.o diff --git a/board/cadence/xtfpga/README b/board/cadence/xtfpga/README new file mode 100644 index 0000000..47305a2 --- /dev/null +++ b/board/cadence/xtfpga/README @@ -0,0 +1,121 @@ + Tensilica 'xtfpga' Evaluation Boards + ==================================== + +Tensilica's 'xtfpga' evaluation boards are actually a set of different +boards that share configurations. The following is a list of supported +hardware by this board type: + +- XT-AV60 / LX60 +- XT-AV110 / LX110 +- XT-AV200 / LX200 +- ML605 +- KC705 + +All boards provide the following common configurations: + +- An Xtensa or Diamond processor core. +- An on-chip-debug (OCD) JTAG interface. +- A 16550 compatible UART and serial port. +- An OpenCores Wishbone 10/100-base-T ethernet interface. +- A 32 char two line LCD display. (except for the LX200) + +LX60/LX110/LX200: + +- Virtex-4 (XC4VLX60 / XCV4LX200) / Virtext-5 (XC5VLX110) +- 128MB / 64MB (LX60) memory +- 16MB / 4MB (LX60) Linear Flash + +ML605 + +- Virtex-6 (XC6VLX240T) +- 512MB DDR3 memory +- 32MB Linear BPI Flash + +KC705 (Xilinx) + +- Kintex-7 XC7K325T FPGA +- 1GB DDR3 memory +- 128MB Linear BPI Flash + + +Setting up the Board +-------------------- + +The serial port defaults to 115200 baud, no parity and 1 stop bit. +A terminal emulator must be set accordingly to see the U-Boot prompt. + + +Board Configurations LX60/LX110/LX200 +------------------------------------- + +The LX60/LX110/LX200 contain an 8-way DIP switch that controls the boot +mapping and selects from a range of default ethernet MAC addresses. + +Boot Mapping (DIP switch 8): + + DIP switch 8 maps the system ROM address space (in which the + reset vector resides) to either SRAM (off, 0, down) or Flash + (on, 1, up). This mapping is implemented in the FPGA bitstream + and cannot be disabled by software, therefore DIP switch 8 is no + available for application use. Note DIP switch 7 is reserved by + Tensilica for future possible hardware use. + + Mapping to SRAM allows U-Boot to be debugged with an OCD/JTAG + tool such as the Xtensa OCD Daemon connected via a suppored probe. + See the tools documentation for supported probes and how to + connect them. Be aware that the board has only 128 KB of SRAM, + therefore U-Boot must fit within this space to debug an image + intended for the Flash. This issues is discussed in a separate + section toward the end. + + Mapping to flash allows U-Boot to start on reset, provided it + has been programmed into the first two 64 KB sectors of the Flash. + + The Flash is always mapped at a device (memory mapped I/O) address + (the address is board specific and is expressed as CFG_FLASH_BASE). + The device address is used by U-Boot to program the flash, and may + be used to specify an application to run or U-Boot image to boot. + +Default MAC Address (DIP switches 1-6): + + When the board is first powered on, or after the environment has + been reinitialized, the ethernet MAC address receives a default + value whose least significant 6 bits come from DIP switches 1-6. + The default is 00:50:C2:13:6F:xx where xx ranges from 0..3F + according to the DIP switches, where "on"==1 and "off"==0, and + switch 1 is the least-significant bit. + + After initial startup, the MAC address is stored in the U-Boot + environment variable 'ethaddr'. The user may change this to any + other address with the "setenv" comamnd. After the environment + has been saved to Flash by the "saveenv" command, this will be + used and the DIP switches no longer consulted. DIP swithes 1-6 + may then be used for application purposes. + + +Limitation of SDRAM Size for OCD Debugging on the LX60 +------------------------------------------------------ + +The XT-AV60 board has only 128 KB of SDRAM that can be mapped +to the system ROM address space for debugging a ROM image under +OCD/JTAG. This limits the useful size of U-Boot to 128 KB (0x20000) +or the first 2 sectors of the flash. + +This can pose a problem if all the sources are compiled with -O0 +for debugging. The code size is then too large, in which case it +would be necessary to temporarily alter the linker script to place +the load addresses (LMA) in the RAM (VMA) so that OCD loads U-Boot +directly there and does not unpack. In practice this is not really +necessary as long as only a limited set of sources need to be +debugged, because the image can still fit into the 128 KB SRAM. + +The recommended procedure for debugging is to first build U-Boot +with the default optimization level (-Os), and then touch and +rebuild incrementally with -O0 so that only the touched sources +are recompiled with -O0. To build with -O0, modify the top level +config.mk and add '-O0' to the make variable OPTFLAGS. + +Because this problem is easy to fall into and difficult to debug +if one doesn't expect it, the linker script provides a link-time +check and fatal error message if the image size exceeds 128 KB. + diff --git a/board/cadence/xtfpga/lcd.c b/board/cadence/xtfpga/lcd.c new file mode 100644 index 0000000..4ea06bb --- /dev/null +++ b/board/cadence/xtfpga/lcd.c @@ -0,0 +1,88 @@ +/* + * Driver for the LCD display on the Tensilica XT-AV60 Board. + * + * Copyright (C) 2001 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/* + * The LCD functions busy wait due to limitations of the LCD controller. + * This is a single-threaded boot-loader, so we don't care about that. + */ + + +#include <config.h> +#include <common.h> + +#define LCD_INSTR_ADDR (char *)(CONFIG_SYS_ASCDISP_ADDR + 0) +#define LCD_DATA_ADDR (char *)(CONFIG_SYS_ASCDISP_ADDR + 4) + +#define LCD_PAUSE_ITERATIONS 4000 +#define LCD_CLEAR 0x1 +#define LCD_DISPLAY_ON 0xc + +/* The KC704 requires 4-bit mode */ +#ifdef CONFIG_XTFPGA_KC705 +# define LCD_DISPLAY_FUNC 0x28 /* 4 bits and 2 lines display */ +# define LCD_DISPLAY_MODE 0x06 /* increase, not-shifted */ +#else +# define LCD_DISPLAY_FUNC 0x38 /* 8 bits and 2 lines display */ +# define LCD_DISPLAY_MODE 0x06 /* increase, not-shifted */ +#endif + +#define LCD_SHIFT_LEFT 0x18 +#define LCD_SHIFT_RIGHT 0x1c +#define LCD_DISPLAY_POS 0x80 + +#ifdef CONFIG_XTFPGA_KC705 +static inline void lcd_write(char *addr, char value) +{ + *addr = value; + udelay(500); + *addr = value << 4; + udelay(500); +} +#else +static inline void lcd_write(char *addr, char value) +{ + *addr = value; + udelay(500); +} +#endif + +void lcd_init(void) +{ + /* switching back to 8-bit mode needs at least 3 writes */ + *LCD_INSTR_ADDR = 0x33; + udelay(500); + *LCD_INSTR_ADDR = 0x33; + udelay(500); + *LCD_INSTR_ADDR = 0x33; + udelay(500); + *LCD_INSTR_ADDR = LCD_DISPLAY_FUNC; + udelay(500); + lcd_write(LCD_INSTR_ADDR, LCD_DISPLAY_FUNC); + lcd_write(LCD_INSTR_ADDR, LCD_DISPLAY_ON); + lcd_write(LCD_INSTR_ADDR, LCD_DISPLAY_MODE); + lcd_write(LCD_INSTR_ADDR, LCD_CLEAR); + udelay(2000); +} + +void lcd_disp_at_pos(char *str, char pos) +{ + lcd_write(LCD_INSTR_ADDR, LCD_DISPLAY_POS | pos); + udelay(100); + while (*str != 0) + lcd_write(LCD_DATA_ADDR, *str++); +} + +void lcd_shiftleft(void) +{ + lcd_write(LCD_INSTR_ADDR, LCD_SHIFT_LEFT); +} + +void lcd_shiftright(void) +{ + lcd_write(LCD_INSTR_ADDR, LCD_SHIFT_RIGHT); +} diff --git a/board/cadence/xtfpga/lcd.h b/board/cadence/xtfpga/lcd.h new file mode 100644 index 0000000..878b740 --- /dev/null +++ b/board/cadence/xtfpga/lcd.h @@ -0,0 +1,12 @@ +/* + * Driver for the LCD display on the Tensilica LX60 Board. + * + * Copyright (C) 2001 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +void lcd_init(void); +void lcd_disp_at_pos(char *, unsigned char); +void lcd_shiftleft(void); +void lcd_shiftright(void); diff --git a/board/cadence/xtfpga/xtfpga.c b/board/cadence/xtfpga/xtfpga.c new file mode 100644 index 0000000..cf6eaf0 --- /dev/null +++ b/board/cadence/xtfpga/xtfpga.c @@ -0,0 +1,173 @@ +/* + * (C) Copyright 2007 - 2013 Tensilica Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <linux/ctype.h> +#include <linux/string.h> +#include <linux/stringify.h> +#include <asm/xtensa.h> +#include <asm/global_data.h> +#include <netdev.h> + +#include "lcd.h" + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Check board idendity. + * (Print information about the board to stdout.) + */ + + +#if defined(CONFIG_XTFPGA_LX60) +const char *board = "XT_AV60"; +const char *description = "Avnet Xilinx LX60 FPGA Evaluation Board / "; +#elif defined(CONFIG_XTFPGA_LX110) +const char *board = "XT_AV110"; +const char *description = "Avnet Xilinx Virtex-5 LX110 Evaluation Kit / "; +#elif defined(CONFIG_XTFPGA_LX200) +const char *board = "XT_AV200"; +const char *description = "Avnet Xilinx Virtex-4 LX200 Evaluation Kit / "; +#elif defined(CONFIG_XTFPGA_ML605) +const char *board = "XT_ML605"; +const char *description = "Xilinx Virtex-6 FPGA ML605 Evaluation Kit / "; +#elif defined(CONFIG_XTFPGA_KC705) +const char *board = "XT_KC705"; +const char *description = "Xilinx Kintex-7 FPGA KC705 Evaluation Kit / "; +#else +const char *board = "<unknown>"; +const char *description = ""; +#endif + +int checkboard(void) +{ + printf("Board: %s: %sTensilica bitstream\n", board, description); + return 0; +} + +int dram_init(void) +{ + gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + return 0; +} + +int board_postclk_init(void) +{ + /* + * Obtain CPU clock frequency from board and cache in global + * data structure (Hz). Return 0 on success (OK to continue), + * else non-zero (hang). + */ + +#ifdef CONFIG_SYS_FPGAREG_FREQ + gd->cpu_clk = (*(volatile unsigned long *)CONFIG_SYS_FPGAREG_FREQ); +#else + /* early Tensilica bitstreams lack this reg, but most run at 50 MHz */ + gd->cpu_clk = 50000000UL; +#endif + return 0; +} + +/* + * Miscellaneous early initializations. + * We use this hook to retrieve the processor frequency + * and to initialize the LCD display. + */ + +int misc_init_f(void) +{ +#ifdef CONFIG_SYS_ASCDISP + /* Initialize the LCD. */ + + lcd_init(); +#endif + display_printf("U-Boot starting", NULL); + + return 0; +} + +/* + * Miscellaneous late initializations. + * The environment has been set up, so we can set the Ethernet address. + */ + +int misc_init_r(void) +{ +#ifdef CONFIG_CMD_NET + /* + * Initialize ethernet environment variables and board info. + * Default MAC address comes from CONFIG_ETHADDR + DIP switches 1-6. + */ + + char *s = getenv("ethaddr"); + if (s == 0) { + unsigned int x; + s = __stringify(CONFIG_ETHBASE); + x = (*(volatile u32 *)CONFIG_SYS_FPGAREG_DIPSW) + & FPGAREG_MAC_MASK; + sprintf(&s[15], "%02x", x); + setenv("ethaddr", s); + } +#endif /* CONFIG_CMD_NET */ + + return 0; +} + +#ifdef CONFIG_CMD_NET +int board_eth_init(bd_t *bis) +{ + return ethoc_initialize(0, CONFIG_SYS_ETHOC_BASE); +} +#endif + + +/* + * Print a formatted string to the board's ASCII character display. + * String may have embedded newlines. Starts at top left and wraps long lines. + */ + +#ifdef CONFIG_SYS_ASCDISP +void display_printf(const char *fmt, ...) +{ + va_list args; + + /* Warning: sprintf() can overflow this buffer if too small! */ + char buf[CONFIG_SYS_ASCDISP_BUFSZ]; + int i; + + va_start(args, fmt); + vsprintf(buf, fmt, args); + + /* Truncate to one line and pad line with blanks. */ + for (i = 0; + i < CONFIG_SYS_ASCDISP_BUFSZ-1 && buf[i] != '\0' && buf[i] != '\n'; + ++i) + ; + for (; i < CONFIG_SYS_ASCDISP_CHARS; ++i) + buf[i] = ' '; + buf[CONFIG_SYS_ASCDISP_CHARS] = 0; + + lcd_disp_at_pos(buf, 0); + + va_end(args); +} +#endif + +#ifdef CONFIG_SHOW_BOOT_PROGRESS +/* Display a boot progress number on the LCD display. */ +void show_boot_progress(int val) +{ + display_printf("Progress = %d", val); +} +#endif + +/* Implement the "reset" command. */ +void board_reset(void) +{ + *(vu_long *)CONFIG_SYS_FPGAREG_RESET = CONFIG_SYS_FPGAREG_RESET_CODE; + /* Shouldn't reach here. */ +} diff --git a/configs/xtfpga_defconfig b/configs/xtfpga_defconfig new file mode 100644 index 0000000..009ce35 --- /dev/null +++ b/configs/xtfpga_defconfig @@ -0,0 +1,3 @@ +CONFIG_XTENSA=y +CONFIG_SYS_CPU="dc232b" +CONFIG_XTFPGA_KC705=y diff --git a/include/configs/xtfpga.h b/include/configs/xtfpga.h new file mode 100644 index 0000000..a932ea0 --- /dev/null +++ b/include/configs/xtfpga.h @@ -0,0 +1,305 @@ +/* + * Copyright (C) 2007-2013 Tensilica, Inc. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#include <asm/addrspace.h> + +/* + * The 'xtfpga' board describes a set of very similar boards with only minimal + * differences. Define one of the following in boards.cfg + * XTFPGA_LX60 + * XTFPGA_LX110 + * XTFPGA_LX200 + * XTFPGA_ML605 + * XTFPGA_KC705 + */ + +/*=====================*/ +/* Board and Processor */ +/*=====================*/ + +#define CONFIG_XTFPGA + +/* FPGA CPU freq after init */ +#define CONFIG_SYS_CLK_FREQ (gd->cpu_clk) + +/* Which (core) timer to use */ +#define CONFIG_TIMER_INDEX 0 +#define CONFIG_SYS_HZ 1000 /* timer-ticks/second */ + +/*===================*/ +/* RAM Memory Layout */ +/*===================*/ + +/* Lx60 can only map 128kb memory (instead of 256kb) when running under OCD */ +#ifdef CONFIG_XTFPGA_LX60 +# define CONFIG_SYS_MONITOR_LEN 0x00020000 /* 128 << 10 */ +#else +# define CONFIG_SYS_MONITOR_LEN 0x00040000 /* 256 << 10 */ +#endif + +#define CONFIG_SYS_STACKSIZE (512 << 10) /* stack 128KB */ +#define CONFIG_SYS_MALLOC_LEN (256 << 10) /* heap 256KB */ + +/* Linux boot param area in RAM (used only when booting linux) */ +#define CONFIG_SYS_BOOTPARAMS_LEN (64 << 10) + +/* U-Boot initial RAM area before it unpacks itself (not currently used) */ + +/* Memory test is destructive so default must not overlap vectors or U-Boot*/ +#define CONFIG_SYS_MEMTEST_START MEMADDR(0x01000000) +#define CONFIG_SYS_MEMTEST_END MEMADDR(0x02000000) + +/* Load address for stand-alone applications. + * MEMADDR cannot be used here, because the definition needs to be + * a plain number as it's used as -Ttext argument for ld in standalone + * example makefile. Handle MMUv2 vs MMUv3 distinction here manually. + */ +#if XCHAL_VECBASE_RESET_VADDR == XCHAL_VECBASE_RESET_PADDR +#define CONFIG_STANDALONE_LOAD_ADDR 0x00800000 +#else +#define CONFIG_STANDALONE_LOAD_ADDR 0xd0800000 +#endif + +/* SDRAM sizes: */ +/* LX60 0x04000000 64 MB */ +/* LX110 0x03000000 48 MB */ +/* LX200 0x06000000 96 MB */ +/* ML605 0x20000000 512 MB */ +/* KC705 0x40000000 1 GB */ + +#define CONFIG_SYS_SDRAM_PHYS 0x00000000 +#define CONFIG_SYS_SDRAM_VADDR MEMADDR(0x00000000) +#ifndef CONFIG_SYS_MEMORY_SIZE +# define CONFIG_SYS_MEMORY_SIZE CONFIG_SYS_SDRAM_SIZE +#endif + +#define CONFIG_SYS_MEMORY_TOP \ + (CONFIG_SYS_MEMORY_BASE + CONFIG_SYS_MEMORY_SIZE) + +#define CONFIG_SYS_BOOTPARAMS_ADDR \ + (CONFIG_SYS_MEMORY_TOP - CONFIG_SYS_BOOTPARAMS_LEN) +#define CONFIG_SYS_SP_TOP \ + (CONFIG_SYS_BOOTPARAMS_ADDR - GD_SIZE) +#define CONFIG_SYS_TEXT_ADDR \ + (CONFIG_SYS_SP_TOP - CONFIG_SYS_STACKSIZE - CONFIG_SYS_MONITOR_LEN) + +#define CONFIG_SYS_GD_ADDR CONFIG_SYS_SP_TOP + +/* Used by tftpboot; env var 'loadaddr' */ +#define CONFIG_SYS_LOAD_ADDR MEMADDR(0x02000000) + +/*==============================*/ +/* U-Boot general configuration */ +/*==============================*/ + +#undef CONFIG_USE_IRQ /* Keep it simple, poll only */ +#define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_BOARD_POSTCLK_INIT +#define CONFIG_DISPLAY_BOARDINFO +#define CONFIG_MISC_INIT_R +#define CONFIG_MISC_INIT_F + +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_SYS_PROMPT "U-Boot> " + /* Console I/O Buffer Size */ +#define CONFIG_SYS_CBSIZE 1024 + /* Prt buf */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) + /* max number of command args */ +#define CONFIG_SYS_MAXARGS 16 + /* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE + + +/* Enable device tree support */ +#define CONFIG_OF_LIBFDT 1 +/*#define CONFIG_FIT*/ + +/*=================*/ +/* U-Boot commands */ +/*=================*/ + +#include <config_cmd_default.h> +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_DIAG +#define CONFIG_CMD_PING +#define CONFIG_CMD_SAVES +#define CONFIG_CMD_SAVEENV +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR +#undef CONFIG_CMD_XIMG + +/*==============================*/ +/* U-Boot autoboot configuration */ +/*==============================*/ + +#define CONFIG_BOOTDELAY 10 /* autoboot after 10 seconds */ +#define CONFIG_BOOT_RETRY_TIME 60 /* retry after 60 secs */ +#define CONFIG_BOOT_RETRY_MIN 1 /* at least 1 second timeout */ +/* + * Be selective on what keys can delay or stop the autoboot process + * To stop use: " " + */ +#define CONFIG_AUTOBOOT_KEYED +#define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, " \ + "press <SPACE> to stop\n", bootdelay +#define CONFIG_AUTOBOOT_STOP_STR " " +#undef CONFIG_AUTOBOOT_DELAY_STR +#define DEBUG_BOOTKEYS 0 + +#define CONFIG_VERSION_VARIABLE +#define CONFIG_AUTO_COMPLETE /* Support tab autocompletion */ +#define CONFIG_CMDLINE_EDITING +#define CONFIG_SYS_LONGHELP +#define CONFIG_CRC32_VERIFY +#define CONFIG_MX_CYCLIC +#define CONFIG_SHOW_BOOT_PROGRESS + +#ifdef DEBUG +#define CONFIG_PANIC_HANG 1 /* Require manual reboot */ +#endif + + +/*=========================================*/ +/* FPGA Registers (board info and control) */ +/*=========================================*/ + +/* + * These assume FPGA bitstreams from Tensilica release RB and up. Earlier + * releases may not provide any/all of these registers or at these offsets. + * Some of the FPGA registers are broken down into bitfields described by + * SHIFT left amount and field WIDTH (bits), and also by a bitMASK. + */ + +/* Date of FPGA bitstream build in binary coded decimal (BCD) */ +#define CONFIG_SYS_FPGAREG_DATE IOADDR(0x0D020000) +#define FPGAREG_MTH_SHIFT 24 /* BCD month 1..12 */ +#define FPGAREG_MTH_WIDTH 8 +#define FPGAREG_MTH_MASK 0xFF000000 +#define FPGAREG_DAY_SHIFT 16 /* BCD day 1..31 */ +#define FPGAREG_DAY_WIDTH 8 +#define FPGAREG_DAY_MASK 0x00FF0000 +#define FPGAREG_YEAR_SHIFT 0 /* BCD year 2001..9999*/ +#define FPGAREG_YEAR_WIDTH 16 +#define FPGAREG_YEAR_MASK 0x0000FFFF + +/* FPGA core clock frequency in Hz (also input to UART) */ +#define CONFIG_SYS_FPGAREG_FREQ IOADDR(0x0D020004) /* CPU clock frequency*/ + +/* + * DIP switch (left=sw1=lsb=bit0, right=sw8=msb=bit7; off=0, on=1): + * Bits 0..5 set the lower 6 bits of the default ethernet MAC. + * Bit 6 is reserved for future use by Tensilica. + * Bit 7 maps the first 128KB of ROM address space at CONFIG_SYS_ROM_BASE to + * the base of flash * (when on/1) or to the base of RAM (when off/0). + */ +#define CONFIG_SYS_FPGAREG_DIPSW IOADDR(0x0D02000C) +#define FPGAREG_MAC_SHIFT 0 /* Ethernet MAC bits 0..5 */ +#define FPGAREG_MAC_WIDTH 6 +#define FPGAREG_MAC_MASK 0x3f +#define FPGAREG_BOOT_SHIFT 7 /* Boot ROM addr mapping */ +#define FPGAREG_BOOT_WIDTH 1 +#define FPGAREG_BOOT_MASK 0x80 +#define FPGAREG_BOOT_RAM 0 +#define FPGAREG_BOOT_FLASH (1<<FPGAREG_BOOT_SHIFT) + +/* Force hard reset of board by writing a code to this register */ +#define CONFIG_SYS_FPGAREG_RESET IOADDR(0x0D020010) /* Reset board .. */ +#define CONFIG_SYS_FPGAREG_RESET_CODE 0x0000DEAD /* by writing this code */ + +/*====================*/ +/* ASCII Display Info */ +/*====================*/ + +#ifndef CONFIG_XTFPGA_LX200 /* LX200 has no ascii display */ +# ifdef CONFIG_XTFPGA_LX60 +# define CONFIG_SYS_ASCDISP_ADDR IOADDR(0x0D040000) +# else +# define CONFIG_SYS_ASCDISP_ADDR IOADDR(0x0D0C0000) +# endif +#define CONFIG_SYS_ASCDISP_LINES 2 +#define CONFIG_SYS_ASCDISP_CHARS 16 +#define CONFIG_SYS_ASCDISP_BUFSZ 64 /* Display printf buffer size */ +#endif + +/*====================*/ +/* Serial Driver Info */ +/*====================*/ + +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_REG_SIZE (-4) +#define CONFIG_SYS_NS16550_COM1 IOADDR(0x0D050020) /* Base address */ + +/* Input clk to NS16550 (in Hz; the SYS_CLK_FREQ is in kHz) */ +#define CONFIG_SYS_NS16550_CLK CONFIG_SYS_CLK_FREQ +#define CONFIG_CONS_INDEX 1 /* use UART0 for console */ +#define CONFIG_BAUDRATE 115200 /* Default baud rate */ +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } +#define CONFIG_SYS_NS16550_BROKEN_TEMT + +/*======================*/ +/* Ethernet Driver Info */ +/*======================*/ + +#define CONFIG_ETHOC +#define CONFIG_ETHBASE 00:50:C2:13:6f:00 +#define CONFIG_SYS_ETHOC_BASE IOADDR(0x0d030000) +#define CONFIG_SYS_ETHOC_BUFFER_ADDR IOADDR(0x0D800000) +#define CONFIG_SYS_ETHOC_SETUP_PHY + +/*=====================*/ +/* Flash & Environment */ +/*=====================*/ + +#define CONFIG_SYS_FLASH_CFI +#define CONFIG_FLASH_CFI_DRIVER /* use generic CFI driver */ +#undef CONFIG_FLASH_CFI_LEGACY /* only use CFI for flash */ +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT +#define CONFIG_SYS_MAX_FLASH_BANKS 1 +#ifdef CONFIG_XTFPGA_LX60 +# define CONFIG_SYS_FLASH_SIZE 0x0040000 /* 4MB */ +# define CONFIG_SYS_FLASH_SECT_SZ 0x10000 /* block size 64KB */ +# define CONFIG_SYS_FLASH_PARMSECT_SZ 0x2000 /* param size 8KB */ +# define CONFIG_SYS_FLASH_BASE IOADDR(0x08000000) +#elif defined(CONFIG_XTFPGA_KC705) +# define CONFIG_SYS_FLASH_SIZE 0x8000000 /* 128MB */ +# define CONFIG_SYS_FLASH_SECT_SZ 0x20000 /* block size 128KB */ +# define CONFIG_SYS_FLASH_PARMSECT_SZ 0x8000 /* param size 32KB */ +# define CONFIG_SYS_FLASH_BASE IOADDR(0x00000000) +#else +# define CONFIG_SYS_FLASH_SIZE 0x0200000 /* 32MB */ +# define CONFIG_SYS_FLASH_SECT_SZ 0x20000 /* block size 128KB */ +# define CONFIG_SYS_FLASH_PARMSECT_SZ 0x8000 /* param size 32KB */ +# define CONFIG_SYS_FLASH_BASE IOADDR(0x08000000) +#endif +#define CONFIG_SYS_MAX_FLASH_SECT \ + (CONFIG_SYS_FLASH_SECT_SZ/CONFIG_SYS_FLASH_PARMSECT_SZ + \ + CONFIG_SYS_FLASH_SIZE/CONFIG_SYS_FLASH_SECT_SZ - 1) +#define CONFIG_SYS_FLASH_PROTECTION /* hw flash protection */ + +#define CONFIG_SYS_FLASH_TOP (CONFIG_SYS_FLASH_BASE + CONFIG_SYS_FLASH_SIZE) + +/* U-Boot monitor lives at the base of flash where it's mapped to ROM area */ +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE + +/* + * Put environment in top block (64kB) + * Another option would be to put env. in 2nd param block offs 8KB, size 8KB + */ +#define CONFIG_ENV_IS_IN_FLASH +#define CONFIG_ENV_OFFSET (CONFIG_SYS_FLASH_SIZE - CONFIG_SYS_FLASH_SECT_SZ) +#define CONFIG_ENV_SIZE CONFIG_SYS_FLASH_SECT_SZ + +/* print 'E' for empty sector on flinfo */ +#define CONFIG_SYS_FLASH_EMPTY_INFO + +#endif /* __CONFIG_H */

On Wed, Aug 20, 2014 at 9:42 PM, Max Filippov jcmvbkbc@gmail.com wrote:
Hi Tom,
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Ping?

On Thu, Aug 28, 2014 at 12:59:01AM +0400, Max Filippov wrote:
On Wed, Aug 20, 2014 at 9:42 PM, Max Filippov jcmvbkbc@gmail.com wrote:
Hi Tom,
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Ping?
Sorry, had a buncha things on my plate of late, I'll review the arch port soon.

Hi Max,
On 08/20/2014 07:42 PM, Max Filippov wrote:
Hi Tom,
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Preparation patches clean up OpenCores 10/100 MBit driver, enable it to be used with dedicated packet memory and with gigabit PHY. Two patches add proper xtensa bits: changes to shares files and contents of arch/xtensa. One more patch adds sample xtensa CPU configuration -- Diamond 232. One more patch adds xtfpga board family that consists of Avnet LX60, LX110 and LX200 and Xilinx ML605 and KC705 FPGA boards configured with xtensa bitstream.
Any link to bitstreams? I have ml605 and kc705 here and will be nice to test it.
Thanks, Michal

Hi Michal,
On Fri, Aug 29, 2014 at 3:50 PM, Michal Simek monstr@monstr.eu wrote:
On 08/20/2014 07:42 PM, Max Filippov wrote:
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Preparation patches clean up OpenCores 10/100 MBit driver, enable it to be used with dedicated packet memory and with gigabit PHY. Two patches add proper xtensa bits: changes to shares files and contents of arch/xtensa. One more patch adds sample xtensa CPU configuration -- Diamond 232. One more patch adds xtfpga board family that consists of Avnet LX60, LX110 and LX200 and Xilinx ML605 and KC705 FPGA boards configured with xtensa bitstream.
Any link to bitstreams? I have ml605 and kc705 here and will be nice to test it.
The board alone is not enough to boot xtensa software, as the JTAG connector capable of loading code into CPU goes on a separate daughterboard that plugs into FMC connectors. I will check if I can share a bitstream and if it may be somehow used with the FPGA board alone.
However you should be able to test with qemu, as it simulates all necessary hardware. Some examples are listed here: http://wiki.linux-xtensa.org/index.php/Xtensa_on_QEMU

On 08/29/2014 02:25 PM, Max Filippov wrote:
Hi Michal,
On Fri, Aug 29, 2014 at 3:50 PM, Michal Simek monstr@monstr.eu wrote:
On 08/20/2014 07:42 PM, Max Filippov wrote:
this series adds U-Boot port to Xtensa, configurable processor architecture from Tensilica, Inc., now Cadence Design Systems Inc.
Preparation patches clean up OpenCores 10/100 MBit driver, enable it to be used with dedicated packet memory and with gigabit PHY. Two patches add proper xtensa bits: changes to shares files and contents of arch/xtensa. One more patch adds sample xtensa CPU configuration -- Diamond 232. One more patch adds xtfpga board family that consists of Avnet LX60, LX110 and LX200 and Xilinx ML605 and KC705 FPGA boards configured with xtensa bitstream.
Any link to bitstreams? I have ml605 and kc705 here and will be nice to test it.
The board alone is not enough to boot xtensa software, as the JTAG connector capable of loading code into CPU goes on a separate daughterboard that plugs into FMC connectors. I will check if I can share a bitstream and if it may be somehow used with the FPGA board alone.
Any link to that FMC connector and connections there?
However you should be able to test with qemu, as it simulates all necessary hardware. Some examples are listed here: http://wiki.linux-xtensa.org/index.php/Xtensa_on_QEMU
I am more interested to see this work on real HW than on qemu.
Thanks, Michal

Hi Michal,
On Fri, Aug 29, 2014 at 6:46 AM, Michal Simek monstr@monstr.eu wrote:
On 08/29/2014 02:25 PM, Max Filippov wrote:
On Fri, Aug 29, 2014 at 3:50 PM, Michal Simek monstr@monstr.eu wrote:
Any link to bitstreams? I have ml605 and kc705 here and will be nice to test it.
The board alone is not enough to boot xtensa software, as the JTAG connector capable of loading code into CPU goes on a separate daughterboard that plugs into FMC connectors. I will check if I can share a bitstream and if it may be somehow used with the FPGA board alone.
Any link to that FMC connector and connections there?
However you should be able to test with qemu, as it simulates all necessary hardware. Some examples are listed here: http://wiki.linux-xtensa.org/index.php/Xtensa_on_QEMU
I am more interested to see this work on real HW than on qemu.
Tensilica IP group is willing to provide you the bitstream and the related documentation, but for its own protection it wants you to sign a license agreement. It is said to be short and written in plain language. I will provide additional details privately.
participants (4)
-
Max Filippov
-
Michal Simek
-
Simon Glass
-
Tom Rini