Skip to content

Commit

Permalink
ARCv2: Support for ARCv2 ISA and HS38x cores
Browse files Browse the repository at this point in the history
The notable features are:
    - SMP configurations of upto 4 cores with coherency
    - Optional L2 Cache and IO-Coherency
    - Revised Interrupt Architecture (multiple priorites, reg banks,
        auto stack switch, auto regfile save/restore)
    - MMUv4 (PIPT dcache, Huge Pages)
    - Instructions for
	* 64bit load/store: LDD, STD
	* Hardware assisted divide/remainder: DIV, REM
	* Function prologue/epilogue: ENTER_S, LEAVE_S
	* IRQ enable/disable: CLRI, SETI
	* pop count: FFS, FLS
	* SETcc, BMSKN, XBFU...

Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
  • Loading branch information
Vineet Gupta committed Jun 22, 2015
1 parent 820970a commit 1f6ccff
Show file tree
Hide file tree
Showing 22 changed files with 737 additions and 33 deletions.
80 changes: 75 additions & 5 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,31 @@ source "arch/arc/plat-axs10x/Kconfig"

endmenu

choice
prompt "ARC Instruction Set"
default ISA_ARCOMPACT

config ISA_ARCOMPACT
bool "ARCompact ISA"
help
The original ARC ISA of ARC600/700 cores

### For bisectability, disable ARCv2 support until we have all the bits in place
#config ISA_ARCV2
# bool "ARC ISA v2"
# help
# ISA for the Next Generation ARC-HS cores

endchoice

menu "ARC CPU Configuration"

choice
prompt "ARC Core"
default ARC_CPU_770
default ARC_CPU_770 if ISA_ARCOMPACT
default ARC_CPU_HS if ISA_ARCV2

if ISA_ARCOMPACT

config ARC_CPU_750D
bool "ARC750D"
Expand All @@ -110,6 +130,27 @@ config ARC_CPU_770
-Caches: New Prog Model, Region Flush
-Insns: endian swap, load-locked/store-conditional, time-stamp-ctr

endif #ISA_ARCOMPACT

config ARC_CPU_HS
bool "ARC-HS"
depends on ISA_ARCV2
help
Support for ARC HS38x Cores based on ARCv2 ISA
The notable features are:
- SMP configurations of upto 4 core with coherency
- Optional L2 Cache and IO-Coherency
- Revised Interrupt Architecture (multiple priorites, reg banks,
auto stack switch, auto regfile save/restore)
- MMUv4 (PIPT dcache, Huge Pages)
- Instructions for
* 64bit load/store: LDD, STD
* Hardware assisted divide/remainder: DIV, REM
* Function prologue/epilogue: ENTER_S, LEAVE_S
* IRQ enable/disable: CLRI, SETI
* pop count: FFS, FLS
* SETcc, BMSKN, XBFU...

endchoice

config CPU_BIG_ENDIAN
Expand All @@ -134,7 +175,7 @@ config ARC_HAS_COH_CACHES
config ARC_HAS_REENTRANT_IRQ_LV2
def_bool n

endif
endif #SMP

config NR_CPUS
int "Maximum number of CPUs (2-4096)"
Expand Down Expand Up @@ -223,7 +264,7 @@ config ARC_HAS_HW_MPY
Multipler. Otherwise software multipy lib is used

choice
prompt "ARC700 MMU Version"
prompt "MMU Version"
default ARC_MMU_V3 if ARC_CPU_770
default ARC_MMU_V2 if ARC_CPU_750D

Expand Down Expand Up @@ -268,6 +309,8 @@ config ARC_PAGE_SIZE_4K

endchoice

if ISA_ARCOMPACT

config ARC_COMPACT_IRQ_LEVELS
bool "ARCompact IRQ Priorities: High(2)/Low(1)"
default n
Expand All @@ -287,7 +330,7 @@ config ARC_IRQ5_LV2
config ARC_IRQ6_LV2
bool

endif
endif #ARC_COMPACT_IRQ_LEVELS

config ARC_FPU_SAVE_RESTORE
bool "Enable FPU state persistence across context switch"
Expand All @@ -300,18 +343,43 @@ config ARC_FPU_SAVE_RESTORE
based on actual usage of FPU by a task. Thus our implemn does
this for all tasks in system.

endif #ISA_ARCOMPACT

config ARC_CANT_LLSC
def_bool n

config ARC_HAS_LLSC
bool "Insn: LLOCK/SCOND (efficient atomic ops)"
default y
depends on ARC_CPU_770 && !ARC_CANT_LLSC
depends on !ARC_CPU_750D && !ARC_CANT_LLSC

config ARC_HAS_SWAPE
bool "Insn: SWAPE (endian-swap)"
default y

