add support for ixp12x0

This commit is contained in:
ichiro 2002-07-15 16:27:15 +00:00
parent b767b60c60
commit 7374c0afee
24 changed files with 4597 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.c,v 1.47 2002/07/10 07:00:50 ichiro Exp $ */
/* $NetBSD: cpufunc.c,v 1.48 2002/07/15 16:27:15 ichiro Exp $ */
/*
* arm7tdmi support code Copyright (c) 2001 John Fremlin
@ -555,6 +555,63 @@ struct cpu_functions sa11x0_cpufuncs = {
};
#endif /* CPU_SA1100 || CPU_SA1110 */
#ifdef CPU_IXP12X0
struct cpu_functions ixp12x0_cpufuncs = {
/* CPU functions */
cpufunc_id, /* id */
cpufunc_nullop, /* cpwait */
/* MMU functions */
cpufunc_control, /* control */
cpufunc_domains, /* domain */
sa1_setttb, /* setttb */
cpufunc_faultstatus, /* faultstatus */
cpufunc_faultaddress, /* faultaddress */
/* TLB functions */
armv4_tlb_flushID, /* tlb_flushID */
sa1_tlb_flushID_SE, /* tlb_flushID_SE */
armv4_tlb_flushI, /* tlb_flushI */
(void *)armv4_tlb_flushI, /* tlb_flushI_SE */
armv4_tlb_flushD, /* tlb_flushD */
armv4_tlb_flushD_SE, /* tlb_flushD_SE */
/* Cache operations */
sa1_cache_syncI, /* icache_sync_all */
sa1_cache_syncI_rng, /* icache_sync_range */
sa1_cache_purgeD, /* dcache_wbinv_all */
sa1_cache_purgeD_rng, /* dcache_wbinv_range */
/*XXX*/ sa1_cache_purgeD_rng, /* dcache_inv_range */
sa1_cache_cleanD_rng, /* dcache_wb_range */
sa1_cache_purgeID, /* idcache_wbinv_all */
sa1_cache_purgeID_rng, /* idcache_wbinv_range */
/* Other functions */
ixp12x0_drain_readbuf, /* flush_prefetchbuf */
armv4_drain_writebuf, /* drain_writebuf */
cpufunc_nullop, /* flush_brnchtgt_C */
(void *)cpufunc_nullop, /* flush_brnchtgt_E */
(void *)cpufunc_nullop, /* sleep */
/* Soft functions */
cpufunc_null_fixup, /* dataabt_fixup */
cpufunc_null_fixup, /* prefetchabt_fixup */
ixp12x0_context_switch, /* context_switch */
ixp12x0_setup /* cpu setup */
};
#endif /* CPU_IXP12X0 */
#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0)
struct cpu_functions xscale_cpufuncs = {
@ -693,7 +750,7 @@ get_cachetype_cp15()
#if defined(CPU_ARM2) || defined(CPU_ARM250) || defined(CPU_ARM3) || \
defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_SA110) || \
defined(CPU_SA1100) || defined(CPU_SA1110)
defined(CPU_SA1100) || defined(CPU_SA1110) || defined(CPU_IXP12X0)
/* Cache information for CPUs without cache type registers. */
struct cachetab {
u_int32_t ct_cpuid;
@ -721,6 +778,7 @@ struct cachetab cachetab[] = {
{ CPU_ID_SA110, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 },
{ CPU_ID_SA1100, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 },
{ CPU_ID_SA1110, CPU_CT_CTYPE_WB1, 0, 8192, 32, 32, 16384, 32, 32 },
{ CPU_ID_IXP1200, CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */
{ 0, 0, 0, 0, 0, 0, 0, 0}
};
@ -751,7 +809,7 @@ get_cachetype_table()
arm_dcache_align_mask = arm_dcache_align - 1;
}
#endif /* ARM2 || ARM250 || ARM3 || ARM6 || ARM7 || SA110 || SA1100 || SA1111 */
#endif /* ARM2 || ARM250 || ARM3 || ARM6 || ARM7 || SA110 || SA1100 || SA1111 || IXP12X0 */
/*
* Cannot panic here as we may not have a console yet ...
@ -851,6 +909,15 @@ set_cpufuncs()
return 0;
}
#endif /* CPU_SA1110 */
#ifdef CPU_IXP12X0
if (cputype == CPU_ID_IXP1200) {
cpufuncs = ixp12x0_cpufuncs;
cpu_reset_needs_v4_MMU_disable = 1;
get_cachetype_table();
pmap_pte_init_generic();
return 0;
}
#endif /* CPU_IXP12X0 */
#ifdef CPU_XSCALE_80200
if (cputype == CPU_ID_80200) {
int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
@ -1708,6 +1775,48 @@ sa11x0_setup(args)
}
#endif /* CPU_SA1100 || CPU_SA1110 */
#if defined(CPU_IXP12X0)
struct cpu_option ixp12x0_options[] = {
{ "cpu.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
{ "cpu.nocache", OR, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
{ "ixp12x0.cache", BIC, OR, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
{ "ixp12x0.icache", BIC, OR, CPU_CONTROL_IC_ENABLE },
{ "ixp12x0.dcache", BIC, OR, CPU_CONTROL_DC_ENABLE },
{ "cpu.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE },
{ "cpu.nowritebuf", OR, BIC, CPU_CONTROL_WBUF_ENABLE },
{ "ixp12x0.writebuf", BIC, OR, CPU_CONTROL_WBUF_ENABLE },
{ NULL, IGN, IGN, 0 }
};
void
ixp12x0_setup(args)
char *args;
{
int cpuctrl, cpuctrlmask;
cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE
| CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE
| CPU_CONTROL_IC_ENABLE;
cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE
| CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE
| CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE
| CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE
| CPU_CONTROL_VECRELOC;
cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl);
/* Clear out the cache */
cpu_idcache_wbinv_all();
/* Set the control register */
curcpu()->ci_ctrl = cpuctrl;
/* cpu_control(0xffffffff, cpuctrl); */
cpu_control(cpuctrlmask, cpuctrl);
}
#endif /* CPU_IXP12X0 */
#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0)
struct cpu_option xscale_options[] = {

View File

@ -0,0 +1,89 @@
/* $NetBSD: cpufunc_asm_ixp12x0.S,v 1.1 2002/07/15 16:28:04 ichiro Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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/cpu.h>
#include <machine/asm.h>
/*
* This function is the same as sa110_context_switch for now, the plan
* is to make use of the process id register to avoid cache flushes.
*/
ENTRY(ixp12x0_context_switch)
/*
* CF_CACHE_PURGE_ID will *ALWAYS* be called prior to this.
* Thus the data cache will contain only kernel data and the
* instruction cache will contain only kernel code, and all
* kernel mappings are shared by all processes.
*/
/* Write the TTB */
mcr p15, 0, r0, c2, c0, 0
/* If we have updated the TTB we must flush the TLB */
mcr p15, 0, r0, c8, c7, 0 /* flush the I+D tlb */
/* Make sure that pipeline is emptied */
mov r0, r0
mov r0, r0
mov pc, lr
ENTRY(ixp12x0_drain_readbuf)
mcr p15, 0, r0, c9, c0, 0 /* drain read buffer */
mov pc, lr
/*
* Information for the IXP12X0 cache clean/purge functions:
*
* * Virtual address of the memory region to use
* * Size of memory region
*/
.data
.global _C_LABEL(ixp12x0_cache_clean_addr)
_C_LABEL(ixp12x0_cache_clean_addr):
.word 0xf0000000
.global _C_LABEL(ixp12x0_cache_clean_size)
_C_LABEL(ixp12x0_cache_clean_size):
.word 0x00008000
.text
Lixp12x0_cache_clean_addr:
.word _C_LABEL(ixp12x0_cache_clean_addr)
Lixp12x0_cache_clean_size:
.word _C_LABEL(ixp12x0_cache_clean_size)

View File

@ -1,4 +1,4 @@
# $NetBSD: files.arm,v 1.60 2002/05/03 16:46:52 rjs Exp $
# $NetBSD: files.arm,v 1.61 2002/07/15 16:27:16 ichiro Exp $
# temporary define to allow easy moving to ../arch/arm/arm32
defflag ARM32
@ -7,7 +7,7 @@ defflag ARM32
defflag opt_cputypes.h CPU_ARM2 CPU_ARM250 CPU_ARM3
defflag opt_cputypes.h CPU_ARM6 CPU_ARM7 CPU_ARM7TDMI CPU_ARM8
CPU_ARM9 CPU_SA110 CPU_SA1100 CPU_SA1110
CPU_XSCALE_80200 CPU_XSCALE_80321
CPU_IXP12X0 CPU_XSCALE_80200 CPU_XSCALE_80321
CPU_XSCALE_PXA2X0
defparam opt_cpuoptions.h XSCALE_CCLKCFG
@ -72,15 +72,18 @@ file arch/arm/arm/cpufunc_asm_arm8.S cpu_arm8
file arch/arm/arm/cpufunc_asm_arm9.S cpu_arm9
file arch/arm/arm/cpufunc_asm_armv4.S cpu_arm9 | cpu_sa110 |
cpu_sa1100 | cpu_sa1110 |
cpu_ixp12x0 |
cpu_xscale_80200 |
cpu_xscale_80321 |
cpu_xscale_pxa2x0
file arch/arm/arm/cpufunc_asm_sa1.S cpu_sa110 | cpu_sa1100 |
cpu_sa1110
cpu_sa1110 |
cpu_ixp12x0
file arch/arm/arm/cpufunc_asm_sa11x0.S cpu_sa1100 | cpu_sa1110
file arch/arm/arm/cpufunc_asm_xscale.S cpu_xscale_80200 |
cpu_xscale_80321 |
cpu_xscale_pxa2x0
file arch/arm/arm/cpufunc_asm_ixp12x0.S cpu_ixp12x0
file arch/arm/arm/process_machdep.c
file arch/arm/arm/procfs_machdep.c procfs
file arch/arm/arm/sig_machdep.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuconf.h,v 1.2 2002/05/03 03:28:49 thorpej Exp $ */
/* $NetBSD: cpuconf.h,v 1.3 2002/07/15 16:27:16 ichiro Exp $ */
/*
* Copyright (c 2002 Wasabi Systems, Inc.
@ -53,6 +53,7 @@
defined(CPU_ARM8) + defined(CPU_ARM9) + \
defined(CPU_SA110) + defined(CPU_SA1100) + \
defined(CPU_SA1110) + \
defined(CPU_IXP12X0) + \
defined(CPU_XSCALE_80200) + \
defined(CPU_XSCALE_80321) + \
defined(CPU_XSCALE_PXA2X0))
@ -79,7 +80,8 @@
#if !defined(_KERNEL_OPT) || \
(defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \
defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110))
defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
defined(CPU_IXP12X0))
#define ARM_ARCH_4 1
#else
#define ARM_ARCH_4 0
@ -120,7 +122,7 @@
#if !defined(_KERNEL_OPT) || \
(defined(CPU_ARM6) || defined(CPU_ARM7) || defined(CPU_ARM7TDMI) || \
defined(CPU_ARM8) || defined(CPU_ARM9) || defined(CPU_SA110) || \
defined(CPU_SA1100) || defined(CPU_SA1110))
defined(CPU_SA1100) || defined(CPU_SA1110) || defined(CPU_IXP12X0))
#define ARM_MMU_GENERIC 1
#else
#define ARM_MMU_GENERIC 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpufunc.h,v 1.23 2002/05/03 16:45:22 rjs Exp $ */
/* $NetBSD: cpufunc.h,v 1.24 2002/07/15 16:27:16 ichiro Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
@ -344,6 +344,12 @@ void armv4_tlb_flushD_SE __P((u_int va));
void armv4_drain_writebuf __P((void));
#endif
#if defined(CPU_IXP12X0)
void ixp12x0_drain_readbuf __P((void));
void ixp12x0_context_switch __P((void));
void ixp12x0_setup __P((char *string));
#endif
#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
defined(CPU_XSCALE_PXA2X0)
void xscale_cpwait __P((void));

View File

@ -0,0 +1,31 @@
# $NetBSD: files.ixp12x0,v 1.1 2002/07/15 16:27:16 ichiro Exp $
#
# Configuration info for Intel IXP12x0 CPU support
#
file arch/arm/ixp12x0/ixp12x0_intr.c
file arch/arm/ixp12x0/ixp12x0_irq.S
# IXP1200 Slow peripheral devices
device ixpsip { [addr=-1], [size=0], [intr=-1] }: bus_space_generic
file arch/arm/ixp12x0/ixpsip.c ixpsip
file arch/arm/ixp12x0/ixpsip_io.c ixpsip
# IXP12x0 Processor CPU support
# IXP1200 IX,PCI,SRAM bus
device ixpio: pcibus, bus_space_generic
file arch/arm/ixp12x0/ixp12x0.c ixpio
file arch/arm/ixp12x0/ixp12x0_io.c ixpio
file arch/arm/ixp12x0/ixp12x0_pci.c ixpio
file arch/arm/ixp12x0/ixp12x0_pci_dma.c ixpio
# clock device
device ixpclk
attach ixpclk at ixpsip
file arch/arm/ixp12x0/ixp12x0_clk.c ixpclk needs-flag
# com
device ixpcom: tty
attach ixpcom at ixpsip
file arch/arm/ixp12x0/ixp12x0_com.c ixpcom needs-flag
file arch/arm/ixp12x0/ixp12x0_com_io.c ixpcom

View File

@ -0,0 +1,260 @@
/* $NetBSD: ixp12x0.c,v 1.1 2002/07/15 16:27:16 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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/systm.h>
#include <sys/device.h>
#include <uvm/uvm.h>
#include <machine/bus.h>
#include <arm/ixp12x0/ixp12x0reg.h>
#include <arm/ixp12x0/ixp12x0var.h>
#include <arm/ixp12x0/ixp12x0_pcireg.h>
int ixp12x0_pcibus_print(void *, const char *);
static struct ixp12x0_softc *ixp12x0_softc;
void
ixp12x0_attach(sc)
struct ixp12x0_softc *sc;
{
struct pcibus_attach_args pba;
pcireg_t reg;
ixp12x0_softc = sc;
printf("\n");
/*
* Subregion for PCI Configuration Spase Registers
*/
if (bus_space_subregion(sc->sc_iot, sc->sc_ioh, 0,
IXP12X0_PCI_SIZE, &sc->sc_pci_ioh))
panic("%s: unable to subregion PCI registers\n",
sc->sc_dev.dv_xname);
/*
* PCI bus reset
*/
/* assert PCI reset */
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL) &~ SA_CONTROL_PNR;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL, reg);
DELAY(10);
/* XXX Disable door bell and outbound interrupt */
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
PCI_CAP_PTR, 0xc);
/* Disable door bell int to PCI */
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
DBELL_PCI_MASK, 0xc);
/* Disable door bell int to SA-core */
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
DBELL_SA_MASK, 0xc);
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
PCI_ADDR_EXT, 0);
/* Negate PCI reset */
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL) | SA_CONTROL_PNR;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL, reg);
DELAY(10);
/*
* specify window size of memory access and SDRAM.
*/
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_MEM_BAR) | IXP1200_PCI_MEM_BAR;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_MEM_BAR, reg);
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_IO_BAR) | IXP1200_PCI_IO_BAR;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_IO_BAR, reg);
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_DRAM_BAR) | IXP1200_PCI_DRAM_BAR;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
IXP_PCI_DRAM_BAR, reg);
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
CSR_BASE_ADDR_MASK, CSR_BASE_ADDR_MASK_1M);
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
DRAM_BASE_ADDR_MASK, DRAM_BASE_ADDR_MASK_256MB);
#if DEBUG
printf("IXP_PCI_MEM_BAR = 0x%08x\nIXP_PCI_IO_BAR = 0x%08x\nIXP_PCI_DRAM_BAR = 0x%08x\nCSR_BASE_ADDR_MASK = 0x%08x\n",
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR),
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR),
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR),
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, DRAM_BASE_ADDR_MASK));
#endif
/* Initialize complete */
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL) | 0x1;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
SA_CONTROL, reg);
#if DEBUG
printf("SA_CONTROL = 0x%08x\n",
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, SA_CONTROL));
#endif
/*
* Enable bus mastering and I/O,memory access
*/
/* host only */
reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
PCI_COMMAND_STATUS_REG) |
PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
PCI_COMMAND_STATUS_REG, reg);
#if DEBUG
printf("PCI_COMMAND_STATUS_REG = 0x%08x\n",
bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_COMMAND_STATUS_REG));
#endif
/*
* Initialize the bus space and DMA tags and the PCI chipset tag.
*/
ixp12x0_io_bs_init(&sc->ia_pci_iot, sc);
ixp12x0_mem_bs_init(&sc->ia_pci_memt, sc);
ixp12x0_pci_init(&sc->ia_pci_chipset, sc);
ixp12x0_pci_dma_init(&sc->ia_pci_dmat, sc);
/*
* Attach the PCI bus.
*/
pba.pba_busname = "pci";
pba.pba_pc = &sc->ia_pci_chipset;
pba.pba_iot = &sc->ia_pci_iot;
pba.pba_memt = &sc->ia_pci_memt;
pba.pba_dmat = &sc->ia_pci_dmat;
pba.pba_bus = 0; /* bus number = 0 */
pba.pba_intrswiz = 0; /* XXX */
pba.pba_intrtag = 0;
pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
(void) config_found(&sc->sc_dev, &pba, ixp12x0_pcibus_print);
}
int
ixp12x0_pcibus_print(void *aux, const char *pnp)
{
struct pcibus_attach_args *pba = aux;
if (pnp)
printf("%s at %s", pba->pba_busname, pnp);
printf(" bus %d", pba->pba_bus);
return (UNCONF);
}
/*
* IXP12x0 specific I/O registers mapping table
*/
static struct pmap_ent map_tbl_ixp12x0[] = {
{ "StrongARM System and Peripheral Registers",
IXP12X0_SYS_VBASE, IXP12X0_SYS_HWBASE,
IXP12X0_SYS_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ "PCI Registers Accessible Through StrongARM Core",
IXP12X0_PCI_VBASE, IXP12X0_PCI_HWBASE,
IXP12X0_PCI_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ "PCI Registers Accessible Through I/O Cycle Access",
IXP12X0_PCI_IO_VBASE, IXP12X0_PCI_IO_HWBASE,
IXP12X0_PCI_IO_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ "PCI Registers Accessible Through Memory Cycle Access",
IXP12X0_PCI_MEM_VBASE, IXP12X0_PCI_MEM_VBASE,
IXP12X0_PCI_MEM_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ "PCI Type0 Configuration Space",
IXP12X0_PCI_TYPE0_VBASE, IXP12X0_PCI_TYPE0_VBASE,
IXP12X0_PCI_TYPEX_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ "PCI Type1 Configuration Space",
IXP12X0_PCI_TYPE1_VBASE, IXP12X0_PCI_TYPE1_VBASE,
IXP12X0_PCI_TYPEX_SIZE,
VM_PROT_READ|VM_PROT_WRITE,
PTE_NOCACHE, },
{ NULL, 0, 0, 0, 0, 0 },
};
/*
* mapping virtual memories
*/
void
ixp12x0_pmap_chunk_table(vaddr_t l1pt, struct pmap_ent* m)
{
int loop;
loop = 0;
while (m[loop].msg) {
printf("mapping %s...\n", m[loop].msg);
pmap_map_chunk(l1pt, m[loop].va, m[loop].pa,
m[loop].sz, m[loop].prot, m[loop].cache);
++loop;
}
}
/*
* mapping I/O registers
*/
void
ixp12x0_pmap_io_reg(vaddr_t l1pt)
{
ixp12x0_pmap_chunk_table(l1pt, map_tbl_ixp12x0);
}
void
ixp12x0_reset(void)
{
bus_space_write_4(ixp12x0_softc->sc_iot, ixp12x0_softc->sc_pci_ioh,
IXPPCI_IXP1200_RESET, RESET_FULL);
}

