On Thu, Mar 25, 2004 at 05:40:33PM -0500, Don Bowman wrote: > SMI under freebsd? Ha ha... Good luck! It didn't look very > easy. The SMM, for those who don't know it, is a virtual > 86, real-mode thing, at a location in ram which is locked > and unaccessible unless you are in smm mode :) If you > are lucky, your bios didn't lock you out of it.
I wrote code to unlock the SMM within FreeBSD last summer on an IBM T22 with the 440BX chipset. Here it is. BMS
/* $FreeBSD$ */ /* * A tool for FreeBSD to discover SMRAM on i440BX based motherboards. * This isn't finished or complete, left as exercise for the reader. */ /* * Copyright (c) 2003 Bruce M. Simpson <[EMAIL PROTECTED]> * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Bruce M. Simpson. * 4. Neither the name of Bruce M. Simpson nor the names of co- * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson 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 Bruce M. Simpson 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. */ #include <sys/param.h> #include <sys/types.h> #include <sys/fcntl.h> #include <sys/pciio.h> #include <sys/mman.h> #include <sys/memrange.h> #include <fcntl.h> #include <stddef.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <strings.h> #include <machine/sysarch.h> #include <machine/vm86.h> #include <machine/cpufunc.h> #ifndef _DEV_PCI #define _DEV_PCI "/dev/pci" #endif #ifndef _DEV_MEM #define _DEV_MEM "/dev/mem" #endif /* * It appears as though my ThinkPad does not map SMRAM at the default * location. This isn't too much of a surprise. Firmware is responsible * for reprogramming the default location, and has to issue an SMI * during boot in order to do this. The actual SMI handler code is * located at SMBASE+0x8000. A quick way of issuing the SMI is to use * the on-chip APIC. A number of vendor BIOS do it this way. * * Can we discover if the host bridge remaps SMBASE? Yes. * on the i440BX host bridge, check the SMRAMC register. * * There are two modes: Compatible and Extended SMRAM. Compatible mode * is meant to be backwards compatible with older BIOS PM code. * The C_BASE_SEG bits will tell you where the SMRAM memory * really is. Setting D_OPEN to high will let you get at the SMRAM memory. * * If your VGA controller mapping is active, it would be a good idea not * to use it while you're doing this. * * My ThinkPad's BIOS doesn't set the lock bit. * My ThinkPad's BIOS uses traditional SMRAM semantics. * i440BX Compatible SMRAM is hardwired to 0xA0000-0xB0000. * * By poking D_OPEN to 1, I was able to extract the SMRAM segment from * my machine. * # pciconf -r -b pci0:0:0 0x72 * 0a * # pciconf -w -b pci0:0:0 0x72 0x4A * # dd bs=0x1000 skip=0xA0 count=0x20 if=/dev/mem of=./foo * # pciconf -w -b pci0:0:0 0x72 0x0A */ #define I440BX 1 #ifdef DEF_SMM #define SMBASE 0x30000UL /* default IA-32 SMBASE location */ #define SMSIZE 0x10000UL /* default size of SMM area */ #endif #ifdef I440BX #define SMBASE 0xA0000UL /* default i440BX SMBASE location */ #define SMSIZE 0x20000UL /* default size of SMM area (128KB) */ #endif #ifdef I440BX_HIGH #define SMBASE 0x100A0000UL /* default i440BX SMBASE location */ #define SMSIZE 0x20000UL /* default size of SMM area (128KB) */ #endif #define I440BX_VENDOR 0x8086 /* Intel */ #define I440BX_DEVICE 0x7190 /* I440BX host-to-pci bridge */ #define CSR_SMRAMC 0x72 /* System Management RAM Control */ #define CSR_ESMRAMC 0x73 /* Extended SMRAM Control */ #define SMRAMC_D_OPEN 0x40 #define SMRAMC_D_CLS 0x20 #define SMRAMC_D_LCK 0x10 /* SMRAM locked, game over. */ #define SMRAMC_G_SMRAME 0x08 #define SMRAMC_C_BASE_SEG 0x07 /* mask for Compatible SMRAM base */ #define ESMRAM_H_SMRAM_EN 0x80 /* if set, SMRAM is >1MB boundary */ #define ESMRAM_E_SMRAM_ERR 0x40 /* attempted to access ESMRAM whilst * D_OPEN was not set */ #define ESMRAM_TSEG_SZ 0x06 /* mask for TSEG size */ #define ESMRAM_TSEG_EN 0x01 /* use TSEG to steal some RAM from * the top of main memory for SMRAM */ void usage(void) { printf("usage: smm\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int ret; int pcifd, memfd; struct pci_conf_io pcio; struct pci_io pci_io; struct pci_match_conf i440bx_match[1]; struct pci_conf pci_match[1]; void *smbase; struct mem_range_desc mdf; struct mem_range_op mop; u_int8_t smramc, esmramc; /* Open the pci(4) device. */ pcifd = open(_DEV_PCI, O_RDWR); if (pcifd == -1) { perror("open"); exit(EXIT_FAILURE); } /* Initialize pci match structures. */ bzero(&pcio, sizeof(pcio)); bzero(&i440bx_match, sizeof(i440bx_match)); bzero(&pci_match, sizeof(pci_match)); pcio.pat_buf_len = sizeof(i440bx_match); pcio.patterns = i440bx_match; pcio.num_patterns = 1; pcio.match_buf_len = sizeof(pci_match); pcio.matches = pci_match; i440bx_match[0].pc_vendor = I440BX_VENDOR; i440bx_match[0].pc_device = I440BX_DEVICE; i440bx_match[0].flags = PCI_GETCONF_MATCH_VENDOR | PCI_GETCONF_MATCH_DEVICE; /* * Find the I440BX device. */ ret = ioctl(pcifd, PCIOCGETCONF, &pcio); if (ret == -1) { perror("ioctl PCIOGETCONF"); goto cleanup; } /* Read the CSR_SMRAMC register. */ bzero(&pci_io, sizeof(pci_io)); pci_io.pi_sel = pci_match[0].pc_sel; pci_io.pi_reg = CSR_SMRAMC; pci_io.pi_width = 1; ret = ioctl(pcifd, PCIOCREAD, &pci_io); if (ret == -1) { perror("ioctl PCIOCREAD"); goto cleanup; } smramc = pci_io.pi_data; /* Read the CSR_ESMRAMC register. */ bzero(&pci_io, sizeof(pci_io)); pci_io.pi_sel = pci_match[0].pc_sel; pci_io.pi_reg = CSR_ESMRAMC; pci_io.pi_width = 1; ret = ioctl(pcifd, PCIOCREAD, &pci_io); if (ret == -1) { perror("ioctl PCIOCREAD"); goto cleanup; } esmramc = pci_io.pi_data; fprintf(stderr, "smramc = 0x%02x, esmramc = 0x%02x\n", smramc, esmramc); /* Open the mem(4) device. */ memfd = open(_DEV_MEM, O_RDWR); if (memfd == -1) { perror("open"); goto cleanup; } #if 0 /* XXX Mark the SMRAM range as uncacheable */ /* already done by BIOS, usually */ bzero(&mop, sizeof(mop)); mop.mo_arg[0] = MEMRANGE_SET_UPDATE; mop.mo_desc = &mdf; bzero(&mdf, sizeof(mdf)); mdf.mr_base = SMBASE; mdf.mr_base = SMSIZE; mdf.mr_flags = MDF_UNCACHEABLE; ret = ioctl(memfd, MEMRANGE_SET, &mop); if (ret == -1) perror("ioctl MEMRANGE_SET"); #endif /* Map the SMRAM into our address space. */ smbase = mmap((void *)SMBASE, SMSIZE, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, memfd, SMBASE); if (smbase == MAP_FAILED) { perror("mmap"); goto cleanup; } alarm(30); pause(); cleanup: if (smbase != MAP_FAILED) munmap(smbase, SMSIZE); close(pcifd); close(memfd); exit(EXIT_SUCCESS); }
_______________________________________________ [EMAIL PROTECTED] mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"