(This is migrated from edk2-platforms) It's a generic platform file. Only the device tree decides what happens.
Cc: Daniel Schaefer <daniel.schae...@hpe.com> Cc: Abner Chang <abner.ch...@hpe.com> Cc: Sunil V L <suni...@ventanamicro.com> Reviewed-by: Abner Chang <abner.ch...@hpe.com> Signed-off-by: Daniel Schaefer <daniel.schae...@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.pa...@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.pa...@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.pa...@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/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-