Commit de5e5cea022ab44006ff1edf45a39f0943fb9dff

Authored by Chris Zankel
Committed by Tom Rini
1 parent f225d39d30

xtensa: add support for the xtensa processor architecture [1/2]

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>
Reviewed-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Tom Rini <trini@konsulko.com>

Showing 9 changed files with 179 additions and 6 deletions Side-by-side Diff

... ... @@ -454,6 +454,11 @@
454 454 T: git git://git.denx.de/u-boot-x86.git
455 455 F: arch/x86/
456 456  
  457 +XTENSA
  458 +M: Max Filippov <jcmvbkbc@gmail.com>
  459 +S: Maintained
  460 +F: arch/xtensa/
  461 +
457 462 THE REST
458 463 M: Tom Rini <trini@konsulko.com>
459 464 L: u-boot@lists.denx.de
... ... @@ -557,6 +557,14 @@
557 557 include/config/auto.conf: ;
558 558 endif # $(dot-config)
559 559  
  560 +#
  561 +# Xtensa linker script cannot be preprocessed with -ansi because of
  562 +# preprocessor operations on strings that don't make C identifiers.
  563 +#
  564 +ifeq ($(CONFIG_XTENSA),)
  565 +LDPPFLAGS += -ansi
  566 +endif
  567 +
560 568 ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
561 569 KBUILD_CFLAGS += -Os
562 570 else
... ... @@ -1312,7 +1320,7 @@
1312 1320  
1313 1321 # ---------------------------------------------------------------------------
1314 1322 quiet_cmd_cpp_lds = LDS $@
1315   -cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
  1323 +cmd_cpp_lds = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) \
1316 1324 -D__ASSEMBLY__ -x assembler-with-cpp -P -o $@ $<
1317 1325  
1318 1326 u-boot.lds: $(LDSCRIPT) prepare FORCE
... ... @@ -524,6 +524,14 @@
524 524 return 0;
525 525 }
526 526  
  527 +#elif defined(CONFIG_XTENSA)
  528 +
  529 +int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  530 +{
  531 + print_std_bdinfo(gd->bd);
  532 + return 0;
  533 +}
  534 +
527 535 #else
528 536 #error "a case for this architecture does not exist!"
529 537 #endif
... ... @@ -54,6 +54,8 @@
54 54 #include <asm/sections.h>
55 55 #if defined(CONFIG_X86) || defined(CONFIG_ARC)
56 56 #include <asm/init_helpers.h>
  57 +#endif
  58 +#if defined(CONFIG_X86) || defined(CONFIG_ARC) || defined(CONFIG_XTENSA)
57 59 #include <asm/relocate.h>
58 60 #endif
59 61 #ifdef CONFIG_SANDBOX
... ... @@ -271,7 +273,8 @@
271 273 gd->mon_len = (ulong)&__bss_end - (ulong)_start;
272 274 #elif defined(CONFIG_SANDBOX) || defined(CONFIG_EFI_APP)
273 275 gd->mon_len = (ulong)&_end - (ulong)_init;
274   -#elif defined(CONFIG_BLACKFIN) || defined(CONFIG_NIOS2)
  276 +#elif defined(CONFIG_BLACKFIN) || defined(CONFIG_NIOS2) || \
  277 + defined(CONFIG_XTENSA)
275 278 gd->mon_len = CONFIG_SYS_MONITOR_LEN;
276 279 #elif defined(CONFIG_NDS32)
277 280 gd->mon_len = (ulong)(&__bss_end) - (ulong)(&_start);
... ... @@ -971,7 +974,7 @@
971 974 * - board info struct
972 975 */
973 976 setup_dest_addr,
974   -#if defined(CONFIG_BLACKFIN)
  977 +#if defined(CONFIG_BLACKFIN) || defined(CONFIG_XTENSA)
975 978 /* Blackfin u-boot monitor should be on top of the ram */
976 979 reserve_uboot,
977 980 #endif
... ... @@ -1003,7 +1006,7 @@
1003 1006 # endif
1004 1007 #endif /* CONFIG_DM_VIDEO */
1005 1008 reserve_trace,
1006   -#if !defined(CONFIG_BLACKFIN)
  1009 +#if !defined(CONFIG_BLACKFIN) && !defined(CONFIG_XTENSA)
