diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index a8dc4e2..24f5c02 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -8,30 +8,79 @@ config USE_PRIVATE_LIBGCC default y config SYS_CPU - default "arcv1" + default "arcv1" if ISA_ARCOMPACT + default "arcv2" if ISA_ARCV2 + +choice + prompt "ARC Instruction Set" + default ISA_ARCOMPACT + +config ISA_ARCOMPACT + bool "ARCompact ISA" + help + The original ARC ISA of ARC600/700 cores + +config ISA_ARCV2 + bool "ARC ISA v2" + help + ISA for the Next Generation ARC-HS cores + +endchoice choice prompt "CPU selection" - default CPU_ARC770D + default CPU_ARC770D if ISA_ARCOMPACT + default CPU_ARCHS38 if ISA_ARCV2 config CPU_ARC750D bool "ARC 750D" select ARC_MMU_V2 + depends on ISA_ARCOMPACT help Choose this option to build an U-Boot for ARC750D CPU. config CPU_ARC770D bool "ARC 770D" select ARC_MMU_V3 + depends on ISA_ARCOMPACT help Choose this option to build an U-Boot for ARC770D CPU. +config CPU_ARCEM6 + bool "ARC EM6" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS36 + bool "ARC HS36" + select ARC_MMU_ABSENT + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA without MMU. + +config CPU_ARCHS38 + bool "ARC HS38" + select ARC_MMU_V4 + depends on ISA_ARCV2 + help + Next Generation ARC Core based on ISA-v2 ISA with MMU. + endchoice choice prompt "MMU Version" default ARC_MMU_V3 if CPU_ARC770D default ARC_MMU_V2 if CPU_ARC750D + default ARC_MMU_ABSENT if CPU_ARCEM6 + default ARC_MMU_ABSENT if CPU_ARCHS36 + default ARC_MMU_V4 if CPU_ARCHS38 + +config ARC_MMU_ABSENT + bool "No MMU" + help + No MMU config ARC_MMU_V2 bool "MMU v2" @@ -48,6 +97,12 @@ config ARC_MMU_V3 Variable Page size (1k-16k), var JTLB size 128 x (2 or 4) Shared Address Spaces (SASID) +config ARC_MMU_V4 + bool "MMU v4" + depends on CPU_ARCHS38 + help + Introduced as a part of ARC HS38 release. + endchoice config CPU_BIG_ENDIAN diff --git a/arch/arc/config.mk b/arch/arc/config.mk index f1e81b6..4fcd407 100644 --- a/arch/arc/config.mk +++ b/arch/arc/config.mk @@ -38,6 +38,18 @@ ifdef CONFIG_CPU_ARC770D PLATFORM_CPPFLAGS += -marc700 -mlock -mswape endif +ifdef CONFIG_CPU_ARCEM6 +PLATFORM_CPPFLAGS += -marcem +endif + +ifdef CONFIG_CPU_ARCHS34 +PLATFORM_CPPFLAGS += -marchs +endif + +ifdef CONFIG_CPU_ARCHS38 +PLATFORM_CPPFLAGS += -marchs +endif + PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 # Needed for relocation diff --git a/arch/arc/cpu/arcv2/Makefile b/arch/arc/cpu/arcv2/Makefile new file mode 100644 index 0000000..cc69e5a --- /dev/null +++ b/arch/arc/cpu/arcv2/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += start.o diff --git a/arch/arc/cpu/arcv2/start.S b/arch/arc/cpu/arcv2/start.S new file mode 100644 index 0000000..3ce6896 --- /dev/null +++ b/arch/arc/cpu/arcv2/start.S @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include + +/* + * Note on the LD/ST addressing modes with address register write-back + * + * LD.a same as LD.aw + * + * LD.a reg1, [reg2, x] => Pre Incr + * Eff Addr for load = [reg2 + x] + * + * LD.ab reg1, [reg2, x] => Post Incr + * Eff Addr for load = [reg2] + */ + +.macro PUSH reg + st.a \reg, [%sp, -4] +.endm + +.macro PUSHAX aux + lr %r9, [\aux] + PUSH %r9 +.endm + +.macro SAVE_R1_TO_R24 + PUSH %r1 + PUSH %r2 + PUSH %r3 + PUSH %r4 + PUSH %r5 + PUSH %r6 + PUSH %r7 + PUSH %r8 + PUSH %r9 + PUSH %r10 + PUSH %r11 + PUSH %r12 + PUSH %r13 + PUSH %r14 + PUSH %r15 + PUSH %r16 + PUSH %r17 + PUSH %r18 + PUSH %r19 + PUSH %r20 + PUSH %r21 + PUSH %r22 + PUSH %r23 + PUSH %r24 +.endm + +.macro SAVE_ALL_SYS + /* saving %r0 to reg->r0 in advance since weread %ecr into it */ + st %r0, [%sp, -8] + lr %r0, [%ecr] /* all stack addressing is manual so far */ + st %r0, [%sp] + st %sp, [%sp, -4] + /* now move %sp to reg->r0 position so we can do "push" automatically */ + sub %sp, %sp, 8 + + SAVE_R1_TO_R24 + PUSH %r25 + PUSH %gp + PUSH %fp + PUSH %blink + PUSHAX %eret + PUSHAX %erstatus + PUSH %lp_count + PUSHAX %lp_end + PUSHAX %lp_start + PUSHAX %erbta +.endm + +.macro SAVE_EXCEPTION_SOURCE +#ifdef CONFIG_MMU + /* If MMU exists exception faulting address is loaded in EFA reg */ + lr %r0, [%efa] +#else + /* Otherwise in ERET (exception return) reg */ + lr %r0, [%eret] +#endif +.endm + +.section .ivt, "a",@progbits +.align 4 + /* Critical system events */ +.word _start /* 0 - 0x000 */ +.word memory_error /* 1 - 0x008 */ +.word instruction_error /* 2 - 0x010 */ + + /* Exceptions */ +.word EV_MachineCheck /* 0x100, Fatal Machine check (0x20) */ +.word EV_TLBMissI /* 0x108, Intruction TLB miss (0x21) */ +.word EV_TLBMissD /* 0x110, Data TLB miss (0x22) */ +.word EV_TLBProtV /* 0x118, Protection Violation (0x23) + or Misaligned Access */ +.word EV_PrivilegeV /* 0x120, Privilege Violation (0x24) */ +.word EV_Trap /* 0x128, Trap exception (0x25) */ +.word EV_Extension /* 0x130, Extn Intruction Excp (0x26) */ + + /* Device interrupts */ +.rept 29 + j interrupt_handler /* 3:31 - 0x018:0xF8 */ +.endr + +.text +.globl _start +_start: + /* Setup interrupt vector base that matches "__text_start" */ + sr __ivt_start, [ARC_AUX_INTR_VEC_BASE] + + /* Setup stack pointer */ + mov %sp, CONFIG_SYS_INIT_SP_ADDR + mov %fp, %sp + + /* Clear bss */ + mov %r0, __bss_start + mov %r1, __bss_end + +clear_bss: + st.ab 0, [%r0, 4] + brlt %r0, %r1, clear_bss + + /* Zero the one and only argument of "board_init_f" */ + mov_s %r0, 0 + j board_init_f + +memory_error: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_memory_error + +instruction_error: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_instruction_error + +interrupt_handler: + /* Todo - save and restore CPU context when interrupts will be in use */ + bl do_interrupt_handler + rtie + +EV_MachineCheck: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_machine_check_fault + +EV_TLBMissI: + SAVE_ALL_SYS + mov %r0, %sp + j do_itlb_miss + +EV_TLBMissD: + SAVE_ALL_SYS + mov %r0, %sp + j do_dtlb_miss + +EV_TLBProtV: + SAVE_ALL_SYS + SAVE_EXCEPTION_SOURCE + mov %r1, %sp + j do_tlb_prot_violation + +EV_PrivilegeV: + SAVE_ALL_SYS + mov %r0, %sp + j do_privilege_violation + +EV_Trap: + SAVE_ALL_SYS + mov %r0, %sp + j do_trap + +EV_Extension: + SAVE_ALL_SYS + mov %r0, %sp + j do_extension + +/* + * void relocate_code (addr_sp, gd, addr_moni) + * + * This "function" does not return, instead it continues in RAM + * after relocating the monitor code. + * + * r0 = start_addr_sp + * r1 = new__gd + * r2 = relocaddr + */ +.align 4 +.globl relocate_code +relocate_code: + /* + * r0-r12 might be clobbered by C functions + * so we use r13-r16 for storage here + */ + mov %r13, %r0 /* save addr_sp */ + mov %r14, %r1 /* save addr of gd */ + mov %r15, %r2 /* save addr of destination */ + + mov %r16, %r2 /* %r9 - relocation offset */ + sub %r16, %r16, __image_copy_start + +/* Set up the stack */ +stack_setup: + mov %sp, %r13 + mov %fp, %sp + +/* Check if monitor is loaded right in place for relocation */ + mov %r0, __image_copy_start + cmp %r0, %r15 /* skip relocation if code loaded */ + bz do_board_init_r /* in target location already */ + +/* Copy data (__image_copy_start - __image_copy_end) to new location */ + mov %r1, %r15 + mov %r2, __image_copy_end + sub %r2, %r2, %r0 /* r3 <- amount of bytes to copy */ + asr %r2, %r2, 2 /* r3 <- amount of words to copy */ + mov %lp_count, %r2 + lp copy_end + ld.ab %r2,[%r0,4] + st.ab %r2,[%r1,4] +copy_end: + +/* Fix relocations related issues */ + bl do_elf_reloc_fixups +#ifndef CONFIG_SYS_ICACHE_OFF + bl invalidate_icache_all +#endif +#ifndef CONFIG_SYS_DCACHE_OFF + bl flush_dcache_all +#endif + +/* Update position of intterupt vector table */ + lr %r0, [ARC_AUX_INTR_VEC_BASE] /* Read current position */ + add %r0, %r0, %r16 /* Update address */ + sr %r0, [ARC_AUX_INTR_VEC_BASE] /* Write new position */ + +do_board_init_r: +/* Prepare for exection of "board_init_r" in relocated monitor */ + mov %r2, board_init_r /* old address of "board_init_r()" */ + add %r2, %r2, %r16 /* new address of "board_init_r()" */ + mov %r0, %r14 /* 1-st parameter: gd_t */ + mov %r1, %r15 /* 2-nd parameter: dest_addr */ + j [%r2] diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h index 2725961..8a77cd9 100644 --- a/arch/arc/include/asm/cache.h +++ b/arch/arc/include/asm/cache.h @@ -17,10 +17,14 @@ #define ARCH_DMA_MINALIGN 128 #endif -#if defined(CONFIG_ARC_MMU_V2) +#if defined(ARC_MMU_ABSENT) +#define CONFIG_ARC_MMU_VER 0 +#elif defined(CONFIG_ARC_MMU_V2) #define CONFIG_ARC_MMU_VER 2 #elif defined(CONFIG_ARC_MMU_V3) #define CONFIG_ARC_MMU_VER 3 +#elif defined(CONFIG_ARC_MMU_V4) +#define CONFIG_ARC_MMU_VER 4 #endif #endif /* __ASM_ARC_CACHE_H */ diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig new file mode 100644 index 0000000..c63dd4a --- /dev/null +++ b/configs/axs103_defconfig @@ -0,0 +1,5 @@ +CONFIG_SYS_TEXT_BASE=0x81000000 +CONFIG_SYS_CLK_FREQ=50000000 +CONFIG_ARC=y +CONFIG_ISA_ARCV2=y +CONFIG_TARGET_AXS101=y