View File

@ -0,0 +1,388 @@
/* $NetBSD: ixp12x0_clk.c,v 1.1 2002/07/15 16:27:16 ichiro Exp $ */
/*
* Copyright (c) 1997 Mark Brinicombe.
* Copyright (c) 1997 Causality Limited.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by IWAMOTO Toshihiro and Ichiro FUKUHARA.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/time.h>
#include <sys/device.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <evbarm/ixm1200/ixm1200reg.h>
#include <arm/ixp12x0/ixpsipvar.h>
#include <arm/ixp12x0/ixp12x0_pcireg.h>
#include <arm/ixp12x0/ixp12x0_clkreg.h>
#include <arm/ixp12x0/ixp12x0var.h>
static int ixpclk_match(struct device *, struct cfdata *, void *);
static void ixpclk_attach(struct device *, struct device *, void *);
int gettick(void);
void rtcinit(void);
/* callback functions for intr_functions */
static int ixpclk_intr(void* arg);
struct ixpclk_softc {
struct device sc_dev;
bus_addr_t sc_baseaddr;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
u_int32_t sc_clock_count;
u_int32_t sc_count_per_usec;
u_int32_t sc_coreclock_freq;
};
#define XTAL_FREQ 3686400 /* 3.6864MHz */
#define XTAL_FREQ3686400
#undef XTAL_FREQ3787800
#undef XTAL_FREQ3579500
#define MAX_CCF 22
#if defined(XTAL_FREQ3686400)
static u_int32_t ccf_to_coreclock[MAX_CCF + 1] = {
29491000,
36865000,
44237000,
51610000,
58982000,
66355000,
73728000,
81101000,
88474000,
95846000,
103219000,
110592000,
132710000,
147456000,
154829000,
162202000,
165890000,
176947000,
191693000,
199066000,
206438000,
221184000,
232243000,
};
#elif defined(XTAL_FREQ3787800)
#elif defined(XTAL_FREQ3579500)
#else
#error
#endif
static struct ixpclk_softc *ixpclk_sc = NULL;
#define TIMER_FREQUENCY 3686400 /* 3.6864MHz */
#define TICKS_PER_MICROSECOND (TIMER_FREQUENCY/1000000)
struct cfattach ixpclk_ca = {
sizeof(struct ixpclk_softc), ixpclk_match, ixpclk_attach
};
#define GET_TIMER_VALUE(sc) (bus_space_read_4((sc)->sc_iot, \
(sc)->sc_ioh, \
IXPCLK_VALUE) \
& IXPCL_CTV)
static int
ixpclk_match(parent, match, aux)
struct device *parent;
struct cfdata *match;
void *aux;
{
return (1);
}
static void
ixpclk_attach(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
struct ixpclk_softc *sc = (struct ixpclk_softc*) self;
struct ixpsip_attach_args *sa = aux;
printf("\n");
sc->sc_iot = sa->sa_iot;
sc->sc_baseaddr = sa->sa_addr;
/* using first timer for system ticks */
if (ixpclk_sc == NULL)
ixpclk_sc = sc;
if (bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0,
&sc->sc_ioh))
panic("%s: Cannot map registers\n", self->dv_xname);
/* disable all channel and clear interrupt status */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_CONTROL,
IXPCL_DISABLE | IXPCL_PERIODIC | IXPCL_STP_CORE);
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_CLEAR, 0);
printf("%s: IXP12x0 Interval Timer\n", sc->sc_dev.dv_xname);
}
/*
* ixpclk_intr:
*
* Handle the hardclock interrupt.
*/
static int
ixpclk_intr(void *arg)
{
/* XXX XXX */
if (!(IXPREG(IXPPCI_IRQ_RAW_STATUS)
& (1U << (IXPPCI_INTR_T1 - SYS_NIRQ))))
return (0);
bus_space_write_4(ixpclk_sc->sc_iot, ixpclk_sc->sc_ioh,
IXPCLK_CLEAR, 1);
hardclock((struct clockframe*) arg);
return (1);
}
/*
* setstatclockrate:
*
* Set the rate of the statistics clock.
*
* We assume that hz is either stathz or profhz, and that neither
* will change after being set by cpu_initclocks(). We could
* recalculate the intervals here, but that would be a pain.
*/
void
setstatclockrate(hz)
int hz;
{
/* use hardclock */
/* XXX should I use TIMER2? */
}
/*
* cpu_initclocks:
*
* Initialize the clock and get them going.
*/
void
cpu_initclocks()
{
struct ixpclk_softc* sc = ixpclk_sc;
u_int32_t ccf;
stathz = profhz = 0;
printf("clock: hz = %d stathz = %d\n", hz, stathz);
ccf = IXPREG(IXP12X0_PLL_CFG) & IXP12X0_PLL_CFG_CCF;
sc->sc_coreclock_freq = ccf_to_coreclock[ccf];
printf("pll_cfg:ccf = %x coreclock frequency = %dHz\n",
ccf, sc->sc_coreclock_freq);
sc->sc_clock_count = sc->sc_coreclock_freq / hz;
sc->sc_count_per_usec = sc->sc_coreclock_freq / 10000000;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_CLEAR, IXPT_CLEAR);
ixp12x0_intr_establish(IXPPCI_INTR_T1, IPL_CLOCK, ixpclk_intr, NULL);
IXPREG(IXPPCI_IRQ_ENABLE_SET) = (1U << (IXPPCI_INTR_T1 - SYS_NIRQ));
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_LOAD,
sc->sc_clock_count);
#if 1 /* XXX */
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_CONTROL,
IXPCL_ENABLE | IXPCL_PERIODIC
| IXPCL_STP_CORE);
#else
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCLK_CONTROL,
IXPCL_ENABLE | IXPCL_PERIODIC
| IXPCL_STP_DIV256);
#endif
}
int
gettick()
{
int counter;
u_int savedints;
savedints = disable_interrupts(I32_bit);
counter = GET_TIMER_VALUE(ixpclk_sc);
restore_interrupts(savedints);
return counter;
}
/*
* microtime:
*
* Fill in the specified timeval struct with the current time
* accurate to the microsecond.
*/
void
microtime(tvp)
register struct timeval *tvp;
{
u_int oldirqstate;
u_int32_t counts;
static struct timeval lasttv;
if (ixpclk_sc == NULL) {
#ifdef DEBUG
printf("microtime: called befor initialize ixpclk\n");
#endif
tvp->tv_sec = 0;
tvp->tv_usec = 0;
return;
}
oldirqstate = disable_interrupts(I32_bit);
counts = ixpclk_sc->sc_clock_count - GET_TIMER_VALUE(ixpclk_sc);
#ifdef DEBUG
printf("microtime: counts = %d\n", counts);
#endif
/* Fill in the timeval struct. */
*tvp = time;
tvp->tv_usec += counts / ixpclk_sc->sc_count_per_usec;
/* Make sure microseconds doesn't overflow. */
while (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
/* Make sure the time has advanced. */
if (tvp->tv_sec == lasttv.tv_sec &&
tvp->tv_usec <= lasttv.tv_usec) {
tvp->tv_usec = lasttv.tv_usec + 1;
if (tvp->tv_usec >= 1000000) {
tvp->tv_usec -= 1000000;
tvp->tv_sec++;
}
}
lasttv = *tvp;
restore_interrupts(oldirqstate);
}
/*
* delay:
*
* Delay for at least N microseconds.
*/
void
delay(usecs)
u_int usecs;
{
u_int32_t tick, otick, delta;
int j, csec, usec;
csec = usecs / 10000;
usec = usecs % 10000;
if (ixpclk_sc == NULL) {
static u_int32_t coreclock_freq = 0;
#ifdef DEBUG
printf("delay: called befor initialize ixpclk\n");
#endif
if (coreclock_freq == 0) {
coreclock_freq
= ccf_to_coreclock[IXPREG(IXP12X0_PLL_CFG)
& IXP12X0_PLL_CFG_CCF];
}
usecs = (TIMER_FREQUENCY / 100) * csec
+ (TIMER_FREQUENCY / 100) * usec / 10000;
/* clock isn't initialized yet */
for(; usecs > 0; usecs--)
for(j = 100; j > 0; j--)
;
return;
}
usecs = (ixpclk_sc->sc_coreclock_freq / 100) * csec
+ (ixpclk_sc->sc_coreclock_freq / 100) * usec / 10000;
otick = gettick();
while (1) {
for(j = 100; j > 0; j--)
;
tick = gettick();
delta = otick > tick
? otick - tick
: otick - tick + IXPCL_ITV + 1;
if (delta > usecs)
break;
usecs -= delta;
otick = tick;
}
}
void
resettodr()
{
}
void
inittodr(base)
time_t base;
{
time.tv_sec = base;
time.tv_usec = 0;
}

View File

@ -0,0 +1,125 @@
/* $NetBSD: ixp12x0_clkreg.h,v 1.1 2002/07/15 16:27:16 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA 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 ICHIRO FUKUHARA OR THE VOICES IN HIS
* HEAD 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.
*/
/*
* IXP12X0 TIMER registers
* TIMER_1 v0xf0010300 p0x42000300
* TIMER_2 v0xf0010320 p0x42000320
* TIMER_3 v0xf0010340 p0x42000340
* TIMER_4 v0xf0010360 p0x42000360
*/
#ifndef _IXP12X0_TIMERREG_H_
#define _IXP12X0_TIMERREG_H_
#include <arm/ixp12x0/ixp12x0reg.h>
/* size of I/O space */
#define IXPCLK_VBASE (IXP12X0_PCI_VBASE + 0x300)
#define IXPCLK_SIZE 0x00000010
/* timer load register */
#define IXPCLK_LOAD 0x00000000
#define IXPCL_ITV 0x00ffffff
/* timer value register */
#define IXPCLK_VALUE 0x00000004
#define IXPCL_CTV 0x00ffffff
/* timer control register */
#define IXPCLK_CONTROL 0x00000008
#define IXPCL_STP 0x0c
#define IXPCL_STP_CORE 0x00
#define IXPCL_STP_DIV16 0x04
#define IXPCL_STP_DIV256 0x08
#define IXPCL_MODE 0x40
#define IXPCL_FREERUN 0x00
#define IXPCL_PERIODIC 0x40
#define IXPCL_EN 0x80
#define IXPCL_DISABLE 0x00
#define IXPCL_ENABLE 0x80
/* timer clear register */
#define IXPCLK_CLEAR 0x0000000c
#define IXPT_CLEAR 0
/*
* IXP12X0 real time clock registers
* RTC_DIV 0x90002000
* RTC_TINT 0x90002400
* RTC_TVAL 0x90002800
* RTC_CNTR 0x90002c00
* RTC_ALM 0x90003000
*/
/* RTC_DIV register */
#define RTC_DIV 0x90002000
#define RTC_RDIV 0x0000ffff
#define RTC_WEN 0x00010000
#define RTC_WDIVISER 0x00000000
#define RTC_WINTONLY 0x00010000
#define RTC_IEN 0x00020000
#define RTC_IEN_E 0x00020000
#define RTC_IEN_D 0x00000000
#define RTC_IRST 0x00040000
#define RTC_IRST_NOCLR 0x00040000
#define RTC_IRST_CLR 0x00000000
#define RTC_IRQS 0x00080000
#define RTC_IRQS_IRQ 0x00080000
#define RTC_IRQS_FIQ 0x00000000
/* RTC_TINT register */
#define RTC_TINT 0x90002400
#define RTC_RTINT 0x0000ffff
/* RTC_TVAL register */
#define RTC_TVAL 0x90002800
#define RTC_TVAL_TVAL 0x0000ffff
#define RTC_LD 0x00010000
#define RTC_LD_LOAD 0x00010000
#define RTC_LD_NOLOAD 0x00000000
#define RTC_PRE 0x00020000
#define RTC_PRE_SYSCLK 0x00020000
#define RTC_PRE_DIV128 0x00000000
/* RTC_CNTR register */
#define RTC_CNTR 0x90002c00
#define RTC_RCN_COUNT 0xffffffff
/* RTC_ALM register */
#define RTC_ALM 0x90003000
#define RTC_RTC_ALARM 0xffffffff
#endif /* _IXP12X0_TIMERREG_H_ */

View File

@ -0,0 +1,836 @@
/* $NetBSD: ixp12x0_com.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
#define POLLING_COM
/*
* Copyright (c) 1998, 1999, 2001, 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ichiro FUKUHARA and Naoto Shimazaki.
*
* This code is derived from software contributed to The NetBSD Foundation
* by IWAMOTO Toshihiro.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Charles M. Hannum.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Copyright (c) 1991 The Regents of the University of California.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)com.c 7.5 (Berkeley) 5/16/91
*/
#include "opt_com.h"
#include "opt_ddb.h"
#include "opt_kgdb.h"
#include "rnd.h"
#if NRND > 0 && defined(RND_COM)
#include <sys/rnd.h>
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/device.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/tty.h>
#include <sys/uio.h>
#include <sys/vnode.h>
#include <dev/cons.h>
#include <machine/bus.h>
#include <arm/ixp12x0/ixp12x0_comreg.h>
#include <arm/ixp12x0/ixp12x0_comvar.h>
#include <arm/ixp12x0/ixp12x0reg.h>
#include <arm/ixp12x0/ixp12x0var.h>
#include <arm/ixp12x0/ixpsipvar.h>
#include "ixpcom.h"
#ifdef POLLING_COM
#undef CR_RIE
#define CR_RIE 0
#undef CR_XIE
#define CR_XIE 0
#endif
#ifdef NOXIE
#undef CR_XIE
#define CR_XIE 0
#endif
cdev_decl(ixpcom);
static int ixpcom_match(struct device *, struct cfdata *, void *);
static void ixpcom_attach(struct device *, struct device *, void *);
static int ixpcom_detach(struct device *, int);
static int ixpcom_activate(struct device *, enum devact);
static int ixpcomparam(struct tty *, struct termios *);
static void ixpcomstart(struct tty *);
static int ixpcomhwiflow(struct tty *, int);
static void ixpcom_attach_subr(struct ixpcom_softc *);
static u_int cflag2cr(tcflag_t);
int ixpcomcngetc(dev_t);
void ixpcomcnputc(dev_t, int);
void ixpcomcnpollc(dev_t, int);
static void ixpcomsoft(void* arg);
inline static void ixpcom_txsoft(struct ixpcom_softc *, struct tty *);
inline static void ixpcom_rxsoft(struct ixpcom_softc *, struct tty *);
void ixpcomcnprobe(struct consdev *);
void ixpcomcninit(struct consdev *);
static int ixpcomintr(void* arg);
u_int32_t ixpcom_cr = 0; /* tell cr to *_intr.c */
u_int32_t ixpcom_imask = 0; /* intrrupt mask from *_intr.c */
static bus_space_tag_t ixpcomconstag;
static bus_space_handle_t ixpcomconsioh;
static bus_addr_t ixpcomconsaddr = IXPCOM_UART_BASE; /* XXX initial value */
static int ixpcomconsattached;
static int ixpcomconsrate;
static tcflag_t ixpcomconscflag;
struct cfattach ixpcom_ca = {
sizeof(struct ixpcom_softc), ixpcom_match, ixpcom_attach,
ixpcom_detach, ixpcom_activate
};
extern struct cfdriver ixpcom_cd;
struct consdev ixpcomcons = {
NULL, NULL, ixpcomcngetc, ixpcomcnputc, ixpcomcnpollc, NULL,
NODEV, CN_NORMAL
};
#ifndef DEFAULT_COMSPEED
#define DEFAULT_COMSPEED 38400
#endif
#define COMUNIT_MASK 0x7ffff
#define COMDIALOUT_MASK 0x80000
#define COMUNIT(x) (minor(x) & COMUNIT_MASK)
#define COMDIALOUT(x) (minor(x) & COMDIALOUT_MASK)
#define COM_ISALIVE(sc) ((sc)->enabled != 0 && \
ISSET((sc)->sc_dev.dv_flags, DVF_ACTIVE))
#define COM_BARRIER(t, h, f) bus_space_barrier((t), (h), 0, COM_NPORTS, (f))
#define COM_LOCK(sc);
#define COM_UNLOCK(sc);
#define SET(t, f) (t) |= (f)
#define CLR(t, f) (t) &= ~(f)
#define ISSET(t, f) ((t) & (f))
static int
ixpcom_match(parent, match, aux)
struct device *parent;
struct cfdata *match;
void *aux;
{
return (1);
}
void
ixpcom_attach(parent, self, aux)
struct device *parent;
struct device *self;
void *aux;
{
struct ixpcom_softc *sc = (struct ixpcom_softc *)self;
struct ixpsip_attach_args *sa = aux;
printf("\n");
sc->sc_iot = sa->sa_iot;
sc->sc_baseaddr = sa->sa_addr;
if(bus_space_map(sa->sa_iot, sa->sa_addr, sa->sa_size, 0,
&sc->sc_ioh)) {
printf("%s: unable to map registers\n", sc->sc_dev.dv_xname);
return;
}
printf("%s: IXP12x0 UART\n", sc->sc_dev.dv_xname);
ixpcom_attach_subr(sc);
#ifdef POLLING_COM
{ void* d; d = d = ixpcomintr; }
#else
ixp12x0_intr_establish(IXP12X0_INTR_UART, IPL_SERIAL, ixpcomintr, sc);
#endif
}
void
ixpcom_attach_subr(sc)
struct ixpcom_softc *sc;
{
bus_addr_t iobase = sc->sc_baseaddr;
bus_space_tag_t iot = sc->sc_iot;
struct tty *tp;
if (iot == ixpcomconstag && iobase == ixpcomconsaddr) {
ixpcomconsattached = 1;
sc->sc_speed = IXPCOMSPEED(ixpcomconsrate);
/* Make sure the console is always "hardwired". */
delay(10000); /* wait for output to finish */
SET(sc->sc_hwflags, COM_HW_CONSOLE);
SET(sc->sc_swflags, TIOCFLAG_SOFTCAR);
}
tp = ttymalloc();
tp->t_oproc = ixpcomstart;
tp->t_param = ixpcomparam;
tp->t_hwiflow = ixpcomhwiflow;
sc->sc_tty = tp;
sc->sc_rbuf = malloc(IXPCOM_RING_SIZE << 1, M_DEVBUF, M_NOWAIT);
sc->sc_rbput = sc->sc_rbget = sc->sc_rbuf;
sc->sc_rbavail = IXPCOM_RING_SIZE;
if (sc->sc_rbuf == NULL) {
printf("%s: unable to allocate ring buffer\n",
sc->sc_dev.dv_xname);
return;
}
sc->sc_ebuf = sc->sc_rbuf + (IXPCOM_RING_SIZE << 1);
sc->sc_tbc = 0;
sc->sc_rie = sc->sc_xie = 0;
ixpcom_cr = IXPCOMSPEED2BRD(DEFAULT_COMSPEED)
| CR_UE | sc->sc_rie | sc->sc_xie | DSS_8BIT;
tty_attach(tp);
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
int maj;
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == ixpcomopen)
break;
cn_tab->cn_dev = makedev(maj, sc->sc_dev.dv_unit);
delay(10000); /* XXX */
printf("%s: console\n", sc->sc_dev.dv_xname);
delay(10000); /* XXX */
}
sc->sc_si = softintr_establish(IPL_SOFTSERIAL, ixpcomsoft, sc);
#if NRND > 0 && defined(RND_COM)
rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname,
RND_TYPE_TTY, 0);
#endif
/* if there are no enable/disable functions, assume the device
is always enabled */
if (!sc->enable)
sc->enabled = 1;
/* XXX configure register */
/* xxx_config(sc) */
SET(sc->sc_hwflags, COM_HW_DEV_OK);
}
int
ixpcom_detach(self, flags)
struct device *self;
int flags;
{
struct ixpcom_softc *sc = (struct ixpcom_softc *)self;
int maj, mn;
/* locate the major number */
for (maj = 0; maj < nchrdev; maj++)
if (cdevsw[maj].d_open == ixpcomopen)
break;
/* Nuke the vnodes for any open instances. */
mn = self->dv_unit;
vdevgone(maj, mn, mn, VCHR);
mn |= COMDIALOUT_MASK;
vdevgone(maj, mn, mn, VCHR);
/* Free the receive buffer. */
free(sc->sc_rbuf, M_DEVBUF);
/* Detach and free the tty. */
tty_detach(sc->sc_tty);
ttyfree(sc->sc_tty);
#if NRND > 0 && defined(RND_COM)
/* Unhook the entropy source. */
rnd_detach_source(&sc->rnd_source);
#endif
return (0);
}
int
ixpcom_activate(self, act)
struct device *self;
enum devact act;
{
struct ixpcom_softc *sc = (struct ixpcom_softc *)self;
int s, rv = 0;
s = splserial();
COM_LOCK(sc);
switch (act) {
case DVACT_ACTIVATE:
rv = EOPNOTSUPP;
break;
case DVACT_DEACTIVATE:
if (sc->sc_hwflags & (COM_HW_CONSOLE|COM_HW_KGDB))
rv = EBUSY;
break;
}
COM_UNLOCK(sc);
splx(s);
return (rv);
}
int
ixpcomparam(tp, t)
struct tty *tp;
struct termios *t;
{
return (0);
}
int
ixpcomhwiflow(tp, block)
struct tty *tp;
int block;
{
return (0);
}
void
ixpcomstart(tp)
struct tty *tp;
{
return;
}
int
ixpcomopen(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
return (0);
}
static u_int
cflag2cr(cflag)
tcflag_t cflag;
{
u_int cr;
cr = (cflag & PARENB) ? CR_PE : 0;
cr |= (cflag & PARODD) ? CR_OES : 0;
cr |= (cflag & CSTOPB) ? CR_SBS : 0;
cr |= ((cflag & CSIZE) == CS8) ? DSS_8BIT : 0;
return (cr);
}
static void
ixpcom_loadchannelregs(sc)
struct ixpcom_softc *sc;
{
/* XXX */
ixpcom_cr &= ~(CR_RIE | CR_XIE);
ixpcom_cr |= sc->sc_rie | sc->sc_xie;
ixpcom_cr &= ixpcom_imask;
bus_space_write_4(sc->sc_iot, sc->sc_ioh, IXPCOM_CR, ixpcom_cr);
}
/* Initialization for serial console */
int
ixpcominit(iot, iobase, baud, cflag, iohp)
bus_space_tag_t iot;
bus_addr_t iobase;
int baud;
tcflag_t cflag;
bus_space_handle_t *iohp;
{
int cr;
if (bus_space_map(iot, iobase, IXPCOM_UART_SIZE, 0, iohp))
printf("register map failed\n");
cr = cflag2cr(cflag);
cr |= (IXPCOMSPEED(baud) << 16);
#if 0
cr |= (CR_UE | CR_RIE | CR_XIE);
#endif
cr |= CR_UE;
ixpcom_cr = cr;
/* enable the UART */
bus_space_write_4(iot, *iohp, IXPCOM_CR, cr);
return (0);
}
int
ixpcomcnattach(iot, iobase, rate, cflag)
bus_space_tag_t iot;
bus_addr_t iobase;
int rate;
tcflag_t cflag;
{
int res;
if ((res = ixpcominit(iot, iobase, rate, cflag, &ixpcomconsioh)))
return (res);
cn_tab = &ixpcomcons;
ixpcomconstag = iot;
ixpcomconsaddr = iobase;
ixpcomconsrate = rate;
ixpcomconscflag = cflag;
return (0);
}
#if 0
void
ixpcomcninit(cp)
struct consdev *cp;
{
if (cp == NULL) {
/* XXX cp == NULL means that MMU is disabled. */
ixpcomconsioh = IXPCOM_UART_BASE;
ixpcomconstag = &ixpcom_bs_tag;
cn_tab = &ixpcomcons;
IXPREG(IXPCOM_UART_BASE + IXPCOM_CR)
= (IXPCOMSPEED(38400) << 16)
| DSS_8BIT
| (CR_UE | CR_RIE | CR_XIE);
return;
}
if (ixpcominit(&ixpcom_bs_tag, CONADDR, CONSPEED,
CONMODE, &ixpcomconsioh))
panic("can't init serial console @%x", CONADDR);
cn_tab = &ixpcomcons;
ixpcomconstag = &ixpcom_bs_tag;
}
#endif
void
ixpcomcnprobe(cp)
struct consdev *cp;
{
cp->cn_pri = CN_REMOTE;
}
void
ixpcomcnpollc(dev, on)
dev_t dev;
int on;
{
}
void
ixpcomcnputc(dev, c)
dev_t dev;
int c;
{
int s;
s = spltty(); /* XXX do we need this? */
while(!(bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_SR)
& SR_TXR))
;
bus_space_write_4(ixpcomconstag, ixpcomconsioh, IXPCOM_DR, c);
splx(s);
}
int
ixpcomcngetc(dev)
dev_t dev;
{
int c, s;
s = spltty(); /* XXX do we need this? */
while(!(bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_SR)
& SR_RXR))
;
c = bus_space_read_4(ixpcomconstag, ixpcomconsioh, IXPCOM_DR);
c &= 0xff;
splx(s);
return (c);
}
inline static void
ixpcom_txsoft(sc, tp)
struct ixpcom_softc *sc;
struct tty *tp;
{
}
inline static void
ixpcom_rxsoft(sc, tp)
struct ixpcom_softc *sc;
struct tty *tp;
{
int (*rint) __P((int c, struct tty *tp)) = tp->t_linesw->l_rint;
u_char *get, *end;
u_int cc, scc;
u_char lsr;
int code;
int s;
end = sc->sc_ebuf;
get = sc->sc_rbget;
scc = cc = IXPCOM_RING_SIZE - sc->sc_rbavail;
#if 0
if (cc == IXPCOM_RING_SIZE) {
sc->sc_floods++;
if (sc->sc_errors++ == 0)
callout_reset(&sc->sc_diag_callout, 60 * hz,
comdiag, sc);
}
#endif
while (cc) {
code = get[0];
lsr = get[1];
if (ISSET(lsr, DR_ROR | DR_FRE | DR_PRE)) {
#if 0
if (ISSET(lsr, DR_ROR)) {
sc->sc_overflows++;
if (sc->sc_errors++ == 0)
callout_reset(&sc->sc_diag_callout,
60 * hz, comdiag, sc);
}
#endif
if (ISSET(lsr, DR_FRE))
SET(code, TTY_FE);
if (ISSET(lsr, DR_PRE))
SET(code, TTY_PE);
}
if ((*rint)(code, tp) == -1) {
/*
* The line discipline's buffer is out of space.
*/
if (!ISSET(sc->sc_rx_flags, RX_TTY_BLOCKED)) {
/*
* We're either not using flow control, or the
* line discipline didn't tell us to block for
* some reason. Either way, we have no way to
* know when there's more space available, so
* just drop the rest of the data.
*/
get += cc << 1;
if (get >= end)
get -= IXPCOM_RING_SIZE << 1;
cc = 0;
} else {
/*
* Don't schedule any more receive processing
* until the line discipline tells us there's
* space available (through comhwiflow()).
* Leave the rest of the data in the input
* buffer.
*/
SET(sc->sc_rx_flags, RX_TTY_OVERFLOWED);
}
break;
}
get += 2;
if (get >= end)
get = sc->sc_rbuf;
cc--;
}
if (cc != scc) {
sc->sc_rbget = get;
s = splserial();
COM_LOCK(sc);
cc = sc->sc_rbavail += scc - cc;
/* Buffers should be ok again, release possible block. */
if (cc >= 1) {
if (ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
CLR(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
SET(sc->sc_rie, CR_RIE);
ixpcom_loadchannelregs(sc);
}
if (ISSET(sc->sc_rx_flags, RX_IBUF_BLOCKED)) {
CLR(sc->sc_rx_flags, RX_IBUF_BLOCKED);
#if 0
com_hwiflow(sc);
#endif
}
}
COM_UNLOCK(sc);
splx(s);
}
}
static void
ixpcomsoft(void* arg)
{
struct ixpcom_softc *sc = arg;
if (COM_ISALIVE(sc) == 0)
return;
if (sc->sc_rx_ready) {
sc->sc_rx_ready = 0;
ixpcom_rxsoft(sc, sc->sc_tty);
}
if (sc->sc_tx_done) {
sc->sc_tx_done = 0;
ixpcom_txsoft(sc, sc->sc_tty);
}
}
static int
ixpcomintr(void* arg)
{
struct ixpcom_softc *sc = arg;
bus_space_tag_t iot = sc->sc_iot;
bus_space_handle_t ioh = sc->sc_ioh;
u_char *put, *end;
u_int cc;
u_int cr;
u_int sr;
u_int32_t c;
if (COM_ISALIVE(sc) == 0)
return (0);
COM_LOCK(sc);
cr = bus_space_read_4(iot, ioh, IXPCOM_CR) & CR_UE;
if (!cr) {
COM_UNLOCK(sc);
return (0);
}
sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
if (!ISSET(sr, SR_TXR | SR_RXR))
return (0);
#if 0
/*
* IPX12x0 doesn't have a "Receiver End of Break Status" bit
* in status registar. Currentry I have no idea to determine
* whether break signal is received.
*/
if (XXX) {
bus_space_write_4(iot, ioh, SACOM_SR0, SR0_REB);
#if defined(DDB) || defined(KGDB)
#ifndef DDB_BREAK_CHAR
if (ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
console_debugger();
}
#endif
#endif /* DDB || KGDB */
}
#endif
end = sc->sc_ebuf;
put = sc->sc_rbput;
cc = sc->sc_rbavail;
if (ISSET(sr, SR_RXR)) {
if (!ISSET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED)) {
while (cc > 0) {
if (!ISSET(sr, SR_RXR))
break;
c = bus_space_read_4(iot, ioh, IXPCOM_DR);
put[0] = c & 0xff;
put[1] = (c >> 8) & 0xff;
#if defined(DDB) && defined(DDB_BREAK_CHAR)
if (put[0] == DDB_BREAK_CHAR &&
ISSET(sc->sc_hwflags, COM_HW_CONSOLE)) {
console_debugger();
sr = bus_space_read_4(iot, ioh,
IXPCOM_SR);
continue;
}
#endif
put += 2;
if (put >= end)
put = sc->sc_rbuf;
cc--;
sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
}
/*
* Current string of incoming characters ended because
* no more data was available or we ran out of space.
* Schedule a receive event if any data was received.
* If we're out of space, turn off receive interrupts.
*/
sc->sc_rbput = put;
sc->sc_rbavail = cc;
if (!ISSET(sc->sc_rx_flags, RX_TTY_OVERFLOWED))
sc->sc_rx_ready = 1;
/* XXX do RX hardware flow control */
/*
* If we're out of space, disable receive interrupts
* until the queue has drained a bit.
*/
if (!cc) {
SET(sc->sc_rx_flags, RX_IBUF_OVERFLOWED);
CLR(sc->sc_rie, CR_RIE);
ixpcom_loadchannelregs(sc);
}
} else {
#ifdef DIAGNOSTIC
panic("ixpcomintr: we shouldn't reach here\n");
#endif
CLR(sc->sc_rie, CR_RIE);
ixpcom_loadchannelregs(sc);
}
}
/*
* Done handling any receive interrupts. See if data can be
* transmitted as well. Schedule tx done event if no data left
* and tty was marked busy.
*/
#if 0
sr = bus_space_read_4(iot, ioh, IXPCOM_SR);
if (ISSET(sr, SR_TXR)) {
/*
* If we've delayed a parameter change, do it now, and restart
* output.
* XXX sacom_loadchanelregs() waits TX completion,
* XXX resulting in ~0.1s hang (300bps, 4 bytes) in worst case
*/
if (sc->sc_heldchange) {
ixpcom_loadparams(sc);
sc->sc_heldchange = 0;
sc->sc_tbc = sc->sc_heldtbc;
sc->sc_heldtbc = 0;
}
/* Output the next chunk of the contiguous buffer, if any. */
if (sc->sc_tbc > 0) {
sacom_filltx(sc);
} else {
/* Disable transmit completion interrupts if necessary. */
if (ISSET(sc->sc_cr3, CR3_XIE)) {
CLR(sc->sc_cr3, CR3_XIE);
bus_space_write_4(iot, ioh, SACOM_CR3,
sc->sc_cr3);
}
if (sc->sc_tx_busy) {
sc->sc_tx_busy = 0;
sc->sc_tx_done = 1;
}
}
}
#endif
COM_UNLOCK(sc);
/* Wake up the poller. */
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
softintr_schedule(sc->sc_si);
#else
setsoftserial();
#endif
#if NRND > 0 && defined(RND_COM)
rnd_add_uint32(&sc->rnd_source, iir | lsr);
#endif
return (1);
}

View File

@ -0,0 +1,202 @@
/* $NetBSD: ixp12x0_com_io.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*/
/*
* bus_space functions for UART
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <uvm/uvm.h>
#include <machine/bus.h>
/* Proto types for all the bus_space structure functions */
bs_protos(ixpcom);
bs_protos(generic);
bs_protos(bs_notimpl);
struct bus_space ixpcom_bs_tag = {
/* cookie */
NULL, /* never used */
/* mapping/unmapping */
ixpcom_bs_map,
ixpcom_bs_unmap,
ixpcom_bs_subregion,
/* allocation/deallocation */
ixpcom_bs_alloc,
ixpcom_bs_free,
/* get kernel virtual address */
NULL,
/* mmap bus space for userland */
bs_notimpl_bs_mmap,
/* barrier */
ixpcom_bs_barrier,
/* read (single) */
bs_notimpl_bs_r_1,
bs_notimpl_bs_r_2,
generic_bs_r_4,
bs_notimpl_bs_r_8,
/* read multiple */
bs_notimpl_bs_rm_1,
bs_notimpl_bs_rm_2,
bs_notimpl_bs_rm_4,
bs_notimpl_bs_rm_8,
/* read region */
bs_notimpl_bs_rr_1,
bs_notimpl_bs_rr_2,
bs_notimpl_bs_rr_4,
bs_notimpl_bs_rr_8,
/* write (single) */
bs_notimpl_bs_w_1,
bs_notimpl_bs_w_2,
generic_bs_w_4,
bs_notimpl_bs_w_8,
/* write multiple */
bs_notimpl_bs_wm_1,
bs_notimpl_bs_wm_2,
bs_notimpl_bs_wm_4,
bs_notimpl_bs_wm_8,
/* write region */
bs_notimpl_bs_wr_1,
bs_notimpl_bs_wr_2,
bs_notimpl_bs_wr_4,
bs_notimpl_bs_wr_8,
/* set multiple */
bs_notimpl_bs_sm_1,
bs_notimpl_bs_sm_2,
bs_notimpl_bs_sm_4,
bs_notimpl_bs_sm_8,
/* set region */
bs_notimpl_bs_sr_1,
bs_notimpl_bs_sr_2,
bs_notimpl_bs_sr_4,
bs_notimpl_bs_sr_8,
/* copy */
bs_notimpl_bs_c_1,
bs_notimpl_bs_c_2,
bs_notimpl_bs_c_4,
bs_notimpl_bs_c_8,
};
/* bus space functions */
int
ixpcom_bs_map(t, bpa, size, cacheable, bshp)
void *t;
bus_addr_t bpa;
bus_size_t size;
int cacheable;
bus_space_handle_t *bshp;
{
/*
* Temporary implementation as all I/O is already mapped etc.
*/
*bshp = bpa;
return(0);
}
void
ixpcom_bs_unmap(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
/*
* Temporary implementation
*/
}
int
ixpcom_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
bpap, bshp)
void *t;
bus_addr_t rstart, rend;
bus_size_t size, alignment, boundary;
int cacheable;
bus_addr_t *bpap;
bus_space_handle_t *bshp;
{
panic("ixpcom_bs_alloc(): Help!\n");
}
void
ixpcom_bs_free(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
panic("ixpcom_bs_free(): Help!\n");
}
int
ixpcom_bs_subregion(t, bsh, offset, size, nbshp)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, size;
bus_space_handle_t *nbshp;
{
*nbshp = bsh + offset;
return (0);
}
void
ixpcom_bs_barrier(t, bsh, offset, len, flags)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, len;
int flags;
{
/* NULL */
}
/* End of ixp12x0_com_io.c */

View File

@ -0,0 +1,94 @@
/* $NetBSD: ixp12x0_comreg.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA 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 ICHIRO FUKUHARA OR THE VOICES IN HIS
* HEAD 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.
*/
/*
* IXP12X0 UART register
* UART_SR 0x90003400
* UART_CR 0x90003800
* UART_DR 0x90003C00
*/
#define IXPCOM_FREQ (3686400 / 16)
#define IXPCOMSPEED(b) (IXPCOM_FREQ / (b) - 1)
#define IXPCOMSPEED2BRD(b) (IXPCOMSPEED(b) << 16)
/* size of I/O space */
#define IXPCOM_UART_HWBASE 0x90000000UL
#define IXPCOM_UART_SIZE 0x00004000
/* Register base virtual addresses mapped by initarm() */
#define IXPCOM_UART_BASE 0xf0000000UL
/* UART control register */
#define IXPCOM_CR 0x00003800UL
#define CR_BRK 0x01 /* Break */
#define CR_PE 0x02 /* Parity enable */
#define CR_OES 0x04 /* Odd/even parity select */
#define CR_SBS 0x08 /* Stop bit select */
#define SBS_1STOP (0 << 3) /* 1 Stop Bit */
#define SBS_2STOP (1 << 3) /* 2 Stop Bit */
#define CR_RIE 0x10 /* Receive FIFO interrupt enable */
#define CR_DSS 0x60 /* Data size select */
#define DSS_5BIT (0 << 5) /* 5Bits */
#define DSS_6BIT (1 << 5) /* 6Bits */
#define DSS_7BIT (2 << 5) /* 7Bits */
#define DSS_8BIT (3 << 5) /* 8Bits */
#define CR_UE 0x80 /* UART Enable */
#define UE_DISABLE (0 << 7) /* UART Disabled */
#define UE_ENABLE (1 << 7) /* UART Enabled */
#define CR_XIE 0x100 /* Transmit FIFO interrupt enable */
#define CR_UIS 0x200 /* UART Interrupt Select */
#define CR_BRD 0x03ff0000 /* Baud rate divisor */
/* UART Status register */
#define IXPCOM_SR 0x00003400
#define SR_PRE 0x01 /* Parity error */
#define SR_FRE 0x02 /* Framing error */
#define SR_TXR 0x04 /* Transmit FIFO Ready */
#define SR_ROR 0x08 /* Receiver overrun */
#define SR_RXR 0x10 /* Receiver FIFO Ready */
#define SR_TXE 0x20 /* Transmitter enable */
#define SR_RXF 0x40 /* Receiver FIFO Full */
#define SR_TXF 0x80 /* Transmit FIFO Full */
/* UART data register */
#define IXPCOM_DR 0x00003C00
#define DR_PRE 0x100 /* Parity error */
#define DR_FRE 0x200 /* Framing error */
#define DR_ROR 0x400 /* Receiver overrun */
#define IXPCOMSPLRAISED (~(CR_RIE | CR_XIE))
#define IXPCOMSPLLOWERD (~0UL);

View File

@ -0,0 +1,102 @@
/* $NetBSD: ixp12x0_comvar.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*-
* Copyright (c) 2001, The NetBSD Foundation, Inc. All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by IWAMOTO Toshihiro and Ichiro FUKUHARA.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 _IXP12X0_COMVAR_H_
#define _IXP12X0_COMVAR_H_
/* Hardware flag masks */
#define COM_HW_NOIEN 0x01
#define COM_HW_DEV_OK 0x20
#define COM_HW_CONSOLE 0x40
#define COM_HW_KGDB 0x80
#define RX_TTY_BLOCKED 0x01
#define RX_TTY_OVERFLOWED 0x02
#define RX_IBUF_BLOCKED 0x04
#define RX_IBUF_OVERFLOWED 0x08
#define RX_ANY_BLOCK 0x0f
#define IXPCOM_RING_SIZE 2048
struct ixpcom_softc {
struct device sc_dev;
bus_addr_t sc_baseaddr;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
#ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
void *sc_si;
#endif
struct tty *sc_tty;
u_char *sc_rbuf, *sc_ebuf;
u_char *sc_tba;
u_int sc_tbc, sc_heldtbc;
u_char *volatile sc_rbget,
*volatile sc_rbput;
volatile u_int sc_rbavail;
/* status flags */
int sc_hwflags, sc_swflags;
volatile u_int sc_rx_flags,
sc_tx_busy,
sc_tx_done,
sc_tx_stopped,
sc_st_check,
sc_rx_ready;
volatile int sc_heldchange;
/* control registers */
u_int sc_xie;
u_int sc_rie;
u_int sc_speed;
/* power management hooks */
int (*enable)(struct ixpcom_softc *);
int (*disable)(struct ixpcom_softc *);
int enabled;
};
extern struct bus_space ixpcom_bs_tag;
int ixpcomcnattach(bus_space_tag_t, bus_addr_t, int, tcflag_t);
#endif /* _IXP12X0_COMVAR_H_ */

View File

@ -0,0 +1,569 @@
/* $NetBSD: ixp12x0_intr.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ichiro FUKUHARA and Naoto Shimazaki.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* Interrupt support for the Intel ixp12x0
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <uvm/uvm_extern.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <arm/cpufunc.h>
#include <arm/ixp12x0/ixp12x0reg.h>
#include <arm/ixp12x0/ixp12x0var.h>
#include <arm/ixp12x0/ixp12x0_comreg.h>
#include <arm/ixp12x0/ixp12x0_pcireg.h>
extern u_int32_t ixpcom_cr; /* current cr from *_com.c */
extern u_int32_t ixpcom_imask; /* tell mask to *_com.c */
/* Interrupt handler queues. */
struct intrq intrq[NIRQ];
/* Interrupts to mask at each level. */
static u_int32_t imask[NIPL];
static u_int32_t pci_imask[NIPL];
/* Current interrupt priority level. */
__volatile int current_spl_level;
/* Software copy of the IRQs we have enabled. */
__volatile u_int32_t intr_enabled;
__volatile u_int32_t pci_intr_enabled;
/* Interrupts pending. */
static __volatile int ipending;
/*
* Map a software interrupt queue index (to the unused bits in the
* ICU registers -- XXX will need to revisit this if those bits are
* ever used in future steppings).
*/
static const uint32_t si_to_irqbit[SI_NQUEUES] = {
IXP12X0_INTR_bit30, /* SI_SOFT */
IXP12X0_INTR_bit29, /* SI_SOFTCLOCK */
IXP12X0_INTR_bit28, /* SI_SOFTNET */
IXP12X0_INTR_bit27, /* SI_SOFTSERIAL */
};
#define INT_SWMASK \
((1U << IXP12X0_INTR_bit30) | (1U << IXP12X0_INTR_bit29) | \
(1U << IXP12X0_INTR_bit28) | (1U << IXP12X0_INTR_bit27))
#define SI_TO_IRQBIT(si) (1U << si_to_irqbit[(si)])
/*
* Map a software interrupt queue to an interrupt priority level.
*/
static const int si_to_ipl[SI_NQUEUES] = {
IPL_SOFT, /* SI_SOFT */
IPL_SOFTCLOCK, /* SI_SOFTCLOCK */
IPL_SOFTNET, /* SI_SOFTNET */
IPL_SOFTSERIAL, /* SI_SOFTSERIAL */
};
void ixp12x0_intr_dispatch(struct irqframe *frame);
static __inline u_int32_t
ixp12x0_irq_read(void)
{
return IXPREG(IXP12X0_IRQ_VBASE) & IXP12X0_INTR_MASK;
}
static __inline u_int32_t
ixp12x0_pci_irq_read(void)
{
return IXPREG(IXPPCI_IRQ_STATUS);
}
static void
ixp12x0_enable_uart_irq(void)
{
ixpcom_imask = 0;
IXPREG(IXPCOM_UART_BASE + IXPCOM_CR) = ixpcom_cr & ~ixpcom_imask;
}
static void
ixp12x0_disable_uart_irq(void)
{
ixpcom_imask = CR_RIE | CR_XIE;
IXPREG(IXPCOM_UART_BASE + IXPCOM_CR) = ixpcom_cr & ~ixpcom_imask;
}
static void
ixp12x0_set_intrmask(u_int32_t irqs, u_int32_t pci_irqs)
{
if (irqs & (1U << IXP12X0_INTR_UART)) {
ixp12x0_disable_uart_irq();
} else {
ixp12x0_enable_uart_irq();
}
IXPREG(IXPPCI_IRQ_ENABLE_CLEAR) = pci_irqs;
IXPREG(IXPPCI_IRQ_ENABLE_SET) = pci_intr_enabled & ~pci_irqs;
}
static void
ixp12x0_enable_irq(int irq)
{
if (irq < SYS_NIRQ) {
intr_enabled |= (1U << irq);
switch (irq) {
case IXP12X0_INTR_UART:
ixp12x0_enable_uart_irq();
break;
case IXP12X0_INTR_PCI:
/* nothing to do */
break;
default:
panic("enable_irq:bad IRQ %d\n", irq);
}
} else {
pci_intr_enabled |= (1U << (irq - SYS_NIRQ));
IXPREG(IXPPCI_IRQ_ENABLE_SET) = (1U << (irq - SYS_NIRQ));
}
}
static __inline void
ixp12x0_disable_irq(int irq)
{
if (irq < SYS_NIRQ) {
intr_enabled ^= ~(1U << irq);
switch (irq) {
case IXP12X0_INTR_UART:
ixp12x0_disable_uart_irq();
break;
case IXP12X0_INTR_PCI:
/* nothing to do */
break;
default:
/* nothing to do */
}
} else {
pci_intr_enabled &= (1U << (irq - SYS_NIRQ));
IXPREG(IXPPCI_IRQ_ENABLE_CLEAR) = (1U << (irq - SYS_NIRQ));
}
}
/*
* NOTE: This routine must be called with interrupts disabled in the CPSR.
*/
static void
ixp12x0_intr_calculate_masks(void)
{
struct intrq *iq;
struct intrhand *ih;
int irq, ipl;
/* First, figure out which IPLs each IRQ has. */
for (irq = 0; irq < NIRQ; irq++) {
int levels = 0;
iq = &intrq[irq];
ixp12x0_disable_irq(irq);
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list))
levels |= (1U << ih->ih_ipl);
iq->iq_levels = levels;
}
/* Next, figure out which IRQs are used by each IPL. */
for (ipl = 0; ipl < NIPL; ipl++) {
int irqs = 0;
int pci_irqs = 0;
for (irq = 0; irq < SYS_NIRQ; irq++) {
if (intrq[irq].iq_levels & (1U << ipl))
irqs |= (1U << irq);
}
imask[ipl] = irqs;
for (irq = 0; irq < SYS_NIRQ; irq++) {
if (intrq[irq + SYS_NIRQ].iq_levels & (1U << ipl))
pci_irqs |= (1U << irq);
}
pci_imask[ipl] = pci_irqs;
}
imask[IPL_NONE] = 0;
pci_imask[IPL_NONE] = 0;
/*
* Initialize the soft interrupt masks to block themselves.
*/
imask[IPL_SOFT] = SI_TO_IRQBIT(SI_SOFT);
imask[IPL_SOFTCLOCK] = SI_TO_IRQBIT(SI_SOFTCLOCK);
imask[IPL_SOFTNET] = SI_TO_IRQBIT(SI_SOFTNET);
imask[IPL_SOFTSERIAL] = SI_TO_IRQBIT(SI_SOFTSERIAL);
/*
* splsoftclock() is the only interface that users of the
* generic software interrupt facility have to block their
* soft intrs, so splsoftclock() must also block IPL_SOFT.
*/
imask[IPL_SOFTCLOCK] |= imask[IPL_SOFT];
pci_imask[IPL_SOFTCLOCK] |= pci_imask[IPL_SOFT];
/*
* splsoftnet() must also block splsoftclock(), since we don't
* want timer-driven network events to occur while we're
* processing incoming packets.
*/
imask[IPL_SOFTNET] |= imask[IPL_SOFTCLOCK];
pci_imask[IPL_SOFTNET] |= pci_imask[IPL_SOFTCLOCK];
/*
* Enforce a heirarchy that gives "slow" device (or devices with
* limited input buffer space/"real-time" requirements) a better
* chance at not dropping data.
*/
imask[IPL_BIO] |= imask[IPL_SOFTNET];
pci_imask[IPL_BIO] |= pci_imask[IPL_SOFTNET];
imask[IPL_NET] |= imask[IPL_BIO];
pci_imask[IPL_NET] |= pci_imask[IPL_BIO];
imask[IPL_SOFTSERIAL] |= pci_imask[IPL_NET];
pci_imask[IPL_SOFTSERIAL] |= pci_imask[IPL_NET];
imask[IPL_TTY] |= imask[IPL_SOFTSERIAL];
pci_imask[IPL_TTY] |= pci_imask[IPL_SOFTSERIAL];
/*
* splvm() blocks all interrupts that use the kernel memory
* allocation facilities.
*/
imask[IPL_IMP] |= imask[IPL_TTY];
pci_imask[IPL_IMP] |= pci_imask[IPL_TTY];
/*
* Audio devices are not allowed to perform memory allocation
* in their interrupt routines, and they have fairly "real-time"
* requirements, so give them a high interrupt priority.
*/
imask[IPL_AUDIO] |= imask[IPL_IMP];
pci_imask[IPL_AUDIO] |= pci_imask[IPL_IMP];
/*
* splclock() must block anything that uses the scheduler.
*/
imask[IPL_CLOCK] |= imask[IPL_AUDIO];
pci_imask[IPL_CLOCK] |= pci_imask[IPL_AUDIO];
/*
* No separate statclock on the IQ80310.
*/
imask[IPL_STATCLOCK] |= imask[IPL_CLOCK];
pci_imask[IPL_STATCLOCK] |= pci_imask[IPL_CLOCK];
/*
* splhigh() must block "everything".
*/
imask[IPL_HIGH] |= imask[IPL_STATCLOCK];
pci_imask[IPL_HIGH] |= pci_imask[IPL_STATCLOCK];
/*
* XXX We need serial drivers to run at the absolute highest priority
* in order to avoid overruns, so serial > high.
*/
imask[IPL_SERIAL] |= imask[IPL_HIGH];
pci_imask[IPL_SERIAL] |= pci_imask[IPL_HIGH];
/*
* Now compute which IRQs must be blocked when servicing any
* given IRQ.
*/
for (irq = 0; irq < NIRQ; irq++) {
int irqs;
int pci_irqs;
if (irq < SYS_NIRQ) {
irqs = (1U << irq);
pci_irqs = 0;
} else {
irqs = 0;
pci_irqs = (1U << (irq - SYS_NIRQ));
}
iq = &intrq[irq];
if (TAILQ_FIRST(&iq->iq_list) != NULL)
ixp12x0_enable_irq(irq);
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list)) {
irqs |= imask[ih->ih_ipl];
pci_irqs |= pci_imask[ih->ih_ipl];
}
iq->iq_mask = irqs;
iq->iq_pci_mask = pci_irqs;
}
}
static void
ixp12x0_do_pending(void)
{
static __cpu_simple_lock_t processing = __SIMPLELOCK_UNLOCKED;
int new;
u_int oldirqstate;
if (__cpu_simple_lock_try(&processing) == 0)
return;
new = current_spl_level;
oldirqstate = disable_interrupts(I32_bit);
#define DO_SOFTINT(si) \
if ((ipending & ~imask[new]) & SI_TO_IRQBIT(si)) { \
ipending &= ~SI_TO_IRQBIT(si); \
current_spl_level = si_to_ipl[(si)]; \
restore_interrupts(oldirqstate); \
softintr_dispatch(si); \
oldirqstate = disable_interrupts(I32_bit); \
current_spl_level = new; \
}
DO_SOFTINT(SI_SOFTSERIAL);
DO_SOFTINT(SI_SOFTNET);
DO_SOFTINT(SI_SOFTCLOCK);
DO_SOFTINT(SI_SOFT);
__cpu_simple_unlock(&processing);
restore_interrupts(oldirqstate);
}
__inline void
splx(int new)
{
int old;
u_int oldirqstate;
if (current_spl_level == new)
return;
oldirqstate = disable_interrupts(I32_bit);
old = current_spl_level;
current_spl_level = new;
ixp12x0_set_intrmask(imask[new], pci_imask[new]);
restore_interrupts(oldirqstate);
/* If there are software interrupts to process, do it. */
if ((ipending & INT_SWMASK) & ~imask[new])
ixp12x0_do_pending();
}
int
_splraise(int ipl)
{
int old = current_spl_level;
if (old >= ipl)
return (old);
splx(ipl);
return (old);
}
int
_spllower(int ipl)
{
int old = current_spl_level;
if (old <= ipl)
return (old);
splx(ipl);
return (old);
}
void
_setsoftintr(int si)
{
u_int oldirqstate;
oldirqstate = disable_interrupts(I32_bit);
ipending |= SI_TO_IRQBIT(si);
restore_interrupts(oldirqstate);
/* Process unmasked pending soft interrupts. */
if ((ipending & INT_SWMASK) & ~imask[current_spl_level])
ixp12x0_do_pending();
}
/*
* ixp12x0_intr_init:
*
* Initialize the rest of the interrupt subsystem, making it
* ready to handle interrupts from devices.
*/
void
ixp12x0_intr_init(void)
{
struct intrq *iq;
int i;
intr_enabled = 0;
pci_intr_enabled = 0;
for (i = 0; i < NIRQ; i++) {
iq = &intrq[i];
TAILQ_INIT(&iq->iq_list);
sprintf(iq->iq_name, "ipl %d", i);
evcnt_attach_dynamic(&iq->iq_ev, EVCNT_TYPE_INTR,
NULL, "ixpintr", iq->iq_name);
}
current_intr_depth = 0;
current_spl_level = 0;
/* Enable IRQs (don't yet use FIQs). */
enable_interrupts(I32_bit);
}
void *
ixp12x0_intr_establish(int irq, int ipl, int (*ih_func)(void *), void *arg)
{
struct intrq* iq;
struct intrhand* ih;
u_int oldirqstate;
#ifdef DEBUG
printf("ixp12x0_intr_establish(%d, %d, %08x, %08x)\n",
irq, ipl, (u_int32_t) ih_func, (u_int32_t) arg);
#endif
if (irq < 0 || irq > NIRQ)
panic("ixp12x0_intr_establish: IRQ %d out of range", ipl);
if (ipl < 0 || ipl > NIPL)
panic("ixp12x0_intr_establish: IPL %d out of range", ipl);
ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
if (ih == NULL)
return (NULL);
ih->ih_func = ih_func;
ih->ih_arg = arg;
ih->ih_irq = irq;
ih->ih_ipl = ipl;
iq = &intrq[irq];
oldirqstate = disable_interrupts(I32_bit);
TAILQ_INSERT_TAIL(&iq->iq_list, ih, ih_list);
ixp12x0_intr_calculate_masks();
restore_interrupts(oldirqstate);
return (ih);
}
void
ixp12x0_intr_disestablish(void *cookie)
{
struct intrhand* ih = cookie;
struct intrq* iq = &intrq[ih->ih_ipl];
u_int oldirqstate;
oldirqstate = disable_interrupts(I32_bit);
TAILQ_REMOVE(&iq->iq_list, ih, ih_list);
ixp12x0_intr_calculate_masks();
restore_interrupts(oldirqstate);
}
void
ixp12x0_intr_dispatch(struct clockframe *frame)
{
struct intrq* iq;
struct intrhand* ih;
u_int oldirqstate;
int pcpl;
u_int32_t hwpend;
u_int32_t pci_hwpend;
int irq;
u_int32_t ibit;
pcpl = current_spl_level;
hwpend = ixp12x0_irq_read();
pci_hwpend = ixp12x0_pci_irq_read();
while (hwpend) {
irq = ffs(hwpend) - 1;
ibit = (1U << irq);
iq = &intrq[irq];
iq->iq_ev.ev_count++;
uvmexp.intrs++;
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list)) {
int ipl;
current_spl_level = ipl = ih->ih_ipl;
ixp12x0_set_intrmask(imask[ipl] | hwpend,
pci_imask[ipl] | pci_hwpend);
oldirqstate = enable_interrupts(I32_bit);
(void) (*ih->ih_func)(ih->ih_arg ? ih->ih_arg : frame);
restore_interrupts(oldirqstate);
hwpend &= ~ibit;
}
}
while (pci_hwpend) {
irq = ffs(pci_hwpend) - 1;
ibit = (1U << irq);
iq = &intrq[irq + SYS_NIRQ];
iq->iq_ev.ev_count++;
uvmexp.intrs++;
for (ih = TAILQ_FIRST(&iq->iq_list); ih != NULL;
ih = TAILQ_NEXT(ih, ih_list)) {
int ipl;
current_spl_level = ipl = ih->ih_ipl;
ixp12x0_set_intrmask(imask[ipl] | hwpend,
pci_imask[ipl] | pci_hwpend);
oldirqstate = enable_interrupts(I32_bit);
(void) (*ih->ih_func)(ih->ih_arg ? ih->ih_arg : frame);
restore_interrupts(oldirqstate);
pci_hwpend &= ~ibit;
}
}
splx(pcpl);
/* Check for pendings soft intrs. */
if ((ipending & INT_SWMASK) & ~imask[pcpl]) {
oldirqstate = enable_interrupts(I32_bit);
ixp12x0_do_pending();
restore_interrupts(oldirqstate);
}
}

View File

@ -0,0 +1,382 @@
/* $NetBSD: ixp12x0_io.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*/
/*
* bus_space I/O functions for ixp12x0
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <uvm/uvm.h>
#include <machine/bus.h>
#include <arm/ixp12x0/ixp12x0reg.h>
#include <arm/ixp12x0/ixp12x0var.h>
/* Proto types for all the bus_space structure functions */
bs_protos(ixp12x0);
bs_protos(ixp12x0_io);
bs_protos(ixp12x0_mem);
bs_protos(generic);
bs_protos(generic_armv4);
bs_protos(bs_notimpl);
struct bus_space ixp12x0_bs_tag = {
/* cookie */
(void *) 0,
/* mapping/unmapping */
NULL,
NULL,
ixp12x0_bs_subregion,
/* allocation/deallocation */
NULL,
NULL,
/* get kernel virtual address */
ixp12x0_bs_vaddr,
/* mmap bus space for userland */
ixp12x0_bs_mmap,
/* barrier */
ixp12x0_bs_barrier,
/* read (single) */
generic_bs_r_1,
generic_armv4_bs_r_2,
generic_bs_r_4,
bs_notimpl_bs_r_8,
/* read multiple */
generic_bs_rm_1,
generic_armv4_bs_rm_2,
generic_bs_rm_4,
bs_notimpl_bs_rm_8,
/* read region */
bs_notimpl_bs_rr_1,
generic_armv4_bs_rr_2,
generic_bs_rr_4,
bs_notimpl_bs_rr_8,
/* write (single) */
generic_bs_w_1,
generic_armv4_bs_w_2,
generic_bs_w_4,
bs_notimpl_bs_w_8,
/* write multiple */
generic_bs_wm_1,
generic_armv4_bs_wm_2,
generic_bs_wm_4,
bs_notimpl_bs_wm_8,
/* write region */
bs_notimpl_bs_wr_1,
generic_armv4_bs_wr_2,
bs_notimpl_bs_wr_4,
bs_notimpl_bs_wr_8,
/* set multiple */
bs_notimpl_bs_sm_1,
bs_notimpl_bs_sm_2,
bs_notimpl_bs_sm_4,
bs_notimpl_bs_sm_8,
/* set region */
bs_notimpl_bs_sr_1,
generic_armv4_bs_sr_2,
bs_notimpl_bs_sr_4,
bs_notimpl_bs_sr_8,
/* copy */
bs_notimpl_bs_c_1,
generic_armv4_bs_c_2,
bs_notimpl_bs_c_4,
bs_notimpl_bs_c_8,
};
void
ixp12x0_bs_init(bs, cookie)
bus_space_tag_t bs;
void *cookie;
{
*bs = ixp12x0_bs_tag;
bs->bs_cookie = cookie;
}
void
ixp12x0_io_bs_init(bs, cookie)
bus_space_tag_t bs;
void *cookie;
{
*bs = ixp12x0_bs_tag;
bs->bs_cookie = cookie;
bs->bs_map = ixp12x0_io_bs_map;
bs->bs_unmap = ixp12x0_io_bs_unmap;
bs->bs_alloc = ixp12x0_io_bs_alloc;
bs->bs_free = ixp12x0_io_bs_free;
bs->bs_vaddr = ixp12x0_io_bs_vaddr;
}
void
ixp12x0_mem_bs_init(bs, cookie)
bus_space_tag_t bs;
void *cookie;
{
*bs = ixp12x0_bs_tag;
bs->bs_cookie = cookie;
bs->bs_map = ixp12x0_mem_bs_map;
bs->bs_unmap = ixp12x0_mem_bs_unmap;
bs->bs_alloc = ixp12x0_mem_bs_alloc;
bs->bs_free = ixp12x0_mem_bs_free;
bs->bs_mmap = ixp12x0_mem_bs_mmap;
}
/* mem bus space functions */
int
ixp12x0_mem_bs_map(t, bpa, size, cacheable, bshp)
void *t;
bus_addr_t bpa;
bus_size_t size;
int cacheable;
bus_space_handle_t *bshp;
{
#if 0
struct ixp12x0_softc *sc = t;
#endif
paddr_t pa, endpa;
vaddr_t va;
if ((bpa + size) >= IXP12X0_PCI_MEM_SIZE)
return (EINVAL);
/*
* PCI MEM space is mapped same address as real memory
*/
pa = trunc_page(bpa + IXP12X0_PCI_MEM_VBASE);
endpa = round_page((bpa + IXP12X0_PCI_MEM_VBASE) + size);
/* XXX use extent manager to check duplicate mapping */
va = uvm_km_valloc(kernel_map, endpa - pa);
if (va == 0)
return(ENOMEM);
/* Store the bus space handle */
*bshp = va + (bpa & PAGE_MASK);
for(; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
pmap_enter(pmap_kernel(), va, pa,
VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
}
pmap_update(pmap_kernel());
return(0);
}
void
ixp12x0_mem_bs_unmap(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
vaddr_t startva, endva;
startva = trunc_page(bsh);
endva = round_page(bsh + size);
uvm_km_free(kernel_map, startva, endva - startva);
}
int
ixp12x0_mem_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
bpap, bshp)
void *t;
bus_addr_t rstart, rend;
bus_size_t size, alignment, boundary;
int cacheable;
bus_addr_t *bpap;
bus_space_handle_t *bshp;
{
panic("ixp12x0_mem_bs_alloc(): Help!\n");
}
void
ixp12x0_mem_bs_free(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
panic("ixp12x0_mem_bs_free(): Help!\n");
}
paddr_t
ixp12x0_mem_bs_mmap(t, addr, off, prot, flags)
void *t;
bus_addr_t addr;
off_t off;
int prot;
int flags;
{
/* Not supported. */
return (-1);
}
/* I/O bus space functions */
int
ixp12x0_io_bs_map(t, bpa, size, cacheable, bshp)
void *t;
bus_addr_t bpa;
bus_size_t size;
int cacheable;
bus_space_handle_t *bshp;
{
#if 0
struct ixp12x0_softc *sc = t;
#endif
#if 0
if ((bpa + size) >= IXP12X0_PCI_IO_SIZE)
return (EINVAL);
#endif
/*
* PCI I/O space is mapped at virtual address of each evaluation board.
* Translate the bus address to the virtual address.
*/
*bshp = bpa + IXP12X0_PCI_IO_VBASE;
return(0);
}
void
ixp12x0_io_bs_unmap(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
/*
* Temporary implementation
*/
}
int
ixp12x0_io_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
bpap, bshp)
void *t;
bus_addr_t rstart, rend;
bus_size_t size, alignment, boundary;
int cacheable;
bus_addr_t *bpap;
bus_space_handle_t *bshp;
{
panic("ixp12x0_io_bs_alloc(): Help!\n");
}
void
ixp12x0_io_bs_free(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
panic("ixp12x0_io_bs_free(): Help!\n");
}
void *
ixp12x0_io_bs_vaddr(t, bsh)
void *t;
bus_space_handle_t bsh;
{
/* Not supported. */
return (NULL);
}
/* Common routines */
int
ixp12x0_bs_subregion(t, bsh, offset, size, nbshp)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, size;
bus_space_handle_t *nbshp;
{
*nbshp = bsh + offset;
return (0);
}
void *
ixp12x0_bs_vaddr(t, bsh)
void *t;
bus_space_handle_t bsh;
{
return ((void *)bsh);
}
paddr_t
ixp12x0_bs_mmap(t, addr, off, prot, flags)
void *t;
bus_addr_t addr;
off_t off;
int prot;
int flags;
{
/* Not supported. */
return (-1);
}
void
ixp12x0_bs_barrier(t, bsh, offset, len, flags)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, len;
int flags;
{
/* NULL */
}
/* End of ixp12x0_io.c */

View File

@ -0,0 +1,155 @@
/* $NetBSD: ixp12x0_irq.S,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed for the NetBSD Project by
* Wasabi Systems, Inc.
* 4. The name of Wasabi Systems, Inc. may not be used to endorse
* or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``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 WASABI SYSTEMS, INC
* 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 "assym.h"
#include <machine/asm.h>
#include <machine/cpu.h>
#include <machine/frame.h>
/*
* irq_entry:
*
* Main entry point for the IRQ vector.
*/
.text
.align 0
Lcurrent_intr_depth:
.word _C_LABEL(current_intr_depth)
.word _C_LABEL(prev_intr_depth)
Lintr_dispatch:
.word _C_LABEL(ixp12x0_intr_dispatch)
Lastpending:
.word _C_LABEL(astpending)
ASENTRY_NP(irq_entry)
sub lr, lr, #0x00000004 /* Adjust the lr */
PUSHFRAMEINSVC /* Push an interrupt frame */
/*
* Note that we have entered the IRQ handler. We are
* in SVC mode so we cannot use the processor mode to
* determine if we are in an IRQ. Instead, we will
* count each time the interrupt handler is nested.
*/
ldr r0, Lcurrent_intr_depth
ldr r2, Lcurrent_intr_depth+4
ldr r1, [r0]
str r1, [r2]
add r1, r1, #1
str r1, [r0]
/*
* Call the C interrupt dispatch routine.
*/
add lr, pc, #(Lirq_return - . - 8)
mov r0, sp
ldr pc, Lintr_dispatch
Lirq_return:
/* Decremement the nest count. */
ldr r0, Lcurrent_intr_depth
ldr r2, Lcurrent_intr_depth+4
ldr r1, [r0]
str r1, [r2]
sub r1, r1, #1
str r1, [r0]
/*
* If we're returning to user mode, check for pending ASTs.
*/
ldr r0, [sp] /* Get the SPSR from stack */
and r0, r0, #(PSR_MODE) /* Test for USR32 mode before the IRQ */
teq r0, #(PSR_USR32_MODE)
bne Lirqout /* Nope, get out now */
Lastloop:
ldr r0, Lastpending /* Do we have an AST pending? */
ldr r1, [r0]
teq r1, #0x00000000
beq Lirqout /* Nope, get out now */
mov r1, #0x00000000
str r1, [r0] /* Clear astpending */
mrs r4, cpsr_all /* save CPSR */
bic r0, r4, #(I32_bit) /* Enable IRQs */
msr cpsr_all, r0
mov r0, sp
bl _C_LABEL(ast) /* ast(frame) */
msr cpsr_all, r4 /* Disable IRQs */
b Lastloop /* Check for more ASTs */
Lirqout:
PULLFRAMEFROMSVCANDEXIT
movs pc, lr /* Exit */
.bss
.align 0
.global _C_LABEL(astpending)
_C_LABEL(astpending):
.word 0
.global _C_LABEL(current_intr_depth)
_C_LABEL(current_intr_depth):
.word 0
.global _C_LABEL(prev_intr_depth)
_C_LABEL(prev_intr_depth):
.word 0
/*
* XXX Provide intrnames/intrcnt for legacy code, but
* don't actually use them.
*/
.global _C_LABEL(intrnames), _C_LABEL(eintrnames)
.global _C_LABEL(intrcnt), _C_LABEL(eintrcnt)
_C_LABEL(intrnames):
_C_LABEL(eintrnames):
.global _C_LABEL(intrcnt), _C_LABEL(sintrcnt), _C_LABEL(eintrcnt)
_C_LABEL(intrcnt):
_C_LABEL(eintrcnt):

View File

@ -0,0 +1,193 @@
/* $NetBSD: ixp12x0_pci.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Ichiro FUKUHARA and Naoto Shimazaki.
*
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
*/
/*
* PCI configuration support for IXP12x0 Network Processor chip.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/extent.h>
#include <sys/malloc.h>
#include <uvm/uvm_extern.h>
#include <arm/ixp12x0/ixp12x0reg.h>
#include <arm/ixp12x0/ixp12x0var.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "opt_pci.h"
#include "pci.h"
void ixp12x0_pci_attach_hook(struct device *, struct device *,
struct pcibus_attach_args *);
int ixp12x0_pci_bus_maxdevs(void *, int);
pcitag_t ixp12x0_pci_make_tag(void *, int, int, int);
void ixp12x0_pci_decompose_tag(void *, pcitag_t, int *, int *, int *);
pcireg_t ixp12x0_pci_conf_read(void *, pcitag_t, int);
void ixp12x0_pci_conf_write(void *, pcitag_t, int, pcireg_t);
#define MAX_PCI_DEVICES 21
void
ixp12x0_pci_init(pc, cookie)
pci_chipset_tag_t pc;
void *cookie;
{
pc->pc_conf_v = cookie;
pc->pc_attach_hook = ixp12x0_pci_attach_hook;
pc->pc_bus_maxdevs = ixp12x0_pci_bus_maxdevs;
pc->pc_make_tag = ixp12x0_pci_make_tag;
pc->pc_decompose_tag = ixp12x0_pci_decompose_tag;
pc->pc_conf_read = ixp12x0_pci_conf_read;
pc->pc_conf_write = ixp12x0_pci_conf_write;
}
void
pci_conf_interrupt(pc, a, b, c, d, p)
pci_chipset_tag_t pc;
int a, b, c, d, *p;
{
/* Nothing */
}
void
ixp12x0_pci_attach_hook(parent, self, pba)
struct device *parent;
struct device *self;
struct pcibus_attach_args *pba;
{
/* Nothing to do. */
}
int
ixp12x0_pci_bus_maxdevs(v, busno)
void *v;
int busno;
{
return(MAX_PCI_DEVICES);
}
pcitag_t
ixp12x0_pci_make_tag(v, bus, device, function)
void *v;
int bus, device, function;
{
#ifdef PCI_DEBUG
printf("ixp12x0_pci_make_tag(v=%p, bus=%d, device=%d, function=%d)\n",
v, bus, device, function);
#endif
return ((bus << 16) | (device << 11) | (function << 8));
}
void
ixp12x0_pci_decompose_tag(v, tag, busp, devicep, functionp)
void *v;
pcitag_t tag;
int *busp, *devicep, *functionp;
{
#ifdef PCI_DEBUG
printf("ixp12x0_pci_decompose_tag(v=%p, tag=0x%08lx, bp=%x, dp=%x, fp=%x)\n",
v, tag, (int)busp, (int)devicep, (int)functionp);
#endif
if (busp != NULL)
*busp = (tag >> 16) & 0xff;
if (devicep != NULL)
*devicep = (tag >> 11) & 0x1f;
if (functionp != NULL)
*functionp = (tag >> 8) & 0x7;
}
pcireg_t
ixp12x0_pci_conf_read(v, tag, offset)
void *v;
pcitag_t tag;
int offset;
{
int bus, device, function;
u_int address;
pcireg_t val;
ixp12x0_pci_decompose_tag(v, tag, &bus, &device, &function);
if (bus != 0)
address = IXP12X0_PCI_TYPE1_VBASE | ((bus & 0xff) << 16) |
((device & 0x1F) << 8) | (offset & 0xff);
else /* bus == 0 */
address = IXP12X0_PCI_TYPE0_VBASE | 0xc00000 |
((device &0x1f) << 3 | (function & 0x7)) << 8 |
(offset & 0xff);
val = *((unsigned int *)address);
#ifdef PCI_DEBUG
printf("ixp12x0_pci_conf_read(addr=%08x)(v=%p tag=0x%08lx offset=0x%02x)=0x%08x\n",
address, v, tag, offset, val);
#endif
return(val);
}
void
ixp12x0_pci_conf_write(v, tag, offset, val)
void *v;
pcitag_t tag;
int offset;
pcireg_t val;
{
int bus, device, function;
u_int address;
ixp12x0_pci_decompose_tag(v, tag, &bus, &device, &function);
if (bus != 0)
address = IXP12X0_PCI_TYPE1_VBASE | ((bus & 0xff) << 16) |
((device & 0x1F) << 8) | (offset & 0xff);
else /* bus == 0 */
address = IXP12X0_PCI_TYPE0_VBASE | 0xc00000 |
((device &0x1f) << 3 | (function & 0x7)) << 8 |
(offset & 0xff);
#ifdef PCI_DEBUG
printf("ixp12x0_pci_conf_write(addr=%08x)(v=%p tag=0x%08lx offset=0x%02x)=0x%08x\n",
address, v, tag, offset, val);
#endif
*((unsigned int *)address) = val;
}

View File

@ -0,0 +1,66 @@
/* $NetBSD: ixp12x0_pci_dma.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <uvm/uvm_extern.h>
#define _ARM32_BUS_DMA_PRIVATE
#include <machine/bus.h>
void
ixp12x0_pci_dma_init(bus_dma_tag_t dmat, void *cookie)
{
dmat->_ranges = 0;
dmat->_nranges = 0;
dmat->_dmamap_create = _bus_dmamap_create;
dmat->_dmamap_destroy = _bus_dmamap_destroy;
dmat->_dmamap_load = _bus_dmamap_load; /* XXX */
dmat->_dmamap_load_mbuf = _bus_dmamap_load_mbuf; /* XXX */
dmat->_dmamap_load_uio = _bus_dmamap_load_uio; /* XXX */
dmat->_dmamap_load_raw = _bus_dmamap_load_raw; /* XXX */
dmat->_dmamap_unload = _bus_dmamap_unload;
dmat->_dmamap_sync = _bus_dmamap_sync;
dmat->_dmamem_alloc = _bus_dmamem_alloc; /* XXX */
dmat->_dmamem_free = _bus_dmamem_free;
dmat->_dmamem_map = _bus_dmamem_map;
dmat->_dmamem_unmap = _bus_dmamem_unmap;
dmat->_dmamem_mmap = _bus_dmamem_mmap;
}

View File

@ -0,0 +1,195 @@
/* $NetBSD: ixp12x0_pcireg.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA 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 ICHIRO FUKUHARA OR THE VOICES IN HIS
* HEAD 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 _IXP12X0_PCIREG_H_
#define _IXP12X0_PCIREG_H_
#include <arm/ixp12x0/ixp12x0reg.h>
/* PCI Configuration Space Registers */
/* base address */
#define IXP_PCI_MEM_BAR 0x10
# define IXP1200_PCI_MEM_BAR 0x40000000UL
#define IXP_PCI_IO_BAR 0x14
# define IXP1200_PCI_IO_BAR 0x0000f000UL
#define IXP_PCI_DRAM_BAR 0x18
# define IXP1200_PCI_DRAM_BAR 0x00000000UL
#define PCI_CAP_PTR 0x34
#define PCI_INT_LINE 0x3C
#define MAILBOX_0 0x50
#define MAILBOX_1 0x54
#define MAILBOX_2 0x58
#define MAILBOX_3 0x5C
#define DOORBELL 0x60
#define DOORBELL_SETUP 0x64
#define ROM_BYTE_WRITE 0x68
#define CAP_PTR_EXT 0x70
#define PWR_MGMT 0x74
/* Reset Registers*/
#define IXPPCI_IXP1200_RESET 0x7C
# define RESET_UE0 (1U << 0)
# define RESET_UE1 (1U << 1)
# define RESET_UE2 (1U << 2)
# define RESET_UE3 (1U << 3)
# define RESET_UE4 (1U << 4)
# define RESET_UE5 (1U << 5)
# define RESET_PCIRST (1U << 14)
# define RESET_EXRST (1U << 15)
# define RESET_FBI (1U << 16)
# define RESET_CMDARB (1U << 17)
# define RESET_SDRAM (1U << 18)
# define RESET_SRAM (1U << 29)
# define RESET_PCI (1U << 30)
# define RESET_SACORE (1U << 31)
# define RESET_FULL (RESET_UE0 | RESET_UE1 | RESET_UE2 | \
RESET_UE3 | RESET_UE4 | RESET_UE5 | \
RESET_EXRST | RESET_FBI | \
RESET_CMDARB | RESET_SDRAM | RESET_SRAM | \
RESET_PCI | RESET_SACORE)
#define CHAN_1_BYTE_COUNT 0x80
#define CHAN_1_PCI_ADDR 0x84
#define CHAN_1_DRAM_ADDR 0x88
#define CHAN_1_DESC_PTR 0x8C
#define CHAN_1_CONTROL 0x90
#define DMA_INF_MODE 0x9C
#define CHAN_2_BYTE_COUNT 0xA0
#define CHAN_2_PCI_ADDR 0xA4
#define CHAN_2_DRAM_ADDR 0xA8
#define CHAN_2_DESC_PTR 0xAC
#define CHAN_2_CONTROL 0xB0
#define CSR_BASE_ADDR_MASK 0x0F8
#define CSR_BASE_ADDR_OFF 0xFC
# define CSR_BASE_ADDR_MASK_1M 0x000c0000UL
#define DRAM_BASE_ADDR_MASK 0x100
#define DRAM_BASE_ADDR_OFF 0x104
# define DRAM_BASE_ADDR_MASK_256MB 0x0ffc0000UL
#define ROM_BASE_ADDR_MASK 0x108
#define DRAM_TIMING 0x10C
#define DRAM_ADDR_SIZE_0 0x110
#define DRAM_ADDR_SIZE_1 0x114
#define DRAM_ADDR_SIZE_2 0x118
#define DRAM_ADDR_SIZE_3 0x11C
#define I2O_IFH 0x120
#define I2O_IPT 0x124
#define I2O_OPH 0x128
#define I2O_OFT 0x12C
#define I2O_IFC 0x130
#define I2O_OPC 0x134
#define I2O_IPC 0x138
#define SA_CONTROL 0x13C
# define SA_CONTROL_PNR (1 << 9)
# define SA_CONTROL_COMPLETE (1 << 0)
#define PCI_ADDR_EXT 0x140
#define PREFETCH_RANGE 0x144
#define PCI_ABITOR_STATUS 0x148
#define DBELL_PCI_MASK 0x150
#define DBELL_SA_MASK 0x154
/*
* Interrupt index assignment
*
* FIQ/IRQ bitmap in "PCI Registers Accessible Through StrongARM Core"
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* bit 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+-+-+-+-+---+-+-+
* |D|R|R|D|D|P|I|S|R|S|D|D| |P|D|D|D| |T|T|T|T| |S| |
* |P|T|M|P|T|W|I|D|S|B|M|M|R|I|M|M|F| |4|3|2|1| |I| |
* |E|A|A|E|E|R|P|P|E| |A|A|E|L|A|A|H| RES | | | | |RES| | |
* | | | |D| |M| |A|R| |2|1|S| |2|1| | | | | | | | | |
* | | | | | | | |R|R| |N|N| | | | | | | | | | | | | |
* | | | | | | | | | | |B|B| | | | | | | | | | | | | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-------------+-+-+-+-+---+-+-+
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1
* index 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 7 6 5 4 1 0
*
*/
/* PCI_IRQ_STATUS */
#define IXPPCI_IRQ_STATUS (IXP12X0_PCI_VBASE + 0x180)
#define IXPPCI_FIQ_STATUS (IXP12X0_PCI_VBASE + 0x280)
#define IXPPCI_IRQ_RAW_STATUS (IXP12X0_PCI_VBASE + 0x184)
#define IXPPCI_FIQ_RAW_STATUS (IXP12X0_PCI_VBASE + 0x284)
#define IXPPCI_IRQ_ENABLE (IXP12X0_PCI_VBASE + 0x188)
#define IXPPCI_FIQ_ENABLE (IXP12X0_PCI_VBASE + 0x288)
#define IXPPCI_IRQ_ENABLE_SET (IXP12X0_PCI_VBASE + 0x188)
#define IXPPCI_FIQ_ENABLE_SET (IXP12X0_PCI_VBASE + 0x288)
#define IXPPCI_IRQ_ENABLE_CLEAR (IXP12X0_PCI_VBASE + 0x18c)
#define IXPPCI_FIQ_ENABLE_CLEAR (IXP12X0_PCI_VBASE + 0x28c)
#define IXPPCI_IRQ_SOFT (IXP12X0_PCI_VBASE + 0x190)
#define IXPPCI_FIQ_SOFT (IXP12X0_PCI_VBASE + 0x290)
#define IXPPCI_IRQST_TIMER (IXP12X0_PCI_VBASE + 0x010)
#define IXPPCI_INTR_DPE 63
#define IXPPCI_INTR_RTA 62
#define IXPPCI_INTR_RMA 61
#define IXPPCI_INTR_DPED 60
#define IXPPCI_INTR_DTE 59
#define IXPPCI_INTR_PWRM 58
#define IXPPCI_INTR_IIP 57
#define IXPPCI_INTR_SDPAR 56
#define IXPPCI_INTR_RSERR 55
#define IXPPCI_INTR_SB 54
#define IXPPCI_INTR_DMA2NB 53
#define IXPPCI_INTR_DMA1NB 52
#define IXPPCI_INTR_bit19 51
#define IXPPCI_INTR_PIL 50
#define IXPPCI_INTR_DMA2 49
#define IXPPCI_INTR_DMA1 48
#define IXPPCI_INTR_DFH 47
#define IXPPCI_INTR_bit14 46
#define IXPPCI_INTR_bit13 45
#define IXPPCI_INTR_bit12 44
#define IXPPCI_INTR_bit11 43
#define IXPPCI_INTR_bit10 42
#define IXPPCI_INTR_bit9 41
#define IXPPCI_INTR_bit8 40
#define IXPPCI_INTR_T4 39
#define IXPPCI_INTR_T3 38
#define IXPPCI_INTR_T2 37
#define IXPPCI_INTR_T1 36
#define IXPPCI_INTR_bit3 35
#define IXPPCI_INTR_bit2 34
#define IXPPCI_INTR_SI 33
#define IXPPCI_INTR_bit0 32
#endif /* _IXP12X0_PCIREG_H_ */

View File

