diff options
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/loongson/conf/files.loongson | 6 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonito.c | 290 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonito_irq.h | 92 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonitoreg.h | 8 | ||||
-rw-r--r-- | sys/arch/loongson/dev/bonitovar.h | 5 | ||||
-rw-r--r-- | sys/arch/loongson/dev/lemote_irq.h | 72 | ||||
-rw-r--r-- | sys/arch/loongson/include/autoconf.h | 11 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/gdium_machdep.c | 82 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/machdep.c | 64 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/pmon.c | 4 | ||||
-rw-r--r-- | sys/arch/loongson/loongson/yeeloong_machdep.c | 84 | ||||
-rw-r--r-- | sys/arch/mips64/include/archtype.h | 5 |
12 files changed, 507 insertions, 216 deletions
diff --git a/sys/arch/loongson/conf/files.loongson b/sys/arch/loongson/conf/files.loongson index 52b3c00347d..f7d56de48bc 100644 --- a/sys/arch/loongson/conf/files.loongson +++ b/sys/arch/loongson/conf/files.loongson @@ -1,4 +1,4 @@ -# $OpenBSD: files.loongson,v 1.1 2009/12/25 21:09:57 miod Exp $ +# $OpenBSD: files.loongson,v 1.2 2010/02/05 20:51:20 miod Exp $ # Standard stanzas config(8) can't run without maxpartitions 16 @@ -17,6 +17,7 @@ file arch/loongson/loongson/bus_dma.c file arch/loongson/loongson/bus_space.c file arch/loongson/loongson/conf.c file arch/loongson/loongson/disksubr.c disk +file arch/loongson/loongson/gdium_machdep.c file arch/loongson/loongson/loongson2_machdep.c file arch/loongson/loongson/machdep.c file arch/loongson/loongson/mutex.c @@ -24,6 +25,7 @@ file arch/loongson/loongson/pciide_machdep.c pciide file arch/loongson/loongson/pmon.c file arch/loongson/loongson/pmon32.S file arch/loongson/loongson/wscons_machdep.c wsdisplay +file arch/loongson/loongson/yeeloong_machdep.c include "dev/ata/files.ata" include "dev/atapiscsi/files.atapiscsi" @@ -65,7 +67,7 @@ attach glxpcib at pci file arch/loongson/dev/glxpcib.c glxpcib file arch/loongson/dev/pcib.c glxpcib -# RTC +# Lemote Yeeloong RTC device mcclock attach mcclock at isa with mcclock_isa file arch/loongson/dev/mcclock.c mcclock diff --git a/sys/arch/loongson/dev/bonito.c b/sys/arch/loongson/dev/bonito.c index 78c42b997f3..ba2c0348338 100644 --- a/sys/arch/loongson/dev/bonito.c +++ b/sys/arch/loongson/dev/bonito.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bonito.c,v 1.5 2010/02/05 20:47:15 miod Exp $ */ +/* $OpenBSD: bonito.c,v 1.6 2010/02/05 20:51:22 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 $ */ @@ -57,6 +57,8 @@ #include <sys/extent.h> #include <sys/malloc.h> +#include <mips64/archtype.h> + #include <machine/autoconf.h> #include <machine/bus.h> #include <machine/intr.h> @@ -71,8 +73,8 @@ #include <loongson/dev/bonitoreg.h> #include <loongson/dev/bonitovar.h> +#include <loongson/dev/bonito_irq.h> #include <loongson/dev/glxvar.h> -#include <loongson/dev/lemote_irq.h> int bonito_match(struct device *, void *, void *); void bonito_attach(struct device *, struct device *, void *); @@ -92,10 +94,7 @@ bus_addr_t bonito_pa_to_device(paddr_t); paddr_t bonito_device_to_pa(bus_addr_t); void bonito_intr_makemasks(void); -void bonito_splx(int); uint32_t bonito_intr(uint32_t, struct trap_frame *); -uint32_t bonito_isa_intr(uint32_t, struct trap_frame *); -void bonito_setintrmask(int); void bonito_attach_hook(struct device *, struct device *, struct pcibus_attach_args *); @@ -119,25 +118,19 @@ uint bonito_get_isa_isr(void); void bonito_set_isa_imr(uint); void bonito_isa_specific_eoi(int); -/* - * Bonito interrupt handling declarations: on the Yeelong, we have 14 - * interrupts on Bonito, and 16 (well, 15) ISA interrupts with the usual - * 8259 pair. Bonito and ISA interrupts happen on two different levels. - * - * For simplicity we allocate 16 vectors for direct interrupts, and 16 - * vectors for ISA interrupts as well. - */ - -#define BONITO_NINTS (16 + 16) -struct intrhand *bonito_intrhand[BONITO_NINTS]; +uint32_t bonito_isa_intr(uint32_t, struct trap_frame *); -#define BONITO_ISA_IRQ(i) ((i) + 16) -#define BONITO_DIRECT_IRQ(i) (i) -#define BONITO_IRQ_IS_ISA(i) ((i) >= 16) +void bonito_splx(int); +void bonito_setintrmask(int); -#define INTPRI_BONITO (INTPRI_CLOCK + 1) -#define INTPRI_ISA (INTPRI_BONITO + 1) +void bonito_isa_splx(int); +void bonito_isa_setintrmask(int); +/* + * Bonito interrupt handling declarations. + * See <loongson/dev/bonito_irq.h> for details. + */ +struct intrhand *bonito_intrhand[BONITO_NINTS]; uint64_t bonito_intem; uint64_t bonito_imask[NIPLS]; @@ -220,17 +213,6 @@ bonito_match(struct device *parent, void *vcf, void *aux) return (0); } -const struct bonito_config yeelong_bonito = { - .bc_adbase = 11, - - .bc_gpioIE = YEELONG_INTRMASK_GPIO, - .bc_intEdge = YEELONG_INTRMASK_PCI_SYSERR | YEELONG_INTRMASK_PCI_PARERR, - .bc_intSteer = 0, - .bc_intPol = YEELONG_INTRMASK_DRAM_PARERR | - YEELONG_INTRMASK_PCI_SYSERR | YEELONG_INTRMASK_PCI_PARERR | - YEELONG_INTRMASK_INT0 | YEELONG_INTRMASK_INT1 -}; - void bonito_attach(struct device *parent, struct device *self, void *aux) { @@ -240,12 +222,31 @@ bonito_attach(struct device *parent, struct device *self, void *aux) const struct bonito_config *bc; struct extent *ioex, *memex; uint32_t reg; + int real_bonito; - printf(": memory and PCI-X controller, rev. %d\n", - PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG)))); + /* + * Loongson 2F processors do not use a real Bonito64 chip but + * their own derivative, which is no longer 100% compatible. + * We need to make sure we never try to access an unimplemented + * register... + */ + if (curcpu()->ci_hw.type == MIPS_LOONGSON2 && + (curcpu()->ci_hw.c0prid & 0xff) == 0x2f - 0x2c) + real_bonito = 0; + else + real_bonito = 1; - bc = &yeelong_bonito; + reg = PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG))); + if (real_bonito) { + 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)); + } else { + printf(": memory and PCI-X controller, rev %d\n", + PCI_REVISION(REGVAL(BONITO_PCI_REG(PCI_CLASS_REG)))); + } + bc = sys_config.sys_bc; sc->sc_bonito = bc; SLIST_INIT(&sc->sc_hook); @@ -253,18 +254,26 @@ bonito_attach(struct device *parent, struct device *self, void *aux) * Setup proper abitration. */ - /* - * according to linux, changing the value of this undocumented - * register ``avoids deadlock of PCI reading/writing lock operation''. - */ - REGVAL(BONITO_PCI_REG(0x4c)) = 0xd2000001; /* instead of c2000001 */ + 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 */ + } - /* all pci devices may need to hold the bus */ - reg = REGVAL(LOONGSON_PXARB_CFG); - reg &= ~LOONGSON_PXARB_RUDE_DEV_MSK; - reg |= 0xfe << LOONGSON_PXARB_RUDE_DEV_SHFT; - REGVAL(LOONGSON_PXARB_CFG) = reg; - (void)REGVAL(LOONGSON_PXARB_CFG); + /* all pci devices may need to hold the bus */ + reg = REGVAL(LOONGSON_PXARB_CFG); + reg &= ~LOONGSON_PXARB_RUDE_DEV_MSK; + reg |= 0xfe << LOONGSON_PXARB_RUDE_DEV_SHFT; + REGVAL(LOONGSON_PXARB_CFG) = reg; + (void)REGVAL(LOONGSON_PXARB_CFG); + } /* * Setup interrupt handling. @@ -272,15 +281,29 @@ 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) + REGVAL(BONITO_INTSTEER) = bc->bc_intSteer; REGVAL(BONITO_INTPOL) = bc->bc_intPol; + REGVAL(BONITO_INTENCLR) = 0xffffffff; (void)REGVAL(BONITO_INTENCLR); - bonito_isaimr = bonito_get_isa_imr(); - - set_intr(INTPRI_BONITO, CR_INT_4, bonito_intr); - set_intr(INTPRI_ISA, CR_INT_0, bonito_isa_intr); - register_splx_handler(bonito_splx); + switch (sys_config.system_type) { + case LOONGSON_YEELOONG: + 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_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. @@ -304,6 +327,10 @@ bonito_attach(struct device *parent, struct device *self, void *aux) (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 */ + } } /* @@ -415,6 +442,11 @@ bonito_intr_disestablish(void *ih) panic("%s not implemented", __func__); } +/* + * Update interrupt masks. Two set of routines: one when ISA interrupts + * are involved, one without. + */ + void bonito_splx(int newipl) { @@ -430,6 +462,68 @@ bonito_splx(int newipl) setsoftintr0(); } +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; + uint32_t clear, set; + uint32_t sr; + + active = bonito_intem & ~bonito_imask[level]; + /* don't bother masking high bits, there are no isa interrupt sources */ + clear = bonito_imask[level]; + set = active; + + sr = disableintr(); + + if (clear != 0) + REGVAL(BONITO_INTENCLR) = clear; + if (set != 0) + REGVAL(BONITO_INTENSET) = set; + (void)REGVAL(BONITO_INTENSET); + + 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. */ @@ -493,7 +587,7 @@ bonito_intr(uint32_t hwpend, struct trap_frame *frame) struct intrhand *ih; int rc; - isr = REGVAL(BONITO_INTISR) & YEELONG_INTRMASK_LVL4; + isr = REGVAL(BONITO_INTISR) & LOONGSON_INTRMASK_LVL4; imr = REGVAL(BONITO_INTEN); isr &= imr; #ifdef DEBUG @@ -525,7 +619,7 @@ bonito_intr(uint32_t hwpend, struct trap_frame *frame) uint64_t tmpisr; /* Service higher level interrupts first */ - bit = YEELONG_INTR_DRAM_PARERR; + bit = LOONGSON_INTR_DRAM_PARERR; /* skip non-pci interrupts */ for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) { tmpisr = isr & (bonito_imask[lvl] ^ bonito_imask[lvl - 1]); if (tmpisr == 0) @@ -567,8 +661,8 @@ done: /* * Process ISA interrupts. * - * XXX ISA interrupts only occur on YEELONG_INTR_INT0, but since the other - * XXX YEELONG_INTR_INT# are unmaskable, bad things will happen if they + * 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... */ @@ -604,7 +698,7 @@ bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame) * If interrupts are spl-masked, mask them and wait for splx() * to reenable them when necessary. */ - if ((mask = isr & (bonito_imask[frame->ipl] >> 16)) != 0) { + if ((mask = isr & (BONITO_ISA_MASK(bonito_imask[frame->ipl]))) != 0) { isr &= ~mask; imr &= ~mask; } @@ -617,10 +711,10 @@ bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame) uint64_t tmpisr; /* Service higher level interrupts first */ - bit = 15; + bit = BONITO_NISA - 1; for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) { - tmpisr = isr & - ((bonito_imask[lvl] ^ bonito_imask[lvl - 1]) >> 16); + tmpisr = isr & BONITO_ISA_MASK(bonito_imask[lvl] ^ + bonito_imask[lvl - 1]); if (tmpisr == 0) continue; for (bitno = bit, mask = 1UL << bitno; mask != 0; @@ -629,7 +723,7 @@ bonito_isa_intr(uint32_t hwpend, struct trap_frame *frame) continue; rc = 0; - for (ih = bonito_intrhand[bitno + 16]; + for (ih = bonito_intrhand[BONITO_ISA_IRQ(bitno)]; ih != NULL; ih = ih->ih_next) { if ((*ih->ih_fun)(ih->ih_arg) != 0) { rc = 1; @@ -659,31 +753,6 @@ done: return hwpend; } - -void -bonito_setintrmask(int level) -{ - uint64_t active; - uint32_t clear, set; - uint32_t sr; - - active = bonito_intem & ~bonito_imask[level]; - clear = bonito_imask[level] & 0xffff; - set = active & 0xffff; - - sr = disableintr(); - - if (clear != 0) - REGVAL(BONITO_INTENCLR) = clear; - if (set != 0) - REGVAL(BONITO_INTENSET) = set; - (void)REGVAL(BONITO_INTENSET); - - bonito_set_isa_imr(active >> 16); - - setsr(sr); -} - /* * various PCI helpers */ @@ -895,7 +964,9 @@ bonito_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data) int bonito_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) { - int dev, fn, pin; + struct bonito_softc *sc = pa->pa_pc->pc_intr_v; + const struct bonito_config *bc = sc->sc_bonito; + int bus, dev, fn, pin; *ihp = -1; @@ -909,44 +980,13 @@ bonito_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) } #endif - pci_decompose_tag(pa->pa_pc, pa->pa_tag, NULL, &dev, &fn); + pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn); if (pa->pa_bridgetag) { pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev); *ihp = pa->pa_bridgeih[pin - 1]; } else { - switch (dev) { - /* onboard devices, only pin A is wired */ - case 6: - case 7: - case 8: - case 9: - if (pa->pa_intrpin == PCI_INTERRUPT_PIN_A) - *ihp = BONITO_DIRECT_IRQ(YEELONG_INTR_PCIA + - (dev - 6)); - break; - /* PCI slot */ - case 10: - *ihp = BONITO_DIRECT_IRQ(YEELONG_INTR_PCIA + - (pa->pa_intrpin - PCI_INTERRUPT_PIN_A)); - break; - /* Geode chip */ - case 14: - switch (fn) { - case 1: /* Flash */ - *ihp = BONITO_ISA_IRQ(6); - break; - case 2: /* AC97 */ - *ihp = BONITO_ISA_IRQ(9); - break; - case 4: /* OHCI */ - case 5: /* EHCI */ - *ihp = BONITO_ISA_IRQ(11); - break; - } - break; - default: - break; - } + if (bus == 0) + *ihp = (*bc->bc_intr_map)(dev, fn, pa->pa_intrpin); if (*ihp < 0) return 1; @@ -961,7 +1001,8 @@ bonito_pci_intr_string(void *cookie, pci_intr_handle_t ih) static char irqstr[1 + 12]; if (BONITO_IRQ_IS_ISA(ih)) - snprintf(irqstr, sizeof irqstr, "isa irq %d", ih - 16); + snprintf(irqstr, sizeof irqstr, "isa irq %d", + ih - BONITO_NDIRECT); else snprintf(irqstr, sizeof irqstr, "irq %d", ih); return irqstr; @@ -1016,7 +1057,12 @@ bonito_set_isa_imr(uint newimr) imr1 &= ~(1 << 2); /* enable cascade */ imr2 = 0xff & ~(newimr >> 8); - /* interrupts have been disabled by the caller */ + /* + * For some reason, trying to write the same value to the PIC + * registers causes an immediate system freeze, so we only do + * this if the value changes. + * Note that interrupts have been disabled by the caller. + */ if ((newimr ^ bonito_isaimr) & 0xff00) { REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 1) = imr2; (void)REGVAL8(BONITO_PCIIO_BASE + IO_ICU2 + 1); diff --git a/sys/arch/loongson/dev/bonito_irq.h b/sys/arch/loongson/dev/bonito_irq.h new file mode 100644 index 00000000000..667a2b991ac --- /dev/null +++ b/sys/arch/loongson/dev/bonito_irq.h @@ -0,0 +1,92 @@ +/* $OpenBSD: bonito_irq.h,v 1.1 2010/02/05 20:51:22 miod Exp $ */ + +/* + * 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Bonito interrupt assignments + */ + +#define LOONGSON_INTR_GPIO0 0 +#define LOONGSON_INTR_GPIO1 1 +#define LOONGSON_INTR_GPIO2 2 +#define LOONGSON_INTR_GPIO3 3 + +/* pci interrupts */ +#define LOONGSON_INTR_PCIA 4 +#define LOONGSON_INTR_PCIB 5 +#define LOONGSON_INTR_PCIC 6 +#define LOONGSON_INTR_PCID 7 + +#define LOONGSON_INTR_PCI_PARERR 8 +#define LOONGSON_INTR_PCI_SYSERR 9 +#define LOONGSON_INTR_DRAM_PARERR 10 + +/* non-PCI interrupts */ +#define LOONGSON_INTR_INT0 11 +#define LOONGSON_INTR_INT1 12 +#define LOONGSON_INTR_INT2 13 +#define LOONGSON_INTR_INT3 14 + +#define LOONGSON_INTRMASK_GPIO0 0x00000001 /* can't interrupt */ +#define LOONGSON_INTRMASK_GPIO1 0x00000002 +#define LOONGSON_INTRMASK_GPIO2 0x00000004 +#define LOONGSON_INTRMASK_GPIO3 0x00000008 + +#define LOONGSON_INTRMASK_GPIO 0x0000000f + +/* pci interrupts */ +#define LOONGSON_INTRMASK_PCIA 0x00000010 +#define LOONGSON_INTRMASK_PCIB 0x00000020 +#define LOONGSON_INTRMASK_PCIC 0x00000040 +#define LOONGSON_INTRMASK_PCID 0x00000080 + +#define LOONGSON_INTRMASK_PCI_PARERR 0x00000100 +#define LOONGSON_INTRMASK_PCI_SYSERR 0x00000200 +#define LOONGSON_INTRMASK_DRAM_PARERR 0x00000400 + +/* non-PCI interrupts */ +#define LOONGSON_INTRMASK_INT0 0x00000800 +#define LOONGSON_INTRMASK_INT1 0x00001000 +#define LOONGSON_INTRMASK_INT2 0x00002000 +#define LOONGSON_INTRMASK_INT3 0x00004000 + +#define LOONGSON_INTRMASK_LVL0 0x00007800 /* not maskable in bonito */ +#define LOONGSON_INTRMASK_LVL4 0x000007ff + +/* + * Bonito interrupt handling recipes: + * - we have 14 interrupts on Bonito + * - on the Yeeloong, there are also 16 (well, 15) ISA interrupts with the + * usual 8259 pair. Bonito and ISA interrupts happen on two different levels. + * + * For simplicity we allocate 16 vectors for direct interrupts, and 16 + * vectors for ISA interrupts as well (which will only be used if we are + * running on a Yeeloong). + */ + +#define INTPRI_BONITO (INTPRI_CLOCK + 1) +#define INTPRI_ISA (INTPRI_BONITO + 1) + +#define BONITO_NDIRECT 16 +#define BONITO_NISA 16 +#define BONITO_NINTS (BONITO_NDIRECT + BONITO_NISA) +#define BONITO_ISA_IRQ(i) ((i) + BONITO_NDIRECT) +#define BONITO_DIRECT_IRQ(i) (i) +#define BONITO_IRQ_IS_ISA(i) ((i) >= BONITO_NDIRECT) + +#define BONITO_DIRECT_MASK(imask) ((imask) & ((1 << BONITO_NDIRECT) - 1)) +#define BONITO_ISA_MASK(imask) ((imask) >> BONITO_NDIRECT) diff --git a/sys/arch/loongson/dev/bonitoreg.h b/sys/arch/loongson/dev/bonitoreg.h index 0ece5e21c19..23b5097cc18 100644 --- a/sys/arch/loongson/dev/bonitoreg.h +++ b/sys/arch/loongson/dev/bonitoreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bonitoreg.h,v 1.2 2010/01/31 19:12:12 miod Exp $ */ +/* $OpenBSD: bonitoreg.h,v 1.3 2010/02/05 20:51:22 miod Exp $ */ /* $NetBSD: bonitoreg.h,v 1.6 2005/12/24 20:07:19 perry Exp $ */ /* @@ -70,6 +70,10 @@ #define BONITO_PCI_REG(x) BONITO(BONITO_PCICONFIGBASE + (x)) +#define BONITO_REV_FPGA(x) ((x) & 0x80) +#define BONITO_REV_MAJOR(x) (((x) >> 4) & 0x7) +#define BONITO_REV_MINOR(x) ((x) & 0xf) + /* Controller configuration */ #define LOONGSON_PONCFG BONITO(BONITO_REGBASE + 0x00) @@ -90,7 +94,7 @@ /* ICU Configuration Regs - r/w */ #define BONITO_INTEDGE BONITO(BONITO_REGBASE + 0x24) -/* INTSTEER is not implemented */ +#define BONITO_INTSTEER BONITO(BONITO_REGBASE + 0x28) #define BONITO_INTPOL BONITO(BONITO_REGBASE + 0x2c) /* ICU Enable Regs - INTEN and INTISR are read only */ diff --git a/sys/arch/loongson/dev/bonitovar.h b/sys/arch/loongson/dev/bonitovar.h index 4e184740808..061950cfa4f 100644 --- a/sys/arch/loongson/dev/bonitovar.h +++ b/sys/arch/loongson/dev/bonitovar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bonitovar.h,v 1.1 2009/12/25 21:28:23 miod Exp $ */ +/* $OpenBSD: bonitovar.h,v 1.2 2010/02/05 20:51:22 miod Exp $ */ /* $NetBSD: bonitovar.h,v 1.4 2008/04/28 20:23:28 martin Exp $ */ /*- @@ -45,6 +45,9 @@ struct bonito_config { uint32_t bc_intEdge; uint32_t bc_intSteer; uint32_t bc_intPol; + + /* PCI Interrupt Assignment for the first bus */ + int (*bc_intr_map)(int, int, int); }; struct bonito_softc { diff --git a/sys/arch/loongson/dev/lemote_irq.h b/sys/arch/loongson/dev/lemote_irq.h deleted file mode 100644 index b38df51649a..00000000000 --- a/sys/arch/loongson/dev/lemote_irq.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $OpenBSD: lemote_irq.h,v 1.1 2009/12/25 21:11:07 miod Exp $ */ - -/* - * Copyright (c) 2009 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 - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Lemote Yeelong specific hardware defines - */ - -/* - * Bonito interrupt assignments - */ - -#define YEELONG_INTR_GPIO0 0 -#define YEELONG_INTR_GPIO1 1 -#define YEELONG_INTR_GPIO2 2 -#define YEELONG_INTR_GPIO3 3 - -/* pci interrupts */ -#define YEELONG_INTR_PCIA 4 -#define YEELONG_INTR_PCIB 5 -#define YEELONG_INTR_PCIC 6 -#define YEELONG_INTR_PCID 7 - -#define YEELONG_INTR_PCI_PARERR 8 -#define YEELONG_INTR_PCI_SYSERR 9 -#define YEELONG_INTR_DRAM_PARERR 10 - -/* isa interrupts on i8259 */ -#define YEELONG_INTR_INT0 11 -#define YEELONG_INTR_INT1 12 -#define YEELONG_INTR_INT2 13 -#define YEELONG_INTR_INT3 14 - -#define YEELONG_INTRMASK_GPIO0 0x00000001 /* can't interrupt */ -#define YEELONG_INTRMASK_GPIO1 0x00000002 -#define YEELONG_INTRMASK_GPIO2 0x00000004 -#define YEELONG_INTRMASK_GPIO3 0x00000008 - -#define YEELONG_INTRMASK_GPIO 0x0000000f - -/* pci interrupts */ -#define YEELONG_INTRMASK_PCIA 0x00000010 -#define YEELONG_INTRMASK_PCIB 0x00000020 -#define YEELONG_INTRMASK_PCIC 0x00000040 -#define YEELONG_INTRMASK_PCID 0x00000080 - -#define YEELONG_INTRMASK_PCI_PARERR 0x00000100 -#define YEELONG_INTRMASK_PCI_SYSERR 0x00000200 -#define YEELONG_INTRMASK_DRAM_PARERR 0x00000400 - -/* isa interrupts on i8259 */ -#define YEELONG_INTRMASK_INT0 0x00000800 -#define YEELONG_INTRMASK_INT1 0x00001000 -#define YEELONG_INTRMASK_INT2 0x00002000 -#define YEELONG_INTRMASK_INT3 0x00004000 - -#define YEELONG_INTRMASK_LVL4 0x000007ff -#define YEELONG_INTRMASK_LVL0 0x00007800 /* not maskable in bonito */ diff --git a/sys/arch/loongson/include/autoconf.h b/sys/arch/loongson/include/autoconf.h index eb471091533..ae1fe1e7d43 100644 --- a/sys/arch/loongson/include/autoconf.h +++ b/sys/arch/loongson/include/autoconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.h,v 1.2 2010/01/09 20:33:16 miod Exp $ */ +/* $OpenBSD: autoconf.h,v 1.3 2010/02/05 20:51:22 miod Exp $ */ /* * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -35,14 +35,16 @@ #include <machine/bus.h> +struct bonito_config; + /* * Structure holding all misc config information. */ struct sys_rec { int system_type; - /* Serial console configuration. */ - struct mips_bus_space console_io; + /* Bonito configuration */ + const struct bonito_config *sys_bc; }; extern struct sys_rec sys_config; @@ -51,6 +53,9 @@ 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 new file mode 100644 index 00000000000..c01c9f04159 --- /dev/null +++ b/sys/arch/loongson/loongson/gdium_machdep.c @@ -0,0 +1,82 @@ +/* $OpenBSD: gdium_machdep.c,v 1.1 2010/02/05 20:51:22 miod Exp $ */ + +/* + * Copyright (c) 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Gdium Liberty specific code and configuration data. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/autoconf.h> + +#include <dev/pci/pcireg.h> + +#include <loongson/dev/bonitovar.h> +#include <loongson/dev/bonito_irq.h> + +int gdium_intr_map(int, int, int); + +const struct bonito_config gdium_bonito = { + .bc_adbase = 11, + + .bc_gpioIE = LOONGSON_INTRMASK_GPIO, + .bc_intEdge = LOONGSON_INTRMASK_PCI_SYSERR | + LOONGSON_INTRMASK_PCI_PARERR, + .bc_intSteer = 0, + .bc_intPol = LOONGSON_INTRMASK_DRAM_PARERR | + LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR, + + .bc_intr_map = gdium_intr_map +}; + +int +gdium_intr_map(int dev, int fn, int pin) +{ + switch (dev) { + /* Wireless */ + case 13: /* C D A B */ + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + (pin + 1) % 4); + /* Frame buffer */ + case 14: + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA); + /* USB */ + case 15: +#if 0 /* on revision 1 -- how to tell them apart? */ + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + + (pa->pa_intrpin - 1)); +#else + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIB); +#endif + /* Ethernet */ + case 16: + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCID); + /* USB */ + case 17: +#if 0 /* not present on revision 1 */ + break; +#else + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIC); +#endif + default: + break; + } + + return -1; +} diff --git a/sys/arch/loongson/loongson/machdep.c b/sys/arch/loongson/loongson/machdep.c index 8658e3f4d09..2b2425740d3 100644 --- a/sys/arch/loongson/loongson/machdep.c +++ b/sys/arch/loongson/loongson/machdep.c @@ -1,7 +1,7 @@ -/* $OpenBSD: machdep.c,v 1.8 2010/02/04 16:41:16 otto Exp $ */ +/* $OpenBSD: machdep.c,v 1.9 2010/02/05 20:51:22 miod 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 @@ -78,6 +78,7 @@ #include <mips64/archtype.h> #include <loongson/dev/bonitoreg.h> +#include <loongson/dev/bonitovar.h> /* The following is used externally (sysctl_hw) */ char machine[] = MACHINE; /* Machine "architecture" */ @@ -143,6 +144,28 @@ struct consdev pmoncons = { }; /* + * List of supported system types, from the ``Version'' environment + * variable. + */ + +struct bonito_flavour { + const char *prefix; + int systype; + const struct bonito_config *bc; +}; + +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 }, + /* EMTEC Gdium Liberty 1000 */ + { "Gdium", LOONGSON_GDIUM, &gdium_bonito }, + { NULL } +}; + +/* * Do all the stuff that locore normally does before calling main(). * Reset mapping and set up mapping to hardware and init "wired" reg. */ @@ -155,6 +178,7 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv) vaddr_t xtlb_handler; const char *envvar; int i; + const struct bonito_flavour *f; extern char start[], edata[], end[]; extern char exception[], e_exception[]; @@ -241,10 +265,12 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv) goto unsupported; } - /* Lemote Yeelong 8089 */ - if (strncmp(envvar, "LM8089", 6) == 0) { - sys_config.system_type = LOONGSON_YEELONG; - } + 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; + break; + } if (sys_config.system_type == 0) { pmon_printf("This kernel doesn't support model \"%s\".\n", @@ -253,9 +279,13 @@ mips_init(int32_t argc, int32_t argv, int32_t envp, int32_t cv) } switch (sys_config.system_type) { - case LOONGSON_YEELONG: + case LOONGSON_YEELOONG: hw_vendor = "Lemote"; - hw_prod = "Yeelong"; + hw_prod = "Yeeloong"; + break; + case LOONGSON_GDIUM: + hw_vendor = "EMTEC"; + hw_prod = "Gdium"; break; default: /* won't happen */ goto unsupported; @@ -784,8 +814,18 @@ haltsys: if (howto & RB_HALT) { if (howto & RB_POWERDOWN) { printf("System Power Down.\n"); - REGVAL(BONITO_GPIODATA) &= ~0x00000001; - REGVAL(BONITO_GPIOIE) &= ~0x00000001; + 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; + } } else printf("System Halt.\n"); } else { @@ -909,6 +949,10 @@ pmoncngetc(dev_t dev) * PMON does not give us a getc routine. So try to get a whole line * and return it char by char, trying not to lose the \n. Kind * of ugly but should work. + * + * Note that one could theoretically use pmon_read(STDIN, &c, 1) + * but the value of STDIN within PMON is not a constant and there + * does not seem to be a way of letting us know which value to use. */ static char buf[1 + PMON_MAXLN]; static char *bufpos = buf; diff --git a/sys/arch/loongson/loongson/pmon.c b/sys/arch/loongson/loongson/pmon.c index fec7d956332..9268dacf873 100644 --- a/sys/arch/loongson/loongson/pmon.c +++ b/sys/arch/loongson/loongson/pmon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmon.c,v 1.1 2009/11/23 14:47:13 miod Exp $ */ +/* $OpenBSD: pmon.c,v 1.2 2010/02/05 20:51:22 miod Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. @@ -60,7 +60,7 @@ pmon_getenv(const char *var) while (*envptr != 0) { envstr = (const char *)(vaddr_t)*envptr; /* - * There is a PMON2000 bug, at least on Lemote Yeelong, + * There is a PMON2000 bug, at least on Lemote Yeeloong, * which causes it to override part of the environment * pointers array with the environment data itself. * diff --git a/sys/arch/loongson/loongson/yeeloong_machdep.c b/sys/arch/loongson/loongson/yeeloong_machdep.c new file mode 100644 index 00000000000..1f812872159 --- /dev/null +++ b/sys/arch/loongson/loongson/yeeloong_machdep.c @@ -0,0 +1,84 @@ +/* $OpenBSD: yeeloong_machdep.c,v 1.1 2010/02/05 20:51:22 miod Exp $ */ + +/* + * 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 + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Lemote Yeeloong specific code and configuration data. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <machine/autoconf.h> + +#include <dev/pci/pcireg.h> + +#include <loongson/dev/bonitovar.h> +#include <loongson/dev/bonito_irq.h> + +int yeeloong_intr_map(int, int, int); + +const struct bonito_config yeeloong_bonito = { + .bc_adbase = 11, + + .bc_gpioIE = LOONGSON_INTRMASK_GPIO, + .bc_intEdge = LOONGSON_INTRMASK_PCI_SYSERR | + LOONGSON_INTRMASK_PCI_PARERR, + .bc_intSteer = 0, + .bc_intPol = LOONGSON_INTRMASK_DRAM_PARERR | + LOONGSON_INTRMASK_PCI_SYSERR | LOONGSON_INTRMASK_PCI_PARERR | + LOONGSON_INTRMASK_INT0 | LOONGSON_INTRMASK_INT1, + + .bc_intr_map = yeeloong_intr_map +}; + +int +yeeloong_intr_map(int dev, int fn, int pin) +{ + switch (dev) { + /* onboard devices, only pin A is wired */ + case 6: + case 7: + case 8: + case 9: + if (pin == PCI_INTERRUPT_PIN_A) + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + + (dev - 6)); + break; + /* PCI slot */ + case 10: + return BONITO_DIRECT_IRQ(LOONGSON_INTR_PCIA + + (pin - PCI_INTERRUPT_PIN_A)); + /* Geode chip */ + case 14: + switch (fn) { + case 1: /* Flash */ + return BONITO_ISA_IRQ(6); + case 2: /* AC97 */ + return BONITO_ISA_IRQ(9); + case 4: /* OHCI */ + case 5: /* EHCI */ + return BONITO_ISA_IRQ(11); + } + break; + default: + break; + } + + return -1; +} diff --git a/sys/arch/mips64/include/archtype.h b/sys/arch/mips64/include/archtype.h index 17afe639c8a..8411bb1f07d 100644 --- a/sys/arch/mips64/include/archtype.h +++ b/sys/arch/mips64/include/archtype.h @@ -1,4 +1,4 @@ -/* $OpenBSD: archtype.h,v 1.8 2009/11/07 14:49:00 miod Exp $ */ +/* $OpenBSD: archtype.h,v 1.9 2010/02/05 20:51:22 miod Exp $ */ /* * Copyright (c) 1997-2004 Opsycon AB, Sweden (www.opsycon.se) * @@ -78,7 +78,8 @@ #define WG8232 0x005a /* Willowglen CPU-8232 */ #define LOONGSON_CLASS 0x0060 /* Loongson + PMON2000 class */ -#define LOONGSON_YEELONG 0x0061 /* Lemote Yeelong */ +#define LOONGSON_YEELOONG 0x0061 /* Lemote Yeeloong */ +#define LOONGSON_GDIUM 0x0062 /* EMTEC Gdium Liberty */ #define MISC_CLASS 0x00f0 /* Misc machines... */ #define LAGUNA 0x00f1 /* Heurikon Laguna VME board */ |