From nobody Sun Nov 24 22:07:44 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1722944504; cv=none; d=zohomail.com; s=zohoarc; b=ER1Z4n/8vdyaNfWUgS/9mjyACjaq8LZz/aFvFSxpnuOIJCqWiz1VOm/uF3o3ETHqu0yGxDrqvfWvKBugGV/fca8G7ZVadKCb3McTffPN3lrPvBMj3Ag52pLjsUFHRps3c1jo1ZodOg2Ai841BmmTihiuWFQOB1wMpxnSOttFyCE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1722944504; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ca5ZXo630vry9EjSQxd1/+2PESi5C2mBKEiwPXnd7Q4=; b=YhNg2UqLXuc6oSrh1b1W5+nByUdXClYP4Q6LeNGs6xmPiyAzFTYKY9RnUApXQMm1GcoLivZd2YqQ1YEK3Vav8sLTi5FlFEUZweEX872026vpvyaN8/AR2Snt9E2pVDGg2n7oYm9U9QqpLJjZI2t/xHJ9fwk7SNhsnUHcakwFuTo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1722944503997720.1643189889279; Tue, 6 Aug 2024 04:41:43 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.772828.1183278 (Exim 4.92) (envelope-from ) id 1sbIZB-0006ky-Bi; Tue, 06 Aug 2024 11:41:25 +0000 Received: by outflank-mailman (output) from mailman id 772828.1183278; Tue, 06 Aug 2024 11:41:25 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sbIZB-0006k3-74; Tue, 06 Aug 2024 11:41:25 +0000 Received: by outflank-mailman (input) for mailman id 772828; Tue, 06 Aug 2024 11:41:23 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1sbIZ9-0006hC-9T for xen-devel@lists.xenproject.org; Tue, 06 Aug 2024 11:41:23 +0000 Received: from mail-lf1-x132.google.com (mail-lf1-x132.google.com [2a00:1450:4864:20::132]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id cc29d6f9-53e8-11ef-8776-851b0ebba9a2; Tue, 06 Aug 2024 13:41:19 +0200 (CEST) Received: by mail-lf1-x132.google.com with SMTP id 2adb3069b0e04-52fc4388a64so649655e87.1 for ; Tue, 06 Aug 2024 04:41:19 -0700 (PDT) Received: from fedora.. ([94.75.70.14]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-530bba07891sm1466093e87.22.2024.08.06.04.41.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Aug 2024 04:41:17 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: cc29d6f9-53e8-11ef-8776-851b0ebba9a2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722944479; x=1723549279; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ca5ZXo630vry9EjSQxd1/+2PESi5C2mBKEiwPXnd7Q4=; b=lOxkj29UknKbkCD0as7vrYkyrWOk9LCvtuBguBs81VSqmTbrTS0ZrIvzgJ2bxvvoVI JvPzyoVDn7/eAon7G71xaab4VjlDiSfXtSeQWJlOZoNvLitEbrwT0RfzQIBbzlCEEvdv HchkOBq9LcLpqO0cne+q1i6FQSi3I8z6n1DtxyVD4xyuuqqzFikEnko9HDZB042F5v0M T+6vKsaM0ETM5BZoGsKKAMZ29Kdrz5MNjFNv6yiJHVHd7jl9iSOPiOzTYDMxIcnx8b0B yakrTwWvn29/bFw7OYkF0Auko7cKC3J0UyXib1gfFM9fYaH9zCuC8tAbpeAbvGCvdnUF UJhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722944479; x=1723549279; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ca5ZXo630vry9EjSQxd1/+2PESi5C2mBKEiwPXnd7Q4=; b=GZ+pFJgoH7CZ9kttKYA4M4hE0X0hnUFYiOvSVbttr6hnYPgeAztOhTmz393gctp3So pY86CCUyEWtJLyj3c5uoD9mDlGisiZcCtR33U75d5tr4Vl1TSiShcssAwSY80zbDU2x6 qjVR9on9ZiExfLxGTatU+C4bmbRJw3iDUDvrzYs88JL/YamWrScmEs5YFYBcF86yyPE1 HA3lNdZ1dk3uBo/lxRmyGdMIt0dUMun5oRL/+yfjHXk5Ym+3KCqbCh3YFRzmeM1nrZ8v io31Ln0XPKK1AV6Au+qm8d6ujiXsLwtZoEjiarv7DAQhQob5eQDAcDewLwD0Rr8UsTqE laWA== X-Gm-Message-State: AOJu0Yy62oDuTx+1ncwD5yylKnkDyHcjrppYAGYxV8f1Pqcmr6ME1T5L /enA6mDnOOebuCDv+7PXL7pFFhPJBi2ySUesZJIkpDcE3cPp64y0JvRqpQ== X-Google-Smtp-Source: AGHT+IFJY9zq4dtupWct6NBDBLTwQTe0g/6ZfEO9g2HxfPf6u6Sczcg2h9NZ5YJFlv1Bsv4qtQaZoQ== X-Received: by 2002:a05:6512:308c:b0:52e:fdeb:9381 with SMTP id 2adb3069b0e04-530bb39b806mr10179422e87.43.1722944478093; Tue, 06 Aug 2024 04:41:18 -0700 (PDT) From: Oleksii Kurochko To: xen-devel@lists.xenproject.org Cc: Shawn Anastasio , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini , Bertrand Marquis , Michal Orzel , Volodymyr Babchuk , "Daniel P. Smith" , Oleksii Kurochko , Julien Grall Subject: [PATCH v2 1/2] xen/device-tree: Move Arm's setup.c bootinfo functions to common Date: Tue, 6 Aug 2024 13:41:13 +0200 Message-ID: <811f6e0001e7a83ea9282a98513407aa19d26256.1722941799.git.oleksii.kurochko@gmail.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1722944505861116600 Content-Type: text/plain; charset="utf-8" From: Shawn Anastasio Arm's setup.c contains a collection of functions for parsing memory map and other boot information from a device tree. Since these routines are generally useful on any architecture that supports device tree booting, move them into xen/common/device-tree. Also, common/device_tree.c has been moved to the device-tree folder with the corresponding updates to common/Makefile and common/device-tree/Makefil= e. Mentioning of arm32 is changed to CONFIG_SEPARATE_XENHEAP in comparison with original ARM's code as now it is moved in common code. Suggested-by: Julien Grall Signed-off-by: Shawn Anastasio Signed-off-by: Oleksii Kurochko Acked-by: Julien Grall --- Changes in V9: - rename xen/common/device_tree.c to xen/common/device-tree.c - update MAINTAINERS file: drop xen/common/device_tree.c from it. --- Changes in V8: - add the version of Xen from which bootinfo.c was derived from. - update the commit message. - add Acked-by: Julien Grall . --- Changes in V7: - move obj-$(CONFIG_HAS_DEVICE_TREE) +=3D device-tree/ to proper place in = common/Makefile. - rename macros __XEN_BOOTFDT_H__ to XEN_BOOTFDT_H to not violate MISRA ru= le 21.1. - drop definition of "#define MAX_FDT_SIZE SZ_2M" in xen/bootfdt.h as it i= s expected to be arch-specific. Back "#define MAX_FDT_SIZE SZ_2M" to arm/setup.h where= it was before these changes. - git mv xen/common/device_tree.c xen/common/device-tree/ and update corre= spondingly Makefiles of common/ and common/device-tree - update the commit message --- Changes in V6: - update the version of the patch to v6. =20 --- Changes in V5: - After rebase the Shawn's patch v4 on top of current staging the following was done: - add xen/include/xen/bootfdt.h to MAINTAINERS file. - drop message "Early device tree parsing and". - After rebase on top of the current staging the following changes were = done: - init bootinfo variable in with BOOTI= NFO_INIT; - update the code of dt_unreserved_regions(): CONFIG_STATIC_SHM related changes and getting of reserved_mem bootinfo_get_shmem() - update the code of meminfo_overlap_check(): add check ( INVALID_PADDR =3D=3D bank_start ) to if case. - update the code of check_reserved_regions_overlap(): CONFIG_STATIC_SHM related changes. - struct bootinfo was updated ( CONFIG_STATIC_SHM changes ) - add shared_meminfo ( because of CONFIG_STATIC_SHM ) - struct struct membanks was update with __struct group so is neeeded to be included in bootfdt.h - move BOOTINFO_ACPI_INIT, BOOTINFO_SHMEM_INIT, BOOTINFO_INIT to gener= ic bootfdt.h - bootinfo_get_reserved_mem(), bootinfo_get_mem(), bootinfo_get_acpi(), bootinfo_get_shmem() and bootinfo_get_shmem_extra() were moved to xe= n/bootfdt.h - s/arm32/CONFIG_SEPARATE_XENHEAP/ - add inclusion of because there are function in which are using container_of(). --- Changes in v4: - create new xen/include/bootinfo.h rather than relying on arch's asm/setup.h to provide required definitions for bootinfo.c - build bootinfo.c as .init.o - clean up and sort bootinfo.c's #includes - use CONFIG_SEPARATE_XENHEAP rather than CONFIG_ARM_32 to guard xenheap-specific behavior of populate_boot_allocator - (MAINTAINERS) include all of common/device-tree rather than just bootinfo.c --- MAINTAINERS | 3 +- xen/arch/arm/include/asm/setup.h | 185 +------ xen/arch/arm/setup.c | 432 ----------------- xen/common/Makefile | 2 +- xen/common/device-tree/Makefile | 2 + xen/common/device-tree/bootinfo.c | 459 ++++++++++++++++++ .../device-tree.c} | 0 xen/include/xen/bootfdt.h | 195 ++++++++ 8 files changed, 660 insertions(+), 618 deletions(-) create mode 100644 xen/common/device-tree/Makefile create mode 100644 xen/common/device-tree/bootinfo.c rename xen/common/{device_tree.c =3D> device-tree/device-tree.c} (100%) create mode 100644 xen/include/xen/bootfdt.h diff --git a/MAINTAINERS b/MAINTAINERS index 7c524a8a93..89be48fdf9 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -291,9 +291,10 @@ M: Bertrand Marquis M: Michal Orzel S: Supported F: xen/common/libfdt/ -F: xen/common/device_tree.c +F: xen/common/device-tree/ F: xen/common/dt-overlay.c F: xen/include/xen/libfdt/ +F: xen/include/xen/bootfdt.h F: xen/include/xen/device_tree.h F: xen/drivers/passthrough/device_tree.c =20 diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/se= tup.h index c34179da93..1748be29e5 100644 --- a/xen/arch/arm/include/asm/setup.h +++ b/xen/arch/arm/include/asm/setup.h @@ -3,159 +3,11 @@ =20 #include #include +#include #include =20 -#define MIN_FDT_ALIGN 8 #define MAX_FDT_SIZE SZ_2M =20 -#define NR_MEM_BANKS 256 -#define NR_SHMEM_BANKS 32 - -#define MAX_MODULES 32 /* Current maximum useful modules */ - -typedef enum { - BOOTMOD_XEN, - BOOTMOD_FDT, - BOOTMOD_KERNEL, - BOOTMOD_RAMDISK, - BOOTMOD_XSM, - BOOTMOD_GUEST_DTB, - BOOTMOD_UNKNOWN -} bootmodule_kind; - -enum membank_type { - /* - * The MEMBANK_DEFAULT type refers to either reserved memory for the - * device/firmware (when the bank is in 'reserved_mem') or any RAM (wh= en - * the bank is in 'mem'). - */ - MEMBANK_DEFAULT, - /* - * The MEMBANK_STATIC_DOMAIN type is used to indicate whether the memo= ry - * bank is bound to a static Xen domain. It is only valid when the bank - * is in reserved_mem. - */ - MEMBANK_STATIC_DOMAIN, - /* - * The MEMBANK_STATIC_HEAP type is used to indicate whether the memory - * bank is reserved as static heap. It is only valid when the bank is - * in reserved_mem. - */ - MEMBANK_STATIC_HEAP, - /* - * The MEMBANK_FDT_RESVMEM type is used to indicate whether the memory - * bank is from the FDT reserve map. - */ - MEMBANK_FDT_RESVMEM, -}; - -/* Indicates the maximum number of characters(\0 included) for shm_id */ -#define MAX_SHM_ID_LENGTH 16 - -struct shmem_membank_extra { - char shm_id[MAX_SHM_ID_LENGTH]; - unsigned int nr_shm_borrowers; -}; - -struct membank { - paddr_t start; - paddr_t size; - union { - enum membank_type type; -#ifdef CONFIG_STATIC_SHM - struct shmem_membank_extra *shmem_extra; -#endif - }; -}; - -struct membanks { - __struct_group(membanks_hdr, common, , - unsigned int nr_banks; - unsigned int max_banks; - ); - struct membank bank[]; -}; - -struct meminfo { - struct membanks_hdr common; - struct membank bank[NR_MEM_BANKS]; -}; - -struct shared_meminfo { - struct membanks_hdr common; - struct membank bank[NR_SHMEM_BANKS]; - struct shmem_membank_extra extra[NR_SHMEM_BANKS]; -}; - -/* - * The domU flag is set for kernels and ramdisks of "xen,domain" nodes. - * The purpose of the domU flag is to avoid getting confused in - * kernel_probe, where we try to guess which is the dom0 kernel and - * initrd to be compatible with all versions of the multiboot spec.=20 - */ -#define BOOTMOD_MAX_CMDLINE 1024 -struct bootmodule { - bootmodule_kind kind; - bool domU; - paddr_t start; - paddr_t size; -}; - -/* DT_MAX_NAME is the node name max length according the DT spec */ -#define DT_MAX_NAME 41 -struct bootcmdline { - bootmodule_kind kind; - bool domU; - paddr_t start; - char dt_name[DT_MAX_NAME]; - char cmdline[BOOTMOD_MAX_CMDLINE]; -}; - -struct bootmodules { - int nr_mods; - struct bootmodule module[MAX_MODULES]; -}; - -struct bootcmdlines { - unsigned int nr_mods; - struct bootcmdline cmdline[MAX_MODULES]; -}; - -struct bootinfo { - struct meminfo mem; - /* The reserved regions are only used when booting using Device-Tree */ - struct meminfo reserved_mem; - struct bootmodules modules; - struct bootcmdlines cmdlines; -#ifdef CONFIG_ACPI - struct meminfo acpi; -#endif -#ifdef CONFIG_STATIC_SHM - struct shared_meminfo shmem; -#endif - bool static_heap; -}; - -#ifdef CONFIG_ACPI -#define BOOTINFO_ACPI_INIT .acpi.common.max_banks =3D NR_MEM_BANKS, -#else -#define BOOTINFO_ACPI_INIT -#endif - -#ifdef CONFIG_STATIC_SHM -#define BOOTINFO_SHMEM_INIT .shmem.common.max_banks =3D NR_SHMEM_BANKS, -#else -#define BOOTINFO_SHMEM_INIT -#endif - -#define BOOTINFO_INIT \ -{ \ - .mem.common.max_banks =3D NR_MEM_BANKS, \ - .reserved_mem.common.max_banks =3D NR_MEM_BANKS, \ - BOOTINFO_ACPI_INIT \ - BOOTINFO_SHMEM_INIT \ -} - struct map_range_data { struct domain *d; @@ -167,39 +19,8 @@ struct map_range_data struct rangeset *irq_ranges; }; =20 -extern struct bootinfo bootinfo; - extern domid_t max_init_domid; =20 -static inline struct membanks *bootinfo_get_mem(void) -{ - return container_of(&bootinfo.mem.common, struct membanks, common); -} - -static inline struct membanks *bootinfo_get_reserved_mem(void) -{ - return container_of(&bootinfo.reserved_mem.common, struct membanks, co= mmon); -} - -#ifdef CONFIG_ACPI -static inline struct membanks *bootinfo_get_acpi(void) -{ - return container_of(&bootinfo.acpi.common, struct membanks, common); -} -#endif - -#ifdef CONFIG_STATIC_SHM -static inline struct membanks *bootinfo_get_shmem(void) -{ - return container_of(&bootinfo.shmem.common, struct membanks, common); -} - -static inline struct shmem_membank_extra *bootinfo_get_shmem_extra(void) -{ - return bootinfo.shmem.extra; -} -#endif - void copy_from_paddr(void *dst, paddr_t paddr, unsigned long len); =20 size_t estimate_efi_size(unsigned int mem_nr_banks); @@ -220,9 +41,6 @@ void fw_unreserved_regions(paddr_t s, paddr_t e, void (*cb)(paddr_t ps, paddr_t pe), unsigned int first); =20 -size_t boot_fdt_info(const void *fdt, paddr_t paddr); -const char *boot_fdt_cmdline(const void *fdt); - bool check_reserved_regions_overlap(paddr_t region_start, paddr_t region_s= ize); =20 struct bootmodule *add_boot_module(bootmodule_kind kind, @@ -237,7 +55,6 @@ struct bootcmdline * boot_cmdline_find_by_name(const cha= r *name); const char *boot_module_kind_as_string(bootmodule_kind kind); =20 void init_pdx(void); -void populate_boot_allocator(void); void setup_mm(void); =20 extern uint32_t hyp_traps_vector[]; diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 0c2fdaceaf..cb2c0a16b8 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -48,8 +48,6 @@ #include #include =20 -struct bootinfo __initdata bootinfo =3D BOOTINFO_INIT; - /* * Sanitized version of cpuinfo containing only features available on all * cores (only on arm64 as there is no sanitization support on arm32). @@ -203,321 +201,6 @@ static void __init processor_id(void) processor_setup(); } =20 -static void __init dt_unreserved_regions(paddr_t s, paddr_t e, - void (*cb)(paddr_t ps, paddr_t pe= ), - unsigned int first) -{ - const struct membanks *reserved_mem =3D bootinfo_get_reserved_mem(); -#ifdef CONFIG_STATIC_SHM - const struct membanks *shmem =3D bootinfo_get_shmem(); - unsigned int offset; -#endif - unsigned int i; - - /* - * i is the current bootmodule we are evaluating across all possible - * kinds. - */ - for ( i =3D first; i < reserved_mem->nr_banks; i++ ) - { - paddr_t r_s =3D reserved_mem->bank[i].start; - paddr_t r_e =3D r_s + reserved_mem->bank[i].size; - - if ( s < r_e && r_s < e ) - { - dt_unreserved_regions(r_e, e, cb, i + 1); - dt_unreserved_regions(s, r_s, cb, i + 1); - return; - } - } - -#ifdef CONFIG_STATIC_SHM - /* - * When retrieving the corresponding shared memory addresses - * below, we need to index the shmem->bank starting from 0, hence - * we need to use i - reserved_mem->nr_banks. - */ - offset =3D reserved_mem->nr_banks; - for ( ; i - offset < shmem->nr_banks; i++ ) - { - paddr_t r_s, r_e; - - r_s =3D shmem->bank[i - offset].start; - - /* Shared memory banks can contain INVALID_PADDR as start */ - if ( INVALID_PADDR =3D=3D r_s ) - continue; - - r_e =3D r_s + shmem->bank[i - offset].size; - - if ( s < r_e && r_s < e ) - { - dt_unreserved_regions(r_e, e, cb, i + 1); - dt_unreserved_regions(s, r_s, cb, i + 1); - return; - } - } -#endif - - cb(s, e); -} - -/* - * TODO: '*_end' could be 0 if the bank/region is at the end of the physic= al - * address space. This is for now not handled as it requires more rework. - */ -static bool __init meminfo_overlap_check(const struct membanks *mem, - paddr_t region_start, - paddr_t region_size) -{ - paddr_t bank_start =3D INVALID_PADDR, bank_end =3D 0; - paddr_t region_end =3D region_start + region_size; - unsigned int i, bank_num =3D mem->nr_banks; - - for ( i =3D 0; i < bank_num; i++ ) - { - bank_start =3D mem->bank[i].start; - bank_end =3D bank_start + mem->bank[i].size; - - if ( INVALID_PADDR =3D=3D bank_start || region_end <=3D bank_start= || - region_start >=3D bank_end ) - continue; - else - { - printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with = bank[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", - region_start, region_end, i, bank_start, bank_end); - return true; - } - } - - return false; -} - -/* - * TODO: '*_end' could be 0 if the module/region is at the end of the phys= ical - * address space. This is for now not handled as it requires more rework. - */ -static bool __init bootmodules_overlap_check(struct bootmodules *bootmodul= es, - paddr_t region_start, - paddr_t region_size) -{ - paddr_t mod_start =3D INVALID_PADDR, mod_end =3D 0; - paddr_t region_end =3D region_start + region_size; - unsigned int i, mod_num =3D bootmodules->nr_mods; - - for ( i =3D 0; i < mod_num; i++ ) - { - mod_start =3D bootmodules->module[i].start; - mod_end =3D mod_start + bootmodules->module[i].size; - - if ( region_end <=3D mod_start || region_start >=3D mod_end ) - continue; - else - { - printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with = mod[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", - region_start, region_end, i, mod_start, mod_end); - return true; - } - } - - return false; -} - -void __init fw_unreserved_regions(paddr_t s, paddr_t e, - void (*cb)(paddr_t ps, paddr_t pe), - unsigned int first) -{ - if ( acpi_disabled ) - dt_unreserved_regions(s, e, cb, first); - else - cb(s, e); -} - -/* - * Given an input physical address range, check if this range is overlappi= ng - * with the existing reserved memory regions defined in bootinfo. - * Return true if the input physical address range is overlapping with any - * existing reserved memory regions, otherwise false. - */ -bool __init check_reserved_regions_overlap(paddr_t region_start, - paddr_t region_size) -{ - const struct membanks *mem_banks[] =3D { - bootinfo_get_reserved_mem(), -#ifdef CONFIG_ACPI - bootinfo_get_acpi(), -#endif -#ifdef CONFIG_STATIC_SHM - bootinfo_get_shmem(), -#endif - }; - unsigned int i; - - /* - * Check if input region is overlapping with reserved memory banks or - * ACPI EfiACPIReclaimMemory (when ACPI feature is enabled) or static - * shared memory banks (when static shared memory feature is enabled) - */ - for ( i =3D 0; i < ARRAY_SIZE(mem_banks); i++ ) - if ( meminfo_overlap_check(mem_banks[i], region_start, region_size= ) ) - return true; - - /* Check if input region is overlapping with bootmodules */ - if ( bootmodules_overlap_check(&bootinfo.modules, - region_start, region_size) ) - return true; - - return false; -} - -struct bootmodule __init *add_boot_module(bootmodule_kind kind, - paddr_t start, paddr_t size, - bool domU) -{ - struct bootmodules *mods =3D &bootinfo.modules; - struct bootmodule *mod; - unsigned int i; - - if ( mods->nr_mods =3D=3D MAX_MODULES ) - { - printk("Ignoring %s boot module at %"PRIpaddr"-%"PRIpaddr" (too ma= ny)\n", - boot_module_kind_as_string(kind), start, start + size); - return NULL; - } - - if ( check_reserved_regions_overlap(start, size) ) - return NULL; - - for ( i =3D 0 ; i < mods->nr_mods ; i++ ) - { - mod =3D &mods->module[i]; - if ( mod->kind =3D=3D kind && mod->start =3D=3D start ) - { - if ( !domU ) - mod->domU =3D false; - return mod; - } - } - - mod =3D &mods->module[mods->nr_mods++]; - mod->kind =3D kind; - mod->start =3D start; - mod->size =3D size; - mod->domU =3D domU; - - return mod; -} - -/* - * boot_module_find_by_kind can only be used to return Xen modules (e.g - * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest - * modules. - */ -struct bootmodule * __init boot_module_find_by_kind(bootmodule_kind kind) -{ - struct bootmodules *mods =3D &bootinfo.modules; - struct bootmodule *mod; - int i; - for (i =3D 0 ; i < mods->nr_mods ; i++ ) - { - mod =3D &mods->module[i]; - if ( mod->kind =3D=3D kind && !mod->domU ) - return mod; - } - return NULL; -} - -void __init add_boot_cmdline(const char *name, const char *cmdline, - bootmodule_kind kind, paddr_t start, bool dom= U) -{ - struct bootcmdlines *cmds =3D &bootinfo.cmdlines; - struct bootcmdline *cmd; - - if ( cmds->nr_mods =3D=3D MAX_MODULES ) - { - printk("Ignoring %s cmdline (too many)\n", name); - return; - } - - cmd =3D &cmds->cmdline[cmds->nr_mods++]; - cmd->kind =3D kind; - cmd->domU =3D domU; - cmd->start =3D start; - - ASSERT(strlen(name) <=3D DT_MAX_NAME); - safe_strcpy(cmd->dt_name, name); - - if ( strlen(cmdline) > BOOTMOD_MAX_CMDLINE ) - panic("module %s command line too long\n", name); - safe_strcpy(cmd->cmdline, cmdline); -} - -/* - * boot_cmdline_find_by_kind can only be used to return Xen modules (e.g - * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest - * modules. - */ -struct bootcmdline * __init boot_cmdline_find_by_kind(bootmodule_kind kind) -{ - struct bootcmdlines *cmds =3D &bootinfo.cmdlines; - struct bootcmdline *cmd; - int i; - - for ( i =3D 0 ; i < cmds->nr_mods ; i++ ) - { - cmd =3D &cmds->cmdline[i]; - if ( cmd->kind =3D=3D kind && !cmd->domU ) - return cmd; - } - return NULL; -} - -struct bootcmdline * __init boot_cmdline_find_by_name(const char *name) -{ - struct bootcmdlines *mods =3D &bootinfo.cmdlines; - struct bootcmdline *mod; - unsigned int i; - - for (i =3D 0 ; i < mods->nr_mods ; i++ ) - { - mod =3D &mods->cmdline[i]; - if ( strcmp(mod->dt_name, name) =3D=3D 0 ) - return mod; - } - return NULL; -} - -struct bootmodule * __init boot_module_find_by_addr_and_kind(bootmodule_ki= nd kind, - paddr_t start) -{ - struct bootmodules *mods =3D &bootinfo.modules; - struct bootmodule *mod; - unsigned int i; - - for (i =3D 0 ; i < mods->nr_mods ; i++ ) - { - mod =3D &mods->module[i]; - if ( mod->kind =3D=3D kind && mod->start =3D=3D start ) - return mod; - } - return NULL; -} - -const char * __init boot_module_kind_as_string(bootmodule_kind kind) -{ - switch ( kind ) - { - case BOOTMOD_XEN: return "Xen"; - case BOOTMOD_FDT: return "Device Tree"; - case BOOTMOD_KERNEL: return "Kernel"; - case BOOTMOD_RAMDISK: return "Ramdisk"; - case BOOTMOD_XSM: return "XSM"; - case BOOTMOD_GUEST_DTB: return "DTB"; - case BOOTMOD_UNKNOWN: return "Unknown"; - default: BUG(); - } -} - void __init discard_initial_modules(void) { struct bootmodules *mi =3D &bootinfo.modules; @@ -556,40 +239,6 @@ static void * __init relocate_fdt(paddr_t dtb_paddr, s= ize_t dtb_size) return fdt; } =20 -/* - * Return the end of the non-module region starting at s. In other - * words return s the start of the next modules after s. - * - * On input *end is the end of the region which should be considered - * and it is updated to reflect the end of the module, clipped to the - * end of the region if it would run over. - */ -static paddr_t __init next_module(paddr_t s, paddr_t *end) -{ - struct bootmodules *mi =3D &bootinfo.modules; - paddr_t lowest =3D ~(paddr_t)0; - int i; - - for ( i =3D 0; i < mi->nr_mods; i++ ) - { - paddr_t mod_s =3D mi->module[i].start; - paddr_t mod_e =3D mod_s + mi->module[i].size; - - if ( !mi->module[i].size ) - continue; - - if ( mod_s < s ) - continue; - if ( mod_s > lowest ) - continue; - if ( mod_s > *end ) - continue; - lowest =3D mod_s; - *end =3D min(*end, mod_e); - } - return lowest; -} - void __init init_pdx(void) { const struct membanks *mem =3D bootinfo_get_mem(); @@ -635,87 +284,6 @@ void __init init_pdx(void) } } =20 -/* - * Populate the boot allocator. - * If a static heap was not provided by the admin, all the RAM but the - * following regions will be added: - * - Modules (e.g., Xen, Kernel) - * - Reserved regions - * - Xenheap (arm32 only) - * If a static heap was provided by the admin, populate the boot - * allocator with the corresponding regions only, but with Xenheap excluded - * on arm32. - */ -void __init populate_boot_allocator(void) -{ - unsigned int i; - const struct membanks *banks =3D bootinfo_get_mem(); - const struct membanks *reserved_mem =3D bootinfo_get_reserved_mem(); - paddr_t s, e; - - if ( bootinfo.static_heap ) - { - for ( i =3D 0 ; i < reserved_mem->nr_banks; i++ ) - { - if ( reserved_mem->bank[i].type !=3D MEMBANK_STATIC_HEAP ) - continue; - - s =3D reserved_mem->bank[i].start; - e =3D s + reserved_mem->bank[i].size; -#ifdef CONFIG_ARM_32 - /* Avoid the xenheap, note that the xenheap cannot across a ba= nk */ - if ( s <=3D mfn_to_maddr(directmap_mfn_start) && - e >=3D mfn_to_maddr(directmap_mfn_end) ) - { - init_boot_pages(s, mfn_to_maddr(directmap_mfn_start)); - init_boot_pages(mfn_to_maddr(directmap_mfn_end), e); - } - else -#endif - init_boot_pages(s, e); - } - - return; - } - - for ( i =3D 0; i < banks->nr_banks; i++ ) - { - const struct membank *bank =3D &banks->bank[i]; - paddr_t bank_end =3D bank->start + bank->size; - - s =3D bank->start; - while ( s < bank_end ) - { - paddr_t n =3D bank_end; - - e =3D next_module(s, &n); - - if ( e =3D=3D ~(paddr_t)0 ) - e =3D n =3D bank_end; - - /* - * Module in a RAM bank other than the one which we are - * not dealing with here. - */ - if ( e > bank_end ) - e =3D bank_end; - -#ifdef CONFIG_ARM_32 - /* Avoid the xenheap */ - if ( s < mfn_to_maddr(directmap_mfn_end) && - mfn_to_maddr(directmap_mfn_start) < e ) - { - e =3D mfn_to_maddr(directmap_mfn_start); - n =3D mfn_to_maddr(directmap_mfn_end); - } -#endif - - fw_unreserved_regions(s, e, init_boot_pages, 0); - s =3D n; - } - } -} - size_t __read_mostly dcache_line_bytes; =20 /* C entry point for boot CPU */ diff --git a/xen/common/Makefile b/xen/common/Makefile index f12a474d40..7e66802a9e 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_HYPFS_CONFIG) +=3D config_data.o obj-$(CONFIG_CORE_PARKING) +=3D core_parking.o obj-y +=3D cpu.o obj-$(CONFIG_DEBUG_TRACE) +=3D debugtrace.o -obj-$(CONFIG_HAS_DEVICE_TREE) +=3D device_tree.o +obj-$(CONFIG_HAS_DEVICE_TREE) +=3D device-tree/ obj-$(CONFIG_IOREQ_SERVER) +=3D dm.o obj-y +=3D domain.o obj-$(CONFIG_OVERLAY_DTB) +=3D dt-overlay.o diff --git a/xen/common/device-tree/Makefile b/xen/common/device-tree/Makef= ile new file mode 100644 index 0000000000..f813f7555f --- /dev/null +++ b/xen/common/device-tree/Makefile @@ -0,0 +1,2 @@ +obj-y +=3D bootinfo.init.o +obj-y +=3D device-tree.o diff --git a/xen/common/device-tree/bootinfo.c b/xen/common/device-tree/boo= tinfo.c new file mode 100644 index 0000000000..f2e6a1145b --- /dev/null +++ b/xen/common/device-tree/bootinfo.c @@ -0,0 +1,459 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Derived from Xen 4.19's $xen/arch/arm/setup.c. + * + * bookkeeping routines. + * + * Tim Deegan + * Copyright (c) 2011 Citrix Systems. + * Copyright (c) 2024 Raptor Engineering LLC + */ + +#include +#include +#include +#include +#include +#include +#include + +struct bootinfo __initdata bootinfo =3D BOOTINFO_INIT; + +const char * __init boot_module_kind_as_string(bootmodule_kind kind) +{ + switch ( kind ) + { + case BOOTMOD_XEN: return "Xen"; + case BOOTMOD_FDT: return "Device Tree"; + case BOOTMOD_KERNEL: return "Kernel"; + case BOOTMOD_RAMDISK: return "Ramdisk"; + case BOOTMOD_XSM: return "XSM"; + case BOOTMOD_GUEST_DTB: return "DTB"; + case BOOTMOD_UNKNOWN: return "Unknown"; + default: BUG(); + } +} + +static void __init dt_unreserved_regions(paddr_t s, paddr_t e, + void (*cb)(paddr_t ps, paddr_t pe= ), + unsigned int first) +{ + const struct membanks *reserved_mem =3D bootinfo_get_reserved_mem(); +#ifdef CONFIG_STATIC_SHM + const struct membanks *shmem =3D bootinfo_get_shmem(); + unsigned int offset; +#endif + unsigned int i; + + /* + * i is the current bootmodule we are evaluating across all possible + * kinds. + */ + for ( i =3D first; i < reserved_mem->nr_banks; i++ ) + { + paddr_t r_s =3D reserved_mem->bank[i].start; + paddr_t r_e =3D r_s + reserved_mem->bank[i].size; + + if ( s < r_e && r_s < e ) + { + dt_unreserved_regions(r_e, e, cb, i + 1); + dt_unreserved_regions(s, r_s, cb, i + 1); + return; + } + } + +#ifdef CONFIG_STATIC_SHM + /* + * When retrieving the corresponding shared memory addresses + * below, we need to index the shmem->bank starting from 0, hence + * we need to use i - reserved_mem->nr_banks. + */ + offset =3D reserved_mem->nr_banks; + for ( ; i - offset < shmem->nr_banks; i++ ) + { + paddr_t r_s, r_e; + + r_s =3D shmem->bank[i - offset].start; + + /* Shared memory banks can contain INVALID_PADDR as start */ + if ( INVALID_PADDR =3D=3D r_s ) + continue; + + r_e =3D r_s + shmem->bank[i - offset].size; + + if ( s < r_e && r_s < e ) + { + dt_unreserved_regions(r_e, e, cb, i + 1); + dt_unreserved_regions(s, r_s, cb, i + 1); + return; + } + } +#endif + + cb(s, e); +} + +/* + * TODO: '*_end' could be 0 if the bank/region is at the end of the physic= al + * address space. This is for now not handled as it requires more rework. + */ +static bool __init meminfo_overlap_check(const struct membanks *mem, + paddr_t region_start, + paddr_t region_size) +{ + paddr_t bank_start =3D INVALID_PADDR, bank_end =3D 0; + paddr_t region_end =3D region_start + region_size; + unsigned int i, bank_num =3D mem->nr_banks; + + for ( i =3D 0; i < bank_num; i++ ) + { + bank_start =3D mem->bank[i].start; + bank_end =3D bank_start + mem->bank[i].size; + + if ( INVALID_PADDR =3D=3D bank_start || region_end <=3D bank_start= || + region_start >=3D bank_end ) + continue; + else + { + printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with = bank[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", + region_start, region_end, i, bank_start, bank_end); + return true; + } + } + + return false; +} + +/* + * TODO: '*_end' could be 0 if the module/region is at the end of the phys= ical + * address space. This is for now not handled as it requires more rework. + */ +static bool __init bootmodules_overlap_check(struct bootmodules *bootmodul= es, + paddr_t region_start, + paddr_t region_size) +{ + paddr_t mod_start =3D INVALID_PADDR, mod_end =3D 0; + paddr_t region_end =3D region_start + region_size; + unsigned int i, mod_num =3D bootmodules->nr_mods; + + for ( i =3D 0; i < mod_num; i++ ) + { + mod_start =3D bootmodules->module[i].start; + mod_end =3D mod_start + bootmodules->module[i].size; + + if ( region_end <=3D mod_start || region_start >=3D mod_end ) + continue; + else + { + printk("Region: [%#"PRIpaddr", %#"PRIpaddr") overlapping with = mod[%u]: [%#"PRIpaddr", %#"PRIpaddr")\n", + region_start, region_end, i, mod_start, mod_end); + return true; + } + } + + return false; +} + +void __init fw_unreserved_regions(paddr_t s, paddr_t e, + void (*cb)(paddr_t ps, paddr_t pe), + unsigned int first) +{ + if ( acpi_disabled ) + dt_unreserved_regions(s, e, cb, first); + else + cb(s, e); +} + +/* + * Given an input physical address range, check if this range is overlappi= ng + * with the existing reserved memory regions defined in bootinfo. + * Return true if the input physical address range is overlapping with any + * existing reserved memory regions, otherwise false. + */ +bool __init check_reserved_regions_overlap(paddr_t region_start, + paddr_t region_size) +{ + const struct membanks *mem_banks[] =3D { + bootinfo_get_reserved_mem(), +#ifdef CONFIG_ACPI + bootinfo_get_acpi(), +#endif +#ifdef CONFIG_STATIC_SHM + bootinfo_get_shmem(), +#endif + }; + unsigned int i; + + /* + * Check if input region is overlapping with reserved memory banks or + * ACPI EfiACPIReclaimMemory (when ACPI feature is enabled) or static + * shared memory banks (when static shared memory feature is enabled) + */ + for ( i =3D 0; i < ARRAY_SIZE(mem_banks); i++ ) + if ( meminfo_overlap_check(mem_banks[i], region_start, region_size= ) ) + return true; + + /* Check if input region is overlapping with bootmodules */ + if ( bootmodules_overlap_check(&bootinfo.modules, + region_start, region_size) ) + return true; + + return false; +} + +struct bootmodule __init *add_boot_module(bootmodule_kind kind, + paddr_t start, paddr_t size, + bool domU) +{ + struct bootmodules *mods =3D &bootinfo.modules; + struct bootmodule *mod; + unsigned int i; + + if ( mods->nr_mods =3D=3D MAX_MODULES ) + { + printk("Ignoring %s boot module at %"PRIpaddr"-%"PRIpaddr" (too ma= ny)\n", + boot_module_kind_as_string(kind), start, start + size); + return NULL; + } + + if ( check_reserved_regions_overlap(start, size) ) + return NULL; + + for ( i =3D 0 ; i < mods->nr_mods ; i++ ) + { + mod =3D &mods->module[i]; + if ( mod->kind =3D=3D kind && mod->start =3D=3D start ) + { + if ( !domU ) + mod->domU =3D false; + return mod; + } + } + + mod =3D &mods->module[mods->nr_mods++]; + mod->kind =3D kind; + mod->start =3D start; + mod->size =3D size; + mod->domU =3D domU; + + return mod; +} + +/* + * boot_module_find_by_kind can only be used to return Xen modules (e.g + * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest + * modules. + */ +struct bootmodule * __init boot_module_find_by_kind(bootmodule_kind kind) +{ + struct bootmodules *mods =3D &bootinfo.modules; + struct bootmodule *mod; + int i; + for (i =3D 0 ; i < mods->nr_mods ; i++ ) + { + mod =3D &mods->module[i]; + if ( mod->kind =3D=3D kind && !mod->domU ) + return mod; + } + return NULL; +} + +void __init add_boot_cmdline(const char *name, const char *cmdline, + bootmodule_kind kind, paddr_t start, bool dom= U) +{ + struct bootcmdlines *cmds =3D &bootinfo.cmdlines; + struct bootcmdline *cmd; + + if ( cmds->nr_mods =3D=3D MAX_MODULES ) + { + printk("Ignoring %s cmdline (too many)\n", name); + return; + } + + cmd =3D &cmds->cmdline[cmds->nr_mods++]; + cmd->kind =3D kind; + cmd->domU =3D domU; + cmd->start =3D start; + + ASSERT(strlen(name) <=3D DT_MAX_NAME); + safe_strcpy(cmd->dt_name, name); + + if ( strlen(cmdline) > BOOTMOD_MAX_CMDLINE ) + panic("module %s command line too long\n", name); + safe_strcpy(cmd->cmdline, cmdline); +} + +/* + * boot_cmdline_find_by_kind can only be used to return Xen modules (e.g + * XSM, DTB) or Dom0 modules. This is not suitable for looking up guest + * modules. + */ +struct bootcmdline * __init boot_cmdline_find_by_kind(bootmodule_kind kind) +{ + struct bootcmdlines *cmds =3D &bootinfo.cmdlines; + struct bootcmdline *cmd; + int i; + + for ( i =3D 0 ; i < cmds->nr_mods ; i++ ) + { + cmd =3D &cmds->cmdline[i]; + if ( cmd->kind =3D=3D kind && !cmd->domU ) + return cmd; + } + return NULL; +} + +struct bootcmdline * __init boot_cmdline_find_by_name(const char *name) +{ + struct bootcmdlines *mods =3D &bootinfo.cmdlines; + struct bootcmdline *mod; + unsigned int i; + + for (i =3D 0 ; i < mods->nr_mods ; i++ ) + { + mod =3D &mods->cmdline[i]; + if ( strcmp(mod->dt_name, name) =3D=3D 0 ) + return mod; + } + return NULL; +} + +struct bootmodule * __init boot_module_find_by_addr_and_kind(bootmodule_ki= nd kind, + paddr_t start) +{ + struct bootmodules *mods =3D &bootinfo.modules; + struct bootmodule *mod; + unsigned int i; + + for (i =3D 0 ; i < mods->nr_mods ; i++ ) + { + mod =3D &mods->module[i]; + if ( mod->kind =3D=3D kind && mod->start =3D=3D start ) + return mod; + } + return NULL; +} + +/* + * Return the end of the non-module region starting at s. In other + * words return s the start of the next modules after s. + * + * On input *end is the end of the region which should be considered + * and it is updated to reflect the end of the module, clipped to the + * end of the region if it would run over. + */ +static paddr_t __init next_module(paddr_t s, paddr_t *end) +{ + struct bootmodules *mi =3D &bootinfo.modules; + paddr_t lowest =3D ~(paddr_t)0; + int i; + + for ( i =3D 0; i < mi->nr_mods; i++ ) + { + paddr_t mod_s =3D mi->module[i].start; + paddr_t mod_e =3D mod_s + mi->module[i].size; + + if ( !mi->module[i].size ) + continue; + + if ( mod_s < s ) + continue; + if ( mod_s > lowest ) + continue; + if ( mod_s > *end ) + continue; + lowest =3D mod_s; + *end =3D min(*end, mod_e); + } + return lowest; +} + +/* + * Populate the boot allocator. + * If a static heap was not provided by the admin, all the RAM but the + * following regions will be added: + * - Modules (e.g., Xen, Kernel) + * - Reserved regions + * - Xenheap (CONFIG_SEPARATE_XENHEAP only) + * If a static heap was provided by the admin, populate the boot + * allocator with the corresponding regions only, but with Xenheap excluded + * on CONFIG_SEPARATE_XENHEAP. + */ +void __init populate_boot_allocator(void) +{ + unsigned int i; + const struct membanks *banks =3D bootinfo_get_mem(); + const struct membanks *reserved_mem =3D bootinfo_get_reserved_mem(); + paddr_t s, e; + + if ( bootinfo.static_heap ) + { + for ( i =3D 0 ; i < reserved_mem->nr_banks; i++ ) + { + if ( reserved_mem->bank[i].type !=3D MEMBANK_STATIC_HEAP ) + continue; + + s =3D reserved_mem->bank[i].start; + e =3D s + reserved_mem->bank[i].size; +#ifdef CONFIG_SEPARATE_XENHEAP + /* Avoid the xenheap, note that the xenheap cannot across a ba= nk */ + if ( s <=3D mfn_to_maddr(directmap_mfn_start) && + e >=3D mfn_to_maddr(directmap_mfn_end) ) + { + init_boot_pages(s, mfn_to_maddr(directmap_mfn_start)); + init_boot_pages(mfn_to_maddr(directmap_mfn_end), e); + } + else +#endif + init_boot_pages(s, e); + } + + return; + } + + for ( i =3D 0; i < banks->nr_banks; i++ ) + { + const struct membank *bank =3D &banks->bank[i]; + paddr_t bank_end =3D bank->start + bank->size; + + s =3D bank->start; + while ( s < bank_end ) + { + paddr_t n =3D bank_end; + + e =3D next_module(s, &n); + + if ( e =3D=3D ~(paddr_t)0 ) + e =3D n =3D bank_end; + + /* + * Module in a RAM bank other than the one which we are + * not dealing with here. + */ + if ( e > bank_end ) + e =3D bank_end; + +#ifdef CONFIG_SEPARATE_XENHEAP + /* Avoid the xenheap */ + if ( s < mfn_to_maddr(directmap_mfn_end) && + mfn_to_maddr(directmap_mfn_start) < e ) + { + e =3D mfn_to_maddr(directmap_mfn_start); + n =3D mfn_to_maddr(directmap_mfn_end); + } +#endif + + fw_unreserved_regions(s, e, init_boot_pages, 0); + s =3D n; + } + } +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/device_tree.c b/xen/common/device-tree/device-tree.c similarity index 100% rename from xen/common/device_tree.c rename to xen/common/device-tree/device-tree.c diff --git a/xen/include/xen/bootfdt.h b/xen/include/xen/bootfdt.h new file mode 100644 index 0000000000..c39428d5f5 --- /dev/null +++ b/xen/include/xen/bootfdt.h @@ -0,0 +1,195 @@ +#ifndef XEN_BOOTFDT_H +#define XEN_BOOTFDT_H + +#include +#include +#include + +#define MIN_FDT_ALIGN 8 + +#define NR_MEM_BANKS 256 +#define NR_SHMEM_BANKS 32 + +#define MAX_MODULES 32 /* Current maximum useful modules */ + +typedef enum { + BOOTMOD_XEN, + BOOTMOD_FDT, + BOOTMOD_KERNEL, + BOOTMOD_RAMDISK, + BOOTMOD_XSM, + BOOTMOD_GUEST_DTB, + BOOTMOD_UNKNOWN +} bootmodule_kind; + +enum membank_type { + /* + * The MEMBANK_DEFAULT type refers to either reserved memory for the + * device/firmware (when the bank is in 'reserved_mem') or any RAM (wh= en + * the bank is in 'mem'). + */ + MEMBANK_DEFAULT, + /* + * The MEMBANK_STATIC_DOMAIN type is used to indicate whether the memo= ry + * bank is bound to a static Xen domain. It is only valid when the bank + * is in reserved_mem. + */ + MEMBANK_STATIC_DOMAIN, + /* + * The MEMBANK_STATIC_HEAP type is used to indicate whether the memory + * bank is reserved as static heap. It is only valid when the bank is + * in reserved_mem. + */ + MEMBANK_STATIC_HEAP, + /* + * The MEMBANK_FDT_RESVMEM type is used to indicate whether the memory + * bank is from the FDT reserve map. + */ + MEMBANK_FDT_RESVMEM, +}; + +/* Indicates the maximum number of characters(\0 included) for shm_id */ +#define MAX_SHM_ID_LENGTH 16 + +struct shmem_membank_extra { + char shm_id[MAX_SHM_ID_LENGTH]; + unsigned int nr_shm_borrowers; +}; + +struct membank { + paddr_t start; + paddr_t size; + union { + enum membank_type type; +#ifdef CONFIG_STATIC_SHM + struct shmem_membank_extra *shmem_extra; +#endif + }; +}; + +struct membanks { + __struct_group(membanks_hdr, common, , + unsigned int nr_banks; + unsigned int max_banks; + ); + struct membank bank[]; +}; + +struct meminfo { + struct membanks_hdr common; + struct membank bank[NR_MEM_BANKS]; +}; + +struct shared_meminfo { + struct membanks_hdr common; + struct membank bank[NR_SHMEM_BANKS]; + struct shmem_membank_extra extra[NR_SHMEM_BANKS]; +}; + +/* + * The domU flag is set for kernels and ramdisks of "xen,domain" nodes. + * The purpose of the domU flag is to avoid getting confused in + * kernel_probe, where we try to guess which is the dom0 kernel and + * initrd to be compatible with all versions of the multiboot spec. + */ +#define BOOTMOD_MAX_CMDLINE 1024 +struct bootmodule { + bootmodule_kind kind; + bool domU; + paddr_t start; + paddr_t size; +}; + +/* DT_MAX_NAME is the node name max length according the DT spec */ +#define DT_MAX_NAME 41 +struct bootcmdline { + bootmodule_kind kind; + bool domU; + paddr_t start; + char dt_name[DT_MAX_NAME]; + char cmdline[BOOTMOD_MAX_CMDLINE]; +}; + +struct bootmodules { + int nr_mods; + struct bootmodule module[MAX_MODULES]; +}; + +struct bootcmdlines { + unsigned int nr_mods; + struct bootcmdline cmdline[MAX_MODULES]; +}; + +struct bootinfo { + struct meminfo mem; + /* The reserved regions are only used when booting using Device-Tree */ + struct meminfo reserved_mem; + struct bootmodules modules; + struct bootcmdlines cmdlines; +#ifdef CONFIG_ACPI + struct meminfo acpi; +#endif +#ifdef CONFIG_STATIC_SHM + struct shared_meminfo shmem; +#endif + bool static_heap; +}; + +#ifdef CONFIG_ACPI +#define BOOTINFO_ACPI_INIT .acpi.common.max_banks =3D NR_MEM_BANKS, +#else +#define BOOTINFO_ACPI_INIT +#endif + +#ifdef CONFIG_STATIC_SHM +#define BOOTINFO_SHMEM_INIT .shmem.common.max_banks =3D NR_SHMEM_BANKS, +#else +#define BOOTINFO_SHMEM_INIT +#endif + +#define BOOTINFO_INIT \ +{ \ + .mem.common.max_banks =3D NR_MEM_BANKS, \ + .reserved_mem.common.max_banks =3D NR_MEM_BANKS, \ + BOOTINFO_ACPI_INIT \ + BOOTINFO_SHMEM_INIT \ +} + +extern struct bootinfo bootinfo; + +void populate_boot_allocator(void); + +size_t boot_fdt_info(const void *fdt, paddr_t paddr); + +const char *boot_fdt_cmdline(const void *fdt); + +static inline struct membanks *bootinfo_get_reserved_mem(void) +{ + return container_of(&bootinfo.reserved_mem.common, struct membanks, co= mmon); +} + +static inline struct membanks *bootinfo_get_mem(void) +{ + return container_of(&bootinfo.mem.common, struct membanks, common); +} + +#ifdef CONFIG_ACPI +static inline struct membanks *bootinfo_get_acpi(void) +{ + return container_of(&bootinfo.acpi.common, struct membanks, common); +} +#endif + +#ifdef CONFIG_STATIC_SHM +static inline struct membanks *bootinfo_get_shmem(void) +{ + return container_of(&bootinfo.shmem.common, struct membanks, common); +} + +static inline struct shmem_membank_extra *bootinfo_get_shmem_extra(void) +{ + return bootinfo.shmem.extra; +} +#endif + +#endif /* XEN_BOOTFDT_H */ --=20 2.45.2