summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/loongson/conf/Makefile.loongson188
-rw-r--r--sys/arch/loongson/dev/glxpcib.c395
-rw-r--r--sys/arch/loongson/dev/glxreg.h292
-rw-r--r--sys/arch/loongson/dev/mcclock.c128
-rw-r--r--sys/arch/loongson/dev/mcclock_isa.c131
-rw-r--r--sys/arch/loongson/dev/pcib.c68
-rw-r--r--sys/arch/loongson/include/param.h25
7 files changed, 1227 insertions, 0 deletions
diff --git a/sys/arch/loongson/conf/Makefile.loongson b/sys/arch/loongson/conf/Makefile.loongson
new file mode 100644
index 00000000000..bf6c56a10c7
--- /dev/null
+++ b/sys/arch/loongson/conf/Makefile.loongson
@@ -0,0 +1,188 @@
+# $OpenBSD: Makefile.loongson,v 1.1 2009/12/25 21:05:14 miod Exp $
+
+# Makefile for OpenBSD
+#
+# This makefile is constructed from a machine description:
+# config ``machineid''
+# Most changes should be made in the machine description
+# /sys/arch/loongson/conf/``machineid''
+# after which you should do
+# config ``machineid''
+# Machine generic makefile changes should be made in
+# /sys/arch/loongson/conf/Makefile.``machinetype''
+# after which config should be rerun for all machines of that type.
+#
+# N.B.: NO DEPENDENCIES ON FOLLOWING FLAGS ARE VISIBLE TO MAKEFILE
+# IF YOU CHANGE THE DEFINITION OF ANY OF THESE RECOMPILE EVERYTHING
+#
+# -DTRACE compile in kernel tracing hooks
+# -DQUOTA compile in file system quotas
+
+
+# DEBUG is set to -g if debugging
+# PROF is set to -pg if profiling
+
+.include <bsd.own.mk>
+
+AS?= as
+CC?= cc
+MKDEP?= mkdep
+SIZE?= size
+CPP?= cpp
+LD?= ld ${ENDIAN}
+STRIP?= strip
+TOUCH?= touch
+
+CPP+=${ENDIAN}
+CC+=${ENDIAN}
+AS+=${ENDIAN}
+LD+=${ENDIAN}
+
+# source tree is located via $S relative to the compilation directory
+.ifndef S
+S!= cd ../../../..; pwd
+.endif
+LOONGSON=$S/arch/loongson
+MIPS64= $S/arch/mips64
+
+INCLUDES= -I. -I$S -I$S/arch -nostdinc
+CPPFLAGS= ${INCLUDES} ${IDENT} -D_KERNEL -D__loongson__
+CDIAGFLAGS= -Werror -Wall -Wmissing-prototypes -Wstrict-prototypes \
+ -Wno-uninitialized -Wno-format -Wno-main \
+ -Wstack-larger-than-2047 -Wvariable-decl
+CMACHFLAGS+= -mno-abicalls ${ABI} -msoft-float \
+ -fno-builtin-printf -fno-builtin-log
+.if ${IDENT:M-DNO_PROPOLICE}
+CMACHFLAGS+= -fno-stack-protector
+.endif
+COPTS?= -O2
+CFLAGS= ${DEBUG} ${CDIAGFLAGS} ${CMACHFLAGS} ${COPTS} ${PIPE}
+AFLAGS= -x assembler-with-cpp -mno-abicalls ${ABI} -D_LOCORE
+STRIPFLAGS= -g -X -x
+
+NORMAL_C_NOP= ${CC} ${CFLAGS} ${CPPFLAGS} -c $<
+NORMAL_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c $<
+NORMAL_C_C= ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} ${PARAM} -c $<
+NORMAL_S= ${CC} ${AFLAGS} ${CPPFLAGS} -c $<
+NORMAL_S_C= ${AS} ${COPTS} ${PARAM} $< -o $@
+
+%OBJS
+
+%CFILES
+
+%SFILES
+
+# load lines for config "xxx" will be emitted as:
+# xxx: ${SYSTEM_DEP} swapxxx.o
+# ${SYSTEM_LD_HEAD}
+# ${SYSTEM_LD} swapxxx.o
+# ${SYSTEM_LD_TAIL}
+SYSTEM_OBJ= locore.o param.o ioconf.o ${OBJS}
+SYSTEM_DEP= Makefile ${SYSTEM_OBJ}
+SYSTEM_LD_HEAD= rm -f $@
+SYSTEM_LD= @if [ X${DEBUG} = X-g ]; \
+ then strip=-X; \
+ else strip=-x; \
+ fi; \
+ echo ${LD} $$strip -o $@ -e start -T ${LOONGSON}/conf/ld.script \
+ -Ttext=${LINK_ADDRESS} '$${SYSTEM_OBJ}' vers.o; \
+ ${LD} $$strip -o $@ -e start -T ${LOONGSON}/conf/ld.script \
+ -Ttext=${LINK_ADDRESS} ${SYSTEM_OBJ} vers.o
+SYSTEM_LD_TAIL= chmod 755 $@; \
+ ${SIZE} $@
+
+DEBUG?=
+.if ${DEBUG} == "-g"
+SYSTEM_LD_TAIL+=; \
+ echo mv $@ $@.gdb; rm -f $@.gdb; mv $@ $@.gdb; \
+ echo ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb; \
+ ${STRIP} ${STRIPFLAGS} -o $@ $@.gdb
+.endif
+
+%LOAD
+
+clean::
+ rm -f eddep bsd bsd.gdb bsd.ecoff tags *.o locore.i [a-z]*.s \
+ Errs errs linterrs makelinks
+
+lint: /tmp param.c
+ @lint -hbxn -DGENERIC -Dvolatile= ${COPTS} ${PARAM} -UKGDB \
+ ${CFILES} ioconf.c param.c
+
+symbols.sort: ${LOONGSON}/loongson/symbols.raw
+ grep -v '^#' ${LOONGSON}/loongson/symbols.raw \
+ | sed 's/^ //' | sort -u > symbols.sort
+
+locore.o: ${LOONGSON}/loongson/locore.S assym.h
+ ${NORMAL_S}
+
+# the following are necessary because the files depend on the types of
+# cpu's included in the system configuration
+clock.o machdep.o autoconf.o conf.o locore.o: Makefile
+
+# depend on network configuration
+uipc_domain.o uipc_proto.o vfs_conf.o: Makefile
+if_tun.o if_loop.o if_ethersubr.o: Makefile
+if_arp.o if_ether.o: Makefile
+ip_input.o ip_output.o in_pcb.o in_proto.o: Makefile
+tcp_subr.o tcp_timer.o tcp_output.o: Makefile
+
+assym.h: $S/kern/genassym.sh ${LOONGSON}/loongson/genassym.cf Makefile
+ sh $S/kern/genassym.sh ${CC} ${CFLAGS} ${CPPFLAGS} \
+ ${PARAM} < ${LOONGSON}/loongson/genassym.cf > assym.h.tmp && \
+ mv -f assym.h.tmp assym.h
+
+links:
+ egrep '#if' ${CFILES} | sed -f $S/conf/defines | \
+ sed -e 's/:.*//' -e 's/\.c/.o/' | sort -u > dontlink
+ echo ${CFILES} | tr -s ' ' '\12' | sed 's/\.c/.o/' | \
+ sort -u | comm -23 - dontlink | \
+ sed 's,../.*/\(.*.o\),rm -f \1;ln -s ../GENERIC/\1 \1,' > makelinks
+ sh makelinks && rm -f dontlink
+
+tags:
+ @echo "see $S/kern/Makefile for tags"
+
+param.c: $S/conf/param.c
+ rm -f param.c
+ cp $S/conf/param.c .
+
+param.o: param.c Makefile
+ ${NORMAL_C_C}
+
+mcount.o: $S/lib/libkern/mcount.c Makefile
+ ${NORMAL_C_NOP}
+
+ioconf.o: ioconf.c
+ ${NORMAL_C}
+
+vers.o: ${SYSTEM_DEP} ${SYSTEM_SWAP_DEP}
+ sh $S/conf/newvers.sh
+ ${CC} ${CFLAGS} ${CPPFLAGS} ${PROF} -c vers.c
+
+SRCS= ${LOONGSON}/loongson/locore.S \
+ param.c ioconf.c ${CFILES} ${SFILES}
+depend:: .depend
+.depend: ${SRCS} assym.h param.c
+ ${MKDEP} ${AFLAGS} ${CPPFLAGS} ${LOONGSON}/loongson/locore.S
+ ${MKDEP} -a ${CFLAGS} ${CPPFLAGS} param.c ioconf.c ${CFILES}
+ ${MKDEP} -a ${AFLAGS} ${CPPFLAGS} ${SFILES}
+ sh $S/kern/genassym.sh ${MKDEP} -f assym.dep ${CFLAGS} \
+ ${CPPFLAGS} < ${LOONGSON}/loongson/genassym.cf
+ @sed -e 's/.*\.o: /assym.h: /' -e 's/\/tmp\/genassym_c.[^ ]*//' \
+ < assym.dep >> .depend
+ @rm -f assym.dep
+
+# The install target can be redefined by putting a
+# install-kernel-${MACHINE_NAME} target into /etc/mk.conf
+MACHINE_NAME!= uname -n
+install: install-kernel-${MACHINE_NAME}
+.if !target(install-kernel-${MACHINE_NAME}})
+install-kernel-${MACHINE_NAME}:
+ rm -f /obsd
+ ln /bsd /obsd
+ cp bsd /nbsd
+ mv /nbsd /bsd
+.endif
+
+%RULES
diff --git a/sys/arch/loongson/dev/glxpcib.c b/sys/arch/loongson/dev/glxpcib.c
new file mode 100644
index 00000000000..c09d5bed3ee
--- /dev/null
+++ b/sys/arch/loongson/dev/glxpcib.c
@@ -0,0 +1,395 @@
+/* $OpenBSD: glxpcib.c,v 1.1 2009/12/25 21:04:25 miod Exp $ */
+
+/*
+ * Copyright (c) 2007 Marc Balmer <mbalmer@openbsd.org>
+ * Copyright (c) 2007 Michael Shalayeff
+ * All rights reserved.
+ *
+ * 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 MIND, 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.
+ */
+
+/*
+ * AMD CS5536 series LPC bridge also containing timer, watchdog, and GPIO.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/gpio.h>
+#include <sys/sysctl.h>
+#include <sys/timetc.h>
+
+#include <machine/bus.h>
+
+#include <dev/gpio/gpiovar.h>
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+
+#include <loongson/dev/glxreg.h>
+#include <loongson/dev/glxvar.h>
+
+#include "gpio.h"
+
+#define AMD5536_REV GLCP_CHIP_REV_ID
+#define AMD5536_REV_MASK 0xff
+#define AMD5536_TMC PMC_LTMR
+
+/* Multi-Functional General Purpose Timer */
+#define MSR_LBAR_MFGPT DIVIL_LBAR_MFGPT
+#define AMD5536_MFGPT0_CMP1 0x00000000
+#define AMD5536_MFGPT0_CMP2 0x00000002
+#define AMD5536_MFGPT0_CNT 0x00000004
+#define AMD5536_MFGPT0_SETUP 0x00000006
+#define AMD5536_MFGPT_DIV_MASK 0x000f /* div = 1 << mask */
+#define AMD5536_MFGPT_CLKSEL 0x0010
+#define AMD5536_MFGPT_REV_EN 0x0020
+#define AMD5536_MFGPT_CMP1DIS 0x0000
+#define AMD5536_MFGPT_CMP1EQ 0x0040
+#define AMD5536_MFGPT_CMP1GE 0x0080
+#define AMD5536_MFGPT_CMP1EV 0x00c0
+#define AMD5536_MFGPT_CMP2DIS 0x0000
+#define AMD5536_MFGPT_CMP2EQ 0x0100
+#define AMD5536_MFGPT_CMP2GE 0x0200
+#define AMD5536_MFGPT_CMP2EV 0x0300
+#define AMD5536_MFGPT_STOP_EN 0x0800
+#define AMD5536_MFGPT_SET 0x1000
+#define AMD5536_MFGPT_CMP1 0x2000
+#define AMD5536_MFGPT_CMP2 0x4000
+#define AMD5536_MFGPT_CNT_EN 0x8000
+#define AMD5536_MFGPT_IRQ MFGPT_IRQ
+#define AMD5536_MFGPT0_C1_IRQM 0x00000001
+#define AMD5536_MFGPT1_C1_IRQM 0x00000002
+#define AMD5536_MFGPT2_C1_IRQM 0x00000004
+#define AMD5536_MFGPT3_C1_IRQM 0x00000008
+#define AMD5536_MFGPT4_C1_IRQM 0x00000010
+#define AMD5536_MFGPT5_C1_IRQM 0x00000020
+#define AMD5536_MFGPT6_C1_IRQM 0x00000040
+#define AMD5536_MFGPT7_C1_IRQM 0x00000080
+#define AMD5536_MFGPT0_C2_IRQM 0x00000100
+#define AMD5536_MFGPT1_C2_IRQM 0x00000200
+#define AMD5536_MFGPT2_C2_IRQM 0x00000400
+#define AMD5536_MFGPT3_C2_IRQM 0x00000800
+#define AMD5536_MFGPT4_C2_IRQM 0x00001000
+#define AMD5536_MFGPT5_C2_IRQM 0x00002000
+#define AMD5536_MFGPT6_C2_IRQM 0x00004000
+#define AMD5536_MFGPT7_C2_IRQM 0x00008000
+#define AMD5536_MFGPT_NR MFGPT_NR
+#define AMD5536_MFGPT0_C1_NMIM 0x00000001
+#define AMD5536_MFGPT1_C1_NMIM 0x00000002
+#define AMD5536_MFGPT2_C1_NMIM 0x00000004
+#define AMD5536_MFGPT3_C1_NMIM 0x00000008
+#define AMD5536_MFGPT4_C1_NMIM 0x00000010
+#define AMD5536_MFGPT5_C1_NMIM 0x00000020
+#define AMD5536_MFGPT6_C1_NMIM 0x00000040
+#define AMD5536_MFGPT7_C1_NMIM 0x00000080
+#define AMD5536_MFGPT0_C2_NMIM 0x00000100
+#define AMD5536_MFGPT1_C2_NMIM 0x00000200
+#define AMD5536_MFGPT2_C2_NMIM 0x00000400
+#define AMD5536_MFGPT3_C2_NMIM 0x00000800
+#define AMD5536_MFGPT4_C2_NMIM 0x00001000
+#define AMD5536_MFGPT5_C2_NMIM 0x00002000
+#define AMD5536_MFGPT6_C2_NMIM 0x00004000
+#define AMD5536_MFGPT7_C2_NMIM 0x00008000
+#define AMD5536_NMI_LEG 0x00010000
+#define AMD5536_MFGPT0_C2_RSTEN 0x01000000
+#define AMD5536_MFGPT1_C2_RSTEN 0x02000000
+#define AMD5536_MFGPT2_C2_RSTEN 0x04000000
+#define AMD5536_MFGPT3_C2_RSTEN 0x08000000
+#define AMD5536_MFGPT4_C2_RSTEN 0x10000000
+#define AMD5536_MFGPT5_C2_RSTEN 0x20000000
+#define AMD5536_MFGPT_SETUP MFGPT_SETUP
+
+/* GPIO */
+#define MSR_LBAR_GPIO DIVIL_LBAR_GPIO
+#define AMD5536_GPIO_NPINS 32
+#define AMD5536_GPIOH_OFFSET 0x80 /* high bank register offset */
+#define AMD5536_GPIO_OUT_VAL 0x00 /* output value */
+#define AMD5536_GPIO_OUT_EN 0x04 /* output enable */
+#define AMD5536_GPIO_OD_EN 0x08 /* open-drain enable */
+#define AMD5536_GPIO_OUT_INVRT_EN 0x0c /* invert output */
+#define AMD5536_GPIO_PU_EN 0x18 /* pull-up enable */
+#define AMD5536_GPIO_PD_EN 0x1c /* pull-down enable */
+#define AMD5536_GPIO_IN_EN 0x20 /* input enable */
+#define AMD5536_GPIO_IN_INVRT_EN 0x24 /* invert input */
+#define AMD5536_GPIO_READ_BACK 0x30 /* read back value */
+
+struct glxpcib_softc {
+ struct device sc_dev;
+
+ struct timecounter sc_timecounter;
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+
+#if NGPIO > 0
+ /* GPIO interface */
+ bus_space_tag_t sc_gpio_iot;
+ bus_space_handle_t sc_gpio_ioh;
+ struct gpio_chipset_tag sc_gpio_gc;
+ gpio_pin_t sc_gpio_pins[AMD5536_GPIO_NPINS];
+#endif
+};
+
+struct cfdriver glxpcib_cd = {
+ NULL, "glxpcib", DV_DULL
+};
+
+int glxpcib_match(struct device *, void *, void *);
+void glxpcib_attach(struct device *, struct device *, void *);
+
+struct cfattach glxpcib_ca = {
+ sizeof(struct glxpcib_softc), glxpcib_match, glxpcib_attach
+};
+
+/* from arch/<*>/pci/pcib.c */
+void pcibattach(struct device *parent, struct device *self, void *aux);
+
+u_int glxpcib_get_timecount(struct timecounter *tc);
+
+#if NGPIO > 0
+void glxpcib_gpio_pin_ctl(void *, int, int);
+int glxpcib_gpio_pin_read(void *, int);
+void glxpcib_gpio_pin_write(void *, int, int);
+int glxpcib_wdogctl_cb(void *, int);
+#endif
+
+const struct pci_matchid glxpcib_devices[] = {
+ { PCI_VENDOR_AMD, PCI_PRODUCT_AMD_CS5536_PCIB }
+};
+
+int
+glxpcib_match(struct device *parent, void *match, void *aux)
+{
+ if (pci_matchbyid((struct pci_attach_args *)aux, glxpcib_devices,
+ sizeof(glxpcib_devices) / sizeof(glxpcib_devices[0])))
+ return 2;
+
+ return 0;
+}
+
+void
+glxpcib_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct glxpcib_softc *sc = (struct glxpcib_softc *)self;
+ struct timecounter *tc = &sc->sc_timecounter;
+#if NGPIO > 0
+ u_int64_t wa, ga;
+ struct gpiobus_attach_args gba;
+ int i, gpio = 0;
+#endif
+
+ tc->tc_get_timecount = glxpcib_get_timecount;
+ tc->tc_counter_mask = 0xffffffff;
+ tc->tc_frequency = 3579545;
+ tc->tc_name = "CS5536";
+ tc->tc_quality = 1000;
+ tc->tc_priv = sc;
+ tc_init(tc);
+
+ printf(": rev %d, 32-bit %lluHz timer",
+ (int)rdmsr(AMD5536_REV) & AMD5536_REV_MASK,
+ tc->tc_frequency);
+
+#if NGPIO > 0
+ /* Attach the watchdog timer */
+ sc->sc_iot = pa->pa_iot;
+ wa = rdmsr(MSR_LBAR_MFGPT);
+ if (wa & 0x100000000ULL &&
+ !bus_space_map(sc->sc_iot, wa & 0xffff, 64, 0, &sc->sc_ioh)) {
+
+ /* count in seconds (as upper level desires) */
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_SETUP,
+ AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2EV |
+ AMD5536_MFGPT_CMP2 | AMD5536_MFGPT_DIV_MASK);
+ wdog_register(sc, glxpcib_wdogctl_cb);
+ printf(", watchdog");
+ }
+
+ /* map GPIO I/O space */
+ sc->sc_gpio_iot = pa->pa_iot;
+ ga = rdmsr(MSR_LBAR_GPIO);
+ if (ga & 0x100000000ULL &&
+ !bus_space_map(sc->sc_gpio_iot, ga & 0xffff, 0xff, 0,
+ &sc->sc_gpio_ioh)) {
+ printf(", gpio");
+
+ /* initialize pin array */
+ for (i = 0; i < AMD5536_GPIO_NPINS; i++) {
+ sc->sc_gpio_pins[i].pin_num = i;
+ sc->sc_gpio_pins[i].pin_caps = GPIO_PIN_INPUT |
+ GPIO_PIN_OUTPUT | GPIO_PIN_OPENDRAIN |
+ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN |
+ GPIO_PIN_INVIN | GPIO_PIN_INVOUT;
+
+ /* read initial state */
+ sc->sc_gpio_pins[i].pin_state =
+ glxpcib_gpio_pin_read(sc, i);
+ }
+
+ /* create controller tag */
+ sc->sc_gpio_gc.gp_cookie = sc;
+ sc->sc_gpio_gc.gp_pin_read = glxpcib_gpio_pin_read;
+ sc->sc_gpio_gc.gp_pin_write = glxpcib_gpio_pin_write;
+ sc->sc_gpio_gc.gp_pin_ctl = glxpcib_gpio_pin_ctl;
+
+ gba.gba_name = "gpio";
+ gba.gba_gc = &sc->sc_gpio_gc;
+ gba.gba_pins = sc->sc_gpio_pins;
+ gba.gba_npins = AMD5536_GPIO_NPINS;
+ gpio = 1;
+
+ }
+#endif
+ pcibattach(parent, self, aux);
+
+#if NGPIO > 0
+ if (gpio)
+ config_found(&sc->sc_dev, &gba, gpiobus_print);
+#endif
+}
+
+u_int
+glxpcib_get_timecount(struct timecounter *tc)
+{
+ return rdmsr(AMD5536_TMC);
+}
+
+#if NGPIO > 0
+int
+glxpcib_wdogctl_cb(void *v, int period)
+{
+ struct glxpcib_softc *sc = v;
+
+ if (period > 0xffff)
+ period = 0xffff;
+
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_SETUP,
+ AMD5536_MFGPT_CNT_EN | AMD5536_MFGPT_CMP2);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_CNT, 0);
+ bus_space_write_2(sc->sc_iot, sc->sc_ioh, AMD5536_MFGPT0_CMP2, period);
+
+ if (period)
+ wrmsr(AMD5536_MFGPT_NR,
+ rdmsr(AMD5536_MFGPT_NR) | AMD5536_MFGPT0_C2_RSTEN);
+ else
+ wrmsr(AMD5536_MFGPT_NR,
+ rdmsr(AMD5536_MFGPT_NR) & ~AMD5536_MFGPT0_C2_RSTEN);
+
+ return period;
+}
+
+int
+glxpcib_gpio_pin_read(void *arg, int pin)
+{
+ struct glxpcib_softc *sc = arg;
+ u_int32_t data;
+ int reg, off = 0;
+
+ reg = AMD5536_GPIO_IN_EN;
+ if (pin > 15) {
+ pin &= 0x0f;
+ off = AMD5536_GPIOH_OFFSET;
+ }
+ reg += off;
+ data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
+
+ if (data & (1 << pin))
+ reg = AMD5536_GPIO_READ_BACK + off;
+ else
+ reg = AMD5536_GPIO_OUT_VAL + off;
+
+ data = bus_space_read_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg);
+
+ return data & 1 << pin ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
+}
+
+void
+glxpcib_gpio_pin_write(void *arg, int pin, int value)
+{
+ struct glxpcib_softc *sc = arg;
+ u_int32_t data;
+ int reg;
+
+ reg = AMD5536_GPIO_OUT_VAL;
+ if (pin > 15) {
+ pin &= 0x0f;
+ reg += AMD5536_GPIOH_OFFSET;
+ }
+ if (value == 1)
+ data = 1 << pin;
+ else
+ data = 1 << (pin + 16);
+
+ bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg, data);
+}
+
+void
+glxpcib_gpio_pin_ctl(void *arg, int pin, int flags)
+{
+ struct glxpcib_softc *sc = arg;
+ int n, reg[7], val[7], nreg = 0, off = 0;
+
+ if (pin > 15) {
+ pin &= 0x0f;
+ off = AMD5536_GPIOH_OFFSET;
+ }
+
+ reg[nreg] = AMD5536_GPIO_IN_EN + off;
+ if (flags & GPIO_PIN_INPUT)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_OUT_EN + off;
+ if (flags & GPIO_PIN_OUTPUT)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_OD_EN + off;
+ if (flags & GPIO_PIN_OPENDRAIN)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_PU_EN + off;
+ if (flags & GPIO_PIN_PULLUP)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_PD_EN + off;
+ if (flags & GPIO_PIN_PULLDOWN)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_IN_INVRT_EN + off;
+ if (flags & GPIO_PIN_INVIN)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ reg[nreg] = AMD5536_GPIO_OUT_INVRT_EN + off;
+ if (flags & GPIO_PIN_INVOUT)
+ val[nreg++] = 1 << pin;
+ else
+ val[nreg++] = 1 << (pin + 16);
+
+ /* set flags */
+ for (n = 0; n < nreg; n++)
+ bus_space_write_4(sc->sc_gpio_iot, sc->sc_gpio_ioh, reg[n],
+ val[n]);
+}
+
+#endif
diff --git a/sys/arch/loongson/dev/glxreg.h b/sys/arch/loongson/dev/glxreg.h
new file mode 100644
index 00000000000..3297afe0829
--- /dev/null
+++ b/sys/arch/loongson/dev/glxreg.h
@@ -0,0 +1,292 @@
+/* $OpenBSD: glxreg.h,v 1.1 2009/12/25 21:04:27 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.
+ */
+
+/*
+ * AMD 5536 Geode companion chip MSR registers
+ */
+
+/*
+ * Base addresses of the MSR groups.
+ */
+
+#ifdef __loongson__
+#define SB_MSR_BASE 0x00000000
+#define GLIU_MSR_BASE 0x10000000
+#define USB_MSR_BASE 0x40000000
+#define IDE_MSR_BASE 0x60000000
+#define DIVIL_MSR_BASE 0x80000000
+#define ACC_MSR_BASE 0xa0000000
+#define GLCP_MSR_BASE 0xe0000000
+#else
+#define SB_MSR_BASE 0x51000000
+#define GLIU_MSR_BASE 0x51010000
+#define USB_MSR_BASE 0x51200000
+#define IDE_MSR_BASE 0x51300000
+#define DIVIL_MSR_BASE 0x51400000
+#define ACC_MSR_BASE 0x51500000
+#define GLCP_MSR_BASE 0x51700000
+#endif
+
+/*
+ * GeodeLink Interface Unit (GLIU)
+ */
+
+#define GLIU_GLD_MSR_CAP (GLIU_MSR_BASE + 0x00)
+#define GLIU_GLD_MSR_CONFIG (GLIU_MSR_BASE + 0x01)
+#define GLIU_GLD_MSR_SMI (GLIU_MSR_BASE + 0x02)
+#define GLIU_GLD_MSR_ERROR (GLIU_MSR_BASE + 0x03)
+#define GLIU_GLD_MSR_PM (GLIU_MSR_BASE + 0x04)
+#define GLIU_GLD_MSR_DIAG (GLIU_MSR_BASE + 0x05)
+
+#define GLIU_P2D_BM0 (GLIU_MSR_BASE + 0x20)
+#define GLIU_P2D_BM1 (GLIU_MSR_BASE + 0x21)
+#define GLIU_P2D_BM2 (GLIU_MSR_BASE + 0x22)
+#define GLIU_P2D_BMK0 (GLIU_MSR_BASE + 0x23)
+#define GLIU_P2D_BMK1 (GLIU_MSR_BASE + 0x24)
+#define GLIU_P2D_BM3 (GLIU_MSR_BASE + 0x25)
+#define GLIU_P2D_BM4 (GLIU_MSR_BASE + 0x26)
+
+#define GLIU_COH (GLIU_MSR_BASE + 0x80)
+#define GLIU_PAE (GLIU_MSR_BASE + 0x81)
+#define GLIU_ARB (GLIU_MSR_BASE + 0x82)
+#define GLIU_ASMI (GLIU_MSR_BASE + 0x83)
+#define GLIU_AERR (GLIU_MSR_BASE + 0x84)
+#define GLIU_DEBUG (GLIU_MSR_BASE + 0x85)
+#define GLIU_PHY_CAP (GLIU_MSR_BASE + 0x86)
+#define GLIU_NOUT_RESP (GLIU_MSR_BASE + 0x87)
+#define GLIU_NOUT_WDATA (GLIU_MSR_BASE + 0x88)
+#define GLIU_WHOAMI (GLIU_MSR_BASE + 0x8b)
+#define GLIU_SLV_DIS (GLIU_MSR_BASE + 0x8c)
+#define GLIU_STATISTIC_CNT0 (GLIU_MSR_BASE + 0xa0)
+#define GLIU_STATISTIC_MASK0 (GLIU_MSR_BASE + 0xa1)
+#define GLIU_STATISTIC_ACTION0 (GLIU_MSR_BASE + 0xa2)
+#define GLIU_STATISTIC_CNT1 (GLIU_MSR_BASE + 0xa4)
+#define GLIU_STATISTIC_MASK1 (GLIU_MSR_BASE + 0xa5)
+#define GLIU_STATISTIC_ACTION1 (GLIU_MSR_BASE + 0xa6)
+#define GLIU_STATISTIC_CNT2 (GLIU_MSR_BASE + 0xa8)
+#define GLIU_STATISTIC_MASK2 (GLIU_MSR_BASE + 0xa9)
+#define GLIU_STATISTIC_ACTION2 (GLIU_MSR_BASE + 0xaa)
+#define GLIU_RQ_COMP_VAL (GLIU_MSR_BASE + 0xc0)
+#define GLIU_RQ_COMP_MASK (GLIU_MSR_BASE + 0xc1)
+#define GLIU_DA_COMP_VAL_LO (GLIU_MSR_BASE + 0xd0)
+#define GLIU_DA_COMP_VAL_HI (GLIU_MSR_BASE + 0xd1)
+#define GLIU_DA_COMP_MASK_LO (GLIU_MSR_BASE + 0xd2)
+#define GLIU_DA_COMP_MASK_HI (GLIU_MSR_BASE + 0xd3)
+
+#define GLIU_IOD_BM0 (GLIU_MSR_BASE + 0xe0)
+#define GLIU_IOD_BM1 (GLIU_MSR_BASE + 0xe1)
+#define GLIU_IOD_BM2 (GLIU_MSR_BASE + 0xe2)
+#define GLIU_IOD_BM3 (GLIU_MSR_BASE + 0xe3)
+#define GLIU_IOD_BM4 (GLIU_MSR_BASE + 0xe4)
+#define GLIU_IOD_BM5 (GLIU_MSR_BASE + 0xe5)
+#define GLIU_IOD_BM6 (GLIU_MSR_BASE + 0xe6)
+#define GLIU_IOD_BM7 (GLIU_MSR_BASE + 0xe7)
+#define GLIU_IOD_BM8 (GLIU_MSR_BASE + 0xe8)
+#define GLIU_IOD_BM9 (GLIU_MSR_BASE + 0xe9)
+#define GLIU_IOD_SC0 (GLIU_MSR_BASE + 0xea)
+#define GLIU_IOD_SC1 (GLIU_MSR_BASE + 0xeb)
+#define GLIU_IOD_SC2 (GLIU_MSR_BASE + 0xec)
+#define GLIU_IOD_SC3 (GLIU_MSR_BASE + 0xed)
+#define GLIU_IOD_SC4 (GLIU_MSR_BASE + 0xee)
+#define GLIU_IOD_SC5 (GLIU_MSR_BASE + 0xef)
+#define GLIU_IOD_SC6 (GLIU_MSR_BASE + 0xf0)
+#define GLIU_IOD_SC7 (GLIU_MSR_BASE + 0xf1)
+
+/*
+ * GeodeLink PCI South Bridge (SB)
+ */
+
+#define GLPCI_GLD_MSR_CAP (SB_MSR_BASE + 0x00)
+#define GLPCI_GLD_MSR_CONFIG (SB_MSR_BASE + 0x01)
+#define GLPCI_GLD_MSR_SMI (SB_MSR_BASE + 0x02)
+#define GLPCI_GLD_MSR_ERROR (SB_MSR_BASE + 0x03)
+#define GLPCI_GLD_MSR_PM (SB_MSR_BASE + 0x04)
+#define GLPCI_GLD_MSR_DIAG (SB_MSR_BASE + 0x05)
+
+#define GLPCI_CTRL (SB_MSR_BASE + 0x10)
+#define GLPCI_R0 (SB_MSR_BASE + 0x20)
+#define GLPCI_R1 (SB_MSR_BASE + 0x21)
+#define GLPCI_R2 (SB_MSR_BASE + 0x22)
+#define GLPCI_R3 (SB_MSR_BASE + 0x23)
+#define GLPCI_R4 (SB_MSR_BASE + 0x24)
+#define GLPCI_R5 (SB_MSR_BASE + 0x25)
+#define GLPCI_R6 (SB_MSR_BASE + 0x26)
+#define GLPCI_R7 (SB_MSR_BASE + 0x27)
+#define GLPCI_R8 (SB_MSR_BASE + 0x28)
+#define GLPCI_R9 (SB_MSR_BASE + 0x29)
+#define GLPCI_R10 (SB_MSR_BASE + 0x2a)
+#define GLPCI_R11 (SB_MSR_BASE + 0x2b)
+#define GLPCI_R12 (SB_MSR_BASE + 0x2c)
+#define GLPCI_R13 (SB_MSR_BASE + 0x2d)
+#define GLPCI_R14 (SB_MSR_BASE + 0x2e)
+#define GLPCI_R15 (SB_MSR_BASE + 0x2f)
+#define GLPCI_PCIHEAD_BYTE0_3 (SB_MSR_BASE + 0x30)
+#define GLPCI_PCIHEAD_BYTE4_7 (SB_MSR_BASE + 0x31)
+#define GLPCI_PCIHEAD_BYTE8_B (SB_MSR_BASE + 0x32)
+#define GLPCI_PCIHEAD_BYTEC_F (SB_MSR_BASE + 0x33)
+
+/*
+ * AC97 Audio Codec Controller (ACC)
+ */
+
+#define ACC_GLD_MSR_CAP (ACC_MSR_BASE + 0x00)
+#define ACC_GLD_MSR_CONFIG (ACC_MSR_BASE + 0x01)
+#define ACC_GLD_MSR_SMI (ACC_MSR_BASE + 0x02)
+#define ACC_GLD_MSR_ERROR (ACC_MSR_BASE + 0x03)
+#define ACC_GLD_MSR_PM (ACC_MSR_BASE + 0x04)
+#define ACC_GLD_MSR_DIAG (ACC_MSR_BASE + 0x05)
+
+/*
+ * USB Controller Registers (USB)
+ */
+
+#define USB_GLD_MSR_CAP (USB_MSR_BASE + 0x00)
+#define USB_GLD_MSR_CONFIG (USB_MSR_BASE + 0x01)
+#define USB_GLD_MSR_SMI (USB_MSR_BASE + 0x02)
+#define USB_GLD_MSR_ERROR (USB_MSR_BASE + 0x03)
+#define USB_GLD_MSR_PM (USB_MSR_BASE + 0x04)
+#define USB_GLD_MSR_DIAG (USB_MSR_BASE + 0x05)
+
+#define USB_MSR_OHCB (USB_MSR_BASE + 0x08)
+#define USB_MSR_EHCB (USB_MSR_BASE + 0x09)
+#define USB_MSR_UDCB (USB_MSR_BASE + 0x0a)
+#define USB_MSR_UOCB (USB_MSR_BASE + 0x0b)
+
+/*
+ * IDE Controller Registers (IDE)
+ */
+
+#define IDE_GLD_MSR_CAP (IDE_MSR_BASE + 0x00)
+#define IDE_GLD_MSR_CONFIG (IDE_MSR_BASE + 0x01)
+#define IDE_GLD_MSR_SMI (IDE_MSR_BASE + 0x02)
+#define IDE_GLD_MSR_ERROR (IDE_MSR_BASE + 0x03)
+#define IDE_GLD_MSR_PM (IDE_MSR_BASE + 0x04)
+#define IDE_GLD_MSR_DIAG (IDE_MSR_BASE + 0x05)
+
+#define IDE_IO_BAR (IDE_MSR_BASE + 0x08)
+#define IDE_CFG (IDE_MSR_BASE + 0x10)
+#define IDE_DTC (IDE_MSR_BASE + 0x12)
+#define IDE_CAST (IDE_MSR_BASE + 0x13)
+#define IDE_ETC (IDE_MSR_BASE + 0x14)
+#define IDE_PM (IDE_MSR_BASE + 0x15)
+
+/*
+ * Diverse Integration Logic (DIVIL)
+ */
+
+#define DIVIL_GLD_MSR_CAP (DIVIL_MSR_BASE + 0x00)
+#define DIVIL_GLD_MSR_CONFIG (DIVIL_MSR_BASE + 0x01)
+#define DIVIL_GLD_MSR_SMI (DIVIL_MSR_BASE + 0x02)
+#define DIVIL_GLD_MSR_ERROR (DIVIL_MSR_BASE + 0x03)
+#define DIVIL_GLD_MSR_PM (DIVIL_MSR_BASE + 0x04)
+#define DIVIL_GLD_MSR_DIAG (DIVIL_MSR_BASE + 0x05)
+
+#define DIVIL_LBAR_IRQ (DIVIL_MSR_BASE + 0x08)
+#define DIVIL_LBAR_KEL (DIVIL_MSR_BASE + 0x09)
+#define DIVIL_LBAR_SMB (DIVIL_MSR_BASE + 0x0b)
+#define DIVIL_LBAR_GPIO (DIVIL_MSR_BASE + 0x0c)
+#define DIVIL_LBAR_MFGPT (DIVIL_MSR_BASE + 0x0d)
+#define DIVIL_LBAR_ACPI (DIVIL_MSR_BASE + 0x0e)
+#define DIVIL_LBAR_PMS (DIVIL_MSR_BASE + 0x0f)
+#define DIVIL_LBAR_FLSH0 (DIVIL_MSR_BASE + 0x10)
+#define DIVIL_LBAR_FLSH1 (DIVIL_MSR_BASE + 0x11)
+#define DIVIL_LBAR_FLSH2 (DIVIL_MSR_BASE + 0x12)
+#define DIVIL_LBAR_FLSH3 (DIVIL_MSR_BASE + 0x13)
+#define DIVIL_LEG_IO (DIVIL_MSR_BASE + 0x14)
+#define DIVIL_BALL_OPTS (DIVIL_MSR_BASE + 0x15)
+#define DIVIL_SOFT_IRQ (DIVIL_MSR_BASE + 0x16)
+#define DIVIL_SOFT_RESET (DIVIL_MSR_BASE + 0x17)
+#define NORF_CTL (DIVIL_MSR_BASE + 0x18)
+#define NORF_T01 (DIVIL_MSR_BASE + 0x19)
+#define NORF_T23 (DIVIL_MSR_BASE + 0x1a)
+#define NANDF_DATA (DIVIL_MSR_BASE + 0x1b)
+#define NANDF_CTL (DIVIL_MSR_BASE + 0x1c)
+#define NANDF_RSVD (DIVIL_MSR_BASE + 0x1d)
+#define DIVIL_AC_DMA (DIVIL_MSR_BASE + 0x1e)
+#define KELX_CTL (DIVIL_MSR_BASE + 0x1f)
+#define PIC_YSEL_LOW (DIVIL_MSR_BASE + 0x20)
+#define PIC_YSEL_HIGH (DIVIL_MSR_BASE + 0x21)
+#define PIC_ZSEL_LOW (DIVIL_MSR_BASE + 0x22)
+#define PIC_ZSEL_HIGH (DIVIL_MSR_BASE + 0x23)
+#define PIC_IRQM_PRIM (DIVIL_MSR_BASE + 0x24)
+#define PIC_IRQM_LPC (DIVIL_MSR_BASE + 0x25)
+#define PIC_XIRR_STS_LOW (DIVIL_MSR_BASE + 0x26)
+#define PIC_XIRR_STS_HIGH (DIVIL_MSR_BASE + 0x27)
+#define MFGPT_IRQ (DIVIL_MSR_BASE + 0x28)
+#define MFGPT_NR (DIVIL_MSR_BASE + 0x29)
+#define MFGPT_RSVD (DIVIL_MSR_BASE + 0x2a)
+#define MFGPT_SETUP (DIVIL_MSR_BASE + 0x2b)
+#define FLPY_3F2_SHDW (DIVIL_MSR_BASE + 0x30)
+#define FLPY_3F7_SHDW (DIVIL_MSR_BASE + 0x31)
+#define FLPY_372_SHDW (DIVIL_MSR_BASE + 0x32)
+#define FLPY_377_SHDW (DIVIL_MSR_BASE + 0x33)
+#define PIC_SHDW (DIVIL_MSR_BASE + 0x34)
+#define PIT_SHDW (DIVIL_MSR_BASE + 0x36)
+#define PIT_CNTRL (DIVIL_MSR_BASE + 0x37)
+#define UART1_MOD (DIVIL_MSR_BASE + 0x38)
+#define UART1_DONG (DIVIL_MSR_BASE + 0x39)
+#define UART1_CONF (DIVIL_MSR_BASE + 0x3a)
+#define UART1_RSVD_MSR (DIVIL_MSR_BASE + 0x3b)
+#define UART2_MOD (DIVIL_MSR_BASE + 0x3c)
+#define UART2_DONG (DIVIL_MSR_BASE + 0x3d)
+#define UART2_CONF (DIVIL_MSR_BASE + 0x3e)
+#define UART2_RSVD_MSR (DIVIL_MSR_BASE + 0x3f)
+#define DMA_MAP (DIVIL_MSR_BASE + 0x40)
+#define DMA_SHDW_CH0 (DIVIL_MSR_BASE + 0x41)
+#define DMA_SHDW_CH1 (DIVIL_MSR_BASE + 0x42)
+#define DMA_SHDW_CH2 (DIVIL_MSR_BASE + 0x43)
+#define DMA_SHDW_CH3 (DIVIL_MSR_BASE + 0x44)
+#define DMA_SHDW_CH4 (DIVIL_MSR_BASE + 0x45)
+#define DMA_SHDW_CH5 (DIVIL_MSR_BASE + 0x46)
+#define DMA_SHDW_CH6 (DIVIL_MSR_BASE + 0x47)
+#define DMA_SHDW_CH7 (DIVIL_MSR_BASE + 0x48)
+#define DMA_MSK_SHDW (DIVIL_MSR_BASE + 0x49)
+#define LPC_EADDR (DIVIL_MSR_BASE + 0x4c)
+#define LPC_ESTAT (DIVIL_MSR_BASE + 0x4d)
+#define LPC_SIRQ (DIVIL_MSR_BASE + 0x4e)
+#define LPC_RSVD (DIVIL_MSR_BASE + 0x4f)
+#define PMC_LTMR (DIVIL_MSR_BASE + 0x50)
+#define PMC_RSVD (DIVIL_MSR_BASE + 0x51)
+#define RTC_RAM_LOCK (DIVIL_MSR_BASE + 0x54)
+#define RTC_DOMA_OFFSET (DIVIL_MSR_BASE + 0x55)
+#define RTC_MONA_OFFSET (DIVIL_MSR_BASE + 0x56)
+#define RTC_CEN_OFFSET (DIVIL_MSR_BASE + 0x57)
+
+/*
+ * GeodeLink Control Processor (GLCP)
+ */
+
+#define GLCP_GLD_MSR_CAP (GLCP_MSR_BASE + 0x00)
+#define GLCP_GLD_MSR_CONFIG (GLCP_MSR_BASE + 0x01)
+#define GLCP_GLD_MSR_SMI (GLCP_MSR_BASE + 0x02)
+#define GLCP_GLD_MSR_ERROR (GLCP_MSR_BASE + 0x03)
+#define GLCP_GLD_MSR_PM (GLCP_MSR_BASE + 0x04)
+#define GLCP_GLD_MSR_DIAG (GLCP_MSR_BASE + 0x05)
+
+#define GLCP_CLK_DIS_DELAY (GLCP_MSR_BASE + 0x08)
+#define GLCP_PMCLKDISABLE (GLCP_MSR_BASE + 0x09)
+#define GLCP_GLB_PM (GLCP_MSR_BASE + 0x0b)
+#define GLCP_DBGOUT (GLCP_MSR_BASE + 0x0c)
+#define GLCP_DOWSER (GLCP_MSR_BASE + 0x0e)
+#define GLCP_CLKOFF (GLCP_MSR_BASE + 0x10)
+#define GLCP_CLKACTIVE (GLCP_MSR_BASE + 0x11)
+#define GLCP_CLKDISABLE (GLCP_MSR_BASE + 0x12)
+#define GLCP_CLK4ACK (GLCP_MSR_BASE + 0x13)
+#define GLCP_SYS_RST (GLCP_MSR_BASE + 0x14)
+#define GLCP_DBGCLKCTRL (GLCP_MSR_BASE + 0x16)
+#define GLCP_CHIP_REV_ID (GLCP_MSR_BASE + 0x17)
diff --git a/sys/arch/loongson/dev/mcclock.c b/sys/arch/loongson/dev/mcclock.c
new file mode 100644
index 00000000000..b0b9b3e4bd8
--- /dev/null
+++ b/sys/arch/loongson/dev/mcclock.c
@@ -0,0 +1,128 @@
+/* $OpenBSD: mcclock.c,v 1.1 2009/12/25 21:04:30 miod Exp $ */
+/* $NetBSD: mcclock.c,v 1.4 1996/10/13 02:59:41 christos Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <mips64/dev/clockvar.h>
+#include <loongson/dev/mcclockvar.h>
+#include <dev/ic/mc146818reg.h>
+
+struct cfdriver mcclock_cd = {
+ NULL, "mcclock", DV_DULL,
+};
+
+void mcclock_get(void *, time_t, struct tod_time *);
+void mcclock_set(void *, struct tod_time *);
+
+struct tod_desc mcclock_clockfns = {
+ NULL, mcclock_get, mcclock_set,
+};
+
+#define mc146818_write(dev, reg, datum) \
+ (*(dev)->sc_busfns->mc_bf_write)(dev, reg, datum)
+#define mc146818_read(dev, reg) \
+ (*(dev)->sc_busfns->mc_bf_read)(dev, reg)
+
+void
+mcclock_attach(sc, busfns)
+ struct mcclock_softc *sc;
+ const struct mcclock_busfns *busfns;
+{
+
+ printf(": mc146818 or compatible\n");
+
+ sc->sc_busfns = busfns;
+
+ /* Turn interrupts off, just in case. */
+ mc146818_write(sc, MC_REGB, MC_REGB_BINARY | MC_REGB_24HR);
+ mc146818_write(sc, MC_REGA, MC_BASE_32_KHz | MC_RATE_NONE);
+
+ sys_tod.tod_cookie = sc;
+ sys_tod.tod_get = mcclock_get;
+ sys_tod.tod_set = mcclock_set;
+}
+
+/*
+ * Get the time of day, based on the clock's value and/or the base value.
+ */
+void
+mcclock_get(dev, base, ct)
+ void *dev;
+ time_t base;
+ struct tod_time *ct;
+{
+ struct mcclock_softc *sc = (struct mcclock_softc *)dev;
+ mc_todregs regs;
+ int s;
+
+ s = splclock();
+ MC146818_GETTOD(sc, &regs)
+ splx(s);
+
+ ct->sec = regs[MC_SEC];
+ ct->min = regs[MC_MIN];
+ ct->hour = regs[MC_HOUR];
+ ct->dow = regs[MC_DOW];
+ ct->day = regs[MC_DOM];
+ ct->mon = regs[MC_MONTH];
+ ct->year = regs[MC_YEAR];
+}
+
+/*
+ * Reset the TODR based on the time value.
+ */
+void
+mcclock_set(dev, ct)
+ void *dev;
+ struct tod_time *ct;
+{
+ struct mcclock_softc *sc = (struct mcclock_softc *)dev;
+ mc_todregs regs;
+ int s;
+
+ s = splclock();
+ MC146818_GETTOD(sc, &regs);
+ splx(s);
+
+ regs[MC_SEC] = ct->sec;
+ regs[MC_MIN] = ct->min;
+ regs[MC_HOUR] = ct->hour;
+ regs[MC_DOW] = ct->dow;
+ regs[MC_DOM] = ct->day;
+ regs[MC_MONTH] = ct->mon;
+ regs[MC_YEAR] = ct->year;
+
+ s = splclock();
+ MC146818_PUTTOD(sc, &regs);
+ splx(s);
+}
diff --git a/sys/arch/loongson/dev/mcclock_isa.c b/sys/arch/loongson/dev/mcclock_isa.c
new file mode 100644
index 00000000000..f4ee8777bba
--- /dev/null
+++ b/sys/arch/loongson/dev/mcclock_isa.c
@@ -0,0 +1,131 @@
+/* $OpenBSD: mcclock_isa.c,v 1.1.1.1 2009/12/25 21:04:32 miod Exp $ */
+/* $NetBSD: mcclock_isa.c,v 1.5 1996/12/05 01:39:29 cgd Exp $ */
+
+/*
+ * Copyright (c) 1995, 1996 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <mips64/dev/clockvar.h>
+#include <loongson/dev/mcclockvar.h>
+#include <dev/ic/mc146818reg.h>
+#include <dev/isa/isavar.h>
+
+struct mcclock_isa_softc {
+ struct mcclock_softc sc_mcclock;
+
+ bus_space_tag_t sc_iot;
+ bus_space_handle_t sc_ioh;
+};
+
+int mcclock_isa_match(struct device *, void *, void *);
+void mcclock_isa_attach(struct device *, struct device *, void *);
+
+struct cfattach mcclock_isa_ca = {
+ sizeof (struct mcclock_isa_softc), mcclock_isa_match,
+ mcclock_isa_attach,
+};
+
+void mcclock_isa_write(struct mcclock_softc *, u_int, u_int);
+u_int mcclock_isa_read(struct mcclock_softc *, u_int);
+
+const struct mcclock_busfns mcclock_isa_busfns = {
+ mcclock_isa_write, mcclock_isa_read,
+};
+
+int
+mcclock_isa_match(parent, match, aux)
+ struct device *parent;
+ void *match;
+ void *aux;
+{
+ struct isa_attach_args *ia = aux;
+ bus_space_handle_t ioh;
+
+ if ((ia->ia_iobase != IOBASEUNK && ia->ia_iobase != 0x70) ||
+ /* (ia->ia_iosize != 0 && ia->ia_iosize != 0x2) || XXX isa.c */
+ ia->ia_maddr != MADDRUNK || ia->ia_msize != 0 ||
+ ia->ia_irq != IRQUNK || ia->ia_drq != DRQUNK)
+ return (0);
+
+ if (bus_space_map(ia->ia_iot, 0x70, 0x2, 0, &ioh))
+ return (0);
+
+ bus_space_unmap(ia->ia_iot, ioh, 0x2);
+
+ ia->ia_iobase = 0x70;
+ ia->ia_iosize = 0x2;
+
+ return (1);
+}
+
+void
+mcclock_isa_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ struct isa_attach_args *ia = aux;
+ struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)self;
+
+ sc->sc_iot = ia->ia_iot;
+ if (bus_space_map(sc->sc_iot, ia->ia_iobase, ia->ia_iosize, 0,
+ &sc->sc_ioh))
+ panic("mcclock_isa_attach: couldn't map clock I/O space");
+
+ mcclock_attach(&sc->sc_mcclock, &mcclock_isa_busfns);
+}
+
+void
+mcclock_isa_write(mcsc, reg, datum)
+ struct mcclock_softc *mcsc;
+ u_int reg, datum;
+{
+ struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)mcsc;
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
+
+ bus_space_write_1(iot, ioh, 0, reg);
+ bus_space_write_1(iot, ioh, 1, datum);
+}
+
+u_int
+mcclock_isa_read(mcsc, reg)
+ struct mcclock_softc *mcsc;
+ u_int reg;
+{
+ struct mcclock_isa_softc *sc = (struct mcclock_isa_softc *)mcsc;
+ bus_space_tag_t iot = sc->sc_iot;
+ bus_space_handle_t ioh = sc->sc_ioh;
+
+ bus_space_write_1(iot, ioh, 0, reg);
+ return bus_space_read_1(iot, ioh, 1);
+}
diff --git a/sys/arch/loongson/dev/pcib.c b/sys/arch/loongson/dev/pcib.c
new file mode 100644
index 00000000000..82707b43219
--- /dev/null
+++ b/sys/arch/loongson/dev/pcib.c
@@ -0,0 +1,68 @@
+/* $OpenBSD: pcib.c,v 1.1 2009/12/25 21:04:34 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <machine/bus.h>
+
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
+#include <dev/isa/isavar.h>
+
+#include <loongson/dev/glxreg.h>
+#include <loongson/dev/glxvar.h>
+
+#include "isa.h"
+
+void pcibattach(struct device *, struct device *, void *);
+int pcib_print(void *, const char *);
+
+void
+pcibattach(struct device *parent, struct device *self, void *aux)
+{
+ struct pci_attach_args *pa = aux;
+ struct isabus_attach_args iba;
+
+ printf("\n");
+
+ /*
+ * Attach the ISA bus behind this bridge.
+ * Note that, since we only have a few legacy I/O devices and
+ * no ISA slots, we can attach immediately.
+ */
+ memset(&iba, 0, sizeof(iba));
+ iba.iba_busname = "isa";
+ iba.iba_iot = pa->pa_iot;
+ iba.iba_memt = pa->pa_memt;
+#if NISADMA > 0
+ iba.iba_dmat = pa->pa_dmat;
+#endif
+ config_found(self, &iba, pcib_print);
+}
+
+int
+pcib_print(void *aux, const char *pnp)
+{
+ /* Only ISAs can attach to pcib's; easy. */
+ if (pnp)
+ printf("isa at %s", pnp);
+ return (UNCONF);
+}
diff --git a/sys/arch/loongson/include/param.h b/sys/arch/loongson/include/param.h
new file mode 100644
index 00000000000..6b2eebaad89
--- /dev/null
+++ b/sys/arch/loongson/include/param.h
@@ -0,0 +1,25 @@
+/* $OpenBSD: param.h,v 1.1 2009/12/25 21:04:47 miod Exp $ */
+/* public domain */
+
+#ifndef _MACHINE_PARAM_H_
+#define _MACHINE_PARAM_H_
+
+#define MACHINE "loongson"
+#define _MACHINE loongson
+#define MACHINE_ARCH "mips64el"
+#define _MACHINE_ARCH mips64el
+
+#define MID_MACHINE MID_MIPS64
+
+/*
+ * The Loongson level 1 cache expects software to prevent virtual
+ * aliases. Unfortunately, since this cache is physically tagged,
+ * this would require all virtual address to have the same bits 14
+ * and 13 as their physical addresses, which is not something the
+ * kernel can guarantee unless the page size is at least 16KB.
+ */
+#define PAGE_SHIFT 14
+
+#include <mips64/param.h>
+
+#endif /* _MACHINE_PARAM_H_ */