summaryrefslogtreecommitdiffstats
path: root/tools/ddcprobe/int10/i10_v86.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/ddcprobe/int10/i10_v86.c')
-rw-r--r--tools/ddcprobe/int10/i10_v86.c516
1 files changed, 0 insertions, 516 deletions
diff --git a/tools/ddcprobe/int10/i10_v86.c b/tools/ddcprobe/int10/i10_v86.c
deleted file mode 100644
index 8fbda312d..000000000
--- a/tools/ddcprobe/int10/i10_v86.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/*
- * Copyright 1999 Egbert Eich
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of the authors not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. The authors makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <unistd.h>
-#include <errno.h>
-#include <asm/unistd.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef __i386__
-#include <sys/vm86.h>
-#else
-#include "vm86_struct.h"
-#endif
-#include <signal.h>
-#include "v86bios.h"
-#include "AsmMacros.h"
-
-extern int emu_vm86(struct vm86_struct *vm);
-
-#define INT2PTR(a) ((a) + (unsigned char *) 0)
-
-void log_err(char *format, ...) __attribute__ ((format (printf, 1, 2)));
-
-struct vm86_struct vm86s;
-
-static int vm86_GP_fault(void);
-static int vm86_do_int(int num);
-#ifdef __i386__
-static int vm86_rep(struct vm86_struct *ptr);
-#endif
-void log_registers(void);
-
-#define CPU_REG(x) (vm86s.regs.x)
-#define CPU_REG_LW(reg) (*((CARD16 *)&CPU_REG(reg)))
-#define CPU_REG_HW(reg) (*((CARD16 *)&CPU_REG(reg) + 1))
-#define CPU_REG_LB(reg) (*(CARD8 *)&CPU_REG(e##reg))
-#define SEG_ADR(type, seg, reg) type((CPU_REG_LW(seg) << 4) + CPU_REG_LW(e##reg) + (unsigned char *) 0)
-#define DF (1 << 10)
-
-struct pio P;
-
-void
-setup_io(void)
-{
- P.inb = (CARD8(*)(CARD16))inb;
- P.inw = (CARD16(*)(CARD16))inw;
- P.inl = (CARD32(*)(CARD16))inl;
- P.outb = (void(*)(CARD16,CARD8))outb;
- P.outw = (void(*)(CARD16,CARD16))outw;
- P.outl = (void(*)(CARD16,CARD32))outl;
-}
-
-
-static void
-setup_vm86(unsigned long bios_start, i86biosRegsPtr regs)
-{
- CARD32 eip;
- CARD16 cs;
-
- vm86s.flags = VM86_SCREEN_BITMAP;
- vm86s.flags = 0;
- vm86s.screen_bitmap = 0;
- vm86s.cpu_type = CPU_586;
- memset(&vm86s.int_revectored, 0xff,sizeof(vm86s.int_revectored)) ;
- memset(&vm86s.int21_revectored, 0xff,sizeof(vm86s.int21_revectored)) ;
-
- eip = bios_start & 0xFFFF;
- cs = (bios_start & 0xFF0000) >> 4;
-
- CPU_REG(eax) = regs->ax;
- CPU_REG(ebx) = regs->bx;
- CPU_REG(ecx) = regs->cx;
- CPU_REG(edx) = regs->dx;
- CPU_REG(esi) = 0;
- CPU_REG(edi) = regs->di;
- CPU_REG(ebp) = 0;
- CPU_REG(eip) = eip;
- CPU_REG(cs) = cs;
- CPU_REG(esp) = 0x100;
- CPU_REG(ss) = 0x30; /* This is the standard pc bios stack */
- CPU_REG(es) = regs->es;
- CPU_REG(ds) = 0x40; /* standard pc ds */
- CPU_REG(fs) = 0;
- CPU_REG(gs) = 0;
- CPU_REG(eflags) |= (VIF_MASK | VIP_MASK);
-}
-
-void
-collect_bios_regs(i86biosRegsPtr regs)
-{
- regs->ax = CPU_REG(eax);
- regs->bx = CPU_REG(ebx);
- regs->cx = CPU_REG(ecx);
- regs->dx = CPU_REG(edx);
- regs->es = CPU_REG(es);
- regs->ds = CPU_REG(ds);
- regs->di = CPU_REG(edi);
- regs->si = CPU_REG(esi);
-}
-
-static int do_vm86(int cpuemu)
-{
- int retval;
-
-#ifdef V86BIOS_DEBUG
- dump_registers();
-#endif
-
-#ifdef __i386__
- if(cpuemu) {
- retval = emu_vm86(&vm86s);
- }
- else {
- retval = vm86_rep(&vm86s);
- }
-#else
- retval = emu_vm86(&vm86s);
-#endif
-
- switch (VM86_TYPE(retval)) {
- case VM86_UNKNOWN:
- if (!vm86_GP_fault())
- return 0;
- break;
- case VM86_STI:
- log_err("vm86_sti :-((\n");
- log_registers();
- return 0;
- case VM86_INTx:
- if (!vm86_do_int(VM86_ARG(retval))) {
- log_err("Unknown vm86_int: %X\n",VM86_ARG(retval));
- log_registers();
- return 0;
- }
- /* I'm not sure yet what to do if we can handle ints */
- break;
- case VM86_SIGNAL:
- log_err("VBE: received a signal!\n");
- log_registers();
- return 0;
- default:
- log_err("unknown type(0x%x)=0x%x\n",
- VM86_ARG(retval),VM86_TYPE(retval));
- log_registers();
- return 0;
- }
-
- return 1;
-}
-
-void
-do_x86(unsigned long bios_start, i86biosRegsPtr regs, int cpuemu)
-{
- setup_vm86(bios_start, regs);
- while(do_vm86(cpuemu)) {};
- collect_bios_regs(regs);
-}
-
-/* get the linear address */
-#define LIN_PREF_SI ((pref_seg << 4) + CPU_REG_LW(esi))
-
-#define LWECX (prefix66 ^ prefix67 ? CPU_REG(ecx) : CPU_REG_LW(ecx))
-#define SET_LWECX(V) do { if (prefix66 ^ prefix67) CPU_REG(ecx) = (V); else CPU_REG_LW(ecx) = (V); } while (0)
-
-static int
-vm86_GP_fault(void)
-{
- unsigned char *csp, *lina;
- CARD32 org_eip;
- int pref_seg;
- int done,is_rep,prefix66,prefix67;
-
-
- csp = lina = SEG_ADR((unsigned char *), cs, ip);
-#ifdef V86BIOS_DEBUG
- printf("exception: \n");
- dump_code();
-#endif
-
- is_rep = 0;
- prefix66 = prefix67 = 0;
- pref_seg = -1;
-
- /* eat up prefixes */
- done = 0;
- do {
- switch (*(csp++)) {
- case 0x66: /* operand prefix */ prefix66=1; break;
- case 0x67: /* address prefix */ prefix67=1; break;
- case 0x2e: /* CS */ pref_seg=CPU_REG(cs); break;
- case 0x3e: /* DS */ pref_seg=CPU_REG(ds); break;
- case 0x26: /* ES */ pref_seg=CPU_REG(es); break;
- case 0x36: /* SS */ pref_seg=CPU_REG(ss); break;
- case 0x65: /* GS */ pref_seg=CPU_REG(gs); break;
- case 0x64: /* FS */ pref_seg=CPU_REG(fs); break;
- case 0xf2: /* repnz */
- case 0xf3: /* rep */ is_rep=1; break;
- default: done=1;
- }
- } while (!done);
- csp--; /* oops one too many */
- org_eip = CPU_REG(eip);
- CPU_REG_LW(eip) += (csp - lina);
-
- switch (*csp) {
-
- case 0x6c: /* insb */
- /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx
- * but is anyone using extended regs in real mode? */
- /* WARNING: no test for DI wrapping! */
- CPU_REG_LW(edi) += port_rep_inb(CPU_REG_LW(edx),
- SEG_ADR((CARD8 *),es,di),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- if (is_rep) SET_LWECX(0);
- CPU_REG_LW(eip)++;
- break;
-
- case 0x6d: /* (rep) insw / insd */
- /* NOTE: ES can't be overwritten */
- /* WARNING: no test for _DI wrapping! */
- if (prefix66) {
- CPU_REG_LW(edi) += port_rep_inl(CPU_REG_LW(edx),
- SEG_ADR((CARD32 *),es,di),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- }
- else {
- CPU_REG_LW(edi) += port_rep_inw(CPU_REG_LW(edx),
- SEG_ADR((CARD16 *),es,di),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- }
- if (is_rep) SET_LWECX(0);
- CPU_REG_LW(eip)++;
- break;
-
- case 0x6e: /* (rep) outsb */
- if (pref_seg < 0) pref_seg = CPU_REG_LW(ds);
- /* WARNING: no test for _SI wrapping! */
- CPU_REG_LW(esi) += port_rep_outb(CPU_REG_LW(edx),(CARD8*)INT2PTR(LIN_PREF_SI),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- if (is_rep) SET_LWECX(0);
- CPU_REG_LW(eip)++;
- break;
-
- case 0x6f: /* (rep) outsw / outsd */
- if (pref_seg < 0) pref_seg = CPU_REG_LW(ds);
- /* WARNING: no test for _SI wrapping! */
- if (prefix66) {
- CPU_REG_LW(esi) += port_rep_outl(CPU_REG_LW(edx),
- (CARD32 *)INT2PTR(LIN_PREF_SI),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- }
- else {
- CPU_REG_LW(esi) += port_rep_outw(CPU_REG_LW(edx),
- (CARD16 *)INT2PTR(LIN_PREF_SI),
- CPU_REG_LW(eflags)&DF,
- (is_rep? LWECX:1));
- }
- if (is_rep) SET_LWECX(0);
- CPU_REG_LW(eip)++;
- break;
-
- case 0xe5: /* inw xx, inl xx */
- if (prefix66) CPU_REG(eax) = P.inl((int) csp[1]);
- else CPU_REG_LW(eax) = P.inw((int) csp[1]);
- CPU_REG_LW(eip) += 2;
- break;
- case 0xe4: /* inb xx */
- CPU_REG_LW(eax) &= ~(CARD32)0xff;
- CPU_REG_LB(ax) |= P.inb((int) csp[1]);
- CPU_REG_LW(eip) += 2;
- break;
- case 0xed: /* inw dx, inl dx */
- if (prefix66) CPU_REG(eax) = P.inl(CPU_REG_LW(edx));
- else CPU_REG_LW(eax) = P.inw(CPU_REG_LW(edx));
- CPU_REG_LW(eip) += 1;
- break;
- case 0xec: /* inb dx */
- CPU_REG_LW(eax) &= ~(CARD32)0xff;
- CPU_REG_LB(ax) |= P.inb(CPU_REG_LW(edx));
- CPU_REG_LW(eip) += 1;
- break;
-
- case 0xe7: /* outw xx */
- if (prefix66) P.outl((int)csp[1], CPU_REG(eax));
- else P.outw((int)csp[1], CPU_REG_LW(eax));
- CPU_REG_LW(eip) += 2;
- break;
- case 0xe6: /* outb xx */
- P.outb((int) csp[1], CPU_REG_LB(ax));
- CPU_REG_LW(eip) += 2;
- break;
- case 0xef: /* outw dx */
- if (prefix66) P.outl(CPU_REG_LW(edx), CPU_REG(eax));
- else P.outw(CPU_REG_LW(edx), CPU_REG_LW(eax));
- CPU_REG_LW(eip) += 1;
- break;
- case 0xee: /* outb dx */
- P.outb(CPU_REG_LW(edx), CPU_REG_LB(ax));
- CPU_REG_LW(eip) += 1;
- break;
-
- case 0xf4:
-#ifdef V86BIOS_DEBUG
- printf("hlt at %p\n", lina);
-#endif
- return 0;
-
- case 0x0f:
- log_err("CPU 0x0f Trap at eip=0x%lx\n",CPU_REG(eip));
- goto op0ferr;
- break;
-
- case 0xf0: /* lock */
- default:
- log_err("unknown reason for exception\n");
- log_registers();
- op0ferr:
- log_err("cannot continue\n");
- return 0;
- } /* end of switch() */
- return 1;
-}
-
-static int
-vm86_do_int(int num)
-{
- int val;
- struct regs86 regs;
-
- /* try to run bios interrupt */
-
- /* if not installed fall back */
-#define COPY(x) regs.x = CPU_REG(x)
-#define COPY_R(x) CPU_REG(x) = regs.x
-
- COPY(eax);
- COPY(ebx);
- COPY(ecx);
- COPY(edx);
- COPY(esi);
- COPY(edi);
- COPY(ebp);
- COPY(eip);
- COPY(esp);
- COPY(cs);
- COPY(ss);
- COPY(ds);
- COPY(es);
- COPY(fs);
- COPY(gs);
- COPY(eflags);
-
- if (!(val = int_handler(num,&regs)))
- if (!(val = run_bios_int(num,&regs)))
- return val;
-
- COPY_R(eax);
- COPY_R(ebx);
- COPY_R(ecx);
- COPY_R(edx);
- COPY_R(esi);
- COPY_R(edi);
- COPY_R(ebp);
- COPY_R(eip);
- COPY_R(esp);
- COPY_R(cs);
- COPY_R(ss);
- COPY_R(ds);
- COPY_R(es);
- COPY_R(fs);
- COPY_R(gs);
- COPY_R(eflags);
-
- return val;
-#undef COPY
-#undef COPY_R
-}
-
-#ifdef __i386__
-
-static int
-vm86_rep(struct vm86_struct *ptr)
-{
-
- int __res;
-
- /* stay away from %ebx */
- __asm__ __volatile__("push %%ebx\n\tmov %%ecx,%%ebx\n\tpush %%gs\n\tint $0x80\n\tpop %%gs\n\tpop %%ebx\n"
- :"=a" (__res):"a" ((int)113),
- "c" ((struct vm86_struct *)ptr));
-
- if ((__res) < 0) {
- errno = -__res;
- __res=-1;
- }
- else errno = 0;
- return __res;
-}
-
-#endif
-
-#ifdef __i386__
-
-#define pushw(base, ptr, val) \
-__asm__ __volatile__( \
- "decw %w0\n\t" \
- "movb %h2,(%1,%0)\n\t" \
- "decw %w0\n\t" \
- "movb %b2,(%1,%0)" \
- : "=r" (ptr) \
- : "r" (base), "q" (val), "0" (ptr))
-
-#else
-
-#define pushw(base, ptr, val) { \
- ptr = ((ptr) - 1) & 0xffff; \
- *((unsigned char *)(base) + (ptr)) = (val) >> 8; \
- ptr = ((ptr) - 1) & 0xffff; \
- *((unsigned char *)(base) + (ptr)) = (val); \
- }
-
-#endif
-
-int
-run_bios_int(int num, struct regs86 *regs)
-{
- CARD16 *ssp;
- CARD32 sp;
- CARD32 eflags;
-
-#ifdef V86BIOS_DEBUG
- static int firsttime = 1;
-#endif
- /* check if bios vector is initialized */
- if (((CARD16*)0)[(num<<1)+1] == 0x0000) { /* SYS_BIOS_SEG ?*/
- return 0;
- }
-
-#ifdef V86BIOS_DEBUG
- if (firsttime) {
- dprint(0,0x3D0);
- firsttime = 0;
- }
-#endif
-
- ssp = (CARD16*)INT2PTR(CPU_REG(ss)<<4);
- sp = (CARD32) CPU_REG_LW(esp);
-
- eflags = regs->eflags;
- eflags = ((eflags & VIF_MASK) != 0)
- ? (eflags | IF_MASK) : (eflags & ~(CARD32) IF_MASK);
- pushw(ssp, sp, eflags);
- pushw(ssp, sp, regs->cs);
- pushw(ssp, sp, (CARD16)regs->eip);
- regs->esp -= 6;
- regs->cs = ((CARD16 *) 0)[(num << 1) + 1];
- regs->eip = (regs->eip & 0xFFFF0000) | ((CARD16 *) 0)[num << 1];
-#ifdef V86BIOS_DEBUG
- dump_code();
-#endif
- regs->eflags = regs->eflags
- & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
- return 1;
-}
-
-CARD32
-getIntVect(int num)
-{
- return ((CARD32*)0)[num];
-}
-
-CARD32
-getIP(void)
-{
- return (CPU_REG(cs) << 4) + CPU_REG(eip);
-}
-
-void log_registers()
-{
- log_err(
- " eax %08x, ebx %08x, ecx %08x, edx %08x\n"
- " esi %08x, edi %08x, ebp %08x, esp %08x\n"
- " ds %04x, es %04x, fs %04x, gs %04x, ss %04x\n"
- " cs:eip %04x:%08x\n",
- (unsigned) CPU_REG(eax), (unsigned) CPU_REG(ebx), (unsigned) CPU_REG(ecx), (unsigned) CPU_REG(edx),
- (unsigned) CPU_REG(esi), (unsigned) CPU_REG(edi), (unsigned) CPU_REG(ebp), (unsigned) CPU_REG(esp),
- (unsigned) CPU_REG(ds), (unsigned) CPU_REG(es),
- (unsigned) CPU_REG(fs), (unsigned) CPU_REG(gs), (unsigned) CPU_REG(ss),
- (unsigned) CPU_REG(cs), (unsigned) CPU_REG(eip)
- );
-}
-