summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorticso <ticso@FreeBSD.org>2005-01-31 23:07:42 +0000
committerticso <ticso@FreeBSD.org>2005-01-31 23:07:42 +0000
commita52292b594fa4bb7a0c7120e270809cb6dbcbf65 (patch)
tree1faa5105012a81cdcf340b1e071c3fb00ae2d1a2
parentf9a616f908fb247928e898992d0217667d8dfa12 (diff)
downloadFreeBSD-src-a52292b594fa4bb7a0c7120e270809cb6dbcbf65.zip
FreeBSD-src-a52292b594fa4bb7a0c7120e270809cb6dbcbf65.tar.gz
add cpu_idle support for 21066A based lca systems
-rw-r--r--sys/alpha/alpha/machdep.c10
-rw-r--r--sys/alpha/include/cpuconf.h1
-rw-r--r--sys/alpha/pci/lca.c29
-rw-r--r--sys/alpha/pci/lcareg.h2
4 files changed, 41 insertions, 1 deletions
diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c
index 2823bc8e..d93a86d 100644
--- a/sys/alpha/alpha/machdep.c
+++ b/sys/alpha/alpha/machdep.c
@@ -1727,10 +1727,18 @@ cpu_halt(void)
prom_halt(1);
}
+static int cpu_idle_hlt = 1;
+SYSCTL_INT(_machdep, OID_AUTO, cpu_idle_hlt, CTLFLAG_RW,
+ &cpu_idle_hlt, 0, "Idle loop HLT enable");
+
+/*
+ * call platform specific code to halt (until next interrupt) for the idle loop
+ */
void
cpu_idle(void)
{
- /* Insert code to halt (until next interrupt) for the idle loop */
+ if (cpu_idle_hlt && platform.cpu_idle != NULL)
+ platform.cpu_idle();
}
/*
diff --git a/sys/alpha/include/cpuconf.h b/sys/alpha/include/cpuconf.h
index 566ccec..669ca6c 100644
--- a/sys/alpha/include/cpuconf.h
+++ b/sys/alpha/include/cpuconf.h
@@ -71,6 +71,7 @@ extern struct platform {
void (*clockintr)(void *);
void (*mcheck_handler)(unsigned long, struct trapframe *,
unsigned long, unsigned long);
+ void (*cpu_idle)(void);
void (*pci_intr_init)(void);
void (*pci_intr_map)(void *);
int (*pci_intr_route)(struct device *, struct device *, int);
diff --git a/sys/alpha/pci/lca.c b/sys/alpha/pci/lca.c
index b00cadb..e279555 100644
--- a/sys/alpha/pci/lca.c
+++ b/sys/alpha/pci/lca.c
@@ -35,6 +35,8 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <machine/bus.h>
#include <sys/rman.h>
+#include <sys/proc.h>
+#include <sys/sched.h>
#include <alpha/pci/lcareg.h>
#include <alpha/pci/lcavar.h>
@@ -222,6 +224,8 @@ static void
lca_machine_check(unsigned long mces, struct trapframe *framep,
unsigned long vector, unsigned long param);
+static void lca_cpu_idle (void);
+
static int
lca_probe(device_t dev)
{
@@ -234,6 +238,7 @@ lca_probe(device_t dev)
lca_init_sgmap();
platform.mcheck_handler = lca_machine_check;
+ platform.cpu_idle = lca_cpu_idle;
device_add_child(dev, "pcib", 0);
@@ -270,5 +275,29 @@ lca_machine_check(unsigned long mces, struct trapframe *framep,
REGVAL64(LCA_IOC_STAT0) = stat0;
}
+void
+lca_cpu_idle (void)
+{
+ /*
+ * 0x0 = 1
+ * 0x1 = 1.5
+ * 0x2 = 2
+ * 0x3 = 4
+ * 0x4 = 8
+ * 0x5 = 16
+ */
+ long override = 0x0;
+ long primary = 0x5;
+ long dma_ovr = 1;
+ long intr_ovr = 1;
+
+ REGVAL64(LCA_PMR) =
+ (dma_ovr << 7) | (intr_ovr << 6) | (override << 3) | primary;
+ if (sched_runnable()) {
+ REGVAL64(LCA_PMR) =
+ (override << 3) | override;
+ }
+}
+
DRIVER_MODULE(lca, root, lca_driver, lca_devclass, 0, 0);
diff --git a/sys/alpha/pci/lcareg.h b/sys/alpha/pci/lcareg.h
index c79a991..c6255d8 100644
--- a/sys/alpha/pci/lcareg.h
+++ b/sys/alpha/pci/lcareg.h
@@ -44,6 +44,8 @@
#define LCA_PCI_SPARSE 0x200000000L /* PCI Sparse Space */
#define LCA_PCI_DENSE 0x300000000L /* PCI Dense Space */
+#define LCA_PMR 0x120000098L /* Power Management (21066A)*/
+
#define LCA_IOC_HAE LCA_IOC_BASE /* Host Address Ext. (64) */
#define IOC_HAE_ADDREXT 0x00000000f8000000UL
#define IOC_HAE_RSVSD 0xffffffff07ffffffUL
OpenPOWER on IntegriCloud