From 6453b2cb9c8cccf0c25e11ee2ad241c2ad0491fa Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Wed, 15 Mar 2023 18:44:10 +0800 Subject: [PATCH 01/16] usb: cdns3: add StarFive JH7110 USB driver. There is a Cadence USB3 core for JH7110 SoCs, the cdns core is the child of this USB wrapper module device. Signed-off-by: Minda Chen --- MAINTAINERS | 14 ++ drivers/usb/cdns3/Kconfig | 11 ++ drivers/usb/cdns3/Makefile | 1 + drivers/usb/cdns3/cdns3-starfive.c | 305 +++++++++++++++++++++++++++++++++++++ 4 files changed, 331 insertions(+) create mode 100644 drivers/usb/cdns3/cdns3-starfive.c diff --git a/MAINTAINERS b/MAINTAINERS index ef37618..7433cf2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19725,6 +19725,20 @@ F: Documentation/devicetree/bindings/reset/starfive,jh7100-reset.yaml F: drivers/reset/starfive/reset-starfive-jh71* F: include/dt-bindings/reset/starfive?jh71*.h +STARFIVE JH71X0 USB DRIVERS +M: Emil Renner Berthing +M: Minda Chen +S: Maintained +F: Documentation/devicetree/bindings/usb/starfive,jh7110-usb.yaml +F: drivers/usb/cdns3/cdns3-starfive.c + +STARFIVE JH71XX PMU CONTROLLER DRIVER +M: Walker Chen +S: Supported +F: Documentation/devicetree/bindings/power/starfive* +F: drivers/soc/starfive/jh71xx_pmu.c +F: include/dt-bindings/power/starfive,jh7110-pmu.h + STARFIVE SOC DRIVERS M: Conor Dooley S: Maintained diff --git a/drivers/usb/cdns3/Kconfig b/drivers/usb/cdns3/Kconfig index b98ca0a..0a514b5 100644 --- a/drivers/usb/cdns3/Kconfig +++ b/drivers/usb/cdns3/Kconfig @@ -78,6 +78,17 @@ config USB_CDNS3_IMX For example, imx8qm and imx8qxp. +config USB_CDNS3_STARFIVE + tristate "Cadence USB3 support on StarFive SoC platforms" + depends on ARCH_STARFIVE || COMPILE_TEST + help + Say 'Y' or 'M' here if you are building for StarFive SoCs + platforms that contain Cadence USB3 controller core. + + e.g. JH7110. + + If you choose to build this driver as module it will + be dynamically linked and module will be called cdns3-starfive.ko endif if USB_CDNS_SUPPORT diff --git a/drivers/usb/cdns3/Makefile b/drivers/usb/cdns3/Makefile index 61edb2f..48dfae7 100644 --- a/drivers/usb/cdns3/Makefile +++ b/drivers/usb/cdns3/Makefile @@ -24,6 +24,7 @@ endif obj-$(CONFIG_USB_CDNS3_PCI_WRAP) += cdns3-pci-wrap.o obj-$(CONFIG_USB_CDNS3_TI) += cdns3-ti.o obj-$(CONFIG_USB_CDNS3_IMX) += cdns3-imx.o +obj-$(CONFIG_USB_CDNS3_STARFIVE) += cdns3-starfive.o cdnsp-udc-pci-y := cdnsp-pci.o diff --git a/drivers/usb/cdns3/cdns3-starfive.c b/drivers/usb/cdns3/cdns3-starfive.c new file mode 100644 index 0000000..a99f98f --- /dev/null +++ b/drivers/usb/cdns3/cdns3-starfive.c @@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * cdns3-starfive.c - StarFive specific Glue layer for Cadence USB Controller + * + * Copyright (C) 2022 Starfive, Inc. + * Author: Yanhong Wang + * Author: Mason Huo + * Author: Minda Chen + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" + +#define USB_STRAP_HOST BIT(17) +#define USB_STRAP_DEVICE BIT(18) +#define USB_STRAP_MASK GENMASK(18, 16) + +#define USB_SUSPENDM_HOST BIT(19) +#define USB_SUSPENDM_MASK BIT(19) + +#define USB_SUSPENDM_BYPS BIT(20) +#define USB_REFCLK_MODE BIT(23) +#define USB_PLL_EN BIT(22) +#define USB_PDRSTN_SPLIT BIT(17) + +#define PCIE_CKREF_SRC_MASK GENMASK(19, 18) +#define PCIE_CLK_SEL_MASK GENMASK(21, 20) +#define PCIE_PHY_MODE BIT(20) +#define PCIE_PHY_MODE_MASK GENMASK(21, 20) +#define PCIE_USB3_BUS_WIDTH_MASK GENMASK(3, 2) +#define PCIE_USB3_RATE_MASK GENMASK(6, 5) +#define PCIE_USB3_RX_STANDBY_MASK BIT(7) +#define PCIE_USB3_PHY_ENABLE BIT(4) + +struct cdns_starfive { + struct device *dev; + struct regmap *stg_syscon; + struct regmap *sys_syscon; + struct reset_control *resets; + struct clk_bulk_data *clks; + int num_clks; + u32 sys_offset; + u32 stg_offset_4; + u32 stg_offset_196; + u32 stg_offset_328; + u32 stg_offset_500; + bool usb2_only; +}; + +static int cdns_mode_init(struct platform_device *pdev, + struct cdns_starfive *data, const char **out_mode) +{ + struct device_node *child; + const char *dr_mode = NULL; + + child = of_get_compatible_child(pdev->dev.of_node, "cdns,usb3"); + if (!child) { + return dev_err_probe(&pdev->dev, -ENODEV, + "Failed to find child node\n"); + } + + /* Init usb 2.0 utmi phy */ + regmap_update_bits(data->stg_syscon, data->stg_offset_4, + USB_SUSPENDM_BYPS, USB_SUSPENDM_BYPS); + regmap_update_bits(data->stg_syscon, data->stg_offset_4, + USB_PLL_EN, USB_PLL_EN); + regmap_update_bits(data->stg_syscon, data->stg_offset_4, + USB_REFCLK_MODE, USB_REFCLK_MODE); + + if (!of_find_property(child, "cdns3,usb3-phy", NULL)) { + /* Disconnect usb 3.0 phy mode */ + regmap_update_bits(data->sys_syscon, data->sys_offset, + USB_PDRSTN_SPLIT, USB_PDRSTN_SPLIT); + data->usb2_only = 1; + } else { + /* Config usb 3.0 pipe phy */ + regmap_update_bits(data->stg_syscon, data->stg_offset_196, + PCIE_CKREF_SRC_MASK, 0); + regmap_update_bits(data->stg_syscon, data->stg_offset_196, + PCIE_CLK_SEL_MASK, 0); + regmap_update_bits(data->stg_syscon, data->stg_offset_328, + PCIE_PHY_MODE_MASK, PCIE_PHY_MODE); + regmap_update_bits(data->stg_syscon, data->stg_offset_500, + PCIE_USB3_BUS_WIDTH_MASK, 0); + regmap_update_bits(data->stg_syscon, data->stg_offset_500, + PCIE_USB3_RATE_MASK, 0); + regmap_update_bits(data->stg_syscon, data->stg_offset_500, + PCIE_USB3_RX_STANDBY_MASK, 0); + regmap_update_bits(data->stg_syscon, data->stg_offset_500, + PCIE_USB3_PHY_ENABLE, PCIE_USB3_PHY_ENABLE); + + /* Connect usb 3.0 phy mode */ + regmap_update_bits(data->sys_syscon, data->sys_offset, + USB_PDRSTN_SPLIT, 0); + } + + if (!of_property_read_string(child, "dr_mode", &dr_mode)) { + if (!strcmp(dr_mode, "host")) { + regmap_update_bits(data->stg_syscon, + data->stg_offset_4, + USB_STRAP_MASK, + USB_STRAP_HOST); + regmap_update_bits(data->stg_syscon, + data->stg_offset_4, + USB_SUSPENDM_MASK, + USB_SUSPENDM_HOST); + } else if (!strcmp(dr_mode, "peripheral")) { + regmap_update_bits(data->stg_syscon, data->stg_offset_4, + USB_STRAP_MASK, USB_STRAP_DEVICE); + regmap_update_bits(data->stg_syscon, data->stg_offset_4, + USB_SUSPENDM_MASK, 0); + } + } + + if (out_mode) + *out_mode = dr_mode; + + return 0; +} + +static int cdns_clk_rst_init(struct cdns_starfive *data) +{ + int ret; + + data->num_clks = devm_clk_bulk_get_all(data->dev, &data->clks); + if (data->num_clks < 0) + return dev_err_probe(data->dev, -ENODEV, + "Failed to get clocks\n"); + + ret = clk_bulk_prepare_enable(data->num_clks, data->clks); + if (ret) + return dev_err_probe(data->dev, ret, + "failed to enable clocks\n"); + + data->resets = devm_reset_control_array_get_exclusive(data->dev); + if (IS_ERR(data->resets)) { + ret = dev_err_probe(data->dev, PTR_ERR(data->resets), + "Failed to get resets"); + goto err_clk_init; + } + + ret = reset_control_deassert(data->resets); + if (ret) { + ret = dev_err_probe(data->dev, ret, + "failed to reset clocks\n"); + goto err_clk_init; + } + + return ret; + +err_clk_init: + clk_bulk_disable_unprepare(data->num_clks, data->clks); + return ret; +} + +static int cdns_starfive_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *node = pdev->dev.of_node; + struct cdns_starfive *data; + unsigned int args[4]; + const char *dr_mode; + int ret; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + platform_set_drvdata(pdev, data); + + data->dev = dev; + + data->stg_syscon = syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node, + "starfive,stg-syscon", 4, args); + + if (IS_ERR(data->stg_syscon)) + return dev_err_probe(dev, PTR_ERR(data->stg_syscon), + "Failed to parse starfive,stg-syscon\n"); + + data->stg_offset_4 = args[0]; + data->stg_offset_196 = args[1]; + data->stg_offset_328 = args[2]; + data->stg_offset_500 = args[3]; + + data->sys_syscon = syscon_regmap_lookup_by_phandle_args(pdev->dev.of_node, + "starfive,sys-syscon", 1, args); + if (IS_ERR(data->sys_syscon)) + return dev_err_probe(dev, PTR_ERR(data->sys_syscon), + "Failed to parse starfive,sys-syscon\n"); + + data->sys_offset = args[0]; + + ret = cdns_mode_init(pdev, data, &dr_mode); + if (ret) + return ret; + + ret = cdns_clk_rst_init(data); + if (ret) + return ret; + + ret = of_platform_populate(node, NULL, NULL, dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to create children\n"); + + device_set_wakeup_capable(dev, true); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + dev_info(dev, "usb mode %s %s probe success\n", + dr_mode ? dr_mode : "unknown", data->usb2_only ? "2.0" : "3.0"); + + return 0; +} + +static int cdns_starfive_remove_core(struct device *dev, void *c) +{ + struct platform_device *pdev = to_platform_device(dev); + + platform_device_unregister(pdev); + + return 0; +} + +static int cdns_starfive_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cdns_starfive *data = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + device_for_each_child(dev, NULL, cdns_starfive_remove_core); + + reset_control_assert(data->resets); + clk_bulk_disable_unprepare(data->num_clks, data->clks); + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM +static int cdns_starfive_resume(struct device *dev) +{ + struct cdns_starfive *data = dev_get_drvdata(dev); + int ret; + + ret = clk_bulk_prepare_enable(data->num_clks, data->clks); + if (ret) + return ret; + + ret = reset_control_deassert(data->resets); + if (ret) + return ret; + + return 0; +} + +static int cdns_starfive_suspend(struct device *dev) +{ + struct cdns_starfive *data = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(data->num_clks, data->clks); + reset_control_assert(data->resets); + + return 0; +} +#endif + +static const struct dev_pm_ops cdns_starfive_pm_ops = { + SET_RUNTIME_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(cdns_starfive_suspend, cdns_starfive_resume) +}; + +static const struct of_device_id cdns_starfive_of_match[] = { + { .compatible = "starfive,jh7110-usb", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, cdns_starfive_of_match); + +static struct platform_driver cdns_starfive_driver = { + .probe = cdns_starfive_probe, + .remove = cdns_starfive_remove, + .driver = { + .name = "cdns3-starfive", + .of_match_table = cdns_starfive_of_match, + .pm = &cdns_starfive_pm_ops, + }, +}; +module_platform_driver(cdns_starfive_driver); + +MODULE_ALIAS("platform:cdns3-starfive"); +MODULE_AUTHOR("YanHong Wang "); +MODULE_AUTHOR("Mason Huo "); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Cadence USB3 StarFive Glue Layer"); -- 2.7.4 From cc73f9d7faf0ca011e8e39bf45cd2b4283301071 Mon Sep 17 00:00:00 2001 From: Minda Chen Date: Wed, 15 Mar 2023 18:44:11 +0800 Subject: [PATCH 02/16] dts: usb: add StarFive JH7110 USB dts configuration. USB Glue layer and Cadence USB subnode configuration, also includes USB and PCIe phy dts configuration. Signed-off-by: Minda Chen --- .../dts/starfive/jh7110-starfive-visionfive-2.dtsi | 7 +++ arch/riscv/boot/dts/starfive/jh7110.dtsi | 54 ++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi index b4808fe..752bb0b 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi @@ -326,3 +326,10 @@ pinctrl-0 = <&uart0_pins>; status = "okay"; }; + +&usb0 { + status = "okay"; + usbdrd_cdns3: usb@0 { + dr_mode = "peripheral"; + }; +}; diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index 61f4de8..95abd5f 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi @@ -382,6 +382,60 @@ status = "disabled"; }; + usb0: usb@10100000 { + compatible = "starfive,jh7110-usb"; + clocks = <&stgcrg JH7110_STGCLK_USB0_LPM>, + <&stgcrg JH7110_STGCLK_USB0_STB>, + <&stgcrg JH7110_STGCLK_USB0_APB>, + <&stgcrg JH7110_STGCLK_USB0_AXI>, + <&stgcrg JH7110_STGCLK_USB0_UTMI_APB>; + clock-names = "lpm", "stb", "apb", "axi", "utmi_apb"; + resets = <&stgcrg JH7110_STGRST_USB0_PWRUP>, + <&stgcrg JH7110_STGRST_USB0_APB>, + <&stgcrg JH7110_STGRST_USB0_AXI>, + <&stgcrg JH7110_STGRST_USB0_UTMI_APB>; + starfive,stg-syscon = <&stg_syscon 0x4 0xc4 0x148 0x1f4>; + starfive,sys-syscon = <&sys_syscon 0x18>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x10100000 0x100000>; + + usbdrd_cdns3: usb@0 { + compatible = "cdns,usb3"; + reg = <0x0 0x10000>, + <0x10000 0x10000>, + <0x20000 0x10000>; + reg-names = "otg", "xhci", "dev"; + interrupts = <100>, <108>, <110>; + interrupt-names = "host", "peripheral", "otg"; + phys = <&usbphy0>; + phy-names = "cdns3,usb2-phy"; + maximum-speed = "super-speed"; + }; + }; + + usbphy0: phy@10200000 { + compatible = "starfive,jh7110-usb-phy"; + reg = <0x0 0x10200000 0x0 0x10000>; + clocks = <&syscrg JH7110_SYSCLK_USB_125M>, + <&stgcrg JH7110_STGCLK_USB0_APP_125>; + clock-names = "125m", "app_125"; + #phy-cells = <0>; + }; + + pciephy0: phy@10210000 { + compatible = "starfive,jh7110-pcie-phy"; + reg = <0x0 0x10210000 0x0 0x10000>; + #phy-cells = <0>; + }; + + pciephy1: phy@10220000 { + compatible = "starfive,jh7110-pcie-phy"; + reg = <0x0 0x10220000 0x0 0x10000>; + #phy-cells = <0>; + }; + stgcrg: clock-controller@10230000 { compatible = "starfive,jh7110-stgcrg"; reg = <0x0 0x10230000 0x0 0x10000>; -- 2.7.4 From 60b15feb55b083a04cddbb3ddbd5f7ef81dc3285 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Tue, 14 Mar 2023 13:03:13 +0800 Subject: [PATCH 03/16] RISC-V: Change suspend_save_csrs and suspend_restore_csrs to public function Currently suspend_save_csrs() and suspend_restore_csrs() functions are statically defined in the suspend.c. Change the function's attribute to public so that the functions can be used by hibernation as well. Signed-off-by: Sia Jee Heng Reviewed-by: Ley Foon Tan Reviewed-by: Mason Huo Reviewed-by: Conor Dooley Reviewed-by: Andrew Jones --- arch/riscv/include/asm/suspend.h | 3 +++ arch/riscv/kernel/suspend.c | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h index 8be391c..67e0474 100644 --- a/arch/riscv/include/asm/suspend.h +++ b/arch/riscv/include/asm/suspend.h @@ -33,4 +33,7 @@ int cpu_suspend(unsigned long arg, /* Low-level CPU resume entry function */ int __cpu_resume_enter(unsigned long hartid, unsigned long context); +/* Used to save and restore the CSRs */ +void suspend_save_csrs(struct suspend_context *context); +void suspend_restore_csrs(struct suspend_context *context); #endif diff --git a/arch/riscv/kernel/suspend.c b/arch/riscv/kernel/suspend.c index 9ba24fb..3c89b8e 100644 --- a/arch/riscv/kernel/suspend.c +++ b/arch/riscv/kernel/suspend.c @@ -8,7 +8,7 @@ #include #include -static void suspend_save_csrs(struct suspend_context *context) +void suspend_save_csrs(struct suspend_context *context) { context->scratch = csr_read(CSR_SCRATCH); context->tvec = csr_read(CSR_TVEC); @@ -29,7 +29,7 @@ static void suspend_save_csrs(struct suspend_context *context) #endif } -static void suspend_restore_csrs(struct suspend_context *context) +void suspend_restore_csrs(struct suspend_context *context) { csr_write(CSR_SCRATCH, context->scratch); csr_write(CSR_TVEC, context->tvec); -- 2.7.4 From 00913b2fdb409a17daefe9074c62aab97c8195fb Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Tue, 14 Mar 2023 13:03:14 +0800 Subject: [PATCH 04/16] RISC-V: Factor out common code of __cpu_resume_enter() The cpu_resume() function is very similar for the suspend to disk and suspend to ram cases. Factor out the common code into suspend_restore_csrs macro and suspend_restore_regs macro. Signed-off-by: Sia Jee Heng Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley --- arch/riscv/include/asm/assembler.h | 62 ++++++++++++++++++++++++++++++++++++++ arch/riscv/kernel/suspend_entry.S | 34 ++------------------- 2 files changed, 65 insertions(+), 31 deletions(-) create mode 100644 arch/riscv/include/asm/assembler.h diff --git a/arch/riscv/include/asm/assembler.h b/arch/riscv/include/asm/assembler.h new file mode 100644 index 0000000..ba59d38 --- /dev/null +++ b/arch/riscv/include/asm/assembler.h @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * + * Author: Jee Heng Sia + */ + +#ifndef __ASSEMBLY__ +#error "Only include this from assembly code" +#endif + +#ifndef __ASM_ASSEMBLER_H +#define __ASM_ASSEMBLER_H + +#include +#include +#include + +/* + * suspend_restore_csrs - restore CSRs + */ + .macro suspend_restore_csrs + REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0) + csrw CSR_EPC, t0 + REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0) + csrw CSR_STATUS, t0 + REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0) + csrw CSR_TVAL, t0 + REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0) + csrw CSR_CAUSE, t0 + .endm + +/* + * suspend_restore_regs - Restore registers (except A0 and T0-T6) + */ + .macro suspend_restore_regs + REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0) + REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0) + REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0) + REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0) + REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0) + REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0) + REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0) + REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0) + REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0) + REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0) + REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0) + REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0) + REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0) + REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0) + REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0) + REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0) + REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0) + REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0) + REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0) + REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0) + REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0) + REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0) + REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0) + .endm + +#endif /* __ASM_ASSEMBLER_H */ diff --git a/arch/riscv/kernel/suspend_entry.S b/arch/riscv/kernel/suspend_entry.S index aafcca5..12b52af 100644 --- a/arch/riscv/kernel/suspend_entry.S +++ b/arch/riscv/kernel/suspend_entry.S @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -83,39 +84,10 @@ ENTRY(__cpu_resume_enter) add a0, a1, zero /* Restore CSRs */ - REG_L t0, (SUSPEND_CONTEXT_REGS + PT_EPC)(a0) - csrw CSR_EPC, t0 - REG_L t0, (SUSPEND_CONTEXT_REGS + PT_STATUS)(a0) - csrw CSR_STATUS, t0 - REG_L t0, (SUSPEND_CONTEXT_REGS + PT_BADADDR)(a0) - csrw CSR_TVAL, t0 - REG_L t0, (SUSPEND_CONTEXT_REGS + PT_CAUSE)(a0) - csrw CSR_CAUSE, t0 + suspend_restore_csrs /* Restore registers (except A0 and T0-T6) */ - REG_L ra, (SUSPEND_CONTEXT_REGS + PT_RA)(a0) - REG_L sp, (SUSPEND_CONTEXT_REGS + PT_SP)(a0) - REG_L gp, (SUSPEND_CONTEXT_REGS + PT_GP)(a0) - REG_L tp, (SUSPEND_CONTEXT_REGS + PT_TP)(a0) - REG_L s0, (SUSPEND_CONTEXT_REGS + PT_S0)(a0) - REG_L s1, (SUSPEND_CONTEXT_REGS + PT_S1)(a0) - REG_L a1, (SUSPEND_CONTEXT_REGS + PT_A1)(a0) - REG_L a2, (SUSPEND_CONTEXT_REGS + PT_A2)(a0) - REG_L a3, (SUSPEND_CONTEXT_REGS + PT_A3)(a0) - REG_L a4, (SUSPEND_CONTEXT_REGS + PT_A4)(a0) - REG_L a5, (SUSPEND_CONTEXT_REGS + PT_A5)(a0) - REG_L a6, (SUSPEND_CONTEXT_REGS + PT_A6)(a0) - REG_L a7, (SUSPEND_CONTEXT_REGS + PT_A7)(a0) - REG_L s2, (SUSPEND_CONTEXT_REGS + PT_S2)(a0) - REG_L s3, (SUSPEND_CONTEXT_REGS + PT_S3)(a0) - REG_L s4, (SUSPEND_CONTEXT_REGS + PT_S4)(a0) - REG_L s5, (SUSPEND_CONTEXT_REGS + PT_S5)(a0) - REG_L s6, (SUSPEND_CONTEXT_REGS + PT_S6)(a0) - REG_L s7, (SUSPEND_CONTEXT_REGS + PT_S7)(a0) - REG_L s8, (SUSPEND_CONTEXT_REGS + PT_S8)(a0) - REG_L s9, (SUSPEND_CONTEXT_REGS + PT_S9)(a0) - REG_L s10, (SUSPEND_CONTEXT_REGS + PT_S10)(a0) - REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0) + suspend_restore_regs /* Return zero value */ add a0, zero, zero -- 2.7.4 From 3de30b400af18ee2cbc229690a34d8b36db9f697 Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Tue, 14 Mar 2023 13:03:15 +0800 Subject: [PATCH 05/16] RISC-V: mm: Enable huge page support to kernel_page_present() function Currently kernel_page_present() function doesn't support huge page detection causes the function to mistakenly return false to the hibernation core. Add huge page detection to the function to solve the problem. Fixes: 9e953cda5cdf ("riscv: Introduce huge page support for 32/64bit kernel") Signed-off-by: Sia Jee Heng Reviewed-by: Ley Foon Tan Reviewed-by: Mason Huo Reviewed-by: Andrew Jones Reviewed-by: Alexandre Ghiti --- arch/riscv/mm/pageattr.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/riscv/mm/pageattr.c b/arch/riscv/mm/pageattr.c index 86c5661..ea3d61d 100644 --- a/arch/riscv/mm/pageattr.c +++ b/arch/riscv/mm/pageattr.c @@ -217,18 +217,26 @@ bool kernel_page_present(struct page *page) pgd = pgd_offset_k(addr); if (!pgd_present(*pgd)) return false; + if (pgd_leaf(*pgd)) + return true; p4d = p4d_offset(pgd, addr); if (!p4d_present(*p4d)) return false; + if (p4d_leaf(*p4d)) + return true; pud = pud_offset(p4d, addr); if (!pud_present(*pud)) return false; + if (pud_leaf(*pud)) + return true; pmd = pmd_offset(pud, addr); if (!pmd_present(*pmd)) return false; + if (pmd_leaf(*pmd)) + return true; pte = pte_offset_kernel(pmd, addr); return pte_present(*pte); -- 2.7.4 From 2b74430e176a7149a81db3c47de41f6ddb12f1bc Mon Sep 17 00:00:00 2001 From: Sia Jee Heng Date: Tue, 14 Mar 2023 13:03:16 +0800 Subject: [PATCH 06/16] RISC-V: Add arch functions to support hibernation/suspend-to-disk Low level Arch functions were created to support hibernation. swsusp_arch_suspend() relies code from __cpu_suspend_enter() to write cpu state onto the stack, then calling swsusp_save() to save the memory image. Arch specific hibernation header is implemented and is utilized by the arch_hibernation_header_restore() and arch_hibernation_header_save() functions. The arch specific hibernation header consists of satp, hartid, and the cpu_resume address. The kernel built version is also need to be saved into the hibernation image header to making sure only the same kernel is restore when resume. swsusp_arch_resume() creates a temporary page table that covering only the linear map. It copies the restore code to a 'safe' page, then start to restore the memory image. Once completed, it restores the original kernel's page table. It then calls into __hibernate_cpu_resume() to restore the CPU context. Finally, it follows the normal hibernation path back to the hibernation core. To enable hibernation/suspend to disk into RISCV, the below config need to be enabled: - CONFIG_ARCH_HIBERNATION_HEADER - CONFIG_ARCH_HIBERNATION_POSSIBLE Signed-off-by: Sia Jee Heng Reviewed-by: Ley Foon Tan Reviewed-by: Mason Huo Reviewed-by: Conor Dooley --- arch/riscv/Kconfig | 6 + arch/riscv/include/asm/assembler.h | 20 ++ arch/riscv/include/asm/suspend.h | 19 ++ arch/riscv/kernel/Makefile | 1 + arch/riscv/kernel/asm-offsets.c | 5 + arch/riscv/kernel/hibernate-asm.S | 77 +++++++ arch/riscv/kernel/hibernate.c | 427 +++++++++++++++++++++++++++++++++++++ 7 files changed, 555 insertions(+) create mode 100644 arch/riscv/kernel/hibernate-asm.S create mode 100644 arch/riscv/kernel/hibernate.c diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 8e5fd56..9ff3a99 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -685,6 +685,12 @@ menu "Power management options" source "kernel/power/Kconfig" +config ARCH_HIBERNATION_POSSIBLE + def_bool y + +config ARCH_HIBERNATION_HEADER + def_bool HIBERNATION + endmenu # "Power management options" menu "CPU Power Management" diff --git a/arch/riscv/include/asm/assembler.h b/arch/riscv/include/asm/assembler.h index ba59d38..44b1457 100644 --- a/arch/riscv/include/asm/assembler.h +++ b/arch/riscv/include/asm/assembler.h @@ -59,4 +59,24 @@ REG_L s11, (SUSPEND_CONTEXT_REGS + PT_S11)(a0) .endm +/* + * copy_page - copy 1 page (4KB) of data from source to destination + * @a0 - destination + * @a1 - source + */ + .macro copy_page a0, a1 + lui a2, 0x1 + add a2, a2, a0 +1 : + REG_L t0, 0(a1) + REG_L t1, SZREG(a1) + + REG_S t0, 0(a0) + REG_S t1, SZREG(a0) + + addi a0, a0, 2 * SZREG + addi a1, a1, 2 * SZREG + bne a2, a0, 1b + .endm + #endif /* __ASM_ASSEMBLER_H */ diff --git a/arch/riscv/include/asm/suspend.h b/arch/riscv/include/asm/suspend.h index 67e0474..02f8786 100644 --- a/arch/riscv/include/asm/suspend.h +++ b/arch/riscv/include/asm/suspend.h @@ -21,6 +21,11 @@ struct suspend_context { #endif }; +/* + * Used by hibernation core and cleared during resume sequence + */ +extern int in_suspend; + /* Low-level CPU suspend entry function */ int __cpu_suspend_enter(struct suspend_context *context); @@ -36,4 +41,18 @@ int __cpu_resume_enter(unsigned long hartid, unsigned long context); /* Used to save and restore the CSRs */ void suspend_save_csrs(struct suspend_context *context); void suspend_restore_csrs(struct suspend_context *context); + +/* Low-level API to support hibernation */ +int swsusp_arch_suspend(void); +int swsusp_arch_resume(void); +int arch_hibernation_header_save(void *addr, unsigned int max_size); +int arch_hibernation_header_restore(void *addr); +int __hibernate_cpu_resume(void); + +/* Used to resume on the CPU we hibernated on */ +int hibernate_resume_nonboot_cpu_disable(void); + +asmlinkage void hibernate_restore_image(unsigned long resume_satp, unsigned long satp_temp, + unsigned long cpu_resume); +asmlinkage int hibernate_core_restore_code(void); #endif diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index db6e4b1..ef98f8b 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULE_SECTIONS) += module-sections.o obj-$(CONFIG_CPU_PM) += suspend_entry.o suspend.o +obj-$(CONFIG_HIBERNATION) += hibernate.o hibernate-asm.o obj-$(CONFIG_FUNCTION_TRACER) += mcount.o ftrace.o obj-$(CONFIG_DYNAMIC_FTRACE) += mcount-dyn.o diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c index df94443..d6a75aa 100644 --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -116,6 +117,10 @@ void asm_offsets(void) OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs); + OFFSET(HIBERN_PBE_ADDR, pbe, address); + OFFSET(HIBERN_PBE_ORIG, pbe, orig_address); + OFFSET(HIBERN_PBE_NEXT, pbe, next); + OFFSET(KVM_ARCH_GUEST_ZERO, kvm_vcpu_arch, guest_context.zero); OFFSET(KVM_ARCH_GUEST_RA, kvm_vcpu_arch, guest_context.ra); OFFSET(KVM_ARCH_GUEST_SP, kvm_vcpu_arch, guest_context.sp); diff --git a/arch/riscv/kernel/hibernate-asm.S b/arch/riscv/kernel/hibernate-asm.S new file mode 100644 index 0000000..effaf5c --- /dev/null +++ b/arch/riscv/kernel/hibernate-asm.S @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Hibernation low level support for RISCV. + * + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * + * Author: Jee Heng Sia + */ + +#include +#include +#include +#include + +#include + +/* + * int __hibernate_cpu_resume(void) + * Switch back to the hibernated image's page table prior to restoring the CPU + * context. + * + * Always returns 0 + */ +ENTRY(__hibernate_cpu_resume) + /* switch to hibernated image's page table. */ + csrw CSR_SATP, s0 + sfence.vma + + REG_L a0, hibernate_cpu_context + + suspend_restore_csrs + suspend_restore_regs + + /* Return zero value. */ + mv a0, zero + + ret +END(__hibernate_cpu_resume) + +/* + * Prepare to restore the image. + * a0: satp of saved page tables. + * a1: satp of temporary page tables. + * a2: cpu_resume. + */ +ENTRY(hibernate_restore_image) + mv s0, a0 + mv s1, a1 + mv s2, a2 + REG_L s4, restore_pblist + REG_L a1, relocated_restore_code + + jalr a1 +END(hibernate_restore_image) + +/* + * The below code will be executed from a 'safe' page. + * It first switches to the temporary page table, then starts to copy the pages + * back to the original memory location. Finally, it jumps to __hibernate_cpu_resume() + * to restore the CPU context. + */ +ENTRY(hibernate_core_restore_code) + /* switch to temp page table. */ + csrw satp, s1 + sfence.vma +.Lcopy: + /* The below code will restore the hibernated image. */ + REG_L a1, HIBERN_PBE_ADDR(s4) + REG_L a0, HIBERN_PBE_ORIG(s4) + + copy_page a0, a1 + + REG_L s4, HIBERN_PBE_NEXT(s4) + bnez s4, .Lcopy + + jalr s2 +END(hibernate_core_restore_code) diff --git a/arch/riscv/kernel/hibernate.c b/arch/riscv/kernel/hibernate.c new file mode 100644 index 0000000..f11be60 --- /dev/null +++ b/arch/riscv/kernel/hibernate.c @@ -0,0 +1,427 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Hibernation support for RISCV + * + * Copyright (C) 2023 StarFive Technology Co., Ltd. + * + * Author: Jee Heng Sia + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +/* The logical cpu number we should resume on, initialised to a non-cpu number. */ +static int sleep_cpu = -EINVAL; + +/* Pointer to the temporary resume page table. */ +static pgd_t *resume_pg_dir; + +/* CPU context to be saved. */ +struct suspend_context *hibernate_cpu_context; +EXPORT_SYMBOL_GPL(hibernate_cpu_context); + +unsigned long relocated_restore_code; +EXPORT_SYMBOL_GPL(relocated_restore_code); + +/** + * struct arch_hibernate_hdr_invariants - container to store kernel build version. + * @uts_version: to save the build number and date so that the we do not resume with + * a different kernel. + */ +struct arch_hibernate_hdr_invariants { + char uts_version[__NEW_UTS_LEN + 1]; +}; + +/** + * struct arch_hibernate_hdr - helper parameters that help us to restore the image. + * @invariants: container to store kernel build version. + * @hartid: to make sure same boot_cpu executes the hibernate/restore code. + * @saved_satp: original page table used by the hibernated image. + * @restore_cpu_addr: the kernel's image address to restore the CPU context. + */ +static struct arch_hibernate_hdr { + struct arch_hibernate_hdr_invariants invariants; + unsigned long hartid; + unsigned long saved_satp; + unsigned long restore_cpu_addr; +} resume_hdr; + +static void arch_hdr_invariants(struct arch_hibernate_hdr_invariants *i) +{ + memset(i, 0, sizeof(*i)); + memcpy(i->uts_version, init_utsname()->version, sizeof(i->uts_version)); +} + +/* + * Check if the given pfn is in the 'nosave' section. + */ +int pfn_is_nosave(unsigned long pfn) +{ + unsigned long nosave_begin_pfn = sym_to_pfn(&__nosave_begin); + unsigned long nosave_end_pfn = sym_to_pfn(&__nosave_end - 1); + + return ((pfn >= nosave_begin_pfn) && (pfn <= nosave_end_pfn)); +} + +void notrace save_processor_state(void) +{ + WARN_ON(num_online_cpus() != 1); +} + +void notrace restore_processor_state(void) +{ +} + +/* + * Helper parameters need to be saved to the hibernation image header. + */ +int arch_hibernation_header_save(void *addr, unsigned int max_size) +{ + struct arch_hibernate_hdr *hdr = addr; + + if (max_size < sizeof(*hdr)) + return -EOVERFLOW; + + arch_hdr_invariants(&hdr->invariants); + + hdr->hartid = cpuid_to_hartid_map(sleep_cpu); + hdr->saved_satp = csr_read(CSR_SATP); + hdr->restore_cpu_addr = (unsigned long)__hibernate_cpu_resume; + + return 0; +} +EXPORT_SYMBOL_GPL(arch_hibernation_header_save); + +/* + * Retrieve the helper parameters from the hibernation image header. + */ +int arch_hibernation_header_restore(void *addr) +{ + struct arch_hibernate_hdr_invariants invariants; + struct arch_hibernate_hdr *hdr = addr; + int ret = 0; + + arch_hdr_invariants(&invariants); + + if (memcmp(&hdr->invariants, &invariants, sizeof(invariants))) { + pr_crit("Hibernate image not generated by this kernel!\n"); + return -EINVAL; + } + + sleep_cpu = riscv_hartid_to_cpuid(hdr->hartid); + if (sleep_cpu < 0) { + pr_crit("Hibernated on a CPU not known to this kernel!\n"); + sleep_cpu = -EINVAL; + return -EINVAL; + } + +#ifdef CONFIG_SMP + ret = bringup_hibernate_cpu(sleep_cpu); + if (ret) { + sleep_cpu = -EINVAL; + return ret; + } +#endif + resume_hdr = *hdr; + + return ret; +} +EXPORT_SYMBOL_GPL(arch_hibernation_header_restore); + +int swsusp_arch_suspend(void) +{ + int ret = 0; + + if (__cpu_suspend_enter(hibernate_cpu_context)) { + sleep_cpu = smp_processor_id(); + suspend_save_csrs(hibernate_cpu_context); + ret = swsusp_save(); + } else { + suspend_restore_csrs(hibernate_cpu_context); + flush_tlb_all(); + flush_icache_all(); + + /* + * Tell the hibernation core that we've just restored the memory. + */ + in_suspend = 0; + sleep_cpu = -EINVAL; + } + + return ret; +} + +static int temp_pgtable_map_pte(pmd_t *dst_pmdp, pmd_t *src_pmdp, unsigned long start, + unsigned long end, pgprot_t prot) +{ + pte_t *src_ptep; + pte_t *dst_ptep; + + if (pmd_none(READ_ONCE(*dst_pmdp))) { + dst_ptep = (pte_t *)get_safe_page(GFP_ATOMIC); + if (!dst_ptep) + return -ENOMEM; + + pmd_populate_kernel(NULL, dst_pmdp, dst_ptep); + } + + dst_ptep = pte_offset_kernel(dst_pmdp, start); + src_ptep = pte_offset_kernel(src_pmdp, start); + + do { + pte_t pte = READ_ONCE(*src_ptep); + + if (pte_present(pte)) + set_pte(dst_ptep, __pte(pte_val(pte) | pgprot_val(prot))); + } while (dst_ptep++, src_ptep++, start += PAGE_SIZE, start < end); + + return 0; +} + +static int temp_pgtable_map_pmd(pud_t *dst_pudp, pud_t *src_pudp, unsigned long start, + unsigned long end, pgprot_t prot) +{ + unsigned long next; + unsigned long ret; + pmd_t *src_pmdp; + pmd_t *dst_pmdp; + + if (pud_none(READ_ONCE(*dst_pudp))) { + dst_pmdp = (pmd_t *)get_safe_page(GFP_ATOMIC); + if (!dst_pmdp) + return -ENOMEM; + + pud_populate(NULL, dst_pudp, dst_pmdp); + } + + dst_pmdp = pmd_offset(dst_pudp, start); + src_pmdp = pmd_offset(src_pudp, start); + + do { + pmd_t pmd = READ_ONCE(*src_pmdp); + + next = pmd_addr_end(start, end); + + if (pmd_none(pmd)) + continue; + + if (pmd_leaf(pmd)) { + set_pmd(dst_pmdp, __pmd(pmd_val(pmd) | pgprot_val(prot))); + } else { + ret = temp_pgtable_map_pte(dst_pmdp, src_pmdp, start, next, prot); + if (ret) + return -ENOMEM; + } + } while (dst_pmdp++, src_pmdp++, start = next, start != end); + + return 0; +} + +static int temp_pgtable_map_pud(p4d_t *dst_p4dp, p4d_t *src_p4dp, unsigned long start, + unsigned long end, pgprot_t prot) +{ + unsigned long next; + unsigned long ret; + pud_t *dst_pudp; + pud_t *src_pudp; + + if (p4d_none(READ_ONCE(*dst_p4dp))) { + dst_pudp = (pud_t *)get_safe_page(GFP_ATOMIC); + if (!dst_pudp) + return -ENOMEM; + + p4d_populate(NULL, dst_p4dp, dst_pudp); + } + + dst_pudp = pud_offset(dst_p4dp, start); + src_pudp = pud_offset(src_p4dp, start); + + do { + pud_t pud = READ_ONCE(*src_pudp); + + next = pud_addr_end(start, end); + + if (pud_none(pud)) + continue; + + if (pud_leaf(pud)) { + set_pud(dst_pudp, __pud(pud_val(pud) | pgprot_val(prot))); + } else { + ret = temp_pgtable_map_pmd(dst_pudp, src_pudp, start, next, prot); + if (ret) + return -ENOMEM; + } + } while (dst_pudp++, src_pudp++, start = next, start != end); + + return 0; +} + +static int temp_pgtable_map_p4d(pgd_t *dst_pgdp, pgd_t *src_pgdp, unsigned long start, + unsigned long end, pgprot_t prot) +{ + unsigned long next; + unsigned long ret; + p4d_t *dst_p4dp; + p4d_t *src_p4dp; + + if (pgd_none(READ_ONCE(*dst_pgdp))) { + dst_p4dp = (p4d_t *)get_safe_page(GFP_ATOMIC); + if (!dst_p4dp) + return -ENOMEM; + + pgd_populate(NULL, dst_pgdp, dst_p4dp); + } + + dst_p4dp = p4d_offset(dst_pgdp, start); + src_p4dp = p4d_offset(src_pgdp, start); + + do { + p4d_t p4d = READ_ONCE(*src_p4dp); + + next = p4d_addr_end(start, end); + + if (p4d_none(p4d)) + continue; + + if (p4d_leaf(p4d)) { + set_p4d(dst_p4dp, __p4d(p4d_val(p4d) | pgprot_val(prot))); + } else { + ret = temp_pgtable_map_pud(dst_p4dp, src_p4dp, start, next, prot); + if (ret) + return -ENOMEM; + } + } while (dst_p4dp++, src_p4dp++, start = next, start != end); + + return 0; +} + +static int temp_pgtable_mapping(pgd_t *pgdp, unsigned long start, unsigned long end, pgprot_t prot) +{ + pgd_t *dst_pgdp = pgd_offset_pgd(pgdp, start); + pgd_t *src_pgdp = pgd_offset_k(start); + unsigned long next; + unsigned long ret; + + do { + pgd_t pgd = READ_ONCE(*src_pgdp); + + next = pgd_addr_end(start, end); + + if (pgd_none(pgd)) + continue; + + if (pgd_leaf(pgd)) { + set_pgd(dst_pgdp, __pgd(pgd_val(pgd) | pgprot_val(prot))); + } else { + ret = temp_pgtable_map_p4d(dst_pgdp, src_pgdp, start, next, prot); + if (ret) + return -ENOMEM; + } + } while (dst_pgdp++, src_pgdp++, start = next, start != end); + + return 0; +} + +static unsigned long relocate_restore_code(void) +{ + void *page = (void *)get_safe_page(GFP_ATOMIC); + + if (!page) + return -ENOMEM; + + copy_page(page, hibernate_core_restore_code); + + /* Make the page containing the relocated code executable. */ + set_memory_x((unsigned long)page, 1); + + return (unsigned long)page; +} + +int swsusp_arch_resume(void) +{ + unsigned long end = (unsigned long)pfn_to_virt(max_low_pfn); + unsigned long start = PAGE_OFFSET; + int ret; + + /* + * Memory allocated by get_safe_page() will be dealt with by the hibernation core, + * we don't need to free it here. + */ + resume_pg_dir = (pgd_t *)get_safe_page(GFP_ATOMIC); + if (!resume_pg_dir) + return -ENOMEM; + + /* + * Create a temporary page table and map the whole linear region as executable and + * writable. + */ + ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE | _PAGE_EXEC)); + if (ret) + return ret; + + /* Move the restore code to a new page so that it doesn't get overwritten by itself. */ + relocated_restore_code = relocate_restore_code(); + if (relocated_restore_code == -ENOMEM) + return -ENOMEM; + + /* + * Map the __hibernate_cpu_resume() address to the temporary page table so that the + * restore code can jumps to it after finished restore the image. The next execution + * code doesn't find itself in a different address space after switching over to the + * original page table used by the hibernated image. + * The __hibernate_cpu_resume() mapping is unnecessary for RV32 since the kernel and + * linear addresses are identical, but different for RV64. To ensure consistency, we + * map it for both RV32 and RV64 kernels. + * Additionally, we should ensure that the page is writable before restoring the image. + */ + start = (unsigned long)resume_hdr.restore_cpu_addr; + end = start + PAGE_SIZE; + + ret = temp_pgtable_mapping(resume_pg_dir, start, end, __pgprot(_PAGE_WRITE)); + if (ret) + return ret; + + hibernate_restore_image(resume_hdr.saved_satp, (PFN_DOWN(__pa(resume_pg_dir)) | satp_mode), + resume_hdr.restore_cpu_addr); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP_SMP +int hibernate_resume_nonboot_cpu_disable(void) +{ + if (sleep_cpu < 0) { + pr_err("Failing to resume from hibernate on an unknown CPU\n"); + return -ENODEV; + } + + return freeze_secondary_cpus(sleep_cpu); +} +#endif + +static int __init riscv_hibernate_init(void) +{ + hibernate_cpu_context = kzalloc(sizeof(*hibernate_cpu_context), GFP_KERNEL); + + if (WARN_ON(!hibernate_cpu_context)) + return -ENOMEM; + + return 0; +} + +early_initcall(riscv_hibernate_init); -- 2.7.4 From a1d5ef18d1c3cff5c4adb32a5cb35a4c7526e20f Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 10 Mar 2023 14:32:13 +0900 Subject: [PATCH 07/16] RISCV: configs: Add tizen_vf2_defconfig file Add tizen_vf2_defconfig file for VisionFive2 boardi. This defconfig is an initial version to use Tizen on VisionFive2. Change-Id: Ie675e71129f698d294f637f7545be323466537de Signed-off-by: Jaehoon Chung --- arch/riscv/configs/tizen_vf2_defconfig | 226 +++++++++++++++++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 arch/riscv/configs/tizen_vf2_defconfig diff --git a/arch/riscv/configs/tizen_vf2_defconfig b/arch/riscv/configs/tizen_vf2_defconfig new file mode 100644 index 0000000..f2d4800 --- /dev/null +++ b/arch/riscv/configs/tizen_vf2_defconfig @@ -0,0 +1,226 @@ +CONFIG_SYSVIPC=y +CONFIG_POSIX_MQUEUE=y +CONFIG_NO_HZ_IDLE=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_BPF_SYSCALL=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_CGROUPS=y +CONFIG_MEMCG=y +CONFIG_CGROUP_SCHED=y +CONFIG_CFS_BANDWIDTH=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_CGROUP_PIDS=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_HUGETLB=y +CONFIG_CPUSETS=y +CONFIG_CGROUP_DEVICE=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_PERF=y +CONFIG_CGROUP_BPF=y +CONFIG_NAMESPACES=y +CONFIG_USER_NS=y +CONFIG_CHECKPOINT_RESTORE=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_EXPERT=y +# CONFIG_SYSFS_SYSCALL is not set +CONFIG_PROFILING=y +CONFIG_SOC_MICROCHIP_POLARFIRE=y +CONFIG_SOC_SIFIVE=y +CONFIG_SOC_STARFIVE=y +CONFIG_SOC_VIRT=y +CONFIG_SMP=y +CONFIG_HOTPLUG_CPU=y +CONFIG_PM=y +CONFIG_CPU_IDLE=y +CONFIG_VIRTUALIZATION=y +CONFIG_KVM=m +CONFIG_JUMP_LABEL=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_NET=y +CONFIG_PACKET=y +CONFIG_UNIX=y +CONFIG_XFRM_USER=m +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +CONFIG_IP_PNP_RARP=y +CONFIG_INET_ESP=m +CONFIG_NETFILTER=y +CONFIG_BRIDGE_NETFILTER=m +CONFIG_NF_CONNTRACK=m +CONFIG_NF_CONNTRACK_FTP=m +CONFIG_NF_CONNTRACK_TFTP=m +CONFIG_NETFILTER_XT_MARK=m +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_IPVS=m +CONFIG_IP_VS=m +CONFIG_IP_VS_PROTO_TCP=y +CONFIG_IP_VS_PROTO_UDP=y +CONFIG_IP_VS_RR=m +CONFIG_IP_VS_NFCT=y +CONFIG_NF_LOG_ARP=m +CONFIG_NF_LOG_IPV4=m +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_MANGLE=m +CONFIG_NF_LOG_IPV6=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_IPV6HEADER=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_BRIDGE=m +CONFIG_BRIDGE_VLAN_FILTERING=y +CONFIG_VLAN_8021Q=m +CONFIG_NET_SCHED=y +CONFIG_NET_CLS_CGROUP=m +CONFIG_NETLINK_DIAG=y +CONFIG_CGROUP_NET_PRIO=y +CONFIG_CFG80211=y +# CONFIG_CFG80211_CRDA_SUPPORT is not set +CONFIG_CFG80211_WEXT=y +CONFIG_NET_9P=y +CONFIG_NET_9P_VIRTIO=y +CONFIG_PCI=y +CONFIG_PCIEPORTBUS=y +CONFIG_PCI_HOST_GENERIC=y +CONFIG_PCIE_XILINX=y +CONFIG_PCIE_FU740=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=32768 +CONFIG_VIRTIO_BLK=y +CONFIG_BLK_DEV_NVME=m +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_DEV_SR=y +CONFIG_SCSI_VIRTIO=y +CONFIG_ATA=y +CONFIG_SATA_AHCI=y +CONFIG_SATA_AHCI_PLATFORM=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_DM_THIN_PROVISIONING=m +CONFIG_DM_UEVENT=y +CONFIG_DM_VERITY=y +CONFIG_NETDEVICES=y +CONFIG_DUMMY=m +CONFIG_MACVLAN=m +CONFIG_IPVLAN=m +CONFIG_VXLAN=m +CONFIG_TUN=y +CONFIG_VETH=m +CONFIG_VIRTIO_NET=y +CONFIG_MACB=y +CONFIG_E1000E=y +CONFIG_R8169=y +CONFIG_MICROSEMI_PHY=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_DW=y +CONFIG_SERIAL_OF_PLATFORM=y +CONFIG_VIRTIO_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HW_RANDOM_VIRTIO=y +CONFIG_SPI=y +CONFIG_SPI_SIFIVE=y +# CONFIG_PTP_1588_CLOCK is not set +CONFIG_GPIO_SIFIVE=y +CONFIG_DRM=m +CONFIG_DRM_RADEON=m +CONFIG_DRM_NOUVEAU=m +CONFIG_DRM_VIRTIO_GPU=m +CONFIG_FB=y +CONFIG_FRAMEBUFFER_CONSOLE=y +CONFIG_USB=y +CONFIG_USB_XHCI_HCD=y +CONFIG_USB_XHCI_PLATFORM=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_HCD_PLATFORM=y +CONFIG_USB_OHCI_HCD=y +CONFIG_USB_OHCI_HCD_PLATFORM=y +CONFIG_USB_STORAGE=y +CONFIG_USB_UAS=y +CONFIG_MMC=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MMC_SDHCI_CADENCE=y +CONFIG_MMC_SPI=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_STARFIVE=y +CONFIG_RTC_CLASS=y +CONFIG_VIRTIO_PCI=y +CONFIG_VIRTIO_BALLOON=y +CONFIG_VIRTIO_INPUT=y +CONFIG_VIRTIO_MMIO=y +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_CTRL=y +CONFIG_RPMSG_VIRTIO=y +CONFIG_EXT4_FS=y +CONFIG_EXT4_FS_POSIX_ACL=y +CONFIG_EXT4_FS_SECURITY=y +CONFIG_BTRFS_FS=m +CONFIG_BTRFS_FS_POSIX_ACL=y +CONFIG_AUTOFS4_FS=y +CONFIG_OVERLAY_FS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +CONFIG_ZISOFS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_TMPFS=y +CONFIG_TMPFS_POSIX_ACL=y +CONFIG_HUGETLBFS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V4=y +CONFIG_NFS_V4_1=y +CONFIG_NFS_V4_2=y +CONFIG_ROOT_NFS=y +CONFIG_9P_FS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_ISO8859_1=m +CONFIG_SECURITY=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SECURITY_SMACK=y +CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y +CONFIG_SECURITY_APPARMOR=y +CONFIG_DEFAULT_SECURITY_SMACK=y +CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,smack,bpf" +CONFIG_CRYPTO_USER_API_HASH=y +CONFIG_CRYPTO_DEV_VIRTIO=y +CONFIG_PRINTK_TIME=y +CONFIG_DEBUG_FS=y +CONFIG_DEBUG_PAGEALLOC=y +CONFIG_SCHED_STACK_END_CHECK=y +CONFIG_DEBUG_VM=y +CONFIG_DEBUG_VM_PGFLAGS=y +CONFIG_DEBUG_MEMORY_INIT=y +CONFIG_DEBUG_PER_CPU_MAPS=y +CONFIG_SOFTLOCKUP_DETECTOR=y +CONFIG_WQ_WATCHDOG=y +CONFIG_DEBUG_TIMEKEEPING=y +CONFIG_DEBUG_RT_MUTEXES=y +CONFIG_DEBUG_SPINLOCK=y +CONFIG_DEBUG_MUTEXES=y +CONFIG_DEBUG_RWSEMS=y +CONFIG_DEBUG_ATOMIC_SLEEP=y +CONFIG_DEBUG_LIST=y +CONFIG_DEBUG_PLIST=y +CONFIG_DEBUG_SG=y +# CONFIG_RCU_TRACE is not set +CONFIG_RCU_EQS_DEBUG=y +# CONFIG_FTRACE is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_MEMTEST=y -- 2.7.4 From e6303a1c7cf531457aca1ff35f3d3ee38977eca2 Mon Sep 17 00:00:00 2001 From: Marek Szulc Date: Fri, 19 Aug 2022 12:29:48 +0200 Subject: [PATCH 08/16] riscv: fix riscv64 unrecognized opcode build error MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Considering older gcc version, "imafd" has to be changed to "g", in order for asm to handle "zicsr" and "zifencei" extensions. Support for the mentioned extensions has been added in GCC 11.1, hence this commit may be removed after GCC update. The lack of this causes following errors: Error: unrecognized opcode `csrr a5,0xc01' Error: unrecognized opcode `csrr a2,0xc01' Change-Id: I0768a7b1255c828c4fc319f74f2783bc7e1581bf Signed-off-by: Marek Szulc Signed-off-by: Łukasz Stelmach --- arch/riscv/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile index 8b4ddcc..7324855 100644 --- a/arch/riscv/Makefile +++ b/arch/riscv/Makefile @@ -55,6 +55,7 @@ endif riscv-march-$(CONFIG_ARCH_RV32I) := rv32ima riscv-march-$(CONFIG_ARCH_RV64I) := rv64ima riscv-march-$(CONFIG_FPU) := $(riscv-march-y)fd +riscv-march-y := $(subst imafd,g,$(riscv-march-y)) riscv-march-$(CONFIG_RISCV_ISA_C) := $(riscv-march-y)c # Newer binutils versions default to ISA spec version 20191213 which moves some -- 2.7.4 From 64ddecb8ec334e78d2b480bae2b6603865932a00 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Fri, 10 Mar 2023 15:31:40 +0900 Subject: [PATCH 09/16] packaging: Add linux-visionfive2 spec file Add linux-visionfive2 spec vile to build with gbs. This is for only visionfive2 board. Change-Id: Icc8feec48b9d77c27b4ce8f2d9468ca882d1fca1 Signed-off-by: Jaehoon Chung --- .gbs.conf | 4 + packaging/linux-visionfive2.spec | 193 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 .gbs.conf create mode 100644 packaging/linux-visionfive2.spec diff --git a/.gbs.conf b/.gbs.conf new file mode 100644 index 0000000..f744dba --- /dev/null +++ b/.gbs.conf @@ -0,0 +1,4 @@ +[general] +upstream_branch = upstream +upstream_tag = v${upstreamversion} +squash_patches_until = HEAD~10 diff --git a/packaging/linux-visionfive2.spec b/packaging/linux-visionfive2.spec new file mode 100644 index 0000000..e76c309 --- /dev/null +++ b/packaging/linux-visionfive2.spec @@ -0,0 +1,193 @@ +# Ignore double dash in version for rpmbuild +%define _wrong_version_format_terminate_build 0 + +%define config_name tizen_vf2_defconfig +%define buildarch riscv +%define target_board visionfive2 +%define variant %{buildarch}-%{target_board} + +Name: visionfive2-linux-kernel +Summary: The Linux Kernel for VisionFive2 Board +Version: 6.1.21 +Release: 0 +License: GPL-2.0 +ExclusiveArch: riscv64 +Group: System/Kernel +Vendor: The Linux Community +URL: https://www.kernel.org +Source0: linux-kernel-%{version}.tar.xz +BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root + +%define fullVersion %{version}-%{variant} + +BuildRequires: bc +BuildRequires: module-init-tools +BuildRequires: bison +BuildRequires: flex +BuildRequires: libopenssl1.1-devel +BuildRequires: libunwind-devel +BuildRequires: libdw-devel +BuildRequires: libelf-devel +BuildRequires: elfutils +BuildRequires: xz-devel +BuildRequires: binutils-devel +BuildRequires: python3 +BuildRequires: rsync + +%description +The Linux Kernel, the operating system core itself + +# kernel +%package -n %{variant}-linux-kernel +License: GPL-2.0 +Summary: Tizen kernel for %{target_board} +Group: System/Kernel +Provides: %{variant}-kernel-uname-r = %{fullVersion} +Provides: linux-kernel = %{version}-%{release} + +%description -n %{variant}-linux-kernel +This package contains the Linux kernel for Tizen (arch %{buildarch}, target board %{target_board}) + +# modules + +%package -n %{variant}-linux-kernel-modules +Summary: Kernel modules for %{target_board} +Group: System/Kernel +Provides: %{variant}-kernel-modules = %{fullVersion} +Provides: %{variant}-kernel-modules-uname-r = %{fullVersion} + +%description -n %{variant}-linux-kernel-modules +Kernel-modules includes the loadable kernel modules(.ko files) for %{target_board} + +# devel + +%package -n %{variant}-linux-kernel-devel +License: GPL-2.0 +Summary: Linux support kernel map and etc for other packages +Group: System/Kernel +Provides: %{variant}-kernel-devel = %{fullVersion} +Provides: %{variant}-kernel-devel-uname-r = %{fullVersion} + +%description -n %{variant}-linux-kernel-devel +This package provides kernel map and etc information. + +#headers +%package -n %{variant}-linux-kernel-headers +License: GPL-2.0 +Summary: Linux support headers for userspace development +Group: System/Kernel +Provides: kernel-headers-tizen-dev + +%description -n %{variant}-linux-kernel-headers +This package provides userspaces headers from the Linux kernel. These +headers are used by the installed headers for GNU glibc and other system + libraries. + +%package -n linux-kernel-perf +Summary: The perf performance counter tool +Group: System/Kernel +Provides: perf = %{version} + +%description -n linux-kernel-perf +This package provides the "perf" tool that can be used to monitor performance +counter events as well as various kernel internal events. + +%prep +%setup -q + +%build +%{?asan:/usr/bin/gcc-unforce-options} +%{?ubsan:/usr/bin/gcc-unforce-options} + +# extract uapi headers +make headers_install %{?_smp_mflags} + +# Set config file +make %{config_name} %{?_smp_mflags} + +# Build perf +make -s -C tools/lib/traceevent %{?_smp_mflags} +make -s -C tools/perf EXTRA_CFLAGS="-fPIE -rdynamic" %{?_smp_mflags} + +# Build Image/Image.gz +make %{?_smp_mflags} + +# Build modules +make modules %{?_smp_mflags} + +%install +QA_SKIP_BUILD_ROOT="DO_NOT_WANT"; export QA_SKIP_BUILD_ROOT + +# Destination directories +mkdir -p %{buildroot}/boot +mkdir -p %{buildroot}/lib/modules + +# Install kernel DTB +install -m 644 arch/%{buildarch}/boot/dts/starfive/jh7110*.dtb %{buildroot}/boot/ +mkdir -p %{buildroot}/boot/overlays + +# Install kernel headers +make headers_install %{?_smp_mflags} INSTALL_HDR_PATH=%{buildroot}/usr + +install -m 644 arch/%{buildarch}/boot/Image %{buildroot}/boot/Image + +# Install perf +make -s -C tools/perf EXTRA_CFLAGS="-fPIE -rdynamic" DESTDIR=%{buildroot}/usr install +rm -rf %{buildroot}/usr/etc +rm -rf %{buildroot}/usr/lib/debug +rm -rf %{buildroot}/usr/lib/perf +rm -rf %{buildroot}/usr/share + +# Install modules +make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=%{buildroot} modules_install + +# Copy files for devel package +mkdir -p %{buildroot}/boot/kernel/devel/kernel-devel-%{variant} +rsync -r \ + --include "/scripts/**.c" \ + --exclude "/debug*.list" \ + --exclude "/documentation.list" \ + --exclude "/*.manifest" \ + --exclude "/packaging/" \ + --exclude "/.gbs.conf" \ + --exclude "/.git**" \ + --exclude ".gitignore" \ + --exclude "*\.c" \ + --exclude ".tmp_vmlinux*" \ + --exclude ".*dtb*tmp" \ + --exclude ".*dtb" \ + --exclude "*.*tmp" \ + --exclude "vmlinux" \ + --exclude "Image" \ + --exclude "zImage" \ + --exclude "Image.gz" \ + --exclude "*.cmd" \ + --exclude "*.ko" \ + --exclude "*.o" \ + --exclude "*.S" \ + --exclude "*.HEX" \ + --exclude "/build/" \ + ./ %{buildroot}/boot/kernel/devel/kernel-devel-%{variant} + +%clean +rm -rf %{buildroot} + +%files -n %{variant}-linux-kernel-modules +/lib/modules/ + +%files -n %{variant}-linux-kernel-devel +/boot/kernel/devel/ + +%files -n %{variant}-linux-kernel +%license COPYING +/boot/Image +/boot/jh7110*.dtb + +%files -n %{variant}-linux-kernel-headers +/usr/include/* + +%files -n linux-kernel-perf +%license COPYING +/usr/bin/* +/usr/libexec/* +/usr/lib/traceevent/* -- 2.7.4 From 7e88f65f322cbf0ca6227fcad6ac5113c0c47b47 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Mon, 13 Mar 2023 12:31:05 +0900 Subject: [PATCH 10/16] build: Add local build script for VisionFive2 Add local build script for VisionFive2. Change-Id: I0ca80fd1e383b9ce62797944fba1755e315fa9c7 Signed-off-by: Jaehoon Chung --- build.sh | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100755 build.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..828ec06 --- /dev/null +++ b/build.sh @@ -0,0 +1,83 @@ +#!/bin/bash +MOD_DIR="usr/tmp_mod" +MOD_IMG="usr/modules.img" +MOD_SIZE=32 +NCPUS=`grep ^processor /proc/cpuinfo | wc -l` +NCPUS=$(($NCPUS * 2)) + +# Check this system has ccache +check_ccache() +{ + type ccache + if [ "$?" -eq "0" ]; then + CCACHE=ccache + fi +} + +function mk_modules() { + [ -e /usr/bin/make_ext4fs ] && USE_MAKE_EXT4FS=1 + if [ "$USE_MAKE_EXT4FS" != "1" ]; then + sudo ls > /dev/null + fi + + make ARCH=${ARCH} CROSS_COMPILE="$CROSS_COMPILER" modules_prepare + make ARCH=${ARCH} CROSS_COMPILE="$CROSS_COMPILER" modules -j ${NCPUS} + + if [ "$?" != "0" ]; then + echo "Failed to make modules" + exit 1 + fi + + [ -d ${MOD_DIR} ] || mkdir ${MOD_DIR} + + make ARCH=${ARCH} CROSS_COMPILE="$CROSS_COMPILER" modules_install INSTALL_MOD_PATH=${MOD_DIR} INSTALL_MOD_STRIP=1 + + if [ "$USE_MAKE_EXT4FS" == "1" ]; then + /usr/bin/make_ext4fs -b 4096 -L modules -l ${MOD_SIZE}M $MOD_IMG ${MOD_DIR}/lib/modules/ + else + dd if=/dev/zero of=${MOD_IMG} bs=1M count=${MOD_SIZE} + mkfs.ext4 -F -b 4096 -L modules ${MOD_IMG} + [ -d ${MOD_DIR}/mnt ] || mkdir ${MOD_DIR}/mnt + sudo mount -o loop ${MOD_IMG} ${MOD_DIR}/mnt + sudo cp -rf ${MOD_DIR}/lib/modules/* ${MOD_DIR}/mnt + sync + sudo umount ${MOD_DIR}/mnt + fi + rm -rf ${MOD_DIR} + ls -al ${MOD_IMG} +} + +check_ccache + +echo "riscv64" +rm -f arch/riscv/boot/Image +rm -f arch/riscv/boot/dts/starfive/*.dtb +rm -f output/Image +rm -f output/*.dtb +rm -f output/modules.img +rm -f output/*.tar + +CROSS_COMPILER=riscv64-linux-gnu- +ARCH=riscv +if ! [ -e .config ] ; then + make ARCH=${ARCH} CROSS_COMPILE="$CROSS_COMPILER" tizen_vf2_defconfig +fi +make ARCH=${ARCH} CROSS_COMPILE="$CROSS_COMPILER" -j8 +if [ ! -f "./arch/riscv/boot/Image" ]; then + echo "Build fail" + exit 1 +fi + +# Make module.img file +mk_modules + +if [ ! -d output ] ; then + mkdir ./output +fi + +cp usr/modules.img ./output + +cp ./arch/riscv/boot/Image ./output +cp ./arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-v2.dtb ./output +tar cvf linux-visionfive2.tar -C output Image jh7110-starfive-visionfive-v2.dtb modules.img +mv linux-visionfive2.tar ./output/ -- 2.7.4 From 60f005304c50ce2a28e9a6ad5802422358bd2dce Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Tue, 28 Mar 2023 17:32:52 +0900 Subject: [PATCH 11/16] build: add the separated device tree file Add the separated device tree file according to VisionFive2 board revision. Change-Id: I35fa7e81199f363e0cda53fd9ecac5943743a3ab Signed-off-by: Jaehoon Chung --- build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 828ec06..58d6956 100755 --- a/build.sh +++ b/build.sh @@ -78,6 +78,6 @@ fi cp usr/modules.img ./output cp ./arch/riscv/boot/Image ./output -cp ./arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-v2.dtb ./output -tar cvf linux-visionfive2.tar -C output Image jh7110-starfive-visionfive-v2.dtb modules.img +cp ./arch/riscv/boot/dts/starfive/*.dtb ./output +tar cvf linux-visionfive2.tar -C output Image jh7110-starfive-visionfive-2-v1.2a.dtb jh7110-starfive-visionfive-2-v1.3b.dtb modules.img mv linux-visionfive2.tar ./output/ -- 2.7.4 From 6a0dc69c52138234863c880df1bbbea329f3e73e Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Wed, 29 Mar 2023 17:06:58 +0900 Subject: [PATCH 12/16] RISCV: configs: enable USB/ETH configurations Enable USB/ETH configuration relevant to JH7110. Change-Id: I14b9e28cb96b38765997373375f87bdb71ca00f7 Signed-off-by: Jaehoon Chung --- arch/riscv/configs/tizen_vf2_defconfig | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/riscv/configs/tizen_vf2_defconfig b/arch/riscv/configs/tizen_vf2_defconfig index f2d4800..ef2ce3d 100644 --- a/arch/riscv/configs/tizen_vf2_defconfig +++ b/arch/riscv/configs/tizen_vf2_defconfig @@ -125,6 +125,8 @@ CONFIG_VIRTIO_NET=y CONFIG_MACB=y CONFIG_E1000E=y CONFIG_R8169=y +CONFIG_STMMAC_ETH=y +CONFIG_DWMAC_STARFIVE=y CONFIG_MICROSEMI_PHY=y CONFIG_INPUT_MOUSEDEV=y CONFIG_SERIAL_8250=y @@ -138,6 +140,9 @@ CONFIG_SPI=y CONFIG_SPI_SIFIVE=y # CONFIG_PTP_1588_CLOCK is not set CONFIG_GPIO_SIFIVE=y +CONFIG_WATCHDOG=y +# CONFIG_MEDIA_CEC_SUPPORT is not set +CONFIG_MEDIA_SUPPORT=y CONFIG_DRM=m CONFIG_DRM_RADEON=m CONFIG_DRM_NOUVEAU=m @@ -146,13 +151,21 @@ CONFIG_FB=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_USB=y CONFIG_USB_XHCI_HCD=y -CONFIG_USB_XHCI_PLATFORM=y CONFIG_USB_EHCI_HCD=y CONFIG_USB_EHCI_HCD_PLATFORM=y CONFIG_USB_OHCI_HCD=y CONFIG_USB_OHCI_HCD_PLATFORM=y CONFIG_USB_STORAGE=y CONFIG_USB_UAS=y +CONFIG_USB_CDNS_SUPPORT=y +CONFIG_USB_CDNS3=y +CONFIG_USB_CDNS3_GADGET=y +CONFIG_USB_CDNS3_HOST=y +CONFIG_USB_CDNS3_STARFIVE=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_MASS_STORAGE=y +CONFIG_USB_CONFIGFS_F_FS=y CONFIG_MMC=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_PLTFM=y @@ -168,6 +181,9 @@ CONFIG_VIRTIO_MMIO=y CONFIG_RPMSG_CHAR=y CONFIG_RPMSG_CTRL=y CONFIG_RPMSG_VIRTIO=y +CONFIG_PHY_STARFIVE_DPHY_RX=y +CONFIG_PHY_STARFIVE_JH7110_USB=y +CONFIG_PHY_STARFIVE_JH7110_PCIE=y CONFIG_EXT4_FS=y CONFIG_EXT4_FS_POSIX_ACL=y CONFIG_EXT4_FS_SECURITY=y -- 2.7.4 From fa231f3d88dceea8b0a3f31dcf557e14a20e07da Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C5=81ukasz=20Stelmach?= Date: Wed, 29 Mar 2023 14:28:23 +0200 Subject: [PATCH 13/16] media: starfive: add "WITH Linux-syscall-note" to SPDX tag of uapi headers MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit UAPI headers licensed under GPL are supposed to have exception "WITH Linux-syscall-note" so that they can be included into non-GPL user space application code. Change-Id: I129c7bf343e3da61f8d49a023b5d16699cb18796 Origin: upstream, https://github.com/starfive-tech/linux/pull/94 Signed-off-by: Łukasz Stelmach --- include/uapi/linux/stf_isp_ioctl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/linux/stf_isp_ioctl.h b/include/uapi/linux/stf_isp_ioctl.h index 3f302ef..84a584a 100644 --- a/include/uapi/linux/stf_isp_ioctl.h +++ b/include/uapi/linux/stf_isp_ioctl.h @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ /* * stf_isp_ioctl.h * -- 2.7.4 From 7105200c2a7461745a2762d7786c24bac7286ed0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Piku=C5=82a?= Date: Fri, 31 Mar 2023 15:13:17 +0200 Subject: [PATCH 14/16] config: Enable NBD module MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Useful for development with networked SD card emulation. Change-Id: Ie02b2bdd81b44d874978497cb9dded874a9482a3 Signed-off-by: Marek Pikuła --- arch/riscv/configs/tizen_vf2_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/riscv/configs/tizen_vf2_defconfig b/arch/riscv/configs/tizen_vf2_defconfig index ef2ce3d..6056f77 100644 --- a/arch/riscv/configs/tizen_vf2_defconfig +++ b/arch/riscv/configs/tizen_vf2_defconfig @@ -99,6 +99,7 @@ CONFIG_PCIE_FU740=y CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=32768 CONFIG_VIRTIO_BLK=y -- 2.7.4 From 7dafe6dbad02f8b42277c71bfc950ead4804bb35 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Piku=C5=82a?= Date: Fri, 31 Mar 2023 15:14:22 +0200 Subject: [PATCH 15/16] packaging: Add version to modules directory MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Prevents conflict with `filesystem` package. Change-Id: I5281cf8f5349d82bdcaed9b66fdc0cb6896af96b Signed-off-by: Marek Pikuła --- packaging/linux-visionfive2.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/linux-visionfive2.spec b/packaging/linux-visionfive2.spec index e76c309..4d1279e 100644 --- a/packaging/linux-visionfive2.spec +++ b/packaging/linux-visionfive2.spec @@ -173,7 +173,7 @@ rsync -r \ rm -rf %{buildroot} %files -n %{variant}-linux-kernel-modules -/lib/modules/ +/lib/modules/%{version} %files -n %{variant}-linux-kernel-devel /boot/kernel/devel/ -- 2.7.4 From 42334fadac6fc765a558819525ff618cd9aa7611 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Piku=C5=82a?= Date: Fri, 31 Mar 2023 16:16:59 +0200 Subject: [PATCH 16/16] config: Enable FTRACE MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Required by IoT-headless preset. Change-Id: I779f566b1e7bd74a7db168c909e1ebdb7287caee Signed-off-by: Marek Pikuła --- arch/riscv/configs/tizen_vf2_defconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/riscv/configs/tizen_vf2_defconfig b/arch/riscv/configs/tizen_vf2_defconfig index 6056f77..8b5f630 100644 --- a/arch/riscv/configs/tizen_vf2_defconfig +++ b/arch/riscv/configs/tizen_vf2_defconfig @@ -218,7 +218,6 @@ CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,smack,bpf" CONFIG_CRYPTO_USER_API_HASH=y CONFIG_CRYPTO_DEV_VIRTIO=y CONFIG_PRINTK_TIME=y -CONFIG_DEBUG_FS=y CONFIG_DEBUG_PAGEALLOC=y CONFIG_SCHED_STACK_END_CHECK=y CONFIG_DEBUG_VM=y @@ -238,6 +237,6 @@ CONFIG_DEBUG_PLIST=y CONFIG_DEBUG_SG=y # CONFIG_RCU_TRACE is not set CONFIG_RCU_EQS_DEBUG=y -# CONFIG_FTRACE is not set +CONFIG_BLK_DEV_IO_TRACE=y # CONFIG_RUNTIME_TESTING_MENU is not set CONFIG_MEMTEST=y -- 2.7.4