From fb05f6da35ea1c15c553abe6f23f656bf18dc5db Mon Sep 17 00:00:00 2001
From: Michal Simek <monstr@monstr.eu>
Date: Mon, 7 May 2007 23:58:31 +0200
Subject: [PATCH] new: USE_MSR_INTR support

---
 board/xilinx/ml401/xparameters.h |  3 ++-
 cpu/microblaze/cache.c           |  9 ++++----
 cpu/microblaze/interrupts.c      |  4 ++--
 cpu/microblaze/irq.S             | 14 ++++++++++++
 include/asm-microblaze/asm.h     | 37 ++++++++++++++++++++++++++++++++
 5 files changed, 60 insertions(+), 7 deletions(-)
 mode change 100644 => 100755 cpu/microblaze/cache.c
 mode change 100644 => 100755 cpu/microblaze/interrupts.c
 mode change 100644 => 100755 cpu/microblaze/irq.S
 mode change 100644 => 100755 include/asm-microblaze/asm.h

diff --git a/board/xilinx/ml401/xparameters.h b/board/xilinx/ml401/xparameters.h
index 2b0c045b9f..1a116ead1b 100755
--- a/board/xilinx/ml401/xparameters.h
+++ b/board/xilinx/ml401/xparameters.h
@@ -29,11 +29,12 @@
 #define XILINX_CLOCK_FREQ	100000000
 
 /* Microblaze is microblaze_0 */
+#define XILINX_USE_MSR_INSTR	1
 #define XILINX_FSL_NUMBER	3
 
 /* Interrupt controller is opb_intc_0 */
 #define XILINX_INTC_BASEADDR	0x41200000
-#define XILINX_INTC_NUM_INTR_INPUTS	5
+#define XILINX_INTC_NUM_INTR_INPUTS	6
 
 /* Timer pheriphery is opb_timer_1 */
 #define XILINX_TIMER_BASEADDR	0x41c00000
diff --git a/cpu/microblaze/cache.c b/cpu/microblaze/cache.c
old mode 100644
new mode 100755
index 683044caea..4f36a84ec4
--- a/cpu/microblaze/cache.c
+++ b/cpu/microblaze/cache.c
@@ -23,6 +23,7 @@
  */
 
 #include <common.h>
+#include <asm/asm.h>
 
 #if (CONFIG_COMMANDS & CFG_CMD_CACHE)
 
@@ -47,18 +48,18 @@ int icache_status (void)
 }
 
 void	icache_enable (void) {
-	__asm__ __volatile__ ("msrset r0, 0x80");
+	MSRSET(0x20);
 }
 
 void	icache_disable(void) {
-	__asm__ __volatile__ ("msrclr r0, 0x80");
+	MSRCLR(0x20);
 }
 
 void	dcache_enable (void) {
-	__asm__ __volatile__ ("msrset r0, 0x20");
+	MSRSET(0x80);
 }
 
 void	dcache_disable(void) {
-	__asm__ __volatile__ ("msrclr r0, 0x20");
+	MSRCLR(0x80);
 }
 #endif
diff --git a/cpu/microblaze/interrupts.c b/cpu/microblaze/interrupts.c
old mode 100644
new mode 100755
index dd6a0c7776..b61153f8e6
--- a/cpu/microblaze/interrupts.c
+++ b/cpu/microblaze/interrupts.c
@@ -36,12 +36,12 @@ extern void microblaze_enable_interrupts (void);
 
 void enable_interrupts (void)
 {
-	__asm__ __volatile__ ("msrset r0, 0x2");
+	MSRSET(0x2);
 }
 
 int disable_interrupts (void)
 {
-	__asm__ __volatile__ ("msrclr r0, 0x2");
+	MSRCLR(0x2);
 	return 0;
 }
 
diff --git a/cpu/microblaze/irq.S b/cpu/microblaze/irq.S
old mode 100644
new mode 100755
index 393d6e8dd4..e1fc19046c
--- a/cpu/microblaze/irq.S
+++ b/cpu/microblaze/irq.S
@@ -23,6 +23,7 @@
  */
 
 #include <config.h>
+#include <asm/asm.h>
 	.text
 	.global _interrupt_handler
 _interrupt_handler:
@@ -151,7 +152,20 @@ _interrupt_handler:
 	addi	r1, r1, 4
 
 	/* enable_interrupt */
+#ifdef XILINX_USE_MSR_INSTR
 	msrset	r0, 2
+#else
+	/* FIXME unstable in stressed mode - two irqs */
+	nop
+	addi	r1, r1, -4
+	swi	r12, r1, 0
+	mfs	r12, rmsr
+	ori	r12, r12, 2
+	mts	rmsr, r12
+	lwi	r12, r1, 0
+	addi	r1, r1, 4
+	nop
+#endif
 	bra	r14
 	nop
 	nop
diff --git a/include/asm-microblaze/asm.h b/include/asm-microblaze/asm.h
old mode 100644
new mode 100755
index fcda31f4a8..c59854a860
--- a/include/asm-microblaze/asm.h
+++ b/include/asm-microblaze/asm.h
@@ -39,5 +39,42 @@
 #define MTS(val) \
 	__asm__ __volatile__ ("mts rmsr, %0"::"r" (val));
 
+/* get return address from interrupt */
 #define R14(val) \
 	__asm__ __volatile__ ("addi %0, r14, 0":"=r" (val));
+
+/* use machine status registe USE_MSR_REG */
+#ifdef XILINX_USE_MSR_INSTR
+#define MSRSET(val) \
+	__asm__ __volatile__ ("msrset r0," #val );
+
+#define MSRCLR(val) \
+	__asm__ __volatile__ ("msrclr r0," #val );
+
+#else
+#define MSRSET(val)						\
+{								\
+	register unsigned tmp;					\
+	__asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			ori	%0, %0, "#val";			\
+			mts	rmsr, %0;			\
+			nop;"					\
+			: "=r" (tmp)				\
+			: "d" (val)				\
+			: "memory");				\
+}
+
+#define MSRCLR(val)						\
+{								\
+	register unsigned tmp;					\
+	__asm__ __volatile__ ("					\
+			mfs 	%0, rmsr;			\
+			andi	%0, %0, ~"#val";		\
+			mts	rmsr, %0;			\
+			nop;"					\
+			: "=r" (tmp)				\
+			: "d" (val)				\
+			: "memory");				\
+}
+#endif
-- 
2.39.5