diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/dts/meson-gx.dtsi | 97 | ||||
-rw-r--r-- | arch/arm/dts/meson-gxbb-odroidc2.dts | 82 | ||||
-rw-r--r-- | arch/arm/dts/meson-gxbb.dtsi | 187 | ||||
-rw-r--r-- | arch/arm/dts/stm32f746-disco.dts | 1 | ||||
-rw-r--r-- | arch/arm/dts/stm32f746.dtsi | 30 | ||||
-rw-r--r-- | arch/arm/dts/stm32f769-disco.dts | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-meson/gpio.h | 11 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-stm32f7/fmc.h | 74 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-stm32f7/rcc.h | 24 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-stm32f7/stm32.h | 13 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-stm32f7/stm32_periph.h | 15 | ||||
-rw-r--r-- | arch/arm/mach-keystone/cmd_mon.c | 8 | ||||
-rw-r--r-- | arch/arm/mach-keystone/include/mach/mon.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-keystone/mon.c | 11 | ||||
-rw-r--r-- | arch/mips/Makefile.postlink | 23 | ||||
-rw-r--r-- | arch/mips/config.mk | 21 | ||||
-rw-r--r-- | arch/mips/cpu/start.S | 130 | ||||
-rw-r--r-- | arch/mips/cpu/u-boot.lds | 41 | ||||
-rw-r--r-- | arch/mips/include/asm/relocs.h | 24 | ||||
-rw-r--r-- | arch/mips/include/asm/sections.h | 7 | ||||
-rw-r--r-- | arch/mips/lib/Makefile | 1 | ||||
-rw-r--r-- | arch/mips/lib/bootm.c | 8 | ||||
-rw-r--r-- | arch/mips/lib/reloc.c | 164 |
23 files changed, 603 insertions, 372 deletions
diff --git a/arch/arm/dts/meson-gx.dtsi b/arch/arm/dts/meson-gx.dtsi index c1291007b3..436b875060 100644 --- a/arch/arm/dts/meson-gx.dtsi +++ b/arch/arm/dts/meson-gx.dtsi @@ -71,6 +71,14 @@ reg = <0x0 0x10000000 0x0 0x200000>; no-map; }; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0xbc00000>; + alignment = <0x0 0x400000>; + linux,cma-default; + }; }; cpus { @@ -233,7 +241,7 @@ }; i2c_A: i2c@8500 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x08500 0x0 0x20>; interrupts = <GIC_SPI 21 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -255,6 +263,14 @@ status = "disabled"; }; + saradc: adc@8680 { + compatible = "amlogic,meson-saradc"; + reg = <0x0 0x8680 0x0 0x34>; + #io-channel-cells = <1>; + interrupts = <GIC_SPI 73 IRQ_TYPE_EDGE_RISING>; + status = "disabled"; + }; + pwm_ef: pwm@86c0 { compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; reg = <0x0 0x086c0 0x0 0x10>; @@ -271,7 +287,7 @@ }; i2c_B: i2c@87c0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087c0 0x0 0x20>; interrupts = <GIC_SPI 214 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -280,7 +296,7 @@ }; i2c_C: i2c@87e0 { - compatible = "amlogic,meson-gxbb-i2c"; + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; reg = <0x0 0x087e0 0x0 0x20>; interrupts = <GIC_SPI 215 IRQ_TYPE_EDGE_RISING>; #address-cells = <1>; @@ -288,6 +304,14 @@ status = "disabled"; }; + spifc: spi@8c80 { + compatible = "amlogic,meson-gx-spifc", "amlogic,meson-gxbb-spifc"; + reg = <0x0 0x08c80 0x0 0x80>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + watchdog@98d0 { compatible = "amlogic,meson-gx-wdt", "amlogic,meson-gxbb-wdt"; reg = <0x0 0x098d0 0x0 0x10>; @@ -309,7 +333,7 @@ }; sram: sram@c8000000 { - compatible = "amlogic,meson-gxbb-sram", "mmio-sram"; + compatible = "amlogic,meson-gx-sram", "amlogic,meson-gxbb-sram", "mmio-sram"; reg = <0x0 0xc8000000 0x0 0x14000>; #address-cells = <1>; @@ -317,12 +341,12 @@ ranges = <0 0x0 0xc8000000 0x14000>; cpu_scp_lpri: scp-shmem@0 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13000 0x400>; }; cpu_scp_hpri: scp-shmem@200 { - compatible = "amlogic,meson-gxbb-scp-shmem"; + compatible = "amlogic,meson-gx-scp-shmem", "amlogic,meson-gxbb-scp-shmem"; reg = <0x13400 0x400>; }; }; @@ -334,6 +358,13 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8100000 0x0 0x100000>; + clkc_AO: clock-controller@040 { + compatible = "amlogic,gx-aoclkc", "amlogic,gxbb-aoclkc"; + reg = <0x0 0x00040 0x0 0x4>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + uart_AO: serial@4c0 { compatible = "amlogic,meson-uart"; reg = <0x0 0x004c0 0x0 0x14>; @@ -350,8 +381,24 @@ status = "disabled"; }; + i2c_AO: i2c@500 { + compatible = "amlogic,meson-gx-i2c", "amlogic,meson-gxbb-i2c"; + reg = <0x0 0x500 0x0 0x20>; + interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm_AO_ab: pwm@550 { + compatible = "amlogic,meson-gx-pwm", "amlogic,meson-gxbb-pwm"; + reg = <0x0 0x00550 0x0 0x10>; + #pwm-cells = <3>; + status = "disabled"; + }; + ir: ir@580 { - compatible = "amlogic,meson-gxbb-ir"; + compatible = "amlogic,meson-gx-ir", "amlogic,meson-gxbb-ir"; reg = <0x0 0x00580 0x0 0x40>; interrupts = <GIC_SPI 196 IRQ_TYPE_EDGE_RISING>; status = "disabled"; @@ -365,13 +412,12 @@ #size-cells = <2>; ranges = <0x0 0x0 0x0 0xc8834000 0x0 0x2000>; - rng { + hwrng: rng { compatible = "amlogic,meson-rng"; reg = <0x0 0x0 0x0 0x4>; }; }; - hiubus: hiubus@c883c000 { compatible = "simple-bus"; reg = <0x0 0xc883c000 0x0 0x2000>; @@ -395,7 +441,6 @@ 0x0 0xc8834540 0x0 0x4>; interrupts = <0 8 1>; interrupt-names = "macirq"; - phy-mode = "rgmii"; status = "disabled"; }; @@ -442,6 +487,38 @@ cvbs_vdac_port: port@0 { reg = <0>; }; + + /* HDMI-TX output port */ + hdmi_tx_port: port@1 { + reg = <1>; + + hdmi_tx_out: endpoint { + remote-endpoint = <&hdmi_tx_in>; + }; + }; + }; + + hdmi_tx: hdmi-tx@c883a000 { + compatible = "amlogic,meson-gx-dw-hdmi"; + reg = <0x0 0xc883a000 0x0 0x1c>; + interrupts = <GIC_SPI 57 IRQ_TYPE_EDGE_RISING>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + /* VPU VENC Input */ + hdmi_tx_venc_port: port@0 { + reg = <0>; + + hdmi_tx_in: endpoint { + remote-endpoint = <&hdmi_tx_out>; + }; + }; + + /* TMDS Output */ + hdmi_tx_tmds_port: port@1 { + reg = <1>; + }; }; }; }; diff --git a/arch/arm/dts/meson-gxbb-odroidc2.dts b/arch/arm/dts/meson-gxbb-odroidc2.dts index c737183a29..54a9c6a6b3 100644 --- a/arch/arm/dts/meson-gxbb-odroidc2.dts +++ b/arch/arm/dts/meson-gxbb-odroidc2.dts @@ -50,7 +50,7 @@ / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; model = "Hardkernel ODROID-C2"; - + aliases { serial0 = &uart_AO; }; @@ -96,7 +96,7 @@ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - gpio = <&gpio_ao GPIOAO_12 GPIO_ACTIVE_HIGH>; + gpio = <&gpio GPIOY_12 GPIO_ACTIVE_HIGH>; enable-active-high; }; @@ -152,6 +152,13 @@ pinctrl-0 = <ð_rgmii_pins>; pinctrl-names = "default"; phy-handle = <ð_phy0>; + phy-mode = "rgmii"; + + snps,reset-gpio = <&gpio GPIOZ_14 0>; + snps,reset-delays-us = <0 10000 1000000>; + snps,reset-active-low; + + amlogic,tx-delay-ns = <2>; mdio { compatible = "snps,dwmac-mdio"; @@ -165,6 +172,57 @@ }; }; +&pinctrl_aobus { + gpio-line-names = "UART TX", "UART RX", "VCCK En", "TF 3V3/1V8 En", + "USB HUB nRESET", "USB OTG Power En", + "J7 Header Pin2", "IR In", "J7 Header Pin4", + "J7 Header Pin6", "J7 Header Pin5", "J7 Header Pin7", + "HDMI CEC", "SYS LED"; +}; + +&pinctrl_periphs { + gpio-line-names = /* Bank GPIOZ */ + "Eth MDIO", "Eth MDC", "Eth RGMII RX Clk", + "Eth RX DV", "Eth RX D0", "Eth RX D1", "Eth RX D2", + "Eth RX D3", "Eth RGMII TX Clk", "Eth TX En", + "Eth TX D0", "Eth TX D1", "Eth TX D2", "Eth TX D3", + "Eth PHY nRESET", "Eth PHY Intc", + /* Bank GPIOH */ + "HDMI HPD", "HDMI DDC SDA", "HDMI DDC SCL", "", + /* Bank BOOT */ + "eMMC D0", "eMMC D1", "eMMC D2", "eMMC D3", "eMMC D4", + "eMMC D5", "eMMC D6", "eMMC D7", "eMMC Clk", + "eMMC Reset", "eMMC CMD", + "", "", "", "", "", "", "", + /* Bank CARD */ + "SDCard D1", "SDCard D0", "SDCard CLK", "SDCard CMD", + "SDCard D3", "SDCard D2", "SDCard Det", + /* Bank GPIODV */ + "", "", "", "", "", "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", "", "", "", + "I2C A SDA", "I2C A SCK", "I2C B SDA", "I2C B SCK", + "PWM D", "PWM B", + /* Bank GPIOY */ + "Revision Bit0", "Revision Bit1", "", + "J2 Header Pin35", "", "", "", "J2 Header Pin36", + "J2 Header Pin31", "", "", "", "TF VDD En", + "J2 Header Pin32", "J2 Header Pin26", "", "", + /* Bank GPIOX */ + "J2 Header Pin29", "J2 Header Pin24", + "J2 Header Pin23", "J2 Header Pin22", + "J2 Header Pin21", "J2 Header Pin18", + "J2 Header Pin33", "J2 Header Pin19", + "J2 Header Pin16", "J2 Header Pin15", + "J2 Header Pin12", "J2 Header Pin13", + "J2 Header Pin8", "J2 Header Pin10", + "", "", "", "", "", + "J2 Header Pin11", "", "J2 Header Pin7", + /* Bank GPIOCLK */ + "", "", "", "", + /* GPIO_TEST_N */ + ""; +}; + &ir { status = "okay"; pinctrl-0 = <&remote_input_ao_pins>; @@ -177,6 +235,21 @@ pinctrl-names = "default"; }; +&gpio_ao { + /* + * WARNING: The USB Hub on the Odroid-C2 needs a reset signal + * to be turned high in order to be detected by the USB Controller + * This signal should be handled by a USB specific power sequence + * in order to reset the Hub when USB bus is powered down. + */ + usb-hub { + gpio-hog; + gpios = <GPIOAO_4 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "usb-hub-reset"; + }; +}; + &usb0_phy { status = "okay"; phy-supply = <&usb_otg_pwr>; @@ -194,6 +267,11 @@ status = "okay"; }; +&saradc { + status = "okay"; + vref-supply = <&vcc1v8>; +}; + /* SD */ &sd_emmc_b { status = "okay"; diff --git a/arch/arm/dts/meson-gxbb.dtsi b/arch/arm/dts/meson-gxbb.dtsi index 39a774ad83..86105a6969 100644 --- a/arch/arm/dts/meson-gxbb.dtsi +++ b/arch/arm/dts/meson-gxbb.dtsi @@ -97,17 +97,6 @@ }; }; -&cbus { - spifc: spi@8c80 { - compatible = "amlogic,meson-gxbb-spifc"; - reg = <0x0 0x08c80 0x0 0x80>; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clkc CLKID_SPI>; - status = "disabled"; - }; -}; - ðmac { clocks = <&clkc CLKID_ETH>, <&clkc CLKID_FCLK_DIV2>, @@ -129,6 +118,7 @@ reg-names = "mux", "pull", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aobus 0 0 14>; }; uart_ao_a_pins: uart_ao_a { @@ -203,30 +193,62 @@ function = "pwm_ao_b"; }; }; - }; - clkc_AO: clock-controller@040 { - compatible = "amlogic,gxbb-aoclkc"; - reg = <0x0 0x00040 0x0 0x4>; - #clock-cells = <1>; - #reset-cells = <1>; - }; + i2s_am_clk_pins: i2s_am_clk { + mux { + groups = "i2s_am_clk"; + function = "i2s_out_ao"; + }; + }; - pwm_ab_AO: pwm@550 { - compatible = "amlogic,meson-gxbb-pwm"; - reg = <0x0 0x0550 0x0 0x10>; - #pwm-cells = <3>; - status = "disabled"; - }; + i2s_out_ao_clk_pins: i2s_out_ao_clk { + mux { + groups = "i2s_out_ao_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_lr_clk_pins: i2s_out_lr_clk { + mux { + groups = "i2s_out_lr_clk"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch01_ao_pins: i2s_out_ch01_ao { + mux { + groups = "i2s_out_ch01_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch23_ao_pins: i2s_out_ch23_ao { + mux { + groups = "i2s_out_ch23_ao"; + function = "i2s_out_ao"; + }; + }; + + i2s_out_ch45_ao_pins: i2s_out_ch45_ao { + mux { + groups = "i2s_out_ch45_ao"; + function = "i2s_out_ao"; + }; + }; + + spdif_out_ao_6_pins: spdif_out_ao_6 { + mux { + groups = "spdif_out_ao_6"; + function = "spdif_out_ao"; + }; + }; - i2c_AO: i2c@500 { - compatible = "amlogic,meson-gxbb-i2c"; - reg = <0x0 0x500 0x0 0x20>; - interrupts = <GIC_SPI 195 IRQ_TYPE_EDGE_RISING>; - clocks = <&clkc CLKID_AO_I2C>; - #address-cells = <1>; - #size-cells = <0>; - status = "disabled"; + spdif_out_ao_13_pins: spdif_out_ao_13 { + mux { + groups = "spdif_out_ao_13"; + function = "spdif_out_ao"; + }; + }; }; }; @@ -245,6 +267,7 @@ reg-names = "mux", "pull", "pull-enable", "gpio"; gpio-controller; #gpio-cells = <2>; + gpio-ranges = <&pinctrl_periphs 0 14 120>; }; emmc_pins: emmc { @@ -467,6 +490,34 @@ function = "hdmi_i2c"; }; }; + + i2sout_ch23_y_pins: i2sout_ch23_y { + mux { + groups = "i2sout_ch23_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch45_y_pins: i2sout_ch45_y { + mux { + groups = "i2sout_ch45_y"; + function = "i2s_out"; + }; + }; + + i2sout_ch67_y_pins: i2sout_ch67_y { + mux { + groups = "i2sout_ch67_y"; + function = "i2s_out"; + }; + }; + + spdif_out_y_pins: spdif_out_y { + mux { + groups = "spdif_out_y"; + function = "spdif_out"; + }; + }; }; }; @@ -478,10 +529,51 @@ }; }; +&apb { + mali: gpu@c0000 { + compatible = "amlogic,meson-gxbb-mali", "arm,mali-450"; + reg = <0x0 0xc0000 0x0 0x40000>; + interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "gp", "gpmmu", "pp", "pmu", + "pp0", "ppmmu0", "pp1", "ppmmu1", + "pp2", "ppmmu2"; + clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>; + clock-names = "bus", "core"; + + /* + * Mali clocking is provided by two identical clock paths + * MALI_0 and MALI_1 muxed to a single clock by a glitch + * free mux to safely change frequency while running. + */ + assigned-clocks = <&clkc CLKID_MALI_0_SEL>, + <&clkc CLKID_MALI_0>, + <&clkc CLKID_MALI>; /* Glitch free mux */ + assigned-clock-parents = <&clkc CLKID_FCLK_DIV3>, + <0>, /* Do Nothing */ + <&clkc CLKID_MALI_0>; + assigned-clock-rates = <0>, /* Do Nothing */ + <666666666>, + <0>; /* Do Nothing */ + }; +}; + &i2c_A { clocks = <&clkc CLKID_I2C>; }; +&i2c_AO { + clocks = <&clkc CLKID_AO_I2C>; +}; + &i2c_B { clocks = <&clkc CLKID_I2C>; }; @@ -490,6 +582,16 @@ clocks = <&clkc CLKID_I2C>; }; +&saradc { + compatible = "amlogic,meson-gxbb-saradc", "amlogic,meson-saradc"; + clocks = <&xtal>, + <&clkc CLKID_SAR_ADC>, + <&clkc CLKID_SANA>, + <&clkc CLKID_SAR_ADC_CLK>, + <&clkc CLKID_SAR_ADC_SEL>; + clock-names = "clkin", "core", "sana", "adc_clk", "adc_sel"; +}; + &sd_emmc_a { clocks = <&clkc CLKID_SD_EMMC_A>, <&xtal>, @@ -511,6 +613,27 @@ clock-names = "core", "clkin0", "clkin1"; }; +&spifc { + clocks = <&clkc CLKID_SPI>; +}; + &vpu { compatible = "amlogic,meson-gxbb-vpu", "amlogic,meson-gx-vpu"; }; + +&hwrng { + clocks = <&clkc CLKID_RNG0>; + clock-names = "core"; +}; + +&hdmi_tx { + compatible = "amlogic,meson-gxbb-dw-hdmi", "amlogic,meson-gx-dw-hdmi"; + resets = <&reset RESET_HDMITX_CAPB3>, + <&reset RESET_HDMI_SYSTEM_RESET>, + <&reset RESET_HDMI_TX>; + reset-names = "hdmitx_apb", "hdmitx", "hdmitx_phy"; + clocks = <&clkc CLKID_HDMI_PCLK>, + <&clkc CLKID_CLK81>, + <&clkc CLKID_GCLK_VENCI_INT0>; + clock-names = "isfr", "iahb", "venci"; +}; diff --git a/arch/arm/dts/stm32f746-disco.dts b/arch/arm/dts/stm32f746-disco.dts index 2c7fa799bf..c92c2e20e8 100644 --- a/arch/arm/dts/stm32f746-disco.dts +++ b/arch/arm/dts/stm32f746-disco.dts @@ -195,7 +195,6 @@ pinctrl-names = "default"; status = "okay"; - mr-nbanks = <1>; /* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */ bank1: bank@0 { st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_16 BANKS_4 diff --git a/arch/arm/dts/stm32f746.dtsi b/arch/arm/dts/stm32f746.dtsi index 54f5bc7a54..783d4e734e 100644 --- a/arch/arm/dts/stm32f746.dtsi +++ b/arch/arm/dts/stm32f746.dtsi @@ -47,6 +47,8 @@ #include "armv7-m.dtsi" #include <dt-bindings/pinctrl/stm32f746-pinfunc.h> +#include <dt-bindings/clock/stm32fx-clock.h> +#include <dt-bindings/mfd/stm32f7-rcc.h> / { clocks { @@ -74,7 +76,7 @@ fmc: fmc@A0000000 { compatible = "st,stm32-fmc"; reg = <0xA0000000 0x1000>; - clocks = <&rcc 0 64>; + clocks = <&rcc 0 STM32F7_AHB3_CLOCK(FMC)>; u-boot,dm-pre-reloc; }; @@ -86,14 +88,14 @@ reg-names = "QuadSPI", "QuadSPI-memory"; interrupts = <92>; spi-max-frequency = <108000000>; - clocks = <&rcc 0 65>; + clocks = <&rcc 0 STM32F7_AHB3_CLOCK(QSPI)>; status = "disabled"; }; usart1: serial@40011000 { compatible = "st,stm32f7-usart", "st,stm32f7-uart"; reg = <0x40011000 0x400>; interrupts = <37>; - clocks = <&rcc 0 164>; + clocks = <&rcc 0 STM32F7_APB2_CLOCK(USART1)>; status = "disabled"; u-boot,dm-pre-reloc; }; @@ -119,7 +121,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x0 0x400>; - clocks = <&rcc 0 0>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOA)>; st,bank-name = "GPIOA"; u-boot,dm-pre-reloc; }; @@ -129,7 +131,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x400 0x400>; - clocks = <&rcc 0 1>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOB)>; st,bank-name = "GPIOB"; u-boot,dm-pre-reloc; }; @@ -140,7 +142,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x800 0x400>; - clocks = <&rcc 0 2>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOC)>; st,bank-name = "GPIOC"; u-boot,dm-pre-reloc; }; @@ -150,7 +152,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0xc00 0x400>; - clocks = <&rcc 0 3>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOD)>; st,bank-name = "GPIOD"; u-boot,dm-pre-reloc; }; @@ -160,7 +162,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1000 0x400>; - clocks = <&rcc 0 4>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOE)>; st,bank-name = "GPIOE"; u-boot,dm-pre-reloc; }; @@ -170,7 +172,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1400 0x400>; - clocks = <&rcc 0 5>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOF)>; st,bank-name = "GPIOF"; u-boot,dm-pre-reloc; }; @@ -180,7 +182,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1800 0x400>; - clocks = <&rcc 0 6>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOG)>; st,bank-name = "GPIOG"; u-boot,dm-pre-reloc; }; @@ -190,7 +192,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x1c00 0x400>; - clocks = <&rcc 0 7>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOH)>; st,bank-name = "GPIOH"; u-boot,dm-pre-reloc; }; @@ -200,7 +202,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2000 0x400>; - clocks = <&rcc 0 8>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOI)>; st,bank-name = "GPIOI"; u-boot,dm-pre-reloc; }; @@ -210,7 +212,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2400 0x400>; - clocks = <&rcc 0 9>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOJ)>; st,bank-name = "GPIOJ"; u-boot,dm-pre-reloc; }; @@ -220,7 +222,7 @@ #gpio-cells = <2>; compatible = "st,stm32-gpio"; reg = <0x2800 0x400>; - clocks = <&rcc 0 10>; + clocks = <&rcc 0 STM32F7_AHB1_CLOCK(GPIOK)>; st,bank-name = "GPIOK"; u-boot,dm-pre-reloc; }; diff --git a/arch/arm/dts/stm32f769-disco.dts b/arch/arm/dts/stm32f769-disco.dts index 6591cc8110..f34ffcc21d 100644 --- a/arch/arm/dts/stm32f769-disco.dts +++ b/arch/arm/dts/stm32f769-disco.dts @@ -209,7 +209,6 @@ pinctrl-names = "default"; status = "okay"; - mr-nbanks = <1>; /* Memory configuration from sdram datasheet MT48LC_4M32_B2B5-6A */ bank1: bank@0 { st,sdram-control = /bits/ 8 <NO_COL_8 NO_ROW_12 MWIDTH_32 BANKS_4 diff --git a/arch/arm/include/asm/arch-meson/gpio.h b/arch/arm/include/asm/arch-meson/gpio.h new file mode 100644 index 0000000000..7079ab32ce --- /dev/null +++ b/arch/arm/include/asm/arch-meson/gpio.h @@ -0,0 +1,11 @@ +/* + * (C) Copyright 2017 - Beniamino Galvani <b.galvani@gmail.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_MESON_GPIO_H +#define __ASM_ARCH_MESON_GPIO_H + + +#endif /* __ASM_ARCH_MESON_GPIO_H */ diff --git a/arch/arm/include/asm/arch-stm32f7/fmc.h b/arch/arm/include/asm/arch-stm32f7/fmc.h deleted file mode 100644 index 4741e5a0a3..0000000000 --- a/arch/arm/include/asm/arch-stm32f7/fmc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * (C) Copyright 2013 - * Pavel Boldin, Emcraft Systems, paboldin@emcraft.com - * - * (C) Copyright 2015 - * Kamil Lulko, <kamil.lulko@gmail.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _MACH_FMC_H_ -#define _MACH_FMC_H_ - -struct stm32_fmc_regs { - u32 sdcr1; /* Control register 1 */ - u32 sdcr2; /* Control register 2 */ - u32 sdtr1; /* Timing register 1 */ - u32 sdtr2; /* Timing register 2 */ - u32 sdcmr; /* Mode register */ - u32 sdrtr; /* Refresh timing register */ - u32 sdsr; /* Status register */ -}; - -/* - * FMC registers base - */ -#define STM32_SDRAM_FMC ((struct stm32_fmc_regs *)SDRAM_FMC_BASE) - -/* Control register SDCR */ -#define FMC_SDCR_RPIPE_SHIFT 13 /* RPIPE bit shift */ -#define FMC_SDCR_RBURST_SHIFT 12 /* RBURST bit shift */ -#define FMC_SDCR_SDCLK_SHIFT 10 /* SDRAM clock divisor shift */ -#define FMC_SDCR_WP_SHIFT 9 /* Write protection shift */ -#define FMC_SDCR_CAS_SHIFT 7 /* CAS latency shift */ -#define FMC_SDCR_NB_SHIFT 6 /* Number of banks shift */ -#define FMC_SDCR_MWID_SHIFT 4 /* Memory width shift */ -#define FMC_SDCR_NR_SHIFT 2 /* Number of row address bits shift */ -#define FMC_SDCR_NC_SHIFT 0 /* Number of col address bits shift */ - -/* Timings register SDTR */ -#define FMC_SDTR_TMRD_SHIFT 0 /* Load mode register to active */ -#define FMC_SDTR_TXSR_SHIFT 4 /* Exit self-refresh time */ -#define FMC_SDTR_TRAS_SHIFT 8 /* Self-refresh time */ -#define FMC_SDTR_TRC_SHIFT 12 /* Row cycle delay */ -#define FMC_SDTR_TWR_SHIFT 16 /* Recovery delay */ -#define FMC_SDTR_TRP_SHIFT 20 /* Row precharge delay */ -#define FMC_SDTR_TRCD_SHIFT 24 /* Row-to-column delay */ - - -#define FMC_SDCMR_NRFS_SHIFT 5 - -#define FMC_SDCMR_MODE_NORMAL 0 -#define FMC_SDCMR_MODE_START_CLOCK 1 -#define FMC_SDCMR_MODE_PRECHARGE 2 -#define FMC_SDCMR_MODE_AUTOREFRESH 3 -#define FMC_SDCMR_MODE_WRITE_MODE 4 -#define FMC_SDCMR_MODE_SELFREFRESH 5 -#define FMC_SDCMR_MODE_POWERDOWN 6 - -#define FMC_SDCMR_BANK_1 BIT(4) -#define FMC_SDCMR_BANK_2 BIT(3) - -#define FMC_SDCMR_MODE_REGISTER_SHIFT 9 - -#define FMC_SDSR_BUSY BIT(5) - -#define FMC_BUSY_WAIT() do { \ - __asm__ __volatile__ ("dsb" : : : "memory"); \ - while (STM32_SDRAM_FMC->sdsr & FMC_SDSR_BUSY) \ - ; \ - } while (0) - - -#endif /* _MACH_FMC_H_ */ diff --git a/arch/arm/include/asm/arch-stm32f7/rcc.h b/arch/arm/include/asm/arch-stm32f7/rcc.h index 0f8d50b4c6..a33f8cf9bc 100644 --- a/arch/arm/include/asm/arch-stm32f7/rcc.h +++ b/arch/arm/include/asm/arch-stm32f7/rcc.h @@ -8,44 +8,24 @@ #ifndef _STM32_RCC_H #define _STM32_RCC_H +#include <dt-bindings/mfd/stm32f7-rcc.h> + /* * RCC AHB1ENR specific definitions */ -#define RCC_AHB1ENR_GPIO_A_EN BIT(0) -#define RCC_AHB1ENR_GPIO_B_EN BIT(1) -#define RCC_AHB1ENR_GPIO_C_EN BIT(2) -#define RCC_AHB1ENR_GPIO_D_EN BIT(3) -#define RCC_AHB1ENR_GPIO_E_EN BIT(4) -#define RCC_AHB1ENR_GPIO_F_EN BIT(5) -#define RCC_AHB1ENR_GPIO_G_EN BIT(6) -#define RCC_AHB1ENR_GPIO_H_EN BIT(7) -#define RCC_AHB1ENR_GPIO_I_EN BIT(8) -#define RCC_AHB1ENR_GPIO_J_EN BIT(9) -#define RCC_AHB1ENR_GPIO_K_EN BIT(10) #define RCC_AHB1ENR_ETHMAC_EN BIT(25) #define RCC_AHB1ENR_ETHMAC_TX_EN BIT(26) #define RCC_AHB1ENR_ETHMAC_RX_EN BIT(27) -#define RCC_AHB1ENR_ETHMAC_PTP_EN BIT(28) - -/* - * RCC AHB3ENR specific definitions - */ -#define RCC_AHB3ENR_FMC_EN BIT(0) -#define RCC_AHB3ENR_QSPI_EN BIT(1) /* * RCC APB1ENR specific definitions */ #define RCC_APB1ENR_TIM2EN BIT(0) -#define RCC_APB1ENR_USART2EN BIT(17) -#define RCC_APB1ENR_USART3EN BIT(18) #define RCC_APB1ENR_PWREN BIT(28) /* * RCC APB2ENR specific definitions */ -#define RCC_APB2ENR_USART1EN BIT(4) -#define RCC_APB2ENR_USART6EN BIT(5) #define RCC_APB2ENR_SYSCFGEN BIT(14) #endif diff --git a/arch/arm/include/asm/arch-stm32f7/stm32.h b/arch/arm/include/asm/arch-stm32f7/stm32.h index 14e3398768..87aee6057b 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32.h @@ -57,12 +57,6 @@ static const u32 sect_sz_kb[CONFIG_SYS_MAX_FLASH_SECT] = { [5 ... 7] = 256 * 1024 }; -enum clock { - CLOCK_CORE, - CLOCK_AHB, - CLOCK_APB1, - CLOCK_APB2 -}; #define STM32_BUS_MASK GENMASK(31, 16) struct stm32_rcc_regs { @@ -101,11 +95,6 @@ struct stm32_rcc_regs { }; #define STM32_RCC ((struct stm32_rcc_regs *)RCC_BASE) -struct stm32_rcc_ext_f7_regs { - u32 dckcfgr2; /* dedicated clocks configuration register */ -}; -#define STM32_RCC_EXT_F7 ((struct stm32_rcc_ext_f7_regs *) (RCC_BASE + sizeof(struct stm32_rcc_regs))) - struct stm32_pwr_regs { u32 cr1; /* power control register 1 */ u32 csr1; /* power control/status register 2 */ @@ -114,8 +103,6 @@ struct stm32_pwr_regs { }; #define STM32_PWR ((struct stm32_pwr_regs *)PWR_BASE) -int configure_clocks(void); -unsigned long clock_get(enum clock clck); void stm32_flash_latency_cfg(int latency); #endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h index 3c5604ae29..9c1ec02233 100644 --- a/arch/arm/include/asm/arch-stm32f7/stm32_periph.h +++ b/arch/arm/include/asm/arch-stm32f7/stm32_periph.h @@ -21,24 +21,9 @@ enum periph_id { }; enum periph_clock { - USART1_CLOCK_CFG = 0, - USART2_CLOCK_CFG, - GPIO_A_CLOCK_CFG, - GPIO_B_CLOCK_CFG, - GPIO_C_CLOCK_CFG, - GPIO_D_CLOCK_CFG, - GPIO_E_CLOCK_CFG, - GPIO_F_CLOCK_CFG, - GPIO_G_CLOCK_CFG, - GPIO_H_CLOCK_CFG, - GPIO_I_CLOCK_CFG, - GPIO_J_CLOCK_CFG, - GPIO_K_CLOCK_CFG, SYSCFG_CLOCK_CFG, TIMER2_CLOCK_CFG, - FMC_CLOCK_CFG, STMMAC_CLOCK_CFG, - QSPI_CLOCK_CFG, }; #endif /* __ASM_ARM_ARCH_PERIPH_H */ diff --git a/arch/arm/mach-keystone/cmd_mon.c b/arch/arm/mach-keystone/cmd_mon.c index 591e75826b..c2525bd756 100644 --- a/arch/arm/mach-keystone/cmd_mon.c +++ b/arch/arm/mach-keystone/cmd_mon.c @@ -19,6 +19,7 @@ static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, u32 addr, dpsc_base = 0x1E80000, freq, load_addr, size; int rcode = 0; struct image_header *header; + u32 ecrypt_bm_addr = 0; if (argc < 2) return CMD_RET_USAGE; @@ -39,14 +40,17 @@ static int do_mon_install(cmd_tbl_t *cmdtp, int flag, int argc, memcpy((void *)load_addr, (void *)(addr + sizeof(struct image_header)), size); - rcode = mon_install(load_addr, dpsc_base, freq); + if (argc >= 3) + ecrypt_bm_addr = simple_strtoul(argv[2], NULL, 16); + + rcode = mon_install(load_addr, dpsc_base, freq, ecrypt_bm_addr); printf("## installed monitor @ 0x%x, freq [%d], status %d\n", load_addr, freq, rcode); return 0; } -U_BOOT_CMD(mon_install, 2, 0, do_mon_install, +U_BOOT_CMD(mon_install, 3, 0, do_mon_install, "Install boot kernel at 'addr'", "" ); diff --git a/arch/arm/mach-keystone/include/mach/mon.h b/arch/arm/mach-keystone/include/mach/mon.h index eb7aa938af..30c57e0f8f 100644 --- a/arch/arm/mach-keystone/include/mach/mon.h +++ b/arch/arm/mach-keystone/include/mach/mon.h @@ -10,7 +10,7 @@ #ifndef _MACH_MON_H_ #define _MACH_MON_H_ -int mon_install(u32 addr, u32 dpsc, u32 freq); +int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr); int mon_power_on(int core_id, void *ep); int mon_power_off(int core_id); diff --git a/arch/arm/mach-keystone/mon.c b/arch/arm/mach-keystone/mon.c index ebfb483a1b..dd446ab011 100644 --- a/arch/arm/mach-keystone/mon.c +++ b/arch/arm/mach-keystone/mon.c @@ -13,7 +13,7 @@ #include <spl.h> asm(".arch_extension sec\n\t"); -int mon_install(u32 addr, u32 dpsc, u32 freq) +int mon_install(u32 addr, u32 dpsc, u32 freq, u32 bm_addr) { int result; @@ -22,11 +22,13 @@ int mon_install(u32 addr, u32 dpsc, u32 freq) "mov r0, %1\n" "mov r1, %2\n" "mov r2, %3\n" + "mov r3, %4\n" "blx r0\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) - : "r" (addr), "r" (dpsc), "r" (freq) - : "cc", "r0", "r1", "r2", "memory"); + : "r" (addr), "r" (dpsc), "r" (freq), "r" (bm_addr) + : "cc", "r0", "r1", "r2", "r3", "memory"); return result; } @@ -40,6 +42,7 @@ int mon_power_on(int core_id, void *ep) "mov r2, %2\n" "mov r0, #0\n" "smc #0\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) : "r" (core_id), "r" (ep) @@ -56,6 +59,7 @@ int mon_power_off(int core_id) "mov r1, %1\n" "mov r0, #1\n" "smc #1\n" + "mov %0, r0\n" "ldmfd r13!, {lr}\n" : "=&r" (result) : "r" (core_id) @@ -89,6 +93,7 @@ static int k2_hs_bm_auth(int cmd, void *arg1) "mov r0, %1\n" "mov r1, %2\n" "smc #2\n" + "mov %0, r0\n" "ldmfd r13!, {r4-r12, lr}\n" : "=&r" (result) : "r" (cmd), "r" (arg1) diff --git a/arch/mips/Makefile.postlink b/arch/mips/Makefile.postlink new file mode 100644 index 0000000000..7da3acdf52 --- /dev/null +++ b/arch/mips/Makefile.postlink @@ -0,0 +1,23 @@ +# +# Copyright (c) 2017 Imagination Technologies Ltd. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +PHONY := __archpost +__archpost: + +-include include/config/auto.conf +include scripts/Kbuild.include + +CMD_RELOCS = tools/mips-relocs +quiet_cmd_relocs = RELOCS $@ + cmd_relocs = $(CMD_RELOCS) $@ + +u-boot: FORCE + @true + $(call if_changed,relocs) + +.PHONY: FORCE + +FORCE: diff --git a/arch/mips/config.mk b/arch/mips/config.mk index 2c72c1553d..cefdbe65e1 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -56,25 +56,14 @@ PLATFORM_ELFFLAGS += -B mips $(OBJCOPYFLAGS) # LDFLAGS_vmlinux += -G 0 -static -n -nostdlib # MODFLAGS += -mlong-calls # -# On the other hand, we want PIC in the U-Boot code to relocate it from ROM -# to RAM. $28 is always used as gp. -# -ifdef CONFIG_SPL_BUILD -PF_ABICALLS := -mno-abicalls -PF_PIC := -fno-pic -PF_PIE := -else -PF_ABICALLS := -mabicalls -PF_PIC := -fpic -PF_PIE := -pie -PF_OBJCOPY := -j .got -j .rel.dyn -j .padding -PF_OBJCOPY += -j .dtb.init.rodata +ifndef CONFIG_SPL_BUILD +OBJCOPYFLAGS += -j .got -j .rel -j .padding -j .dtb.init.rodata +LDFLAGS_FINAL += --emit-relocs endif -PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) +PLATFORM_CPPFLAGS += -G 0 -mno-abicalls -fno-pic PLATFORM_CPPFLAGS += -msoft-float PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections -LDFLAGS_FINAL += --gc-sections $(PF_PIE) +LDFLAGS_FINAL += --gc-sections OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list -OBJCOPYFLAGS += $(PF_OBJCOPY) diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S index d01ee9f9bd..952c57afd7 100644 --- a/arch/mips/cpu/start.S +++ b/arch/mips/cpu/start.S @@ -221,18 +221,6 @@ wr_done: ehb #endif - /* - * Initialize $gp, force pointer sized alignment of bal instruction to - * forbid the compiler to put nop's between bal and _gp. This is - * required to keep _gp and ra aligned to 8 byte. - */ - .align PTRLOG - bal 1f - nop - PTR _gp -1: - PTR_L gp, 0(ra) - #ifdef CONFIG_MIPS_CM PTR_LA t9, mips_cm_map jalr t9 @@ -291,121 +279,3 @@ wr_done: move ra, zero END(_start) - -/* - * void relocate_code (addr_sp, gd, addr_moni) - * - * This "function" does not return, instead it continues in RAM - * after relocating the monitor code. - * - * a0 = addr_sp - * a1 = gd - * a2 = destination address - */ -ENTRY(relocate_code) - move sp, a0 # set new stack pointer - move fp, sp - - move s0, a1 # save gd in s0 - move s2, a2 # save destination address in s2 - - PTR_LI t0, CONFIG_SYS_MONITOR_BASE - PTR_SUB s1, s2, t0 # s1 <-- relocation offset - - PTR_LA t2, __image_copy_end - move t1, a2 - - /* - * t0 = source address - * t1 = target address - * t2 = source end address - */ -1: - PTR_L t3, 0(t0) - PTR_S t3, 0(t1) - PTR_ADDU t0, PTRSIZE - blt t0, t2, 1b - PTR_ADDU t1, PTRSIZE - - /* - * Now we want to update GOT. - * - * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object - * generated by GNU ld. Skip these reserved entries from relocation. - */ - PTR_LA t3, num_got_entries - PTR_LA t8, _GLOBAL_OFFSET_TABLE_ - PTR_ADD t8, s1 # t8 now holds relocated _G_O_T_ - PTR_ADDIU t8, t8, 2 * PTRSIZE # skipping first two entries - PTR_LI t2, 2 -1: - PTR_L t1, 0(t8) - beqz t1, 2f - PTR_ADD t1, s1 - PTR_S t1, 0(t8) -2: - PTR_ADDIU t2, 1 - blt t2, t3, 1b - PTR_ADDIU t8, PTRSIZE - - /* Update dynamic relocations */ - PTR_LA t1, __rel_dyn_start - PTR_LA t2, __rel_dyn_end - - b 2f # skip first reserved entry - PTR_ADDIU t1, 2 * PTRSIZE - -1: - lw t8, -4(t1) # t8 <-- relocation info - - PTR_LI t3, MIPS_RELOC - bne t8, t3, 2f # skip non-MIPS_RELOC entries - nop - - PTR_L t3, -(2 * PTRSIZE)(t1) # t3 <-- location to fix up in FLASH - - PTR_L t8, 0(t3) # t8 <-- original pointer - PTR_ADD t8, s1 # t8 <-- adjusted pointer - - PTR_ADD t3, s1 # t3 <-- location to fix up in RAM - PTR_S t8, 0(t3) - -2: - blt t1, t2, 1b - PTR_ADDIU t1, 2 * PTRSIZE # each rel.dyn entry is 2*PTRSIZE bytes - - /* - * Flush caches to ensure our newly modified instructions are visible - * to the instruction cache. We're still running with the old GOT, so - * apply the reloc offset to the start address. - */ - PTR_LA a0, __text_start - PTR_LA a1, __text_end - PTR_SUB a1, a1, a0 - PTR_LA t9, flush_cache - jalr t9 - PTR_ADD a0, s1 - - PTR_ADD gp, s1 # adjust gp - - /* - * Clear BSS - * - * GOT is now relocated. Thus __bss_start and __bss_end can be - * accessed directly via $gp. - */ - PTR_LA t1, __bss_start # t1 <-- __bss_start - PTR_LA t2, __bss_end # t2 <-- __bss_end - -1: - PTR_S zero, 0(t1) - blt t1, t2, 1b - PTR_ADDIU t1, PTRSIZE - - move a0, s0 # a0 <-- gd - move a1, s2 - PTR_LA t9, board_init_r - jr t9 - move ra, zero - - END(relocate_code) diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index 0129c99611..bd5536f013 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -34,15 +34,6 @@ SECTIONS *(.data*) } - . = .; - _gp = ALIGN(16) + 0x7ff0; - - .got : { - *(.got) - } - - num_got_entries = SIZEOF(.got) >> PTR_COUNT_SHIFT; - . = ALIGN(4); .sdata : { *(.sdata*) @@ -57,33 +48,19 @@ SECTIONS __image_copy_end = .; __init_end = .; - .rel.dyn : { - __rel_dyn_start = .; - *(.rel.dyn) - __rel_dyn_end = .; - } - - .padding : { - /* - * Workaround for a binutils feature (or bug?). - * - * The GNU ld from binutils puts the dynamic relocation - * entries into the .rel.dyn section. Sometimes it - * allocates more dynamic relocation entries than it needs - * and the unused slots are set to R_MIPS_NONE entries. - * - * However the size of the .rel.dyn section in the ELF - * section header does not cover the unused entries, so - * objcopy removes those during stripping. - * - * Create a small section here to avoid that. - */ - LONG(0xFFFFFFFF) + /* + * .rel must come last so that the mips-relocs tool can shrink + * the section size & the PT_LOAD program header filesz. + */ + .rel : { + __rel_start = .; + BYTE(0x0) + . += (32 * 1024) - 1; } _end = .; - .bss __rel_dyn_start (OVERLAY) : { + .bss __rel_start (OVERLAY) : { __bss_start = .; *(.sbss.*) *(.bss.*) diff --git a/arch/mips/include/asm/relocs.h b/arch/mips/include/asm/relocs.h new file mode 100644 index 0000000000..92e9d04f7c --- /dev/null +++ b/arch/mips/include/asm/relocs.h @@ -0,0 +1,24 @@ +/* + * MIPS Relocations + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_MIPS_RELOCS_H__ +#define __ASM_MIPS_RELOCS_H__ + +#define R_MIPS_NONE 0 +#define R_MIPS_32 2 +#define R_MIPS_26 4 +#define R_MIPS_HI16 5 +#define R_MIPS_LO16 6 +#define R_MIPS_PC16 10 +#define R_MIPS_64 18 +#define R_MIPS_HIGHER 28 +#define R_MIPS_HIGHEST 29 +#define R_MIPS_PC21_S2 60 +#define R_MIPS_PC26_S2 61 + +#endif /* __ASM_MIPS_RELOCS_H__ */ diff --git a/arch/mips/include/asm/sections.h b/arch/mips/include/asm/sections.h index fc4640a392..b9d217999e 100644 --- a/arch/mips/include/asm/sections.h +++ b/arch/mips/include/asm/sections.h @@ -8,4 +8,11 @@ #include <asm-generic/sections.h> +/** + * __rel_start: Relocation data generated by the mips-relocs tool + * + * See arch/mips/lib/reloc.c for details on the format & use of this data. + */ +extern uint8_t __rel_start[]; + #endif diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile index 659c6ad187..ef557c6932 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -8,6 +8,7 @@ obj-y += cache.o obj-y += cache_init.o obj-y += genex.o +obj-y += reloc.o obj-y += stack.o obj-y += traps.o diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c index be877625a8..2b6790524c 100644 --- a/arch/mips/lib/bootm.c +++ b/arch/mips/lib/bootm.c @@ -279,17 +279,17 @@ static void boot_prep_linux(bootm_headers_t *images) boot_reloc_fdt(images); boot_setup_fdt(images); } else { - if (CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) - linux_env_legacy(images); - if (CONFIG_IS_ENABLED(MIPS_BOOT_CMDLINE_LEGACY)) { linux_cmdline_legacy(images); - if (!CONFIG_IS_ENABLED(CONFIG_MIPS_BOOT_ENV_LEGACY)) + if (!CONFIG_IS_ENABLED(MIPS_BOOT_ENV_LEGACY)) linux_cmdline_append(images); linux_cmdline_dump(); } + + if (CONFIG_IS_ENABLED(MIPS_BOOT_ENV_LEGACY)) + linux_env_legacy(images); } } diff --git a/arch/mips/lib/reloc.c b/arch/mips/lib/reloc.c new file mode 100644 index 0000000000..d0c52c9674 --- /dev/null +++ b/arch/mips/lib/reloc.c @@ -0,0 +1,164 @@ +/* + * MIPS Relocation + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Relocation data, found in the .rel section, is generated by the mips-relocs + * tool & contains a record of all locations in the U-Boot binary that need to + * be fixed up during relocation. + * + * The data is a sequence of unsigned integers, which are of somewhat arbitrary + * size. This is achieved by encoding integers as a sequence of bytes, each of + * which contains 7 bits of data with the most significant bit indicating + * whether any further bytes need to be read. The least significant bits of the + * integer are found in the first byte - ie. it somewhat resembles little + * endian. + * + * Each pair of two integers represents a relocation that must be applied. The + * first integer represents the type of relocation as a standard ELF relocation + * type (ie. R_MIPS_*). The second integer represents the offset at which to + * apply the relocation, relative to the previous relocation or for the first + * relocation the start of the relocated .text section. + * + * The end of the relocation data is indicated when type R_MIPS_NONE (0) is + * read, at which point no further integers should be read. That is, the + * terminating R_MIPS_NONE reloc includes no offset. + */ + +#include <common.h> +#include <asm/relocs.h> +#include <asm/sections.h> + +/** + * read_uint() - Read an unsigned integer from the buffer + * @buf: pointer to a pointer to the reloc buffer + * + * Read one whole unsigned integer from the relocation data pointed to by @buf, + * advancing @buf past the bytes encoding the integer. + * + * Returns: the integer read from @buf + */ +static unsigned long read_uint(uint8_t **buf) +{ + unsigned long val = 0; + unsigned int shift = 0; + uint8_t new; + + do { + new = *(*buf)++; + val |= (new & 0x7f) << shift; + shift += 7; + } while (new & 0x80); + + return val; +} + +/** + * apply_reloc() - Apply a single relocation + * @type: the type of reloc (R_MIPS_*) + * @addr: the address that the reloc should be applied to + * @off: the relocation offset, ie. number of bytes we're moving U-Boot by + * + * Apply a single relocation of type @type at @addr. This function is + * intentionally simple, and does the bare minimum needed to fixup the + * relocated U-Boot - in particular, it does not check for overflows. + */ +static void apply_reloc(unsigned int type, void *addr, long off) +{ + uint32_t u32; + + switch (type) { + case R_MIPS_26: + u32 = *(uint32_t *)addr; + u32 = (u32 & GENMASK(31, 26)) | + ((u32 + (off >> 2)) & GENMASK(25, 0)); + *(uint32_t *)addr = u32; + break; + + case R_MIPS_32: + *(uint32_t *)addr += off; + break; + + case R_MIPS_64: + *(uint64_t *)addr += off; + break; + + case R_MIPS_HI16: + *(uint32_t *)addr += off >> 16; + break; + + default: + panic("Unhandled reloc type %u\n", type); + } +} + +/** + * relocate_code() - Relocate U-Boot, generally from flash to DDR + * @start_addr_sp: new stack pointer + * @new_gd: pointer to relocated global data + * @relocaddr: the address to relocate to + * + * Relocate U-Boot from its current location (generally in flash) to a new one + * (generally in DDR). This function will copy the U-Boot binary & apply + * relocations as necessary, then jump to board_init_r in the new build of + * U-Boot. As such, this function does not return. + */ +void relocate_code(ulong start_addr_sp, gd_t *new_gd, ulong relocaddr) +{ + unsigned long addr, length, bss_len; + uint8_t *buf, *bss_start; + unsigned int type; + long off; + + /* + * Ensure that we're relocating by an offset which is a multiple of + * 64KiB, ie. doesn't change the least significant 16 bits of any + * addresses. This allows us to discard R_MIPS_LO16 relocs, saving + * space in the U-Boot binary & complexity in handling them. + */ + off = relocaddr - (unsigned long)__text_start; + if (off & 0xffff) + panic("Mis-aligned relocation\n"); + + /* Copy U-Boot to RAM */ + length = __image_copy_end - __text_start; + memcpy((void *)relocaddr, __text_start, length); + + /* Now apply relocations to the copy in RAM */ + buf = __rel_start; + addr = relocaddr; + while (true) { + type = read_uint(&buf); + if (type == R_MIPS_NONE) + break; + + addr += read_uint(&buf) << 2; + apply_reloc(type, (void *)addr, off); + } + + /* Ensure the icache is coherent */ + flush_cache(relocaddr, length); + + /* Clear the .bss section */ + bss_start = (uint8_t *)((unsigned long)__bss_start + off); + bss_len = (unsigned long)&__bss_end - (unsigned long)__bss_start; + memset(bss_start, 0, bss_len); + + /* Jump to the relocated U-Boot */ + asm volatile( + "move $29, %0\n" + " move $4, %1\n" + " move $5, %2\n" + " move $31, $0\n" + " jr %3" + : /* no outputs */ + : "r"(start_addr_sp), + "r"(new_gd), + "r"(relocaddr), + "r"((unsigned long)board_init_r + off)); + + /* Since we jumped to the new U-Boot above, we won't get here */ + unreachable(); +} |