[edk2-devel] [PATCH 38/79] Move OpenSbiPlatformLib to RISC-V/PlatformPkg
Abner Chang
abner.chang at hpe.com
Sat Jan 8 04:10:58 UTC 2022
(This is migrated from edk2-platforms)
It's a generic platform file. Only the device tree decides what happens.
Cc: Daniel Schaefer <daniel.schaefer at hpe.com>
Cc: Abner Chang <abner.chang at hpe.com>
Cc: Sunil V L <sunilvl at ventanamicro.com>
Reviewed-by: Abner Chang <abner.chang at hpe.com>
Signed-off-by: Daniel Schaefer <daniel.schaefer at hpe.com>
---
.../OpensbiPlatformLib/OpensbiPlatformLib.inf | 56 +++++
.../OpensbiPlatformLib/PlatformOverride.h | 30 +++
.../Library/OpensbiPlatformLib/Platform.c | 224 ++++++++++++++++++
.../Library/OpensbiPlatformLib/SifiveFu540.c | 47 ++++
4 files changed, 357 insertions(+)
create mode 100644 Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf
create mode 100644 Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/PlatformOverride.h
create mode 100644 Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c
create mode 100644 Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/SifiveFu540.c
diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf
new file mode 100644
index 0000000000..f9f2073a5b
--- /dev/null
+++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf
@@ -0,0 +1,56 @@
+## @file
+# RISC-V OpenSBI Platform Library
+# This is the the library which provides platform
+# level opensbi functions follow RISC-V OpenSBI implementation.
+#
+# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001b
+ BASE_NAME = RiscVOpensbiPlatformLib
+ FILE_GUID = 80C09428-44DD-437F-8252-F7AB64711AA5
+ MODULE_TYPE = SEC
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = RiscVOpensbiPlatformLib
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = RISCV64
+#
+
+[Sources]
+ Platform.c
+ SifiveFu540.c
+ PlatformOverride.h
+
+[Packages]
+ EmbeddedPkg/EmbeddedPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+ Platform/SiFive/U5SeriesPkg/U5SeriesPkg.dec
+ Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec
+ Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ DebugAgentLib
+ FdtLib
+ PcdLib
+ PrintLib
+ RiscVCpuLib
+
+[FixedPcd]
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber
+ gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize
+
+ gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5UartBase
+ gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdU5PlatformSystemClock
diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/PlatformOverride.h b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/PlatformOverride.h
new file mode 100644
index 0000000000..2fbb8ca45d
--- /dev/null
+++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/PlatformOverride.h
@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel at wdc.com>
+ */
+
+#ifndef __PLATFORM_OVERRIDE_H__
+#define __PLATFORM_OVERRIDE_H__
+
+#include <sbi/sbi_types.h>
+
+struct platform_override {
+ const struct fdt_match *match_table;
+ u64 (*features)(const struct fdt_match *match);
+ u64 (*tlbr_flush_limit)(const struct fdt_match *match);
+ int (*early_init)(bool cold_boot, const struct fdt_match *match);
+ int (*final_init)(bool cold_boot, const struct fdt_match *match);
+ void (*early_exit)(const struct fdt_match *match);
+ void (*final_exit)(const struct fdt_match *match);
+ int (*system_reset_check)(u32 reset_type, u32 reset_reason,
+ const struct fdt_match *match);
+ void (*system_reset)(u32 reset_type, u32 reset_reason,
+ const struct fdt_match *match);
+ int (*fdt_fixup)(void *fdt, const struct fdt_match *match);
+};
+
+#endif
diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c
new file mode 100644
index 0000000000..79a78b834e
--- /dev/null
+++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/Platform.c
@@ -0,0 +1,224 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel at wdc.com>
+ */
+
+#include <libfdt.h>
+#include <PlatformOverride.h>
+#include <sbi/riscv_asm.h>
+#include <sbi/sbi_hartmask.h>
+#include <sbi/sbi_platform.h>
+#include <sbi/sbi_string.h>
+#include <sbi/sbi_math.h>
+#include <sbi_utils/fdt/fdt_domain.h>
+#include <sbi_utils/fdt/fdt_fixup.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/irqchip/fdt_irqchip.h>
+#include <sbi_utils/serial/fdt_serial.h>
+#include <sbi_utils/timer/fdt_timer.h>
+#include <sbi_utils/ipi/fdt_ipi.h>
+#include <sbi_utils/reset/fdt_reset.h>
+
+extern const struct platform_override sifive_fu540;
+
+static const struct platform_override *special_platforms[] = {
+ &sifive_fu540,
+};
+
+static const struct platform_override *generic_plat = NULL;
+static const struct fdt_match *generic_plat_match = NULL;
+
+static void fw_platform_lookup_special(void *fdt, int root_offset)
+{
+ int pos, noff;
+ const struct platform_override *plat;
+ const struct fdt_match *match;
+
+ for (pos = 0; pos < array_size(special_platforms); pos++) {
+ plat = special_platforms[pos];
+ if (!plat->match_table)
+ continue;
+
+ noff = fdt_find_match(fdt, -1, plat->match_table, &match);
+ if (noff < 0)
+ continue;
+
+ generic_plat = plat;
+ generic_plat_match = match;
+ break;
+ }
+}
+
+extern struct sbi_platform platform;
+static u32 generic_hart_index2id[SBI_HARTMASK_MAX_BITS] = { 0 };
+
+/*
+ * The fw_platform_init() function is called very early on the boot HART
+ * OpenSBI reference firmwares so that platform specific code get chance
+ * to update "platform" instance before it is used.
+ *
+ * The arguments passed to fw_platform_init() function are boot time state
+ * of A0 to A4 register. The "arg0" will be boot HART id and "arg1" will
+ * be address of FDT passed by previous booting stage.
+ *
+ * The return value of fw_platform_init() function is the FDT location. If
+ * FDT is unchanged (or FDT is modified in-place) then fw_platform_init()
+ * can always return the original FDT location (i.e. 'arg1') unmodified.
+ */
+unsigned long fw_platform_init(unsigned long arg0, unsigned long arg1,
+ unsigned long arg2, unsigned long arg3,
+ unsigned long arg4)
+{
+ const char *model;
+ void *fdt = (void *)arg1;
+ u32 hartid, hart_count = 0;
+ int rc, root_offset, cpus_offset, cpu_offset, len;
+
+ root_offset = fdt_path_offset(fdt, "/");
+ if (root_offset < 0)
+ goto fail;
+
+ fw_platform_lookup_special(fdt, root_offset);
+
+ model = fdt_getprop(fdt, root_offset, "model", &len);
+ if (model)
+ sbi_strncpy(platform.name, model, sizeof(platform.name));
+
+ if (generic_plat && generic_plat->features)
+ platform.features = generic_plat->features(generic_plat_match);
+
+ cpus_offset = fdt_path_offset(fdt, "/cpus");
+ if (cpus_offset < 0)
+ goto fail;
+
+ fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
+ rc = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
+ if (rc)
+ continue;
+
+ if (SBI_HARTMASK_MAX_BITS <= hartid)
+ continue;
+
+ generic_hart_index2id[hart_count++] = hartid;
+ }
+
+ platform.hart_count = hart_count;
+
+ /* Return original FDT pointer */
+ return arg1;
+
+fail:
+ while (1)
+ wfi();
+}
+
+static int generic_early_init(bool cold_boot)
+{
+ int rc;
+
+ if (generic_plat && generic_plat->early_init) {
+ rc = generic_plat->early_init(cold_boot, generic_plat_match);
+ if (rc)
+ return rc;
+ }
+
+ if (!cold_boot)
+ return 0;
+
+ return fdt_reset_init();
+}
+
+static int generic_final_init(bool cold_boot)
+{
+ void *fdt;
+ int rc;
+
+ if (generic_plat && generic_plat->final_init) {
+ rc = generic_plat->final_init(cold_boot, generic_plat_match);
+ if (rc)
+ return rc;
+ }
+
+ if (!cold_boot)
+ return 0;
+
+ fdt = sbi_scratch_thishart_arg1_ptr();
+
+ fdt_cpu_fixup(fdt);
+ fdt_fixups(fdt);
+ fdt_domain_fixup(fdt);
+
+ if (generic_plat && generic_plat->fdt_fixup) {
+ rc = generic_plat->fdt_fixup(fdt, generic_plat_match);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
+static void generic_early_exit(void)
+{
+ if (generic_plat && generic_plat->early_exit)
+ generic_plat->early_exit(generic_plat_match);
+}
+
+static void generic_final_exit(void)
+{
+ if (generic_plat && generic_plat->final_exit)
+ generic_plat->final_exit(generic_plat_match);
+}
+
+static int generic_domains_init(void)
+{
+ return fdt_domains_populate(sbi_scratch_thishart_arg1_ptr());
+}
+
+static u64 generic_tlbr_flush_limit(void)
+{
+ if (generic_plat && generic_plat->tlbr_flush_limit)
+ return generic_plat->tlbr_flush_limit(generic_plat_match);
+ return SBI_PLATFORM_TLB_RANGE_FLUSH_LIMIT_DEFAULT;
+}
+
+const struct sbi_platform_operations platform_ops = {
+ .early_init = generic_early_init,
+ .final_init = generic_final_init,
+ .early_exit = generic_early_exit,
+ .final_exit = generic_final_exit,
+ .domains_init = generic_domains_init,
+ .console_init = fdt_serial_init,
+ .irqchip_init = fdt_irqchip_init,
+ .irqchip_exit = fdt_irqchip_exit,
+ .ipi_init = fdt_ipi_init,
+ .ipi_exit = fdt_ipi_exit,
+ .get_tlbr_flush_limit = generic_tlbr_flush_limit,
+ .timer_init = fdt_timer_init,
+ .timer_exit = fdt_timer_exit,
+};
+
+#if FixedPcdGet32(PcdBootableHartNumber) == 4
+#define U540_BOOTABLE_HART_COUNT FixedPcdGet32(PcdBootableHartNumber)
+static u32 U540_hart_index2id[U540_BOOTABLE_HART_COUNT] = {1, 2, 3, 4};
+#endif
+
+struct sbi_platform platform = {
+ .opensbi_version = OPENSBI_VERSION,
+ .platform_version = SBI_PLATFORM_VERSION(0x0, 0x01),
+ .name = "Generic",
+ .features = SBI_PLATFORM_DEFAULT_FEATURES,
+ .hart_count = SBI_HARTMASK_MAX_BITS,
+// TODO: Workaround for U540. Not sure why we need this. OpenSBI doesn't need it.
+#if FixedPcdGet32(PcdBootableHartNumber) == 4
+ .hart_index2id = U540_hart_index2id,
+#else
+ .hart_index2id = generic_hart_index2id,
+#endif
+ // TODO: Any reason why it shouldn't just be SBI_PLATFORM_DEFAULT_HART_STACK_SIZE?
+ .hart_stack_size = FixedPcdGet32(PcdOpenSbiStackSize),
+ .platform_ops_addr = (unsigned long)&platform_ops
+};
diff --git a/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/SifiveFu540.c b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/SifiveFu540.c
new file mode 100644
index 0000000000..748b058840
--- /dev/null
+++ b/Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/SifiveFu540.c
@@ -0,0 +1,47 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2020 Western Digital Corporation or its affiliates.
+ *
+ * Authors:
+ * Anup Patel <anup.patel at wdc.com>
+ */
+
+#include <PlatformOverride.h>
+#include <sbi_utils/fdt/fdt_helper.h>
+#include <sbi_utils/fdt/fdt_fixup.h>
+
+static u64 sifive_fu540_tlbr_flush_limit(const struct fdt_match *match)
+{
+ /*
+ * The sfence.vma by virtual address does not work on
+ * SiFive FU540 so we return remote TLB flush limit as zero.
+ */
+ return 0;
+}
+
+static int sifive_fu540_fdt_fixup(void *fdt, const struct fdt_match *match)
+{
+ /*
+ * SiFive Freedom U540 has an erratum that prevents S-mode software
+ * to access a PMP protected region using 1GB page table mapping, so
+ * always add the no-map attribute on this platform.
+ */
+ fdt_reserved_memory_nomap_fixup(fdt);
+
+ return 0;
+}
+
+static const struct fdt_match sifive_fu540_match[] = {
+ { .compatible = "sifive,fu540" },
+ { .compatible = "sifive,fu540g" },
+ { .compatible = "sifive,fu540-c000" },
+ { .compatible = "sifive,hifive-unleashed-a00" },
+ { },
+};
+
+const struct platform_override sifive_fu540 = {
+ .match_table = sifive_fu540_match,
+ .tlbr_flush_limit = sifive_fu540_tlbr_flush_limit,
+ .fdt_fixup = sifive_fu540_fdt_fixup,
+};
--
2.31.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85379): https://edk2.groups.io/g/devel/message/85379
Mute This Topic: https://groups.io/mt/88278554/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list