From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 333C8C61DA3 for ; Tue, 21 Feb 2023 22:49:10 +0000 (UTC) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 0195D85A63; Tue, 21 Feb 2023 23:49:08 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (2048-bit key; unprotected) header.d=kernel.org header.i=@kernel.org header.b="unad1Lcx"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 7E98D85A63; Tue, 21 Feb 2023 23:49:06 +0100 (CET) Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id A28FC85A73 for ; Tue, 21 Feb 2023 23:49:02 +0100 (CET) Authentication-Results: phobos.denx.de; dmarc=pass (p=none dis=none) header.from=kernel.org Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=pali@kernel.org Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 202CBB81109 for ; Tue, 21 Feb 2023 22:49:02 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6C854C433EF for ; Tue, 21 Feb 2023 22:49:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1677019740; bh=BKCDneQx+ojdzHCgh5kRTtQ/0qxhsjcws78HP/OwbIU=; h=Resent-From:Resent-Date:Resent-To:From:To:Cc:Subject:Date: In-Reply-To:References:From; b=unad1Lcxk9khOBQDrFhN+7WaTqvJnae5RXTWtW/nmMCjyisX3KUJM/v+5XNYWiJVm mNCVgnQLUXziB0p3Zr5NvXWepTUW00ba8E8FzItZhTPUVIUVgunxsG9WFCB+L4T4m7 Pqt/58gnv7xwS/MXoSxEbKcjwZY6uOod6q99ZgYCmuWykllypJfV0HLgkaIxkjDGCP lahT+KCEcRHTRsb4hPA+bhlJu6PSRdSCnI6kt/ZiNewNV5c6ERyS04zwcQSY+exaqA ffA0UidanFW76YKelfEdLkzNG29rnBB0eRnwGGniIEO+IQtFP8vycA1bobS7RAWedv A7jRmFuHRlxWA== Received: by pali.im (Postfix) id 213FB70C; Tue, 21 Feb 2023 23:48:58 +0100 (CET) Resent-From: Pali =?utf-8?B?Um9ow6Fy?= Resent-Date: Tue, 21 Feb 2023 23:48:58 +0100 Resent-Message-ID: <20230221224858.dkaufgbtzerht5f4@pali> Resent-To: u-boot@lists.denx.de Received: by pali.im (Postfix) id 44954708; Tue, 21 Feb 2023 21:22:35 +0100 (CET) From: =?UTF-8?q?Pali=20Roh=C3=A1r?= To: u-boot@lists.denx.de Cc: Stefan Roese , Tony Dinh , Josua Mayer Subject: [PATCH RFC u-boot-mvebu 46/59] tools: kwbimage: Add support for XIP SPI/NOR images Date: Tue, 21 Feb 2023 21:19:12 +0100 Message-Id: <20230221201925.9644-47-pali@kernel.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20230221201925.9644-1-pali@kernel.org> References: <20230221201925.9644-1-pali@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.6 at phobos.denx.de X-Virus-Status: Clean Marvell BootROM can execute SPI images directly from NOR (either SPI/serial or parallel) without copying them to DDR RAM. This is know at XIP - execute in place. To achieve that, destination address in kwbimage must be set to 0xFFFFFFFF and execute address to the offset in bytes from the beginning of NOR memory. Kirkwood and Dove which use kwbimage v0 format and have SPI address space mapped to physical memory at 0xE8000000-0xEFFFFFFF by BootROM. Armada SoCs use kwbimage v1 format and have SPI address space mapped to physical memory at 0xD4000000-0xD7FFFFFF and Device bus address space (used for parallel NOR) at 0xD8000000-0xDFFFFFFF. Add support for generating XIP kwbimages by mkimage -x flag and mark xflag as valid option in kwbimage.c. Signed-off-by: Pali Rohár --- tools/kwbimage.c | 96 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 7 deletions(-) diff --git a/tools/kwbimage.c b/tools/kwbimage.c index da539541742d..7ebb625d03b9 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -927,6 +927,71 @@ done: return ret; } +static int image_fill_xip_header(void *image, struct image_tool_params *params) +{ + struct main_hdr_v1 *main_hdr = image; /* kwbimage v0 and v1 have same XIP members */ + int version = kwbimage_version(image); + uint32_t srcaddr = le32_to_cpu(main_hdr->srcaddr); + uint32_t startaddr = 0; + + if (main_hdr->blockid != IBR_HDR_SPI_ID) { + fprintf(stderr, "XIP is supported only for SPI images\n"); + return 0; + } + + if (version == 0 && + params->addr >= 0xE8000000 && params->addr < 0xEFFFFFFF && + params->ep >= 0xE8000000 && params->ep < 0xEFFFFFFF) { + /* Load and Execute address is in SPI address space (kwbimage v0) */ + startaddr = 0xE8000000; + } else if (version != 0 && + params->addr >= 0xD4000000 && params->addr < 0xD7FFFFFF && + params->ep >= 0xD4000000 && params->ep < 0xD7FFFFFF) { + /* Load and Execute address is in SPI address space (kwbimage v1) */ + startaddr = 0xD4000000; + } else if (version != 0 && + params->addr >= 0xD8000000 && params->addr < 0xDFFFFFFF && + params->ep >= 0xD8000000 && params->ep < 0xDFFFFFFF) { + /* Load and Execute address is in Device bus space (kwbimage v1) */ + startaddr = 0xD8000000; + } else if (params->addr != 0x0) { + /* Load address is non-zero */ + if (version == 0) + fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI address space\n"); + else + fprintf(stderr, "XIP Load Address or XIP Entry Point is not in SPI nor in Device bus address space\n"); + return 0; + } + + /* + * For XIP destaddr must be set to 0xFFFFFFFF and + * execaddr relative to the start of XIP memory address space. + */ + main_hdr->destaddr = cpu_to_le32(0xFFFFFFFF); + + if (startaddr == 0) { + /* + * mkimage's --load-address 0x0 means that binary is Position + * Independent and in this case mkimage's --entry-point address + * is relative offset from beginning of the data part of image. + */ + main_hdr->execaddr = cpu_to_le32(srcaddr + params->ep); + } else { + /* The lowest possible load address is after the header at srcaddr. */ + if (params->addr - startaddr < srcaddr) { + fprintf(stderr, + "Invalid XIP Load Address 0x%08x.\n" + "The lowest address for this configuration is 0x%08x.\n", + params->addr, (unsigned)(startaddr + srcaddr)); + return 0; + } + main_hdr->srcaddr = cpu_to_le32(params->addr - startaddr); + main_hdr->execaddr = cpu_to_le32(params->ep - startaddr); + } + + return 1; +} + static size_t image_headersz_align(size_t headersz, uint8_t blockid) { /* @@ -1022,6 +1087,14 @@ static void *image_create_v0(size_t *dataoff, struct image_tool_params *params, if (main_hdr->blockid == IBR_HDR_PEX_ID) main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF); + if (params->xflag) { + if (!image_fill_xip_header(main_hdr, params)) { + free(image); + return NULL; + } + *dataoff = le32_to_cpu(main_hdr->srcaddr); + } + /* Generate the ext header */ if (has_ext) { struct ext_hdr_v0 *ext_hdr; @@ -1461,6 +1534,14 @@ static void *image_create_v1(size_t *dataoff, struct image_tool_params *params, if (main_hdr->blockid == IBR_HDR_PEX_ID) main_hdr->srcaddr = cpu_to_le32(0xFFFFFFFF); + if (params->xflag) { + if (!image_fill_xip_header(main_hdr, params)) { + free(image); + return NULL; + } + *dataoff = le32_to_cpu(main_hdr->srcaddr); + } + if (image_get_csk_index() >= 0) { /* * only reserve the space here; we fill the header later since @@ -1915,8 +1996,13 @@ static void kwbimage_print_header(const void *ptr) le32_to_cpu(mhdr->srcaddr) != 1 ? "s" : ""); else genimg_print_size(le32_to_cpu(mhdr->srcaddr)); - printf("Load Address: %08x\n", le32_to_cpu(mhdr->destaddr)); - printf("Entry Point: %08x\n", le32_to_cpu(mhdr->execaddr)); + if (mhdr->blockid == IBR_HDR_SPI_ID && le32_to_cpu(mhdr->destaddr) == 0xFFFFFFFF) { + printf("Load Address: XIP\n"); + printf("Execute Offs: %08x\n", le32_to_cpu(mhdr->execaddr)); + } else { + printf("Load Address: %08x\n", le32_to_cpu(mhdr->destaddr)); + printf("Entry Point: %08x\n", le32_to_cpu(mhdr->execaddr)); + } } static int kwbimage_check_image_types(uint8_t type) @@ -2414,9 +2500,6 @@ static int kwbimage_extract_subimage(void *ptr, struct image_tool_params *params return imagetool_save_subimage(params->outfile, image, size); } -/* - * Report Error if xflag is set in addition to default - */ static int kwbimage_check_params(struct image_tool_params *params) { if (!params->lflag && !params->iflag && !params->pflag && @@ -2429,8 +2512,7 @@ static int kwbimage_check_params(struct image_tool_params *params) return (params->dflag && (params->fflag || params->lflag)) || (params->fflag) || - (params->lflag && (params->dflag || params->fflag)) || - (params->xflag); + (params->lflag && (params->dflag || params->fflag)); } /* -- 2.20.1