svn commit: r203509 - head/sys/mips/sibyte

Neel Natu neel at FreeBSD.org
Fri Feb 5 03:20:47 UTC 2010


Author: neel
Date: Fri Feb  5 03:20:47 2010
New Revision: 203509
URL: http://svn.freebsd.org/changeset/base/203509

Log:
  Reimplement all functions to access the system control unit in C.
  
  The only reason we need to have the sb_load64() and sb_store64()
  functions in assembly is to cheat the compiler and generate the
  'ld' and 'sd' instructions which it otherwise will not do when
  compiling for a 32-bit architecture. There are some 64-bit
  registers in the SCD unit that must be accessed using 64-bit
  load and store instructions.

Modified:
  head/sys/mips/sibyte/sb_asm.S
  head/sys/mips/sibyte/sb_scd.c
  head/sys/mips/sibyte/sb_scd.h
  head/sys/mips/sibyte/sb_zbbus.c

Modified: head/sys/mips/sibyte/sb_asm.S
==============================================================================
--- head/sys/mips/sibyte/sb_asm.S	Fri Feb  5 02:40:42 2010	(r203508)
+++ head/sys/mips/sibyte/sb_asm.S	Fri Feb  5 03:20:47 2010	(r203509)
@@ -22,6 +22,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ * $FreeBSD$
  */
 
 #include <machine/asm.h>
@@ -41,115 +43,40 @@
 .set	noreorder
 
 /*
- * return (MIPS_PHYS_TO_KSEG1(0x10020008))
- * Parameters: none
+ * Parameters:		uint32_t ptr
+ * Return value: 	*(uint64_t *)ptr
  */
-LEAF(sb_read_syscfg)
-	lui     v0, 0xb002
-	ori     v0, v0, 0x8
-	ld      v1, 0(v0)	/* syscfg = MIPS_PHYS_TO_KSEG1(0x10020008) */
+LEAF(sb_load64)
+	ld      v1, 0(a0)	/* result = *(uint64_t *)ptr */
 	move	v0, v1
-	dsll32	v0, v0, 0
-	dsrl32	v0, v0, 0	/* v0 = lower_uint32(mask) */
+#if defined(TARGET_BIG_ENDIAN)
+	dsll32	v1, v1, 0
+	dsrl32	v1, v1, 0	/* v1 = lower_uint32(result) */
 	jr	ra
-	dsrl32	v1, v1, 0	/* v1 = upper_uint32(mask) */
-END(sb_read_syscfg)
-
-/*
- * MIPS_PHYS_TO_KSEG1(0x10020008) = (uint64_t)val
- * Parameters:
- * - lower_uint32(val): a0
- * - upper_uint32(val): a1
- */
-LEAF(sb_write_syscfg)
-	lui     v0, 0xb002
-	ori     v0, v0, 0x8
-	dsll32	a1, a1, 0	/* clear lower 32 bits of a1 */
-	dsll32	a0, a0, 0
-	dsrl32	a0, a0, 0	/* clear upper 32 bits of a0 */
-	or	a1, a1, a0
-	sd	a1, 0(v0)	/* MIPS_PHYS_TO_KSEG1(0x10020008) = val */
-	jr	ra
-	nop
-	nop
-END(sb_write_syscfg)
-
-/*
- * MIPS_PHYS_TO_KSEG1(0x10020028) |= (1 << intsrc)
- *
- * Parameters:
- * - intsrc (a0)
- */
-LEAF(sb_disable_intsrc)
-	lui     v0, 0xb002
-	ori     v0, v0, 0x28
-	ld      v1, 0(v0)	/* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
-	li      a1, 1
-	dsllv   a1, a1, a0
-	or      a1, a1, v1	/* mask |= (1 << intsrc) */
-	jr	ra
-	sd      a1, 0(v0)	/* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */
-END(sb_disable_intsrc)
-
-/*
- * MIPS_PHYS_TO_KSEG1(0x10020028) &= ~(1 << intsrc)
- *
- * Parameters:
- * - intsrc (a0)
- */
-LEAF(sb_enable_intsrc)
-	lui     v0, 0xb002
-	ori     v0, v0, 0x28
-	ld      v1, 0(v0)	/* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
-	li      a2, 1
-	dsllv   a2, a2, a0
-	nor     a2, zero, a2
-	and     a2, a2, v1	/* mask &= ~(1 << intsrc) */
-	sd      a2, 0(v0)	/* MIPS_PHYS_TO_KSEG1(0x10020028) = mask */
-	jr      ra
-	nop
-END(sb_enable_intsrc)
-
-/*
- * return ((uint64_t)MIPS_PHYS_TO_KSEG1(0x10020028))
- * Parameters: none
- */
-LEAF(sb_read_intsrc_mask)
-	lui     v0, 0xb002
-	ori     v0, v0, 0x28
-	ld      v1, 0(v0)	/* mask = MIPS_PHYS_TO_KSEG1(0x10020028) */
-	move	v0, v1
+	dsrl32	v0, v0, 0	/* v0 = upper_uint32(result) */
+#else
 	dsll32	v0, v0, 0
