Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1f6ccfff authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARCv2: Support for ARCv2 ISA and HS38x cores



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: default avatarVineet Gupta <vgupta@synopsys.com>
parent 820970a5
Loading
Loading
Loading
Loading
+75 −5
Original line number Diff line number Diff line
@@ -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"
@@ -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
@@ -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)"
@@ -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

@@ -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
@@ -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"
@@ -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
@@ -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
+7 −1
Original line number Diff line number Diff line
@@ -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
@@ -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
+49 −4
Original line number Diff line number Diff line
@@ -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
@@ -52,6 +53,7 @@
 * [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
@@ -59,6 +61,15 @@
#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 */

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

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

@@ -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;
@@ -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 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
+5 −0
Original line number Diff line number Diff line
@@ -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
Loading