if ISA_ARCV2

config ARC_HAS_LL64
bool "Insn: 64bit LDD/STD"
help
Enable gcc to generate 64-bit load/store instructions
ISA mandates even/odd registers to allow encoding of two
dest operands with 2 possible source operands.
default y

config ARC_NUMBER_OF_INTERRUPTS
int "Number of interrupts"
range 8 240
default 32
help
This defines the number of interrupts on the ARCv2HS core.
It affects the size of vector table.
The initial 8 IRQs are fixed (Timer, ICI etc) and although configurable
in hardware, it keep things simple for Linux to assume they are always
present.

endif # ISA_ARCV2

endmenu # "ARC CPU Configuration"

config LINUX_LINK_BASE
Expand All @@ -337,8 +405,10 @@ config ARC_CURR_IN_REG

config ARC_EMUL_UNALIGNED
bool "Emulate unaligned memory access (userspace only)"
default N
select SYSCTL_ARCH_UNALIGN_NO_WARN
select SYSCTL_ARCH_UNALIGN_ALLOW
depends on ISA_ARCOMPACT
help
This enables misaligned 16 & 32 bit memory access from user space.
Use ONLY-IF-ABS-NECESSARY as it will be very slow and also can hide
Expand Down
8 changes: 7 additions & 1 deletion arch/arc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ endif

KBUILD_DEFCONFIG := nsim_700_defconfig

cflags-y += -mA7 -fno-common -pipe -fno-builtin -D__linux__
cflags-y += -fno-common -pipe -fno-builtin -D__linux__
cflags-${CONFIG_ISA_ARCOMPACT} += -mA7
cflags-${CONFIG_ISA_ARCV2} += -mcpu=archs

ifdef CONFIG_ARC_CURR_IN_REG
# For a global register defintion, make sure it gets passed to every file
Expand All @@ -34,6 +36,10 @@ cflags-$(atleast_gcc44) += -fsection-anchors
cflags-$(CONFIG_ARC_HAS_LLSC) += -mlock
cflags-$(CONFIG_ARC_HAS_SWAPE) += -mswape

ifndef CONFIG_ARC_HAS_LL64
cflags-y += -mno-ll64
endif

cflags-$(CONFIG_ARC_DW2_UNWIND) += -fasynchronous-unwind-tables

# By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
Expand Down
53 changes: 49 additions & 4 deletions arch/arc/include/asm/arcregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#define ARC_REG_PERIBASE_BCR 0x69
#define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */
#define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */
#define ARC_REG_FP_V2_BCR 0xc8 /* ARCv2 FPU */
#define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */
#define ARC_REG_TIMERS_BCR 0x75
#define ARC_REG_AP_BCR 0x76
Expand Down Expand Up @@ -52,13 +53,23 @@
* [15: 8] = Exception Cause Code
* [ 7: 0] = Exception Parameters (for certain types only)
*/
#ifdef CONFIG_ISA_ARCOMPACT
#define ECR_V_MEM_ERR 0x01
#define ECR_V_INSN_ERR 0x02
#define ECR_V_MACH_CHK 0x20
#define ECR_V_ITLB_MISS 0x21
#define ECR_V_DTLB_MISS 0x22
#define ECR_V_PROTV 0x23
#define ECR_V_TRAP 0x25
#else
#define ECR_V_MEM_ERR 0x01
#define ECR_V_INSN_ERR 0x02
#define ECR_V_MACH_CHK 0x03
#define ECR_V_ITLB_MISS 0x04
#define ECR_V_DTLB_MISS 0x05
#define ECR_V_PROTV 0x06
#define ECR_V_TRAP 0x09
#endif

/* DTLB Miss and Protection Violation Cause Codes */

Expand Down Expand Up @@ -202,9 +213,11 @@ struct bcr_identity {

struct bcr_isa {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad1:23, atomic1:1, ver:8;
unsigned int div_rem:4, pad2:4, ldd:1, unalign:1, atomic:1, be:1,
pad1:11, atomic1:1, ver:8;
#else
unsigned int ver:8, atomic1:1, pad1:23;
unsigned int ver:8, atomic1:1, pad1:11, be:1, atomic:1, unalign:1,
ldd:1, pad2:4, div_rem:4;
#endif
};

Expand Down Expand Up @@ -267,11 +280,19 @@ struct bcr_fp_arcompact {
#endif
};

struct bcr_fp_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad2:15, dp:1, pad1:7, sp:1, ver:8;
#else
unsigned int ver:8, sp:1, pad1:7, dp:1, pad2:15;
#endif
};

