From patchwork Wed Nov 28 23:33:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kim Phillips X-Patchwork-Id: 202573 X-Patchwork-Delegate: vanbaren@cideas.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 3582D2C00D6 for ; Thu, 29 Nov 2012 10:36:10 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A8C4C4A0C5; Thu, 29 Nov 2012 00:36:07 +0100 (CET) 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 cngxU4dFj3Ga; Thu, 29 Nov 2012 00:36:07 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 065644A0AE; Thu, 29 Nov 2012 00:36:00 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 4836C4A0AE for ; Thu, 29 Nov 2012 00:35:57 +0100 (CET) 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 5pGWbK7z9-H0 for ; Thu, 29 Nov 2012 00:35:56 +0100 (CET) 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 am1outboundpool.messaging.microsoft.com (am1ehsobe004.messaging.microsoft.com [213.199.154.207]) by theia.denx.de (Postfix) with ESMTPS id 1D3584A0A9 for ; Thu, 29 Nov 2012 00:35:54 +0100 (CET) Received: from mail92-am1-R.bigfish.com (10.3.201.242) by AM1EHSOBE003.bigfish.com (10.3.204.23) with Microsoft SMTP Server id 14.1.225.23; Wed, 28 Nov 2012 23:35:53 +0000 Received: from mail92-am1 (localhost [127.0.0.1]) by mail92-am1-R.bigfish.com (Postfix) with ESMTP id C769A2A01B2; Wed, 28 Nov 2012 23:35:52 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1de0h1202h1d1ah1d2ahzz8275bhz2dh2a8h668h839h944hd24he5bhf0ah1220h1288h12a5h12a9h12bdh137ah139eh13b6h1441h1504h1537h162dh1631h1155h) Received: from mail92-am1 (localhost.localdomain [127.0.0.1]) by mail92-am1 (MessageSwitch) id 1354145751704647_19266; Wed, 28 Nov 2012 23:35:51 +0000 (UTC) Received: from AM1EHSMHS006.bigfish.com (unknown [10.3.201.240]) by mail92-am1.bigfish.com (Postfix) with ESMTP id 9F8064C01BE; Wed, 28 Nov 2012 23:35:51 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by AM1EHSMHS006.bigfish.com (10.3.207.106) with Microsoft SMTP Server (TLS) id 14.1.225.23; Wed, 28 Nov 2012 23:35:48 +0000 Received: from tx30smr01.am.freescale.net (10.81.153.31) by 039-SN1MMR1-005.039d.mgd.msft.net (10.84.1.17) with Microsoft SMTP Server (TLS) id 14.2.318.3; Wed, 28 Nov 2012 23:35:46 +0000 Received: from x9.am.freescale.net (x9.am.freescale.net [10.82.120.9]) by tx30smr01.am.freescale.net (8.14.3/8.14.0) with SMTP id qASNZOhJ001713; Wed, 28 Nov 2012 16:35:34 -0700 Date: Wed, 28 Nov 2012 17:33:01 -0600 From: Kim Phillips To: David Gibson Message-ID: <20121128173301.2b52b22a39fe6c3ce5a088fb@freescale.com> In-Reply-To: <20121119023039.GK5735@truffula.fritz.box> References: <1352941199-19393-1-git-send-email-kim.phillips@freescale.com> <1352941199-19393-3-git-send-email-kim.phillips@freescale.com> <20121115044340.GI32290@truffula.fritz.box> <20121114231204.8f19082c7acc1cea2a2d794f@freescale.com> <20121119023039.GK5735@truffula.fritz.box> Organization: Freescale Semiconductor, Inc. X-Mailer: Sylpheed 3.2.0 (GTK+ 2.24.13; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-OriginatorOrg: freescale.com Cc: u-boot@lists.denx.de, jdl@jdl.com, devicetree-discuss@lists.ozlabs.org Subject: Re: [U-Boot] [PATCH v4 3/4] dtc/libfdt: introduce fdt types for annotation by endian checkers 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: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Projects such as linux and u-boot run sparse on libfdt. libfdt contains the notion of endianness via usage of endian conversion functions such as fdt32_to_cpu. As such, in order to pass endian checks, libfdt has to annotate its fdt variables such that sparse can warn when mixing bitwise and regular integers. This patch adds these new fdtXX_t types and, ifdef __CHECKER__ (a symbol sparse defines), includes the bitwise annotation. Signed-off-by: Kim Phillips Acked-by: David Gibson --- v2: adds bitwise awareness: determine host endianness manually, and annotate swabs with __force in fdtXX_to_cpu and cpu_to_fdtXX conversion functions (the inline endian condition checks are optimized out at compile time). This allows us to be able to check libfdt bitwise conversions with sparse by building dtc with make CC=cgcc. v2 also moves fdt32 definitions from fdt.h to libfdt_env.h and changes fdt32 definitions to use __bitwise instead of __be32. No separate _FDT_SPARSE was introduced because there's no need: using __CHECKER__ directly is valid because it only occurs once, and in libfdt_env.h. In addition, the libfdt sparse fixes have been moved to a subsequent patch. v3: address comments from jdl: o single set of fdt typedefs, since __bitwise is not defined if !CHECKER o re-work EXTRACT_BYTE to take 'x' as a parameter, not a global o SWAB function macros converted to take lowercase 'x' as a parameter, not a global v4: address comments from David Gibson o rename byte swap routines CPU_TO_FDTXX o properly define fdt<->cpu conversion routines to use CPU_TO_FDTXX macros with correct checker attributions. libfdt/fdt.h | 42 +++++++++++++++++++++--------------------- libfdt/libfdt_env.h | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/libfdt/fdt.h b/libfdt/fdt.h index 48ccfd9..45dd134 100644 --- a/libfdt/fdt.h +++ b/libfdt/fdt.h @@ -4,45 +4,45 @@ #ifndef __ASSEMBLY__ struct fdt_header { - uint32_t magic; /* magic word FDT_MAGIC */ - uint32_t totalsize; /* total size of DT block */ - uint32_t off_dt_struct; /* offset to structure */ - uint32_t off_dt_strings; /* offset to strings */ - uint32_t off_mem_rsvmap; /* offset to memory reserve map */ - uint32_t version; /* format version */ - uint32_t last_comp_version; /* last compatible version */ + fdt32_t magic; /* magic word FDT_MAGIC */ + fdt32_t totalsize; /* total size of DT block */ + fdt32_t off_dt_struct; /* offset to structure */ + fdt32_t off_dt_strings; /* offset to strings */ + fdt32_t off_mem_rsvmap; /* offset to memory reserve map */ + fdt32_t version; /* format version */ + fdt32_t last_comp_version; /* last compatible version */ /* version 2 fields below */ - uint32_t boot_cpuid_phys; /* Which physical CPU id we're + fdt32_t boot_cpuid_phys; /* Which physical CPU id we're booting on */ /* version 3 fields below */ - uint32_t size_dt_strings; /* size of the strings block */ + fdt32_t size_dt_strings; /* size of the strings block */ /* version 17 fields below */ - uint32_t size_dt_struct; /* size of the structure block */ + fdt32_t size_dt_struct; /* size of the structure block */ }; struct fdt_reserve_entry { - uint64_t address; - uint64_t size; + fdt64_t address; + fdt64_t size; }; struct fdt_node_header { - uint32_t tag; + fdt32_t tag; char name[0]; }; struct fdt_property { - uint32_t tag; - uint32_t len; - uint32_t nameoff; + fdt32_t tag; + fdt32_t len; + fdt32_t nameoff; char data[0]; }; #endif /* !__ASSEMBLY */ #define FDT_MAGIC 0xd00dfeed /* 4: version, 4: total size */ -#define FDT_TAGSIZE sizeof(uint32_t) +#define FDT_TAGSIZE sizeof(fdt32_t) #define FDT_BEGIN_NODE 0x1 /* Start node: full name */ #define FDT_END_NODE 0x2 /* End node */ @@ -51,10 +51,10 @@ struct fdt_property { #define FDT_NOP 0x4 /* nop */ #define FDT_END 0x9 -#define FDT_V1_SIZE (7*sizeof(uint32_t)) -#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(uint32_t)) -#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(uint32_t)) +#define FDT_V1_SIZE (7*sizeof(fdt32_t)) +#define FDT_V2_SIZE (FDT_V1_SIZE + sizeof(fdt32_t)) +#define FDT_V3_SIZE (FDT_V2_SIZE + sizeof(fdt32_t)) #define FDT_V16_SIZE FDT_V3_SIZE -#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(uint32_t)) +#define FDT_V17_SIZE (FDT_V16_SIZE + sizeof(fdt32_t)) #endif /* _FDT_H */ diff --git a/libfdt/libfdt_env.h b/libfdt/libfdt_env.h index 213d7fb..956b4ae 100644 --- a/libfdt/libfdt_env.h +++ b/libfdt/libfdt_env.h @@ -5,25 +5,56 @@ #include #include -#define EXTRACT_BYTE(n) ((unsigned long long)((uint8_t *)&x)[n]) -static inline uint16_t fdt16_to_cpu(uint16_t x) +#ifdef __CHECKER__ +#define __force __attribute__((force)) +#define __bitwise __attribute__((bitwise)) +#else +#define __force +#define __bitwise +#endif + +typedef uint16_t __bitwise fdt16_t; +typedef uint32_t __bitwise fdt32_t; +typedef uint64_t __bitwise fdt64_t; + +#define EXTRACT_BYTE(x, n) ((unsigned long long)((uint8_t *)&x)[n]) +#define CPU_TO_FDT16(x) ((EXTRACT_BYTE(x, 0) << 8) | EXTRACT_BYTE(x, 1)) +#define CPU_TO_FDT32(x) ((EXTRACT_BYTE(x, 0) << 24) | (EXTRACT_BYTE(x, 1) << 16) | \ + (EXTRACT_BYTE(x, 2) << 8) | EXTRACT_BYTE(x, 3)) +#define CPU_TO_FDT64(x) ((EXTRACT_BYTE(x, 0) << 56) | (EXTRACT_BYTE(x, 1) << 48) | \ + (EXTRACT_BYTE(x, 2) << 40) | (EXTRACT_BYTE(x, 3) << 32) | \ + (EXTRACT_BYTE(x, 4) << 24) | (EXTRACT_BYTE(x, 5) << 16) | \ + (EXTRACT_BYTE(x, 6) << 8) | EXTRACT_BYTE(x, 7)) + +static inline uint16_t fdt16_to_cpu(fdt16_t x) +{ + return (__force uint16_t)CPU_TO_FDT16(x); +} +static inline fdt16_t cpu_to_fdt16(uint16_t x) { - return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1); + return (__force fdt16_t)CPU_TO_FDT16(x); } -#define cpu_to_fdt16(x) fdt16_to_cpu(x) -static inline uint32_t fdt32_to_cpu(uint32_t x) +static inline uint32_t fdt32_to_cpu(fdt32_t x) { - return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3); + return (__force uint32_t)CPU_TO_FDT32(x); +} +static inline fdt32_t cpu_to_fdt32(uint32_t x) +{ + return (__force fdt32_t)CPU_TO_FDT32(x); } -#define cpu_to_fdt32(x) fdt32_to_cpu(x) -static inline uint64_t fdt64_to_cpu(uint64_t x) +static inline uint64_t fdt64_to_cpu(fdt64_t x) +{ + return (__force uint64_t)CPU_TO_FDT64(x); +} +static inline fdt64_t cpu_to_fdt64(uint64_t x) { - return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32) - | (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7); + return (__force fdt64_t)CPU_TO_FDT64(x); } -#define cpu_to_fdt64(x) fdt64_to_cpu(x) +#undef CPU_TO_FDT64 +#undef CPU_TO_FDT32 +#undef CPU_TO_FDT16 #undef EXTRACT_BYTE #endif /* _LIBFDT_ENV_H */