-	dsrl32	v0, v0, 0	/* v0 = lower_uint32(mask) */
+	dsrl32	v0, v0, 0	/* v0 = lower_uint32(result) */
 	jr	ra
-	dsrl32	v1, v1, 0	/* v1 = upper_uint32(mask) */
-END(sb_read_intsrc_mask)
-
-/*
- * return ((uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc)
- * Parameters:
- * - intsrc (a0)
- */
-LEAF(sb_read_intmap)
-	sll	a0, a0, 3	/* compute the offset of the intmap register */
-	lui     v0, 0xb002
-	addu    a0, a0, v0
-	ld      v0, 512(a0)	/* v0 = MIPS_PHYS_TO_KSEG1(0x10020200) + off */
-	jr      ra
-	nop
-END(sb_read_intmap)
-
-/*
- * (uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc = irq
- * Parameters:
- * - intsrc (a0)
- * - irq    (a1)
- */
-LEAF(sb_write_intmap)
-	sll     a0, a0, 0x3 /* compute the offset of the intmap register */
-	lui     v0, 0xb002
-	addu    a0, a0, v0
-	sd      a1, 512(a0) /* MIPS_PHYS_TO_KSEG1(0x10020200) + off = irq */
-	jr      ra
-	nop
-END(sb_write_intmap)
+	dsrl32	v1, v1, 0	/* v1 = upper_uint32(result) */
+#endif
+END(sb_load64)
+
+/*
+ * Parameters:		uint32_t ptr, uint64_t val
+ * Return value:	void
+ */
+LEAF(sb_store64)
+#if defined(TARGET_BIG_ENDIAN)
+	dsll32	a2, a2, 0	/* a2 = upper_uint32(val) */
+	dsll32	a3, a3, 0	/* a3 = lower_uint32(val) */
+	dsrl32	a3, a3, 0
+#else
+	dsll32	a3, a3, 0	/* a3 = upper_uint32(val) */
+	dsll32	a2, a2, 0	/* a2 = lower_uint32(val) */
+	dsrl32	a2, a2, 0
+#endif
+	or	t0, a2, a3
+	jr	ra
+	sd	t0, 0(a0)
+END(sb_store64)

Modified: head/sys/mips/sibyte/sb_scd.c
==============================================================================
--- head/sys/mips/sibyte/sb_scd.c	Fri Feb  5 02:40:42 2010	(r203508)
+++ head/sys/mips/sibyte/sb_scd.c	Fri Feb  5 03:20:47 2010	(r203509)
@@ -23,6 +23,10 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/systm.h>
@@ -30,10 +34,12 @@
 #include <sys/bus.h>
 
 #include <machine/resource.h>
+#include <machine/intr_machdep.h>
 
 #include "sb_scd.h"
 
-__FBSDID("$FreeBSD$");
+extern void	sb_store64(uint32_t addr, uint64_t val);
+extern uint64_t	sb_load64(uint32_t addr);
 
 /*
  * System Control and Debug (SCD) unit on the Sibyte ZBbus.
@@ -44,8 +50,38 @@ __FBSDID("$FreeBSD$");
  */
 #define	GET_VAL_64(x, b, n)	(((x) >> (b)) & ((1ULL << (n)) - 1))
 
+#define	SYSREV_ADDR		MIPS_PHYS_TO_KSEG1(0x10020000)
+#define	SYSREV_NUM_PROCESSORS(x) GET_VAL_64((x), 24, 4)
+
+#define	SYSCFG_ADDR		MIPS_PHYS_TO_KSEG1(0x10020008)
 #define SYSCFG_PLLDIV(x)	GET_VAL_64((x), 7, 5)
 
+#define	INTSRC_MASK_ADDR(cpu)	\
+	(MIPS_PHYS_TO_KSEG1(0x10020028) | ((cpu) << 13))
+
+#define	INTSRC_MAP_ADDR(cpu, intsrc)	\
+	(MIPS_PHYS_TO_KSEG1(0x10020200) | ((cpu) << 13)) + (intsrc * 8)
+
+#define	MAILBOX_SET_ADDR(cpu)	\
+	(MIPS_PHYS_TO_KSEG1(0x100200C8) | ((cpu) << 13))
+
+#define	MAILBOX_CLEAR_ADDR(cpu)	\
+	(MIPS_PHYS_TO_KSEG1(0x100200D0) | ((cpu) << 13))
+
+static uint64_t
+sb_read_syscfg(void)
+{
+
+	return (sb_load64(SYSCFG_ADDR));
+}
+
+static void
+sb_write_syscfg(uint64_t val)
+{
+	
+	sb_store64(SYSCFG_ADDR, val);
+}
+
 uint64_t
 sb_cpu_speed(void)
 {
@@ -76,6 +112,71 @@ sb_system_reset(void)
 	sb_write_syscfg(syscfg);
 }
 
