From 19e99fb4ff73f648f2b316d0ddd8ee3c01496bd4 Mon Sep 17 00:00:00 2001 From: Siarhei Siamashka Date: Tue, 7 Jun 2016 14:28:34 +0300 Subject: sunxi: Support booting from SPI flash Allwinner devices support SPI flash as one of the possible bootable media type. The SPI flash chip needs to be connected to SPI0 pins (port C) to make this work. More information is available at: https://linux-sunxi.org/Bootable_SPI_flash This patch adds the initial support for booting from SPI flash. The existing SPI frameworks are not used in order to reduce the SPL code size. Right now the SPL size grows by ~370 bytes when CONFIG_SPL_SPI_SUNXI option is enabled. While there are no popular Allwinner devices with SPI flash at the moment, testing can be done using a SPI flash module (it can be bought for ~2$ on ebay) and jumper wires with the boards, which expose relevant pins on the expansion header. The SPI flash chips themselves are very cheap (some prices are even listed as low as 4 cents) and should not cost much if somebody decides to design a development board with an SPI flash chip soldered on the PCB. Another nice feature of the SPI flash is that it can be safely accessed in a device-independent way (since we know that the boot ROM is already probing these pins during the boot time). And if, for example, Olimex boards opted to use SPI flash instead of EEPROM, then they would have been able to have U-Boot installed in the SPI flash now and boot the rest of the system from the SATA hard drive. Hopefully we may see new interesting Allwinner based development boards in the future, now that the software support for the SPI flash is in a better shape :-) Testing can be done by enabling the CONFIG_SPL_SPI_SUNXI option in a board defconfig, then building U-Boot and finally flashing the resulting u-boot-sunxi-with-spl.bin binary over USB OTG with a help of the sunxi-fel tool: sunxi-fel spiflash-write 0 u-boot-sunxi-with-spl.bin The device needs to be switched into FEL (USB recovery) mode first. The most suitable boards for testing are Orange Pi PC and Pine64. Because these boards are cheap, have no built-in NAND/eMMC and expose SPI0 pins on the Raspberry Pi compatible expansion header. The A13-OLinuXino-Micro board also can be used. Signed-off-by: Siarhei Siamashka Reviewed-by: Simon Glass Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/gpio.h | 3 +++ arch/arm/mach-sunxi/board.c | 5 +++++ 2 files changed, 8 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 1ace548..bff7d14 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -141,6 +141,7 @@ enum sunxi_gpio_number { /* GPIO pin function config */ #define SUNXI_GPIO_INPUT 0 #define SUNXI_GPIO_OUTPUT 1 +#define SUNXI_GPIO_DISABLE 7 #define SUNXI_GPA_EMAC 2 #define SUN6I_GPA_GMAC 2 @@ -162,8 +163,10 @@ enum sunxi_gpio_number { #define SUN50I_GPB_UART0 4 #define SUNXI_GPC_NAND 2 +#define SUNXI_GPC_SPI0 3 #define SUNXI_GPC_SDC2 3 #define SUN6I_GPC_SDC3 4 +#define SUN50I_GPC_SPI0 4 #define SUN8I_GPD_SDC1 3 #define SUNXI_GPD_LCD0 2 diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 66e028e..3f5116b 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -223,6 +223,11 @@ u32 spl_boot_device(void) if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ return BOOT_DEVICE_BOARD; +#ifdef CONFIG_SPL_SPI_SUNXI + if (readb(SPL_ADDR + 0x28) == SUNXI_BOOTED_FROM_SPI) + return BOOT_DEVICE_SPI; +#endif + /* The BROM will try to boot from mmc0 first, so try that first. */ #ifdef CONFIG_MMC mmc_initialize(gd->bd); -- cgit v1.1 From 320e0570e67efbd093d7750655a758c66e9d5528 Mon Sep 17 00:00:00 2001 From: Bernhard Nortmann Date: Thu, 9 Jun 2016 07:37:35 +0200 Subject: sunxi: FEL - Add the ability to recognize and auto-import uEnv-style data The patch converts one of the "reserved" fields in the sunxi SPL header to a fel_uEnv_length entry. When booting over USB ("FEL mode"), this enables the sunxi-fel utility to pass the string length of uEnv.txt compatible data; at the same time requesting that this data be imported into the U-Boot environment. If parse_spl_header() in the sunxi board.c encounters a non-zero value in this header field, it will therefore call himport_r() to merge the string (lines) passed via FEL into the default settings. Environment vars can be changed this way even before U-Boot will attempt to autoboot - specifically, this also allows overriding "bootcmd". With fel_script_addr set and a zero fel_uEnv_length, U-Boot is safe to assume that data in .scr format (a mkimage-type script) was passed at fel_script_addr, and will handle it using the existing mechanism ("bootcmd_fel"). Signed-off-by: Bernhard Nortmann Acked-by: Siarhei Siamashka Signed-off-by: Hans de Goede --- arch/arm/include/asm/arch-sunxi/spl.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h index ec73379..5d7ab55 100644 --- a/arch/arm/include/asm/arch-sunxi/spl.h +++ b/arch/arm/include/asm/arch-sunxi/spl.h @@ -51,7 +51,14 @@ struct boot_file_head { uint8_t spl_signature[4]; }; uint32_t fel_script_address; - uint32_t reserved1[3]; + /* + * If the fel_uEnv_length member below is set to a non-zero value, + * it specifies the size (byte count) of data at fel_script_address. + * At the same time this indicates that the data is in uEnv.txt + * compatible format, ready to be imported via "env import -t". + */ + uint32_t fel_uEnv_length; + uint32_t reserved1[2]; uint32_t boot_media; /* written here by the boot ROM */ uint32_t reserved2[5]; /* padding, align to 64 bytes */ }; -- cgit v1.1 From a29710c525ff43c3031b879e2beac306a09c6944 Mon Sep 17 00:00:00 2001 From: Amit Singh Tomar Date: Wed, 6 Jul 2016 17:59:44 +0530 Subject: net: Add EMAC driver for H3/A83T/A64 SoCs. This patch add EMAC driver support for H3/A83T/A64 SoCs. Tested on Pine64(A64-External PHY) and Orangepipc(H3-Internal PHY). BIG Thanks to Andre for providing some of the DT code. Signed-off-by: Amit Singh Tomar Acked-by: Hans de Goede Signed-off-by: Hans de Goede --- arch/arm/dts/sun50i-a64-pine64-plus.dts | 13 +++++++++++ arch/arm/dts/sun50i-a64.dtsi | 33 +++++++++++++++++++++++++++ arch/arm/dts/sun8i-h3-orangepi-2.dts | 13 +++++++++++ arch/arm/dts/sun8i-h3-orangepi-pc.dts | 12 ++++++++++ arch/arm/dts/sun8i-h3.dtsi | 25 ++++++++++++++++++++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 +++- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 3 ++- 7 files changed, 101 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/dts/sun50i-a64-pine64-plus.dts b/arch/arm/dts/sun50i-a64-pine64-plus.dts index 549dc15..389c609 100644 --- a/arch/arm/dts/sun50i-a64-pine64-plus.dts +++ b/arch/arm/dts/sun50i-a64-pine64-plus.dts @@ -57,3 +57,16 @@ reg = <0x40000000 0x40000000>; }; }; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + phy-mode = "rgmii"; + phy = <&phy1>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + diff --git a/arch/arm/dts/sun50i-a64.dtsi b/arch/arm/dts/sun50i-a64.dtsi index 1bd436f..7d0dc76 100644 --- a/arch/arm/dts/sun50i-a64.dtsi +++ b/arch/arm/dts/sun50i-a64.dtsi @@ -506,6 +506,25 @@ allwinner,drive = ; allwinner,pull = ; }; + + rmii_pins: rmii_pins { + allwinner,pins = "PD10", "PD11", "PD13", "PD14", + "PD17", "PD18", "PD19", "PD20", + "PD22", "PD23"; + allwinner,function = "emac"; + allwinner,drive = ; + allwinner,pull = ; + }; + + rgmii_pins: rgmii_pins { + allwinner,pins = "PD8", "PD9", "PD10", "PD11", + "PD12", "PD13", "PD15", + "PD16", "PD17", "PD18", "PD19", + "PD20", "PD21", "PD22", "PD23"; + allwinner,function = "emac"; + allwinner,drive = ; + allwinner,pull = ; + }; }; ahb_rst: reset@1c202c0 { @@ -620,5 +639,19 @@ #address-cells = <1>; #size-cells = <0>; }; + + emac: ethernet@01c30000 { + compatible = "allwinner,sun50i-a64-emac"; + reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; + reg-names = "emac", "syscon"; + interrupts = ; + resets = <&ahb_rst 17>; + reset-names = "ahb"; + clocks = <&bus_gates 17>; + clock-names = "ahb"; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; }; }; diff --git a/arch/arm/dts/sun8i-h3-orangepi-2.dts b/arch/arm/dts/sun8i-h3-orangepi-2.dts index f93f5d1..d3f8f55 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-2.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-2.dts @@ -184,3 +184,16 @@ usb1_vbus-supply = <®_usb1_vbus>; status = "okay"; }; + +&emac { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_pins>; + phy-mode = "rgmii"; + phy = <&phy1>; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; + diff --git a/arch/arm/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/dts/sun8i-h3-orangepi-pc.dts index 30ccca0..0a74a91 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-pc.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-pc.dts @@ -173,3 +173,15 @@ /* USB VBUS is always on */ status = "okay"; }; + +&emac { + phy = <&phy1>; + phy-mode = "mii"; + allwinner,use-internal-phy; + allwinner,leds-active-low; + status = "okay"; + + phy1: ethernet-phy@1 { + reg = <1>; + }; +}; diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi index c2f63c5..6ca5e34 100644 --- a/arch/arm/dts/sun8i-h3.dtsi +++ b/arch/arm/dts/sun8i-h3.dtsi @@ -501,6 +501,17 @@ interrupt-controller; #interrupt-cells = <3>; + rgmii_pins: rgmii_pins { + allwinner,pins = "PD0", "PD1", "PD2", "PD3", + "PD4", "PD5", "PD7", + "PD8", "PD9", "PD10", + "PD12", "PD13", "PD15", + "PD16", "PD17"; + allwinner,function = "emac"; + allwinner,drive = ; + allwinner,pull = ; + }; + uart0_pins_a: uart0@0 { allwinner,pins = "PA4", "PA5"; allwinner,function = "uart0"; @@ -616,6 +627,20 @@ status = "disabled"; }; + emac: ethernet@01c30000 { + compatible = "allwinner,sun8i-h3-emac"; + reg = <0x01c30000 0x2000>, <0x01c00030 0x4>; + reg-names = "emac", "syscon"; + interrupts = ; + resets = <&ahb_rst 17>, <&ahb_rst 66>; + reset-names = "ahb", "ephy"; + clocks = <&bus_gates 17>, <&bus_gates 128>; + clock-names = "ahb", "ephy"; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index c2e72f5..d4dff1e 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -40,7 +40,8 @@ struct sunxi_ccm_reg { u32 ahb_gate1; /* 0x64 ahb module clock gating 1 */ u32 apb1_gate; /* 0x68 apb1 module clock gating */ u32 apb2_gate; /* 0x6c apb2 module clock gating */ - u32 reserved9[4]; + u32 bus_gate4; /* 0x70 gate 4 module clock gating */ + u8 res3[0xc]; u32 nand0_clk_cfg; /* 0x80 nand0 clock control */ u32 nand1_clk_cfg; /* 0x84 nand1 clock control */ u32 sd0_clk_cfg; /* 0x88 sd0 clock control */ @@ -387,6 +388,7 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_LCD0 4 /* ahb_reset2 offsets */ +#define AHB_RESET_OFFSET_EPHY 2 #define AHB_RESET_OFFSET_LVDS 0 /* apb2 reset */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index c5e9d88..cd009d7 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -87,7 +87,8 @@ #define SUNXI_KEYPAD_BASE 0x01c23000 #define SUNXI_TZPC_BASE 0x01c23400 -#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) +#if defined(CONFIG_MACH_SUN8I_A83T) || defined(CONFIG_MACH_SUN8I_H3) || \ +defined(CONFIG_MACH_SUN50I) /* SID address space starts at 0x01c1400, but e-fuse is at offset 0x200 */ #define SUNXI_SID_BASE 0x01c14200 #else -- cgit v1.1 From ef36d9ae1646e5aee7c1425ee507d275699a072e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jul 2016 15:31:47 +0200 Subject: sunxi: Use BROM stored boot_media value to determine our boot-source Now that we know that the BROM stores a value indicating the boot-source at the beginning of SRAM, use that instead of trying to recreate the BROM's boot probing. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/include/asm/arch-sunxi/mmc.h | 1 - arch/arm/mach-sunxi/board.c | 34 +++++++++++----------------------- 2 files changed, 11 insertions(+), 24 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h index 3da360b..cb52e64 100644 --- a/arch/arm/include/asm/arch-sunxi/mmc.h +++ b/arch/arm/include/asm/arch-sunxi/mmc.h @@ -127,5 +127,4 @@ struct sunxi_mmc { #define SUNXI_MMC_COMMON_RESET (1 << 18) struct mmc *sunxi_mmc_init(int sdc_no); -int sunxi_mmc_has_egon_boot_signature(struct mmc *mmc); #endif /* _SUNXI_MMC_H */ diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 3f5116b..06a1986 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -203,7 +203,8 @@ DECLARE_GLOBAL_DATA_PTR; */ u32 spl_boot_device(void) { - __maybe_unused struct mmc *mmc0, *mmc1; + int boot_source; + /* * When booting from the SD card or NAND memory, the "eGON.BT0" * signature is expected to be found in memory at the address 0x0004 @@ -223,32 +224,19 @@ u32 spl_boot_device(void) if (!is_boot0_magic(SPL_ADDR + 4)) /* eGON.BT0 */ return BOOT_DEVICE_BOARD; -#ifdef CONFIG_SPL_SPI_SUNXI - if (readb(SPL_ADDR + 0x28) == SUNXI_BOOTED_FROM_SPI) - return BOOT_DEVICE_SPI; -#endif - - /* The BROM will try to boot from mmc0 first, so try that first. */ -#ifdef CONFIG_MMC - mmc_initialize(gd->bd); - mmc0 = find_mmc_device(0); - if (sunxi_mmc_has_egon_boot_signature(mmc0)) + boot_source = readb(SPL_ADDR + 0x28); + switch (boot_source) { + case SUNXI_BOOTED_FROM_MMC0: return BOOT_DEVICE_MMC1; -#endif - - /* Fallback to booting NAND if enabled. */ - if (IS_ENABLED(CONFIG_SPL_NAND_SUPPORT)) + case SUNXI_BOOTED_FROM_NAND: return BOOT_DEVICE_NAND; - -#ifdef CONFIG_MMC - if (CONFIG_MMC_SUNXI_SLOT_EXTRA == 2) { - mmc1 = find_mmc_device(1); - if (sunxi_mmc_has_egon_boot_signature(mmc1)) - return BOOT_DEVICE_MMC2; + case SUNXI_BOOTED_FROM_MMC2: + return BOOT_DEVICE_MMC2; + case SUNXI_BOOTED_FROM_SPI: + return BOOT_DEVICE_SPI; } -#endif - panic("Could not determine boot source\n"); + panic("Unknown boot source %d\n", boot_source); return -1; /* Never reached */ } -- cgit v1.1 From fa8a485d06188e38abc9c46fbd1be916fe16fb7a Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jul 2016 17:31:14 +0200 Subject: sunxi: Sync sun8i-h3-orangepi-plus.dts with upstream This enables extra USB controllers which enable use of the 3rd USB port on the new Orange Pi Plus 2E variant. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/dts/sun8i-h3-orangepi-plus.dts | 127 +++++++------------------------- arch/arm/dts/sun8i-h3.dtsi | 10 +++ 2 files changed, 37 insertions(+), 100 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/dts/sun8i-h3-orangepi-plus.dts b/arch/arm/dts/sun8i-h3-orangepi-plus.dts index 900ec4f..28f74f6 100644 --- a/arch/arm/dts/sun8i-h3-orangepi-plus.dts +++ b/arch/arm/dts/sun8i-h3-orangepi-plus.dts @@ -40,26 +40,13 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -/dts-v1/; -#include "sun8i-h3.dtsi" -#include "sunxi-common-regulators.dtsi" - -#include -#include -#include +/* The Orange Pi Plus is an extended version of the Orange Pi 2 */ +#include "sun8i-h3-orangepi-2.dts" / { - model = "Xunlong Orange Pi Plus"; + model = "Xunlong Orange Pi Plus / Plus 2 / Plus 2E"; compatible = "xunlong,orangepi-plus", "allwinner,sun8i-h3"; - aliases { - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - reg_usb3_vbus: usb3-vbus { compatible = "regulator-fixed"; pinctrl-names = "default"; @@ -71,75 +58,42 @@ enable-active-high; gpio = <&pio 6 11 GPIO_ACTIVE_HIGH>; }; +}; - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&leds_opc>; - - status_led { - label = "status:red:user"; - gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; - }; - }; - - r_leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&leds_r_opc>; - - tx { - label = "pwr:green:user"; - gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; - default-state = "on"; - }; - }; - - r_gpio_keys { - compatible = "gpio-keys"; - input-name = "sw4"; - - pinctrl-names = "default"; - pinctrl-0 = <&sw_r_opc>; +&ehci2 { + status = "okay"; +}; - sw4@0 { - label = "sw4"; - linux,code = ; - gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; - }; - }; +&ehci3 { + status = "okay"; }; -&pio { - leds_opc: led_pins@0 { - allwinner,pins = "PA15"; - allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; - }; +&mmc2 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_8bit_pins>; + vmmc-supply = <®_vcc3v3>; + bus-width = <8>; + non-removable; + cap-mmc-hw-reset; + status = "okay"; }; -&r_pio { - leds_r_opc: led_pins@0 { - allwinner,pins = "PL10"; - allwinner,function = "gpio_out"; - allwinner,drive = ; - allwinner,pull = ; - }; +&mmc2_8bit_pins { + /* Increase drive strength for DDR modes */ + allwinner,drive = ; + /* eMMC is missing pull-ups */ + allwinner,pull = ; +}; - sw_r_opc: key_pins@0 { - allwinner,pins = "PL03"; - allwinner,function = "gpio_in"; - allwinner,drive = ; - allwinner,pull = ; - }; +&ohci1 { + status = "okay"; }; -&ehci1 { +&ohci2 { status = "okay"; }; -&ehci3 { +&ohci3 { status = "okay"; }; @@ -152,33 +106,6 @@ }; }; -&mmc0 { - pinctrl-names = "default"; - pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; - vmmc-supply = <®_vcc3v3>; - bus-width = <4>; - cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ - cd-inverted; - status = "okay"; -}; - -®_usb1_vbus { - gpio = <&pio 6 13 GPIO_ACTIVE_HIGH>; - status = "okay"; -}; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; - status = "okay"; -}; - -&usb1_vbus_pin_a { - allwinner,pins = "PG13"; -}; - &usbphy { - usb1_vbus-supply = <®_usb1_vbus>; usb3_vbus-supply = <®_usb3_vbus>; - status = "okay"; }; diff --git a/arch/arm/dts/sun8i-h3.dtsi b/arch/arm/dts/sun8i-h3.dtsi index 6ca5e34..72c0920 100644 --- a/arch/arm/dts/sun8i-h3.dtsi +++ b/arch/arm/dts/sun8i-h3.dtsi @@ -541,6 +541,16 @@ allwinner,drive = ; allwinner,pull = ; }; + + mmc2_8bit_pins: mmc2_8bit { + allwinner,pins = "PC5", "PC6", "PC8", + "PC9", "PC10", "PC11", + "PC12", "PC13", "PC14", + "PC15", "PC16"; + allwinner,function = "mmc2"; + allwinner,drive = ; + allwinner,pull = ; + }; }; ahb_rst: reset@01c202c0 { -- cgit v1.1 From 66ab5286736e47cc4fdec9ceab4cc1b2f24ed066 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Sat, 9 Jul 2016 22:20:00 +0200 Subject: sunxi: Add defconfig and dts file for the Orange Pi Lite SBC The Orange Pi Lite SBC is a small H3 based SBC, with 512MB RAM, micro-sd slot, HDMI out, 2 USB-A connectors, 1 micro-USB connector, sdio attached rtl8189ftv wifi and an ir receiver. The dts file is identical to the one submitted to the upstream kernel. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- arch/arm/dts/Makefile | 1 + arch/arm/dts/sun8i-h3-orangepi-lite.dts | 178 ++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 arch/arm/dts/sun8i-h3-orangepi-lite.dts (limited to 'arch/arm') diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ef573ec..acecb7c 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -242,6 +242,7 @@ dtb-$(CONFIG_MACH_SUN8I_A83T) += \ sun8i-a83t-sinovoip-bpi-m3.dtb dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-2.dtb \ + sun8i-h3-orangepi-lite.dtb \ sun8i-h3-orangepi-one.dtb \ sun8i-h3-orangepi-pc.dtb \ sun8i-h3-orangepi-plus.dtb diff --git a/arch/arm/dts/sun8i-h3-orangepi-lite.dts b/arch/arm/dts/sun8i-h3-orangepi-lite.dts new file mode 100644 index 0000000..ac71749 --- /dev/null +++ b/arch/arm/dts/sun8i-h3-orangepi-lite.dts @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2016 Hans de Goede + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-h3.dtsi" +#include "sunxi-common-regulators.dtsi" + +#include +#include +#include + +/ { + model = "Xunlong Orange Pi Lite"; + compatible = "xunlong,orangepi-lite", "allwinner,sun8i-h3"; + + aliases { + /* The H3 emac is not used so the wifi is ethernet0 */ + ethernet1 = &rtl8189ftv; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&leds_opc>, <&leds_r_opc>; + + pwr_led { + label = "orangepi:green:pwr"; + gpios = <&r_pio 0 10 GPIO_ACTIVE_HIGH>; + default-state = "on"; + }; + + status_led { + label = "orangepi:red:status"; + gpios = <&pio 0 15 GPIO_ACTIVE_HIGH>; + }; + }; + + r_gpio_keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&sw_r_opc>; + + sw4 { + label = "sw4"; + linux,code = ; + gpios = <&r_pio 0 3 GPIO_ACTIVE_LOW>; + }; + }; +}; + +&ehci1 { + status = "okay"; +}; + +&ehci2 { + status = "okay"; +}; + +&ir { + pinctrl-names = "default"; + pinctrl-0 = <&ir_pins_a>; + status = "okay"; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 */ + cd-inverted; + status = "okay"; +}; + +&mmc1 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_pins_a>; + vmmc-supply = <®_vcc3v3>; + bus-width = <4>; + non-removable; + status = "okay"; + + /* + * Explicitly define the sdio device, so that we can add an ethernet + * alias for it (which e.g. makes u-boot set a mac-address). + */ + rtl8189ftv: sdio_wifi@1 { + reg = <1>; + }; +}; + +&ohci1 { + status = "okay"; +}; + +&ohci2 { + status = "okay"; +}; + +&pio { + leds_opc: led_pins@0 { + allwinner,pins = "PA15"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +&r_pio { + leds_r_opc: led_pins@0 { + allwinner,pins = "PL10"; + allwinner,function = "gpio_out"; + allwinner,drive = ; + allwinner,pull = ; + }; + + sw_r_opc: key_pins@0 { + allwinner,pins = "PL3"; + allwinner,function = "gpio_in"; + allwinner,drive = ; + allwinner,pull = ; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&usbphy { + /* USB VBUS is always on */ + status = "okay"; +}; -- cgit v1.1 From b52813239c10d857bd262dc850232ccccdbaa69e Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:31 +0800 Subject: ARM: PSCI: Split out common stack setup code from psci_arch_init Every platform has the same stack setup code in assembly as part of psci_arch_init. Move this out into a common separate function, psci_stack_setup, for all platforms. This will allow us to move the remaining parts of psci_arch_init into C code, or drop it entirely. Also provide a stub no-op psci_arch_init for platforms that don't need their own specific setup code. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/ls102xa/psci.S | 10 ---------- arch/arm/cpu/armv7/mx7/psci.S | 16 ---------------- arch/arm/cpu/armv7/nonsec_virt.S | 7 ++++++- arch/arm/cpu/armv7/psci.S | 18 ++++++++++++++++++ arch/arm/cpu/armv7/sunxi/psci_head.S | 16 +--------------- arch/arm/mach-tegra/psci.S | 3 --- 6 files changed, 25 insertions(+), 45 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index cf5cd48..86116e1f 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -111,16 +111,6 @@ psci_cpu_off: 1: wfi b 1b -.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - .globl psci_text_end psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 34c6ab3..12cca7c 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -9,22 +9,6 @@ .arch_extension sec - @ r1 = target CPU - @ r2 = target PC - -.globl psci_arch_init -psci_arch_init: - mov r6, lr - - bl psci_get_cpu_id - bl psci_get_cpu_stack_top - mov sp, r0 - - bx r6 - - @ r1 = target CPU - @ r2 = target PC - .globl psci_cpu_on psci_cpu_on: push {lr} diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S index b7563ed..95ce938 100644 --- a/arch/arm/cpu/armv7/nonsec_virt.S +++ b/arch/arm/cpu/armv7/nonsec_virt.S @@ -49,8 +49,13 @@ _secure_monitor: mcr p15, 0, r5, c12, c0, 1 isb - @ Obtain a secure stack, and configure the PSCI backend + @ Obtain a secure stack + bl psci_stack_setup + + @ Configure the PSCI backend + push {r0, r1, r2, ip} bl psci_arch_init + pop {r0, r1, r2, ip} #endif #ifdef CONFIG_ARM_ERRATA_773022 diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index ab40837..46fcf77 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -211,6 +211,24 @@ ENTRY(psci_get_cpu_stack_top) bx lr ENDPROC(psci_get_cpu_stack_top) +@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in +@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across +@ this function. +ENTRY(psci_stack_setup) + mov r6, lr + mov r7, r0 + bl psci_get_cpu_id @ CPU ID => r0 + bl psci_get_cpu_stack_top @ stack top => r0 + mov sp, r0 + mov r0, r7 + bx r6 +ENDPROC(psci_stack_setup) + +ENTRY(psci_arch_init) + mov pc, lr +ENDPROC(psci_arch_init) +.weak psci_arch_init + ENTRY(psci_cpu_entry) bl psci_enable_smp diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S index 8fa823d..e51db04 100644 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ b/arch/arm/cpu/armv7/sunxi/psci_head.S @@ -44,22 +44,8 @@ #define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) #define GICC_BASE (SUNXI_GIC400_BASE + 0x2000) -@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in -@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across -@ this function. ENTRY(psci_arch_init) - mov r6, lr - mov r7, r0 - bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - sub r0, r0, #4 @ Save space for target PC - mov sp, r0 - mov r0, r7 - mov lr, r6 - - push {r0, r1, r2, ip, lr} - bl sunxi_gic_init - pop {r0, r1, r2, ip, pc} + b sunxi_gic_init ENDPROC(psci_arch_init) ENTRY(psci_text_end) diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index b836da1..75068f3 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -61,9 +61,6 @@ ENTRY(psci_arch_init) ldrne r7, [r5] mcrne p15, 0, r7, c14, c0, 0 @ write CNTFRQ to CPU1..3 - bl psci_get_cpu_stack_top @ stack top => r0 - mov sp, r0 - bx r6 ENDPROC(psci_arch_init) -- cgit v1.1 From 94a389b257039511784b91a263913c845c8146e4 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:32 +0800 Subject: sunxi: Move remaining PSCI assembly code to C This patch finishes the rewrite of sunxi specific PSCI parts into C code. The assembly-only stack setup code has been factored out into a common function for ARMv7. The GIC setup code can be renamed as psci_arch_init. And we can use an empty stub function for psci_text_end. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/sunxi/Makefile | 1 - arch/arm/cpu/armv7/sunxi/psci.c | 7 ++++- arch/arm/cpu/armv7/sunxi/psci_head.S | 52 ------------------------------------ 3 files changed, 6 insertions(+), 54 deletions(-) delete mode 100644 arch/arm/cpu/armv7/sunxi/psci_head.S (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index c208510..b35b9df 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_ARMV7_PSCI) += psci.o -obj-$(CONFIG_ARMV7_PSCI) += psci_head.o endif ifdef CONFIG_SPL_BUILD diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index a118e9d..cd0d944 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -250,7 +250,7 @@ void __secure psci_cpu_off(void) wfi(); } -void __secure sunxi_gic_init(void) +void __secure psci_arch_init(void) { u32 reg; @@ -271,3 +271,8 @@ void __secure sunxi_gic_init(void) reg &= ~BIT(0); /* Secure mode */ cp15_write_scr(reg); } + +/* dummy entry for end of psci text */ +void __secure psci_text_end(void) +{ +} diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S deleted file mode 100644 index e51db04..0000000 --- a/arch/arm/cpu/armv7/sunxi/psci_head.S +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2013 - ARM Ltd - * Author: Marc Zyngier - * - * Based on code by Carl van Schaik . - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include -#include -#include -#include -#include - -/* - * Memory layout: - * - * SECURE_RAM to text_end : - * ._secure_text section - * text_end to ALIGN_PAGE(text_end): - * nothing - * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000) - * 1kB of stack per CPU (4 CPUs max). - */ - - .pushsection ._secure.text, "ax" - - .arch_extension sec - -#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000) -#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000) - -ENTRY(psci_arch_init) - b sunxi_gic_init -ENDPROC(psci_arch_init) - -ENTRY(psci_text_end) - .popsection -- cgit v1.1 From a1274cc94a20a0fc6715522d021ab84969b6bf91 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:34 +0800 Subject: ARM: Page align secure section only when it is executed in situ Targets that define CONFIG_ARMV7_SECURE_BASE will copy the secure section to another address before execution. Since the secure section in the u-boot image is only storage, there's no reason to page align it and increase the binary image size. Page align the secure section only when CONFIG_ARMV7_SECURE_BASE is not defined. And instead of just aligning the __secure_start symbol, align the whole .__secure_start section. This also makes the section empty, so we need to add KEEP() to the input entry to prevent the section from being garbage collected. Also use ld constant "COMMONPAGESIZE" instead of hardcoded page size. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 1769b6e..ba17778 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -48,16 +48,20 @@ SECTIONS #ifdef CONFIG_ARMV7_NONSEC + /* Align the secure section only if we're going to use it in situ */ + .__secure_start : +#ifndef CONFIG_ARMV7_SECURE_BASE + ALIGN(CONSTANT(COMMONPAGESIZE)) +#endif + { + KEEP(*(.__secure_start)) + } + #ifndef CONFIG_ARMV7_SECURE_BASE #define CONFIG_ARMV7_SECURE_BASE #define __ARMV7_PSCI_STACK_IN_RAM #endif - .__secure_start : { - . = ALIGN(0x1000); - *(.__secure_start) - } - .secure_text CONFIG_ARMV7_SECURE_BASE : AT(ADDR(.__secure_start) + SIZEOF(.__secure_start)) { -- cgit v1.1 From 980d6a55119f757ade4abed88bf4b2b7494c68e6 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:36 +0800 Subject: ARM: Add an empty secure stack section Until now we've been using memory beyond psci_text_end as stack space for the secure monitor or PSCI implementation, even if space was not allocated for it. This was partially fixed in ("ARM: allocate extra space for PSCI stack in secure section during link phase"). However, calculating stack space from psci_text_end in one place, while allocating the space in another is error prone. This patch adds a separate empty secure stack section, with space for CONFIG_ARMV7_PSCI_NR_CPUS stacks, each 1 KB. There's also __secure_stack_start and __secure_stack_end symbols. The linker script handles calculating the correct VMAs for the stack section. For platforms that relocate/copy the secure monitor before using it, the space is not allocated in the executable, saving space. For platforms that do not define CONFIG_ARMV7_PSCI_NR_CPUS, a whole page of stack space for 4 CPUs is allocated, matching the previous behavior. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 32 +++++++++++++++++++++++--------- arch/arm/include/asm/armv7.h | 2 ++ arch/arm/include/asm/psci.h | 4 ++++ arch/arm/lib/sections.c | 2 ++ 4 files changed, 31 insertions(+), 9 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index ba17778..002706a 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -8,6 +8,7 @@ */ #include +#include OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) @@ -68,18 +69,31 @@ SECTIONS *(._secure.text) } - . = LOADADDR(.__secure_start) + - SIZEOF(.__secure_start) + - SIZEOF(.secure_text); - + .secure_stack ALIGN(ADDR(.secure_text) + SIZEOF(.secure_text), + CONSTANT(COMMONPAGESIZE)) (NOLOAD) : #ifdef __ARMV7_PSCI_STACK_IN_RAM - /* Align to page boundary and skip 2 pages */ - . = (. & ~ 0xfff) + 0x2000; -#undef __ARMV7_PSCI_STACK_IN_RAM + AT(ADDR(.secure_stack)) +#else + AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) +#endif + { + KEEP(*(.__secure_stack_start)) + + /* Skip addreses for stack */ + . = . + CONFIG_ARMV7_PSCI_NR_CPUS * ARM_PSCI_STACK_SIZE; + + /* Align end of stack section to page boundary */ + . = ALIGN(CONSTANT(COMMONPAGESIZE)); + + KEEP(*(.__secure_stack_end)) + } + +#ifndef __ARMV7_PSCI_STACK_IN_RAM + /* Reset VMA but don't allocate space if we have secure SRAM */ + . = LOADADDR(.secure_stack); #endif - __secure_end_lma = .; - .__secure_end : AT(__secure_end_lma) { + .__secure_end : AT(ADDR(.__secure_end)) { *(.__secure_end) LONG(0x1d1071c); /* Must output something to reset LMA */ } diff --git a/arch/arm/include/asm/armv7.h b/arch/arm/include/asm/armv7.h index 423fc70..a20702e 100644 --- a/arch/arm/include/asm/armv7.h +++ b/arch/arm/include/asm/armv7.h @@ -126,6 +126,8 @@ void _smp_pen(void); extern char __secure_start[]; extern char __secure_end[]; +extern char __secure_stack_start[]; +extern char __secure_stack_end[]; #endif /* CONFIG_ARMV7_NONSEC */ diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index bc5edda..dab5769 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -47,6 +47,10 @@ #define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8) #define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9) +/* 1KB stack per core */ +#define ARM_PSCI_STACK_SHIFT 10 +#define ARM_PSCI_STACK_SIZE (1 << ARM_PSCI_STACK_SHIFT) + #ifndef __ASSEMBLY__ #include diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c index 6a94522..952e8ae 100644 --- a/arch/arm/lib/sections.c +++ b/arch/arm/lib/sections.c @@ -27,6 +27,8 @@ char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); char __secure_start[0] __attribute__((section(".__secure_start"))); char __secure_end[0] __attribute__((section(".__secure_end"))); +char __secure_stack_start[0] __attribute__((section(".__secure_stack_start"))); +char __secure_stack_end[0] __attribute__((section(".__secure_stack_end"))); char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start"))); -- cgit v1.1 From 8c0ef7fad676827125ad91060361d05ab4b16f44 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:37 +0800 Subject: ARM: PSCI: Allocate PSCI stack in secure stack section Now that we have a secure stack section that guarantees usable memory, allocate the PSCI stacks in that section. Also add a diagram detailing how the stacks are placed in memory. Reserved space for the target PC remains unchanged. This should be moved to global variables within a secure data section in the future. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/psci.S | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 46fcf77..bfc4475 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -196,18 +196,28 @@ ENTRY(psci_cpu_off_common) bx lr ENDPROC(psci_cpu_off_common) -@ expects CPU ID in r0 and returns stack top in r0 +@ The stacks are allocated in reverse order, i.e. +@ the stack for CPU0 has the highest memory address. +@ +@ -------------------- __secure_stack_end +@ | CPU0 target PC | +@ |------------------| +@ | | +@ | CPU0 stack | +@ | | +@ |------------------| __secure_stack_end - 1KB +@ | . | +@ | . | +@ | . | +@ | . | +@ -------------------- __secure_stack_start +@ +@ This expects CPU ID in r0 and returns stack top in r0 ENTRY(psci_get_cpu_stack_top) - mov r3, #0x400 @ 1kB of stack per CPU - mul r0, r0, r3 - - ldr r3, =psci_text_end @ end of monitor text - add r3, r3, #0x2000 @ Skip two pages - lsr r3, r3, #12 @ Align to start of page - lsl r3, r3, #12 - sub r3, r3, #4 @ reserve 1 word for target PC - sub r0, r3, r0 @ here's our stack! - + @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT) + ldr r3, =__secure_stack_end + sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT + sub r0, r0, #4 @ Save space for target PC bx lr ENDPROC(psci_get_cpu_stack_top) -- cgit v1.1 From 28f90357323bc65e7da01c458222b84dc42988bb Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:38 +0800 Subject: ARM: PSCI: Remove unused psci_text_end symbol psci_text_end was used to calculate the PSCI stack address following the secure monitor text. Now that we have an explicit secure stack section, this is no longer used. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/ls102xa/psci.S | 2 -- arch/arm/cpu/armv7/mx7/psci.S | 2 -- arch/arm/cpu/armv7/sunxi/psci.c | 5 ----- arch/arm/mach-tegra/psci.S | 2 -- 4 files changed, 11 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index 86116e1f..ba043ef 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -111,6 +111,4 @@ psci_cpu_off: 1: wfi b 1b - .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index 12cca7c..d9e9fbf 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -33,6 +33,4 @@ psci_cpu_off: 1: wfi b 1b - .globl psci_text_end -psci_text_end: .popsection diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index cd0d944..c7d97fe 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -271,8 +271,3 @@ void __secure psci_arch_init(void) reg &= ~BIT(0); /* Secure mode */ cp15_write_scr(reg); } - -/* dummy entry for end of psci text */ -void __secure psci_text_end(void) -{ -} diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 75068f3..85d5b6b 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -106,6 +106,4 @@ ENTRY(psci_cpu_on) pop {pc} ENDPROC(psci_cpu_on) - .globl psci_text_end -psci_text_end: .popsection -- cgit v1.1 From 3eff681818e2c858175a7cc4e766f75e95827920 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:39 +0800 Subject: ARM: Add CONFIG_ARMV7_SECURE_MAX_SIZE and check size of secure section As the PSCI implementation grows, we might exceed the size of the secure memory that holds the firmware. Add a configurable CONFIG_ARMV7_SECURE_MAX_SIZE so platforms can define how much secure memory is available. The linker then checks the size of the whole secure section against this. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/u-boot.lds | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 002706a..5a65c27 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -86,6 +86,17 @@ SECTIONS . = ALIGN(CONSTANT(COMMONPAGESIZE)); KEEP(*(.__secure_stack_end)) + +#ifdef CONFIG_ARMV7_SECURE_MAX_SIZE + /* + * We are not checking (__secure_end - __secure_start) here, + * as these are the load addresses, and do not include the + * stack section. Instead, use the end of the stack section + * and the start of the text section. + */ + ASSERT((. - ADDR(.secure_text)) <= CONFIG_ARMV7_SECURE_MAX_SIZE, + "Error: secure section exceeds secure memory size"); +#endif } #ifndef __ARMV7_PSCI_STACK_IN_RAM -- cgit v1.1 From afc1f65f504324cd5f87a8cb480bebeb0c61e4e0 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:41 +0800 Subject: ARM: Move __secure definition to common asm/secure.h sunxi and i.mx7 both define the __secure modifier to put functions in the secure section. Move this to a common place. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/mx7/psci-mx7.c | 2 +- arch/arm/cpu/armv7/sunxi/psci.c | 2 +- arch/arm/include/asm/secure.h | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c index 9a33047..502552d 100644 --- a/arch/arm/cpu/armv7/mx7/psci-mx7.c +++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c @@ -1,9 +1,9 @@ #include #include +#include #include #include -#define __secure __attribute__((section("._secure.text"))) #define GPC_CPU_PGC_SW_PDN_REQ 0xfc #define GPC_CPU_PGC_SW_PUP_REQ 0xf0 diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index c7d97fe..be3a1fb 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -17,11 +17,11 @@ #include #include #include +#include #include #include -#define __secure __attribute__ ((section ("._secure.text"))) #define __irq __attribute__ ((interrupt ("IRQ"))) #define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET) diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index effdb18..6d9088b 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -3,6 +3,8 @@ #include +#define __secure __attribute__ ((section ("._secure.text"))) + #ifdef CONFIG_ARMV7_SECURE_BASE /* * Warning, horror ahead. -- cgit v1.1 From a5aa7ff33a942ce8ea38006fd5225a800827bb2c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 5 Jul 2016 21:45:06 +0800 Subject: ARM: Add secure section for initialized data The secure monitor may need to store global or static values within the secure section of memory, such as target PC or CPU power status. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/config.mk | 4 ++-- arch/arm/cpu/u-boot.lds | 9 +++++++-- arch/arm/include/asm/secure.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/config.mk b/arch/arm/config.mk index 9a5a974..8f85862 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -120,8 +120,8 @@ endif ifdef CONFIG_ARM64 OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -j .rela.dyn else -OBJCOPYFLAGS += -j .text -j .secure_text -j .rodata -j .hash -j .data -j \ - .got -j .got.plt -j .u_boot_list -j .rel.dyn +OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \ + -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn endif ifdef CONFIG_OF_EMBED diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 5a65c27..36c9fd0 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -69,12 +69,17 @@ SECTIONS *(._secure.text) } - .secure_stack ALIGN(ADDR(.secure_text) + SIZEOF(.secure_text), + .secure_data : AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + { + *(._secure.data) + } + + .secure_stack ALIGN(ADDR(.secure_data) + SIZEOF(.secure_data), CONSTANT(COMMONPAGESIZE)) (NOLOAD) : #ifdef __ARMV7_PSCI_STACK_IN_RAM AT(ADDR(.secure_stack)) #else - AT(LOADADDR(.secure_text) + SIZEOF(.secure_text)) + AT(LOADADDR(.secure_data) + SIZEOF(.secure_data)) #endif { KEEP(*(.__secure_stack_start)) diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index 6d9088b..5a403bc 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -4,6 +4,7 @@ #include #define __secure __attribute__ ((section ("._secure.text"))) +#define __secure_data __attribute__ ((section ("._secure.data"))) #ifdef CONFIG_ARMV7_SECURE_BASE /* -- cgit v1.1 From 45c334e6b22bae75ada8662b88000c4347b1361b Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Tue, 5 Jul 2016 21:45:07 +0800 Subject: ARM: PSCI: Add helper functions to access per-CPU target PC storage Now that we have a data section, add helper functions to save and fetch per-CPU target PC. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/Makefile | 2 +- arch/arm/cpu/armv7/psci-common.c | 39 +++++++++++++++++++++++++++++++++++++++ arch/arm/include/asm/psci.h | 4 ++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/psci-common.c (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index ddd8d12..0d4bfbc 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -19,7 +19,7 @@ endif endif obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o -obj-$(CONFIG_ARMV7_PSCI) += psci.o +obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o obj-$(CONFIG_IPROC) += iproc-common/ obj-$(CONFIG_KONA) += kona-common/ diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c new file mode 100644 index 0000000..d14b693 --- /dev/null +++ b/arch/arm/cpu/armv7/psci-common.c @@ -0,0 +1,39 @@ +/* + * Common PSCI functions + * + * Copyright (C) 2016 Chen-Yu Tsai + * Author: Chen-Yu Tsai + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 }; + +void __secure psci_save_target_pc(int cpu, u32 pc) +{ + psci_target_pc[cpu] = pc; + DSB; +} + +u32 __secure psci_get_target_pc(int cpu) +{ + return psci_target_pc[cpu]; +} + diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index dab5769..a0da023 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -54,6 +54,10 @@ #ifndef __ASSEMBLY__ #include +/* These 2 helper functions assume cpu < CONFIG_ARMV7_PSCI_NR_CPUS */ +u32 psci_get_target_pc(int cpu); +void psci_save_target_pc(int cpu, u32 pc); + void psci_cpu_entry(void); u32 psci_get_cpu_id(void); u32 psci_get_cpu_stack_top(int cpu); -- cgit v1.1 From 6e6622de166f53597172687b7269b07cf48844df Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:44 +0800 Subject: ARM: PSCI: Switch to per-CPU target PC storage in secure data section Now that we have a secure data section and space to store per-CPU target PC address, switch to it instead of storing the target PC on the stack. Also save clobbered r4-r7 registers on the stack and restore them on return in psci_cpu_on for Tegra, i.MX7, and LS102xA platforms. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/ls102xa/psci.S | 14 +++++++------- arch/arm/cpu/armv7/mx7/psci.S | 13 ++++++++----- arch/arm/cpu/armv7/psci.S | 3 +-- arch/arm/cpu/armv7/sunxi/psci.c | 5 ++--- arch/arm/mach-tegra/psci.S | 11 ++++++----- 5 files changed, 24 insertions(+), 22 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S index ba043ef..f9b26b4 100644 --- a/arch/arm/cpu/armv7/ls102xa/psci.S +++ b/arch/arm/cpu/armv7/ls102xa/psci.S @@ -29,16 +29,16 @@ @ r2 = target PC .globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, r6, lr} @ Clear and Get the correct CPU number @ r1 = 0xf01 - and r1, r1, #0xff + and r4, r1, #0xff - mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r0, r4 + mov r1, r2 + bl psci_save_target_pc + mov r1, r4 @ Get DCFG base address movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff) @@ -101,7 +101,7 @@ holdoff_release: @ Return mov r0, #ARM_PSCI_RET_SUCCESS - pop {lr} + pop {r4, r5, r6, lr} bx lr .globl psci_cpu_off diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S index d9e9fbf..96e88d6 100644 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ b/arch/arm/cpu/armv7/mx7/psci.S @@ -11,17 +11,20 @@ .globl psci_cpu_on psci_cpu_on: - push {lr} + push {r4, r5, lr} + mov r4, r0 + mov r5, r1 mov r0, r1 - bl psci_get_cpu_stack_top - str r2, [r0] - dsb + mov r1, r2 + bl psci_save_target_pc + mov r0, r4 + mov r1, r5 ldr r2, =psci_cpu_entry bl imx_cpu_on - pop {pc} + pop {r4, r5, pc} .globl psci_cpu_off psci_cpu_off: diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index bfc4475..50dfddb 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -245,8 +245,7 @@ ENTRY(psci_cpu_entry) bl _nonsec_init bl psci_get_cpu_id @ CPU ID => r0 - bl psci_get_cpu_stack_top @ stack top => r0 - ldr r0, [r0] @ target PC at stack top + bl psci_get_target_pc @ target PC => r0 b _do_nonsec_entry ENDPROC(psci_cpu_entry) diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c index be3a1fb..7ac8406 100644 --- a/arch/arm/cpu/armv7/sunxi/psci.c +++ b/arch/arm/cpu/armv7/sunxi/psci.c @@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc) (struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE; u32 cpu = (mpidr & 0x3); - /* store target PC at target CPU stack top */ - writel(pc, psci_get_cpu_stack_top(cpu)); - DSB; + /* store target PC */ + psci_save_target_pc(cpu, pc); /* Set secondary core power on PC */ writel((u32)&psci_cpu_entry, &cpucfg->priv0); diff --git a/arch/arm/mach-tegra/psci.S b/arch/arm/mach-tegra/psci.S index 85d5b6b..645d08f 100644 --- a/arch/arm/mach-tegra/psci.S +++ b/arch/arm/mach-tegra/psci.S @@ -85,12 +85,13 @@ _loop: wfi ENDPROC(psci_cpu_off) ENTRY(psci_cpu_on) - push {lr} + push {r4, r5, r6, lr} + mov r4, r1 mov r0, r1 - bl psci_get_cpu_stack_top @ get stack top of target CPU - str r2, [r0] @ store target PC at stack top - dsb + mov r1, r2 + bl psci_save_target_pc @ store target PC + mov r1, r4 ldr r6, =TEGRA_RESET_EXCEPTION_VECTOR ldr r5, =psci_cpu_entry @@ -103,7 +104,7 @@ ENTRY(psci_cpu_on) str r5, [r6, r2] mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS - pop {pc} + pop {r4, r5, r6, pc} ENDPROC(psci_cpu_on) .popsection -- cgit v1.1 From b7073965a343fca2bcde4195fbba664c98f309d8 Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Sun, 19 Jun 2016 12:38:45 +0800 Subject: ARM: PSCI: Make psci_get_cpu_stack_top local to armv7/psci.S Now that we have a secure data section for storing variables, there should be no need for platform code to get the stack address. Make psci_get_cpu_stack_top a local function, as it should only be used in armv7/psci.S and only by psci_stack_setup. Signed-off-by: Chen-Yu Tsai Signed-off-by: Hans de Goede --- arch/arm/cpu/armv7/psci.S | 2 +- arch/arm/include/asm/psci.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S index 50dfddb..350b75c 100644 --- a/arch/arm/cpu/armv7/psci.S +++ b/arch/arm/cpu/armv7/psci.S @@ -213,7 +213,7 @@ ENDPROC(psci_cpu_off_common) @ -------------------- __secure_stack_start @ @ This expects CPU ID in r0 and returns stack top in r0 -ENTRY(psci_get_cpu_stack_top) +LENTRY(psci_get_cpu_stack_top) @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT) ldr r3, =__secure_stack_end sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT diff --git a/arch/arm/include/asm/psci.h b/arch/arm/include/asm/psci.h index a0da023..7ba7ce3 100644 --- a/arch/arm/include/asm/psci.h +++ b/arch/arm/include/asm/psci.h @@ -60,7 +60,6 @@ void psci_save_target_pc(int cpu, u32 pc); void psci_cpu_entry(void); u32 psci_get_cpu_id(void); -u32 psci_get_cpu_stack_top(int cpu); void psci_cpu_off_common(void); int psci_update_dt(void *fdt); -- cgit v1.1