summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Bennett <sb476@cam.ac.uk>2007-11-15 23:52:36 +0000
committerStuart Bennett <sb476@cam.ac.uk>2007-11-16 01:45:57 +0000
commit0cbb7dd01ad08b150e7cd0d4e7dfadd0c7375598 (patch)
tree17dfa354b5632e07e40933f8225ded6afe1d366b
parent21939967f530f6a421f2ffc821aa736d90f49574 (diff)
Allow mode setting and retrieval, allow cmdline args
-rw-r--r--inttool.c117
1 files changed, 93 insertions, 24 deletions
diff --git a/inttool.c b/inttool.c
index 11a5e5b..e5cad6d 100644
--- a/inttool.c
+++ b/inttool.c
@@ -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));
+ }
}
}