aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arc/plat-eznps
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arc/plat-eznps')
-rw-r--r--arch/arc/plat-eznps/Kconfig26
-rw-r--r--arch/arc/plat-eznps/Makefile2
-rw-r--r--arch/arc/plat-eznps/ctop.c32
-rw-r--r--arch/arc/plat-eznps/entry.S2
-rw-r--r--arch/arc/plat-eznps/include/plat/ctop.h2
-rw-r--r--arch/arc/plat-eznps/mtm.c50
6 files changed, 106 insertions, 8 deletions
diff --git a/arch/arc/plat-eznps/Kconfig b/arch/arc/plat-eznps/Kconfig
index 1595a38e50cd..e151e2067886 100644
--- a/arch/arc/plat-eznps/Kconfig
+++ b/arch/arc/plat-eznps/Kconfig
@@ -12,8 +12,8 @@ menuconfig ARC_PLAT_EZNPS
help
Support for EZchip development platforms,
based on ARC700 cores.
- We handle few flavours:
- - Hardware Emulator AKA HE which is FPGA based chasis
+ We handle few flavors:
+ - Hardware Emulator AKA HE which is FPGA based chassis
- Simulator based on MetaWare nSIM
- NPS400 chip based on ASIC
@@ -32,3 +32,25 @@ config EZNPS_MTM_EXT
any of them seem like CPU from Linux point of view.
All threads within same core share the execution unit of the
core and HW scheduler round robin between them.
+
+config EZNPS_MEM_ERROR_ALIGN
+ bool "ARC-EZchip Memory error as an exception"
+ depends on EZNPS_MTM_EXT
+ default n
+ help
+ On the real chip of the NPS, user memory errors are handled
+ as a machine check exception, which is fatal, whereas on
+ simulator platform for NPS, is handled as a Level 2 interrupt
+ (just a stock ARC700) which is recoverable. This option makes
+ simulator behave like hardware.
+
+config EZNPS_SHARED_AUX_REGS
+ bool "ARC-EZchip Shared Auxiliary Registers Per Core"
+ depends on ARC_PLAT_EZNPS
+ default y
+ help
+ On the real chip of the NPS, auxiliary registers are shared between
+ all the cpus of the core, whereas on simulator platform for NPS,
+ each cpu has a different set of auxiliary registers. Configuration
+ should be unset if auxiliary registers are not shared between the cpus
+ of the core, so there will be a need to initialize them per cpu.
diff --git a/arch/arc/plat-eznps/Makefile b/arch/arc/plat-eznps/Makefile
index 21091b199df0..8d4371706b2f 100644
--- a/arch/arc/plat-eznps/Makefile
+++ b/arch/arc/plat-eznps/Makefile
@@ -2,6 +2,6 @@
# Makefile for the linux kernel.
#
-obj-y := entry.o platform.o
+obj-y := entry.o platform.o ctop.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_EZNPS_MTM_EXT) += mtm.o
diff --git a/arch/arc/plat-eznps/ctop.c b/arch/arc/plat-eznps/ctop.c
new file mode 100644
index 000000000000..030bcd070a1b
--- /dev/null
+++ b/arch/arc/plat-eznps/ctop.c
@@ -0,0 +1,32 @@
+/*
+ * Copyright(c) 2015 EZchip Technologies.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * The full GNU General Public License is included in this distribution in
+ * the file called "COPYING".
+ */
+
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <plat/ctop.h>
+
+void dp_save_restore(struct task_struct *prev, struct task_struct *next)
+{
+ struct eznps_dp *prev_task_dp = &prev->thread.dp;
+ struct eznps_dp *next_task_dp = &next->thread.dp;
+
+ /* Here we save all Data Plane related auxiliary registers */
+ prev_task_dp->eflags = read_aux_reg(CTOP_AUX_EFLAGS);
+ write_aux_reg(CTOP_AUX_EFLAGS, next_task_dp->eflags);
+
+ prev_task_dp->gpa1 = read_aux_reg(CTOP_AUX_GPA1);
+ write_aux_reg(CTOP_AUX_GPA1, next_task_dp->gpa1);
+}
diff --git a/arch/arc/plat-eznps/entry.S b/arch/arc/plat-eznps/entry.S
index 328261c27cda..091c92c32ab6 100644
--- a/arch/arc/plat-eznps/entry.S
+++ b/arch/arc/plat-eznps/entry.S
@@ -27,7 +27,7 @@
.align 1024 ; HW requierment for restart first PC
ENTRY(res_service)
-#ifdef CONFIG_EZNPS_MTM_EXT
+#if defined(CONFIG_EZNPS_MTM_EXT) && defined(CONFIG_EZNPS_SHARED_AUX_REGS)
; There is no work for HW thread id != 0
lr r3, [CTOP_AUX_THREAD_ID]
cmp r3, 0
diff --git a/arch/arc/plat-eznps/include/plat/ctop.h b/arch/arc/plat-eznps/include/plat/ctop.h
index ee2e32df5e90..0c7d11022d0f 100644
--- a/arch/arc/plat-eznps/include/plat/ctop.h
+++ b/arch/arc/plat-eznps/include/plat/ctop.h
@@ -39,6 +39,7 @@
#define CTOP_AUX_LOGIC_CORE_ID (CTOP_AUX_BASE + 0x018)
#define CTOP_AUX_MT_CTRL (CTOP_AUX_BASE + 0x020)
#define CTOP_AUX_HW_COMPLY (CTOP_AUX_BASE + 0x024)
+#define CTOP_AUX_DPC (CTOP_AUX_BASE + 0x02C)
#define CTOP_AUX_LPC (CTOP_AUX_BASE + 0x030)
#define CTOP_AUX_EFLAGS (CTOP_AUX_BASE + 0x080)
#define CTOP_AUX_IACK (CTOP_AUX_BASE + 0x088)
@@ -46,6 +47,7 @@
#define CTOP_AUX_UDMC (CTOP_AUX_BASE + 0x300)
/* EZchip core instructions */
+#define CTOP_INST_HWSCHD_WFT_IE12 0x3E6F7344
#define CTOP_INST_HWSCHD_OFF_R4 0x3C6F00BF
#define CTOP_INST_HWSCHD_RESTORE_R4 0x3E6F7103
#define CTOP_INST_SCHD_RW 0x3E6F7004
diff --git a/arch/arc/plat-eznps/mtm.c b/arch/arc/plat-eznps/mtm.c
index aaaaffd3d940..2388de3d09ef 100644
--- a/arch/arc/plat-eznps/mtm.c
+++ b/arch/arc/plat-eznps/mtm.c
@@ -21,10 +21,22 @@
#include <plat/mtm.h>
#include <plat/smp.h>
-#define MT_CTRL_HS_CNT 0xFF
+#define MT_HS_CNT_MIN 0x01
+#define MT_HS_CNT_MAX 0xFF
#define MT_CTRL_ST_CNT 0xF
#define NPS_NUM_HW_THREADS 0x10
+static int mtm_hs_ctr = MT_HS_CNT_MAX;
+
+#ifdef CONFIG_EZNPS_MEM_ERROR_ALIGN
+int do_memory_error(unsigned long address, struct pt_regs *regs)
+{
+ die("Invalid Mem Access", regs, address);
+
+ return 1;
+}
+#endif
+
static void mtm_init_nat(int cpu)
{
struct nps_host_reg_mtm_cfg mtm_cfg;
@@ -98,6 +110,18 @@ void mtm_enable_core(unsigned int cpu)
int i;
struct nps_host_reg_aux_mt_ctrl mt_ctrl;
struct nps_host_reg_mtm_cfg mtm_cfg;
+ struct nps_host_reg_aux_dpc dpc;
+
+ /*
+ * Initializing dpc register in each CPU.
+ * Overwriting the init value of the DPC
+ * register so that CMEM and FMT virtual address
+ * spaces are accessible, and Data Plane HW
+ * facilities are enabled.
+ */
+ dpc.ien = 1;
+ dpc.men = 1;
+ write_aux_reg(CTOP_AUX_DPC, dpc.value);
if (NPS_CPU_TO_THREAD_NUM(cpu) != 0)
return;
@@ -118,9 +142,7 @@ void mtm_enable_core(unsigned int cpu)
/* Enable HW schedule, stall counter, mtm */
mt_ctrl.value = 0;
mt_ctrl.hsen = 1;
- mt_ctrl.hs_cnt = MT_CTRL_HS_CNT;
- mt_ctrl.sten = 1;
- mt_ctrl.st_cnt = MT_CTRL_ST_CNT;
+ mt_ctrl.hs_cnt = mtm_hs_ctr;
mt_ctrl.mten = 1;
write_aux_reg(CTOP_AUX_MT_CTRL, mt_ctrl.value);
@@ -131,3 +153,23 @@ void mtm_enable_core(unsigned int cpu)
*/
cpu_relax();
}
+
+/* Verify and set the value of the mtm hs counter */
+static int __init set_mtm_hs_ctr(char *ctr_str)
+{
+ long hs_ctr;
+ int ret;
+
+ ret = kstrtol(ctr_str, 0, &hs_ctr);
+
+ if (ret || hs_ctr > MT_HS_CNT_MAX || hs_ctr < MT_HS_CNT_MIN) {
+ pr_err("** Invalid @nps_mtm_hs_ctr [%d] needs to be [%d:%d] (incl)\n",
+ hs_ctr, MT_HS_CNT_MIN, MT_HS_CNT_MAX);
+ return -EINVAL;
+ }
+
+ mtm_hs_ctr = hs_ctr;
+
+ return 0;
+}
+early_param("nps_mtm_hs_ctr", set_mtm_hs_ctr);