commit 266603019eceab96582d374e3673a4f8ff870c18 Author: Andriy Gapon Date: Thu Jun 10 10:22:46 2010 +0300 [local]smap: a micromodule to (re)print SMAP information from loader diff --git a/sys/dev/smap/smap.c b/sys/dev/smap/smap.c new file mode 100644 index 0000000..e233ee2 --- /dev/null +++ b/sys/dev/smap/smap.c @@ -0,0 +1,150 @@ +/*- + * Copyright (c) 2010 Andriy Gapon + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if 0 +#include + + +struct smap_buf { + struct bios_smap smap; + uint32_t xattr; /* Extended attribute from ACPI 3.0 */ +}; +#define SMAP_BUFSIZE sizeof(struct smap_buf) + + +static int +smap_getsmap(void) +{ + x86regs_t regs; + struct smap_buf *buf; + uint32_t off; + + if (x86bios_get_intr(0x15) == 0) + return (ENXIO); + + buf = x86bios_alloc(&off, SMAP_BUFSIZE); + + x86bios_init_regs(®s); + regs.R_EBX = 0; + + do { + regs.R_EAX = 0xE820; + regs.R_ECX = SMAP_BUFSIZE; + regs.R_EDX = SMAP_SIG; + regs.R_ES = X86BIOS_PHYSTOSEG(off); + regs.R_EDI = X86BIOS_PHYSTOOFF(off); + + x86bios_intr(®s, 0x15); + + if ((regs.R_EFLG & PSL_C) != 0 || regs.R_EAX != SMAP_SIG || + regs.R_ECX < sizeof(buf->smap) || regs.R_ECX > SMAP_BUFSIZE) { + printf("error\n"); + break; + } + printf("SMAP type=%02x base=%016llx len=%016llx", + (unsigned int)buf->smap.type, + (unsigned long long)buf->smap.base, + (unsigned long long)buf->smap.length); + if (regs.R_ECX == SMAP_BUFSIZE) + printf(" attr=%02x", (unsigned int)buf->xattr); + printf("\n"); + } while (regs.R_EBX != 0); + + x86bios_free(&off, SMAP_BUFSIZE); + return (0); +} +#endif + +static void +smap_getsmap(void) +{ + struct bios_smap *smapbase, *smap, *smapend; + caddr_t kmdp; + u_int32_t smapsize; + + kmdp = preload_search_by_type("elf kernel"); + if (kmdp == NULL) + kmdp = preload_search_by_type("elf64 kernel"); + if (kmdp == NULL) { + printf("Can't find kernel!\n"); + return; + } + + /* + * get memory map from INT 15:E820, kindly supplied by the loader. + * + * subr_module.c says: + * "Consumer may safely assume that size value precedes data." + * ie: an int32_t immediately precedes smap. + */ + smapbase = (struct bios_smap *)preload_search_info(kmdp, + MODINFO_METADATA | MODINFOMD_SMAP); + if (smapbase == NULL) { + printf("No BIOS smap info from loader!\n"); + return; + } + + smapsize = *((u_int32_t *)smapbase - 1); + smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize); + + for (smap = smapbase; smap < smapend; smap++) + printf("SMAP type=%02x base=%016lx end=%016lx len=%016lx\n", + smap->type, smap->base, smap->base + smap->length, + smap->length); +} + +static int +smap_modevent(module_t mod __unused, int type, void *data __unused) +{ + switch (type) { + case MOD_LOAD: + printf("smap: loaded\n"); + smap_getsmap(); + break; + case MOD_UNLOAD: + case MOD_SHUTDOWN: + printf("smap: unloaded\n"); + break; + default: + return (EOPNOTSUPP); + } + return (0); +} +DEV_MODULE(smap, smap_modevent, NULL); diff --git a/sys/modules/smap/Makefile b/sys/modules/smap/Makefile new file mode 100644 index 0000000..cc04193 --- /dev/null +++ b/sys/modules/smap/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/smap + +KMOD= smap +SRCS= smap.c + +.include