svn commit: r195333 - projects/mips/sys/mips/sibyte

Warner Losh imp at FreeBSD.org
Sat Jul 4 03:05:48 UTC 2009


Author: imp
Date: Sat Jul  4 03:05:48 2009
New Revision: 195333
URL: http://svn.freebsd.org/changeset/base/195333

Log:
  Add sibyte device support.
  
  Submitted by:	Neelkanth Natu

Added:
  projects/mips/sys/mips/sibyte/
  projects/mips/sys/mips/sibyte/ata_zbbus.c   (contents, props changed)
  projects/mips/sys/mips/sibyte/files.sibyte
  projects/mips/sys/mips/sibyte/sb_asm.S   (contents, props changed)
  projects/mips/sys/mips/sibyte/sb_machdep.c   (contents, props changed)
  projects/mips/sys/mips/sibyte/sb_scd.c   (contents, props changed)
  projects/mips/sys/mips/sibyte/sb_scd.h   (contents, props changed)
  projects/mips/sys/mips/sibyte/sb_zbbus.c   (contents, props changed)
  projects/mips/sys/mips/sibyte/sb_zbpci.c   (contents, props changed)

Added: projects/mips/sys/mips/sibyte/ata_zbbus.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/ata_zbbus.c	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,170 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sema.h>
+#include <sys/taskqueue.h>
+
+#include <machine/bus.h>
+
+#include <vm/uma.h>
+
+#include <sys/ata.h>
+#include <dev/ata/ata-all.h>
+
+#include <machine/resource.h>
+
+__FBSDID("$FreeBSD$");
+
+static int
+ata_zbbus_probe(device_t dev)
+{
+
+	return (ata_probe(dev));
+}
+
+static int
+ata_zbbus_attach(device_t dev)
+{
+	int i, rid, regshift, regoffset;
+	struct ata_channel *ch;
+	struct resource *io;
+	
+	ch = device_get_softc(dev);
+
+	if (ch->attached)
+		return (0);
+	ch->attached = 1;
+
+	rid = 0;
+	io = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 0, ~0, 1, RF_ACTIVE);
+	if (io == NULL)
+		return (ENXIO);
+
+	/*
+	 * SWARM needs an address shift of 5 when accessing ATA registers.
+	 *
+	 * For e.g. an access to register 4 actually needs an address
+	 * of (4 << 5) to be output on the generic bus.
+	 */
+	regshift = 5;
+	resource_int_value(device_get_name(dev), device_get_unit(dev),
+			   "regshift", &regshift);
+	if (regshift && bootverbose)
+		device_printf(dev, "using a register shift of %d\n", regshift);
+
+	regoffset = 0x1F0;
+	resource_int_value(device_get_name(dev), device_get_unit(dev),
+			   "regoffset", &regoffset);
+	if (regoffset && bootverbose) {
+		device_printf(dev, "using a register offset of 0x%0x\n",
+			      regoffset);
+	}
+
+	/* setup the ata register addresses */
+	for (i = ATA_DATA; i <= ATA_COMMAND; ++i) {
+		ch->r_io[i].res = io;
+		ch->r_io[i].offset = (regoffset + i) << regshift;
+	}
+
+	ch->r_io[ATA_CONTROL].res = io;
+	ch->r_io[ATA_CONTROL].offset = (regoffset + ATA_CTLOFFSET) << regshift;
+	ch->r_io[ATA_IDX_ADDR].res = io;	/* XXX what is this used for */
+	ata_default_registers(dev);
+
+	/* initialize softc for this channel */
+	ch->unit = 0;
+	ch->flags |= ATA_USE_16BIT;
+	ata_generic_hw(dev);
+
+	return (ata_attach(dev));
+}
+
+static int
+ata_zbbus_detach(device_t dev)
+{
+	int error;
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (!ch->attached)
+		return (0);
+	ch->attached = 0;
+
+	error = ata_detach(dev);
+
+	bus_release_resource(dev, SYS_RES_MEMORY, 0,
+			     ch->r_io[ATA_IDX_ADDR].res);
+
+	return (error);
+}
+
+static int
+ata_zbbus_suspend(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (!ch->attached)
+		return (0);
+
+	return (ata_suspend(dev));
+}
+
+static int
+ata_zbbus_resume(device_t dev)
+{
+	struct ata_channel *ch = device_get_softc(dev);
+
+	if (!ch->attached)
+		return (0);
+
+	return (ata_resume(dev));
+}
+
+static device_method_t ata_zbbus_methods[] = {
+	/* device interface */
+	DEVMETHOD(device_probe,		ata_zbbus_probe),
+	DEVMETHOD(device_attach,	ata_zbbus_attach),
+	DEVMETHOD(device_detach,	ata_zbbus_detach),
+	DEVMETHOD(device_suspend,	ata_zbbus_suspend),
+	DEVMETHOD(device_resume,	ata_zbbus_resume),
+
+	{ 0, 0 }
+};
+
+static driver_t ata_zbbus_driver = {
+	"ata",
+	ata_zbbus_methods,
+	sizeof(struct ata_channel)
+};
+
+DRIVER_MODULE(ata, zbbus, ata_zbbus_driver, ata_devclass, 0, 0);

