diff options
Diffstat (limited to 'arch')
65 files changed, 842 insertions, 252 deletions
diff --git a/arch/arm/boards/ls1046ardb/lowlevel.c b/arch/arm/boards/ls1046ardb/lowlevel.c index 6de16063a7..0c95fbb035 100644 --- a/arch/arm/boards/ls1046ardb/lowlevel.c +++ b/arch/arm/boards/ls1046ardb/lowlevel.c @@ -3,6 +3,7 @@ #include <common.h> #include <debug_ll.h> #include <ddr_spd.h> +#include <image-metadata.h> #include <platform_data/mmc-esdhc-imx.h> #include <i2c/i2c-early.h> #include <soc/fsl/fsl_ddr_sdram.h> @@ -201,6 +202,8 @@ static noinline __noreturn void ls1046ardb_r_entry(unsigned long memsize) debug_ll_init(); ls1046a_init_lowlevel(); + IMD_USED_OF(fsl_ls1046a_rdb); + i2c = ls1046_i2c_init(IOMEM(LSCH2_I2C1_BASE_ADDR)); ret = spd_read_eeprom(i2c, i2c_fsl_xfer, 0x51, &spd_eeprom); if (ret) { diff --git a/arch/arm/boards/tqmls1046a/board.c b/arch/arm/boards/tqmls1046a/board.c index 5d6d5ad62c..8cc4d73de5 100644 --- a/arch/arm/boards/tqmls1046a/board.c +++ b/arch/arm/boards/tqmls1046a/board.c @@ -3,10 +3,15 @@ #include <common.h> #include <init.h> #include <envfs.h> +#include <bbu.h> +#include <bootsource.h> #include <asm/memory.h> #include <linux/sizes.h> #include <linux/clk.h> #include <linux/clkdev.h> +#include <soc/fsl/immap_lsch2.h> +#include <mach/bbu.h> +#include <mach/layerscape.h> static int tqmls1046a_mem_init(void) { @@ -21,11 +26,39 @@ mem_initcall(tqmls1046a_mem_init); static int tqmls1046a_postcore_init(void) { + struct ccsr_scfg *scfg = IOMEM(LSCH2_SCFG_ADDR); + enum bootsource bootsource; + unsigned long sd_bbu_flags = 0, qspi_bbu_flags = 0; + if (!of_machine_is_compatible("tqc,tqmls1046a")) return 0; defaultenv_append_directory(defaultenv_tqmls1046a); + /* Configure iomux for i2c4 */ + out_be32(&scfg->rcwpmuxcr0, 0x3300); + + /* divide CGA1/CGA2 PLL by 24 to get QSPI interface clock */ + out_be32(&scfg->qspi_cfg, 0x30100000); + + bootsource = ls1046_bootsource_get(); + + switch (bootsource) { + case BOOTSOURCE_MMC: + of_device_enable_path("/chosen/environment-sd"); + sd_bbu_flags = BBU_HANDLER_FLAG_DEFAULT; + break; + case BOOTSOURCE_SPI_NOR: + of_device_enable_path("/chosen/environment-qspi"); + qspi_bbu_flags = BBU_HANDLER_FLAG_DEFAULT; + break; + default: + break; + } + + ls1046a_bbu_mmc_register_handler("sd", "/dev/mmc0.barebox", sd_bbu_flags); + ls1046a_bbu_qspi_register_handler("qspi", "/dev/qspiflash0.barebox", qspi_bbu_flags); + return 0; } diff --git a/arch/arm/boards/tqmls1046a/lowlevel.c b/arch/arm/boards/tqmls1046a/lowlevel.c index 044d6a418d..dc0e179694 100644 --- a/arch/arm/boards/tqmls1046a/lowlevel.c +++ b/arch/arm/boards/tqmls1046a/lowlevel.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0+ #include <common.h> #include <debug_ll.h> +#include <image-metadata.h> #include <platform_data/mmc-esdhc-imx.h> #include <soc/fsl/fsl_ddr_sdram.h> #include <soc/fsl/immap_lsch2.h> @@ -116,7 +117,7 @@ found: DDR_CDR2_VREF_TRAIN_EN | DDR_CDR2_VREF_RANGE_2; /* optimize cpo for erratum A-009942 */ - popts->cpo_sample = 0x61; + popts->cpo_sample = 0x48; } static struct dimm_params dimm_params[] = { @@ -169,37 +170,97 @@ static struct fsl_ddr_controller ddrc[] = { .erratum_A009942 = 1, .chip_selects_per_ctrl = 4, .board_options = ddr_board_options, + .fsl_ddr_config_reg = { + .cs[0].bnds = 0x0000007F, + .cs[0].config = 0x80010312, + .cs[0].config_2 = 0x00000000, + .cs[1].bnds = 0x00000000, + .cs[1].config = 0x00000000, + .cs[1].config_2 = 0x00000000, + .cs[2].bnds = 0x00000000, + .cs[2].config = 0x00000000, + .cs[2].config_2 = 0x00000000, + .cs[3].bnds = 0x00000000, + .cs[3].config = 0x00000000, + .cs[3].config_2 = 0x00000000, + .timing_cfg_3 = 0x020F1100, + .timing_cfg_0 = 0x77660008, + .timing_cfg_1 = 0xF1FCC265, + .timing_cfg_2 = 0x0059415E, + .ddr_sdram_cfg = 0x65000000, + .ddr_sdram_cfg_2 = 0x00401150, + .ddr_sdram_cfg_3 = 0x00000000, + .ddr_sdram_mode = 0x03010625, + .ddr_sdram_mode_2 = 0x00100200, + .ddr_sdram_mode_3 = 0x00010625, + .ddr_sdram_mode_4 = 0x00100200, + .ddr_sdram_mode_5 = 0x00010625, + .ddr_sdram_mode_6 = 0x00100200, + .ddr_sdram_mode_7 = 0x00010625, + .ddr_sdram_mode_8 = 0x00100200, + .ddr_sdram_mode_9 = 0x00000500, + .ddr_sdram_mode_10 = 0x04400000, + .ddr_sdram_mode_11 = 0x00000400, + .ddr_sdram_mode_12 = 0x04400000, + .ddr_sdram_mode_13 = 0x00000400, + .ddr_sdram_mode_14 = 0x04400000, + .ddr_sdram_mode_15 = 0x00000400, + .ddr_sdram_mode_16 = 0x04400000, + .ddr_sdram_interval = 0x0F3C0000, + .ddr_data_init = 0xDEADBEEF, + .ddr_sdram_clk_cntl = 0x02000000, + .ddr_init_addr = 0x00000000, + .ddr_init_ext_addr = 0x00000000, + .timing_cfg_4 = 0x00224002, + .timing_cfg_5 = 0x04401400, + .timing_cfg_6 = 0x00000000, + .timing_cfg_7 = 0x25500000, + .timing_cfg_8 = 0x03335A00, + .timing_cfg_9 = 0x00000000, + .ddr_zq_cntl = 0x8A090705, + .ddr_wrlvl_cntl = 0x86550609, + .ddr_wrlvl_cntl_2 = 0x09080806, + .ddr_wrlvl_cntl_3 = 0x06040409, + .ddr_sr_cntr = 0x00000000, + .ddr_sdram_rcw_1 = 0x00000000, + .ddr_sdram_rcw_2 = 0x00000000, + .ddr_sdram_rcw_3 = 0x00000000, + .ddr_cdr1 = 0x80080000, + .ddr_cdr2 = 0x000000C0, + .dq_map_0 = 0x00000000, + .dq_map_1 = 0x00000000, + .dq_map_2 = 0x00000000, + .dq_map_3 = 0x00000000, + .debug[28] = 0x00700046, + }, }, }; -static struct fsl_ddr_info ls1046a_info = { - .num_ctrls = ARRAY_SIZE(ddrc), - .c = ddrc, -}; - extern char __dtb_fsl_tqmls1046a_mbls10xxa_start[]; -static noinline __noreturn void tqmls1046a_r_entry(unsigned long memsize) +static noinline __noreturn void tqmls1046a_r_entry(void) { unsigned long membase = LS1046A_DDR_SDRAM_BASE; - if (get_pc() >= membase) { - if (memsize + membase >= 0x100000000) - memsize = 0x100000000 - membase; - + if (get_pc() >= membase) barebox_arm_entry(membase, 0x80000000, __dtb_fsl_tqmls1046a_mbls10xxa_start); - } arm_cpu_lowlevel_init(); - debug_ll_init(); ls1046a_init_lowlevel(); - memsize = fsl_ddr_sdram(&ls1046a_info); + debug_ll_init(); + + udelay(500); + putc_ll('>'); + + IMD_USED_OF(fsl_tqmls1046a_mbls10xxa); + + fsl_ddr_set_memctl_regs(&ddrc[0], 0); ls1046a_errata_post_ddr(); - ls1046a_esdhc_start_image(memsize, 0, 0); + ls1046a_xload_start_image(0, 0, 0); pr_err("Booting failed\n"); @@ -213,5 +274,5 @@ __noreturn void tqmls1046a_entry(unsigned long r0, unsigned long r1, unsigned lo relocate_to_current_adr(); setup_c(); - tqmls1046a_r_entry(r0); + tqmls1046a_r_entry(); } diff --git a/arch/arm/boards/tqmls1046a/tqmls1046a_pbi_sd.cfg b/arch/arm/boards/tqmls1046a/tqmls1046a_pbi.cfg index 7ac1398123..0a04afa770 100644 --- a/arch/arm/boards/tqmls1046a/tqmls1046a_pbi_sd.cfg +++ b/arch/arm/boards/tqmls1046a/tqmls1046a_pbi.cfg @@ -1,3 +1,5 @@ +#Configure QSPI clock +0957015c 40100000 #Configure Scratch register 09570600 00000000 09570604 10000000 diff --git a/arch/arm/boards/tqmls1046a/tqmls1046a_pbi_qspi.cfg b/arch/arm/boards/tqmls1046a/tqmls1046a_pbi_qspi.cfg deleted file mode 100644 index 32865ca2d0..0000000000 --- a/arch/arm/boards/tqmls1046a/tqmls1046a_pbi_qspi.cfg +++ /dev/null @@ -1,33 +0,0 @@ -#Configure QSPI clock -0957015c 40100000 -#Configure Scratch register -09570600 00000000 -09570604 40010000 -#Disable CCI barrier tranaction -09570178 0000e010 -09180000 00000008 -#USB PHY frequency sel -09570418 0000009c -0957041c 0000009c -09570420 0000009c -#Serdes SATA -09eb1300 80104e20 -09eb08dc 00502880 -#PEX gen3 link (errata A-010477) -09570158 00000300 -89400890 01048000 -89500890 01048000 -89600890 01048000 -#PEX gen3 equalization preset values (errata A-008851) -894008bc 01000000 -89400154 47474747 -89400158 47474747 -894008bc 00000000 -895008bc 01000000 -89500154 47474747 -89500158 47474747 -895008bc 00000000 -896008bc 01000000 -89600154 47474747 -89600158 47474747 -896008bc 00000000 diff --git a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_emmc_3333_5559.cfg b/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_emmc_3333_5559.cfg deleted file mode 100644 index 6c72d001c3..0000000000 --- a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_emmc_3333_5559.cfg +++ /dev/null @@ -1,84 +0,0 @@ -# RCW values -# 0: 1 - SYS_PLL_CFG : 0 [0x0 / 0b00] -# 2: 6 - SYS_PLL_RAT : 6 [0x6 / 0b00110] -# 8: 9 - MEM_PLL_CFG : 0 [0x0 / 0b00] -# 10: 15 - MEM_PLL_RAT : 20 [0x14 / 0b010100] -# 24: 25 - CGA_PLL1_CFG : 0 [0x0 / 0b00] -# 26: 31 - CGA_PLL1_RAT : 16 [0x10 / 0b010000] -# 32: 33 - CGA_PLL2_CFG : 0 [0x0 / 0b00] -# 34: 39 - CGA_PLL2_RAT : 14 [0xe / 0b001110] -# 96: 99 - C1_PLL_SEL : 0 [0x0 / 0b0000] -# 128:143 - SRDS_PRTCL_S1 : 13107 [0x3333 / 0b0011001100110011] -# 144:159 - SRDS_PRTCL_S2 : 21849 [0x5559 / 0b0101010101011001] -# 160:161 - SRDS_PLL_REF_CLK_SEL_S1 : 3 [0x3 / 0b11] -# 162:163 - SRDS_PLL_REF_CLK_SEL_S2 : 3 [0x3 / 0b11] -# 168:169 - SRDS_PLL_PD_S1 : 0 [0x0 / 0b00] -# 170:171 - SRDS_PLL_PD_S2 : 0 [0x0 / 0b00] -# 176:177 - SRDS_DIV_PEX_S1 : 1 [0x1 / 0b01] -# 178:179 - SRDS_DIV_PEX_S2 : 1 [0x1 / 0b01] -# 186:187 - DDR_REFCLK_SEL : 0 [0x0 / 0b00] -# 188:188 - SRDS_REFCLK_SEL_S1 : 0 [0x0 / 0b0] -# 189:189 - SRDS_REFCLK_SEL_S2 : 0 [0x0 / 0b0] -# 190:191 - DDR_FDBK_MULT : 2 [0x2 / 0b10] -# 192:195 - PBI_SRC : 6 [0x6 / 0b0110] -# 201:201 - BOOT_HO : 0 [0x0 / 0b0] -# 202:202 - SB_EN : 0 [0x0 / 0b0] -# 203:211 - IFC_MODE : 64 [0x40 / 0b001000000] -# 224:226 - HWA_CGA_M1_CLK_SEL : 6 [0x6 / 0b110] -# 230:231 - DRAM_LAT : 1 [0x1 / 0b01] -# 232:232 - DDR_RATE : 0 [0x0 / 0b0] -# 234:234 - DDR_RSV0 : 0 [0x0 / 0b0] -# 242:242 - SYS_PLL_SPD : 0 [0x0 / 0b0] -# 243:243 - MEM_PLL_SPD : 0 [0x0 / 0b0] -# 244:244 - CGA_PLL1_SPD : 0 [0x0 / 0b0] -# 245:245 - CGA_PLL2_SPD : 0 [0x0 / 0b0] -# 264:266 - HOST_AGT_PEX : 0 [0x0 / 0b000] -# 288:295 - GP_INFO1 : 0 [0x00 / 0b00000000] -# 299:319 - GP_INFO2 : 0 [0x00000 / 0b000000000000000000000] -# 354:356 - UART_EXT : 0 [0x0 / 0b000] -# 357:359 - IRQ_EXT : 0 [0x0 / 0b000] -# 360:362 - SPI_EXT : 0 [0x0 / 0b000] -# 363:365 - SDHC_EXT : 0 [0x0 / 0b000] -# 366:368 - UART_BASE : 5 [0x5 / 0b101] -# 369:369 - ASLEEP : 0 [0x0 / 0b0] -# 370:370 - RTC : 0 [0x0 / 0b0] -# 371:371 - SDHC_BASE : 0 [0x0 / 0b0] -# 372:372 - IRQ_OUT : 1 [0x1 / 0b1] -# 373:381 - IRQ_BASE : 0 [0x00 / 0b000000000] -# 382:383 - SPI_BASE : 0 [0x0 / 0b00] -# 384:386 - IFC_GRP_A_EXT : 1 [0x1 / 0b001] -# 393:395 - IFC_GRP_D_EXT : 0 [0x0 / 0b000] -# 396:398 - IFC_GRP_E1_EXT : 0 [0x0 / 0b000] -# 399:401 - IFC_GRP_F_EXT : 1 [0x1 / 0b001] -# 405:405 - IFC_GRP_E1_BASE : 0 [0x0 / 0b0] -# 407:407 - IFC_GRP_D_BASE : 0 [0x0 / 0b0] -# 412:413 - IFC_GRP_A_BASE : 0 [0x0 / 0b00] -# 415:415 - IFC_A_22_24 : 0 [0x0 / 0b0] -# 416:418 - EC1 : 0 [0x0 / 0b000] -# 419:421 - EC2 : 0 [0x0 / 0b000] -# 422:423 - LVDD_VSEL : 1 [0x1 / 0b01] -# 424:424 - I2C_IPGCLK_SEL : 0 [0x0 / 0b0] -# 425:425 - EM1 : 0 [0x0 / 0b0] -# 426:426 - EM2 : 0 [0x0 / 0b0] -# 427:427 - EMI2_DMODE : 1 [0x1 / 0b1] -# 428:428 - EMI2_CMODE : 0 [0x0 / 0b0] -# 429:429 - USB_DRVVBUS : 0 [0x0 / 0b0] -# 430:430 - USB_PWRFAULT : 0 [0x0 / 0b0] -# 433:434 - TVDD_VSEL : 1 [0x1 / 0b01] -# 435:436 - DVDD_VSEL : 2 [0x2 / 0b10] -# 438:438 - EMI1_DMODE : 1 [0x1 / 0b1] -# 439:440 - EVDD_VSEL : 0 [0x0 / 0b00] -# 441:443 - IIC2_BASE : 0 [0x0 / 0b000] -# 444:444 - EMI1_CMODE : 0 [0x0 / 0b0] -# 445:447 - IIC2_EXT : 2 [0x2 / 0b010] -# 472:481 - SYSCLK_FREQ : 600 [0x258 / 0b1001011000] -# 509:511 - HWA_CGA_M2_CLK_SEL : 1 [0x1 / 0b001] - - -#PBL preamble and RCW header -aa55aa55 01ee0100 -# RCW -0c140010 0e000000 00000000 00000000 -33335559 f0005002 60040000 c1000000 -00000000 00000000 00000000 00028800 -20004000 01103202 00000096 00000001 diff --git a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_qspi_3333_5559.cfg b/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_qspi_3333_5559.cfg index 395c75c7d0..2df229c56c 100644 --- a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_qspi_3333_5559.cfg +++ b/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_qspi_3333_5559.cfg @@ -8,7 +8,7 @@ # 32: 33 - CGA_PLL2_CFG : 0 [0x0 / 0b00] # 34: 39 - CGA_PLL2_RAT : 14 [0xe / 0b001110] # 96: 99 - C1_PLL_SEL : 0 [0x0 / 0b0000] -# 128:143 - SRDS_PRTCL_S1 : 13107 [0x3333 / 0b0011001100110011] +# 128:143 - SRDS_PRTCL_S1 : 4403 [0x1133 / 0b0001000100110011] # 144:159 - SRDS_PRTCL_S2 : 21849 [0x5559 / 0b0101010101011001] # 160:161 - SRDS_PLL_REF_CLK_SEL_S1 : 3 [0x3 / 0b11] # 162:163 - SRDS_PLL_REF_CLK_SEL_S2 : 3 [0x3 / 0b11] @@ -39,7 +39,7 @@ # 357:359 - IRQ_EXT : 0 [0x0 / 0b000] # 360:362 - SPI_EXT : 0 [0x0 / 0b000] # 363:365 - SDHC_EXT : 0 [0x0 / 0b000] -# 366:368 - UART_BASE : 5 [0x5 / 0b101] +# 366:368 - UART_BASE : 6 [0x6 / 0b110] # 369:369 - ASLEEP : 0 [0x0 / 0b0] # 370:370 - RTC : 0 [0x0 / 0b0] # 371:371 - SDHC_BASE : 0 [0x0 / 0b0] @@ -79,6 +79,6 @@ aa55aa55 01ee0100 # RCW 0c140010 0e000000 00000000 00000000 -33335559 f0005002 40025000 c1000000 -00000000 00000000 00000000 00028800 +11335559 f0005002 40025000 c1000000 +00000000 00000000 00000000 00030800 20004000 01103202 00000096 00000001 diff --git a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_sd_3333_5559.cfg b/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_sd_3333_5559.cfg index 4ef6d576ed..72ab1cd7d7 100644 --- a/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_sd_3333_5559.cfg +++ b/arch/arm/boards/tqmls1046a/tqmls1046a_rcw_sd_3333_5559.cfg @@ -8,7 +8,7 @@ # 32: 33 - CGA_PLL2_CFG : 0 [0x0 / 0b00] # 34: 39 - CGA_PLL2_RAT : 14 [0xe / 0b001110] # 96: 99 - C1_PLL_SEL : 0 [0x0 / 0b0000] -# 128:143 - SRDS_PRTCL_S1 : 13107 [0x3333 / 0b0011001100110011] +# 128:143 - SRDS_PRTCL_S1 : 4403 [0x1133 / 0b0001000100110011] # 144:159 - SRDS_PRTCL_S2 : 21849 [0x5559 / 0b0101010101011001] # 160:161 - SRDS_PLL_REF_CLK_SEL_S1 : 3 [0x3 / 0b11] # 162:163 - SRDS_PLL_REF_CLK_SEL_S2 : 3 [0x3 / 0b11] @@ -39,7 +39,7 @@ # 357:359 - IRQ_EXT : 0 [0x0 / 0b000] # 360:362 - SPI_EXT : 0 [0x0 / 0b000] # 363:365 - SDHC_EXT : 0 [0x0 / 0b000] -# 366:368 - UART_BASE : 5 [0x5 / 0b101] +# 366:368 - UART_BASE : 6 [0x6 / 0b110] # 369:369 - ASLEEP : 0 [0x0 / 0b0] # 370:370 - RTC : 0 [0x0 / 0b0] # 371:371 - SDHC_BASE : 0 [0x0 / 0b0] @@ -67,10 +67,10 @@ # 433:434 - TVDD_VSEL : 1 [0x1 / 0b01] # 435:436 - DVDD_VSEL : 2 [0x2 / 0b10] # 438:438 - EMI1_DMODE : 1 [0x1 / 0b1] -# 439:440 - EVDD_VSEL : 2 [0x2 / 0b10] +# 439:440 - EVDD_VSEL : 0 [0x0 / 0b00] # 441:443 - IIC2_BASE : 0 [0x0 / 0b000] # 444:444 - EMI1_CMODE : 0 [0x0 / 0b0] -# 445:447 - IIC2_EXT : 1 [0x1 / 0b001] +# 445:447 - IIC2_EXT : 2 [0x2 / 0b010] # 472:481 - SYSCLK_FREQ : 600 [0x258 / 0b1001011000] # 509:511 - HWA_CGA_M2_CLK_SEL : 1 [0x1 / 0b001] @@ -79,6 +79,6 @@ aa55aa55 01ee0100 # RCW 0c140010 0e000000 00000000 00000000 -33335559 f0005002 60040000 c1000000 -00000000 00000000 00000000 00028800 -20004000 01103301 00000096 00000001 +11335559 f0005002 60040000 c1000000 +00000000 00000000 00000000 00030800 +20004000 01103202 00000096 00000001 diff --git a/arch/arm/boards/zii-imx51-rdu1/Makefile b/arch/arm/boards/zii-imx51-rdu1/Makefile index 01c7a259e9..604b3621be 100644 --- a/arch/arm/boards/zii-imx51-rdu1/Makefile +++ b/arch/arm/boards/zii-imx51-rdu1/Makefile @@ -1,2 +1,3 @@ obj-y += board.o +CFLAGS_pbl-lowlevel.o := -fno-tree-switch-conversion -fno-jump-tables lwl-y += lowlevel.o diff --git a/arch/arm/boards/zii-imx51-rdu1/lowlevel.c b/arch/arm/boards/zii-imx51-rdu1/lowlevel.c index 849c5624c5..da05b0564c 100644 --- a/arch/arm/boards/zii-imx51-rdu1/lowlevel.c +++ b/arch/arm/boards/zii-imx51-rdu1/lowlevel.c @@ -84,13 +84,6 @@ ENTRY_FUNCTION(start_imx51_zii_rdu1, r0, r1, r2) switch (system_type) { default: - /* - * see similar code in - * arch/arm/boards/zii-vf610-dev/lowlevel.c for - * reasoning for placing barrier() below. - */ - barrier(); - if (IS_ENABLED(CONFIG_DEBUG_LL)) { relocate_to_current_adr(); setup_c(); diff --git a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c index 0fd2ddfca5..33c007e05d 100644 --- a/arch/arm/boards/zii-imx8mq-dev/lowlevel.c +++ b/arch/arm/boards/zii-imx8mq-dev/lowlevel.c @@ -179,13 +179,6 @@ ENTRY_FUNCTION(start_zii_imx8mq_dev, r0, r1, r2) switch (system_type) { default: - /* - * see similar code in - * arch/arm/boards/zii-vf610-dev/lowlevel.c for - * reasoning for placing barrier() below. - */ - barrier(); - if (IS_ENABLED(CONFIG_DEBUG_LL)) { relocate_to_current_adr(); setup_c(); diff --git a/arch/arm/boards/zii-vf610-dev/Makefile b/arch/arm/boards/zii-vf610-dev/Makefile index 1297d815e3..3c3a3f2387 100644 --- a/arch/arm/boards/zii-vf610-dev/Makefile +++ b/arch/arm/boards/zii-vf610-dev/Makefile @@ -1,3 +1,4 @@ obj-y += board.o +CFLAGS_pbl-lowlevel.o := -fno-tree-switch-conversion -fno-jump-tables lwl-y += lowlevel.o bbenv-y += defaultenv-zii-vf610-dev diff --git a/arch/arm/boards/zii-vf610-dev/board.c b/arch/arm/boards/zii-vf610-dev/board.c index 1296f70317..90d4535684 100644 --- a/arch/arm/boards/zii-vf610-dev/board.c +++ b/arch/arm/boards/zii-vf610-dev/board.c @@ -122,6 +122,7 @@ static int zii_vf610_dev_set_hostname(void) const char *compatible; const char *hostname; } boards[] = { + { "zii,vf610dtu", "dtu" }, { "zii,vf610spu3", "spu3" }, { "zii,vf610spb4", "spb4" }, { "zii,vf610cfu1", "cfu1" }, @@ -170,7 +171,8 @@ static int zii_vf610_register_emmc_bbu(void) if (!of_machine_is_compatible("zii,vf610spu3") && !of_machine_is_compatible("zii,vf610cfu1") && - !of_machine_is_compatible("zii,vf610spb4")) + !of_machine_is_compatible("zii,vf610spb4") && + !of_machine_is_compatible("zii,vf610dtu")) return 0; ret = vf610_bbu_internal_mmcboot_register_handler("eMMC", diff --git a/arch/arm/boards/zii-vf610-dev/lowlevel.c b/arch/arm/boards/zii-vf610-dev/lowlevel.c index 79588ac381..b320fbc0cf 100644 --- a/arch/arm/boards/zii-vf610-dev/lowlevel.c +++ b/arch/arm/boards/zii-vf610-dev/lowlevel.c @@ -42,6 +42,7 @@ enum zii_platform_vf610_type { ZII_PLATFORM_VF610_CFU1 = 0x04, ZII_PLATFORM_VF610_DEV_REV_C = 0x05, ZII_PLATFORM_VF610_SPB4 = 0x06, + ZII_PLATFORM_VF610_SSMB_DTU = 0x07, }; static unsigned int get_system_type(void) @@ -79,6 +80,7 @@ extern char __dtb_vf610_zii_dev_rev_c_start[]; extern char __dtb_vf610_zii_cfu1_start[]; extern char __dtb_vf610_zii_ssmb_spu3_start[]; extern char __dtb_vf610_zii_scu4_aib_start[]; +extern char __dtb_vf610_zii_ssmb_dtu_start[]; extern char __dtb_vf610_zii_spb4_start[]; ENTRY_FUNCTION(start_zii_vf610_dev, r0, r1, r2) @@ -93,23 +95,6 @@ ENTRY_FUNCTION(start_zii_vf610_dev, r0, r1, r2) switch (system_type) { default: - /* - * GCC can be smart enough to, when DEBUG_LL is - * disabled, reduce this switch statement to a LUT - * fetch. Unfortunately here, this early in the boot - * process before any relocation/address fixups could - * happen, the address of that LUT used by the code is - * incorrect and any access to it would result in - * bogus values. - * - * Adding the following barrier() statement seem to - * force the compiler to always translate this block - * to a sequence of consecutive checks and jumps with - * relative fetches, which should work with or without - * relocation/fixups. - */ - barrier(); - if (IS_ENABLED(CONFIG_DEBUG_LL)) { relocate_to_current_adr(); setup_c(); @@ -137,6 +122,9 @@ ENTRY_FUNCTION(start_zii_vf610_dev, r0, r1, r2) case ZII_PLATFORM_VF610_SPB4: fdt = __dtb_vf610_zii_spb4_start; break; + case ZII_PLATFORM_VF610_SSMB_DTU: + fdt = __dtb_vf610_zii_ssmb_dtu_start; + break; } vf610_barebox_entry(fdt + get_runtime_offset()); diff --git a/arch/arm/configs/layerscape_defconfig b/arch/arm/configs/layerscape_defconfig index dadbcc214c..b81f375415 100644 --- a/arch/arm/configs/layerscape_defconfig +++ b/arch/arm/configs/layerscape_defconfig @@ -22,7 +22,6 @@ CONFIG_PBL_CONSOLE=y CONFIG_PARTITION_DISK_EFI=y CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y CONFIG_RESET_SOURCE=y -CONFIG_DEBUG_LL=y CONFIG_CMD_DMESG=y CONFIG_LONGHELP=y CONFIG_CMD_IOMEM=y @@ -85,8 +84,13 @@ CONFIG_DRIVER_NET_FSL_FMAN=y CONFIG_DP83867_PHY=y CONFIG_REALTEK_PHY=y CONFIG_NET_DSA_MV88E6XXX=y +CONFIG_DRIVER_SPI_FSL_QUADSPI=y CONFIG_I2C=y CONFIG_I2C_IMX=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_MTD=y +CONFIG_MTD_M25P80=y CONFIG_MCI=y CONFIG_MCI_MMC_BOOT_PARTITIONS=y CONFIG_MCI_IMX_ESDHC=y @@ -94,10 +98,12 @@ CONFIG_LED=y CONFIG_LED_GPIO=y CONFIG_LED_GPIO_OF=y CONFIG_LED_TRIGGERS=y +CONFIG_LED_PCA955X=y CONFIG_EEPROM_AT25=y CONFIG_EEPROM_AT24=y CONFIG_WATCHDOG=y CONFIG_WATCHDOG_IMX=y +CONFIG_GPIO_PCA953X=y CONFIG_NVMEM=y CONFIG_REGULATOR=y CONFIG_REGULATOR_FIXED=y diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig index 2577103293..f8abbccfca 100644 --- a/arch/arm/cpu/Kconfig +++ b/arch/arm/cpu/Kconfig @@ -86,6 +86,7 @@ config CPU_V8 select CPU_64v8 select CPU_SUPPORTS_64BIT_KERNEL select ARM_EXCEPTIONS + select GENERIC_FIND_NEXT_BIT config CPU_XSC3 bool diff --git a/arch/arm/cpu/cache-armv7.S b/arch/arm/cpu/cache-armv7.S index 7a1c5c0189..6a8aff8bb1 100644 --- a/arch/arm/cpu/cache-armv7.S +++ b/arch/arm/cpu/cache-armv7.S @@ -83,7 +83,10 @@ hierarchical: ands r3, r0, #0x7000000 @ extract loc from clidr mov r3, r3, lsr #23 @ left align loc bit field beq finished @ if loc is 0, then no need to clean - mov r12, #0 @ start clean at cache level 0 + cmp r8, #0 +THUMB( ite eq ) + moveq r12, #0 + subne r12, r3, #2 @ start invalidate at outmost cache level loop1: add r2, r12, r12, lsr #1 @ work out 3x current cache level mov r1, r0, lsr r2 @ extract cache type bits from clidr @@ -118,8 +121,16 @@ THUMB( ite eq ) subs r7, r7, #1 @ decrement the index bge loop2 skip: + cmp r8, #0 + bne inval_check add r12, r12, #2 @ increment cache number cmp r3, r12 + b loop_end_check +inval_check: + cmp r12, #0 + sub r12, r12, #2 @ decrement cache number +loop_end_check: + dsb @ work-around Cortex-A7 erratum 814220 bgt loop1 finished: ldmfd sp!, {r4-r11} diff --git a/arch/arm/cpu/lowlevel_64.S b/arch/arm/cpu/lowlevel_64.S index af1cd8b5bc..6a23132ed1 100644 --- a/arch/arm/cpu/lowlevel_64.S +++ b/arch/arm/cpu/lowlevel_64.S @@ -12,6 +12,13 @@ ENTRY(arm_cpu_lowlevel_init) orr x0, x0, #(1 << 10) /* 64-bit EL2 */ msr scr_el3, x0 msr cptr_el3, xzr + + mrs x0, sctlr_el3 + ldr x1, =SCTLR_ELx_FLAGS + bic x0, x0, x1 + msr sctlr_el3, x0 + isb + b done 2: diff --git a/arch/arm/cpu/mmu-early.c b/arch/arm/cpu/mmu-early.c index d39a03ed95..2f5876fc46 100644 --- a/arch/arm/cpu/mmu-early.c +++ b/arch/arm/cpu/mmu-early.c @@ -5,17 +5,20 @@ #include <asm/memory.h> #include <asm/system.h> #include <asm/cache.h> +#include <asm-generic/sections.h> #include "mmu.h" static uint32_t *ttb; -static void map_cachable(unsigned long start, unsigned long size) +static inline void map_region(unsigned long start, unsigned long size, + uint64_t flags) + { start = ALIGN_DOWN(start, SZ_1M); size = ALIGN(size, SZ_1M); - create_sections(ttb, start, start + size - 1, PMD_SECT_DEF_CACHED); + create_sections(ttb, start, start + size - 1, flags); } void mmu_early_enable(unsigned long membase, unsigned long memsize, @@ -28,9 +31,27 @@ void mmu_early_enable(unsigned long membase, unsigned long memsize, set_ttbr(ttb); set_domain(DOMAIN_MANAGER); + /* + * This marks the whole address space as uncachable as well as + * unexecutable if possible + */ create_flat_mapping(ttb); - map_cachable(membase, memsize); + /* + * There can be SoCs that have a section shared between device memory + * and the on-chip RAM hosting the PBL. Thus mark this section + * uncachable, but executable. + * On such SoCs, executing from OCRAM could cause the instruction + * prefetcher to speculatively access that device memory, triggering + * potential errant behavior. + * + * If your SoC has such a memory layout, you should rewrite the code + * here to map the OCRAM page-wise. + */ + map_region((unsigned long)_stext, _etext - _stext, PMD_SECT_DEF_UNCACHED); + + /* maps main memory as cachable */ + map_region(membase, memsize, PMD_SECT_DEF_CACHED); __mmu_cache_on(); } diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 29816ad563..123e19e9e5 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -34,7 +34,6 @@ #include "mmu.h" -#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED) #define PTRS_PER_PTE (PGDIR_SIZE / PAGE_SIZE) #define ARCH_MAP_WRITECOMBINE ((unsigned)-1) @@ -58,11 +57,13 @@ static inline void tlb_invalidate(void) } #define PTE_FLAGS_CACHED_V7 (PTE_EXT_TEX(1) | PTE_BUFFERABLE | PTE_CACHEABLE) -#define PTE_FLAGS_WC_V7 PTE_EXT_TEX(1) -#define PTE_FLAGS_UNCACHED_V7 (0) +#define PTE_FLAGS_WC_V7 (PTE_EXT_TEX(1) | PTE_EXT_XN) +#define PTE_FLAGS_UNCACHED_V7 PTE_EXT_XN #define PTE_FLAGS_CACHED_V4 (PTE_SMALL_AP_UNO_SRW | PTE_BUFFERABLE | PTE_CACHEABLE) #define PTE_FLAGS_UNCACHED_V4 PTE_SMALL_AP_UNO_SRW -#define PGD_FLAGS_WC_V7 (PMD_SECT_TEX(1) | PMD_TYPE_SECT | PMD_SECT_BUFFERABLE) +#define PGD_FLAGS_WC_V7 (PMD_SECT_TEX(1) | PMD_TYPE_SECT | PMD_SECT_BUFFERABLE | \ + PMD_SECT_XN) +#define PGD_FLAGS_UNCACHED_V7 (PMD_SECT_DEF_UNCACHED | PMD_SECT_XN) /* * PTE flags to set cached and uncached areas. @@ -72,6 +73,7 @@ static uint32_t pte_flags_cached; static uint32_t pte_flags_wc; static uint32_t pte_flags_uncached; static uint32_t pgd_flags_wc; +static uint32_t pgd_flags_uncached; #define PTE_MASK ((1 << 12) - 1) @@ -164,7 +166,7 @@ int arch_remap_range(void *start, size_t size, unsigned flags) break; case MAP_UNCACHED: pte_flags = pte_flags_uncached; - pgd_flags = PMD_SECT_DEF_UNCACHED; + pgd_flags = pgd_flags_uncached; break; case ARCH_MAP_WRITECOMBINE: pte_flags = pte_flags_wc; @@ -247,7 +249,7 @@ void *map_io_sections(unsigned long phys, void *_start, size_t size) unsigned long start = (unsigned long)_start, sec; for (sec = start; sec < start + size; sec += PGDIR_SIZE, phys += PGDIR_SIZE) - ttb[pgd_index(sec)] = phys | PMD_SECT_DEF_UNCACHED; + ttb[pgd_index(sec)] = phys | pgd_flags_uncached; dma_flush_range(ttb, 0x4000); tlb_invalidate(); @@ -411,11 +413,13 @@ void __mmu_init(bool mmu_on) pte_flags_cached = PTE_FLAGS_CACHED_V7; pte_flags_wc = PTE_FLAGS_WC_V7; pgd_flags_wc = PGD_FLAGS_WC_V7; + pgd_flags_uncached = PGD_FLAGS_UNCACHED_V7; pte_flags_uncached = PTE_FLAGS_UNCACHED_V7; } else { pte_flags_cached = PTE_FLAGS_CACHED_V4; pte_flags_wc = PTE_FLAGS_UNCACHED_V4; pgd_flags_wc = PMD_SECT_DEF_UNCACHED; + pgd_flags_uncached = PMD_SECT_DEF_UNCACHED; pte_flags_uncached = PTE_FLAGS_UNCACHED_V4; } diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h index 338728aacd..c911ee209f 100644 --- a/arch/arm/cpu/mmu.h +++ b/arch/arm/cpu/mmu.h @@ -3,6 +3,7 @@ #include <asm/pgtable.h> #include <linux/sizes.h> +#include <asm/system_info.h> #include "mmu-common.h" @@ -62,8 +63,13 @@ create_sections(uint32_t *ttb, unsigned long first, static inline void create_flat_mapping(uint32_t *ttb) { + unsigned int flags = PMD_SECT_DEF_UNCACHED; + + if (cpu_architecture() >= CPU_ARCH_ARMv7) + flags |= PMD_SECT_XN; + /* create a flat mapping using 1MiB sections */ - create_sections(ttb, 0, 0xffffffff, PMD_SECT_DEF_UNCACHED); + create_sections(ttb, 0, 0xffffffff, flags); } #endif /* __ARM_MMU_H */ diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1c6129816d..be3edbb0cc 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -125,7 +125,8 @@ pbl-dtb-$(CONFIG_MACH_ZII_VF610_DEV) += \ vf610-zii-cfu1.dtb.o \ vf610-zii-ssmb-spu3.dtb.o \ vf610-zii-scu4-aib.dtb.o \ - vf610-zii-spb4.dtb.o + vf610-zii-spb4.dtb.o \ + vf610-zii-ssmb-dtu.dtb.o pbl-dtb-$(CONFIG_MACH_AT91SAM9263EK_DT) += at91sam9263ek.dtb.o pbl-dtb-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += at91-microchip-ksz9477-evb.dtb.o pbl-dtb-$(CONFIG_MACH_AT91SAM9X5EK) += at91sam9x5ek.dtb.o diff --git a/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts b/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts index f21479eef8..f0332e3999 100644 --- a/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts +++ b/arch/arm/dts/fsl-tqmls1046a-mbls10xxa.dts @@ -20,10 +20,30 @@ serial0 = &duart0; serial1 = &duart1; mmc0 = &esdhc; + qspiflash0 = &qflash0; + qspiflash1 = &qflash1; + qsgmii_s1_p1 = &qsgmii1_phy1; + qsgmii_s1_p2 = &qsgmii1_phy2; + qsgmii_s2_p1 = &qsgmii2_phy1; + qsgmii_s2_p2 = &qsgmii2_phy2; + qsgmii_s2_p3 = &qsgmii2_phy3; + qsgmii_s2_p4 = &qsgmii2_phy4; }; chosen { stdout-path = "serial1:115200n8"; + + environment-sd { + compatible = "barebox,environment"; + device-path = &environment_sd; + status = "disabled"; + }; + + environment-qspi { + compatible = "barebox,environment"; + device-path = &environment_qspi; + status = "disabled"; + }; }; gpio-keys-polled { @@ -57,6 +77,24 @@ }; +&esdhc { + partitions { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "fixed-partitions"; + + partition@0 { + label = "barebox"; + reg = <0x1000 0xdf000>; + }; + + environment_sd: partition@e0000 { + label = "barebox-environment"; + reg = <0xe0000 0x20000>; + }; + }; +}; &duart0 { status = "okay"; @@ -66,6 +104,14 @@ status = "okay"; }; +&esdhc { + mmc-hs200-1_8v; + sd-uhs-sdr104; + sd-uhs-sdr50; + sd-uhs-sdr25; + sd-uhs-sdr12; +}; + &i2c3 { status = "okay"; @@ -132,43 +178,40 @@ &fman0 { status = "okay"; - ethernet@e0000 { - status = "disabled"; + ethernet@e0000 { /* EMAC.1 */ + phy-connection-type = "sgmii"; + }; - ethernet@e2000 { - phy-handle = <&qsgmii1_phy2>; + ethernet@e2000 { /* EMAC.2 */ phy-connection-type = "sgmii"; }; - ethernet@e4000 { + ethernet@e4000 { /* EMAC.3 */ phy-handle = <&rgmii_phy1>; phy-connection-type = "rgmii"; phy-mode = "rgmii-id"; }; - ethernet@e6000 { + ethernet@e6000 { /* EMAC.4 */ phy-handle = <&rgmii_phy2>; phy-connection-type = "rgmii"; phy-mode = "rgmii-id"; }; - ethernet@e8000 { - status = "disabled"; + ethernet@e8000 { /* EMAC.5 */ + phy-connection-type = "sgmii"; }; - ethernet@ea000 { - phy-handle = <&qsgmii2_phy2>; + ethernet@ea000 { /* EMAC.6 */ phy-connection-type = "sgmii"; }; - ethernet@f0000 { - phy-handle = <&qsgmii1_phy1>; + ethernet@f0000 { /* EMAC.9 */ phy-connection-type = "sgmii"; }; - ethernet@f2000 { - phy-handle = <&qsgmii2_phy1>; + ethernet@f2000 { /* EMAC.10 */ phy-connection-type = "sgmii"; }; @@ -212,6 +255,13 @@ ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>; }; + rgmii_phy2: ethernet-phy@0c { + reg = <0x0c>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>; + ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>; + }; + qsgmii1_phy1: ethernet-phy@1c { reg = <0x1c>; }; @@ -219,15 +269,6 @@ qsgmii1_phy2: ethernet-phy@1d { reg = <0x1d>; }; - }; - - mdio@fd000 { - rgmii_phy2: ethernet-phy@0c { - reg = <0x0c>; - ti,rx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>; - ti,tx-internal-delay = <DP83867_RGMIIDCTL_1_50_NS>; - ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>; - }; qsgmii2_phy1: ethernet-phy@00 { reg = <0x00>; @@ -236,5 +277,41 @@ qsgmii2_phy2: ethernet-phy@01 { reg = <0x01>; }; + + qsgmii2_phy3: ethernet-phy@02 { + reg = <0x02>; + }; + + qsgmii2_phy4: ethernet-phy@03 { + reg = <0x03>; + }; + }; + + mdio@fd000 { + status = "disabled"; + }; +}; + +&qflash0 { + partitions { + #address-cells = <1>; + #size-cells = <1>; + + compatible = "fixed-partitions"; + + partition@0 { + label = "barebox"; + reg = <0x0 0x200000>; + }; + + environment_qspi: partition@200000 { + label = "barebox-environment"; + reg = <0x200000 0x80000>; + }; + + partition@280000 { + label = "data"; + reg = <0x280000 0x0>; + }; }; }; diff --git a/arch/arm/dts/fsl-tqmls1046a.dtsi b/arch/arm/dts/fsl-tqmls1046a.dtsi index 4717e66857..0ea2612cbf 100644 --- a/arch/arm/dts/fsl-tqmls1046a.dtsi +++ b/arch/arm/dts/fsl-tqmls1046a.dtsi @@ -40,15 +40,15 @@ #address-cells = <1>; #size-cells = <1>; compatible = "jedec,spi-nor"; - spi-max-frequency = <108000000>; + spi-max-frequency = <62500000>; reg = <0>; }; qflash1: mx66u51235f@1 { #address-cells = <1>; #size-cells = <1>; - spi-max-frequency = <108000000>; compatible = "jedec,spi-nor"; + spi-max-frequency = <62500000>; reg = <1>; }; }; diff --git a/arch/arm/dts/imx8mq.dtsi b/arch/arm/dts/imx8mq.dtsi index d1d8bdaa0e..1d59615238 100644 --- a/arch/arm/dts/imx8mq.dtsi +++ b/arch/arm/dts/imx8mq.dtsi @@ -198,3 +198,7 @@ <25000000>, <125000000>; }; + +&pgc_pcie1 { + power-domains = <&pgc_pcie2>; +}; diff --git a/arch/arm/dts/vf610-zii-ssmb-dtu.dts b/arch/arm/dts/vf610-zii-ssmb-dtu.dts new file mode 100644 index 0000000000..6ffb7aa62d --- /dev/null +++ b/arch/arm/dts/vf610-zii-ssmb-dtu.dts @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) + +#include <arm/vf610-zii-ssmb-dtu.dts> + +#include "vf610-zii-dev.dtsi" + +/ { + aliases { + /* + * NVMEM device corresponding to EEPROM attached to + * the switch shared DT node with it, so we use that + * fact to create a desirable naming + */ + switch-eeprom = &switch0; + }; +};
\ No newline at end of file diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index 348a76b2c1..d8a4d9b667 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -82,6 +82,12 @@ static inline int test_bit(int nr, const void * addr) #define test_and_clear_bit(x, y) __test_and_clear_bit(x, y) #define test_and_change_bit(x, y) __test_and_change_bit(x, y) +#ifdef CONFIG_CPU_V8 + +#include <asm-generic/bitops/find.h> + +#else /* CONFIG_CPU_V8 */ + #ifndef __ARMEB__ /* * These are the little endian definitions. @@ -115,6 +121,8 @@ extern int _find_next_bit_be(const unsigned long *p, int size, int offset); #endif /* __ARMEB__ */ +#endif /* CONFIG_CPU_V8 */ + #if defined (CONFIG_CPU_32) && defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ >= 5) static inline int constant_fls(int x) { diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index ef9cb98bf0..a0180f2df8 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -1,6 +1,26 @@ #ifndef __ASM_ARM_SYSTEM_H #define __ASM_ARM_SYSTEM_H +#include <linux/const.h> + +/* Common SCTLR_ELx flags. */ +#define SCTLR_ELx_DSSBS (_BITUL(44)) +#define SCTLR_ELx_ENIA (_BITUL(31)) +#define SCTLR_ELx_ENIB (_BITUL(30)) +#define SCTLR_ELx_ENDA (_BITUL(27)) +#define SCTLR_ELx_EE (_BITUL(25)) +#define SCTLR_ELx_IESB (_BITUL(21)) +#define SCTLR_ELx_WXN (_BITUL(19)) +#define SCTLR_ELx_ENDB (_BITUL(13)) +#define SCTLR_ELx_I (_BITUL(12)) +#define SCTLR_ELx_SA (_BITUL(3)) +#define SCTLR_ELx_C (_BITUL(2)) +#define SCTLR_ELx_A (_BITUL(1)) +#define SCTLR_ELx_M (_BITUL(0)) + +#define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \ + SCTLR_ELx_SA | SCTLR_ELx_I | SCTLR_ELx_IESB) + #if __LINUX_ARM_ARCH__ >= 7 #define isb() __asm__ __volatile__ ("isb" : : : "memory") #ifdef CONFIG_CPU_64v8 diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index c4e7500e8f..71d37cee90 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -454,6 +454,7 @@ config MACH_ZII_IMX8MQ_DEV select FIRMWARE_IMX8MQ_ATF select ARM_SMCCC select MCI_IMX_ESDHC_PBL + select MACH_ZII_COMMON config MACH_ZII_VF610_DEV bool "ZII VF610 Dev Family" diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c index 01b4274ed3..e898be9ab5 100644 --- a/arch/arm/mach-imx/imx6.c +++ b/arch/arm/mach-imx/imx6.c @@ -117,7 +117,7 @@ static void imx6_setup_ipu_qos(void) uint32_t val; if (!cpu_mx6_is_mx6q() && !cpu_mx6_is_mx6d() && - !cpu_mx6_is_mx6dl() && cpu_mx6_is_mx6s()) + !cpu_mx6_is_mx6dl() && !cpu_mx6_is_mx6s()) return; val = readl(iomux + IOMUXC_GPR4); diff --git a/arch/arm/mach-imx/include/mach/imx25-regs.h b/arch/arm/mach-imx/include/mach/imx25-regs.h index 71812764c9..5974897a16 100644 --- a/arch/arm/mach-imx/include/mach/imx25-regs.h +++ b/arch/arm/mach-imx/include/mach/imx25-regs.h @@ -62,12 +62,14 @@ #define MX25_SSI2_BASE_ADDR 0x50014000 #define MX25_SSI1_BASE_ADDR 0x50034000 #define MX25_NFC_BASE_ADDR 0xbb000000 +#define MX25_SCC_BASE_ADDR 0x53fac000 #define MX25_IIM_BASE_ADDR 0x53ff0000 #define MX25_DRYICE_BASE_ADDR 0x53ffc000 #define MX25_ESDHC1_BASE_ADDR 0x53fb4000 #define MX25_ESDHC2_BASE_ADDR 0x53fb8000 #define MX25_LCDC_BASE_ADDR 0x53fbc000 #define MX25_KPP_BASE_ADDR 0x43fa8000 +#define MX25_RNGB_BASE_ADDR 0x53fb0000 #define MX25_SDMA_BASE_ADDR 0x53fd4000 #define MX25_USB_BASE_ADDR 0x53ff4000 #define MX25_USB_OTG_BASE_ADDR (MX25_USB_BASE_ADDR + 0x0000) diff --git a/arch/arm/mach-layerscape/Makefile b/arch/arm/mach-layerscape/Makefile index 269839254b..73cd61a7cf 100644 --- a/arch/arm/mach-layerscape/Makefile +++ b/arch/arm/mach-layerscape/Makefile @@ -2,3 +2,5 @@ obj- := __dummy__.o lwl-y += lowlevel.o errata.o lwl-$(CONFIG_ARCH_LS1046) += lowlevel-ls1046a.o obj-y += icid.o +obj-pbl-y += boot.o +pbl-y += xload-qspi.o xload.o diff --git a/arch/arm/mach-layerscape/boot.c b/arch/arm/mach-layerscape/boot.c new file mode 100644 index 0000000000..c804977d22 --- /dev/null +++ b/arch/arm/mach-layerscape/boot.c @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <common.h> +#include <init.h> +#include <bootsource.h> +#include <mach/layerscape.h> +#include <soc/fsl/immap_lsch2.h> + +enum bootsource ls1046_bootsource_get(void) +{ + void __iomem *dcfg = IOMEM(LSCH2_DCFG_ADDR); + uint32_t rcw_src; + + rcw_src = in_be32(dcfg) >> 23; + + if (rcw_src == 0x40) + return BOOTSOURCE_MMC; + if ((rcw_src & 0x1fe) == 0x44) + return BOOTSOURCE_SPI_NOR; + if ((rcw_src & 0x1f0) == 0x10) + /* 8bit NOR Flash */ + return BOOTSOURCE_NOR; + if ((rcw_src & 0x1f0) == 0x20) + /* 16bit NOR Flash */ + return BOOTSOURCE_NOR; + + return BOOTSOURCE_UNKNOWN; +} + +static int ls1046a_bootsource_init(void) +{ + if (!of_machine_is_compatible("fsl,ls1046a")) + return 0; + + bootsource_set(ls1046_bootsource_get()); + + return 0; +} +coredevice_initcall(ls1046a_bootsource_init);
\ No newline at end of file diff --git a/arch/arm/mach-layerscape/include/mach/bbu.h b/arch/arm/mach-layerscape/include/mach/bbu.h new file mode 100644 index 0000000000..1ea0cbb11f --- /dev/null +++ b/arch/arm/mach-layerscape/include/mach/bbu.h @@ -0,0 +1,22 @@ +#ifndef __MACH_LAYERSCAPE_BBU_H +#define __MACH_LAYERSCAPE_BBU_H + +#include <bbu.h> + +static inline int ls1046a_bbu_mmc_register_handler(const char *name, + const char *devicefile, + unsigned long flags) +{ + return bbu_register_std_file_update(name, flags, devicefile, + filetype_layerscape_image); +} + +static inline int ls1046a_bbu_qspi_register_handler(const char *name, + const char *devicefile, + unsigned long flags) +{ + return bbu_register_std_file_update(name, flags, devicefile, + filetype_layerscape_qspi_image); +} + +#endif /* __MACH_LAYERSCAPE_BBU_H */
\ No newline at end of file diff --git a/arch/arm/mach-layerscape/include/mach/layerscape.h b/arch/arm/mach-layerscape/include/mach/layerscape.h index 55e0b7bc96..3366e7f258 100644 --- a/arch/arm/mach-layerscape/include/mach/layerscape.h +++ b/arch/arm/mach-layerscape/include/mach/layerscape.h @@ -4,4 +4,6 @@ #define LS1046A_DDR_SDRAM_BASE 0x80000000 #define LS1046A_DDR_FREQ 2100000000 +enum bootsource ls1046_bootsource_get(void); + #endif /* __MACH_LAYERSCAPE_H */ diff --git a/arch/arm/mach-layerscape/include/mach/xload.h b/arch/arm/mach-layerscape/include/mach/xload.h index fedd36e020..eb2d998865 100644 --- a/arch/arm/mach-layerscape/include/mach/xload.h +++ b/arch/arm/mach-layerscape/include/mach/xload.h @@ -2,5 +2,9 @@ #define __MACH_XLOAD_H int ls1046a_esdhc_start_image(unsigned long r0, unsigned long r1, unsigned long r2); +int ls1046a_qspi_start_image(unsigned long r0, unsigned long r1, + unsigned long r2); +int ls1046a_xload_start_image(unsigned long r0, unsigned long r1, + unsigned long r2); #endif /* __MACH_XLOAD_H */ diff --git a/arch/arm/mach-layerscape/xload-qspi.c b/arch/arm/mach-layerscape/xload-qspi.c new file mode 100644 index 0000000000..c76780a0e8 --- /dev/null +++ b/arch/arm/mach-layerscape/xload-qspi.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <common.h> +#include <soc/fsl/immap_lsch2.h> +#include <asm-generic/sections.h> +#include <asm/cache.h> +#include <mach/xload.h> +#include <mach/layerscape.h> + +/* + * The offset of the 2nd stage image in the output file. This must match with the + * offset the pblimage tool puts barebox to. + */ +#define BAREBOX_START (128 * 1024) + +int ls1046a_qspi_start_image(unsigned long r0, unsigned long r1, + unsigned long r2) +{ + void *qspi_reg_base = IOMEM(LSCH2_QSPI0_BASE_ADDR); + void *membase = (void *)LS1046A_DDR_SDRAM_BASE; + void *qspi_mem_base = IOMEM(0x40000000); + void (*barebox)(unsigned long, unsigned long, unsigned long) = membase; + + /* Switch controller into little endian mode */ + out_be32(qspi_reg_base, 0x000f400c); + + memcpy(membase, qspi_mem_base + BAREBOX_START, barebox_image_size); + icache_invalidate(); + + printf("Starting barebox\n"); + + barebox(r0, r1, r2); + + printf("failed\n"); + + return -EIO; +} diff --git a/arch/arm/mach-layerscape/xload.c b/arch/arm/mach-layerscape/xload.c new file mode 100644 index 0000000000..54495d7f97 --- /dev/null +++ b/arch/arm/mach-layerscape/xload.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <common.h> +#include <bootsource.h> +#include <mach/layerscape.h> +#include <mach/xload.h> + +int ls1046a_xload_start_image(unsigned long r0, unsigned long r1, + unsigned long r2) +{ + enum bootsource src; + + src = ls1046_bootsource_get(); + + switch (src) { + case BOOTSOURCE_SPI_NOR: + return ls1046a_qspi_start_image(r0, r1, r2); + case BOOTSOURCE_MMC: + return ls1046a_esdhc_start_image(r0, r1, r2); + default: + pr_err("Unknown bootsource\n"); + return -EINVAL; + } +} diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a4070cfe32..5901930a73 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -7,7 +7,6 @@ config MIPS select GENERIC_LIB_ASHRDI3 select GENERIC_LIB_LSHRDI3 select HAS_KALLSYMS - select HAVE_CONFIGURABLE_MEMORY_LAYOUT select HAVE_CONFIGURABLE_TEXT_BASE select HAVE_PBL_MULTI_IMAGES select HAS_DMA @@ -32,6 +31,24 @@ config PHYS_ADDR_T_64BIT menu "Machine selection" +config MIPS_RELOCATION_TABLE_SIZE + hex "Relocation table size" + range 0x100 0x10000 + default "0x8000" + ---help--- + A table of relocation data will be appended to the Barebox binary + and parsed in relocate_code() to fix up all offsets in the relocated + Barebox. + + This option allows the amount of space reserved for the table to be + adjusted in a range from 256 up to 64k. The default is 32k and should + be ok in most cases. Reduce this value to shrink the size of U-Boot + binary. + + The build will fail and a valid size suggested if this is too small. + + If unsure, leave at the default value. + config BUILTIN_DTB bool "link a DTB into the barebox image" depends on OFTREE diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 5fbd51ceee..6f1a1ce617 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -59,7 +59,7 @@ CPPFLAGS += -DTEXT_BASE=$(CONFIG_TEXT_BASE) ifndef CONFIG_MODULES # Add cleanup flags CPPFLAGS += -fdata-sections -ffunction-sections -LDFLAGS_barebox += -static --gc-sections +LDFLAGS_barebox += -static --gc-sections --emit-relocs endif ifdef CONFIG_IMAGE_COMPRESSION @@ -116,6 +116,13 @@ CFLAGS += $(cflags-y) lds-$(CONFIG_GENERIC_LINKER_SCRIPT) := arch/mips/lib/barebox.lds +cmd_barebox__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_barebox) -o $@ \ + -T $(barebox-lds) \ + --start-group $(barebox-common) --end-group \ + $(filter-out $(barebox-lds) $(barebox-common) FORCE ,$^); \ + $(objtree)/scripts/mips-relocs $@ + + CLEAN_FILES += arch/mips/lib/barebox.lds barebox.map barebox.S pbl := arch/mips/pbl diff --git a/arch/mips/boards/8devices-lima/lowlevel.S b/arch/mips/boards/8devices-lima/lowlevel.S index b53b23b42a..dd1ab6247d 100644 --- a/arch/mips/boards/8devices-lima/lowlevel.S +++ b/arch/mips/boards/8devices-lima/lowlevel.S @@ -11,6 +11,7 @@ #include <mach/pbl_macros.h> #include <mach/pbl_ll_init_qca4531.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -38,4 +39,4 @@ skip_flash_test: dcache_enable skip_pll_ram_config: -ENTRY_FUNCTION_END(BOARD_PBL_START, qca4531_8devices_lima) +ENTRY_FUNCTION_END(BOARD_PBL_START, qca4531_8devices_lima, SZ_64M) diff --git a/arch/mips/boards/black-swift/lowlevel.S b/arch/mips/boards/black-swift/lowlevel.S index 0ba77435f8..5c5afcdf09 100644 --- a/arch/mips/boards/black-swift/lowlevel.S +++ b/arch/mips/boards/black-swift/lowlevel.S @@ -11,9 +11,10 @@ #include <asm/asm.h> #include <mach/pbl_macros.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) ar9331_pbl_generic_start -ENTRY_FUNCTION_END(BOARD_PBL_START, black_swift) +ENTRY_FUNCTION_END(BOARD_PBL_START, black_swift, SZ_64M) diff --git a/arch/mips/boards/dlink-dir-320/lowlevel.S b/arch/mips/boards/dlink-dir-320/lowlevel.S index 9f3bd5dead..da969bc74e 100644 --- a/arch/mips/boards/dlink-dir-320/lowlevel.S +++ b/arch/mips/boards/dlink-dir-320/lowlevel.S @@ -9,6 +9,7 @@ #include <asm/pbl_macros.h> #include <mach/debug_ll.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -19,4 +20,4 @@ ENTRY_FUNCTION(BOARD_PBL_START) /* CPU/SoC specific setup ... */ /* ... absent */ -ENTRY_FUNCTION_END(BOARD_PBL_START, dlink_dir_320) +ENTRY_FUNCTION_END(BOARD_PBL_START, dlink_dir_320, SZ_32M) diff --git a/arch/mips/boards/dptechnics-dpt-module/lowlevel.S b/arch/mips/boards/dptechnics-dpt-module/lowlevel.S index 28b8f4fac7..b5621963c3 100644 --- a/arch/mips/boards/dptechnics-dpt-module/lowlevel.S +++ b/arch/mips/boards/dptechnics-dpt-module/lowlevel.S @@ -12,9 +12,10 @@ #include <asm/pbl_macros.h> #include <mach/pbl_macros.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) ar9331_pbl_generic_start -ENTRY_FUNCTION_END(BOARD_PBL_START, ar9331_dptechnics_dpt_module) +ENTRY_FUNCTION_END(BOARD_PBL_START, ar9331_dptechnics_dpt_module, SZ_64M) diff --git a/arch/mips/boards/img-ci20/lowlevel.S b/arch/mips/boards/img-ci20/lowlevel.S index 056df17bf8..0295e44d1a 100644 --- a/arch/mips/boards/img-ci20/lowlevel.S +++ b/arch/mips/boards/img-ci20/lowlevel.S @@ -10,6 +10,7 @@ #include <asm/pbl_macros.h> #include <mach/debug_ll.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -23,4 +24,4 @@ ENTRY_FUNCTION(BOARD_PBL_START) debug_ll_outc '.' debug_ll_ns16550_outnl -ENTRY_FUNCTION_END(BOARD_PBL_START, img_ci20) +ENTRY_FUNCTION_END(BOARD_PBL_START, img_ci20, SZ_1G) diff --git a/arch/mips/boards/loongson-ls1b/lowlevel.S b/arch/mips/boards/loongson-ls1b/lowlevel.S index 37744e9fac..c533df3ce5 100644 --- a/arch/mips/boards/loongson-ls1b/lowlevel.S +++ b/arch/mips/boards/loongson-ls1b/lowlevel.S @@ -9,6 +9,7 @@ #include <mach/loongson1.h> #include <mach/debug_ll.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -21,4 +22,4 @@ ENTRY_FUNCTION(BOARD_PBL_START) debug_ll_outc '.' debug_ll_ns16550_outnl -ENTRY_FUNCTION_END(BOARD_PBL_START, loongson_ls1b) +ENTRY_FUNCTION_END(BOARD_PBL_START, loongson_ls1b, SZ_64M) diff --git a/arch/mips/boards/qemu-malta/lowlevel.S b/arch/mips/boards/qemu-malta/lowlevel.S index 3861ae9e46..e4ecde45cf 100644 --- a/arch/mips/boards/qemu-malta/lowlevel.S +++ b/arch/mips/boards/qemu-malta/lowlevel.S @@ -10,6 +10,7 @@ #include <asm/asm.h> #include <asm/pbl_macros.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> #include <asm/addrspace.h> #include <asm/gt64120.h> @@ -82,4 +83,4 @@ __start: li t0, GT_LD(0x1bdfffff) sw t0, GT_PCI0M1HD_OFS(t1) -ENTRY_FUNCTION_END(BOARD_PBL_START, qemu_malta) +ENTRY_FUNCTION_END(BOARD_PBL_START, qemu_malta, SZ_256M) diff --git a/arch/mips/boards/ritmix-rzx50/lowlevel.S b/arch/mips/boards/ritmix-rzx50/lowlevel.S index 7a9743835e..33810f67f5 100644 --- a/arch/mips/boards/ritmix-rzx50/lowlevel.S +++ b/arch/mips/boards/ritmix-rzx50/lowlevel.S @@ -10,6 +10,7 @@ #include <asm/pbl_macros.h> #include <mach/debug_ll.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -23,4 +24,4 @@ ENTRY_FUNCTION(BOARD_PBL_START) debug_ll_outc '.' debug_ll_ns16550_outnl -ENTRY_FUNCTION_END(BOARD_PBL_START, rzx50) +ENTRY_FUNCTION_END(BOARD_PBL_START, rzx50, SZ_64M) diff --git a/arch/mips/boards/tplink-mr3020/lowlevel.S b/arch/mips/boards/tplink-mr3020/lowlevel.S index 0a1c193c1e..b96292ecc4 100644 --- a/arch/mips/boards/tplink-mr3020/lowlevel.S +++ b/arch/mips/boards/tplink-mr3020/lowlevel.S @@ -11,9 +11,10 @@ #include <asm/asm.h> #include <mach/pbl_macros.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) ar9331_pbl_generic_start -ENTRY_FUNCTION_END(BOARD_PBL_START, tplink_mr3020) +ENTRY_FUNCTION_END(BOARD_PBL_START, tplink_mr3020, SZ_32M) diff --git a/arch/mips/boards/tplink-wdr4300/lowlevel.S b/arch/mips/boards/tplink-wdr4300/lowlevel.S index 461b257f41..8aed5ddcf1 100644 --- a/arch/mips/boards/tplink-wdr4300/lowlevel.S +++ b/arch/mips/boards/tplink-wdr4300/lowlevel.S @@ -11,6 +11,7 @@ #include <mach/pbl_macros.h> #include <mach/pbl_ll_init_ar9344_1.1.h> #include <asm/pbl_nmon.h> +#include <linux/sizes.h> ENTRY_FUNCTION(BOARD_PBL_START) @@ -35,4 +36,4 @@ skip_flash_test: skip_pll_ram_config: -ENTRY_FUNCTION_END(BOARD_PBL_START, ar9344_tl_wdr4300_v1.7) +ENTRY_FUNCTION_END(BOARD_PBL_START, ar9344_tl_wdr4300_v1.7, SZ_128M) diff --git a/arch/mips/boot/dtb.c b/arch/mips/boot/dtb.c index ea30e16f21..5e316270f6 100644 --- a/arch/mips/boot/dtb.c +++ b/arch/mips/boot/dtb.c @@ -29,10 +29,6 @@ void of_add_memory_bank(struct device_node *node, bool dump, int r, if (dump) pr_info("%s: %s: 0x%llx@0x%llx\n", node->name, str, size, base); - - if (glob_fdt && glob_fdt_size) - request_sdram_region("fdt", (resource_size_t)glob_fdt, - glob_fdt_size); } extern char __dtb_start[]; diff --git a/arch/mips/boot/main_entry-pbl.c b/arch/mips/boot/main_entry-pbl.c index b40887b064..02ddd5ec24 100644 --- a/arch/mips/boot/main_entry-pbl.c +++ b/arch/mips/boot/main_entry-pbl.c @@ -18,14 +18,14 @@ extern void *input_data_end; unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; -void pbl_main_entry(void *fdt, void *fdt_end); +void pbl_main_entry(void *fdt, void *fdt_end, u32 ram_size); static unsigned long *ttb; static void barebox_uncompress(void *compressed_start, unsigned int len) { /* set 128 KiB at the end of the MALLOC_BASE for early malloc */ - free_mem_ptr = MALLOC_BASE + MALLOC_SIZE - SZ_128K; + free_mem_ptr = TEXT_BASE - SZ_128K; free_mem_end_ptr = free_mem_ptr + SZ_128K; ttb = (void *)((free_mem_ptr - 0x4000) & ~0x3fff); @@ -33,11 +33,12 @@ static void barebox_uncompress(void *compressed_start, unsigned int len) pbl_barebox_uncompress((void*)TEXT_BASE, compressed_start, len); } -void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end) +void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end, + u32 ram_size) { u32 pg_start, pg_end, pg_len, fdt_len; void *fdt_new; - void (*barebox)(void *fdt, u32 fdt_len); + void (*barebox)(void *fdt, u32 fdt_len, u32 ram_size); puts_ll("pbl_main_entry()\n"); @@ -51,9 +52,9 @@ void __section(.text_entry) pbl_main_entry(void *fdt, void *fdt_end) barebox_uncompress(&input_data, pg_len); fdt_len = (u32)fdt_end - (u32)fdt; - fdt_new = (void *)PAGE_ALIGN_DOWN(STACK_BASE - fdt_len); + fdt_new = (void *)PAGE_ALIGN_DOWN(TEXT_BASE - MALLOC_SIZE - STACK_SIZE - fdt_len); memcpy(fdt_new, fdt, fdt_len); barebox = (void *)TEXT_BASE; - barebox(fdt_new, fdt_len); + barebox(fdt_new, fdt_len, ram_size); } diff --git a/arch/mips/boot/main_entry.c b/arch/mips/boot/main_entry.c index 84325da93a..5b88730b07 100644 --- a/arch/mips/boot/main_entry.c +++ b/arch/mips/boot/main_entry.c @@ -12,6 +12,7 @@ #include <asm/cpu-features.h> #include <asm/mipsregs.h> #include <asm/addrspace.h> +#include <linux/sizes.h> extern void handle_reserved(void); @@ -61,6 +62,7 @@ static void trap_init(void) extern void *glob_fdt; extern u32 glob_fdt_size; +extern unsigned long mips_stack_top; /** * Called plainly from assembler code @@ -69,6 +71,7 @@ extern u32 glob_fdt_size; */ void __bare_init main_entry(void *fdt, u32 fdt_size) { + unsigned long malloc_start, malloc_end; /* clear the BSS first */ memset(__bss_start, 0x00, __bss_stop - __bss_start); @@ -82,8 +85,18 @@ void __bare_init main_entry(void *fdt, u32 fdt_size) trap_init(); - mem_malloc_init((void *)MALLOC_BASE, - (void *)(MALLOC_BASE + MALLOC_SIZE - 1)); + malloc_end = _stext; + + if (MALLOC_SIZE > 0) + malloc_start = malloc_end - MALLOC_SIZE; + else + malloc_start = malloc_end - SZ_8M; + + pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n", + malloc_start, malloc_end - malloc_start); + + mem_malloc_init((void *)malloc_start, (void *)_stext - 1); + mips_stack_top = malloc_start; glob_fdt = fdt; glob_fdt_size = fdt_size; diff --git a/arch/mips/boot/start.S b/arch/mips/boot/start.S index 6efe03e98d..c1cd2d9dd5 100644 --- a/arch/mips/boot/start.S +++ b/arch/mips/boot/start.S @@ -18,6 +18,7 @@ EXPORT(_start) /* save dtb pointer */ move s0, a0 move s1, a1 + move s2, a2 /* disable watchpoints */ mtc0 zero, CP0_WATCHLO @@ -32,7 +33,8 @@ EXPORT(_start) /* restore dtb pointer */ move a0, s0 move a1, s1 - la v0, main_entry + move a2, s2 + la v0, relocate_code jal v0 nop diff --git a/arch/mips/include/asm/asm.h b/arch/mips/include/asm/asm.h index 7d2b673bd9..a85467ceed 100644 --- a/arch/mips/include/asm/asm.h +++ b/arch/mips/include/asm/asm.h @@ -89,13 +89,14 @@ EXPORT(symbol) /* * ENTRY_FUNCTION_END - mark end of entry function */ -#define ENTRY_FUNCTION_END(symbol, dtb) \ +#define ENTRY_FUNCTION_END(symbol, dtb, ram_size) \ mips_nmon; \ copy_to_link_location symbol; \ stack_setup; \ \ la a0, __dtb_ ## dtb##_start; \ la a1, __dtb_ ## dtb##_end; \ + li a2, ram_size; \ la v0, pbl_main_entry; \ jal v0; \ nop; \ diff --git a/arch/mips/include/asm/pbl_macros.h b/arch/mips/include/asm/pbl_macros.h index e78d1afe6a..c62910ff60 100644 --- a/arch/mips/include/asm/pbl_macros.h +++ b/arch/mips/include/asm/pbl_macros.h @@ -187,7 +187,7 @@ copy_loop_exit: * */ -#if (STACK_BASE + STACK_SIZE) % 16 != 0 +#if (TEXT_BASE - MALLOC_SIZE) % 16 != 0 #error stack pointer must be 16-byte-aligned #endif @@ -196,7 +196,7 @@ copy_loop_exit: .set noreorder /* set stack pointer; reserve four 32-bit argument slots */ - la sp, STACK_BASE + STACK_SIZE - 16 + la sp, (TEXT_BASE - MALLOC_SIZE - 16) .set pop .endm diff --git a/arch/mips/include/asm/relocs.h b/arch/mips/include/asm/relocs.h new file mode 100644 index 0000000000..0987c4bb13 --- /dev/null +++ b/arch/mips/include/asm/relocs.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * MIPS Relocations + * + * Copyright (c) 2017 Imagination Technologies Ltd. + */ + +#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 2b8c516038..8e004eaf34 100644 --- a/arch/mips/include/asm/sections.h +++ b/arch/mips/include/asm/sections.h @@ -1 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef __ASM_MIPS_SECTIONS_H +#define __ASM_MIPS_SECTIONS_H + #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 7372e8dc27..4ba42e526e 100644 --- a/arch/mips/lib/Makefile +++ b/arch/mips/lib/Makefile @@ -4,6 +4,8 @@ obj-y += cpu-probe.o lwl-y += end.o obj-y += traps.o obj-y += genex.o +obj-y += reloc.o +obj-y += sections.o obj-y += shutdown.o obj-y += dma-default.o diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S index 8ddf954517..58b0c5919d 100644 --- a/arch/mips/lib/barebox.lds.S +++ b/arch/mips/lib/barebox.lds.S @@ -13,6 +13,8 @@ SECTIONS . = TEXT_BASE; . = ALIGN(4); + + .image_start : { *(.__image_start) } .text : { _stext = .; @@ -79,9 +81,28 @@ SECTIONS .dtb : { BAREBOX_DTB() } _edata = .; + .image_end : { *(.__image_end) } + . = ALIGN(4); - __bss_start = .; - .bss : { *(.bss*) } - __bss_stop = .; + /* + * .rel must come last so that the mips-relocs tool can shrink + * the section size & the PT_LOAD program header filesz. + */ + .data.reloc : { + __rel_start = .; + BYTE(0x0) + . += (32 * 1024) - 1; + } + _end = .; + + .bss __rel_start (OVERLAY) : { + __bss_start = .; + *(.sbss.*) + *(.bss.*) + *(COMMON) + . = ALIGN(4); + __bss_stop = .; + } + } diff --git a/arch/mips/lib/cpu-probe.c b/arch/mips/lib/cpu-probe.c index cf63849743..2556a8b240 100644 --- a/arch/mips/lib/cpu-probe.c +++ b/arch/mips/lib/cpu-probe.c @@ -11,6 +11,9 @@ #include <asm/mipsregs.h> #include <asm/cpu-info.h> #include <asm/cpu.h> +#include <memory.h> +#include <asm-generic/memory_layout.h> +#include <init.h> const char *__cpu_name; struct cpuinfo_mips cpu_data[1]; @@ -161,3 +164,14 @@ void cpu_probe(void) break; } } + +unsigned long mips_stack_top; + +static int mips_request_stack(void) +{ + if (!request_sdram_region("stack", mips_stack_top - STACK_SIZE, STACK_SIZE)) + pr_err("Error: Cannot request SDRAM region for stack\n"); + + return 0; +} +coredevice_initcall(mips_request_stack); diff --git a/arch/mips/lib/pbl.lds.S b/arch/mips/lib/pbl.lds.S index f1752ec720..75069b0c50 100644 --- a/arch/mips/lib/pbl.lds.S +++ b/arch/mips/lib/pbl.lds.S @@ -6,11 +6,14 @@ #include <asm-generic/barebox.lds.h> #include <asm-generic/memory_layout.h> +#include <linux/sizes.h> + +#define BASE (TEXT_BASE - SZ_2M) OUTPUT_ARCH("mips") SECTIONS { - . = HEAD_TEXT_BASE; + . = BASE; PRE_IMAGE @@ -38,21 +41,21 @@ SECTIONS . = ALIGN(4); .data : { *(.data*) } - pbl_code_size = . - HEAD_TEXT_BASE; + pbl_code_size = . - BASE; . = ALIGN(4); __piggydata_start = .; .piggydata : { *(.piggydata) } - __piggydata_end = .; + __piggydata_end = . - BASE; - pbl_image_size = . - HEAD_TEXT_BASE; + pbl_image_size = .; . = ALIGN(4); __bss_start = .; .bss : { *(.bss*) } __bss_stop = .; - pbl_memory_size = . - HEAD_TEXT_BASE; + pbl_memory_size = . - BASE; _end = .; } diff --git a/arch/mips/lib/reloc.c b/arch/mips/lib/reloc.c new file mode 100644 index 0000000000..9756d61666 --- /dev/null +++ b/arch/mips/lib/reloc.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * MIPS Relocation + * + * Copyright (c) 2017 Imagination Technologies Ltd. + * + * Relocation data, found in the .rel section, is generated by the mips-relocs + * tool & contains a record of all locations in the Barebox 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/bitops.h> +#include <asm/cache.h> +#include <asm/cacheops.h> +#include <asm/cpu.h> +#include <asm/cpu-info.h> +#include <asm/io.h> +#include <asm/mipsregs.h> +#include <asm/relocs.h> +#include <asm/sections.h> +#include <linux/sizes.h> +#include <asm-generic/memory_layout.h> + +#define MAX_BSS_SIZE SZ_1M + +void main_entry(void *fdt, u32 fdt_size); +void relocate_code(void *fdt, u32 fdt_size, u32 relocaddr); + +/** + * 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 Barebox 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 Barebox - 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 Barebox, 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 Barebox from its current location (generally in flash) to a new one + * (generally in DDR). This function will copy the Barebox binary & apply + * relocations as necessary, then jump to board_init_r in the new build of + * Barebox. As such, this function does not return. + */ +void relocate_code(void *fdt, u32 fdt_size, u32 ram_size) +{ + unsigned long addr, length, bss_len; + u32 relocaddr, new_stack; + uint8_t *buf, *bss_start; + unsigned int type; + long off; + + length = barebox_image_size + MAX_BSS_SIZE; + relocaddr = ALIGN_DOWN(ram_size - barebox_image_size, SZ_64K); + relocaddr = KSEG0ADDR(relocaddr); + new_stack = relocaddr - MALLOC_SIZE - 16; + + /* + * 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 Barebox binary & complexity in handling them. + */ + off = relocaddr - (unsigned long)__image_start; + if (off & 0xffff) + panic("Mis-aligned relocation\n"); + + /* Copy Barebox to RAM */ + memcpy((void *)relocaddr, __image_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_all(); + + /* Clear the .bss section */ + bss_start = (uint8_t *)((unsigned long)__bss_start + off); + bss_len = (unsigned long)&__bss_stop - (unsigned long)__bss_start; + memset(bss_start, 0, bss_len); + + __asm__ __volatile__ ( + "move $a0, %0\n" + " move $a1, %1\n" + " move $31, $0\n" + " move $sp, %2\n" + " jr %3\n" + : /* no outputs */ + : "r"(fdt), + "r"(fdt_size), + "r"(new_stack), + "r"((unsigned long)main_entry + off)); + + /* Since we jumped to the new Barebox above, we won't get here */ + unreachable(); +} diff --git a/arch/mips/lib/sections.c b/arch/mips/lib/sections.c new file mode 100644 index 0000000000..66d559f94a --- /dev/null +++ b/arch/mips/lib/sections.c @@ -0,0 +1,9 @@ +#include <common.h> +#include <asm/sections.h> +#include <linux/types.h> + +char _text[0] __attribute__((section("._text"))); +char __bss_start[0] __attribute__((section(".__bss_start"))); +char __bss_stop[0] __attribute__((section(".__bss_stop"))); +char __image_start[0] __attribute__((section(".__image_start"))); +char __image_end[0] __attribute__((section(".__image_end"))); diff --git a/arch/sandbox/os/common.c b/arch/sandbox/os/common.c index 665e8194ef..a7ea8f2d3b 100644 --- a/arch/sandbox/os/common.c +++ b/arch/sandbox/os/common.c @@ -94,7 +94,7 @@ int linux_tstc(int fd) return 0; } -int ctrlc(void) +int arch_ctrlc(void) { char chr; |