diff options
author | Stuart Bennett <sb476@cam.ac.uk> | 2007-11-15 23:52:36 +0000 |
---|---|---|
committer | Stuart Bennett <sb476@cam.ac.uk> | 2007-11-16 01:45:57 +0000 |
commit | 0cbb7dd01ad08b150e7cd0d4e7dfadd0c7375598 (patch) | |
tree | 17dfa354b5632e07e40933f8225ded6afe1d366b | |
parent | 21939967f530f6a421f2ffc821aa736d90f49574 (diff) |
Allow mode setting and retrieval, allow cmdline args
-rw-r--r-- | inttool.c | 117 |
1 files changed, 93 insertions, 24 deletions
@@ -10,24 +10,55 @@ version 2 */ #include <pci/pci.h> -#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include <sys/ioctl.h> -#include <sys/types.h> #include <sys/io.h> -#include <sys/kd.h> -#include <sys/stat.h> -#include <errno.h> #include "lrmi.h" #include "x86emu.h" -int do_int(unsigned pci_device) +int do_set_mode(unsigned mode) +{ + struct LRMI_regs r; + memset(&r, 0, sizeof(r)); + + r.eax = 0x4f02; + r.ebx = (mode & 0xffff) | 0x8000; + r.ecx = 0; + r.edx = 0; + + if (!LRMI_int(0x10, &r)) { + fprintf(stderr, "Error: something went wrong performing real mode call\n"); + return 1; + } + printf("ax: 0x%04x, bx: 0x%04x\n", r.eax & 0xffff, r.ebx & 0xffff); + + return 0; +} + +int do_get_mode(void) +{ + struct LRMI_regs r; + memset(&r, 0, sizeof(r)); + + r.eax = 0x4f03; + r.ebx = 0; + r.ecx = 0; + r.edx = 0; + + if (!LRMI_int(0x10, &r)) { + fprintf(stderr, "Error: something went wrong performing real mode call\n"); + return 1; + } + printf("ax: 0x%04x, bx: 0x%04x, mode: 0x%04x (%d)\n", r.eax & 0xffff, r.ebx & 0xffff, r.ebx & 0x3fff, r.ebx & 0x3fff); + + return 0; +} + +int do_post_int(unsigned pci_device) { - int error = 0; struct LRMI_regs r; memset(&r, 0, sizeof(r)); @@ -44,14 +75,12 @@ int do_int(unsigned pci_device) r.edx = 0x80; r.ds = 0x0040; - M.x86.debug = DEBUG_TRACE_F | DEBUG_DECODE_F; /* x86emu debug flags */ - if (!LRMI_call(&r)) { fprintf(stderr, "Error: something went wrong performing real mode call\n"); - error = 1; + return 1; } - return error; + return 0; } int main(int argc, char *argv[]) @@ -60,26 +89,66 @@ int main(int argc, char *argv[]) struct pci_dev *p; unsigned int c; unsigned int pci_id; + int opt, debug = 0, mode, op = 0, opset = 0; + + while ((opt = getopt(argc, argv, "dgps:")) != -1) { + switch (opt) { + case 'd': + debug = 1; + break; + case 'g': + opset++; + break; + case 'p': + op = 2; + opset++; + break; + case 's': + op = 1; + opset++; + mode = atoi(optarg); + break; + default: + opset = 2; + } + } + + if (optind < argc || opset > 1) { + printf("eh?\n"); + exit(EXIT_FAILURE); + } if (!LRMI_init()) { fprintf(stderr, "Failed to initialise LRMI (Linux Real-Mode Interface).\n"); - exit(1); + exit(EXIT_FAILURE); } ioperm(0, 1024, 1); iopl(3); - - pacc = pci_alloc(); - pacc->numeric_ids = 1; - pci_init(pacc); - - pci_scan_bus(pacc); - for (p = pacc->devices; p; p = p->next) { - c = pci_read_word(p, PCI_CLASS_DEVICE); - if (c == 0x300) { - pci_id = (p->bus << 8) + (p->dev << 3) + (p->func & 0x7); - return (do_int(pci_id)); + if (debug) + M.x86.debug = DEBUG_TRACE_F | DEBUG_DECODE_F; /* x86emu debug flags */ + else + M.x86.debug = 0; + + switch (op) { + case 0: + return (do_get_mode()); + case 1: + return (do_set_mode(mode)); + case 2: + pacc = pci_alloc(); + pacc->numeric_ids = 1; + pci_init(pacc); + + pci_scan_bus(pacc); + + for (p = pacc->devices; p; p = p->next) { + c = pci_read_word(p, PCI_CLASS_DEVICE); + if (c == 0x300) { + pci_id = (p->bus << 8) + (p->dev << 3) + (p->func & 0x7); + return (do_post_int(pci_id)); + } } } |