Date: Sat, 4 Jul 2009 03:05:48 +0000 (UTC) From: Warner Losh <imp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r195333 - projects/mips/sys/mips/sibyte Message-ID: <200907040305.n6435mb7095513@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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", ®shift); + 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", ®offset); + 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 ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907040305.n6435mb7095513>