struct bcr_timer {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8;
unsigned int pad2:15, rtsc:1, pad1:5, rtc:1, t1:1, t0:1, ver:8;
#else
unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15;
unsigned int ver:8, t0:1, t1:1, rtc:1, pad1:5, rtsc:1, pad2:15;
#endif
};

Expand All @@ -283,6 +304,14 @@ struct bcr_bpu_arcompact {
#endif
};

struct bcr_bpu_arcv2 {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:6, fbe:2, tqe:2, ts:4, ft:1, rse:2, pte:3, bce:3, ver:8;
#else
unsigned int ver:8, bce:3, pte:3, rse:2, ft:1, ts:4, tqe:2, fbe:2, pad:6;
#endif
};

struct bcr_generic {
#ifdef CONFIG_CPU_BIG_ENDIAN
unsigned int pad:24, ver:8;
Expand Down Expand Up @@ -334,6 +363,22 @@ struct cpuinfo_arc {

extern struct cpuinfo_arc cpuinfo_arc700[];

static inline int is_isa_arcv2(void)
{
return IS_ENABLED(CONFIG_ISA_ARCV2);
}

static inline int is_isa_arcompact(void)
{
return IS_ENABLED(CONFIG_ISA_ARCOMPACT);
}

#if defined(CONFIG_ISA_ARCOMPACT) && !defined(_CPU_DEFAULT_A7)
#error "Toolchain not configured for ARCompact builds"
#elif defined(CONFIG_ISA_ARCV2) && !defined(_CPU_DEFAULT_HS)
#error "Toolchain not configured for ARCv2 builds"
#endif

#endif /* __ASEMBLY__ */

#endif /* _ASM_ARC_ARCREGS_H */
71 changes: 71 additions & 0 deletions arch/arc/include/asm/bitops.h
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,8 @@ test_bit(unsigned int nr, const volatile unsigned long *addr)
return ((mask & *addr) != 0);
}

#ifdef CONFIG_ISA_ARCOMPACT

/*
* Count the number of zeros, starting from MSB
* Helper for fls( ) friends
Expand Down Expand Up @@ -494,6 +496,75 @@ static inline __attribute__ ((const)) int __ffs(unsigned long word)
return ffs(word) - 1;
}

#else /* CONFIG_ISA_ARCV2 */

/*
* fls = Find Last Set in word
* @result: [1-32]
* fls(1) = 1, fls(0x80000000) = 32, fls(0) = 0
*/
static inline __attribute__ ((const)) int fls(unsigned long x)
{
int n;

asm volatile(
" fls.f %0, %1 \n" /* 0:31; 0(Z) if src 0 */
" add.nz %0, %0, 1 \n" /* 0:31 -> 1:32 */
: "=r"(n) /* Early clobber not needed */
: "r"(x)
: "cc");

return n;
}

/*
* __fls: Similar to fls, but zero based (0-31). Also 0 if no bit set
*/
static inline __attribute__ ((const)) int __fls(unsigned long x)
{
/* FLS insn has exactly same semantics as the API */
return __builtin_arc_fls(x);
}

/*
* ffs = Find First Set in word (LSB to MSB)
* @result: [1-32], 0 if all 0's
*/
static inline __attribute__ ((const)) int ffs(unsigned long x)
{
int n;

asm volatile(
" ffs.f %0, %1 \n" /* 0:31; 31(Z) if src 0 */
" add.nz %0, %0, 1 \n" /* 0:31 -> 1:32 */
" mov.z %0, 0 \n" /* 31(Z)-> 0 */
: "=r"(n) /* Early clobber not needed */
: "r"(x)
: "cc");

return n;
}

/*
* __ffs: Similar to ffs, but zero based (0-31)
*/
static inline __attribute__ ((const)) int __ffs(unsigned long x)
{
int n;

asm volatile(
" ffs.f %0, %1 \n" /* 0:31; 31(Z) if src 0 */
" mov.z %0, 0 \n" /* 31(Z)-> 0 */
: "=r"(n)
: "r"(x)
: "cc");

return n;

}

#endif /* CONFIG_ISA_ARCOMPACT */

/*
* ffz = Find First Zero in word.
* @return:[0-31], 32 if all 1's
Expand Down
5 changes: 5 additions & 0 deletions arch/arc/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
/* These ELF defines belong to uapi but libc elf.h already defines them */
#define EM_ARCOMPACT 93

#define EM_ARCV2 195 /* ARCv2 Cores */

#define EM_ARC_INUSE (IS_ENABLED(CONFIG_ISA_ARCOMPACT) ? \
EM_ARCOMPACT : EM_ARCV2)

/* ARC Relocations (kernel Modules only) */
#define R_ARC_32 0x4
#define R_ARC_32_ME 0x1B
Expand Down
Loading

0 comments on commit 1f6ccff

Please sign in to comment.