diff options
author | msmith <msmith@FreeBSD.org> | 1999-04-07 03:57:45 +0000 |
---|---|---|
committer | msmith <msmith@FreeBSD.org> | 1999-04-07 03:57:45 +0000 |
commit | 6cdad5105e3d13b98967eb814b38490c8957bca1 (patch) | |
tree | 99c7e8db20bae641424a1880322226dbba4008b7 /sys/amd64/amd64/mem.c | |
parent | 6813d2f8711bb4421f7e07164e0c5a2379650596 (diff) | |
download | FreeBSD-src-6cdad5105e3d13b98967eb814b38490c8957bca1.zip FreeBSD-src-6cdad5105e3d13b98967eb814b38490c8957bca1.tar.gz |
mem.c
Split out ioctl handler a little more cleanly, add memory
range attribute handling for both kernel and user-space
consumers.
pmap.c
Remove obsolete P6 MTRR-related code.
i686_mem.c
Map generic memory-range attribute interface to the P6 MTRR
model.
Diffstat (limited to 'sys/amd64/amd64/mem.c')
-rw-r--r-- | sys/amd64/amd64/mem.c | 127 |
1 files changed, 119 insertions, 8 deletions
diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c index 725eaa1..36fdd27 100644 --- a/sys/amd64/amd64/mem.c +++ b/sys/amd64/amd64/mem.c @@ -38,7 +38,7 @@ * * from: Utah $Hdr: mem.c 1.13 89/10/08$ * from: @(#)mem.c 7.2 (Berkeley) 5/9/91 - * $Id: mem.c,v 1.53 1998/11/08 12:39:01 dfr Exp $ + * $Id: mem.c,v 1.54 1999/02/02 14:14:05 bde Exp $ */ /* @@ -57,13 +57,17 @@ #include <sys/kernel.h> #include <sys/systm.h> #include <sys/uio.h> +#include <sys/ioccom.h> #include <sys/malloc.h> +#include <sys/memrange.h> #include <sys/proc.h> #include <sys/signalvar.h> #include <machine/frame.h> +#include <machine/md_var.h> #include <machine/random.h> #include <machine/psl.h> +#include <machine/specialreg.h> #ifdef PERFMON #include <machine/perfmon.h> #endif @@ -75,7 +79,6 @@ #include <vm/vm_extern.h> - static d_open_t mmopen; static d_close_t mmclose; static d_read_t mmrw; @@ -92,6 +95,12 @@ static struct cdevsw mem_cdevsw = static struct random_softc random_softc[16]; static caddr_t zbuf; +MALLOC_DEFINE(M_MEMDESC, "memdesc", "memory range descriptors"); +static int mem_ioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); +static int random_ioctl __P((dev_t, u_long, caddr_t, int, struct proc *)); + +struct mem_range_softc mem_range_softc; + #ifdef DEVFS static void *mem_devfs_token; static void *kmem_devfs_token; @@ -418,23 +427,119 @@ mmioctl(dev, cmd, data, flags, p) int flags; struct proc *p; { - static intrmask_t interrupt_allowed; - intrmask_t interrupt_mask; - int error, intr; - struct random_softc *sc; switch (minor(dev)) { + case 0: + return mem_ioctl(dev, cmd, data, flags, p); case 3: case 4: - break; + return random_ioctl(dev, cmd, data, flags, p); #ifdef PERFMON case 32: return perfmon_ioctl(dev, cmd, data, flags, p); #endif + } + return (ENODEV); +} + +/* + * Operations for changing memory attributes. + * + * This is basically just an ioctl shim for mem_range_attr_get + * and mem_range_attr_set. + */ +static int +mem_ioctl(dev, cmd, data, flags, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flags; + struct proc *p; +{ + int nd, error = 0; + struct mem_range_op *mo = (struct mem_range_op *)data; + struct mem_range_desc *md; + + /* is this for us? */ + if ((cmd != MEMRANGE_GET) && + (cmd != MEMRANGE_SET)) + return(ENODEV); + + /* any chance we can handle this? */ + if (mem_range_softc.mr_op == NULL) + return(EOPNOTSUPP); + + /* do we have any descriptors? */ + if (mem_range_softc.mr_ndesc == 0) + return(ENXIO); + + switch(cmd) { + case MEMRANGE_GET: + nd = imin(mo->mo_arg[0], mem_range_softc.mr_ndesc); + if (nd > 0) { + md = (struct mem_range_desc *) + malloc(nd * sizeof(struct mem_range_desc), + M_MEMDESC, M_WAITOK); + mem_range_attr_get(md, &nd); + error = copyout(md, mo->mo_desc, + nd * sizeof(struct mem_range_desc)); + free(md, M_MEMDESC); + } else { + nd = mem_range_softc.mr_ndesc; + } + mo->mo_arg[0] = nd; + break; + + case MEMRANGE_SET: + md = (struct mem_range_desc *)malloc(sizeof(struct mem_range_desc), + M_MEMDESC, M_WAITOK); + error = copyin(mo->mo_desc, md, sizeof(struct mem_range_desc)); + /* clamp description string */ + md->mr_owner[sizeof(md->mr_owner) - 1] = 0; + if (error == 0) + error = mem_range_attr_set(md, &mo->mo_arg[0]); + free(md, M_MEMDESC); + break; + default: - return (ENODEV); + error = EOPNOTSUPP; } + return(error); +} + +/* + * Implementation-neutral, kernel-callable functions for manipulating + * memory range attributes. + */ +void +mem_range_attr_get(struct mem_range_desc *mrd, int *arg) +{ + if (*arg == 0) { + *arg = mem_range_softc.mr_ndesc; + } else { + bcopy(mem_range_softc.mr_desc, mrd, (*arg) * sizeof(struct mem_range_desc)); + } +} + +int +mem_range_attr_set(struct mem_range_desc *mrd, int *arg) +{ + return(mem_range_softc.mr_op->set(&mem_range_softc, mrd, arg)); +} +static int +random_ioctl(dev, cmd, data, flags, p) + dev_t dev; + u_long cmd; + caddr_t data; + int flags; + struct proc *p; +{ + static intrmask_t interrupt_allowed; + intrmask_t interrupt_mask; + int error, intr; + struct random_softc *sc; + /* * We're the random or urandom device. The only ioctls are for * selecting and inspecting which interrupts are used in the muck @@ -539,7 +644,13 @@ mem_drvinit(void *unused) { dev_t dev; + /* Initialise memory range handling */ + if (mem_range_softc.mr_op != NULL) + mem_range_softc.mr_op->init(&mem_range_softc); + + /* device registration */ if( ! mem_devsw_installed ) { + dev = makedev(CDEV_MAJOR, 0); cdevsw_add(&dev,&mem_cdevsw, NULL); mem_devsw_installed = 1; |