diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 01975d7c60c4171dabc8fa1bc437f5789fddab48..85e15ebffa1dfbce3a3c01fb8f5f6400612a110c 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -224,7 +224,7 @@ config XIP config STACK_SIZE_SHIFT int - default 13 + default 14 config SPL_LDSCRIPT default "arch/riscv/cpu/u-boot-spl.lds" diff --git a/arch/riscv/cpu/ax25/Kconfig b/arch/riscv/cpu/ax25/Kconfig index d411a79c211f80b6d76017b4633d5ff23ebc3046..8d8d71dcbf970e64a92849b35e366078cd68218e 100644 --- a/arch/riscv/cpu/ax25/Kconfig +++ b/arch/riscv/cpu/ax25/Kconfig @@ -6,7 +6,9 @@ config RISCV_NDS imply RISCV_TIMER imply ANDES_PLIC if (RISCV_MMODE || SPL_RISCV_MMODE) imply ANDES_PLMT if (RISCV_MMODE || SPL_RISCV_MMODE) - imply V5L2_CACHE + imply SPL_CPU_SUPPORT + imply SPL_OPENSBI + imply SPL_LOAD_FIT help Run U-Boot on AndeStar V5 platforms and use some specific features which are provided by Andes Technology AndeStar V5 families. diff --git a/arch/riscv/cpu/ax25/cache.c b/arch/riscv/cpu/ax25/cache.c index 1455f2298f74db9276c0469e7fe3ba6bd196e457..9f424198b4a6a7b48ffddfd8f8ce3b5a182f172f 100644 --- a/arch/riscv/cpu/ax25/cache.c +++ b/arch/riscv/cpu/ax25/cache.c @@ -12,18 +12,46 @@ #include #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) /* mcctlcommand */ #define CCTL_REG_MCCTLCOMMAND_NUM 0x7cc /* D-cache operation */ #define CCTL_L1D_WBINVAL_ALL 6 #endif +#endif + +#ifdef CONFIG_V5L2_CACHE +static void _cache_enable(void) +{ + struct udevice *dev = NULL; + + uclass_find_first_device(UCLASS_CACHE, &dev); + + if (dev) + cache_enable(dev); +} + +static void _cache_disable(void) +{ + struct udevice *dev = NULL; + + uclass_find_first_device(UCLASS_CACHE, &dev); + + if (dev) + cache_disable(dev); +} +#endif void flush_dcache_all(void) { +#if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL); #endif +#endif +#endif } void flush_dcache_range(unsigned long start, unsigned long end) @@ -40,6 +68,7 @@ void icache_enable(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x1\n\t" @@ -47,12 +76,14 @@ void icache_enable(void) ); #endif #endif +#endif } void icache_disable(void) { #if !CONFIG_IS_ENABLED(SYS_ICACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) asm volatile ( "fence.i\n\t" "csrr t1, mcache_ctl\n\t" @@ -61,24 +92,23 @@ void icache_disable(void) ); #endif #endif +#endif } void dcache_enable(void) { #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE - struct udevice *dev = NULL; - +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "ori t0, t1, 0x2\n\t" "csrw mcache_ctl, t0\n\t" ); - - uclass_find_first_device(UCLASS_CACHE, &dev); - - if (dev) - cache_enable(dev); +#endif +#ifdef CONFIG_V5L2_CACHE + _cache_enable(); +#endif #endif #endif } @@ -87,19 +117,17 @@ void dcache_disable(void) { #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #ifdef CONFIG_RISCV_NDS_CACHE - struct udevice *dev = NULL; - +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) csr_write(CCTL_REG_MCCTLCOMMAND_NUM, CCTL_L1D_WBINVAL_ALL); asm volatile ( "csrr t1, mcache_ctl\n\t" "andi t0, t1, ~0x2\n\t" "csrw mcache_ctl, t0\n\t" ); - - uclass_find_first_device(UCLASS_CACHE, &dev); - - if (dev) - cache_disable(dev); +#endif +#ifdef CONFIG_V5L2_CACHE + _cache_disable(); +#endif #endif #endif } @@ -109,6 +137,7 @@ int icache_status(void) int ret = 0; #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x01\n\t" @@ -116,6 +145,7 @@ int icache_status(void) : : "memory" ); +#endif #endif return ret; @@ -126,6 +156,7 @@ int dcache_status(void) int ret = 0; #ifdef CONFIG_RISCV_NDS_CACHE +#if CONFIG_IS_ENABLED(RISCV_MMODE) || CONFIG_IS_ENABLED(SPL_RISCV_MMODE) asm volatile ( "csrr t1, mcache_ctl\n\t" "andi %0, t1, 0x02\n\t" @@ -133,6 +164,7 @@ int dcache_status(void) : : "memory" ); +#endif #endif return ret; diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 0a2ce6d6913ed96868af9dbb6d1614fbbf9ada8a..1a55b7d57091c2318695f6b4e908dc57c74a0aa1 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -174,7 +174,7 @@ spl_clear_bss: spl_clear_bss_loop: SREG zero, 0(t0) addi t0, t0, REGBYTES - bne t0, t1, spl_clear_bss_loop + blt t0, t1, spl_clear_bss_loop spl_stack_gd_setup: jal spl_relocate_stack_gd @@ -197,6 +197,7 @@ spl_secondary_hart_stack_gd_setup: la a0, secondary_hart_relocate mv a1, s0 mv a2, s0 + mv a3, zero jal smp_call_function /* hang if relocation of secondary harts has failed */ @@ -324,7 +325,7 @@ clear_bss: clbss_l: SREG zero, 0(t0) /* clear loop... */ addi t0, t0, REGBYTES - bne t0, t1, clbss_l + blt t0, t1, clbss_l relocate_secondary_harts: #ifdef CONFIG_SMP @@ -337,6 +338,7 @@ relocate_secondary_harts: mv a1, s2 mv a2, s3 + mv a3, zero jal smp_call_function /* hang if relocation of secondary harts has failed */ diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index 32255d58deba9ab6f6f0f1b98ce8e831f2ede6c6..955dd3106dcd7049f496e87824252a9ac5a4c47b 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -76,7 +76,7 @@ SECTIONS .bss : { __bss_start = .; *(.bss*) - . = ALIGN(4); + . = ALIGN(8); __bss_end = .; } > .bss_mem } diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds index 11bc4a738b676a6fdfe868c48e87e204373e53ef..838a8443999cda6c450a37b5bf7f99d7671d6942 100644 --- a/arch/riscv/cpu/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -82,7 +82,7 @@ SECTIONS .bss : { __bss_start = .; *(.bss*) - . = ALIGN(4); + . = ALIGN(8); __bss_end = .; } } diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index f9cd606a9aaf030aeccc27fd28ccdcf704c5eacf..4f30e6936f5121f5a5e6b2e58b7594ce2286643b 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0+ dtb-$(CONFIG_TARGET_AX25_AE350) += ae350_32.dtb ae350_64.dtb +dtb-$(CONFIG_TARGET_SIFIVE_FU540) += hifive-unleashed-a00.dtb targets += $(dtb-y) diff --git a/arch/riscv/dts/ae350_32.dts b/arch/riscv/dts/ae350_32.dts index 97b7cee983db4a6c84059cf8726981733b3c1928..3f8525fe56a91fe792a3a09fc6c67ff4a4942ec2 100644 --- a/arch/riscv/dts/ae350_32.dts +++ b/arch/riscv/dts/ae350_32.dts @@ -62,6 +62,48 @@ compatible = "riscv,cpu-intc"; }; }; + CPU2: cpu@2 { + device_type = "cpu"; + reg = <2>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv32imafdc"; + riscv,priv-major = <1>; + riscv,priv-minor = <10>; + mmu-type = "riscv,sv32"; + clock-frequency = <60000000>; + i-cache-size = <0x8000>; + i-cache-line-size = <32>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + next-level-cache = <&L2>; + CPU2_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + CPU3: cpu@3 { + device_type = "cpu"; + reg = <3>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv32imafdc"; + riscv,priv-major = <1>; + riscv,priv-minor = <10>; + mmu-type = "riscv,sv32"; + clock-frequency = <60000000>; + i-cache-size = <0x8000>; + i-cache-line-size = <32>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + next-level-cache = <&L2>; + CPU3_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; }; L2: l2-cache@e0500000 { @@ -94,7 +136,10 @@ interrupt-controller; reg = <0xe4000000 0x2000000>; riscv,ndev=<71>; - interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 &CPU1_intc 11 &CPU1_intc 9>; + interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 + &CPU1_intc 11 &CPU1_intc 9 + &CPU2_intc 11 &CPU2_intc 9 + &CPU3_intc 11 &CPU3_intc 9>; }; plic1: interrupt-controller@e6400000 { @@ -104,12 +149,18 @@ interrupt-controller; reg = <0xe6400000 0x400000>; riscv,ndev=<2>; - interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>; + interrupts-extended = <&CPU0_intc 3 + &CPU1_intc 3 + &CPU2_intc 3 + &CPU3_intc 3>; }; plmt0@e6000000 { compatible = "riscv,plmt0"; - interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>; + interrupts-extended = <&CPU0_intc 7 + &CPU1_intc 7 + &CPU2_intc 7 + &CPU3_intc 7>; reg = <0xe6000000 0x100000>; }; }; @@ -245,8 +296,10 @@ }; nor@0,0 { + #address-cells = <1>; + #size-cells = <1>; compatible = "cfi-flash"; - reg = <0x88000000 0x1000>; + reg = <0x88000000 0x4000000>; bank-width = <2>; device-width = <1>; }; diff --git a/arch/riscv/dts/ae350_64.dts b/arch/riscv/dts/ae350_64.dts index d8f00f8d3a7b82a89828ad4ba89e57183c70bbfa..482c70750300574f7bb24ddb2517a40ceaa0724b 100644 --- a/arch/riscv/dts/ae350_64.dts +++ b/arch/riscv/dts/ae350_64.dts @@ -62,6 +62,48 @@ compatible = "riscv,cpu-intc"; }; }; + CPU2: cpu@2 { + device_type = "cpu"; + reg = <2>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdc"; + riscv,priv-major = <1>; + riscv,priv-minor = <10>; + mmu-type = "riscv,sv39"; + clock-frequency = <60000000>; + i-cache-size = <0x8000>; + i-cache-line-size = <32>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + next-level-cache = <&L2>; + CPU2_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; + CPU3: cpu@3 { + device_type = "cpu"; + reg = <3>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdc"; + riscv,priv-major = <1>; + riscv,priv-minor = <10>; + mmu-type = "riscv,sv39"; + clock-frequency = <60000000>; + i-cache-size = <0x8000>; + i-cache-line-size = <32>; + d-cache-size = <0x8000>; + d-cache-line-size = <32>; + next-level-cache = <&L2>; + CPU3_intc: interrupt-controller { + #interrupt-cells = <1>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + }; + }; }; L2: l2-cache@e0500000 { @@ -94,7 +136,10 @@ interrupt-controller; reg = <0x0 0xe4000000 0x0 0x2000000>; riscv,ndev=<71>; - interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 &CPU1_intc 11 &CPU1_intc 9>; + interrupts-extended = <&CPU0_intc 11 &CPU0_intc 9 + &CPU1_intc 11 &CPU1_intc 9 + &CPU2_intc 11 &CPU2_intc 9 + &CPU3_intc 11 &CPU3_intc 9>; }; plic1: interrupt-controller@e6400000 { @@ -104,12 +149,18 @@ interrupt-controller; reg = <0x0 0xe6400000 0x0 0x400000>; riscv,ndev=<2>; - interrupts-extended = <&CPU0_intc 3 &CPU1_intc 3>; + interrupts-extended = <&CPU0_intc 3 + &CPU1_intc 3 + &CPU2_intc 3 + &CPU3_intc 3>; }; plmt0@e6000000 { compatible = "riscv,plmt0"; - interrupts-extended = <&CPU0_intc 7 &CPU1_intc 7>; + interrupts-extended = <&CPU0_intc 7 + &CPU1_intc 7 + &CPU2_intc 7 + &CPU3_intc 7>; reg = <0x0 0xe6000000 0x0 0x100000>; }; }; @@ -245,8 +296,10 @@ }; nor@0,0 { + #address-cells = <2>; + #size-cells = <2>; compatible = "cfi-flash"; - reg = <0x0 0x88000000 0x0 0x1000>; + reg = <0x0 0x88000000 0x0 0x4000000>; bank-width = <2>; device-width = <1>; }; diff --git a/arch/riscv/dts/fu540-c000.dtsi b/arch/riscv/dts/fu540-c000.dtsi new file mode 100644 index 0000000000000000000000000000000000000000..afa43c7ea3690db3fceb535759652a9488d22049 --- /dev/null +++ b/arch/riscv/dts/fu540-c000.dtsi @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2018-2019 SiFive, Inc */ + +/dts-v1/; + +#include + +/ { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu540-c000", "sifive,fu540"; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + ethernet0 = ð0; + }; + + chosen { + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + cpu0: cpu@0 { + compatible = "sifive,e51", "sifive,rocket0", "riscv"; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <128>; + i-cache-size = <16384>; + reg = <0>; + riscv,isa = "rv64imac"; + status = "disabled"; + cpu0_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu1: cpu@1 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <1>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu1_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu2: cpu@2 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <2>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu2_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu3: cpu@3 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <3>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu3_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + cpu4: cpu@4 { + compatible = "sifive,u54-mc", "sifive,rocket0", "riscv"; + d-cache-block-size = <64>; + d-cache-sets = <64>; + d-cache-size = <32768>; + d-tlb-sets = <1>; + d-tlb-size = <32>; + device_type = "cpu"; + i-cache-block-size = <64>; + i-cache-sets = <64>; + i-cache-size = <32768>; + i-tlb-sets = <1>; + i-tlb-size = <32>; + mmu-type = "riscv,sv39"; + reg = <4>; + riscv,isa = "rv64imafdc"; + tlb-split; + cpu4_intc: interrupt-controller { + #interrupt-cells = <1>; + compatible = "riscv,cpu-intc"; + interrupt-controller; + }; + }; + }; + soc { + #address-cells = <2>; + #size-cells = <2>; + compatible = "sifive,fu540-c000", "sifive,fu540", "simple-bus"; + ranges; + plic0: interrupt-controller@c000000 { + #interrupt-cells = <1>; + compatible = "sifive,plic-1.0.0"; + reg = <0x0 0xc000000 0x0 0x4000000>; + riscv,ndev = <53>; + interrupt-controller; + interrupts-extended = < + &cpu0_intc 0xffffffff + &cpu1_intc 0xffffffff &cpu1_intc 9 + &cpu2_intc 0xffffffff &cpu2_intc 9 + &cpu3_intc 0xffffffff &cpu3_intc 9 + &cpu4_intc 0xffffffff &cpu4_intc 9>; + }; + prci: clock-controller@10000000 { + compatible = "sifive,fu540-c000-prci"; + reg = <0x0 0x10000000 0x0 0x1000>; + clocks = <&hfclk>, <&rtcclk>; + #clock-cells = <1>; + }; + uart0: serial@10010000 { + compatible = "sifive,fu540-c000-uart", "sifive,uart0"; + reg = <0x0 0x10010000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <4>; + clocks = <&prci PRCI_CLK_TLCLK>; + status = "disabled"; + }; + uart1: serial@10011000 { + compatible = "sifive,fu540-c000-uart", "sifive,uart0"; + reg = <0x0 0x10011000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <5>; + clocks = <&prci PRCI_CLK_TLCLK>; + status = "disabled"; + }; + i2c0: i2c@10030000 { + compatible = "sifive,fu540-c000-i2c", "sifive,i2c0"; + reg = <0x0 0x10030000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <50>; + clocks = <&prci PRCI_CLK_TLCLK>; + reg-shift = <2>; + reg-io-width = <1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi0: spi@10040000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10040000 0x0 0x1000 + 0x0 0x20000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <51>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi1: spi@10041000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10041000 0x0 0x1000 + 0x0 0x30000000 0x0 0x10000000>; + interrupt-parent = <&plic0>; + interrupts = <52>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + qspi2: spi@10050000 { + compatible = "sifive,fu540-c000-spi", "sifive,spi0"; + reg = <0x0 0x10050000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <6>; + clocks = <&prci PRCI_CLK_TLCLK>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + eth0: ethernet@10090000 { + compatible = "sifive,fu540-c000-gem"; + interrupt-parent = <&plic0>; + interrupts = <53>; + reg = <0x0 0x10090000 0x0 0x2000 + 0x0 0x100a0000 0x0 0x1000>; + local-mac-address = [00 00 00 00 00 00]; + clock-names = "pclk", "hclk"; + clocks = <&prci PRCI_CLK_GEMGXLPLL>, + <&prci PRCI_CLK_GEMGXLPLL>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + pwm0: pwm@10020000 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10020000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <42 43 44 45>; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; + pwm1: pwm@10021000 { + compatible = "sifive,fu540-c000-pwm", "sifive,pwm0"; + reg = <0x0 0x10021000 0x0 0x1000>; + interrupt-parent = <&plic0>; + interrupts = <46 47 48 49>; + clocks = <&prci PRCI_CLK_TLCLK>; + #pwm-cells = <3>; + status = "disabled"; + }; + + }; +}; diff --git a/arch/riscv/dts/hifive-unleashed-a00.dts b/arch/riscv/dts/hifive-unleashed-a00.dts new file mode 100644 index 0000000000000000000000000000000000000000..88cfcb96bf233d3bb1c7677eb5526f6072e8ce77 --- /dev/null +++ b/arch/riscv/dts/hifive-unleashed-a00.dts @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* Copyright (c) 2018-2019 SiFive, Inc */ + +#include "fu540-c000.dtsi" + +/* Clock frequency (in Hz) of the PCB crystal for rtcclk */ +#define RTCCLK_FREQ 1000000 + +/ { + #address-cells = <2>; + #size-cells = <2>; + model = "SiFive HiFive Unleashed A00"; + compatible = "sifive,hifive-unleashed-a00", "sifive,fu540-c000"; + + chosen { + stdout-path = "serial0"; + }; + + cpus { + timebase-frequency = ; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x2 0x00000000>; + }; + + soc { + }; + + hfclk: hfclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <33333333>; + clock-output-names = "hfclk"; + }; + + rtcclk: rtcclk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = ; + clock-output-names = "rtcclk"; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; +}; + +&qspi0 { + status = "okay"; + flash@0 { + compatible = "issi,is25wp256", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + spi-tx-bus-width = <4>; + spi-rx-bus-width = <4>; + }; +}; + +&qspi2 { + status = "okay"; + mmc@0 { + compatible = "mmc-spi-slot"; + reg = <0>; + spi-max-frequency = <20000000>; + voltage-ranges = <3300 3300>; + disable-wp; + }; +}; + +ð0 { + status = "okay"; + phy-mode = "gmii"; + phy-handle = <&phy0>; + phy0: ethernet-phy@0 { + reg = <0>; + }; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h index bc863fdbafbcfe54689134652caf8f728d551a9e..74de92ed130ebb4bfae1050581c70183a563746b 100644 --- a/arch/riscv/include/asm/smp.h +++ b/arch/riscv/include/asm/smp.h @@ -46,8 +46,9 @@ void handle_ipi(ulong hart); * @addr: Address of function * @arg0: First argument of function * @arg1: Second argument of function + * @wait: Wait for harts to acknowledge request * @return 0 if OK, -ve on error */ -int smp_call_function(ulong addr, ulong arg0, ulong arg1); +int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait); #endif diff --git a/arch/riscv/lib/andes_plic.c b/arch/riscv/lib/andes_plic.c index 28568e4e2b6f7f0468d0b8fa5023b1af0d294a17..3868569a65a96d1ad4a7ad34901661d7ef87c0d0 100644 --- a/arch/riscv/lib/andes_plic.c +++ b/arch/riscv/lib/andes_plic.c @@ -19,7 +19,7 @@ #include /* pending register */ -#define PENDING_REG(base, hart) ((ulong)(base) + 0x1000 + (hart) * 8) +#define PENDING_REG(base, hart) ((ulong)(base) + 0x1000 + ((hart) / 4) * 4) /* enable register */ #define ENABLE_REG(base, hart) ((ulong)(base) + 0x2000 + (hart) * 0x80) /* claim register */ @@ -46,7 +46,7 @@ static int init_plic(void); static int enable_ipi(int hart) { - int en; + unsigned int en; en = ENABLE_HART_IPI >> hart; writel(en, (void __iomem *)ENABLE_REG(gd->arch.plic, hart)); @@ -94,10 +94,13 @@ static int init_plic(void) int riscv_send_ipi(int hart) { + unsigned int ipi; + PLIC_BASE_GET(); - writel(SEND_IPI_TO_HART(hart), - (void __iomem *)PENDING_REG(gd->arch.plic, gd->arch.boot_hart)); + ipi = (SEND_IPI_TO_HART(hart) << (8 * gd->arch.boot_hart)); + writel(ipi, (void __iomem *)PENDING_REG(gd->arch.plic, + gd->arch.boot_hart)); return 0; } @@ -114,6 +117,17 @@ int riscv_clear_ipi(int hart) return 0; } +int riscv_get_ipi(int hart, int *pending) +{ + PLIC_BASE_GET(); + + *pending = readl((void __iomem *)PENDING_REG(gd->arch.plic, + gd->arch.boot_hart)); + *pending = !!(*pending & SEND_IPI_TO_HART(hart)); + + return 0; +} + static const struct udevice_id andes_plic_ids[] = { { .compatible = "riscv,plic1", .data = RISCV_SYSCON_PLIC }, { } diff --git a/arch/riscv/lib/bootm.c b/arch/riscv/lib/bootm.c index efbd3e23e7a570e3f693eca1645118ebb9c7277f..e96137a50cb124657381fb12c18f14642920781c 100644 --- a/arch/riscv/lib/bootm.c +++ b/arch/riscv/lib/bootm.c @@ -99,7 +99,7 @@ static void boot_jump_linux(bootm_headers_t *images, int flag) if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) { #ifdef CONFIG_SMP ret = smp_call_function(images->ep, - (ulong)images->ft_addr, 0); + (ulong)images->ft_addr, 0, 0); if (ret) hang(); #endif diff --git a/arch/riscv/lib/sbi_ipi.c b/arch/riscv/lib/sbi_ipi.c index 170346da68c23feca6c55506276720a3c386f795..9a698ce74e67127209c46cec82fbee9e2e907f19 100644 --- a/arch/riscv/lib/sbi_ipi.c +++ b/arch/riscv/lib/sbi_ipi.c @@ -23,3 +23,14 @@ int riscv_clear_ipi(int hart) return 0; } + +int riscv_get_ipi(int hart, int *pending) +{ + /* + * The SBI does not support reading the IPI status. We always return 0 + * to indicate that no IPI is pending. + */ + *pending = 0; + + return 0; +} diff --git a/arch/riscv/lib/sifive_clint.c b/arch/riscv/lib/sifive_clint.c index d24e0d585b5380b15102ba3f91cac6fcf89fa058..d7899d16d7a2be5fe988c450afa262d1eb99eb3d 100644 --- a/arch/riscv/lib/sifive_clint.c +++ b/arch/riscv/lib/sifive_clint.c @@ -71,6 +71,15 @@ int riscv_clear_ipi(int hart) return 0; } +int riscv_get_ipi(int hart, int *pending) +{ + CLINT_BASE_GET(); + + *pending = readl((void __iomem *)MSIP_REG(gd->arch.clint, hart)); + + return 0; +} + static const struct udevice_id sifive_clint_ids[] = { { .compatible = "riscv,clint0", .data = RISCV_SYSCON_CLINT }, { } diff --git a/arch/riscv/lib/smp.c b/arch/riscv/lib/smp.c index 705437862a0d1402f13c4cf0f5e62e6ccabb5d06..17adb35730d83c08d67f477c534379cd561fe5c7 100644 --- a/arch/riscv/lib/smp.c +++ b/arch/riscv/lib/smp.c @@ -32,11 +32,23 @@ extern int riscv_send_ipi(int hart); */ extern int riscv_clear_ipi(int hart); -static int send_ipi_many(struct ipi_data *ipi) +/** + * riscv_get_ipi() - Get status of inter-processor interrupt (IPI) + * + * Platform code must provide this function. + * + * @hart: Hart ID of hart to be checked + * @pending: Pointer to variable with result of the check, + * 1 if IPI is pending, 0 otherwise + * @return 0 if OK, -ve on error + */ +extern int riscv_get_ipi(int hart, int *pending); + +static int send_ipi_many(struct ipi_data *ipi, int wait) { ofnode node, cpus; u32 reg; - int ret; + int ret, pending; cpus = ofnode_path("/cpus"); if (!ofnode_valid(cpus)) { @@ -79,6 +91,15 @@ static int send_ipi_many(struct ipi_data *ipi) pr_err("Cannot send IPI to hart %d\n", reg); return ret; } + + if (wait) { + pending = 1; + while (pending) { + ret = riscv_get_ipi(reg, &pending); + if (ret) + return ret; + } + } } return 0; @@ -92,21 +113,25 @@ void handle_ipi(ulong hart) if (hart >= CONFIG_NR_CPUS) return; + __smp_mb(); + + smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr; + invalidate_icache_all(); + + /* + * Clear the IPI to acknowledge the request before jumping to the + * requested function. + */ ret = riscv_clear_ipi(hart); if (ret) { pr_err("Cannot clear IPI of hart %ld\n", hart); return; } - __smp_mb(); - - smp_function = (void (*)(ulong, ulong, ulong))gd->arch.ipi[hart].addr; - invalidate_icache_all(); - smp_function(hart, gd->arch.ipi[hart].arg0, gd->arch.ipi[hart].arg1); } -int smp_call_function(ulong addr, ulong arg0, ulong arg1) +int smp_call_function(ulong addr, ulong arg0, ulong arg1, int wait) { int ret = 0; struct ipi_data ipi; @@ -115,7 +140,7 @@ int smp_call_function(ulong addr, ulong arg0, ulong arg1) ipi.arg0 = arg0; ipi.arg1 = arg1; - ret = send_ipi_many(&ipi); + ret = send_ipi_many(&ipi, wait); return ret; } diff --git a/arch/riscv/lib/spl.c b/arch/riscv/lib/spl.c index a544df0a2b1a648005cb49eeb93bdf59f8de405f..dc7577f751660dfdc744d316464b236ce01707c3 100644 --- a/arch/riscv/lib/spl.c +++ b/arch/riscv/lib/spl.c @@ -41,7 +41,7 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) debug("image entry point: 0x%lX\n", spl_image->entry_point); #ifdef CONFIG_SMP - ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0); + ret = smp_call_function(spl_image->entry_point, (ulong)fdt_blob, 0, 0); if (ret) hang(); #endif diff --git a/board/AndesTech/ax25-ae350/Kconfig b/board/AndesTech/ax25-ae350/Kconfig index 5e682b679d8aa536ee5370a37a74653e2b1ceb22..321dd0cb10ff5d5454f3cd43e6866b27d0e209cf 100644 --- a/board/AndesTech/ax25-ae350/Kconfig +++ b/board/AndesTech/ax25-ae350/Kconfig @@ -21,9 +21,18 @@ config ENV_SIZE config ENV_OFFSET default 0x140000 if ENV_IS_IN_SPI_FLASH +config SPL_TEXT_BASE + default 0x800000 + +config SPL_OPENSBI_LOAD_ADDR + default 0x01000000 + config BOARD_SPECIFIC_OPTIONS # dummy def_bool y select RISCV_NDS + select SUPPORT_SPL imply SMP + imply SPL_RAM_SUPPORT + imply SPL_RAM_DEVICE endif diff --git a/board/AndesTech/ax25-ae350/MAINTAINERS b/board/AndesTech/ax25-ae350/MAINTAINERS index feed5d1298ffd9690fb45d5181c517f499c0b60e..eebee167c3b63f4cc7db4b344e632236938b4267 100644 --- a/board/AndesTech/ax25-ae350/MAINTAINERS +++ b/board/AndesTech/ax25-ae350/MAINTAINERS @@ -7,3 +7,7 @@ F: configs/ae350_rv32_defconfig F: configs/ae350_rv64_defconfig F: configs/ae350_rv32_xip_defconfig F: configs/ae350_rv64_xip_defconfig +F: configs/ae350_rv32_spl_defconfig +F: configs/ae350_rv64_spl_defconfig +F: configs/ae350_rv32_spl_xip_defconfig +F: configs/ae350_rv64_spl_xip_defconfig diff --git a/board/AndesTech/ax25-ae350/ax25-ae350.c b/board/AndesTech/ax25-ae350/ax25-ae350.c index b43eebb7a61a4a3ec7de2b154a6cab37c9625c1e..47e692936503da50304343302d902dc16baf7636 100644 --- a/board/AndesTech/ax25-ae350/ax25-ae350.c +++ b/board/AndesTech/ax25-ae350/ax25-ae350.c @@ -12,6 +12,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -29,29 +30,12 @@ int board_init(void) int dram_init(void) { - unsigned long sdram_base = PHYS_SDRAM_0; - unsigned long expected_size = PHYS_SDRAM_0_SIZE + PHYS_SDRAM_1_SIZE; - unsigned long actual_size; - - actual_size = get_ram_size((void *)sdram_base, expected_size); - gd->ram_size = actual_size; - - if (expected_size != actual_size) { - printf("Warning: Only %lu of %lu MiB SDRAM is working\n", - actual_size >> 20, expected_size >> 20); - } - - return 0; + return fdtdec_setup_mem_size_base(); } int dram_init_banksize(void) { - gd->bd->bi_dram[0].start = PHYS_SDRAM_0; - gd->bd->bi_dram[0].size = PHYS_SDRAM_0_SIZE; - gd->bd->bi_dram[1].start = PHYS_SDRAM_1; - gd->bd->bi_dram[1].size = PHYS_SDRAM_1_SIZE; - - return 0; + return fdtdec_setup_memory_banksize(); } #if defined(CONFIG_FTMAC100) && !defined(CONFIG_DM_ETH) @@ -110,3 +94,29 @@ int board_early_init_f(void) return 0; } #endif + +#ifdef CONFIG_SPL +void board_boot_order(u32 *spl_boot_list) +{ + u8 i; + u32 boot_devices[] = { +#ifdef CONFIG_SPL_RAM_SUPPORT + BOOT_DEVICE_RAM, +#endif +#ifdef CONFIG_SPL_MMC_SUPPORT + BOOT_DEVICE_MMC1, +#endif + }; + + for (i = 0; i < ARRAY_SIZE(boot_devices); i++) + spl_boot_list[i] = boot_devices[i]; +} +#endif + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* boot using first FIT config */ + return 0; +} +#endif diff --git a/common/spl/Kconfig b/common/spl/Kconfig index c8cb715c3a3ee6a79a8d08444e6ff4e3930814c8..a72412718bd89257104426baa195be71a44cec66 100644 --- a/common/spl/Kconfig +++ b/common/spl/Kconfig @@ -439,6 +439,13 @@ config SPL_FIT_IMAGE_TINY ensure this information is available to the next image invoked). +config SPL_CACHE_SUPPORT + bool "Support CACHE drivers" + help + Enable CACHE drivers in SPL. These drivers can keep data so that + future requests for that data can be served faster. Enable this option + to build the drivers in drivers/cache as part of an SPL build. + config SPL_CPU_SUPPORT bool "Support CPU drivers" help diff --git a/common/spl/spl_opensbi.c b/common/spl/spl_opensbi.c index 2345f949f05b48d86b2e51d844ffe6138afe253a..6404373ecadfbdd9c713f2209879051aa3cf2159 100644 --- a/common/spl/spl_opensbi.c +++ b/common/spl/spl_opensbi.c @@ -70,14 +70,25 @@ void spl_invoke_opensbi(struct spl_image_info *spl_image) opensbi_info.next_addr = uboot_entry; opensbi_info.next_mode = FW_DYNAMIC_INFO_NEXT_MODE_S; opensbi_info.options = SBI_SCRATCH_NO_BOOT_PRINTS; + opensbi_info.boot_hart = gd->arch.boot_hart; opensbi_entry = (void (*)(ulong, ulong, ulong))spl_image->entry_point; invalidate_icache_all(); #ifdef CONFIG_SMP + /* + * Start OpenSBI on all secondary harts and wait for acknowledgment. + * + * OpenSBI first relocates itself to its link address. This is done by + * the main hart. To make sure no hart is still running U-Boot SPL + * during relocation, we wait for all secondary harts to acknowledge + * the call-function request before entering OpenSBI on the main hart. + * Otherwise, code corruption can occur if the link address ranges of + * U-Boot SPL and OpenSBI overlap. + */ ret = smp_call_function((ulong)spl_image->entry_point, (ulong)spl_image->fdt_addr, - (ulong)&opensbi_info); + (ulong)&opensbi_info, 1); if (ret) hang(); #endif diff --git a/configs/ae350_rv32_spl_defconfig b/configs/ae350_rv32_spl_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..8bd6a2638b1852dbcab2a296eff6d890c58f33f8 --- /dev/null +++ b/configs/ae350_rv32_spl_defconfig @@ -0,0 +1,38 @@ +CONFIG_RISCV=y +CONFIG_SPL=y +CONFIG_RISCV_SMODE=y +CONFIG_SYS_TEXT_BASE=0x01200000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_AX25_AE350=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="RISC-V # " +CONFIG_CMD_IMLS=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SF_TEST=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_CMD_CACHE=y +CONFIG_OF_PRIOR_STAGE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_SECT_SIZE=0x1000 +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_MMC=y +CONFIG_FTSDC010=y +CONFIG_FTSDC010_SDIO=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_FTMAC100=y +CONFIG_BAUDRATE=38400 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_ATCSPI200_SPI=y diff --git a/configs/ae350_rv32_spl_xip_defconfig b/configs/ae350_rv32_spl_xip_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..9c605fe90731e513970009e0ae31e61754aa7332 --- /dev/null +++ b/configs/ae350_rv32_spl_xip_defconfig @@ -0,0 +1,40 @@ +CONFIG_RISCV=y +CONFIG_SPL=y +CONFIG_RISCV_SMODE=y +CONFIG_SPL_TEXT_BASE=0x80000000 +CONFIG_SYS_TEXT_BASE=0x01200000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_AX25_AE350=y +CONFIG_XIP=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="RISC-V # " +CONFIG_CMD_IMLS=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SF_TEST=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_CMD_CACHE=y +CONFIG_OF_BOARD=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_SECT_SIZE=0x1000 +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_MMC=y +CONFIG_FTSDC010=y +CONFIG_FTSDC010_SDIO=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_FTMAC100=y +CONFIG_BAUDRATE=38400 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_ATCSPI200_SPI=y diff --git a/configs/ae350_rv64_spl_defconfig b/configs/ae350_rv64_spl_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..806f327610b6524a4e0f76aececc883d15693cc1 --- /dev/null +++ b/configs/ae350_rv64_spl_defconfig @@ -0,0 +1,39 @@ +CONFIG_RISCV=y +CONFIG_SPL=y +CONFIG_RISCV_SMODE=y +CONFIG_SYS_TEXT_BASE=0x01200000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_AX25_AE350=y +CONFIG_ARCH_RV64I=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="RISC-V # " +CONFIG_CMD_IMLS=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SF_TEST=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_CMD_CACHE=y +CONFIG_OF_PRIOR_STAGE=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_SECT_SIZE=0x1000 +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_MMC=y +CONFIG_FTSDC010=y +CONFIG_FTSDC010_SDIO=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_FTMAC100=y +CONFIG_BAUDRATE=38400 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_ATCSPI200_SPI=y diff --git a/configs/ae350_rv64_spl_xip_defconfig b/configs/ae350_rv64_spl_xip_defconfig new file mode 100644 index 0000000000000000000000000000000000000000..1bacc5f36bb7335bbbd334026ea03fa7ce00545b --- /dev/null +++ b/configs/ae350_rv64_spl_xip_defconfig @@ -0,0 +1,41 @@ +CONFIG_RISCV=y +CONFIG_SPL=y +CONFIG_RISCV_SMODE=y +CONFIG_SPL_TEXT_BASE=0x80000000 +CONFIG_SYS_TEXT_BASE=0x01200000 +CONFIG_NR_DRAM_BANKS=2 +CONFIG_TARGET_AX25_AE350=y +CONFIG_ARCH_RV64I=y +CONFIG_XIP=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_BOOTDELAY=3 +CONFIG_BOARD_EARLY_INIT_F=y +CONFIG_SYS_PROMPT="RISC-V # " +CONFIG_CMD_IMLS=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SF_TEST=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_BOOTP_PREFER_SERVERIP=y +CONFIG_CMD_CACHE=y +CONFIG_OF_BOARD=y +CONFIG_ENV_IS_IN_SPI_FLASH=y +CONFIG_ENV_SECT_SIZE=0x1000 +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_MMC=y +CONFIG_FTSDC010=y +CONFIG_FTSDC010_SDIO=y +CONFIG_MTD_NOR_FLASH=y +CONFIG_FLASH_CFI_DRIVER=y +CONFIG_CFI_FLASH=y +CONFIG_SYS_FLASH_USE_BUFFER_WRITE=y +CONFIG_SYS_FLASH_CFI=y +CONFIG_SPI_FLASH=y +CONFIG_SF_DEFAULT_MODE=0x0 +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_FTMAC100=y +CONFIG_BAUDRATE=38400 +CONFIG_SYS_NS16550=y +CONFIG_SPI=y +CONFIG_ATCSPI200_SPI=y diff --git a/configs/sifive_fu540_defconfig b/configs/sifive_fu540_defconfig index 48eccd766bc1e36549d99931912087d0dbfa771f..7d38ec9a7072f87e27179b2beca5db4882c5d942 100644 --- a/configs/sifive_fu540_defconfig +++ b/configs/sifive_fu540_defconfig @@ -7,8 +7,9 @@ CONFIG_RISCV_SMODE=y CONFIG_DISTRO_DEFAULTS=y CONFIG_FIT=y CONFIG_MISC_INIT_R=y +CONFIG_DEFAULT_DEVICE_TREE="hifive-unleashed-a00" CONFIG_DISPLAY_CPUINFO=y CONFIG_DISPLAY_BOARDINFO=y -CONFIG_OF_PRIOR_STAGE=y +CONFIG_OF_SEPARATE=y CONFIG_SYS_RELOC_GD_ENV_ADDR=y CONFIG_DM_MTD=y diff --git a/doc/board/AndesTech/ax25-ae350.rst b/doc/board/AndesTech/ax25-ae350.rst index 7a0189382d060fb1510016110420d72ccd74a04c..a7bd1a75e8ace3e0371010b093f078c450ff9445 100644 --- a/doc/board/AndesTech/ax25-ae350.rst +++ b/doc/board/AndesTech/ax25-ae350.rst @@ -324,6 +324,209 @@ Boot bbl and riscv-linux via U-Boot on QEMU / # -TODO ----- -Boot bbl and riscv-linux via U-Boot on AE350 board +Running U-Boot SPL +------------------ +The U-Boot SPL will boot in M mode and load the FIT image which include +OpenSBI and U-Boot proper images. After loading progress, it will jump +to OpenSBI first and then U-Boot proper which will run in S mode. + + +How to build U-Boot SPL +----------------------- +Before building U-Boot SPL, OpenSBI must be build first. OpenSBI can be +cloned and build for AE350 as below: + +git clone https://github.com/riscv/opensbi.git +cd opensbi +make PLATFORM=andes/ae350 + +Copy OpenSBI FW_DYNAMIC image (build\platform\andes\ae350\firmware\fw_dynamic.bin) +into U-Boot root directory + + +How to build U-Boot SPL booting from RAM +---------------------------------------- +With ae350_rv[32|64]_spl_defconfigs: + +U-Boot SPL will be loaded by gdb or FSBL and runs in RAM in machine mode +and then load FIT image from RAM device on AE350. + + +How to build U-Boot SPL booting from ROM +---------------------------------------- +With ae350_rv[32|64]_spl_xip_defconfigs: + +U-Boot SPL can be burned into SPI flash and run in flash in machine mode +and then load FIT image from SPI flash or MMC device on AE350. + + +Messages of U-Boot SPL boots Kernel on AE350 board +-------------------------------------------------- + +.. code-block:: none + +U-Boot SPL 2020.01-rc1-00292-g67a3313-dirty (Nov 14 2019 - 11:26:21 +0800) +Trying to boot from RAM + +OpenSBI v0.5-1-gdd8ef28 (Nov 14 2019 11:08:39) + ____ _____ ____ _____ + / __ \ / ____| _ \_ _| + | | | |_ __ ___ _ __ | (___ | |_) || | + | | | | '_ \ / _ \ '_ \ \___ \| _ < | | + | |__| | |_) | __/ | | |____) | |_) || |_ + \____/| .__/ \___|_| |_|_____/|____/_____| + | | + |_| + +Platform Name : Andes AE350 +Platform HART Features : RV64ACIMSUX +Platform Max HARTs : 4 +Current Hart : 0 +Firmware Base : 0x0 +Firmware Size : 84 KB +Runtime SBI Version : 0.2 + +PMP0: 0x0000000000000000-0x000000000001ffff (A) +PMP1: 0x0000000000000000-0x00000001ffffffff (A,R,W,X) + + +U-Boot 2020.01-rc1-00292-g67a3313-dirty (Nov 14 2019 - 11:26:21 +0800) + +DRAM: 1 GiB +Flash: 64 MiB +MMC: mmc@f0e00000: 0 +Loading Environment from SPI Flash... SF: Detected mx25u1635e with page size 256 Bytes, erase size 4 KiB, total 2 MiB +OK +In: serial@f0300000 +Out: serial@f0300000 +Err: serial@f0300000 +Net: no alias for ethernet0 + +Warning: mac@e0100000 (eth0) using random MAC address - a2:ae:93:7b:cc:8f +eth0: mac@e0100000 +Hit any key to stop autoboot: 0 +6455 bytes read in 31 ms (203.1 KiB/s) +20421684 bytes read in 8647 ms (2.3 MiB/s) +## Booting kernel from Legacy Image at 00600000 ... + Image Name: + Image Type: RISC-V Linux Kernel Image (uncompressed) + Data Size: 20421620 Bytes = 19.5 MiB + Load Address: 00200000 + Entry Point: 00200000 + Verifying Checksum ... OK +## Flattened Device Tree blob at 20000000 + Booting using the fdt blob at 0x20000000 + Loading Kernel Image + Loading Device Tree to 000000001effb000, end 000000001efff936 ... OK + +Starting kernel ... + +OF: fdt: Ignoring memory range 0x0 - 0x200000 +Linux version 4.17.0-00253-g49136e10bcb2 (sqa@atcsqa07) (gcc version 7.3.0 (2019-04-06_nds64le-linux-glibc-v5_experimental)) #1 SMP PREEMPT Sat Apr 6 23:41:49 CST 2019 +bootconsole [early0] enabled +Initial ramdisk at: 0x (ptrval) (13665712 bytes) +Zone ranges: + DMA32 [mem 0x0000000000200000-0x000000003fffffff] + Normal empty +Movable zone start for each node +Early memory node ranges + node 0: [mem 0x0000000000200000-0x000000003fffffff] +Initmem setup node 0 [mem 0x0000000000200000-0x000000003fffffff] +software IO TLB [mem 0x3b1f8000-0x3f1f8000] (64MB) mapped at [ (ptrval)- (ptrval)] +elf_platform is rv64i2p0m2p0a2p0c2p0xv5-0p0 +compatible privileged spec version 1.10 +percpu: Embedded 16 pages/cpu @ (ptrval) s28184 r8192 d29160 u65536 +Built 1 zonelists, mobility grouping on. Total pages: 258055 +Kernel command line: console=ttyS0,38400n8 debug loglevel=7 +log_buf_len individual max cpu contribution: 4096 bytes +log_buf_len total cpu_extra contributions: 12288 bytes +log_buf_len min size: 16384 bytes +log_buf_len: 32768 bytes +early log buf free: 14608(89%) +Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes) +Inode-cache hash table entries: 65536 (order: 7, 524288 bytes) +Sorting __ex_table... +Memory: 944428K/1046528K available (3979K kernel code, 246K rwdata, 1490K rodata, 13523K init, 688K bss, 102100K reserved, 0K cma-reserved) +SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=4, Nodes=1 +Preemptible hierarchical RCU implementation. + Tasks RCU enabled. +NR_IRQS: 72, nr_irqs: 72, preallocated irqs: 0 +riscv,cpu_intc,0: 64 local interrupts mapped +riscv,cpu_intc,1: 64 local interrupts mapped +riscv,cpu_intc,2: 64 local interrupts mapped +riscv,cpu_intc,3: 64 local interrupts mapped +riscv,plic0,e4000000: mapped 71 interrupts to 8/8 handlers +clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x1bacf917bf, max_idle_ns: 881590412290 ns +sched_clock: 64 bits at 60MHz, resolution 16ns, wraps every 4398046511098ns +Console: colour dummy device 40x30 +Calibrating delay loop (skipped), value calculated using timer frequency.. 120.00 BogoMIPS (lpj=600000) +pid_max: default: 32768 minimum: 301 +Mount-cache hash table entries: 2048 (order: 2, 16384 bytes) +Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes) +Hierarchical SRCU implementation. +smp: Bringing up secondary CPUs ... +CPU0: online +CPU2: online +CPU3: online +smp: Brought up 1 node, 4 CPUs +devtmpfs: initialized +random: get_random_u32 called from bucket_table_alloc+0x198/0x1d8 with crng_init=0 +clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604462750000 ns +futex hash table entries: 1024 (order: 4, 65536 bytes) +NET: Registered protocol family 16 +Advanced Linux Sound Architecture Driver Initialized. +clocksource: Switched to clocksource riscv_clocksource +NET: Registered protocol family 2 +tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes) +TCP established hash table entries: 8192 (order: 4, 65536 bytes) +TCP bind hash table entries: 8192 (order: 5, 131072 bytes) +TCP: Hash tables configured (established 8192 bind 8192) +UDP hash table entries: 512 (order: 2, 16384 bytes) +UDP-Lite hash table entries: 512 (order: 2, 16384 bytes) +NET: Registered protocol family 1 +RPC: Registered named UNIX socket transport module. +RPC: Registered udp transport module. +RPC: Registered tcp transport module. +RPC: Registered tcp NFSv4.1 backchannel transport module. +Unpacking initramfs... +workingset: timestamp_bits=62 max_order=18 bucket_order=0 +NFS: Registering the id_resolver key type +Key type id_resolver registered +Key type id_legacy registered +nfs4filelayout_init: NFSv4 File Layout Driver Registering... +io scheduler noop registered +io scheduler cfq registered (default) +io scheduler mq-deadline registered +io scheduler kyber registered +Console: switching to colour frame buffer device 40x30 +Serial: 8250/16550 driver, 4 ports, IRQ sharing disabled +console [ttyS0] disabled +f0300000.serial: ttyS0 at MMIO 0xf0300020 (irq = 20, base_baud = 1228800) is a 16550A +console [ttyS0] enabled +console [ttyS0] enabled +bootconsole [early0] disabled +bootconsole [early0] disabled +loop: module loaded +tun: Universal TUN/TAP device driver, 1.6 +ftmac100: Loading version 0.2 ... +ftmac100 e0100000.mac eth0: irq 21, mapped at (ptrval) +ftmac100 e0100000.mac eth0: generated random MAC address 4e:fd:bd:f3:04:fc +ftsdc010 f0e00000.mmc: mmc0 - using hw SDIO IRQ +mmc0: new SDHC card at address d555 +ftssp010 card registered! +mmcblk0: mmc0:d555 SD04G 3.79 GiB +NET: Registered protocol family 10 + mmcblk0: p1 +Segment Routing with IPv6 +sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver +NET: Registered protocol family 17 +NET: Registered protocol family 15 +ALSA device list: + #0: ftssp_ac97 controller +Freeing unused kernel memory: 13520K +This architecture does not have kernel memory protection. +Sysinit starting +Sat Apr 6 23:33:53 CST 2019 +nfs4flexfilelayout_init: NFSv4 Flexfile Layout Driver Registering... + +~ # diff --git a/doc/board/sifive/fu540.rst b/doc/board/sifive/fu540.rst index 7807f5b2c1286fea33b2e64d01dc5748964e37de..3937222c6c6dfee4415f45fb3470bc46233e76f6 100644 --- a/doc/board/sifive/fu540.rst +++ b/doc/board/sifive/fu540.rst @@ -58,10 +58,7 @@ firmware. We need to compile OpenSBI with below command: .. code-block:: none - make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH= FW_PAYLOAD_FDT_PATH= - -(Note: Prefer hifive-unleashed-a00.dtb from Linux-5.3 or higher) -(Note: Linux-5.2 is also fine but it does not have ethernet DT node) +make PLATFORM=sifive/fu540 FW_PAYLOAD_PATH= More detailed description of steps required to build FW_PAYLOAD firmware is beyond the scope of this document. Please refer OpenSBI documenation. diff --git a/drivers/Makefile b/drivers/Makefile index 0d1d6bd851fd6ba2aa6a35df08f1318298a51ed3..e977f19af6822d527e74cb638c4189414527a800 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -30,6 +30,7 @@ ifndef CONFIG_TPL_BUILD ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_BOOTCOUNT_LIMIT) += bootcount/ +obj-$(CONFIG_SPL_CACHE_SUPPORT) += cache/ obj-$(CONFIG_SPL_CPU_SUPPORT) += cpu/ obj-$(CONFIG_SPL_CRYPTO_SUPPORT) += crypto/ obj-$(CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/ diff --git a/include/configs/ax25-ae350.h b/include/configs/ax25-ae350.h index 5fd7a6043f516a8a0c9de00c146e08fb86cebb35..45049621710f05e14e27452e93d26da55b109db3 100644 --- a/include/configs/ax25-ae350.h +++ b/include/configs/ax25-ae350.h @@ -7,6 +7,23 @@ #ifndef __CONFIG_H #define __CONFIG_H +#ifdef CONFIG_SPL +#define CONFIG_SPL_MAX_SIZE 0x00100000 +#define CONFIG_SPL_BSS_START_ADDR 0x04000000 +#define CONFIG_SPL_BSS_MAX_SIZE 0x00100000 + +#ifndef CONFIG_XIP +#define CONFIG_SPL_LOAD_FIT_ADDRESS 0x00200000 +#else +#define CONFIG_SPL_LOAD_FIT_ADDRESS 0x80010000 +#endif + +#ifdef CONFIG_SPL_MMC_SUPPORT +#define CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 1 +#define CONFIG_SPL_FS_LOAD_PAYLOAD_NAME "u-boot.itb" +#endif +#endif + /* * CPU and Board Configuration Options */ diff --git a/include/opensbi.h b/include/opensbi.h index 9f1d62e7dde39e95044b125f2a68e9ece36a76e4..d812cc8ccd9413337821be5f9227d00aa943d4f0 100644 --- a/include/opensbi.h +++ b/include/opensbi.h @@ -11,7 +11,7 @@ #define FW_DYNAMIC_INFO_MAGIC_VALUE 0x4942534f /** Maximum supported info version */ -#define FW_DYNAMIC_INFO_VERSION 0x1 +#define FW_DYNAMIC_INFO_VERSION 0x2 /** Possible next mode values */ #define FW_DYNAMIC_INFO_NEXT_MODE_U 0x0 @@ -35,6 +35,22 @@ struct fw_dynamic_info { unsigned long next_mode; /** Options for OpenSBI library */ unsigned long options; + /** + * Preferred boot HART id + * + * It is possible that the previous booting stage uses same link + * address as the FW_DYNAMIC firmware. In this case, the relocation + * lottery mechanism can potentially overwrite the previous booting + * stage while other HARTs are still running in the previous booting + * stage leading to boot-time crash. To avoid this boot-time crash, + * the previous booting stage can specify last HART that will jump + * to the FW_DYNAMIC firmware as the preferred boot HART. + * + * To avoid specifying a preferred boot HART, the previous booting + * stage can set it to -1UL which will force the FW_DYNAMIC firmware + * to use the relocation lottery mechanism. + */ + unsigned long boot_hart; } __packed; #endif