Added: projects/mips/sys/mips/sibyte/files.sibyte
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/files.sibyte	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+mips/sibyte/sb_machdep.c			standard
+mips/sibyte/sb_zbbus.c				standard
+mips/sibyte/sb_zbpci.c				standard
+mips/sibyte/sb_scd.c				standard
+mips/sibyte/ata_zbbus.c				standard
+
+mips/sibyte/sb_asm.S				standard

Added: projects/mips/sys/mips/sibyte/sb_asm.S
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/sb_asm.S	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,155 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#include <machine/asm.h>
+
+/*
+ * We compile a 32-bit kernel to run on the SB-1 processor which is a 64-bit
+ * processor. It has some registers that must be accessed using 64-bit load
+ * and store instructions.
+ *
+ * So we have to resort to assembly because the compiler does not emit the
+ * 'ld' and 'sd' instructions since it thinks that it is compiling for a
+ * 32-bit mips processor.
+ */
+
+.set	mips64
+.set	noat
+.set	noreorder
+
+/*
+ * return (MIPS_PHYS_TO_KSEG1(0x10020008))
+ * Parameters: none
+ */
+LEAF(sb_read_syscfg)
+	lui     v0, 0xb002
+	ori     v0, v0, 0x8
+	ld      v1, 0(v0)	/* syscfg = MIPS_PHYS_TO_KSEG1(0x10020008) */
+	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 */
+	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
+	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_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)