+void
+sb_disable_intsrc(int cpu, int src)
+{
+	uint32_t regaddr;
+	uint64_t val;
+
+	regaddr = INTSRC_MASK_ADDR(cpu);
+
+	val = sb_load64(regaddr);
+	val |= 1ULL << src;
+	sb_store64(regaddr, val);
+}
+
+void
+sb_enable_intsrc(int cpu, int src)
+{
+	uint32_t regaddr;
+	uint64_t val;
+
+	regaddr = INTSRC_MASK_ADDR(cpu);
+
+	val = sb_load64(regaddr);
+	val &= ~(1ULL << src);
+	sb_store64(regaddr, val);
+}
+
+void
+sb_write_intsrc_mask(int cpu, uint64_t val)
+{
+	uint32_t regaddr;
+
+	regaddr = INTSRC_MASK_ADDR(cpu);
+	sb_store64(regaddr, val);
+}
+
+uint64_t
+sb_read_intsrc_mask(int cpu)
+{
+	uint32_t regaddr;
+	uint64_t val;
+
+	regaddr = INTSRC_MASK_ADDR(cpu);
+	val = sb_load64(regaddr);
+
+	return (val);
+}
+
+void
+sb_write_intmap(int cpu, int intsrc, int intrnum)
+{
+	uint32_t regaddr;
+
+	regaddr = INTSRC_MAP_ADDR(cpu, intsrc);
+	sb_store64(regaddr, intrnum);
+}
+
+int
+sb_read_intmap(int cpu, int intsrc)
+{
+	uint32_t regaddr;
+
+	regaddr = INTSRC_MAP_ADDR(cpu, intsrc);
+	return (sb_load64(regaddr) & 0x7);
+}
+
 int
 sb_route_intsrc(int intsrc)
 {
@@ -86,16 +187,10 @@ sb_route_intsrc(int intsrc)
 
 	/*
 	 * Interrupt 5 is used by sources internal to the CPU (e.g. timer).
-	 * Use a deterministic mapping for the remaining sources to map to
-	 * interrupt numbers 0 through 4.
+	 * Use a deterministic mapping for the remaining sources.
 	 */
 	intrnum = intsrc % 5;
 
-	/*
-	 * Program the interrupt mapper while we are here.
-	 */
-	sb_write_intmap(intsrc, intrnum);
-
 	return (intrnum);
 }
 
@@ -116,16 +211,14 @@ scd_attach(device_t dev)
 	int rid;
 	struct resource *res;
 
-	if (bootverbose) {
+	if (bootverbose)
 		device_printf(dev, "attached.\n");
-	}
 
 	rid = 0;
 	res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, SCD_PHYSADDR,
 				 SCD_PHYSADDR + SCD_SIZE - 1, SCD_SIZE, 0);
-	if (res == NULL) {
+	if (res == NULL)
 		panic("Cannot allocate resource for system control and debug.");
-	}
 	
 	return (0);
 }

Modified: head/sys/mips/sibyte/sb_scd.h
==============================================================================
--- head/sys/mips/sibyte/sb_scd.h	Fri Feb  5 02:40:42 2010	(r203508)
+++ head/sys/mips/sibyte/sb_scd.h	Fri Feb  5 03:20:47 2010	(r203509)
@@ -22,6 +22,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ * $FreeBSD$
  */
 
 #ifndef _SB_SCD_H_
@@ -33,14 +35,11 @@ uint64_t	sb_cpu_speed(void);
 void		sb_system_reset(void);
 
 int		sb_route_intsrc(int src);
-void		sb_enable_intsrc(int src);
-void		sb_disable_intsrc(int src);
-uint64_t	sb_read_intsrc_mask(void);
-
-int		sb_read_intmap(int intsrc);
-void		sb_write_intmap(int intsrc, int intrnum);
-
-uint64_t	sb_read_syscfg(void);
-void		sb_write_syscfg(uint64_t val);
+void		sb_enable_intsrc(int cpu, int src);
+void		sb_disable_intsrc(int cpu, int src);
+uint64_t	sb_read_intsrc_mask(int cpu);
+void		sb_write_intsrc_mask(int cpu, uint64_t mask);
+void		sb_write_intmap(int cpu, int intsrc, int intrnum);
+int		sb_read_intmap(int cpu, int intsrc);
 
 #endif	/* _SB_SCD_H_ */

Modified: head/sys/mips/sibyte/sb_zbbus.c
==============================================================================
--- head/sys/mips/sibyte/sb_zbbus.c	Fri Feb  5 02:40:42 2010	(r203508)
+++ head/sys/mips/sibyte/sb_zbbus.c	Fri Feb  5 03:20:47 2010	(r203509)
@@ -118,7 +118,7 @@ sb_intmap_activate(int intrnum, device_t
 
 	map = sb_intmap_lookup(intrnum, dev, rid);
 	if (map) {
-		sb_enable_intsrc(map->intsrc);
+		sb_enable_intsrc(0, map->intsrc);
 	} else {
 		/*
 		 * In zbbus_setup_intr() we blindly call sb_intmap_activate()


More information about the svn-src-all mailing list