summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2007-03-20 21:08:39 +0000
committerjhb <jhb@FreeBSD.org>2007-03-20 21:08:39 +0000
commit9c3aae940304a96fc50dbe9e3e92f5f783d3bf03 (patch)
treed89922f08f83dd4aa8a274080b570ff447a07dd1 /sys/i386
parentd7f955fd677357b4d95e38bdfbd4839173e00241 (diff)
downloadFreeBSD-src-9c3aae940304a96fc50dbe9e3e92f5f783d3bf03.zip
FreeBSD-src-9c3aae940304a96fc50dbe9e3e92f5f783d3bf03.tar.gz
Add a new ram0 pseudo-device that claims memory resouces for physical
addresses corresponding to system RAM. On amd64 ram0 uses the SMAP and claims all the type 1 SMAP regions. On i386 ram0 uses the dump_avail[] array. Note that on i386 we have to ignore regions above 4G in PAE kernels since bus resources use longs.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/nexus.c78
1 files changed, 78 insertions, 0 deletions
diff --git a/sys/i386/i386/nexus.c b/sys/i386/i386/nexus.c
index 069cbfc..44b3c69 100644
--- a/sys/i386/i386/nexus.c
+++ b/sys/i386/i386/nexus.c
@@ -607,6 +607,84 @@ nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs)
}
#endif
+/* Placeholder for system RAM. */
+static void
+ram_identify(driver_t *driver, device_t parent)
+{
+
+ if (resource_disabled("ram", 0))
+ return;
+ if (BUS_ADD_CHILD(parent, 0, "ram", 0) == NULL)
+ panic("ram_identify");
+}
+
+static int
+ram_probe(device_t dev)
+{
+
+ device_quiet(dev);
+ device_set_desc(dev, "System RAM");
+ return (0);
+}
+
+static int
+ram_attach(device_t dev)
+{
+ struct resource *res;
+ vm_paddr_t *p;
+ int error, i, rid;
+
+ /*
+ * We use the dump_avail[] array rather than phys_avail[] for
+ * the memory map as phys_avail[] contains holes for kernel
+ * memory, page 0, the message buffer, and the dcons buffer.
+ * We test the end address in the loop instead of the start
+ * since the start address for the first segment is 0.
+ *
+ * XXX: It would be preferable to use the SMAP if it exists
+ * instead since if the SMAP is very fragmented we may not
+ * include some memory regions in dump_avail[] and phys_avail[].
+ */
+ for (i = 0, p = dump_avail; p[1] != 0; i++, p += 2) {
+ rid = i;
+#ifdef PAE
+ /*
+ * Resources use long's to track resources, so we can't
+ * include memory regions above 4GB.
+ */
+ if (p[0] >= ~0ul)
+ break;
+#endif
+ error = bus_set_resource(dev, SYS_RES_MEMORY, rid, p[0],
+ p[1] - p[0]);
+ if (error)
+ panic("ram_attach: resource %d failed set with %d", i,
+ error);
+ res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
+ if (res == NULL)
+ panic("ram_attach: resource %d failed to attach", i);
+ }
+ return (0);
+}
+
+static device_method_t ram_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_identify, ram_identify),
+ DEVMETHOD(device_probe, ram_probe),
+ DEVMETHOD(device_attach, ram_attach),
+ { 0, 0 }
+};
+
+static driver_t ram_driver = {
+ "ram",
+ ram_methods,
+ 1, /* no softc */
+};
+
+static devclass_t ram_devclass;
+
+DRIVER_MODULE(ram, nexus, ram_driver, ram_devclass, 0, 0);
+
#ifdef DEV_ISA
/*
* Placeholder which claims PnP 'devices' which describe system
OpenPOWER on IntegriCloud