Added: projects/mips/sys/mips/sibyte/sb_machdep.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/sb_machdep.c	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,259 @@
+/*-
+ * Copyright (c) 2007 Bruce M. Simpson.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <machine/cpuregs.h>
+
+#include "opt_ddb.h"
+#include "opt_kdb.h"
+
+#include <sys/param.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/imgact.h>
+#include <sys/bio.h>
+#include <sys/buf.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/cons.h>
+#include <sys/exec.h>
+#include <sys/ucontext.h>
+#include <sys/proc.h>
+#include <sys/kdb.h>
+#include <sys/ptrace.h>
+#include <sys/reboot.h>
+#include <sys/signalvar.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/user.h>
+
+#include <vm/vm.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
+
+#include <machine/cache.h>
+#include <machine/clock.h>
+#include <machine/cpu.h>
+#include <machine/cpuinfo.h>
+#include <machine/cpufunc.h>
+#include <machine/cpuregs.h>
+#include <machine/hwfunc.h>
+#include <machine/intr_machdep.h>
+#include <machine/locore.h>
+#include <machine/md_var.h>
+#include <machine/pte.h>
+#include <machine/sigframe.h>
+#include <machine/trap.h>
+#include <machine/vmparam.h>
+
+#ifdef CFE
+#include <dev/cfe/cfe_api.h>
+#endif
+
+#include "sb_scd.h"
+
+#ifdef DDB
+#ifndef KDB
+#error KDB must be enabled in order for DDB to work!
+#endif
+#endif
+
+#ifdef CFE
+extern uint32_t cfe_handle;
+extern uint32_t cfe_vector;
+#endif
+
+#ifdef CFE_ENV
+extern void cfe_env_init(void);
+#endif
+
+extern int *edata;
+extern int *end;
+
+static void
+mips_init(void)
+{
+	int i, cfe_mem_idx, tmp;
+	uint64_t maxmem;
+
+#ifdef CFE_ENV
+	cfe_env_init();
+#endif
+
+	TUNABLE_INT_FETCH("boothowto", &boothowto);
+
+	if (boothowto & RB_VERBOSE)
+		bootverbose++;
+
+#ifdef MAXMEM
+	tmp = MAXMEM;
+#else
+	tmp = 0;
+#endif
+	TUNABLE_INT_FETCH("hw.physmem", &tmp);
+	maxmem = (uint64_t)tmp * 1024;
+
+#ifdef CFE
+	/*
+	 * Query DRAM memory map from CFE.
+	 */
+	physmem = 0;
+	cfe_mem_idx = 0;
+	for (i = 0; i < 10; i += 2) {
+		int result;
+		uint64_t addr, len, type;
+
+		result = cfe_enummem(cfe_mem_idx++, 0, &addr, &len, &type);
+		if (result < 0) {
+			phys_avail[i] = phys_avail[i + 1] = 0;
+			break;
+		}
+
+		KASSERT(type == CFE_MI_AVAILABLE,
+			("CFE DRAM region is not available?"));
+
+		if (bootverbose)
+			printf("cfe_enummem: 0x%016jx/%llu.\n", addr, len);
+
+		if (maxmem != 0) {
+			if (addr >= maxmem) {
+				printf("Ignoring %llu bytes of memory at 0x%jx "
+				       "that is above maxmem %dMB\n",
+				       len, addr,
+				       (int)(maxmem / (1024 * 1024)));
+				continue;
+			}
+
+			if (addr + len > maxmem) {
+				printf("Ignoring %llu bytes of memory "
+				       "that is above maxmem %dMB\n",
+				       (addr + len) - maxmem,
+				       (int)(maxmem / (1024 * 1024)));
+				len = maxmem - addr;
+			}
+		}
+
+		phys_avail[i] = addr;
+		if (i == 0 && addr == 0) {
+			/*
+			 * If this is the first physical memory segment probed
+			 * from CFE, omit the region at the start of physical
+			 * memory where the kernel has been loaded.
+			 */
+			phys_avail[i] += MIPS_KSEG0_TO_PHYS((vm_offset_t)&end);
+		}
+		phys_avail[i + 1] = addr + len;
+		physmem += len;
+	}
+
+	realmem = btoc(physmem);
+#endif
+
+	physmem = realmem;
+
+	init_param1();
+	init_param2(physmem);
+	mips_cpu_init();
+	pmap_bootstrap();
+	mips_proc0_init();
+	mutex_init();
+
+	kdb_init();
+#ifdef KDB
+	if (boothowto & RB_KDB)
+		kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
+#endif
+}
+
+void
+platform_halt(void)
+{
+
+}
+
+
+void
+platform_identify(void)
+{
+
+}
+
+void
+platform_reset(void)
+{
+	
+	/*
+	 * XXX SMP
+	 * XXX flush data caches
+	 */
+	sb_system_reset();
+}
+
+void
+platform_trap_enter(void)
+{
+
+}
+
+void
+platform_trap_exit(void)
+{
+
+}
+
+void
+platform_start(__register_t a0 __unused, __register_t a1 __unused, 
+    __register_t a2 __unused, __register_t a3 __unused)
+{
+	vm_offset_t kernend;
+
+	/* clear the BSS and SBSS segments */
+	memset(&edata, 0, (vm_offset_t)&end - (vm_offset_t)&edata);
+	kernend = round_page((vm_offset_t)&end);
+
+#ifdef CFE
+	/*
+	 * Initialize CFE firmware trampolines before
+	 * we initialize the low-level console.
+	 */
+	if (cfe_handle != 0)
+		cfe_init(cfe_handle, cfe_vector);
+#endif
+	cninit();
+
+#ifdef CFE
+	if (cfe_handle == 0)
+		panic("CFE was not detected by locore.\n");
+#endif
+	mips_init();
+
+	mips_timer_init_params(sb_cpu_speed(), 0);
+}

