From patchwork Wed Aug 20 17:42:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Filippov X-Patchwork-Id: 381803 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id 0E912140093 for ; Thu, 21 Aug 2014 07:02:40 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 706DFA747E; Wed, 20 Aug 2014 23:02:21 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kTWlV5055NQl; Wed, 20 Aug 2014 23:02:21 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 33777A74B8; Wed, 20 Aug 2014 23:00:44 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 7719FA73E5 for ; Wed, 20 Aug 2014 19:50:17 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fhrgy5GE7vzG for ; Wed, 20 Aug 2014 19:50:14 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-la0-f47.google.com (mail-la0-f47.google.com [209.85.215.47]) by theia.denx.de (Postfix) with ESMTPS id 9DB05A73E2 for ; Wed, 20 Aug 2014 19:50:10 +0200 (CEST) Received: by mail-la0-f47.google.com with SMTP id mc6so7472072lab.6 for ; Wed, 20 Aug 2014 10:50:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=sj3aCNVFgPLbJGfVcJUMvfGnEJ+/526NFbfPDZ9UEAo=; b=IwIxNRJ6lFIQZ0xO3ZzAnjaxVK32OfaINQUmib5qdzJFw4PMpHvqOztadeLepBsSUV af0vW1TOmS4WWEdagx5Vh6e6CsMzHUo8MrzglRxjEAUKyzIjpdHx4XcTKPTsduIcQBti 4DbTNYE3iEwA6YEeUHN/Ue3B+T8Lw4kb2sb3RM2VB/oWI4oQMHe2/m9s1XU4m0AhhE/J A/jfmVeFpd8SlP8U4faBWZHGxCgDuRazhd7ZbUJWJtcLM8XBoneHhRRs3LALRoIsqzbA osooZcYoHdP85SDcEtkW+lDRQXnommbMAmhFuUV4ok0SI2d+fsMnPq7T1Dbv9+PzNoM1 thcg== X-Received: by 10.152.87.97 with SMTP id w1mr4231943laz.92.1408556565448; Wed, 20 Aug 2014 10:42:45 -0700 (PDT) Received: from octofox.metropolis ([5.18.160.9]) by mx.google.com with ESMTPSA id b6sm1182296laa.21.2014.08.20.10.42.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 20 Aug 2014 10:42:44 -0700 (PDT) From: Max Filippov To: u-boot@lists.denx.de Date: Wed, 20 Aug 2014 21:42:10 +0400 Message-Id: <1408556533-22433-6-git-send-email-jcmvbkbc@gmail.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1408556533-22433-1-git-send-email-jcmvbkbc@gmail.com> References: <1408556533-22433-1-git-send-email-jcmvbkbc@gmail.com> X-Mailman-Approved-At: Wed, 20 Aug 2014 23:00:32 +0200 Cc: Tom Rini , Marc Gauthier Subject: [U-Boot] [PATCH 5/8] xtensa: add support for the xtensa processor architecture [1/2] X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Chris Zankel 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 Signed-off-by: Max Filippov --- 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 }