* [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2
2013-03-22 16:24 [RFC PATCH 0/5] Cop2 save/restore for XLR/XLP Jayachandran C
@ 2013-03-22 16:24 ` Jayachandran C
0 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C @ 2013-03-22 16:24 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
Kernel threads should be able to use COP2 if the platform needs it.
Do not call die_if_kernel() for a coprocessor unusable exception if
the exception due to COP2 usage. Instead, the default notifier for
COP2 exceptions is updated to call die_if_kernel.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/kernel/traps.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index a200b5b..36c242f 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -970,15 +970,9 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
{
struct pt_regs *regs = data;
- switch (action) {
- default:
- die_if_kernel("Unhandled kernel unaligned access or invalid "
+ die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
"instruction", regs);
- /* Fall through */
-
- case CU2_EXCEPTION:
- force_sig(SIGILL, current);
- }
+ force_sig(SIGILL, current);
return NOTIFY_OK;
}
@@ -992,10 +986,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
int status;
unsigned long __maybe_unused flags;
- die_if_kernel("do_cpu invoked from kernel context!", regs);
-
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
+ if (cpid != 2)
+ die_if_kernel("do_cpu invoked from kernel context!", regs);
+
switch (cpid) {
case 0:
epc = (unsigned int __user *)exception_epc(regs);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP
@ 2013-06-10 7:29 Jayachandran C
2013-06-10 7:30 ` [PATCH 1/5] MIPS: Move cop2 save/restore to switch_to() Jayachandran C
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:29 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
This patchset is to generalize the COP2 save/restore implemented for
Octeon and to use it for Netlogic XLP.
Patch 1 and 2 of the series affects the Octeon platform as well, please
let me know if there are any suggestions/comments.
Thanks,
JC.
---
Changes in v2:
- XLR support dropped, status register is readonly in XLR and cannot
be restored
- fix naming of COP2 registers
Jayachandran C (5):
MIPS: Move cop2 save/restore to switch_to()
MIPS: Allow kernel to use coprocessor 2
MIPS: Netlogic: Fix nlm_read_c2_status() definition
MIPS: Netlogic: rename nlm_cop2_save/restore
MIPS: Netlogic: COP2 save/restore code
arch/mips/include/asm/cop2.h | 29 ++++++++
arch/mips/include/asm/netlogic/xlr/fmn.h | 12 ++-
arch/mips/include/asm/processor.h | 31 +++++---
arch/mips/include/asm/switch_to.h | 19 ++++-
arch/mips/kernel/octeon_switch.S | 27 -------
arch/mips/kernel/traps.c | 15 ++--
arch/mips/netlogic/xlp/Makefile | 2 +-
arch/mips/netlogic/xlp/cop2-ex.c | 118 ++++++++++++++++++++++++++++++
arch/mips/netlogic/xlr/fmn.c | 18 ++---
9 files changed, 208 insertions(+), 63 deletions(-)
create mode 100644 arch/mips/netlogic/xlp/cop2-ex.c
--
1.7.9.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/5] MIPS: Move cop2 save/restore to switch_to()
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
@ 2013-06-10 7:30 ` Jayachandran C
2013-06-10 7:30 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:30 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
Move the common code for saving and restoring platform specific COP2
registers to switch_to(). This will make supporting new platforms (like
Netlogic XLP) easier.
The platform specific COP2 definitions are to be specified in
asm/processor.h and in asm/cop2.h.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/cop2.h | 19 +++++++++++++++++++
arch/mips/include/asm/processor.h | 18 +++++++-----------
arch/mips/include/asm/switch_to.h | 19 ++++++++++++++++++-
arch/mips/kernel/octeon_switch.S | 27 ---------------------------
4 files changed, 44 insertions(+), 39 deletions(-)
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
index 3532e2c..b17f38e 100644
--- a/arch/mips/include/asm/cop2.h
+++ b/arch/mips/include/asm/cop2.h
@@ -11,6 +11,25 @@
#include <linux/notifier.h>
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
+
+extern void octeon_cop2_save(struct octeon_cop2_state *);
+extern void octeon_cop2_restore(struct octeon_cop2_state *);
+
+#define cop2_save(r) octeon_cop2_save(r)
+#define cop2_restore(r) octeon_cop2_restore(r)
+
+#define cop2_present 1
+#define cop2_lazy_restore 1
+
+#else
+
+#define cop2_present 0
+#define cop2_lazy_restore 0
+#define cop2_save(r)
+#define cop2_restore(r)
+#endif
+
enum cu2_ops {
CU2_EXCEPTION,
CU2_LWC2_OP,
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 1470b7b..7c637a4 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -137,7 +137,7 @@ union mips_watch_reg_state {
struct mips3264_watch_reg_state mips3264;
};
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#if defined(CONFIG_CPU_CAVIUM_OCTEON)
struct octeon_cop2_state {
/* DMFC2 rt, 0x0201 */
@@ -182,13 +182,16 @@ struct octeon_cop2_state {
/* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
unsigned long cop2_gfm_result[2];
};
-#define INIT_OCTEON_COP2 {0,}
+#define COP2_INIT \
+ .cp2 = {0,},
struct octeon_cvmseg_state {
unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
[cpu_dcache_line_size() / sizeof(unsigned long)];
};
+#else
+#define COP2_INIT
#endif
typedef struct {
@@ -245,13 +248,6 @@ struct thread_struct {
#define FPAFF_INIT
#endif /* CONFIG_MIPS_MT_FPAFF */
-#ifdef CONFIG_CPU_CAVIUM_OCTEON
-#define OCTEON_INIT \
- .cp2 = INIT_OCTEON_COP2,
-#else
-#define OCTEON_INIT
-#endif /* CONFIG_CPU_CAVIUM_OCTEON */
-
#define INIT_THREAD { \
/* \
* Saved main processor registers \
@@ -300,9 +296,9 @@ struct thread_struct {
.cp0_baduaddr = 0, \
.error_code = 0, \
/* \
- * Cavium Octeon specifics (null if not Octeon) \
+ * Platform specific cop2 registers(null if no COP2) \
*/ \
- OCTEON_INIT \
+ COP2_INIT \
}
struct task_struct;
diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
index fd16bcb..eb0af15 100644
--- a/arch/mips/include/asm/switch_to.h
+++ b/arch/mips/include/asm/switch_to.h
@@ -15,6 +15,7 @@
#include <asm/cpu-features.h>
#include <asm/watch.h>
#include <asm/dsp.h>
+#include <asm/cop2.h>
struct task_struct;
@@ -66,10 +67,18 @@ do { \
#define switch_to(prev, next, last) \
do { \
- u32 __usedfpu; \
+ u32 __usedfpu, __c0_stat; \
__mips_mt_fpaff_switch_to(prev); \
if (cpu_has_dsp) \
__save_dsp(prev); \
+ if (cop2_present && (KSTK_STATUS(prev) & ST0_CU2)) { \
+ if (cop2_lazy_restore) \
+ KSTK_STATUS(prev) &= ~ST0_CU2; \
+ __c0_stat = read_c0_status(); \
+ write_c0_status(__c0_stat | ST0_CU2); \
+ cop2_save(&prev->thread.cp2); \
+ write_c0_status(__c0_stat & ~ST0_CU2); \
+ } \
__clear_software_ll_bit(); \
__usedfpu = test_and_clear_tsk_thread_flag(prev, TIF_USEDFPU); \
(last) = resume(prev, next, task_thread_info(next), __usedfpu); \
@@ -77,6 +86,14 @@ do { \
#define finish_arch_switch(prev) \
do { \
+ u32 __c0_stat; \
+ if (cop2_present && !cop2_lazy_restore && \
+ (KSTK_STATUS(current) & ST0_CU2)) { \
+ __c0_stat = read_c0_status(); \
+ write_c0_status(__c0_stat | ST0_CU2); \
+ cop2_restore(¤t->thread.cp2); \
+ write_c0_status(__c0_stat & ~ST0_CU2); \
+ } \
if (cpu_has_dsp) \
__restore_dsp(current); \
if (cpu_has_userlocal) \
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 0e23343..22e2aa1 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -40,33 +40,6 @@
cpu_save_nonscratch a0
LONG_S ra, THREAD_REG31(a0)
- /* check if we need to save COP2 registers */
- PTR_L t2, TASK_THREAD_INFO(a0)
- LONG_L t0, ST_OFF(t2)
- bbit0 t0, 30, 1f
-
- /* Disable COP2 in the stored process state */
- li t1, ST0_CU2
- xor t0, t1
- LONG_S t0, ST_OFF(t2)
-
- /* Enable COP2 so we can save it */
- mfc0 t0, CP0_STATUS
- or t0, t1
- mtc0 t0, CP0_STATUS
-
- /* Save COP2 */
- daddu a0, THREAD_CP2
- jal octeon_cop2_save
- dsubu a0, THREAD_CP2
-
- /* Disable COP2 now that we are done */
- mfc0 t0, CP0_STATUS
- li t1, ST0_CU2
- xor t0, t1
- mtc0 t0, CP0_STATUS
-
-1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
/* Check if we need to store CVMSEG state */
mfc0 t0, $11,7 /* CvmMemCtl */
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
2013-06-10 7:30 ` [PATCH 1/5] MIPS: Move cop2 save/restore to switch_to() Jayachandran C
@ 2013-06-10 7:30 ` Jayachandran C
2013-06-10 11:31 ` Sergei Shtylyov
2013-06-10 12:42 ` Ralf Baechle
2013-06-10 7:30 ` [PATCH 3/5] MIPS: Netlogic: Fix nlm_read_c2_status() definition Jayachandran C
` (2 subsequent siblings)
4 siblings, 2 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:30 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
Kernel threads should be able to use COP2 if the platform needs it.
Do not call die_if_kernel() for a coprocessor unusable exception if
the exception due to COP2 usage. Instead, the default notifier for
COP2 exceptions is updated to call die_if_kernel.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/kernel/traps.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index beba1e6..142d2be 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1056,15 +1056,9 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
{
struct pt_regs *regs = data;
- switch (action) {
- default:
- die_if_kernel("Unhandled kernel unaligned access or invalid "
+ die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
"instruction", regs);
- /* Fall through */
-
- case CU2_EXCEPTION:
- force_sig(SIGILL, current);
- }
+ force_sig(SIGILL, current);
return NOTIFY_OK;
}
@@ -1080,10 +1074,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
unsigned long __maybe_unused flags;
prev_state = exception_enter();
- die_if_kernel("do_cpu invoked from kernel context!", regs);
-
cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
+ if (cpid != 2)
+ die_if_kernel("do_cpu invoked from kernel context!", regs);
+
switch (cpid) {
case 0:
epc = (unsigned int __user *)exception_epc(regs);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/5] MIPS: Netlogic: Fix nlm_read_c2_status() definition
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
2013-06-10 7:30 ` [PATCH 1/5] MIPS: Move cop2 save/restore to switch_to() Jayachandran C
2013-06-10 7:30 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
@ 2013-06-10 7:30 ` Jayachandran C
2013-06-10 7:30 ` [PATCH 4/5] MIPS: Netlogic: rename nlm_cop2_save/restore Jayachandran C
2013-06-10 7:30 ` [PATCH 5/5] MIPS: Netlogic: COP2 save/restore code Jayachandran C
4 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:30 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
The sel argument os nlm_read_c2_status() was not used and the macro
returned the sel 0 in all cases. Fix this by defining two macros:
nlm_read_c2_status0() and nlm_read_c2_status1() to return the two
status registers.
Add functions to write to the status registers as well.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/netlogic/xlr/fmn.h | 8 ++++++--
arch/mips/netlogic/xlr/fmn.c | 2 +-
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h
index 2a78929..56c7b85 100644
--- a/arch/mips/include/asm/netlogic/xlr/fmn.h
+++ b/arch/mips/include/asm/netlogic/xlr/fmn.h
@@ -175,6 +175,10 @@
#define nlm_write_c2_cc14(s, v) __write_32bit_c2_register($30, s, v)
#define nlm_write_c2_cc15(s, v) __write_32bit_c2_register($31, s, v)
+#define nlm_read_c2_status0() __read_32bit_c2_register($2, 0)
+#define nlm_write_c2_status0(v) __write_32bit_c2_register($2, 0, v)
+#define nlm_read_c2_status1() __read_32bit_c2_register($2, 1)
+#define nlm_write_c2_status1(v) __write_32bit_c2_register($2, 1, v)
#define nlm_read_c2_status(sel) __read_32bit_c2_register($2, 0)
#define nlm_read_c2_config() __read_32bit_c2_register($3, 0)
#define nlm_write_c2_config(v) __write_32bit_c2_register($3, 0, v)
@@ -296,7 +300,7 @@ static inline int nlm_fmn_send(unsigned int size, unsigned int code,
*/
for (i = 0; i < 8; i++) {
nlm_msgsnd(dest);
- status = nlm_read_c2_status(0);
+ status = nlm_read_c2_status0();
if ((status & 0x2) == 1)
pr_info("Send pending fail!\n");
if ((status & 0x4) == 0)
@@ -316,7 +320,7 @@ static inline int nlm_fmn_receive(int bucket, int *size, int *code, int *stid,
/* wait for load pending to clear */
do {
- status = nlm_read_c2_status(1);
+ status = nlm_read_c2_status0();
} while ((status & 0x08) != 0);
/* receive error bits */
diff --git a/arch/mips/netlogic/xlr/fmn.c b/arch/mips/netlogic/xlr/fmn.c
index 4d74f03..0fdce61 100644
--- a/arch/mips/netlogic/xlr/fmn.c
+++ b/arch/mips/netlogic/xlr/fmn.c
@@ -80,7 +80,7 @@ static irqreturn_t fmn_message_handler(int irq, void *data)
while (1) {
/* 8 bkts per core, [24:31] each bit represents one bucket
* Bit is Zero if bucket is not empty */
- bkt_status = (nlm_read_c2_status() >> 24) & 0xff;
+ bkt_status = (nlm_read_c2_status0() >> 24) & 0xff;
if (bkt_status == 0xff)
break;
for (bucket = 0; bucket < 8; bucket++) {
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/5] MIPS: Netlogic: rename nlm_cop2_save/restore
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
` (2 preceding siblings ...)
2013-06-10 7:30 ` [PATCH 3/5] MIPS: Netlogic: Fix nlm_read_c2_status() definition Jayachandran C
@ 2013-06-10 7:30 ` Jayachandran C
2013-06-10 7:30 ` [PATCH 5/5] MIPS: Netlogic: COP2 save/restore code Jayachandran C
4 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:30 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
Rename macro nlm_cop2_enable() to nlm_cop2_enable_irqsave() and the macro
nlm_cop2_restore to nlm_cop2_disable_irqrestore(). The new names will
reflect the functionality better, and will make nlm_cop2_restore()
available to be used later in COP2 save/restore patch.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/netlogic/xlr/fmn.h | 4 ++--
arch/mips/netlogic/xlr/fmn.c | 16 ++++++++--------
2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/mips/include/asm/netlogic/xlr/fmn.h b/arch/mips/include/asm/netlogic/xlr/fmn.h
index 56c7b85..5604db3 100644
--- a/arch/mips/include/asm/netlogic/xlr/fmn.h
+++ b/arch/mips/include/asm/netlogic/xlr/fmn.h
@@ -241,7 +241,7 @@ static inline void nlm_msgwait(unsigned int mask)
/*
* Disable interrupts and enable COP2 access
*/
-static inline uint32_t nlm_cop2_enable(void)
+static inline uint32_t nlm_cop2_enable_irqsave(void)
{
uint32_t sr = read_c0_status();
@@ -249,7 +249,7 @@ static inline uint32_t nlm_cop2_enable(void)
return sr;
}
-static inline void nlm_cop2_restore(uint32_t sr)
+static inline void nlm_cop2_disable_irqrestore(uint32_t sr)
{
write_c0_status(sr);
}
diff --git a/arch/mips/netlogic/xlr/fmn.c b/arch/mips/netlogic/xlr/fmn.c
index 0fdce61..d428e84 100644
--- a/arch/mips/netlogic/xlr/fmn.c
+++ b/arch/mips/netlogic/xlr/fmn.c
@@ -74,7 +74,7 @@ static irqreturn_t fmn_message_handler(int irq, void *data)
struct nlm_fmn_msg msg;
uint32_t mflags, bkt_status;
- mflags = nlm_cop2_enable();
+ mflags = nlm_cop2_enable_irqsave();
/* Disable message ring interrupt */
nlm_fmn_setup_intr(irq, 0);
while (1) {
@@ -97,16 +97,16 @@ static irqreturn_t fmn_message_handler(int irq, void *data)
pr_warn("No msgring handler for stnid %d\n",
src_stnid);
else {
- nlm_cop2_restore(mflags);
+ nlm_cop2_disable_irqrestore(mflags);
hndlr->action(bucket, src_stnid, size, code,
&msg, hndlr->arg);
- mflags = nlm_cop2_enable();
+ mflags = nlm_cop2_enable_irqsave();
}
}
};
/* Enable message ring intr, to any thread in core */
nlm_fmn_setup_intr(irq, (1 << nlm_threads_per_core) - 1);
- nlm_cop2_restore(mflags);
+ nlm_cop2_disable_irqrestore(mflags);
return IRQ_HANDLED;
}
@@ -128,7 +128,7 @@ void xlr_percpu_fmn_init(void)
bucket_sizes = xlr_board_fmn_config.bucket_size;
cpu_fmn_info = &xlr_board_fmn_config.cpu[id];
- flags = nlm_cop2_enable();
+ flags = nlm_cop2_enable_irqsave();
/* Setup bucket sizes for the core. */
nlm_write_c2_bucksize(0, bucket_sizes[id * 8 + 0]);
@@ -166,7 +166,7 @@ void xlr_percpu_fmn_init(void)
/* enable FMN interrupts on this CPU */
nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
- nlm_cop2_restore(flags);
+ nlm_cop2_disable_irqrestore(flags);
}
@@ -198,7 +198,7 @@ void nlm_setup_fmn_irq(void)
/* setup irq only once */
setup_irq(IRQ_FMN, &fmn_irqaction);
- flags = nlm_cop2_enable();
+ flags = nlm_cop2_enable_irqsave();
nlm_fmn_setup_intr(IRQ_FMN, (1 << nlm_threads_per_core) - 1);
- nlm_cop2_restore(flags);
+ nlm_cop2_disable_irqrestore(flags);
}
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/5] MIPS: Netlogic: COP2 save/restore code
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
` (3 preceding siblings ...)
2013-06-10 7:30 ` [PATCH 4/5] MIPS: Netlogic: rename nlm_cop2_save/restore Jayachandran C
@ 2013-06-10 7:30 ` Jayachandran C
4 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C @ 2013-06-10 7:30 UTC (permalink / raw)
To: linux-mips, ralf, ddaney.cavm; +Cc: Jayachandran C
Add COP2 register state structure and functions for Netlogic XLP. The
RX and TX buffers and status registers are to be saved. Since the
registers are 64-bit, do the implementation in inline assembly which
works on both 32-bit and 64-bit kernels.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/mips/include/asm/cop2.h | 10 ++++
arch/mips/include/asm/processor.h | 13 ++++
arch/mips/netlogic/xlp/Makefile | 2 +-
arch/mips/netlogic/xlp/cop2-ex.c | 118 +++++++++++++++++++++++++++++++++++++
4 files changed, 142 insertions(+), 1 deletion(-)
create mode 100644 arch/mips/netlogic/xlp/cop2-ex.c
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h
index b17f38e..c1516cc 100644
--- a/arch/mips/include/asm/cop2.h
+++ b/arch/mips/include/asm/cop2.h
@@ -22,6 +22,16 @@ extern void octeon_cop2_restore(struct octeon_cop2_state *);
#define cop2_present 1
#define cop2_lazy_restore 1
+#elif defined(CONFIG_CPU_XLP)
+
+extern void nlm_cop2_save(struct nlm_cop2_state *);
+extern void nlm_cop2_restore(struct nlm_cop2_state *);
+#define cop2_save(r) nlm_cop2_save(r)
+#define cop2_restore(r) nlm_cop2_restore(r)
+
+#define cop2_present 1
+#define cop2_lazy_restore 0
+
#else
#define cop2_present 0
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 7c637a4..016dc4b 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -190,6 +190,16 @@ struct octeon_cvmseg_state {
[cpu_dcache_line_size() / sizeof(unsigned long)];
};
+#elif defined(CONFIG_CPU_XLP)
+struct nlm_cop2_state {
+ u64 rx[4];
+ u64 tx[4];
+ u32 tx_msg_status;
+ u32 rx_msg_status;
+};
+
+#define COP2_INIT \
+ .cp2 = {{0}, {0}, 0, 0},
#else
#define COP2_INIT
#endif
@@ -237,6 +247,9 @@ struct thread_struct {
struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
#endif
+#ifdef CONFIG_CPU_XLP
+ struct nlm_cop2_state cp2;
+#endif
struct mips_abi *abi;
};
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
index a84d6ed..e8dd14c 100644
--- a/arch/mips/netlogic/xlp/Makefile
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -1,3 +1,3 @@
-obj-y += setup.o nlm_hal.o
+obj-y += setup.o nlm_hal.o cop2-ex.o
obj-$(CONFIG_SMP) += wakeup.o
obj-$(CONFIG_USB) += usb-init.o
diff --git a/arch/mips/netlogic/xlp/cop2-ex.c b/arch/mips/netlogic/xlp/cop2-ex.c
new file mode 100644
index 0000000..52bc5de
--- /dev/null
+++ b/arch/mips/netlogic/xlp/cop2-ex.c
@@ -0,0 +1,118 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2013 Broadcom Corporation.
+ *
+ * based on arch/mips/cavium-octeon/cpu.c
+ * Copyright (C) 2009 Wind River Systems,
+ * written by Ralf Baechle <ralf@linux-mips.org>
+ */
+#include <linux/init.h>
+#include <linux/irqflags.h>
+#include <linux/notifier.h>
+#include <linux/prefetch.h>
+#include <linux/sched.h>
+
+#include <asm/cop2.h>
+#include <asm/current.h>
+#include <asm/mipsregs.h>
+#include <asm/page.h>
+
+#include <asm/netlogic/mips-extns.h>
+
+/*
+ * 64 bit ops are done in inline assembly to support 32 bit
+ * compilation
+ */
+void nlm_cop2_save(struct nlm_cop2_state *r)
+{
+ asm volatile(
+ ".set push\n"
+ ".set noat\n"
+ "dmfc2 $1, $0, 0\n"
+ "sd $1, 0(%1)\n"
+ "dmfc2 $1, $0, 1\n"
+ "sd $1, 8(%1)\n"
+ "dmfc2 $1, $0, 2\n"
+ "sd $1, 16(%1)\n"
+ "dmfc2 $1, $0, 3\n"
+ "sd $1, 24(%1)\n"
+ "dmfc2 $1, $1, 0\n"
+ "sd $1, 0(%2)\n"
+ "dmfc2 $1, $1, 1\n"
+ "sd $1, 8(%2)\n"
+ "dmfc2 $1, $1, 2\n"
+ "sd $1, 16(%2)\n"
+ "dmfc2 $1, $1, 3\n"
+ "sd $1, 24(%2)\n"
+ ".set pop\n"
+ : "=m"(*r)
+ : "r"(r->tx), "r"(r->rx));
+
+ r->tx_msg_status = __read_32bit_c2_register($2, 0);
+ r->rx_msg_status = __read_32bit_c2_register($3, 0) & 0x0fffffff;
+}
+
+void nlm_cop2_restore(struct nlm_cop2_state *r)
+{
+ u32 rstat;
+
+ asm volatile(
+ ".set push\n"
+ ".set noat\n"
+ "ld $1, 0(%1)\n"
+ "dmtc2 $1, $0, 0\n"
+ "ld $1, 8(%1)\n"
+ "dmtc2 $1, $0, 1\n"
+ "ld $1, 16(%1)\n"
+ "dmtc2 $1, $0, 2\n"
+ "ld $1, 24(%1)\n"
+ "dmtc2 $1, $0, 3\n"
+ "ld $1, 0(%2)\n"
+ "dmtc2 $1, $1, 0\n"
+ "ld $1, 8(%2)\n"
+ "dmtc2 $1, $1, 1\n"
+ "ld $1, 16(%2)\n"
+ "dmtc2 $1, $1, 2\n"
+ "ld $1, 24(%2)\n"
+ "dmtc2 $1, $1, 3\n"
+ ".set pop\n"
+ : : "m"(*r), "r"(r->tx), "r"(r->rx));
+
+ __write_32bit_c2_register($2, 0, r->tx_msg_status);
+ rstat = __read_32bit_c2_register($3, 0) & 0xf0000000u;
+ __write_32bit_c2_register($3, 0, r->rx_msg_status | rstat);
+}
+
+static int nlm_cu2_call(struct notifier_block *nfb, unsigned long action,
+ void *data)
+{
+ unsigned long flags;
+ unsigned int status;
+
+ switch (action) {
+ case CU2_EXCEPTION:
+ if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
+ break;
+ local_irq_save(flags);
+ KSTK_STATUS(current) |= ST0_CU2;
+ status = read_c0_status();
+ write_c0_status(status | ST0_CU2);
+ nlm_cop2_restore(&(current->thread.cp2));
+ write_c0_status(status & ~ST0_CU2);
+ local_irq_restore(flags);
+ pr_info("COP2 access enabled for pid %d (%s)\n",
+ current->pid, current->comm);
+ return NOTIFY_BAD; /* Don't call default notifier */
+ }
+
+ return NOTIFY_OK; /* Let default notifier send signals */
+}
+
+static int __init nlm_cu2_setup(void)
+{
+ return cu2_notifier(nlm_cu2_call, 0);
+}
+early_initcall(nlm_cu2_setup);
--
1.7.9.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2
2013-06-10 7:30 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
@ 2013-06-10 11:31 ` Sergei Shtylyov
2013-06-10 12:42 ` Ralf Baechle
1 sibling, 0 replies; 10+ messages in thread
From: Sergei Shtylyov @ 2013-06-10 11:31 UTC (permalink / raw)
To: Jayachandran C; +Cc: linux-mips, ralf, ddaney.cavm
On 10.06.2013 11:30, Jayachandran C wrote:
> Kernel threads should be able to use COP2 if the platform needs it.
> Do not call die_if_kernel() for a coprocessor unusable exception if
> the exception due to COP2 usage. Instead, the default notifier for
> COP2 exceptions is updated to call die_if_kernel.
> Signed-off-by: Jayachandran C <jchandra@broadcom.com>
> ---
> arch/mips/kernel/traps.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index beba1e6..142d2be 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -1056,15 +1056,9 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
> {
> struct pt_regs *regs = data;
>
> - switch (action) {
> - default:
> - die_if_kernel("Unhandled kernel unaligned access or invalid "
> + die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
> "instruction", regs);
Do not wrap the message please -- it's useful for grepping.
checkpatch.pl shouldn't complain about the line length.
WBR, Sergei
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2
2013-06-10 7:30 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
2013-06-10 11:31 ` Sergei Shtylyov
@ 2013-06-10 12:42 ` Ralf Baechle
2013-06-11 4:12 ` Jayachandran C.
1 sibling, 1 reply; 10+ messages in thread
From: Ralf Baechle @ 2013-06-10 12:42 UTC (permalink / raw)
To: Jayachandran C; +Cc: linux-mips, ddaney.cavm
On Mon, Jun 10, 2013 at 01:00:01PM +0530, Jayachandran C wrote:
> Kernel threads should be able to use COP2 if the platform needs it.
> Do not call die_if_kernel() for a coprocessor unusable exception if
> the exception due to COP2 usage. Instead, the default notifier for
> COP2 exceptions is updated to call die_if_kernel.
>
> Signed-off-by: Jayachandran C <jchandra@broadcom.com>
> ---
> arch/mips/kernel/traps.c | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> index beba1e6..142d2be 100644
> --- a/arch/mips/kernel/traps.c
> +++ b/arch/mips/kernel/traps.c
> @@ -1056,15 +1056,9 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
> {
> struct pt_regs *regs = data;
>
> - switch (action) {
> - default:
> - die_if_kernel("Unhandled kernel unaligned access or invalid "
> + die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
> "instruction", regs);
> - /* Fall through */
> -
> - case CU2_EXCEPTION:
> - force_sig(SIGILL, current);
> - }
> + force_sig(SIGILL, current);
>
> return NOTIFY_OK;
> }
The idea for cu2_chain notifiers is that they should return a value with
NOTIFY_STOP_MASK set. That would prevent further calls to other notifiers.
The default_cu2_call() notifier is installed with the lowest possible
priority and is meant to only be called if there is no other notifier was
installed, that is on a bog standard MIPS core with no CP2.
> @@ -1080,10 +1074,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
> unsigned long __maybe_unused flags;
>
> prev_state = exception_enter();
> - die_if_kernel("do_cpu invoked from kernel context!", regs);
> -
> cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
>
> + if (cpid != 2)
> + die_if_kernel("do_cpu invoked from kernel context!", regs);
> +
> switch (cpid) {
> case 0:
> epc = (unsigned int __user *)exception_epc(regs);
I'm ok with this segment.
Ralf
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2
2013-06-10 12:42 ` Ralf Baechle
@ 2013-06-11 4:12 ` Jayachandran C.
0 siblings, 0 replies; 10+ messages in thread
From: Jayachandran C. @ 2013-06-11 4:12 UTC (permalink / raw)
To: Ralf Baechle; +Cc: linux-mips, ddaney.cavm
On Mon, Jun 10, 2013 at 02:42:29PM +0200, Ralf Baechle wrote:
> On Mon, Jun 10, 2013 at 01:00:01PM +0530, Jayachandran C wrote:
>
> > Kernel threads should be able to use COP2 if the platform needs it.
> > Do not call die_if_kernel() for a coprocessor unusable exception if
> > the exception due to COP2 usage. Instead, the default notifier for
> > COP2 exceptions is updated to call die_if_kernel.
> >
> > Signed-off-by: Jayachandran C <jchandra@broadcom.com>
> > ---
> > arch/mips/kernel/traps.c | 15 +++++----------
> > 1 file changed, 5 insertions(+), 10 deletions(-)
> >
> > diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
> > index beba1e6..142d2be 100644
> > --- a/arch/mips/kernel/traps.c
> > +++ b/arch/mips/kernel/traps.c
> > @@ -1056,15 +1056,9 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action,
> > {
> > struct pt_regs *regs = data;
> >
> > - switch (action) {
> > - default:
> > - die_if_kernel("Unhandled kernel unaligned access or invalid "
> > + die_if_kernel("COP2: Unhandled kernel unaligned access or invalid "
> > "instruction", regs);
> > - /* Fall through */
> > -
> > - case CU2_EXCEPTION:
> > - force_sig(SIGILL, current);
> > - }
> > + force_sig(SIGILL, current);
> >
> > return NOTIFY_OK;
> > }
>
> The idea for cu2_chain notifiers is that they should return a value with
> NOTIFY_STOP_MASK set. That would prevent further calls to other notifiers.
> The default_cu2_call() notifier is installed with the lowest possible
> priority and is meant to only be called if there is no other notifier was
> installed, that is on a bog standard MIPS core with no CP2.
I am trying to move the die_if_kernel from do_cpu() to here for COP2
exceptions. In the existing code, COP2 unusable exception calls
die_if_kernel in do_cpu() itself, so COP2 unusable generated by kernel
threads will not make it to the notifiers. With this change (and the
one below), die_if_kernel() is called only if the all the notifiers
pass it thru.
>
> > @@ -1080,10 +1074,11 @@ asmlinkage void do_cpu(struct pt_regs *regs)
> > unsigned long __maybe_unused flags;
> >
> > prev_state = exception_enter();
> > - die_if_kernel("do_cpu invoked from kernel context!", regs);
> > -
> > cpid = (regs->cp0_cause >> CAUSEB_CE) & 3;
> >
> > + if (cpid != 2)
> > + die_if_kernel("do_cpu invoked from kernel context!", regs);
> > +
> > switch (cpid) {
> > case 0:
> > epc = (unsigned int __user *)exception_epc(regs);
>
> I'm ok with this segment.
>
> Ralf
JC.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-06-11 4:12 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-10 7:29 [PATCH 0/5 v2] Cop2 save and restore for Netlogic XLP Jayachandran C
2013-06-10 7:30 ` [PATCH 1/5] MIPS: Move cop2 save/restore to switch_to() Jayachandran C
2013-06-10 7:30 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
2013-06-10 11:31 ` Sergei Shtylyov
2013-06-10 12:42 ` Ralf Baechle
2013-06-11 4:12 ` Jayachandran C.
2013-06-10 7:30 ` [PATCH 3/5] MIPS: Netlogic: Fix nlm_read_c2_status() definition Jayachandran C
2013-06-10 7:30 ` [PATCH 4/5] MIPS: Netlogic: rename nlm_cop2_save/restore Jayachandran C
2013-06-10 7:30 ` [PATCH 5/5] MIPS: Netlogic: COP2 save/restore code Jayachandran C
-- strict thread matches above, loose matches on Subject: below --
2013-03-22 16:24 [RFC PATCH 0/5] Cop2 save/restore for XLR/XLP Jayachandran C
2013-03-22 16:24 ` [PATCH 2/5] MIPS: Allow kernel to use coprocessor 2 Jayachandran C
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.