Added: projects/mips/sys/mips/sibyte/sb_scd.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/sb_scd.c	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,152 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+
+#include <machine/resource.h>
+
+#include "sb_scd.h"
+
+__FBSDID("$FreeBSD$");
+
+/*
+ * System Control and Debug (SCD) unit on the Sibyte ZBbus.
+ */
+
+/*
+ * Extract the value starting at bit position 'b' for 'n' bits from 'x'.
+ */
+#define	GET_VAL_64(x, b, n)	(((x) >> (b)) & ((1ULL << (n)) - 1))
+
+#define SYSCFG_PLLDIV(x)	GET_VAL_64((x), 7, 5)
+
+uint64_t
+sb_cpu_speed(void)
+{
+	int plldiv;
+	const uint64_t MHZ = 1000000;
+	
+	plldiv = SYSCFG_PLLDIV(sb_read_syscfg());
+	if (plldiv == 0) {
+		printf("PLL_DIV is 0 - assuming 6 (300MHz).\n");
+		plldiv = 6;
+	}
+
+	return (plldiv * 50 * MHZ);
+}
+
+void
+sb_system_reset(void)
+{
+	uint64_t syscfg;
+
+	const uint64_t SYSTEM_RESET = 1ULL << 60;
+	const uint64_t EXT_RESET = 1ULL << 59;
+	const uint64_t SOFT_RESET = 1ULL << 58;
+
+	syscfg = sb_read_syscfg();
+	syscfg &= ~SOFT_RESET;
+	syscfg |= SYSTEM_RESET | EXT_RESET;
+	sb_write_syscfg(syscfg);
+}
+
+int
+sb_route_intsrc(int intsrc)
+{
+	int intrnum;
+
+	KASSERT(intsrc >= 0 && intsrc < NUM_INTSRC,
+		("Invalid interrupt source number (%d)", 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.
+	 */
+	intrnum = intsrc % 5;
+
+	/*
+	 * Program the interrupt mapper while we are here.
+	 */
+	sb_write_intmap(intsrc, intrnum);
+
+	return (intrnum);
+}
+
+#define	SCD_PHYSADDR	0x10000000
+#define	SCD_SIZE	0x00060000
+
+static int
+scd_probe(device_t dev)
+{
+
+	device_set_desc(dev, "Broadcom/Sibyte System Control and Debug");
+	return (0);
+}
+
+static int
+scd_attach(device_t dev)
+{
+	int rid;
+	struct resource *res;
+
+	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) {
+		panic("Cannot allocate resource for system control and debug.");
+	}
+	
+	return (0);
+}
+
+static device_method_t scd_methods[] ={
+	/* Device interface */
+	DEVMETHOD(device_probe,		scd_probe),
+	DEVMETHOD(device_attach,	scd_attach),
+	DEVMETHOD(device_detach,	bus_generic_detach),
+	DEVMETHOD(device_shutdown,	bus_generic_shutdown),
+	DEVMETHOD(device_suspend,	bus_generic_suspend),
+	DEVMETHOD(device_resume,	bus_generic_resume),
+
+	{ 0, 0 }
+};
+
+static driver_t scd_driver = {
+	"scd",
+	scd_methods
+};
+
+static devclass_t scd_devclass;
+
+DRIVER_MODULE(scd, zbbus, scd_driver, scd_devclass, 0, 0);

Added: projects/mips/sys/mips/sibyte/sb_scd.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/sb_scd.h	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,46 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#ifndef _SB_SCD_H_
+#define	_SB_SCD_H_
+
+#define	NUM_INTSRC		64	/* total number of interrupt sources */
+
+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);
+
+#endif	/* _SB_SCD_H_ */

