From patchwork Wed Jul 31 18:16:26 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregor Haas X-Patchwork-Id: 1967258 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=lkrHlelG; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20230601 header.b=BKIFrWNg; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WZ0g12FS2z20Mw for ; Thu, 1 Aug 2024 04:17:01 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=a0XCOFiv6KRBgsnmV0AAKKwGm+3KtbezpmjBYRLlj8U=; b=lkrHlelGKoSZut U/eoXaUifP2SSgmx6s384BoZaPhws9LdWgI7vzlFXwg+50f2RyiSFkB9vOI0HIKMqzTf0tXOPTHjK LRlBuWt6hmBdrPas1cid5GnI4CLXKTnga9qBjua3wkyAMxpFvrOifwdFPPZyWb6vazVHINsd+SFbW D/XMO+/iCplIeVMs5y6q5/j2w2e3FNmMHHXaZmMy3Af8ZvZcTlmOjvPQYvPFBasVHdj7Gq4zPVQ0J 4WilKCAMn4i7OOicL/j6gTaG+Ku2WOtDFQA30CeCF0izU4SeAO26hVljmnXMN4qW5Gf36pRUi8OuT qt59NRgyKZrAsJNK/Wmw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sZDsa-000000026iV-3zW9; Wed, 31 Jul 2024 18:16:52 +0000 Received: from mail-pf1-x429.google.com ([2607:f8b0:4864:20::429]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sZDsV-000000026dp-2XUt for opensbi@lists.infradead.org; Wed, 31 Jul 2024 18:16:49 +0000 Received: by mail-pf1-x429.google.com with SMTP id d2e1a72fcca58-7104f93a20eso822701b3a.1 for ; Wed, 31 Jul 2024 11:16:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722449806; x=1723054606; darn=lists.infradead.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=vBtMgBOiQv5+IiJxT41dcejGtsH4vQ5/uLTfXQZW0zQ=; b=BKIFrWNgu4hjr1fqzyOWoYvlaRlNnTJlZkEa/i76ajS/HB3yspPFw6CQaAIW0Qy9JE N8PrpKm36I0ywj/ndcikV/7xflL9yTaGtOGbP3asaVcrL2AS1+kBnw5z6a/lo/GFt/e3 brYAIv2Uj8xW4yQA/Eg8MG9n5Nphcei5KqfqgpmG7xX+rEJwTdUo98cqQ8P2E1yELOoA XmK1ZQ1vJJ86wYYOAccGDQOG71Q/HcgDaGBK2Uf71zCqq+Kow6lqT7WXv7p8hN+W7iOW a+8C8oPcXkJ+vLFYRyEeuRCWwnnU1rxlCayF90Zjo8X1/kIs0CS4fzDzO6J3YwEKFDZj f0Eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722449806; x=1723054606; 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=vBtMgBOiQv5+IiJxT41dcejGtsH4vQ5/uLTfXQZW0zQ=; b=hylgm7J+IeD+QiAUVCZ2SY8SMgCItAs1i5FzAC1gLAOxit1W2bCL50JTlmBfDumEEP KJU/JB4zHwgXghwK5VhGgXUDJNCvEmVTpqg/uHwO5UuydtiDxWNdSEvwVMAD60ehzTTW fbhsJ/iVul5btfXktmIbGE3MV1l8PkhOqsZL9OGPg5DRG9q6w1Ca3a3i0iK8lpAAphPB Qg8q1S3ExSYjwG10AYBYC9RQvS/ZAt1ZrkCt8f6O3NnRYKFpQdbvQtOAGsrcIdXzBs4u ap5iobYRjbczVMqTgOZ6c1YLEnfXR4eTBaT0RlpHdm+K2vp2RqC9AtxpQbsvrl3oUZLg mm6Q== X-Gm-Message-State: AOJu0Yz6F4n1bz5pjTrJ9eL4ENWjhRVL15X4Ww1hTiAXHLTWnGgOjxs8 tAG+zj3axhniM9qWx4Xj32+fS0edWzXa5V7b/95e1CL4+RgAV2RdbqViAi9J X-Google-Smtp-Source: AGHT+IEJU397HpjOU69rnZjRtG0Cgs6GwFGCf27QoyWJf5DMcjQQQvMTp7r9DYWAZvtt4zwXM+L4GQ== X-Received: by 2002:a05:6a20:1590:b0:1c4:7d53:bf76 with SMTP id adf61e73a8af0-1c68d0da5c1mr317145637.38.1722449805523; Wed, 31 Jul 2024 11:16:45 -0700 (PDT) Received: from localhost ([136.27.11.53]) by smtp.gmail.com with UTF8SMTPSA id d2e1a72fcca58-70eeb9aa93fsm5136723b3a.190.2024.07.31.11.16.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 31 Jul 2024 11:16:45 -0700 (PDT) From: Gregor Haas To: opensbi@lists.infradead.org Cc: atishp@rivosinc.com, Gregor Haas Subject: [PATCH 5/8] lib: sbi: memregion: Make memregions keep track of raw size rather than order Date: Wed, 31 Jul 2024 11:16:26 -0700 Message-ID: <20240731181629.269898-6-gregorhaas1997@gmail.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240731181629.269898-1-gregorhaas1997@gmail.com> References: <20240731181629.269898-1-gregorhaas1997@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240731_111647_790688_E94B6161 X-CRM114-Status: GOOD ( 28.17 ) X-Spam-Score: -1.8 (-) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: In order to accomodate isolation primitives other than PMP (such as the forthcoming SMMTT implementation), make memregions keep track of their raw size rather than prerounding the size to a power-of-t [...] Content analysis details: (-1.8 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [2607:f8b0:4864:20:0:0:0:429 listed in] [list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit [gregorhaas1997(at)gmail.com] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider [gregorhaas1997(at)gmail.com] X-BeenThere: opensbi@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "opensbi" Errors-To: opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org In order to accomodate isolation primitives other than PMP (such as the forthcoming SMMTT implementation), make memregions keep track of their raw size rather than prerounding the size to a power-of-two order. Not all isolation primitives have the same stringent naturally-aligned power-of-two requirements as PMP, and so we need a layer of abstraction between memregion information as it is discovered (from device trees or otherwise) and isolation information as applied using a specific primitive. This commit lays the groundwork for such an abstraction. --- docs/domain_support.md | 41 +++++++++++++++++++++++++------------ include/sbi/sbi_domain.h | 2 +- include/sbi/sbi_memregion.h | 10 ++++----- lib/sbi/sbi_domain.c | 18 ++++++++-------- lib/sbi/sbi_hart.c | 23 +++++++++++++++------ lib/sbi/sbi_memregion.c | 30 +++++++++++++++++---------- lib/utils/fdt/fdt_domain.c | 29 ++++++++++++++++++-------- lib/utils/fdt/fdt_fixup.c | 10 ++++----- 8 files changed, 102 insertions(+), 61 deletions(-) diff --git a/docs/domain_support.md b/docs/domain_support.md index 91677d3..33bd8d6 100644 --- a/docs/domain_support.md +++ b/docs/domain_support.md @@ -24,10 +24,9 @@ Domain Memory Region A domain memory region is represented by **struct sbi_memregion** in OpenSBI and has following details: -* **order** - The size of a memory region is **2 ^ order** where **order** - must be **3 <= order <= __riscv_xlen** -* **base** - The base address of a memory region is **2 ^ order** - aligned start address +* **size** - The size of a memory region, where the maximum size is encoded + as -1UL. +* **base** - The base address of a memory region. * **flags** - The flags of a memory region represent memory type (i.e. RAM or MMIO) and allowed accesses (i.e. READ, WRITE, EXECUTE, etc.) @@ -56,10 +55,16 @@ has following details: * **system_suspend_allowed** - Is domain allowed to suspend the system? The memory regions represented by **regions** in **struct sbi_domain** have -following additional constraints to align with RISC-V PMP requirements: +following additional constraints: * A memory region to protect OpenSBI firmware from S-mode and U-mode should always be present + +When applying the specific isolation primitive to the domain, there may be +other specific constraints on memory regions. These are listed below. + +To align with RISC-V PMP requirements: + * For two overlapping memory regions, one should be sub-region of another * Two overlapping memory regions should not be of same size * Two overlapping memory regions cannot have same flags @@ -138,17 +143,26 @@ The DT properties of a domain memory region DT node are as follows: * **compatible** (Mandatory) - The compatible string of the domain memory region. This DT property should have value *"opensbi,domain,memregion"* -* **base** (Mandatory) - The base address of the domain memory region. This - DT property should have a **2 ^ order** aligned 64 bit address (i.e. two - DT cells). -* **order** (Mandatory) - The order of the domain memory region. This DT - property should have a 32 bit value (i.e. one DT cell) in the range - **3 <= order <= __riscv_xlen**. +* **base** (Mandatory) - The base address of the domain memory region. If + **order** is specified (see below), this DT property should have a + **2 ^ order** aligned 64 bit address (i.e. two DT cells). Otherwise, if + **size** is specified (see below), this DT property should have a 64 bit + address (i.e. two DT cells). * **mmio** (Optional) - A boolean flag representing whether the domain memory region is a memory-mapped I/O (MMIO) region. * **devices** (Optional) - The list of device DT node phandles for devices which fall under this domain memory region. +Additionally, **one** of the two DT properties **must** be specified: + +* **size** - The size of the domain memory region. This DT property should + have a 64 bit value (i.e. two DT cells). The maximum possible size should + be encoded as `<0xFFFFFFFF 0xFFFFFFFF>`. +* **order** - The order of the domain memory region. This DT property should + have a 32 bit value (i.e. one DT cell) in the range **3 <= order <= __riscv_xlen**. + This property is kept for compatibility purposes; new device trees should + use the **size** property instead. + ### Domain Instance Node The domain instance DT node describes set of possible HARTs, set of memory @@ -237,6 +251,7 @@ be done: opensbi-domains { compatible = "opensbi,domain,config"; + /* Region using "order" property rather than size */ tmem: tmem { compatible = "opensbi,domain,memregion"; base = <0x0 0x80100000>; @@ -246,7 +261,7 @@ be done: tuart: tuart { compatible = "opensbi,domain,memregion"; base = <0x0 0x10011000>; - order = <12>; + size = <0x0 0x1000>; mmio; devices = <&uart1>; }; @@ -254,7 +269,7 @@ be done: allmem: allmem { compatible = "opensbi,domain,memregion"; base = <0x0 0x0>; - order = <64>; + size = <0xFFFFFFFF 0xFFFFFFFF>; }; tdomain: trusted-domain { diff --git a/include/sbi/sbi_domain.h b/include/sbi/sbi_domain.h index a712504..74e3ea9 100644 --- a/include/sbi/sbi_domain.h +++ b/include/sbi/sbi_domain.h @@ -86,7 +86,7 @@ extern struct sbi_domain *domidx_to_domain_table[]; /** Iterate over each memory region of a domain */ #define sbi_domain_for_each_memregion(__d, __r) \ - for ((__r) = (__d)->regions; (__r)->order; (__r)++) + for ((__r) = (__d)->regions; (__r)->size; (__r)++) /** * Check whether given HART is assigned to specified domain diff --git a/include/sbi/sbi_memregion.h b/include/sbi/sbi_memregion.h index 6e1b771..99faba7 100644 --- a/include/sbi/sbi_memregion.h +++ b/include/sbi/sbi_memregion.h @@ -15,13 +15,11 @@ enum sbi_domain_access { /** Representation of OpenSBI domain memory region */ struct sbi_memregion { /** - * Size of memory region as power of 2 - * It has to be minimum 3 and maximum __riscv_xlen + * Size of memory region. The maximum value is encoded as -1UL */ - unsigned long order; + unsigned long size; /** * Base address of memory region - * It must be 2^order aligned address */ unsigned long base; /** Flags representing memory region attributes */ @@ -149,8 +147,8 @@ struct sbi_memregion { ((reg)->base) #define memregion_end(reg) \ - ((reg)->order < __riscv_xlen) ? \ - (reg)->base + ((1UL << (reg)->order) - 1) : -1UL; + (((reg)->size == -1UL) ? -1UL : (reg)->base + (reg)->size - 1) + /** * Initialize a domain memory region based on it's physical * address and size. diff --git a/lib/sbi/sbi_domain.c b/lib/sbi/sbi_domain.c index 22d5d8b..e272d81 100644 --- a/lib/sbi/sbi_domain.c +++ b/lib/sbi/sbi_domain.c @@ -98,7 +98,7 @@ ulong sbi_domain_get_assigned_hartmask(const struct sbi_domain *dom, static int sanitize_domain(struct sbi_domain *dom) { - u32 i, rc; + int i, rc; /* Check possible HARTs */ if (!dom->possible_harts) { @@ -302,7 +302,7 @@ int sbi_domain_root_add_memregion(const struct sbi_memregion *reg) nreg = &root.regions[root_memregs_count]; sbi_memcpy(nreg, reg, sizeof(*reg)); root_memregs_count++; - root.regions[root_memregs_count].order = 0; + root.regions[root_memregs_count].size = 0; /* Sort and optimize root regions */ do { @@ -315,19 +315,17 @@ int sbi_domain_root_add_memregion(const struct sbi_memregion *reg) return rc; } - /* Merge consecutive memregions with same order and flags */ + /* Merge consecutive memregions with same flags */ reg_merged = false; sbi_domain_for_each_memregion(&root, nreg) { nreg1 = nreg + 1; - if (!nreg1->order) + if (!nreg1->size) continue; - if (!(nreg->base & (BIT(nreg->order + 1) - 1)) && - (nreg->base + BIT(nreg->order)) == nreg1->base && - nreg->order == nreg1->order && + if ((nreg->base + nreg->size) == nreg1->base && nreg->flags == nreg1->flags) { - nreg->order++; - while (nreg1->order) { + nreg->size += nreg1->size; + while (nreg1->size) { nreg2 = nreg1 + 1; sbi_memcpy(nreg1, nreg2, sizeof(*nreg1)); nreg1++; @@ -505,7 +503,7 @@ int sbi_domain_init(struct sbi_scratch *scratch, u32 cold_hartid) &root_memregs[root_memregs_count++]); /* Root domain memory region end */ - root_memregs[root_memregs_count].order = 0; + root_memregs[root_memregs_count].size = 0; /* Root domain boot HART id is same as coldboot HART id */ root.boot_hartid = cold_hartid; diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index 4dd1a25..e82045c 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -346,6 +346,11 @@ static unsigned int sbi_hart_get_smepmp_flags(struct sbi_scratch *scratch, return pmp_flags; } +static inline bool pmp_is_power_of_two(unsigned long order, unsigned long size) +{ + return order == __riscv_xlen ? true : BIT(order) == size; +} + static void sbi_hart_smepmp_set(struct sbi_scratch *scratch, struct sbi_domain *dom, struct sbi_memregion *reg, @@ -355,14 +360,16 @@ static void sbi_hart_smepmp_set(struct sbi_scratch *scratch, unsigned long pmp_addr_max) { unsigned long pmp_addr = reg->base >> PMP_SHIFT; + unsigned long order = log2roundup(reg->size); - if (pmp_log2gran <= reg->order && pmp_addr < pmp_addr_max) { - pmp_set(pmp_idx, pmp_flags, reg->base, reg->order); + if (pmp_is_power_of_two(order, reg->size) && + pmp_log2gran <= order && pmp_addr < pmp_addr_max) { + pmp_set(pmp_idx, pmp_flags, reg->base, order); } else { sbi_printf("Can not configure pmp for domain %s because" " memory region address 0x%lx or size 0x%lx " "is not in range.\n", dom->name, reg->base, - reg->order); + reg->size); } } @@ -451,6 +458,7 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch, unsigned int pmp_idx = 0; unsigned int pmp_flags; unsigned long pmp_addr; + unsigned long order; sbi_domain_for_each_memregion(dom, reg) { if (pmp_count <= pmp_idx) @@ -473,13 +481,16 @@ static int sbi_hart_oldpmp_configure(struct sbi_scratch *scratch, pmp_flags |= PMP_X; pmp_addr = reg->base >> PMP_SHIFT; - if (pmp_log2gran <= reg->order && pmp_addr < pmp_addr_max) { - pmp_set(pmp_idx++, pmp_flags, reg->base, reg->order); + order = log2roundup(reg->size); + + if (pmp_is_power_of_two(order, reg->size) && + pmp_log2gran <= order && pmp_addr < pmp_addr_max) { + pmp_set(pmp_idx++, pmp_flags, reg->base, order); } else { sbi_printf("Can not configure pmp for domain %s because" " memory region address 0x%lx or size 0x%lx " "is not in range.\n", dom->name, reg->base, - reg->order); + reg->size); } } diff --git a/lib/sbi/sbi_memregion.c b/lib/sbi/sbi_memregion.c index 8978793..56ee649 100644 --- a/lib/sbi/sbi_memregion.c +++ b/lib/sbi/sbi_memregion.c @@ -28,7 +28,7 @@ void sbi_memregion_init(unsigned long addr, if (reg) { reg->base = base; - reg->order = order; + reg->size = (order == __riscv_xlen) ? -1UL : BIT(order); reg->flags = flags; } } @@ -64,13 +64,14 @@ static bool is_region_compatible(const struct sbi_memregion *regA, /* Check if region complies with constraints */ static bool is_region_valid(const struct sbi_memregion *reg) { - if (reg->order < 3 || __riscv_xlen < reg->order) + unsigned int order = log2roundup(reg->size); + if (order < 3 || __riscv_xlen < order) return false; - if (reg->order == __riscv_xlen && reg->base != 0) + if (order == __riscv_xlen && reg->base != 0) return false; - if (reg->order < __riscv_xlen && (reg->base & (BIT(reg->order) - 1))) + if (order < __riscv_xlen && (reg->base & (BIT(order) - 1))) return false; return true; @@ -80,10 +81,17 @@ static bool is_region_valid(const struct sbi_memregion *reg) static bool is_region_before(const struct sbi_memregion *regA, const struct sbi_memregion *regB) { - if (regA->order < regB->order) + // Sentinel region always goes last + if (!regA->size) + return false; + + if (!regB->size) + return true; + + if (regA->size < regB->size) return true; - if ((regA->order == regB->order) && + if ((regA->size == regB->size) && (regA->base < regB->base)) return true; @@ -121,8 +129,8 @@ int sbi_memregion_sanitize(struct sbi_domain *dom) sbi_domain_for_each_memregion(dom, reg) { if (!is_region_valid(reg)) { sbi_printf("%s: %s has invalid region base=0x%lx " - "order=%lu flags=0x%lx\n", __func__, - dom->name, reg->base, reg->order, + "size=0x%lx flags=0x%lx\n", __func__, + dom->name, reg->base, reg->size, reg->flags); return SBI_EINVAL; } @@ -260,7 +268,7 @@ static const struct sbi_memregion *find_next_subset_region( continue; if (!ret || (sreg->base < ret->base) || - ((sreg->base == ret->base) && (sreg->order < ret->order))) + ((sreg->base == ret->base) && (sreg->size < ret->size))) ret = sreg; } @@ -289,8 +297,8 @@ bool sbi_domain_check_addr_range(const struct sbi_domain *dom, sreg = find_next_subset_region(dom, reg, addr); if (sreg) addr = sreg->base; - else if (reg->order < __riscv_xlen) - addr = reg->base + (1UL << reg->order); + else if (reg->size != -1UL) + addr = reg->base + reg->size; else break; } diff --git a/lib/utils/fdt/fdt_domain.c b/lib/utils/fdt/fdt_domain.c index 779acec..51d9e9d 100644 --- a/lib/utils/fdt/fdt_domain.c +++ b/lib/utils/fdt/fdt_domain.c @@ -233,7 +233,6 @@ static int __fdt_parse_region(void *fdt, int domain_offset, void *opaque) { int len; - u32 val32; u64 val64; const u32 *val; struct parse_region_data *preg = opaque; @@ -264,14 +263,26 @@ static int __fdt_parse_region(void *fdt, int domain_offset, val64 = (val64 << 32) | fdt32_to_cpu(val[1]); region->base = val64; - /* Read "order" DT property */ - val = fdt_getprop(fdt, region_offset, "order", &len); - if (!val || len != 4) - return SBI_EINVAL; - val32 = fdt32_to_cpu(*val); - if (val32 < 3 || __riscv_xlen < val32) - return SBI_EINVAL; - region->order = val32; + /* Read "size" DT property */ + val = fdt_getprop(fdt, region_offset, "size", &len); + if (!val || len != 8) { + // Check for older "order" property + val = fdt_getprop(fdt, region_offset, "order", &len); + if (!val || len != 4) { + return SBI_EINVAL; + } + + val64 = fdt32_to_cpu(*val); + if (val64 < 3 || __riscv_xlen < val64) + return SBI_EINVAL; + + val64 = BIT(val64); + } else { + val64 = ((uint64_t) fdt32_to_cpu(val[0])) << 32; + val64 |= fdt32_to_cpu(val[1]); + } + + region->size = val64; /* Read "mmio" DT property */ region->flags = region_access & SBI_MEMREGION_ACCESS_MASK; diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c index fd45763..20819f9 100644 --- a/lib/utils/fdt/fdt_fixup.c +++ b/lib/utils/fdt/fdt_fixup.c @@ -285,7 +285,7 @@ int fdt_reserved_memory_fixup(void *fdt) struct sbi_memregion *reg; struct sbi_domain *dom = sbi_domain_thishart_ptr(); unsigned long filtered_base[PMP_COUNT] = { 0 }; - unsigned char filtered_order[PMP_COUNT] = { 0 }; + unsigned long filtered_size[PMP_COUNT] = { 0 }; unsigned long addr, size; int err, parent, i, j; int na = fdt_address_cells(fdt, 0); @@ -362,23 +362,23 @@ int fdt_reserved_memory_fixup(void *fdt) addr = reg->base; for (j = 0; j < i; j++) { if (addr == filtered_base[j] - && filtered_order[j] < reg->order) { + && filtered_size[j] < reg->size) { overlap = true; - filtered_order[j] = reg->order; + filtered_size[j] = reg->size; break; } } if (!overlap) { filtered_base[i] = reg->base; - filtered_order[i] = reg->order; + filtered_size[i] = reg->size; i++; } } for (j = 0; j < i; j++) { addr = filtered_base[j]; - size = 1UL << filtered_order[j]; + size = filtered_size[j]; fdt_resv_memory_update_node(fdt, addr, size, j, parent); }