summaryrefslogtreecommitdiff
path: root/sys/arch/alpha/tc/tc_3000_500.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/alpha/tc/tc_3000_500.c')
-rw-r--r--sys/arch/alpha/tc/tc_3000_500.c97
1 files changed, 85 insertions, 12 deletions
diff --git a/sys/arch/alpha/tc/tc_3000_500.c b/sys/arch/alpha/tc/tc_3000_500.c
index 79c987a8b27..a1e03986559 100644
--- a/sys/arch/alpha/tc/tc_3000_500.c
+++ b/sys/arch/alpha/tc/tc_3000_500.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: tc_3000_500.c,v 1.9 2002/03/14 03:15:51 millert Exp $ */
-/* $NetBSD: tc_3000_500.c,v 1.12 1996/11/15 23:59:00 cgd Exp $ */
+/* $OpenBSD: tc_3000_500.c,v 1.10 2002/05/02 22:56:06 miod Exp $ */
+/* $NetBSD: tc_3000_500.c,v 1.24 2001/07/27 00:25:21 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -31,17 +31,24 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
+#include <sys/malloc.h>
#include <machine/autoconf.h>
#include <machine/pte.h>
-#ifndef EVCNT_COUNTERS
+#include <machine/rpb.h>
#include <machine/intrcnt.h>
-#endif
#include <dev/tc/tcvar.h>
#include <alpha/tc/tc_conf.h>
#include <alpha/tc/tc_3000_500.h>
+#include "wsdisplay.h"
+#include "sfb.h"
+
+#if NSFB > 0
+extern int sfb_cnattach(tc_addr_t);
+#endif
+
void tc_3000_500_intr_setup(void);
void tc_3000_500_intr_establish(struct device *, void *,
tc_intrlevel_t, int (*)(void *), void *);
@@ -49,6 +56,7 @@ void tc_3000_500_intr_disestablish(struct device *, void *);
void tc_3000_500_iointr(void *, unsigned long);
int tc_3000_500_intrnull(void *);
+int tc_3000_500_fb_cnattach(u_int64_t);
#define C(x) ((void *)(u_long)x)
#define KV(x) (ALPHA_PHYS_TO_K0SEG(x))
@@ -96,6 +104,7 @@ u_int32_t tc_3000_500_intrbits[TC_3000_500_NCOOKIES] = {
struct tcintr {
int (*tci_func)(void *);
void *tci_arg;
+ struct evcnt tci_evcnt;
} tc_3000_500_intr[TC_3000_500_NCOOKIES];
u_int32_t tc_3000_500_imask; /* intrs we want to ignore; mirrors IMR. */
@@ -103,6 +112,7 @@ u_int32_t tc_3000_500_imask; /* intrs we want to ignore; mirrors IMR. */
void
tc_3000_500_intr_setup()
{
+ char *cp;
u_long i;
/*
@@ -121,9 +131,32 @@ tc_3000_500_intr_setup()
for (i = 0; i < TC_3000_500_NCOOKIES; i++) {
tc_3000_500_intr[i].tci_func = tc_3000_500_intrnull;
tc_3000_500_intr[i].tci_arg = (void *)i;
+
+ cp = malloc(12, M_DEVBUF, M_NOWAIT);
+ if (cp == NULL)
+ panic("tc_3000_500_intr_setup");
+ sprintf(cp, "slot %lu", i);
+#ifdef EVCNT_COUNTERS
+ evcnt_attach_dynamic(&tc_3000_500_intr[i].tci_evcnt,
+ EVCNT_TYPE_INTR, NULL, "tc", cp);
+#endif
}
}
+const struct evcnt *
+tc_3000_500_intr_evcnt(tcadev, cookie)
+ struct device *tcadev;
+ void *cookie;
+{
+ u_long dev = (u_long)cookie;
+
+#ifdef DIAGNOSTIC
+ /* XXX bounds-check cookie. */
+#endif
+
+ return (&tc_3000_500_intr[dev].tci_evcnt);
+}
+
void
tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
struct device *tcadev;
@@ -138,7 +171,7 @@ tc_3000_500_intr_establish(tcadev, cookie, level, func, arg)
#endif
if (tc_3000_500_intr[dev].tci_func != tc_3000_500_intrnull)
- panic("tc_3000_500_intr_establish: cookie %d twice", dev);
+ panic("tc_3000_500_intr_establish: cookie %lu twice", dev);
tc_3000_500_intr[dev].tci_func = func;
tc_3000_500_intr[dev].tci_arg = arg;
@@ -160,7 +193,7 @@ tc_3000_500_intr_disestablish(tcadev, cookie)
#endif
if (tc_3000_500_intr[dev].tci_func == tc_3000_500_intrnull)
- panic("tc_3000_500_intr_disestablish: cookie %d bad intr",
+ panic("tc_3000_500_intr_disestablish: cookie %lu bad intr",
dev);
tc_3000_500_imask |= tc_3000_500_intrbits[dev];
@@ -181,8 +214,8 @@ tc_3000_500_intrnull(val)
}
void
-tc_3000_500_iointr(framep, vec)
- void *framep;
+tc_3000_500_iointr(arg, vec)
+ void *arg;
unsigned long vec;
{
u_int32_t ir;
@@ -209,11 +242,10 @@ tc_3000_500_iointr(framep, vec)
ifound = 0;
#ifdef EVCNT_COUNTERS
- /* No interrupt counting via evcnt counters */
- XXX BREAK HERE XXX
-#else /* !EVCNT_COUNTERS */
+#define INCRINTRCNT(slot) tc_3000_500_intr[slot].tci_evcnt.ev_count++
+#else
#define INCRINTRCNT(slot) intrcnt[INTRCNT_KN15 + slot]++
-#endif /* EVCNT_COUNTERS */
+#endif
#define CHECKINTR(slot) \
if (ir & tc_3000_500_intrbits[slot]) { \
@@ -257,6 +289,47 @@ tc_3000_500_iointr(framep, vec)
} while (ifound);
}
+#if NWSDISPLAY > 0
+/*
+ * tc_3000_500_fb_cnattach --
+ * Attempt to map the CTB output device to a slot and attach the
+ * framebuffer as the output side of the console.
+ */
+int
+tc_3000_500_fb_cnattach(turbo_slot)
+ u_int64_t turbo_slot;
+{
+ u_int32_t output_slot;
+
+ output_slot = turbo_slot & 0xffffffff;
+
+ if (output_slot >= tc_3000_500_nslots) {
+ return EINVAL;
+ }
+
+ if (hwrpb->rpb_variation & SV_GRAPHICS) {
+ if (output_slot == 0) {
+#if NSFB > 0
+ sfb_cnattach(KV(0x1e0000000) + 0x02000000);
+ return 0;
+#else
+ return ENXIO;
+#endif
+ }
+ } else {
+ /*
+ * Slots 0-2 in the tc_3000_500_slots array are only
+ * on the 500 models that also have the CXTurbo
+ * (500/800/900) and a total of 6 TC slots. For the
+ * 400/600/700, slots 0-2 are in table locations 3-5, so
+ * offset the CTB slot by 3 to get the address in our table.
+ */
+ output_slot += 3;
+ }
+ return tc_fb_cnattach(tc_3000_500_slots[output_slot-1].tcs_addr);
+}
+#endif /* NWSDISPLAY */
+
#if 0
/*
* tc_3000_500_ioslot --