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.
This commit is contained in:
parent
d7f955fd67
commit
9c3aae9403
@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/systm.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/linker.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
#include <machine/bus.h>
|
||||
@ -59,7 +60,9 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
#include <machine/metadata.h>
|
||||
#include <machine/resource.h>
|
||||
#include <machine/pc/bios.h>
|
||||
|
||||
#include "pcib_if.h"
|
||||
|
||||
@ -550,6 +553,79 @@ nexus_release_msi(device_t pcib, device_t dev, int count, int *irqs)
|
||||
return (msi_release(irqs, count));
|
||||
}
|
||||
|
||||
/* 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 bios_smap *smapbase, *smap, *smapend;
|
||||
struct resource *res;
|
||||
caddr_t kmdp;
|
||||
uint32_t smapsize;
|
||||
int error, rid;
|
||||
|
||||
/* Retrieve the system memory map from the loader. */
|
||||
kmdp = preload_search_by_type("elf kernel");
|
||||
if (kmdp == NULL)
|
||||
kmdp = preload_search_by_type("elf64 kernel");
|
||||
smapbase = (struct bios_smap *)preload_search_info(kmdp,
|
||||
MODINFO_METADATA | MODINFOMD_SMAP);
|
||||
smapsize = *((u_int32_t *)smapbase - 1);
|
||||
smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
|
||||
|
||||
rid = 0;
|
||||
for (smap = smapbase; smap < smapend; smap++) {
|
||||
if (smap->type != 0x01 || smap->length == 0)
|
||||
continue;
|
||||
error = bus_set_resource(dev, SYS_RES_MEMORY, rid, smap->base,
|
||||
smap->length);
|
||||
if (error)
|
||||
panic("ram_attach: resource %d failed set with %d", rid,
|
||||
error);
|
||||
res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 0);
|
||||
if (res == NULL)
|
||||
panic("ram_attach: resource %d failed to attach", rid);
|
||||
rid++;
|
||||
}
|
||||
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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user