* [PATCH v5 0/14] Add basic support for arm64
@ 2016-07-04 11:52 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 01/14] arm64: add armv8 Kconfig entries Raphael Poggi
` (14 more replies)
0 siblings, 15 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox
Chance since v4:
PATCH 14/14 new patch, add documentation about aarch64 qemu virt
Change since v3:
PATCH 2/14 remove hunk belonging to PATCH 3/14
PATCH 3/14 create a lib/ for common code and lib32/ lib64/
PATCH 4/14 add setupc_64, for now setup_c() only memset bss
PATCH 12/14 use default memory layout, chance TEXT_BASE address to let
malloc space below
Change since v2:
PATCH 1/14 add PHYS_ADDR_T_64BIT config
PATCH 3/14 remove modules.c and clean atags functions in armlinux.c,
and fix also parameters passed to linux kernel.
PATCH 12/14 move lowlevel file from mach-qemu/ to boards/ (like others boards)
split dram and flash init
increase dram/flash size
PATCH 13/14 new patch, in case of armv8, swab need to be done on 32-bit wide register
otherwise swapping the value: "0xAAAABBBB" will become "0xAAAABBBB00000000"
and see as a null value in uint32_t variable.
PATCH 14/14 new patch, add define to handle arm64 uimage format
Change since v1:
PATCH 2/12: remove hunk which belongs to patch adding mach-qemu
PATCH 3/12: remove unused files
PATCH 4/12: create lowlevel64
PATCH 11/12: create pgtables64 (nothing in common with the arm32 version)
PATCH 12/12: rename "mach-virt" => "mach-qemu"
rename board "qemu_virt64"
remove board env files
Hello,
This patch series introduces a basic support for arm64.
The arm64 code is merged in the current arch/arm directory.
I try to be iterative in the merge process, and find correct solutions
to handle both architecture at some places.
I test the patch series by compiling arm64 virt machine and arm32 vexpress-a9 and test it
in qemu, everything seems to work.
Thanks,
Raphaël
Documentation/boards/aarch64-qemu-virt.rst | 13 ++
arch/arm/Kconfig | 28 +++
arch/arm/Makefile | 41 +++-
arch/arm/boards/Makefile | 1 +
arch/arm/boards/qemu-virt64/Kconfig | 8 +
arch/arm/boards/qemu-virt64/Makefile | 2 +
arch/arm/boards/qemu-virt64/env/config | 8 +
arch/arm/boards/qemu-virt64/init.c | 72 ++++++
arch/arm/boards/qemu-virt64/lowlevel.c | 19 ++
arch/arm/configs/qemu_virt64_defconfig | 47 ++++
arch/arm/cpu/Kconfig | 33 ++-
arch/arm/cpu/Makefile | 28 ++-
arch/arm/cpu/cache-armv8.S | 168 ++++++++++++++
arch/arm/cpu/cache.c | 19 ++
arch/arm/cpu/cpu.c | 7 +
arch/arm/cpu/cpuinfo.c | 58 ++++-
arch/arm/cpu/exceptions_64.S | 127 +++++++++++
arch/arm/cpu/interrupts.c | 47 ++++
arch/arm/cpu/lowlevel_64.S | 40 ++++
arch/arm/cpu/mmu.h | 54 +++++
arch/arm/cpu/mmu_64.c | 331 +++++++++++++++++++++++++++
arch/arm/cpu/setupc_64.S | 18 ++
arch/arm/include/asm/bitops.h | 5 +
arch/arm/include/asm/cache.h | 9 +
arch/arm/include/asm/mmu.h | 14 +-
arch/arm/include/asm/pgtable64.h | 140 ++++++++++++
arch/arm/include/asm/swab.h | 4 +
arch/arm/include/asm/system.h | 46 +++-
arch/arm/include/asm/system_info.h | 38 ++++
arch/arm/lib/.gitignore | 1 -
arch/arm/lib/Makefile | 27 ---
arch/arm/lib/armlinux.c | 281 -----------------------
arch/arm/lib/ashldi3.S | 50 ----
arch/arm/lib/ashrdi3.S | 50 ----
arch/arm/lib/barebox.lds.S | 126 -----------
arch/arm/lib/bootz.c | 136 -----------
arch/arm/lib/copy_template.S | 268 ----------------------
arch/arm/lib/div0.c | 27 ---
arch/arm/lib/findbit.S | 197 ----------------
arch/arm/lib/io-readsb.S | 125 ----------
arch/arm/lib/io-readsl.S | 81 -------
arch/arm/lib/io-readsw-armv4.S | 133 -----------
arch/arm/lib/io-writesb.S | 96 --------
arch/arm/lib/io-writesl.S | 69 ------
arch/arm/lib/io-writesw-armv4.S | 102 ---------
arch/arm/lib/io.c | 50 ----
arch/arm/lib/lib1funcs.S | 351 -----------------------------
arch/arm/lib/lshrdi3.S | 50 ----
arch/arm/lib/memcpy.S | 64 ------
arch/arm/lib/memset.S | 124 ----------
arch/arm/lib/module.c | 98 --------
arch/arm/lib/pbl.lds.S | 96 --------
arch/arm/lib/runtime-offset.S | 52 -----
arch/arm/lib/semihosting-trap.S | 28 ---
arch/arm/lib/semihosting.c | 227 -------------------
arch/arm/lib/unwind.c | 349 ----------------------------
arch/arm/lib32/.gitignore | 1 +
arch/arm/lib32/Makefile | 27 +++
arch/arm/lib32/armlinux.c | 281 +++++++++++++++++++++++
arch/arm/lib32/ashldi3.S | 50 ++++
arch/arm/lib32/ashrdi3.S | 50 ++++
arch/arm/lib32/barebox.lds.S | 126 +++++++++++
arch/arm/lib32/bootz.c | 136 +++++++++++
arch/arm/lib32/copy_template.S | 268 ++++++++++++++++++++++
arch/arm/lib32/div0.c | 27 +++
arch/arm/lib32/findbit.S | 197 ++++++++++++++++
arch/arm/lib32/io-readsb.S | 125 ++++++++++
arch/arm/lib32/io-readsl.S | 81 +++++++
arch/arm/lib32/io-readsw-armv4.S | 133 +++++++++++
arch/arm/lib32/io-writesb.S | 96 ++++++++
arch/arm/lib32/io-writesl.S | 69 ++++++
arch/arm/lib32/io-writesw-armv4.S | 102 +++++++++
arch/arm/lib32/io.c | 50 ++++
arch/arm/lib32/lib1funcs.S | 351 +++++++++++++++++++++++++++++
arch/arm/lib32/lshrdi3.S | 50 ++++
arch/arm/lib32/memcpy.S | 64 ++++++
arch/arm/lib32/memset.S | 124 ++++++++++
arch/arm/lib32/module.c | 98 ++++++++
arch/arm/lib32/pbl.lds.S | 96 ++++++++
arch/arm/lib32/runtime-offset.S | 52 +++++
arch/arm/lib32/semihosting-trap.S | 28 +++
arch/arm/lib32/semihosting.c | 227 +++++++++++++++++++
arch/arm/lib32/unwind.c | 349 ++++++++++++++++++++++++++++
arch/arm/lib64/Makefile | 9 +
arch/arm/lib64/armlinux.c | 50 ++++
arch/arm/lib64/barebox.lds.S | 125 ++++++++++
arch/arm/lib64/copy_template.S | 192 ++++++++++++++++
arch/arm/lib64/div0.c | 27 +++
arch/arm/lib64/memcpy.S | 74 ++++++
arch/arm/lib64/memset.S | 215 ++++++++++++++++++
arch/arm/mach-qemu/Kconfig | 18 ++
arch/arm/mach-qemu/Makefile | 1 +
arch/arm/mach-qemu/include/mach/debug_ll.h | 24 ++
arch/arm/mach-qemu/include/mach/devices.h | 13 ++
arch/arm/mach-qemu/virt_devices.c | 30 +++
common/image.c | 1 +
include/image.h | 5 +
97 files changed, 5449 insertions(+), 3276 deletions(-)
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 01/14] arm64: add armv8 Kconfig entries
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 02/14] arm: Makefile: rework makefile to handle armv8 Raphael Poggi
` (13 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/Kconfig | 23 +++++++++++++++++++++++
arch/arm/cpu/Kconfig | 33 ++++++++++++++++++++++++++++++++-
2 files changed, 55 insertions(+), 1 deletion(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1fc887b..986fdaa 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -315,6 +315,29 @@ config ARM_BOARD_APPEND_ATAG
endmenu
+choice
+ prompt "Barebox code model"
+ help
+ You should only select this option if you have a workload that
+ actually benefits from 64-bit processing or if your machine has
+ large memory. You will only be presented a single option in this
+ menu if your system does not support both 32-bit and 64-bit modes.
+
+config 32BIT
+ bool "32-bit barebox"
+ depends on CPU_SUPPORTS_32BIT_KERNEL && SYS_SUPPORTS_32BIT_KERNEL
+ help
+ Select this option if you want to build a 32-bit barebox.
+
+config 64BIT
+ bool "64-bit barebox"
+ depends on CPU_SUPPORTS_64BIT_KERNEL && SYS_SUPPORTS_64BIT_KERNEL
+ select ARCH_DMA_ADDR_T_64BIT
+ help
+ Select this option if you want to build a 64-bit barebox.
+
+endchoice
+
menu "ARM specific settings"
config ARM_OPTIMZED_STRING_FUNCTIONS
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 4f5d9b6..450a6d5 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -1,8 +1,14 @@
comment "Processor Type"
+config PHYS_ADDR_T_64BIT
+ bool
+
config CPU_32
bool
- default y
+
+config CPU_64
+ bool
+ select PHYS_ADDR_T_64BIT
# Select CPU types depending on the architecture selected. This selects
# which CPUs we support in the kernel image, and the compiler instruction
@@ -69,6 +75,12 @@ config CPU_V7
bool
select CPU_32v7
+# ARMv8
+config CPU_V8
+ bool
+ select CPU_64v8
+ select CPU_SUPPORTS_64BIT_KERNEL
+
config CPU_XSC3
bool
select CPU_32v4T
@@ -84,15 +96,23 @@ config CPU_XSCALE
# This defines the compiler instruction set which depends on the machine type.
config CPU_32v4T
bool
+ select CPU_32
config CPU_32v5
bool
+ select CPU_32
config CPU_32v6
bool
+ select CPU_32
config CPU_32v7
bool
+ select CPU_32
+
+config CPU_64v8
+ bool
+ select CPU_64
comment "processor features"
@@ -124,3 +144,14 @@ config CACHE_L2X0
bool "Enable L2x0 PrimeCell"
depends on MMU && ARCH_HAS_L2X0
+config SYS_SUPPORTS_32BIT_KERNEL
+ bool
+
+config SYS_SUPPORTS_64BIT_KERNEL
+ bool
+
+config CPU_SUPPORTS_32BIT_KERNEL
+ bool
+
+config CPU_SUPPORTS_64BIT_KERNEL
+ bool
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 02/14] arm: Makefile: rework makefile to handle armv8
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 01/14] arm64: add armv8 Kconfig entries Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 03/14] arm: rework lib directory to support arm64 Raphael Poggi
` (12 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/Makefile | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 5ccdb83..2cf5feb 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -1,7 +1,11 @@
CPPFLAGS += -D__ARM__ -fno-strict-aliasing
# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
+ifeq ($(CONFIG_CPU_V8),y)
+CPPFLAGS +=$(call cc-option,-maarch64,)
+else
CPPFLAGS +=$(call cc-option,-marm,)
+endif
ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
CPPFLAGS += -mbig-endian
@@ -17,13 +21,16 @@ endif
# at least some of the code would be executed with MMU off, lets be
# conservative and instruct the compiler not to generate any unaligned
# accesses
+ifeq ($(CONFIG_CPU_V8),n)
CFLAGS += -mno-unaligned-access
+endif
# This selects which instruction set is used.
# Note that GCC does not numerically define an architecture version
# macro, but instead defines a whole series of macros which makes
# testing for a specific architecture or later rather impossible.
+arch-$(CONFIG_CPU_64v8) := -D__LINUX_ARM_ARCH__=8 $(call cc-option,-march=armv8-a)
arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
arch-$(CONFIG_CPU_32v5) :=-D__LINUX_ARM_ARCH__=5 $(call cc-option,-march=armv5te,-march=armv4t)
@@ -34,11 +41,15 @@ tune-$(CONFIG_CPU_ARM920T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_ARM926T) :=-mtune=arm9tdmi
tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) -Wa,-mcpu=xscale
+ifeq ($(CONFIG_CPU_V8), y)
+CFLAGS_ABI :=-mabi=lp64
+else
ifeq ($(CONFIG_AEABI),y)
CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork
else
CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,)
endif
+endif
ifeq ($(CONFIG_ARM_UNWIND),y)
CFLAGS_ABI +=-funwind-tables
@@ -51,8 +62,13 @@ CFLAGS_THUMB2 :=-mthumb $(AFLAGS_AUTOIT) $(AFLAGS_NOWARN)
AFLAGS_THUMB2 :=$(CFLAGS_THUMB2) -Wa$(comma)-mthumb
endif
+ifeq ($(CONFIG_CPU_V8), y)
+CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y)
+AFLAGS += -include asm/unified.h
+else
CPPFLAGS += $(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float $(CFLAGS_THUMB2)
AFLAGS += -include asm/unified.h -msoft-float $(AFLAGS_THUMB2)
+endif
# Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 03/14] arm: rework lib directory to support arm64
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 01/14] arm64: add armv8 Kconfig entries Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 02/14] arm: Makefile: rework makefile to handle armv8 Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 04/14] arm: cpu: add arm64 specific code Raphael Poggi
` (11 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
This commit create a common directory, lib/,
for arm and arm64 common code.
It also create lib32/ and lib64/ for 32bit
and 64bit code respectively.
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/Makefile | 24 ++-
arch/arm/lib/.gitignore | 1 -
arch/arm/lib/Makefile | 27 ---
arch/arm/lib/armlinux.c | 281 ------------------------------
arch/arm/lib/ashldi3.S | 50 ------
arch/arm/lib/ashrdi3.S | 50 ------
arch/arm/lib/barebox.lds.S | 126 --------------
arch/arm/lib/bootz.c | 136 ---------------
arch/arm/lib/copy_template.S | 268 -----------------------------
arch/arm/lib/div0.c | 27 ---
arch/arm/lib/findbit.S | 197 ---------------------
arch/arm/lib/io-readsb.S | 125 --------------
arch/arm/lib/io-readsl.S | 81 ---------
arch/arm/lib/io-readsw-armv4.S | 133 ---------------
arch/arm/lib/io-writesb.S | 96 -----------
arch/arm/lib/io-writesl.S | 69 --------
arch/arm/lib/io-writesw-armv4.S | 102 -----------
arch/arm/lib/io.c | 50 ------
arch/arm/lib/lib1funcs.S | 351 --------------------------------------
arch/arm/lib/lshrdi3.S | 50 ------
arch/arm/lib/memcpy.S | 64 -------
arch/arm/lib/memset.S | 124 --------------
arch/arm/lib/module.c | 98 -----------
arch/arm/lib/pbl.lds.S | 96 -----------
arch/arm/lib/runtime-offset.S | 52 ------
arch/arm/lib/semihosting-trap.S | 28 ---
arch/arm/lib/semihosting.c | 227 ------------------------
arch/arm/lib/unwind.c | 349 -------------------------------------
arch/arm/lib32/.gitignore | 1 +
arch/arm/lib32/Makefile | 27 +++
arch/arm/lib32/armlinux.c | 281 ++++++++++++++++++++++++++++++
arch/arm/lib32/ashldi3.S | 50 ++++++
arch/arm/lib32/ashrdi3.S | 50 ++++++
arch/arm/lib32/barebox.lds.S | 126 ++++++++++++++
arch/arm/lib32/bootz.c | 136 +++++++++++++++
arch/arm/lib32/copy_template.S | 268 +++++++++++++++++++++++++++++
arch/arm/lib32/div0.c | 27 +++
arch/arm/lib32/findbit.S | 197 +++++++++++++++++++++
arch/arm/lib32/io-readsb.S | 125 ++++++++++++++
arch/arm/lib32/io-readsl.S | 81 +++++++++
arch/arm/lib32/io-readsw-armv4.S | 133 +++++++++++++++
arch/arm/lib32/io-writesb.S | 96 +++++++++++
arch/arm/lib32/io-writesl.S | 69 ++++++++
arch/arm/lib32/io-writesw-armv4.S | 102 +++++++++++
arch/arm/lib32/io.c | 50 ++++++
arch/arm/lib32/lib1funcs.S | 351 ++++++++++++++++++++++++++++++++++++++
arch/arm/lib32/lshrdi3.S | 50 ++++++
arch/arm/lib32/memcpy.S | 64 +++++++
arch/arm/lib32/memset.S | 124 ++++++++++++++
arch/arm/lib32/module.c | 98 +++++++++++
arch/arm/lib32/pbl.lds.S | 96 +++++++++++
arch/arm/lib32/runtime-offset.S | 52 ++++++
arch/arm/lib32/semihosting-trap.S | 28 +++
arch/arm/lib32/semihosting.c | 227 ++++++++++++++++++++++++
arch/arm/lib32/unwind.c | 349 +++++++++++++++++++++++++++++++++++++
arch/arm/lib64/Makefile | 9 +
arch/arm/lib64/armlinux.c | 50 ++++++
arch/arm/lib64/barebox.lds.S | 125 ++++++++++++++
arch/arm/lib64/copy_template.S | 192 +++++++++++++++++++++
arch/arm/lib64/div0.c | 27 +++
arch/arm/lib64/memcpy.S | 74 ++++++++
arch/arm/lib64/memset.S | 215 +++++++++++++++++++++++
62 files changed, 3970 insertions(+), 3262 deletions(-)
delete mode 100644 arch/arm/lib/.gitignore
delete mode 100644 arch/arm/lib/armlinux.c
delete mode 100644 arch/arm/lib/ashldi3.S
delete mode 100644 arch/arm/lib/ashrdi3.S
delete mode 100644 arch/arm/lib/barebox.lds.S
delete mode 100644 arch/arm/lib/bootz.c
delete mode 100644 arch/arm/lib/copy_template.S
delete mode 100644 arch/arm/lib/div0.c
delete mode 100644 arch/arm/lib/findbit.S
delete mode 100644 arch/arm/lib/io-readsb.S
delete mode 100644 arch/arm/lib/io-readsl.S
delete mode 100644 arch/arm/lib/io-readsw-armv4.S
delete mode 100644 arch/arm/lib/io-writesb.S
delete mode 100644 arch/arm/lib/io-writesl.S
delete mode 100644 arch/arm/lib/io-writesw-armv4.S
delete mode 100644 arch/arm/lib/io.c
delete mode 100644 arch/arm/lib/lib1funcs.S
delete mode 100644 arch/arm/lib/lshrdi3.S
delete mode 100644 arch/arm/lib/memcpy.S
delete mode 100644 arch/arm/lib/memset.S
delete mode 100644 arch/arm/lib/module.c
delete mode 100644 arch/arm/lib/pbl.lds.S
delete mode 100644 arch/arm/lib/runtime-offset.S
delete mode 100644 arch/arm/lib/semihosting-trap.S
delete mode 100644 arch/arm/lib/semihosting.c
delete mode 100644 arch/arm/lib/unwind.c
create mode 100644 arch/arm/lib32/.gitignore
create mode 100644 arch/arm/lib32/Makefile
create mode 100644 arch/arm/lib32/armlinux.c
create mode 100644 arch/arm/lib32/ashldi3.S
create mode 100644 arch/arm/lib32/ashrdi3.S
create mode 100644 arch/arm/lib32/barebox.lds.S
create mode 100644 arch/arm/lib32/bootz.c
create mode 100644 arch/arm/lib32/copy_template.S
create mode 100644 arch/arm/lib32/div0.c
create mode 100644 arch/arm/lib32/findbit.S
create mode 100644 arch/arm/lib32/io-readsb.S
create mode 100644 arch/arm/lib32/io-readsl.S
create mode 100644 arch/arm/lib32/io-readsw-armv4.S
create mode 100644 arch/arm/lib32/io-writesb.S
create mode 100644 arch/arm/lib32/io-writesl.S
create mode 100644 arch/arm/lib32/io-writesw-armv4.S
create mode 100644 arch/arm/lib32/io.c
create mode 100644 arch/arm/lib32/lib1funcs.S
create mode 100644 arch/arm/lib32/lshrdi3.S
create mode 100644 arch/arm/lib32/memcpy.S
create mode 100644 arch/arm/lib32/memset.S
create mode 100644 arch/arm/lib32/module.c
create mode 100644 arch/arm/lib32/pbl.lds.S
create mode 100644 arch/arm/lib32/runtime-offset.S
create mode 100644 arch/arm/lib32/semihosting-trap.S
create mode 100644 arch/arm/lib32/semihosting.c
create mode 100644 arch/arm/lib32/unwind.c
create mode 100644 arch/arm/lib64/Makefile
create mode 100644 arch/arm/lib64/armlinux.c
create mode 100644 arch/arm/lib64/barebox.lds.S
create mode 100644 arch/arm/lib64/copy_template.S
create mode 100644 arch/arm/lib64/div0.c
create mode 100644 arch/arm/lib64/memcpy.S
create mode 100644 arch/arm/lib64/memset.S
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2cf5feb..2b056af 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -291,13 +291,29 @@ MACH :=
endif
common-y += $(BOARD) arch/arm/boards/ $(MACH)
-common-y += arch/arm/lib/ arch/arm/cpu/
-common-y += arch/arm/crypto/
+common-y += arch/arm/cpu/
+common-y += arch/arm/lib/
+
+ifeq ($(CONFIG_CPU_V8), y)
+common-y += arch/arm/lib64/
+else
+common-y += arch/arm/lib32/ arch/arm/crypto/
+endif
common-$(CONFIG_OFTREE) += arch/arm/dts/
-lds-y := arch/arm/lib/barebox.lds
+ifeq ($(CONFIG_CPU_V8), y)
+lds-y := arch/arm/lib64/barebox.lds
+else
+lds-y := arch/arm/lib32/barebox.lds
+endif
common- += $(patsubst %,arch/arm/boards/%/,$(board-))
-CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds barebox-flash-image
+CLEAN_FILES += include/generated/mach-types.h barebox-flash-image
+
+ifeq ($(CONFIG_CPU_V8), y)
+CLEAN_FILES += arch/arm/lib64/barebox.lds
+else
+CLEAN_FILES += arch/arm/lib32/barebox.lds
+endif
diff --git a/arch/arm/lib/.gitignore b/arch/arm/lib/.gitignore
deleted file mode 100644
index d116578..0000000
--- a/arch/arm/lib/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-barebox.lds
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index e1c6f5b..33db735 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -1,29 +1,2 @@
-obj-$(CONFIG_ARM_LINUX) += armlinux.o
obj-$(CONFIG_BOOTM) += bootm.o
-obj-$(CONFIG_CMD_BOOTZ) += bootz.o
obj-$(CONFIG_CMD_BOOTU) += bootu.o
-obj-y += div0.o
-obj-y += findbit.o
-obj-y += io.o
-obj-y += io-readsb.o
-obj-y += io-readsw-armv4.o
-obj-y += io-readsl.o
-obj-y += io-writesb.o
-obj-y += io-writesw-armv4.o
-obj-y += io-writesl.o
-obj-y += lib1funcs.o
-obj-y += ashrdi3.o
-obj-y += ashldi3.o
-obj-y += lshrdi3.o
-obj-y += runtime-offset.o
-pbl-y += runtime-offset.o
-obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o
-obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
-obj-$(CONFIG_ARM_UNWIND) += unwind.o
-obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap.o semihosting.o
-obj-$(CONFIG_MODULES) += module.o
-extra-y += barebox.lds
-
-pbl-y += lib1funcs.o
-pbl-y += ashldi3.o
-pbl-y += div0.o
diff --git a/arch/arm/lib/armlinux.c b/arch/arm/lib/armlinux.c
deleted file mode 100644
index 47b9bd3..0000000
--- a/arch/arm/lib/armlinux.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * (C) Copyright 2002
- * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
- * Marius Groeger <mgroeger@sysgo.de>
- *
- * 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 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 <boot.h>
-#include <common.h>
-#include <command.h>
-#include <driver.h>
-#include <environment.h>
-#include <image.h>
-#include <init.h>
-#include <fs.h>
-#include <linux/list.h>
-#include <xfuncs.h>
-#include <malloc.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <memory.h>
-#include <of.h>
-#include <magicvar.h>
-
-#include <asm/byteorder.h>
-#include <asm/setup.h>
-#include <asm/barebox-arm.h>
-#include <asm/armlinux.h>
-#include <asm/system.h>
-
-static struct tag *params;
-static void *armlinux_bootparams = NULL;
-
-static int armlinux_architecture;
-static u32 armlinux_system_rev;
-static u64 armlinux_system_serial;
-
-BAREBOX_MAGICVAR(armlinux_architecture, "ARM machine ID");
-BAREBOX_MAGICVAR(armlinux_system_rev, "ARM system revision");
-BAREBOX_MAGICVAR(armlinux_system_serial, "ARM system serial");
-
-void armlinux_set_architecture(int architecture)
-{
- export_env_ull("armlinux_architecture", architecture);
- armlinux_architecture = architecture;
-}
-
-int armlinux_get_architecture(void)
-{
- getenv_uint("armlinux_architecture", &armlinux_architecture);
-
- return armlinux_architecture;
-}
-
-void armlinux_set_revision(unsigned int rev)
-{
- export_env_ull("armlinux_system_rev", rev);
- armlinux_system_rev = rev;
-}
-
-unsigned int armlinux_get_revision(void)
-{
- getenv_uint("armlinux_system_rev", &armlinux_system_rev);
-
- return armlinux_system_rev;
-}
-
-void armlinux_set_serial(u64 serial)
-{
- export_env_ull("armlinux_system_serial", serial);
- armlinux_system_serial = serial;
-}
-
-u64 armlinux_get_serial(void)
-{
- getenv_ull("armlinux_system_serial", &armlinux_system_serial);
-
- return armlinux_system_serial;
-}
-
-void armlinux_set_bootparams(void *params)
-{
- armlinux_bootparams = params;
-}
-
-static struct tag *armlinux_get_bootparams(void)
-{
- struct memory_bank *mem;
-
- if (armlinux_bootparams)
- return armlinux_bootparams;
-
- for_each_memory_bank(mem)
- return (void *)mem->start + 0x100;
-
- BUG();
-}
-
-#ifdef CONFIG_ARM_BOARD_APPEND_ATAG
-static struct tag *(*atag_appender)(struct tag *);
-void armlinux_set_atag_appender(struct tag *(*func)(struct tag *))
-{
- atag_appender = func;
-}
-#endif
-
-static void setup_start_tag(void)
-{
- params = armlinux_get_bootparams();
-
- params->hdr.tag = ATAG_CORE;
- params->hdr.size = tag_size(tag_core);
-
- params->u.core.flags = 0;
- params->u.core.pagesize = 0;
- params->u.core.rootdev = 0;
-
- params = tag_next(params);
-}
-
-static void setup_memory_tags(void)
-{
- struct memory_bank *bank;
-
- for_each_memory_bank(bank) {
- params->hdr.tag = ATAG_MEM;
- params->hdr.size = tag_size(tag_mem32);
-
- params->u.mem.start = bank->start;
- params->u.mem.size = bank->size;
-
- params = tag_next(params);
- }
-}
-
-static void setup_commandline_tag(const char *commandline, int swap)
-{
- const char *p;
- size_t words;
-
- if (!commandline)
- return;
-
- /* eat leading white space */
- for (p = commandline; *p == ' '; p++) ;
-
- /*
- * skip non-existent command lines so the kernel will still
- * use its default command line.
- */
- if (*p == '\0')
- return;
-
- words = (strlen(p) + 1 /* NUL */ + 3 /* round up */) >> 2;
- params->hdr.tag = ATAG_CMDLINE;
- params->hdr.size = (sizeof(struct tag_header) >> 2) + words;
-
- strcpy(params->u.cmdline.cmdline, p);
-
-#ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
- if (swap) {
- u32 *cmd = (u32 *)params->u.cmdline.cmdline;
- while (words--)
- cmd[words] = swab32(cmd[words]);
- }
-#endif
-
- params = tag_next(params);
-}
-
-static void setup_revision_tag(void)
-{
- u32 system_rev = armlinux_get_revision();
-
- if (system_rev) {
- params->hdr.tag = ATAG_REVISION;
- params->hdr.size = tag_size(tag_revision);
-
- params->u.revision.rev = system_rev;
-
- params = tag_next(params);
- }
-}
-
-static void setup_serial_tag(void)
-{
- u64 system_serial = armlinux_get_serial();
-
- if (system_serial) {
- params->hdr.tag = ATAG_SERIAL;
- params->hdr.size = tag_size(tag_serialnr);
-
- params->u.serialnr.low = system_serial & 0xffffffff;
- params->u.serialnr.high = system_serial >> 32;
-
- params = tag_next(params);
- }
-}
-
-static void setup_initrd_tag(unsigned long start, unsigned long size)
-{
- /* an ATAG_INITRD node tells the kernel where the compressed
- * ramdisk can be found. ATAG_RDIMG is a better name, actually.
- */
- params->hdr.tag = ATAG_INITRD2;
- params->hdr.size = tag_size(tag_initrd);
-
- params->u.initrd.start = start;
- params->u.initrd.size = size;
-
- params = tag_next(params);
-}
-
-static void setup_end_tag (void)
-{
- params->hdr.tag = ATAG_NONE;
- params->hdr.size = 0;
-}
-
-static void setup_tags(unsigned long initrd_address,
- unsigned long initrd_size, int swap)
-{
- const char *commandline = linux_bootargs_get();
-
- setup_start_tag();
- setup_memory_tags();
- setup_commandline_tag(commandline, swap);
-
- if (initrd_size)
- setup_initrd_tag(initrd_address, initrd_size);
-
- setup_revision_tag();
- setup_serial_tag();
-#ifdef CONFIG_ARM_BOARD_APPEND_ATAG
- if (atag_appender != NULL)
- params = atag_appender(params);
-#endif
- setup_end_tag();
-
- printf("commandline: %s\n"
- "arch_number: %d\n", commandline, armlinux_get_architecture());
-
-}
-
-void start_linux(void *adr, int swap, unsigned long initrd_address,
- unsigned long initrd_size, void *oftree)
-{
- void (*kernel)(int zero, int arch, void *params) = adr;
- void *params = NULL;
- int architecture;
-
- if (oftree) {
- pr_debug("booting kernel with devicetree\n");
- params = oftree;
- } else {
- setup_tags(initrd_address, initrd_size, swap);
- params = armlinux_get_bootparams();
- }
- architecture = armlinux_get_architecture();
-
- shutdown_barebox();
- if (swap) {
- u32 reg;
- __asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
- reg ^= CR_B; /* swap big-endian flag */
- __asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
- }
-
- kernel(0, architecture, params);
-}
diff --git a/arch/arm/lib/ashldi3.S b/arch/arm/lib/ashldi3.S
deleted file mode 100644
index b62e06f..0000000
--- a/arch/arm/lib/ashldi3.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
- Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file. (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-*/
-
-#include <linux/linkage.h>
-
-#ifdef __ARMEB__
-#define al r1
-#define ah r0
-#else
-#define al r0
-#define ah r1
-#endif
-
-.section .text.__ashldi3
-ENTRY(__ashldi3)
-ENTRY(__aeabi_llsl)
-
- subs r3, r2, #32
- rsb ip, r2, #32
- movmi ah, ah, lsl r2
- movpl ah, al, lsl r3
- ARM( orrmi ah, ah, al, lsr ip )
- THUMB( lsrmi r3, al, ip )
- THUMB( orrmi ah, ah, r3 )
- mov al, al, lsl r2
- mov pc, lr
-
-ENDPROC(__ashldi3)
-ENDPROC(__aeabi_llsl)
diff --git a/arch/arm/lib/ashrdi3.S b/arch/arm/lib/ashrdi3.S
deleted file mode 100644
index db849b6..0000000
--- a/arch/arm/lib/ashrdi3.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
- Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file. (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-*/
-
-#include <linux/linkage.h>
-
-#ifdef __ARMEB__
-#define al r1
-#define ah r0
-#else
-#define al r0
-#define ah r1
-#endif
-
-.section .text.__ashrdi3
-ENTRY(__ashrdi3)
-ENTRY(__aeabi_lasr)
-
- subs r3, r2, #32
- rsb ip, r2, #32
- movmi al, al, lsr r2
- movpl al, ah, asr r3
- ARM( orrmi al, al, ah, lsl ip )
- THUMB( lslmi r3, ah, ip )
- THUMB( orrmi al, al, r3 )
- mov ah, ah, asr r2
- mov pc, lr
-
-ENDPROC(__ashrdi3)
-ENDPROC(__aeabi_lasr)
diff --git a/arch/arm/lib/barebox.lds.S b/arch/arm/lib/barebox.lds.S
deleted file mode 100644
index 6dc8bd2..0000000
--- a/arch/arm/lib/barebox.lds.S
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * (C) Copyright 2000-2004
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 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 <asm-generic/barebox.lds.h>
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-ENTRY(start)
-SECTIONS
-{
-#ifdef CONFIG_RELOCATABLE
- . = 0x0;
-#else
- . = TEXT_BASE;
-#endif
-
-#ifndef CONFIG_PBL_IMAGE
- PRE_IMAGE
-#endif
- . = ALIGN(4);
- .text :
- {
- _stext = .;
- _text = .;
- *(.text_entry*)
- __bare_init_start = .;
- *(.text_bare_init*)
- __bare_init_end = .;
- . = ALIGN(4);
- __exceptions_start = .;
- KEEP(*(.text_exceptions*))
- __exceptions_stop = .;
- *(.text*)
- }
- BAREBOX_BARE_INIT_SIZE
-
- . = 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 = .;
-
- . = ALIGN(4);
- .data : { *(.data*) }
-
- .barebox_imd : { BAREBOX_IMD }
-
- . = .;
- __barebox_cmd_start = .;
- .barebox_cmd : { BAREBOX_CMDS }
- __barebox_cmd_end = .;
-
- __barebox_magicvar_start = .;
- .barebox_magicvar : { BAREBOX_MAGICVARS }
- __barebox_magicvar_end = .;
-
- __barebox_initcalls_start = .;
- .barebox_initcalls : { INITCALLS }
- __barebox_initcalls_end = .;
-
- __barebox_exitcalls_start = .;
- .barebox_exitcalls : { EXITCALLS }
- __barebox_exitcalls_end = .;
-
- __usymtab_start = .;
- __usymtab : { BAREBOX_SYMS }
- __usymtab_end = .;
-
- .oftables : { BAREBOX_CLK_TABLE() }
-
- .dtb : { BAREBOX_DTB() }
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- __dynsym_end = .;
- }
-
- _edata = .;
-
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss*) }
- __bss_stop = .;
- _end = .;
- _barebox_image_size = __bss_start - TEXT_BASE;
-}
diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c
deleted file mode 100644
index 5167c9d..0000000
--- a/arch/arm/lib/bootz.c
+++ /dev/null
@@ -1,136 +0,0 @@
-#include <common.h>
-#include <command.h>
-#include <fs.h>
-#include <of.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <malloc.h>
-#include <linux/sizes.h>
-#include <asm/byteorder.h>
-#include <asm/armlinux.h>
-#include <asm/system.h>
-#include <asm-generic/memory_layout.h>
-#include <memory.h>
-
-struct zimage_header {
- u32 unused[9];
- u32 magic;
- u32 start;
- u32 end;
-};
-
-#define ZIMAGE_MAGIC 0x016F2818
-
-static int do_bootz(int argc, char *argv[])
-{
- int fd, ret, swap = 0;
- struct zimage_header __header, *header;
- void *zimage;
- void *oftree = NULL;
- u32 end;
- int usemap = 0;
- struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list);
- struct resource *res = NULL;
-
- if (argc != 2)
- return COMMAND_ERROR_USAGE;
-
- fd = open(argv[1], O_RDONLY);
- if (fd < 0) {
- perror("open");
- return 1;
- }
-
- /*
- * We can save the memcpy of the zImage if it already is in
- * the first 128MB of SDRAM.
- */
- zimage = memmap(fd, PROT_READ);
- if (zimage && (unsigned long)zimage >= bank->start &&
- (unsigned long)zimage < bank->start + SZ_128M) {
- usemap = 1;
- header = zimage;
- }
-
- if (!usemap) {
- header = &__header;
- ret = read(fd, header, sizeof(*header));
- if (ret < sizeof(*header)) {
- printf("could not read %s\n", argv[1]);
- goto err_out;
- }
- }
-
- switch (header->magic) {
-#ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
- case swab32(ZIMAGE_MAGIC):
- swap = 1;
- /* fall through */
-#endif
- case ZIMAGE_MAGIC:
- break;
- default:
- printf("invalid magic 0x%08x\n", header->magic);
- goto err_out;
- }
-
- end = header->end;
-
- if (swap)
- end = swab32(end);
-
- if (!usemap) {
- if (bank->size <= SZ_128M) {
- zimage = xmalloc(end);
- } else {
- zimage = (void *)bank->start + SZ_8M;
- res = request_sdram_region("zimage",
- bank->start + SZ_8M, end);
- if (!res) {
- printf("can't request region for kernel\n");
- goto err_out1;
- }
- }
-
- memcpy(zimage, header, sizeof(*header));
-
- ret = read(fd, zimage + sizeof(*header), end - sizeof(*header));
- if (ret < end - sizeof(*header)) {
- printf("could not read %s\n", argv[1]);
- goto err_out2;
- }
- }
-
- if (swap) {
- void *ptr;
- for (ptr = zimage; ptr < zimage + end; ptr += 4)
- *(u32 *)ptr = swab32(*(u32 *)ptr);
- }
-
- printf("loaded zImage from %s with size %d\n", argv[1], end);
-#ifdef CONFIG_OFTREE
- oftree = of_get_fixed_tree(NULL);
-#endif
-
- start_linux(zimage, swap, 0, 0, oftree);
-
- return 0;
-
-err_out2:
- if (res)
- release_sdram_region(res);
-err_out1:
- free(zimage);
-err_out:
- close(fd);
-
- return 1;
-}
-
-BAREBOX_CMD_START(bootz)
- .cmd = do_bootz,
- BAREBOX_CMD_DESC("boot Linux zImage")
- BAREBOX_CMD_OPTS("FILE")
- BAREBOX_CMD_GROUP(CMD_GRP_BOOT)
-BAREBOX_CMD_END
-
diff --git a/arch/arm/lib/copy_template.S b/arch/arm/lib/copy_template.S
deleted file mode 100644
index d8eb063..0000000
--- a/arch/arm/lib/copy_template.S
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * linux/arch/arm/lib/copy_template.s
- *
- * Code template for optimized memory copy functions
- *
- * Author: Nicolas Pitre
- * Created: Sep 28, 2005
- * Copyright: MontaVista Software, Inc.
- *
- * 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.
- */
-
-/*
- * Theory of operation
- * -------------------
- *
- * This file provides the core code for a forward memory copy used in
- * the implementation of memcopy(), copy_to_user() and copy_from_user().
- *
- * The including file must define the following accessor macros
- * according to the need of the given function:
- *
- * ldr1w ptr reg abort
- *
- * This loads one word from 'ptr', stores it in 'reg' and increments
- * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
- *
- * ldr4w ptr reg1 reg2 reg3 reg4 abort
- * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- *
- * This loads four or eight words starting from 'ptr', stores them
- * in provided registers and increments 'ptr' past those words.
- * The'abort' argument is used for fixup tables.
- *
- * ldr1b ptr reg cond abort
- *
- * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
- * It also must apply the condition code if provided, otherwise the
- * "al" condition is assumed by default.
- *
- * str1w ptr reg abort
- * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- * str1b ptr reg cond abort
- *
- * Same as their ldr* counterparts, but data is stored to 'ptr' location
- * rather than being loaded.
- *
- * enter reg1 reg2
- *
- * Preserve the provided registers on the stack plus any additional
- * data as needed by the implementation including this code. Called
- * upon code entry.
- *
- * exit reg1 reg2
- *
- * Restore registers with the values previously saved with the
- * 'preserv' macro. Called upon code termination.
- *
- * LDR1W_SHIFT
- * STR1W_SHIFT
- *
- * Correction to be applied to the "ip" register when branching into
- * the ldr1w or str1w instructions (some of these macros may expand to
- * than one 32bit instruction in Thumb-2)
- */
-
-
- enter r4, lr
-
- subs r2, r2, #4
- blt 8f
- ands ip, r0, #3
- PLD( pld [r1, #0] )
- bne 9f
- ands ip, r1, #3
- bne 10f
-
-1: subs r2, r2, #(28)
- stmfd sp!, {r5 - r8}
- blt 5f
-
- CALGN( ands ip, r0, #31 )
- CALGN( rsb r3, ip, #32 )
- CALGN( sbcnes r4, r3, r2 ) @ C is always set here
- CALGN( bcs 2f )
- CALGN( adr r4, 6f )
- CALGN( subs r2, r2, r3 ) @ C gets set
- CALGN( add pc, r4, ip )
-
- PLD( pld [r1, #0] )
-2: PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 4f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-3: PLD( pld [r1, #124] )
-4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- subs r2, r2, #32
- str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
- bge 3b
- PLD( cmn r2, #96 )
- PLD( bge 4b )
-
-5: ands ip, r2, #28
- rsb ip, ip, #32
-#if LDR1W_SHIFT > 0
- lsl ip, ip, #LDR1W_SHIFT
-#endif
- addne pc, pc, ip @ C is always clear here
- b 7f
-6:
- .rept (1 << LDR1W_SHIFT)
- W(nop)
- .endr
- ldr1w r1, r3, abort=20f
- ldr1w r1, r4, abort=20f
- ldr1w r1, r5, abort=20f
- ldr1w r1, r6, abort=20f
- ldr1w r1, r7, abort=20f
- ldr1w r1, r8, abort=20f
- ldr1w r1, lr, abort=20f
-
-#if LDR1W_SHIFT < STR1W_SHIFT
- lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
-#elif LDR1W_SHIFT > STR1W_SHIFT
- lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
-#endif
- add pc, pc, ip
- nop
- .rept (1 << STR1W_SHIFT)
- W(nop)
- .endr
- str1w r0, r3, abort=20f
- str1w r0, r4, abort=20f
- str1w r0, r5, abort=20f
- str1w r0, r6, abort=20f
- str1w r0, r7, abort=20f
- str1w r0, r8, abort=20f
- str1w r0, lr, abort=20f
-
- CALGN( bcs 2b )
-
-7: ldmfd sp!, {r5 - r8}
-
-8: movs r2, r2, lsl #31
- ldr1b r1, r3, ne, abort=21f
- ldr1b r1, r4, cs, abort=21f
- ldr1b r1, ip, cs, abort=21f
- str1b r0, r3, ne, abort=21f
- str1b r0, r4, cs, abort=21f
- str1b r0, ip, cs, abort=21f
-
- exit r4, pc
-
-9: rsb ip, ip, #4
- cmp ip, #2
- ldr1b r1, r3, gt, abort=21f
- ldr1b r1, r4, ge, abort=21f
- ldr1b r1, lr, abort=21f
- str1b r0, r3, gt, abort=21f
- str1b r0, r4, ge, abort=21f
- subs r2, r2, ip
- str1b r0, lr, abort=21f
- blt 8b
- ands ip, r1, #3
- beq 1b
-
-10: bic r1, r1, #3
- cmp ip, #2
- ldr1w r1, lr, abort=21f
- beq 17f
- bgt 18f
-
-
- .macro forward_copy_shift pull push
-
- subs r2, r2, #28
- blt 14f
-
- CALGN( ands ip, r0, #31 )
- CALGN( rsb ip, ip, #32 )
- CALGN( sbcnes r4, ip, r2 ) @ C is always set here
- CALGN( subcc r2, r2, ip )
- CALGN( bcc 15f )
-
-11: stmfd sp!, {r5 - r9}
-
- PLD( pld [r1, #0] )
- PLD( subs r2, r2, #96 )
- PLD( pld [r1, #28] )
- PLD( blt 13f )
- PLD( pld [r1, #60] )
- PLD( pld [r1, #92] )
-
-12: PLD( pld [r1, #124] )
-13: ldr4w r1, r4, r5, r6, r7, abort=19f
- mov r3, lr, pull #\pull
- subs r2, r2, #32
- ldr4w r1, r8, r9, ip, lr, abort=19f
- orr r3, r3, r4, push #\push
- mov r4, r4, pull #\pull
- orr r4, r4, r5, push #\push
- mov r5, r5, pull #\pull
- orr r5, r5, r6, push #\push
- mov r6, r6, pull #\pull
- orr r6, r6, r7, push #\push
- mov r7, r7, pull #\pull
- orr r7, r7, r8, push #\push
- mov r8, r8, pull #\pull
- orr r8, r8, r9, push #\push
- mov r9, r9, pull #\pull
- orr r9, r9, ip, push #\push
- mov ip, ip, pull #\pull
- orr ip, ip, lr, push #\push
- str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
- bge 12b
- PLD( cmn r2, #96 )
- PLD( bge 13b )
-
- ldmfd sp!, {r5 - r9}
-
-14: ands ip, r2, #28
- beq 16f
-
-15: mov r3, lr, pull #\pull
- ldr1w r1, lr, abort=21f
- subs ip, ip, #4
- orr r3, r3, lr, push #\push
- str1w r0, r3, abort=21f
- bgt 15b
- CALGN( cmp r2, #0 )
- CALGN( bge 11b )
-
-16: sub r1, r1, #(\push / 8)
- b 8b
-
- .endm
-
-
- forward_copy_shift pull=8 push=24
-
-17: forward_copy_shift pull=16 push=16
-
-18: forward_copy_shift pull=24 push=8
-
-
-/*
- * Abort preamble and completion macros.
- * If a fixup handler is required then those macros must surround it.
- * It is assumed that the fixup code will handle the private part of
- * the exit macro.
- */
-
- .macro copy_abort_preamble
-19: ldmfd sp!, {r5 - r9}
- b 21f
-20: ldmfd sp!, {r5 - r8}
-21:
- .endm
-
- .macro copy_abort_end
- ldmfd sp!, {r4, pc}
- .endm
-
-
diff --git a/arch/arm/lib/div0.c b/arch/arm/lib/div0.c
deleted file mode 100644
index 852cb72..0000000
--- a/arch/arm/lib/div0.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * (C) Copyright 2002
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * 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 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 <common.h>
-
-extern void __div0(void);
-
-/* Replacement (=dummy) for GNU/Linux division-by zero handler */
-void __div0 (void)
-{
- panic("division by zero\n");
-}
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
deleted file mode 100644
index ef4caff..0000000
--- a/arch/arm/lib/findbit.S
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Originally from Linux kernel
- * arch/arm/lib/findbit.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- *
- * 16th March 2001 - John Ripley <jripley@sonicblue.com>
- * Fixed so that "size" is an exclusive not an inclusive quantity.
- * All users of these functions expect exclusive sizes, and may
- * also call with zero size.
- * Reworked by rmk.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
- .text
-
-/*
- * Purpose : Find a 'zero' bit
- * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
- */
-ENTRY(_find_first_zero_bit_le)
- teq r1, #0
- beq 3f
- mov r2, #0
-1:
- ARM( ldrb r3, [r0, r2, lsr #3] )
- THUMB( lsr r3, r2, #3 )
- THUMB( ldrb r3, [r0, r3] )
- eors r3, r3, #0xff @ invert bits
- bne .L_found @ any now set - found zero bit
- add r2, r2, #8 @ next bit pointer
-2: cmp r2, r1 @ any more?
- blo 1b
-3: mov r0, r1 @ no free bits
- mov pc, lr
-ENDPROC(_find_first_zero_bit_le)
-
-/*
- * Purpose : Find next 'zero' bit
- * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
- */
-ENTRY(_find_next_zero_bit_le)
- teq r1, #0
- beq 3b
- ands ip, r2, #7
- beq 1b @ If new byte, goto old routine
- ARM( ldrb r3, [r0, r2, lsr #3] )
- THUMB( lsr r3, r2, #3 )
- THUMB( ldrb r3, [r0, r3] )
- eor r3, r3, #0xff @ now looking for a 1 bit
- movs r3, r3, lsr ip @ shift off unused bits
- bne .L_found
- orr r2, r2, #7 @ if zero, then no bits here
- add r2, r2, #1 @ align bit pointer
- b 2b @ loop for next bit
-ENDPROC(_find_next_zero_bit_le)
-
-/*
- * Purpose : Find a 'one' bit
- * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
- */
-ENTRY(_find_first_bit_le)
- teq r1, #0
- beq 3f
- mov r2, #0
-1:
- ARM( ldrb r3, [r0, r2, lsr #3] )
- THUMB( lsr r3, r2, #3 )
- THUMB( ldrb r3, [r0, r3] )
- movs r3, r3
- bne .L_found @ any now set - found zero bit
- add r2, r2, #8 @ next bit pointer
-2: cmp r2, r1 @ any more?
- blo 1b
-3: mov r0, r1 @ no free bits
- mov pc, lr
-ENDPROC(_find_first_bit_le)
-
-/*
- * Purpose : Find next 'one' bit
- * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
- */
-ENTRY(_find_next_bit_le)
- teq r1, #0
- beq 3b
- ands ip, r2, #7
- beq 1b @ If new byte, goto old routine
- ARM( ldrb r3, [r0, r2, lsr #3] )
- THUMB( lsr r3, r2, #3 )
- THUMB( ldrb r3, [r0, r3] )
- movs r3, r3, lsr ip @ shift off unused bits
- bne .L_found
- orr r2, r2, #7 @ if zero, then no bits here
- add r2, r2, #1 @ align bit pointer
- b 2b @ loop for next bit
-ENDPROC(_find_next_bit_le)
-
-#ifdef __ARMEB__
-
-ENTRY(_find_first_zero_bit_be)
- teq r1, #0
- beq 3f
- mov r2, #0
-1: eor r3, r2, #0x18 @ big endian byte ordering
- ARM( ldrb r3, [r0, r3, lsr #3] )
- THUMB( lsr r3, #3 )
- THUMB( ldrb r3, [r0, r3] )
- eors r3, r3, #0xff @ invert bits
- bne .L_found @ any now set - found zero bit
- add r2, r2, #8 @ next bit pointer
-2: cmp r2, r1 @ any more?
- blo 1b
-3: mov r0, r1 @ no free bits
- mov pc, lr
-ENDPROC(_find_first_zero_bit_be)
-
-ENTRY(_find_next_zero_bit_be)
- teq r1, #0
- beq 3b
- ands ip, r2, #7
- beq 1b @ If new byte, goto old routine
- eor r3, r2, #0x18 @ big endian byte ordering
- ARM( ldrb r3, [r0, r3, lsr #3] )
- THUMB( lsr r3, #3 )
- THUMB( ldrb r3, [r0, r3] )
- eor r3, r3, #0xff @ now looking for a 1 bit
- movs r3, r3, lsr ip @ shift off unused bits
- bne .L_found
- orr r2, r2, #7 @ if zero, then no bits here
- add r2, r2, #1 @ align bit pointer
- b 2b @ loop for next bit
-ENDPROC(_find_next_zero_bit_be)
-
-ENTRY(_find_first_bit_be)
- teq r1, #0
- beq 3f
- mov r2, #0
-1: eor r3, r2, #0x18 @ big endian byte ordering
- ARM( ldrb r3, [r0, r3, lsr #3] )
- THUMB( lsr r3, #3 )
- THUMB( ldrb r3, [r0, r3] )
- movs r3, r3
- bne .L_found @ any now set - found zero bit
- add r2, r2, #8 @ next bit pointer
-2: cmp r2, r1 @ any more?
- blo 1b
-3: mov r0, r1 @ no free bits
- mov pc, lr
-ENDPROC(_find_first_bit_be)
-
-ENTRY(_find_next_bit_be)
- teq r1, #0
- beq 3b
- ands ip, r2, #7
- beq 1b @ If new byte, goto old routine
- eor r3, r2, #0x18 @ big endian byte ordering
- ARM( ldrb r3, [r0, r3, lsr #3] )
- THUMB( lsr r3, #3 )
- THUMB( ldrb r3, [r0, r3] )
- movs r3, r3, lsr ip @ shift off unused bits
- bne .L_found
- orr r2, r2, #7 @ if zero, then no bits here
- add r2, r2, #1 @ align bit pointer
- b 2b @ loop for next bit
-ENDPROC(_find_next_bit_be)
-
-#endif
-
-/*
- * One or more bits in the LSB of r3 are assumed to be set.
- */
-.L_found:
-#if __LINUX_ARM_ARCH__ >= 5
- rsb r0, r3, #0
- and r3, r3, r0
- clz r3, r3
- rsb r3, r3, #31
- add r0, r2, r3
-#else
- tst r3, #0x0f
- addeq r2, r2, #4
- movne r3, r3, lsl #4
- tst r3, #0x30
- addeq r2, r2, #2
- movne r3, r3, lsl #2
- tst r3, #0x40
- addeq r2, r2, #1
- mov r0, r2
-#endif
- cmp r1, r0 @ Clamp to maxbit
- movlo r0, r1
- mov pc, lr
-
diff --git a/arch/arm/lib/io-readsb.S b/arch/arm/lib/io-readsb.S
deleted file mode 100644
index 963c455..0000000
--- a/arch/arm/lib/io-readsb.S
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * linux/arch/arm/lib/io-readsb.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-.section .text.readsb
-
-.Linsb_align: rsb ip, ip, #4
- cmp ip, r2
- movgt ip, r2
- cmp ip, #2
- ldrb r3, [r0]
- strb r3, [r1], #1
- ldrgeb r3, [r0]
- strgeb r3, [r1], #1
- ldrgtb r3, [r0]
- strgtb r3, [r1], #1
- subs r2, r2, ip
- bne .Linsb_aligned
-
-ENTRY(readsb)
- teq r2, #0 @ do we have to check for the zero len?
- moveq pc, lr
- ands ip, r1, #3
- bne .Linsb_align
-
-.Linsb_aligned: stmfd sp!, {r4 - r6, lr}
-
- subs r2, r2, #16
- bmi .Linsb_no_16
-
-.Linsb_16_lp: ldrb r3, [r0]
- ldrb r4, [r0]
- ldrb r5, [r0]
- mov r3, r3, put_byte_0
- ldrb r6, [r0]
- orr r3, r3, r4, put_byte_1
- ldrb r4, [r0]
- orr r3, r3, r5, put_byte_2
- ldrb r5, [r0]
- orr r3, r3, r6, put_byte_3
- ldrb r6, [r0]
- mov r4, r4, put_byte_0
- ldrb ip, [r0]
- orr r4, r4, r5, put_byte_1
- ldrb r5, [r0]
- orr r4, r4, r6, put_byte_2
- ldrb r6, [r0]
- orr r4, r4, ip, put_byte_3
- ldrb ip, [r0]
- mov r5, r5, put_byte_0
- ldrb lr, [r0]
- orr r5, r5, r6, put_byte_1
- ldrb r6, [r0]
- orr r5, r5, ip, put_byte_2
- ldrb ip, [r0]
- orr r5, r5, lr, put_byte_3
- ldrb lr, [r0]
- mov r6, r6, put_byte_0
- orr r6, r6, ip, put_byte_1
- ldrb ip, [r0]
- orr r6, r6, lr, put_byte_2
- orr r6, r6, ip, put_byte_3
- stmia r1!, {r3 - r6}
-
- subs r2, r2, #16
- bpl .Linsb_16_lp
-
- tst r2, #15
- ldmeqfd sp!, {r4 - r6, pc}
-
-.Linsb_no_16: tst r2, #8
- beq .Linsb_no_8
-
- ldrb r3, [r0]
- ldrb r4, [r0]
- ldrb r5, [r0]
- mov r3, r3, put_byte_0
- ldrb r6, [r0]
- orr r3, r3, r4, put_byte_1
- ldrb r4, [r0]
- orr r3, r3, r5, put_byte_2
- ldrb r5, [r0]
- orr r3, r3, r6, put_byte_3
- ldrb r6, [r0]
- mov r4, r4, put_byte_0
- ldrb ip, [r0]
- orr r4, r4, r5, put_byte_1
- orr r4, r4, r6, put_byte_2
- orr r4, r4, ip, put_byte_3
- stmia r1!, {r3, r4}
-
-.Linsb_no_8: tst r2, #4
- beq .Linsb_no_4
-
- ldrb r3, [r0]
- ldrb r4, [r0]
- ldrb r5, [r0]
- ldrb r6, [r0]
- mov r3, r3, put_byte_0
- orr r3, r3, r4, put_byte_1
- orr r3, r3, r5, put_byte_2
- orr r3, r3, r6, put_byte_3
- str r3, [r1], #4
-
-.Linsb_no_4: ands r2, r2, #3
- ldmeqfd sp!, {r4 - r6, pc}
-
- cmp r2, #2
- ldrb r3, [r0]
- strb r3, [r1], #1
- ldrgeb r3, [r0]
- strgeb r3, [r1], #1
- ldrgtb r3, [r0]
- strgtb r3, [r1]
-
- ldmfd sp!, {r4 - r6, pc}
-ENDPROC(readsb)
diff --git a/arch/arm/lib/io-readsl.S b/arch/arm/lib/io-readsl.S
deleted file mode 100644
index 47a2974..0000000
--- a/arch/arm/lib/io-readsl.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * linux/arch/arm/lib/io-readsl.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-.section .text.readsl
-
-ENTRY(readsl)
- teq r2, #0 @ do we have to check for the zero len?
- moveq pc, lr
- ands ip, r1, #3
- bne 3f
-
- subs r2, r2, #4
- bmi 2f
- stmfd sp!, {r4, lr}
-1: ldr r3, [r0, #0]
- ldr r4, [r0, #0]
- ldr ip, [r0, #0]
- ldr lr, [r0, #0]
- subs r2, r2, #4
- stmia r1!, {r3, r4, ip, lr}
- bpl 1b
- ldmfd sp!, {r4, lr}
-2: movs r2, r2, lsl #31
- ldrcs r3, [r0, #0]
- ldrcs ip, [r0, #0]
- stmcsia r1!, {r3, ip}
- ldrne r3, [r0, #0]
- strne r3, [r1, #0]
- mov pc, lr
-
-3: ldr r3, [r0]
- cmp ip, #2
- mov ip, r3, get_byte_0
- strb ip, [r1], #1
- bgt 6f
- mov ip, r3, get_byte_1
- strb ip, [r1], #1
- beq 5f
- mov ip, r3, get_byte_2
- strb ip, [r1], #1
-
-4: subs r2, r2, #1
- mov ip, r3, pull #24
- ldrne r3, [r0]
- orrne ip, ip, r3, push #8
- strne ip, [r1], #4
- bne 4b
- b 8f
-
-5: subs r2, r2, #1
- mov ip, r3, pull #16
- ldrne r3, [r0]
- orrne ip, ip, r3, push #16
- strne ip, [r1], #4
- bne 5b
- b 7f
-
-6: subs r2, r2, #1
- mov ip, r3, pull #8
- ldrne r3, [r0]
- orrne ip, ip, r3, push #24
- strne ip, [r1], #4
- bne 6b
-
- mov r3, ip, get_byte_2
- strb r3, [r1, #2]
-7: mov r3, ip, get_byte_1
- strb r3, [r1, #1]
-8: mov r3, ip, get_byte_0
- strb r3, [r1, #0]
- mov pc, lr
-ENDPROC(readsl)
diff --git a/arch/arm/lib/io-readsw-armv4.S b/arch/arm/lib/io-readsw-armv4.S
deleted file mode 100644
index f5b34a3..0000000
--- a/arch/arm/lib/io-readsw-armv4.S
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * linux/arch/arm/lib/io-readsw-armv4.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
- .macro pack, rd, hw1, hw2
-#ifndef __ARMEB__
- orr \rd, \hw1, \hw2, lsl #16
-#else
- orr \rd, \hw2, \hw1, lsl #16
-#endif
- .endm
-
-.section .text.readsw
-
-.Linsw_align: movs ip, r1, lsl #31
- bne .Linsw_noalign
- ldrh ip, [r0]
- sub r2, r2, #1
- strh ip, [r1], #2
-
-ENTRY(readsw)
- teq r2, #0
- moveq pc, lr
- tst r1, #3
- bne .Linsw_align
-
- stmfd sp!, {r4, r5, lr}
-
- subs r2, r2, #8
- bmi .Lno_insw_8
-
-.Linsw_8_lp: ldrh r3, [r0]
- ldrh r4, [r0]
- pack r3, r3, r4
-
- ldrh r4, [r0]
- ldrh r5, [r0]
- pack r4, r4, r5
-
- ldrh r5, [r0]
- ldrh ip, [r0]
- pack r5, r5, ip
-
- ldrh ip, [r0]
- ldrh lr, [r0]
- pack ip, ip, lr
-
- subs r2, r2, #8
- stmia r1!, {r3 - r5, ip}
- bpl .Linsw_8_lp
-
-.Lno_insw_8: tst r2, #4
- beq .Lno_insw_4
-
- ldrh r3, [r0]
- ldrh r4, [r0]
- pack r3, r3, r4
-
- ldrh r4, [r0]
- ldrh ip, [r0]
- pack r4, r4, ip
-
- stmia r1!, {r3, r4}
-
-.Lno_insw_4: movs r2, r2, lsl #31
- bcc .Lno_insw_2
-
- ldrh r3, [r0]
- ldrh ip, [r0]
- pack r3, r3, ip
- str r3, [r1], #4
-
-.Lno_insw_2: ldrneh r3, [r0]
- strneh r3, [r1]
-
- ldmfd sp!, {r4, r5, pc}
-
-#ifdef __ARMEB__
-#define _BE_ONLY_(code...) code
-#define _LE_ONLY_(code...)
-#define push_hbyte0 lsr #8
-#define pull_hbyte1 lsl #24
-#else
-#define _BE_ONLY_(code...)
-#define _LE_ONLY_(code...) code
-#define push_hbyte0 lsl #24
-#define pull_hbyte1 lsr #8
-#endif
-
-.Linsw_noalign: stmfd sp!, {r4, lr}
- ldrccb ip, [r1, #-1]!
- bcc 1f
-
- ldrh ip, [r0]
- sub r2, r2, #1
- _BE_ONLY_( mov ip, ip, ror #8 )
- strb ip, [r1], #1
- _LE_ONLY_( mov ip, ip, lsr #8 )
- _BE_ONLY_( mov ip, ip, lsr #24 )
-
-1: subs r2, r2, #2
- bmi 3f
- _BE_ONLY_( mov ip, ip, lsl #24 )
-
-2: ldrh r3, [r0]
- ldrh r4, [r0]
- subs r2, r2, #2
- orr ip, ip, r3, lsl #8
- orr ip, ip, r4, push_hbyte0
- str ip, [r1], #4
- mov ip, r4, pull_hbyte1
- bpl 2b
-
- _BE_ONLY_( mov ip, ip, lsr #24 )
-
-3: tst r2, #1
- strb ip, [r1], #1
- ldrneh ip, [r0]
- _BE_ONLY_( movne ip, ip, ror #8 )
- strneb ip, [r1], #1
- _LE_ONLY_( movne ip, ip, lsr #8 )
- _BE_ONLY_( movne ip, ip, lsr #24 )
- strneb ip, [r1]
- ldmfd sp!, {r4, pc}
-ENDPROC(readsw)
diff --git a/arch/arm/lib/io-writesb.S b/arch/arm/lib/io-writesb.S
deleted file mode 100644
index 1ab8e47..0000000
--- a/arch/arm/lib/io-writesb.S
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * linux/arch/arm/lib/io-writesb.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
- .macro outword, rd
-#ifndef __ARMEB__
- strb \rd, [r0]
- mov \rd, \rd, lsr #8
- strb \rd, [r0]
- mov \rd, \rd, lsr #8
- strb \rd, [r0]
- mov \rd, \rd, lsr #8
- strb \rd, [r0]
-#else
- mov lr, \rd, lsr #24
- strb lr, [r0]
- mov lr, \rd, lsr #16
- strb lr, [r0]
- mov lr, \rd, lsr #8
- strb lr, [r0]
- strb \rd, [r0]
-#endif
- .endm
-
-.section .text.writesb
-
-.Loutsb_align: rsb ip, ip, #4
- cmp ip, r2
- movgt ip, r2
- cmp ip, #2
- ldrb r3, [r1], #1
- strb r3, [r0]
- ldrgeb r3, [r1], #1
- strgeb r3, [r0]
- ldrgtb r3, [r1], #1
- strgtb r3, [r0]
- subs r2, r2, ip
- bne .Loutsb_aligned
-
-ENTRY(writesb)
- teq r2, #0 @ do we have to check for the zero len?
- moveq pc, lr
- ands ip, r1, #3
- bne .Loutsb_align
-
-.Loutsb_aligned:
- stmfd sp!, {r4, r5, lr}
-
- subs r2, r2, #16
- bmi .Loutsb_no_16
-
-.Loutsb_16_lp: ldmia r1!, {r3, r4, r5, ip}
- outword r3
- outword r4
- outword r5
- outword ip
- subs r2, r2, #16
- bpl .Loutsb_16_lp
-
- tst r2, #15
- ldmeqfd sp!, {r4, r5, pc}
-
-.Loutsb_no_16: tst r2, #8
- beq .Loutsb_no_8
-
- ldmia r1!, {r3, r4}
- outword r3
- outword r4
-
-.Loutsb_no_8: tst r2, #4
- beq .Loutsb_no_4
-
- ldr r3, [r1], #4
- outword r3
-
-.Loutsb_no_4: ands r2, r2, #3
- ldmeqfd sp!, {r4, r5, pc}
-
- cmp r2, #2
- ldrb r3, [r1], #1
- strb r3, [r0]
- ldrgeb r3, [r1], #1
- strgeb r3, [r0]
- ldrgtb r3, [r1]
- strgtb r3, [r0]
-
- ldmfd sp!, {r4, r5, pc}
-ENDPROC(writesb)
diff --git a/arch/arm/lib/io-writesl.S b/arch/arm/lib/io-writesl.S
deleted file mode 100644
index 8a3bcd6..0000000
--- a/arch/arm/lib/io-writesl.S
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * linux/arch/arm/lib/io-writesl.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-.section .text.writesl
-
-ENTRY(writesl)
- teq r2, #0 @ do we have to check for the zero len?
- moveq pc, lr
- ands ip, r1, #3
- bne 3f
-
- subs r2, r2, #4
- bmi 2f
- stmfd sp!, {r4, lr}
-1: ldmia r1!, {r3, r4, ip, lr}
- subs r2, r2, #4
- str r3, [r0, #0]
- str r4, [r0, #0]
- str ip, [r0, #0]
- str lr, [r0, #0]
- bpl 1b
- ldmfd sp!, {r4, lr}
-2: movs r2, r2, lsl #31
- ldmcsia r1!, {r3, ip}
- strcs r3, [r0, #0]
- ldrne r3, [r1, #0]
- strcs ip, [r0, #0]
- strne r3, [r0, #0]
- mov pc, lr
-
-3: bic r1, r1, #3
- ldr r3, [r1], #4
- cmp ip, #2
- blt 5f
- bgt 6f
-
-4: mov ip, r3, pull #16
- ldr r3, [r1], #4
- subs r2, r2, #1
- orr ip, ip, r3, push #16
- str ip, [r0]
- bne 4b
- mov pc, lr
-
-5: mov ip, r3, pull #8
- ldr r3, [r1], #4
- subs r2, r2, #1
- orr ip, ip, r3, push #24
- str ip, [r0]
- bne 5b
- mov pc, lr
-
-6: mov ip, r3, pull #24
- ldr r3, [r1], #4
- subs r2, r2, #1
- orr ip, ip, r3, push #8
- str ip, [r0]
- bne 6b
- mov pc, lr
-ENDPROC(writesl)
diff --git a/arch/arm/lib/io-writesw-armv4.S b/arch/arm/lib/io-writesw-armv4.S
deleted file mode 100644
index 9e8308d..0000000
--- a/arch/arm/lib/io-writesw-armv4.S
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * linux/arch/arm/lib/io-writesw-armv4.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
- .macro outword, rd
-#ifndef __ARMEB__
- strh \rd, [r0]
- mov \rd, \rd, lsr #16
- strh \rd, [r0]
-#else
- mov lr, \rd, lsr #16
- strh lr, [r0]
- strh \rd, [r0]
-#endif
- .endm
-
-.section .text.__raw_writesw
-
-.Loutsw_align: movs ip, r1, lsl #31
- bne .Loutsw_noalign
-
- ldrh r3, [r1], #2
- sub r2, r2, #1
- strh r3, [r0]
-
-ENTRY(__raw_writesw)
- teq r2, #0
- moveq pc, lr
- ands r3, r1, #3
- bne .Loutsw_align
-
- stmfd sp!, {r4, r5, lr}
-
- subs r2, r2, #8
- bmi .Lno_outsw_8
-
-.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
- subs r2, r2, #8
- outword r3
- outword r4
- outword r5
- outword ip
- bpl .Loutsw_8_lp
-
-.Lno_outsw_8: tst r2, #4
- beq .Lno_outsw_4
-
- ldmia r1!, {r3, ip}
- outword r3
- outword ip
-
-.Lno_outsw_4: movs r2, r2, lsl #31
- bcc .Lno_outsw_2
-
- ldr r3, [r1], #4
- outword r3
-
-.Lno_outsw_2: ldrneh r3, [r1]
- strneh r3, [r0]
-
- ldmfd sp!, {r4, r5, pc}
-
-#ifdef __ARMEB__
-#define pull_hbyte0 lsl #8
-#define push_hbyte1 lsr #24
-#else
-#define pull_hbyte0 lsr #24
-#define push_hbyte1 lsl #8
-#endif
-
-.Loutsw_noalign:
- ARM( ldr r3, [r1, -r3]! )
- THUMB( rsb r3, r3, #0 )
- THUMB( ldr r3, [r1, r3] )
- THUMB( sub r1, r3 )
- subcs r2, r2, #1
- bcs 2f
- subs r2, r2, #2
- bmi 3f
-
-1: mov ip, r3, lsr #8
- strh ip, [r0]
-2: mov ip, r3, pull_hbyte0
- ldr r3, [r1, #4]!
- subs r2, r2, #2
- orr ip, ip, r3, push_hbyte1
- strh ip, [r0]
- bpl 1b
-
- tst r2, #1
-3: movne ip, r3, lsr #8
- strneh ip, [r0]
- mov pc, lr
-ENDPROC(__raw_writesw)
diff --git a/arch/arm/lib/io.c b/arch/arm/lib/io.c
deleted file mode 100644
index abfd887..0000000
--- a/arch/arm/lib/io.c
+++ /dev/null
@@ -1,50 +0,0 @@
-#include <module.h>
-#include <linux/types.h>
-#include <io.h>
-
-/*
- * Copy data from IO memory space to "real" memory space.
- * This needs to be optimized.
- */
-void memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
-{
- unsigned char *t = to;
- while (count) {
- count--;
- *t = readb(from);
- t++;
- from++;
- }
-}
-
-/*
- * Copy data from "real" memory space to IO memory space.
- * This needs to be optimized.
- */
-void memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
-{
- const unsigned char *f = from;
- while (count) {
- count--;
- writeb(*f, to);
- f++;
- to++;
- }
-}
-
-/*
- * "memset" on IO memory space.
- * This needs to be optimized.
- */
-void memset_io(volatile void __iomem *dst, int c, size_t count)
-{
- while (count) {
- count--;
- writeb(c, dst);
- dst++;
- }
-}
-
-EXPORT_SYMBOL(memcpy_fromio);
-EXPORT_SYMBOL(memcpy_toio);
-EXPORT_SYMBOL(memset_io);
diff --git a/arch/arm/lib/lib1funcs.S b/arch/arm/lib/lib1funcs.S
deleted file mode 100644
index bf1d019..0000000
--- a/arch/arm/lib/lib1funcs.S
+++ /dev/null
@@ -1,351 +0,0 @@
-/*
- * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
- *
- * Author: Nicolas Pitre <nico@fluxnic.net>
- * - contributed to gcc-3.4 on Sep 30, 2003
- * - adapted for the Linux kernel on Oct 2, 2003
- */
-
-/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file. (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-*/
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-
-.macro ARM_DIV_BODY dividend, divisor, result, curbit
-
-#if __LINUX_ARM_ARCH__ >= 5
-
- clz \curbit, \divisor
- clz \result, \dividend
- sub \result, \curbit, \result
- mov \curbit, #1
- mov \divisor, \divisor, lsl \result
- mov \curbit, \curbit, lsl \result
- mov \result, #0
-
-#else
-
- @ Initially shift the divisor left 3 bits if possible,
- @ set curbit accordingly. This allows for curbit to be located
- @ at the left end of each 4 bit nibbles in the division loop
- @ to save one loop in most cases.
- tst \divisor, #0xe0000000
- moveq \divisor, \divisor, lsl #3
- moveq \curbit, #8
- movne \curbit, #1
-
- @ Unless the divisor is very big, shift it up in multiples of
- @ four bits, since this is the amount of unwinding in the main
- @ division loop. Continue shifting until the divisor is
- @ larger than the dividend.
-1: cmp \divisor, #0x10000000
- cmplo \divisor, \dividend
- movlo \divisor, \divisor, lsl #4
- movlo \curbit, \curbit, lsl #4
- blo 1b
-
- @ For very big divisors, we must shift it a bit at a time, or
- @ we will be in danger of overflowing.
-1: cmp \divisor, #0x80000000
- cmplo \divisor, \dividend
- movlo \divisor, \divisor, lsl #1
- movlo \curbit, \curbit, lsl #1
- blo 1b
-
- mov \result, #0
-
-#endif
-
- @ Division loop
-1: cmp \dividend, \divisor
- subhs \dividend, \dividend, \divisor
- orrhs \result, \result, \curbit
- cmp \dividend, \divisor, lsr #1
- subhs \dividend, \dividend, \divisor, lsr #1
- orrhs \result, \result, \curbit, lsr #1
- cmp \dividend, \divisor, lsr #2
- subhs \dividend, \dividend, \divisor, lsr #2
- orrhs \result, \result, \curbit, lsr #2
- cmp \dividend, \divisor, lsr #3
- subhs \dividend, \dividend, \divisor, lsr #3
- orrhs \result, \result, \curbit, lsr #3
- cmp \dividend, #0 @ Early termination?
- movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
- movne \divisor, \divisor, lsr #4
- bne 1b
-
-.endm
-
-
-.macro ARM_DIV2_ORDER divisor, order
-
-#if __LINUX_ARM_ARCH__ >= 5
-
- clz \order, \divisor
- rsb \order, \order, #31
-
-#else
-
- cmp \divisor, #(1 << 16)
- movhs \divisor, \divisor, lsr #16
- movhs \order, #16
- movlo \order, #0
-
- cmp \divisor, #(1 << 8)
- movhs \divisor, \divisor, lsr #8
- addhs \order, \order, #8
-
- cmp \divisor, #(1 << 4)
- movhs \divisor, \divisor, lsr #4
- addhs \order, \order, #4
-
- cmp \divisor, #(1 << 2)
- addhi \order, \order, #3
- addls \order, \order, \divisor, lsr #1
-
-#endif
-
-.endm
-
-
-.macro ARM_MOD_BODY dividend, divisor, order, spare
-
-#if __LINUX_ARM_ARCH__ >= 5
-
- clz \order, \divisor
- clz \spare, \dividend
- sub \order, \order, \spare
- mov \divisor, \divisor, lsl \order
-
-#else
-
- mov \order, #0
-
- @ Unless the divisor is very big, shift it up in multiples of
- @ four bits, since this is the amount of unwinding in the main
- @ division loop. Continue shifting until the divisor is
- @ larger than the dividend.
-1: cmp \divisor, #0x10000000
- cmplo \divisor, \dividend
- movlo \divisor, \divisor, lsl #4
- addlo \order, \order, #4
- blo 1b
-
- @ For very big divisors, we must shift it a bit at a time, or
- @ we will be in danger of overflowing.
-1: cmp \divisor, #0x80000000
- cmplo \divisor, \dividend
- movlo \divisor, \divisor, lsl #1
- addlo \order, \order, #1
- blo 1b
-
-#endif
-
- @ Perform all needed substractions to keep only the reminder.
- @ Do comparisons in batch of 4 first.
- subs \order, \order, #3 @ yes, 3 is intended here
- blt 2f
-
-1: cmp \dividend, \divisor
- subhs \dividend, \dividend, \divisor
- cmp \dividend, \divisor, lsr #1
- subhs \dividend, \dividend, \divisor, lsr #1
- cmp \dividend, \divisor, lsr #2
- subhs \dividend, \dividend, \divisor, lsr #2
- cmp \dividend, \divisor, lsr #3
- subhs \dividend, \dividend, \divisor, lsr #3
- cmp \dividend, #1
- mov \divisor, \divisor, lsr #4
- subges \order, \order, #4
- bge 1b
-
- tst \order, #3
- teqne \dividend, #0
- beq 5f
-
- @ Either 1, 2 or 3 comparison/substractions are left.
-2: cmn \order, #2
- blt 4f
- beq 3f
- cmp \dividend, \divisor
- subhs \dividend, \dividend, \divisor
- mov \divisor, \divisor, lsr #1
-3: cmp \dividend, \divisor
- subhs \dividend, \dividend, \divisor
- mov \divisor, \divisor, lsr #1
-4: cmp \dividend, \divisor
- subhs \dividend, \dividend, \divisor
-5:
-.endm
-
-
-.section .text.__udivsi3
-ENTRY(__udivsi3)
-ENTRY(__aeabi_uidiv)
-
- subs r2, r1, #1
- moveq pc, lr
- bcc Ldiv0
- cmp r0, r1
- bls 11f
- tst r1, r2
- beq 12f
-
- ARM_DIV_BODY r0, r1, r2, r3
-
- mov r0, r2
- mov pc, lr
-
-11: moveq r0, #1
- movne r0, #0
- mov pc, lr
-
-12: ARM_DIV2_ORDER r1, r2
-
- mov r0, r0, lsr r2
- mov pc, lr
-
-ENDPROC(__udivsi3)
-ENDPROC(__aeabi_uidiv)
-
-.section .text.__umodsi3
-ENTRY(__umodsi3)
-
- subs r2, r1, #1 @ compare divisor with 1
- bcc Ldiv0
- cmpne r0, r1 @ compare dividend with divisor
- moveq r0, #0
- tsthi r1, r2 @ see if divisor is power of 2
- andeq r0, r0, r2
- movls pc, lr
-
- ARM_MOD_BODY r0, r1, r2, r3
-
- mov pc, lr
-
-ENDPROC(__umodsi3)
-
-.section .text.__divsi3
-ENTRY(__divsi3)
-ENTRY(__aeabi_idiv)
-
- cmp r1, #0
- eor ip, r0, r1 @ save the sign of the result.
- beq Ldiv0
- rsbmi r1, r1, #0 @ loops below use unsigned.
- subs r2, r1, #1 @ division by 1 or -1 ?
- beq 10f
- movs r3, r0
- rsbmi r3, r0, #0 @ positive dividend value
- cmp r3, r1
- bls 11f
- tst r1, r2 @ divisor is power of 2 ?
- beq 12f
-
- ARM_DIV_BODY r3, r1, r0, r2
-
- cmp ip, #0
- rsbmi r0, r0, #0
- mov pc, lr
-
-10: teq ip, r0 @ same sign ?
- rsbmi r0, r0, #0
- mov pc, lr
-
-11: movlo r0, #0
- moveq r0, ip, asr #31
- orreq r0, r0, #1
- mov pc, lr
-
-12: ARM_DIV2_ORDER r1, r2
-
- cmp ip, #0
- mov r0, r3, lsr r2
- rsbmi r0, r0, #0
- mov pc, lr
-
-ENDPROC(__divsi3)
-ENDPROC(__aeabi_idiv)
-
-.section .text.__modsi3
-ENTRY(__modsi3)
-
- cmp r1, #0
- beq Ldiv0
- rsbmi r1, r1, #0 @ loops below use unsigned.
- movs ip, r0 @ preserve sign of dividend
- rsbmi r0, r0, #0 @ if negative make positive
- subs r2, r1, #1 @ compare divisor with 1
- cmpne r0, r1 @ compare dividend with divisor
- moveq r0, #0
- tsthi r1, r2 @ see if divisor is power of 2
- andeq r0, r0, r2
- bls 10f
-
- ARM_MOD_BODY r0, r1, r2, r3
-
-10: cmp ip, #0
- rsbmi r0, r0, #0
- mov pc, lr
-
-ENDPROC(__modsi3)
-
-#ifdef CONFIG_AEABI
-
-.section .text.__aeabi_uidivmod
-ENTRY(__aeabi_uidivmod)
-
- stmfd sp!, {r0, r1, ip, lr}
- bl __aeabi_uidiv
- ldmfd sp!, {r1, r2, ip, lr}
- mul r3, r0, r2
- sub r1, r1, r3
- mov pc, lr
-
-ENDPROC(__aeabi_uidivmod)
-
-.section .text.__aeabi_idivmod
-ENTRY(__aeabi_idivmod)
-
- stmfd sp!, {r0, r1, ip, lr}
- bl __aeabi_idiv
- ldmfd sp!, {r1, r2, ip, lr}
- mul r3, r0, r2
- sub r1, r1, r3
- mov pc, lr
-
-ENDPROC(__aeabi_idivmod)
-
-#endif
-
-.section .text.Ldiv0
-Ldiv0:
-
- str lr, [sp, #-8]!
- bl __div0
- mov r0, #0 @ About as wrong as it could be.
- ldr pc, [sp], #8
-
-
diff --git a/arch/arm/lib/lshrdi3.S b/arch/arm/lib/lshrdi3.S
deleted file mode 100644
index e77e96c..0000000
--- a/arch/arm/lib/lshrdi3.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
- Free Software Foundation, Inc.
-
-This file is free software; you can redistribute it and/or modify it
-under the terms of the GNU General Public License as published by the
-Free Software Foundation; either version 2, or (at your option) any
-later version.
-
-In addition to the permissions in the GNU General Public License, the
-Free Software Foundation gives you unlimited permission to link the
-compiled version of this file into combinations with other programs,
-and to distribute those combinations without any restriction coming
-from the use of this file. (The General Public License restrictions
-do apply in other respects; for example, they cover modification of
-the file, and distribution when not linked into a combine
-executable.)
-
-This file is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-General Public License for more details.
-
-*/
-
-#include <linux/linkage.h>
-
-#ifdef __ARMEB__
-#define al r1
-#define ah r0
-#else
-#define al r0
-#define ah r1
-#endif
-
-.section .text.__lshrdi3
-ENTRY(__lshrdi3)
-ENTRY(__aeabi_llsr)
-
- subs r3, r2, #32
- rsb ip, r2, #32
- movmi al, al, lsr r2
- movpl al, ah, lsr r3
- ARM( orrmi al, al, ah, lsl ip )
- THUMB( lslmi r3, ah, ip )
- THUMB( orrmi al, al, r3 )
- mov ah, ah, lsr r2
- mov pc, lr
-
-ENDPROC(__lshrdi3)
-ENDPROC(__aeabi_llsr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
deleted file mode 100644
index 5123691..0000000
--- a/arch/arm/lib/memcpy.S
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * linux/arch/arm/lib/memcpy.S
- *
- * Author: Nicolas Pitre
- * Created: Sep 28, 2005
- * Copyright: MontaVista Software, Inc.
- *
- * 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.
- */
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-#define LDR1W_SHIFT 0
-#define STR1W_SHIFT 0
-
- .macro ldr1w ptr reg abort
- W(ldr) \reg, [\ptr], #4
- .endm
-
- .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
- .endm
-
- .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro ldr1b ptr reg cond=al abort
- ldr\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro str1w ptr reg abort
- W(str) \reg, [\ptr], #4
- .endm
-
- .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
- stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
- .endm
-
- .macro str1b ptr reg cond=al abort
- str\cond\()b \reg, [\ptr], #1
- .endm
-
- .macro enter reg1 reg2
- stmdb sp!, {r0, \reg1, \reg2}
- .endm
-
- .macro exit reg1 reg2
- ldmfd sp!, {r0, \reg1, \reg2}
- .endm
-
- .text
-
-/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
-
-ENTRY(memcpy)
-
-#include "copy_template.S"
-
-ENDPROC(memcpy)
-
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
deleted file mode 100644
index c4d2672..0000000
--- a/arch/arm/lib/memset.S
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * linux/arch/arm/lib/memset.S
- *
- * Copyright (C) 1995-2000 Russell King
- *
- * 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.
- *
- * ASM optimised string functions
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
- .text
- .align 5
-
-ENTRY(memset)
- ands r3, r0, #3 @ 1 unaligned?
- mov ip, r0 @ preserve r0 as return value
- bne 6f @ 1
-/*
- * we know that the pointer in ip is aligned to a word boundary.
- */
-1: orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- mov r3, r1
- cmp r2, #16
- blt 4f
-
-#if ! CALGN(1)+0
-
-/*
- * We need an 2 extra registers for this loop - use r8 and the LR
- */
- stmfd sp!, {r8, lr}
- mov r8, r1
- mov lr, r1
-
-2: subs r2, r2, #64
- stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time.
- stmgeia ip!, {r1, r3, r8, lr}
- stmgeia ip!, {r1, r3, r8, lr}
- stmgeia ip!, {r1, r3, r8, lr}
- bgt 2b
- ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
-/*
- * No need to correct the count; we're only testing bits from now on
- */
- tst r2, #32
- stmneia ip!, {r1, r3, r8, lr}
- stmneia ip!, {r1, r3, r8, lr}
- tst r2, #16
- stmneia ip!, {r1, r3, r8, lr}
- ldmfd sp!, {r8, lr}
-
-#else
-
-/*
- * This version aligns the destination pointer in order to write
- * whole cache lines at once.
- */
-
- stmfd sp!, {r4-r8, lr}
- mov r4, r1
- mov r5, r1
- mov r6, r1
- mov r7, r1
- mov r8, r1
- mov lr, r1
-
- cmp r2, #96
- tstgt ip, #31
- ble 3f
-
- and r8, ip, #31
- rsb r8, r8, #32
- sub r2, r2, r8
- movs r8, r8, lsl #(32 - 4)
- stmcsia ip!, {r4, r5, r6, r7}
- stmmiia ip!, {r4, r5}
- tst r8, #(1 << 30)
- mov r8, r1
- strne r1, [ip], #4
-
-3: subs r2, r2, #64
- stmgeia ip!, {r1, r3-r8, lr}
- stmgeia ip!, {r1, r3-r8, lr}
- bgt 3b
- ldmeqfd sp!, {r4-r8, pc}
-
- tst r2, #32
- stmneia ip!, {r1, r3-r8, lr}
- tst r2, #16
- stmneia ip!, {r4-r7}
- ldmfd sp!, {r4-r8, lr}
-
-#endif
-
-4: tst r2, #8
- stmneia ip!, {r1, r3}
- tst r2, #4
- strne r1, [ip], #4
-/*
- * When we get here, we've got less than 4 bytes to zero. We
- * may have an unaligned pointer as well.
- */
-5: tst r2, #2
- strneb r1, [ip], #1
- strneb r1, [ip], #1
- tst r2, #1
- strneb r1, [ip], #1
- mov pc, lr
-
-6: subs r2, r2, #4 @ 1 do we have enough
- blt 5b @ 1 bytes to align with?
- cmp r3, #2 @ 1
- strltb r1, [ip], #1 @ 1
- strleb r1, [ip], #1 @ 1
- strb r1, [ip], #1 @ 1
- add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
- b 1b
-ENDPROC(memset)
-
diff --git a/arch/arm/lib/module.c b/arch/arm/lib/module.c
deleted file mode 100644
index be7965d..0000000
--- a/arch/arm/lib/module.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * linux/arch/arm/kernel/module.c
- *
- * Copyright (C) 2002 Russell King.
- * Modified for nommu by Hyok S. Choi
- *
- * 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.
- *
- * Module allocation method suggested by Andi Kleen.
- */
-
-//#include <asm/pgtable.h>
-#include <common.h>
-#include <elf.h>
-#include <module.h>
-#include <errno.h>
-
-int
-apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
- unsigned int relindex, struct module *module)
-{
- Elf32_Shdr *symsec = sechdrs + symindex;
- Elf32_Shdr *relsec = sechdrs + relindex;
- Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
- Elf32_Rel *rel = (void *)relsec->sh_addr;
- unsigned int i;
-
- for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
- unsigned long loc;
- Elf32_Sym *sym;
- s32 offset;
-
- offset = ELF32_R_SYM(rel->r_info);
- if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
- printf("%s: bad relocation, section %u reloc %u\n",
- module->name, relindex, i);
- return -ENOEXEC;
- }
-
- sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
-
- if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
- printf("%s: out of bounds relocation, "
- "section %u reloc %u offset %d size %d\n",
- module->name, relindex, i, rel->r_offset,
- dstsec->sh_size);
- return -ENOEXEC;
- }
-
- loc = dstsec->sh_addr + rel->r_offset;
-
- switch (ELF32_R_TYPE(rel->r_info)) {
- case R_ARM_ABS32:
- *(u32 *)loc += sym->st_value;
- break;
-
- case R_ARM_PC24:
- case R_ARM_CALL:
- case R_ARM_JUMP24:
- offset = (*(u32 *)loc & 0x00ffffff) << 2;
- if (offset & 0x02000000)
- offset -= 0x04000000;
-
- offset += sym->st_value - loc;
- if (offset & 3 ||
- offset <= (s32)0xfe000000 ||
- offset >= (s32)0x02000000) {
- printf("%s: relocation out of range, section "
- "%u reloc %u sym '%s'\n", module->name,
- relindex, i, strtab + sym->st_name);
- return -ENOEXEC;
- }
-
- offset >>= 2;
-
- *(u32 *)loc &= 0xff000000;
- *(u32 *)loc |= offset & 0x00ffffff;
- break;
-
- default:
- printf("%s: unknown relocation: %u\n",
- module->name, ELF32_R_TYPE(rel->r_info));
- return -ENOEXEC;
- }
- }
- return 0;
-}
-
-int
-apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
- unsigned int symindex, unsigned int relsec, struct module *module)
-{
- printf("module %s: ADD RELOCATION unsupported\n",
- module->name);
- return -ENOEXEC;
-}
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
deleted file mode 100644
index 73baff0..0000000
--- a/arch/arm/lib/pbl.lds.S
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * (C) Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>, 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 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 <linux/sizes.h>
-#include <asm-generic/barebox.lds.h>
-#include <asm-generic/memory_layout.h>
-
-#ifdef CONFIG_PBL_RELOCATABLE
-#define BASE 0x0
-#else
-#define BASE (TEXT_BASE - SZ_2M)
-#endif
-
-OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
-OUTPUT_ARCH(arm)
-SECTIONS
-{
- . = BASE;
-
- PRE_IMAGE
-
- . = ALIGN(4);
- .text :
- {
- _stext = .;
- _text = .;
- *(.text_head_entry*)
- __bare_init_start = .;
- *(.text_bare_init*)
- __bare_init_end = .;
- *(.text*)
- }
-
- /* Discard unwind if enable in barebox */
- /DISCARD/ : { *(.ARM.ex*) }
-
- BAREBOX_BARE_INIT_SIZE
- BAREBOX_PBL_SIZE
-
- . = ALIGN(4);
- .rodata : { *(.rodata*) }
-
- .barebox_imd : { BAREBOX_IMD }
-
- _etext = .; /* End of text and rodata section */
-
- . = ALIGN(4);
- .data : { *(.data*) }
-
- .rel.dyn : {
- __rel_dyn_start = .;
- *(.rel*)
- __rel_dyn_end = .;
- }
-
- .dynsym : {
- __dynsym_start = .;
- *(.dynsym)
- __dynsym_end = .;
- }
-
- . = ALIGN(4);
- __bss_start = .;
- .bss : { *(.bss*) }
- __bss_stop = .;
- _end = .;
-
- . = ALIGN(4);
- __piggydata_start = .;
- .piggydata : {
- *(.piggydata)
- }
- __piggydata_end = .;
-
- . = ALIGN(4);
- .image_end : {
- KEEP(*(.image_end))
- }
- __image_end = .;
- _barebox_image_size = __image_end - BASE;
- _barebox_pbl_size = __bss_start - BASE;
-}
diff --git a/arch/arm/lib/runtime-offset.S b/arch/arm/lib/runtime-offset.S
deleted file mode 100644
index f10c4c8..0000000
--- a/arch/arm/lib/runtime-offset.S
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-.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 r0, 1b
- ldr r1, linkadr
- subs r0, r1, r0
-THUMB( subs 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 _barebox_image_size
-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/lib/semihosting-trap.S b/arch/arm/lib/semihosting-trap.S
deleted file mode 100644
index 9e40ebf..0000000
--- a/arch/arm/lib/semihosting-trap.S
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * semihosting-trap.S -- Assembly code needed to make a semihosting call
- *
- * Copyright (c) 2015 Zodiac Inflight Innovations
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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 <linux/linkage.h>
-#include <asm/unified.h>
-
-.section .text.semihosting_trap
-ENTRY(semihosting_trap)
- @ In supervisor mode SVC would clobber LR
- push {lr}
- ARM( svc #0x123456 )
- THUMB( svc #0xAB )
- pop {pc}
-ENDPROC(semihosting_trap)
diff --git a/arch/arm/lib/semihosting.c b/arch/arm/lib/semihosting.c
deleted file mode 100644
index a735196..0000000
--- a/arch/arm/lib/semihosting.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * semihosting.c -- ARM Semihoting API implementation
- *
- * Copyright (c) 2015 Zodiac Inflight Innovations
- * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
- *
- * based on a smiliar code from U-Boot
- * Copyright (c) 2014 Broadcom Corporation
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * 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 <common.h>
-#include <command.h>
-#include <fcntl.h>
-
-#ifndef O_BINARY
-#define O_BINARY 0
-#endif
-
-
-enum {
- SEMIHOSTING_SYS_OPEN = 0x01,
- SEMIHOSTING_SYS_CLOSE = 0x02,
- SEMIHOSTING_SYS_WRITEC = 0x03,
- SEMIHOSTING_SYS_WRITE0 = 0x04,
- SEMIHOSTING_SYS_WRITE = 0x05,
- SEMIHOSTING_SYS_READ = 0x06,
- SEMIHOSTING_SYS_READC = 0x07,
- /* SYS_ISERROR is not implemented */
- SEMIHOSTING_SYS_ISATTY = 0x09,
- SEMIHOSTING_SYS_SEEK = 0x0a,
- SEMIHOSTING_SYS_FLEN = 0x0c,
- SEMIHOSTING_SYS_REMOVE = 0x0e,
- SEMIHOSTING_SYS_RENAME = 0x0f,
- SEMIHOSTING_SYS_TIME = 0x11,
- SEMIHOSTING_SYS_ERRNO = 0x13,
- /* SYS_GET_CMDLINE is not implemented */
- /* SYS_HEAPINFO is not implemented */
- /* angel_SWIreason_ReportException is not implemented */
- SEMIHOSTING_SYS_SYSTEM = 0x12,
-};
-
-uint32_t semihosting_trap(uint32_t sysnum, void *addr);
-
-static uint32_t semihosting_flags_to_mode(int flags)
-{
- static const int semihosting_open_modeflags[12] = {
- O_RDONLY,
- O_RDONLY | O_BINARY,
- O_RDWR,
- O_RDWR | O_BINARY,
- O_WRONLY | O_CREAT | O_TRUNC,
- O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
- O_RDWR | O_CREAT | O_TRUNC,
- O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
- O_WRONLY | O_CREAT | O_APPEND,
- O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
- O_RDWR | O_CREAT | O_APPEND,
- O_RDWR | O_CREAT | O_APPEND | O_BINARY
- };
-
- int i;
- for (i = 0; i < ARRAY_SIZE(semihosting_open_modeflags); i++) {
- if (semihosting_open_modeflags[i] == flags)
- return i;
- }
-
- return 0;
-}
-
-int semihosting_open(const char *fname, int flags)
-{
- struct __packed {
- uint32_t fname;
- uint32_t mode;
- uint32_t len;
- } open = {
- .fname = (uint32_t)fname,
- .len = strlen(fname),
- .mode = semihosting_flags_to_mode(flags),
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_OPEN, &open);
-}
-EXPORT_SYMBOL(semihosting_open);
-
-int semihosting_close(int fd)
-{
- return semihosting_trap(SEMIHOSTING_SYS_CLOSE, &fd);
-}
-EXPORT_SYMBOL(semihosting_close);
-
-int semihosting_writec(char c)
-{
- return semihosting_trap(SEMIHOSTING_SYS_WRITEC, &c);
-}
-EXPORT_SYMBOL(semihosting_writec);
-
-int semihosting_write0(const char *str)
-{
- return semihosting_trap(SEMIHOSTING_SYS_WRITE0, (void *)str);
-}
-EXPORT_SYMBOL(semihosting_write0);
-
-struct __packed semihosting_file_io {
- uint32_t fd;
- uint32_t memp;
- uint32_t len;
-};
-
-ssize_t semihosting_write(int fd, const void *buf, size_t count)
-{
- struct semihosting_file_io write = {
- .fd = fd,
- .memp = (uint32_t)buf,
- .len = count,
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_WRITE, &write);
-}
-EXPORT_SYMBOL(semihosting_write);
-
-ssize_t semihosting_read(int fd, void *buf, size_t count)
-{
- struct semihosting_file_io read = {
- .fd = fd,
- .memp = (uint32_t)buf,
- .len = count,
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_READ, &read);
-}
-EXPORT_SYMBOL(semihosting_read);
-
-int semihosting_readc(void)
-{
- return semihosting_trap(SEMIHOSTING_SYS_READC, NULL);
-}
-EXPORT_SYMBOL(semihosting_readc);
-
-int semihosting_isatty(int fd)
-{
- return semihosting_trap(SEMIHOSTING_SYS_ISATTY, &fd);
-}
-EXPORT_SYMBOL(semihosting_isatty);
-
-int semihosting_seek(int fd, off_t pos)
-{
- struct __packed {
- uint32_t fd;
- uint32_t pos;
- } seek = {
- .fd = fd,
- .pos = pos,
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_SEEK, &seek);
-}
-EXPORT_SYMBOL(semihosting_seek);
-
-int semihosting_flen(int fd)
-{
- return semihosting_trap(SEMIHOSTING_SYS_FLEN, &fd);
-}
-EXPORT_SYMBOL(semihosting_flen);
-
-int semihosting_remove(const char *fname)
-{
- struct __packed {
- uint32_t fname;
- uint32_t fname_length;
- } remove = {
- .fname = (uint32_t)fname,
- .fname_length = strlen(fname),
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_REMOVE, &remove);
-}
-EXPORT_SYMBOL(semihosting_remove);
-
-int semihosting_rename(const char *fname1, const char *fname2)
-{
- struct __packed {
- uint32_t fname1;
- uint32_t fname1_length;
- uint32_t fname2;
- uint32_t fname2_length;
- } rename = {
- .fname1 = (uint32_t)fname1,
- .fname1_length = strlen(fname1),
- .fname2 = (uint32_t)fname2,
- .fname2_length = strlen(fname2),
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_RENAME, &rename);
-}
-EXPORT_SYMBOL(semihosting_rename);
-
-int semihosting_errno(void)
-{
- return semihosting_trap(SEMIHOSTING_SYS_ERRNO, NULL);
-}
-EXPORT_SYMBOL(semihosting_errno);
-
-
-int semihosting_system(const char *command)
-{
- struct __packed {
- uint32_t cmd;
- uint32_t cmd_len;
- } system = {
- .cmd = (uint32_t)command,
- .cmd_len = strlen(command),
- };
-
- return semihosting_trap(SEMIHOSTING_SYS_SYSTEM, &system);
-}
-EXPORT_SYMBOL(semihosting_system);
diff --git a/arch/arm/lib/unwind.c b/arch/arm/lib/unwind.c
deleted file mode 100644
index c3dca5b..0000000
--- a/arch/arm/lib/unwind.c
+++ /dev/null
@@ -1,349 +0,0 @@
-#include <common.h>
-#include <init.h>
-#include <asm/stacktrace.h>
-#include <asm/unwind.h>
-#include <asm/sections.h>
-
-/* Dummy functions to avoid linker complaints */
-void __aeabi_unwind_cpp_pr0(void)
-{
-};
-EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
-
-void __aeabi_unwind_cpp_pr1(void)
-{
-};
-EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
-
-void __aeabi_unwind_cpp_pr2(void)
-{
-};
-EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
-
-struct unwind_ctrl_block {
- unsigned long vrs[16]; /* virtual register set */
- unsigned long *insn; /* pointer to the current instructions word */
- int entries; /* number of entries left to interpret */
- int byte; /* current byte number in the instructions word */
-};
-
-enum regs {
- FP = 11,
- SP = 13,
- LR = 14,
- PC = 15
-};
-
-#define THREAD_SIZE 8192
-
-extern struct unwind_idx __start_unwind_idx[];
-extern struct unwind_idx __stop_unwind_idx[];
-
-/* Convert a prel31 symbol to an absolute address */
-#define prel31_to_addr(ptr) \
-({ \
- /* sign-extend to 32 bits */ \
- long offset = (((long)*(ptr)) << 1) >> 1; \
- (unsigned long)(ptr) + offset; \
-})
-
-static inline int is_kernel_text(unsigned long addr)
-{
- if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext))
- return 1;
- return 0;
-}
-
-void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
-{
-#ifdef CONFIG_KALLSYMS
- printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
-#else
- printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
-#endif
-}
-
-/*
- * Binary search in the unwind index. The entries entries are
- * guaranteed to be sorted in ascending order by the linker.
- */
-static struct unwind_idx *search_index(unsigned long addr,
- struct unwind_idx *first,
- struct unwind_idx *last)
-{
- pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
-
- if (addr < first->addr) {
- pr_warning("unwind: Unknown symbol address %08lx\n", addr);
- return NULL;
- } else if (addr >= last->addr)
- return last;
-
- while (first < last - 1) {
- struct unwind_idx *mid = first + ((last - first + 1) >> 1);
-
- if (addr < mid->addr)
- last = mid;
- else
- first = mid;
- }
-
- return first;
-}
-
-static struct unwind_idx *unwind_find_idx(unsigned long addr)
-{
- struct unwind_idx *idx = NULL;
-
- pr_debug("%s(%08lx)\n", __func__, addr);
-
- if (is_kernel_text(addr))
- /* main unwind table */
- idx = search_index(addr, __start_unwind_idx,
- __stop_unwind_idx - 1);
- else {
- /* module unwinding not supported */
- }
-
- pr_debug("%s: idx = %p\n", __func__, idx);
- return idx;
-}
-
-static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
-{
- unsigned long ret;
-
- if (ctrl->entries <= 0) {
- pr_warning("unwind: Corrupt unwind table\n");
- return 0;
- }
-
- ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
-
- if (ctrl->byte == 0) {
- ctrl->insn++;
- ctrl->entries--;
- ctrl->byte = 3;
- } else
- ctrl->byte--;
-
- return ret;
-}
-
-/*
- * Execute the current unwind instruction.
- */
-static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
-{
- unsigned long insn = unwind_get_byte(ctrl);
-
- pr_debug("%s: insn = %08lx\n", __func__, insn);
-
- if ((insn & 0xc0) == 0x00)
- ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xc0) == 0x40)
- ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
- else if ((insn & 0xf0) == 0x80) {
- unsigned long mask;
- unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
- int load_sp, reg = 4;
-
- insn = (insn << 8) | unwind_get_byte(ctrl);
- mask = insn & 0x0fff;
- if (mask == 0) {
- pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
- insn);
- return -URC_FAILURE;
- }
-
- /* pop R4-R15 according to mask */
- load_sp = mask & (1 << (13 - 4));
- while (mask) {
- if (mask & 1)
- ctrl->vrs[reg] = *vsp++;
- mask >>= 1;
- reg++;
- }
- if (!load_sp)
- ctrl->vrs[SP] = (unsigned long)vsp;
- } else if ((insn & 0xf0) == 0x90 &&
- (insn & 0x0d) != 0x0d)
- ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
- else if ((insn & 0xf0) == 0xa0) {
- unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
- int reg;
-
- /* pop R4-R[4+bbb] */
- for (reg = 4; reg <= 4 + (insn & 7); reg++)
- ctrl->vrs[reg] = *vsp++;
- if (insn & 0x80)
- ctrl->vrs[14] = *vsp++;
- ctrl->vrs[SP] = (unsigned long)vsp;
- } else if (insn == 0xb0) {
- if (ctrl->vrs[PC] == 0)
- ctrl->vrs[PC] = ctrl->vrs[LR];
- /* no further processing */
- ctrl->entries = 0;
- } else if (insn == 0xb1) {
- unsigned long mask = unwind_get_byte(ctrl);
- unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
- int reg = 0;
-
- if (mask == 0 || mask & 0xf0) {
- pr_warning("unwind: Spare encoding %04lx\n",
- (insn << 8) | mask);
- return -URC_FAILURE;
- }
-
- /* pop R0-R3 according to mask */
- while (mask) {
- if (mask & 1)
- ctrl->vrs[reg] = *vsp++;
- mask >>= 1;
- reg++;
- }
- ctrl->vrs[SP] = (unsigned long)vsp;
- } else if (insn == 0xb2) {
- unsigned long uleb128 = unwind_get_byte(ctrl);
-
- ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
- } else {
- pr_warning("unwind: Unhandled instruction %02lx\n", insn);
- return -URC_FAILURE;
- }
-
- pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
- ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
-
- return URC_OK;
-}
-
-/*
- * Unwind a single frame starting with *sp for the symbol at *pc. It
- * updates the *pc and *sp with the new values.
- */
-int unwind_frame(struct stackframe *frame)
-{
- unsigned long high, low;
- struct unwind_idx *idx;
- struct unwind_ctrl_block ctrl;
-
- /* only go to a higher address on the stack */
- low = frame->sp;
- high = ALIGN(low, THREAD_SIZE);
-
- pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
- frame->pc, frame->lr, frame->sp);
-
- if (!is_kernel_text(frame->pc))
- return -URC_FAILURE;
-
- idx = unwind_find_idx(frame->pc);
- if (!idx) {
- pr_warning("unwind: Index not found %08lx\n", frame->pc);
- return -URC_FAILURE;
- }
-
- ctrl.vrs[FP] = frame->fp;
- ctrl.vrs[SP] = frame->sp;
- ctrl.vrs[LR] = frame->lr;
- ctrl.vrs[PC] = 0;
-
- if (idx->insn == 1)
- /* can't unwind */
- return -URC_FAILURE;
- else if ((idx->insn & 0x80000000) == 0)
- /* prel31 to the unwind table */
- ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
- else if ((idx->insn & 0xff000000) == 0x80000000)
- /* only personality routine 0 supported in the index */
- ctrl.insn = &idx->insn;
- else {
- pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
- idx->insn, idx);
- return -URC_FAILURE;
- }
-
- /* check the personality routine */
- if ((*ctrl.insn & 0xff000000) == 0x80000000) {
- ctrl.byte = 2;
- ctrl.entries = 1;
- } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
- ctrl.byte = 1;
- ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
- } else {
- pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
- *ctrl.insn, ctrl.insn);
- return -URC_FAILURE;
- }
-
- while (ctrl.entries > 0) {
- int urc = unwind_exec_insn(&ctrl);
- if (urc < 0)
- return urc;
- if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
- return -URC_FAILURE;
- }
-
- if (ctrl.vrs[PC] == 0)
- ctrl.vrs[PC] = ctrl.vrs[LR];
-
- /* check for infinite loop */
- if (frame->pc == ctrl.vrs[PC])
- return -URC_FAILURE;
-
- frame->fp = ctrl.vrs[FP];
- frame->sp = ctrl.vrs[SP];
- frame->lr = ctrl.vrs[LR];
- frame->pc = ctrl.vrs[PC];
-
- return URC_OK;
-}
-
-void unwind_backtrace(struct pt_regs *regs)
-{
- struct stackframe frame;
- register unsigned long current_sp asm ("sp");
-
- pr_debug("%s\n", __func__);
-
- if (regs) {
- frame.fp = regs->ARM_fp;
- frame.sp = regs->ARM_sp;
- frame.lr = regs->ARM_lr;
- /* PC might be corrupted, use LR in that case. */
- frame.pc = is_kernel_text(regs->ARM_pc)
- ? regs->ARM_pc : regs->ARM_lr;
- } else {
- frame.sp = current_sp;
- frame.lr = (unsigned long)__builtin_return_address(0);
- frame.pc = (unsigned long)unwind_backtrace;
- }
-
- while (1) {
- int urc;
- unsigned long where = frame.pc;
-
- urc = unwind_frame(&frame);
- if (urc < 0)
- break;
- dump_backtrace_entry(where, frame.pc, frame.sp - 4);
- }
-}
-
-void dump_stack(void)
-{
- unwind_backtrace(NULL);
-}
-
-static int unwind_init(void)
-{
- struct unwind_idx *idx;
-
- /* Convert the symbol addresses to absolute values */
- for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
- idx->addr = prel31_to_addr(&idx->addr);
-
- return 0;
-}
-core_initcall(unwind_init);
diff --git a/arch/arm/lib32/.gitignore b/arch/arm/lib32/.gitignore
new file mode 100644
index 0000000..d116578
--- /dev/null
+++ b/arch/arm/lib32/.gitignore
@@ -0,0 +1 @@
+barebox.lds
diff --git a/arch/arm/lib32/Makefile b/arch/arm/lib32/Makefile
new file mode 100644
index 0000000..cdd0732
--- /dev/null
+++ b/arch/arm/lib32/Makefile
@@ -0,0 +1,27 @@
+obj-$(CONFIG_ARM_LINUX) += armlinux.o
+obj-$(CONFIG_CMD_BOOTZ) += bootz.o
+obj-y += div0.o
+obj-y += findbit.o
+obj-y += io.o
+obj-y += io-readsb.o
+obj-y += io-readsw-armv4.o
+obj-y += io-readsl.o
+obj-y += io-writesb.o
+obj-y += io-writesw-armv4.o
+obj-y += io-writesl.o
+obj-y += lib1funcs.o
+obj-y += ashrdi3.o
+obj-y += ashldi3.o
+obj-y += lshrdi3.o
+obj-y += runtime-offset.o
+pbl-y += runtime-offset.o
+obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memcpy.o
+obj-$(CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS) += memset.o
+obj-$(CONFIG_ARM_UNWIND) += unwind.o
+obj-$(CONFIG_ARM_SEMIHOSTING) += semihosting-trap.o semihosting.o
+obj-$(CONFIG_MODULES) += module.o
+extra-y += barebox.lds
+
+pbl-y += lib1funcs.o
+pbl-y += ashldi3.o
+pbl-y += div0.o
diff --git a/arch/arm/lib32/armlinux.c b/arch/arm/lib32/armlinux.c
new file mode 100644
index 0000000..47b9bd3
--- /dev/null
+++ b/arch/arm/lib32/armlinux.c
@@ -0,0 +1,281 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 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 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 <boot.h>
+#include <common.h>
+#include <command.h>
+#include <driver.h>
+#include <environment.h>
+#include <image.h>
+#include <init.h>
+#include <fs.h>
+#include <linux/list.h>
+#include <xfuncs.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <memory.h>
+#include <of.h>
+#include <magicvar.h>
+
+#include <asm/byteorder.h>
+#include <asm/setup.h>
+#include <asm/barebox-arm.h>
+#include <asm/armlinux.h>
+#include <asm/system.h>
+
+static struct tag *params;
+static void *armlinux_bootparams = NULL;
+
+static int armlinux_architecture;
+static u32 armlinux_system_rev;
+static u64 armlinux_system_serial;
+
+BAREBOX_MAGICVAR(armlinux_architecture, "ARM machine ID");
+BAREBOX_MAGICVAR(armlinux_system_rev, "ARM system revision");
+BAREBOX_MAGICVAR(armlinux_system_serial, "ARM system serial");
+
+void armlinux_set_architecture(int architecture)
+{
+ export_env_ull("armlinux_architecture", architecture);
+ armlinux_architecture = architecture;
+}
+
+int armlinux_get_architecture(void)
+{
+ getenv_uint("armlinux_architecture", &armlinux_architecture);
+
+ return armlinux_architecture;
+}
+
+void armlinux_set_revision(unsigned int rev)
+{
+ export_env_ull("armlinux_system_rev", rev);
+ armlinux_system_rev = rev;
+}
+
+unsigned int armlinux_get_revision(void)
+{
+ getenv_uint("armlinux_system_rev", &armlinux_system_rev);
+
+ return armlinux_system_rev;
+}
+
+void armlinux_set_serial(u64 serial)
+{
+ export_env_ull("armlinux_system_serial", serial);
+ armlinux_system_serial = serial;
+}
+
+u64 armlinux_get_serial(void)
+{
+ getenv_ull("armlinux_system_serial", &armlinux_system_serial);
+
+ return armlinux_system_serial;
+}
+
+void armlinux_set_bootparams(void *params)
+{
+ armlinux_bootparams = params;
+}
+
+static struct tag *armlinux_get_bootparams(void)
+{
+ struct memory_bank *mem;
+
+ if (armlinux_bootparams)
+ return armlinux_bootparams;
+
+ for_each_memory_bank(mem)
+ return (void *)mem->start + 0x100;
+
+ BUG();
+}
+
+#ifdef CONFIG_ARM_BOARD_APPEND_ATAG
+static struct tag *(*atag_appender)(struct tag *);
+void armlinux_set_atag_appender(struct tag *(*func)(struct tag *))
+{
+ atag_appender = func;
+}
+#endif
+
+static void setup_start_tag(void)
+{
+ params = armlinux_get_bootparams();
+
+ params->hdr.tag = ATAG_CORE;
+ params->hdr.size = tag_size(tag_core);
+
+ params->u.core.flags = 0;
+ params->u.core.pagesize = 0;
+ params->u.core.rootdev = 0;
+
+ params = tag_next(params);
+}
+
+static void setup_memory_tags(void)
+{
+ struct memory_bank *bank;
+
+ for_each_memory_bank(bank) {
+ params->hdr.tag = ATAG_MEM;
+ params->hdr.size = tag_size(tag_mem32);
+
+ params->u.mem.start = bank->start;
+ params->u.mem.size = bank->size;
+
+ params = tag_next(params);
+ }
+}
+
+static void setup_commandline_tag(const char *commandline, int swap)
+{
+ const char *p;
+ size_t words;
+
+ if (!commandline)
+ return;
+
+ /* eat leading white space */
+ for (p = commandline; *p == ' '; p++) ;
+
+ /*
+ * skip non-existent command lines so the kernel will still
+ * use its default command line.
+ */
+ if (*p == '\0')
+ return;
+
+ words = (strlen(p) + 1 /* NUL */ + 3 /* round up */) >> 2;
+ params->hdr.tag = ATAG_CMDLINE;
+ params->hdr.size = (sizeof(struct tag_header) >> 2) + words;
+
+ strcpy(params->u.cmdline.cmdline, p);
+
+#ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
+ if (swap) {
+ u32 *cmd = (u32 *)params->u.cmdline.cmdline;
+ while (words--)
+ cmd[words] = swab32(cmd[words]);
+ }
+#endif
+
+ params = tag_next(params);
+}
+
+static void setup_revision_tag(void)
+{
+ u32 system_rev = armlinux_get_revision();
+
+ if (system_rev) {
+ params->hdr.tag = ATAG_REVISION;
+ params->hdr.size = tag_size(tag_revision);
+
+ params->u.revision.rev = system_rev;
+
+ params = tag_next(params);
+ }
+}
+
+static void setup_serial_tag(void)
+{
+ u64 system_serial = armlinux_get_serial();
+
+ if (system_serial) {
+ params->hdr.tag = ATAG_SERIAL;
+ params->hdr.size = tag_size(tag_serialnr);
+
+ params->u.serialnr.low = system_serial & 0xffffffff;
+ params->u.serialnr.high = system_serial >> 32;
+
+ params = tag_next(params);
+ }
+}
+
+static void setup_initrd_tag(unsigned long start, unsigned long size)
+{
+ /* an ATAG_INITRD node tells the kernel where the compressed
+ * ramdisk can be found. ATAG_RDIMG is a better name, actually.
+ */
+ params->hdr.tag = ATAG_INITRD2;
+ params->hdr.size = tag_size(tag_initrd);
+
+ params->u.initrd.start = start;
+ params->u.initrd.size = size;
+
+ params = tag_next(params);
+}
+
+static void setup_end_tag (void)
+{
+ params->hdr.tag = ATAG_NONE;
+ params->hdr.size = 0;
+}
+
+static void setup_tags(unsigned long initrd_address,
+ unsigned long initrd_size, int swap)
+{
+ const char *commandline = linux_bootargs_get();
+
+ setup_start_tag();
+ setup_memory_tags();
+ setup_commandline_tag(commandline, swap);
+
+ if (initrd_size)
+ setup_initrd_tag(initrd_address, initrd_size);
+
+ setup_revision_tag();
+ setup_serial_tag();
+#ifdef CONFIG_ARM_BOARD_APPEND_ATAG
+ if (atag_appender != NULL)
+ params = atag_appender(params);
+#endif
+ setup_end_tag();
+
+ printf("commandline: %s\n"
+ "arch_number: %d\n", commandline, armlinux_get_architecture());
+
+}
+
+void start_linux(void *adr, int swap, unsigned long initrd_address,
+ unsigned long initrd_size, void *oftree)
+{
+ void (*kernel)(int zero, int arch, void *params) = adr;
+ void *params = NULL;
+ int architecture;
+
+ if (oftree) {
+ pr_debug("booting kernel with devicetree\n");
+ params = oftree;
+ } else {
+ setup_tags(initrd_address, initrd_size, swap);
+ params = armlinux_get_bootparams();
+ }
+ architecture = armlinux_get_architecture();
+
+ shutdown_barebox();
+ if (swap) {
+ u32 reg;
+ __asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));
+ reg ^= CR_B; /* swap big-endian flag */
+ __asm__ __volatile__("mcr p15, 0, %0, c1, c0" :: "r" (reg));
+ }
+
+ kernel(0, architecture, params);
+}
diff --git a/arch/arm/lib32/ashldi3.S b/arch/arm/lib32/ashldi3.S
new file mode 100644
index 0000000..b62e06f
--- /dev/null
+++ b/arch/arm/lib32/ashldi3.S
@@ -0,0 +1,50 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+*/
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.section .text.__ashldi3
+ENTRY(__ashldi3)
+ENTRY(__aeabi_llsl)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi ah, ah, lsl r2
+ movpl ah, al, lsl r3
+ ARM( orrmi ah, ah, al, lsr ip )
+ THUMB( lsrmi r3, al, ip )
+ THUMB( orrmi ah, ah, r3 )
+ mov al, al, lsl r2
+ mov pc, lr
+
+ENDPROC(__ashldi3)
+ENDPROC(__aeabi_llsl)
diff --git a/arch/arm/lib32/ashrdi3.S b/arch/arm/lib32/ashrdi3.S
new file mode 100644
index 0000000..db849b6
--- /dev/null
+++ b/arch/arm/lib32/ashrdi3.S
@@ -0,0 +1,50 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+*/
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.section .text.__ashrdi3
+ENTRY(__ashrdi3)
+ENTRY(__aeabi_lasr)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, asr r3
+ ARM( orrmi al, al, ah, lsl ip )
+ THUMB( lslmi r3, ah, ip )
+ THUMB( orrmi al, al, r3 )
+ mov ah, ah, asr r2
+ mov pc, lr
+
+ENDPROC(__ashrdi3)
+ENDPROC(__aeabi_lasr)
diff --git a/arch/arm/lib32/barebox.lds.S b/arch/arm/lib32/barebox.lds.S
new file mode 100644
index 0000000..6dc8bd2
--- /dev/null
+++ b/arch/arm/lib32/barebox.lds.S
@@ -0,0 +1,126 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 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 <asm-generic/barebox.lds.h>
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(start)
+SECTIONS
+{
+#ifdef CONFIG_RELOCATABLE
+ . = 0x0;
+#else
+ . = TEXT_BASE;
+#endif
+
+#ifndef CONFIG_PBL_IMAGE
+ PRE_IMAGE
+#endif
+ . = ALIGN(4);
+ .text :
+ {
+ _stext = .;
+ _text = .;
+ *(.text_entry*)
+ __bare_init_start = .;
+ *(.text_bare_init*)
+ __bare_init_end = .;
+ . = ALIGN(4);
+ __exceptions_start = .;
+ KEEP(*(.text_exceptions*))
+ __exceptions_stop = .;
+ *(.text*)
+ }
+ BAREBOX_BARE_INIT_SIZE
+
+ . = 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 = .;
+
+ . = ALIGN(4);
+ .data : { *(.data*) }
+
+ .barebox_imd : { BAREBOX_IMD }
+
+ . = .;
+ __barebox_cmd_start = .;
+ .barebox_cmd : { BAREBOX_CMDS }
+ __barebox_cmd_end = .;
+
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
+ __barebox_initcalls_start = .;
+ .barebox_initcalls : { INITCALLS }
+ __barebox_initcalls_end = .;
+
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
+ __usymtab_start = .;
+ __usymtab : { BAREBOX_SYMS }
+ __usymtab_end = .;
+
+ .oftables : { BAREBOX_CLK_TABLE() }
+
+ .dtb : { BAREBOX_DTB() }
+
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .dynsym : {
+ __dynsym_start = .;
+ *(.dynsym)
+ __dynsym_end = .;
+ }
+
+ _edata = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss*) }
+ __bss_stop = .;
+ _end = .;
+ _barebox_image_size = __bss_start - TEXT_BASE;
+}
diff --git a/arch/arm/lib32/bootz.c b/arch/arm/lib32/bootz.c
new file mode 100644
index 0000000..5167c9d
--- /dev/null
+++ b/arch/arm/lib32/bootz.c
@@ -0,0 +1,136 @@
+#include <common.h>
+#include <command.h>
+#include <fs.h>
+#include <of.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <malloc.h>
+#include <linux/sizes.h>
+#include <asm/byteorder.h>
+#include <asm/armlinux.h>
+#include <asm/system.h>
+#include <asm-generic/memory_layout.h>
+#include <memory.h>
+
+struct zimage_header {
+ u32 unused[9];
+ u32 magic;
+ u32 start;
+ u32 end;
+};
+
+#define ZIMAGE_MAGIC 0x016F2818
+
+static int do_bootz(int argc, char *argv[])
+{
+ int fd, ret, swap = 0;
+ struct zimage_header __header, *header;
+ void *zimage;
+ void *oftree = NULL;
+ u32 end;
+ int usemap = 0;
+ struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list);
+ struct resource *res = NULL;
+
+ if (argc != 2)
+ return COMMAND_ERROR_USAGE;
+
+ fd = open(argv[1], O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ /*
+ * We can save the memcpy of the zImage if it already is in
+ * the first 128MB of SDRAM.
+ */
+ zimage = memmap(fd, PROT_READ);
+ if (zimage && (unsigned long)zimage >= bank->start &&
+ (unsigned long)zimage < bank->start + SZ_128M) {
+ usemap = 1;
+ header = zimage;
+ }
+
+ if (!usemap) {
+ header = &__header;
+ ret = read(fd, header, sizeof(*header));
+ if (ret < sizeof(*header)) {
+ printf("could not read %s\n", argv[1]);
+ goto err_out;
+ }
+ }
+
+ switch (header->magic) {
+#ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
+ case swab32(ZIMAGE_MAGIC):
+ swap = 1;
+ /* fall through */
+#endif
+ case ZIMAGE_MAGIC:
+ break;
+ default:
+ printf("invalid magic 0x%08x\n", header->magic);
+ goto err_out;
+ }
+
+ end = header->end;
+
+ if (swap)
+ end = swab32(end);
+
+ if (!usemap) {
+ if (bank->size <= SZ_128M) {
+ zimage = xmalloc(end);
+ } else {
+ zimage = (void *)bank->start + SZ_8M;
+ res = request_sdram_region("zimage",
+ bank->start + SZ_8M, end);
+ if (!res) {
+ printf("can't request region for kernel\n");
+ goto err_out1;
+ }
+ }
+
+ memcpy(zimage, header, sizeof(*header));
+
+ ret = read(fd, zimage + sizeof(*header), end - sizeof(*header));
+ if (ret < end - sizeof(*header)) {
+ printf("could not read %s\n", argv[1]);
+ goto err_out2;
+ }
+ }
+
+ if (swap) {
+ void *ptr;
+ for (ptr = zimage; ptr < zimage + end; ptr += 4)
+ *(u32 *)ptr = swab32(*(u32 *)ptr);
+ }
+
+ printf("loaded zImage from %s with size %d\n", argv[1], end);
+#ifdef CONFIG_OFTREE
+ oftree = of_get_fixed_tree(NULL);
+#endif
+
+ start_linux(zimage, swap, 0, 0, oftree);
+
+ return 0;
+
+err_out2:
+ if (res)
+ release_sdram_region(res);
+err_out1:
+ free(zimage);
+err_out:
+ close(fd);
+
+ return 1;
+}
+
+BAREBOX_CMD_START(bootz)
+ .cmd = do_bootz,
+ BAREBOX_CMD_DESC("boot Linux zImage")
+ BAREBOX_CMD_OPTS("FILE")
+ BAREBOX_CMD_GROUP(CMD_GRP_BOOT)
+BAREBOX_CMD_END
+
diff --git a/arch/arm/lib32/copy_template.S b/arch/arm/lib32/copy_template.S
new file mode 100644
index 0000000..d8eb063
--- /dev/null
+++ b/arch/arm/lib32/copy_template.S
@@ -0,0 +1,268 @@
+/*
+ * linux/arch/arm/lib/copy_template.s
+ *
+ * Code template for optimized memory copy functions
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+/*
+ * Theory of operation
+ * -------------------
+ *
+ * This file provides the core code for a forward memory copy used in
+ * the implementation of memcopy(), copy_to_user() and copy_from_user().
+ *
+ * The including file must define the following accessor macros
+ * according to the need of the given function:
+ *
+ * ldr1w ptr reg abort
+ *
+ * This loads one word from 'ptr', stores it in 'reg' and increments
+ * 'ptr' to the next word. The 'abort' argument is used for fixup tables.
+ *
+ * ldr4w ptr reg1 reg2 reg3 reg4 abort
+ * ldr8w ptr, reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ *
+ * This loads four or eight words starting from 'ptr', stores them
+ * in provided registers and increments 'ptr' past those words.
+ * The'abort' argument is used for fixup tables.
+ *
+ * ldr1b ptr reg cond abort
+ *
+ * Similar to ldr1w, but it loads a byte and increments 'ptr' one byte.
+ * It also must apply the condition code if provided, otherwise the
+ * "al" condition is assumed by default.
+ *
+ * str1w ptr reg abort
+ * str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ * str1b ptr reg cond abort
+ *
+ * Same as their ldr* counterparts, but data is stored to 'ptr' location
+ * rather than being loaded.
+ *
+ * enter reg1 reg2
+ *
+ * Preserve the provided registers on the stack plus any additional
+ * data as needed by the implementation including this code. Called
+ * upon code entry.
+ *
+ * exit reg1 reg2
+ *
+ * Restore registers with the values previously saved with the
+ * 'preserv' macro. Called upon code termination.
+ *
+ * LDR1W_SHIFT
+ * STR1W_SHIFT
+ *
+ * Correction to be applied to the "ip" register when branching into
+ * the ldr1w or str1w instructions (some of these macros may expand to
+ * than one 32bit instruction in Thumb-2)
+ */
+
+
+ enter r4, lr
+
+ subs r2, r2, #4
+ blt 8f
+ ands ip, r0, #3
+ PLD( pld [r1, #0] )
+ bne 9f
+ ands ip, r1, #3
+ bne 10f
+
+1: subs r2, r2, #(28)
+ stmfd sp!, {r5 - r8}
+ blt 5f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb r3, ip, #32 )
+ CALGN( sbcnes r4, r3, r2 ) @ C is always set here
+ CALGN( bcs 2f )
+ CALGN( adr r4, 6f )
+ CALGN( subs r2, r2, r3 ) @ C gets set
+ CALGN( add pc, r4, ip )
+
+ PLD( pld [r1, #0] )
+2: PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 4f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+3: PLD( pld [r1, #124] )
+4: ldr8w r1, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ subs r2, r2, #32
+ str8w r0, r3, r4, r5, r6, r7, r8, ip, lr, abort=20f
+ bge 3b
+ PLD( cmn r2, #96 )
+ PLD( bge 4b )
+
+5: ands ip, r2, #28
+ rsb ip, ip, #32
+#if LDR1W_SHIFT > 0
+ lsl ip, ip, #LDR1W_SHIFT
+#endif
+ addne pc, pc, ip @ C is always clear here
+ b 7f
+6:
+ .rept (1 << LDR1W_SHIFT)
+ W(nop)
+ .endr
+ ldr1w r1, r3, abort=20f
+ ldr1w r1, r4, abort=20f
+ ldr1w r1, r5, abort=20f
+ ldr1w r1, r6, abort=20f
+ ldr1w r1, r7, abort=20f
+ ldr1w r1, r8, abort=20f
+ ldr1w r1, lr, abort=20f
+
+#if LDR1W_SHIFT < STR1W_SHIFT
+ lsl ip, ip, #STR1W_SHIFT - LDR1W_SHIFT
+#elif LDR1W_SHIFT > STR1W_SHIFT
+ lsr ip, ip, #LDR1W_SHIFT - STR1W_SHIFT
+#endif
+ add pc, pc, ip
+ nop
+ .rept (1 << STR1W_SHIFT)
+ W(nop)
+ .endr
+ str1w r0, r3, abort=20f
+ str1w r0, r4, abort=20f
+ str1w r0, r5, abort=20f
+ str1w r0, r6, abort=20f
+ str1w r0, r7, abort=20f
+ str1w r0, r8, abort=20f
+ str1w r0, lr, abort=20f
+
+ CALGN( bcs 2b )
+
+7: ldmfd sp!, {r5 - r8}
+
+8: movs r2, r2, lsl #31
+ ldr1b r1, r3, ne, abort=21f
+ ldr1b r1, r4, cs, abort=21f
+ ldr1b r1, ip, cs, abort=21f
+ str1b r0, r3, ne, abort=21f
+ str1b r0, r4, cs, abort=21f
+ str1b r0, ip, cs, abort=21f
+
+ exit r4, pc
+
+9: rsb ip, ip, #4
+ cmp ip, #2
+ ldr1b r1, r3, gt, abort=21f
+ ldr1b r1, r4, ge, abort=21f
+ ldr1b r1, lr, abort=21f
+ str1b r0, r3, gt, abort=21f
+ str1b r0, r4, ge, abort=21f
+ subs r2, r2, ip
+ str1b r0, lr, abort=21f
+ blt 8b
+ ands ip, r1, #3
+ beq 1b
+
+10: bic r1, r1, #3
+ cmp ip, #2
+ ldr1w r1, lr, abort=21f
+ beq 17f
+ bgt 18f
+
+
+ .macro forward_copy_shift pull push
+
+ subs r2, r2, #28
+ blt 14f
+
+ CALGN( ands ip, r0, #31 )
+ CALGN( rsb ip, ip, #32 )
+ CALGN( sbcnes r4, ip, r2 ) @ C is always set here
+ CALGN( subcc r2, r2, ip )
+ CALGN( bcc 15f )
+
+11: stmfd sp!, {r5 - r9}
+
+ PLD( pld [r1, #0] )
+ PLD( subs r2, r2, #96 )
+ PLD( pld [r1, #28] )
+ PLD( blt 13f )
+ PLD( pld [r1, #60] )
+ PLD( pld [r1, #92] )
+
+12: PLD( pld [r1, #124] )
+13: ldr4w r1, r4, r5, r6, r7, abort=19f
+ mov r3, lr, pull #\pull
+ subs r2, r2, #32
+ ldr4w r1, r8, r9, ip, lr, abort=19f
+ orr r3, r3, r4, push #\push
+ mov r4, r4, pull #\pull
+ orr r4, r4, r5, push #\push
+ mov r5, r5, pull #\pull
+ orr r5, r5, r6, push #\push
+ mov r6, r6, pull #\pull
+ orr r6, r6, r7, push #\push
+ mov r7, r7, pull #\pull
+ orr r7, r7, r8, push #\push
+ mov r8, r8, pull #\pull
+ orr r8, r8, r9, push #\push
+ mov r9, r9, pull #\pull
+ orr r9, r9, ip, push #\push
+ mov ip, ip, pull #\pull
+ orr ip, ip, lr, push #\push
+ str8w r0, r3, r4, r5, r6, r7, r8, r9, ip, , abort=19f
+ bge 12b
+ PLD( cmn r2, #96 )
+ PLD( bge 13b )
+
+ ldmfd sp!, {r5 - r9}
+
+14: ands ip, r2, #28
+ beq 16f
+
+15: mov r3, lr, pull #\pull
+ ldr1w r1, lr, abort=21f
+ subs ip, ip, #4
+ orr r3, r3, lr, push #\push
+ str1w r0, r3, abort=21f
+ bgt 15b
+ CALGN( cmp r2, #0 )
+ CALGN( bge 11b )
+
+16: sub r1, r1, #(\push / 8)
+ b 8b
+
+ .endm
+
+
+ forward_copy_shift pull=8 push=24
+
+17: forward_copy_shift pull=16 push=16
+
+18: forward_copy_shift pull=24 push=8
+
+
+/*
+ * Abort preamble and completion macros.
+ * If a fixup handler is required then those macros must surround it.
+ * It is assumed that the fixup code will handle the private part of
+ * the exit macro.
+ */
+
+ .macro copy_abort_preamble
+19: ldmfd sp!, {r5 - r9}
+ b 21f
+20: ldmfd sp!, {r5 - r8}
+21:
+ .endm
+
+ .macro copy_abort_end
+ ldmfd sp!, {r4, pc}
+ .endm
+
+
diff --git a/arch/arm/lib32/div0.c b/arch/arm/lib32/div0.c
new file mode 100644
index 0000000..852cb72
--- /dev/null
+++ b/arch/arm/lib32/div0.c
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 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 <common.h>
+
+extern void __div0(void);
+
+/* Replacement (=dummy) for GNU/Linux division-by zero handler */
+void __div0 (void)
+{
+ panic("division by zero\n");
+}
diff --git a/arch/arm/lib32/findbit.S b/arch/arm/lib32/findbit.S
new file mode 100644
index 0000000..ef4caff
--- /dev/null
+++ b/arch/arm/lib32/findbit.S
@@ -0,0 +1,197 @@
+/*
+ * Originally from Linux kernel
+ * arch/arm/lib/findbit.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ *
+ * 16th March 2001 - John Ripley <jripley@sonicblue.com>
+ * Fixed so that "size" is an exclusive not an inclusive quantity.
+ * All users of these functions expect exclusive sizes, and may
+ * also call with zero size.
+ * Reworked by rmk.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/*
+ * Purpose : Find a 'zero' bit
+ * Prototype: int find_first_zero_bit(void *addr, unsigned int maxbit);
+ */
+ENTRY(_find_first_zero_bit_le)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1:
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_zero_bit_le)
+
+/*
+ * Purpose : Find next 'zero' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(_find_next_zero_bit_le)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_zero_bit_le)
+
+/*
+ * Purpose : Find a 'one' bit
+ * Prototype: int find_first_bit(const unsigned long *addr, unsigned int maxbit);
+ */
+ENTRY(_find_first_bit_le)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1:
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_bit_le)
+
+/*
+ * Purpose : Find next 'one' bit
+ * Prototype: int find_next_zero_bit(void *addr, unsigned int maxbit, int offset)
+ */
+ENTRY(_find_next_bit_le)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ ARM( ldrb r3, [r0, r2, lsr #3] )
+ THUMB( lsr r3, r2, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_bit_le)
+
+#ifdef __ARMEB__
+
+ENTRY(_find_first_zero_bit_be)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eors r3, r3, #0xff @ invert bits
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_zero_bit_be)
+
+ENTRY(_find_next_zero_bit_be)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ eor r3, r3, #0xff @ now looking for a 1 bit
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_zero_bit_be)
+
+ENTRY(_find_first_bit_be)
+ teq r1, #0
+ beq 3f
+ mov r2, #0
+1: eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3
+ bne .L_found @ any now set - found zero bit
+ add r2, r2, #8 @ next bit pointer
+2: cmp r2, r1 @ any more?
+ blo 1b
+3: mov r0, r1 @ no free bits
+ mov pc, lr
+ENDPROC(_find_first_bit_be)
+
+ENTRY(_find_next_bit_be)
+ teq r1, #0
+ beq 3b
+ ands ip, r2, #7
+ beq 1b @ If new byte, goto old routine
+ eor r3, r2, #0x18 @ big endian byte ordering
+ ARM( ldrb r3, [r0, r3, lsr #3] )
+ THUMB( lsr r3, #3 )
+ THUMB( ldrb r3, [r0, r3] )
+ movs r3, r3, lsr ip @ shift off unused bits
+ bne .L_found
+ orr r2, r2, #7 @ if zero, then no bits here
+ add r2, r2, #1 @ align bit pointer
+ b 2b @ loop for next bit
+ENDPROC(_find_next_bit_be)
+
+#endif
+
+/*
+ * One or more bits in the LSB of r3 are assumed to be set.
+ */
+.L_found:
+#if __LINUX_ARM_ARCH__ >= 5
+ rsb r0, r3, #0
+ and r3, r3, r0
+ clz r3, r3
+ rsb r3, r3, #31
+ add r0, r2, r3
+#else
+ tst r3, #0x0f
+ addeq r2, r2, #4
+ movne r3, r3, lsl #4
+ tst r3, #0x30
+ addeq r2, r2, #2
+ movne r3, r3, lsl #2
+ tst r3, #0x40
+ addeq r2, r2, #1
+ mov r0, r2
+#endif
+ cmp r1, r0 @ Clamp to maxbit
+ movlo r0, r1
+ mov pc, lr
+
diff --git a/arch/arm/lib32/io-readsb.S b/arch/arm/lib32/io-readsb.S
new file mode 100644
index 0000000..963c455
--- /dev/null
+++ b/arch/arm/lib32/io-readsb.S
@@ -0,0 +1,125 @@
+/*
+ * linux/arch/arm/lib/io-readsb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.section .text.readsb
+
+.Linsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1], #1
+ subs r2, r2, ip
+ bne .Linsb_aligned
+
+ENTRY(readsb)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne .Linsb_align
+
+.Linsb_aligned: stmfd sp!, {r4 - r6, lr}
+
+ subs r2, r2, #16
+ bmi .Linsb_no_16
+
+.Linsb_16_lp: ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3, put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4, put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ ldrb r5, [r0]
+ orr r4, r4, r6, put_byte_2
+ ldrb r6, [r0]
+ orr r4, r4, ip, put_byte_3
+ ldrb ip, [r0]
+ mov r5, r5, put_byte_0
+ ldrb lr, [r0]
+ orr r5, r5, r6, put_byte_1
+ ldrb r6, [r0]
+ orr r5, r5, ip, put_byte_2
+ ldrb ip, [r0]
+ orr r5, r5, lr, put_byte_3
+ ldrb lr, [r0]
+ mov r6, r6, put_byte_0
+ orr r6, r6, ip, put_byte_1
+ ldrb ip, [r0]
+ orr r6, r6, lr, put_byte_2
+ orr r6, r6, ip, put_byte_3
+ stmia r1!, {r3 - r6}
+
+ subs r2, r2, #16
+ bpl .Linsb_16_lp
+
+ tst r2, #15
+ ldmeqfd sp!, {r4 - r6, pc}
+
+.Linsb_no_16: tst r2, #8
+ beq .Linsb_no_8
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ mov r3, r3, put_byte_0
+ ldrb r6, [r0]
+ orr r3, r3, r4, put_byte_1
+ ldrb r4, [r0]
+ orr r3, r3, r5, put_byte_2
+ ldrb r5, [r0]
+ orr r3, r3, r6, put_byte_3
+ ldrb r6, [r0]
+ mov r4, r4, put_byte_0
+ ldrb ip, [r0]
+ orr r4, r4, r5, put_byte_1
+ orr r4, r4, r6, put_byte_2
+ orr r4, r4, ip, put_byte_3
+ stmia r1!, {r3, r4}
+
+.Linsb_no_8: tst r2, #4
+ beq .Linsb_no_4
+
+ ldrb r3, [r0]
+ ldrb r4, [r0]
+ ldrb r5, [r0]
+ ldrb r6, [r0]
+ mov r3, r3, put_byte_0
+ orr r3, r3, r4, put_byte_1
+ orr r3, r3, r5, put_byte_2
+ orr r3, r3, r6, put_byte_3
+ str r3, [r1], #4
+
+.Linsb_no_4: ands r2, r2, #3
+ ldmeqfd sp!, {r4 - r6, pc}
+
+ cmp r2, #2
+ ldrb r3, [r0]
+ strb r3, [r1], #1
+ ldrgeb r3, [r0]
+ strgeb r3, [r1], #1
+ ldrgtb r3, [r0]
+ strgtb r3, [r1]
+
+ ldmfd sp!, {r4 - r6, pc}
+ENDPROC(readsb)
diff --git a/arch/arm/lib32/io-readsl.S b/arch/arm/lib32/io-readsl.S
new file mode 100644
index 0000000..47a2974
--- /dev/null
+++ b/arch/arm/lib32/io-readsl.S
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/arm/lib/io-readsl.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.section .text.readsl
+
+ENTRY(readsl)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne 3f
+
+ subs r2, r2, #4
+ bmi 2f
+ stmfd sp!, {r4, lr}
+1: ldr r3, [r0, #0]
+ ldr r4, [r0, #0]
+ ldr ip, [r0, #0]
+ ldr lr, [r0, #0]
+ subs r2, r2, #4
+ stmia r1!, {r3, r4, ip, lr}
+ bpl 1b
+ ldmfd sp!, {r4, lr}
+2: movs r2, r2, lsl #31
+ ldrcs r3, [r0, #0]
+ ldrcs ip, [r0, #0]
+ stmcsia r1!, {r3, ip}
+ ldrne r3, [r0, #0]
+ strne r3, [r1, #0]
+ mov pc, lr
+
+3: ldr r3, [r0]
+ cmp ip, #2
+ mov ip, r3, get_byte_0
+ strb ip, [r1], #1
+ bgt 6f
+ mov ip, r3, get_byte_1
+ strb ip, [r1], #1
+ beq 5f
+ mov ip, r3, get_byte_2
+ strb ip, [r1], #1
+
+4: subs r2, r2, #1
+ mov ip, r3, pull #24
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #8
+ strne ip, [r1], #4
+ bne 4b
+ b 8f
+
+5: subs r2, r2, #1
+ mov ip, r3, pull #16
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #16
+ strne ip, [r1], #4
+ bne 5b
+ b 7f
+
+6: subs r2, r2, #1
+ mov ip, r3, pull #8
+ ldrne r3, [r0]
+ orrne ip, ip, r3, push #24
+ strne ip, [r1], #4
+ bne 6b
+
+ mov r3, ip, get_byte_2
+ strb r3, [r1, #2]
+7: mov r3, ip, get_byte_1
+ strb r3, [r1, #1]
+8: mov r3, ip, get_byte_0
+ strb r3, [r1, #0]
+ mov pc, lr
+ENDPROC(readsl)
diff --git a/arch/arm/lib32/io-readsw-armv4.S b/arch/arm/lib32/io-readsw-armv4.S
new file mode 100644
index 0000000..f5b34a3
--- /dev/null
+++ b/arch/arm/lib32/io-readsw-armv4.S
@@ -0,0 +1,133 @@
+/*
+ * linux/arch/arm/lib/io-readsw-armv4.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .macro pack, rd, hw1, hw2
+#ifndef __ARMEB__
+ orr \rd, \hw1, \hw2, lsl #16
+#else
+ orr \rd, \hw2, \hw1, lsl #16
+#endif
+ .endm
+
+.section .text.readsw
+
+.Linsw_align: movs ip, r1, lsl #31
+ bne .Linsw_noalign
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ strh ip, [r1], #2
+
+ENTRY(readsw)
+ teq r2, #0
+ moveq pc, lr
+ tst r1, #3
+ bne .Linsw_align
+
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_insw_8
+
+.Linsw_8_lp: ldrh r3, [r0]
+ ldrh r4, [r0]
+ pack r3, r3, r4
+
+ ldrh r4, [r0]
+ ldrh r5, [r0]
+ pack r4, r4, r5
+
+ ldrh r5, [r0]
+ ldrh ip, [r0]
+ pack r5, r5, ip
+
+ ldrh ip, [r0]
+ ldrh lr, [r0]
+ pack ip, ip, lr
+
+ subs r2, r2, #8
+ stmia r1!, {r3 - r5, ip}
+ bpl .Linsw_8_lp
+
+.Lno_insw_8: tst r2, #4
+ beq .Lno_insw_4
+
+ ldrh r3, [r0]
+ ldrh r4, [r0]
+ pack r3, r3, r4
+
+ ldrh r4, [r0]
+ ldrh ip, [r0]
+ pack r4, r4, ip
+
+ stmia r1!, {r3, r4}
+
+.Lno_insw_4: movs r2, r2, lsl #31
+ bcc .Lno_insw_2
+
+ ldrh r3, [r0]
+ ldrh ip, [r0]
+ pack r3, r3, ip
+ str r3, [r1], #4
+
+.Lno_insw_2: ldrneh r3, [r0]
+ strneh r3, [r1]
+
+ ldmfd sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define _BE_ONLY_(code...) code
+#define _LE_ONLY_(code...)
+#define push_hbyte0 lsr #8
+#define pull_hbyte1 lsl #24
+#else
+#define _BE_ONLY_(code...)
+#define _LE_ONLY_(code...) code
+#define push_hbyte0 lsl #24
+#define pull_hbyte1 lsr #8
+#endif
+
+.Linsw_noalign: stmfd sp!, {r4, lr}
+ ldrccb ip, [r1, #-1]!
+ bcc 1f
+
+ ldrh ip, [r0]
+ sub r2, r2, #1
+ _BE_ONLY_( mov ip, ip, ror #8 )
+ strb ip, [r1], #1
+ _LE_ONLY_( mov ip, ip, lsr #8 )
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+1: subs r2, r2, #2
+ bmi 3f
+ _BE_ONLY_( mov ip, ip, lsl #24 )
+
+2: ldrh r3, [r0]
+ ldrh r4, [r0]
+ subs r2, r2, #2
+ orr ip, ip, r3, lsl #8
+ orr ip, ip, r4, push_hbyte0
+ str ip, [r1], #4
+ mov ip, r4, pull_hbyte1
+ bpl 2b
+
+ _BE_ONLY_( mov ip, ip, lsr #24 )
+
+3: tst r2, #1
+ strb ip, [r1], #1
+ ldrneh ip, [r0]
+ _BE_ONLY_( movne ip, ip, ror #8 )
+ strneb ip, [r1], #1
+ _LE_ONLY_( movne ip, ip, lsr #8 )
+ _BE_ONLY_( movne ip, ip, lsr #24 )
+ strneb ip, [r1]
+ ldmfd sp!, {r4, pc}
+ENDPROC(readsw)
diff --git a/arch/arm/lib32/io-writesb.S b/arch/arm/lib32/io-writesb.S
new file mode 100644
index 0000000..1ab8e47
--- /dev/null
+++ b/arch/arm/lib32/io-writesb.S
@@ -0,0 +1,96 @@
+/*
+ * linux/arch/arm/lib/io-writesb.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .macro outword, rd
+#ifndef __ARMEB__
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+ mov \rd, \rd, lsr #8
+ strb \rd, [r0]
+#else
+ mov lr, \rd, lsr #24
+ strb lr, [r0]
+ mov lr, \rd, lsr #16
+ strb lr, [r0]
+ mov lr, \rd, lsr #8
+ strb lr, [r0]
+ strb \rd, [r0]
+#endif
+ .endm
+
+.section .text.writesb
+
+.Loutsb_align: rsb ip, ip, #4
+ cmp ip, r2
+ movgt ip, r2
+ cmp ip, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1], #1
+ strgtb r3, [r0]
+ subs r2, r2, ip
+ bne .Loutsb_aligned
+
+ENTRY(writesb)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne .Loutsb_align
+
+.Loutsb_aligned:
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #16
+ bmi .Loutsb_no_16
+
+.Loutsb_16_lp: ldmia r1!, {r3, r4, r5, ip}
+ outword r3
+ outword r4
+ outword r5
+ outword ip
+ subs r2, r2, #16
+ bpl .Loutsb_16_lp
+
+ tst r2, #15
+ ldmeqfd sp!, {r4, r5, pc}
+
+.Loutsb_no_16: tst r2, #8
+ beq .Loutsb_no_8
+
+ ldmia r1!, {r3, r4}
+ outword r3
+ outword r4
+
+.Loutsb_no_8: tst r2, #4
+ beq .Loutsb_no_4
+
+ ldr r3, [r1], #4
+ outword r3
+
+.Loutsb_no_4: ands r2, r2, #3
+ ldmeqfd sp!, {r4, r5, pc}
+
+ cmp r2, #2
+ ldrb r3, [r1], #1
+ strb r3, [r0]
+ ldrgeb r3, [r1], #1
+ strgeb r3, [r0]
+ ldrgtb r3, [r1]
+ strgtb r3, [r0]
+
+ ldmfd sp!, {r4, r5, pc}
+ENDPROC(writesb)
diff --git a/arch/arm/lib32/io-writesl.S b/arch/arm/lib32/io-writesl.S
new file mode 100644
index 0000000..8a3bcd6
--- /dev/null
+++ b/arch/arm/lib32/io-writesl.S
@@ -0,0 +1,69 @@
+/*
+ * linux/arch/arm/lib/io-writesl.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.section .text.writesl
+
+ENTRY(writesl)
+ teq r2, #0 @ do we have to check for the zero len?
+ moveq pc, lr
+ ands ip, r1, #3
+ bne 3f
+
+ subs r2, r2, #4
+ bmi 2f
+ stmfd sp!, {r4, lr}
+1: ldmia r1!, {r3, r4, ip, lr}
+ subs r2, r2, #4
+ str r3, [r0, #0]
+ str r4, [r0, #0]
+ str ip, [r0, #0]
+ str lr, [r0, #0]
+ bpl 1b
+ ldmfd sp!, {r4, lr}
+2: movs r2, r2, lsl #31
+ ldmcsia r1!, {r3, ip}
+ strcs r3, [r0, #0]
+ ldrne r3, [r1, #0]
+ strcs ip, [r0, #0]
+ strne r3, [r0, #0]
+ mov pc, lr
+
+3: bic r1, r1, #3
+ ldr r3, [r1], #4
+ cmp ip, #2
+ blt 5f
+ bgt 6f
+
+4: mov ip, r3, pull #16
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #16
+ str ip, [r0]
+ bne 4b
+ mov pc, lr
+
+5: mov ip, r3, pull #8
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #24
+ str ip, [r0]
+ bne 5b
+ mov pc, lr
+
+6: mov ip, r3, pull #24
+ ldr r3, [r1], #4
+ subs r2, r2, #1
+ orr ip, ip, r3, push #8
+ str ip, [r0]
+ bne 6b
+ mov pc, lr
+ENDPROC(writesl)
diff --git a/arch/arm/lib32/io-writesw-armv4.S b/arch/arm/lib32/io-writesw-armv4.S
new file mode 100644
index 0000000..9e8308d
--- /dev/null
+++ b/arch/arm/lib32/io-writesw-armv4.S
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/arm/lib/io-writesw-armv4.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .macro outword, rd
+#ifndef __ARMEB__
+ strh \rd, [r0]
+ mov \rd, \rd, lsr #16
+ strh \rd, [r0]
+#else
+ mov lr, \rd, lsr #16
+ strh lr, [r0]
+ strh \rd, [r0]
+#endif
+ .endm
+
+.section .text.__raw_writesw
+
+.Loutsw_align: movs ip, r1, lsl #31
+ bne .Loutsw_noalign
+
+ ldrh r3, [r1], #2
+ sub r2, r2, #1
+ strh r3, [r0]
+
+ENTRY(__raw_writesw)
+ teq r2, #0
+ moveq pc, lr
+ ands r3, r1, #3
+ bne .Loutsw_align
+
+ stmfd sp!, {r4, r5, lr}
+
+ subs r2, r2, #8
+ bmi .Lno_outsw_8
+
+.Loutsw_8_lp: ldmia r1!, {r3, r4, r5, ip}
+ subs r2, r2, #8
+ outword r3
+ outword r4
+ outword r5
+ outword ip
+ bpl .Loutsw_8_lp
+
+.Lno_outsw_8: tst r2, #4
+ beq .Lno_outsw_4
+
+ ldmia r1!, {r3, ip}
+ outword r3
+ outword ip
+
+.Lno_outsw_4: movs r2, r2, lsl #31
+ bcc .Lno_outsw_2
+
+ ldr r3, [r1], #4
+ outword r3
+
+.Lno_outsw_2: ldrneh r3, [r1]
+ strneh r3, [r0]
+
+ ldmfd sp!, {r4, r5, pc}
+
+#ifdef __ARMEB__
+#define pull_hbyte0 lsl #8
+#define push_hbyte1 lsr #24
+#else
+#define pull_hbyte0 lsr #24
+#define push_hbyte1 lsl #8
+#endif
+
+.Loutsw_noalign:
+ ARM( ldr r3, [r1, -r3]! )
+ THUMB( rsb r3, r3, #0 )
+ THUMB( ldr r3, [r1, r3] )
+ THUMB( sub r1, r3 )
+ subcs r2, r2, #1
+ bcs 2f
+ subs r2, r2, #2
+ bmi 3f
+
+1: mov ip, r3, lsr #8
+ strh ip, [r0]
+2: mov ip, r3, pull_hbyte0
+ ldr r3, [r1, #4]!
+ subs r2, r2, #2
+ orr ip, ip, r3, push_hbyte1
+ strh ip, [r0]
+ bpl 1b
+
+ tst r2, #1
+3: movne ip, r3, lsr #8
+ strneh ip, [r0]
+ mov pc, lr
+ENDPROC(__raw_writesw)
diff --git a/arch/arm/lib32/io.c b/arch/arm/lib32/io.c
new file mode 100644
index 0000000..abfd887
--- /dev/null
+++ b/arch/arm/lib32/io.c
@@ -0,0 +1,50 @@
+#include <module.h>
+#include <linux/types.h>
+#include <io.h>
+
+/*
+ * Copy data from IO memory space to "real" memory space.
+ * This needs to be optimized.
+ */
+void memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)
+{
+ unsigned char *t = to;
+ while (count) {
+ count--;
+ *t = readb(from);
+ t++;
+ from++;
+ }
+}
+
+/*
+ * Copy data from "real" memory space to IO memory space.
+ * This needs to be optimized.
+ */
+void memcpy_toio(volatile void __iomem *to, const void *from, size_t count)
+{
+ const unsigned char *f = from;
+ while (count) {
+ count--;
+ writeb(*f, to);
+ f++;
+ to++;
+ }
+}
+
+/*
+ * "memset" on IO memory space.
+ * This needs to be optimized.
+ */
+void memset_io(volatile void __iomem *dst, int c, size_t count)
+{
+ while (count) {
+ count--;
+ writeb(c, dst);
+ dst++;
+ }
+}
+
+EXPORT_SYMBOL(memcpy_fromio);
+EXPORT_SYMBOL(memcpy_toio);
+EXPORT_SYMBOL(memset_io);
diff --git a/arch/arm/lib32/lib1funcs.S b/arch/arm/lib32/lib1funcs.S
new file mode 100644
index 0000000..bf1d019
--- /dev/null
+++ b/arch/arm/lib32/lib1funcs.S
@@ -0,0 +1,351 @@
+/*
+ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines
+ *
+ * Author: Nicolas Pitre <nico@fluxnic.net>
+ * - contributed to gcc-3.4 on Sep 30, 2003
+ * - adapted for the Linux kernel on Oct 2, 2003
+ */
+
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+*/
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+
+.macro ARM_DIV_BODY dividend, divisor, result, curbit
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \curbit, \divisor
+ clz \result, \dividend
+ sub \result, \curbit, \result
+ mov \curbit, #1
+ mov \divisor, \divisor, lsl \result
+ mov \curbit, \curbit, lsl \result
+ mov \result, #0
+
+#else
+
+ @ Initially shift the divisor left 3 bits if possible,
+ @ set curbit accordingly. This allows for curbit to be located
+ @ at the left end of each 4 bit nibbles in the division loop
+ @ to save one loop in most cases.
+ tst \divisor, #0xe0000000
+ moveq \divisor, \divisor, lsl #3
+ moveq \curbit, #8
+ movne \curbit, #1
+
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ movlo \curbit, \curbit, lsl #4
+ blo 1b
+
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ movlo \curbit, \curbit, lsl #1
+ blo 1b
+
+ mov \result, #0
+
+#endif
+
+ @ Division loop
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ orrhs \result, \result, \curbit
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ orrhs \result, \result, \curbit, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ orrhs \result, \result, \curbit, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ orrhs \result, \result, \curbit, lsr #3
+ cmp \dividend, #0 @ Early termination?
+ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
+ movne \divisor, \divisor, lsr #4
+ bne 1b
+
+.endm
+
+
+.macro ARM_DIV2_ORDER divisor, order
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ rsb \order, \order, #31
+
+#else
+
+ cmp \divisor, #(1 << 16)
+ movhs \divisor, \divisor, lsr #16
+ movhs \order, #16
+ movlo \order, #0
+
+ cmp \divisor, #(1 << 8)
+ movhs \divisor, \divisor, lsr #8
+ addhs \order, \order, #8
+
+ cmp \divisor, #(1 << 4)
+ movhs \divisor, \divisor, lsr #4
+ addhs \order, \order, #4
+
+ cmp \divisor, #(1 << 2)
+ addhi \order, \order, #3
+ addls \order, \order, \divisor, lsr #1
+
+#endif
+
+.endm
+
+
+.macro ARM_MOD_BODY dividend, divisor, order, spare
+
+#if __LINUX_ARM_ARCH__ >= 5
+
+ clz \order, \divisor
+ clz \spare, \dividend
+ sub \order, \order, \spare
+ mov \divisor, \divisor, lsl \order
+
+#else
+
+ mov \order, #0
+
+ @ Unless the divisor is very big, shift it up in multiples of
+ @ four bits, since this is the amount of unwinding in the main
+ @ division loop. Continue shifting until the divisor is
+ @ larger than the dividend.
+1: cmp \divisor, #0x10000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #4
+ addlo \order, \order, #4
+ blo 1b
+
+ @ For very big divisors, we must shift it a bit at a time, or
+ @ we will be in danger of overflowing.
+1: cmp \divisor, #0x80000000
+ cmplo \divisor, \dividend
+ movlo \divisor, \divisor, lsl #1
+ addlo \order, \order, #1
+ blo 1b
+
+#endif
+
+ @ Perform all needed substractions to keep only the reminder.
+ @ Do comparisons in batch of 4 first.
+ subs \order, \order, #3 @ yes, 3 is intended here
+ blt 2f
+
+1: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ cmp \dividend, \divisor, lsr #1
+ subhs \dividend, \dividend, \divisor, lsr #1
+ cmp \dividend, \divisor, lsr #2
+ subhs \dividend, \dividend, \divisor, lsr #2
+ cmp \dividend, \divisor, lsr #3
+ subhs \dividend, \dividend, \divisor, lsr #3
+ cmp \dividend, #1
+ mov \divisor, \divisor, lsr #4
+ subges \order, \order, #4
+ bge 1b
+
+ tst \order, #3
+ teqne \dividend, #0
+ beq 5f
+
+ @ Either 1, 2 or 3 comparison/substractions are left.
+2: cmn \order, #2
+ blt 4f
+ beq 3f
+ cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+3: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+ mov \divisor, \divisor, lsr #1
+4: cmp \dividend, \divisor
+ subhs \dividend, \dividend, \divisor
+5:
+.endm
+
+
+.section .text.__udivsi3
+ENTRY(__udivsi3)
+ENTRY(__aeabi_uidiv)
+
+ subs r2, r1, #1
+ moveq pc, lr
+ bcc Ldiv0
+ cmp r0, r1
+ bls 11f
+ tst r1, r2
+ beq 12f
+
+ ARM_DIV_BODY r0, r1, r2, r3
+
+ mov r0, r2
+ mov pc, lr
+
+11: moveq r0, #1
+ movne r0, #0
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ mov r0, r0, lsr r2
+ mov pc, lr
+
+ENDPROC(__udivsi3)
+ENDPROC(__aeabi_uidiv)
+
+.section .text.__umodsi3
+ENTRY(__umodsi3)
+
+ subs r2, r1, #1 @ compare divisor with 1
+ bcc Ldiv0
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ movls pc, lr
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+ mov pc, lr
+
+ENDPROC(__umodsi3)
+
+.section .text.__divsi3
+ENTRY(__divsi3)
+ENTRY(__aeabi_idiv)
+
+ cmp r1, #0
+ eor ip, r0, r1 @ save the sign of the result.
+ beq Ldiv0
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ subs r2, r1, #1 @ division by 1 or -1 ?
+ beq 10f
+ movs r3, r0
+ rsbmi r3, r0, #0 @ positive dividend value
+ cmp r3, r1
+ bls 11f
+ tst r1, r2 @ divisor is power of 2 ?
+ beq 12f
+
+ ARM_DIV_BODY r3, r1, r0, r2
+
+ cmp ip, #0
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+10: teq ip, r0 @ same sign ?
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+11: movlo r0, #0
+ moveq r0, ip, asr #31
+ orreq r0, r0, #1
+ mov pc, lr
+
+12: ARM_DIV2_ORDER r1, r2
+
+ cmp ip, #0
+ mov r0, r3, lsr r2
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+ENDPROC(__divsi3)
+ENDPROC(__aeabi_idiv)
+
+.section .text.__modsi3
+ENTRY(__modsi3)
+
+ cmp r1, #0
+ beq Ldiv0
+ rsbmi r1, r1, #0 @ loops below use unsigned.
+ movs ip, r0 @ preserve sign of dividend
+ rsbmi r0, r0, #0 @ if negative make positive
+ subs r2, r1, #1 @ compare divisor with 1
+ cmpne r0, r1 @ compare dividend with divisor
+ moveq r0, #0
+ tsthi r1, r2 @ see if divisor is power of 2
+ andeq r0, r0, r2
+ bls 10f
+
+ ARM_MOD_BODY r0, r1, r2, r3
+
+10: cmp ip, #0
+ rsbmi r0, r0, #0
+ mov pc, lr
+
+ENDPROC(__modsi3)
+
+#ifdef CONFIG_AEABI
+
+.section .text.__aeabi_uidivmod
+ENTRY(__aeabi_uidivmod)
+
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_uidiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+ENDPROC(__aeabi_uidivmod)
+
+.section .text.__aeabi_idivmod
+ENTRY(__aeabi_idivmod)
+
+ stmfd sp!, {r0, r1, ip, lr}
+ bl __aeabi_idiv
+ ldmfd sp!, {r1, r2, ip, lr}
+ mul r3, r0, r2
+ sub r1, r1, r3
+ mov pc, lr
+
+ENDPROC(__aeabi_idivmod)
+
+#endif
+
+.section .text.Ldiv0
+Ldiv0:
+
+ str lr, [sp, #-8]!
+ bl __div0
+ mov r0, #0 @ About as wrong as it could be.
+ ldr pc, [sp], #8
+
+
diff --git a/arch/arm/lib32/lshrdi3.S b/arch/arm/lib32/lshrdi3.S
new file mode 100644
index 0000000..e77e96c
--- /dev/null
+++ b/arch/arm/lib32/lshrdi3.S
@@ -0,0 +1,50 @@
+/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005
+ Free Software Foundation, Inc.
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+This file is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+*/
+
+#include <linux/linkage.h>
+
+#ifdef __ARMEB__
+#define al r1
+#define ah r0
+#else
+#define al r0
+#define ah r1
+#endif
+
+.section .text.__lshrdi3
+ENTRY(__lshrdi3)
+ENTRY(__aeabi_llsr)
+
+ subs r3, r2, #32
+ rsb ip, r2, #32
+ movmi al, al, lsr r2
+ movpl al, ah, lsr r3
+ ARM( orrmi al, al, ah, lsl ip )
+ THUMB( lslmi r3, ah, ip )
+ THUMB( orrmi al, al, r3 )
+ mov ah, ah, lsr r2
+ mov pc, lr
+
+ENDPROC(__lshrdi3)
+ENDPROC(__aeabi_llsr)
diff --git a/arch/arm/lib32/memcpy.S b/arch/arm/lib32/memcpy.S
new file mode 100644
index 0000000..5123691
--- /dev/null
+++ b/arch/arm/lib32/memcpy.S
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/lib/memcpy.S
+ *
+ * Author: Nicolas Pitre
+ * Created: Sep 28, 2005
+ * Copyright: MontaVista Software, Inc.
+ *
+ * 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.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+#define LDR1W_SHIFT 0
+#define STR1W_SHIFT 0
+
+ .macro ldr1w ptr reg abort
+ W(ldr) \reg, [\ptr], #4
+ .endm
+
+ .macro ldr4w ptr reg1 reg2 reg3 reg4 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4}
+ .endm
+
+ .macro ldr8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ ldmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro ldr1b ptr reg cond=al abort
+ ldr\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro str1w ptr reg abort
+ W(str) \reg, [\ptr], #4
+ .endm
+
+ .macro str8w ptr reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 abort
+ stmia \ptr!, {\reg1, \reg2, \reg3, \reg4, \reg5, \reg6, \reg7, \reg8}
+ .endm
+
+ .macro str1b ptr reg cond=al abort
+ str\cond\()b \reg, [\ptr], #1
+ .endm
+
+ .macro enter reg1 reg2
+ stmdb sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .macro exit reg1 reg2
+ ldmfd sp!, {r0, \reg1, \reg2}
+ .endm
+
+ .text
+
+/* Prototype: void *memcpy(void *dest, const void *src, size_t n); */
+
+ENTRY(memcpy)
+
+#include "copy_template.S"
+
+ENDPROC(memcpy)
+
diff --git a/arch/arm/lib32/memset.S b/arch/arm/lib32/memset.S
new file mode 100644
index 0000000..c4d2672
--- /dev/null
+++ b/arch/arm/lib32/memset.S
@@ -0,0 +1,124 @@
+/*
+ * linux/arch/arm/lib/memset.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * 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.
+ *
+ * ASM optimised string functions
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+ .align 5
+
+ENTRY(memset)
+ ands r3, r0, #3 @ 1 unaligned?
+ mov ip, r0 @ preserve r0 as return value
+ bne 6f @ 1
+/*
+ * we know that the pointer in ip is aligned to a word boundary.
+ */
+1: orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+
+#if ! CALGN(1)+0
+
+/*
+ * We need an 2 extra registers for this loop - use r8 and the LR
+ */
+ stmfd sp!, {r8, lr}
+ mov r8, r1
+ mov lr, r1
+
+2: subs r2, r2, #64
+ stmgeia ip!, {r1, r3, r8, lr} @ 64 bytes at a time.
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
+ stmgeia ip!, {r1, r3, r8, lr}
+ bgt 2b
+ ldmeqfd sp!, {r8, pc} @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia ip!, {r1, r3, r8, lr}
+ stmneia ip!, {r1, r3, r8, lr}
+ tst r2, #16
+ stmneia ip!, {r1, r3, r8, lr}
+ ldmfd sp!, {r8, lr}
+
+#else
+
+/*
+ * This version aligns the destination pointer in order to write
+ * whole cache lines at once.
+ */
+
+ stmfd sp!, {r4-r8, lr}
+ mov r4, r1
+ mov r5, r1
+ mov r6, r1
+ mov r7, r1
+ mov r8, r1
+ mov lr, r1
+
+ cmp r2, #96
+ tstgt ip, #31
+ ble 3f
+
+ and r8, ip, #31
+ rsb r8, r8, #32
+ sub r2, r2, r8
+ movs r8, r8, lsl #(32 - 4)
+ stmcsia ip!, {r4, r5, r6, r7}
+ stmmiia ip!, {r4, r5}
+ tst r8, #(1 << 30)
+ mov r8, r1
+ strne r1, [ip], #4
+
+3: subs r2, r2, #64
+ stmgeia ip!, {r1, r3-r8, lr}
+ stmgeia ip!, {r1, r3-r8, lr}
+ bgt 3b
+ ldmeqfd sp!, {r4-r8, pc}
+
+ tst r2, #32
+ stmneia ip!, {r1, r3-r8, lr}
+ tst r2, #16
+ stmneia ip!, {r4-r7}
+ ldmfd sp!, {r4-r8, lr}
+
+#endif
+
+4: tst r2, #8
+ stmneia ip!, {r1, r3}
+ tst r2, #4
+ strne r1, [ip], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [ip], #1
+ strneb r1, [ip], #1
+ tst r2, #1
+ strneb r1, [ip], #1
+ mov pc, lr
+
+6: subs r2, r2, #4 @ 1 do we have enough
+ blt 5b @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [ip], #1 @ 1
+ strleb r1, [ip], #1 @ 1
+ strb r1, [ip], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+ b 1b
+ENDPROC(memset)
+
diff --git a/arch/arm/lib32/module.c b/arch/arm/lib32/module.c
new file mode 100644
index 0000000..be7965d
--- /dev/null
+++ b/arch/arm/lib32/module.c
@@ -0,0 +1,98 @@
+/*
+ * linux/arch/arm/kernel/module.c
+ *
+ * Copyright (C) 2002 Russell King.
+ * Modified for nommu by Hyok S. Choi
+ *
+ * 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.
+ *
+ * Module allocation method suggested by Andi Kleen.
+ */
+
+//#include <asm/pgtable.h>
+#include <common.h>
+#include <elf.h>
+#include <module.h>
+#include <errno.h>
+
+int
+apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
+ unsigned int relindex, struct module *module)
+{
+ Elf32_Shdr *symsec = sechdrs + symindex;
+ Elf32_Shdr *relsec = sechdrs + relindex;
+ Elf32_Shdr *dstsec = sechdrs + relsec->sh_info;
+ Elf32_Rel *rel = (void *)relsec->sh_addr;
+ unsigned int i;
+
+ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rel); i++, rel++) {
+ unsigned long loc;
+ Elf32_Sym *sym;
+ s32 offset;
+
+ offset = ELF32_R_SYM(rel->r_info);
+ if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
+ printf("%s: bad relocation, section %u reloc %u\n",
+ module->name, relindex, i);
+ return -ENOEXEC;
+ }
+
+ sym = ((Elf32_Sym *)symsec->sh_addr) + offset;
+
+ if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
+ printf("%s: out of bounds relocation, "
+ "section %u reloc %u offset %d size %d\n",
+ module->name, relindex, i, rel->r_offset,
+ dstsec->sh_size);
+ return -ENOEXEC;
+ }
+
+ loc = dstsec->sh_addr + rel->r_offset;
+
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ case R_ARM_ABS32:
+ *(u32 *)loc += sym->st_value;
+ break;
+
+ case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
+ offset = (*(u32 *)loc & 0x00ffffff) << 2;
+ if (offset & 0x02000000)
+ offset -= 0x04000000;
+
+ offset += sym->st_value - loc;
+ if (offset & 3 ||
+ offset <= (s32)0xfe000000 ||
+ offset >= (s32)0x02000000) {
+ printf("%s: relocation out of range, section "
+ "%u reloc %u sym '%s'\n", module->name,
+ relindex, i, strtab + sym->st_name);
+ return -ENOEXEC;
+ }
+
+ offset >>= 2;
+
+ *(u32 *)loc &= 0xff000000;
+ *(u32 *)loc |= offset & 0x00ffffff;
+ break;
+
+ default:
+ printf("%s: unknown relocation: %u\n",
+ module->name, ELF32_R_TYPE(rel->r_info));
+ return -ENOEXEC;
+ }
+ }
+ return 0;
+}
+
+int
+apply_relocate_add(Elf32_Shdr *sechdrs, const char *strtab,
+ unsigned int symindex, unsigned int relsec, struct module *module)
+{
+ printf("module %s: ADD RELOCATION unsupported\n",
+ module->name);
+ return -ENOEXEC;
+}
diff --git a/arch/arm/lib32/pbl.lds.S b/arch/arm/lib32/pbl.lds.S
new file mode 100644
index 0000000..73baff0
--- /dev/null
+++ b/arch/arm/lib32/pbl.lds.S
@@ -0,0 +1,96 @@
+/*
+ * (C) Copyright 2012 Sascha Hauer <s.hauer@pengutronix.de>, 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 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 <linux/sizes.h>
+#include <asm-generic/barebox.lds.h>
+#include <asm-generic/memory_layout.h>
+
+#ifdef CONFIG_PBL_RELOCATABLE
+#define BASE 0x0
+#else
+#define BASE (TEXT_BASE - SZ_2M)
+#endif
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+SECTIONS
+{
+ . = BASE;
+
+ PRE_IMAGE
+
+ . = ALIGN(4);
+ .text :
+ {
+ _stext = .;
+ _text = .;
+ *(.text_head_entry*)
+ __bare_init_start = .;
+ *(.text_bare_init*)
+ __bare_init_end = .;
+ *(.text*)
+ }
+
+ /* Discard unwind if enable in barebox */
+ /DISCARD/ : { *(.ARM.ex*) }
+
+ BAREBOX_BARE_INIT_SIZE
+ BAREBOX_PBL_SIZE
+
+ . = ALIGN(4);
+ .rodata : { *(.rodata*) }
+
+ .barebox_imd : { BAREBOX_IMD }
+
+ _etext = .; /* End of text and rodata section */
+
+ . = ALIGN(4);
+ .data : { *(.data*) }
+
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .dynsym : {
+ __dynsym_start = .;
+ *(.dynsym)
+ __dynsym_end = .;
+ }
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss*) }
+ __bss_stop = .;
+ _end = .;
+
+ . = ALIGN(4);
+ __piggydata_start = .;
+ .piggydata : {
+ *(.piggydata)
+ }
+ __piggydata_end = .;
+
+ . = ALIGN(4);
+ .image_end : {
+ KEEP(*(.image_end))
+ }
+ __image_end = .;
+ _barebox_image_size = __image_end - BASE;
+ _barebox_pbl_size = __bss_start - BASE;
+}
diff --git a/arch/arm/lib32/runtime-offset.S b/arch/arm/lib32/runtime-offset.S
new file mode 100644
index 0000000..f10c4c8
--- /dev/null
+++ b/arch/arm/lib32/runtime-offset.S
@@ -0,0 +1,52 @@
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+.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 r0, 1b
+ ldr r1, linkadr
+ subs r0, r1, r0
+THUMB( subs 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 _barebox_image_size
+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/lib32/semihosting-trap.S b/arch/arm/lib32/semihosting-trap.S
new file mode 100644
index 0000000..9e40ebf
--- /dev/null
+++ b/arch/arm/lib32/semihosting-trap.S
@@ -0,0 +1,28 @@
+/*
+ * semihosting-trap.S -- Assembly code needed to make a semihosting call
+ *
+ * Copyright (c) 2015 Zodiac Inflight Innovations
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <linux/linkage.h>
+#include <asm/unified.h>
+
+.section .text.semihosting_trap
+ENTRY(semihosting_trap)
+ @ In supervisor mode SVC would clobber LR
+ push {lr}
+ ARM( svc #0x123456 )
+ THUMB( svc #0xAB )
+ pop {pc}
+ENDPROC(semihosting_trap)
diff --git a/arch/arm/lib32/semihosting.c b/arch/arm/lib32/semihosting.c
new file mode 100644
index 0000000..a735196
--- /dev/null
+++ b/arch/arm/lib32/semihosting.c
@@ -0,0 +1,227 @@
+/*
+ * semihosting.c -- ARM Semihoting API implementation
+ *
+ * Copyright (c) 2015 Zodiac Inflight Innovations
+ * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
+ *
+ * based on a smiliar code from U-Boot
+ * Copyright (c) 2014 Broadcom Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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 <common.h>
+#include <command.h>
+#include <fcntl.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+
+enum {
+ SEMIHOSTING_SYS_OPEN = 0x01,
+ SEMIHOSTING_SYS_CLOSE = 0x02,
+ SEMIHOSTING_SYS_WRITEC = 0x03,
+ SEMIHOSTING_SYS_WRITE0 = 0x04,
+ SEMIHOSTING_SYS_WRITE = 0x05,
+ SEMIHOSTING_SYS_READ = 0x06,
+ SEMIHOSTING_SYS_READC = 0x07,
+ /* SYS_ISERROR is not implemented */
+ SEMIHOSTING_SYS_ISATTY = 0x09,
+ SEMIHOSTING_SYS_SEEK = 0x0a,
+ SEMIHOSTING_SYS_FLEN = 0x0c,
+ SEMIHOSTING_SYS_REMOVE = 0x0e,
+ SEMIHOSTING_SYS_RENAME = 0x0f,
+ SEMIHOSTING_SYS_TIME = 0x11,
+ SEMIHOSTING_SYS_ERRNO = 0x13,
+ /* SYS_GET_CMDLINE is not implemented */
+ /* SYS_HEAPINFO is not implemented */
+ /* angel_SWIreason_ReportException is not implemented */
+ SEMIHOSTING_SYS_SYSTEM = 0x12,
+};
+
+uint32_t semihosting_trap(uint32_t sysnum, void *addr);
+
+static uint32_t semihosting_flags_to_mode(int flags)
+{
+ static const int semihosting_open_modeflags[12] = {
+ O_RDONLY,
+ O_RDONLY | O_BINARY,
+ O_RDWR,
+ O_RDWR | O_BINARY,
+ O_WRONLY | O_CREAT | O_TRUNC,
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
+ O_RDWR | O_CREAT | O_TRUNC,
+ O_RDWR | O_CREAT | O_TRUNC | O_BINARY,
+ O_WRONLY | O_CREAT | O_APPEND,
+ O_WRONLY | O_CREAT | O_APPEND | O_BINARY,
+ O_RDWR | O_CREAT | O_APPEND,
+ O_RDWR | O_CREAT | O_APPEND | O_BINARY
+ };
+
+ int i;
+ for (i = 0; i < ARRAY_SIZE(semihosting_open_modeflags); i++) {
+ if (semihosting_open_modeflags[i] == flags)
+ return i;
+ }
+
+ return 0;
+}
+
+int semihosting_open(const char *fname, int flags)
+{
+ struct __packed {
+ uint32_t fname;
+ uint32_t mode;
+ uint32_t len;
+ } open = {
+ .fname = (uint32_t)fname,
+ .len = strlen(fname),
+ .mode = semihosting_flags_to_mode(flags),
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_OPEN, &open);
+}
+EXPORT_SYMBOL(semihosting_open);
+
+int semihosting_close(int fd)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_CLOSE, &fd);
+}
+EXPORT_SYMBOL(semihosting_close);
+
+int semihosting_writec(char c)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_WRITEC, &c);
+}
+EXPORT_SYMBOL(semihosting_writec);
+
+int semihosting_write0(const char *str)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_WRITE0, (void *)str);
+}
+EXPORT_SYMBOL(semihosting_write0);
+
+struct __packed semihosting_file_io {
+ uint32_t fd;
+ uint32_t memp;
+ uint32_t len;
+};
+
+ssize_t semihosting_write(int fd, const void *buf, size_t count)
+{
+ struct semihosting_file_io write = {
+ .fd = fd,
+ .memp = (uint32_t)buf,
+ .len = count,
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_WRITE, &write);
+}
+EXPORT_SYMBOL(semihosting_write);
+
+ssize_t semihosting_read(int fd, void *buf, size_t count)
+{
+ struct semihosting_file_io read = {
+ .fd = fd,
+ .memp = (uint32_t)buf,
+ .len = count,
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_READ, &read);
+}
+EXPORT_SYMBOL(semihosting_read);
+
+int semihosting_readc(void)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_READC, NULL);
+}
+EXPORT_SYMBOL(semihosting_readc);
+
+int semihosting_isatty(int fd)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_ISATTY, &fd);
+}
+EXPORT_SYMBOL(semihosting_isatty);
+
+int semihosting_seek(int fd, off_t pos)
+{
+ struct __packed {
+ uint32_t fd;
+ uint32_t pos;
+ } seek = {
+ .fd = fd,
+ .pos = pos,
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_SEEK, &seek);
+}
+EXPORT_SYMBOL(semihosting_seek);
+
+int semihosting_flen(int fd)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_FLEN, &fd);
+}
+EXPORT_SYMBOL(semihosting_flen);
+
+int semihosting_remove(const char *fname)
+{
+ struct __packed {
+ uint32_t fname;
+ uint32_t fname_length;
+ } remove = {
+ .fname = (uint32_t)fname,
+ .fname_length = strlen(fname),
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_REMOVE, &remove);
+}
+EXPORT_SYMBOL(semihosting_remove);
+
+int semihosting_rename(const char *fname1, const char *fname2)
+{
+ struct __packed {
+ uint32_t fname1;
+ uint32_t fname1_length;
+ uint32_t fname2;
+ uint32_t fname2_length;
+ } rename = {
+ .fname1 = (uint32_t)fname1,
+ .fname1_length = strlen(fname1),
+ .fname2 = (uint32_t)fname2,
+ .fname2_length = strlen(fname2),
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_RENAME, &rename);
+}
+EXPORT_SYMBOL(semihosting_rename);
+
+int semihosting_errno(void)
+{
+ return semihosting_trap(SEMIHOSTING_SYS_ERRNO, NULL);
+}
+EXPORT_SYMBOL(semihosting_errno);
+
+
+int semihosting_system(const char *command)
+{
+ struct __packed {
+ uint32_t cmd;
+ uint32_t cmd_len;
+ } system = {
+ .cmd = (uint32_t)command,
+ .cmd_len = strlen(command),
+ };
+
+ return semihosting_trap(SEMIHOSTING_SYS_SYSTEM, &system);
+}
+EXPORT_SYMBOL(semihosting_system);
diff --git a/arch/arm/lib32/unwind.c b/arch/arm/lib32/unwind.c
new file mode 100644
index 0000000..c3dca5b
--- /dev/null
+++ b/arch/arm/lib32/unwind.c
@@ -0,0 +1,349 @@
+#include <common.h>
+#include <init.h>
+#include <asm/stacktrace.h>
+#include <asm/unwind.h>
+#include <asm/sections.h>
+
+/* Dummy functions to avoid linker complaints */
+void __aeabi_unwind_cpp_pr0(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr0);
+
+void __aeabi_unwind_cpp_pr1(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr1);
+
+void __aeabi_unwind_cpp_pr2(void)
+{
+};
+EXPORT_SYMBOL(__aeabi_unwind_cpp_pr2);
+
+struct unwind_ctrl_block {
+ unsigned long vrs[16]; /* virtual register set */
+ unsigned long *insn; /* pointer to the current instructions word */
+ int entries; /* number of entries left to interpret */
+ int byte; /* current byte number in the instructions word */
+};
+
+enum regs {
+ FP = 11,
+ SP = 13,
+ LR = 14,
+ PC = 15
+};
+
+#define THREAD_SIZE 8192
+
+extern struct unwind_idx __start_unwind_idx[];
+extern struct unwind_idx __stop_unwind_idx[];
+
+/* Convert a prel31 symbol to an absolute address */
+#define prel31_to_addr(ptr) \
+({ \
+ /* sign-extend to 32 bits */ \
+ long offset = (((long)*(ptr)) << 1) >> 1; \
+ (unsigned long)(ptr) + offset; \
+})
+
+static inline int is_kernel_text(unsigned long addr)
+{
+ if ((addr >= (unsigned long)_stext && addr <= (unsigned long)_etext))
+ return 1;
+ return 0;
+}
+
+void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
+{
+#ifdef CONFIG_KALLSYMS
+ printk("[<%08lx>] (%pS) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
+#else
+ printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
+#endif
+}
+
+/*
+ * Binary search in the unwind index. The entries entries are
+ * guaranteed to be sorted in ascending order by the linker.
+ */
+static struct unwind_idx *search_index(unsigned long addr,
+ struct unwind_idx *first,
+ struct unwind_idx *last)
+{
+ pr_debug("%s(%08lx, %p, %p)\n", __func__, addr, first, last);
+
+ if (addr < first->addr) {
+ pr_warning("unwind: Unknown symbol address %08lx\n", addr);
+ return NULL;
+ } else if (addr >= last->addr)
+ return last;
+
+ while (first < last - 1) {
+ struct unwind_idx *mid = first + ((last - first + 1) >> 1);
+
+ if (addr < mid->addr)
+ last = mid;
+ else
+ first = mid;
+ }
+
+ return first;
+}
+
+static struct unwind_idx *unwind_find_idx(unsigned long addr)
+{
+ struct unwind_idx *idx = NULL;
+
+ pr_debug("%s(%08lx)\n", __func__, addr);
+
+ if (is_kernel_text(addr))
+ /* main unwind table */
+ idx = search_index(addr, __start_unwind_idx,
+ __stop_unwind_idx - 1);
+ else {
+ /* module unwinding not supported */
+ }
+
+ pr_debug("%s: idx = %p\n", __func__, idx);
+ return idx;
+}
+
+static unsigned long unwind_get_byte(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long ret;
+
+ if (ctrl->entries <= 0) {
+ pr_warning("unwind: Corrupt unwind table\n");
+ return 0;
+ }
+
+ ret = (*ctrl->insn >> (ctrl->byte * 8)) & 0xff;
+
+ if (ctrl->byte == 0) {
+ ctrl->insn++;
+ ctrl->entries--;
+ ctrl->byte = 3;
+ } else
+ ctrl->byte--;
+
+ return ret;
+}
+
+/*
+ * Execute the current unwind instruction.
+ */
+static int unwind_exec_insn(struct unwind_ctrl_block *ctrl)
+{
+ unsigned long insn = unwind_get_byte(ctrl);
+
+ pr_debug("%s: insn = %08lx\n", __func__, insn);
+
+ if ((insn & 0xc0) == 0x00)
+ ctrl->vrs[SP] += ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xc0) == 0x40)
+ ctrl->vrs[SP] -= ((insn & 0x3f) << 2) + 4;
+ else if ((insn & 0xf0) == 0x80) {
+ unsigned long mask;
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int load_sp, reg = 4;
+
+ insn = (insn << 8) | unwind_get_byte(ctrl);
+ mask = insn & 0x0fff;
+ if (mask == 0) {
+ pr_warning("unwind: 'Refuse to unwind' instruction %04lx\n",
+ insn);
+ return -URC_FAILURE;
+ }
+
+ /* pop R4-R15 according to mask */
+ load_sp = mask & (1 << (13 - 4));
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ if (!load_sp)
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if ((insn & 0xf0) == 0x90 &&
+ (insn & 0x0d) != 0x0d)
+ ctrl->vrs[SP] = ctrl->vrs[insn & 0x0f];
+ else if ((insn & 0xf0) == 0xa0) {
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg;
+
+ /* pop R4-R[4+bbb] */
+ for (reg = 4; reg <= 4 + (insn & 7); reg++)
+ ctrl->vrs[reg] = *vsp++;
+ if (insn & 0x80)
+ ctrl->vrs[14] = *vsp++;
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb0) {
+ if (ctrl->vrs[PC] == 0)
+ ctrl->vrs[PC] = ctrl->vrs[LR];
+ /* no further processing */
+ ctrl->entries = 0;
+ } else if (insn == 0xb1) {
+ unsigned long mask = unwind_get_byte(ctrl);
+ unsigned long *vsp = (unsigned long *)ctrl->vrs[SP];
+ int reg = 0;
+
+ if (mask == 0 || mask & 0xf0) {
+ pr_warning("unwind: Spare encoding %04lx\n",
+ (insn << 8) | mask);
+ return -URC_FAILURE;
+ }
+
+ /* pop R0-R3 according to mask */
+ while (mask) {
+ if (mask & 1)
+ ctrl->vrs[reg] = *vsp++;
+ mask >>= 1;
+ reg++;
+ }
+ ctrl->vrs[SP] = (unsigned long)vsp;
+ } else if (insn == 0xb2) {
+ unsigned long uleb128 = unwind_get_byte(ctrl);
+
+ ctrl->vrs[SP] += 0x204 + (uleb128 << 2);
+ } else {
+ pr_warning("unwind: Unhandled instruction %02lx\n", insn);
+ return -URC_FAILURE;
+ }
+
+ pr_debug("%s: fp = %08lx sp = %08lx lr = %08lx pc = %08lx\n", __func__,
+ ctrl->vrs[FP], ctrl->vrs[SP], ctrl->vrs[LR], ctrl->vrs[PC]);
+
+ return URC_OK;
+}
+
+/*
+ * Unwind a single frame starting with *sp for the symbol at *pc. It
+ * updates the *pc and *sp with the new values.
+ */
+int unwind_frame(struct stackframe *frame)
+{
+ unsigned long high, low;
+ struct unwind_idx *idx;
+ struct unwind_ctrl_block ctrl;
+
+ /* only go to a higher address on the stack */
+ low = frame->sp;
+ high = ALIGN(low, THREAD_SIZE);
+
+ pr_debug("%s(pc = %08lx lr = %08lx sp = %08lx)\n", __func__,
+ frame->pc, frame->lr, frame->sp);
+
+ if (!is_kernel_text(frame->pc))
+ return -URC_FAILURE;
+
+ idx = unwind_find_idx(frame->pc);
+ if (!idx) {
+ pr_warning("unwind: Index not found %08lx\n", frame->pc);
+ return -URC_FAILURE;
+ }
+
+ ctrl.vrs[FP] = frame->fp;
+ ctrl.vrs[SP] = frame->sp;
+ ctrl.vrs[LR] = frame->lr;
+ ctrl.vrs[PC] = 0;
+
+ if (idx->insn == 1)
+ /* can't unwind */
+ return -URC_FAILURE;
+ else if ((idx->insn & 0x80000000) == 0)
+ /* prel31 to the unwind table */
+ ctrl.insn = (unsigned long *)prel31_to_addr(&idx->insn);
+ else if ((idx->insn & 0xff000000) == 0x80000000)
+ /* only personality routine 0 supported in the index */
+ ctrl.insn = &idx->insn;
+ else {
+ pr_warning("unwind: Unsupported personality routine %08lx in the index at %p\n",
+ idx->insn, idx);
+ return -URC_FAILURE;
+ }
+
+ /* check the personality routine */
+ if ((*ctrl.insn & 0xff000000) == 0x80000000) {
+ ctrl.byte = 2;
+ ctrl.entries = 1;
+ } else if ((*ctrl.insn & 0xff000000) == 0x81000000) {
+ ctrl.byte = 1;
+ ctrl.entries = 1 + ((*ctrl.insn & 0x00ff0000) >> 16);
+ } else {
+ pr_warning("unwind: Unsupported personality routine %08lx at %p\n",
+ *ctrl.insn, ctrl.insn);
+ return -URC_FAILURE;
+ }
+
+ while (ctrl.entries > 0) {
+ int urc = unwind_exec_insn(&ctrl);
+ if (urc < 0)
+ return urc;
+ if (ctrl.vrs[SP] < low || ctrl.vrs[SP] >= high)
+ return -URC_FAILURE;
+ }
+
+ if (ctrl.vrs[PC] == 0)
+ ctrl.vrs[PC] = ctrl.vrs[LR];
+
+ /* check for infinite loop */
+ if (frame->pc == ctrl.vrs[PC])
+ return -URC_FAILURE;
+
+ frame->fp = ctrl.vrs[FP];
+ frame->sp = ctrl.vrs[SP];
+ frame->lr = ctrl.vrs[LR];
+ frame->pc = ctrl.vrs[PC];
+
+ return URC_OK;
+}
+
+void unwind_backtrace(struct pt_regs *regs)
+{
+ struct stackframe frame;
+ register unsigned long current_sp asm ("sp");
+
+ pr_debug("%s\n", __func__);
+
+ if (regs) {
+ frame.fp = regs->ARM_fp;
+ frame.sp = regs->ARM_sp;
+ frame.lr = regs->ARM_lr;
+ /* PC might be corrupted, use LR in that case. */
+ frame.pc = is_kernel_text(regs->ARM_pc)
+ ? regs->ARM_pc : regs->ARM_lr;
+ } else {
+ frame.sp = current_sp;
+ frame.lr = (unsigned long)__builtin_return_address(0);
+ frame.pc = (unsigned long)unwind_backtrace;
+ }
+
+ while (1) {
+ int urc;
+ unsigned long where = frame.pc;
+
+ urc = unwind_frame(&frame);
+ if (urc < 0)
+ break;
+ dump_backtrace_entry(where, frame.pc, frame.sp - 4);
+ }
+}
+
+void dump_stack(void)
+{
+ unwind_backtrace(NULL);
+}
+
+static int unwind_init(void)
+{
+ struct unwind_idx *idx;
+
+ /* Convert the symbol addresses to absolute values */
+ for (idx = __start_unwind_idx; idx < __stop_unwind_idx; idx++)
+ idx->addr = prel31_to_addr(&idx->addr);
+
+ return 0;
+}
+core_initcall(unwind_init);
diff --git a/arch/arm/lib64/Makefile b/arch/arm/lib64/Makefile
new file mode 100644
index 0000000..87e26f6
--- /dev/null
+++ b/arch/arm/lib64/Makefile
@@ -0,0 +1,9 @@
+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
+
+pbl-y += lib1funcs.o
+pbl-y += ashldi3.o
+pbl-y += div0.o
diff --git a/arch/arm/lib64/armlinux.c b/arch/arm/lib64/armlinux.c
new file mode 100644
index 0000000..020e6d7
--- /dev/null
+++ b/arch/arm/lib64/armlinux.c
@@ -0,0 +1,50 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * 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 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 <boot.h>
+#include <common.h>
+#include <command.h>
+#include <driver.h>
+#include <environment.h>
+#include <image.h>
+#include <init.h>
+#include <fs.h>
+#include <linux/list.h>
+#include <xfuncs.h>
+#include <malloc.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <memory.h>
+#include <of.h>
+#include <magicvar.h>
+
+#include <asm/byteorder.h>
+#include <asm/setup.h>
+#include <asm/barebox-arm.h>
+#include <asm/armlinux.h>
+#include <asm/system.h>
+
+void start_linux(void *adr, int swap, unsigned long initrd_address,
+ unsigned long initrd_size, void *oftree)
+{
+ void (*kernel)(void *dtb) = adr;
+
+ shutdown_barebox();
+
+ kernel(oftree);
+}
diff --git a/arch/arm/lib64/barebox.lds.S b/arch/arm/lib64/barebox.lds.S
new file mode 100644
index 0000000..240699f
--- /dev/null
+++ b/arch/arm/lib64/barebox.lds.S
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 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 <asm-generic/barebox.lds.h>
+
+OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
+OUTPUT_ARCH(aarch64)
+ENTRY(start)
+SECTIONS
+{
+#ifdef CONFIG_RELOCATABLE
+ . = 0x0;
+#else
+ . = TEXT_BASE;
+#endif
+
+#ifndef CONFIG_PBL_IMAGE
+ PRE_IMAGE
+#endif
+ . = ALIGN(4);
+ .text :
+ {
+ _stext = .;
+ _text = .;
+ *(.text_entry*)
+ __bare_init_start = .;
+ *(.text_bare_init*)
+ __bare_init_end = .;
+ __exceptions_start = .;
+ KEEP(*(.text_exceptions*))
+ __exceptions_stop = .;
+ *(.text*)
+ }
+ BAREBOX_BARE_INIT_SIZE
+
+ . = 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 = .;
+
+ . = ALIGN(4);
+ .data : { *(.data*) }
+
+ .barebox_imd : { BAREBOX_IMD }
+
+ . = .;
+ __barebox_cmd_start = .;
+ .barebox_cmd : { BAREBOX_CMDS }
+ __barebox_cmd_end = .;
+
+ __barebox_magicvar_start = .;
+ .barebox_magicvar : { BAREBOX_MAGICVARS }
+ __barebox_magicvar_end = .;
+
+ __barebox_initcalls_start = .;
+ .barebox_initcalls : { INITCALLS }
+ __barebox_initcalls_end = .;
+
+ __barebox_exitcalls_start = .;
+ .barebox_exitcalls : { EXITCALLS }
+ __barebox_exitcalls_end = .;
+
+ __usymtab_start = .;
+ __usymtab : { BAREBOX_SYMS }
+ __usymtab_end = .;
+
+ .oftables : { BAREBOX_CLK_TABLE() }
+
+ .dtb : { BAREBOX_DTB() }
+
+ .rel.dyn : {
+ __rel_dyn_start = .;
+ *(.rel*)
+ __rel_dyn_end = .;
+ }
+
+ .dynsym : {
+ __dynsym_start = .;
+ *(.dynsym)
+ __dynsym_end = .;
+ }
+
+ _edata = .;
+
+ . = ALIGN(4);
+ __bss_start = .;
+ .bss : { *(.bss*) }
+ __bss_stop = .;
+ _end = .;
+ _barebox_image_size = __bss_start - TEXT_BASE;
+}
diff --git a/arch/arm/lib64/copy_template.S b/arch/arm/lib64/copy_template.S
new file mode 100644
index 0000000..cc9a842
--- /dev/null
+++ b/arch/arm/lib64/copy_template.S
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * and re-licensed under GPLv2 for the Linux kernel. The original code can
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ * x0 - dest
+ * x1 - src
+ * x2 - n
+ * Returns:
+ * x0 - dest
+ */
+dstin .req x0
+src .req x1
+count .req x2
+tmp1 .req x3
+tmp1w .req w3
+tmp2 .req x4
+tmp2w .req w4
+dst .req x6
+
+A_l .req x7
+A_h .req x8
+B_l .req x9
+B_h .req x10
+C_l .req x11
+C_h .req x12
+D_l .req x13
+D_h .req x14
+
+ mov dst, dstin
+ cmp count, #16
+ /*When memory length is less than 16, the accessed are not aligned.*/
+ b.lo .Ltiny15
+
+ neg tmp2, src
+ ands tmp2, tmp2, #15/* Bytes to reach alignment. */
+ b.eq .LSrcAligned
+ sub count, count, tmp2
+ /*
+ * Copy the leading memory data from src to dst in an increasing
+ * address order.By this way,the risk of overwritting the source
+ * memory data is eliminated when the distance between src and
+ * dst is less than 16. The memory accesses here are alignment.
+ */
+ tbz tmp2, #0, 1f
+ ldrb1 tmp1w, src, #1
+ strb1 tmp1w, dst, #1
+1:
+ tbz tmp2, #1, 2f
+ ldrh1 tmp1w, src, #2
+ strh1 tmp1w, dst, #2
+2:
+ tbz tmp2, #2, 3f
+ ldr1 tmp1w, src, #4
+ str1 tmp1w, dst, #4
+3:
+ tbz tmp2, #3, .LSrcAligned
+ ldr1 tmp1, src, #8
+ str1 tmp1, dst, #8
+
+.LSrcAligned:
+ cmp count, #64
+ b.ge .Lcpy_over64
+ /*
+ * Deal with small copies quickly by dropping straight into the
+ * exit block.
+ */
+.Ltail63:
+ /*
+ * Copy up to 48 bytes of data. At this point we only need the
+ * bottom 6 bits of count to be accurate.
+ */
+ ands tmp1, count, #0x30
+ b.eq .Ltiny15
+ cmp tmp1w, #0x20
+ b.eq 1f
+ b.lt 2f
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+1:
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+2:
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+.Ltiny15:
+ /*
+ * Prefer to break one ldp/stp into several load/store to access
+ * memory in an increasing address order,rather than to load/store 16
+ * bytes from (src-16) to (dst-16) and to backward the src to aligned
+ * address,which way is used in original cortex memcpy. If keeping
+ * the original memcpy process here, memmove need to satisfy the
+ * precondition that src address is at least 16 bytes bigger than dst
+ * address,otherwise some source data will be overwritten when memove
+ * call memcpy directly. To make memmove simpler and decouple the
+ * memcpy's dependency on memmove, withdrew the original process.
+ */
+ tbz count, #3, 1f
+ ldr1 tmp1, src, #8
+ str1 tmp1, dst, #8
+1:
+ tbz count, #2, 2f
+ ldr1 tmp1w, src, #4
+ str1 tmp1w, dst, #4
+2:
+ tbz count, #1, 3f
+ ldrh1 tmp1w, src, #2
+ strh1 tmp1w, dst, #2
+3:
+ tbz count, #0, .Lexitfunc
+ ldrb1 tmp1w, src, #1
+ strb1 tmp1w, dst, #1
+
+ b .Lexitfunc
+
+.Lcpy_over64:
+ subs count, count, #128
+ b.ge .Lcpy_body_large
+ /*
+ * Less than 128 bytes to copy, so handle 64 here and then jump
+ * to the tail.
+ */
+ ldp1 A_l, A_h, src, #16
+ stp1 A_l, A_h, dst, #16
+ ldp1 B_l, B_h, src, #16
+ ldp1 C_l, C_h, src, #16
+ stp1 B_l, B_h, dst, #16
+ stp1 C_l, C_h, dst, #16
+ ldp1 D_l, D_h, src, #16
+ stp1 D_l, D_h, dst, #16
+
+ tst count, #0x3f
+ b.ne .Ltail63
+ b .Lexitfunc
+
+ /*
+ * Critical loop. Start at a new cache line boundary. Assuming
+ * 64 bytes per line this ensures the entire loop is in one line.
+ */
+.Lcpy_body_large:
+ /* pre-get 64 bytes data. */
+ ldp1 A_l, A_h, src, #16
+ ldp1 B_l, B_h, src, #16
+ ldp1 C_l, C_h, src, #16
+ ldp1 D_l, D_h, src, #16
+1:
+ /*
+ * interlace the load of next 64 bytes data block with store of the last
+ * loaded 64 bytes data.
+ */
+ stp1 A_l, A_h, dst, #16
+ ldp1 A_l, A_h, src, #16
+ stp1 B_l, B_h, dst, #16
+ ldp1 B_l, B_h, src, #16
+ stp1 C_l, C_h, dst, #16
+ ldp1 C_l, C_h, src, #16
+ stp1 D_l, D_h, dst, #16
+ ldp1 D_l, D_h, src, #16
+ subs count, count, #64
+ b.ge 1b
+ stp1 A_l, A_h, dst, #16
+ stp1 B_l, B_h, dst, #16
+ stp1 C_l, C_h, dst, #16
+ stp1 D_l, D_h, dst, #16
+
+ tst count, #0x3f
+ b.ne .Ltail63
+.Lexitfunc:
diff --git a/arch/arm/lib64/div0.c b/arch/arm/lib64/div0.c
new file mode 100644
index 0000000..852cb72
--- /dev/null
+++ b/arch/arm/lib64/div0.c
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 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 <common.h>
+
+extern void __div0(void);
+
+/* Replacement (=dummy) for GNU/Linux division-by zero handler */
+void __div0 (void)
+{
+ panic("division by zero\n");
+}
diff --git a/arch/arm/lib64/memcpy.S b/arch/arm/lib64/memcpy.S
new file mode 100644
index 0000000..cfed319
--- /dev/null
+++ b/arch/arm/lib64/memcpy.S
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * and re-licensed under GPLv2 for the Linux kernel. The original code can
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Copy a buffer from src to dest (alignment handled by the hardware)
+ *
+ * Parameters:
+ * x0 - dest
+ * x1 - src
+ * x2 - n
+ * Returns:
+ * x0 - dest
+ */
+ .macro ldrb1 ptr, regB, val
+ ldrb \ptr, [\regB], \val
+ .endm
+
+ .macro strb1 ptr, regB, val
+ strb \ptr, [\regB], \val
+ .endm
+
+ .macro ldrh1 ptr, regB, val
+ ldrh \ptr, [\regB], \val
+ .endm
+
+ .macro strh1 ptr, regB, val
+ strh \ptr, [\regB], \val
+ .endm
+
+ .macro ldr1 ptr, regB, val
+ ldr \ptr, [\regB], \val
+ .endm
+
+ .macro str1 ptr, regB, val
+ str \ptr, [\regB], \val
+ .endm
+
+ .macro ldp1 ptr, regB, regC, val
+ ldp \ptr, \regB, [\regC], \val
+ .endm
+
+ .macro stp1 ptr, regB, regC, val
+ stp \ptr, \regB, [\regC], \val
+ .endm
+
+ .weak memcpy
+ENTRY(memcpy)
+#include "copy_template.S"
+ ret
+ENDPROC(memcpy)
diff --git a/arch/arm/lib64/memset.S b/arch/arm/lib64/memset.S
new file mode 100644
index 0000000..380a540
--- /dev/null
+++ b/arch/arm/lib64/memset.S
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2013 ARM Ltd.
+ * Copyright (C) 2013 Linaro.
+ *
+ * This code is based on glibc cortex strings work originally authored by Linaro
+ * and re-licensed under GPLv2 for the Linux kernel. The original code can
+ * be found @
+ *
+ * http://bazaar.launchpad.net/~linaro-toolchain-dev/cortex-strings/trunk/
+ * files/head:/src/aarch64/
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * Fill in the buffer with character c (alignment handled by the hardware)
+ *
+ * Parameters:
+ * x0 - buf
+ * x1 - c
+ * x2 - n
+ * Returns:
+ * x0 - buf
+ */
+
+dstin .req x0
+val .req w1
+count .req x2
+tmp1 .req x3
+tmp1w .req w3
+tmp2 .req x4
+tmp2w .req w4
+zva_len_x .req x5
+zva_len .req w5
+zva_bits_x .req x6
+
+A_l .req x7
+A_lw .req w7
+dst .req x8
+tmp3w .req w9
+tmp3 .req x9
+
+ .weak memset
+ENTRY(memset)
+ mov dst, dstin /* Preserve return value. */
+ and A_lw, val, #255
+ orr A_lw, A_lw, A_lw, lsl #8
+ orr A_lw, A_lw, A_lw, lsl #16
+ orr A_l, A_l, A_l, lsl #32
+
+ cmp count, #15
+ b.hi .Lover16_proc
+ /*All store maybe are non-aligned..*/
+ tbz count, #3, 1f
+ str A_l, [dst], #8
+1:
+ tbz count, #2, 2f
+ str A_lw, [dst], #4
+2:
+ tbz count, #1, 3f
+ strh A_lw, [dst], #2
+3:
+ tbz count, #0, 4f
+ strb A_lw, [dst]
+4:
+ ret
+
+.Lover16_proc:
+ /*Whether the start address is aligned with 16.*/
+ neg tmp2, dst
+ ands tmp2, tmp2, #15
+ b.eq .Laligned
+/*
+* The count is not less than 16, we can use stp to store the start 16 bytes,
+* then adjust the dst aligned with 16.This process will make the current
+* memory address at alignment boundary.
+*/
+ stp A_l, A_l, [dst] /*non-aligned store..*/
+ /*make the dst aligned..*/
+ sub count, count, tmp2
+ add dst, dst, tmp2
+
+.Laligned:
+ cbz A_l, .Lzero_mem
+
+.Ltail_maybe_long:
+ cmp count, #64
+ b.ge .Lnot_short
+.Ltail63:
+ ands tmp1, count, #0x30
+ b.eq 3f
+ cmp tmp1w, #0x20
+ b.eq 1f
+ b.lt 2f
+ stp A_l, A_l, [dst], #16
+1:
+ stp A_l, A_l, [dst], #16
+2:
+ stp A_l, A_l, [dst], #16
+/*
+* The last store length is less than 16,use stp to write last 16 bytes.
+* It will lead some bytes written twice and the access is non-aligned.
+*/
+3:
+ ands count, count, #15
+ cbz count, 4f
+ add dst, dst, count
+ stp A_l, A_l, [dst, #-16] /* Repeat some/all of last store. */
+4:
+ ret
+
+ /*
+ * Critical loop. Start at a new cache line boundary. Assuming
+ * 64 bytes per line, this ensures the entire loop is in one line.
+ */
+.Lnot_short:
+ sub dst, dst, #16/* Pre-bias. */
+ sub count, count, #64
+1:
+ stp A_l, A_l, [dst, #16]
+ stp A_l, A_l, [dst, #32]
+ stp A_l, A_l, [dst, #48]
+ stp A_l, A_l, [dst, #64]!
+ subs count, count, #64
+ b.ge 1b
+ tst count, #0x3f
+ add dst, dst, #16
+ b.ne .Ltail63
+.Lexitfunc:
+ ret
+
+ /*
+ * For zeroing memory, check to see if we can use the ZVA feature to
+ * zero entire 'cache' lines.
+ */
+.Lzero_mem:
+ cmp count, #63
+ b.le .Ltail63
+ /*
+ * For zeroing small amounts of memory, it's not worth setting up
+ * the line-clear code.
+ */
+ cmp count, #128
+ b.lt .Lnot_short /*count is at least 128 bytes*/
+
+ mrs tmp1, dczid_el0
+ tbnz tmp1, #4, .Lnot_short
+ mov tmp3w, #4
+ and zva_len, tmp1w, #15 /* Safety: other bits reserved. */
+ lsl zva_len, tmp3w, zva_len
+
+ ands tmp3w, zva_len, #63
+ /*
+ * ensure the zva_len is not less than 64.
+ * It is not meaningful to use ZVA if the block size is less than 64.
+ */
+ b.ne .Lnot_short
+.Lzero_by_line:
+ /*
+ * Compute how far we need to go to become suitably aligned. We're
+ * already at quad-word alignment.
+ */
+ cmp count, zva_len_x
+ b.lt .Lnot_short /* Not enough to reach alignment. */
+ sub zva_bits_x, zva_len_x, #1
+ neg tmp2, dst
+ ands tmp2, tmp2, zva_bits_x
+ b.eq 2f /* Already aligned. */
+ /* Not aligned, check that there's enough to copy after alignment.*/
+ sub tmp1, count, tmp2
+ /*
+ * grantee the remain length to be ZVA is bigger than 64,
+ * avoid to make the 2f's process over mem range.*/
+ cmp tmp1, #64
+ ccmp tmp1, zva_len_x, #8, ge /* NZCV=0b1000 */
+ b.lt .Lnot_short
+ /*
+ * We know that there's at least 64 bytes to zero and that it's safe
+ * to overrun by 64 bytes.
+ */
+ mov count, tmp1
+1:
+ stp A_l, A_l, [dst]
+ stp A_l, A_l, [dst, #16]
+ stp A_l, A_l, [dst, #32]
+ subs tmp2, tmp2, #64
+ stp A_l, A_l, [dst, #48]
+ add dst, dst, #64
+ b.ge 1b
+ /* We've overrun a bit, so adjust dst downwards.*/
+ add dst, dst, tmp2
+2:
+ sub count, count, zva_len_x
+3:
+ dc zva, dst
+ add dst, dst, zva_len_x
+ subs count, count, zva_len_x
+ b.ge 3b
+ ands count, count, zva_bits_x
+ b.ne .Ltail_maybe_long
+ ret
+ENDPROC(memset)
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 04/14] arm: cpu: add arm64 specific code
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (2 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 03/14] arm: rework lib directory to support arm64 Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 05/14] arm: include: system: add arm64 helper functions Raphael Poggi
` (10 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
This patch adds arm64 specific codes, which are:
- exception support
- cache support
- rework Makefile to support arm64
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/cpu/Makefile | 26 +++++--
arch/arm/cpu/cache-armv8.S | 168 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/cpu/cache.c | 19 +++++
arch/arm/cpu/exceptions_64.S | 127 ++++++++++++++++++++++++++++++++
arch/arm/cpu/interrupts.c | 47 ++++++++++++
arch/arm/cpu/lowlevel_64.S | 40 +++++++++++
arch/arm/cpu/setupc_64.S | 18 +++++
arch/arm/include/asm/cache.h | 9 +++
8 files changed, 450 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/cpu/cache-armv8.S
create mode 100644 arch/arm/cpu/exceptions_64.S
create mode 100644 arch/arm/cpu/lowlevel_64.S
create mode 100644 arch/arm/cpu/setupc_64.S
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 854df60e..7eb06fb 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -1,7 +1,24 @@
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) += interrupts.o
-obj-y += start.o setupc.o entry.o
+obj-y += start.o entry.o
+
+ifeq ($(CONFIG_CPU_64v8), y)
+obj-y += setupc_64.o
+else
+obj-y += setupc.o
+endif
#
# Any variants can be called as start-armxyz.S
@@ -11,7 +28,6 @@ obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o
obj-$(CONFIG_OFDEVICE) += dtb.o
obj-$(CONFIG_MMU) += mmu.o cache.o mmu-early.o
pbl-$(CONFIG_MMU) += mmu-early.o
-
ifeq ($(CONFIG_MMU),)
obj-y += no-mmu.o
endif
@@ -27,6 +43,10 @@ obj-$(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
+AFLAGS_pbl-cache-armv8.o :=-Wa,-march=armv8-a
+pbl-$(CONFIG_CPU_64v8) += cache-armv8.o
pbl-y += setupc.o entry.o
pbl-$(CONFIG_PBL_SINGLE_IMAGE) += start-pbl.o
@@ -34,5 +54,3 @@ pbl-$(CONFIG_PBL_MULTI_IMAGES) += uncompress.o
obj-y += common.o cache.o
pbl-y += common.o cache.o
-
-lwl-y += lowlevel.o
diff --git a/arch/arm/cpu/cache-armv8.S b/arch/arm/cpu/cache-armv8.S
new file mode 100644
index 0000000..82b2f81
--- /dev/null
+++ b/arch/arm/cpu/cache-armv8.S
@@ -0,0 +1,168 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * This file is based on sample code from ARMv8 ARM.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <linux/linkage.h>
+#include <init.h>
+
+/*
+ * void v8_flush_dcache_level(level)
+ *
+ * clean and invalidate one level cache.
+ *
+ * x0: cache level
+ * x1: 0 flush & invalidate, 1 invalidate only
+ * x2~x9: clobbered
+ */
+.section .text.v8_flush_dcache_level
+ENTRY(v8_flush_dcache_level)
+ lsl x12, x0, #1
+ msr csselr_el1, x12 /* select cache level */
+ isb /* sync change of cssidr_el1 */
+ mrs x6, ccsidr_el1 /* read the new cssidr_el1 */
+ and x2, x6, #7 /* x2 <- log2(cache line size)-4 */
+ add x2, x2, #4 /* x2 <- log2(cache line size) */
+ mov x3, #0x3ff
+ and x3, x3, x6, lsr #3 /* x3 <- max number of #ways */
+ clz w5, w3 /* bit position of #ways */
+ mov x4, #0x7fff
+ and x4, x4, x6, lsr #13 /* x4 <- max number of #sets */
+ /* x12 <- cache level << 1 */
+ /* x2 <- line length offset */
+ /* x3 <- number of cache ways - 1 */
+ /* x4 <- number of cache sets - 1 */
+ /* x5 <- bit position of #ways */
+
+loop_set:
+ mov x6, x3 /* x6 <- working copy of #ways */
+loop_way:
+ lsl x7, x6, x5
+ orr x9, x12, x7 /* map way and level to cisw value */
+ lsl x7, x4, x2
+ orr x9, x9, x7 /* map set number to cisw value */
+ tbz w1, #0, 1f
+ dc isw, x9
+ b 2f
+1: dc cisw, x9 /* clean & invalidate by set/way */
+2: subs x6, x6, #1 /* decrement the way */
+ b.ge loop_way
+ subs x4, x4, #1 /* decrement the set */
+ b.ge loop_set
+
+ ret
+ENDPROC(v8_flush_dcache_level)
+
+/*
+ * void v8_flush_dcache_all(int invalidate_only)
+ *
+ * x0: 0 flush & invalidate, 1 invalidate only
+ *
+ * clean and invalidate all data cache by SET/WAY.
+ */
+.section .text.v8_dcache_all
+ENTRY(v8_dcache_all)
+ mov x1, x0
+ dsb sy
+ mrs x10, clidr_el1 /* read clidr_el1 */
+ lsr x11, x10, #24
+ and x11, x11, #0x7 /* x11 <- loc */
+ cbz x11, finished /* if loc is 0, exit */
+ mov x15, x30
+ mov x0, #0 /* start flush at cache level 0 */
+ /* x0 <- cache level */
+ /* x10 <- clidr_el1 */
+ /* x11 <- loc */
+ /* x15 <- return address */
+
+loop_level:
+ lsl x12, x0, #1
+ add x12, x12, x0 /* x0 <- tripled cache level */
+ lsr x12, x10, x12
+ and x12, x12, #7 /* x12 <- cache type */
+ cmp x12, #2
+ b.lt skip /* skip if no cache or icache */
+ bl v8_flush_dcache_level /* x1 = 0 flush, 1 invalidate */
+skip:
+ add x0, x0, #1 /* increment cache level */
+ cmp x11, x0
+ b.gt loop_level
+
+ mov x0, #0
+ msr csselr_el1, x0 /* restore csselr_el1 */
+ dsb sy
+ isb
+ mov x30, x15
+
+finished:
+ ret
+ENDPROC(v8_dcache_all)
+
+.section .text.v8_flush_dcache_all
+ENTRY(v8_flush_dcache_all)
+ mov x16, x30
+ mov x0, #0
+ bl v8_dcache_all
+ mov x30, x16
+ ret
+ENDPROC(v8_flush_dcache_all)
+
+.section .text.v8_invalidate_dcache_all
+ENTRY(v8_invalidate_dcache_all)
+ mov x16, x30
+ mov x0, #0x1
+ bl v8_dcache_all
+ mov x30, x16
+ ret
+ENDPROC(v8_invalidate_dcache_all)
+
+/*
+ * void v8_flush_dcache_range(start, end)
+ *
+ * clean & invalidate data cache in the range
+ *
+ * x0: start address
+ * x1: end address
+ */
+.section .text.v8_flush_dcache_range
+ENTRY(v8_flush_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 civac, x0 /* clean & invalidate data or unified cache */
+ add x0, x0, x2
+ cmp x0, x1
+ b.lo 1b
+ dsb sy
+ ret
+ENDPROC(v8_flush_dcache_range)
+
+/*
+ * void v8_invalidate_icache_all(void)
+ *
+ * invalidate all tlb entries.
+ */
+.section .text.v8_invalidate_icache_all
+ENTRY(v8_invalidate_icache_all)
+ ic ialluis
+ isb sy
+ ret
+ENDPROC(v8_invalidate_icache_all)
+
+.section .text.v8_flush_l3_cache
+ENTRY(v8_flush_l3_cache)
+ mov x0, #0 /* return status as success */
+ ret
+ENDPROC(v8_flush_l3_cache)
+ .weak v8_flush_l3_cache
diff --git a/arch/arm/cpu/cache.c b/arch/arm/cpu/cache.c
index 27ead1c..929c385 100644
--- a/arch/arm/cpu/cache.c
+++ b/arch/arm/cpu/cache.c
@@ -36,6 +36,7 @@ DEFINE_CPU_FNS(v4)
DEFINE_CPU_FNS(v5)
DEFINE_CPU_FNS(v6)
DEFINE_CPU_FNS(v7)
+DEFINE_CPU_FNS(v8)
void __dma_clean_range(unsigned long start, unsigned long end)
{
@@ -101,6 +102,11 @@ int arm_set_cache_functions(void)
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);
}
@@ -138,6 +144,11 @@ void arm_early_mmu_cache_flush(void)
v7_mmu_cache_flush();
return;
#endif
+#ifdef CONFIG_CPU_64v8
+ case CPU_ARCH_ARMv8:
+ v8_dcache_all();
+ return;
+#endif
}
}
@@ -146,6 +157,7 @@ void v7_mmu_cache_invalidate(void);
void arm_early_mmu_cache_invalidate(void)
{
switch (arm_early_get_cpu_architecture()) {
+#if __LINUX_ARM_ARCH__ <= 7
case CPU_ARCH_ARMv4T:
case CPU_ARCH_ARMv5:
case CPU_ARCH_ARMv5T:
@@ -159,5 +171,12 @@ void arm_early_mmu_cache_invalidate(void)
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/exceptions_64.S b/arch/arm/cpu/exceptions_64.S
new file mode 100644
index 0000000..5812025
--- /dev/null
+++ b/arch/arm/cpu/exceptions_64.S
@@ -0,0 +1,127 @@
+/*
+ * (C) Copyright 2013
+ * David Feng <fenghua@phytium.com.cn>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/ptrace.h>
+#include <linux/linkage.h>
+
+/*
+ * Enter Exception.
+ * This will save the processor state that is ELR/X0~X30
+ * to the stack frame.
+ */
+.macro exception_entry
+ stp x29, x30, [sp, #-16]!
+ stp x27, x28, [sp, #-16]!
+ stp x25, x26, [sp, #-16]!
+ stp x23, x24, [sp, #-16]!
+ stp x21, x22, [sp, #-16]!
+ stp x19, x20, [sp, #-16]!
+ stp x17, x18, [sp, #-16]!
+ stp x15, x16, [sp, #-16]!
+ stp x13, x14, [sp, #-16]!
+ stp x11, x12, [sp, #-16]!
+ stp x9, x10, [sp, #-16]!
+ stp x7, x8, [sp, #-16]!
+ stp x5, x6, [sp, #-16]!
+ 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
+3: mrs x1, esr_el3
+ mrs x2, elr_el3
+ b 0f
+2: mrs x1, esr_el2
+ mrs x2, elr_el2
+ b 0f
+1: mrs x1, esr_el1
+ mrs x2, elr_el1
+0:
+ stp x2, x0, [sp, #-16]!
+ mov x0, sp
+.endm
+
+/*
+ * Exception vectors.
+ */
+ .align 11
+ .globl vectors
+vectors:
+ .align 7
+ b _do_bad_sync /* Current EL Synchronous Thread */
+
+ .align 7
+ b _do_bad_irq /* Current EL IRQ Thread */
+
+ .align 7
+ b _do_bad_fiq /* Current EL FIQ Thread */
+
+ .align 7
+ b _do_bad_error /* Current EL Error Thread */
+
+ .align 7
+ b _do_sync /* Current EL Synchronous Handler */
+
+ .align 7
+ b _do_irq /* Current EL IRQ Handler */
+
+ .align 7
+ b _do_fiq /* Current EL FIQ Handler */
+
+ .align 7
+ b _do_error /* Current EL Error Handler */
+
+
+_do_bad_sync:
+ exception_entry
+ bl do_bad_sync
+
+_do_bad_irq:
+ exception_entry
+ bl do_bad_irq
+
+_do_bad_fiq:
+ exception_entry
+ bl do_bad_fiq
+
+_do_bad_error:
+ exception_entry
+ bl do_bad_error
+
+_do_sync:
+ exception_entry
+ bl do_sync
+
+_do_irq:
+ exception_entry
+ bl do_irq
+
+_do_fiq:
+ exception_entry
+ bl do_fiq
+
+_do_error:
+ exception_entry
+ bl do_error
+
+.section .data
+.align 4
+.global arm_ignore_data_abort
+arm_ignore_data_abort:
+.word 0 /* When != 0 data aborts are ignored */
+.global arm_data_abort_occurred
+arm_data_abort_occurred:
+.word 0 /* set != 0 by the data abort handler */
+abort_stack:
+.space 8
diff --git a/arch/arm/cpu/interrupts.c b/arch/arm/cpu/interrupts.c
index fb4bb78..c34108a 100644
--- a/arch/arm/cpu/interrupts.c
+++ b/arch/arm/cpu/interrupts.c
@@ -27,6 +27,8 @@
#include <asm/ptrace.h>
#include <asm/unwind.h>
+
+#if __LINUX_ARM_ARCH__ <= 7
/**
* Display current register set content
* @param[in] regs Guess what
@@ -70,10 +72,13 @@ void show_regs (struct pt_regs *regs)
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("");
}
@@ -121,6 +126,8 @@ void do_prefetch_abort (struct pt_regs *pt_regs)
*/
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");
@@ -128,6 +135,7 @@ void do_data_abort (struct pt_regs *pt_regs)
printf("unable to handle %s at address 0x%08x\n",
far < PAGE_SIZE ? "NULL pointer dereference" :
"paging request", far);
+#endif
do_exception(pt_regs);
}
@@ -156,6 +164,45 @@ void do_irq (struct pt_regs *pt_regs)
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/lowlevel_64.S b/arch/arm/cpu/lowlevel_64.S
new file mode 100644
index 0000000..4850895
--- /dev/null
+++ b/arch/arm/cpu/lowlevel_64.S
@@ -0,0 +1,40 @@
+#include <linux/linkage.h>
+#include <init.h>
+#include <asm/system.h>
+
+.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
+
+1:
+ msr vbar_el3, x0
+ mov x0, #1 /* Non-Secure EL0/1 */
+ orr x0, x0, #(1 << 10) /* 64-bit EL2 */
+ msr scr_el3, x0
+ msr cptr_el3, xzr
+ b done
+
+2:
+ msr vbar_el2, x0
+ mov x0, #0x33ff /* Enable FP/SIMD */
+ msr cptr_el2, x0
+ b done
+
+
+3:
+ msr vbar_el1, x0
+ mov x0, #(3 << 20) /* Enable FP/SIMD */
+ msr cpacr_el1, x0
+ b done
+
+done:
+ ret
+
+ENDPROC(arm_cpu_lowlevel_init)
diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S
new file mode 100644
index 0000000..3515854
--- /dev/null
+++ b/arch/arm/cpu/setupc_64.S
@@ -0,0 +1,18 @@
+#include <linux/linkage.h>
+#include <asm/sections.h>
+
+.section .text.setupc
+
+/*
+ * setup_c: clear bss
+ */
+ENTRY(setup_c)
+ mov x15, x30
+ ldr x0, =__bss_start
+ mov x1, #0
+ ldr x2, =__bss_stop
+ sub x2, x2, x0
+ bl memset /* clear bss */
+ mov x30, x15
+ ret
+ENDPROC(setup_c)
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index 2f6eab0..8fcdb64 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -1,9 +1,18 @@
#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
+
static inline void flush_icache(void)
{
+#if __LINUX_ARM_ARCH__ <= 7
asm volatile("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
+#else
+ v8_invalidate_icache_all();
+#endif
}
int arm_set_cache_functions(void);
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 05/14] arm: include: system: add arm64 helper functions
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (3 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 04/14] arm: cpu: add arm64 specific code Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 06/14] arm: include: bitops: arm64 use generic __fls Raphael Poggi
` (9 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/include/asm/system.h | 46 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index b118a42..57c7618 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -3,7 +3,11 @@
#if __LINUX_ARM_ARCH__ >= 7
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
+#ifdef CONFIG_CPU_64v8
+#define dsb() __asm__ __volatile__ ("dsb sy" : : : "memory")
+#else
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
+#endif
#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
@@ -57,17 +61,58 @@
#define CR_TE (1 << 30) /* Thumb exception enable */
#ifndef __ASSEMBLY__
+#if __LINUX_ARM_ARCH__ >= 7
+static inline unsigned int current_el(void)
+{
+ unsigned int el;
+ asm volatile("mrs %0, CurrentEL" : "=r" (el) : : "cc");
+ return el >> 2;
+}
+
+static inline unsigned long read_mpidr(void)
+{
+ unsigned long val;
+
+ asm volatile("mrs %0, mpidr_el1" : "=r" (val));
+
+ return val;
+}
+#endif
static inline unsigned int get_cr(void)
{
unsigned int val;
+
+#ifdef CONFIG_CPU_64v8
+ unsigned int el = current_el();
+ if (el == 1)
+ asm volatile("mrs %0, sctlr_el1" : "=r" (val) : : "cc");
+ else if (el == 2)
+ asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc");
+ else
+ asm volatile("mrs %0, sctlr_el3" : "=r" (val) : : "cc");
+#else
asm volatile ("mrc p15, 0, %0, c1, c0, 0 @ get CR" : "=r" (val) : : "cc");
+#endif
+
return val;
}
static inline void set_cr(unsigned int val)
{
+#ifdef CONFIG_CPU_64v8
+ unsigned int el;
+
+ el = current_el();
+ if (el == 1)
+ asm volatile("msr sctlr_el1, %0" : : "r" (val) : "cc");
+ else if (el == 2)
+ asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc");
+ else
+ asm volatile("msr sctlr_el3, %0" : : "r" (val) : "cc");
+#else
asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
: : "r" (val) : "cc");
+#endif
isb();
}
@@ -90,7 +135,6 @@ static inline void set_vbar(unsigned int vbar)
static inline unsigned int get_vbar(void) { return 0; }
static inline void set_vbar(unsigned int vbar) {}
#endif
-
#endif
#endif /* __ASM_ARM_SYSTEM_H */
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 06/14] arm: include: bitops: arm64 use generic __fls
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (4 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 05/14] arm: include: system: add arm64 helper functions Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 07/14] arm: include: system_info: add armv8 identification Raphael Poggi
` (8 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/include/asm/bitops.h | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index 138ebe2..b51225e 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -177,6 +177,11 @@ static inline unsigned long ffz(unsigned long word)
#include <asm-generic/bitops/ffs.h>
#include <asm-generic/bitops/fls.h>
#endif /* __ARM__USE_GENERIC_FF */
+
+#if __LINUX_ARM_ARCH__ == 8
+#include <asm-generic/bitops/__fls.h>
+#endif
+
#include <asm-generic/bitops/fls64.h>
#include <asm-generic/bitops/hweight.h>
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 07/14] arm: include: system_info: add armv8 identification
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (5 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 06/14] arm: include: bitops: arm64 use generic __fls Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 08/14] arm: cpu: cpuinfo: add armv8 support Raphael Poggi
` (7 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/include/asm/system_info.h | 38 ++++++++++++++++++++++++++++++++++++++
1 file changed, 38 insertions(+)
diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
index 0761848..25fffd2 100644
--- a/arch/arm/include/asm/system_info.h
+++ b/arch/arm/include/asm/system_info.h
@@ -13,6 +13,7 @@
#define CPU_ARCH_ARMv5TEJ 7
#define CPU_ARCH_ARMv6 8
#define CPU_ARCH_ARMv7 9
+#define CPU_ARCH_ARMv8 10
#define CPU_IS_ARM720 0x41007200
#define CPU_IS_ARM720_MASK 0xff00fff0
@@ -41,6 +42,12 @@
#define CPU_IS_CORTEX_A15 0x410fc0f0
#define CPU_IS_CORTEX_A15_MASK 0xff0ffff0
+#define CPU_IS_CORTEX_A53 0x410fd034
+#define CPU_IS_CORTEX_A53_MASK 0xff0ffff0
+
+#define CPU_IS_CORTEX_A57 0x411fd070
+#define CPU_IS_CORTEX_A57_MASK 0xff0ffff0
+
#define CPU_IS_PXA250 0x69052100
#define CPU_IS_PXA250_MASK 0xfffff7f0
@@ -112,6 +119,19 @@
#define cpu_is_cortex_a15() (0)
#endif
+#ifdef CONFIG_CPU_64v8
+#ifdef ARM_ARCH
+#define ARM_MULTIARCH
+#else
+#define ARM_ARCH CPU_ARCH_ARMv8
+#endif
+#define cpu_is_cortex_a53() cpu_is_arm(CORTEX_A53)
+#define cpu_is_cortex_a57() cpu_is_arm(CORTEX_A57)
+#else
+#define cpu_is_cortex_a53() (0)
+#define cpu_is_cortex_a57() (0)
+#endif
+
#ifndef __ASSEMBLY__
#ifdef ARM_MULTIARCH
@@ -133,6 +153,23 @@ static inline int arm_early_get_cpu_architecture(void)
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
} else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_CPU_64v8
+ unsigned int isar2;
+
+ __asm__ __volatile__(
+ "mrs %0, id_isar2_el1\n"
+ : "=r" (isar2)
+ :
+ : "memory");
+
+
+ /* Check Load/Store acquire to check if ARMv8 or not */
+
+ if (isar2 & 0x2)
+ cpu_arch = CPU_ARCH_ARMv8;
+ else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+#else
unsigned int mmfr0;
/* Revised CPUID format. Read the Memory Model Feature
@@ -149,6 +186,7 @@ static inline int arm_early_get_cpu_architecture(void)
cpu_arch = CPU_ARCH_UNKNOWN;
} else
cpu_arch = CPU_ARCH_UNKNOWN;
+#endif
return cpu_arch;
}
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 08/14] arm: cpu: cpuinfo: add armv8 support
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (6 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 07/14] arm: include: system_info: add armv8 identification Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 09/14] arm: cpu: disable code portion in armv8 case Raphael Poggi
` (6 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/cpu/cpuinfo.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/arch/arm/cpu/cpuinfo.c b/arch/arm/cpu/cpuinfo.c
index 8b22e9b..86e19d9 100644
--- a/arch/arm/cpu/cpuinfo.c
+++ b/arch/arm/cpu/cpuinfo.c
@@ -30,12 +30,15 @@
#define CPU_ARCH_ARMv5TEJ 7
#define CPU_ARCH_ARMv6 8
#define CPU_ARCH_ARMv7 9
+#define CPU_ARCH_ARMv8 10
#define ARM_CPU_PART_CORTEX_A5 0xC050
#define ARM_CPU_PART_CORTEX_A7 0xC070
#define ARM_CPU_PART_CORTEX_A8 0xC080
#define ARM_CPU_PART_CORTEX_A9 0xC090
#define ARM_CPU_PART_CORTEX_A15 0xC0F0
+#define ARM_CPU_PART_CORTEX_A53 0xD030
+#define ARM_CPU_PART_CORTEX_A57 0xD070
static void decode_cache(unsigned long size)
{
@@ -60,6 +63,25 @@ static int do_cpuinfo(int argc, char *argv[])
int i;
int cpu_arch;
+#ifdef CONFIG_CPU_64v8
+ __asm__ __volatile__(
+ "mrs %0, midr_el1\n"
+ : "=r" (mainid)
+ :
+ : "memory");
+
+ __asm__ __volatile__(
+ "mrs %0, ctr_el0\n"
+ : "=r" (cache)
+ :
+ : "memory");
+
+ __asm__ __volatile__(
+ "mrs %0, sctlr_el1\n"
+ : "=r" (cr)
+ :
+ : "memory");
+#else
__asm__ __volatile__(
"mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
: "=r" (mainid)
@@ -74,9 +96,10 @@ static int do_cpuinfo(int argc, char *argv[])
__asm__ __volatile__(
"mrc p15, 0, %0, c1, c0, 0 @ read control reg\n"
- : "=r" (cr)
- :
- : "memory");
+ : "=r" (cr)
+ :
+ : "memory");
+#endif
switch (mainid >> 24) {
case 0x41:
@@ -107,6 +130,23 @@ static int do_cpuinfo(int argc, char *argv[])
if (cpu_arch)
cpu_arch += CPU_ARCH_ARMv3;
} else if ((mainid & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_CPU_64v8
+ unsigned int isar2;
+
+ __asm__ __volatile__(
+ "mrs %0, id_isar2_el1\n"
+ : "=r" (isar2)
+ :
+ : "memory");
+
+
+ /* Check Load/Store acquire to check if ARMv8 or not */
+
+ if (isar2 & 0x2)
+ cpu_arch = CPU_ARCH_ARMv8;
+ else
+ cpu_arch = CPU_ARCH_UNKNOWN;
+#else
unsigned int mmfr0;
/* Revised CPUID format. Read the Memory Model Feature
@@ -121,6 +161,7 @@ static int do_cpuinfo(int argc, char *argv[])
cpu_arch = CPU_ARCH_ARMv6;
else
cpu_arch = CPU_ARCH_UNKNOWN;
+#endif
} else
cpu_arch = CPU_ARCH_UNKNOWN;
@@ -152,6 +193,9 @@ static int do_cpuinfo(int argc, char *argv[])
case CPU_ARCH_ARMv7:
architecture = "v7";
break;
+ case CPU_ARCH_ARMv8:
+ architecture = "v8";
+ break;
case CPU_ARCH_UNKNOWN:
default:
architecture = "Unknown";
@@ -160,7 +204,7 @@ static int do_cpuinfo(int argc, char *argv[])
printf("implementer: %s\narchitecture: %s\n",
implementer, architecture);
- if (cpu_arch == CPU_ARCH_ARMv7) {
+ if (cpu_arch >= CPU_ARCH_ARMv7) {
unsigned int major, minor;
char *part;
major = (mainid >> 20) & 0xf;
@@ -181,6 +225,12 @@ static int do_cpuinfo(int argc, char *argv[])
case ARM_CPU_PART_CORTEX_A15:
part = "Cortex-A15";
break;
+ case ARM_CPU_PART_CORTEX_A53:
+ part = "Cortex-A53";
+ break;
+ case ARM_CPU_PART_CORTEX_A57:
+ part = "Cortex-A57";
+ break;
default:
part = "unknown";
}
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 09/14] arm: cpu: disable code portion in armv8 case
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (7 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 08/14] arm: cpu: cpuinfo: add armv8 support Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 10/14] arm: cpu: add basic arm64 mmu support Raphael Poggi
` (5 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Enclosed by #if directive OMAP specific code
and mmu_disable (ARMv8 code will implemented it somewhere else).
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/cpu/cpu.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index eb12166..cc54324 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -68,6 +68,7 @@ int icache_status(void)
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
@@ -86,6 +87,7 @@ void mmu_disable(void)
}
__mmu_cache_off();
}
+#endif
/**
* Disable MMU and D-cache, flush caches
@@ -100,6 +102,8 @@ static void arch_shutdown(void)
mmu_disable();
flush_icache();
+
+#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
@@ -108,6 +112,7 @@ static void arch_shutdown(void)
__asm__ __volatile__("mrs %0, cpsr" : "=r"(r));
r |= PSR_I_BIT;
__asm__ __volatile__("msr cpsr, %0" : : "r"(r));
+#endif
}
archshutdown_exitcall(arch_shutdown);
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 10/14] arm: cpu: add basic arm64 mmu support
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (8 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 09/14] arm: cpu: disable code portion in armv8 case Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 11/14] arm: boards: add mach-qemu and virt64 board Raphael Poggi
` (4 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
This commit adds basic mmu support, ie:
- DMA cache handling is not supported
- Remapping memory region also
The current mmu setting is:
- 4KB granularity
- 3 level lookup (skipping L0)
- 33 bits per VA
This is based on coreboot and u-boot mmu configuration.
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/cpu/Makefile | 4 +-
arch/arm/cpu/cpu.c | 2 +
arch/arm/cpu/mmu.h | 54 +++++++
arch/arm/cpu/mmu_64.c | 331 +++++++++++++++++++++++++++++++++++++++
arch/arm/include/asm/mmu.h | 14 +-
arch/arm/include/asm/pgtable64.h | 140 +++++++++++++++++
6 files changed, 540 insertions(+), 5 deletions(-)
create mode 100644 arch/arm/cpu/mmu_64.c
create mode 100644 arch/arm/include/asm/pgtable64.h
diff --git a/arch/arm/cpu/Makefile b/arch/arm/cpu/Makefile
index 7eb06fb..331c1cd 100644
--- a/arch/arm/cpu/Makefile
+++ b/arch/arm/cpu/Makefile
@@ -26,8 +26,8 @@ endif
obj-$(CONFIG_CMD_ARM_CPUINFO) += cpuinfo.o
obj-$(CONFIG_CMD_ARM_MMUINFO) += mmuinfo.o
obj-$(CONFIG_OFDEVICE) += dtb.o
-obj-$(CONFIG_MMU) += mmu.o cache.o mmu-early.o
-pbl-$(CONFIG_MMU) += mmu-early.o
+obj-$(CONFIG_MMU) += cache.o
+
ifeq ($(CONFIG_MMU),)
obj-y += no-mmu.o
endif
diff --git a/arch/arm/cpu/cpu.c b/arch/arm/cpu/cpu.c
index cc54324..b480463 100644
--- a/arch/arm/cpu/cpu.c
+++ b/arch/arm/cpu/cpu.c
@@ -100,7 +100,9 @@ static void arch_shutdown(void)
{
uint32_t r;
+#ifdef CONFIG_MMU
mmu_disable();
+#endif
flush_icache();
#if __LINUX_ARM_ARCH__ <= 7
diff --git a/arch/arm/cpu/mmu.h b/arch/arm/cpu/mmu.h
index 79ebc80..186d408 100644
--- a/arch/arm/cpu/mmu.h
+++ b/arch/arm/cpu/mmu.h
@@ -1,6 +1,60 @@
#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
new file mode 100644
index 0000000..bfd80c0
--- /dev/null
+++ b/arch/arm/cpu/mmu_64.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2009-2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ * Copyright (c) 2016 Raphaël Poggi <poggi.raph@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#define pr_fmt(fmt) "mmu: " fmt
+
+#include <common.h>
+#include <dma-dir.h>
+#include <init.h>
+#include <mmu.h>
+#include <errno.h>
+#include <linux/sizes.h>
+#include <asm/memory.h>
+#include <asm/barebox-arm.h>
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <memory.h>
+#include <asm/system_info.h>
+
+#include "mmu.h"
+
+static uint64_t *ttb;
+static int free_idx;
+
+static void arm_mmu_not_initialized_error(void)
+{
+ /*
+ * This means:
+ * - one of the MMU functions like dma_alloc_coherent
+ * or remap_range is called too early, before the MMU is initialized
+ * - Or the MMU initialization has failed earlier
+ */
+ 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;
+ *pt = val;
+}
+
+static uint64_t *create_table(void)
+{
+ uint64_t *new_table = ttb + free_idx * 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)
+{
+ uint64_t *pte;
+ uint64_t block_shift;
+ uint64_t idx;
+ int i;
+
+ pte = ttb;
+
+ for (i = 1; i < 4; i++) {
+ block_shift = level2shift(i);
+ idx = (addr & level2mask(i)) >> block_shift;
+ pte += idx;
+
+ if ((pte_type(pte) != PMD_TYPE_TABLE) || (block_shift <= GRANULE_SIZE_SHIFT))
+ break;
+ else
+ pte = (uint64_t *)(*pte & XLAT_ADDR_MASK);
+ }
+
+ return pte;
+}
+
+static void map_region(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;
+ int level;
+
+ if (!ttb)
+ arm_mmu_not_initialized_error();
+
+ addr = virt;
+
+ attr &= ~(PMD_TYPE_SECT);
+
+ 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);
+
+ 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;
+ addr += block_size;
+ phys += block_size;
+ size -= block_size;
+ break;
+
+ }
+
+ table = get_level_table(pte);
+ }
+
+ }
+}
+
+static void create_sections(uint64_t virt, uint64_t phys, uint64_t size_m, uint64_t flags)
+{
+
+ map_region(virt, phys, size_m, 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);
+ tlb_invalidate();
+
+ return 0;
+}
+
+/*
+ * Prepare MMU for usage enable it.
+ */
+static int mmu_init(void)
+{
+ struct memory_bank *bank;
+
+ if (list_empty(&memory_banks))
+ /*
+ * If you see this it means you have no memory registered.
+ * This can be done either with arm_add_mem_device() in an
+ * initcall prior to mmu_initcall or via devicetree in the
+ * memory node.
+ */
+ 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;
+
+ memset(ttb, 0, GRANULE_SIZE);
+
+ set_ttbr_tcr_mair(current_el(), (uint64_t)ttb, TCR_FLAGS, UNCACHED_MEM);
+ }
+
+ pr_debug("ttb: 0x%p\n", ttb);
+
+ /* create a flat mapping using 1MiB sections */
+ create_sections(0, 0, GRANULE_SIZE, UNCACHED_MEM);
+
+ /* Map sdram cached. */
+ for_each_memory_bank(bank)
+ create_sections(bank->start, bank->start, bank->size, CACHED_MEM);
+
+ 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);
+
+ 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)
+{
+ return (unsigned long)virt;
+}
+
+void *phys_to_virt(unsigned long phys)
+{
+ return (void *)phys;
+}
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 8de6544..f68ab37 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -6,16 +6,24 @@
#include <malloc.h>
#include <xfuncs.h>
+#ifdef CONFIG_CPU_64v8
+#include <asm/pgtable64.h>
+
+#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 <asm/pgtable.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)
+#endif
+
+
struct arm_memory;
-static inline void mmu_enable(void)
-{
-}
+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)
diff --git a/arch/arm/include/asm/pgtable64.h b/arch/arm/include/asm/pgtable64.h
new file mode 100644
index 0000000..20bea5b
--- /dev/null
+++ b/arch/arm/include/asm/pgtable64.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 ARM Ltd.
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+#ifndef __ASM_PGTABLE64_H
+#define __ASM_PGTABLE64_H
+
+#define UL(x) _AC(x, UL)
+
+#define UNUSED_DESC 0x6EbAAD0BBADbA6E0
+
+#define VA_START 0x0
+#define BITS_PER_VA 33
+
+/* Granule size of 4KB is being used */
+#define GRANULE_SIZE_SHIFT 12
+#define GRANULE_SIZE (1 << GRANULE_SIZE_SHIFT)
+#define XLAT_ADDR_MASK ((1UL << BITS_PER_VA) - GRANULE_SIZE)
+#define GRANULE_SIZE_MASK ((1 << GRANULE_SIZE_SHIFT) - 1)
+
+#define BITS_RESOLVED_PER_LVL (GRANULE_SIZE_SHIFT - 3)
+#define L1_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 2)
+#define L2_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 1)
+#define L3_ADDR_SHIFT (GRANULE_SIZE_SHIFT + BITS_RESOLVED_PER_LVL * 0)
+
+
+#define L1_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L1_ADDR_SHIFT)
+#define L2_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L2_ADDR_SHIFT)
+#define L3_ADDR_MASK (((1UL << BITS_RESOLVED_PER_LVL) - 1) << L3_ADDR_SHIFT)
+
+/* These macros give the size of the region addressed by each entry of a xlat
+ table at any given level */
+#define L3_XLAT_SIZE (1UL << L3_ADDR_SHIFT)
+#define L2_XLAT_SIZE (1UL << L2_ADDR_SHIFT)
+#define L1_XLAT_SIZE (1UL << L1_ADDR_SHIFT)
+
+#define GRANULE_MASK GRANULE_SIZE
+
+
+/*
+ * 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)
+
+/*
+ * 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 */
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PTE_ATTRINDX(t) ((t) << 2)
+#define PTE_ATTRINDX_MASK (7 << 2)
+
+/*
+ * Memory types available.
+ */
+#define MT_DEVICE_nGnRnE 0
+#define MT_DEVICE_nGnRE 1
+#define MT_DEVICE_GRE 2
+#define MT_NORMAL_NC 3
+#define MT_NORMAL 4
+#define MT_NORMAL_WT 5
+
+/*
+ * TCR flags.
+ */
+#define TCR_T0SZ(x) ((64 - (x)) << 0)
+#define TCR_IRGN_NC (0 << 8)
+#define TCR_IRGN_WBWA (1 << 8)
+#define TCR_IRGN_WT (2 << 8)
+#define TCR_IRGN_WBNWA (3 << 8)
+#define TCR_IRGN_MASK (3 << 8)
+#define TCR_ORGN_NC (0 << 10)
+#define TCR_ORGN_WBWA (1 << 10)
+#define TCR_ORGN_WT (2 << 10)
+#define TCR_ORGN_WBNWA (3 << 10)
+#define TCR_ORGN_MASK (3 << 10)
+#define TCR_SHARED_NON (0 << 12)
+#define TCR_SHARED_OUTER (2 << 12)
+#define TCR_SHARED_INNER (3 << 12)
+#define TCR_TG0_4K (0 << 14)
+#define TCR_TG0_64K (1 << 14)
+#define TCR_TG0_16K (2 << 14)
+#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_EL1_RSVD (1 << 31)
+#define TCR_EL2_RSVD (1 << 31 | 1 << 23)
+#define TCR_EL3_RSVD (1 << 31 | 1 << 23)
+
+#endif
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 11/14] arm: boards: add mach-qemu and virt64 board
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (9 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 10/14] arm: cpu: add basic arm64 mmu support Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 12/14] arm: include: swab: use rigth assembly for armv8 Raphael Poggi
` (3 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Introduce mach-qemu and add qemu virt64 board which emulates arm64 board.
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/Kconfig | 5 +++
arch/arm/Makefile | 1 +
arch/arm/boards/Makefile | 1 +
arch/arm/boards/qemu-virt64/Kconfig | 8 ++++
arch/arm/boards/qemu-virt64/Makefile | 2 +
arch/arm/boards/qemu-virt64/env/config | 8 ++++
arch/arm/boards/qemu-virt64/init.c | 72 ++++++++++++++++++++++++++++++
arch/arm/boards/qemu-virt64/lowlevel.c | 19 ++++++++
arch/arm/configs/qemu_virt64_defconfig | 47 +++++++++++++++++++
arch/arm/mach-qemu/Kconfig | 18 ++++++++
arch/arm/mach-qemu/Makefile | 1 +
arch/arm/mach-qemu/include/mach/debug_ll.h | 24 ++++++++++
arch/arm/mach-qemu/include/mach/devices.h | 13 ++++++
arch/arm/mach-qemu/virt_devices.c | 30 +++++++++++++
14 files changed, 249 insertions(+)
create mode 100644 arch/arm/boards/qemu-virt64/Kconfig
create mode 100644 arch/arm/boards/qemu-virt64/Makefile
create mode 100644 arch/arm/boards/qemu-virt64/env/config
create mode 100644 arch/arm/boards/qemu-virt64/init.c
create mode 100644 arch/arm/boards/qemu-virt64/lowlevel.c
create mode 100644 arch/arm/configs/qemu_virt64_defconfig
create mode 100644 arch/arm/mach-qemu/Kconfig
create mode 100644 arch/arm/mach-qemu/Makefile
create mode 100644 arch/arm/mach-qemu/include/mach/debug_ll.h
create mode 100644 arch/arm/mach-qemu/include/mach/devices.h
create mode 100644 arch/arm/mach-qemu/virt_devices.c
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 986fdaa..f904579 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -255,6 +255,10 @@ config ARCH_ZYNQ
bool "Xilinx Zynq-based boards"
select HAS_DEBUG_LL
+config ARCH_QEMU
+ bool "ARM QEMU boards"
+ select HAS_DEBUG_LL
+
endchoice
source arch/arm/cpu/Kconfig
@@ -280,6 +284,7 @@ source arch/arm/mach-vexpress/Kconfig
source arch/arm/mach-tegra/Kconfig
source arch/arm/mach-uemd/Kconfig
source arch/arm/mach-zynq/Kconfig
+source arch/arm/mach-qemu/Kconfig
config ARM_ASM_UNIFIED
bool
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2b056af..865de04 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -94,6 +94,7 @@ machine-$(CONFIG_ARCH_VEXPRESS) := vexpress
machine-$(CONFIG_ARCH_TEGRA) := tegra
machine-$(CONFIG_ARCH_UEMD) := uemd
machine-$(CONFIG_ARCH_ZYNQ) := zynq
+machine-$(CONFIG_ARCH_QEMU) := qemu
# Board directory name. This list is sorted alphanumerically
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index 9241b66..c271f5d 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -135,3 +135,4 @@ obj-$(CONFIG_MACH_VIRT2REAL) += virt2real/
obj-$(CONFIG_MACH_ZEDBOARD) += avnet-zedboard/
obj-$(CONFIG_MACH_ZYLONITE) += zylonite/
obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/
+obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/
diff --git a/arch/arm/boards/qemu-virt64/Kconfig b/arch/arm/boards/qemu-virt64/Kconfig
new file mode 100644
index 0000000..b7bee3a
--- /dev/null
+++ b/arch/arm/boards/qemu-virt64/Kconfig
@@ -0,0 +1,8 @@
+
+if MACH_QEMU
+
+config ARCH_TEXT_BASE
+ hex
+ default 0x40000000
+
+endif
diff --git a/arch/arm/boards/qemu-virt64/Makefile b/arch/arm/boards/qemu-virt64/Makefile
new file mode 100644
index 0000000..2da0494
--- /dev/null
+++ b/arch/arm/boards/qemu-virt64/Makefile
@@ -0,0 +1,2 @@
+obj-y += init.o
+lwl-y += lowlevel.o
diff --git a/arch/arm/boards/qemu-virt64/env/config b/arch/arm/boards/qemu-virt64/env/config
new file mode 100644
index 0000000..781dbfe
--- /dev/null
+++ b/arch/arm/boards/qemu-virt64/env/config
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+autoboot_timeout=3
+
+bootargs="console=ttyAMA0,115200"
+
+# set a fancy prompt (if support is compiled in)
+PS1="\e[1;31m[barebox@\h]:\w\e[0m\n# "
diff --git a/arch/arm/boards/qemu-virt64/init.c b/arch/arm/boards/qemu-virt64/init.c
new file mode 100644
index 0000000..58dba0f
--- /dev/null
+++ b/arch/arm/boards/qemu-virt64/init.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com>
+ *
+ * GPLv2 only
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <asm/system_info.h>
+#include <mach/devices.h>
+#include <environment.h>
+#include <linux/sizes.h>
+#include <io.h>
+#include <globalvar.h>
+#include <asm/mmu.h>
+
+static int virt_mem_init(void)
+{
+ virt_add_ddram(SZ_2G);
+
+ return 0;
+}
+mem_initcall(virt_mem_init);
+
+static int virt_env_init(void)
+{
+ add_cfi_flash_device(0, 0x00000000, SZ_128M, 0);
+
+ devfs_add_partition("nor0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0");
+ devfs_add_partition("nor0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0");
+
+ return 0;
+}
+device_initcall(virt_env_init);
+
+static int virt_console_init(void)
+{
+ virt_register_uart(0);
+
+ return 0;
+}
+console_initcall(virt_console_init);
+
+static int virt_core_init(void)
+{
+ char *hostname = "virt64";
+
+ if (cpu_is_cortex_a53())
+ hostname = "virt64-a53";
+ else if (cpu_is_cortex_a57())
+ hostname = "virt64-a57";
+
+ barebox_set_model("ARM QEMU virt64");
+ barebox_set_hostname(hostname);
+
+ 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/qemu-virt64/lowlevel.c b/arch/arm/boards/qemu-virt64/lowlevel.c
new file mode 100644
index 0000000..a60c4b0
--- /dev/null
+++ b/arch/arm/boards/qemu-virt64/lowlevel.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2013 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * GPLv2 only
+ */
+
+#include <common.h>
+#include <linux/sizes.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <asm/system_info.h>
+
+void barebox_arm_reset_vector(void)
+{
+ arm_cpu_lowlevel_init();
+ arm_setup_stack(0x40000000 + SZ_2G - SZ_16K);
+
+ barebox_arm_entry(0x40000000, SZ_2G, NULL);
+}
diff --git a/arch/arm/configs/qemu_virt64_defconfig b/arch/arm/configs/qemu_virt64_defconfig
new file mode 100644
index 0000000..ed5abef
--- /dev/null
+++ b/arch/arm/configs/qemu_virt64_defconfig
@@ -0,0 +1,47 @@
+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
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qemu-virt64/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_LONGHELP=y
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_GO=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_UIMAGE=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_LOGIN=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_OFTREE=y
+CONFIG_SERIAL_AMBA_PL011=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_DRIVER_CFI=y
+CONFIG_CFI_BUFFER_WRITE=y
+CONFIG_DIGEST_SHA1_GENERIC=y
+CONFIG_DIGEST_SHA256_GENERIC=y
diff --git a/arch/arm/mach-qemu/Kconfig b/arch/arm/mach-qemu/Kconfig
new file mode 100644
index 0000000..d30bae4
--- /dev/null
+++ b/arch/arm/mach-qemu/Kconfig
@@ -0,0 +1,18 @@
+if ARCH_QEMU
+
+config ARCH_TEXT_BASE
+ hex
+ default 0x40000000
+
+choice
+ prompt "ARM Board type"
+
+config MACH_QEMU_VIRT64
+ bool "QEMU arm64 virt machine"
+ select CPU_V8
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select ARM_AMBA
+ select HAVE_CONFIGURABLE_MEMORY_LAYOUT
+
+endchoice
+endif
diff --git a/arch/arm/mach-qemu/Makefile b/arch/arm/mach-qemu/Makefile
new file mode 100644
index 0000000..ece277c
--- /dev/null
+++ b/arch/arm/mach-qemu/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_MACH_QEMU_VIRT64) += virt_devices.o
diff --git a/arch/arm/mach-qemu/include/mach/debug_ll.h b/arch/arm/mach-qemu/include/mach/debug_ll.h
new file mode 100644
index 0000000..89b0692
--- /dev/null
+++ b/arch/arm/mach-qemu/include/mach/debug_ll.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2013 Jean-Christophe PLAGNIOL-VILLARD <plagniol@jcrosoft.com>
+ *
+ * GPLv2 only
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <io.h>
+
+#define DEBUG_LL_PHYS_BASE 0x10000000
+#define DEBUG_LL_PHYS_BASE_RS1 0x1c000000
+
+#ifdef MP
+#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE
+#else
+#define DEBUG_LL_UART_ADDR DEBUG_LL_PHYS_BASE_RS1
+#endif
+
+#include <asm/debug_ll_pl011.h>
+
+#endif
diff --git a/arch/arm/mach-qemu/include/mach/devices.h b/arch/arm/mach-qemu/include/mach/devices.h
new file mode 100644
index 0000000..9872c61
--- /dev/null
+++ b/arch/arm/mach-qemu/include/mach/devices.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com>
+ *
+ * GPLv2 only
+ */
+
+#ifndef __ASM_ARCH_DEVICES_H__
+#define __ASM_ARCH_DEVICES_H__
+
+void virt_add_ddram(u32 size);
+void virt_register_uart(unsigned id);
+
+#endif /* __ASM_ARCH_DEVICES_H__ */
diff --git a/arch/arm/mach-qemu/virt_devices.c b/arch/arm/mach-qemu/virt_devices.c
new file mode 100644
index 0000000..999f463
--- /dev/null
+++ b/arch/arm/mach-qemu/virt_devices.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2016 Raphaël Poggi <poggi.raph@gmail.com>
+ *
+ * GPLv2 only
+ */
+
+#include <common.h>
+#include <linux/amba/bus.h>
+#include <asm/memory.h>
+#include <mach/devices.h>
+#include <linux/ioport.h>
+
+void virt_add_ddram(u32 size)
+{
+ arm_add_mem_device("ram0", 0x40000000, size);
+}
+
+void virt_register_uart(unsigned id)
+{
+ resource_size_t start;
+
+ switch (id) {
+ case 0:
+ start = 0x09000000;
+ break;
+ default:
+ return;
+ }
+ amba_apb_device_add(NULL, "uart-pl011", id, start, 4096, NULL, 0);
+}
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 12/14] arm: include: swab: use rigth assembly for armv8
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (10 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 11/14] arm: boards: add mach-qemu and virt64 board Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 13/14] uimage: add define for ARM64 architecture Raphael Poggi
` (2 subsequent siblings)
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
arch/arm/include/asm/swab.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
index 9997ad2..3795437 100644
--- a/arch/arm/include/asm/swab.h
+++ b/arch/arm/include/asm/swab.h
@@ -33,7 +33,11 @@ static inline __attribute_const__ __u16 __arch_swab16(__u16 x)
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
{
+#if __LINUX_ARM_ARCH__ == 8
+ __asm__ ("rev %w0, %w1" : "=r" (x) : "r" (x));
+#else
__asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
+#endif
return x;
}
#define __arch_swab32 __arch_swab32
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 13/14] uimage: add define for ARM64 architecture
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (11 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 12/14] arm: include: swab: use rigth assembly for armv8 Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 14/14] Documentation: add aarch64-qemu-virt board doc Raphael Poggi
2016-07-06 8:37 ` [PATCH v5 0/14] Add basic support for arm64 Sascha Hauer
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
common/image.c | 1 +
include/image.h | 5 +++++
2 files changed, 6 insertions(+)
diff --git a/common/image.c b/common/image.c
index f3ec071..04cd86b 100644
--- a/common/image.c
+++ b/common/image.c
@@ -59,6 +59,7 @@ static table_entry_t arch_name[] = {
{ IH_ARCH_AVR32, "avr32", "AVR32", },
{ IH_ARCH_NDS32, "nds32", "NDS32", },
{ IH_ARCH_OPENRISC, "or1k", "OpenRISC 1000",},
+ { IH_ARCH_ARM64, "arm64", "AArch64", },
{ -1, "", "", },
};
diff --git a/include/image.h b/include/image.h
index 07ab0f1..3e75d49 100644
--- a/include/image.h
+++ b/include/image.h
@@ -84,11 +84,16 @@
#define IH_ARCH_SANDBOX 19 /* Sandbox architecture (test only) */
#define IH_ARCH_NDS32 20 /* ANDES Technology - NDS32 */
#define IH_ARCH_OPENRISC 21 /* OpenRISC 1000 */
+#define IH_ARCH_ARM64 22 /* ARM64 */
#if defined(__PPC__)
#define IH_ARCH IH_ARCH_PPC
#elif defined(__ARM__)
+#ifdef CONFIG_CPU_64v8
+#define IH_ARCH IH_ARCH_ARM64
+#else
#define IH_ARCH IH_ARCH_ARM
+#endif
#elif defined(__I386__) || defined(__x86_64__) || defined(__i386__)
#define IH_ARCH IH_ARCH_I386
#elif defined(__mips__)
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v5 14/14] Documentation: add aarch64-qemu-virt board doc.
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (12 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 13/14] uimage: add define for ARM64 architecture Raphael Poggi
@ 2016-07-04 11:52 ` Raphael Poggi
2016-07-06 8:37 ` [PATCH v5 0/14] Add basic support for arm64 Sascha Hauer
14 siblings, 0 replies; 16+ messages in thread
From: Raphael Poggi @ 2016-07-04 11:52 UTC (permalink / raw)
To: barebox; +Cc: Raphael Poggi
Signed-off-by: Raphael Poggi <poggi.raph@gmail.com>
---
Documentation/boards/aarch64-qemu-virt.rst | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 Documentation/boards/aarch64-qemu-virt.rst
diff --git a/Documentation/boards/aarch64-qemu-virt.rst b/Documentation/boards/aarch64-qemu-virt.rst
new file mode 100644
index 0000000..b6b446e
--- /dev/null
+++ b/Documentation/boards/aarch64-qemu-virt.rst
@@ -0,0 +1,13 @@
+===========
+
+Aarch64 Qemu virt
+------------------------
+
+Running barebox on QEMU aarch64 virt machine
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Usage::
+ $ qemu-system-aarch64 -m 2048M \
+ -cpu cortex-a57 -machine virt \
+ -display none -serial stdio \
+ -kernel ../barebox/barebox
--
2.1.0
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v5 0/14] Add basic support for arm64
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
` (13 preceding siblings ...)
2016-07-04 11:52 ` [PATCH v5 14/14] Documentation: add aarch64-qemu-virt board doc Raphael Poggi
@ 2016-07-06 8:37 ` Sascha Hauer
14 siblings, 0 replies; 16+ messages in thread
From: Sascha Hauer @ 2016-07-06 8:37 UTC (permalink / raw)
To: Raphael Poggi; +Cc: barebox
On Mon, Jul 04, 2016 at 01:52:43PM +0200, Raphael Poggi wrote:
> Chance since v4:
> PATCH 14/14 new patch, add documentation about aarch64 qemu virt
>
> Change since v3:
> PATCH 2/14 remove hunk belonging to PATCH 3/14
>
> PATCH 3/14 create a lib/ for common code and lib32/ lib64/
>
> PATCH 4/14 add setupc_64, for now setup_c() only memset bss
>
> PATCH 12/14 use default memory layout, chance TEXT_BASE address to let
> malloc space below
>
> Change since v2:
> PATCH 1/14 add PHYS_ADDR_T_64BIT config
>
> PATCH 3/14 remove modules.c and clean atags functions in armlinux.c,
> and fix also parameters passed to linux kernel.
>
> PATCH 12/14 move lowlevel file from mach-qemu/ to boards/ (like others boards)
> split dram and flash init
> increase dram/flash size
>
> PATCH 13/14 new patch, in case of armv8, swab need to be done on 32-bit wide register
> otherwise swapping the value: "0xAAAABBBB" will become "0xAAAABBBB00000000"
> and see as a null value in uint32_t variable.
>
> PATCH 14/14 new patch, add define to handle arm64 uimage format
>
>
> Change since v1:
> PATCH 2/12: remove hunk which belongs to patch adding mach-qemu
>
> PATCH 3/12: remove unused files
>
> PATCH 4/12: create lowlevel64
>
> PATCH 11/12: create pgtables64 (nothing in common with the arm32 version)
>
> PATCH 12/12: rename "mach-virt" => "mach-qemu"
> rename board "qemu_virt64"
> remove board env files
>
>
> Hello,
>
> This patch series introduces a basic support for arm64.
>
> The arm64 code is merged in the current arch/arm directory.
> I try to be iterative in the merge process, and find correct solutions
> to handle both architecture at some places.
>
> I test the patch series by compiling arm64 virt machine and arm32 vexpress-a9 and test it
> in qemu, everything seems to work.
Applied, thanks
This series currently runs through my compile tester, but if that works
consider this series applied.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2016-07-06 8:37 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-04 11:52 [PATCH v5 0/14] Add basic support for arm64 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 01/14] arm64: add armv8 Kconfig entries Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 02/14] arm: Makefile: rework makefile to handle armv8 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 03/14] arm: rework lib directory to support arm64 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 04/14] arm: cpu: add arm64 specific code Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 05/14] arm: include: system: add arm64 helper functions Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 06/14] arm: include: bitops: arm64 use generic __fls Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 07/14] arm: include: system_info: add armv8 identification Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 08/14] arm: cpu: cpuinfo: add armv8 support Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 09/14] arm: cpu: disable code portion in armv8 case Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 10/14] arm: cpu: add basic arm64 mmu support Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 11/14] arm: boards: add mach-qemu and virt64 board Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 12/14] arm: include: swab: use rigth assembly for armv8 Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 13/14] uimage: add define for ARM64 architecture Raphael Poggi
2016-07-04 11:52 ` [PATCH v5 14/14] Documentation: add aarch64-qemu-virt board doc Raphael Poggi
2016-07-06 8:37 ` [PATCH v5 0/14] Add basic support for arm64 Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox