summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2010-02-12 08:14:03 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2010-02-12 08:14:03 +0000
commit366c630a0b1904abc330618f8cbb768c50cf6638 (patch)
tree98010acfa66515504957e4c476e0ee34dc79d103 /sys
parentb6d0a50e9558bc0e1b1d189cfcacb6422ff0cdfc (diff)
Overhaul per-platform specific operation by moving all the differences into
per-platform structs or function pointers; therefore bonito(4) no longer needs to know about particular systems. While there, bring little bits of Fuloong 2F support, tested on otto@'s machine.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/loongson/conf/GENERIC5
-rw-r--r--sys/arch/loongson/dev/bonito.c546
-rw-r--r--sys/arch/loongson/dev/bonitoreg.h3
-rw-r--r--sys/arch/loongson/dev/bonitovar.h8
-rw-r--r--sys/arch/loongson/include/autoconf.h29
-rw-r--r--sys/arch/loongson/loongson/gdium_machdep.c54
-rw-r--r--sys/arch/loongson/loongson/machdep.c65
-rw-r--r--sys/arch/loongson/loongson/wscons_machdep.c4
-rw-r--r--sys/arch/loongson/loongson/yeeloong_machdep.c76
9 files changed, 499 insertions, 291 deletions
diff --git a/sys/arch/loongson/conf/GENERIC b/sys/arch/loongson/conf/GENERIC
index dfc989dc8e6..27ba3c0085e 100644
--- a/sys/arch/loongson/conf/GENERIC
+++ b/sys/arch/loongson/conf/GENERIC
@@ -1,4 +1,4 @@
-# $OpenBSD: GENERIC,v 1.7 2010/02/09 12:15:37 jasper Exp $
+# $OpenBSD: GENERIC,v 1.8 2010/02/12 08:14:00 miod Exp $
#
# For further information on compiling OpenBSD kernels, see the config(8)
# man page.
@@ -43,6 +43,7 @@ pckbd* at pckbc?
wskbd* at pckbd? mux 1
pmsi* at pckbc?
wsmouse* at pmsi? mux 0
+com0 at isa? port 0x2f8 irq 3
pciide* at pci?
wd* at pciide? flags 0x0000
@@ -118,6 +119,7 @@ wsdisplay* at udl?
# NICs
ral* at pci?
+re* at pci?
rl* at pci?
# Media Independent Interface (mii) drivers
@@ -125,6 +127,7 @@ acphy* at mii? # Altima AC101 PHYs
amphy* at mii? # AMD 79C873 PHYs
bmtphy* at mii? # Broadcom 10/100 PHYs
eephy* at mii? # Marvell 88E1000 series PHY
+rgephy* at mii? # Realtek 8169S/8110S PHY
rlphy* at mii? # RealTek 8139 internal PHYs
urlphy* at mii? # Realtek RTL8150L internal PHY
ukphy* at mii? # "unknown" PHYs
diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c
index 2bb0e19e953..6762eec2025 100644
--- a/sys/arch/loongson/dev/bonito.c
+++ b/sys/arch/loongson/dev/bonito.c
@@ -1,9 +1,9 @@
-/* $OpenBSD: bonito.c,v 1.9 2010/02/10 21:09:40 miod Exp $ */
+/* $OpenBSD: bonito.c,v 1.10 2010/02/12 08:14:02 miod Exp $ */
/* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */
/* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */
/*
- * Copyright (c) 2009 Miodrag Vallat.
+ * Copyright (c) 2009, 2010 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -50,6 +50,10 @@
* PCI configuration space support for the Loongson PCI and memory controller
* chip, which is derived from the Algorithmics BONITO chip.
*/
+/*
+ * XXX The legacy interrupt scheme is entangled and as many parts as
+ * XXX possible should move to pcib.c...
+ */
#include <sys/param.h>
#include <sys/systm.h>
@@ -75,6 +79,10 @@
#include <loongson/dev/bonitovar.h>
#include <loongson/dev/bonito_irq.h>
+#if 0
+#define BONITO_DEBUG
+#endif
+
int bonito_match(struct device *, void *, void *);
void bonito_attach(struct device *, struct device *, void *);
@@ -113,18 +121,16 @@ void bonito_pci_intr_disestablish(void *, void *);
int bonito_conf_addr(const struct bonito_config *, pcitag_t, int,
u_int32_t *, u_int32_t *);
-uint bonito_get_isa_imr(void);
-uint bonito_get_isa_isr(void);
-void bonito_set_isa_imr(uint);
-void bonito_isa_specific_eoi(int);
-
-uint32_t bonito_isa_intr(uint32_t, struct trap_frame *);
-
void bonito_splx(int);
void bonito_setintrmask(int);
-void bonito_isa_splx(int);
-void bonito_isa_setintrmask(int);
+uint loongson_get_isa_imr(void);
+uint loongson_get_isa_isr(void);
+void loongson_set_isa_imr(uint);
+void loongson_isa_specific_eoi(int);
+uint32_t loongson_isa_intr(uint32_t, struct trap_frame *);
+void loongson_isa_splx(int);
+void loongson_isa_setintrmask(int);
/*
* Bonito interrupt handling declarations.
@@ -134,8 +140,7 @@ struct intrhand *bonito_intrhand[BONITO_NINTS];
uint64_t bonito_intem;
uint64_t bonito_imask[NIPLS];
-#define REGVAL8(x) *((volatile u_int8_t *)PHYS_TO_XKPHYS(x, CCA_NC))
-uint bonito_isaimr;
+uint loongson_isaimr;
struct machine_bus_dma_tag bonito_bus_dma_tag = {
._dmamap_create = _dmamap_create,
@@ -158,6 +163,9 @@ struct machine_bus_dma_tag bonito_bus_dma_tag = {
._device_to_pa = bonito_device_to_pa
};
+int bonito_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+
struct mips_bus_space bonito_pci_io_space_tag = {
.bus_base = PHYS_TO_XKPHYS(BONITO_PCIIO_BASE, CCA_NC),
._space_read_1 = generic_space_read_1,
@@ -174,7 +182,7 @@ struct mips_bus_space bonito_pci_io_space_tag = {
._space_write_raw_4 = generic_space_write_raw_4,
._space_read_raw_8 = generic_space_read_raw_8,
._space_write_raw_8 = generic_space_write_raw_8,
- ._space_map = generic_space_map,
+ ._space_map = bonito_io_map,
._space_unmap = generic_space_unmap,
._space_subregion = generic_space_region,
._space_vaddr = generic_space_vaddr
@@ -220,9 +228,7 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
struct pcibus_attach_args pba;
pci_chipset_tag_t pc = &sc->sc_pc;
const struct bonito_config *bc;
- struct extent *ioex, *memex;
uint32_t reg;
- int real_bonito;
/*
* Loongson 2F processors do not use a real Bonito64 chip but
@@ -232,12 +238,12 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
*/
if (curcpu()->ci_hw.type == MIPS_LOONGSON2 &&
(curcpu()->ci_hw.c0prid & 0xff) == 0x2f - 0x2c)
- real_bonito = 0;
+ sc->sc_compatible = 0;
else
- real_bonito = 1;
+ sc->sc_compatible = 1;
reg = PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG)));
- if (real_bonito) {
+ if (sc->sc_compatible) {
printf(": BONITO Memory and PCI controller, %s rev %d.%d\n",
BONITO_REV_FPGA(reg) ? "FPGA" : "ASIC",
BONITO_REV_MAJOR(reg), BONITO_REV_MINOR(reg));
@@ -246,26 +252,51 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG))));
}
- bc = sys_config.sys_bc;
+ bc = sys_platform->bonito_config;
sc->sc_bonito = bc;
SLIST_INIT(&sc->sc_hook);
+#ifdef BONITO_DEBUG
+ if (!sc->sc_compatible)
+ printf("ISR4C: %08x\n", REGVAL(BONITO_PCI_REG(0x4c)));
+ printf("PCIMAP: %08x\n", REGVAL(BONITO_PCIMAP));
+ printf("MEMWIN: %08x.%08x - %08x.%08x\n",
+ REGVAL(BONITO_MEM_WIN_BASE_H), REGVAL(BONITO_MEM_WIN_BASE_L),
+ REGVAL(BONITO_MEM_WIN_MASK_H), REGVAL(BONITO_MEM_WIN_MASK_L));
+ if (!sc->sc_compatible) {
+ printf("HITSEL0: %08x.%08x\n",
+ REGVAL(LOONGSON_PCI_HIT0_SEL_H),
+ REGVAL(LOONGSON_PCI_HIT0_SEL_L));
+ printf("HITSEL1: %08x.%08x\n",
+ REGVAL(LOONGSON_PCI_HIT1_SEL_H),
+ REGVAL(LOONGSON_PCI_HIT1_SEL_L));
+ printf("HITSEL2: %08x.%08x\n",
+ REGVAL(LOONGSON_PCI_HIT2_SEL_H),
+ REGVAL(LOONGSON_PCI_HIT2_SEL_L));
+ }
+ printf("PCI BAR 0:%08x 1:%08x 2:%08x 3:%08x 4:%08x 5:%08x\n",
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 0 * 4)),
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 1 * 4)),
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 2 * 4)),
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 3 * 4)),
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 4 * 4)),
+ REGVAL(BONITO_PCI_REG(PCI_MAPREG_START + 5 * 4)));
+#endif
+
/*
* Setup proper abitration.
*/
- if (!real_bonito) {
- if (sys_config.system_type == LOONGSON_YEELOONG) {
- /*
- * According to Linux, changing the value of this
- * undocumented register ``avoids deadlock of PCI
- * reading/writing lock operation''.
- * Is this really necessary, and if so, does it
- * matter on other designs?
- */
- REGVAL(BONITO_PCI_REG(0x4c)) = 0xd2000001;
- /* was c2000001 */
- }
+ if (!sc->sc_compatible) {
+ /*
+ * According to Linux, changing the value of this
+ * undocumented register ``avoids deadlock of PCI
+ * reading/writing lock operation''.
+ * Is this really necessary, and if so, does it
+ * matter on other designs?
+ */
+ /* c2000001 -> d2000001 */
+ REGVAL(BONITO_PCI_REG(0x4c)) |= 0x10000000;
/* all pci devices may need to hold the bus */
reg = REGVAL(LOONGSON_PXARB_CFG);
@@ -281,56 +312,21 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
REGVAL(BONITO_GPIOIE) = bc->bc_gpioIE;
REGVAL(BONITO_INTEDGE) = bc->bc_intEdge;
- if (real_bonito)
+ if (sc->sc_compatible)
REGVAL(BONITO_INTSTEER) = bc->bc_intSteer;
REGVAL(BONITO_INTPOL) = bc->bc_intPol;
REGVAL(BONITO_INTENCLR) = 0xffffffff;
(void)REGVAL(BONITO_INTENCLR);
- switch (sys_config.system_type) {
- case LOONGSON_YEELOONG:
+ if (bc->bc_legacy_pic) {
set_intr(INTPRI_BONITO, CR_INT_4, bonito_intr);
- set_intr(INTPRI_ISA, CR_INT_0, bonito_isa_intr);
- bonito_isaimr = bonito_get_isa_imr();
- register_splx_handler(bonito_isa_splx);
- break;
- case LOONGSON_GDIUM:
+ set_intr(INTPRI_ISA, CR_INT_0, loongson_isa_intr);
+ loongson_isaimr = loongson_get_isa_imr();
+ register_splx_handler(loongson_isa_splx);
+ } else {
set_intr(INTPRI_BONITO, CR_INT_4, bonito_intr);
register_splx_handler(bonito_splx);
- break;
- default:
- /* we should have died way earlier */
- panic("missing interrupt configuration code for this system");
- break;
- }
-
- /*
- * Setup PCI resource extents.
- */
-
- ioex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF, NULL, 0,
- EX_NOWAIT | EX_FILLED);
- if (ioex != NULL)
- (void)extent_free(ioex, 0, BONITO_PCIIO_SIZE, EX_NOWAIT);
-
- memex = extent_create("pcimem", 0, 0xffffffff, M_DEVBUF, NULL, 0,
- EX_NOWAIT | EX_FILLED);
- if (memex != NULL) {
- reg = REGVAL(BONITO_PCIMAP);
- (void)extent_free(memex, BONITO_PCIMAP_WINBASE((reg &
- BONITO_PCIMAP_PCIMAP_LO0) >> BONITO_PCIMAP_PCIMAP_LO0_SHIFT),
- BONITO_PCIMAP_WINSIZE, EX_NOWAIT);
- (void)extent_free(memex, BONITO_PCIMAP_WINBASE((reg &
- BONITO_PCIMAP_PCIMAP_LO1) >> BONITO_PCIMAP_PCIMAP_LO1_SHIFT),
- BONITO_PCIMAP_WINSIZE, EX_NOWAIT);
- (void)extent_free(memex, BONITO_PCIMAP_WINBASE((reg &
- BONITO_PCIMAP_PCIMAP_LO2) >> BONITO_PCIMAP_PCIMAP_LO2_SHIFT),
- BONITO_PCIMAP_WINSIZE, EX_NOWAIT);
-
- if (real_bonito) {
- /* XXX make PCIMAP_HI available if PCIMAP_2 set */
- }
}
/*
@@ -359,8 +355,10 @@ bonito_attach(struct device *parent, struct device *self, void *aux)
pba.pba_pc = pc;
pba.pba_domain = pci_ndomains++;
pba.pba_bus = 0;
- pba.pba_ioex = ioex;
- pba.pba_memex = memex;
+#ifdef notyet
+ pba.pba_ioex = bonito_get_resource_extent(pc, 1);
+ pba.pba_memex = bonito_get_resource_extent(pc, 0);
+#endif
config_found(&sc->sc_dev, &pba, bonito_print);
}
@@ -443,8 +441,7 @@ bonito_intr_disestablish(void *ih)
}
/*
- * Update interrupt masks. Two set of routines: one when ISA interrupts
- * are involved, one without.
+ * Update interrupt masks. This is for designs without legacy PIC.
*/
void
@@ -463,21 +460,6 @@ bonito_splx(int newipl)
}
void
-bonito_isa_splx(int newipl)
-{
- struct cpu_info *ci = curcpu();
-
- /* Update masks to new ipl. Order highly important! */
- __asm__ (".set noreorder\n");
- ci->ci_ipl = newipl;
- __asm__ ("sync\n\t.set reorder\n");
- bonito_isa_setintrmask(newipl);
- /* If we still have softints pending trigger processing. */
- if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
- setsoftintr0();
-}
-
-void
bonito_setintrmask(int level)
{
uint64_t active;
@@ -500,30 +482,6 @@ bonito_setintrmask(int level)
setsr(sr);
}
-void
-bonito_isa_setintrmask(int level)
-{
- uint64_t active;
- uint32_t clear, set;
- uint32_t sr;
-
- active = bonito_intem & ~bonito_imask[level];
- clear = BONITO_DIRECT_MASK(bonito_imask[level]);
- set = BONITO_DIRECT_MASK(active);
-
- sr = disableintr();
-
- if (clear != 0)
- REGVAL(BONITO_INTENCLR) = clear;
- if (set != 0)
- REGVAL(BONITO_INTENSET) = set;
- (void)REGVAL(BONITO_INTENSET);
-
- bonito_set_isa_imr(BONITO_ISA_MASK(active));
-
- setsr(sr);
-}
-
/*
* Recompute interrupt masks.
*/
@@ -576,7 +534,7 @@ bonito_intr_makemasks()
}
/*
- * Process direct interrupts
+ * Process native interrupts
*/
uint32_t
@@ -660,101 +618,6 @@ done:
}
/*
- * Process ISA interrupts.
- *
- * XXX ISA interrupts only occur on LOONGSON_INTR_INT0, but since the other
- * XXX LOONGSON_INTR_INT# are unmaskable, bad things will happen if they
- * XXX are triggered...
- */
-
-/*
- * Interrupt dispatcher.
- */
-uint32_t
-bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame)
-{
- uint64_t imr, isr, mask;
- int bit;
- struct intrhand *ih;
- int rc;
-
- isr = bonito_get_isa_isr();
- imr = bonito_get_isa_imr();
-
- isr &= imr;
- isr &= ~(1 << 2); /* cascade */
-#ifdef DEBUG
- printf("isa interrupt: imr %04x isr %04x\n", imr, isr);
-#endif
- if (isr == 0)
- return 0; /* not for us */
-
- /*
- * Mask all pending interrupts.
- */
-
- bonito_set_isa_imr(imr & ~isr);
-
- /*
- * If interrupts are spl-masked, mask them and wait for splx()
- * to reenable them when necessary.
- */
- if ((mask = isr & (BONITO_ISA_MASK(bonito_imask[frame->ipl]))) != 0) {
- isr &= ~mask;
- imr &= ~mask;
- }
-
- /*
- * Now process allowed interrupts.
- */
- if (isr != 0) {
- int lvl, bitno;
- uint64_t tmpisr;
-
- /* Service higher level interrupts first */
- bit = BONITO_NISA - 1;
- for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) {
- tmpisr = isr & BONITO_ISA_MASK(bonito_imask[lvl] ^
- bonito_imask[lvl - 1]);
- if (tmpisr == 0)
- continue;
- for (bitno = bit, mask = 1UL << bitno; mask != 0;
- bitno--, mask >>= 1) {
- if ((tmpisr & mask) == 0)
- continue;
-
- rc = 0;
- for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)];
- ih != NULL; ih = ih->ih_next) {
- if ((*ih->ih_fun)(ih->ih_arg) != 0) {
- rc = 1;
- ih->ih_count.ec_count++;
- }
- }
- if (rc == 0)
- printf("spurious isa interrupt %d\n",
- bitno);
-
- bonito_isa_specific_eoi(bitno);
-
- if ((isr ^= mask) == 0)
- goto done;
- if ((tmpisr ^= mask) == 0)
- break;
- }
- }
-done:
-
- /*
- * Reenable interrupts which have been serviced.
- */
- bonito_set_isa_imr(imr);
- }
-
- return hwpend;
-}
-
-/*
* various PCI helpers
*/
@@ -1018,11 +881,108 @@ bonito_pci_intr_disestablish(void *cookie, void *ihp)
}
/*
- * ISA Interrupt handling
+ * Legacy (ISA) interrupt handling
*/
+/*
+ * Process legacy interrupts.
+ *
+ * XXX ISA interrupts only occur on LOONGSON_INTR_INT0, but since the other
+ * XXX LOONGSON_INTR_INT# are unmaskable, bad things will happen if they
+ * XXX are triggered...
+ */
+
+/*
+ * Interrupt dispatcher.
+ */
+uint32_t
+loongson_isa_intr(uint32_t hwpend, struct trap_frame *frame)
+{
+ uint64_t imr, isr, mask;
+ int bit;
+ struct intrhand *ih;
+ int rc;
+
+ isr = loongson_get_isa_isr();
+ imr = loongson_get_isa_imr();
+
+ isr &= imr;
+ isr &= ~(1 << 2); /* cascade */
+#ifdef DEBUG
+ printf("isa interrupt: imr %04x isr %04x\n", imr, isr);
+#endif
+ if (isr == 0)
+ return 0; /* not for us */
+
+ /*
+ * Mask all pending interrupts.
+ */
+
+ loongson_set_isa_imr(imr & ~isr);
+
+ /*
+ * If interrupts are spl-masked, mask them and wait for splx()
+ * to reenable them when necessary.
+ */
+ if ((mask = isr & (BONITO_ISA_MASK(bonito_imask[frame->ipl]))) != 0) {
+ isr &= ~mask;
+ imr &= ~mask;
+ }
+
+ /*
+ * Now process allowed interrupts.
+ */
+ if (isr != 0) {
+ int lvl, bitno;
+ uint64_t tmpisr;
+
+ /* Service higher level interrupts first */
+ bit = BONITO_NISA - 1;
+ for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) {
+ tmpisr = isr & BONITO_ISA_MASK(bonito_imask[lvl] ^
+ bonito_imask[lvl - 1]);
+ if (tmpisr == 0)
+ continue;
+ for (bitno = bit, mask = 1UL << bitno; mask != 0;
+ bitno--, mask >>= 1) {
+ if ((tmpisr & mask) == 0)
+ continue;
+
+ rc = 0;
+ for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)];
+ ih != NULL; ih = ih->ih_next) {
+ if ((*ih->ih_fun)(ih->ih_arg) != 0) {
+ rc = 1;
+ ih->ih_count.ec_count++;
+ }
+ }
+ if (rc == 0)
+ printf("spurious isa interrupt %d\n",
+ bitno);
+
+ loongson_isa_specific_eoi(bitno);
+
+ if ((isr ^= mask) == 0)
+ goto done;
+ if ((tmpisr ^= mask) == 0)
+ break;
+ }
+ }
+done:
+
+ /*
+ * Reenable interrupts which have been serviced.
+ */
+ loongson_set_isa_imr(imr);
+ }
+
+ return hwpend;
+}
+
+#define REGVAL8(x) *((volatile u_int8_t *)PHYS_TO_XKPHYS(x, CCA_NC))
+
uint
-bonito_get_isa_imr()
+loongson_get_isa_imr()
{
uint imr1, imr2;
@@ -1034,7 +994,7 @@ bonito_get_isa_imr()
}
uint
-bonito_get_isa_isr()
+loongson_get_isa_isr()
{
uint isr1, isr2;
@@ -1045,7 +1005,7 @@ bonito_get_isa_isr()
}
void
-bonito_set_isa_imr(uint newimr)
+loongson_set_isa_imr(uint newimr)
{
uint imr1, imr2;
@@ -1059,19 +1019,19 @@ bonito_set_isa_imr(uint newimr)
* this if the value changes.
* Note that interrupts have been disabled by the caller.
*/
- if ((newimr ^ bonito_isaimr) & 0xff00) {
+ if ((newimr ^ loongson_isaimr) & 0xff00) {
REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 1) = imr2;
(void)REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 1);
}
- if ((newimr ^ bonito_isaimr) & 0x00ff) {
+ if ((newimr ^ loongson_isaimr) & 0x00ff) {
REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + 1) = imr1;
(void)REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + 1);
}
- bonito_isaimr = newimr;
+ loongson_isaimr = newimr;
}
void
-bonito_isa_specific_eoi(int bit)
+loongson_isa_specific_eoi(int bit)
{
if (bit & 8) {
REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 0) = 0x60 | (bit & 7);
@@ -1082,6 +1042,49 @@ bonito_isa_specific_eoi(int bit)
(void)REGVAL8(BONITO_PCIIO_BASE + IO_ICU1 + 0);
}
+/*
+ * Update interrupt masks. This is for designs with legacy PIC.
+ */
+
+void
+loongson_isa_splx(int newipl)
+{
+ struct cpu_info *ci = curcpu();
+
+ /* Update masks to new ipl. Order highly important! */
+ __asm__ (".set noreorder\n");
+ ci->ci_ipl = newipl;
+ __asm__ ("sync\n\t.set reorder\n");
+ loongson_isa_setintrmask(newipl);
+ /* If we still have softints pending trigger processing. */
+ if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
+ setsoftintr0();
+}
+
+void
+loongson_isa_setintrmask(int level)
+{
+ uint64_t active;
+ uint32_t clear, set;
+ uint32_t sr;
+
+ active = bonito_intem & ~bonito_imask[level];
+ clear = BONITO_DIRECT_MASK(bonito_imask[level]);
+ set = BONITO_DIRECT_MASK(active);
+
+ sr = disableintr();
+
+ if (clear != 0)
+ REGVAL(BONITO_INTENCLR) = clear;
+ if (set != 0)
+ REGVAL(BONITO_INTENSET) = set;
+ (void)REGVAL(BONITO_INTENSET);
+
+ loongson_set_isa_imr(BONITO_ISA_MASK(active));
+
+ setsr(sr);
+}
+
void
isa_attach_hook(struct device *parent, struct device *self,
struct isabus_attach_args *iba)
@@ -1103,6 +1106,107 @@ isa_intr_disestablish(void *v, void *ih)
}
/*
+ * Legacy I/O access protection.
+ * Since MI ISA code does not expect bus access to cause any failure when
+ * accessing missing hardware, but only receive bogus data in return, we
+ * force bus_space_map() to fail if there is no hardware there.
+ */
+
+int
+bonito_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
+ bus_space_handle_t *bshp)
+{
+ const struct legacy_io_range *r;
+
+ if (offs < BONITO_PCIIO_LEGACY) {
+ size--;
+ for (r = sys_platform->legacy_io_ranges; r->start != 0; r++)
+ if (offs >= r->start && offs + size <= r->end)
+ break;
+
+ if (r->start == 0)
+ return ENXIO;
+ }
+
+ *bshp = t->bus_base + offs;
+ return 0;
+}
+
+/*
+ * PCI resource handling
+ */
+
+struct extent *
+bonito_get_resource_extent(pci_chipset_tag_t pc, int io)
+{
+ struct bonito_softc *sc = pc->pc_conf_v;
+ struct extent *ex;
+ char *exname;
+ size_t exnamesz;
+ uint32_t reg;
+ int errors;
+
+ exnamesz = 1 + 16 + 4;
+ exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT);
+ if (exname == NULL)
+ return NULL;
+ snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
+ io ? "_io" : "_mem");
+
+ ex = extent_create(exname, 0, 0xffffffff, M_DEVBUF, NULL, 0,
+ EX_NOWAIT | EX_FILLED);
+ if (ex == NULL)
+ goto out;
+
+ errors = 0;
+ if (io) {
+ /*
+ * Reserve the low 16KB of I/O space to the legacy hardware,
+ * if any.
+ */
+ if (extent_free(ex, BONITO_PCIIO_LEGACY, BONITO_PCIIO_SIZE,
+ EX_NOWAIT) != 0)
+ errors++;
+ } else {
+ reg = REGVAL(BONITO_PCIMAP);
+ if (extent_free(ex,
+ BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO0) >>
+ BONITO_PCIMAP_PCIMAP_LO0_SHIFT),
+ BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
+ errors++;
+ if (extent_free(ex,
+ BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO1) >>
+ BONITO_PCIMAP_PCIMAP_LO1_SHIFT),
+ BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
+ errors++;
+ if (extent_free(ex,
+ BONITO_PCIMAP_WINBASE((reg & BONITO_PCIMAP_PCIMAP_LO2) >>
+ BONITO_PCIMAP_PCIMAP_LO2_SHIFT),
+ BONITO_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
+ errors++;
+
+ if (sc->sc_compatible) {
+ /* XXX make PCIMAP_HI available if PCIMAP_2 set */
+ }
+ }
+
+ if (errors != 0) {
+ extent_destroy(ex);
+ ex = NULL;
+ }
+
+#ifdef BONITO_DEBUG
+ extent_print(ex);
+#endif
+
+out:
+ if (exname != NULL)
+ free(exname, M_DEVBUF);
+
+ return ex;
+}
+
+/*
* Functions used during early system configuration (before bonito attaches).
*/
@@ -1115,5 +1219,5 @@ pci_make_tag_early(int b, int d, int f)
pcireg_t
pci_conf_read_early(pcitag_t tag, int reg)
{
- return bonito_conf_read_internal(sys_config.sys_bc, tag, reg);
+ return bonito_conf_read_internal(sys_platform->bonito_config, tag, reg);
}
diff --git a/sys/arch/loongson/dev/bonitoreg.h b/sys/arch/loongson/dev/bonitoreg.h
index 23b5097cc18..99c3f7f0ed2 100644
--- a/sys/arch/loongson/dev/bonitoreg.h
+++ b/sys/arch/loongson/dev/bonitoreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonitoreg.h,v 1.3 2010/02/05 20:51:22 miod Exp $ */
+/* $OpenBSD: bonitoreg.h,v 1.4 2010/02/12 08:14:02 miod Exp $ */
/* $NetBSD: bonitoreg.h,v 1.6 2005/12/24 20:07:19 perry Exp $ */
/*
@@ -55,6 +55,7 @@
#define BONITO_PCIHI_SIZE 0x20000000
#define BONITO_PCIHI_TOP (BONITO_PCIHI_BASE+BONITO_PCIHI_SIZE-1)
#define BONITO_PCIIO_BASE 0x1fd00000
+#define BONITO_PCIIO_LEGACY 0x00004000
#define BONITO_PCIIO_SIZE 0x00100000
#define BONITO_PCIIO_TOP (BONITO_PCIIO_BASE+BONITO_PCIIO_SIZE-1)
#define BONITO_PCICFG_BASE 0x1fe80000
diff --git a/sys/arch/loongson/dev/bonitovar.h b/sys/arch/loongson/dev/bonitovar.h
index 400d8ccfcc8..1d181be1c77 100644
--- a/sys/arch/loongson/dev/bonitovar.h
+++ b/sys/arch/loongson/dev/bonitovar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bonitovar.h,v 1.3 2010/02/09 21:31:46 miod Exp $ */
+/* $OpenBSD: bonitovar.h,v 1.4 2010/02/12 08:14:02 miod Exp $ */
/* $NetBSD: bonitovar.h,v 1.4 2008/04/28 20:23:28 martin Exp $ */
/*-
@@ -36,6 +36,7 @@
#include <dev/pci/pcivar.h>
struct bonito_cfg_hook;
+struct extent;
struct bonito_config {
int bc_adbase; /* AD line base for config access */
@@ -46,6 +47,8 @@ struct bonito_config {
uint32_t bc_intSteer;
uint32_t bc_intPol;
+ int bc_legacy_pic; /* nonzero if legacy PIC */
+
/* PCI Attach hook for the first bus */
void (*bc_attach_hook)(pci_chipset_tag_t);
@@ -55,6 +58,7 @@ struct bonito_config {
struct bonito_softc {
struct device sc_dev;
+ int sc_compatible; /* real Bonito hw */
const struct bonito_config *sc_bonito;
struct mips_pci_chipset sc_pc;
@@ -70,6 +74,8 @@ int bonito_pci_hook(pci_chipset_tag_t, void *,
int (*)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t *),
int (*)(void *, pci_chipset_tag_t, pcitag_t, int, pcireg_t));
int bonito_print(void *, const char *);
+struct extent
+ *bonito_get_resource_extent(pci_chipset_tag_t, int);
#endif /* _KERNEL */
#endif /* _LOONGSON_DEV_BONITOVAR_H_ */
diff --git a/sys/arch/loongson/include/autoconf.h b/sys/arch/loongson/include/autoconf.h
index ae1fe1e7d43..93a91e7d303 100644
--- a/sys/arch/loongson/include/autoconf.h
+++ b/sys/arch/loongson/include/autoconf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.h,v 1.3 2010/02/05 20:51:22 miod Exp $ */
+/* $OpenBSD: autoconf.h,v 1.4 2010/02/12 08:14:02 miod Exp $ */
/*
* Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -38,24 +38,33 @@
struct bonito_config;
/*
- * Structure holding all misc config information.
+ * List of legacy I/O ranges.
*/
-struct sys_rec {
- int system_type;
+struct legacy_io_range {
+ bus_addr_t start;
+ bus_size_t end; /* inclusive */
+};
+
+/*
+ * Per platform information.
+ */
+struct platform {
+ int system_type;
+ char *vendor;
+ char *product;
+
+ const struct bonito_config *bonito_config;
+ const struct legacy_io_range *legacy_io_ranges;
- /* Bonito configuration */
- const struct bonito_config *sys_bc;
+ void (*powerdown)(void);
};
-extern struct sys_rec sys_config;
+extern const struct platform *sys_platform;
struct mainbus_attach_args {
const char *maa_name;
};
-extern const struct bonito_config gdium_bonito;
-extern const struct bonito_config yeeloong_bonito;
-
#include <mips64/autoconf.h>
#endif /* _MACHINE_AUTOCONF_H_ */
diff --git a/sys/arch/loongson/loongson/gdium_machdep.c b/sys/arch/loongson/loongson/gdium_machdep.c
index dfd1355def7..84a5fdd4245 100644
--- a/sys/arch/loongson/loongson/gdium_machdep.c
+++ b/sys/arch/loongson/loongson/gdium_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gdium_machdep.c,v 1.2 2010/02/09 21:31:47 miod Exp $ */
+/* $OpenBSD: gdium_machdep.c,v 1.3 2010/02/12 08:14:02 miod Exp $ */
/*
* Copyright (c) 2010 Miodrag Vallat.
@@ -24,11 +24,13 @@
#include <sys/systm.h>
#include <sys/device.h>
+#include <mips64/archtype.h>
#include <machine/autoconf.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
+#include <loongson/dev/bonitoreg.h>
#include <loongson/dev/bonitovar.h>
#include <loongson/dev/bonito_irq.h>
@@ -36,6 +38,7 @@ int gdium_revision = 0;
void gdium_attach_hook(pci_chipset_tag_t);
int gdium_intr_map(int, int, int);
+void gdium_powerdown(void);
const struct bonito_config gdium_bonito = {
.bc_adbase = 11,
@@ -47,52 +50,76 @@ const struct bonito_config gdium_bonito = {
.bc_intPol = LOONGSON_INTRMASK_DRAM_PARERR |
LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR,
+ .bc_legacy_pic = 0,
+
.bc_attach_hook = gdium_attach_hook,
.bc_intr_map = gdium_intr_map
};
+const struct platform gdium_platform = {
+ .system_type = LOONGSON_GDIUM,
+ .vendor = "EMTEC",
+ .product = "Gdium",
+
+ .bonito_config = &gdium_bonito,
+ .legacy_io_ranges = NULL,
+
+ .powerdown = gdium_powerdown
+};
+
void
gdium_attach_hook(pci_chipset_tag_t pc)
{
pcireg_t id;
pcitag_t tag;
+#ifdef notyet
int bar;
+#endif
#if 0
pcireg_t reg;
int dev, func;
#endif
+#ifdef notyet
/*
* Clear all BAR of the mini PCI slot; PMON did not initialize
* it, and we do not want it to conflict with anything.
*/
-
tag = pci_make_tag(pc, 0, 13, 0);
for (bar = PCI_MAPREG_START; bar < PCI_MAPREG_END; bar += 4)
pci_conf_write(pc, tag, bar, 0);
+#else
+ /*
+ * Force a non conflicting BAR for the wireless controller,
+ * until proper resource configuration code is added to
+ * bonito (work in progress).
+ * XXX The card does not work correctly anyway at the moment.
+ */
+ tag = pci_make_tag(pc, 0, 13, 0);
+ pci_conf_write(pc, tag, PCI_MAPREG_START, 0x06228000);
+#endif
/*
* Figure out which motherboard we are running on.
* Might not be good enough...
*/
-
tag = pci_make_tag(pc, 0, 17, 0);
id = pci_conf_read(pc, tag, PCI_ID_REG);
if (id == PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB))
gdium_revision = 1;
-#if 0 /* XXX Linux does this... but this causes enumeration to fail */
+#if 0
/*
* Tweak the usb controller capabilities.
*/
-
for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) {
tag = pci_make_tag(pc, 0, dev, 0);
id = pci_conf_read(pc, tag, PCI_ID_REG);
if (id != PCI_ID_CODE(PCI_VENDOR_NEC, PCI_PRODUCT_NEC_USB))
continue;
- if (gdium_revision == 0) {
+ if (gdium_revision != 0) {
reg = pci_conf_read(pc, tag, 0xe0);
+ /* enable ports 1 and 2 */
reg |= 0x00000003;
pci_conf_write(pc, tag, 0xe0, reg);
} else {
@@ -105,16 +132,12 @@ gdium_attach_hook(pci_chipset_tag_t pc)
PCI_PRODUCT(id) != PCI_PRODUCT_NEC_USB2)
continue;
- /* 0114331f -> 0114331d */
reg = pci_conf_read(pc, tag, 0xe0);
+ /* enable ports 1 and 3, disable port 2 */
reg &= ~0x00000007;
reg |= 0x00000005;
pci_conf_write(pc, tag, 0xe0, reg);
-
- /* 00006c42 -> 00006c62 */
- reg = pci_conf_read(pc, tag, 0xe4);
- reg |= 0x00000020;
- pci_conf_write(pc, tag, 0xe4, reg);
+ pci_conf_write(pc, tag, 0xe4, 0x00000020);
}
}
}
@@ -153,3 +176,10 @@ gdium_intr_map(int dev, int fn, int pin)
return -1;
}
+
+void
+gdium_powerdown()
+{
+ REGVAL(BONITO_GPIODATA) |= 0x00000002;
+ REGVAL(BONITO_GPIOIE) &= ~0x00000002;
+}
diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c
index cb2363a1170..892a64aca88 100644
--- a/sys/arch/loongson/loongson/machdep.c
+++ b/sys/arch/loongson/loongson/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.11 2010/02/09 21:30:11 miod Exp $ */
+/* $OpenBSD: machdep.c,v 1.12 2010/02/12 08:14:02 miod Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -108,7 +108,7 @@ int ncpu = 1; /* At least one CPU in the system. */
struct user *proc0paddr;
int kbd_reset;
-struct sys_rec sys_config;
+const struct platform *sys_platform;
struct cpu_hwinfo bootcpu_hwinfo;
/* Pointers to the start and end of the symbol table. */
@@ -150,18 +150,23 @@ struct consdev pmoncons = {
struct bonito_flavour {
const char *prefix;
- int systype;
- const struct bonito_config *bc;
+ const struct platform *platform;
};
+extern const struct platform fuloong_platform;
+extern const struct platform gdium_platform;
+extern const struct platform yeeloong_platform;
+
const struct bonito_flavour bonito_flavours[] = {
- /* 8.9" Lemote Yeeloong netbook */
- { "LM8089", LOONGSON_YEELOONG, &yeeloong_bonito },
- /* supposedly 10.1" Lemote Yeeloong netbook, but those found so far
- report themselves as LM8089 */
- { "LM8101", LOONGSON_YEELOONG, &yeeloong_bonito },
+ /* Lemote Fuloong 2F mini-PC */
+ { "LM6004", &fuloong_platform },
/* EMTEC Gdium Liberty 1000 */
- { "Gdium", LOONGSON_GDIUM, &gdium_bonito },
+ { "Gdium", &gdium_platform },
+ /* Lemote Yeeloong 8.9" netbook */
+ { "LM8089", &yeeloong_platform },
+ /* supposedly Lemote Yeeloong 10.1" netbook, but those found so far
+ report themselves as LM8089 */
+ { "LM8101", &yeeloong_platform },
{ NULL }
};
@@ -267,30 +272,18 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv)
for (f = bonito_flavours; f->prefix != NULL; f++)
if (strncmp(envvar, f->prefix, strlen(f->prefix)) == 0) {
- sys_config.system_type = f->systype;
- sys_config.sys_bc = f->bc;
+ sys_platform = f->platform;
break;
}
- if (sys_config.system_type == 0) {
+ if (sys_platform == NULL) {
pmon_printf("This kernel doesn't support model \"%s\".\n",
envvar);
goto unsupported;
}
- switch (sys_config.system_type) {
- case LOONGSON_YEELOONG:
- hw_vendor = "Lemote";
- hw_prod = "Yeeloong";
- break;
- case LOONGSON_GDIUM:
- hw_vendor = "EMTEC";
- hw_prod = "Gdium";
- break;
- default: /* won't happen */
- goto unsupported;
- }
-
+ hw_vendor = sys_platform->vendor;
+ hw_prod = sys_platform->product;
pmon_printf("Found %s %s, setting up.\n", hw_vendor, hw_prod);
snprintf(cpu_model, sizeof cpu_model, "Loongson %X", loongson_ver);
@@ -424,8 +417,6 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv)
/*
* Configure cache.
- * Note that the caches being physically tagged, there is no
- * need to invalidate or flush it.
*/
Loongson2_ConfigCache(curcpu());
@@ -823,18 +814,12 @@ haltsys:
if (howto & RB_HALT) {
if (howto & RB_POWERDOWN) {
- printf("System Power Down.\n");
- switch (sys_config.system_type) {
- case LOONGSON_YEELOONG:
- REGVAL(BONITO_GPIODATA) &= ~0x00000001;
- REGVAL(BONITO_GPIOIE) &= ~0x00000001;
- break;
- case LOONGSON_GDIUM:
- REGVAL(BONITO_GPIODATA) |= 0x00000002;
- REGVAL(BONITO_GPIOIE) &= ~0x00000002;
- break;
- default:
- break;
+ if (sys_platform->powerdown != NULL) {
+ printf("System Power Down.\n");
+ (*(sys_platform->powerdown))();
+ } else {
+ printf("System Power Down not supported,"
+ " halting system.\n");
}
} else
printf("System Halt.\n");
diff --git a/sys/arch/loongson/loongson/wscons_machdep.c b/sys/arch/loongson/loongson/wscons_machdep.c
index 50b3a613748..a8187830b92 100644
--- a/sys/arch/loongson/loongson/wscons_machdep.c
+++ b/sys/arch/loongson/loongson/wscons_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_machdep.c,v 1.3 2010/02/11 20:15:29 otto Exp $ */
+/* $OpenBSD: wscons_machdep.c,v 1.4 2010/02/12 08:14:02 miod Exp $ */
/*
* Copyright (c) 2010 Miodrag Vallat.
@@ -157,7 +157,7 @@ setup_kbd:
rc = ENXIO;
#if NPCKBC > 0
- switch (sys_config.system_type) {
+ switch (sys_platform->system_type) {
default:
/* no pckbc or no legacy hardware */
break;
diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c
index b70383a63bb..786eb58593d 100644
--- a/sys/arch/loongson/loongson/yeeloong_machdep.c
+++ b/sys/arch/loongson/loongson/yeeloong_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: yeeloong_machdep.c,v 1.2 2010/02/09 21:31:47 miod Exp $ */
+/* $OpenBSD: yeeloong_machdep.c,v 1.3 2010/02/12 08:14:02 miod Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -17,18 +17,22 @@
*/
/*
- * Lemote Yeeloong specific code and configuration data.
+ * Lemote Fuloong 2F and Yeeloong specific code and configuration data.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <mips64/archtype.h>
#include <machine/autoconf.h>
+#include <dev/isa/isareg.h>
+
#include <dev/pci/pcireg.h>
#include <dev/pci/pcidevs.h>
+#include <loongson/dev/bonitoreg.h>
#include <loongson/dev/bonitovar.h>
#include <loongson/dev/bonito_irq.h>
#include <loongson/dev/glxvar.h>
@@ -36,6 +40,8 @@
void yeeloong_attach_hook(pci_chipset_tag_t);
int yeeloong_intr_map(int, int, int);
+void yeeloong_powerdown(void);
+
const struct bonito_config yeeloong_bonito = {
.bc_adbase = 11,
@@ -47,10 +53,67 @@ const struct bonito_config yeeloong_bonito = {
LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR |
LOONGSON_INTRMASK_INT0 | LOONGSON_INTRMASK_INT1,
+ .bc_legacy_pic = 1,
+
.bc_attach_hook = yeeloong_attach_hook,
.bc_intr_map = yeeloong_intr_map
};
+const struct legacy_io_range fuloong_legacy_ranges[] = {
+ /* isa */
+ { IO_DMAPG + 4, IO_DMAPG + 4 },
+ /* mcclock */
+ { IO_RTC, IO_RTC + 1 },
+ /* pciide */
+ { 0x170, 0x170 + 7 },
+ { 0x1f0, 0x1f0 + 7 },
+ { 0x376, 0x376 },
+ { 0x3f6, 0x3f6 },
+ /* com */
+ { IO_COM2, IO_COM2 + 8 },
+
+ { 0 }
+};
+
+const struct legacy_io_range yeeloong_legacy_ranges[] = {
+ /* isa */
+ { IO_DMAPG + 4, IO_DMAPG + 4 },
+ /* pckbc */
+ { IO_KBD, IO_KBD },
+ { IO_KBD + 4, IO_KBD + 4 },
+ /* mcclock */
+ { IO_RTC, IO_RTC + 1 },
+ /* pciide */
+ { 0x170, 0x170 + 7 },
+ { 0x1f0, 0x1f0 + 7 },
+ { 0x376, 0x376 },
+ { 0x3f6, 0x3f6 },
+
+ { 0 }
+};
+
+const struct platform fuloong_platform = {
+ .system_type = LOONGSON_FULOONG,
+ .vendor = "Lemote",
+ .product = "Fuloong",
+
+ .bonito_config = &yeeloong_bonito,
+ .legacy_io_ranges = fuloong_legacy_ranges,
+
+ .powerdown = NULL /* XXX TBD */
+};
+
+const struct platform yeeloong_platform = {
+ .system_type = LOONGSON_YEELOONG,
+ .vendor = "Lemote",
+ .product = "Yeeloong",
+
+ .bonito_config = &yeeloong_bonito,
+ .legacy_io_ranges = yeeloong_legacy_ranges,
+
+ .powerdown = yeeloong_powerdown
+};
+
void
yeeloong_attach_hook(pci_chipset_tag_t pc)
{
@@ -96,7 +159,7 @@ yeeloong_intr_map(int dev, int fn, int pin)
switch (fn) {
case 1: /* Flash */
return BONITO_ISA_IRQ(6);
- case 2: /* AC97 */
+ case 3: /* AC97 */
return BONITO_ISA_IRQ(9);
case 4: /* OHCI */
case 5: /* EHCI */
@@ -109,3 +172,10 @@ yeeloong_intr_map(int dev, int fn, int pin)
return -1;
}
+
+void
+yeeloong_powerdown()
+{
+ REGVAL(BONITO_GPIODATA) &= ~0x00000001;
+ REGVAL(BONITO_GPIOIE) &= ~0x00000001;
+}