summaryrefslogtreecommitdiffstats
path: root/sys/mips/sibyte
diff options
context:
space:
mode:
authorneel <neel@FreeBSD.org>2010-02-05 03:20:47 +0000
committerneel <neel@FreeBSD.org>2010-02-05 03:20:47 +0000
commit5b7a1d2513215266bae13233b65c25a0c0c4e41e (patch)
tree90d80c2dd16f26dc6b50ee39753078612ea5cc8a /sys/mips/sibyte
parent39dbfe1f7618ec63e0648730f30c3263f05dbf23 (diff)
downloadFreeBSD-src-5b7a1d2513215266bae13233b65c25a0c0c4e41e.zip
FreeBSD-src-5b7a1d2513215266bae13233b65c25a0c0c4e41e.tar.gz
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.
Diffstat (limited to 'sys/mips/sibyte')
-rw-r--r--sys/mips/sibyte/sb_asm.S135
-rw-r--r--sys/mips/sibyte/sb_scd.c117
-rw-r--r--sys/mips/sibyte/sb_scd.h17
-rw-r--r--sys/mips/sibyte/sb_zbbus.c2
4 files changed, 145 insertions, 126 deletions
diff --git a/sys/mips/sibyte/sb_asm.S b/sys/mips/sibyte/sb_asm.S
index d878113..b81c067 100644
--- a/sys/mips/sibyte/sb_asm.S
+++ b/sys/mips/sibyte/sb_asm.S
@@ -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) */
- 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 */
+#if defined(TARGET_BIG_ENDIAN)
+ dsll32 v1, v1, 0
+ dsrl32 v1, v1, 0 /* v1 = lower_uint32(result) */
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)
+ dsrl32 v1, v1, 0 /* v1 = upper_uint32(result) */
+#endif
+END(sb_load64)
/*
- * return ((uint64_t *)MIPS_PHYS_TO_KSEG1(0x10020200) + intsrc)
- * Parameters:
- * - intsrc (a0)
+ * Parameters: uint32_t ptr, uint64_t val
+ * Return value: void
*/
-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)
+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)
diff --git a/sys/mips/sibyte/sb_scd.c b/sys/mips/sibyte/sb_scd.c
index d6a80e1..c499822 100644
--- a/sys/mips/sibyte/sb_scd.c
+++ b/sys/mips/sibyte/sb_scd.c
@@ -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);
}
diff --git a/sys/mips/sibyte/sb_scd.h b/sys/mips/sibyte/sb_scd.h
index 8de3aae..8f60716 100644
--- a/sys/mips/sibyte/sb_scd.h
+++ b/sys/mips/sibyte/sb_scd.h
@@ -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_ */
diff --git a/sys/mips/sibyte/sb_zbbus.c b/sys/mips/sibyte/sb_zbbus.c
index 93ace1b..bede796 100644
--- a/sys/mips/sibyte/sb_zbbus.c
+++ b/sys/mips/sibyte/sb_zbbus.c
@@ -118,7 +118,7 @@ sb_intmap_activate(int intrnum, device_t dev, int rid)
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()
OpenPOWER on IntegriCloud