From 99970893290223f2006c3a0c6f34ab9eaf5cb4c9 Mon Sep 17 00:00:00 2001 From: Jacob Potter Date: Fri, 12 Sep 2008 17:55:01 -0400 Subject: [PATCH] Split smm-open-ich2 into two files: - ich2/smram-ich2.c, smram manipulation functions capable of running on Linux or raw (using an appropriate pci-???.c) - tools/smram-linux-tool.c, replacement for smram-open-ich2 using the above driver functions. --- ich2/smm-open-ich2.c | 6 +++ ich2/smram-ich2.c | 102 +++++++++++++++++++++++++++++++++++++++ tools/.gitignore | 1 + tools/Makefile | 2 + tools/smram-linux-tool.c | 68 ++++++++++++++++++++++++++ 5 files changed, 179 insertions(+) create mode 100644 ich2/smram-ich2.c create mode 100644 tools/.gitignore create mode 100644 tools/Makefile create mode 100644 tools/smram-linux-tool.c diff --git a/ich2/smm-open-ich2.c b/ich2/smm-open-ich2.c index e76fcfc..120ac74 100644 --- a/ich2/smm-open-ich2.c +++ b/ich2/smm-open-ich2.c @@ -4,6 +4,12 @@ #include #include +/*********************************************************************** + * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED + * + * This should be replaced by ../util/smram-ich2 once it's verified to work properly. + */ + unsigned long memsz[] = { 0, // 0 32*1024*1024, // 1 diff --git a/ich2/smram-ich2.c b/ich2/smram-ich2.c new file mode 100644 index 0000000..1052f3b --- /dev/null +++ b/ich2/smram-ich2.c @@ -0,0 +1,102 @@ +#include "reg-82815.h" + +unsigned long memsz[] = { + 0, // 0 + 32*1024*1024, // 1 + 32*1024*1024, // 2 + 48*1024*1024, // 3 + 64*1024*1024, // 4 + 64*1024*1024, // 5 + 96*1024*1024, // 6 + 128*1024*1024, // 7 + 128*1024*1024, // 8 + 128*1024*1024, // 9 + 128*1024*1024, // A + 192*1024*1024, // B + 256*1024*1024, // C + 256*1024*1024, // D + 256*1024*1024, // E + 512*1024*1024 // F +}; + +#ifdef __linux__ + +void smram_aseg_dump(void) { + + unsigned char smramc, drp, drp2; + unsigned int tom = 0; + int usmm, lsmm; + + smramc = pci_read8(0, 0, 0, SMRAMC); + drp = pci_read8(0, 0, 0, DRP); + drp2 = pci_read8(0, 0, 0, DRP2); + + printf("SMRAMC: %02x\n", smramc); + + tom += memsz[drp & 0xF]; + tom += memsz[drp >> 4]; + tom += memsz[drp2 & 0xF]; + + printf("Top of DRAM: %08x\n", tom); + + usmm = (smramc >> 4) & 0x3; + lsmm = (smramc >> 2) & 0x3; + + switch (usmm) + { + case 0: + printf("TSEG and HSEG both off\n"); + break; + case 1: + printf("TSEG off, HSEG %s\n", lsmm ? "off" : "on"); + break; + case 2: + printf("TSEG 512KB (%08x - %08x), HSEG %s\n", + tom - 512 * 1024, tom - 1, lsmm ? "off" : "on"); + break; + case 3: + printf("TSEG 1MB (%08x - %08x), HSEG %s\n", + tom - 1 * 1024 * 1024, tom - 1, lsmm ? "off" : "on"); + break; + } + + switch (lsmm) + { + case 0: + printf("ABSEG disabled\n"); + break; + case 1: + printf("ABSEG enabled as system RAM\n"); + break; + case 2: + printf("ABSEG enabled for SMM code only\n"); + break; + case 3: + printf("ABSEG enabled for both SMM code and data\n"); + break; + } +} +#endif + +int smram_aseg_set_state (int open) { + unsigned char smramc; + smramc = pci_read8(0, 0, 0, SMRAMC); + + if (smramc & SMRAMC_LOCK) + { + /* SMRAM is locked; can't load anything. */ + return 1; + } + + if (open) { + /* Set LSMM to 01 (ABseg = system RAM) */ + smramc = (smramc & 0xF0) | 0x04; + } else { + /* Set LSMM to 11 (ABseg = SMM RAM) */ + smramc = (smramc & 0xF0) | 0x0C; + } + + pci_write8(0, 0, 0, SMRAMC); + + return 0; +} diff --git a/tools/.gitignore b/tools/.gitignore new file mode 100644 index 0000000..e2ec8c1 --- /dev/null +++ b/tools/.gitignore @@ -0,0 +1 @@ +smram-ich2 diff --git a/tools/Makefile b/tools/Makefile new file mode 100644 index 0000000..35f37d4 --- /dev/null +++ b/tools/Makefile @@ -0,0 +1,2 @@ +smram-ich2: smram-linux-tool.c ../pci/pci-linux.c ../ich2/smram-ich2.c + gcc -o smram-ich2 smram-linux-tool.c ../pci/pci-linux.c ../ich2/smram-ich2.c diff --git a/tools/smram-linux-tool.c b/tools/smram-linux-tool.c new file mode 100644 index 0000000..0d47bb4 --- /dev/null +++ b/tools/smram-linux-tool.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include + +static struct option longopts[] = { + { "open", no_argument, NULL, 'o' }, + { "close", no_argument, NULL, 'c' }, + { "dump", no_argument, NULL, 'd' }, + { NULL, 0, NULL, 0 } +}; + +#define OP_DUMP 1 +#define OP_SET 2 + +void usage(int argc, char **argv) +{ + printf("Usage: %s [ --dump ] [ --open | --close ]\n", + argv[0]); + exit(1); +} + +int main(int argc, char **argv) +{ + if (geteuid() != 0) + { + printf("This program must be run as root, dumbass.\n"); + return 1; + } + + int ch; + int op = 0; + int do_open = 0; + while ((ch = getopt_long(argc, argv, "ocsd:", longopts, NULL)) != -1) + { + switch (ch) + { + case 'o': + if (op & OP_SET) usage(argc, argv); + op |= OP_SET; + do_open = 1; + break; + case 'c': + if (op & OP_SET) usage(argc, argv); + op |= OP_SET; + break; + case 'd': + op |= OP_DUMP; + break; + default: + usage(argc, argv); + } + } + + if (!op) usage(argc, argv); + + if (op & OP_DUMP) + { + smram_aseg_dump(); + } + + if (op & OP_SET) + { + smram_aseg_set_state(do_open); + } + + return 0; +} -- 2.43.0