diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e7edc2a..37cde0c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2,7 +2,7 @@ bool select HAS_KALLSYMS select HAS_CACHE - select HAVE_CONFIGURABLE_TEXT_BASE + select HAVE_CONFIGURABLE_TEXT_BASE if !RELOCATABLE select HAVE_IMAGE_COMPRESSION default y @@ -19,6 +19,10 @@ select UNCOMPRESS select LZO_DECOMPRESS +config TEXT_BASE + hex + default 0x0 + menu "System Type" config BUILTIN_DTB @@ -282,6 +286,7 @@ config AEABI bool "Use the ARM EABI to compile barebox" + depends on !CPU_V8 help This option allows for barebox to be compiled using the latest ARM ABI (aka EABI). @@ -304,7 +309,7 @@ config ARM_BOARD_APPEND_ATAG bool "Let board specific code to add ATAGs to be passed to the kernel" - depends on ARM_LINUX + depends on ARM_LINUX && !CPU_V8 help This option is purely to start some vendor provided kernels. ** DO NOT USE FOR YOUR OWN DESIGNS! ** diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 620a3cc..ac97de1 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -23,6 +23,8 @@ # accesses ifneq ($(CONFIG_CPU_V8),y) CFLAGS += -mno-unaligned-access +else +CFLAGS += -mstrict-align endif @@ -65,6 +67,7 @@ ifeq ($(CONFIG_CPU_V8), y) CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) AFLAGS += -include asm/unified.h +export S64 = _64 else CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float $(CFLAGS_THUMB2) AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2) @@ -295,7 +298,6 @@ common-y += $(BOARD) arch/arm/boards/ $(MACH) common-y += arch/arm/cpu/ -common-y += arch/arm/lib/ ifeq ($(CONFIG_CPU_V8), y) common-y += arch/arm/lib64/ diff --git a/arch/arm/boards/afi-gf/lowlevel.c b/arch/arm/boards/afi-gf/lowlevel.c index 91b4b68..1afc965 100644 --- a/arch/arm/boards/afi-gf/lowlevel.c +++ b/arch/arm/boards/afi-gf/lowlevel.c @@ -258,7 +258,7 @@ { void *fdt; - fdt = __dtb_z_am335x_afi_gf_start - get_runtime_offset(); + fdt = __dtb_z_am335x_afi_gf_start + get_runtime_offset(); putc_ll('>'); diff --git a/arch/arm/boards/altera-socdk/lowlevel.c b/arch/arm/boards/altera-socdk/lowlevel.c index 8cfe839..08e70a0 100644 --- a/arch/arm/boards/altera-socdk/lowlevel.c +++ b/arch/arm/boards/altera-socdk/lowlevel.c @@ -26,7 +26,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_socfpga_cyclone5_socdk_start - get_runtime_offset(); + fdt = __dtb_socfpga_cyclone5_socdk_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); } diff --git a/arch/arm/boards/at91sam9263ek/lowlevel_init.c b/arch/arm/boards/at91sam9263ek/lowlevel_init.c index 2004d70..30c1408 100644 --- a/arch/arm/boards/at91sam9263ek/lowlevel_init.c +++ b/arch/arm/boards/at91sam9263ek/lowlevel_init.c @@ -126,7 +126,7 @@ arm_setup_stack(AT91SAM9263_SRAM0_BASE + AT91SAM9263_SRAM0_SIZE - 16); if (IS_ENABLED(CONFIG_MACH_AT91SAM9263EK_DT)) - fdt = __dtb_at91sam9263ek_start - get_runtime_offset(); + fdt = __dtb_at91sam9263ek_start + get_runtime_offset(); else fdt = NULL; diff --git a/arch/arm/boards/at91sam9x5ek/lowlevel.c b/arch/arm/boards/at91sam9x5ek/lowlevel.c index acf80d7..9aa0e8b 100644 --- a/arch/arm/boards/at91sam9x5ek/lowlevel.c +++ b/arch/arm/boards/at91sam9x5ek/lowlevel.c @@ -15,7 +15,7 @@ arm_cpu_lowlevel_init(); arm_setup_stack(AT91SAM9X5_SRAM_BASE + AT91SAM9X5_SRAM_SIZE - 16); - fdt = __dtb_at91sam9x5ek_start - get_runtime_offset(); + fdt = __dtb_at91sam9x5ek_start + get_runtime_offset(); barebox_arm_entry(AT91_CHIPSELECT_1, at91sam9x5_get_ddram_size(), fdt); } diff --git a/arch/arm/boards/beaglebone/lowlevel.c b/arch/arm/boards/beaglebone/lowlevel.c index a56b4b6..a1ba1d3 100644 --- a/arch/arm/boards/beaglebone/lowlevel.c +++ b/arch/arm/boards/beaglebone/lowlevel.c @@ -184,7 +184,7 @@ fdt = __dtb_z_am335x_bone_start; } - fdt -= get_runtime_offset(); + fdt += get_runtime_offset(); barebox_arm_entry(0x80000000, sdram_size, fdt); } diff --git a/arch/arm/boards/boundarydevices-nitrogen6/lowlevel.c b/arch/arm/boards/boundarydevices-nitrogen6/lowlevel.c index bee70a5..74ff71f 100644 --- a/arch/arm/boards/boundarydevices-nitrogen6/lowlevel.c +++ b/arch/arm/boards/boundarydevices-nitrogen6/lowlevel.c @@ -11,7 +11,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_nitrogen6x_start - get_runtime_offset(); + fdt = __dtb_imx6q_nitrogen6x_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -22,7 +22,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_nitrogen6x_start - get_runtime_offset(); + fdt = __dtb_imx6q_nitrogen6x_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -35,7 +35,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_nitrogen6x_start - get_runtime_offset(); + fdt = __dtb_imx6dl_nitrogen6x_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -46,7 +46,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_nitrogen6x_start - get_runtime_offset(); + fdt = __dtb_imx6dl_nitrogen6x_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -59,7 +59,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6qp_nitrogen6_max_start - get_runtime_offset(); + fdt = __dtb_imx6qp_nitrogen6_max_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } diff --git a/arch/arm/boards/ccxmx53/lowlevel.c b/arch/arm/boards/ccxmx53/lowlevel.c index 2249214..c27e330 100644 --- a/arch/arm/boards/ccxmx53/lowlevel.c +++ b/arch/arm/boards/ccxmx53/lowlevel.c @@ -41,7 +41,7 @@ IMD_USED(ccxmx53_memsize_SZ_512M); - fdt = __dtb_imx53_ccxmx53_start - get_runtime_offset(); + fdt = __dtb_imx53_ccxmx53_start + get_runtime_offset(); imx53_barebox_entry(fdt); } @@ -55,7 +55,7 @@ IMD_USED(ccxmx53_memsize_SZ_1G); - fdt = __dtb_imx53_ccxmx53_start - get_runtime_offset(); + fdt = __dtb_imx53_ccxmx53_start + get_runtime_offset(); imx53_barebox_entry(fdt); } diff --git a/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c b/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c index 28b4aa2..3ecdb66 100644 --- a/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c +++ b/arch/arm/boards/datamodul-edm-qmx6/lowlevel.c @@ -147,7 +147,7 @@ arm_setup_stack(0x00940000 - 8); - fdt = __dtb_imx6q_dmo_edmqmx6_start - get_runtime_offset(); + fdt = __dtb_imx6q_dmo_edmqmx6_start + get_runtime_offset(); if (get_pc() < 0x10000000) { sdram_init(); diff --git a/arch/arm/boards/dfi-fs700-m60/lowlevel.c b/arch/arm/boards/dfi-fs700-m60/lowlevel.c index a22f66a..b419228 100644 --- a/arch/arm/boards/dfi-fs700-m60/lowlevel.c +++ b/arch/arm/boards/dfi-fs700-m60/lowlevel.c @@ -115,7 +115,7 @@ early_uart_init_6q(); - fdt = __dtb_imx6q_dfi_fs700_m60_6q_start - get_runtime_offset(); + fdt = __dtb_imx6q_dfi_fs700_m60_6q_start + get_runtime_offset(); barebox_arm_entry(0x10000000, memsize_1G_2G(), fdt); } @@ -134,7 +134,7 @@ early_uart_init_6q(); - fdt = __dtb_imx6q_dfi_fs700_m60_6q_start - get_runtime_offset(); + fdt = __dtb_imx6q_dfi_fs700_m60_6q_start + get_runtime_offset(); *(uint32_t *)0x10000000 = SZ_1G; @@ -157,7 +157,7 @@ early_uart_init_6s(); - fdt = __dtb_imx6dl_dfi_fs700_m60_6s_start - get_runtime_offset(); + fdt = __dtb_imx6dl_dfi_fs700_m60_6s_start + get_runtime_offset(); barebox_arm_entry(0x10000000, memsize_512M_1G(), fdt); } diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c index c00a9a0..2922e40 100644 --- a/arch/arm/boards/duckbill/lowlevel.c +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -20,7 +20,7 @@ pr_debug("here we are!\n"); - fdt = __dtb_imx28_duckbill_start - get_runtime_offset(); + fdt = __dtb_imx28_duckbill_start + get_runtime_offset(); barebox_arm_entry(IMX_MEMORY_BASE, SZ_128M, fdt); } diff --git a/arch/arm/boards/ebv-socrates/lowlevel.c b/arch/arm/boards/ebv-socrates/lowlevel.c index 9643269..ef9f453 100644 --- a/arch/arm/boards/ebv-socrates/lowlevel.c +++ b/arch/arm/boards/ebv-socrates/lowlevel.c @@ -52,7 +52,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_socfpga_cyclone5_socrates_start - get_runtime_offset(); + fdt = __dtb_socfpga_cyclone5_socrates_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); } diff --git a/arch/arm/boards/efika-mx-smartbook/lowlevel.c b/arch/arm/boards/efika-mx-smartbook/lowlevel.c index 52454c7..6da5bfa 100644 --- a/arch/arm/boards/efika-mx-smartbook/lowlevel.c +++ b/arch/arm/boards/efika-mx-smartbook/lowlevel.c @@ -15,7 +15,7 @@ arm_setup_stack(0x20000000 - 16); imx51_init_lowlevel(800); - fdt = __dtb_imx51_genesi_efika_sb_start - get_runtime_offset(); + fdt = __dtb_imx51_genesi_efika_sb_start + get_runtime_offset(); imx51_barebox_entry(fdt); } diff --git a/arch/arm/boards/element14-warp7/lowlevel.c b/arch/arm/boards/element14-warp7/lowlevel.c index 89a77d2..6ca733a 100644 --- a/arch/arm/boards/element14-warp7/lowlevel.c +++ b/arch/arm/boards/element14-warp7/lowlevel.c @@ -35,7 +35,7 @@ pr_debug("Element14 i.MX7 Warp\n"); - fdt = __dtb_imx7s_warp_start - get_runtime_offset(); + fdt = __dtb_imx7s_warp_start + get_runtime_offset(); barebox_arm_entry(0x80000000, SZ_512M, fdt); } diff --git a/arch/arm/boards/eltec-hipercam/lowlevel.c b/arch/arm/boards/eltec-hipercam/lowlevel.c index 21542e4..b0d3155 100644 --- a/arch/arm/boards/eltec-hipercam/lowlevel.c +++ b/arch/arm/boards/eltec-hipercam/lowlevel.c @@ -44,7 +44,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6dl_eltec_hipercam_start - get_runtime_offset(); + fdt = __dtb_imx6dl_eltec_hipercam_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_256M, fdt); } diff --git a/arch/arm/boards/embedsky-e9/lowlevel.c b/arch/arm/boards/embedsky-e9/lowlevel.c index fb1ba5f..845c4ec 100644 --- a/arch/arm/boards/embedsky-e9/lowlevel.c +++ b/arch/arm/boards/embedsky-e9/lowlevel.c @@ -12,7 +12,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_embedsky_e9_start - get_runtime_offset(); + fdt = __dtb_imx6q_embedsky_e9_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_2G, fdt); } diff --git a/arch/arm/boards/embest-riotboard/lowlevel.c b/arch/arm/boards/embest-riotboard/lowlevel.c index d26bc98..07f669f 100644 --- a/arch/arm/boards/embest-riotboard/lowlevel.c +++ b/arch/arm/boards/embest-riotboard/lowlevel.c @@ -23,6 +23,6 @@ putc_ll('a'); } - fdt = __dtb_imx6s_riotboard_start - get_runtime_offset(); + fdt = __dtb_imx6s_riotboard_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c index af40f44..1c20b6a 100644 --- a/arch/arm/boards/freescale-mx51-babbage/lowlevel.c +++ b/arch/arm/boards/freescale-mx51-babbage/lowlevel.c @@ -50,7 +50,7 @@ arm_setup_stack(0x20000000 - 16); - fdt = __dtb_imx51_babbage_start - get_runtime_offset(); + fdt = __dtb_imx51_babbage_start + get_runtime_offset(); imx51_barebox_entry(fdt); } diff --git a/arch/arm/boards/freescale-mx53-qsb/lowlevel.c b/arch/arm/boards/freescale-mx53-qsb/lowlevel.c index bed8863..cfe01f7 100644 --- a/arch/arm/boards/freescale-mx53-qsb/lowlevel.c +++ b/arch/arm/boards/freescale-mx53-qsb/lowlevel.c @@ -15,7 +15,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); - fdt = __dtb_imx53_qsb_start - get_runtime_offset(); + fdt = __dtb_imx53_qsb_start + get_runtime_offset(); imx53_barebox_entry(fdt); } @@ -29,7 +29,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(MX53_IRAM_BASE_ADDR + MX53_IRAM_SIZE - 8); - fdt = __dtb_imx53_qsrb_start - get_runtime_offset(); + fdt = __dtb_imx53_qsrb_start + get_runtime_offset(); imx53_barebox_entry(fdt); } diff --git a/arch/arm/boards/freescale-mx53-vmx53/lowlevel.c b/arch/arm/boards/freescale-mx53-vmx53/lowlevel.c index 3545a1c..aac784c 100644 --- a/arch/arm/boards/freescale-mx53-vmx53/lowlevel.c +++ b/arch/arm/boards/freescale-mx53-vmx53/lowlevel.c @@ -13,7 +13,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(0xf8020000 - 8); - fdt = __dtb_imx53_voipac_bsb_start - get_runtime_offset(); + fdt = __dtb_imx53_voipac_bsb_start + get_runtime_offset(); imx53_barebox_entry(fdt); } diff --git a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c index 5743dbc..ae847fe 100644 --- a/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c +++ b/arch/arm/boards/freescale-mx6-sabresd/lowlevel.c @@ -31,7 +31,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6q_sabresd_start - get_runtime_offset(); + fdt = __dtb_imx6q_sabresd_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c index af26557..6a6e27b 100644 --- a/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c +++ b/arch/arm/boards/freescale-mx6sx-sabresdb/lowlevel.c @@ -46,7 +46,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6sx_sdb_start - get_runtime_offset(); + fdt = __dtb_imx6sx_sdb_start + get_runtime_offset(); barebox_arm_entry(0x80000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c b/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c index 96ccbbf..43aa610 100644 --- a/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c +++ b/arch/arm/boards/freescale-mx7-sabresd/lowlevel.c @@ -40,7 +40,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx7d_sdb_start - get_runtime_offset(); + fdt = __dtb_imx7d_sdb_start + get_runtime_offset(); barebox_arm_entry(0x80000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/freescale-vf610-twr/lowlevel.c b/arch/arm/boards/freescale-vf610-twr/lowlevel.c index 53c7b3a..deabe4e 100644 --- a/arch/arm/boards/freescale-vf610-twr/lowlevel.c +++ b/arch/arm/boards/freescale-vf610-twr/lowlevel.c @@ -34,6 +34,6 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_vf610_twr_start - get_runtime_offset(); + fdt = __dtb_vf610_twr_start + get_runtime_offset(); barebox_arm_entry(0x80000000, SZ_128M, fdt); } diff --git a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c index fea00ef..4b9ba87 100644 --- a/arch/arm/boards/friendlyarm-tiny210/lowlevel.c +++ b/arch/arm/boards/friendlyarm-tiny210/lowlevel.c @@ -96,7 +96,7 @@ debug_led(1, 1); - if (! load_stage2((void*)(ld_var(_text) - 16), + if (! load_stage2((void*)(_text - 16), barebox_image_size + 16)) { debug_led(3, 1); while (1) { } /* hang */ @@ -104,7 +104,7 @@ debug_led(2, 1); - jump_sdram(IRAM_CODE_BASE - ld_var(_text)); + jump_sdram(IRAM_CODE_BASE - (unsigned long)_text); debug_led(1, 0); diff --git a/arch/arm/boards/gateworks-ventana/lowlevel.c b/arch/arm/boards/gateworks-ventana/lowlevel.c index 746beb8..0a79d82 100644 --- a/arch/arm/boards/gateworks-ventana/lowlevel.c +++ b/arch/arm/boards/gateworks-ventana/lowlevel.c @@ -12,7 +12,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_gw54xx_start - get_runtime_offset(); + fdt = __dtb_imx6q_gw54xx_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/gk802/lowlevel.c b/arch/arm/boards/gk802/lowlevel.c index b571969..a41b711 100644 --- a/arch/arm/boards/gk802/lowlevel.c +++ b/arch/arm/boards/gk802/lowlevel.c @@ -12,6 +12,6 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_gk802_start - get_runtime_offset(); + fdt = __dtb_imx6q_gk802_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/globalscale-guruplug/lowlevel.c b/arch/arm/boards/globalscale-guruplug/lowlevel.c index 67c3b23..92424cb 100644 --- a/arch/arm/boards/globalscale-guruplug/lowlevel.c +++ b/arch/arm/boards/globalscale-guruplug/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_kirkwood_guruplug_server_plus_bb_start - + fdt = __dtb_kirkwood_guruplug_server_plus_bb_start + get_runtime_offset(); kirkwood_barebox_entry(fdt); diff --git a/arch/arm/boards/globalscale-mirabox/lowlevel.c b/arch/arm/boards/globalscale-mirabox/lowlevel.c index 7b070d7..69786c8 100644 --- a/arch/arm/boards/globalscale-mirabox/lowlevel.c +++ b/arch/arm/boards/globalscale-mirabox/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_370_mirabox_bb_start - + fdt = __dtb_armada_370_mirabox_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/karo-tx25/lowlevel.c b/arch/arm/boards/karo-tx25/lowlevel.c index b7ff2d4..78e6f4d 100644 --- a/arch/arm/boards/karo-tx25/lowlevel.c +++ b/arch/arm/boards/karo-tx25/lowlevel.c @@ -171,7 +171,7 @@ arm_setup_stack(MX25_IRAM_BASE_ADDR + MX25_IRAM_SIZE - 8); - fdt = __dtb_imx25_karo_tx25_start - get_runtime_offset(); + fdt = __dtb_imx25_karo_tx25_start + get_runtime_offset(); karo_tx25_common_init(fdt); } diff --git a/arch/arm/boards/karo-tx6x/lowlevel.c b/arch/arm/boards/karo-tx6x/lowlevel.c index f2643ef..7b58a49 100644 --- a/arch/arm/boards/karo-tx6x/lowlevel.c +++ b/arch/arm/boards/karo-tx6x/lowlevel.c @@ -53,7 +53,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6dl_tx6u_start - get_runtime_offset(); + fdt = __dtb_imx6dl_tx6u_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_512M, fdt); } @@ -73,7 +73,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6dl_tx6u_start - get_runtime_offset(); + fdt = __dtb_imx6dl_tx6u_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } @@ -93,7 +93,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6q_tx6q_start - get_runtime_offset(); + fdt = __dtb_imx6q_tx6q_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -113,7 +113,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6q_tx6q_start - get_runtime_offset(); + fdt = __dtb_imx6q_tx6q_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } diff --git a/arch/arm/boards/kindle-mx50/lowlevel.c b/arch/arm/boards/kindle-mx50/lowlevel.c index dc321b5..20f86c8 100644 --- a/arch/arm/boards/kindle-mx50/lowlevel.c +++ b/arch/arm/boards/kindle-mx50/lowlevel.c @@ -20,7 +20,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(MX50_IRAM_BASE_ADDR + MX50_IRAM_SIZE - 8); - fdt = __dtb_imx50_kindle_d01100_start - get_runtime_offset(); + fdt = __dtb_imx50_kindle_d01100_start + get_runtime_offset(); barebox_arm_entry(MX50_CSD0_BASE_ADDR, SZ_256M, fdt); } @@ -32,7 +32,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(MX50_IRAM_BASE_ADDR + MX50_IRAM_SIZE - 8); - fdt = __dtb_imx50_kindle_d01200_start - get_runtime_offset(); + fdt = __dtb_imx50_kindle_d01200_start + get_runtime_offset(); barebox_arm_entry(MX50_CSD0_BASE_ADDR, SZ_256M, fdt); } @@ -44,7 +44,7 @@ imx5_cpu_lowlevel_init(); arm_setup_stack(MX50_IRAM_BASE_ADDR + MX50_IRAM_SIZE - 8); - fdt = __dtb_imx50_kindle_ey21_start - get_runtime_offset(); + fdt = __dtb_imx50_kindle_ey21_start + get_runtime_offset(); barebox_arm_entry(MX50_CSD0_BASE_ADDR, SZ_256M, fdt); } diff --git a/arch/arm/boards/lenovo-ix4-300d/lowlevel.c b/arch/arm/boards/lenovo-ix4-300d/lowlevel.c index f8313cd..40145b5 100644 --- a/arch/arm/boards/lenovo-ix4-300d/lowlevel.c +++ b/arch/arm/boards/lenovo-ix4-300d/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_xp_lenovo_ix4_300d_bb_start - + fdt = __dtb_armada_xp_lenovo_ix4_300d_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c b/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c index da6d4aa..e62627c 100644 --- a/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c +++ b/arch/arm/boards/marvell-armada-xp-gp/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_xp_gp_bb_start - get_runtime_offset(); + fdt = __dtb_armada_xp_gp_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); } diff --git a/arch/arm/boards/netgear-rn104/lowlevel.c b/arch/arm/boards/netgear-rn104/lowlevel.c index 97590d8..8a53615 100644 --- a/arch/arm/boards/netgear-rn104/lowlevel.c +++ b/arch/arm/boards/netgear-rn104/lowlevel.c @@ -15,7 +15,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_370_rn104_bb_start - + fdt = __dtb_armada_370_rn104_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/netgear-rn2120/lowlevel.c b/arch/arm/boards/netgear-rn2120/lowlevel.c index 59b9985..e05f2f4 100644 --- a/arch/arm/boards/netgear-rn2120/lowlevel.c +++ b/arch/arm/boards/netgear-rn2120/lowlevel.c @@ -51,7 +51,7 @@ /* Win 0 Control Register: size=0x4000000, wincs=0, en=1 */ writel(0x3fffffe1, base + 0x20184); - fdt = __dtb_armada_xp_rn2120_bb_start - + fdt = __dtb_armada_xp_rn2120_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c index 7e4a9f0..e1132e0 100644 --- a/arch/arm/boards/phytec-phycard-imx27/lowlevel.c +++ b/arch/arm/boards/phytec-phycard-imx27/lowlevel.c @@ -109,7 +109,7 @@ arm_setup_stack(MX27_IRAM_BASE_ADDR + MX27_IRAM_SIZE - 12); - fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start - get_runtime_offset(); + fdt = __dtb_imx27_phytec_phycard_s_rdk_bb_start + get_runtime_offset(); phytec_phycard_imx27_common_init(fdt); } diff --git a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c index b9b2ab5..b858ff3 100644 --- a/arch/arm/boards/phytec-phycore-imx27/lowlevel.c +++ b/arch/arm/boards/phytec-phycore-imx27/lowlevel.c @@ -108,7 +108,7 @@ arm_setup_stack(MX27_IRAM_BASE_ADDR + MX27_IRAM_SIZE - 12); - fdt = __dtb_imx27_phytec_phycore_rdk_start - get_runtime_offset(); + fdt = __dtb_imx27_phytec_phycore_rdk_start + get_runtime_offset(); phytec_phycorce_imx27_common_init(fdt); } diff --git a/arch/arm/boards/phytec-phycore-imx7/lowlevel.c b/arch/arm/boards/phytec-phycore-imx7/lowlevel.c index ee2d7ae..3d2038e 100644 --- a/arch/arm/boards/phytec-phycore-imx7/lowlevel.c +++ b/arch/arm/boards/phytec-phycore-imx7/lowlevel.c @@ -29,7 +29,7 @@ pr_debug("Phytec phyCORE i.MX7\n"); - fdt = __dtb_imx7d_phyboard_zeta_start - get_runtime_offset(); + fdt = __dtb_imx7d_phyboard_zeta_start + get_runtime_offset(); barebox_arm_entry(0x80000000, SZ_512M, fdt); } @@ -45,4 +45,4 @@ barrier(); phytec_phycore_imx7_start(); -} \ No newline at end of file +} diff --git a/arch/arm/boards/phytec-som-am335x/lowlevel.c b/arch/arm/boards/phytec-som-am335x/lowlevel.c index 338d13a..a028449 100644 --- a/arch/arm/boards/phytec-som-am335x/lowlevel.c +++ b/arch/arm/boards/phytec-som-am335x/lowlevel.c @@ -210,7 +210,7 @@ ENTRY_FUNCTION(name, bootinfo, r1, r2) \ { \ extern char __dtb_z_##fdt_name##_start[]; \ - void *fdt = __dtb_z_##fdt_name##_start - \ + void *fdt = __dtb_z_##fdt_name##_start + \ get_runtime_offset(); \ physom_board_entry(bootinfo, 0, fdt, module_family); \ } @@ -219,7 +219,7 @@ ENTRY_FUNCTION(name, bootinfo, r1, r2) \ { \ extern char __dtb_z_##fdt_name##_start[]; \ - void *fdt = __dtb_z_##fdt_name##_start - \ + void *fdt = __dtb_z_##fdt_name##_start + \ get_runtime_offset(); \ physom_board_entry(bootinfo, sdram, fdt, NONE); \ } @@ -228,7 +228,7 @@ ENTRY_FUNCTION(name, r0, r1, r2) \ { \ extern char __dtb_z_##fdt_name##_start[]; \ - void *fdt = __dtb_z_##fdt_name##_start - \ + void *fdt = __dtb_z_##fdt_name##_start + \ get_runtime_offset(); \ am335x_barebox_entry(fdt); \ } diff --git a/arch/arm/boards/phytec-som-imx6/lowlevel.c b/arch/arm/boards/phytec-som-imx6/lowlevel.c index 29811d3..12c3cfa 100644 --- a/arch/arm/boards/phytec-som-imx6/lowlevel.c +++ b/arch/arm/boards/phytec-som-imx6/lowlevel.c @@ -68,7 +68,7 @@ if (do_early_uart_config && IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = fdt_blob_fixed_offset - get_runtime_offset(); + fdt = fdt_blob_fixed_offset + get_runtime_offset(); if (cpu_type == IMX6_CPUTYPE_IMX6UL || cpu_type == IMX6_CPUTYPE_IMX6ULL) diff --git a/arch/arm/boards/phytec-som-rk3288/lowlevel.c b/arch/arm/boards/phytec-som-rk3288/lowlevel.c index 7649ef8..9def80d 100644 --- a/arch/arm/boards/phytec-som-rk3288/lowlevel.c +++ b/arch/arm/boards/phytec-som-rk3288/lowlevel.c @@ -37,7 +37,7 @@ GPIO7C6_UART2DBG_SIN << GPIO7C6_SHIFT); INIT_LL(); } - fdt = __dtb_rk3288_phycore_som_start - get_runtime_offset(); + fdt = __dtb_rk3288_phycore_som_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); } diff --git a/arch/arm/boards/plathome-openblocks-a6/lowlevel.c b/arch/arm/boards/plathome-openblocks-a6/lowlevel.c index 785ec21..31a28c8 100644 --- a/arch/arm/boards/plathome-openblocks-a6/lowlevel.c +++ b/arch/arm/boards/plathome-openblocks-a6/lowlevel.c @@ -25,7 +25,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_kirkwood_openblocks_a6_bb_start - + fdt = __dtb_kirkwood_openblocks_a6_bb_start + get_runtime_offset(); kirkwood_barebox_entry(fdt); diff --git a/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c b/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c index ae3664d..f029bd1 100644 --- a/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c +++ b/arch/arm/boards/plathome-openblocks-ax3/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_xp_openblocks_ax3_4_bb_start - + fdt = __dtb_armada_xp_openblocks_ax3_4_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/qemu-virt64/init.c b/arch/arm/boards/qemu-virt64/init.c index a85bd84..19cfcae 100644 --- a/arch/arm/boards/qemu-virt64/init.c +++ b/arch/arm/boards/qemu-virt64/init.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -61,16 +62,3 @@ return 0; } postcore_initcall(virt_core_init); - -#ifdef CONFIG_MMU -static int virt_mmu_enable(void) -{ - /* Mapping all periph and flash range */ - arch_remap_range((void *)0x00000000, 0x40000000, DEV_MEM); - - mmu_enable(); - - return 0; -} -postmmu_initcall(virt_mmu_enable); -#endif diff --git a/arch/arm/boards/radxa-rock/lowlevel.c b/arch/arm/boards/radxa-rock/lowlevel.c index 1c07bc3..611dc93 100644 --- a/arch/arm/boards/radxa-rock/lowlevel.c +++ b/arch/arm/boards/radxa-rock/lowlevel.c @@ -24,7 +24,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_rk3188_radxarock_start - get_runtime_offset(); + fdt = __dtb_rk3188_radxarock_start + get_runtime_offset(); barebox_arm_entry(0x60000000, SZ_2G, fdt); } diff --git a/arch/arm/boards/raspberry-pi/lowlevel.c b/arch/arm/boards/raspberry-pi/lowlevel.c index 4e71e29..cbc6caa 100644 --- a/arch/arm/boards/raspberry-pi/lowlevel.c +++ b/arch/arm/boards/raspberry-pi/lowlevel.c @@ -7,7 +7,7 @@ extern char __dtb_bcm2835_rpi_start[]; ENTRY_FUNCTION(start_raspberry_pi1, r0, r1, r2) { - void *fdt = __dtb_bcm2835_rpi_start - get_runtime_offset(); + void *fdt = __dtb_bcm2835_rpi_start + get_runtime_offset(); arm_cpu_lowlevel_init(); @@ -17,7 +17,7 @@ extern char __dtb_bcm2836_rpi_2_start[]; ENTRY_FUNCTION(start_raspberry_pi2, r0, r1, r2) { - void *fdt = __dtb_bcm2836_rpi_2_start - get_runtime_offset(); + void *fdt = __dtb_bcm2836_rpi_2_start + get_runtime_offset(); arm_cpu_lowlevel_init(); diff --git a/arch/arm/boards/reflex-achilles/lowlevel.c b/arch/arm/boards/reflex-achilles/lowlevel.c index 1299417..25e7ad0 100644 --- a/arch/arm/boards/reflex-achilles/lowlevel.c +++ b/arch/arm/boards/reflex-achilles/lowlevel.c @@ -33,7 +33,7 @@ puts_ll("SDRAM setup done\n"); - fdt = __dtb_socfpga_arria10_achilles_start - get_runtime_offset(); + fdt = __dtb_socfpga_arria10_achilles_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_2G + SZ_1G, fdt); } diff --git a/arch/arm/boards/solidrun-cubox/lowlevel.c b/arch/arm/boards/solidrun-cubox/lowlevel.c index 071309e..ec63986 100644 --- a/arch/arm/boards/solidrun-cubox/lowlevel.c +++ b/arch/arm/boards/solidrun-cubox/lowlevel.c @@ -29,7 +29,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_dove_cubox_bb_start - get_runtime_offset(); + fdt = __dtb_dove_cubox_bb_start + get_runtime_offset(); dove_barebox_entry(fdt); } diff --git a/arch/arm/boards/solidrun-microsom/lowlevel.c b/arch/arm/boards/solidrun-microsom/lowlevel.c index cc15958..ea204e1 100644 --- a/arch/arm/boards/solidrun-microsom/lowlevel.c +++ b/arch/arm/boards/solidrun-microsom/lowlevel.c @@ -15,7 +15,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_hummingboard_start - get_runtime_offset(); + fdt = __dtb_imx6dl_hummingboard_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -25,7 +25,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_hummingboard_start - get_runtime_offset(); + fdt = __dtb_imx6dl_hummingboard_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -35,7 +35,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_hummingboard_start - get_runtime_offset(); + fdt = __dtb_imx6q_hummingboard_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -45,7 +45,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_hummingboard_start - get_runtime_offset(); + fdt = __dtb_imx6q_hummingboard_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -55,7 +55,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_hummingboard2_start - get_runtime_offset(); + fdt = __dtb_imx6dl_hummingboard2_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -65,7 +65,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6dl_hummingboard2_start - get_runtime_offset(); + fdt = __dtb_imx6dl_hummingboard2_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -75,7 +75,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_hummingboard2_start - get_runtime_offset(); + fdt = __dtb_imx6q_hummingboard2_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -85,7 +85,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_hummingboard2_start - get_runtime_offset(); + fdt = __dtb_imx6q_hummingboard2_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } @@ -95,6 +95,6 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_h100_start - get_runtime_offset(); + fdt = __dtb_imx6q_h100_start + get_runtime_offset(); imx6q_barebox_entry(fdt); } diff --git a/arch/arm/boards/technexion-pico-hobbit/lowlevel.c b/arch/arm/boards/technexion-pico-hobbit/lowlevel.c index f351e67..77f4804 100644 --- a/arch/arm/boards/technexion-pico-hobbit/lowlevel.c +++ b/arch/arm/boards/technexion-pico-hobbit/lowlevel.c @@ -55,7 +55,7 @@ writew(0x0, 0x020c0008); writew(0x0, 0x021e4008); - fdt = fdt_blob_fixed_offset - get_runtime_offset(); + fdt = fdt_blob_fixed_offset + get_runtime_offset(); imx6ul_barebox_entry(fdt); } diff --git a/arch/arm/boards/terasic-de0-nano-soc/lowlevel.c b/arch/arm/boards/terasic-de0-nano-soc/lowlevel.c index 1d5ea6b..dfb8271 100644 --- a/arch/arm/boards/terasic-de0-nano-soc/lowlevel.c +++ b/arch/arm/boards/terasic-de0-nano-soc/lowlevel.c @@ -26,7 +26,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_socfpga_cyclone5_de0_nano_soc_start - get_runtime_offset(); + fdt = __dtb_socfpga_cyclone5_de0_nano_soc_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); } diff --git a/arch/arm/boards/terasic-sockit/lowlevel.c b/arch/arm/boards/terasic-sockit/lowlevel.c index 0a6eb21..05b7d80 100644 --- a/arch/arm/boards/terasic-sockit/lowlevel.c +++ b/arch/arm/boards/terasic-sockit/lowlevel.c @@ -52,7 +52,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_socfpga_cyclone5_sockit_start - get_runtime_offset(); + fdt = __dtb_socfpga_cyclone5_sockit_start + get_runtime_offset(); barebox_arm_entry(0x0, SZ_1G, fdt); } diff --git a/arch/arm/boards/tqma53/lowlevel.c b/arch/arm/boards/tqma53/lowlevel.c index 0cb5952..0d0b168 100644 --- a/arch/arm/boards/tqma53/lowlevel.c +++ b/arch/arm/boards/tqma53/lowlevel.c @@ -51,7 +51,7 @@ imx53_init_lowlevel_early(800); - fdt = __dtb_imx53_mba53_start - get_runtime_offset(); + fdt = __dtb_imx53_mba53_start + get_runtime_offset(); start_imx53_tqma53_common(fdt); } @@ -70,7 +70,7 @@ imx53_init_lowlevel_early(800); - fdt = __dtb_imx53_mba53_start - get_runtime_offset(); + fdt = __dtb_imx53_mba53_start + get_runtime_offset(); start_imx53_tqma53_common(fdt); } diff --git a/arch/arm/boards/tqma6x/lowlevel.c b/arch/arm/boards/tqma6x/lowlevel.c index 52afee4..a90cd40 100644 --- a/arch/arm/boards/tqma6x/lowlevel.c +++ b/arch/arm/boards/tqma6x/lowlevel.c @@ -42,7 +42,7 @@ arm_early_mmu_cache_invalidate(); - fdt = __dtb_imx6q_mba6x_start - get_runtime_offset(); + fdt = __dtb_imx6q_mba6x_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } @@ -63,7 +63,7 @@ arm_early_mmu_cache_invalidate(); - fdt = __dtb_imx6dl_mba6x_start - get_runtime_offset(); + fdt = __dtb_imx6dl_mba6x_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_512M, fdt); } diff --git a/arch/arm/boards/turris-omnia/lowlevel.c b/arch/arm/boards/turris-omnia/lowlevel.c index 3f20908..7236211 100644 --- a/arch/arm/boards/turris-omnia/lowlevel.c +++ b/arch/arm/boards/turris-omnia/lowlevel.c @@ -26,7 +26,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_armada_385_turris_omnia_bb_start - + fdt = __dtb_armada_385_turris_omnia_bb_start + get_runtime_offset(); armada_370_xp_barebox_entry(fdt); diff --git a/arch/arm/boards/udoo/lowlevel.c b/arch/arm/boards/udoo/lowlevel.c index 785ab16..1f06f7e 100644 --- a/arch/arm/boards/udoo/lowlevel.c +++ b/arch/arm/boards/udoo/lowlevel.c @@ -12,7 +12,7 @@ imx6_cpu_lowlevel_init(); - fdt = __dtb_imx6q_udoo_start - get_runtime_offset(); + fdt = __dtb_imx6q_udoo_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/usi-topkick/lowlevel.c b/arch/arm/boards/usi-topkick/lowlevel.c index 4c731e5..4202138 100644 --- a/arch/arm/boards/usi-topkick/lowlevel.c +++ b/arch/arm/boards/usi-topkick/lowlevel.c @@ -28,7 +28,7 @@ arm_cpu_lowlevel_init(); - fdt = __dtb_kirkwood_topkick_bb_start - get_runtime_offset(); + fdt = __dtb_kirkwood_topkick_bb_start + get_runtime_offset(); kirkwood_barebox_entry(fdt); } diff --git a/arch/arm/boards/variscite-mx6/lowlevel.c b/arch/arm/boards/variscite-mx6/lowlevel.c index 5cb738a..337bc58 100644 --- a/arch/arm/boards/variscite-mx6/lowlevel.c +++ b/arch/arm/boards/variscite-mx6/lowlevel.c @@ -50,7 +50,7 @@ if (IS_ENABLED(CONFIG_DEBUG_LL)) setup_uart(); - fdt = __dtb_imx6q_var_custom_start - get_runtime_offset(); + fdt = __dtb_imx6q_var_custom_start + get_runtime_offset(); barebox_arm_entry(0x10000000, SZ_1G, fdt); } diff --git a/arch/arm/boards/vexpress/lowlevel.c b/arch/arm/boards/vexpress/lowlevel.c index 9fe7c83..ac27fbd 100644 --- a/arch/arm/boards/vexpress/lowlevel.c +++ b/arch/arm/boards/vexpress/lowlevel.c @@ -14,7 +14,7 @@ static inline void start_vexpress_common(void *internal_dt) { - void *fdt = internal_dt - get_runtime_offset(); + void *fdt = internal_dt + get_runtime_offset(); unsigned long membase, memsize = SZ_512M; arm_cpu_lowlevel_init(); diff --git a/arch/arm/boards/vscom-baltos/lowlevel.c b/arch/arm/boards/vscom-baltos/lowlevel.c index c4e2341..98bbbaa 100644 --- a/arch/arm/boards/vscom-baltos/lowlevel.c +++ b/arch/arm/boards/vscom-baltos/lowlevel.c @@ -134,7 +134,7 @@ fdt = __dtb_am335x_baltos_minimal_start; - fdt -= get_runtime_offset(); + fdt += get_runtime_offset(); am335x_barebox_entry(fdt); } diff --git a/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c b/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c index fb5e961..22ffdf8 100644 --- a/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c +++ b/arch/arm/boards/zii-imx6q-rdu2/lowlevel.c @@ -308,9 +308,9 @@ rdu2_sram_setup(); if (__imx6_cpu_revision() == IMX_CHIP_REV_2_0) - imx6q_barebox_entry(__dtb_imx6qp_zii_rdu2_start - + imx6q_barebox_entry(__dtb_imx6qp_zii_rdu2_start + get_runtime_offset()); else - imx6q_barebox_entry(__dtb_imx6q_zii_rdu2_start - + imx6q_barebox_entry(__dtb_imx6q_zii_rdu2_start + get_runtime_offset()); } diff --git a/arch/arm/boards/zii-vf610-dev/lowlevel.c b/arch/arm/boards/zii-vf610-dev/lowlevel.c index 95b68d5..c6663c1 100644 --- a/arch/arm/boards/zii-vf610-dev/lowlevel.c +++ b/arch/arm/boards/zii-vf610-dev/lowlevel.c @@ -133,5 +133,5 @@ break; } - barebox_arm_entry(0x80000000, SZ_512M, fdt - get_runtime_offset()); + barebox_arm_entry(0x80000000, SZ_512M, fdt + get_runtime_offset()); } diff --git a/arch/arm/configs/qemu_virt64_defconfig b/arch/arm/configs/qemu_virt64_defconfig index f8128aa..9b7e11f 100644 --- a/arch/arm/configs/qemu_virt64_defconfig +++ b/arch/arm/configs/qemu_virt64_defconfig @@ -1,11 +1,8 @@ +CONFIG_TEXT_BASE=0x41000000 CONFIG_ARCH_QEMU=y -CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x05000000 -CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y CONFIG_MMU=y # CONFIG_MMU_EARLY is not set -CONFIG_TEXT_BASE=0x41000000 -CONFIG_BAREBOX_MAX_BARE_INIT_SIZE=0x01000000 CONFIG_PROMPT="qemu-virt64: " CONFIG_GLOB=y CONFIG_HUSH_FANCY_PROMPT=y diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile index 13fe12c..0316d25 100644 --- a/arch/arm/cpu/Makefile +++ b/arch/arm/cpu/Makefile @@ -1,26 +1,13 @@ obj-y += cpu.o -ifeq ($(CONFIG_CPU_64v8), y) -obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions_64.o -obj-$(CONFIG_MMU) += mmu_64.o -lwl-y += lowlevel_64.o -else -obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions.o -obj-$(CONFIG_MMU) += mmu.o mmu-early.o -pbl-$(CONFIG_MMU) += mmu-early.o -lwl-y += lowlevel.o -endif +obj-$(CONFIG_ARM_EXCEPTIONS) += exceptions$(S64).o interrupts$(S64).o +obj-$(CONFIG_MMU) += mmu$(S64).o +lwl-y += lowlevel$(S64).o +obj-pbl-$(CONFIG_MMU) += mmu-early$(S64).o -obj-$(CONFIG_ARM_EXCEPTIONS) += interrupts.o obj-y += start.o entry.o -ifeq ($(CONFIG_CPU_64v8), y) -obj-y += setupc_64.o -pbl-y += setupc_64.o -else -obj-y += setupc.o -pbl-y += setupc.o -endif +obj-pbl-y += setupc$(S64).o cache$(S64).o # # Any variants can be called as start-armxyz.S @@ -28,7 +15,6 @@ obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o obj-$(CONFIG_OFDEVICE) += dtb.o -obj-$(CONFIG_MMU) += cache.o ifeq ($(CONFIG_MMU),) obj-y += no-mmu.o @@ -40,25 +26,19 @@ obj-$(CONFIG_ARM_SECURE_MONITOR) += sm.o sm_as.o AFLAGS_sm_as.o :=-Wa,-march=armv7-a -obj-$(CONFIG_CPU_32v4T) += cache-armv4.o -pbl-$(CONFIG_CPU_32v4T) += cache-armv4.o -obj-$(CONFIG_CPU_32v5) += cache-armv5.o -pbl-$(CONFIG_CPU_32v5) += cache-armv5.o -obj-$(CONFIG_CPU_32v6) += cache-armv6.o -pbl-$(CONFIG_CPU_32v6) += cache-armv6.o +obj-pbl-$(CONFIG_CPU_32v4T) += cache-armv4.o +obj-pbl-$(CONFIG_CPU_32v5) += cache-armv5.o +obj-pbl-$(CONFIG_CPU_32v6) += cache-armv6.o AFLAGS_cache-armv7.o :=-Wa,-march=armv7-a -obj-$(CONFIG_CPU_32v7) += cache-armv7.o +obj-pbl-$(CONFIG_CPU_32v7) += cache-armv7.o AFLAGS_pbl-cache-armv7.o :=-Wa,-march=armv7-a -pbl-$(CONFIG_CPU_32v7) += cache-armv7.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o AFLAGS_cache-armv8.o :=-Wa,-march=armv8-a -obj-$(CONFIG_CPU_64v8) += cache-armv8.o +obj-pbl-$(CONFIG_CPU_64v8) += cache-armv8.o AFLAGS_pbl-cache-armv8.o :=-Wa,-march=armv8-a -pbl-$(CONFIG_CPU_64v8) += cache-armv8.o pbl-y += entry.o pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o pbl-$(CONFIG_PBL_MULTI_IMAGES) += uncompress.o -obj-y += common.o cache.o -pbl-y += common.o cache.o +obj-pbl-y += common.o sections.o diff --git a/arch/arm/cpu/cache-armv4.S b/arch/arm/cpu/cache-armv4.S index 1d1a1e3..db87de1 100644 --- a/arch/arm/cpu/cache-armv4.S +++ b/arch/arm/cpu/cache-armv4.S @@ -3,7 +3,7 @@ #define CACHE_DLINESIZE 32 -.section .text.__mmu_cache_on +.section .text.v4_mmu_cache_on ENTRY(v4_mmu_cache_on) mov r12, lr #ifdef CONFIG_MMU diff --git a/arch/arm/cpu/cache-armv8.S b/arch/arm/cpu/cache-armv8.S index 82b2f81..3e21b35 100644 --- a/arch/arm/cpu/cache-armv8.S +++ b/arch/arm/cpu/cache-armv8.S @@ -148,6 +148,25 @@ ret ENDPROC(v8_flush_dcache_range) +.section .text.v8_inv_dcache_range +ENTRY(v8_inv_dcache_range) + mrs x3, ctr_el0 + lsr x3, x3, #16 + and x3, x3, #0xf + mov x2, #4 + lsl x2, x2, x3 /* cache line size */ + + /* x2 <- minimal cache line size in cache system */ + sub x3, x2, #1 + bic x0, x0, x3 +1: dc ivac, x0 /* invalidate data or unified cache */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(v8_inv_dcache_range) + /* * void v8_invalidate_icache_all(void) * diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c index 929c385..7047470 100644 --- a/arch/arm/cpu/cache.c +++ b/arch/arm/cpu/cache.c @@ -102,11 +102,6 @@ cache_fns = &cache_fns_armv7; break; #endif -#ifdef CONFIG_CPU_64v8 - case CPU_ARCH_ARMv8: - cache_fns = &cache_fns_armv8; - break; -#endif default: while(1); } @@ -144,11 +139,6 @@ v7_mmu_cache_flush(); return; #endif -#ifdef CONFIG_CPU_64v8 - case CPU_ARCH_ARMv8: - v8_dcache_all(); - return; -#endif } } @@ -171,12 +161,6 @@ v7_mmu_cache_invalidate(); return; #endif -#else -#ifdef CONFIG_CPU_64v8 - case CPU_ARCH_ARMv8: - v8_invalidate_icache_all(); - return; -#endif #endif } } diff --git a/arch/arm/cpu/cache_64.c b/arch/arm/cpu/cache_64.c new file mode 100644 index 0000000..45f01e8 --- /dev/null +++ b/arch/arm/cpu/cache_64.c @@ -0,0 +1,35 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include +#include +#include +#include + +int arm_set_cache_functions(void) +{ + return 0; +} + +/* + * Early function to flush the caches. This is for use when the + * C environment is not yet fully initialized. + */ +void arm_early_mmu_cache_flush(void) +{ + v8_flush_dcache_all(); +} + +void arm_early_mmu_cache_invalidate(void) +{ + v8_invalidate_icache_all(); +} diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index 7d74996..00ce3ef 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -17,50 +17,90 @@ #include #include +#include #include #include #include #include #include #include -#include #include +#include + +#define R_ARM_RELATIVE 23 +#define R_AARCH64_RELATIVE 1027 /* * relocate binary to the currently running address */ void relocate_to_current_adr(void) { - uint32_t offset; - uint32_t *dstart, *dend, *dynsym, *dynend; + unsigned long offset, offset_var; + unsigned long __maybe_unused *dynsym, *dynend; + void *dstart, *dend; /* Get offset between linked address and runtime address */ offset = get_runtime_offset(); + offset_var = global_variable_offset(); - dstart = (void *)(ld_var(__rel_dyn_start) - offset); - dend = (void *)(ld_var(__rel_dyn_end) - offset); + dstart = (void *)__rel_dyn_start + offset_var; + dend = (void *)__rel_dyn_end + offset_var; - dynsym = (void *)(ld_var(__dynsym_start) - offset); - dynend = (void *)(ld_var(__dynsym_end) - offset); - +#if defined(CONFIG_CPU_64) while (dstart < dend) { - uint32_t *fixup = (uint32_t *)(*dstart - offset); - uint32_t type = *(dstart + 1); + struct elf64_rela *rel = dstart; - if ((type & 0xff) == 0x17) { - *fixup = *fixup - offset; + if (ELF64_R_TYPE(rel->r_info) == R_AARCH64_RELATIVE) { + unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + + *fixup = rel->r_addend + offset; } else { - int index = type >> 8; - uint32_t r = dynsym[index * 4 + 1]; - - *fixup = *fixup + r - offset; + putc_ll('>'); + puthex_ll(rel->r_info); + putc_ll(' '); + puthex_ll(rel->r_offset); + putc_ll(' '); + puthex_ll(rel->r_addend); + putc_ll('\n'); + panic(""); } - *dstart -= offset; - dstart += 2; + dstart += sizeof(*rel); + } +#elif defined(CONFIG_CPU_32) + dynsym = (void *)__dynsym_start + offset_var; + dynend = (void *)__dynsym_end + offset_var; + + while (dstart < dend) { + struct elf32_rel *rel = dstart; + + if (ELF32_R_TYPE(rel->r_info) == R_ARM_RELATIVE) { + unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + + *fixup = *fixup + offset; + + rel->r_offset += offset; + } else if (ELF32_R_TYPE(rel->r_info) == R_ARM_ABS32) { + unsigned long r = dynsym[ELF32_R_SYM(rel->r_info) * 4 + 1]; + unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + + *fixup = *fixup + r + offset; + } else { + putc_ll('>'); + puthex_ll(rel->r_info); + putc_ll(' '); + puthex_ll(rel->r_offset); + putc_ll('\n'); + panic(""); + } + + dstart += sizeof(*rel); } memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); +#else +#error "Architecture not specified" +#endif arm_early_mmu_cache_flush(); icache_invalidate(); @@ -78,6 +118,3 @@ return __cpu_architecture; } #endif - -char __image_start[0] __attribute__((section(".__image_start"))); -char __image_end[0] __attribute__((section(".__image_end"))); \ No newline at end of file diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c index bf604fd..c5daf6c 100644 --- a/arch/arm/cpu/cpu.c +++ b/arch/arm/cpu/cpu.c @@ -68,26 +68,27 @@ return (get_cr () & CR_I) != 0; } -#if __LINUX_ARM_ARCH__ <= 7 /* * SoC like the ux500 have the l2x0 always enable * with or without MMU enable */ struct outer_cache_fns outer_cache; -/* - * Clean and invalide caches, disable MMU - */ -void mmu_disable(void) +static void disable_interrupts(void) { - __mmu_cache_flush(); - if (outer_cache.disable) { - outer_cache.flush_all(); - outer_cache.disable(); - } - __mmu_cache_off(); -} +#if __LINUX_ARM_ARCH__ <= 7 + uint32_t r; + + /* + * barebox normally does not use interrupts, but some functionalities + * (eg. OMAP4_USBBOOT) require them enabled. So be sure interrupts are + * disabled before exiting. + */ + __asm__ __volatile__("mrs %0, cpsr" : "=r"(r)); + r |= PSR_I_BIT; + __asm__ __volatile__("msr cpsr, %0" : : "r"(r)); #endif +} /** * Disable MMU and D-cache, flush caches @@ -98,23 +99,13 @@ */ static void arch_shutdown(void) { - uint32_t r; #ifdef CONFIG_MMU mmu_disable(); #endif icache_invalidate(); -#if __LINUX_ARM_ARCH__ <= 7 - /* - * barebox normally does not use interrupts, but some functionalities - * (eg. OMAP4_USBBOOT) require them enabled. So be sure interrupts are - * disabled before exiting. - */ - __asm__ __volatile__("mrs %0, cpsr" : "=r"(r)); - r |= PSR_I_BIT; - __asm__ __volatile__("msr cpsr, %0" : : "r"(r)); -#endif + disable_interrupts(); } archshutdown_exitcall(arch_shutdown); diff --git a/arch/arm/cpu/entry.c b/arch/arm/cpu/entry.c index 33b1429..b48c1ca 100644 --- a/arch/arm/cpu/entry.c +++ b/arch/arm/cpu/entry.c @@ -24,7 +24,7 @@ * be fine. */ -void __naked __noreturn barebox_arm_entry(unsigned long membase, +void NAKED __noreturn barebox_arm_entry(unsigned long membase, unsigned long memsize, void *boarddata) { arm_setup_stack(arm_mem_stack_top(membase, membase + memsize) - 16); diff --git a/arch/arm/cpu/exceptions_64.S b/arch/arm/cpu/exceptions_64.S index 5812025..22034ea 100644 --- a/arch/arm/cpu/exceptions_64.S +++ b/arch/arm/cpu/exceptions_64.S @@ -7,6 +7,7 @@ #include #include +#include #include /* @@ -31,22 +32,18 @@ stp x3, x4, [sp, #-16]! stp x1, x2, [sp, #-16]! - /* Could be running at EL3/EL2/EL1 */ - mrs x11, CurrentEL - cmp x11, #0xC /* Check EL3 state */ - b.eq 1f - cmp x11, #0x8 /* Check EL2 state */ - b.eq 2f - cmp x11, #0x4 /* Check EL1 state */ - b.eq 3f + switch_el x11, 3f, 2f, 1f 3: mrs x1, esr_el3 mrs x2, elr_el3 + mrs x3, far_el3 b 0f 2: mrs x1, esr_el2 mrs x2, elr_el2 + mrs x3, far_el2 b 0f 1: mrs x1, esr_el1 mrs x2, elr_el1 + mrs x3, far_el1 0: stp x2, x0, [sp, #-16]! mov x0, sp @@ -86,34 +83,69 @@ _do_bad_sync: exception_entry bl do_bad_sync + b exception_exit _do_bad_irq: exception_entry bl do_bad_irq + b exception_exit _do_bad_fiq: exception_entry bl do_bad_fiq + b exception_exit _do_bad_error: exception_entry bl do_bad_error + b exception_exit _do_sync: exception_entry + mov x2, x3 bl do_sync + b exception_exit _do_irq: exception_entry bl do_irq + b exception_exit _do_fiq: exception_entry bl do_fiq + b exception_exit _do_error: exception_entry bl do_error + b exception_exit + +exception_exit: + ldp x2, x0, [sp],#16 + switch_el x11, 3f, 2f, 1f +3: msr elr_el3, x2 + b 0f +2: msr elr_el2, x2 + b 0f +1: msr elr_el1, x2 +0: + ldp x1, x2, [sp],#16 + ldp x3, x4, [sp],#16 + ldp x5, x6, [sp],#16 + ldp x7, x8, [sp],#16 + ldp x9, x10, [sp],#16 + ldp x11, x12, [sp],#16 + ldp x13, x14, [sp],#16 + ldp x15, x16, [sp],#16 + ldp x17, x18, [sp],#16 + ldp x19, x20, [sp],#16 + ldp x21, x22, [sp],#16 + ldp x23, x24, [sp],#16 + ldp x25, x26, [sp],#16 + ldp x27, x28, [sp],#16 + ldp x29, x30, [sp],#16 + eret .section .data .align 4 diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c index c34108a..73f023b 100644 --- a/arch/arm/cpu/interrupts.c +++ b/arch/arm/cpu/interrupts.c @@ -26,9 +26,8 @@ #include #include #include +#include - -#if __LINUX_ARM_ARCH__ <= 7 /** * Display current register set content * @param[in] regs Guess what @@ -72,13 +71,10 @@ unwind_backtrace(regs); #endif } -#endif static void __noreturn do_exception(struct pt_regs *pt_regs) { -#if __LINUX_ARM_ARCH__ <= 7 show_regs(pt_regs); -#endif panic(""); } @@ -126,8 +122,6 @@ */ void do_data_abort (struct pt_regs *pt_regs) { - -#if __LINUX_ARM_ARCH__ <= 7 u32 far; asm volatile ("mrc p15, 0, %0, c6, c0, 0" : "=r" (far) : : "cc"); @@ -135,7 +129,6 @@ printf("unable to handle %s at address 0x%08x\n", far < PAGE_SIZE ? "NULL pointer dereference" : "paging request", far); -#endif do_exception(pt_regs); } @@ -164,45 +157,6 @@ do_exception(pt_regs); } -#ifdef CONFIG_CPU_64v8 -void do_bad_sync(struct pt_regs *pt_regs) -{ - printf("bad sync\n"); - do_exception(pt_regs); -} - -void do_bad_irq(struct pt_regs *pt_regs) -{ - printf("bad irq\n"); - do_exception(pt_regs); -} - -void do_bad_fiq(struct pt_regs *pt_regs) -{ - printf("bad fiq\n"); - do_exception(pt_regs); -} - -void do_bad_error(struct pt_regs *pt_regs) -{ - printf("bad error\n"); - do_exception(pt_regs); -} - -void do_sync(struct pt_regs *pt_regs) -{ - printf("sync exception\n"); - do_exception(pt_regs); -} - - -void do_error(struct pt_regs *pt_regs) -{ - printf("error exception\n"); - do_exception(pt_regs); -} -#endif - extern volatile int arm_ignore_data_abort; extern volatile int arm_data_abort_occurred; diff --git a/arch/arm/cpu/interrupts_64.c b/arch/arm/cpu/interrupts_64.c new file mode 100644 index 0000000..32c8dfc --- /dev/null +++ b/arch/arm/cpu/interrupts_64.c @@ -0,0 +1,198 @@ +/* + * interrupts_64.c - Interrupt Support Routines + * + * Copyright (c) 2018 Sascha Hauer , Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static const char *esr_class_str[] = { + [0 ... ESR_ELx_EC_MAX] = "UNRECOGNIZED EC", + [ESR_ELx_EC_UNKNOWN] = "Unknown/Uncategorized", + [ESR_ELx_EC_WFx] = "WFI/WFE", + [ESR_ELx_EC_CP15_32] = "CP15 MCR/MRC", + [ESR_ELx_EC_CP15_64] = "CP15 MCRR/MRRC", + [ESR_ELx_EC_CP14_MR] = "CP14 MCR/MRC", + [ESR_ELx_EC_CP14_LS] = "CP14 LDC/STC", + [ESR_ELx_EC_FP_ASIMD] = "ASIMD", + [ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS", + [ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC", + [ESR_ELx_EC_ILL] = "PSTATE.IL", + [ESR_ELx_EC_SVC32] = "SVC (AArch32)", + [ESR_ELx_EC_HVC32] = "HVC (AArch32)", + [ESR_ELx_EC_SMC32] = "SMC (AArch32)", + [ESR_ELx_EC_SVC64] = "SVC (AArch64)", + [ESR_ELx_EC_HVC64] = "HVC (AArch64)", + [ESR_ELx_EC_SMC64] = "SMC (AArch64)", + [ESR_ELx_EC_SYS64] = "MSR/MRS (AArch64)", + [ESR_ELx_EC_IMP_DEF] = "EL3 IMP DEF", + [ESR_ELx_EC_IABT_LOW] = "IABT (lower EL)", + [ESR_ELx_EC_IABT_CUR] = "IABT (current EL)", + [ESR_ELx_EC_PC_ALIGN] = "PC Alignment", + [ESR_ELx_EC_DABT_LOW] = "DABT (lower EL)", + [ESR_ELx_EC_DABT_CUR] = "DABT (current EL)", + [ESR_ELx_EC_SP_ALIGN] = "SP Alignment", + [ESR_ELx_EC_FP_EXC32] = "FP (AArch32)", + [ESR_ELx_EC_FP_EXC64] = "FP (AArch64)", + [ESR_ELx_EC_SERROR] = "SError", + [ESR_ELx_EC_BREAKPT_LOW] = "Breakpoint (lower EL)", + [ESR_ELx_EC_BREAKPT_CUR] = "Breakpoint (current EL)", + [ESR_ELx_EC_SOFTSTP_LOW] = "Software Step (lower EL)", + [ESR_ELx_EC_SOFTSTP_CUR] = "Software Step (current EL)", + [ESR_ELx_EC_WATCHPT_LOW] = "Watchpoint (lower EL)", + [ESR_ELx_EC_WATCHPT_CUR] = "Watchpoint (current EL)", + [ESR_ELx_EC_BKPT32] = "BKPT (AArch32)", + [ESR_ELx_EC_VECTOR32] = "Vector catch (AArch32)", + [ESR_ELx_EC_BRK64] = "BRK (AArch64)", +}; + +const char *esr_get_class_string(u32 esr) +{ + return esr_class_str[esr >> ESR_ELx_EC_SHIFT]; +} + +/** + * Display current register set content + * @param[in] regs Guess what + */ +void show_regs(struct pt_regs *regs) +{ + int i; + + printf("elr: %016lx lr : %016lx\n", regs->elr, regs->regs[30]); + + for (i = 0; i < 29; i += 2) + printf("x%-2d: %016lx x%-2d: %016lx\n", + i, regs->regs[i], i + 1, regs->regs[i + 1]); + printf("\n"); +} + +static void __noreturn do_exception(struct pt_regs *pt_regs) +{ + show_regs(pt_regs); + + unwind_backtrace(pt_regs); + + panic("panic: unhandled exception"); +} + +/** + * The CPU catches a fast interrupt request. + * @param[in] pt_regs Register set content when the interrupt happens + * + * We never enable FIQs, so this should not happen + */ +void do_fiq(struct pt_regs *pt_regs) +{ + printf ("fast interrupt request\n"); + do_exception(pt_regs); +} + +/** + * The CPU catches a regular interrupt. + * @param[in] pt_regs Register set content when the interrupt happens + * + * We never enable interrupts, so this should not happen + */ +void do_irq(struct pt_regs *pt_regs) +{ + printf ("interrupt request\n"); + do_exception(pt_regs); +} + +void do_bad_sync(struct pt_regs *pt_regs) +{ + printf("bad sync\n"); + do_exception(pt_regs); +} + +void do_bad_irq(struct pt_regs *pt_regs) +{ + printf("bad irq\n"); + do_exception(pt_regs); +} + +void do_bad_fiq(struct pt_regs *pt_regs) +{ + printf("bad fiq\n"); + do_exception(pt_regs); +} + +void do_bad_error(struct pt_regs *pt_regs) +{ + printf("bad error\n"); + do_exception(pt_regs); +} + +extern volatile int arm_ignore_data_abort; +extern volatile int arm_data_abort_occurred; + +void do_sync(struct pt_regs *pt_regs, unsigned int esr, unsigned long far) +{ + if ((esr >> ESR_ELx_EC_SHIFT) == ESR_ELx_EC_DABT_CUR && + arm_ignore_data_abort) { + arm_data_abort_occurred = 1; + pt_regs->elr += 4; + return; + } + + printf("%s exception at 0x%016lx\n", esr_get_class_string(esr), far); + do_exception(pt_regs); +} + + +void do_error(struct pt_regs *pt_regs) +{ + printf("error exception\n"); + do_exception(pt_regs); +} + +void data_abort_mask(void) +{ + arm_data_abort_occurred = 0; + arm_ignore_data_abort = 1; +} + +int data_abort_unmask(void) +{ + arm_ignore_data_abort = 0; + + return arm_data_abort_occurred != 0; +} + +extern unsigned long vectors; + +static int aarch64_init_vectors(void) +{ + unsigned int el; + + el = current_el(); + if (el == 1) + asm volatile("msr vbar_el1, %0" : : "r" (&vectors) : "cc"); + else if (el == 2) + asm volatile("msr vbar_el2, %0" : : "r" (&vectors) : "cc"); + else + asm volatile("msr vbar_el3, %0" : : "r" (&vectors) : "cc"); + + return 0; +} +pure_initcall(aarch64_init_vectors); diff --git a/arch/arm/cpu/lowlevel_64.S b/arch/arm/cpu/lowlevel_64.S index 4850895..af1cd8b 100644 --- a/arch/arm/cpu/lowlevel_64.S +++ b/arch/arm/cpu/lowlevel_64.S @@ -1,20 +1,13 @@ #include #include #include +#include .section ".text_bare_init_","ax" ENTRY(arm_cpu_lowlevel_init) - adr x0, vectors - mrs x1, CurrentEL - cmp x1, #0xC /* Check EL3 state */ - b.eq 1f - cmp x1, #0x8 /* Check EL2 state */ - b.eq 2f - cmp x1, #0x4 /* Check EL1 state */ - b.eq 3f + switch_el x1, 3f, 2f, 1f -1: - msr vbar_el3, x0 +3: mov x0, #1 /* Non-Secure EL0/1 */ orr x0, x0, #(1 << 10) /* 64-bit EL2 */ msr scr_el3, x0 @@ -22,14 +15,12 @@ b done 2: - msr vbar_el2, x0 mov x0, #0x33ff /* Enable FP/SIMD */ msr cptr_el2, x0 b done -3: - msr vbar_el1, x0 +1: mov x0, #(3 << 20) /* Enable FP/SIMD */ msr cpacr_el1, x0 b done diff --git a/arch/arm/cpu/mmu-early.c b/arch/arm/cpu/mmu-early.c index 2e4d316..70cb5fe 100644 --- a/arch/arm/cpu/mmu-early.c +++ b/arch/arm/cpu/mmu-early.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "mmu.h" @@ -29,7 +30,8 @@ PMD_SECT_AP_READ | PMD_TYPE_SECT | PMD_SECT_WB); } -void mmu_early_enable(uint32_t membase, uint32_t memsize, uint32_t _ttb) +void mmu_early_enable(unsigned long membase, unsigned long memsize, + unsigned long _ttb) { int i; diff --git a/arch/arm/cpu/mmu-early.h b/arch/arm/cpu/mmu-early.h deleted file mode 100644 index af21f52..0000000 --- a/arch/arm/cpu/mmu-early.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ARM_CPU_MMU_EARLY_H -#define __ARM_CPU_MMU_EARLY_H - -void mmu_early_enable(uint32_t membase, uint32_t memsize, uint32_t ttb); - -#endif /* __ARM_CPU_MMU_EARLY_H */ diff --git a/arch/arm/cpu/mmu-early_64.c b/arch/arm/cpu/mmu-early_64.c new file mode 100644 index 0000000..f07d107 --- /dev/null +++ b/arch/arm/cpu/mmu-early_64.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "mmu_64.h" + +static void create_sections(void *ttb, uint64_t virt, uint64_t phys, + uint64_t size, uint64_t attr) +{ + uint64_t block_size; + uint64_t block_shift; + uint64_t *pte; + uint64_t idx; + uint64_t addr; + uint64_t *table; + + addr = virt; + + attr &= ~PTE_TYPE_MASK; + + table = ttb; + + while (1) { + block_shift = level2shift(1); + idx = (addr & level2mask(1)) >> block_shift; + block_size = (1ULL << block_shift); + + pte = table + idx; + + *pte = phys | attr | PTE_TYPE_BLOCK; + + if (size < block_size) + break; + + addr += block_size; + phys += block_size; + size -= block_size; + } +} + +void mmu_early_enable(unsigned long membase, unsigned long memsize, + unsigned long ttb) +{ + int el; + + /* + * For the early code we only create level 1 pagetables which only + * allow for a 1GiB granularity. If our membase is not aligned to that + * bail out without enabling the MMU. + */ + if (membase & ((1ULL << level2shift(1)) - 1)) + return; + + memset((void *)ttb, 0, GRANULE_SIZE); + + el = current_el(); + set_ttbr_tcr_mair(el, ttb, calc_tcr(el), MEMORY_ATTRIBUTES); + create_sections((void *)ttb, 0, 0, 1UL << (BITS_PER_VA - 1), UNCACHED_MEM); + create_sections((void *)ttb, membase, membase, memsize, CACHED_MEM); + tlb_invalidate(); + isb(); + set_cr(get_cr() | CR_M); +} + +void mmu_early_disable(void) +{ + unsigned int cr; + + cr = get_cr(); + cr &= ~(CR_M | CR_C); + + set_cr(cr); + v8_flush_dcache_all(); + tlb_invalidate(); + + dsb(); + isb(); +} \ No newline at end of file diff --git a/arch/arm/cpu/mmu.c b/arch/arm/cpu/mmu.c index 459abe5..6ccd589 100644 --- a/arch/arm/cpu/mmu.c +++ b/arch/arm/cpu/mmu.c @@ -27,11 +27,16 @@ #include #include #include +#include #include #include +#include #include "mmu.h" +#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT) +#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED) + static unsigned long *ttb; static void create_sections(unsigned long virt, unsigned long phys, int size_m, @@ -507,6 +512,19 @@ } mmu_initcall(mmu_init); +/* + * Clean and invalide caches, disable MMU + */ +void mmu_disable(void) +{ + __mmu_cache_flush(); + if (outer_cache.disable) { + outer_cache.flush_all(); + outer_cache.disable(); + } + __mmu_cache_off(); +} + void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) { void *ret; @@ -557,7 +575,7 @@ free(mem); } -void dma_sync_single_for_cpu(unsigned long address, size_t size, +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) { if (dir != DMA_TO_DEVICE) { @@ -567,7 +585,7 @@ } } -void dma_sync_single_for_device(unsigned long address, size_t size, +void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { if (dir == DMA_FROM_DEVICE) { @@ -580,3 +598,19 @@ outer_cache.clean_range(address, address + size); } } + +dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + unsigned long addr = (unsigned long)ptr; + + dma_sync_single_for_device(addr, size, dir); + + return addr; +} + +void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) +{ + dma_sync_single_for_cpu(addr, size, dir); +} diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h index 186d408..79ebc80 100644 --- a/arch/arm/cpu/mmu.h +++ b/arch/arm/cpu/mmu.h @@ -1,60 +1,6 @@ #ifndef __ARM_MMU_H #define __ARM_MMU_H -#ifdef CONFIG_CPU_64v8 - -#define TCR_FLAGS (TCR_TG0_4K | \ - TCR_SHARED_OUTER | \ - TCR_SHARED_INNER | \ - TCR_IRGN_WBWA | \ - TCR_ORGN_WBWA | \ - TCR_T0SZ(BITS_PER_VA)) - -#ifndef __ASSEMBLY__ - -static inline void set_ttbr_tcr_mair(int el, uint64_t table, uint64_t tcr, uint64_t attr) -{ - asm volatile("dsb sy"); - if (el == 1) { - asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory"); - asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory"); - asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory"); - } else if (el == 2) { - asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory"); - asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory"); - asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory"); - } else if (el == 3) { - asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory"); - asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory"); - asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory"); - } else { - hang(); - } - asm volatile("isb"); -} - -static inline uint64_t get_ttbr(int el) -{ - uint64_t val; - if (el == 1) { - asm volatile("mrs %0, ttbr0_el1" : "=r" (val)); - } else if (el == 2) { - asm volatile("mrs %0, ttbr0_el2" : "=r" (val)); - } else if (el == 3) { - asm volatile("mrs %0, ttbr0_el3" : "=r" (val)); - } else { - hang(); - } - - return val; -} - -void mmu_early_enable(uint64_t membase, uint64_t memsize, uint64_t _ttb); - -#endif - -#endif /* CONFIG_CPU_64v8 */ - #ifdef CONFIG_MMU void __mmu_cache_on(void); void __mmu_cache_off(void); diff --git a/arch/arm/cpu/mmu_64.c b/arch/arm/cpu/mmu_64.c index bfd80c0..8355a4c 100644 --- a/arch/arm/cpu/mmu_64.c +++ b/arch/arm/cpu/mmu_64.c @@ -25,16 +25,16 @@ #include #include #include +#include #include #include #include #include #include -#include "mmu.h" +#include "mmu_64.h" static uint64_t *ttb; -static int free_idx; static void arm_mmu_not_initialized_error(void) { @@ -47,86 +47,25 @@ panic("MMU not initialized\n"); } - -/* - * Do it the simple way for now and invalidate the entire - * tlb - */ -static inline void tlb_invalidate(void) -{ - unsigned int el = current_el(); - - dsb(); - - if (el == 1) - __asm__ __volatile__("tlbi vmalle1\n\t" : : : "memory"); - else if (el == 2) - __asm__ __volatile__("tlbi alle2\n\t" : : : "memory"); - else if (el == 3) - __asm__ __volatile__("tlbi alle3\n\t" : : : "memory"); - - dsb(); - isb(); -} - -static int level2shift(int level) -{ - /* Page is 12 bits wide, every level translates 9 bits */ - return (12 + 9 * (3 - level)); -} - -static uint64_t level2mask(int level) -{ - uint64_t mask = -EINVAL; - - if (level == 1) - mask = L1_ADDR_MASK; - else if (level == 2) - mask = L2_ADDR_MASK; - else if (level == 3) - mask = L3_ADDR_MASK; - - return mask; -} - -static int pte_type(uint64_t *pte) -{ - return *pte & PMD_TYPE_MASK; -} - static void set_table(uint64_t *pt, uint64_t *table_addr) { uint64_t val; - val = PMD_TYPE_TABLE | (uint64_t)table_addr; + val = PTE_TYPE_TABLE | (uint64_t)table_addr; *pt = val; } static uint64_t *create_table(void) { - uint64_t *new_table = ttb + free_idx * GRANULE_SIZE; + uint64_t *new_table = xmemalign(GRANULE_SIZE, GRANULE_SIZE); /* Mark all entries as invalid */ memset(new_table, 0, GRANULE_SIZE); - free_idx++; - return new_table; } -static uint64_t *get_level_table(uint64_t *pte) -{ - uint64_t *table = (uint64_t *)(*pte & XLAT_ADDR_MASK); - - if (pte_type(pte) != PMD_TYPE_TABLE) { - table = create_table(); - set_table(pte, table); - } - - return table; -} - -static uint64_t *find_pte(uint64_t addr) +static __maybe_unused uint64_t *find_pte(uint64_t addr) { uint64_t *pte; uint64_t block_shift; @@ -140,7 +79,7 @@ idx = (addr & level2mask(i)) >> block_shift; pte += idx; - if ((pte_type(pte) != PMD_TYPE_TABLE) || (block_shift <= GRANULE_SIZE_SHIFT)) + if ((pte_type(pte) != PTE_TYPE_TABLE) || (block_shift <= GRANULE_SIZE_SHIFT)) break; else pte = (uint64_t *)(*pte & XLAT_ADDR_MASK); @@ -149,6 +88,36 @@ return pte; } +#define MAX_PTE_ENTRIES 512 + +/* Splits a block PTE into table with subpages spanning the old block */ +static void split_block(uint64_t *pte, int level) +{ + uint64_t old_pte = *pte; + uint64_t *new_table; + uint64_t i = 0; + int levelshift; + + if ((*pte & PTE_TYPE_MASK) == PTE_TYPE_TABLE) + return; + + /* level describes the parent level, we need the child ones */ + levelshift = level2shift(level + 1); + + new_table = create_table(); + + for (i = 0; i < MAX_PTE_ENTRIES; i++) { + new_table[i] = old_pte | (i << levelshift); + + /* Level 3 block PTEs have the table type */ + if ((level + 1) == 3) + new_table[i] |= PTE_TYPE_TABLE; + } + + /* Set the new table into effect */ + set_table(pte, new_table); +} + static void map_region(uint64_t virt, uint64_t phys, uint64_t size, uint64_t attr) { uint64_t block_size; @@ -164,29 +133,29 @@ addr = virt; - attr &= ~(PMD_TYPE_SECT); + attr &= ~PTE_TYPE_MASK; while (size) { table = ttb; for (level = 1; level < 4; level++) { block_shift = level2shift(level); idx = (addr & level2mask(level)) >> block_shift; - block_size = (1 << block_shift); + block_size = (1ULL << block_shift); pte = table + idx; - if (level == 3) - attr |= PTE_TYPE_PAGE; - else - attr |= PMD_TYPE_SECT; - if (size >= block_size && IS_ALIGNED(addr, block_size)) { - *pte = phys | attr; + if (level == 3) + *pte = phys | attr | PTE_TYPE_PAGE; + else + *pte = phys | attr | PTE_TYPE_BLOCK; + addr += block_size; phys += block_size; size -= block_size; break; - + } else { + split_block(pte, level); } table = get_level_table(pte); @@ -195,23 +164,12 @@ } } -static void create_sections(uint64_t virt, uint64_t phys, uint64_t size_m, uint64_t flags) +static void create_sections(uint64_t virt, uint64_t phys, uint64_t size, uint64_t flags) { - - map_region(virt, phys, size_m, flags); + map_region(virt, phys, size, flags); tlb_invalidate(); } -void *map_io_sections(unsigned long phys, void *_start, size_t size) -{ - - map_region((uint64_t)_start, phys, (uint64_t)size, UNCACHED_MEM); - - tlb_invalidate(); - return _start; -} - - int arch_remap_range(void *_start, size_t size, unsigned flags) { map_region((uint64_t)_start, (uint64_t)_start, (uint64_t)size, flags); @@ -220,12 +178,19 @@ return 0; } +static void mmu_enable(void) +{ + isb(); + set_cr(get_cr() | CR_M | CR_C | CR_I); +} + /* * Prepare MMU for usage enable it. */ static int mmu_init(void) { struct memory_bank *bank; + unsigned int el; if (list_empty(&memory_banks)) /* @@ -236,88 +201,46 @@ */ panic("MMU: No memory bank found! Cannot continue\n"); - if (get_cr() & CR_M) { - ttb = (uint64_t *)get_ttbr(current_el()); - if (!request_sdram_region("ttb", (unsigned long)ttb, SZ_16K)) - /* - * This can mean that: - * - the early MMU code has put the ttb into a place - * which we don't have inside our available memory - * - Somebody else has occupied the ttb region which means - * the ttb will get corrupted. - */ - pr_crit("Critical Error: Can't request SDRAM region for ttb at %p\n", - ttb); - } else { - ttb = memalign(GRANULE_SIZE, SZ_16K); - free_idx = 1; + if (get_cr() & CR_M) + mmu_disable(); - memset(ttb, 0, GRANULE_SIZE); + ttb = xmemalign(GRANULE_SIZE, GRANULE_SIZE); - set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, UNCACHED_MEM); - } + memset(ttb, 0, GRANULE_SIZE); + + el = current_el(); + set_ttbr_tcr_mair(el, (uint64_t)ttb, calc_tcr(el), MEMORY_ATTRIBUTES); pr_debug("ttb: 0x%p\n", ttb); - /* create a flat mapping using 1MiB sections */ - create_sections(0, 0, GRANULE_SIZE, UNCACHED_MEM); + /* create a flat mapping */ + create_sections(0, 0, 1UL << (BITS_PER_VA - 1), UNCACHED_MEM); /* Map sdram cached. */ for_each_memory_bank(bank) create_sections(bank->start, bank->start, bank->size, CACHED_MEM); + create_sections(0x0, 0x0, 0x1000, 0x0); + + mmu_enable(); + return 0; } mmu_initcall(mmu_init); -void mmu_enable(void) -{ - if (!ttb) - arm_mmu_not_initialized_error(); - - if (!(get_cr() & CR_M)) { - - isb(); - set_cr(get_cr() | CR_M | CR_C | CR_I); - } -} - void mmu_disable(void) { unsigned int cr; - if (!ttb) - arm_mmu_not_initialized_error(); - cr = get_cr(); - cr &= ~(CR_M | CR_C | CR_I); + cr &= ~(CR_M | CR_C); + set_cr(cr); + v8_flush_dcache_all(); tlb_invalidate(); dsb(); isb(); - - set_cr(cr); - - dsb(); - isb(); -} - -void mmu_early_enable(uint64_t membase, uint64_t memsize, uint64_t _ttb) -{ - ttb = (uint64_t *)_ttb; - - memset(ttb, 0, GRANULE_SIZE); - free_idx = 1; - - set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, UNCACHED_MEM); - - create_sections(0, 0, 4096, UNCACHED_MEM); - - create_sections(membase, membase, memsize, CACHED_MEM); - - isb(); - set_cr(get_cr() | CR_M); } unsigned long virt_to_phys(volatile void *virt) @@ -329,3 +252,58 @@ { return (void *)phys; } + +void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle) +{ + void *ret; + + size = PAGE_ALIGN(size); + ret = xmemalign(PAGE_SIZE, size); + if (dma_handle) + *dma_handle = (dma_addr_t)ret; + + map_region((unsigned long)ret, (unsigned long)ret, size, UNCACHED_MEM); + tlb_invalidate(); + + return ret; +} + +void dma_free_coherent(void *mem, dma_addr_t dma_handle, size_t size) +{ + size = PAGE_ALIGN(size); + + map_region((unsigned long)mem, (unsigned long)mem, size, CACHED_MEM); + + free(mem); +} + +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, + enum dma_data_direction dir) +{ + if (dir != DMA_TO_DEVICE) + v8_inv_dcache_range(address, address + size - 1); +} + +void dma_sync_single_for_device(dma_addr_t address, size_t size, + enum dma_data_direction dir) +{ + if (dir == DMA_FROM_DEVICE) + v8_inv_dcache_range(address, address + size - 1); + v8_flush_dcache_range(address, address + size - 1); +} + +dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, + enum dma_data_direction dir) +{ + unsigned long addr = (unsigned long)ptr; + + dma_sync_single_for_device(addr, size, dir); + + return addr; +} + +void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir) +{ + dma_sync_single_for_cpu(addr, size, dir); +} diff --git a/arch/arm/cpu/mmu_64.h b/arch/arm/cpu/mmu_64.h new file mode 100644 index 0000000..c280d2c --- /dev/null +++ b/arch/arm/cpu/mmu_64.h @@ -0,0 +1,121 @@ + +#define CACHED_MEM (PTE_BLOCK_MEMTYPE(MT_NORMAL) | \ + PTE_BLOCK_OUTER_SHARE | \ + PTE_BLOCK_AF) +#define UNCACHED_MEM (PTE_BLOCK_MEMTYPE(MT_DEVICE_nGnRnE) | \ + PTE_BLOCK_OUTER_SHARE | \ + PTE_BLOCK_AF) + +/* + * Do it the simple way for now and invalidate the entire tlb + */ +static inline void tlb_invalidate(void) +{ + unsigned int el = current_el(); + + dsb(); + + if (el == 1) + __asm__ __volatile__("tlbi vmalle1\n\t" : : : "memory"); + else if (el == 2) + __asm__ __volatile__("tlbi alle2\n\t" : : : "memory"); + else if (el == 3) + __asm__ __volatile__("tlbi alle3\n\t" : : : "memory"); + + dsb(); + isb(); +} + +static inline void set_ttbr_tcr_mair(int el, uint64_t table, uint64_t tcr, uint64_t attr) +{ + asm volatile("dsb sy"); + if (el == 1) { + asm volatile("msr ttbr0_el1, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el1, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el1, %0" : : "r" (attr) : "memory"); + } else if (el == 2) { + asm volatile("msr ttbr0_el2, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el2, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el2, %0" : : "r" (attr) : "memory"); + } else if (el == 3) { + asm volatile("msr ttbr0_el3, %0" : : "r" (table) : "memory"); + asm volatile("msr tcr_el3, %0" : : "r" (tcr) : "memory"); + asm volatile("msr mair_el3, %0" : : "r" (attr) : "memory"); + } else { + hang(); + } + asm volatile("isb"); +} + +static inline uint64_t get_ttbr(int el) +{ + uint64_t val; + if (el == 1) { + asm volatile("mrs %0, ttbr0_el1" : "=r" (val)); + } else if (el == 2) { + asm volatile("mrs %0, ttbr0_el2" : "=r" (val)); + } else if (el == 3) { + asm volatile("mrs %0, ttbr0_el3" : "=r" (val)); + } else { + hang(); + } + + return val; +} + +static inline int level2shift(int level) +{ + /* Page is 12 bits wide, every level translates 9 bits */ + return (12 + 9 * (3 - level)); +} + +static inline uint64_t level2mask(int level) +{ + uint64_t mask = -EINVAL; + + if (level == 1) + mask = L1_ADDR_MASK; + else if (level == 2) + mask = L2_ADDR_MASK; + else if (level == 3) + mask = L3_ADDR_MASK; + + return mask; +} + +static inline uint64_t calc_tcr(int el) +{ + u64 ips, va_bits; + u64 tcr; + + ips = 2; + va_bits = BITS_PER_VA; + + if (el == 1) + tcr = (ips << 32) | TCR_EPD1_DISABLE; + else if (el == 2) + tcr = (ips << 16); + else + tcr = (ips << 16); + + /* PTWs cacheable, inner/outer WBWA and inner shareable */ + tcr |= TCR_TG0_4K | TCR_SHARED_INNER | TCR_ORGN_WBWA | TCR_IRGN_WBWA; + tcr |= TCR_T0SZ(va_bits); + + return tcr; +} + +static inline int pte_type(uint64_t *pte) +{ + return *pte & PTE_TYPE_MASK; +} + +static inline uint64_t *get_level_table(uint64_t *pte) +{ + uint64_t *table = (uint64_t *)(*pte & XLAT_ADDR_MASK); + + if (pte_type(pte) != PTE_TYPE_TABLE) + BUG(); + + return table; +} diff --git a/arch/arm/cpu/no-mmu.c b/arch/arm/cpu/no-mmu.c index e227b45..7268fa9 100644 --- a/arch/arm/cpu/no-mmu.c +++ b/arch/arm/cpu/no-mmu.c @@ -28,7 +28,7 @@ #include #include #include - +#include #define __exceptions_size (__exceptions_stop - __exceptions_start) diff --git a/arch/arm/cpu/sections.c b/arch/arm/cpu/sections.c new file mode 100644 index 0000000..5874da2 --- /dev/null +++ b/arch/arm/cpu/sections.c @@ -0,0 +1,11 @@ +#include + +char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); +char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); +char __dynsym_start[0] __attribute__((section(".__dynsym_start"))); +char __dynsym_end[0] __attribute__((section(".__dynsym_end"))); +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/arm/cpu/setupc.S b/arch/arm/cpu/setupc.S index c232b08..717500c 100644 --- a/arch/arm/cpu/setupc.S +++ b/arch/arm/cpu/setupc.S @@ -15,7 +15,7 @@ push {r4, r5} mov r5, lr bl get_runtime_offset - subs r4, r0, #0 + adds r4, r0, #0 beq 1f /* skip memcpy if already at correct address */ ldr r0,=_text ldr r2,=__bss_start @@ -55,21 +55,21 @@ mov r5, r0 - ld_var _text, r0, r4 - mov r8, r0 + ldr r8, =_text - sub r1, r0, r5 /* r1: from address */ + add r1, r8, r5 /* r1: from address */ cmp r1, r6 /* already at correct address? */ beq 1f /* yes, skip copy to new address */ - ld_var __bss_start, r2, r4 + ldr r2, =__bss_start - sub r2, r2, r0 /* r2: size */ + sub r2, r2, r8 /* r2: size */ mov r0, r6 /* r0: target */ - add r7, r7, r0 /* adjust return address */ - sub r7, r7, r1 /* lr += offset */ + /* adjust return address */ + sub r7, r7, r1 /* sub address where we are actually running */ + add r7, r7, r0 /* add address where we are going to run */ bl memcpy /* copy binary */ diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S index 3515854..61e7085 100644 --- a/arch/arm/cpu/setupc_64.S +++ b/arch/arm/cpu/setupc_64.S @@ -16,3 +16,63 @@ mov x30, x15 ret ENDPROC(setup_c) + +/* + * void relocate_to_adr(unsigned long targetadr) + * + * Copy binary to targetadr, relocate code and continue + * executing at new address. + */ +.section .text.relocate_to_adr +ENTRY(relocate_to_adr) + /* x0: target address */ + + stp x19, x20, [sp, #-16]! + stp x21, x22, [sp, #-16]! + + mov x19, x30 + + mov x21, x0 + + bl get_runtime_offset + mov x5, x0 + + ldr x0, =_text + mov x20, x0 + + add x1, x0, x5 /* x1: from address */ + + cmp x1, x21 /* already at correct address? */ + beq 1f /* yes, skip copy to new address */ + + ldr x2, =__bss_start + + sub x2, x2, x0 /* x2: size */ + mov x0, x21 /* x0: target */ + + /* adjust return address */ + sub x19, x19, x1 /* sub address where we are actually running */ + add x19, x19, x0 /* add address where we are going to run */ + + bl memcpy /* copy binary */ + +#ifdef CONFIG_MMU + bl arm_early_mmu_cache_flush +#endif + mov x0,#0 + ic ivau, x0 /* flush icache */ + + ldr x0,=1f + sub x0, x0, x20 + add x0, x0, x21 + br x0 /* jump to relocated address */ +1: + bl relocate_to_current_adr /* relocate binary */ + + mov x30, x19 + + ldp x21, x22, [sp], #16 + ldp x19, x20, [sp], #16 + ret + +ENDPROC(relocate_to_adr) diff --git a/arch/arm/cpu/start-pbl.c b/arch/arm/cpu/start-pbl.c index e851b4a..16159d7 100644 --- a/arch/arm/cpu/start-pbl.c +++ b/arch/arm/cpu/start-pbl.c @@ -26,12 +26,10 @@ #include #include #include -#include #include +#include #include -#include "mmu-early.h" - unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; @@ -49,10 +47,10 @@ __noreturn void barebox_single_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { - uint32_t offset; - uint32_t pg_start, pg_end, pg_len, uncompressed_len; + unsigned long offset; + unsigned long pg_start, pg_end, pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); - uint32_t endmem = membase + memsize; + unsigned long endmem = membase + memsize; unsigned long barebox_base; if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) @@ -61,8 +59,8 @@ /* Get offset between linked address and runtime address */ offset = get_runtime_offset(); - pg_start = (uint32_t)&input_data - offset; - pg_end = (uint32_t)&input_data_end - offset; + pg_start = (unsigned long)&input_data + global_variable_offset(); + pg_end = (unsigned long)&input_data_end + global_variable_offset(); pg_len = pg_end - pg_start; uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c index 171e6ad..68fff89 100644 --- a/arch/arm/cpu/start.c +++ b/arch/arm/cpu/start.c @@ -26,12 +26,12 @@ #include #include #include +#include #include #include #include #include -#include "mmu-early.h" unsigned long arm_stack_top; static unsigned long arm_barebox_size; @@ -229,7 +229,7 @@ #ifndef CONFIG_PBL_IMAGE -void __naked __section(.text_entry) start(void) +void NAKED __section(.text_entry) start(void) { barebox_arm_head(); } @@ -239,7 +239,7 @@ * First function in the uncompressed image. We get here from * the pbl. The stack already has been set up by the pbl. */ -void __naked __section(.text_entry) start(unsigned long membase, +void NAKED __section(.text_entry) start(unsigned long membase, unsigned long memsize, void *boarddata) { barebox_non_pbl_start(membase, memsize, boarddata); diff --git a/arch/arm/cpu/uncompress.c b/arch/arm/cpu/uncompress.c index 9d7fe0e..b07087e 100644 --- a/arch/arm/cpu/uncompress.c +++ b/arch/arm/cpu/uncompress.c @@ -27,33 +27,30 @@ #include #include #include -#include #include +#include #include #include -#include "mmu-early.h" - unsigned long free_mem_ptr; unsigned long free_mem_end_ptr; -static int __attribute__((__used__)) - __attribute__((__section__(".image_end"))) - __image_end_dummy = 0xdeadbeef; +static int __attribute__((__section__(".image_end"))) + image_end_marker = 0xdeadbeef; void __noreturn barebox_multi_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata) { uint32_t pg_len, uncompressed_len; void __noreturn (*barebox)(unsigned long, unsigned long, void *); - uint32_t endmem = membase + memsize; + unsigned long endmem = membase + memsize; unsigned long barebox_base; uint32_t *image_end; void *pg_start; unsigned long pc = get_pc(); - image_end = (void *)ld_var(__image_end) - get_runtime_offset(); + image_end = (void *)&image_end_marker + global_variable_offset(); if (IS_ENABLED(CONFIG_PBL_RELOCATABLE)) { /* @@ -68,11 +65,13 @@ } /* - * image_end is the first location after the executable. It contains - * the size of the appended compressed binary followed by the binary. + * image_end is the image_end_marker defined above. It is the last location + * in the executable. Right after the executable the build process adds + * the size of the appended compressed binary followed by the compressed + * binary itself. */ - pg_start = image_end + 1; - pg_len = *(image_end); + pg_start = image_end + 2; + pg_len = *(image_end + 1); uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4)); if (IS_ENABLED(CONFIG_RELOCATABLE)) diff --git a/arch/arm/include/asm/assembler64.h b/arch/arm/include/asm/assembler64.h new file mode 100644 index 0000000..26182aa --- /dev/null +++ b/arch/arm/include/asm/assembler64.h @@ -0,0 +1,21 @@ +#ifndef __ASM_ARCH_ASSEMBLY_H +#define __ASM_ARCH_ASSEMBLY_H + +#ifndef __ASSEMBLY__ +#error "Only include this from assembly code" +#endif + +/* + * Branch according to exception level + */ +.macro switch_el, xreg, el3_label, el2_label, el1_label + mrs \xreg, CurrentEL + cmp \xreg, 0xc + b.eq \el3_label + cmp \xreg, 0x8 + b.eq \el2_label + cmp \xreg, 0x4 + b.eq \el1_label +.endm + +#endif /* __ASM_ARCH_ASSEMBLY_H */ \ No newline at end of file diff --git a/arch/arm/include/asm/barebox-arm-head.h b/arch/arm/include/asm/barebox-arm-head.h index bd9c9b1..4d0da6c 100644 --- a/arch/arm/include/asm/barebox-arm-head.h +++ b/arch/arm/include/asm/barebox-arm-head.h @@ -21,6 +21,7 @@ static inline void __barebox_arm_head(void) { __asm__ __volatile__ ( +#ifdef CONFIG_CPU_32 #ifdef CONFIG_THUMB2_BAREBOX ".arm\n" "adr r9, 1f + 1\n" @@ -41,10 +42,22 @@ "1: b 1b\n" "1: b 1b\n" #endif +#else + "b 2f\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" + "nop\n" +#endif ".asciz \"barebox\"\n" +#ifdef CONFIG_CPU_32 ".word _text\n" /* text base. If copied there, * barebox can skip relocation */ +#else + ".word 0xffffffff\n" +#endif ".word _barebox_image_size\n" /* image size to copy */ ".rept 8\n" ".word 0x55555555\n" diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index 3aea2e0..fa673a6 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -32,17 +32,21 @@ #include #include -/* cpu/.../cpu.c */ -int cleanup_before_linux(void); +unsigned long get_runtime_offset(void); -/* arch/board(s)/.../... */ -int board_init(void); -int dram_init (void); - -extern char __exceptions_start[], __exceptions_stop[]; - -void board_init_lowlevel(void); -uint32_t get_runtime_offset(void); +/* global_variable_offset() - Access global variables when not running at link address + * + * Get the offset of global variables when not running at the address we are + * linked at. ARM uses absolute addresses, so we must add the runtime offset + * whereas aarch64 uses PC relative addresses, so nothing must be done here. + */ +static inline unsigned long global_variable_offset(void) +{ + if (IS_ENABLED(CONFIG_CPU_32)) + return get_runtime_offset(); + else + return 0; +} void setup_c(void); void relocate_to_current_adr(void); @@ -161,13 +165,13 @@ #define ENTRY_FUNCTION(name, arg0, arg1, arg2) \ static void __##name(uint32_t, uint32_t, uint32_t); \ \ - void __naked __section(.text_head_entry_##name) name \ + void NAKED __section(.text_head_entry_##name) name \ (uint32_t r0, uint32_t r1, uint32_t r2) \ { \ __barebox_arm_head(); \ __##name(r0, r1, r2); \ } \ - static void __naked noinline __##name \ + static void NAKED noinline __##name \ (uint32_t arg0, uint32_t arg1, uint32_t arg2) /* @@ -181,4 +185,17 @@ #define barebox_image_size (__image_end - __image_start) +#ifdef CONFIG_CPU_32 +#define NAKED __naked +#else +/* + * There is no naked support for aarch64, so do not rely on it. + * This basically means we must have a stack configured when a + * function with the naked attribute is entered. On nowadays hardware + * the ROM should have some basic stack already. If not, set one + * up before jumping into the barebox entry functions. + */ +#define NAKED +#endif + #endif /* _BAREBOX_ARM_H_ */ diff --git a/arch/arm/include/asm/barebox.h b/arch/arm/include/asm/barebox.h index 5a66222..4e89466 100644 --- a/arch/arm/include/asm/barebox.h +++ b/arch/arm/include/asm/barebox.h @@ -2,9 +2,11 @@ #define _BAREBOX_H_ 1 #ifdef CONFIG_ARM_UNWIND -#ifndef CONFIG_CPU_V8 #define ARCH_HAS_STACK_DUMP #endif + +#ifdef CONFIG_CPU_V8 +#define ARCH_HAS_STACK_DUMP #endif #ifdef CONFIG_ARM_EXCEPTIONS diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index b51225e..348a76b 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h @@ -115,7 +115,7 @@ #endif /* __ARMEB__ */ -#if defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ >= 5) +#if defined (CONFIG_CPU_32) && defined(__LINUX_ARM_ARCH__) && (__LINUX_ARM_ARCH__ >= 5) static inline int constant_fls(int x) { int r = 32; @@ -156,31 +156,13 @@ #define __ffs(x) (ffs(x) - 1) #define ffz(x) __ffs(~(x)) #else /* ! __ARM__USE_GENERIC_FF */ -/* - * ffz = Find First Zero in word. Undefined if no zero exists, - * so code should check against ~0UL first.. - */ -static inline unsigned long ffz(unsigned long word) -{ - int k; - - word = ~word; - k = 31; - if (word & 0x0000ffff) { k -= 16; word <<= 16; } - if (word & 0x00ff0000) { k -= 8; word <<= 8; } - if (word & 0x0f000000) { k -= 4; word <<= 4; } - if (word & 0x30000000) { k -= 2; word <<= 2; } - if (word & 0x40000000) { k -= 1; } - return k; -} +#include #include #include #include #endif /* __ARM__USE_GENERIC_FF */ -#if __LINUX_ARM_ARCH__ == 8 #include -#endif #include diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index b5460a7..0822cb7 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -1,10 +1,11 @@ #ifndef __ASM_CACHE_H #define __ASM_CACHE_H -#ifdef CONFIG_CPU_64v8 -extern void v8_invalidate_icache_all(void); -extern void v8_dcache_all(void); -#endif +void v8_invalidate_icache_all(void); +void v8_flush_dcache_all(void); +void v8_invalidate_dcache_all(void); +void v8_flush_dcache_range(unsigned long start, unsigned long end); +void v8_inv_dcache_range(unsigned long start, unsigned long end); static inline void icache_invalidate(void) { diff --git a/arch/arm/include/asm/common.h b/arch/arm/include/asm/common.h index 07ae619..97bfdc4 100644 --- a/arch/arm/include/asm/common.h +++ b/arch/arm/include/asm/common.h @@ -4,13 +4,19 @@ static inline unsigned long get_pc(void) { unsigned long pc; - +#ifdef CONFIG_CPU_32 __asm__ __volatile__( "mov %0, pc\n" : "=r" (pc) : : "memory"); - +#else + __asm__ __volatile__( + "adr %0, .\n" + : "=r" (pc) + : + : "memory"); +#endif return pc; } diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h index 1ba2edf..a68886b 100644 --- a/arch/arm/include/asm/dma.h +++ b/arch/arm/include/asm/dma.h @@ -34,12 +34,12 @@ free(mem); } -static inline void dma_sync_single_for_cpu(unsigned long address, size_t size, +static inline void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) { } -static inline void dma_sync_single_for_device(unsigned long address, size_t size, +static inline void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { } diff --git a/arch/arm/include/asm/esr.h b/arch/arm/include/asm/esr.h new file mode 100644 index 0000000..77eeb2c --- /dev/null +++ b/arch/arm/include/asm/esr.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2013 - ARM Ltd + * Author: Marc Zyngier + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __ASM_ESR_H +#define __ASM_ESR_H + +#include + +#define ESR_ELx_EC_UNKNOWN (0x00) +#define ESR_ELx_EC_WFx (0x01) +/* Unallocated EC: 0x02 */ +#define ESR_ELx_EC_CP15_32 (0x03) +#define ESR_ELx_EC_CP15_64 (0x04) +#define ESR_ELx_EC_CP14_MR (0x05) +#define ESR_ELx_EC_CP14_LS (0x06) +#define ESR_ELx_EC_FP_ASIMD (0x07) +#define ESR_ELx_EC_CP10_ID (0x08) +/* Unallocated EC: 0x09 - 0x0B */ +#define ESR_ELx_EC_CP14_64 (0x0C) +/* Unallocated EC: 0x0d */ +#define ESR_ELx_EC_ILL (0x0E) +/* Unallocated EC: 0x0F - 0x10 */ +#define ESR_ELx_EC_SVC32 (0x11) +#define ESR_ELx_EC_HVC32 (0x12) +#define ESR_ELx_EC_SMC32 (0x13) +/* Unallocated EC: 0x14 */ +#define ESR_ELx_EC_SVC64 (0x15) +#define ESR_ELx_EC_HVC64 (0x16) +#define ESR_ELx_EC_SMC64 (0x17) +#define ESR_ELx_EC_SYS64 (0x18) +/* Unallocated EC: 0x19 - 0x1E */ +#define ESR_ELx_EC_IMP_DEF (0x1f) +#define ESR_ELx_EC_IABT_LOW (0x20) +#define ESR_ELx_EC_IABT_CUR (0x21) +#define ESR_ELx_EC_PC_ALIGN (0x22) +/* Unallocated EC: 0x23 */ +#define ESR_ELx_EC_DABT_LOW (0x24) +#define ESR_ELx_EC_DABT_CUR (0x25) +#define ESR_ELx_EC_SP_ALIGN (0x26) +/* Unallocated EC: 0x27 */ +#define ESR_ELx_EC_FP_EXC32 (0x28) +/* Unallocated EC: 0x29 - 0x2B */ +#define ESR_ELx_EC_FP_EXC64 (0x2C) +/* Unallocated EC: 0x2D - 0x2E */ +#define ESR_ELx_EC_SERROR (0x2F) +#define ESR_ELx_EC_BREAKPT_LOW (0x30) +#define ESR_ELx_EC_BREAKPT_CUR (0x31) +#define ESR_ELx_EC_SOFTSTP_LOW (0x32) +#define ESR_ELx_EC_SOFTSTP_CUR (0x33) +#define ESR_ELx_EC_WATCHPT_LOW (0x34) +#define ESR_ELx_EC_WATCHPT_CUR (0x35) +/* Unallocated EC: 0x36 - 0x37 */ +#define ESR_ELx_EC_BKPT32 (0x38) +/* Unallocated EC: 0x39 */ +#define ESR_ELx_EC_VECTOR32 (0x3A) +/* Unallocted EC: 0x3B */ +#define ESR_ELx_EC_BRK64 (0x3C) +/* Unallocated EC: 0x3D - 0x3F */ +#define ESR_ELx_EC_MAX (0x3F) + +#define ESR_ELx_EC_SHIFT (26) +#define ESR_ELx_EC_MASK (UL(0x3F) << ESR_ELx_EC_SHIFT) + +#define ESR_ELx_IL (UL(1) << 25) +#define ESR_ELx_ISS_MASK (ESR_ELx_IL - 1) +#define ESR_ELx_ISV (UL(1) << 24) +#define ESR_ELx_SAS_SHIFT (22) +#define ESR_ELx_SAS (UL(3) << ESR_ELx_SAS_SHIFT) +#define ESR_ELx_SSE (UL(1) << 21) +#define ESR_ELx_SRT_SHIFT (16) +#define ESR_ELx_SRT_MASK (UL(0x1F) << ESR_ELx_SRT_SHIFT) +#define ESR_ELx_SF (UL(1) << 15) +#define ESR_ELx_AR (UL(1) << 14) +#define ESR_ELx_EA (UL(1) << 9) +#define ESR_ELx_CM (UL(1) << 8) +#define ESR_ELx_S1PTW (UL(1) << 7) +#define ESR_ELx_WNR (UL(1) << 6) +#define ESR_ELx_FSC (0x3F) +#define ESR_ELx_FSC_TYPE (0x3C) +#define ESR_ELx_FSC_EXTABT (0x10) +#define ESR_ELx_FSC_ACCESS (0x08) +#define ESR_ELx_FSC_FAULT (0x04) +#define ESR_ELx_FSC_PERM (0x0C) +#define ESR_ELx_CV (UL(1) << 24) +#define ESR_ELx_COND_SHIFT (20) +#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) +#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0) +#define ESR_ELx_xVC_IMM_MASK ((1UL << 16) - 1) + +/* ESR value templates for specific events */ + +/* BRK instruction trap from AArch64 state */ +#define ESR_ELx_VAL_BRK64(imm) \ + ((ESR_ELx_EC_BRK64 << ESR_ELx_EC_SHIFT) | ESR_ELx_IL | \ + ((imm) & 0xffff)) + +#ifndef __ASSEMBLY__ +#include + +const char *esr_get_class_string(u32 esr); +#endif /* __ASSEMBLY */ + +#endif /* __ASM_ESR_H */ diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index f68ab37..99833ac 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -6,24 +6,8 @@ #include #include -#ifdef CONFIG_CPU_64v8 -#include - -#define DEV_MEM (PMD_ATTRINDX(MT_DEVICE_nGnRnE) | PMD_SECT_AF | PMD_TYPE_SECT) -#define CACHED_MEM (PMD_ATTRINDX(MT_NORMAL) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT) -#define UNCACHED_MEM (PMD_ATTRINDX(MT_NORMAL_NC) | PMD_SECT_S | PMD_SECT_AF | PMD_TYPE_SECT) -#else -#include - -#define PMD_SECT_DEF_UNCACHED (PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT) -#define PMD_SECT_DEF_CACHED (PMD_SECT_WB | PMD_SECT_DEF_UNCACHED) -#endif - - - struct arm_memory; -void mmu_enable(void); void mmu_disable(void); static inline void arm_create_section(unsigned long virt, unsigned long phys, int size_m, unsigned int flags) @@ -70,4 +54,7 @@ void __dma_flush_range(unsigned long, unsigned long); void __dma_inv_range(unsigned long, unsigned long); +void mmu_early_enable(unsigned long membase, unsigned long memsize, + unsigned long ttb); + #endif /* __ASM_MMU_H */ diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h index 20bea5b..d838250 100644 --- a/arch/arm/include/asm/pgtable64.h +++ b/arch/arm/include/asm/pgtable64.h @@ -21,7 +21,7 @@ #define UNUSED_DESC 0x6EbAAD0BBADbA6E0 #define VA_START 0x0 -#define BITS_PER_VA 33 +#define BITS_PER_VA 39 /* Granule size of 4KB is being used */ #define GRANULE_SIZE_SHIFT 12 @@ -47,51 +47,28 @@ #define GRANULE_MASK GRANULE_SIZE +/* Hardware page table definitions */ +#define PTE_TYPE_MASK (3 << 0) +#define PTE_TYPE_FAULT (0 << 0) +#define PTE_TYPE_TABLE (3 << 0) +#define PTE_TYPE_PAGE (3 << 0) +#define PTE_TYPE_BLOCK (1 << 0) -/* - * Level 2 descriptor (PMD). - */ -#define PMD_TYPE_MASK (3 << 0) -#define PMD_TYPE_FAULT (0 << 0) -#define PMD_TYPE_TABLE (3 << 0) -#define PMD_TYPE_SECT (1 << 0) -#define PMD_TABLE_BIT (1 << 1) +#define PTE_TABLE_PXN (1UL << 59) +#define PTE_TABLE_XN (1UL << 60) +#define PTE_TABLE_AP (1UL << 61) +#define PTE_TABLE_NS (1UL << 63) -/* - * Section - */ -#define PMD_SECT_VALID (1 << 0) -#define PMD_SECT_USER (1 << 6) /* AP[1] */ -#define PMD_SECT_RDONLY (1 << 7) /* AP[2] */ -#define PMD_SECT_S (3 << 8) -#define PMD_SECT_AF (1 << 10) -#define PMD_SECT_NG (1 << 11) -#define PMD_SECT_CONT (1 << 52) -#define PMD_SECT_PXN (1 << 53) -#define PMD_SECT_UXN (1 << 54) - -/* - * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). - */ -#define PMD_ATTRINDX(t) ((t) << 2) -#define PMD_ATTRINDX_MASK (7 << 2) - -/* - * Level 3 descriptor (PTE). - */ -#define PTE_TYPE_MASK (3 << 0) -#define PTE_TYPE_FAULT (0 << 0) -#define PTE_TYPE_PAGE (3 << 0) -#define PTE_TABLE_BIT (1 << 1) -#define PTE_USER (1 << 6) /* AP[1] */ -#define PTE_RDONLY (1 << 7) /* AP[2] */ -#define PTE_SHARED (3 << 8) /* SH[1:0], inner shareable */ -#define PTE_AF (1 << 10) /* Access Flag */ -#define PTE_NG (1 << 11) /* nG */ -#define PTE_DBM (1 << 51) /* Dirty Bit Management */ -#define PTE_CONT (1 << 52) /* Contiguous range */ -#define PTE_PXN (1 << 53) /* Privileged XN */ -#define PTE_UXN (1 << 54) /* User XN */ +/* Block */ +#define PTE_BLOCK_MEMTYPE(x) ((x) << 2) +#define PTE_BLOCK_NS (1 << 5) +#define PTE_BLOCK_NON_SHARE (0 << 8) +#define PTE_BLOCK_OUTER_SHARE (2 << 8) +#define PTE_BLOCK_INNER_SHARE (3 << 8) +#define PTE_BLOCK_AF (1 << 10) +#define PTE_BLOCK_NG (1 << 11) +#define PTE_BLOCK_PXN (UL(1) << 53) +#define PTE_BLOCK_UXN (UL(1) << 54) /* * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers). @@ -109,6 +86,13 @@ #define MT_NORMAL 4 #define MT_NORMAL_WT 5 +#define MEMORY_ATTRIBUTES ((0x00 << (MT_DEVICE_nGnRnE * 8)) | \ + (0x04 << (MT_DEVICE_nGnRE * 8)) | \ + (0x0c << (MT_DEVICE_GRE * 8)) | \ + (0x44 << (MT_NORMAL_NC * 8)) | \ + (UL(0xff) << (MT_NORMAL * 8)) | \ + (UL(0xbb) << (MT_NORMAL_WT * 8))) + /* * TCR flags. */ @@ -132,6 +116,7 @@ #define TCR_EL1_IPS_BITS (UL(3) << 32) /* 42 bits physical address */ #define TCR_EL2_IPS_BITS (3 << 16) /* 42 bits physical address */ #define TCR_EL3_IPS_BITS (3 << 16) /* 42 bits physical address */ +#define TCR_EPD1_DISABLE (1 << 23) #define TCR_EL1_RSVD (1 << 31) #define TCR_EL2_RSVD (1 << 31 | 1 << 23) diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 6520a0a..7fbd8d9 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -10,6 +10,23 @@ #ifndef __ASM_ARM_PTRACE_H #define __ASM_ARM_PTRACE_H +#ifdef CONFIG_CPU_64 + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored + * on the stack during an exception. + */ +struct pt_regs { + unsigned long elr; + unsigned long regs[31]; +}; + +#endif /* __ASSEMBLY__ */ + +#else /* CONFIG_CPU_64 */ + #define PTRACE_GETREGS 12 #define PTRACE_SETREGS 13 #define PTRACE_GETFPREGS 14 @@ -141,4 +158,6 @@ #endif /* __ASSEMBLY__ */ +#endif /* CONFIG_CPU_64 */ + #endif diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h index 8c7bc8c..6933c70 100644 --- a/arch/arm/include/asm/sections.h +++ b/arch/arm/include/asm/sections.h @@ -4,30 +4,12 @@ #ifndef __ASSEMBLY__ #include -/* - * Access a linker supplied variable. Use this if your code might not be running - * at the address it is linked at. - */ -#define ld_var(name) ({ \ - unsigned long __ld_var_##name(void); \ - __ld_var_##name(); \ -}) - -#else - -/* - * Access a linker supplied variable, assembler macro version - */ -.macro ld_var name, reg, scratch - 1000: - ldr \reg, 1001f - ldr \scratch, =1000b - add \reg, \reg, \scratch - b 1002f - 1001: - .word \name - 1000b - 1002: -.endm +extern char __rel_dyn_start[]; +extern char __rel_dyn_end[]; +extern char __dynsym_start[]; +extern char __dynsym_end[]; +extern char __exceptions_start[]; +extern char __exceptions_stop[]; #endif diff --git a/arch/arm/include/asm/stacktrace.h b/arch/arm/include/asm/stacktrace.h index 10f70e1..602e79c 100644 --- a/arch/arm/include/asm/stacktrace.h +++ b/arch/arm/include/asm/stacktrace.h @@ -4,7 +4,9 @@ struct stackframe { unsigned long fp; unsigned long sp; +#ifdef CONFIG_CPU_32 unsigned long lr; +#endif unsigned long pc; }; diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c deleted file mode 100644 index 25efb42..0000000 --- a/arch/arm/lib/bootm.c +++ /dev/null @@ -1,620 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* - * sdram_start_and_size() - determine place for putting the kernel/oftree/initrd - * - * @start: returns the start address of the first RAM bank - * @size: returns the usable space at the beginning of the first RAM bank - * - * This function returns the base address of the first RAM bank and the free - * space found there. - * - * return: 0 for success, negative error code otherwise - */ -static int sdram_start_and_size(unsigned long *start, unsigned long *size) -{ - struct memory_bank *bank; - struct resource *res; - - /* - * We use the first memory bank for the kernel and other resources - */ - bank = list_first_entry_or_null(&memory_banks, struct memory_bank, - list); - if (!bank) { - printf("cannot find first memory bank\n"); - return -EINVAL; - } - - /* - * If the first memory bank has child resources we can use the bank up - * to the beginning of the first child resource, otherwise we can use - * the whole bank. - */ - res = list_first_entry_or_null(&bank->res->children, struct resource, - sibling); - if (res) - *size = res->start - bank->start; - else - *size = bank->size; - - *start = bank->start; - - return 0; -} - -static int get_kernel_addresses(size_t image_size, - int verbose, unsigned long *load_address, - unsigned long *mem_free) -{ - unsigned long mem_start, mem_size; - int ret; - size_t image_decomp_size; - unsigned long spacing; - - ret = sdram_start_and_size(&mem_start, &mem_size); - if (ret) - return ret; - - /* - * The kernel documentation "Documentation/arm/Booting" advises - * to place the compressed image outside of the lowest 32 MiB to - * avoid relocation. We should do this if we have at least 64 MiB - * of ram. If we have less space, we assume a maximum - * compression factor of 5. - */ - image_decomp_size = PAGE_ALIGN(image_size * 5); - if (mem_size >= SZ_64M) - image_decomp_size = max_t(size_t, image_decomp_size, SZ_32M); - - /* - * By default put oftree/initrd close behind compressed kernel image to - * avoid placing it outside of the kernels lowmem region. - */ - spacing = SZ_1M; - - if (*load_address == UIMAGE_INVALID_ADDRESS) { - /* - * Place the kernel at an address where it does not need to - * relocate itself before decompression. - */ - *load_address = mem_start + image_decomp_size; - if (verbose) - printf("no OS load address, defaulting to 0x%08lx\n", - *load_address); - } else if (*load_address <= mem_start + image_decomp_size) { - /* - * If the user/image specified an address where the kernel needs - * to relocate itself before decompression we need to extend the - * spacing to allow this relocation to happen without - * overwriting anything placed behind the kernel. - */ - spacing += image_decomp_size; - } - - *mem_free = PAGE_ALIGN(*load_address + image_size + spacing); - - /* - * Place oftree/initrd outside of the first 128 MiB, if we have space - * for it. This avoids potential conflicts with the kernel decompressor. - */ - if (mem_size > SZ_256M) - *mem_free = max(*mem_free, mem_start + SZ_128M); - - return 0; -} - -static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap) -{ - unsigned long kernel; - unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0; - enum arm_security_state state = bootm_arm_security_state(); - int ret; - - kernel = data->os_res->start + data->os_entry; - - initrd_start = data->initrd_address; - - if (initrd_start == UIMAGE_INVALID_ADDRESS) { - initrd_start = PAGE_ALIGN(free_mem); - - if (bootm_verbose(data)) { - printf("no initrd load address, defaulting to 0x%08lx\n", - initrd_start); - } - } - - if (bootm_has_initrd(data)) { - ret = bootm_load_initrd(data, initrd_start); - if (ret) - return ret; - } - - if (data->initrd_res) { - initrd_start = data->initrd_res->start; - initrd_end = data->initrd_res->end; - initrd_size = resource_size(data->initrd_res); - free_mem = PAGE_ALIGN(initrd_end + 1); - } - - ret = bootm_load_devicetree(data, free_mem); - if (ret) - return ret; - - if (bootm_verbose(data)) { - printf("\nStarting kernel at 0x%08lx", kernel); - if (initrd_size) - printf(", initrd at 0x%08lx", initrd_start); - if (data->oftree) - printf(", oftree at 0x%p", data->oftree); - printf("...\n"); - } - - if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR)) { - if (file_detect_type((void *)data->os_res->start, 0x100) == - filetype_arm_barebox) - state = ARM_STATE_SECURE; - - printf("Starting kernel in %s mode\n", - bootm_arm_security_state_name(state)); - } - - if (data->dryrun) - return 0; - - start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree, - state); - - restart_machine(); - - return -ERESTARTSYS; -} - -static int do_bootm_linux(struct image_data *data) -{ - unsigned long load_address, mem_free; - int ret; - - load_address = data->os_address; - - ret = get_kernel_addresses(bootm_get_os_size(data), - bootm_verbose(data), &load_address, &mem_free); - if (ret) - return ret; - - ret = bootm_load_os(data, load_address); - if (ret) - return ret; - - return __do_bootm_linux(data, mem_free, 0); -} - -static struct image_handler uimage_handler = { - .name = "ARM Linux uImage", - .bootm = do_bootm_linux, - .filetype = filetype_uimage, - .ih_os = IH_OS_LINUX, -}; - -static struct image_handler rawimage_handler = { - .name = "ARM raw image", - .bootm = do_bootm_linux, - .filetype = filetype_unknown, -}; - -struct zimage_header { - u32 unused[9]; - u32 magic; - u32 start; - u32 end; -}; - -#define ZIMAGE_MAGIC 0x016F2818 - -static int do_bootz_linux_fdt(int fd, struct image_data *data) -{ - struct fdt_header __header, *header; - void *oftree; - int ret; - - u32 end; - - if (data->oftree) - return -ENXIO; - - header = &__header; - ret = read(fd, header, sizeof(*header)); - if (ret < 0) - return ret; - if (ret < sizeof(*header)) - return -ENXIO; - - if (file_detect_type(header, sizeof(*header)) != filetype_oftree) - return -ENXIO; - - end = be32_to_cpu(header->totalsize); - - oftree = malloc(end + 0x8000); - if (!oftree) { - perror("zImage: oftree malloc"); - return -ENOMEM; - } - - memcpy(oftree, header, sizeof(*header)); - - end -= sizeof(*header); - - ret = read_full(fd, oftree + sizeof(*header), end); - if (ret < 0) - goto err_free; - if (ret < end) { - printf("premature end of image\n"); - ret = -EIO; - goto err_free; - } - - if (IS_BUILTIN(CONFIG_OFTREE)) { - struct device_node *root; - - root = of_unflatten_dtb(oftree); - if (IS_ERR(root)) { - pr_err("unable to unflatten devicetree\n"); - goto err_free; - } - data->oftree = of_get_fixed_tree(root); - if (!data->oftree) { - pr_err("Unable to get fixed tree\n"); - ret = -EINVAL; - goto err_free; - } - - free(oftree); - } else { - data->oftree = oftree; - } - - pr_info("zImage: concatenated oftree detected\n"); - - return 0; - -err_free: - free(oftree); - - return ret; -} - -static int do_bootz_linux(struct image_data *data) -{ - int fd, ret, swap = 0; - struct zimage_header __header, *header; - void *zimage; - u32 end, start; - size_t image_size; - unsigned long load_address = data->os_address; - unsigned long mem_free; - - fd = open(data->os_file, O_RDONLY); - if (fd < 0) { - perror("open"); - return 1; - } - - header = &__header; - ret = read(fd, header, sizeof(*header)); - if (ret < sizeof(*header)) { - printf("could not read %s\n", data->os_file); - goto err_out; - } - - switch (header->magic) { - case swab32(ZIMAGE_MAGIC): - swap = 1; - /* fall through */ - case ZIMAGE_MAGIC: - break; - default: - printf("invalid magic 0x%08x\n", header->magic); - ret = -EINVAL; - goto err_out; - } - - end = header->end; - start = header->start; - - if (swap) { - end = swab32(end); - start = swab32(start); - } - - image_size = end - start; - load_address = data->os_address; - - ret = get_kernel_addresses(image_size, bootm_verbose(data), - &load_address, &mem_free); - if (ret) - return ret; - - data->os_res = request_sdram_region("zimage", load_address, image_size); - if (!data->os_res) { - pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%d).\n", - load_address, load_address + image_size, image_size); - ret = -ENOMEM; - goto err_out; - } - - zimage = (void *)data->os_res->start; - - memcpy(zimage, header, sizeof(*header)); - - ret = read_full(fd, zimage + sizeof(*header), - image_size - sizeof(*header)); - if (ret < 0) - goto err_out; - if (ret < image_size - sizeof(*header)) { - printf("premature end of image\n"); - ret = -EIO; - goto err_out; - } - - if (swap) { - void *ptr; - for (ptr = zimage; ptr < zimage + end; ptr += 4) - *(u32 *)ptr = swab32(*(u32 *)ptr); - } - - ret = do_bootz_linux_fdt(fd, data); - if (ret && ret != -ENXIO) - goto err_out; - - close(fd); - - return __do_bootm_linux(data, mem_free, swap); - -err_out: - close(fd); - - return ret; -} - -static struct image_handler zimage_handler = { - .name = "ARM zImage", - .bootm = do_bootz_linux, - .filetype = filetype_arm_zimage, -}; - -static struct image_handler barebox_handler = { - .name = "ARM barebox", - .bootm = do_bootm_linux, - .filetype = filetype_arm_barebox, -}; - -#include - -static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps) -{ - int ret; - void *image = (void *)r->start; - unsigned to_read = ps - resource_size(r) % ps; - - ret = read_full(fd, image, resource_size(r)); - if (ret < 0) - return ret; - - ret = read_full(fd, buf, to_read); - if (ret < 0) - printf("could not read dummy %u\n", to_read); - - return ret; -} - -static int do_bootm_aimage(struct image_data *data) -{ - struct resource *snd_stage_res; - int fd, ret; - struct android_header __header, *header; - void *buf; - int to_read; - struct android_header_comp *cmp; - unsigned long mem_free; - unsigned long mem_start, mem_size; - - ret = sdram_start_and_size(&mem_start, &mem_size); - if (ret) - return ret; - - fd = open(data->os_file, O_RDONLY); - if (fd < 0) { - perror("open"); - return 1; - } - - header = &__header; - ret = read(fd, header, sizeof(*header)); - if (ret < sizeof(*header)) { - printf("could not read %s\n", data->os_file); - goto err_out; - } - - printf("Android Image for '%s'\n", header->name); - - /* - * As on tftp we do not support lseek and we will just have to seek - * for the size of a page - 1 max just buffer instead to read to dummy - * data - */ - buf = xmalloc(header->page_size); - - to_read = header->page_size - sizeof(*header); - ret = read_full(fd, buf, to_read); - if (ret < 0) { - printf("could not read dummy %d from %s\n", to_read, data->os_file); - goto err_out; - } - - cmp = &header->kernel; - data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size); - if (!data->os_res) { - pr_err("Cannot request region 0x%08x - 0x%08x, using default load address\n", - cmp->load_addr, cmp->size); - - data->os_address = mem_start + PAGE_ALIGN(cmp->size * 4); - data->os_res = request_sdram_region("akernel", data->os_address, cmp->size); - if (!data->os_res) { - pr_err("Cannot request region 0x%08x - 0x%08x\n", - cmp->load_addr, cmp->size); - ret = -ENOMEM; - goto err_out; - } - } - - ret = aimage_load_resource(fd, data->os_res, buf, header->page_size); - if (ret < 0) { - perror("could not read kernel"); - goto err_out; - } - - /* - * fastboot always expect a ramdisk - * in barebox we can be less restrictive - */ - cmp = &header->ramdisk; - if (cmp->size) { - data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size); - if (!data->initrd_res) { - ret = -ENOMEM; - goto err_out; - } - - ret = aimage_load_resource(fd, data->initrd_res, buf, header->page_size); - if (ret < 0) { - perror("could not read initrd"); - goto err_out; - } - } - - if (!getenv("aimage_noverwrite_bootargs")) - linux_bootargs_overwrite(header->cmdline); - - if (!getenv("aimage_noverwrite_tags")) - armlinux_set_bootparams((void*)header->tags_addr); - - cmp = &header->second_stage; - if (cmp->size) { - void (*second)(void); - - snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size); - if (!snd_stage_res) { - ret = -ENOMEM; - goto err_out; - } - - ret = aimage_load_resource(fd, snd_stage_res, buf, header->page_size); - if (ret < 0) { - perror("could not read initrd"); - goto err_out; - } - - second = (void*)snd_stage_res->start; - shutdown_barebox(); - - second(); - - restart_machine(); - } - - close(fd); - - /* - * Put devicetree right after initrd if present or after the kernel - * if not. - */ - if (data->initrd_res) - mem_free = PAGE_ALIGN(data->initrd_res->end); - else - mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M); - - return __do_bootm_linux(data, mem_free, 0); - -err_out: - linux_bootargs_overwrite(NULL); - close(fd); - - return ret; -} - -static struct image_handler aimage_handler = { - .name = "ARM Android Image", - .bootm = do_bootm_aimage, - .filetype = filetype_aimage, -}; - -#ifdef CONFIG_BOOTM_AIMAGE -BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs with the one present in aimage"); -BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage"); -#endif - -static struct image_handler arm_fit_handler = { - .name = "FIT image", - .bootm = do_bootm_linux, - .filetype = filetype_oftree, -}; - -static struct binfmt_hook binfmt_aimage_hook = { - .type = filetype_aimage, - .exec = "bootm", -}; - -static struct binfmt_hook binfmt_arm_zimage_hook = { - .type = filetype_arm_zimage, - .exec = "bootm", -}; - -static struct binfmt_hook binfmt_barebox_hook = { - .type = filetype_arm_barebox, - .exec = "bootm", -}; - -static int armlinux_register_image_handler(void) -{ - register_image_handler(&barebox_handler); - register_image_handler(&uimage_handler); - register_image_handler(&rawimage_handler); - register_image_handler(&zimage_handler); - if (IS_BUILTIN(CONFIG_BOOTM_AIMAGE)) { - register_image_handler(&aimage_handler); - binfmt_register(&binfmt_aimage_hook); - } - if (IS_BUILTIN(CONFIG_FITIMAGE)) - register_image_handler(&arm_fit_handler); - binfmt_register(&binfmt_arm_zimage_hook); - binfmt_register(&binfmt_barebox_hook); - - return 0; -} -late_initcall(armlinux_register_image_handler); diff --git a/arch/arm/lib/bootu.c b/arch/arm/lib/bootu.c deleted file mode 100644 index d811da3..0000000 --- a/arch/arm/lib/bootu.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -static int do_bootu(int argc, char *argv[]) -{ - int fd; - void *kernel = NULL; - void *oftree = NULL; - - if (argc != 2) - return COMMAND_ERROR_USAGE; - - fd = open(argv[1], O_RDONLY); - if (fd > 0) - kernel = (void *)memmap(fd, PROT_READ); - - if (!kernel) - kernel = (void *)simple_strtoul(argv[1], NULL, 0); - -#ifdef CONFIG_OFTREE - oftree = of_get_fixed_tree(NULL); -#endif - - start_linux(kernel, 0, 0, 0, oftree, ARM_STATE_SECURE); - - return 1; -} - -static const __maybe_unused char cmd_bootu_help[] = -"Usage: bootu
\n"; - -BAREBOX_CMD_START(bootu) - .cmd = do_bootu, - BAREBOX_CMD_DESC("boot into already loaded Linux kernel") - BAREBOX_CMD_OPTS("ADDRESS") - BAREBOX_CMD_GROUP(CMD_GRP_BOOT) - BAREBOX_CMD_HELP(cmd_bootu_help) -BAREBOX_CMD_END - diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S index 73baff0..9df1800 100644 --- a/arch/arm/lib/pbl.lds.S +++ b/arch/arm/lib/pbl.lds.S @@ -25,8 +25,13 @@ #define BASE (TEXT_BASE - SZ_2M) #endif +#ifdef CONFIG_CPU_32 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) +#else +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +#endif SECTIONS { . = BASE; @@ -34,10 +39,10 @@ PRE_IMAGE . = ALIGN(4); + ._text : { *(._text) } .text : { _stext = .; - _text = .; *(.text_head_entry*) __bare_init_start = .; *(.text_bare_init*) @@ -61,22 +66,22 @@ . = ALIGN(4); .data : { *(.data*) } - .rel.dyn : { - __rel_dyn_start = .; - *(.rel*) - __rel_dyn_end = .; - } + .rel_dyn_start : { *(.__rel_dyn_start) } +#ifdef CONFIG_CPU_32 + .rel.dyn : { *(.rel*) } +#else + .rela.dyn : { *(.rela*) } +#endif + .rel_dyn_end : { *(.__rel_dyn_end) } - .dynsym : { - __dynsym_start = .; - *(.dynsym) - __dynsym_end = .; - } + .__dynsym_start : { *(.__dynsym_start) } + .dynsym : { *(.dynsym) } + .__dynsym_end : { *(.__dynsym_end) } . = ALIGN(4); - __bss_start = .; + .__bss_start : { *(.__bss_start) } .bss : { *(.bss*) } - __bss_stop = .; + .__bss_stop : { *(.__bss_stop) } _end = .; . = ALIGN(4); @@ -87,10 +92,9 @@ __piggydata_end = .; . = ALIGN(4); - .image_end : { - KEEP(*(.image_end)) - } + .image_end : { *(.image_end) } __image_end = .; + _barebox_image_size = __image_end - BASE; _barebox_pbl_size = __bss_start - BASE; } diff --git a/arch/arm/lib32/Makefile b/arch/arm/lib32/Makefile index cdd0732..3c02a0b 100644 --- a/arch/arm/lib32/Makefile +++ b/arch/arm/lib32/Makefile @@ -1,5 +1,7 @@ obj-$(CONFIG_ARM_LINUX) += armlinux.o obj-$(CONFIG_CMD_BOOTZ) += bootz.o +obj-$(CONFIG_BOOTM) += bootm.o +obj-$(CONFIG_CMD_BOOTU) += bootu.o obj-y += div0.o obj-y += findbit.o obj-y += io.o diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S index 6fadc2a..594bf56 100644 --- a/arch/arm/lib32/barebox.lds.S +++ b/arch/arm/lib32/barebox.lds.S @@ -37,10 +37,11 @@ PRE_IMAGE #endif . = ALIGN(4); + + ._text : { *(._text) } .text : { _stext = .; - _text = .; *(.text_entry*) __bare_init_start = .; *(.text_bare_init*) @@ -109,25 +110,21 @@ .dtb : { BAREBOX_DTB() } - .rel.dyn : { - __rel_dyn_start = .; - *(.rel*) - __rel_dyn_end = .; - } + .rel_dyn_start : { *(.__rel_dyn_start) } + .rel.dyn : { *(.rel*) } + .rel_dyn_end : { *(.__rel_dyn_end) } - .dynsym : { - __dynsym_start = .; - *(.dynsym) - __dynsym_end = .; - } + .__dynsym_start : { *(.__dynsym_start) } + .dynsym : { *(.dynsym) } + .__dynsym_end : { *(.__dynsym_end) } _edata = .; .image_end : { *(.__image_end) } . = ALIGN(4); - __bss_start = .; + .__bss_start : { *(.__bss_start) } .bss : { *(.bss*) } - __bss_stop = .; + .__bss_stop : { *(.__bss_stop) } #ifdef CONFIG_ARM_SECURE_MONITOR . = ALIGN(16); diff --git a/arch/arm/lib32/bootm.c b/arch/arm/lib32/bootm.c new file mode 100644 index 0000000..c8bf72f --- /dev/null +++ b/arch/arm/lib32/bootm.c @@ -0,0 +1,620 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * sdram_start_and_size() - determine place for putting the kernel/oftree/initrd + * + * @start: returns the start address of the first RAM bank + * @size: returns the usable space at the beginning of the first RAM bank + * + * This function returns the base address of the first RAM bank and the free + * space found there. + * + * return: 0 for success, negative error code otherwise + */ +static int sdram_start_and_size(unsigned long *start, unsigned long *size) +{ + struct memory_bank *bank; + struct resource *res; + + /* + * We use the first memory bank for the kernel and other resources + */ + bank = list_first_entry_or_null(&memory_banks, struct memory_bank, + list); + if (!bank) { + printf("cannot find first memory bank\n"); + return -EINVAL; + } + + /* + * If the first memory bank has child resources we can use the bank up + * to the beginning of the first child resource, otherwise we can use + * the whole bank. + */ + res = list_first_entry_or_null(&bank->res->children, struct resource, + sibling); + if (res) + *size = res->start - bank->start; + else + *size = bank->size; + + *start = bank->start; + + return 0; +} + +static int get_kernel_addresses(size_t image_size, + int verbose, unsigned long *load_address, + unsigned long *mem_free) +{ + unsigned long mem_start, mem_size; + int ret; + size_t image_decomp_size; + unsigned long spacing; + + ret = sdram_start_and_size(&mem_start, &mem_size); + if (ret) + return ret; + + /* + * The kernel documentation "Documentation/arm/Booting" advises + * to place the compressed image outside of the lowest 32 MiB to + * avoid relocation. We should do this if we have at least 64 MiB + * of ram. If we have less space, we assume a maximum + * compression factor of 5. + */ + image_decomp_size = PAGE_ALIGN(image_size * 5); + if (mem_size >= SZ_64M) + image_decomp_size = max_t(size_t, image_decomp_size, SZ_32M); + + /* + * By default put oftree/initrd close behind compressed kernel image to + * avoid placing it outside of the kernels lowmem region. + */ + spacing = SZ_1M; + + if (*load_address == UIMAGE_INVALID_ADDRESS) { + /* + * Place the kernel at an address where it does not need to + * relocate itself before decompression. + */ + *load_address = mem_start + image_decomp_size; + if (verbose) + printf("no OS load address, defaulting to 0x%08lx\n", + *load_address); + } else if (*load_address <= mem_start + image_decomp_size) { + /* + * If the user/image specified an address where the kernel needs + * to relocate itself before decompression we need to extend the + * spacing to allow this relocation to happen without + * overwriting anything placed behind the kernel. + */ + spacing += image_decomp_size; + } + + *mem_free = PAGE_ALIGN(*load_address + image_size + spacing); + + /* + * Place oftree/initrd outside of the first 128 MiB, if we have space + * for it. This avoids potential conflicts with the kernel decompressor. + */ + if (mem_size > SZ_256M) + *mem_free = max(*mem_free, mem_start + SZ_128M); + + return 0; +} + +static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int swap) +{ + unsigned long kernel; + unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0; + enum arm_security_state state = bootm_arm_security_state(); + int ret; + + kernel = data->os_res->start + data->os_entry; + + initrd_start = data->initrd_address; + + if (initrd_start == UIMAGE_INVALID_ADDRESS) { + initrd_start = PAGE_ALIGN(free_mem); + + if (bootm_verbose(data)) { + printf("no initrd load address, defaulting to 0x%08lx\n", + initrd_start); + } + } + + if (bootm_has_initrd(data)) { + ret = bootm_load_initrd(data, initrd_start); + if (ret) + return ret; + } + + if (data->initrd_res) { + initrd_start = data->initrd_res->start; + initrd_end = data->initrd_res->end; + initrd_size = resource_size(data->initrd_res); + free_mem = PAGE_ALIGN(initrd_end + 1); + } + + ret = bootm_load_devicetree(data, free_mem); + if (ret) + return ret; + + if (bootm_verbose(data)) { + printf("\nStarting kernel at 0x%08lx", kernel); + if (initrd_size) + printf(", initrd at 0x%08lx", initrd_start); + if (data->oftree) + printf(", oftree at 0x%p", data->oftree); + printf("...\n"); + } + + if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR)) { + if (file_detect_type((void *)data->os_res->start, 0x100) == + filetype_arm_barebox) + state = ARM_STATE_SECURE; + + printf("Starting kernel in %s mode\n", + bootm_arm_security_state_name(state)); + } + + if (data->dryrun) + return 0; + + start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree, + state); + + restart_machine(); + + return -ERESTARTSYS; +} + +static int do_bootm_linux(struct image_data *data) +{ + unsigned long load_address, mem_free; + int ret; + + load_address = data->os_address; + + ret = get_kernel_addresses(bootm_get_os_size(data), + bootm_verbose(data), &load_address, &mem_free); + if (ret) + return ret; + + ret = bootm_load_os(data, load_address); + if (ret) + return ret; + + return __do_bootm_linux(data, mem_free, 0); +} + +static struct image_handler uimage_handler = { + .name = "ARM Linux uImage", + .bootm = do_bootm_linux, + .filetype = filetype_uimage, + .ih_os = IH_OS_LINUX, +}; + +static struct image_handler rawimage_handler = { + .name = "ARM raw image", + .bootm = do_bootm_linux, + .filetype = filetype_unknown, +}; + +struct zimage_header { + u32 unused[9]; + u32 magic; + u32 start; + u32 end; +}; + +#define ZIMAGE_MAGIC 0x016F2818 + +static int do_bootz_linux_fdt(int fd, struct image_data *data) +{ + struct fdt_header __header, *header; + void *oftree; + int ret; + + u32 end; + + if (data->oftree) + return -ENXIO; + + header = &__header; + ret = read(fd, header, sizeof(*header)); + if (ret < 0) + return ret; + if (ret < sizeof(*header)) + return -ENXIO; + + if (file_detect_type(header, sizeof(*header)) != filetype_oftree) + return -ENXIO; + + end = be32_to_cpu(header->totalsize); + + oftree = malloc(end + 0x8000); + if (!oftree) { + perror("zImage: oftree malloc"); + return -ENOMEM; + } + + memcpy(oftree, header, sizeof(*header)); + + end -= sizeof(*header); + + ret = read_full(fd, oftree + sizeof(*header), end); + if (ret < 0) + goto err_free; + if (ret < end) { + printf("premature end of image\n"); + ret = -EIO; + goto err_free; + } + + if (IS_BUILTIN(CONFIG_OFTREE)) { + struct device_node *root; + + root = of_unflatten_dtb(oftree); + if (IS_ERR(root)) { + pr_err("unable to unflatten devicetree\n"); + goto err_free; + } + data->oftree = of_get_fixed_tree(root); + if (!data->oftree) { + pr_err("Unable to get fixed tree\n"); + ret = -EINVAL; + goto err_free; + } + + free(oftree); + } else { + data->oftree = oftree; + } + + pr_info("zImage: concatenated oftree detected\n"); + + return 0; + +err_free: + free(oftree); + + return ret; +} + +static int do_bootz_linux(struct image_data *data) +{ + int fd, ret, swap = 0; + struct zimage_header __header, *header; + void *zimage; + u32 end, start; + size_t image_size; + unsigned long load_address = data->os_address; + unsigned long mem_free; + + fd = open(data->os_file, O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + header = &__header; + ret = read(fd, header, sizeof(*header)); + if (ret < sizeof(*header)) { + printf("could not read %s\n", data->os_file); + goto err_out; + } + + switch (header->magic) { + case swab32(ZIMAGE_MAGIC): + swap = 1; + /* fall through */ + case ZIMAGE_MAGIC: + break; + default: + printf("invalid magic 0x%08x\n", header->magic); + ret = -EINVAL; + goto err_out; + } + + end = header->end; + start = header->start; + + if (swap) { + end = swab32(end); + start = swab32(start); + } + + image_size = end - start; + load_address = data->os_address; + + ret = get_kernel_addresses(image_size, bootm_verbose(data), + &load_address, &mem_free); + if (ret) + return ret; + + data->os_res = request_sdram_region("zimage", load_address, image_size); + if (!data->os_res) { + pr_err("bootm/zImage: failed to request memory at 0x%lx to 0x%lx (%zu).\n", + load_address, load_address + image_size, image_size); + ret = -ENOMEM; + goto err_out; + } + + zimage = (void *)data->os_res->start; + + memcpy(zimage, header, sizeof(*header)); + + ret = read_full(fd, zimage + sizeof(*header), + image_size - sizeof(*header)); + if (ret < 0) + goto err_out; + if (ret < image_size - sizeof(*header)) { + printf("premature end of image\n"); + ret = -EIO; + goto err_out; + } + + if (swap) { + void *ptr; + for (ptr = zimage; ptr < zimage + end; ptr += 4) + *(u32 *)ptr = swab32(*(u32 *)ptr); + } + + ret = do_bootz_linux_fdt(fd, data); + if (ret && ret != -ENXIO) + goto err_out; + + close(fd); + + return __do_bootm_linux(data, mem_free, swap); + +err_out: + close(fd); + + return ret; +} + +static struct image_handler zimage_handler = { + .name = "ARM zImage", + .bootm = do_bootz_linux, + .filetype = filetype_arm_zimage, +}; + +static struct image_handler barebox_handler = { + .name = "ARM barebox", + .bootm = do_bootm_linux, + .filetype = filetype_arm_barebox, +}; + +#include + +static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps) +{ + int ret; + void *image = (void *)r->start; + unsigned to_read = ps - resource_size(r) % ps; + + ret = read_full(fd, image, resource_size(r)); + if (ret < 0) + return ret; + + ret = read_full(fd, buf, to_read); + if (ret < 0) + printf("could not read dummy %u\n", to_read); + + return ret; +} + +static int do_bootm_aimage(struct image_data *data) +{ + struct resource *snd_stage_res; + int fd, ret; + struct android_header __header, *header; + void *buf; + int to_read; + struct android_header_comp *cmp; + unsigned long mem_free; + unsigned long mem_start, mem_size; + + ret = sdram_start_and_size(&mem_start, &mem_size); + if (ret) + return ret; + + fd = open(data->os_file, O_RDONLY); + if (fd < 0) { + perror("open"); + return 1; + } + + header = &__header; + ret = read(fd, header, sizeof(*header)); + if (ret < sizeof(*header)) { + printf("could not read %s\n", data->os_file); + goto err_out; + } + + printf("Android Image for '%s'\n", header->name); + + /* + * As on tftp we do not support lseek and we will just have to seek + * for the size of a page - 1 max just buffer instead to read to dummy + * data + */ + buf = xmalloc(header->page_size); + + to_read = header->page_size - sizeof(*header); + ret = read_full(fd, buf, to_read); + if (ret < 0) { + printf("could not read dummy %d from %s\n", to_read, data->os_file); + goto err_out; + } + + cmp = &header->kernel; + data->os_res = request_sdram_region("akernel", cmp->load_addr, cmp->size); + if (!data->os_res) { + pr_err("Cannot request region 0x%08x - 0x%08x, using default load address\n", + cmp->load_addr, cmp->size); + + data->os_address = mem_start + PAGE_ALIGN(cmp->size * 4); + data->os_res = request_sdram_region("akernel", data->os_address, cmp->size); + if (!data->os_res) { + pr_err("Cannot request region 0x%08x - 0x%08x\n", + cmp->load_addr, cmp->size); + ret = -ENOMEM; + goto err_out; + } + } + + ret = aimage_load_resource(fd, data->os_res, buf, header->page_size); + if (ret < 0) { + perror("could not read kernel"); + goto err_out; + } + + /* + * fastboot always expect a ramdisk + * in barebox we can be less restrictive + */ + cmp = &header->ramdisk; + if (cmp->size) { + data->initrd_res = request_sdram_region("ainitrd", cmp->load_addr, cmp->size); + if (!data->initrd_res) { + ret = -ENOMEM; + goto err_out; + } + + ret = aimage_load_resource(fd, data->initrd_res, buf, header->page_size); + if (ret < 0) { + perror("could not read initrd"); + goto err_out; + } + } + + if (!getenv("aimage_noverwrite_bootargs")) + linux_bootargs_overwrite(header->cmdline); + + if (!getenv("aimage_noverwrite_tags")) + armlinux_set_bootparams((void *)(unsigned long)header->tags_addr); + + cmp = &header->second_stage; + if (cmp->size) { + void (*second)(void); + + snd_stage_res = request_sdram_region("asecond", cmp->load_addr, cmp->size); + if (!snd_stage_res) { + ret = -ENOMEM; + goto err_out; + } + + ret = aimage_load_resource(fd, snd_stage_res, buf, header->page_size); + if (ret < 0) { + perror("could not read initrd"); + goto err_out; + } + + second = (void*)snd_stage_res->start; + shutdown_barebox(); + + second(); + + restart_machine(); + } + + close(fd); + + /* + * Put devicetree right after initrd if present or after the kernel + * if not. + */ + if (data->initrd_res) + mem_free = PAGE_ALIGN(data->initrd_res->end); + else + mem_free = PAGE_ALIGN(data->os_res->end + SZ_1M); + + return __do_bootm_linux(data, mem_free, 0); + +err_out: + linux_bootargs_overwrite(NULL); + close(fd); + + return ret; +} + +static struct image_handler aimage_handler = { + .name = "ARM Android Image", + .bootm = do_bootm_aimage, + .filetype = filetype_aimage, +}; + +#ifdef CONFIG_BOOTM_AIMAGE +BAREBOX_MAGICVAR(aimage_noverwrite_bootargs, "Disable overwrite of the bootargs with the one present in aimage"); +BAREBOX_MAGICVAR(aimage_noverwrite_tags, "Disable overwrite of the tags addr with the one present in aimage"); +#endif + +static struct image_handler arm_fit_handler = { + .name = "FIT image", + .bootm = do_bootm_linux, + .filetype = filetype_oftree, +}; + +static struct binfmt_hook binfmt_aimage_hook = { + .type = filetype_aimage, + .exec = "bootm", +}; + +static struct binfmt_hook binfmt_arm_zimage_hook = { + .type = filetype_arm_zimage, + .exec = "bootm", +}; + +static struct binfmt_hook binfmt_barebox_hook = { + .type = filetype_arm_barebox, + .exec = "bootm", +}; + +static int armlinux_register_image_handler(void) +{ + register_image_handler(&barebox_handler); + register_image_handler(&uimage_handler); + register_image_handler(&rawimage_handler); + register_image_handler(&zimage_handler); + if (IS_BUILTIN(CONFIG_BOOTM_AIMAGE)) { + register_image_handler(&aimage_handler); + binfmt_register(&binfmt_aimage_hook); + } + if (IS_BUILTIN(CONFIG_FITIMAGE)) + register_image_handler(&arm_fit_handler); + binfmt_register(&binfmt_arm_zimage_hook); + binfmt_register(&binfmt_barebox_hook); + + return 0; +} +late_initcall(armlinux_register_image_handler); diff --git a/arch/arm/lib32/bootu.c b/arch/arm/lib32/bootu.c new file mode 100644 index 0000000..d811da3 --- /dev/null +++ b/arch/arm/lib32/bootu.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include +#include +#include +#include + +static int do_bootu(int argc, char *argv[]) +{ + int fd; + void *kernel = NULL; + void *oftree = NULL; + + if (argc != 2) + return COMMAND_ERROR_USAGE; + + fd = open(argv[1], O_RDONLY); + if (fd > 0) + kernel = (void *)memmap(fd, PROT_READ); + + if (!kernel) + kernel = (void *)simple_strtoul(argv[1], NULL, 0); + +#ifdef CONFIG_OFTREE + oftree = of_get_fixed_tree(NULL); +#endif + + start_linux(kernel, 0, 0, 0, oftree, ARM_STATE_SECURE); + + return 1; +} + +static const __maybe_unused char cmd_bootu_help[] = +"Usage: bootu
\n"; + +BAREBOX_CMD_START(bootu) + .cmd = do_bootu, + BAREBOX_CMD_DESC("boot into already loaded Linux kernel") + BAREBOX_CMD_OPTS("ADDRESS") + BAREBOX_CMD_GROUP(CMD_GRP_BOOT) + BAREBOX_CMD_HELP(cmd_bootu_help) +BAREBOX_CMD_END + diff --git a/arch/arm/lib32/runtime-offset.S b/arch/arm/lib32/runtime-offset.S index 7375cb9..f86ca78 100644 --- a/arch/arm/lib32/runtime-offset.S +++ b/arch/arm/lib32/runtime-offset.S @@ -10,42 +10,10 @@ ENTRY(get_runtime_offset) 1: adr r0, 1b ldr r1, linkadr - subs r0, r1, r0 -THUMB( subs r0, r0, #1) + subs r0, r0, r1 +THUMB( adds r0, r0, #1) mov pc, lr linkadr: .word get_runtime_offset ENDPROC(get_runtime_offset) - -.globl __ld_var_base -__ld_var_base: - -/* - * Functions to calculate selected linker supplied variables during runtime. - * This is needed for relocatable binaries when the linker variables are - * needed before finxing up the relocations. - */ -.macro ld_var_entry name - ENTRY(__ld_var_\name) - ldr r0, __\name - b 1f - __\name: .word \name - __ld_var_base - ENDPROC(__ld_var_\name) -.endm - -ld_var_entry _text -ld_var_entry __rel_dyn_start -ld_var_entry __rel_dyn_end -ld_var_entry __dynsym_start -ld_var_entry __dynsym_end -ld_var_entry __bss_start -ld_var_entry __bss_stop -#ifdef __PBL__ -ld_var_entry __image_end -#endif - -1: - ldr r1, =__ld_var_base - adds r0, r0, r1 - mov pc, lr diff --git a/arch/arm/lib64/Makefile b/arch/arm/lib64/Makefile index 4b7b7e3..7764712 100644 --- a/arch/arm/lib64/Makefile +++ b/arch/arm/lib64/Makefile @@ -1,7 +1,9 @@ +obj-y += stacktrace.o obj-$(CONFIG_ARM_LINUX) += armlinux.o obj-y += div0.o obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o extra-y += barebox.lds +obj-pbl-y += runtime-offset.o pbl-y += div0.o diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c index 54ce6ca..238e8b6 100644 --- a/arch/arm/lib64/armlinux.c +++ b/arch/arm/lib64/armlinux.c @@ -1,51 +1,127 @@ /* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger + * Copyright (C) 2018 Sascha Hauer * - * Copyright (C) 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. */ #include #include -#include -#include #include #include -#include #include -#include #include #include #include #include #include #include -#include - +#include +#include +#include #include #include #include #include #include -void start_linux(void *adr, int swap, unsigned long initrd_address, - unsigned long initrd_size, void *oftree, - enum arm_security_state bootm_secure_state) +static int do_bootm_linux(struct image_data *data) { - void (*kernel)(void *dtb) = adr; + void (*fn)(unsigned long dtb, unsigned long x1, unsigned long x2, + unsigned long x3); + resource_size_t start, end; + unsigned long text_offset, image_size, devicetree, kernel; + int ret; + + text_offset = le64_to_cpup(data->os_header + 8); + image_size = le64_to_cpup(data->os_header + 16); + + ret = memory_bank_first_find_space(&start, &end); + if (ret) + goto out; + + kernel = ALIGN(start, SZ_2M) + text_offset; + + ret = bootm_load_os(data, kernel); + if (ret) + goto out; + + devicetree = ALIGN(kernel + image_size, PAGE_SIZE); + + ret = bootm_load_devicetree(data, devicetree); + if (ret) + goto out; + + printf("Loaded kernel to 0x%08lx, devicetree at 0x%08lx\n", + kernel, devicetree); shutdown_barebox(); - kernel(oftree); + fn = (void *)kernel; + + fn(devicetree, 0, 0, 0); + + ret = -EINVAL; + +out: + return ret; } + +static struct image_handler aarch64_linux_handler = { + .name = "ARM aarch64 Linux image", + .bootm = do_bootm_linux, + .filetype = filetype_arm64_linux_image, +}; + +static int do_bootm_barebox(struct image_data *data) +{ + void (*fn)(unsigned long x0, unsigned long x1, unsigned long x2, + unsigned long x3); + resource_size_t start, end; + unsigned long barebox; + int ret; + + ret = memory_bank_first_find_space(&start, &end); + if (ret) + goto out; + + barebox = start; + + ret = bootm_load_os(data, barebox); + if (ret) + goto out; + + printf("Loaded barebox image to 0x%08lx\n", barebox); + + shutdown_barebox(); + + fn = (void *)barebox; + + fn(0, 0, 0, 0); + + ret = -EINVAL; + +out: + return ret; +} + +static struct image_handler aarch64_barebox_handler = { + .name = "ARM aarch64 barebox image", + .bootm = do_bootm_barebox, + .filetype = filetype_arm_barebox, +}; + +static int aarch64_register_image_handler(void) +{ + register_image_handler(&aarch64_linux_handler); + register_image_handler(&aarch64_barebox_handler); + + return 0; +} +late_initcall(aarch64_register_image_handler); diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S index a53b933..08adc44 100644 --- a/arch/arm/lib64/barebox.lds.S +++ b/arch/arm/lib64/barebox.lds.S @@ -35,10 +35,10 @@ PRE_IMAGE #endif . = ALIGN(4); + ._text : { *(._text) } .text : { _stext = .; - _text = .; *(.text_entry*) __bare_init_start = .; *(.text_bare_init*) @@ -53,22 +53,6 @@ . = ALIGN(4); .rodata : { *(.rodata*) } -#ifdef CONFIG_ARM_UNWIND - /* - * Stack unwinding tables - */ - . = ALIGN(8); - .ARM.unwind_idx : { - __start_unwind_idx = .; - *(.ARM.exidx*) - __stop_unwind_idx = .; - } - .ARM.unwind_tab : { - __start_unwind_tab = .; - *(.ARM.extab*) - __stop_unwind_tab = .; - } -#endif _etext = .; /* End of text and rodata section */ _sdata = .; @@ -106,24 +90,20 @@ .dtb : { BAREBOX_DTB() } - .rel.dyn : { - __rel_dyn_start = .; - *(.rel*) - __rel_dyn_end = .; - } + .rel_dyn_start : { *(.__rel_dyn_start) } + .rela.dyn : { *(.rela*) } + .rel_dyn_end : { *(.__rel_dyn_end) } - .dynsym : { - __dynsym_start = .; - *(.dynsym) - __dynsym_end = .; - } + .__dynsym_start : { *(.__dynsym_start) } + .dynsym : { *(.dynsym) } + .__dynsym_end : { *(.__dynsym_end) } _edata = .; . = ALIGN(4); - __bss_start = .; + .__bss_start : { *(.__bss_start) } .bss : { *(.bss*) } - __bss_stop = .; + .__bss_stop : { *(.__bss_stop) } _end = .; _barebox_image_size = __bss_start - TEXT_BASE; } diff --git a/arch/arm/lib64/runtime-offset.S b/arch/arm/lib64/runtime-offset.S new file mode 100644 index 0000000..177ca64 --- /dev/null +++ b/arch/arm/lib64/runtime-offset.S @@ -0,0 +1,19 @@ +#include +#include + +.section ".text_bare_init","ax" + +/* + * Get the offset between the link address and the address + * we are currently running at. + */ +ENTRY(get_runtime_offset) +1: adr x0, 1b + ldr x1, linkadr + subs x0, x0, x1 + ret + +.align 3 +linkadr: +.quad get_runtime_offset +ENDPROC(get_runtime_offset) diff --git a/arch/arm/lib64/stacktrace.c b/arch/arm/lib64/stacktrace.c new file mode 100644 index 0000000..b8352c1 --- /dev/null +++ b/arch/arm/lib64/stacktrace.c @@ -0,0 +1,86 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ + +#include +#include + +#define THREAD_SIZE 16384 + +/* + * AArch64 PCS assigns the frame pointer to x29. + * + * A simple function prologue looks like this: + * sub sp, sp, #0x10 + * stp x29, x30, [sp] + * mov x29, sp + * + * A simple function epilogue looks like this: + * mov sp, x29 + * ldp x29, x30, [sp] + * add sp, sp, #0x10 + */ +int unwind_frame(struct stackframe *frame) +{ + unsigned long high, low; + unsigned long fp = frame->fp; + + low = frame->sp; + high = ALIGN(low, THREAD_SIZE); + + if (fp < low || fp > high - 0x18 || fp & 0xf) + return -EINVAL; + + frame->sp = fp + 0x10; + frame->fp = *(unsigned long *)(fp); + frame->pc = *(unsigned long *)(fp + 8); + + return 0; +} + +void dump_backtrace_entry(unsigned long where, unsigned long from) +{ +#ifdef CONFIG_KALLSYMS + printf("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from); +#else + printf("Function entered at [<%08lx>] from [<%08lx>]\n", where, from); +#endif +} + +void unwind_backtrace(struct pt_regs *regs) +{ + struct stackframe frame = {}; + register unsigned long current_sp asm ("sp"); + + if (regs) { + frame.fp = regs->regs[29]; + frame.pc = regs->elr; + } else { + frame.fp = (unsigned long)__builtin_frame_address(0); + frame.sp = current_sp; + frame.pc = (unsigned long)unwind_backtrace; + } + + printf("Call trace:\n"); + while (1) { + unsigned long where = frame.pc; + int ret; + + ret = unwind_frame(&frame); + if (ret < 0) + break; + dump_backtrace_entry(where, frame.pc); + } +} + +void dump_stack(void) +{ + unwind_backtrace(NULL); +} diff --git a/arch/arm/mach-imx/xload-common.c b/arch/arm/mach-imx/xload-common.c index 2644438..13cd612 100644 --- a/arch/arm/mach-imx/xload-common.c +++ b/arch/arm/mach-imx/xload-common.c @@ -5,7 +5,7 @@ int imx_image_size(void) { - uint32_t *image_end = (void *)ld_var(__image_end); + uint32_t *image_end = (void *)__image_end; uint32_t payload_len, pbl_len, imx_header_len, sizep; void *pg_start; @@ -15,7 +15,7 @@ imx_header_len = SZ_4K; /* The length of the PBL image */ - pbl_len = ld_var(__image_end) - ld_var(_text); + pbl_len = __image_end - _text; sizep = 4; diff --git a/arch/arm/mach-mvebu/include/mach/common.h b/arch/arm/mach-mvebu/include/mach/common.h index 529eb61..8e15723 100644 --- a/arch/arm/mach-mvebu/include/mach/common.h +++ b/arch/arm/mach-mvebu/include/mach/common.h @@ -25,12 +25,12 @@ #define MVEBU_REMAP_INT_REG_BASE 0xf1000000 /* #including yields a circle, so we need a forward decl */ -uint32_t get_runtime_offset(void); +unsigned long get_runtime_offset(void); static inline void __iomem *mvebu_get_initial_int_reg_base(void) { #ifdef __PBL__ - u32 base = __get_unaligned_le32(_text - get_runtime_offset() + 0x30); + u32 base = __get_unaligned_le32(_text + get_runtime_offset() + 0x30); return (void __force __iomem *)base; #else return (void __force __iomem *)MVEBU_REMAP_INT_REG_BASE; diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h index e9ba5ee..c862778 100644 --- a/arch/arm/mach-tegra/include/mach/lowlevel.h +++ b/arch/arm/mach-tegra/include/mach/lowlevel.h @@ -264,7 +264,7 @@ arm_setup_stack(TEGRA_IRAM_BASE + SZ_256K - 8); if (tegra_cpu_is_maincomplex()) - tegra_maincomplex_entry(fdt - get_runtime_offset()); + tegra_maincomplex_entry(fdt + get_runtime_offset()); tegra_ll_delay_setup(); } diff --git a/arch/arm/mach-tegra/tegra_avp_init.c b/arch/arm/mach-tegra/tegra_avp_init.c index 16dc65b..8a11e06 100644 --- a/arch/arm/mach-tegra/tegra_avp_init.c +++ b/arch/arm/mach-tegra/tegra_avp_init.c @@ -140,7 +140,7 @@ conf = &pllx_config_table[chiptype][osc_freq]; /* we are not relocated yet - globals are a bit more tricky here */ - conf = (struct pll_config *)((char *)conf - get_runtime_offset()); + conf = (struct pll_config *)((char *)conf + get_runtime_offset()); /* set PLL bypass and frequency parameters */ reg = CRC_PLLX_BASE_BYPASS; diff --git a/arch/mips/lib/dma-default.c b/arch/mips/lib/dma-default.c index 9b2fe7d..71c1e42 100644 --- a/arch/mips/lib/dma-default.c +++ b/arch/mips/lib/dma-default.c @@ -44,13 +44,13 @@ } #endif -void dma_sync_single_for_cpu(unsigned long address, size_t size, +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir) { __dma_sync_mips(address, size, dir); } -void dma_sync_single_for_device(unsigned long address, size_t size, +void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir) { __dma_sync_mips(address, size, dir); diff --git a/arch/openrisc/cpu/cpu.c b/arch/openrisc/cpu/cpu.c index e7f9445..cae42d4 100644 --- a/arch/openrisc/cpu/cpu.c +++ b/arch/openrisc/cpu/cpu.c @@ -23,11 +23,6 @@ #include #include -int cleanup_before_linux(void) -{ - return 0; -} - extern void __reset(void); static void __noreturn openrisc_restart_cpu(struct restart_handler *rst) diff --git a/commands/Kconfig b/commands/Kconfig index 17bbe0f..951a869 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -348,7 +348,7 @@ config CMD_BOOTU tristate default y - depends on ARM + depends on ARM && !CPU_64v8 prompt "bootu" help Boot into already loaded Linux kernel, which must be raw (uncompressed). @@ -357,7 +357,7 @@ config CMD_BOOTZ tristate - depends on ARM + depends on ARM && !CPU_64v8 prompt "bootz" help Boot Linux zImage diff --git a/common/Kconfig b/common/Kconfig index af71d68..b7000c4 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -344,7 +344,7 @@ This is useful to print a nice backtrace when an exception occurs. config RELOCATABLE - depends on PPC || (ARM && !CPU_V8) + depends on PPC || ARM bool "generate relocatable barebox binary" help A non relocatable barebox binary will run at it's compiled in diff --git a/common/bootm.c b/common/bootm.c index 3e48ca1..5ff6683 100644 --- a/common/bootm.c +++ b/common/bootm.c @@ -529,6 +529,7 @@ struct image_handler *handler; int ret; enum filetype os_type; + size_t size; if (!bootm_data->os_file) { printf("no image given\n"); @@ -548,7 +549,13 @@ data->os_address = bootm_data->os_address; data->os_entry = bootm_data->os_entry; - os_type = file_name_detect_type(data->os_file); + ret = read_file_2(data->os_file, &size, &data->os_header, PAGE_SIZE); + if (ret < 0 && ret != -EFBIG) + goto err_out; + if (size < PAGE_SIZE) + goto err_out; + + os_type = file_detect_type(data->os_header, PAGE_SIZE); if ((int)os_type < 0) { printf("could not open %s: %s\n", data->os_file, strerror(-os_type)); @@ -674,6 +681,7 @@ of_delete_node(data->of_root_node); globalvar_remove("linux.bootargs.bootm.appendroot"); + free(data->os_header); free(data->os_file); free(data->oftree_file); free(data->initrd_file); diff --git a/common/filetype.c b/common/filetype.c index 71691fd..444ec14 100644 --- a/common/filetype.c +++ b/common/filetype.c @@ -67,6 +67,7 @@ [filetype_socfpga_xload] = { "SoCFPGA prebootloader image", "socfpga-xload" }, [filetype_kwbimage_v1] = { "MVEBU kwbimage (v1)", "kwb" }, [filetype_android_sparse] = { "Android sparse image", "sparse" }, + [filetype_arm64_linux_image] = { "ARM aarch64 Linux image", "aarch64-linux" }, }; const char *file_type_to_string(enum filetype f) @@ -296,6 +297,8 @@ return filetype_mips_barebox; if (buf[0] == be32_to_cpu(0x534F4659)) return filetype_bpk; + if (le32_to_cpu(buf[14]) == 0x644d5241) + return filetype_arm64_linux_image; if ((buf8[0] == 0x5a || buf8[0] == 0x69 || buf8[0] == 0x78 || buf8[0] == 0x8b || buf8[0] == 0x9c) && buf8[0x1] == 0 && buf8[0x2] == 0 && buf8[0x3] == 0 && diff --git a/common/memory.c b/common/memory.c index ff5bdc1..00fa7c5 100644 --- a/common/memory.c +++ b/common/memory.c @@ -171,6 +171,57 @@ return release_region(res); } +void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart, + resource_size_t *retend) +{ + resource_size_t freeptr, size, maxfree = 0; + struct resource *last, *child; + + if (list_empty(&bank->res->children)) { + /* No children - return the whole bank */ + *retstart = bank->res->start; + *retend = bank->res->end; + return; + } + + freeptr = bank->res->start; + + list_for_each_entry(child, &bank->res->children, sibling) { + /* Check gaps between child resources */ + size = child->start - freeptr; + if (size > maxfree) { + *retstart = freeptr; + *retend = child->start - 1; + maxfree = size; + } + freeptr = child->start + resource_size(child); + } + + last = list_last_entry(&bank->res->children, struct resource, sibling); + + /* Check gap between last child and end of memory bank */ + freeptr = last->start + resource_size(last); + size = bank->res->start + resource_size(bank->res) - freeptr; + + if (size > maxfree) { + *retstart = freeptr; + *retend = bank->res->end; + } +} + +int memory_bank_first_find_space(resource_size_t *retstart, + resource_size_t *retend) +{ + struct memory_bank *bank; + + for_each_memory_bank(bank) { + memory_bank_find_space(bank, retstart, retend); + return 0; + } + + return -ENOENT; +} + #ifdef CONFIG_OFTREE static int of_memory_fixup(struct device_node *node, void *unused) diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 23ad20a..3d63f7f 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -65,3 +65,8 @@ config CLOCKSOURCE_ATMEL_PIT bool depends on SOC_AT91SAM9 || SOC_SAMA5 + +config CLOCKSOURCE_ARMV8_TIMER + bool + default y + depends on ARM && CPU_64v8 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index f774ede..ea33fff 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -11,3 +11,4 @@ obj-$(CONFIG_CLOCKSOURCE_UEMD) += uemd.o obj-$(CONFIG_CLOCKSOURCE_ROCKCHIP)+= rk_timer.o obj-$(CONFIG_CLOCKSOURCE_ATMEL_PIT) += timer-atmel-pit.o +obj-$(CONFIG_CLOCKSOURCE_ARMV8_TIMER) += armv8-timer.o diff --git a/drivers/clocksource/armv8-timer.c b/drivers/clocksource/armv8-timer.c new file mode 100644 index 0000000..57b0b69 --- /dev/null +++ b/drivers/clocksource/armv8-timer.c @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2018 Sascha Hauer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include + +uint64_t armv8_clocksource_read(void) +{ + unsigned long cntpct; + + isb(); + asm volatile("mrs %0, cntpct_el0" : "=r" (cntpct)); + + return cntpct; +} + +static struct clocksource cs = { + .read = armv8_clocksource_read, + .mask = CLOCKSOURCE_MASK(64), + .shift = 0, +}; + +static int armv8_timer_probe(struct device_d *dev) +{ + unsigned long cntfrq; + + asm volatile("mrs %0, cntfrq_el0" : "=r" (cntfrq)); + + cs.mult = clocksource_hz2mult(cntfrq, cs.shift); + + return init_clock(&cs); +} + +static struct of_device_id armv8_timer_dt_ids[] = { + { .compatible = "arm,armv8-timer", }, + { } +}; + +static struct driver_d armv8_timer_driver = { + .name = "armv8-timer", + .probe = armv8_timer_probe, + .of_compatible = DRV_OF_COMPAT(armv8_timer_dt_ids), +}; + +static int armv8_timer_init(void) +{ + return platform_driver_register(&armv8_timer_driver); +} +postcore_initcall(armv8_timer_init); diff --git a/include/bootm.h b/include/bootm.h index 35c18dc..62951d6 100644 --- a/include/bootm.h +++ b/include/bootm.h @@ -81,6 +81,13 @@ struct fdt_header *oftree; struct resource *oftree_res; + /* + * The first PAGE_SIZE bytes of the OS image. Can be used by the image + * handlers to analyze the OS image before actually loading the bulk of + * it. + */ + void *os_header; + enum bootm_verify verify; int verbose; int force; diff --git a/include/debug_ll.h b/include/debug_ll.h index b0eb7cd..5047516 100644 --- a/include/debug_ll.h +++ b/include/debug_ll.h @@ -42,7 +42,7 @@ { int i; unsigned char ch; - for (i = 8; i--; ) { + for (i = sizeof(unsigned long) * 2; i--; ) { ch = ((value >> (i * 4)) & 0xf); ch += (ch >= 10) ? 'a' - 10 : '0'; putc_ll(ch); diff --git a/include/dma.h b/include/dma.h index 4d31797..5fdcb17 100644 --- a/include/dma.h +++ b/include/dma.h @@ -30,11 +30,23 @@ } #endif +dma_addr_t dma_map_single(struct device_d *dev, void *ptr, size_t size, + enum dma_data_direction dir); +void dma_unmap_single(struct device_d *dev, dma_addr_t addr, size_t size, + enum dma_data_direction dir); + +#define DMA_ERROR_CODE (~(dma_addr_t)0) + +static inline int dma_mapping_error(struct device_d *dev, dma_addr_t dma_addr) +{ + return dma_addr == DMA_ERROR_CODE; +} + /* streaming DMA - implement the below calls to support HAS_DMA */ -void dma_sync_single_for_cpu(unsigned long address, size_t size, +void dma_sync_single_for_cpu(dma_addr_t address, size_t size, enum dma_data_direction dir); -void dma_sync_single_for_device(unsigned long address, size_t size, +void dma_sync_single_for_device(dma_addr_t address, size_t size, enum dma_data_direction dir); void *dma_alloc_coherent(size_t size, dma_addr_t *dma_handle); diff --git a/include/dt-bindings/clock/tegra30-car.h b/include/dt-bindings/clock/tegra30-car.h deleted file mode 100644 index e40fae8..0000000 --- a/include/dt-bindings/clock/tegra30-car.h +++ /dev/null @@ -1,265 +0,0 @@ -/* - * This header provides constants for binding nvidia,tegra30-car. - * - * The first 130 clocks are numbered to match the bits in the CAR's CLK_OUT_ENB - * registers. These IDs often match those in the CAR's RST_DEVICES registers, - * but not in all cases. Some bits in CLK_OUT_ENB affect multiple clocks. In - * this case, those clocks are assigned IDs above 160 in order to highlight - * this issue. Implementations that interpret these clock IDs as bit values - * within the CLK_OUT_ENB or RST_DEVICES registers should be careful to - * explicitly handle these special cases. - * - * The balance of the clocks controlled by the CAR are assigned IDs of 160 and - * above. - */ - -#ifndef _DT_BINDINGS_CLOCK_TEGRA30_CAR_H -#define _DT_BINDINGS_CLOCK_TEGRA30_CAR_H - -#define TEGRA30_CLK_CPU 0 -/* 1 */ -/* 2 */ -/* 3 */ -#define TEGRA30_CLK_RTC 4 -#define TEGRA30_CLK_TIMER 5 -#define TEGRA30_CLK_UARTA 6 -/* 7 (register bit affects uartb and vfir) */ -#define TEGRA30_CLK_GPIO 8 -#define TEGRA30_CLK_SDMMC2 9 -/* 10 (register bit affects spdif_in and spdif_out) */ -#define TEGRA30_CLK_I2S1 11 -#define TEGRA30_CLK_I2C1 12 -#define TEGRA30_CLK_NDFLASH 13 -#define TEGRA30_CLK_SDMMC1 14 -#define TEGRA30_CLK_SDMMC4 15 -/* 16 */ -#define TEGRA30_CLK_PWM 17 -#define TEGRA30_CLK_I2S2 18 -#define TEGRA30_CLK_EPP 19 -/* 20 (register bit affects vi and vi_sensor) */ -#define TEGRA30_CLK_GR2D 21 -#define TEGRA30_CLK_USBD 22 -#define TEGRA30_CLK_ISP 23 -#define TEGRA30_CLK_GR3D 24 -/* 25 */ -#define TEGRA30_CLK_DISP2 26 -#define TEGRA30_CLK_DISP1 27 -#define TEGRA30_CLK_HOST1X 28 -#define TEGRA30_CLK_VCP 29 -#define TEGRA30_CLK_I2S0 30 -#define TEGRA30_CLK_COP_CACHE 31 - -#define TEGRA30_CLK_MC 32 -#define TEGRA30_CLK_AHBDMA 33 -#define TEGRA30_CLK_APBDMA 34 -/* 35 */ -#define TEGRA30_CLK_KBC 36 -#define TEGRA30_CLK_STATMON 37 -#define TEGRA30_CLK_PMC 38 -/* 39 (register bit affects fuse and fuse_burn) */ -#define TEGRA30_CLK_KFUSE 40 -#define TEGRA30_CLK_SBC1 41 -#define TEGRA30_CLK_NOR 42 -/* 43 */ -#define TEGRA30_CLK_SBC2 44 -/* 45 */ -#define TEGRA30_CLK_SBC3 46 -#define TEGRA30_CLK_I2C5 47 -#define TEGRA30_CLK_DSIA 48 -/* 49 (register bit affects cve and tvo) */ -#define TEGRA30_CLK_MIPI 50 -#define TEGRA30_CLK_HDMI 51 -#define TEGRA30_CLK_CSI 52 -#define TEGRA30_CLK_TVDAC 53 -#define TEGRA30_CLK_I2C2 54 -#define TEGRA30_CLK_UARTC 55 -/* 56 */ -#define TEGRA30_CLK_EMC 57 -#define TEGRA30_CLK_USB2 58 -#define TEGRA30_CLK_USB3 59 -#define TEGRA30_CLK_MPE 60 -#define TEGRA30_CLK_VDE 61 -#define TEGRA30_CLK_BSEA 62 -#define TEGRA30_CLK_BSEV 63 - -#define TEGRA30_CLK_SPEEDO 64 -#define TEGRA30_CLK_UARTD 65 -#define TEGRA30_CLK_UARTE 66 -#define TEGRA30_CLK_I2C3 67 -#define TEGRA30_CLK_SBC4 68 -#define TEGRA30_CLK_SDMMC3 69 -#define TEGRA30_CLK_PCIE 70 -#define TEGRA30_CLK_OWR 71 -#define TEGRA30_CLK_AFI 72 -#define TEGRA30_CLK_CSITE 73 -#define TEGRA30_CLK_PCIEX 74 -#define TEGRA30_CLK_AVPUCQ 75 -#define TEGRA30_CLK_LA 76 -/* 77 */ -/* 78 */ -#define TEGRA30_CLK_DTV 79 -#define TEGRA30_CLK_NDSPEED 80 -#define TEGRA30_CLK_I2CSLOW 81 -#define TEGRA30_CLK_DSIB 82 -/* 83 */ -#define TEGRA30_CLK_IRAMA 84 -#define TEGRA30_CLK_IRAMB 85 -#define TEGRA30_CLK_IRAMC 86 -#define TEGRA30_CLK_IRAMD 87 -#define TEGRA30_CLK_CRAM2 88 -/* 89 */ -#define TEGRA30_CLK_AUDIO_2X 90 /* a/k/a audio_2x_sync_clk */ -/* 91 */ -#define TEGRA30_CLK_CSUS 92 -#define TEGRA30_CLK_CDEV2 93 -#define TEGRA30_CLK_CDEV1 94 -/* 95 */ - -#define TEGRA30_CLK_CPU_G 96 -#define TEGRA30_CLK_CPU_LP 97 -#define TEGRA30_CLK_GR3D2 98 -#define TEGRA30_CLK_MSELECT 99 -#define TEGRA30_CLK_TSENSOR 100 -#define TEGRA30_CLK_I2S3 101 -#define TEGRA30_CLK_I2S4 102 -#define TEGRA30_CLK_I2C4 103 -#define TEGRA30_CLK_SBC5 104 -#define TEGRA30_CLK_SBC6 105 -#define TEGRA30_CLK_D_AUDIO 106 -#define TEGRA30_CLK_APBIF 107 -#define TEGRA30_CLK_DAM0 108 -#define TEGRA30_CLK_DAM1 109 -#define TEGRA30_CLK_DAM2 110 -#define TEGRA30_CLK_HDA2CODEC_2X 111 -#define TEGRA30_CLK_ATOMICS 112 -#define TEGRA30_CLK_AUDIO0_2X 113 -#define TEGRA30_CLK_AUDIO1_2X 114 -#define TEGRA30_CLK_AUDIO2_2X 115 -#define TEGRA30_CLK_AUDIO3_2X 116 -#define TEGRA30_CLK_AUDIO4_2X 117 -#define TEGRA30_CLK_SPDIF_2X 118 -#define TEGRA30_CLK_ACTMON 119 -#define TEGRA30_CLK_EXTERN1 120 -#define TEGRA30_CLK_EXTERN2 121 -#define TEGRA30_CLK_EXTERN3 122 -#define TEGRA30_CLK_SATA_OOB 123 -#define TEGRA30_CLK_SATA 124 -#define TEGRA30_CLK_HDA 125 -/* 126 */ -#define TEGRA30_CLK_SE 127 - -#define TEGRA30_CLK_HDA2HDMI 128 -#define TEGRA30_CLK_SATA_COLD 129 -/* 130 */ -/* 131 */ -/* 132 */ -/* 133 */ -/* 134 */ -/* 135 */ -/* 136 */ -/* 137 */ -/* 138 */ -/* 139 */ -/* 140 */ -/* 141 */ -/* 142 */ -/* 143 */ -/* 144 */ -/* 145 */ -/* 146 */ -/* 147 */ -/* 148 */ -/* 149 */ -/* 150 */ -/* 151 */ -/* 152 */ -/* 153 */ -/* 154 */ -/* 155 */ -/* 156 */ -/* 157 */ -/* 158 */ -/* 159 */ - -#define TEGRA30_CLK_UARTB 160 -#define TEGRA30_CLK_VFIR 161 -#define TEGRA30_CLK_SPDIF_IN 162 -#define TEGRA30_CLK_SPDIF_OUT 163 -#define TEGRA30_CLK_VI 164 -#define TEGRA30_CLK_VI_SENSOR 165 -#define TEGRA30_CLK_FUSE 166 -#define TEGRA30_CLK_FUSE_BURN 167 -#define TEGRA30_CLK_CVE 168 -#define TEGRA30_CLK_TVO 169 -#define TEGRA30_CLK_CLK_32K 170 -#define TEGRA30_CLK_CLK_M 171 -#define TEGRA30_CLK_CLK_M_DIV2 172 -#define TEGRA30_CLK_CLK_M_DIV4 173 -#define TEGRA30_CLK_PLL_REF 174 -#define TEGRA30_CLK_PLL_C 175 -#define TEGRA30_CLK_PLL_C_OUT1 176 -#define TEGRA30_CLK_PLL_M 177 -#define TEGRA30_CLK_PLL_M_OUT1 178 -#define TEGRA30_CLK_PLL_P 179 -#define TEGRA30_CLK_PLL_P_OUT1 180 -#define TEGRA30_CLK_PLL_P_OUT2 181 -#define TEGRA30_CLK_PLL_P_OUT3 182 -#define TEGRA30_CLK_PLL_P_OUT4 183 -#define TEGRA30_CLK_PLL_A 184 -#define TEGRA30_CLK_PLL_A_OUT0 185 -#define TEGRA30_CLK_PLL_D 186 -#define TEGRA30_CLK_PLL_D_OUT0 187 -#define TEGRA30_CLK_PLL_D2 188 -#define TEGRA30_CLK_PLL_D2_OUT0 189 -#define TEGRA30_CLK_PLL_U 190 -#define TEGRA30_CLK_PLL_X 191 - -#define TEGRA30_CLK_PLL_X_OUT0 192 -#define TEGRA30_CLK_PLL_E 193 -#define TEGRA30_CLK_SPDIF_IN_SYNC 194 -#define TEGRA30_CLK_I2S0_SYNC 195 -#define TEGRA30_CLK_I2S1_SYNC 196 -#define TEGRA30_CLK_I2S2_SYNC 197 -#define TEGRA30_CLK_I2S3_SYNC 198 -#define TEGRA30_CLK_I2S4_SYNC 199 -#define TEGRA30_CLK_VIMCLK_SYNC 200 -#define TEGRA30_CLK_AUDIO0 201 -#define TEGRA30_CLK_AUDIO1 202 -#define TEGRA30_CLK_AUDIO2 203 -#define TEGRA30_CLK_AUDIO3 204 -#define TEGRA30_CLK_AUDIO4 205 -#define TEGRA30_CLK_SPDIF 206 -#define TEGRA30_CLK_CLK_OUT_1 207 /* (extern1) */ -#define TEGRA30_CLK_CLK_OUT_2 208 /* (extern2) */ -#define TEGRA30_CLK_CLK_OUT_3 209 /* (extern3) */ -#define TEGRA30_CLK_SCLK 210 -#define TEGRA30_CLK_BLINK 211 -#define TEGRA30_CLK_CCLK_G 212 -#define TEGRA30_CLK_CCLK_LP 213 -#define TEGRA30_CLK_TWD 214 -#define TEGRA30_CLK_CML0 215 -#define TEGRA30_CLK_CML1 216 -#define TEGRA30_CLK_HCLK 217 -#define TEGRA30_CLK_PCLK 218 -/* 219 */ -/* 220 */ -/* 221 */ -/* 222 */ -/* 223 */ - -/* 288 */ -/* 289 */ -/* 290 */ -/* 291 */ -/* 292 */ -/* 293 */ -/* 294 */ -/* 295 */ -/* 296 */ -/* 297 */ -/* 298 */ -/* 299 */ -#define TEGRA30_CLK_CLK_OUT_1_MUX 300 -#define TEGRA30_CLK_CLK_MAX 301 - -#endif /* _DT_BINDINGS_CLOCK_TEGRA30_CAR_H */ diff --git a/include/dt-bindings/pinctrl/pinctrl-tegra.h b/include/dt-bindings/pinctrl/pinctrl-tegra.h deleted file mode 100644 index ebafa49..0000000 --- a/include/dt-bindings/pinctrl/pinctrl-tegra.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This header provides constants for Tegra pinctrl bindings. - * - * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. - * - * Author: Laxman Dewangan - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#ifndef _DT_BINDINGS_PINCTRL_TEGRA_H -#define _DT_BINDINGS_PINCTRL_TEGRA_H - -/* - * Enable/disable for diffeent dt properties. This is applicable for - * properties nvidia,enable-input, nvidia,tristate, nvidia,open-drain, - * nvidia,lock, nvidia,rcv-sel, nvidia,high-speed-mode, nvidia,schmitt. - */ -#define TEGRA_PIN_DISABLE 0 -#define TEGRA_PIN_ENABLE 1 - -#define TEGRA_PIN_PULL_NONE 0 -#define TEGRA_PIN_PULL_DOWN 1 -#define TEGRA_PIN_PULL_UP 2 - -/* Low power mode driver */ -#define TEGRA_PIN_LP_DRIVE_DIV_8 0 -#define TEGRA_PIN_LP_DRIVE_DIV_4 1 -#define TEGRA_PIN_LP_DRIVE_DIV_2 2 -#define TEGRA_PIN_LP_DRIVE_DIV_1 3 - -/* Rising/Falling slew rate */ -#define TEGRA_PIN_SLEW_RATE_FASTEST 0 -#define TEGRA_PIN_SLEW_RATE_FAST 1 -#define TEGRA_PIN_SLEW_RATE_SLOW 2 -#define TEGRA_PIN_SLEW_RATE_SLOWEST 3 - -#endif diff --git a/include/dt-bindings/pinctrl/rockchip.h b/include/dt-bindings/pinctrl/rockchip.h deleted file mode 100644 index cd5788b..0000000 --- a/include/dt-bindings/pinctrl/rockchip.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Header providing constants for Rockchip pinctrl bindings. - * - * Copyright (c) 2013 MundoReader S.L. - * Author: Heiko Stuebner - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ -#define __DT_BINDINGS_ROCKCHIP_PINCTRL_H__ - -#define RK_GPIO0 0 -#define RK_GPIO1 1 -#define RK_GPIO2 2 -#define RK_GPIO3 3 -#define RK_GPIO4 4 -#define RK_GPIO6 6 - -#define RK_FUNC_GPIO 0 -#define RK_FUNC_1 1 -#define RK_FUNC_2 2 - -#endif diff --git a/include/filetype.h b/include/filetype.h index ec5aea2..9986938 100644 --- a/include/filetype.h +++ b/include/filetype.h @@ -40,6 +40,7 @@ filetype_socfpga_xload, filetype_kwbimage_v1, filetype_android_sparse, + filetype_arm64_linux_image, filetype_max, }; diff --git a/include/memory.h b/include/memory.h index 165d2dc..56d16d2 100644 --- a/include/memory.h +++ b/include/memory.h @@ -27,4 +27,9 @@ resource_size_t size); int release_sdram_region(struct resource *res); +void memory_bank_find_space(struct memory_bank *bank, resource_size_t *retstart, + resource_size_t *retend); +int memory_bank_first_find_space(resource_size_t *retstart, + resource_size_t *retend); + #endif