arc: introduce U-Boot port for ARCv2 ISA

ARC HS and ARC EM are new cores based on ARCv2 ISA which is binary
incompatible with ISAv1 (AKA ARCompact).

Significant difference between ISAv2 and v1 is implementation of
interrupt vector table.

In v1 it is implemented in the same way as on many other architectures -
as a special location where user may put whether code executed in place
(if machine word of space is enough) or jump to a full-scale interrupt
handler.

In v2 interrupt table is just an array of adresses of real interrupt
handlers. That requires a separate section for IVT that is not encoded
as code by assembler.

This change adds support for following cores:
 * ARC EM6 (simple 32-bit microcontroller without MMU)
 * ARC HS36 (advanced 32-bit microcontroller without MMU)
 * ARC HS38 (advanced 32-bit microcontroller with MMU)

As a part of ARC HS38 new version of MMU (v4) was introduced.

Also this change adds AXS131 board which is the same DW ARC SDP base board but
with ARC HS38 CPU tile.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
master
Alexey Brodkin 9 years ago
parent bd2a4888b1
commit f13606b77d
  1. 59
      arch/arc/Kconfig
  2. 12
      arch/arc/config.mk
  3. 7
      arch/arc/cpu/arcv2/Makefile
  4. 254
      arch/arc/cpu/arcv2/start.S
  5. 6
      arch/arc/include/asm/cache.h
  6. 5
      configs/axs103_defconfig

@ -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

@ -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

@ -0,0 +1,7 @@
#
# Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += start.o

@ -0,0 +1,254 @@
/*
* Copyright (C) 2013-2015 Synopsys, Inc. All rights reserved.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm-offsets.h>
#include <config.h>
#include <asm/arcregs.h>
/*
* 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]

@ -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 */

@ -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
Loading…
Cancel
Save