
From: David Feng fenghua@phytium.com.cn
This patch provide u-boot with arm64 support. Currently, it works on Foundation Model for armv8 or Fast Model for armv8.
Signed-off-by: David Feng fenghua@phytium.com.cn --- Changes for v3: - rewrite cache.S and exception.S that partly originated from linux kernel, so the license should be ok.
arch/arm64/config.mk | 32 +++++ arch/arm64/cpu/armv8/Makefile | 51 +++++++ arch/arm64/cpu/armv8/cache.S | 144 +++++++++++++++++++ arch/arm64/cpu/armv8/config.mk | 29 ++++ arch/arm64/cpu/armv8/cpu.c | 108 ++++++++++++++ arch/arm64/cpu/armv8/exceptions.S | 189 +++++++++++++++++++++++++ arch/arm64/cpu/armv8/start.S | 197 ++++++++++++++++++++++++++ arch/arm64/cpu/armv8/tlb.S | 38 +++++ arch/arm64/cpu/u-boot.lds | 73 ++++++++++ arch/arm64/dts/aemv8a.dtsi | 234 +++++++++++++++++++++++++++++++ arch/arm64/include/asm/arch-armv8/mmu.h | 117 ++++++++++++++++ arch/arm64/include/asm/atomic.h | 115 +++++++++++++++ arch/arm64/include/asm/bitops.h | 153 ++++++++++++++++++++ arch/arm64/include/asm/byteorder.h | 31 ++++ arch/arm64/include/asm/cache.h | 53 +++++++ arch/arm64/include/asm/config.h | 41 ++++++ arch/arm64/include/asm/errno.h | 1 + arch/arm64/include/asm/global_data.h | 38 +++++ arch/arm64/include/asm/gpio.h | 1 + arch/arm64/include/asm/io.h | 193 +++++++++++++++++++++++++ arch/arm64/include/asm/linkage.h | 49 +++++++ arch/arm64/include/asm/posix_types.h | 61 ++++++++ arch/arm64/include/asm/processor.h | 59 ++++++++ arch/arm64/include/asm/ptrace.h | 64 +++++++++ arch/arm64/include/asm/sections.h | 27 ++++ arch/arm64/include/asm/string.h | 49 +++++++ arch/arm64/include/asm/system.h | 106 ++++++++++++++ arch/arm64/include/asm/types.h | 67 +++++++++ arch/arm64/include/asm/u-boot.h | 38 +++++ arch/arm64/include/asm/unaligned.h | 28 ++++ arch/arm64/include/asm/utils.h | 56 ++++++++ 31 files changed, 2442 insertions(+) create mode 100644 arch/arm64/config.mk create mode 100644 arch/arm64/cpu/armv8/Makefile create mode 100644 arch/arm64/cpu/armv8/cache.S create mode 100644 arch/arm64/cpu/armv8/config.mk create mode 100644 arch/arm64/cpu/armv8/cpu.c create mode 100644 arch/arm64/cpu/armv8/exceptions.S create mode 100644 arch/arm64/cpu/armv8/start.S create mode 100644 arch/arm64/cpu/armv8/tlb.S create mode 100644 arch/arm64/cpu/u-boot.lds create mode 100644 arch/arm64/dts/aemv8a.dtsi create mode 100644 arch/arm64/include/asm/arch-armv8/mmu.h create mode 100644 arch/arm64/include/asm/atomic.h create mode 100644 arch/arm64/include/asm/bitops.h create mode 100644 arch/arm64/include/asm/byteorder.h create mode 100644 arch/arm64/include/asm/cache.h create mode 100644 arch/arm64/include/asm/config.h create mode 100644 arch/arm64/include/asm/errno.h create mode 100644 arch/arm64/include/asm/global_data.h create mode 100644 arch/arm64/include/asm/gpio.h create mode 100644 arch/arm64/include/asm/io.h create mode 100644 arch/arm64/include/asm/linkage.h create mode 100644 arch/arm64/include/asm/posix_types.h create mode 100644 arch/arm64/include/asm/processor.h create mode 100644 arch/arm64/include/asm/ptrace.h create mode 100644 arch/arm64/include/asm/sections.h create mode 100644 arch/arm64/include/asm/string.h create mode 100644 arch/arm64/include/asm/system.h create mode 100644 arch/arm64/include/asm/types.h create mode 100644 arch/arm64/include/asm/u-boot.h create mode 100644 arch/arm64/include/asm/unaligned.h create mode 100644 arch/arm64/include/asm/utils.h
diff --git a/arch/arm64/config.mk b/arch/arm64/config.mk new file mode 100644 index 0000000..6ca9a04 --- /dev/null +++ b/arch/arm64/config.mk @@ -0,0 +1,32 @@ +# +# Copyright (c) 2013 FengHua fenghua@phytium.com.cn +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +CROSS_COMPILE ?= aarch64-linux-gnu- + +ifndef CONFIG_STANDALONE_LOAD_ADDR +CONFIG_STANDALONE_LOAD_ADDR = 0x81000000 +endif + +PLATFORM_CPPFLAGS += -DCONFIG_ARM64 -fpic -mstrict-align + +# needed for relocation +LDFLAGS_u-boot += diff --git a/arch/arm64/cpu/armv8/Makefile b/arch/arm64/cpu/armv8/Makefile new file mode 100644 index 0000000..1a8cdd7 --- /dev/null +++ b/arch/arm64/cpu/armv8/Makefile @@ -0,0 +1,51 @@ +# +# Copyright (c) 2013 FengHua fenghua@phytium.com.cn +# +# 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 Foundatio; 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB = $(obj)lib$(CPU).o + +START := start.o + +COBJS += cpu.o + +SOBJS += exceptions.o +SOBJS += cache.o +SOBJS += tlb.o + +SRCS := $(START:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) +START := $(addprefix $(obj),$(START)) + +all: $(obj).depend $(START) $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm64/cpu/armv8/cache.S b/arch/arm64/cpu/armv8/cache.S new file mode 100644 index 0000000..104d15c --- /dev/null +++ b/arch/arm64/cpu/armv8/cache.S @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> + +/* + * void __flush_dcache_level(level) + * + * clean and invalidate one level cache. + * + * x0: cache level + * x1~x9: clobbered + */ +ENTRY(__flush_dcache_level) + lsl x1, x0, #1 + msr csselr_el1, x1 /* select cache level */ + isb /* isb to sych the new cssr&csidr */ + mrs x6, ccsidr_el1 /* read the new ccsidr */ + and x2, x6, #7 /* x2 = length of the cache lines */ + add x2, x2, #4 /* add 4 (line length offset) */ + mov x3, #0x3ff + and x3, x3, x6, lsr #3 /* x3 = maximum number of the way size */ + clz w5, w3 /* bit position of way size */ + mov x4, #0x7fff + and x4, x4, x1, lsr #13 /* x4 = max number of the set size */ + /* x1 = cache level << 1 */ + /* x2 = line length offset */ + /* x3 = number of cache ways */ + /* x4 = number of cache sets */ + /* x5 = bit position of way size */ + +loop_set: + mov x6, x3 /* create working copy of way size */ +loop_way: + lsl x7, x6, x5 + orr x9, x0, x7 /* map way and level to cisw value */ + lsl x7, x4, x2 + orr x9, x9, x7 /* map set number to cisw value */ + dc cisw, x9 /* clean & invalidate by set/way */ + subs x6, x6, #1 /* decrement the way */ + b.ge loop_way + subs x4, x4, #1 /* decrement the set */ + b.ge loop_set + + ret +ENDPROC(__flush_dcache_level) + +/* + * void __flush_dcache_all(void) + * + * clean and invalidate all data cache by SET/WAY. + */ +ENTRY(__flush_dcache_all) + dsb sy + mov x15, lr + mrs x10, clidr_el1 /* read clidr */ + lsr x11, x10, #24 + and x11, x11, #0x7 /* x11 = loc */ + cbz x11, finished /* if loc = 0, no need to clean */ + mov x0, #0 /* start flush at cache level 0 */ + /* x0 = level */ + /* x10 = clidr_el1 */ + /* x11 = loc */ + +loop_level: + lsl x1, x0, #1 + add x1, x1, x0 /* x0 = 3x cache level */ + lsr x1, x10, x1 + and x1, x1, #7 /* x1 = cache type */ + cmp x1, #2 + b.lt skip /* skip if no cache or icache */ + bl __flush_dcache_level /* flush dcache of level */ +skip: + add x0, x0, #1 /* increment cache level */ + cmp x11, x0 + b.gt loop_level + +finished: + mov x0, #0 + msr csselr_el1, x0 /* swith back to cache level 0 */ + dsb sy + isb + mov lr, x15 + ret +ENDPROC(__flush_dcache_all) + +/* + * void __flush_dcache_range(start, end) + * + * clean & invalidate data cache in the range + * + * x0: start address + * x1: end address + */ +ENTRY(__flush_dcache_range) + mrs x3, ctr_el0 /* read CTR */ + lsr x3, x3, #16 + and x3, x3, #0xf /* cache line size encoding */ + mov x2, #4 /* bytes per word */ + lsl x2, x2, x3 /* actual 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 D line / unified line */ + add x0, x0, x2 + cmp x0, x1 + b.lo 1b + dsb sy + ret +ENDPROC(__flush_dcache_range) + +/* + * void __invalidate_icache_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__invalidate_icache_all) + ic ialluis + isb sy + ret +ENDPROC(__invalidate_icache_all) diff --git a/arch/arm64/cpu/armv8/config.mk b/arch/arm64/cpu/armv8/config.mk new file mode 100644 index 0000000..113075c --- /dev/null +++ b/arch/arm64/cpu/armv8/config.mk @@ -0,0 +1,29 @@ +# +# Copyright (c) 2013 FengHua fenghua@phytium.com.cn +# +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# +PLATFORM_RELFLAGS += -fno-common -ffixed-x18 + +PF_CPPFLAGS_ARMV8 := $(call cc-option, -march=armv8-a) +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV8) + +# SEE README.arm-unaligned-accesses +PF_NO_UNALIGNED := $(call cc-option, -mstrict-align) +PLATFORM_NO_UNALIGNED := $(PF_NO_UNALIGNED) diff --git a/arch/arm64/cpu/armv8/cpu.c b/arch/arm64/cpu/armv8/cpu.c new file mode 100644 index 0000000..7c6f158 --- /dev/null +++ b/arch/arm64/cpu/armv8/cpu.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2008 Texas Insturments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <asm/cache.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Default implementation of arch_cpu_init() + * Real implementation should be in platform code + */ +int __arch_cpu_init(void) +{ + return 0; +} +int arch_cpu_init(void) + __attribute__((weak, alias("__arch_cpu_init"))); + +/* + * Default implementation of dram_init() + * Real implementation should be in platform code + */ +int __dram_init(void) +{ + int i; + + gd->ram_size = PHYS_SDRAM_1_SIZE; + + gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + + puts("RAM Configuration:\n"); + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + printf(" Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); + print_size(gd->bd->bi_dram[i].size, "\n"); + } + + return 0; +} +int dram_init(void) + __attribute__((weak, alias("__dram_init"))); + + +int cleanup_before_linux(void) +{ + /* + * this function is called just before we call linux + * it prepares the processor for linux + */ + disable_interrupts(); + + /* + * Turn off I-cache and invalidate it + */ + icache_disable(); + invalidate_icache_all(); + + /* + * turn off D-cache + * dcache_disable() in turn flushes the d-cache and disables MMU + */ + dcache_disable(); + outer_cache_disable(); + + /* + * After D-cache is flushed and before it is disabled there may + * be some new valid entries brought into the cache. We are sure + * that these lines are not dirty and will not affect our execution. + * (because unwinding the call-stack and setting a bit in CP15 SCTRL + * is all we did during this. We have not pushed anything on to the + * stack. Neither have we affected any static data) + * So just invalidate the entire d-cache again to avoid coherency + * problems for kernel + */ + invalidate_dcache_all(); + + return 0; +} diff --git a/arch/arm64/cpu/armv8/exceptions.S b/arch/arm64/cpu/armv8/exceptions.S new file mode 100644 index 0000000..060bd22 --- /dev/null +++ b/arch/arm64/cpu/armv8/exceptions.S @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <asm/ptrace.h> +#include <linux/linkage.h> + +/* + * Exception vectors. + */ + .align 11 +ENTRY(vectors) + ventry el_current_sync_invalid /* Current EL Synchronous Thread */ + ventry el_current_irq_invalid /* Current EL IRQ Thread */ + ventry el_current_fiq_invalid /* Current EL FIQ Thread */ + ventry el_current_error_invalid /* Current EL Error Thread */ + + ventry el_current_sync_invalid /* Current EL Synchronous Handler */ + ventry el_current_irq_invalid /* Current EL IRQ Handler */ + ventry el_current_fiq_invalid /* Current EL FIQ Handler */ + ventry el_current_error_invalid /* Current EL Error Handler */ + + ventry el_lower_sync_invalid /* Lower EL Synchronous 64-bit Handler */ + ventry el_lower_irq_invalid /* Lower EL IRQ 64-bit Handler */ + ventry el_lower_fiq_invalid /* Lower EL FIQ 64-bit Handler */ + ventry el_lower_error_invalid /* Lower EL Error 64-bit Handler */ + + ventry el_lower_sync_invalid /* Lower EL Synchronous 32-bit Handler */ + ventry el_lower_irq_invalid /* Lower EL IRQ 32-bit Handler */ + ventry el_lower_fiq_invalid /* Lower EL FIQ 32-bit Handler */ + ventry el_lower_error_invalid /* Lower EL Error 32-bit Handler */ +END(vectors) + +/* + * Enter Exception. + * This will save the processor state that is X0~X29/LR/SP/ELR/PSTATE + * to the stack frame. + */ +.macro exception_entry, el + sub sp, sp, #S_FRAME_SIZE - S_LR /* LR,SP,ELR,PSTATE will be saved later */ + push x28, x29 + push x26, x27 + push x24, x25 + push x22, x23 + push x20, x21 + push x18, x19 + push x16, x17 + push x14, x15 + push x12, x13 + push x10, x11 + push x8, x9 + push x6, x7 + push x4, x5 + push x2, x3 + push x0, x1 + .if \el == 2 + add x21, sp, #S_FRAME_SIZE + .else + mrs x21, sp_el1 + .endif + mrs x22, elr_el2 + mrs x23, spsr_el2 + stp lr, x21, [sp, #S_LR] + stp x22, x23, [sp, #S_PC] +.endm + +/* + * Exit Exception. + * This will restore the processor state that is X0~X29/LR/SP/ELR/PSTATE + * from the stack frame and return from exceprion. + */ +.macro exception_exit, el + ldp x21, x22, [sp, #S_PC] + msr elr_el2, x21 /* restore elr register */ + msr spsr_el2, x22 /* restore spsr register */ + .if \el == 1 + ldr x23, [sp, #S_SP] + msr sp_el1, x23 /* restore return stack pointer */ + .endif + pop x0, x1 /* restore the general registers */ + pop x2, x3 + pop x4, x5 + pop x6, x7 + pop x8, x9 + pop x10, x11 + pop x12, x13 + pop x14, x15 + pop x16, x17 + pop x18, x19 + pop x20, x21 + pop x22, x23 + pop x24, x25 + pop x26, x27 + pop x28, x29 + ldr lr, [sp], #S_FRAME_SIZE - S_LR /* restore LR and SP */ + eret /* exception return */ +.endm + +/* + * Current EL exception entry + */ +ENTRY(el_current_sync_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_SYNC + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_sync_invalid) + +ENTRY(el_current_irq_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_IRQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_irq_invalid) + +ENTRY(el_current_fiq_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_FIQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_fiq_invalid) + +ENTRY(el_current_error_invalid) + exception_entry 2 + mov x0, sp + mov x1, #EXCEPTION_ERROR + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_current_error_invalid) + + +/* + * Lower EL exception entry + */ +ENTRY(el_lower_sync_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_SYNC + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_sync_invalid) + +ENTRY(el_lower_irq_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_IRQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_irq_invalid) + +ENTRY(el_lower_fiq_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_FIQ + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_fiq_invalid) + +ENTRY(el_lower_error_invalid) + exception_entry 1 + mov x0, sp + mov x1, #EXCEPTION_ERROR + mrs x2, esr_el2 + b bad_mode +ENDPROC(el_lower_error_invalid) diff --git a/arch/arm64/cpu/armv8/start.S b/arch/arm64/cpu/armv8/start.S new file mode 100644 index 0000000..06d8caa --- /dev/null +++ b/arch/arm64/cpu/armv8/start.S @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> +#include <asm/arch/mmu.h> + +/************************************************************************* + * + * Startup Code (reset vector) + * + *************************************************************************/ + +.globl _start +_start: + b reset + + .align 3 + +.globl _TEXT_BASE +_TEXT_BASE: + .quad CONFIG_SYS_TEXT_BASE + +.globl _end_ofs +_end_ofs: + .quad _end - _start + +.globl _bss_start_ofs +_bss_start_ofs: + .quad __bss_start - _start + +.globl _bss_end_ofs +_bss_end_ofs: + .quad __bss_end - _start + +reset: + /* + * EL3 initialisation + */ + mrs x0, CurrentEL + cmp x0, #0xc /* EL3? */ + b.ne reset_nonsecure /* skip EL3 initialisation */ + + mov x0, #0x30 /* RES1 */ + orr x0, x0, #(1 << 0) /* Non-secure EL1 */ + orr x0, x0, #(1 << 8) /* HVC enable */ + orr x0, x0, #(1 << 10) /* 64-bit EL2 */ + msr scr_el3, x0 + + msr cptr_el3, xzr /* Disable copro. traps to EL3 */ + + /* Counter frequency initialisation */ + ldr x0, =CONFIG_SYS_CNTFRQ + msr cntfrq_el0, x0 + + /* GIC initialisation */ + mrs x0, mpidr_el1 + tst x0, #15 + b.ne 1f /* secondary CPU */ + + ldr x1, =GIC_DIST_BASE /* GICD_CTLR */ + mov w0, #3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1] + +1: ldr x1, =GIC_DIST_BASE + 0x80 /* GICD_IGROUPR */ + mov w0, #~0 /* Grp1 interrupts */ + str w0, [x1], #4 + b.ne 2f /* Only local interrupts for secondary CPUs */ + str w0, [x1], #4 + str w0, [x1], #4 + +2: ldr x1, =GIC_CPU_BASE /* GICC_CTLR */ + ldr w0, [x1] + mov w0, #3 /* EnableGrp0 | EnableGrp1 */ + str w0, [x1] + + mov w0, #1 << 7 /* allow NS access to GICC_PMR */ + str w0, [x1, #4] /* GICC_PMR */ + + /* SCTLR_EL2 initialisation */ + msr sctlr_el2, xzr + + /* Return to the EL2_SP1 mode from EL3 */ + adr x0, reset_nonsecure + mov x1, #0x3c9 /* EL2_SP1 | D | A | I | F */ + msr elr_el3, x0 + msr spsr_el3, x1 + eret + + /* + * EL2 initialisation: + * MMU Disabled, iCache Disabled, dCache Disabled + */ +reset_nonsecure: + /* SCTLR_EL2 initialisation */ + mov x0, #0x2 /* Alignment check enable */ + msr sctlr_el2, x0 + + /* Initialize vBAR */ + adr x0, vectors + msr vbar_el2, x0 + + /* Cache/BPB/TLB Invalidate */ + bl __flush_dcache_all /* dCache invalidate */ + bl __invalidate_icache_all /* iCache invalidate */ + bl __invalidate_tlb_all /* invalidate I + D TLBs */ + + /* Processor specific initialisation */ +#ifndef CONFIG_SKIP_LOWLEVEL_INIT + bl lowlevel_init +#endif + + mrs x0, mpidr_el1 + tst x0, #15 + b.eq master_cpu + + /* + * Secondary CPUs + */ +slave_cpu: + + wfe + ldr x1, =SECONDARY_CPU_MAILBOX + ldr x0, [x1] + cbz x0, slave_cpu + br x0 /* branch to the given address */ + + /* + * Primary CPU + */ +master_cpu: + + bl _main + +/*------------------------------------------------------------------------------*/ + +ENTRY(c_runtime_cpu_setup) + /* If I-cache is enabled invalidate it */ +#ifndef CONFIG_SYS_ICACHE_OFF + ic iallu /* I+BTB cache invalidate */ + isb sy +#endif + +#ifndef CONFIG_SYS_DCACHE_OFF + /* + * Memory region attributes: + * + * n = AttrIndx[2:0] + * n MAIR + * DEVICE_nGnRnE 000 00000000 + * DEVICE_nGnRE 001 00000100 + * DEVICE_GRE 010 00001100 + * NORMAL_NC 011 01000100 + * NORMAL 100 11111111 + */ + ldr x0, =MAIR(0x00, MT_DEVICE_nGnRnE) | \ + MAIR(0x04, MT_DEVICE_nGnRE) | \ + MAIR(0x0c, MT_DEVICE_GRE) | \ + MAIR(0x44, MT_NORMAL_NC) | \ + MAIR(0xff, MT_NORMAL) + msr mair_el2, x0 + + /* + * Set/prepare TCR and TTBR. Using 512GB (39-bit) address range. + */ + ldr x0, =TCR_T0SZ(VA_BITS) | TCR_FLAGS | TCR_IPS_40BIT + orr x0, x0, TCR_TG0_64K + msr tcr_el2, x0 +#endif + + /* Relocate vBAR */ + adr x0, vectors + msr vbar_el2, x0 + + ret +ENDPROC(c_runtime_cpu_setup) diff --git a/arch/arm64/cpu/armv8/tlb.S b/arch/arm64/cpu/armv8/tlb.S new file mode 100644 index 0000000..8622157 --- /dev/null +++ b/arch/arm64/cpu/armv8/tlb.S @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <asm-offsets.h> +#include <config.h> +#include <version.h> +#include <linux/linkage.h> + +/* + * void __invalidate_tlb_all(void) + * + * invalidate all tlb entries. + */ +ENTRY(__invalidate_tlb_all) + tlbi alle2 + dsb sy + isb + ret +ENDPROC(__invalidate_tlb_all) diff --git a/arch/arm64/cpu/u-boot.lds b/arch/arm64/cpu/u-boot.lds new file mode 100644 index 0000000..98d01d2 --- /dev/null +++ b/arch/arm64/cpu/u-boot.lds @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 FengHua fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") +OUTPUT_ARCH(aarch64) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(8); + .text : + { + __image_copy_start = .; + CPUDIR/start.o (.text*) + *(.text*) + } + + . = ALIGN(8); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(8); + .data : { + *(.data*) + } + + . = ALIGN(8); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(8); + .reloc : { + __rel_got_start = .; + *(.got) + __rel_got_end = .; + } + + __image_copy_end = .; + _end = .; + + . = ALIGN(8); + .bss : { + __bss_start = .; + *(.bss*) + . = ALIGN(8); + __bss_end = .; + } + + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/arch/arm64/dts/aemv8a.dtsi b/arch/arm64/dts/aemv8a.dtsi new file mode 100644 index 0000000..b45e5f3 --- /dev/null +++ b/arch/arm64/dts/aemv8a.dtsi @@ -0,0 +1,234 @@ +/* + * ARM Ltd. Fast Models + * + * Versatile Express (VE) system model + * Motherboard component + * + * VEMotherBoard.lisa + */ + + motherboard { + arm,v2m-memory-map = "rs1"; + compatible = "arm,vexpress,v2m-p1", "simple-bus"; + #address-cells = <2>; /* SMB chipselect number and offset */ + #size-cells = <1>; + #interrupt-cells = <1>; + ranges; + + flash@0,00000000 { + compatible = "arm,vexpress-flash", "cfi-flash"; + reg = <0 0x00000000 0x04000000>, + <4 0x00000000 0x04000000>; + bank-width = <4>; + }; + + vram@2,00000000 { + compatible = "arm,vexpress-vram"; + reg = <2 0x00000000 0x00800000>; + }; + + ethernet@2,02000000 { + compatible = "smsc,lan91c111"; + reg = <2 0x02000000 0x10000>; + interrupts = <15>; + }; + + v2m_clk24mhz: clk24mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "v2m:clk24mhz"; + }; + + v2m_refclk1mhz: refclk1mhz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <1000000>; + clock-output-names = "v2m:refclk1mhz"; + }; + + v2m_refclk32khz: refclk32khz { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "v2m:refclk32khz"; + }; + + iofpga@3,00000000 { + compatible = "arm,amba-bus", "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 3 0 0x200000>; + + v2m_sysreg: sysreg@010000 { + compatible = "arm,vexpress-sysreg"; + reg = <0x010000 0x1000>; + gpio-controller; + #gpio-cells = <2>; + }; + + v2m_sysctl: sysctl@020000 { + compatible = "arm,sp810", "arm,primecell"; + reg = <0x020000 0x1000>; + clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; + clock-names = "refclk", "timclk", "apb_pclk"; + #clock-cells = <1>; + clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; + }; + + aaci@040000 { + compatible = "arm,pl041", "arm,primecell"; + reg = <0x040000 0x1000>; + interrupts = <11>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + mmci@050000 { + compatible = "arm,pl180", "arm,primecell"; + reg = <0x050000 0x1000>; + interrupts = <9 10>; + cd-gpios = <&v2m_sysreg 0 0>; + wp-gpios = <&v2m_sysreg 1 0>; + max-frequency = <12000000>; + vmmc-supply = <&v2m_fixed_3v3>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "mclk", "apb_pclk"; + }; + + kmi@060000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x060000 0x1000>; + interrupts = <12>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + kmi@070000 { + compatible = "arm,pl050", "arm,primecell"; + reg = <0x070000 0x1000>; + interrupts = <13>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "KMIREFCLK", "apb_pclk"; + }; + + v2m_serial0: uart@090000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x090000 0x1000>; + interrupts = <5>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial1: uart@0a0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0a0000 0x1000>; + interrupts = <6>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial2: uart@0b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0b0000 0x1000>; + interrupts = <7>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + v2m_serial3: uart@0c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0c0000 0x1000>; + interrupts = <8>; + clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; + clock-names = "uartclk", "apb_pclk"; + }; + + wdt@0f0000 { + compatible = "arm,sp805", "arm,primecell"; + reg = <0x0f0000 0x1000>; + interrupts = <0>; + clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; + clock-names = "wdogclk", "apb_pclk"; + }; + + v2m_timer01: timer@110000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x110000 0x1000>; + interrupts = <2>; + clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + v2m_timer23: timer@120000 { + compatible = "arm,sp804", "arm,primecell"; + reg = <0x120000 0x1000>; + interrupts = <3>; + clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; + clock-names = "timclken1", "timclken2", "apb_pclk"; + }; + + rtc@170000 { + compatible = "arm,pl031", "arm,primecell"; + reg = <0x170000 0x1000>; + interrupts = <4>; + clocks = <&v2m_clk24mhz>; + clock-names = "apb_pclk"; + }; + + clcd@1f0000 { + compatible = "arm,pl111", "arm,primecell"; + reg = <0x1f0000 0x1000>; + interrupts = <14>; + clocks = <&v2m_oscclk1>, <&v2m_clk24mhz>; + clock-names = "clcdclk", "apb_pclk"; + }; + }; + + v2m_fixed_3v3: fixedregulator@0 { + compatible = "regulator-fixed"; + regulator-name = "3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + mcc { + compatible = "arm,vexpress,config-bus", "simple-bus"; + arm,vexpress,config-bridge = <&v2m_sysreg>; + + v2m_oscclk1: osc@1 { + /* CLCD clock */ + compatible = "arm,vexpress-osc"; + arm,vexpress-sysreg,func = <1 1>; + freq-range = <23750000 63500000>; + #clock-cells = <0>; + clock-output-names = "v2m:oscclk1"; + }; + + reset@0 { + compatible = "arm,vexpress-reset"; + arm,vexpress-sysreg,func = <5 0>; + }; + + muxfpga@0 { + compatible = "arm,vexpress-muxfpga"; + arm,vexpress-sysreg,func = <7 0>; + }; + + shutdown@0 { + compatible = "arm,vexpress-shutdown"; + arm,vexpress-sysreg,func = <8 0>; + }; + + reboot@0 { + compatible = "arm,vexpress-reboot"; + arm,vexpress-sysreg,func = <9 0>; + }; + + dvimode@0 { + compatible = "arm,vexpress-dvimode"; + arm,vexpress-sysreg,func = <11 0>; + }; + }; + }; diff --git a/arch/arm64/include/asm/arch-armv8/mmu.h b/arch/arm64/include/asm/arch-armv8/mmu.h new file mode 100644 index 0000000..2127649 --- /dev/null +++ b/arch/arm64/include/asm/arch-armv8/mmu.h @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ARMV8_MMU_H_ +#define _ASM_ARMV8_MMU_H_ + +#ifdef __ASSEMBLY__ +#define _AC(X,Y) X +#define _AT(T,X) X +#else +#define __AC(X,Y) (X##Y) +#define _AC(X,Y) __AC(X,Y) +#define _AT(T,X) ((T)(X)) +#endif + +#define UL(x) _AC(x, UL) + +/***************************************************************/ +/* + * The following definitions are related each other, shoud be + * calculated specifically. + */ +#define VA_BITS (39) + +/* PAGE_SHIFT determines the page size */ +#undef PAGE_SIZE +#define PAGE_SHIFT 16 +#define PAGE_SIZE (1 << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) + +/* + * section address mask and size definitions. + */ +#define SECTION_SHIFT 29 +#define SECTION_SIZE (_AC(1, UL) << SECTION_SHIFT) +#define SECTION_MASK (~(SECTION_SIZE-1)) +/***************************************************************/ + +/* + * 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 MAIR(attr, mt) ((attr) << ((mt) * 8)) + +/* + * Hardware page table definitions. + * + * 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) + +/* + * Section + */ +#define PMD_SECT_S (UL(3) << 8) +#define PMD_SECT_AF (UL(1) << 10) +#define PMD_SECT_NG (UL(1) << 11) +#define PMD_SECT_PXN (UL(1) << 53) +#define PMD_SECT_UXN (UL(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) + +/* + * TCR_EL2 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 (3 << 12) +#define TCR_TG0_4K (0 << 14) +#define TCR_TG0_64K (1 << 14) +#define TCR_TG0_16K (2 << 14) +#define TCR_IPS_40BIT (2 << 16) + +/* PTWs cacheable, inner/outer WBWA not shareable */ +#define TCR_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA + +#endif /* _ASM_ARMV8_MMU_H_ */ diff --git a/arch/arm64/include/asm/atomic.h b/arch/arm64/include/asm/atomic.h new file mode 100644 index 0000000..2117ec1 --- /dev/null +++ b/arch/arm64/include/asm/atomic.h @@ -0,0 +1,115 @@ +/* + * linux/include/asm-arm/atomic.h + * + * Copyright (c) 1996 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. + * + * Changelog: + * 27-06-1996 RMK Created + * 13-04-1997 RMK Made functions atomic! + * 07-12-1997 RMK Upgraded for v2.1. + * 26-08-1998 PJB Added #ifdef __KERNEL__ + */ +#ifndef __ASM_ARM64_ATOMIC_H +#define __ASM_ARM64_ATOMIC_H + +#include <linux/config.h> + +#ifdef CONFIG_SMP +#error SMP not supported +#endif + +typedef struct { volatile int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ + +#include <asm/system.h> + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) (((v)->counter) = (i)) + +static inline void atomic_add(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += i; + local_irq_restore(flags); +} + +static inline void atomic_sub(int i, volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= i; + local_irq_restore(flags); +} + +static inline void atomic_inc(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter += 1; + local_irq_restore(flags); +} + +static inline void atomic_dec(volatile atomic_t *v) +{ + unsigned long flags; + + local_irq_save(flags); + v->counter -= 1; + local_irq_restore(flags); +} + +static inline int atomic_dec_and_test(volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val -= 1; + local_irq_restore(flags); + + return val == 0; +} + +static inline int atomic_add_negative(int i, volatile atomic_t *v) +{ + unsigned long flags; + int val; + + local_irq_save(flags); + val = v->counter; + v->counter = val += i; + local_irq_restore(flags); + + return val < 0; +} + +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) +{ + unsigned long flags; + + local_irq_save(flags); + *addr &= ~mask; + local_irq_restore(flags); +} + +/* Atomic operations are already serializing on ARM */ +#define smp_mb__before_atomic_dec() barrier() +#define smp_mb__after_atomic_dec() barrier() +#define smp_mb__before_atomic_inc() barrier() +#define smp_mb__after_atomic_inc() barrier() + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_ATOMIC_H */ diff --git a/arch/arm64/include/asm/bitops.h b/arch/arm64/include/asm/bitops.h new file mode 100644 index 0000000..a1d53eb --- /dev/null +++ b/arch/arm64/include/asm/bitops.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_BITOPS_H +#define __ASM_ARM64_BITOPS_H + +#ifdef __KERNEL__ + +#include <asm/system.h> + +/* + * Function prototypes to keep gcc -Wall happy. + */ +static inline void __change_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + + *p ^= mask; +} + +static inline int __test_and_set_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old | mask; + return (old & mask) != 0; +} + +static inline int test_and_set_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_set_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +static inline int __test_and_clear_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old & ~mask; + return (old & mask) != 0; +} + +static inline int test_and_clear_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_clear_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +static inline int __test_and_change_bit(int nr, volatile void *addr) +{ + unsigned long mask = BIT_MASK(nr); + unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); + unsigned long old = *p; + + *p = old ^ mask; + return (old & mask) != 0; +} + +static inline int test_and_change_bit(int nr, volatile void * addr) +{ + unsigned long flags; + int out; + + local_irq_save(flags); + out = __test_and_change_bit(nr, addr); + local_irq_restore(flags); + + return out; +} + +/* + * This routine doesn't need to be atomic. + */ +static inline int test_bit(int nr, const void * addr) +{ + return ((unsigned char *) addr)[nr >> 3] & (1U << (nr & 7)); +} + +static inline int __ilog2(unsigned int x) +{ + return generic_fls(x) - 1; +} + +/* + * ffz = Find First Zero in word. Undefined if no zero exists, + * so code should check against ~0UL first.. + */ +static inline unsigned long ffz(unsigned long word) +{ + int k; + + word = ~word; + k = 31; + if (word & 0x0000ffff) { k -= 16; word <<= 16; } + if (word & 0x00ff0000) { k -= 8; word <<= 8; } + if (word & 0x0f000000) { k -= 4; word <<= 4; } + if (word & 0x30000000) { k -= 2; word <<= 2; } + if (word & 0x40000000) { k -= 1; } + return k; +} + +/* + * hweightN: returns the hamming weight (i.e. the number + * of bits set) of a N-bit word + */ + +#define hweight32(x) generic_hweight32(x) +#define hweight16(x) generic_hweight16(x) +#define hweight8(x) generic_hweight8(x) + +#define ext2_set_bit test_and_set_bit +#define ext2_clear_bit test_and_clear_bit +#define ext2_test_bit test_bit + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_BITOPS_H */ diff --git a/arch/arm64/include/asm/byteorder.h b/arch/arm64/include/asm/byteorder.h new file mode 100644 index 0000000..d5edfe8 --- /dev/null +++ b/arch/arm64/include/asm/byteorder.h @@ -0,0 +1,31 @@ +/* + * linux/include/asm-arm/byteorder.h + * + * ARM Endian-ness. In little endian mode, the data bus is connected such + * that byte accesses appear as: + * 0 = d0...d7, 1 = d8...d15, 2 = d16...d23, 3 = d24...d31 + * and word accesses (data or instruction) appear as: + * d0...d31 + * + * When in big endian mode, byte accesses appear as: + * 0 = d24...d31, 1 = d16...d23, 2 = d8...d15, 3 = d0...d7 + * and word accesses (data or instruction) appear as: + * d0...d31 + */ +#ifndef __ASM_ARM64_BYTEORDER_H +#define __ASM_ARM64_BYTEORDER_H + +#include <asm/types.h> + +#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) +# define __BYTEORDER_HAS_U64__ +# define __SWAB_64_THRU_32__ +#endif + +#ifdef __BIG_ENDIAN__ +#include <linux/byteorder/big_endian.h> +#else +#include <linux/byteorder/little_endian.h> +#endif + +#endif /* __ASM_ARM64_BYTEORDER_H */ diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h new file mode 100644 index 0000000..e49d2e0 --- /dev/null +++ b/arch/arm64/include/asm/cache.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ARM64_CACHE_H +#define _ASM_ARM64_CACHE_H + +/* + * The current upper bound for ARM L1 data cache line sizes is 64 bytes. We + * use that value for aligning DMA buffers unless the board config has specified + * an alternate cache line size. + */ +#ifdef CONFIG_SYS_CACHELINE_SIZE +#define ARCH_DMA_MINALIGN CONFIG_SYS_CACHELINE_SIZE +#else +#define ARCH_DMA_MINALIGN 64 +#endif + +#ifndef __ASSEMBLY__ + +void __flush_dcache_all(void); +void __flush_dcache_range(unsigned long start, unsigned long stop); +void __invalidate_icache_all(void); +void __invalidate_tlb_all(void); + +void outer_cache_enable(void); +void outer_cache_disable(void); +void outer_cache_flush_all(void); +void outer_cache_inval_all(void); +void outer_cache_flush_range(unsigned long start, unsigned long end); +void outer_cache_inval_range(unsigned long start, unsigned long end); + +#endif /* __ASSEMBLY__ */ + +#endif /* _ASM_ARM64_CACHE_H */ diff --git a/arch/arm64/include/asm/config.h b/arch/arm64/include/asm/config.h new file mode 100644 index 0000000..8fa1b56 --- /dev/null +++ b/arch/arm64/include/asm/config.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ARM64_CONFIG_H_ +#define _ASM_ARM64_CONFIG_H_ + +#define CONFIG_LMB + +#define CONFIG_SYS_BOOT_RAMDISK_HIGH + +/* + * Currently, gcc-aarch64 produce error when compiling with + * -pie and rel_dyn. So, GOT is used to relocate u-boot and + * configuration CONFIG_NEEDS_MANUAL_RELOC is needed. + */ +#define CONFIG_NEEDS_MANUAL_RELOC + +#define CONFIG_SYS_HZ 1000 + +#define CONFIG_PHYS_64BIT + +#endif /* _ASM_ARM64_CONFIG_H_ */ diff --git a/arch/arm64/include/asm/errno.h b/arch/arm64/include/asm/errno.h new file mode 100644 index 0000000..4c82b50 --- /dev/null +++ b/arch/arm64/include/asm/errno.h @@ -0,0 +1 @@ +#include <asm-generic/errno.h> diff --git a/arch/arm64/include/asm/global_data.h b/arch/arm64/include/asm/global_data.h new file mode 100644 index 0000000..13b66d4 --- /dev/null +++ b/arch/arm64/include/asm/global_data.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_GBL_DATA_H +#define __ASM_ARM64_GBL_DATA_H + +/* Architecture-specific global data */ +struct arch_global_data { +#ifndef CONFIG_SYS_DCACHE_OFF + unsigned long tlb_addr; + unsigned long tlb_size; +#endif +}; + +#include <asm-generic/global_data.h> + +#define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm ("x18") + +#endif /* __ASM_ARM64_GBL_DATA_H */ diff --git a/arch/arm64/include/asm/gpio.h b/arch/arm64/include/asm/gpio.h new file mode 100644 index 0000000..306ab4c --- /dev/null +++ b/arch/arm64/include/asm/gpio.h @@ -0,0 +1 @@ +#include <asm-generic/gpio.h> diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h new file mode 100644 index 0000000..398ae53 --- /dev/null +++ b/arch/arm64/include/asm/io.h @@ -0,0 +1,193 @@ +/* + * linux/include/asm-arm/io.h + * + * Copyright (C) 1996-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. + * + * Modifications: + * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both + * constant addresses and variable addresses. + * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture + * specific IO header files. + * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. + * 04-Apr-1999 PJB Added check_signature. + * 12-Dec-1999 RMK More cleanups + * 18-Jun-2000 RMK Removed virt_to_* and friends definitions + */ + +#ifndef __ASM_ARM64_IO_H +#define __ASM_ARM64_IO_H + +#ifdef __KERNEL__ + +#include <linux/types.h> +#include <asm/byteorder.h> + +/* + * Given a physical address and a length, return a virtual address + * that can be used to access the memory range with the caching + * properties specified by "flags". + */ +#define MAP_NOCACHE (0) +#define MAP_WRCOMBINE (0) +#define MAP_WRBACK (0) +#define MAP_WRTHROUGH (0) + +static inline void * +map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags) +{ + return (void *)paddr; +} + +/* + * Take down a mapping set up by map_physmem(). + */ +static inline void unmap_physmem(void *vaddr, unsigned long flags) +{ +} + +static inline phys_addr_t virt_to_phys(void * vaddr) +{ + return (phys_addr_t)(vaddr); +} + +/* + * Generic virtual read/write. Note that we don't support half-word + * read/writes. We define __arch_*[bl] here, and leave __arch_*w + * to the architecture specific code. + */ +#define __arch_getb(a) (*(volatile unsigned char *)(a)) +#define __arch_getw(a) (*(volatile unsigned short *)(a)) +#define __arch_getl(a) (*(volatile unsigned int *)(a)) + +#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v)) +#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v)) +#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v)) + +extern inline void __raw_writesb(unsigned long addr, const void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + __arch_putb(*buf++, addr); +} + +extern inline void __raw_writesw(unsigned long addr, const void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + __arch_putw(*buf++, addr); +} + +extern inline void __raw_writesl(unsigned long addr, const void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + __arch_putl(*buf++, addr); +} + +extern inline void __raw_readsb(unsigned long addr, void *data, int bytelen) +{ + uint8_t *buf = (uint8_t *)data; + while(bytelen--) + *buf++ = __arch_getb(addr); +} + +extern inline void __raw_readsw(unsigned long addr, void *data, int wordlen) +{ + uint16_t *buf = (uint16_t *)data; + while(wordlen--) + *buf++ = __arch_getw(addr); +} + +extern inline void __raw_readsl(unsigned long addr, void *data, int longlen) +{ + uint32_t *buf = (uint32_t *)data; + while(longlen--) + *buf++ = __arch_getl(addr); +} + +#define __raw_writeb(v,a) __arch_putb(v,a) +#define __raw_writew(v,a) __arch_putw(v,a) +#define __raw_writel(v,a) __arch_putl(v,a) + +#define __raw_readb(a) __arch_getb(a) +#define __raw_readw(a) __arch_getw(a) +#define __raw_readl(a) __arch_getl(a) + +/* + * TODO: The kernel offers some more advanced versions of barriers, it might + * have some advantages to use them instead of the simple one here. + */ +#define dmb() __asm__ __volatile__ ("" : : : "memory") +#define __iormb() dmb() +#define __iowmb() dmb() + +#define writeb(v,c) ({ u8 __v = v; __iowmb(); __arch_putb(__v,c); __v; }) +#define writew(v,c) ({ u16 __v = v; __iowmb(); __arch_putw(__v,c); __v; }) +#define writel(v,c) ({ u32 __v = v; __iowmb(); __arch_putl(__v,c); __v; }) + +#define readb(c) ({ u8 __v = __arch_getb(c); __iormb(); __v; }) +#define readw(c) ({ u16 __v = __arch_getw(c); __iormb(); __v; }) +#define readl(c) ({ u32 __v = __arch_getl(c); __iormb(); __v; }) + +/* + * Clear and set bits in one shot. These macros can be used to clear and + * set multiple bits in a register using a single call. These macros can + * also be used to set a multiple-bit bit pattern using a mask, by + * specifying the mask in the 'clear' parameter and the new bit pattern + * in the 'set' parameter. + */ + +#define out_arch(type,endian,a,v) __raw_write##type(cpu_to_##endian(v),a) +#define in_arch(type,endian,a) endian##_to_cpu(__raw_read##type(a)) + +#define out_le32(a,v) out_arch(l,le32,a,v) +#define out_le16(a,v) out_arch(w,le16,a,v) + +#define in_le32(a) in_arch(l,le32,a) +#define in_le16(a) in_arch(w,le16,a) + +#define out_be32(a,v) out_arch(l,be32,a,v) +#define out_be16(a,v) out_arch(w,be16,a,v) + +#define in_be32(a) in_arch(l,be32,a) +#define in_be16(a) in_arch(w,be16,a) + +#define out_8(a,v) __raw_writeb(v,a) +#define in_8(a) __raw_readb(a) + +#define clrbits(type, addr, clear) \ + out_##type((addr), in_##type(addr) & ~(clear)) + +#define setbits(type, addr, set) \ + out_##type((addr), in_##type(addr) | (set)) + +#define clrsetbits(type, addr, clear, set) \ + out_##type((addr), (in_##type(addr) & ~(clear)) | (set)) + +#define clrbits_be32(addr, clear) clrbits(be32, addr, clear) +#define setbits_be32(addr, set) setbits(be32, addr, set) +#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set) + +#define clrbits_le32(addr, clear) clrbits(le32, addr, clear) +#define setbits_le32(addr, set) setbits(le32, addr, set) +#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set) + +#define clrbits_be16(addr, clear) clrbits(be16, addr, clear) +#define setbits_be16(addr, set) setbits(be16, addr, set) +#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set) + +#define clrbits_le16(addr, clear) clrbits(le16, addr, clear) +#define setbits_le16(addr, set) setbits(le16, addr, set) +#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set) + +#define clrbits_8(addr, clear) clrbits(8, addr, clear) +#define setbits_8(addr, set) setbits(8, addr, set) +#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_IO_H */ diff --git a/arch/arm64/include/asm/linkage.h b/arch/arm64/include/asm/linkage.h new file mode 100644 index 0000000..05e909e --- /dev/null +++ b/arch/arm64/include/asm/linkage.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_LINKAGE_H +#define __ASM_ARM64_LINKAGE_H + +/* + * Register aliases. + */ +lr .req x30 // link register + +/* + * Stack pushing/popping (register pairs only). + * Equivalent to store decrement before, + * load increment after. + */ +.macro push, xreg1, xreg2 + stp \xreg1, \xreg2, [sp, #-16]! +.endm + +.macro pop, xreg1, xreg2 + ldp \xreg1, \xreg2, [sp], #16 +.endm + +.macro ventry label + .align 7 + b \label +.endm + +#endif /* __ASM_ARM64_LINKAGE_H */ diff --git a/arch/arm64/include/asm/posix_types.h b/arch/arm64/include/asm/posix_types.h new file mode 100644 index 0000000..d272a35 --- /dev/null +++ b/arch/arm64/include/asm/posix_types.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ARCH_ARM64_POSIX_TYPES_H +#define __ARCH_ARM64_POSIX_TYPES_H + +/* + * This file is generally used by user-level software, so you need to + * be a little careful about namespace pollution etc. Also, we cannot + * assume GCC is being used. + */ + +typedef unsigned short __kernel_dev_t; +typedef unsigned long __kernel_ino_t; +typedef unsigned short __kernel_mode_t; +typedef unsigned short __kernel_nlink_t; +typedef long __kernel_off_t; +typedef int __kernel_pid_t; +typedef unsigned short __kernel_ipc_pid_t; +typedef unsigned short __kernel_uid_t; +typedef unsigned short __kernel_gid_t; +typedef unsigned long __kernel_size_t; +typedef long __kernel_ssize_t; +typedef long __kernel_ptrdiff_t; +typedef long __kernel_time_t; +typedef long __kernel_suseconds_t; +typedef long __kernel_clock_t; +typedef long __kernel_daddr_t; +typedef char * __kernel_caddr_t; +typedef unsigned short __kernel_uid16_t; +typedef unsigned short __kernel_gid16_t; +typedef unsigned int __kernel_uid32_t; +typedef unsigned int __kernel_gid32_t; + +typedef __kernel_uid_t __kernel_old_uid_t; +typedef __kernel_gid_t __kernel_old_gid_t; + +#ifdef __GNUC__ +typedef long long __kernel_loff_t; +#endif + +#endif /* __ARCH_ARM64_POSIX_TYPES_H */ diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h new file mode 100644 index 0000000..67c0233 --- /dev/null +++ b/arch/arm64/include/asm/processor.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_PROCESSOR_H +#define __ASM_ARM64_PROCESSOR_H + +/* CCSIDR */ +#define CCSIDR_LINE_SIZE_OFFSET 0 +#define CCSIDR_LINE_SIZE_MASK 0x7 +#define CCSIDR_ASSOCIATIVITY_OFFSET 3 +#define CCSIDR_ASSOCIATIVITY_MASK (0x3FF << 3) +#define CCSIDR_NUM_SETS_OFFSET 13 +#define CCSIDR_NUM_SETS_MASK (0x7FFF << 13) + +/* + * Values for InD field in CSSELR + * Selects the type of cache + */ +#define CSSELR_IND_DATA_UNIFIED 0 +#define CSSELR_IND_INSTRUCTION 1 + +/* Values for Ctype fields in CLIDR */ +#define CLIDR_CTYPE_NO_CACHE 0 +#define CLIDR_CTYPE_INSTRUCTION_ONLY 1 +#define CLIDR_CTYPE_DATA_ONLY 2 +#define CLIDR_CTYPE_INSTRUCTION_DATA 3 +#define CLIDR_CTYPE_UNIFIED 4 + +/* + * SCTLR_EL2 bits definitions + */ +#define CR_M (1 << 0) /* MMU enable */ +#define CR_A (1 << 1) /* Alignment abort enable */ +#define CR_C (1 << 2) /* Dcache enable */ +#define CR_SA (1 << 3) /* Stack Alignment Check Enable */ +#define CR_I (1 << 12) /* Icache enable */ +#define CR_WXN (1 << 19) /* Write Permision Imply XN */ +#define CR_EE (1 << 25) /* Exception (Big) Endian */ + +#endif /* __ASM_ARM64_PROCESSOR_H */ diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h new file mode 100644 index 0000000..ed4eee3 --- /dev/null +++ b/arch/arm64/include/asm/ptrace.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_PTRACE_H +#define __ASM_ARM64_PTRACE_H + +/* + * exception type numbers + */ +#define EXCEPTION_SYNC 0 +#define EXCEPTION_IRQ 1 +#define EXCEPTION_FIQ 2 +#define EXCEPTION_ERROR 3 + +#define S_X0 (0) /* offsetof(struct pt_regs, regs[0]) */ +#define S_X1 (8) /* offsetof(struct pt_regs, regs[1]) */ +#define S_X2 (16) /* offsetof(struct pt_regs, regs[2]) */ +#define S_X3 (24 /* offsetof(struct pt_regs, regs[3]) */ +#define S_X4 (32) /* offsetof(struct pt_regs, regs[4]) */ +#define S_X5 (40) /* offsetof(struct pt_regs, regs[5]) */ +#define S_X6 (48) /* offsetof(struct pt_regs, regs[6]) */ +#define S_X7 (56) /* offsetof(struct pt_regs, regs[7]) */ +#define S_LR (240) /* offsetof(struct pt_regs, regs[30]) */ +#define S_SP (248) /* offsetof(struct pt_regs, sp) */ +#define S_PC (256) /* offsetof(struct pt_regs, pc) */ +#define S_PSTATE (264) /* offsetof(struct pt_regs, pstate) */ +#define S_FRAME_SIZE (272) /* sizeof(struct pt_regs) */ + +#ifndef __ASSEMBLY__ + +/* + * This struct defines the way the registers are stored on the stack during an + * exception. Note that sizeof(struct pt_regs) has to be a multiple of 16 (for + * stack alignment). struct user_pt_regs must form a prefix of struct pt_regs. + */ +struct pt_regs { + u64 regs[31]; + u64 sp; + u64 pc; + u64 pstate; +}; + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM64_PTRACE_H */ diff --git a/arch/arm64/include/asm/sections.h b/arch/arm64/include/asm/sections.h new file mode 100644 index 0000000..c042cb6 --- /dev/null +++ b/arch/arm64/include/asm/sections.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM_SECTIONS_H +#define __ASM_ARM_SECTIONS_H + +#include <asm-generic/sections.h> + +#endif diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h new file mode 100644 index 0000000..550201f --- /dev/null +++ b/arch/arm64/include/asm/string.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_STRING_H +#define __ASM_ARM64_STRING_H + +#include <config.h> + +#undef __HAVE_ARCH_STRRCHR +extern char * strrchr(const char * s, int c); + +#undef __HAVE_ARCH_STRCHR +extern char * strchr(const char * s, int c); + +#undef __HAVE_ARCH_MEMCPY +extern void * memcpy(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMMOVE +extern void * memmove(void *, const void *, __kernel_size_t); + +#undef __HAVE_ARCH_MEMCHR +extern void * memchr(const void *, int, __kernel_size_t); + +#undef __HAVE_ARCH_MEMZERO +extern void memzero(void *ptr, __kernel_size_t n); + +#undef __HAVE_ARCH_MEMSET +extern void * memset(void *, int, __kernel_size_t); + +#endif /* __ASM_ARM64_STRING_H */ diff --git a/arch/arm64/include/asm/system.h b/arch/arm64/include/asm/system.h new file mode 100644 index 0000000..135c5e1 --- /dev/null +++ b/arch/arm64/include/asm/system.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_ARCH_SYSTEM_H +#define __ASM_ARM64_ARCH_SYSTEM_H + +#include <linux/types.h> + +#ifndef __ASSEMBLY__ + +/* + * Save the current interrupt enable state + * and disable IRQs/FIQs + */ +#define local_irq_save(flags) \ + { \ + asm volatile( \ + "mrs %0, daif" \ + "msr daifset, #3" \ + : "=r" (flags) \ + : \ + : "memory"); \ + } + +/* + * restore saved IRQ & FIQ state + */ +#define local_irq_restore(flags) \ + { \ + asm volatile( \ + "msr daif, %0" \ + : \ + : "r" (flags) \ + : "memory"); \ + } + +/* + * Enable IRQs/FIQs + */ +#define local_irq_enable() \ + { \ + asm volatile( \ + "msr daifclr, #3" \ + : \ + : \ + : "memory"); \ + } + +/* + * Disable IRQs/FIQs + */ +#define local_irq_disable() \ + { \ + asm volatile( \ + "msr daifset, #3" \ + : \ + : \ + : "memory"); \ + } + +#define sev() asm volatile("sev" : : : "memory") +#define wfe() asm volatile("wfe" : : : "memory") +#define wfi() asm volatile("wfi" : : : "memory") + +#define isb() asm volatile("isb" : : : "memory") +#define dsb() asm volatile("dsb sy" : : : "memory") + +#define mb() dsb() +#define rmb() asm volatile("dsb ld" : : : "memory") +#define wmb() asm volatile("dsb st" : : : "memory") + +static inline unsigned int get_sctlr(void) +{ + unsigned int val; + asm volatile("mrs %0, sctlr_el2" : "=r" (val) : : "cc"); + return val; +} + +static inline void set_sctlr(unsigned int val) +{ + asm volatile("msr sctlr_el2, %0" : : "r" (val) : "cc"); + asm volatile("isb"); +} + +#endif /* __ASSEMBLY__ */ + +#endif /* __ASM_ARM64_ARCH_SYSTEM_H */ diff --git a/arch/arm64/include/asm/types.h b/arch/arm64/include/asm/types.h new file mode 100644 index 0000000..7aa08cb --- /dev/null +++ b/arch/arm64/include/asm/types.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef __ASM_ARM64_TYPES_H +#define __ASM_ARM64_TYPES_H + +#define BITS_PER_LONG 64 + +typedef unsigned short umode_t; + +typedef __signed__ char __s8; +typedef unsigned char __u8; + +typedef __signed__ short __s16; +typedef unsigned short __u16; + +typedef __signed__ int __s32; +typedef unsigned int __u32; + +typedef __signed__ long __s64; +typedef unsigned long __u64; + +/* + * These aren't exported outside the kernel to avoid name space clashes + */ +#ifdef __KERNEL__ + +typedef signed char s8; +typedef unsigned char u8; + +typedef signed short s16; +typedef unsigned short u16; + +typedef signed int s32; +typedef unsigned int u32; + +typedef signed long s64; +typedef unsigned long u64; + +/* Dma addresses are 32-bits wide. */ +typedef u32 dma_addr_t; + +typedef unsigned long phys_addr_t; +typedef unsigned long phys_size_t; + +#endif /* __KERNEL__ */ + +#endif /* __ASM_ARM64_TYPES_H */ diff --git a/arch/arm64/include/asm/u-boot.h b/arch/arm64/include/asm/u-boot.h new file mode 100644 index 0000000..c0cf855 --- /dev/null +++ b/arch/arm64/include/asm/u-boot.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _U_BOOT_ARM64_H_ +#define _U_BOOT_ARM64_H_ + +typedef struct bd_info { + unsigned long bi_baudrate; /* serial console baudrate */ + struct /* RAM configuration */ + { + unsigned long start; + unsigned long size; + } bi_dram[CONFIG_NR_DRAM_BANKS]; +} bd_t; + +/* For image.h:image_check_target_arch() */ +#define IH_ARCH_DEFAULT IH_ARCH_ARM64 + +#endif /* _U_BOOT_ARM64_H_ */ diff --git a/arch/arm64/include/asm/unaligned.h b/arch/arm64/include/asm/unaligned.h new file mode 100644 index 0000000..39b509a --- /dev/null +++ b/arch/arm64/include/asm/unaligned.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013 David Feng fenghua@phytium.com.cn + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#ifndef _ASM_ARM64_UNALIGNED_H +#define _ASM_ARM64_UNALIGNED_H + +#include <asm-generic/unaligned.h> + +#endif /* _ASM_ARM64_UNALIGNED_H */ diff --git a/arch/arm64/include/asm/utils.h b/arch/arm64/include/asm/utils.h new file mode 100644 index 0000000..828b86c --- /dev/null +++ b/arch/arm64/include/asm/utils.h @@ -0,0 +1,56 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * Aneesh V aneesh@ti.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 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#ifndef _UTILS_H_ +#define _UTILS_H_ + +static inline s32 log_2_n_round_up(u32 n) +{ + s32 log2n = -1; + u32 temp = n; + + while (temp) { + log2n++; + temp >>= 1; + } + + if (n & (n - 1)) + return log2n + 1; /* not power of 2 - round up */ + else + return log2n; /* power of 2 */ +} + +static inline s32 log_2_n_round_down(u32 n) +{ + s32 log2n = -1; + u32 temp = n; + + while (temp) { + log2n++; + temp >>= 1; + } + + return log2n; +} + +#endif