1007 1010 reserve_uboot,
1008 1011 #endif
1009 1012 #ifndef CONFIG_SPL_BUILD
... ... @@ -1035,6 +1038,9 @@
1035 1038 copy_uboot_to_ram,
1036 1039 clear_bss,
1037 1040 do_elf_reloc_fixups,
  1041 +#endif
  1042 +#if defined(CONFIG_XTENSA)
  1043 + clear_bss,
1038 1044 #endif
1039 1045 #if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX)
1040 1046 jump_to_copy,
... ... @@ -93,6 +93,7 @@
93 93 { IH_ARCH_ARM64, "arm64", "AArch64", },
94 94 { IH_ARCH_ARC, "arc", "ARC", },
95 95 { IH_ARCH_X86_64, "x86_64", "AMD x86_64", },
  96 + { IH_ARCH_XTENSA, "xtensa", "Xtensa", },
96 97 { -1, "", "", },
97 98 };
98 99  
  1 +U-Boot for the Xtensa Architecture
  2 +==================================
  3 +
  4 +Xtensa Architecture and Diamond Cores
  5 +-------------------------------------
  6 +
  7 +Xtensa is a configurable processor architecture from Tensilica, Inc.
  8 +Diamond Cores are pre-configured instances available for license and
  9 +SoC cores in the same manner as ARM, MIPS, etc.
  10 +
  11 +Xtensa licensees create their own Xtensa cores with selected features
  12 +and custom instructions, registers and co-processors. The custom core
  13 +is configured with Tensilica tools and built with Tensilica's Xtensa
  14 +Processor Generator.
  15 +
  16 +There are an effectively infinite number of CPUs in the Xtensa
  17 +architecture family. It is, however, not feasible to support individual
  18 +Xtensa CPUs in U-Boot. Therefore, there is only a single 'xtensa' CPU
  19 +in the cpu tree of U-Boot.
  20 +
  21 +In the same manner as the Linux port to Xtensa, U-Boot adapts to an
  22 +individual Xtensa core configuration using a set of macros provided with
  23 +the particular core. This is part of what is known as the hardware
  24 +abstraction layer (HAL). For the purpose of U-Boot, the HAL consists only
  25 +of a few header files. These provide CPP macros that customize sources,
  26 +Makefiles, and the linker script.
  27 +
  28 +
  29 +Adding support for an additional processor configuration
  30 +--------------------------------------------------------
  31 +
  32 +The header files for one particular processor configuration are inside
  33 +a variant-specific directory located in the arch/xtensa/include/asm
  34 +directory. The name of that directory starts with 'arch-' followed by
  35 +the name for the processor configuration, for example, arch-dc233c for
  36 +the Diamond DC233 processor.
  37 +
  38 + core.h Definitions for the core itself.
  39 +
  40 +The following files are part of the overlay but not used by U-Boot.
  41 +
  42 + tie.h Co-processors and custom extensions defined
  43 + in the Tensilica Instruction Extension (TIE)
  44 + language.
  45 + tie-asm.h Assembly macros to access custom-defined registers
  46 + and states.
  47 +
  48 +
  49 +Global Data Pointer, Exported Function Stubs, and the ABI
  50 +---------------------------------------------------------
  51 +
  52 +To support standalone applications launched with the "go" command,
  53 +U-Boot provides a jump table of entrypoints to exported functions
  54 +(grep for EXPORT_FUNC). The implementation for Xtensa depends on
  55 +which ABI (or function calling convention) is used.
  56 +
  57 +Windowed ABI presents unique difficulties with the approach based on
  58 +keeping global data pointer in dedicated register. Because the register
  59 +window rotates during a call, there is no register that is constantly
  60 +available for the gd pointer. Therefore, on xtensa gd is a simple
  61 +global variable. Another difficulty arises from the requirement to have
  62 +an 'entry' at the beginning of a function, which rotates the register
  63 +file and reserves a stack frame. This is an integral part of the
  64 +windowed ABI implemented in hardware. It makes using a jump table to an
  65 +arbitrary (separately compiled) function a bit tricky. Use of a simple
  66 +wrapper is also very tedious due to the need to move all possible
  67 +register arguments and adjust the stack to handle arguments that cannot
  68 +be passed in registers. The most efficient approach is to have the jump
  69 +table perform the 'entry' so as to pretend it's the start of the real
  70 +function. This requires decoding the target function's 'entry'
  71 +instruction to determine the stack frame size, and adjusting the stack
  72 +pointer accordingly, then jumping into the target function just after
  73 +the 'entry'. Decoding depends on the processor's endianness so uses the
  74 +HAL. The implementation (12 instructions) is in examples/stubs.c.
  75 +
  76 +
  77 +Access to Invalid Memory Addresses
  78 +----------------------------------
  79 +
  80 +U-Boot does not check if memory addresses given as arguments to commands
  81 +such as "md" are valid. There are two possible types of invalid
  82 +addresses: an area of physical address space may not be mapped to RAM
  83 +or peripherals, or in the presence of MMU an area of virtual address
  84 +space may not be mapped to physical addresses.
  85 +
  86 +Accessing first type of invalid addresses may result in hardware lockup,
  87 +reading of meaningless data, written data being ignored or an exception,
  88 +depending on the CPU wiring to the system. Accessing second type of
  89 +invalid addresses always ends with an exception.
  90 +
  91 +U-Boot for Xtensa provides a special memory exception handler that
  92 +reports such access attempts and resets the board.
  93 +
  94 +
  95 +------------------------------------------------------------------------------
  96 +Chris Zankel
  97 +Ross Morley
examples/standalone/stubs.c
... ... @@ -240,6 +240,53 @@
240 240 " ld r10, [r10, %1]\n" \
241 241 " j [r10]\n" \
242 242 : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r10");
  243 +#elif defined(CONFIG_XTENSA)
  244 +/*
  245 + * Global data ptr is in global_data, jump table ptr is in jt.
  246 + * Windowed ABI: Jump just past 'entry' in target and adjust stack frame
  247 + * (extract stack frame size from target 'entry' instruction).
  248 + */
  249 +
  250 +static void **jt;
  251 +
  252 +#if defined(__XTENSA_CALL0_ABI__)
  253 +#define EXPORT_FUNC(f, a, x, ...) \
  254 + asm volatile ( \
  255 +" .extern jt\n" \
  256 +" .globl " #x "\n" \
  257 +" .align 4\n" \
  258 +#x ":\n" \
  259 +" l32i a8, %0, 0\n" \
  260 +" l32i a8, a8, %1\n" \
  261 +" jx a8\n" \
  262 + : : "r"(jt), "i" (FO(x)) : "a8");
  263 +#elif defined(__XTENSA_WINDOWED_ABI__)
  264 +#if XCHAL_HAVE_BE
  265 +# define SFT "8"
  266 +#else
  267 +# define SFT "12"
  268 +#endif
  269 +#define EXPORT_FUNC(f, a, x, ...) \
  270 + asm volatile ( \
  271 +" .extern jt\n" \
  272 +" .globl " #x "\n" \
  273 +" .align 4\n" \
  274 +#x ":\n" \
  275 +" entry sp, 16\n" \
  276 +" l32i a8, %0, 0\n" \
  277 +" l32i a8, a8, %1\n" \
  278 +" l32i a9, a8, 0\n" \
  279 +" extui a9, a9, " SFT ", 12\n" \
  280 +" subx8 a9, a9, sp\n" \
  281 +" movi a10, 16\n" \
  282 +" sub a9, a10, a9\n" \
  283 +" movsp sp, a9\n" \
  284 +" addi a8, a8, 3\n" \
  285 +" jx a8\n" \
  286 + : : "r"(jt), "i" (FO(x)) : "a8", "a9", "a10");
  287 +#else
  288 +#error Unsupported Xtensa ABI
  289 +#endif
243 290 #else
244 291 /*" addi $sp, $sp, -24\n" \
245 292 " br $r16\n" \*/
... ... @@ -200,6 +200,7 @@
200 200 IH_ARCH_ARM64, /* ARM64 */
201 201 IH_ARCH_ARC, /* Synopsys DesignWare ARC */
202 202 IH_ARCH_X86_64, /* AMD x86_64, Intel and Via */
  203 + IH_ARCH_XTENSA, /* Xtensa */
203 204  
204 205 IH_ARCH_COUNT,
205 206 };
include/linux/stat.h
... ... @@ -126,7 +126,7 @@
126 126  
127 127 #endif /* __MIPS__ */
128 128  
129   -#if defined(__AVR32__) || defined(__SH__)
  129 +#if defined(__AVR32__) || defined(__SH__) || defined(__XTENSA__)
130 130  
131 131 struct stat {
132 132 unsigned long st_dev;
... ... @@ -149,7 +149,7 @@
149 149 unsigned long __unused5;
150 150 };
151 151  
152   -#endif /* __AVR32__ || __SH__ */
  152 +#endif /* __AVR32__ || __SH__ || __XTENSA__ */
153 153  
154 154 #ifdef __cplusplus
155 155 }