From: Chris Zankel <ch...@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 <ch...@zankel.net>
Signed-off-by: Max Filippov <jcmvb...@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: phi...@opensdr.com
 D: Port to Lyrtech SFFSDR development board.
 W: www.opensdr.com
+
+N: Chris Zankel
+E: ch...@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
 }
-- 
1.8.1.4

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to