Added: projects/mips/sys/mips/sibyte/sb_zbbus.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/mips/sys/mips/sibyte/sb_zbbus.c	Sat Jul  4 03:05:48 2009	(r195333)
@@ -0,0 +1,501 @@
+/*-
+ * Copyright (c) 2009 Neelkanth Natu
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/rman.h>
+
+#include <machine/resource.h>
+#include <machine/intr_machdep.h>
+
+#include "sb_scd.h"
+
+__FBSDID("$FreeBSD$");
+
+static MALLOC_DEFINE(M_INTMAP, "sb1250 intmap", "Sibyte 1250 Interrupt Mapper");
+
+#define	NUM_HARD_IRQS	6
+
+struct sb_intmap {
+	int intsrc;		/* interrupt mapper register number (0 - 63) */
+	int active;		/* Does this source generate interrupts? */
+
+	/*
+	 * The device that the interrupt belongs to. Note that multiple
+	 * devices may share an interrupt. For e.g. PCI_INT_x lines.
+	 *
+	 * The device 'dev' in combination with the 'rid' uniquely
+	 * identify this interrupt source.
+	 */
+	device_t dev;
+	int rid;
+
+	SLIST_ENTRY(sb_intmap) next;
+};
+
+/*
+ * We register 'sb_intsrc.isrc' using cpu_register_hard_intsrc() for each
+ * hard interrupt source [0-5].
+ *
+ * The mask/unmask callbacks use the information in 'sb_intmap' to figure
+ * out the corresponding interrupt sources to mask/unmask.
+ */
+struct sb_intsrc {
+	struct intsrc isrc;
+	SLIST_HEAD(, sb_intmap) sb_intmap_head;
+};
+
+static struct sb_intsrc sb_intsrc[NUM_HARD_IRQS];
+
+static struct sb_intmap *
+sb_intmap_lookup(int intrnum, device_t dev, int rid)
+{
+	struct sb_intsrc *isrc;
+	struct sb_intmap *map;
+
+	isrc = &sb_intsrc[intrnum];
+	SLIST_FOREACH(map, &isrc->sb_intmap_head, next) {
+		if (dev == map->dev && rid == map->rid)
+			break;
+	}
+	return (map);
+}
+
+/*
+ * Keep track of which (dev,rid) tuple is using the interrupt source.
+ *
+ * We don't actually unmask the interrupt source until the device calls
+ * a bus_setup_intr() on the resource.
+ */
+static void
+sb_intmap_add(int intrnum, device_t dev, int rid, int intsrc)
+{
+	struct sb_intsrc *isrc;
+	struct sb_intmap *map;
+	register_t sr;
+	
+	KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS,
+		("intrnum is out of range: %d", intrnum));
+
+	isrc = &sb_intsrc[intrnum];
+	map = sb_intmap_lookup(intrnum, dev, rid);
+	if (map) {
+		KASSERT(intsrc == map->intsrc,
+			("%s%d allocating SYS_RES_IRQ resource with rid %d "
+			 "with a different intsrc (%d versus %d)",
+			device_get_name(dev), device_get_unit(dev), rid,
+			intsrc, map->intsrc));
+		return;
+	}
+
+	map = malloc(sizeof(*map), M_INTMAP, M_WAITOK | M_ZERO);
+	map->intsrc = intsrc;
+	map->dev = dev;
+	map->rid = rid;
+
+	sr = intr_disable();
+	SLIST_INSERT_HEAD(&isrc->sb_intmap_head, map, next);
+	intr_restore(sr);
+}
+
+static void
+sb_intmap_activate(int intrnum, device_t dev, int rid)
+{
+	struct sb_intmap *map;
+	register_t sr;
+	
+	KASSERT(intrnum >= 0 && intrnum < NUM_HARD_IRQS,
+		("intrnum is out of range: %d", intrnum));
+
+	map = sb_intmap_lookup(intrnum, dev, rid);
+	if (map) {
+		/*
+		 * See comments in sb_unmask_func() about disabling cpu intr
+		 */
+		sr = intr_disable();
+		map->active = 1;
+		sb_enable_intsrc(map->intsrc);
+		intr_restore(sr);
+	} else {
+		/*
+		 * In zbbus_setup_intr() we blindly call sb_intmap_activate()
+		 * for every interrupt activation that comes our way.
+		 *
+		 * We might end up here if we did not "hijack" the SYS_RES_IRQ
+		 * resource in zbbus_alloc_resource().
+		 */
+		printf("sb_intmap_activate: unable to activate interrupt %d "
+		       "for device %s%d rid %d.\n", intrnum,
+		       device_get_name(dev), device_get_unit(dev), rid);
+	}
+}
+
+static void
+sb_mask_func(struct intsrc *arg)
+{
+	struct sb_intmap *map;
+	struct sb_intsrc *isrc;
+	uint64_t isrc_bitmap;
+
+	isrc_bitmap = 0;
+	isrc = (struct sb_intsrc *)arg;
+	SLIST_FOREACH(map, &isrc->sb_intmap_head, next) {
+		if (map->active == 0)
+			continue;
+		/*
+		 * If we have already disabled this interrupt source then don't
+		 * do it again. This can happen when multiple devices share
+		 * an interrupt source (e.g. PCI_INT_x).
+		 */
+		if (isrc_bitmap & (1ULL << map->intsrc))
+			continue;
+		sb_disable_intsrc(map->intsrc);
+		isrc_bitmap |= 1ULL << map->intsrc;
+	}
+}
+
+static void
+sb_unmask_func(struct intsrc *arg)
+{
+	struct sb_intmap *map;
+	struct sb_intsrc *sb_isrc;

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list