diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree.fdf.inc b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree.fdf.inc new file mode 100644 index 00000000000..dae829db513 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree.fdf.inc @@ -0,0 +1,35 @@ +## @file +# FDF include file with Layout Regions that define an empty variable store. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +$(DTB_OFFSET)|$(DTB_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDtbFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDtbFvSize +FV = DTBFV + +[FV.DTBFV] +BlockSize = 0x1000 +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +INF RuleOverride = DTB Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/U740DeviceTree.inf diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/U740DeviceTree.inf b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/U740DeviceTree.inf new file mode 100644 index 00000000000..71cd467a539 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/U740DeviceTree.inf @@ -0,0 +1,25 @@ +## @file +# +# Device tree description of the Hifive Unleashed platform +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved. +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001A + BASE_NAME = U740DeviceTree + FILE_GUID = 0FFA746F-9B5D-48F7-A561-E47D555C5E3E + MODULE_TYPE = USER_DEFINED + VERSION_STRING = 1.0 + +[Sources] + gpio.h + hifive-unleashed-a00.dts + fu540-c000.dtsi + sifive-fu540-prci.h + +[Packages] + MdePkg/MdePkg.dec diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/fu540-c000.dtsi b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/fu540-c000.dtsi new file mode 100644 index 00000000000..b4fc06b25ba --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/fu540-c000.dtsi @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2018-2019 SiFive, Inc */ + +/dts-v1/; + +/**@file + SiFive U540 platform Device Tree + + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "sifive-fu540-prci.h" + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu540-c000", "sifive,fu540"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + ethernet0 = ð0; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "sifive,e51", "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + reg = <0>; + riscv,isa = "rv64imac"; + status = "disabled"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <1>; + riscv,isa = "rv64imafdc"; + tlb-split; + next-level-cache = <&l2cache>; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <2>; + riscv,isa = "rv64imafdc"; + tlb-split; + next-level-cache = <&l2cache>; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <3>; + riscv,isa = "rv64imafdc"; + tlb-split; + next-level-cache = <&l2cache>; + cpu3_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu4: cpu@4 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <4>; + riscv,isa = "rv64imafdc"; + tlb-split; + next-level-cache = <&l2cache>; + cpu4_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu540-c000", "sifive,fu540", "simple-bus"; + ranges; + plic0: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "sifive,plic-1.0.0"; + reg = <0x0 0xc000000 0x0 0x4000000>; + riscv,ndev = <53>; + interrupt-controller; + interrupts-extended = < + &cpu0_intc 0xffffffff + &cpu1_intc 0xffffffff &cpu1_intc 9 + &cpu2_intc 0xffffffff &cpu2_intc 9 + &cpu3_intc 0xffffffff &cpu3_intc 9 + &cpu4_intc 0xffffffff &cpu4_intc 9>; + }; + prci: clock-controller@10000000 { + compatible = "sifive,fu540-c000-prci"; + reg = <0x0 0x10000000 0x0 0x1000>; + clocks = <&hfclk>, <&rtcclk>; + #clock-cells = <1>; + }; + uart0: serial@10010000 { + compatible = "sifive,fu540-c000-uart", "sifive,uart0"; + reg = <0x0 0x10010000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <4>; + clocks = <&prci PRCI_CLK_TLCLK>; + status = "disabled"; + }; + dma: dma@3000000 { + compatible = "sifive,fu540-c000-pdma"; + reg = <0x0 0x3000000 0x0 0x8000>; + interrupt-parent = <&plic0>; + interrupts = <23 24 25 26 27 28 29 30>; + #dma-cells = <1>; + }; + uart1: serial@10011000 { + compatible = "sifive,fu540-c000-uart", "sifive,uart0"; + reg = <0x0 0x10011000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <5>; + clocks = <&prci PRCI_CLK_TLCLK>; + status = "disabled"; + }; + i2c0: i2c@10030000 { + compatible = "sifive,fu540-c000-i2c", "sifive,i2c0"; + reg = <0x0 0x10030000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <50>; + clocks = <&prci PRCI_CLK_TLCLK>; + reg-shift = <2>; + reg-io-width = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi0: spi@10040000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10040000 0x0 0x1000 + 0x0 0x20000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <51>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi1: spi@10041000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10041000 0x0 0x1000 + 0x0 0x30000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <52>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi2: spi@10050000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10050000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <6>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + eth0: ethernet@10090000 { + compatible = "sifive,fu540-c000-gem"; + interrupt-parent = <&plic0>; + interrupts = <53>; + reg = <0x0 0x10090000 0x0 0x2000 + 0x0 0x100a0000 0x0 0x1000>; + local-mac-address = [00 00 00 00 00 00]; + clock-names = "pclk", "hclk"; + clocks = <&prci PRCI_CLK_GEMGXLPLL>, + <&prci PRCI_CLK_GEMGXLPLL>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pwm0: pwm@10020000 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10020000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <42 43 44 45>; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; + pwm1: pwm@10021000 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10021000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <46 47 48 49>; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; + l2cache: cache-controller@2010000 { + compatible = "sifive,fu540-c000-ccache", "cache"; + cache-block-size = <64>; + cache-level = <2>; + cache-sets = <1024>; + cache-size = <2097152>; + cache-unified; + interrupt-parent = <&plic0>; + interrupts = <1 2 3>; + reg = <0x0 0x2010000 0x0 0x1000>; + }; + gpio: gpio@10060000 { + compatible = "sifive,fu540-c000-gpio", "sifive,gpio0"; + interrupt-parent = <&plic0>; + interrupts = <7>, <8>, <9>, <10>, <11>, <12>, <13>, + <14>, <15>, <16>, <17>, <18>, <19>, <20>, + <21>, <22>; + reg = <0x0 0x10060000 0x0 0x1000>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + clocks = <&prci PRCI_CLK_TLCLK>; + status = "disabled"; + }; + clint: clint@2000000 { + compatible = "riscv,clint0"; + interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7 + &cpu1_intc 3 &cpu1_intc 7 + &cpu2_intc 3 &cpu2_intc 7 + &cpu3_intc 3 &cpu3_intc 7 + &cpu4_intc 3 &cpu4_intc 7>; + reg = <0x0 0x2000000 0x0 0xc0000>; + }; + }; +}; diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/gpio.h b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/gpio.h new file mode 100644 index 00000000000..1ad335d693b --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/gpio.h @@ -0,0 +1,43 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * This header provides constants for most GPIO bindings. + * + * Most GPIO bindings include a flags cell as part of the GPIO specifier. + * In most cases, the format of the flags cell uses the standard values + * defined in this header. + */ + +#ifndef _DT_BINDINGS_GPIO_GPIO_H +#define _DT_BINDINGS_GPIO_GPIO_H + +/* Bit 0 express polarity */ +#define GPIO_ACTIVE_HIGH 0 +#define GPIO_ACTIVE_LOW 1 + +/* Bit 1 express single-endedness */ +#define GPIO_PUSH_PULL 0 +#define GPIO_SINGLE_ENDED 2 + +/* Bit 2 express Open drain or open source */ +#define GPIO_LINE_OPEN_SOURCE 0 +#define GPIO_LINE_OPEN_DRAIN 4 + +/* + * Open Drain/Collector is the combination of single-ended open drain interface. + * Open Source/Emitter is the combination of single-ended open source interface. + */ +#define GPIO_OPEN_DRAIN (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_DRAIN) +#define GPIO_OPEN_SOURCE (GPIO_SINGLE_ENDED | GPIO_LINE_OPEN_SOURCE) + +/* Bit 3 express GPIO suspend/resume and reset persistence */ +#define GPIO_PERSISTENT 0 +#define GPIO_TRANSITORY 8 + +/* Bit 4 express pull up */ +#define GPIO_PULL_UP 16 + +/* Bit 5 express pull down */ +#define GPIO_PULL_DOWN 32 + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/hifive-unleashed-a00.dts b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/hifive-unleashed-a00.dts new file mode 100644 index 00000000000..df06f1c8c43 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/hifive-unleashed-a00.dts @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2018-2019 SiFive, Inc */ + +#include "fu540-c000.dtsi" +/*#include */ +#include "gpio.h" + +/* Clock frequency (in Hz) of the PCB crystal for rtcclk */ +#define RTCCLK_FREQ 1000000 + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "SiFive HiFive Unleashed A00"; + compatible = "sifive,hifive-unleashed-a00", "sifive,fu540-c000"; + + chosen { + stdout-path = "serial0"; + }; + + cpus { + timebase-frequency = ; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x2 0x00000000>; + }; + + soc { + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <33333333>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + clock-output-names = "rtcclk"; + }; + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpio 10 GPIO_ACTIVE_LOW>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&qspi0 { + status = "okay"; + flash@0 { + compatible = "issi,is25wp256", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&qspi2 { + status = "okay"; + mmc@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3300 3300>; + disable-wp; + }; +}; + +ð0 { + status = "okay"; + phy-mode = "gmii"; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&gpio { + status = "okay"; +}; diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/sifive-fu540-prci.h b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/sifive-fu540-prci.h new file mode 100644 index 00000000000..4446b28548e --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/sifive-fu540-prci.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (C) 2018-2019 SiFive, Inc. + * Wesley Terpstra + * Paul Walmsley + */ + +#ifndef __DT_BINDINGS_CLOCK_SIFIVE_FU540_PRCI_H +#define __DT_BINDINGS_CLOCK_SIFIVE_FU540_PRCI_H + +/* Clock indexes for use by Device Tree data and the PRCI driver */ + +#define PRCI_CLK_COREPLL 0 +#define PRCI_CLK_DDRPLL 1 +#define PRCI_CLK_GEMGXLPLL 2 +#define PRCI_CLK_TLCLK 3 + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf new file mode 100644 index 00000000000..5a95e28dbd3 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf @@ -0,0 +1,36 @@ +## @file +# Null library instance to provide platform_override for the +# special RISC-V platform. This module incorporates with +# OpensbiPlatformLib and RISC-V Opensbi library. +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = RiscVSpecialPlatformLib + FILE_GUID = FE0AE3E6-90A4-421D-851D-E092CBEEE645 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RiscVSpecialPlatformLib|SEC + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + SifiveFu740.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + +[LibraryClasses] + BaseLib diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/SifiveFu740.c b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/SifiveFu740.c new file mode 100644 index 00000000000..871608db485 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/SifiveFu740.c @@ -0,0 +1,63 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel + + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + */ + +#include +#include +#include + +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, +}; + +const struct platform_override *special_platforms[] = { + &sifive_fu540, +}; +INTN NumberOfPlaformsInArray = array_size (special_platforms); diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dec b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dec new file mode 100644 index 00000000000..f3b714172a0 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dec @@ -0,0 +1,26 @@ +## @file U740.dec +# This Package provides SiFive U740 modules and libraries. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x0001001b + PACKAGE_NAME = U740 + PACKAGE_UNI_FILE = U740.uni + PACKAGE_GUID = 0E5F5459-20DF-4748-BCE8-F8CBDC5C41DB + PACKAGE_VERSION = 1.0 + +[Includes] + +[LibraryClasses] + +[Guids] + gUefiRiscVPlatformU740PkgTokenSpaceGuid = {0xF73592FF, 0xD846, 0x445B, { 0xBD, 0x19, 0x2D, 0xD5, 0x72, 0x8B, 0xDE, 0x61 }} + +[UserExtensions.TianoCore."ExtraFiles"] + U740PkgExtra.uni diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dsc b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dsc new file mode 100644 index 00000000000..2af45f87390 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.dsc @@ -0,0 +1,571 @@ +## @file +# RISC-V EFI on SiFive Freedom U740 HiFive Unmatched RISC-V platform +# +# Copyright (c) 2019-2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +################################################################################ +# +# Defines Section - statements that will be processed to create a Makefile. +# +################################################################################ +[Defines] + PLATFORM_NAME = FreedomU740HiFiveUnmatched + PLATFORM_GUID = 5035C873-6747-4548-BDB3-21E11903911F + PLATFORM_VERSION = 0.1 + DSC_SPECIFICATION = 0x0001001c + OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME) + SUPPORTED_ARCHITECTURES = RISCV64 + BUILD_TARGETS = DEBUG|RELEASE|NOOPT + SKUID_IDENTIFIER = DEFAULT + FLASH_DEFINITION = Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf + + # + # Enable below options may cause build error or may not work on + # the initial version of RISC-V package + # Defines for default states. These can be changed on the command line. + # -D FLAG=VALUE + # + DEFINE SECURE_BOOT_ENABLE = FALSE + DEFINE DEBUG_ON_SERIAL_PORT = TRUE + + # + # Network definition + # + DEFINE NETWORK_SNP_ENABLE = FALSE + DEFINE NETWORK_IP6_ENABLE = FALSE + DEFINE NETWORK_TLS_ENABLE = FALSE + DEFINE NETWORK_HTTP_BOOT_ENABLE = FALSE + DEFINE NETWORK_ISCSI_ENABLE = FALSE + +[BuildOptions] + GCC:RELEASE_*_*_CC_FLAGS = -DMDEPKG_NDEBUG +!ifdef $(SOURCE_DEBUG_ENABLE) + GCC:*_*_RISCV64_GENFW_FLAGS = --keepexceptiontable +!endif + +################################################################################ +# +# SKU Identification section - list of all SKU IDs supported by this Platform. +# +################################################################################ +[SkuIds] + 0|DEFAULT + +################################################################################ +# +# Library Class section - list of all Library Classes needed by this Platform. +# +################################################################################ + +!include MdePkg/MdeLibs.dsc.inc + +[LibraryClasses] + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf + BaseLib|MdePkg/Library/BaseLib/BaseLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + SynchronizationLib|MdePkg/Library/BaseSynchronizationLib/BaseSynchronizationLib.inf + CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf + PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf + UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf + HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf + CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf + DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf + DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf + PciCf8Lib|MdePkg/Library/BasePciCf8Lib/BasePciCf8Lib.inf + PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf + IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + SerialPortLib|Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialIoLib.inf + UefiLib|MdePkg/Library/UefiLib/UefiLib.inf + UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf + UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf + UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf + UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf + UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf + CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf + SortLib|MdeModulePkg/Library/BaseSortLib/BaseSortLib.inf + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + +# RISC-V Platform Library + TimeBaseLib|EmbeddedPkg//Library/TimeBaseLib/TimeBaseLib.inf + RealTimeClockLib|EmbeddedPkg//Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf + +# RISC-V Core Library + RiscVOpensbiLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVOpensbiLib/RiscVOpensbiLib.inf + +!ifdef $(SOURCE_DEBUG_ENABLE) + PeCoffExtraActionLib|SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf + DebugCommunicationLib|SourceLevelDebugPkg/Library/DebugCommunicationLibSerialPort/DebugCommunicationLibSerialPort.inf +!else + PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf + DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf +!endif + + DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf + +!if $(SECURE_BOOT_ENABLE) == TRUE + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf + TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf + AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + SecureBootVariableLib|SecurityPkg/Library/SecureBootVariableLib/SecureBootVariableLib.inf + SecureBootVariableProvisionLib|SecurityPkg/Library/SecureBootVariableProvisionLib/SecureBootVariableProvisionLib.inf +!else + TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf + AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf +!endif + VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf + +!if $(HTTP_BOOT_ENABLE) == TRUE + HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf +!endif + +# ACPI not supported yet. + #S3BootScriptLib|MdeModulePkg/Library/PiDxeS3BootScriptLib/DxeS3BootScriptLib.inf + SmbusLib|MdePkg/Library/BaseSmbusLibNull/BaseSmbusLibNull.inf + OrderedCollectionLib|MdePkg/Library/BaseOrderedCollectionRedBlackTreeLib/BaseOrderedCollectionRedBlackTreeLib.inf + +[LibraryClasses.common] +!if $(SECURE_BOOT_ENABLE) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf +!endif + RiscVCpuLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVCpuLib/RiscVCpuLib.inf + RiscVEdk2SbiLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVEdk2SbiLib/RiscVEdk2SbiLib.inf + RiscVPlatformTimerLib|Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf + #MachineModeTimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVReadMachineModeTimer/MachineModeTimerLib/MachineModeTimerLib.inf + MachineModeTimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVReadMachineModeTimer/EmulatedMachineModeTimerLib/EmulatedMachineModeTimerLib.inf + CpuExceptionHandlerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVExceptionLib/CpuExceptionHandlerDxeLib.inf + + + # Flattened Device Tree (FDT) access library + FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf + +[LibraryClasses.common.SEC] +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf + Edk2OpensbiPlatformWrapperLib|Platform/RISC-V/PlatformPkg/Library/Edk2OpensbiPlatformWrapperLib/Edk2OpensbiPlatformWrapperLib.inf + RiscVSpecialPlatformLib|Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/Library/RiscVSpecialPlatformLib/RiscVSpecialPlatformLib.inf + +!ifdef $(SOURCE_DEBUG_ENABLE) + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +!endif + + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + +# +# OpenSBi Platform Library +# + RiscVOpensbiPlatformLib|Platform/RISC-V/PlatformPkg/Library/OpensbiPlatformLib/OpensbiPlatformLib.inf + +[LibraryClasses.common.PEI_CORE] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib|Silicon/RISC-V/ProcessorPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf + RiscVFirmwareContextLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVFirmwareContextSscratchLib/RiscVFirmwareContextSscratchLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + # RISC-V platform PEI core entry point. + PeiCoreEntryPoint|Platform/RISC-V/PlatformPkg/Library/PeiCoreEntryPoint/PeiCoreEntryPoint.inf + PlatformSecPpiLib|Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf + +[LibraryClasses.common.PEIM] + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf + PeiServicesTablePointerLib|Silicon/RISC-V/ProcessorPkg/Library/PeiServicesTablePointerLibOpenSbi/PeiServicesTablePointerLibOpenSbi.inf + RiscVFirmwareContextLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVFirmwareContextSscratchLib/RiscVFirmwareContextSscratchLib.inf + PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf + MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf + ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf + OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf + PeiResourcePublicationLib|MdePkg/Library/PeiResourcePublicationLib/PeiResourcePublicationLib.inf + ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf +!ifdef $(SOURCE_DEBUG_ENABLE) + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgentLib.inf +!endif + FirmwareContextProcessorSpecificLib|Platform/RISC-V/PlatformPkg/Library/FirmwareContextProcessorSpecificLib/FirmwareContextProcessorSpecificLib.inf + +# +# RISC-V core libraries +# +# SiliconSiFiveU74CoreInfoLib|Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLibNull.inf +# RiscVCoreplexInfoLib|Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLibNull.inf +RiscVCoreplexInfoLib|Platform/RISC-V/PlatformPkg/Library/PeiCoreInfoHobLibNull/PeiCoreInfoHobLib.inf + +[LibraryClasses.common.DXE_CORE] + TimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf + HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf +!ifdef $(SOURCE_DEBUG_ENABLE) + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + +[LibraryClasses.common.DXE_RUNTIME_DRIVER] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/RuntimeDxeReportStatusCodeLib.inf + ResetSystemLib|Platform/RISC-V/PlatformPkg/Library/ResetSystemLib/ResetSystemLib.inf + UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif +!if $(SECURE_BOOT_ENABLE) == TRUE + BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf +!endif + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLibRuntimeDxe.inf + +[LibraryClasses.common.UEFI_DRIVER] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf + VariablePolicyLib|MdeModulePkg/Library/VariablePolicyLib/VariablePolicyLib.inf + +[LibraryClasses.common.DXE_DRIVER] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + UefiScsiLib|MdePkg/Library/UefiScsiLib/UefiScsiLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif +!ifdef $(SOURCE_DEBUG_ENABLE) + DebugAgentLib|SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +!endif + UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf + PlatformBootManagerLib|Platform/RISC-V/PlatformPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf + PlatformMemoryTestLib|Platform/RISC-V/PlatformPkg/Library/PlatformMemoryTestLibNull/PlatformMemoryTestLibNull.inf + PlatformUpdateProgressLib|Platform/RISC-V/PlatformPkg/Library/PlatformUpdateProgressLibNull/PlatformUpdateProgressLibNull.inf + +[LibraryClasses.common.UEFI_APPLICATION] + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + TimerLib|Silicon/RISC-V/ProcessorPkg/Library/RiscVTimerLib/BaseRiscVTimerLib.inf + HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf + MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf +!ifdef $(DEBUG_ON_SERIAL_PORT) + DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf +!else + DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf +!endif + ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf + +################################################################################ +# +# Pcd Section - list of all EDK II PCD Entries defined by this Platform. +# +################################################################################ +[PcdsFeatureFlag] + gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportUefiDecompress|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|FALSE + +[PcdsFixedAtBuild] + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseMemory|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeUseSerial|TRUE + gEfiMdeModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1 + gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE + gEfiMdePkgTokenSpaceGuid.PcdMaximumGuidedExtractHandler|0x10 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000 + gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x8000 + gEfiMdeModulePkgTokenSpaceGuid.PcdVariableStoreSize|0xe000 + + gEfiMdeModulePkgTokenSpaceGuid.PcdVpdBaseAddress|0x0 + + gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07 + gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8000004F +!ifdef $(SOURCE_DEBUG_ENABLE) + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x17 +!else + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F +!endif + +!ifdef $(SOURCE_DEBUG_ENABLE) + gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod|0x2 +!endif + +!if $(SECURE_BOOT_ENABLE) == TRUE + # override the default values from SecurityPkg to ensure images from all sources are verified in secure boot + gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04 + gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04 + gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04 +!endif + + # + # F2 for UI APP + # + gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 } + +################################################################################ +# +# Pcd Dynamic Section - list of all EDK II PCD Entries defined by this Platform +# +################################################################################ + +[PcdsDynamicDefault] + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|800 + gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|600 + + gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0 + + # Set video resolution for text setup. + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoHorizontalResolution|640 + gEfiMdeModulePkgTokenSpaceGuid.PcdSetupVideoVerticalResolution|480 + + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosVersion|0x0208 + gEfiMdeModulePkgTokenSpaceGuid.PcdSmbiosDocRev|0x0 + +################################################################################ +# +# Components Section - list of all EDK II Modules needed by this Platform. +# +################################################################################ +[Components] + + # + # SEC Phase modules + # + Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf + + # + # PEI Phase modules + # + MdeModulePkg/Core/Pei/PeiMain.inf + MdeModulePkg/Universal/PCD/Pei/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf { + + NULL|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + } + + Platform/RISC-V/PlatformPkg/Universal/Pei/PlatformPei/PlatformPei.inf { + + PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf + } + Platform/RISC-V/PlatformPkg/Universal/FdtPeim/FdtPeim.inf + + # + # DXE Phase modules + # + MdeModulePkg/Core/Dxe/DxeMain.inf { + + NULL|MdeModulePkg//Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + } + + MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf + MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf + + MdeModulePkg/Universal/PCD/Dxe/Pcd.inf { + + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + + MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + +!if $(SECURE_BOOT_ENABLE) == TRUE + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf { + + NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf + } +!else + MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +!endif + + UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf + MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf { + + PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf + } + MdeModulePkg/Universal/Metronome/Metronome.inf + MdeModulePkg/Universal/BdsDxe/BdsDxe.inf + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf { + + ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf + } + EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + + # + # RISC-V Platform module + # + Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf + Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf + + # + # RISC-V Core module + # + Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe/CpuDxe.inf + Silicon/RISC-V/ProcessorPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf + MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf + + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { + + NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf + VariablePolicyHelperLib|MdeModulePkg/Library/VariablePolicyHelperLib/VariablePolicyHelperLib.inf + } + MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf + MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf + MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf + MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf + +# No graphic console supported yet. +# MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf { +# +# PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf +# } + MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf + MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf { + + DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf + PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf + } + MdeModulePkg/Universal/PrintDxe/PrintDxe.inf + MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf + MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf + MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf + MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf + MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf + MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf + MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf + MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf + MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf + MdeModulePkg/Universal/SerialDxe/SerialDxe.inf + + Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/DeviceTree/U740DeviceTree.inf + + # + # SMBIOS Support + # + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + + # + # Network Support + # + !include NetworkPkg/Network.dsc.inc + + # + # Usb Support + # + MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf + MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf + MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf + MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf + MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + + Silicon/RISC-V/ProcessorPkg/Universal/FdtDxe/FdtDxe.inf + + # + # FAT filesystem + GPT/MBR partitioning + UDF filesystem + # + FatPkg/EnhancedFatDxe/Fat.inf + MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf + + OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf { + + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + + ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + } + + ShellPkg/Application/Shell/Shell.inf { + + ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf + NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf + NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf + HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf + FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf + SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf + PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf + BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf + + + gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF + gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE + gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000 + } + +!if $(SECURE_BOOT_ENABLE) == TRUE + SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif + + MdeModulePkg/Application/UiApp/UiApp.inf diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf new file mode 100644 index 00000000000..8f5ef2658da --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf @@ -0,0 +1,336 @@ +# @file +# Flash definition file on SiFive Freedom U740 HiFive Unmatched RISC-V platform +# +# Copyright (c) 2019-2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# Platform definitions +# +!include U740.fdf.inc + +# +# Build the variable store and the firmware code as one unified flash device +# image. +# +[FD.U740] +BaseAddress = $(FW_BASE_ADDRESS) +Size = $(FW_SIZE) +ErasePolarity = 1 +BlockSize = $(BLOCK_SIZE) +NumBlocks = $(FW_BLOCKS) + +$(SECFV_OFFSET)|$(SECFV_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVSecFvSize +FV = SECFV + +$(PEIFV_OFFSET)|$(PEIFV_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVPeiFvSize +FV = PEIFV + +$(FVMAIN_OFFSET)|$(FVMAIN_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvBase|gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRiscVDxeFvSize +FV = FVMAIN_COMPACT + +!include VarStore.fdf.inc +!include DeviceTree.fdf.inc + +################################################################################ + +[FV.SECFV] +BlockSize = 0x1000 +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +# +# SEC Phase modules +# +# The code in this FV handles the initial firmware startup, and +# decompresses the PEI and DXE FVs which handles the rest of the boot sequence. +# +INF Platform/RISC-V/PlatformPkg/Universal/Sec/SecMain.inf + +################################################################################ +[FV.PEIFV] +BlockSize = 0x10000 +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +APRIORI PEI { + INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf + INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf + INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +} + +# +# PEI Phase modules +# +INF MdeModulePkg/Core/Pei/PeiMain.inf +INF MdeModulePkg/Universal/PCD/Pei/Pcd.inf +INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf +INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf +INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf + +# RISC-V Platform PEI Driver +INF Platform/RISC-V/PlatformPkg/Universal/Pei/PlatformPei/PlatformPei.inf +INF Platform/RISC-V/PlatformPkg/Universal/FdtPeim/FdtPeim.inf + +################################################################################ + +[FV.DXEFV] +BlockSize = 0x10000 +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE + +APRIORI DXE { + INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf + INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + INF Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf +} + +# +# DXE Phase modules +# +INF MdeModulePkg/Core/Dxe/DxeMain.inf + +INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf +INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf +INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf + +INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf +INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf +INF MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf +INF MdeModulePkg/Universal/Metronome/Metronome.inf +INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf + +# RISC-V Platform Drivers +INF Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf + +# RISC-V Core Drivers +INF Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf +INF Silicon/RISC-V/ProcessorPkg/Universal/CpuDxe/CpuDxe.inf +INF Silicon/RISC-V/ProcessorPkg/Universal/SmbiosDxe/RiscVSmbiosDxe.inf + +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf + +INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + INF SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf +!endif + +INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf +INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf +INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf +INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf +INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf +INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf +INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf +INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf +INF MdeModulePkg/Universal/PrintDxe/PrintDxe.inf +INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf +INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf +INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf +INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf +INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf +INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf +INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf +INF MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf +INF FatPkg/EnhancedFatDxe/Fat.inf +INF MdeModulePkg/Universal/Disk/UdfDxe/UdfDxe.inf +INF Silicon/RISC-V/ProcessorPkg/Universal/FdtDxe/FdtDxe.inf + +!ifndef $(SOURCE_DEBUG_ENABLE) +INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf +!endif + +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + +INF OvmfPkg/LinuxInitrdDynamicShellCommand/LinuxInitrdDynamicShellCommand.inf +INF ShellPkg/Application/Shell/Shell.inf + +# +# Network modules +# +!if $(E1000_ENABLE) + FILE DRIVER = 5D695E11-9B3F-4b83-B25F-4A8D5D69BE07 { + SECTION PE32 = Intel3.5/EFIX64/E3507X2.EFI + } +!endif + +!include NetworkPkg/Network.fdf.inc + +# +# Usb Support +# +INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf +INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf +INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf +INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf +INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf + +INF MdeModulePkg/Application/UiApp/UiApp.inf + +################################################################################ + +[FV.FVMAIN_COMPACT] +FvAlignment = 16 +ERASE_POLARITY = 1 +MEMORY_MAPPED = TRUE +STICKY_WRITE = TRUE +LOCK_CAP = TRUE +LOCK_STATUS = TRUE +WRITE_DISABLED_CAP = TRUE +WRITE_ENABLED_CAP = TRUE +WRITE_STATUS = TRUE +WRITE_LOCK_CAP = TRUE +WRITE_LOCK_STATUS = TRUE +READ_DISABLED_CAP = TRUE +READ_ENABLED_CAP = TRUE +READ_STATUS = TRUE +READ_LOCK_CAP = TRUE +READ_LOCK_STATUS = TRUE +FvNameGuid = 27A72E80-3118-4c0c-8673-AA5B4EFA9613 + +FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 { + SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE { + # + # These firmware volumes will have files placed in them uncompressed, + # and then both firmware volumes will be compressed in a single + # compression operation in order to achieve better overall compression. + # + SECTION FV_IMAGE = DXEFV + } + } + +[Rule.Common.SEC] + FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEI_CORE] + FILE PEI_CORE = $(NAMED_GUID) { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING ="$(MODULE_NAME)" Optional + VERSION STRING ="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.PEIM] + FILE PEIM = $(NAMED_GUID) { + PEI_DEPEX PEI_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_CORE] + FILE DXE_CORE = $(NAMED_GUID) { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.DXE_RUNTIME_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align = 4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_DRIVER] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_DRIVER.BINARY] + FILE DRIVER = $(NAMED_GUID) { + DXE_DEPEX DXE_DEPEX Optional |.depex + PE32 PE32 Align=4K |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 Align=4K $(INF_OUTPUT)/$(MODULE_NAME).efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.UEFI_APPLICATION.BINARY] + FILE APPLICATION = $(NAMED_GUID) { + PE32 PE32 Align=4K |.efi + UI STRING="$(MODULE_NAME)" Optional + VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER) + } + +[Rule.Common.USER_DEFINED.ACPITABLE] + FILE FREEFORM = $(NAMED_GUID) { + RAW ACPI |.acpi + RAW ASL |.aml + } + +[Rule.Common.USER_DEFINED.DTB] + FILE FREEFORM = $(NAMED_GUID) { + RAW BIN |.dtb + } diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf.inc b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf.inc new file mode 100644 index 00000000000..537b76d0f3c --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.fdf.inc @@ -0,0 +1,108 @@ +## @file +# Definitions of Flash definition file on SiFive Freedom U740 HiFive Unmatched RISC-V platform +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## +[Defines] +DEFINE BLOCK_SIZE = 0x1000 + +DEFINE FW_BASE_ADDRESS = 0x80000000 +DEFINE FW_SIZE = 0x00900000 +DEFINE FW_BLOCKS = 0x900 + +# +# 0x000000-0x7DFFFF code +# 0x7E0000-0x800000 variables +# +DEFINE CODE_BASE_ADDRESS = 0x80000000 +DEFINE CODE_SIZE = 0x00800000 +DEFINE CODE_BLOCKS = 0x800 +DEFINE VARS_BLOCKS = 0x20 + +# +# SEC + opensbi library is the root FW domain. +# The base address must be round up to log2. +# +DEFINE SECFV_OFFSET = 0x00000000 +DEFINE SECFV_SIZE = 0x00040000 +DEFINE ROOT_FW_DOMAIN_SIZE = $(SECFV_SIZE) + +# +# Other FV regions are in the second FW domain. +# The size of memory region must be power of 2. +# The base address must be aligned with the size. +# +# FW memory region +# +DEFINE PEIFV_OFFSET = 0x00400000 +DEFINE PEIFV_SIZE = 0x00180000 +DEFINE FVMAIN_OFFSET = 0x00580000 +DEFINE FVMAIN_SIZE = 0x00280000 + +# +# EFI Variable memory region. +# The total size of EFI Variable FD must include +# all of sub regions of EFI Variable +# +DEFINE VARS_OFFSET = 0x00800000 +DEFINE VARS_SIZE = 0x00007000 +DEFINE VARS_FTW_WORKING_OFFSET = 0x00807000 +DEFINE VARS_FTW_WORKING_SIZE = 0x00001000 +DEFINE VARS_FTW_SPARE_OFFSET = 0x00808000 +DEFINE VARS_FTW_SPARE_SIZE = 0x00018000 + +# +# Device Tree memory region +# +DEFINE DTB_OFFSET = 0x00840000 +DEFINE DTB_SIZE = 0x00002000 + +# +# Scratch area memory region +# +DEFINE SCRATCH_OFFSET = 0x00880000 +DEFINE SCRATCH_SIZE = 0x00010000 + + +DEFINE FW_DOMAIN_SIZE = $(FVMAIN_OFFSET) + $(FVMAIN_SIZE) - $(PEIFV_OFFSET) +DEFINE VARIABLE_FW_SIZE = $(VARS_FTW_SPARE_OFFSET) + $(VARS_FTW_SPARE_SIZE) - $(VARS_OFFSET) + +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainBaseAddress = $(CODE_BASE_ADDRESS) + $(SECFV_OFFSET) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdRootFirmwareDomainSize = $(ROOT_FW_DOMAIN_SIZE) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainBaseAddress = $(CODE_BASE_ADDRESS) + $(PEIFV_OFFSET) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdFirmwareDomainSize = $(FW_DOMAIN_SIZE) + +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress = $(FW_BASE_ADDRESS) + $(VARS_OFFSET) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize = $(VARS_SIZE) + $(VARS_FTW_WORKING_SIZE) + $(VARS_FTW_SPARE_SIZE) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize = $(BLOCK_SIZE) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionBaseAddress = $(CODE_BASE_ADDRESS) + $(VARS_OFFSET) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFirmwareRegionSize = $(VARIABLE_FW_SIZE) + +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdOpenSbiStackSize = 8192 +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamBase = $(CODE_BASE_ADDRESS) + $(SCRATCH_OFFSET) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdScratchRamSize = $(SCRATCH_SIZE) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamBase = $(CODE_BASE_ADDRESS) + $(FW_SIZE) +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdTemporaryRamSize = 0x10000 + + +SET gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz = 1000000 +SET gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7PlatformSystemClock = 250250000 # 250.250MHz system clock +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId = 1 # Boot hart ID + +# +# The bootable hart number the platform would like to use during boot. +# +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartNumber = 1 +# +# Only use hart ID 1, 2, 3, 4 +# +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootableHartIndexToId = {0x1} + # during boot +SET gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU7Cores = 1 # Total U7 cores enabled on U740 platform +SET gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported = True # E51 MC exists. +SET gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7UartBase = 0x10010000 # Serial port base address +SET gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPeiCorePrivilegeMode = 1 # Set PeiCore to S-Mode diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.uni b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.uni new file mode 100644 index 00000000000..4f386b131ce --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740.uni @@ -0,0 +1,14 @@ +// /** @file +// SiFive U740 HiFive Unmatched Package Localized Strings and Content. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+// Copyright (c) 2022, Boyang Han +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_PACKAGE_ABSTRACT #language en-US "Provides SiFIve Freedom U740 HiFive Unmatched platform modules and libraries" + +#string STR_PACKAGE_DESCRIPTION #language en-US "This Package SiFIve Freedom U740 HiFive Unmatched platform modules and libraries." diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740PkgExtra.uni b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740PkgExtra.uni new file mode 100644 index 00000000000..cf42e1e6518 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/U740PkgExtra.uni @@ -0,0 +1,13 @@ +// /** @file +// SiFive U740 Package Localized Strings and Content. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+// Copyright (c) 2022, Boyang Han +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_PACKAGE_NAME +#language en-US +"SiFive Freedom U740 HiFive Unmatcheded board package" diff --git a/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/VarStore.fdf.inc b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/VarStore.fdf.inc new file mode 100644 index 00000000000..ba93c17a168 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchedBoard/VarStore.fdf.inc @@ -0,0 +1,78 @@ +## @file +# FDF include file with Layout Regions that define an empty variable store. +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (C) 2014, Red Hat, Inc. +# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +$(VARS_OFFSET)|$(VARS_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +# +# NV_VARIABLE_STORE +# +DATA = { + ## This is the EFI_FIRMWARE_VOLUME_HEADER + # ZeroVector [] + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + # FileSystemGuid: gEfiSystemNvDataFvGuid = + # { 0xFFF12B8D, 0x7696, 0x4C8B, + # { 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50 }} + 0x8D, 0x2B, 0xF1, 0xFF, 0x96, 0x76, 0x8B, 0x4C, + 0xA9, 0x85, 0x27, 0x47, 0x07, 0x5B, 0x4F, 0x50, + # FvLength: 0x20000 + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, + # Signature "_FVH" # Attributes + 0x5f, 0x46, 0x56, 0x48, 0xff, 0xfe, 0x04, 0x00, + # HeaderLength # CheckSum # ExtHeaderOffset #Reserved #Revision + 0x48, 0x00, 0x39, 0xF1, 0x00, 0x00, 0x00, 0x02, + # Blockmap[0]: 0x20 Blocks * 0x1000 Bytes / Block + 0x00, 0x08, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, + # Blockmap[1]: End + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ## This is the VARIABLE_STORE_HEADER +!if $(SECURE_BOOT_ENABLE) == TRUE + # Signature: gEfiAuthenticatedVariableGuid = + # { 0xaaf32c78, 0x947b, 0x439a, + # { 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92 }} + 0x78, 0x2c, 0xf3, 0xaa, 0x7b, 0x94, 0x9a, 0x43, + 0xa1, 0x80, 0x2e, 0x14, 0x4e, 0xc3, 0x77, 0x92, +!else + # Signature: gEfiVariableGuid = + # { 0xddcf3616, 0x3275, 0x4164, + # { 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d }} + 0x16, 0x36, 0xcf, 0xdd, 0x75, 0x32, 0x64, 0x41, + 0x98, 0xb6, 0xfe, 0x85, 0x70, 0x7f, 0xfe, 0x7d, +!endif + # Size: 0x7000 (gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize) - + # 0x48 (size of EFI_FIRMWARE_VOLUME_HEADER) = 0x6fb8 + # This can speed up the Variable Dispatch a bit. + 0xB8, 0x6F, 0x00, 0x00, + # FORMATTED: 0x5A #HEALTHY: 0xFE #Reserved: UINT16 #Reserved1: UINT32 + 0x5A, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +$(VARS_FTW_WORKING_OFFSET)|$(VARS_FTW_WORKING_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +# +#NV_FTW_WROK +# +DATA = { + # EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER->Signature = gEdkiiWorkingBlockSignatureGuid = + # { 0x9e58292b, 0x7c68, 0x497d, { 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95 }} + 0x2b, 0x29, 0x58, 0x9e, 0x68, 0x7c, 0x7d, 0x49, + 0xa0, 0xce, 0x65, 0x0, 0xfd, 0x9f, 0x1b, 0x95, + # Crc:UINT32 #WorkingBlockValid:1, WorkingBlockInvalid:1, Reserved + 0x2c, 0xaf, 0x2c, 0x64, 0xFE, 0xFF, 0xFF, 0xFF, + # WriteQueueSize: UINT64 + 0xE0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +} + +$(VARS_FTW_SPARE_OFFSET)|$(VARS_FTW_SPARE_SIZE) +gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase|gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +# +#NV_FTW_SPARE diff --git a/Platform/SiFive/U7SeriesPkg/Include/SiFiveU5MCCoreplex.h b/Platform/SiFive/U7SeriesPkg/Include/SiFiveU5MCCoreplex.h new file mode 100644 index 00000000000..9ce0922791b --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Include/SiFiveU5MCCoreplex.h @@ -0,0 +1,32 @@ +/** @file + SiFive U74 Coreplex library definitions. + + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Boyang Han + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SIFIVE_U7MC_COREPLEX_H_ +#define SIFIVE_U7MC_COREPLEX_H_ + +#include + +#include +#include + +#define SIFIVE_U7MC_COREPLEX_MC_HART_ID 0 + +/** + Build processor and platform information for the U7 platform + + @return EFI_SUCCESS Status. + +**/ +EFI_STATUS +BuildRiscVSmbiosHobs ( + VOID + ); + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Include/SifiveU7Uart.h b/Platform/SiFive/U7SeriesPkg/Include/SifiveU7Uart.h new file mode 100644 index 00000000000..b9025f6f966 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Include/SifiveU7Uart.h @@ -0,0 +1,18 @@ +/** @file + SiFive U7 series UART header file. This is the wrapper file + of sifive-uart.h under opensib include/sbi_utils/serial. + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Boyang Han + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SIFIVE_U7_SERIES_UART_H_ +#define SIFIVE_U7_SERIES_UART_H_ + +#include +#include + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Include/U5Clint.h b/Platform/SiFive/U7SeriesPkg/Include/U5Clint.h new file mode 100644 index 00000000000..35f35f23804 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Include/U5Clint.h @@ -0,0 +1,22 @@ +/** @file + RISC-V Timer Architectural definition for U700 platform. + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Boyang Han + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef U7_CLINT_H_ +#define U7_CLINT_H_ + +#define CLINT_REG_BASE_ADDR 0x02000000 +#define CLINT_REG_MTIME 0x0200BFF8 +#define CLINT_REG_MTIMECMP0 0x02004000 +#define CLINT_REG_MTIMECMP1 0x02004008 +#define CLINT_REG_MTIMECMP2 0x02004010 +#define CLINT_REG_MTIMECMP3 0x02004018 +#define CLINT_REG_MTIMECMP4 0x02004020 + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c new file mode 100644 index 00000000000..c7ce0ea09c3 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/CoreInfoHob.c @@ -0,0 +1,193 @@ +/**@file + Build up platform processor information. + + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The Library classes this module consumes +// +#include +#include +#include + +#include +#include +#include +#include + +/** + Build up processor-specific HOB for U5MC Coreplex + + @param UniqueId Unique ID of this U5MC Coreplex processor + + @return EFI_SUCCESS The PEIM initialized successfully. + +**/ +STATIC +EFI_STATUS +EFIAPI +CreateU5MCCoreplexProcessorSpecificDataHob ( + IN UINTN UniqueId + ) +{ + EFI_STATUS Status; + UINT32 HartIdNumber; + RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *GuidHobData; + EFI_GUID *ParentCoreGuid; + BOOLEAN MCSupport; + + DEBUG ((DEBUG_INFO, "Building U5 Coreplex processor information HOB\n")); + + HartIdNumber = 0; + ParentCoreGuid = PcdGetPtr (PcdSiFiveU5MCCoreplexGuid); + MCSupport = PcdGetBool (PcdE5MCSupported); + if (MCSupport == TRUE) { + Status = CreateU54E51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, FALSE, TRUE, &GuidHobData); + if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { + DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n")); + ASSERT (FALSE); + } else { + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Support E5 Monitor core on U5 platform, HOB at address 0x%x\n", GuidHobData)); + } + } + + HartIdNumber++; + } + + for ( ; HartIdNumber < (FixedPcdGet32 (PcdNumberofU5Cores) + (UINT32)MCSupport); HartIdNumber++) { + Status = CreateU54E51CoreProcessorSpecificDataHob (ParentCoreGuid, UniqueId, HartIdNumber, (HartIdNumber == FixedPcdGet32 (PcdBootHartId)), FALSE, &GuidHobData); + if (EFI_ERROR (Status) && (Status != EFI_UNSUPPORTED)) { + DEBUG ((DEBUG_ERROR, "Faile to build U5MC processor informatino HOB\n")); + ASSERT (FALSE); + } else { + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "Support U5 application core on U5 platform, HOB Data at address 0x%x\n", GuidHobData)); + } + } + } + + DEBUG ((DEBUG_INFO, "Support %d U5 application cores on U5 platform\n", HartIdNumber - (UINT32)MCSupport)); + + return EFI_SUCCESS; +} + +/** + Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collect + this information and build SMBIOS Type4 and Type7 record. + + @param ProcessorUid Unique ID of physical processor which owns this core. + @param SmbiosHobPtr Pointer to receive RISC_V_PROCESSOR_SMBIOS_HOB_DATA. The pointers + maintained in this structure is only valid before memory is discovered. + Access to those pointers after memory is installed will cause unexpected issues. + + @return EFI_SUCCESS The SMBIOS Hobs were created successfully. + +**/ +STATIC +EFI_STATUS +EFIAPI +CreateU5MCProcessorSmbiosDataHob ( + IN UINTN ProcessorUid, + OUT RISC_V_PROCESSOR_SMBIOS_HOB_DATA **SmbiosHobPtr + ) +{ + EFI_GUID *GuidPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA L2CacheDataHob; + RISC_V_PROCESSOR_SMBIOS_HOB_DATA SmbiosDataHob; + RISC_V_PROCESSOR_TYPE4_HOB_DATA *ProcessorDataHobPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L1CacheDataHobPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA *L2CacheDataHobPtr; + RISC_V_PROCESSOR_SMBIOS_HOB_DATA *SmbiosDataHobPtr; + + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); + + if (SmbiosHobPtr == NULL) { + return EFI_INVALID_PARAMETER; + } + + CreateU54SmbiosType7L1DataHob (ProcessorUid, &L1CacheDataHobPtr); + CreateU54SmbiosType4DataHob (ProcessorUid, &ProcessorDataHobPtr); + + // + // Build up SMBIOS type 7 L2 cache record. + // + ZeroMem ((VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + L2CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid)); + L2CacheDataHob.ProcessorUid = ProcessorUid; + L2CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_2 | \ + RISC_V_CACHE_CONFIGURATION_LOCATION_EXTERNAL | \ + RISC_V_CACHE_CONFIGURATION_ENABLED | \ + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; + L2CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; + L2CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; + L2CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR; + L2CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified; + L2CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR; + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); + L2CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L2CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + if (L2CacheDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L2 cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); + ASSERT (FALSE); + } + + ZeroMem ((VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); + SmbiosDataHob.Processor = ProcessorDataHobPtr; + SmbiosDataHob.L1Cache = L1CacheDataHobPtr; + SmbiosDataHob.L2Cache = L2CacheDataHobPtr; + SmbiosDataHob.L3Cache = NULL; + + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosGuidHobGuid); + SmbiosDataHobPtr = (RISC_V_PROCESSOR_SMBIOS_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&SmbiosDataHob, sizeof (RISC_V_PROCESSOR_SMBIOS_HOB_DATA)); + if (SmbiosDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_SMBIOS_HOB_DATA.\n")); + ASSERT (FALSE); + } + + *SmbiosHobPtr = SmbiosDataHobPtr; + DEBUG ((DEBUG_INFO, "%a: Exit\n", __FUNCTION__)); + + return EFI_SUCCESS; +} + +/** + Build processor and platform information for the U5 platform + + @return EFI_SUCCESS Status. + +**/ +EFI_STATUS +BuildRiscVSmbiosHobs ( + VOID + ) +{ + EFI_STATUS Status; + RISC_V_PROCESSOR_SMBIOS_HOB_DATA *SmbiosHobPtr; + + Status = CreateU5MCCoreplexProcessorSpecificDataHob (0); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + } + + Status = CreateU5MCProcessorSmbiosDataHob (0, &SmbiosHobPtr); + if (EFI_ERROR (Status)) { + ASSERT (FALSE); + } + + DEBUG ((DEBUG_INFO, "U5 MC Coreplex SMBIOS DATA HOB at address 0x%x\n", SmbiosHobPtr)); + + return EFI_SUCCESS; +} diff --git a/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf new file mode 100644 index 00000000000..dc9cb122766 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf @@ -0,0 +1,58 @@ +## @file +# Library instance to create core information HOB +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = SiliconSiFiveU7MCCoreplexInfoLib + FILE_GUID = ABB3DECE-488D-4381-83FE-E32FF1C1427A + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = RiscVCoreplexInfoLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + CoreInfoHob.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec + Silicon/SiFive/SiFive.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + +[LibraryClasses] + BaseLib + MemoryAllocationLib + PcdLib + PrintLib + RiscVFirmwareContextLib + SiliconSiFiveU74CoreInfoLib + +[Guids] + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid + +[Ppis] + +[FixedPcd] + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU74CoreGuid + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveE51CoreGuid + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU7MCCoreplexGuid + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU7Cores + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdHartCount + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdBootHartId diff --git a/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.c b/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.c new file mode 100644 index 00000000000..245d54966f3 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.c @@ -0,0 +1,151 @@ +/**@file + Library to install platform PPI before PEI Core + + Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +// +// The package level header files this module uses +// +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ); + +EFI_STATUS +EFIAPI +TemporaryRamDone ( + VOID + ); + +STATIC EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = { + TemporaryRamMigration +}; + +STATIC EFI_PEI_TEMPORARY_RAM_DONE_PPI mTemporaryRamDonePpi = { + TemporaryRamDone +}; + +STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = { + { + EFI_PEI_PPI_DESCRIPTOR_PPI, + &gEfiTemporaryRamSupportPpiGuid, + &mTemporaryRamSupportPpi + }, + { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gEfiTemporaryRamDonePpiGuid, + &mTemporaryRamDonePpi + }, +}; + +/** Temporary RAM migration function. + + This function migrates the data from temporary RAM to permanent + memory. + + @param[in] PeiServices PEI service + @param[in] TemporaryMemoryBase Temporary memory base address + @param[in] PermanentMemoryBase Permanent memory base address + @param[in] CopySize Size to copy + +**/ +EFI_STATUS +EFIAPI +TemporaryRamMigration ( + IN CONST EFI_PEI_SERVICES **PeiServices, + IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, + IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, + IN UINTN CopySize + ) +{ + VOID *OldHeap; + VOID *NewHeap; + VOID *OldStack; + VOID *NewStack; + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext; + + DEBUG (( + DEBUG_INFO, + "%a: Temp Mem Base:0x%Lx, Permanent Mem Base:0x%Lx, CopySize:0x%Lx\n", + __FUNCTION__, + TemporaryMemoryBase, + PermanentMemoryBase, + (UINT64)CopySize + )); + + OldHeap = (VOID *)(UINTN)TemporaryMemoryBase; + NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1)); + + OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1)); + NewStack = (VOID *)(UINTN)PermanentMemoryBase; + + CopyMem (NewHeap, OldHeap, CopySize >> 1); // Migrate Heap + CopyMem (NewStack, OldStack, CopySize >> 1); // Migrate Stack + + // + // Reset firmware context pointer + // + GetFirmwareContextPointer (&FirmwareContext); + FirmwareContext = (VOID *)FirmwareContext + (unsigned long)((UINTN)NewStack - (UINTN)OldStack); + SetFirmwareContextPointer (FirmwareContext); + + // + // Relocate PEI Service ** + // + FirmwareContext->PeiServiceTable += (unsigned long)((UINTN)NewStack - (UINTN)OldStack); + DEBUG ((DEBUG_INFO, "%a: OpenSBI Firmware Context is relocated to 0x%x\n", __FUNCTION__, FirmwareContext)); + DEBUG ((DEBUG_INFO, "OpenSBI Firmware Context at 0x%x\n", FirmwareContext)); + DEBUG ((DEBUG_INFO, " PEI Service at 0x%x\n\n", FirmwareContext->PeiServiceTable)); + + register uintptr_t a0 asm ("a0") = (uintptr_t)((UINTN)NewStack - (UINTN)OldStack); + + asm volatile ("add sp, sp, a0"::"r"(a0):); + return EFI_SUCCESS; +} + +/** Temprary RAM done function. + +**/ +EFI_STATUS EFIAPI +TemporaryRamDone ( + VOID + ) +{ + DEBUG ((DEBUG_INFO, "%a: 2nd time PEI core, temporary ram done.\n", __FUNCTION__)); + return EFI_SUCCESS; +} + +/** Return platform SEC PPI before PEI Core + + @param[in,out] ThisPpiList Pointer to retrieve EFI_PEI_PPI_DESCRIPTOR. + +**/ +EFI_STATUS +GetPlatformPrePeiCorePpiDescriptor ( + IN OUT EFI_PEI_PPI_DESCRIPTOR **ThisPpiList + ) +{ + *ThisPpiList = mPrivateDispatchTable; + return EFI_SUCCESS; +} diff --git a/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf b/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf new file mode 100644 index 00000000000..a3b0aad050c --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/PlatformSecPpiLib/PlatformSecPpiLib.inf @@ -0,0 +1,43 @@ +## @file +# Library instance to to provide PPI before PEI Core +# +# Copyright (c) 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = PlatformSecPpiLib + FILE_GUID = 8F8E049E-F193-427C-998E-1E8FE2612D94 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformSecPpiLib|PEI_CORE + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + PlatformSecPpiLib.c + +[Ppis] +[Ppis] + gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED + gEfiTemporaryRamDonePpiGuid # PPI ALWAYS_PRODUCED + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + +[LibraryClasses] + BaseLib + PcdLib + MemoryAllocationLib + PrintLib + RiscVFirmwareContextLib diff --git a/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S b/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S new file mode 100644 index 00000000000..9582a6d9203 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.S @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +// +// SiFive U7 Series Timer CSR functions. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+// Copyright (c) 2022, Boyang Han +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +//------------------------------------------------------------------------------ +#include +#include +#include + +.data + +.text +.align 3 + +.global ASM_PFX(RiscVReadMachineTimer) +.global ASM_PFX(RiscVSetMachineTimerCmp) +.global ASM_PFX(RiscVReadMachineTimerCmp) + +// +// Read machine timer CSR. +// @retval a0 : 64-bit machine timer. +// +ASM_PFX (RiscVReadMachineTimer): + li t1, CLINT_REG_MTIME + ld a0, (t1) + ret + +// +// Set machine timer compare CSR. +// @param a0 : UINT64 +// +ASM_PFX (RiscVSetMachineTimerCmp): + li t1, CLINT_REG_MTIMECMP0 + sd a0, (t1) + ret + +// +// Read machine timer compare CSR. +// @param a0 : UINT64 +// +ASM_PFX (RiscVReadMachineTimerCmp): + li t1, CLINT_REG_MTIMECMP0 + ld a0, (t1) + ret diff --git a/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf b/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf new file mode 100644 index 00000000000..503abb9d148 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/RiscVPlatformTimerLib/RiscVPlatformTimerLib.inf @@ -0,0 +1,37 @@ +## @file +# RISC-V CPU lib to override timer mechanism for U7 series platform. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = RiscVPlatformTimerLib + FILE_GUID = C7FD58B3-F645-4268-90F8-BD301BD7EA49 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = RiscVPlatformTimerLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + +[Sources.RISCV64] + RiscVPlatformTimerLib.S + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + + + diff --git a/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialIoLib.inf b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialIoLib.inf new file mode 100644 index 00000000000..b56d65e949d --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialIoLib.inf @@ -0,0 +1,39 @@ +## @file +# Library instance for SerialIo library class +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = U7SerialPortLib + MODULE_UNI_FILE = U7SerialPortLib.uni + FILE_GUID = E610093B-BB19-42D7-8F98-1FFEE128FAA6 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SerialPortLib +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# +[Packages] + MdePkg/MdePkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec + +[LibraryClasses] + BaseLib + IoLib + RiscVOpensbiLib + +[FixedPcd] + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7UartBase + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7PlatformSystemClock + +[Sources] + SerialPortLib.c diff --git a/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialPortLib.c b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialPortLib.c new file mode 100644 index 00000000000..6699e799337 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/SerialPortLib.c @@ -0,0 +1,382 @@ +/** @file + UART Serial Port library functions + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include + +// --------------------------------------------- +// UART Register Offsets +// --------------------------------------------- + +#define UART_REG_IP 5 +#define UART_IP_RXWM 0x02 + +#define UART_REG_TXFIFO 0 +#define UART_REG_RXFIFO 1 +#define UART_REG_TXCTRL 2 +#define UART_REG_RXCTRL 3 +#define UART_REG_IE 4 +#define UART_REG_IP 5 +#define UART_REG_DIV 6 + +#define UART_TXFIFO_FULL 0x80000000 +#define UART_RXFIFO_EMPTY 0x80000000 +#define UART_RXFIFO_DATA 0x000000ff +#define UART_TXCTRL_TXEN 0x1 +#define UART_RXCTRL_RXEN 0x1 + +// --------------------------------------------- +// UART Settings +// --------------------------------------------- + +#define UART_BAUDRATE 115200 +#define SYS_CLK FixedPcdGet32(PcdU7PlatformSystemClock) + +BOOLEAN Initiated = TRUE; + +/** + Get value from serial port register. + + @param RegIndex Register index + + @retval Vale returned from from serial port. + +**/ +UINT32 +GetReg ( + IN UINT32 RegIndex + ) +{ + STATIC volatile UINT32 *const uart = (UINT32 *)FixedPcdGet32 (PcdU7UartBase); + + return readl ((volatile void *)(uart + RegIndex)); +} + +/** + Set serial port register. + + @param RegIndex Register index + @param Value Value write to Register + +**/ +VOID +SetReg ( + IN UINT32 RegIndex, + IN UINT32 Value + ) +{ + STATIC volatile UINT32 *const uart = (UINT32 *)FixedPcdGet32 (PcdU7UartBase); + + writel (Value, (volatile void *)(uart + RegIndex)); +} + +/** + Character output to serial port. + + @param Ch The character to serial port. + +**/ +VOID +SifiveUartPutChar ( + IN UINT8 Ch + ) +{ + while (GetReg (UART_REG_TXFIFO) & UART_TXFIFO_FULL) { + } + + SetReg (UART_REG_TXFIFO, Ch); +} + +/** + Get character from serial port. + + @retval character The character from serial port. + +**/ +UINT32 +SifiveUartGetChar ( + VOID + ) +{ + UINT32 Ret; + + Ret = GetReg (UART_REG_RXFIFO); + if (!(Ret & UART_RXFIFO_EMPTY)) { + return Ret & UART_RXFIFO_DATA; + } + + return -1; +} + +/** + Find minimum divisor divides in_freq to max_target_hz; + Based on uart driver n SiFive FSBL. + + f_baud = f_in / (div + 1) => div = (f_in / f_baud) - 1 + The nearest integer solution requires rounding up as to not exceed max_target_hz. + div = ceil(f_in / f_baud) - 1 + = floor((f_in - 1 + f_baud) / f_baud) - 1 + This should not overflow as long as (f_in - 1 + f_baud) does not exceed + 2^32 - 1, which is unlikely since we represent frequencies in kHz. + + @param Freq The given clock to UART. + @param MaxTargetHZ Target baudrate. + +**/ +UINT32 +UartMinClkDivisor ( + IN UINT64 Freq, + IN UINT64 MaxTargetHZ + ) +{ + UINT64 Quotient; + + Quotient = (Freq + MaxTargetHZ - 1) / (MaxTargetHZ); + if (Quotient == 0) { + return 0; + } else { + return Quotient - 1; + } +} + +/** + Initialize the serial device hardware. + + If no initialization is required, then return RETURN_SUCCESS. + If the serial device was successfuly initialized, then return RETURN_SUCCESS. + If the serial device could not be initialized, then return RETURN_DEVICE_ERROR. + + @retval RETURN_SUCCESS The serial device was initialized. + @retval RETURN_DEVICE_ERROR The serail device could not be initialized. + +**/ +EFI_STATUS +EFIAPI +SerialPortInitialize ( + VOID + ) +{ + UINT32 Divisor; + UINT32 CurrentDivisor; + + Divisor = UartMinClkDivisor (SYS_CLK / 2, UART_BAUDRATE); + if (Divisor == 0) { + return EFI_INVALID_PARAMETER; + } + + CurrentDivisor = GetReg (UART_REG_DIV); + if (Divisor != CurrentDivisor) { + sifive_uart_init (FixedPcdGet32 (PcdU7UartBase), SYS_CLK / 2, UART_BAUDRATE); + } + + return EFI_SUCCESS; +} + +/** + Write data from buffer to serial device. + + Writes NumberOfBytes data bytes from Buffer to the serial device. + The number of bytes actually written to the serial device is returned. + If the return value is less than NumberOfBytes, then the write operation failed. + + If Buffer is NULL, then ASSERT(). + + If NumberOfBytes is zero, then return 0. + + @param Buffer Pointer to the data buffer to be written. + @param NumberOfBytes Number of bytes to written to the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes written to the serial device. + If this value is less than NumberOfBytes, then the write operation failed. + +**/ +UINTN +EFIAPI +SerialPortWrite ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN Index; + + if ((Buffer == NULL) || (Initiated == FALSE)) { + return 0; + } + + for (Index = 0; Index < NumberOfBytes; Index++) { + SifiveUartPutChar (Buffer[Index]); + } + + return Index; +} + +/** + Reads data from a serial device into a buffer. + + @param Buffer Pointer to the data buffer to store the data read from the serial device. + @param NumberOfBytes Number of bytes to read from the serial device. + + @retval 0 NumberOfBytes is 0. + @retval >0 The number of bytes read from the serial device. + If this value is less than NumberOfBytes, then the read operation failed. + +**/ +UINTN +EFIAPI +SerialPortRead ( + OUT UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + UINTN Index; + + if ((NULL == Buffer) || (Initiated == FALSE)) { + return 0; + } + + for (Index = 0; Index < NumberOfBytes; Index++) { + Buffer[Index] = (UINT8)SifiveUartGetChar (); + } + + return Index; +} + +/** + Polls a serial device to see if there is any data waiting to be read. + + Polls aserial device to see if there is any data waiting to be read. + If there is data waiting to be read from the serial device, then TRUE is returned. + If there is no data waiting to be read from the serial device, then FALSE is returned. + + @retval TRUE Data is waiting to be read from the serial device. + @retval FALSE There is no data waiting to be read from the serial device. + +**/ +BOOLEAN +EFIAPI +SerialPortPoll ( + VOID + ) +{ + STATIC volatile UINT32 *const uart = (UINT32 *)FixedPcdGet32 (PcdU7UartBase); + UINT32 IP; + + if (Initiated == FALSE) { + return FALSE; + } + + IP = MmioRead32 ((UINTN)(uart + UART_REG_IP)); + if (IP & UART_IP_RXWM) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Sets the control bits on a serial device. + + @param Control Sets the bits of Control that are settable. + + @retval RETURN_SUCCESS The new control bits were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetControl ( + IN UINT32 Control + ) +{ + if (Initiated == FALSE) { + return EFI_NOT_READY; + } + + return RETURN_SUCCESS; +} + +/** + Retrieve the status of the control bits on a serial device. + + @param Control A pointer to return the current control signals from the serial device. + + @retval RETURN_SUCCESS The control bits were read from the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortGetControl ( + OUT UINT32 *Control + ) +{ + if (Initiated == FALSE) { + return EFI_NOT_READY; + } + + *Control = 0; + return RETURN_SUCCESS; +} + +/** + Sets the baud rate, receive FIFO depth, transmit/receice time out, parity, + data bits, and stop bits on a serial device. + + @param BaudRate The requested baud rate. A BaudRate value of 0 will use the + device's default interface speed. + On output, the value actually set. + @param ReveiveFifoDepth The requested depth of the FIFO on the receive side of the + serial interface. A ReceiveFifoDepth value of 0 will use + the device's default FIFO depth. + On output, the value actually set. + @param Timeout The requested time out for a single character in microseconds. + This timeout applies to both the transmit and receive side of the + interface. A Timeout value of 0 will use the device's default time + out value. + On output, the value actually set. + @param Parity The type of parity to use on this serial device. A Parity value of + DefaultParity will use the device's default parity value. + On output, the value actually set. + @param DataBits The number of data bits to use on the serial device. A DataBits + vaule of 0 will use the device's default data bit setting. + On output, the value actually set. + @param StopBits The number of stop bits to use on this serial device. A StopBits + value of DefaultStopBits will use the device's default number of + stop bits. + On output, the value actually set. + + @retval RETURN_SUCCESS The new attributes were set on the serial device. + @retval RETURN_UNSUPPORTED The serial device does not support this operation. + @retval RETURN_INVALID_PARAMETER One or more of the attributes has an unsupported value. + @retval RETURN_DEVICE_ERROR The serial device is not functioning correctly. + +**/ +RETURN_STATUS +EFIAPI +SerialPortSetAttributes ( + IN OUT UINT64 *BaudRate, + IN OUT UINT32 *ReceiveFifoDepth, + IN OUT UINT32 *Timeout, + IN OUT EFI_PARITY_TYPE *Parity, + IN OUT UINT8 *DataBits, + IN OUT EFI_STOP_BITS_TYPE *StopBits + ) +{ + if (Initiated == FALSE) { + return EFI_NOT_READY; + } + + return RETURN_SUCCESS; +} diff --git a/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni new file mode 100644 index 00000000000..dcc8507095e --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Library/SerialIoLib/U5SerialPortLib.uni @@ -0,0 +1,16 @@ +// /** @file +// Library instance for SerialIo library class +// +// Library instance for SerialIO library class. +// +// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Library instance for SerialIO library class" + +#string STR_MODULE_DESCRIPTION #language en-US "Library instance for SerialIO library class." + diff --git a/Platform/SiFive/U7SeriesPkg/Readme.md b/Platform/SiFive/U7SeriesPkg/Readme.md new file mode 100644 index 00000000000..039c04d05a1 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Readme.md @@ -0,0 +1,39 @@ +# Introduction of SiFive U7 Series Platforms +U7SeriesPkg provides the common EDK2 libraries and drivers for SiFive U7 series +platforms. Currently the supported platforms are Freedom U740 HiFive Unmatched +platform. + +## U740 Platform +This is a platform package used for the SiFive Freedom U740 HiFive Unmatched +development board. + +To test this package on hardware, first build EDK2 with: +``` +build -a RISCV64 -t GCC5 -p Platform/SiFive/U7SeriesPkg/FreedomU740HiFiveUnmatchBoard/U740.dsc +``` +The produced image is located at +``` +./Build/FreedomU740HiFiveUnmatched/DEBUG_GCC5/FV/U740.fd +``` + +Then clone and build the fsbl (first stage bootloader, I think this will +eventually reside in the UEFI PEI stage?): +``` +git clone https://github.com/yqszxx/freedom-u740-c000-bootloader +cd freedom-u740-c000-bootloader +CROSSCOMPILE=riscv64-unknown-elf- make +``` +And you will get the fsbl image as `fsbl.bin`. + +Next prepare a micro-SD card, properly partition it, and write the images. +``` +sudo sgdisk -g --clear -a 1 \ + --new=1:34:2081 --change-name=1:fsbl --typecode=1:5B193300-FC78-40CD-8002-E86C45580B47 \ + --new=2:2082:34849 --change-name=2:edk2 --typecode=2:2E54B353-1271-4842-806F-E436D6AF6985 + /dev/sdX +sudo dd if=fsbl.bin of=/dev/sdX1 +sudo dd if=U740.fd of=/dev/sdX2 +``` + +Insert the card into the slot on the unmatched board, press power button, expect +to see the UEFI shell on serial console. diff --git a/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec b/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec new file mode 100644 index 00000000000..8ae7fa46984 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec @@ -0,0 +1,35 @@ +## @file U7SeriesPkg.dec +# This Package provides modules and libraries.for SiFive U7 series platforms. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + DEC_SPECIFICATION = 0x0001001b + PACKAGE_NAME = U7SeriesPkg + PACKAGE_UNI_FILE = U7SeriesPkg.uni + PACKAGE_GUID = 402E1931-A807-4100-B119-5C7415D878AC + PACKAGE_VERSION = 1.0 + +[Includes] + Include + +[LibraryClasses] + +[Guids] + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid = {0x9034A58E, 0x759E, 0x41E2, { 0xAB, 0x11, 0xF5, 0xAC, 0x32, 0x33, 0x61, 0x00 }} + +[PcdsFixedAtBuild] + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7PlatformSystemClock|0x0|UINT32|0x00001000 + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU7Cores|0x8|UINT32|0x00001001 + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported|TRUE|BOOLEAN|0x00001002 + gSiFiveU7SeriesPlatformsPkgTokenSpaceGuid.PcdU7UartBase|0x0|UINT32|0x00001003 + +[PcdsPatchableInModule] + +[UserExtensions.TianoCore."ExtraFiles"] + U7SeriesPkg.uni diff --git a/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.uni b/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.uni new file mode 100644 index 00000000000..b348d9bebaa --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/U7SeriesPkg.uni @@ -0,0 +1,14 @@ +// /** @file +// SiFive U7 Series Package Localized Strings and Content. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+// Copyright (c) 2022, Boyang Han +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_PACKAGE_ABSTRACT #language en-US "Provides SiFIve RISC-V U7 series platform modules and libraries" + +#string STR_PACKAGE_DESCRIPTION #language en-US "This Package SiFIve RISC-V U7 series platform modules and libraries." diff --git a/Platform/SiFive/U7SeriesPkg/U7SeriesPkgExtra.uni b/Platform/SiFive/U7SeriesPkg/U7SeriesPkgExtra.uni new file mode 100644 index 00000000000..83275f55eef --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/U7SeriesPkgExtra.uni @@ -0,0 +1,13 @@ +// /** @file +// SiFive U7 Series Package Localized Strings and Content. +// +// Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+// Copyright (c) 2022, Boyang Han +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_PACKAGE_NAME +#language en-US +"SiFive U7 series platform package" diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c new file mode 100644 index 00000000000..fc0646665dd --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbInfo.c @@ -0,0 +1,130 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2006, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + Module Name: + + FvbInfo.c + + Abstract: + + Defines data structure that is the volume header found.These data is intent + to decouple FVB driver with FV header. + +**/ + +// +// The package level header files this module uses +// +#include + +// +// The protocols, PPI and GUID defintions for this module +// +#include +// +// The Library classes this module consumes +// +#include +#include + +typedef struct { + UINT64 FvLength; + EFI_FIRMWARE_VOLUME_HEADER FvbInfo; + // + // EFI_FV_BLOCK_MAP_ENTRY ExtraBlockMap[n];//n=0 + // + EFI_FV_BLOCK_MAP_ENTRY End[1]; +} EFI_FVB_MEDIA_INFO; + +EFI_FVB_MEDIA_INFO mPlatformFvbMediaInfo[] = { + // + // Systen NvStorage FVB + // + { + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), + { + { + 0, + }, // ZeroVector[16] + EFI_SYSTEM_NV_DATA_FV_GUID, + FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize), + EFI_FVH_SIGNATURE, + EFI_FVB2_MEMORY_MAPPED | + EFI_FVB2_READ_ENABLED_CAP | + EFI_FVB2_READ_STATUS | + EFI_FVB2_WRITE_ENABLED_CAP | + EFI_FVB2_WRITE_STATUS | + EFI_FVB2_ERASE_POLARITY | + EFI_FVB2_ALIGNMENT_16, + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + sizeof (EFI_FV_BLOCK_MAP_ENTRY), + 0, // CheckSum + 0, // ExtHeaderOffset + { + 0, + }, // Reserved[1] + 2, // Revision + { + { + (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)) / + FixedPcdGet32 (PcdVariableFdBlockSize), + FixedPcdGet32 (PcdVariableFdBlockSize), + } + } // BlockMap[1] + }, + { + { + 0, + 0 + } + } // End[1] + } +}; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ) +{ + STATIC BOOLEAN Checksummed = FALSE; + UINTN Index; + + if (!Checksummed) { + for (Index = 0; + Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); + Index += 1) + { + UINT16 Checksum; + mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = 0; + Checksum = CalculateCheckSum16 ( + (UINT16 *)&mPlatformFvbMediaInfo[Index].FvbInfo, + mPlatformFvbMediaInfo[Index].FvbInfo.HeaderLength + ); + mPlatformFvbMediaInfo[Index].FvbInfo.Checksum = Checksum; + } + + Checksummed = TRUE; + } + + for (Index = 0; + Index < sizeof (mPlatformFvbMediaInfo) / sizeof (EFI_FVB_MEDIA_INFO); + Index += 1) + { + if (mPlatformFvbMediaInfo[Index].FvLength == FvLength) { + *FvbInfo = &mPlatformFvbMediaInfo[Index].FvbInfo; + return EFI_SUCCESS; + } + } + + return EFI_NOT_FOUND; +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf new file mode 100644 index 00000000000..8b71eca173c --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FvbServicesRuntimeDxe.inf @@ -0,0 +1,84 @@ +## @file +# Component description file for RAM Flash Fimware Volume Block DXE driver +# module. +# +# This DXE runtime driver implements and produces the Fimware Volue Block +# Protocol for a RAM flash device. +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = FvbServicesRuntimeDxe + FILE_GUID = B04036D3-4C60-43D6-9850-0FCC090FF054 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FvbInitialize + +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + FvbInfo.c + FwBlockService.c + FwBlockServiceDxe.c + RamFlash.c + RamFlashDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevicePathLib + DxeServicesTableLib + MemoryAllocationLib + PcdLib + UefiBootServicesTableLib + UefiDriverEntryPoint + UefiRuntimeLib + +[Guids] + gEfiEventVirtualAddressChangeGuid # ALWAYS_CONSUMED + # gEfiEventVirtualAddressChangeGuid # Create Event: EVENT_GROUP_GUID + +[Protocols] + gEfiFirmwareVolumeBlockProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gEfiDevicePathProtocolGuid # PROTOCOL SOMETIMES_PRODUCED + gPcdProtocolGuid # SOMETIMES_CONSUMES + gEfiPcdProtocolGuid # CONSUMES + gGetPcdInfoProtocolGuid # SOMETIMES_CONSUMES + gEfiGetPcdInfoProtocolGuid # SOMETIMES_CONSUMES + +[FixedPcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageVariableBase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwWorkingBase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdPlatformFlashNvStorageFtwSpareBase + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBaseAddress + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdSize + gUefiRiscVPlatformPkgTokenSpaceGuid.PcdVariableFdBlockSize + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase64 + +[Depex] + gEfiPcdProtocolGuid diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c new file mode 100644 index 00000000000..c1721abe7aa --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.c @@ -0,0 +1,1163 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + Module Name: + + FWBlockService.c + + Abstract: + + Revision History + +**/ + +// +// The protocols, PPI and GUID defintions for this module +// +#include +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include +#include + +#include "FwBlockService.h" +#include "RamFlash.h" + +#define EFI_FVB2_STATUS \ + (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | EFI_FVB2_LOCK_STATUS) + +ESAL_FWB_GLOBAL *mFvbModuleGlobal; + +FV_MEMMAP_DEVICE_PATH mFvMemmapDevicePathTemplate = { + { + { + HARDWARE_DEVICE_PATH, + HW_MEMMAP_DP, + { + (UINT8)(sizeof (MEMMAP_DEVICE_PATH)), + (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8) + } + }, + EfiMemoryMappedIO, + (EFI_PHYSICAL_ADDRESS)0, + (EFI_PHYSICAL_ADDRESS)0, + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +FV_PIWG_DEVICE_PATH mFvPIWGDevicePathTemplate = { + { + { + MEDIA_DEVICE_PATH, + MEDIA_PIWG_FW_VOL_DP, + { + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH)), + (UINT8)(sizeof (MEDIA_FW_VOL_DEVICE_PATH) >> 8) + } + }, + { 0 } + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + END_DEVICE_PATH_LENGTH, + 0 + } + } +}; + +EFI_FW_VOL_BLOCK_DEVICE mFvbDeviceTemplate = { + FVB_DEVICE_SIGNATURE, + NULL, + 0, + { + FvbProtocolGetAttributes, + FvbProtocolSetAttributes, + FvbProtocolGetPhysicalAddress, + FvbProtocolGetBlockSize, + FvbProtocolRead, + FvbProtocolWrite, + FvbProtocolEraseBlocks, + NULL + } +}; + +/*++ + + Routine Description: + Retrieves the physical address of a memory mapped FV + + Arguments: + Instance - The FV instance whose base address is going to be + returned + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + FwhInstance - The EFI_FW_VOL_INSTANCE fimrware instance structure + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +EFI_STATUS +GetFvbInstance ( + IN UINTN Instance, + IN ESAL_FWB_GLOBAL *Global, + OUT EFI_FW_VOL_INSTANCE **FwhInstance + ) +{ + EFI_FW_VOL_INSTANCE *FwhRecord; + + *FwhInstance = NULL; + if (Instance >= Global->NumFv) { + return EFI_INVALID_PARAMETER; + } + + // + // Find the right instance of the FVB private data + // + FwhRecord = Global->FvInstance; + while (Instance > 0) { + FwhRecord = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN)FwhRecord + FwhRecord->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + Instance--; + } + + *FwhInstance = FwhRecord; + + return EFI_SUCCESS; +} + +/*++ + + Routine Description: + Retrieves the physical address of a memory mapped FV + + Arguments: + Instance - The FV instance whose base address is going to be + returned + Address - Pointer to a caller allocated EFI_PHYSICAL_ADDRESS + that on successful return, contains the base + address of the firmware volume. + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + *Address = FwhInstance->FvBase; + + return EFI_SUCCESS; +} + +/*++ + + Routine Description: + Retrieves attributes, insures positive polarity of attribute bits, returns + resulting attributes in output parameter + + Arguments: + Instance - The FV instance whose attributes is going to be + returned + Attributes - Output buffer which contains attributes + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + *Attributes = FwhInstance->VolumeHeader.Attributes; + + return EFI_SUCCESS; +} + +/*++ + + Routine Description: + Retrieves the starting address of an LBA in an FV + + Arguments: + Instance - The FV instance which the Lba belongs to + Lba - The logical block address + LbaAddress - On output, contains the physical starting address + of the Lba + LbaLength - On output, contains the length of the block + NumOfBlocks - A pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_INVALID_PARAMETER - Instance not found + +--*/ +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global + ) +{ + UINT32 NumBlocks; + UINT32 BlockLength; + UINTN Offset; + EFI_LBA StartLba; + EFI_LBA NextLba; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FV_BLOCK_MAP_ENTRY *BlockMap; + EFI_STATUS Status; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + + StartLba = 0; + Offset = 0; + BlockMap = &(FwhInstance->VolumeHeader.BlockMap[0]); + + // + // Parse the blockmap of the FV to find which map entry the Lba belongs to + // + while (TRUE) { + NumBlocks = BlockMap->NumBlocks; + BlockLength = BlockMap->Length; + + if ((NumBlocks == 0) || (BlockLength == 0)) { + return EFI_INVALID_PARAMETER; + } + + NextLba = StartLba + NumBlocks; + + // + // The map entry found + // + if ((Lba >= StartLba) && (Lba < NextLba)) { + Offset = Offset + (UINTN)MultU64x32 ((Lba - StartLba), BlockLength); + if (LbaAddress != NULL) { + *LbaAddress = FwhInstance->FvBase + Offset; + } + + if (LbaLength != NULL) { + *LbaLength = BlockLength; + } + + if (NumOfBlocks != NULL) { + *NumOfBlocks = (UINTN)(NextLba - Lba); + } + + return EFI_SUCCESS; + } + + StartLba = NextLba; + Offset = Offset + NumBlocks * BlockLength; + BlockMap++; + } +} + +/*++ + + Routine Description: + Modifies the current settings of the firmware volume according to the + input parameter, and returns the new setting of the volume + + Arguments: + Instance - The FV instance whose attributes is going to be + modified + Attributes - On input, it is a pointer to EFI_FVB_ATTRIBUTES_2 + containing the desired firmware volume settings. + On successful return, it contains the new settings + of the firmware volume + Global - Pointer to ESAL_FWB_GLOBAL that contains all + instance data + + Returns: + EFI_SUCCESS - Successfully returns + EFI_ACCESS_DENIED - The volume setting is locked and cannot be modified + EFI_INVALID_PARAMETER - Instance not found, or The attributes requested are + in conflict with the capabilities as declared in + the firmware volume header + +--*/ +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FVB_ATTRIBUTES_2 OldAttributes; + EFI_FVB_ATTRIBUTES_2 *AttribPtr; + UINT32 Capabilities; + UINT32 OldStatus; + UINT32 NewStatus; + EFI_STATUS Status; + EFI_FVB_ATTRIBUTES_2 UnchangedAttributes; + + // + // Find the right instance of the FVB private data + // + Status = GetFvbInstance (Instance, Global, &FwhInstance); + ASSERT_EFI_ERROR (Status); + + AttribPtr = + (EFI_FVB_ATTRIBUTES_2 *)&(FwhInstance->VolumeHeader.Attributes); + OldAttributes = *AttribPtr; + Capabilities = OldAttributes & (EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP \ + ); + OldStatus = OldAttributes & EFI_FVB2_STATUS; + NewStatus = *Attributes & EFI_FVB2_STATUS; + + UnchangedAttributes = EFI_FVB2_READ_DISABLED_CAP | \ + EFI_FVB2_READ_ENABLED_CAP | \ + EFI_FVB2_WRITE_DISABLED_CAP | \ + EFI_FVB2_WRITE_ENABLED_CAP | \ + EFI_FVB2_LOCK_CAP | \ + EFI_FVB2_STICKY_WRITE | \ + EFI_FVB2_MEMORY_MAPPED | \ + EFI_FVB2_ERASE_POLARITY | \ + EFI_FVB2_READ_LOCK_CAP | \ + EFI_FVB2_WRITE_LOCK_CAP | \ + EFI_FVB2_ALIGNMENT; + + // + // Some attributes of FV is read only can *not* be set + // + if ((OldAttributes & UnchangedAttributes) ^ + (*Attributes & UnchangedAttributes)) + { + return EFI_INVALID_PARAMETER; + } + + // + // If firmware volume is locked, no status bit can be updated + // + if (OldAttributes & EFI_FVB2_LOCK_STATUS) { + if (OldStatus ^ NewStatus) { + return EFI_ACCESS_DENIED; + } + } + + // + // Test read disable + // + if ((Capabilities & EFI_FVB2_READ_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_READ_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test read enable + // + if ((Capabilities & EFI_FVB2_READ_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_READ_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test write disable + // + if ((Capabilities & EFI_FVB2_WRITE_DISABLED_CAP) == 0) { + if ((NewStatus & EFI_FVB2_WRITE_STATUS) == 0) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test write enable + // + if ((Capabilities & EFI_FVB2_WRITE_ENABLED_CAP) == 0) { + if (NewStatus & EFI_FVB2_WRITE_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + // + // Test lock + // + if ((Capabilities & EFI_FVB2_LOCK_CAP) == 0) { + if (NewStatus & EFI_FVB2_LOCK_STATUS) { + return EFI_INVALID_PARAMETER; + } + } + + *AttribPtr = (*AttribPtr) & (0xFFFFFFFF & (~EFI_FVB2_STATUS)); + *AttribPtr = (*AttribPtr) | NewStatus; + *Attributes = *AttribPtr; + + return EFI_SUCCESS; +} + +/*++ + + Routine Description: + + Retrieves the physical address of the device. + + Arguments: + + This - Calling context + Address - Output buffer containing the address. + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetPhysicalAddress ( + FvbDevice->Instance, + Address, + mFvbModuleGlobal + ); +} + +/*++ + + Routine Description: + Retrieve the size of a logical block + + Arguments: + This - Calling context + Lba - Indicates which block to return the size for. + BlockSize - A pointer to a caller allocated UINTN in which + the size of the block is returned + NumOfBlocks - a pointer to a caller allocated UINTN in which the + number of consecutive blocks starting with Lba is + returned. All blocks in this range have a size of + BlockSize + + Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetLbaAddress ( + FvbDevice->Instance, + Lba, + NULL, + BlockSize, + NumOfBlocks, + mFvbModuleGlobal + ); +} + +/*++ + + Routine Description: + Retrieves Volume attributes. No polarity translations are done. + + Arguments: + This - Calling context + Attributes - output buffer which contains attributes + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbGetVolumeAttributes ( + FvbDevice->Instance, + Attributes, + mFvbModuleGlobal + ); +} + +/*++ + + Routine Description: + Sets Volume attributes. No polarity translations are done. + + Arguments: + This - Calling context + Attributes - output buffer which contains attributes + + Returns: + EFI_SUCCESS - Successfully returns + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + return FvbSetVolumeAttributes ( + FvbDevice->Instance, + Attributes, + mFvbModuleGlobal + ); +} + +/*++ + + Routine Description: + + The EraseBlock() function erases one or more blocks as denoted by the + variable argument list. The entire parameter list of blocks must be + verified prior to erasing any blocks. If a block is requested that does + not exist within the associated firmware volume (it has a larger index than + the last block of the firmware volume), the EraseBlock() function must + return EFI_INVALID_PARAMETER without modifying the contents of the firmware + volume. + + Arguments: + This - Calling context + ... - Starting LBA followed by Number of Lba to erase. + a -1 to terminate the list. + + Returns: + EFI_SUCCESS - The erase request was successfully completed + EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state + EFI_DEVICE_ERROR - The block device is not functioning correctly and + could not be written. Firmware device may have been + partially erased + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ) +{ + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN NumOfBlocks; + VA_LIST args; + EFI_LBA StartingLba; + UINTN NumOfLba; + EFI_STATUS Status; + + FvbDevice = FVB_DEVICE_FROM_THIS (This); + + Status = GetFvbInstance ( + FvbDevice->Instance, + mFvbModuleGlobal, + &FwhInstance + ); + ASSERT_EFI_ERROR (Status); + + NumOfBlocks = FwhInstance->NumOfBlocks; + + VA_START (args, This); + + do { + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba = VA_ARG (args, UINT32); + + // + // Check input parameters + // + if ((NumOfLba == 0) || ((StartingLba + NumOfLba) > NumOfBlocks)) { + VA_END (args); + return EFI_INVALID_PARAMETER; + } + } while (1); + + VA_END (args); + + VA_START (args, This); + do { + StartingLba = VA_ARG (args, EFI_LBA); + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + break; + } + + NumOfLba = VA_ARG (args, UINT32); + + while (NumOfLba > 0) { + Status = RamFlashEraseBlock (StartingLba); + if (EFI_ERROR (Status)) { + VA_END (args); + return Status; + } + + StartingLba++; + NumOfLba--; + } + } while (1); + + VA_END (args); + + return EFI_SUCCESS; +} + +/*++ + + Routine Description: + + Writes data beginning at Lba:Offset from FV. The write terminates either + when *NumBytes of data have been written, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + Arguments: + This - Calling context + Lba - Block in which to begin write + Offset - Offset in the block at which to begin write + NumBytes - On input, indicates the requested write size. On + output, indicates the actual number of bytes + written + Buffer - Buffer containing source data for the write. + + Returns: + EFI_SUCCESS - The firmware volume was written successfully + EFI_BAD_BUFFER_SIZE - Write attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + actually written + EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state + EFI_DEVICE_ERROR - The block device is not functioning correctly and + could not be written + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + return RamFlashWrite (Lba, Offset, NumBytes, Buffer); +} + +/*++ + + Routine Description: + + Reads data beginning at Lba:Offset from FV. The Read terminates either + when *NumBytes of data have been read, or when a block boundary is + reached. *NumBytes is updated to reflect the actual number of bytes + written. The write opertion does not include erase. This routine will + attempt to write only the specified bytes. If the writes do not stick, + it will return an error. + + Arguments: + This - Calling context + Lba - Block in which to begin Read + Offset - Offset in the block at which to begin Read + NumBytes - On input, indicates the requested write size. On + output, indicates the actual number of bytes Read + Buffer - Buffer containing source data for the Read. + + Returns: + EFI_SUCCESS - The firmware volume was read successfully and + contents are in Buffer + EFI_BAD_BUFFER_SIZE - Read attempted across a LBA boundary. On output, + NumBytes contains the total number of bytes + returned in Buffer + EFI_ACCESS_DENIED - The firmware volume is in the ReadDisabled state + EFI_DEVICE_ERROR - The block device is not functioning correctly and + could not be read + EFI_INVALID_PARAMETER - NumBytes or Buffer are NULL + +--*/ +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + IN CONST UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + return RamFlashRead (Lba, Offset, NumBytes, Buffer); +} + +/*++ + + Routine Description: + Check the integrity of firmware volume header + + Arguments: + FwVolHeader - A pointer to a firmware volume header + + Returns: + EFI_SUCCESS - The firmware volume is consistent + EFI_NOT_FOUND - The firmware volume has corrupted. So it is not an + FV + +--*/ +EFI_STATUS +ValidateFvHeader ( + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader + ) +{ + UINT16 Checksum; + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ((FwVolHeader->Revision != EFI_FVH_REVISION) || + (FwVolHeader->Signature != EFI_FVH_SIGNATURE) || + (FwVolHeader->FvLength == ((UINTN)-1)) || + ((FwVolHeader->HeaderLength & 0x01) != 0) + ) + { + return EFI_NOT_FOUND; + } + + // + // Verify the header checksum + // + + Checksum = CalculateSum16 ( + (UINT16 *)FwVolHeader, + FwVolHeader->HeaderLength + ); + if (Checksum != 0) { + UINT16 Expected; + + Expected = + (UINT16)(((UINTN)FwVolHeader->Checksum + 0x10000 - Checksum) & 0xffff); + + DEBUG (( + DEBUG_INFO, + "FV@%p Checksum is 0x%x, expected 0x%x\n", + FwVolHeader, + FwVolHeader->Checksum, + Expected + )); + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +STATIC +EFI_STATUS +MarkMemoryRangeForRuntimeAccess ( + EFI_PHYSICAL_ADDRESS BaseAddress, + UINTN Length + ) +{ + EFI_STATUS Status; + + // + // Mark flash region as runtime memory + // + Status = gDS->RemoveMemorySpace ( + BaseAddress, + Length + ); + + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeSystemMemory, + BaseAddress, + Length, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->AllocatePages ( + AllocateAddress, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (Length), + &BaseAddress + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} + +STATIC +EFI_STATUS +InitializeVariableFvHeader ( + VOID + ) +{ + EFI_STATUS Status; + EFI_FIRMWARE_VOLUME_HEADER *GoodFwVolHeader; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + UINTN Length; + UINTN WriteLength; + UINTN BlockSize; + + FwVolHeader = + (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) + PcdGet32 (PcdPlatformFlashNvStorageVariableBase); + + Length = + (FixedPcdGet32 (PcdFlashNvStorageVariableSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwWorkingSize) + + FixedPcdGet32 (PcdFlashNvStorageFtwSpareSize)); + + BlockSize = PcdGet32 (PcdVariableFdBlockSize); + + Status = ValidateFvHeader (FwVolHeader); + if (!EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "ValidateFvHeader() return ok\n")); + if ((FwVolHeader->FvLength != Length) || + (FwVolHeader->BlockMap[0].Length != BlockSize)) + { + Status = EFI_VOLUME_CORRUPTED; + DEBUG ((DEBUG_INFO, "FwVolHeader->FvLength(%x) != Length(%x) || FwVolHeader->BlockMap[0].Length(%x) != BlockSize(%x)\n", FwVolHeader->FvLength, Length, FwVolHeader->BlockMap[0].Length, BlockSize)); + } + } else { + DEBUG ((DEBUG_INFO, "ValidateFvHeader() return failed\n")); + } + + if (EFI_ERROR (Status)) { + UINTN Offset; + UINTN Start; + + DEBUG (( + DEBUG_INFO, + "Variable FV header is not valid. It will be reinitialized.\n" + )); + + // + // Get FvbInfo to provide in FwhInstance. + // + Status = GetFvbInfo (Length, &GoodFwVolHeader); + ASSERT (!EFI_ERROR (Status)); + + Start = (UINTN)(UINT8 *)FwVolHeader - PcdGet32 (PcdVariableFdBaseAddress); + ASSERT (Start % BlockSize == 0 && Length % BlockSize == 0); + ASSERT (GoodFwVolHeader->HeaderLength <= BlockSize); + + // + // Erase all the blocks + // + for (Offset = Start; Offset < Start + Length; Offset += BlockSize) { + Status = RamFlashEraseBlock (Offset / BlockSize); + ASSERT_EFI_ERROR (Status); + } + + // + // Write good FV header + // + WriteLength = GoodFwVolHeader->HeaderLength; + Status = RamFlashWrite ( + Start / BlockSize, + 0, + &WriteLength, + (UINT8 *)GoodFwVolHeader + ); + ASSERT_EFI_ERROR (Status); + ASSERT (WriteLength == GoodFwVolHeader->HeaderLength); + } + + return Status; +} + +/*++ + + Routine Description: + This function does common initialization for FVB services + + Arguments: + + Returns: + +--*/ +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_FW_VOL_INSTANCE *FwhInstance; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + UINT32 BufferSize; + EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry; + EFI_FW_VOL_BLOCK_DEVICE *FvbDevice; + UINT32 MaxLbaSize; + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN Length; + UINTN NumOfBlocks; + + if (EFI_ERROR (RamFlashInitialize ())) { + // + // Return an error so image will be unloaded + // + DEBUG (( + DEBUG_INFO, + "RAM flash was not detected. Writable FVB is not being installed.\n" + )); + return EFI_WRITE_PROTECTED; + } + + // + // Allocate runtime services data for global variable, which contains + // the private data of all firmware volume block instances + // + mFvbModuleGlobal = AllocateRuntimePool (sizeof (ESAL_FWB_GLOBAL)); + ASSERT (mFvbModuleGlobal != NULL); + + BaseAddress = (UINTN)PcdGet32 (PcdVariableFdBaseAddress); + Length = PcdGet32 (PcdVariableFdSize); + DEBUG ((DEBUG_INFO, "FvbInitialize(): BaseAddress: 0x%lx Length:0x%x\n", BaseAddress, Length)); + Status = InitializeVariableFvHeader (); + if (EFI_ERROR (Status)) { + DEBUG (( + DEBUG_INFO, + "RAM Flash: Unable to initialize variable FV header\n" + )); + return EFI_WRITE_PROTECTED; + } + + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress; + Status = ValidateFvHeader (FwVolHeader); + if (EFI_ERROR (Status)) { + // + // Get FvbInfo + // + DEBUG ((DEBUG_INFO, "FvbInitialize(): ValidateFvHeader() return error(%r)\n", Status)); + + Status = GetFvbInfo (Length, &FwVolHeader); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_INFO, "FvbInitialize(): GetFvbInfo (Length, &FwVolHeader) return error(%r)\n", Status)); + return EFI_WRITE_PROTECTED; + } + } + + BufferSize = (sizeof (EFI_FW_VOL_INSTANCE) + + FwVolHeader->HeaderLength - + sizeof (EFI_FIRMWARE_VOLUME_HEADER) + ); + mFvbModuleGlobal->FvInstance = AllocateRuntimePool (BufferSize); + ASSERT (mFvbModuleGlobal->FvInstance != NULL); + + FwhInstance = mFvbModuleGlobal->FvInstance; + + mFvbModuleGlobal->NumFv = 0; + MaxLbaSize = 0; + + FwVolHeader = + (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN) + PcdGet32 (PcdPlatformFlashNvStorageVariableBase); + + FwhInstance->FvBase = (UINTN)BaseAddress; + + CopyMem ( + (UINTN *)&(FwhInstance->VolumeHeader), + (UINTN *)FwVolHeader, + FwVolHeader->HeaderLength + ); + FwVolHeader = &(FwhInstance->VolumeHeader); + + NumOfBlocks = 0; + + for (PtrBlockMapEntry = FwVolHeader->BlockMap; + PtrBlockMapEntry->NumBlocks != 0; + PtrBlockMapEntry++) + { + // + // Get the maximum size of a block. + // + if (MaxLbaSize < PtrBlockMapEntry->Length) { + MaxLbaSize = PtrBlockMapEntry->Length; + } + + NumOfBlocks = NumOfBlocks + PtrBlockMapEntry->NumBlocks; + } + + // + // The total number of blocks in the FV. + // + FwhInstance->NumOfBlocks = NumOfBlocks; + + // + // Add a FVB Protocol Instance + // + FvbDevice = AllocateRuntimePool (sizeof (EFI_FW_VOL_BLOCK_DEVICE)); + ASSERT (FvbDevice != NULL); + + CopyMem (FvbDevice, &mFvbDeviceTemplate, sizeof (EFI_FW_VOL_BLOCK_DEVICE)); + + FvbDevice->Instance = mFvbModuleGlobal->NumFv; + mFvbModuleGlobal->NumFv++; + + // + // Set up the devicepath + // + if (FwVolHeader->ExtHeaderOffset == 0) { + FV_MEMMAP_DEVICE_PATH *FvMemmapDevicePath; + + // + // FV does not contains extension header, then produce MEMMAP_DEVICE_PATH + // + FvMemmapDevicePath = AllocateCopyPool ( + sizeof (FV_MEMMAP_DEVICE_PATH), + &mFvMemmapDevicePathTemplate + ); + FvMemmapDevicePath->MemMapDevPath.StartingAddress = BaseAddress; + FvMemmapDevicePath->MemMapDevPath.EndingAddress = + BaseAddress + FwVolHeader->FvLength - 1; + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvMemmapDevicePath; + } else { + FV_PIWG_DEVICE_PATH *FvPiwgDevicePath; + + FvPiwgDevicePath = AllocateCopyPool ( + sizeof (FV_PIWG_DEVICE_PATH), + &mFvPIWGDevicePathTemplate + ); + CopyGuid ( + &FvPiwgDevicePath->FvDevPath.FvName, + (GUID *)(UINTN)(BaseAddress + FwVolHeader->ExtHeaderOffset) + ); + FvbDevice->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)FvPiwgDevicePath; + } + + // + // Module type specific hook. + // + InstallProtocolInterfaces (FvbDevice); + + MarkMemoryRangeForRuntimeAccess (BaseAddress, Length); + + // + // Set several PCD values to point to flash + // + Status = PcdSet64S ( + PcdFlashNvStorageVariableBase64, + (UINTN)PcdGet32 (PcdPlatformFlashNvStorageVariableBase) + ); + ASSERT_EFI_ERROR (Status); + Status = PcdSet32S ( + PcdFlashNvStorageFtwWorkingBase, + PcdGet32 (PcdPlatformFlashNvStorageFtwWorkingBase) + ); + ASSERT_EFI_ERROR (Status); + Status = PcdSet32S ( + PcdFlashNvStorageFtwSpareBase, + PcdGet32 (PcdPlatformFlashNvStorageFtwSpareBase) + ); + ASSERT_EFI_ERROR (Status); + + FwhInstance = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN)FwhInstance + FwVolHeader->HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + + // + // Module type specific hook. + // + InstallVirtualAddressChangeHandler (); + return EFI_SUCCESS; +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h new file mode 100644 index 00000000000..dc4afbf9ce0 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockService.h @@ -0,0 +1,187 @@ +/**@file + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2006, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + Module Name: + + FwBlockService.h + + Abstract: + + Firmware volume block driver for RAM based firmware volume block. + +**/ + +#ifndef FW_BLOCK_SERVICE_H_ +#define FW_BLOCK_SERVICE_H_ + +typedef struct { + UINTN FvBase; + UINTN NumOfBlocks; + EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; +} EFI_FW_VOL_INSTANCE; + +typedef struct { + UINT32 NumFv; + EFI_FW_VOL_INSTANCE *FvInstance; +} ESAL_FWB_GLOBAL; + +extern ESAL_FWB_GLOBAL *mFvbModuleGlobal; + +// +// Fvb Protocol instance data +// +#define FVB_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE,\ + FwVolBlockInstance, FVB_DEVICE_SIGNATURE) + +#define FVB_EXTEND_DEVICE_FROM_THIS(a) CR (a, EFI_FW_VOL_BLOCK_DEVICE,\ + FvbExtension, FVB_DEVICE_SIGNATURE) + +#define FVB_DEVICE_SIGNATURE SIGNATURE_32 ('F', 'V', 'B', 'N') + +typedef struct { + MEDIA_FW_VOL_DEVICE_PATH FvDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_PIWG_DEVICE_PATH; + +typedef struct { + MEMMAP_DEVICE_PATH MemMapDevPath; + EFI_DEVICE_PATH_PROTOCOL EndDevPath; +} FV_MEMMAP_DEVICE_PATH; + +typedef struct { + UINTN Signature; + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + UINTN Instance; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance; +} EFI_FW_VOL_BLOCK_DEVICE; + +EFI_STATUS +GetFvbInfo ( + IN UINT64 FvLength, + OUT EFI_FIRMWARE_VOLUME_HEADER **FvbInfo + ); + +EFI_STATUS +FvbSetVolumeAttributes ( + IN UINTN Instance, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +FvbGetVolumeAttributes ( + IN UINTN Instance, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +FvbGetPhysicalAddress ( + IN UINTN Instance, + OUT EFI_PHYSICAL_ADDRESS *Address, + IN ESAL_FWB_GLOBAL *Global + ); + +EFI_STATUS +EFIAPI +FvbInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +VOID +EFIAPI +FvbClassAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +FvbGetLbaAddress ( + IN UINTN Instance, + IN EFI_LBA Lba, + OUT UINTN *LbaAddress, + OUT UINTN *LbaLength, + OUT UINTN *NumOfBlocks, + IN ESAL_FWB_GLOBAL *Global + ); + +// +// Protocol APIs +// +EFI_STATUS +EFIAPI +FvbProtocolGetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolSetAttributes ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbProtocolGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbProtocolRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN CONST EFI_LBA Lba, + IN CONST UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbProtocolEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This, + ... + ); + +// +// The following functions have different implementations dependent on the +// module type chosen for building this driver. +// +VOID +InstallProtocolInterfaces ( + IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice + ); + +VOID +InstallVirtualAddressChangeHandler ( + VOID + ); + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c new file mode 100644 index 00000000000..36b518e9a25 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/FwBlockServiceDxe.c @@ -0,0 +1,152 @@ +/**@file + Functions related to the Firmware Volume Block service whose + implementation is specific to the runtime DXE driver build. + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (C) 2015, Red Hat, Inc. + Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "FwBlockService.h" +#include "RamFlash.h" + +VOID +InstallProtocolInterfaces ( + IN EFI_FW_VOL_BLOCK_DEVICE *FvbDevice + ) +{ + EFI_STATUS Status; + EFI_HANDLE FwbHandle; + EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *OldFwbInterface; + + // + // Find a handle with a matching device path that has supports FW Block + // protocol + // + Status = gBS->LocateDevicePath ( + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->DevicePath, + &FwbHandle + ); + if (EFI_ERROR (Status)) { + // + // LocateDevicePath fails so install a new interface and device path + // + FwbHandle = NULL; + DEBUG ((DEBUG_INFO, "Installing RAM FVB\n")); + Status = gBS->InstallMultipleProtocolInterfaces ( + &FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + &FvbDevice->FwVolBlockInstance, + &gEfiDevicePathProtocolGuid, + FvbDevice->DevicePath, + NULL + ); + ASSERT_EFI_ERROR (Status); + } else if (IsDevicePathEnd (FvbDevice->DevicePath)) { + // + // Device already exists, so reinstall the FVB protocol + // + Status = gBS->HandleProtocol ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + (VOID **)&OldFwbInterface + ); + ASSERT_EFI_ERROR (Status); + + DEBUG ((DEBUG_INFO, "Reinstalling FVB for Ram flash region\n")); + Status = gBS->ReinstallProtocolInterface ( + FwbHandle, + &gEfiFirmwareVolumeBlockProtocolGuid, + OldFwbInterface, + &FvbDevice->FwVolBlockInstance + ); + ASSERT_EFI_ERROR (Status); + } else { + // + // There was a FVB protocol on an End Device Path node + // + ASSERT (FALSE); + } +} + +/*++ + + Routine Description: + + Fixup internal data so that EFI and SAL can be call in virtual mode. + Call the passed in Child Notify event and convert the mFvbModuleGlobal + date items to there virtual address. + + Arguments: + + (Standard EFI notify event - EFI_EVENT_NOTIFY) + + Returns: + + None + +--*/ +STATIC +VOID +EFIAPI +FvbVirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_FW_VOL_INSTANCE *FwhInstance; + UINTN Index; + + FwhInstance = mFvbModuleGlobal->FvInstance; + EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal->FvInstance); + + // + // Convert the base address of all the instances + // + Index = 0; + while (Index < mFvbModuleGlobal->NumFv) { + EfiConvertPointer (0x0, (VOID **)&FwhInstance->FvBase); + FwhInstance = (EFI_FW_VOL_INSTANCE *) + ( + (UINTN)FwhInstance + + FwhInstance->VolumeHeader.HeaderLength + + (sizeof (EFI_FW_VOL_INSTANCE) - sizeof (EFI_FIRMWARE_VOLUME_HEADER)) + ); + Index++; + } + + EfiConvertPointer (0x0, (VOID **)&mFvbModuleGlobal); + RamFlashConvertPointers (); +} + +VOID +InstallVirtualAddressChangeHandler ( + VOID + ) +{ + EFI_STATUS Status; + EFI_EVENT VirtualAddressChangeEvent; + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualAddressChangeEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &VirtualAddressChangeEvent + ); + ASSERT_EFI_ERROR (Status); +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c new file mode 100644 index 00000000000..0f96e1a47d7 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.c @@ -0,0 +1,141 @@ +/** @file + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +#include "RamFlash.h" + +VOID *mFlashBase; + +STATIC UINTN mFdBlockSize = 0; +STATIC UINTN mFdBlockCount = 0; + +STATIC +UINT8 * +RamFlashPtr ( + IN EFI_LBA Lba, + IN UINTN Offset + ) +{ + return mFlashBase + ((UINTN)Lba * mFdBlockSize) + Offset; +} + +/** + Read from Ram Flash + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +RamFlashRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINT8 *Ptr; + + // + // Only write to the first 64k. We don't bother saving the FTW Spare + // block into the flash memory. + // + if (Lba >= mFdBlockCount) { + return EFI_INVALID_PARAMETER; + } + + // + // Get flash address + // + Ptr = (UINT8 *)RamFlashPtr (Lba, Offset); + + CopyMem (Buffer, Ptr, *NumBytes); + + return EFI_SUCCESS; +} + +/** + Write to Ram Flash + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +RamFlashWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINT8 *Ptr; + UINTN i; + + // + // Only write to the first 64k. We don't bother saving the FTW Spare + // block into the flash memory. + // + if (Lba >= mFdBlockCount) { + return EFI_INVALID_PARAMETER; + } + + // + // Program flash + // + Ptr = RamFlashPtr (Lba, Offset); + for (i = 0; i < *NumBytes; i++) { + MmioWrite8 ((UINTN)Ptr, Buffer[i]); + Ptr++; + } + + return EFI_SUCCESS; +} + +/** + Erase a Ram Flash block + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +RamFlashEraseBlock ( + IN EFI_LBA Lba + ) +{ + return EFI_SUCCESS; +} + +/** + Initializes Ram flash memory support + + @retval EFI_WRITE_PROTECTED The Ram flash device is not present. + @retval EFI_SUCCESS The Ram flash device is supported. + +**/ +EFI_STATUS +RamFlashInitialize ( + VOID + ) +{ + mFlashBase = (UINT8 *)(UINTN)PcdGet32 (PcdVariableFdBaseAddress); + mFdBlockSize = PcdGet32 (PcdVariableFdBlockSize); + ASSERT (PcdGet32 (PcdVariableFdSize) % mFdBlockSize == 0); + mFdBlockCount = PcdGet32 (PcdVariableFdSize) / mFdBlockSize; + + return EFI_SUCCESS; +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h new file mode 100644 index 00000000000..e26246400f8 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlash.h @@ -0,0 +1,81 @@ +/** @file + Ram flash device for EFI variable + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef RAM_FLASH_H_ +#define RAM_FLASH_H_ + +#include + +extern VOID *mFlashBase; + +/** + Read from Ram Flash + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +RamFlashRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/** + Write to Ram Flash + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +RamFlashWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + +/** + Erase a Ram Flash block + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +RamFlashEraseBlock ( + IN EFI_LBA Lba + ); + +/** + Initializes Ram flash memory support + + @retval EFI_WRITE_PROTECTED The Ram flash device is not present. + @retval EFI_SUCCESS The Ram flash device is supported. + +**/ +EFI_STATUS +RamFlashInitialize ( + VOID + ); + +VOID +RamFlashConvertPointers ( + VOID + ); + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c new file mode 100644 index 00000000000..1fef9b70162 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/RamFvbServicesRuntimeDxe/RamFlashDxe.c @@ -0,0 +1,20 @@ +/** @file + Ram flash device for EFI variable + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include "RamFlash.h" + +VOID +RamFlashConvertPointers ( + VOID + ) +{ + EfiConvertPointer (0x0, (VOID **)&mFlashBase); +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.c b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.c new file mode 100644 index 00000000000..5c82a3cd0f5 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.c @@ -0,0 +1,315 @@ +/** @file + RISC-V Timer Architectural Protocol for U7 series platform. + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Boyang Han + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "Timer.h" +#include +#include +#include +#include +#include +#include + +BOOLEAN TimerHandlerReentry = FALSE; + +// +// The handle onto which the Timer Architectural Protocol will be installed +// +STATIC EFI_HANDLE mTimerHandle = NULL; + +// +// The Timer Architectural Protocol that this driver produces +// +EFI_TIMER_ARCH_PROTOCOL mTimer = { + TimerDriverRegisterHandler, + TimerDriverSetTimerPeriod, + TimerDriverGetTimerPeriod, + TimerDriverGenerateSoftInterrupt +}; + +// +// Pointer to the CPU Architectural Protocol instance +// +EFI_CPU_ARCH_PROTOCOL *mCpu; + +// +// The notification function to call on every timer interrupt. +// A bug in the compiler prevents us from initializing this here. +// +STATIC EFI_TIMER_NOTIFY mTimerNotifyFunction; + +// +// The current period of the timer interrupt +// +STATIC UINT64 mTimerPeriod = 0; + +/** + U7 Series Timer Interrupt Handler. + + @param InterruptType The type of interrupt that occured + @param SystemContext A pointer to the system context when the interrupt occured +**/ +VOID +EFIAPI +TimerInterruptHandler ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + EFI_TPL OriginalTPL; + UINT64 RiscvTimer; + + if (TimerHandlerReentry) { + // + // MMode timer occurred when processing + // SMode timer handler. + // + RiscvTimer = RiscVReadMachineTimerInterface (); + SbiSetTimer (RiscvTimer += mTimerPeriod); + csr_clear (CSR_SIP, MIP_STIP); + return; + } + + TimerHandlerReentry = TRUE; + + OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL); + csr_clear (CSR_SIE, MIP_STIP); // Disable SMode timer int + csr_clear (CSR_SIP, MIP_STIP); + if (mTimerPeriod == 0) { + gBS->RestoreTPL (OriginalTPL); + csr_clear (CSR_SIE, MIP_STIP); // Disable SMode timer int + return; + } + + if (mTimerNotifyFunction != NULL) { + mTimerNotifyFunction (mTimerPeriod); + } + + RiscvTimer = RiscVReadMachineTimerInterface (); + SbiSetTimer (RiscvTimer += mTimerPeriod); + gBS->RestoreTPL (OriginalTPL); + csr_set (CSR_SIE, MIP_STIP); // enable SMode timer int + TimerHandlerReentry = FALSE; +} + +/** + + This function registers the handler NotifyFunction so it is called every time + the timer interrupt fires. It also passes the amount of time since the last + handler call to the NotifyFunction. If NotifyFunction is NULL, then the + handler is unregistered. If the handler is registered, then EFI_SUCCESS is + returned. If the CPU does not support registering a timer interrupt handler, + then EFI_UNSUPPORTED is returned. If an attempt is made to register a handler + when a handler is already registered, then EFI_ALREADY_STARTED is returned. + If an attempt is made to unregister a handler when a handler is not registered, + then EFI_INVALID_PARAMETER is returned. If an error occurs attempting to + register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR + is returned. + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The function to call when a timer interrupt fires. This + function executes at TPL_HIGH_LEVEL. The DXE Core will + register a handler for the timer interrupt, so it can know + how much time has passed. This information is used to + signal timer based events. NULL will unregister the handler. + + @retval EFI_SUCCESS The timer handler was registered. + @retval EFI_UNSUPPORTED The platform does not support timer interrupts. + @retval EFI_ALREADY_STARTED NotifyFunction is not NULL, and a handler is already + registered. + @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not + previously registered. + @retval EFI_DEVICE_ERROR The timer handler could not be registered. + +**/ +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +{ + DEBUG ((DEBUG_INFO, "TimerDriverRegisterHandler(0x%lx) called\n", NotifyFunction)); + mTimerNotifyFunction = NotifyFunction; + return EFI_SUCCESS; +} + +/** + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +{ + UINT64 RiscvTimer; + + DEBUG ((DEBUG_INFO, "TimerDriverSetTimerPeriod(0x%lx)\n", TimerPeriod)); + + if (TimerPeriod == 0) { + mTimerPeriod = 0; + csr_clear (CSR_SIE, MIP_STIP); // disable timer int + return EFI_SUCCESS; + } + + mTimerPeriod = TimerPeriod; // convert unit from 100ns to 1us + RiscvTimer = RiscVReadMachineTimerInterface (); + SbiSetTimer (RiscvTimer + mTimerPeriod / 10); + + mCpu->EnableInterrupt (mCpu); + csr_set (CSR_SIE, MIP_STIP); // enable timer int + return EFI_SUCCESS; +} + +/** + + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +{ + *TimerPeriod = mTimerPeriod; + return EFI_SUCCESS; +} + +/** + + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft timer interrupts. + +**/ +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +{ + return EFI_SUCCESS; +} + +/** + Initialize the Timer Architectural Protocol driver + + @param ImageHandle ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Timer Architectural Protocol created + @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver. + @retval EFI_DEVICE_ERROR A device error occured attempting to initialize the driver. + +**/ +EFI_STATUS +EFIAPI +TimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + // + // Initialize the pointer to our notify function. + // + mTimerNotifyFunction = NULL; + + // + // Make sure the Timer Architectural Protocol is not already installed in the system + // + ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gEfiTimerArchProtocolGuid); + + // + // Find the CPU architectural protocol. + // + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&mCpu); + ASSERT_EFI_ERROR (Status); + + // + // Force the timer to be disabled + // + Status = TimerDriverSetTimerPeriod (&mTimer, 0); + ASSERT_EFI_ERROR (Status); + + // + // Install interrupt handler for RISC-V Timer. + // + Status = mCpu->RegisterInterruptHandler (mCpu, EXCEPT_RISCV_TIMER_INT, TimerInterruptHandler); + ASSERT_EFI_ERROR (Status); + + // + // Force the timer to be enabled at its default period + // + Status = TimerDriverSetTimerPeriod (&mTimer, DEFAULT_TIMER_TICK_DURATION); + ASSERT_EFI_ERROR (Status); + + // + // Install the Timer Architectural Protocol onto a new handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &mTimerHandle, + &gEfiTimerArchProtocolGuid, + &mTimer, + NULL + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.h b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.h new file mode 100644 index 00000000000..4b00951519b --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.h @@ -0,0 +1,179 @@ +/** @file + RISC-V Timer Architectural Protocol definitions for U7 Series platform, + + Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+ Copyright (c) 2022, Boyang Han + + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef U7_SERIES_TIMER_H_ +#define U7_SERIES_TIMER_H_ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +// +// RISC-V use 100us timer. +// The default timer tick duration is set to 10 ms = 10 * 1000 * 10 100 ns units +// +#define DEFAULT_TIMER_TICK_DURATION 100000 + +extern VOID +RiscvSetTimerPeriod ( + UINT32 TimerPeriod + ); + +// +// Function Prototypes +// + +/** + Initialize the Timer Architectural Protocol driver + + @param ImageHandle ImageHandle of the loaded driver + @param SystemTable Pointer to the System Table + + @retval EFI_SUCCESS Timer Architectural Protocol created + @retval EFI_OUT_OF_RESOURCES Not enough resources available to initialize driver. + @retval EFI_DEVICE_ERROR A device error occured attempting to initialize the driver. + +**/ +EFI_STATUS +EFIAPI +TimerDriverInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +; + +/** + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param NotifyFunction The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +EFI_STATUS +EFIAPI +TimerDriverRegisterHandler ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN EFI_TIMER_NOTIFY NotifyFunction + ) +; + +/** + + This function adjusts the period of timer interrupts to the value specified + by TimerPeriod. If the timer period is updated, then the selected timer + period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is returned. + If an error occurs while attempting to update the timer period, then the + timer hardware will be put back in its state prior to this call, and + EFI_DEVICE_ERROR is returned. If TimerPeriod is 0, then the timer interrupt + is disabled. This is not the same as disabling the CPU's interrupts. + Instead, it must either turn off the timer hardware, or it must adjust the + interrupt controller so that a CPU interrupt is not generated when the timer + interrupt fires. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod The rate to program the timer interrupt in 100 nS units. If + the timer hardware is not programmable, then EFI_UNSUPPORTED is + returned. If the timer is programmable, then the timer period + will be rounded up to the nearest timer period that is supported + by the timer hardware. If TimerPeriod is set to 0, then the + timer interrupts will be disabled. + + @retval EFI_SUCCESS The timer period was changed. + @retval EFI_UNSUPPORTED The platform cannot change the period of the timer interrupt. + @retval EFI_DEVICE_ERROR The timer period could not be changed due to a device error. + +**/ +EFI_STATUS +EFIAPI +TimerDriverSetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + IN UINT64 TimerPeriod + ) +; + +/** + + This function retrieves the period of timer interrupts in 100 ns units, + returns that value in TimerPeriod, and returns EFI_SUCCESS. If TimerPeriod + is NULL, then EFI_INVALID_PARAMETER is returned. If a TimerPeriod of 0 is + returned, then the timer is currently disabled. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + @param TimerPeriod A pointer to the timer period to retrieve in 100 ns units. If + 0 is returned, then the timer is currently disabled. + + @retval EFI_SUCCESS The timer period was returned in TimerPeriod. + @retval EFI_INVALID_PARAMETER TimerPeriod is NULL. + +**/ +EFI_STATUS +EFIAPI +TimerDriverGetTimerPeriod ( + IN EFI_TIMER_ARCH_PROTOCOL *This, + OUT UINT64 *TimerPeriod + ) +; + +/** + + This function generates a soft timer interrupt. If the platform does not support soft + timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned. + If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler() + service, then a soft timer interrupt will be generated. If the timer interrupt is + enabled when this service is called, then the registered handler will be invoked. The + registered handler should not be able to distinguish a hardware-generated timer + interrupt from a software-generated timer interrupt. + + + @param This The EFI_TIMER_ARCH_PROTOCOL instance. + + @retval EFI_SUCCESS The soft timer interrupt was generated. + @retval EFI_UNSUPPORTEDT The platform does not support the generation of soft timer interrupts. + +**/ +EFI_STATUS +EFIAPI +TimerDriverGenerateSoftInterrupt ( + IN EFI_TIMER_ARCH_PROTOCOL *This + ) +; + +#endif diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.uni b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.uni new file mode 100644 index 00000000000..08d8ac7ecdd --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/Timer.uni @@ -0,0 +1,14 @@ +// /** @file +// +// RISC-V Timer Arch protocol strings. +// +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "RISC-V timer driver that provides Timer Arch protocol" + +#string STR_MODULE_DESCRIPTION #language en-US "RISC-V timer driver that provides Timer Arch protocol." diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf new file mode 100644 index 00000000000..e6fd874c249 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerDxe.inf @@ -0,0 +1,55 @@ +## @file +# RISC-V Timer Arch protocol module for U7 Series platform +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# Copyright (c) 2022, Boyang Han +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = Timer + MODULE_UNI_FILE = Timer.uni + FILE_GUID = 182C47AC-8D8F-4E96-BE26-AEDD96F3BD80 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = TimerDriverInitialize +# +# The following information is for reference only and not required by the build +# tools. +# +# VALID_ARCHITECTURES = RISCV64 +# +[Packages] + MdePkg/MdePkg.dec + Platform/SiFive/U7SeriesPkg/U7SeriesPkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + MachineModeTimerLib + RiscVCpuLib + RiscVEdk2SbiLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Sources] + Timer.h + Timer.c + +[Protocols] + gEfiCpuArchProtocolGuid ## CONSUMES + gEfiTimerArchProtocolGuid ## PRODUCES + +[Pcd] + gUefiRiscVPkgTokenSpaceGuid.PcdRiscVMachineTimerFrequencyInHerz + +[Depex] + gEfiCpuArchProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + TimerExtra.uni diff --git a/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerExtra.uni b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerExtra.uni new file mode 100644 index 00000000000..7d7cc40b5e5 --- /dev/null +++ b/Platform/SiFive/U7SeriesPkg/Universal/Dxe/TimerDxe/TimerExtra.uni @@ -0,0 +1,12 @@ +// /** @file +// Timer Localized Strings and Content +// +// Copyright (c) 2016, Hewlett Packard Enterprise Development LP. All rights reserved.
+// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"RISC-V Timer DXE Driver" diff --git a/Silicon/SiFive/SiFive.dec b/Silicon/SiFive/SiFive.dec index bf280864be6..90fe4e07da4 100644 --- a/Silicon/SiFive/SiFive.dec +++ b/Silicon/SiFive/SiFive.dec @@ -30,6 +30,8 @@ gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU54CoreGuid |{0x64, 0x70, 0xF6, 0x90, 0x11, 0x59, 0x47, 0xF1, 0xB8, 0xD5, 0xCF, 0x89, 0x10, 0xC5, 0x30, 0x20}|VOID*|0x00001001 # U5 MC Coreplex GUID gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU5MCCoreplexGuid |{0x06, 0x38, 0x9F, 0x33, 0xF9, 0xDB, 0x43, 0x13, 0x9A, 0x9B, 0x1C, 0x68, 0xD6, 0x04, 0xEA, 0xFF}|VOID*|0x00001003 + # U74 Core GUID + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU74CoreGuid |{0x24, 0xB4, 0x19, 0xC7, 0x20, 0x46, 0x48, 0x27, 0x9F, 0x60, 0x1E, 0xEC, 0x38, 0x3D, 0xAE, 0x26}|VOID*|0x00001005 [PcdsDynamic, PcdsDynamicEx] diff --git a/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/CoreInfoHob.c b/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/CoreInfoHob.c new file mode 100644 index 00000000000..e7e31afd2f7 --- /dev/null +++ b/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/CoreInfoHob.c @@ -0,0 +1,234 @@ +/**@file + Build up platform processor information of SiFive U54 core. + + Copyright (c) 2019 - 2021, Hewlett Packard Enterprise Development LP. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +// +// The Library classes this module consumes +// +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/** + Function to build core specific information HOB for U54 or E51 core. + + @param ParentProcessorGuid Parent processor of this core. ParentProcessorGuid + could be the same as CoreGuid if one processor has + only one core. + @param ParentProcessorUid Unique ID of pysical processor which owns this core. + @param HartId Hart ID of this core. + @param IsBootHart TRUE means this is the boot HART. + @param IsManagementCore TRUE means this is for the E51 management core, not U54 + @param GuidHobData Pointer to RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. + + @return EFI_SUCCESS The PEIM initialized successfully. + EFI_UNSUPPORTED HART is ignored by platform. + EFI_NOT_FOUND Processor specific data hob is not available. +**/ +EFI_STATUS +EFIAPI +CreateU54E51CoreProcessorSpecificDataHob ( + IN EFI_GUID *ParentProcessorGuid, + IN UINTN ParentProcessorUid, + IN UINTN HartId, + IN BOOLEAN IsBootHart, + IN BOOLEAN IsManagementCore, + OUT RISC_V_PROCESSOR_SPECIFIC_HOB_DATA **GuidHobData + ) +{ + RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *CoreGuidHob; + EFI_GUID *ProcessorSpecDataHobGuid; + RISC_V_PROCESSOR_SPECIFIC_HOB_DATA ProcessorSpecDataHob; + EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT *FirmwareContext; + EFI_RISCV_FIRMWARE_CONTEXT_HART_SPECIFIC *FirmwareContextHartSpecific; + + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); + + if (GuidHobData == NULL) { + return EFI_INVALID_PARAMETER; + } + + GetFirmwareContextPointer (&FirmwareContext); + ASSERT (FirmwareContext != NULL); + if (FirmwareContext == NULL) { + DEBUG ((DEBUG_ERROR, "Failed to get the pointer of EFI_RISCV_OPENSBI_FIRMWARE_CONTEXT of hart %d\n", HartId)); + return EFI_NOT_FOUND; + } + + DEBUG ((DEBUG_INFO, " Firmware Context is at 0x%x.\n", FirmwareContext)); + + FirmwareContextHartSpecific = FirmwareContext->HartSpecific[HartId]; + DEBUG ((DEBUG_INFO, " Firmware Context Hart specific is at 0x%x.\n", FirmwareContextHartSpecific)); + if (FirmwareContextHartSpecific == NULL) { + DEBUG ((DEBUG_INFO, " This hart: %d is ignored by platform.\n", HartId)); + return EFI_UNSUPPORTED; + } + + // + // Build up RISC_V_PROCESSOR_SPECIFIC_HOB_DATA. + // + CommonFirmwareContextHartSpecificInfo ( + FirmwareContextHartSpecific, + ParentProcessorGuid, + ParentProcessorUid, + (EFI_GUID *)PcdGetPtr (PcdSiFiveU54CoreGuid), + HartId, + IsBootHart, + &ProcessorSpecDataHob + ); + + ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_L = TO_BE_FILLED; + ProcessorSpecDataHob.ProcessorSpecificData.MModeExcepDelegation.Value64_H = TO_BE_FILLED; + ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_L = TO_BE_FILLED; + ProcessorSpecDataHob.ProcessorSpecificData.MModeInterruptDelegation.Value64_H = TO_BE_FILLED; + ProcessorSpecDataHob.ProcessorSpecificData.HartXlen = RegisterLen64; + ProcessorSpecDataHob.ProcessorSpecificData.MachineModeXlen = RegisterLen64; + ProcessorSpecDataHob.ProcessorSpecificData.UserModeXlen = RegisterLen64; + + if (IsManagementCore) { + // Configuration for E51 + ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen = RegisterUnsupported; + } else { + // Configuration for U54 + ProcessorSpecDataHob.ProcessorSpecificData.SupervisorModeXlen = RegisterLen64; + } + + DebugPrintHartSpecificInfo (&ProcessorSpecDataHob); + + // + // Build GUID HOB for core, this is for SMBIOS type 44 + // + ProcessorSpecDataHobGuid = PcdGetPtr (PcdProcessorSpecificDataGuidHobGuid); + CoreGuidHob = (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA *)BuildGuidDataHob (ProcessorSpecDataHobGuid, (VOID *)&ProcessorSpecDataHob, sizeof (RISC_V_PROCESSOR_SPECIFIC_HOB_DATA)); + if (CoreGuidHob == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U54 core.\n")); + ASSERT (FALSE); + } + + *GuidHobData = CoreGuidHob; + return EFI_SUCCESS; +} + +/** + Function to build cache related SMBIOS information. RISC-V SMBIOS DXE driver collects + this information and builds SMBIOS Type 7 record. + + The caller can adjust the allocated hob data to their needs. + + @param ProcessorUid Unique ID of physical processor which owns this core. + @param L1CacheDataHobPtr Pointer to allocated HOB data. + +**/ +VOID +EFIAPI +CreateU54SmbiosType7L1DataHob ( + IN UINTN ProcessorUid, + OUT RISC_V_PROCESSOR_TYPE7_HOB_DATA **L1CacheDataHobPtr + ) +{ + EFI_GUID *GuidPtr; + RISC_V_PROCESSOR_TYPE7_HOB_DATA L1CacheDataHob; + + // + // Build up SMBIOS type 7 L1 cache record. + // + ZeroMem ((VOID *)&L1CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + L1CacheDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid)); + L1CacheDataHob.ProcessorUid = ProcessorUid; + L1CacheDataHob.SmbiosType7Cache.SocketDesignation = TO_BE_FILLED_BY_VENDOR; + L1CacheDataHob.SmbiosType7Cache.CacheConfiguration = RISC_V_CACHE_CONFIGURATION_CACHE_LEVEL_1 | \ + RISC_V_CACHE_CONFIGURATION_LOCATION_INTERNAL | \ + RISC_V_CACHE_CONFIGURATION_ENABLED | \ + RISC_V_CACHE_CONFIGURATION_MODE_UNKNOWN; + L1CacheDataHob.SmbiosType7Cache.MaximumCacheSize = TO_BE_FILLED_BY_VENDOR; + L1CacheDataHob.SmbiosType7Cache.InstalledSize = TO_BE_FILLED_BY_VENDOR; + L1CacheDataHob.SmbiosType7Cache.SupportedSRAMType.Unknown = 1; + L1CacheDataHob.SmbiosType7Cache.CurrentSRAMType.Unknown = 1; + L1CacheDataHob.SmbiosType7Cache.CacheSpeed = TO_BE_FILLED_BY_VENDOR; + L1CacheDataHob.SmbiosType7Cache.ErrorCorrectionType = TO_BE_FILLED_BY_VENDOR; + L1CacheDataHob.SmbiosType7Cache.SystemCacheType = CacheTypeUnified; + L1CacheDataHob.SmbiosType7Cache.Associativity = TO_BE_FILLED_BY_VENDOR; + + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType7GuidHobGuid); + *L1CacheDataHobPtr = (RISC_V_PROCESSOR_TYPE7_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&L1CacheDataHob, sizeof (RISC_V_PROCESSOR_TYPE7_HOB_DATA)); + if (L1CacheDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5 MC Coreplex L1 cache RISC_V_PROCESSOR_TYPE7_HOB_DATA.\n")); + ASSERT (FALSE); + } +} + +/** + Function to build processor related SMBIOS information. RISC-V SMBIOS DXE driver collects + this information and builds SMBIOS Type 4 record. + + The caller can adjust the allocated hob data to their needs. + + @param ProcessorUid Unique ID of physical processor which owns this core. + @param ProcessorDataHobPtr Pointer to allocated HOB data. + +**/ +VOID +EFIAPI +CreateU54SmbiosType4DataHob ( + IN UINTN ProcessorUid, + OUT RISC_V_PROCESSOR_TYPE4_HOB_DATA **ProcessorDataHobPtr + ) +{ + EFI_GUID *GuidPtr; + RISC_V_PROCESSOR_TYPE4_HOB_DATA ProcessorDataHob; + + // + // Build up SMBIOS type 4 record. + // + ZeroMem ((VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); + ProcessorDataHob.PrcessorGuid = *((EFI_GUID *)PcdGetPtr (PcdSiFiveU5MCCoreplexGuid)); + ProcessorDataHob.ProcessorUid = ProcessorUid; + ProcessorDataHob.SmbiosType4Processor.Socket = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.ProcessorType = CentralProcessor; + ProcessorDataHob.SmbiosType4Processor.ProcessorFamily = ProcessorFamilyIndicatorFamily2; + ProcessorDataHob.SmbiosType4Processor.ProcessorManufacturer = TO_BE_FILLED_BY_VENDOR; + SetMem ((VOID *)&ProcessorDataHob.SmbiosType4Processor.ProcessorId, sizeof (PROCESSOR_ID_DATA), TO_BE_FILLED_BY_CODE); + ProcessorDataHob.SmbiosType4Processor.ProcessorVersion = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.Voltage.ProcessorVoltageCapability3_3V = 1; + ProcessorDataHob.SmbiosType4Processor.ExternalClock = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.MaxSpeed = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.CurrentSpeed = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.Status = TO_BE_FILLED_BY_CODE; + ProcessorDataHob.SmbiosType4Processor.ProcessorUpgrade = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.L1CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; + ProcessorDataHob.SmbiosType4Processor.L2CacheHandle = TO_BE_FILLED_BY_RISC_V_SMBIOS_DXE_DRIVER; + ProcessorDataHob.SmbiosType4Processor.L3CacheHandle = 0xffff; + ProcessorDataHob.SmbiosType4Processor.SerialNumber = TO_BE_FILLED_BY_CODE; + ProcessorDataHob.SmbiosType4Processor.AssetTag = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.PartNumber = TO_BE_FILLED_BY_VENDOR; + ProcessorDataHob.SmbiosType4Processor.CoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); + ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); + ProcessorDataHob.SmbiosType4Processor.ThreadCount = (UINT8)FixedPcdGet32 (PcdNumberofU5Cores) + (UINT8)PcdGetBool (PcdE5MCSupported); + ProcessorDataHob.SmbiosType4Processor.ProcessorCharacteristics = (UINT16)(1 << 2); // 64-bit capable + ProcessorDataHob.SmbiosType4Processor.ProcessorFamily2 = ProcessorFamilyRiscVRV64; + ProcessorDataHob.SmbiosType4Processor.CoreCount2 = 0; + ProcessorDataHob.SmbiosType4Processor.EnabledCoreCount2 = 0; + ProcessorDataHob.SmbiosType4Processor.ThreadCount2 = 0; + + GuidPtr = (EFI_GUID *)PcdGetPtr (PcdProcessorSmbiosType4GuidHobGuid); + *ProcessorDataHobPtr = (RISC_V_PROCESSOR_TYPE4_HOB_DATA *)BuildGuidDataHob (GuidPtr, (VOID *)&ProcessorDataHob, sizeof (RISC_V_PROCESSOR_TYPE4_HOB_DATA)); + if (ProcessorDataHobPtr == NULL) { + DEBUG ((DEBUG_ERROR, "Fail to create GUID HOB of SiFive U5MC Coreplex RISC_V_PROCESSOR_TYPE4_HOB_DATA.\n")); + ASSERT (FALSE); + } +} diff --git a/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf b/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf new file mode 100644 index 00000000000..1e3d3508647 --- /dev/null +++ b/Silicon/SiFive/U74/Library/PeiCoreInfoHobLib/PeiCoreInfoHobLib.inf @@ -0,0 +1,51 @@ +## @file +# Library instance to create core information HOB +# +# Copyright (c) 2019, Hewlett Packard Enterprise Development LP. All rights reserved.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x0001001b + BASE_NAME = SiliconSiFiveU54CoreInfoLib + FILE_GUID = 483DE090-267E-4278-A0A1-15D9836780EA + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + LIBRARY_CLASS = SiliconSiFiveU54CoreInfoLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = RISCV64 +# + +[Sources] + CoreInfoHob.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + Silicon/RISC-V/ProcessorPkg/RiscVProcessorPkg.dec + Platform/RISC-V/PlatformPkg/RiscVPlatformPkg.dec + Platform/SiFive/U5SeriesPkg/U7SeriesPkg.dec + Silicon/SiFive/SiFive.dec + +[LibraryClasses] + BaseLib + PcdLib + MemoryAllocationLib + PrintLib + FirmwareContextProcessorSpecificLib + RiscVEdk2SbiLib + +[FixedPcd] + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSpecificDataGuidHobGuid + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosGuidHobGuid + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType4GuidHobGuid + gUefiRiscVPkgTokenSpaceGuid.PcdProcessorSmbiosType7GuidHobGuid + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU54CoreGuid + gEfiSiFiveSiliconTokenSpaceGuid.PcdSiFiveU5MCCoreplexGuid + gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdNumberofU5Cores + gSiFiveU5SeriesPlatformsPkgTokenSpaceGuid.PcdE5MCSupported