@ -0,0 +1,265 @@
/* $NetBSD: ixp12x0reg.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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 _IXP12X0REG_H_
#define _IXP12X0REG_H_
/*
* Physical memory map for the Intel IXP12X0
*/
/*
* FFFF FFFF ---------------------------
* Device 6
* SDRAM
* FF00 0000 - FF00 0014
* SDRAM Control Register
* D000 0000 - DFFF FFFF
* Prefetch 256MB
* C000 0000 - CFFF FFFF
* non-Prefetch 256MB
* C000 0000 ---------------------------
* Device 5
* AMBA Translation (ATU)
* B000 0000 ---------------------------
* Device 4
* Reserved
* A000 0000 ---------------------------
* Device 3
* StrongARM Core System
* 9000 0000 ---------------------------
* Device 2
* Reserved
* 8000 0000 ---------------------------
* Device 1
* PCI UNIT
* 6000 0000 - 7FFF FFFF
* PCI Memory Cycle Access
* 5400 0000 - 5400 FFFF
* PCI I/O Cycle Access
* 5300 0000 - 53FF FFFF
* PCI Type0 Configuration Cycle Access
* 5200 0000 - 52FF FFFF
* PCI Type1 Configuration Cycle Access
* 4200 0000 - 4200 03FF
* Local PCI Configuration Space
* 4000 0000 ---------------------------
* Device 0
* SRAM UNIT
* 0000 0000 ---------------------------
*/
/*
* Virtual memory map for the Intel IXP12X0 integrated devices
*/
/*
* FFFF FFFF ---------------------------
*
* F002 1000 ---------------------------
* PCI Registers Accessible Through I/O
* VA F001 1000 == PA 5400 0000 (64kbyte)
* F001 1000 ---------------------------
* PCI Registers Accessible Through StrongARM Core
* VA F001 0000 == PA 4200 0000 (4kbyte)
* F001 0300 - F001 036F TIMER
* F001 0000 ---------------------------
* StrongARM System and Peripheral Registers
* VA F001 0000 == PA 9000 0000 (64kbyte)
* F000 3400 - F000 3C03 UART
* F000 3400 - F000 3C03 UART
* F000 2000 - F000 3003 RTC
* F000 1C00 - F000 1C03 GPIO_DATA
* F000 1800 - F000 1C03 GPIO
* F000 1400 - F000 1403 IRQ
* F000 1000 - F000 1003 FIQ
* F000 0C00 - F000 0C03 PLL_CFG
* F000 0000 ---------------------------
* Kernel text and data
* C000 0000 ---------------------------
* L2 tables for user process (XXX should be fixed)
* 6000 0000 ---------------------------
* PCI Registers Accessible Through Memory
* 5400 0000 ---------------------------
* PCI Type 0 Configuration Cycle Access
* VA 5400 0000 == PA 5400 0000
* 5300 0000 ---------------------------
* PCI Type 1 Configuration Cycle Access
* VA 5300 0000 == PA 5300 0000
* 5200 0000 ---------------------------
*
* 0000 0000 ---------------------------
*
*/
/* Virtual address for I/O space */
#define IXP12X0_IO_VBASE 0xf0000000
/* StrongARM System and Peripheral Registers */
#define IXP12X0_SYS_VBASE IXP12X0_IO_VBASE
/* va=0xf0000000 */
#define IXP12X0_SYS_HWBASE 0x90000000
#define IXP12X0_SYS_SIZE 0x00010000 /* 64Kbyte */
#define IXP12X0_PLL_CFG (IXP12X0_IO_VBASE + 0x0c00)
#define IXP12X0_PLL_CFG_CCF 0x1f
/* PCI Registers Accessible Through StrongARM Core */
#define IXP12X0_PCI_VBASE (IXP12X0_IO_VBASE + IXP12X0_SYS_SIZE)
/* va=0xf0010000 */
#define IXP12X0_PCI_HWBASE 0x42000000
#define IXP12X0_PCI_SIZE 0x00001000 /* 4Kbyte */
/* PCI I/O Memory Space */
#define IXP12X0_PCI_IO_VBASE (IXP12X0_PCI_VBASE + IXP12X0_PCI_SIZE)
/* va=0xf0011000 */
#define IXP12X0_PCI_IO_HWBASE 0x54000000
#define IXP12X0_PCI_IO_SIZE 0x00010000 /* 64Kbyte */
#define IXP12X0_PCI_MEM_VBASE 0x60000000 /* VA == PA */
#define IXP12X0_PCI_MEM_SIZE 0x20000000
/* PCI Type0/1 Configuration address */
#define IXP12X0_PCI_TYPEX_SIZE 0x01000000
#define IXP12X0_PCI_TYPE0_VBASE 0x53000000 /* VA == PA */
#define IXP12X0_PCI_TYPE1_VBASE 0x52000000
/*
* SlowPort I/O Register
*/
/* see. arch/evbarm/ixm1200/ixm1200reg.h */
/* Physical register base addresses */
/* #define IXP12X0_GPIO_VBASE */
#define IXP12X0_GPIO_HWBASE 0x90001800
#define IXP12X0_GPIO_SIZE 0x00000800
/* Interrupts */
#define IXP12X0_FIQ_VBASE (IXP12X0_IO_VBASE + 0x1000)
#define IXP12X0_FIQ_HWBASE 0x90001000
#define IXP12X0_FIQ_SIZE 0x00000004
#define IXP12X0_IRQ_VBASE (IXP12X0_IO_VBASE + 0x1400)
#define IXP12X0_IRQ_HWBASE 0x90001400
#define IXP12X0_IRQ_SIZE 0x00000004
/*
* Interrupt index assignment
*
*
* FIQ/IRQ bitmap in "StrongARM System and Peripheral Registers"
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* bit 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-------------------------------------------+-+-+-+-+-+-+-+---+
* |M| |U|S|R|S|U|C|P| |
* |B| |A|D|T|R|E|I|C| |
* |Z| RES |R|R|C|A|N|N|I|RES|
* | | |T|A| |M|G|T| | |
* | | | |M| | | | | | |
* +-+-------------------------------------------+-+-+-+-+-+-+-+---+
* 3
* index 1 8 7 6 5 4 3 2
*
*
* We Map a software interrupt queue index to the unused bits in the
* IRQ/FIQ registers. (in "StrongARM System and Peripheral Registers")
*
* XXX will need to revisit this if those bits are ever used in future
* steppings).
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* bit 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
* +-+-+-+-+-+-----------------------------------+-+-+-+-+-+-+-+---+
* |M|S|C|N|S| |U|S|R|S|U|C|P| |
* |B|O|L|E|E| |A|D|T|R|E|I|C| |
* |Z|F|O|T|R| RES |R|R|C|A|N|N|I|RES|
* | |T|C| |I| |T|A| |M|G|T| | |
* | | |K| |A| | |M| | | | | | |
* | | | | |L| | | | | | | | | |
* +-+-+-+-+-+-----------------------------------+-+-+-+-+-+-+-+---+
* 3 3 2 2 2
* index 1 0 9 8 7 8 7 6 5 4 3 2
*
*/
#define NIRQ 64
#define SYS_NIRQ 32
#define IXP12X0_INTR_MBZ 31
#define IXP12X0_INTR_bit30 30
#define IXP12X0_INTR_bit29 29
#define IXP12X0_INTR_bit28 28
#define IXP12X0_INTR_bit27 27
#define IXP12X0_INTR_bit26 26
#define IXP12X0_INTR_bit25 25
#define IXP12X0_INTR_bit24 24
#define IXP12X0_INTR_bit23 23
#define IXP12X0_INTR_bit22 22
#define IXP12X0_INTR_bit21 21
#define IXP12X0_INTR_bit20 20
#define IXP12X0_INTR_bit19 19
#define IXP12X0_INTR_bit18 18
#define IXP12X0_INTR_bit17 17
#define IXP12X0_INTR_bit16 16
#define IXP12X0_INTR_bit15 15
#define IXP12X0_INTR_bit14 14
#define IXP12X0_INTR_bit13 13
#define IXP12X0_INTR_bit12 12
#define IXP12X0_INTR_bit11 11
#define IXP12X0_INTR_bit10 10
#define IXP12X0_INTR_bit9 9
#define IXP12X0_INTR_UART 8
#define IXP12X0_INTR_SDRAM 7
#define IXP12X0_INTR_RTC 6
#define IXP12X0_INTR_SRAM 5
#define IXP12X0_INTR_UENG 4
#define IXP12X0_INTR_CINT 3
#define IXP12X0_INTR_PCI 2
#define IXP12X0_INTR_bit1 1
#define IXP12X0_INTR_bit0 0
#define IXP12X0_INTR_MASK \
((1U << IXP12X0_INTR_MBZ) \
| (1U << IXP12X0_INTR_UART) \
| (1U << IXP12X0_INTR_SDRAM) \
| (1U << IXP12X0_INTR_RTC) \
| (1U << IXP12X0_INTR_SRAM) \
| (1U << IXP12X0_INTR_UENG) \
| (1U << IXP12X0_INTR_CINT))
#endif /* _IXP12X0REG_H_ */

View File

@ -0,0 +1,111 @@
/* $NetBSD: ixp12x0var.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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 _IXP12X0VAR_H_
#define _IXP12X0VAR_H_
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/queue.h>
#include <machine/bus.h>
#include <dev/pci/pcivar.h>
#define IXPREG(reg) *((volatile u_int32_t*) (reg))
struct ixp12x0_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh; /* IRQ handle */
u_int32_t sc_intrmask;
/* Handles for the various subregions. */
bus_space_handle_t sc_pci_ioh;
/* I/O window vaddr */
/* PCI address */
/* Bus space, DMA, and PCI tags for the PCI bus */
struct bus_space ia_pci_iot;
struct bus_space ia_pci_memt;
struct arm32_bus_dma_tag ia_pci_dmat;
struct arm32_pci_chipset ia_pci_chipset;
/* GPIO */
};
struct intrhand {
TAILQ_ENTRY(intrhand) ih_list; /* link on intrq list */
int (*ih_func)(void *); /* interrupt handler */
void *ih_arg; /* arg for handler */
int ih_ipl; /* IPL_* */
int ih_irq; /* IRQ number */
};
#define IRQNAMESIZE sizeof("ixpintr ipl xxx")
struct intrq {
TAILQ_HEAD(, intrhand) iq_list; /* handler list */
struct evcnt iq_ev; /* event counter */
u_int32_t iq_mask; /* IRQs to mask while handling */
u_int32_t iq_pci_mask; /* PCI IRQs to mask while handling */
u_int32_t iq_levels; /* IPL_*'s this IRQ has */
char iq_name[IRQNAMESIZE]; /* interrupt name */
};
struct pmap_ent {
const char* msg;
vaddr_t va;
paddr_t pa;
vsize_t sz;
int prot;
int cache;
};
void ixp12x0_bs_init(bus_space_tag_t, void *);
void ixp12x0_io_bs_init(bus_space_tag_t, void *);
void ixp12x0_mem_bs_init(bus_space_tag_t, void *);
void ixp12x0_pci_init(pci_chipset_tag_t, void *);
void ixp12x0_pci_dma_init(bus_dma_tag_t, void *);
void ixp12x0_attach(struct ixp12x0_softc *);
void ixp12x0_intr_init(void);
void *ixp12x0_intr_establish(int irq, int ipl, int (*)(void *), void *);
void ixp12x0_intr_disestablish(void *);
void ixp12x0_pmap_chunk_table(vaddr_t l1pt, struct pmap_ent* m);
void ixp12x0_pmap_io_reg(vaddr_t l1pt);
#endif /* _IXP12X0VAR_H_ */

View File

@ -0,0 +1,117 @@
/* $NetBSD: ixpsip.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*/
/*
* Slow peripheral bus of ixp12x0 Processor
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
#include <arm/ixp12x0/ixpsipvar.h>
#include "locators.h"
static int ixpsip_match(struct device *, struct cfdata *, void *);
static void ixpsip_attach(struct device *, struct device *, void *);
static int ixpsip_search(struct device *, struct cfdata *, void *);
static int ixpsip_print(void *, const char *);
struct cfattach ixpsip_ca = {
sizeof(struct ixpsip_softc), ixpsip_match, ixpsip_attach,
};
extern struct bus_space ixpsip_bs_tag;
int
ixpsip_match(struct device *parent, struct cfdata *cf, void *aux)
{
return (1);
}
void
ixpsip_attach(struct device *parent, struct device *self, void *aux)
{
struct ixpsip_softc *sc = (void *) self;
sc->sc_iot = &ixpsip_bs_tag;
printf("\n");
/*
* Attach each devices
*/
config_search(ixpsip_search, self, NULL);
}
int
ixpsip_search(parent, cf, aux)
struct device *parent;
struct cfdata *cf;
void *aux;
{
struct ixpsip_softc *sc = (struct ixpsip_softc *)parent;
struct ixpsip_attach_args sa;
sa.sa_iot = sc->sc_iot;
sa.sa_addr = cf->cf_loc[IXPSIPCF_ADDR];
sa.sa_size = cf->cf_loc[IXPSIPCF_SIZE];
sa.sa_intr = cf->cf_loc[IXPSIPCF_INTR];
if ((*cf->cf_attach->ca_match)(parent, cf, &sa) > 0)
config_attach(parent, cf, &sa, ixpsip_print);
return (0);
}
static int
ixpsip_print(aux, name)
void *aux;
const char *name;
{
struct ixpsip_attach_args *sa = (struct ixpsip_attach_args*)aux;
if (sa->sa_size)
printf(" addr 0x%lx", sa->sa_addr);
if (sa->sa_size > 1)
printf("-0x%lx", sa->sa_addr + sa->sa_size - 1);
if (sa->sa_intr > 1)
printf(" intr %d", sa->sa_intr);
return (UNCONF);
}

View File

@ -0,0 +1,230 @@
/* $NetBSD: ixpsip_io.c,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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.
*/
/*
* bus_space I/O functions for ixp12x0
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/queue.h>
#include <uvm/uvm.h>
#include <machine/bus.h>
/* Proto types for all the bus_space structure functions */
bs_protos(ixpsip);
bs_protos(generic);
bs_protos(bs_notimpl);
struct bus_space ixpsip_bs_tag = {
/* cookie */
(void *) 0,
/* mapping/unmapping */
ixpsip_bs_map,
ixpsip_bs_unmap,
ixpsip_bs_subregion,
/* allocation/deallocation */
ixpsip_bs_alloc,
ixpsip_bs_free,
/* get kernel virtual address */
ixpsip_bs_vaddr,
/* mmap bus space for userland */
bs_notimpl_bs_mmap,
/* barrier */
ixpsip_bs_barrier,
/* read (single) */
generic_bs_r_1,
bs_notimpl_bs_r_2,
generic_bs_r_4,
bs_notimpl_bs_r_8,
/* read multiple */
generic_bs_rm_1,
bs_notimpl_bs_rm_2,
generic_bs_rm_4,
bs_notimpl_bs_rm_8,
/* read region */
bs_notimpl_bs_rr_1,
bs_notimpl_bs_rr_2,
generic_bs_rr_4,
bs_notimpl_bs_rr_8,
/* write (single) */
generic_bs_w_1,
bs_notimpl_bs_w_2,
generic_bs_w_4,
bs_notimpl_bs_w_8,
/* write multiple */
generic_bs_wm_1,
bs_notimpl_bs_wm_2,
generic_bs_wm_4,
bs_notimpl_bs_wm_8,
/* write region */
bs_notimpl_bs_wr_1,
bs_notimpl_bs_wr_2,
bs_notimpl_bs_wr_4,
bs_notimpl_bs_wr_8,
/* set multiple */
bs_notimpl_bs_sm_1,
bs_notimpl_bs_sm_2,
bs_notimpl_bs_sm_4,
bs_notimpl_bs_sm_8,
/* set region */
bs_notimpl_bs_sr_1,
bs_notimpl_bs_sr_2,
bs_notimpl_bs_sr_4,
bs_notimpl_bs_sr_8,
/* copy */
bs_notimpl_bs_c_1,
bs_notimpl_bs_c_2,
bs_notimpl_bs_c_4,
bs_notimpl_bs_c_8,
};
/* bus space functions */
int
ixpsip_bs_map(t, bpa, size, cacheable, bshp)
void *t;
bus_addr_t bpa;
bus_size_t size;
int cacheable;
bus_space_handle_t *bshp;
{
paddr_t pa, endpa;
vaddr_t va;
if (bpa > KERNEL_BASE) {
/* XXX This is a temporary hack to aid transition. */
*bshp = bpa;
return(0);
}
pa = trunc_page(bpa);
endpa = round_page(bpa + size);
/* XXX use extent manager to check duplicate mapping */
va = uvm_km_valloc(kernel_map, endpa - pa);
if (va == 0)
return(ENOMEM);
/* Store the bus space handle */
*bshp = va + (bpa & PAGE_MASK);
for(; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
pmap_enter(pmap_kernel(), va, pa,
VM_PROT_READ | VM_PROT_WRITE, PMAP_WIRED);
}
pmap_update(pmap_kernel());
return(0);
}
void
ixpsip_bs_unmap(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
/* Nothing to do. */
}
int
ixpsip_bs_alloc(t, rstart, rend, size, alignment, boundary, cacheable,
bpap, bshp)
void *t;
bus_addr_t rstart, rend;
bus_size_t size, alignment, boundary;
int cacheable;
bus_addr_t *bpap;
bus_space_handle_t *bshp;
{
panic("ixpsip_bs_alloc(): Help!\n");
}
void
ixpsip_bs_free(t, bsh, size)
void *t;
bus_space_handle_t bsh;
bus_size_t size;
{
panic("ixpsip_bs_free(): Help!\n");
}
int
ixpsip_bs_subregion(t, bsh, offset, size, nbshp)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, size;
bus_space_handle_t *nbshp;
{
*nbshp = bsh + offset;
return (0);
}
void *
ixpsip_bs_vaddr(t, bsh)
void *t;
bus_space_handle_t bsh;
{
return ((void *)bsh);
}
void
ixpsip_bs_barrier(t, bsh, offset, len, flags)
void *t;
bus_space_handle_t bsh;
bus_size_t offset, len;
int flags;
{
/* Nothing to do. */
}
/* End of ixpsip_io.c */

View File

@ -0,0 +1,57 @@
/* $NetBSD: ixpsipvar.h,v 1.1 2002/07/15 16:27:17 ichiro Exp $ */
/*
* Copyright (c) 2002
* Ichiro FUKUHARA <ichiro@ichiro.org>.
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Ichiro FUKUHARA.
* 4. The name of the company nor the name of the author may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``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 ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD 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 _IXPSIPVAR_H_
#define _IXPSIPVAR_H_
#include <sys/conf.h>
#include <sys/device.h>
#include <sys/queue.h>
#include <machine/bus.h>
struct ixpsip_softc {
struct device sc_dev;
bus_space_tag_t sc_iot;
bus_space_handle_t sc_ioh;
};
struct ixpsip_attach_args {
bus_space_tag_t sa_iot; /* Bus tag */
bus_addr_t sa_addr; /* i/o address */
bus_size_t sa_size;
int sa_intr;
};
#endif /* _IXPSIPVAR_H_ */