From c6b944672240353efa93fd74832d688cc1140e93 Mon Sep 17 00:00:00 2001 From: David Given Date: Mon, 4 Jun 2018 16:19:45 +0900 Subject: [PATCH] Check in the x86emu-based emulator. Sadly, just like the 8086tiny-based emulator, FPU instructions aren't supported. --- plat/pc86/emu/build.lua | 4 +- plat/pc86/emu/main.c | 137 +++++- plat/pc86/emu/x86emu/validate.c | 769 -------------------------------- plat/pc86/tests/build.lua | 2 +- 4 files changed, 139 insertions(+), 773 deletions(-) delete mode 100644 plat/pc86/emu/x86emu/validate.c diff --git a/plat/pc86/emu/build.lua b/plat/pc86/emu/build.lua index ee94bea47..b3b81f15f 100644 --- a/plat/pc86/emu/build.lua +++ b/plat/pc86/emu/build.lua @@ -1,7 +1,7 @@ clibrary { name = "x86emu", vars = { - ["+cflags"] = {"-Iplat/pc86/emu/x86emu"} + ["+cflags"] = {"-Iplat/pc86/emu/x86emu", "-DDEBUG"} }, srcs = {"./x86emu/*.c"} } @@ -10,7 +10,7 @@ cprogram { name = "pc86emu", srcs = {"./main.c"}, vars = { - ["+cflags"] = {"-Iplat/pc86/emu/x86emu"} + ["+cflags"] = {"-Iplat/pc86/emu/x86emu", "-DDEBUG"} }, deps = { "+x86emu" diff --git a/plat/pc86/emu/main.c b/plat/pc86/emu/main.c index 70ec1d915..1558884a8 100644 --- a/plat/pc86/emu/main.c +++ b/plat/pc86/emu/main.c @@ -1,9 +1,144 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include +#include "x86emu.h" + +static uint8_t ram[1025*1024]; +static int floppy_fd; +static X86EMU_intrFuncs intr_funcs[256]; + +void printk(const char* format, ...) +{ + va_list ap; + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); +} + +static void unknown_interrupt_cb(int num) +{ + printk("unknown interrupt 0x%02x\n", num); + exit(1); +} + +static void ignored_interrupt_cb(int num) +{ + M.x86.R_AX = 0; +} + +static void int10_cb(int num) +{ + switch (M.x86.R_AH) + { + case 0x0e: /* print char al */ + putchar(M.x86.R_AL); + fflush(stdout); + break; + + default: + printk("unknown int10 service 0x%02x\n", M.x86.R_AH); + exit(1); + } +} + +static void int13_cb(int num) +{ + if (M.x86.R_DL != 0) + { + /* unknown disk */ + M.x86.R_AX = 1; + return; + } + + switch (M.x86.R_AH) + { + case 0x02: /* read sector */ + { + /* On entry: + * al: number of sectors + * bx: address + * ch: track + * cl: sector + * dh: head number + * dl: disk + */ + uint8_t count = M.x86.R_AL; + uint32_t address = (M.x86.R_DS << 4) + M.x86.R_BX; + uint8_t sector = M.x86.R_CL; + uint8_t track = M.x86.R_CH; + uint8_t head = M.x86.R_DH; + uint32_t lba = track*18*2 + head*18 + (sector-1); + //printf("CHS %d.%d.%d -> lba 0x%x\n", track, head, sector, lba); + pread(floppy_fd, &ram[address], count*512, lba*512); + M.x86.R_AX = 0; + CLEAR_FLAG(F_CF); + } + + case 0x08: /* probe disk al */ + M.x86.R_AX = 0; + M.x86.R_CL = 18; /* maximum sector number */ + M.x86.R_DH = 1; /* maximum head number */ + /* there's other stuff we should set as well */ + break; + + default: + printk("unknown int13 service 0x%02x\n", M.x86.R_AH); + exit(1); + } +} int main(int argc, const char* argv[]) { - return 1; + if (argc != 2) + { + printk("syntax: pc86emu \n"); + exit(1); + } + + floppy_fd = open(argv[1], O_RDONLY); + if (floppy_fd == -1) + { + printk("could not open disk image: %s\n", strerror(errno)); + exit(1); + } + + /* Initialise the processor. */ + + M.mem_base = (uintptr_t) ram; + M.mem_size = sizeof(ram); + + /* Load the boot sector at 0x07c0:0000. */ + + for (int i=0; i<512; i++) + { + uint8_t b; + read(floppy_fd, &b, 1); + wrb(0x7c00 + i, b); + } + + /* Initialise. */ + + for (int i=0; i<256; i++) + intr_funcs[i] = unknown_interrupt_cb; + intr_funcs[0x10] = int10_cb; + intr_funcs[0x13] = int13_cb; + intr_funcs[0x14] = ignored_interrupt_cb; /* serial port stuff */ + + //M.x86.debug = DEBUG_TRACE_F|DEBUG_STEP_F|DEBUG_DECODE_F; + M.x86.debug = 0; + M.x86.R_CS = 0x07c0; + M.x86.R_IP = 0x0000; + M.x86.R_DL = 0; /* boot drive */ + X86EMU_setupIntrFuncs(intr_funcs); + X86EMU_exec(); + + return 0; } diff --git a/plat/pc86/emu/x86emu/validate.c b/plat/pc86/emu/x86emu/validate.c deleted file mode 100644 index 4c36e1df5..000000000 --- a/plat/pc86/emu/x86emu/validate.c +++ /dev/null @@ -1,769 +0,0 @@ -/**************************************************************************** -* -* Realmode X86 Emulator Library -* -* Copyright (C) 1996-1999 SciTech Software, Inc. -* Copyright (C) David Mosberger-Tang -* Copyright (C) 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. -* -* ======================================================================== -* -* Language: Watcom C 10.6 or later -* Environment: 32-bit DOS -* Developer: Kendall Bennett -* -* Description: Program to validate the x86 emulator library for -* correctness. We run the emulator primitive operations -* functions against the real x86 CPU, and compare the result -* and flags to ensure correctness. -* -* We use inline assembler to compile and build this program. -* -****************************************************************************/ - -#include -#include -#include -#include -#include "x86emu.h" -#include "x86emu/prim_asm.h" - -/*-------------------------- Implementation -------------------------------*/ - -#define true 1 -#define false 0 - -#define ALL_FLAGS (F_CF | F_PF | F_AF | F_ZF | F_SF | F_OF) - -#define VAL_START_BINARY(parm_type,res_type,dmax,smax,dincr,sincr) \ -{ \ - parm_type d,s; \ - res_type r,r_asm; \ - ulong flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < dmax; d += dincr) { \ - for (s = 0; s < smax; s += sincr) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { - -#define VAL_TEST_BINARY(name) \ - r_asm = name##_asm(&flags,d,s); \ - r = name(d,s); \ - if (r != r_asm || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { - -#define VAL_TEST_BINARY_VOID(name) \ - name##_asm(&flags,d,s); \ - name(d,s); \ - r = r_asm = 0; \ - if (M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { - -#define VAL_FAIL_BYTE_BYTE_BINARY(name) \ - if (failed) \ - printk("fail\n"); \ - printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ - r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%02X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_FAIL_WORD_WORD_BINARY(name) \ - if (failed) \ - printk("fail\n"); \ - printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ - r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_FAIL_LONG_LONG_BINARY(name) \ - if (failed) \ - printk("fail\n"); \ - printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ - r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_END_BINARY() \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_BYTE_BYTE_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_BYTE_BYTE_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_WORD_WORD_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_WORD_WORD_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_LONG_LONG_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_LONG_LONG_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_VOID_BYTE_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u8,u8,0xFF,0xFF,1,1) \ - VAL_TEST_BINARY_VOID(name) \ - VAL_FAIL_BYTE_BYTE_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_VOID_WORD_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u16,u16,0xFF00,0xFF00,0x100,0x100) \ - VAL_TEST_BINARY_VOID(name) \ - VAL_FAIL_WORD_WORD_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_VOID_LONG_BINARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000) \ - VAL_TEST_BINARY_VOID(name) \ - VAL_FAIL_LONG_LONG_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_BYTE_ROTATE(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u8,u8,0xFF,8,1,1) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_BYTE_BYTE_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_WORD_ROTATE(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u16,u16,0xFF00,16,0x100,1) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_WORD_WORD_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_LONG_ROTATE(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_BINARY(u32,u32,0xFF000000,32,0x1000000,1) \ - VAL_TEST_BINARY(name) \ - VAL_FAIL_LONG_LONG_BINARY(name) \ - VAL_END_BINARY() - -#define VAL_START_TERNARY(parm_type,res_type,dmax,smax,dincr,sincr,maxshift)\ -{ \ - parm_type d,s; \ - res_type r,r_asm; \ - u8 shift; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < dmax; d += dincr) { \ - for (s = 0; s < smax; s += sincr) { \ - for (shift = 0; shift < maxshift; shift += 1) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { - -#define VAL_TEST_TERNARY(name) \ - r_asm = name##_asm(&flags,d,s,shift); \ - r = name(d,s,shift); \ - if (r != r_asm || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { - -#define VAL_FAIL_WORD_WORD_TERNARY(name) \ - if (failed) \ - printk("fail\n"); \ - printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \ - r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X = %-15s(0x%04X,0x%04X,%d), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_FAIL_LONG_LONG_TERNARY(name) \ - if (failed) \ - printk("fail\n"); \ - printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \ - r, #name, d, s, shift, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%08X = %-15s(0x%08X,0x%08X,%d), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, shift, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_END_TERNARY() \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_WORD_ROTATE_DBL(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_TERNARY(u16,u16,0xFF00,0xFF00,0x100,0x100,16) \ - VAL_TEST_TERNARY(name) \ - VAL_FAIL_WORD_WORD_TERNARY(name) \ - VAL_END_TERNARY() - -#define VAL_LONG_ROTATE_DBL(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_TERNARY(u32,u32,0xFF000000,0xFF000000,0x1000000,0x1000000,32) \ - VAL_TEST_TERNARY(name) \ - VAL_FAIL_LONG_LONG_TERNARY(name) \ - VAL_END_TERNARY() - -#define VAL_START_UNARY(parm_type,max,incr) \ -{ \ - parm_type d,r,r_asm; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < max; d += incr) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { - -#define VAL_TEST_UNARY(name) \ - r_asm = name##_asm(&flags,d); \ - r = name(d); \ - if (r != r_asm || M.x86.R_EFLG != flags) { \ - failed = true; - -#define VAL_FAIL_BYTE_UNARY(name) \ - printk("fail\n"); \ - printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \ - r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%02X = %-15s(0x%02X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_FAIL_WORD_UNARY(name) \ - printk("fail\n"); \ - printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \ - r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X = %-15s(0x%04X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_FAIL_LONG_UNARY(name) \ - printk("fail\n"); \ - printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \ - r, #name, d, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%08X = %-15s(0x%08X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, print_flags(buf1,inflags), print_flags(buf2,flags)); - -#define VAL_END_UNARY() \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | ALL_FLAGS; \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_BYTE_UNARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_UNARY(u8,0xFF,0x1) \ - VAL_TEST_UNARY(name) \ - VAL_FAIL_BYTE_UNARY(name) \ - VAL_END_UNARY() - -#define VAL_WORD_UNARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_UNARY(u16,0xFF00,0x100) \ - VAL_TEST_UNARY(name) \ - VAL_FAIL_WORD_UNARY(name) \ - VAL_END_UNARY() - -#define VAL_WORD_BYTE_UNARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_UNARY(u16,0xFF,0x1) \ - VAL_TEST_UNARY(name) \ - VAL_FAIL_WORD_UNARY(name) \ - VAL_END_UNARY() - -#define VAL_LONG_UNARY(name) \ - printk("Validating %s ... ", #name); \ - VAL_START_UNARY(u32,0xFF000000,0x1000000) \ - VAL_TEST_UNARY(name) \ - VAL_FAIL_LONG_UNARY(name) \ - VAL_END_UNARY() - -#define VAL_BYTE_MUL(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u8 d,s; \ - u16 r,r_asm; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF; d += 1) { \ - for (s = 0; s < 0xFF; s += 1) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - name##_asm(&flags,&r_asm,d,s); \ - M.x86.R_AL = d; \ - name(s); \ - r = M.x86.R_AX; \ - if (r != r_asm || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ - r, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X = %-15s(0x%02X,0x%02X), flags = %s -> %s\n", \ - r_asm, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_WORD_MUL(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u16 d,s; \ - u16 r_lo,r_asm_lo; \ - u16 r_hi,r_asm_hi; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF00; d += 0x100) { \ - for (s = 0; s < 0xFF00; s += 0x100) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \ - M.x86.R_AX = d; \ - name(s); \ - r_lo = M.x86.R_AX; \ - r_hi = M.x86.R_DX; \ - if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ - r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X:0x%04X = %-15s(0x%04X,0x%04X), flags = %s -> %s\n", \ - r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_LONG_MUL(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u32 d,s; \ - u32 r_lo,r_asm_lo; \ - u32 r_hi,r_asm_hi; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF000000; d += 0x1000000) { \ - for (s = 0; s < 0xFF000000; s += 0x1000000) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - name##_asm(&flags,&r_asm_lo,&r_asm_hi,d,s); \ - M.x86.R_EAX = d; \ - name(s); \ - r_lo = M.x86.R_EAX; \ - r_hi = M.x86.R_EDX; \ - if (r_lo != r_asm_lo || r_hi != r_asm_hi || M.x86.R_EFLG != flags)\ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ - r_hi,r_lo, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%08X:0x%08X = %-15s(0x%08X,0x%08X), flags = %s -> %s\n", \ - r_asm_hi,r_asm_lo, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_BYTE_DIV(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u16 d,s; \ - u8 r_quot,r_rem,r_asm_quot,r_asm_rem; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF00; d += 0x100) { \ - for (s = 1; s < 0xFF; s += 1) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - M.x86.intr = 0; \ - M.x86.R_AX = d; \ - name(s); \ - r_quot = M.x86.R_AL; \ - r_rem = M.x86.R_AH; \ - if (M.x86.intr & INTR_SYNCH) \ - continue; \ - name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,s); \ - if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \ - r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%02X:0x%02X = %-15s(0x%04X,0x%02X), flags = %s -> %s\n", \ - r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_WORD_DIV(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u32 d,s; \ - u16 r_quot,r_rem,r_asm_quot,r_asm_rem; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF000000; d += 0x1000000) { \ - for (s = 0x100; s < 0xFF00; s += 0x100) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - M.x86.intr = 0; \ - M.x86.R_AX = d & 0xFFFF; \ - M.x86.R_DX = d >> 16; \ - name(s); \ - r_quot = M.x86.R_AX; \ - r_rem = M.x86.R_DX; \ - if (M.x86.intr & INTR_SYNCH) \ - continue; \ - name##_asm(&flags,&r_asm_quot,&r_asm_rem,d & 0xFFFF,d >> 16,s);\ - if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \ - r_quot, r_rem, #name, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%04X:0x%04X = %-15s(0x%08X,0x%04X), flags = %s -> %s\n", \ - r_asm_quot, r_asm_rem, #name"_asm", d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -#define VAL_LONG_DIV(name) \ - printk("Validating %s ... ", #name); \ -{ \ - u32 d,s; \ - u32 r_quot,r_rem,r_asm_quot,r_asm_rem; \ - u32 flags,inflags; \ - int f,failed = false; \ - char buf1[80],buf2[80]; \ - for (d = 0; d < 0xFF000000; d += 0x1000000) { \ - for (s = 0x100; s < 0xFF00; s += 0x100) { \ - M.x86.R_EFLG = inflags = flags = def_flags; \ - for (f = 0; f < 2; f++) { \ - M.x86.intr = 0; \ - M.x86.R_EAX = d; \ - M.x86.R_EDX = 0; \ - name(s); \ - r_quot = M.x86.R_EAX; \ - r_rem = M.x86.R_EDX; \ - if (M.x86.intr & INTR_SYNCH) \ - continue; \ - name##_asm(&flags,&r_asm_quot,&r_asm_rem,d,0,s); \ - if (r_quot != r_asm_quot || r_rem != r_asm_rem || M.x86.R_EFLG != flags) \ - failed = true; \ - if (failed || trace) { \ - if (failed) \ - printk("fail\n"); \ - printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \ - r_quot, r_rem, #name, 0, d, s, print_flags(buf1,inflags), print_flags(buf2,M.x86.R_EFLG)); \ - printk("0x%08X:0x%08X = %-15s(0x%08X:0x%08X,0x%08X), flags = %s -> %s\n", \ - r_asm_quot, r_asm_rem, #name"_asm", 0, d, s, print_flags(buf1,inflags), print_flags(buf2,flags)); \ - } \ - M.x86.R_EFLG = inflags = flags = def_flags | (ALL_FLAGS & ~F_OF); \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (failed) \ - break; \ - } \ - if (!failed) \ - printk("passed\n"); \ -} - -void -printk(const char *fmt, ...) -{ - va_list argptr; - - va_start(argptr, fmt); - vfprintf(stdout, fmt, argptr); - fflush(stdout); - va_end(argptr); -} - -char * -print_flags(char *buf, ulong flags) -{ - char *separator = ""; - - buf[0] = 0; - if (flags & F_CF) { - strcat(buf, separator); - strcat(buf, "CF"); - separator = ","; - } - if (flags & F_PF) { - strcat(buf, separator); - strcat(buf, "PF"); - separator = ","; - } - if (flags & F_AF) { - strcat(buf, separator); - strcat(buf, "AF"); - separator = ","; - } - if (flags & F_ZF) { - strcat(buf, separator); - strcat(buf, "ZF"); - separator = ","; - } - if (flags & F_SF) { - strcat(buf, separator); - strcat(buf, "SF"); - separator = ","; - } - if (flags & F_OF) { - strcat(buf, separator); - strcat(buf, "OF"); - separator = ","; - } - if (separator[0] == 0) - strcpy(buf, "None"); - return buf; -} - -int -main(int argc) -{ - ulong def_flags; - int trace = false; - - if (argc > 1) - trace = true; - memset(&M, 0, sizeof(M)); - def_flags = get_flags_asm() & ~ALL_FLAGS; - - VAL_WORD_UNARY(aaa_word); - VAL_WORD_UNARY(aas_word); - - VAL_WORD_UNARY(aad_word); - VAL_WORD_UNARY(aam_word); - - VAL_BYTE_BYTE_BINARY(adc_byte); - VAL_WORD_WORD_BINARY(adc_word); - VAL_LONG_LONG_BINARY(adc_long); - - VAL_BYTE_BYTE_BINARY(add_byte); - VAL_WORD_WORD_BINARY(add_word); - VAL_LONG_LONG_BINARY(add_long); - - VAL_BYTE_BYTE_BINARY(and_byte); - VAL_WORD_WORD_BINARY(and_word); - VAL_LONG_LONG_BINARY(and_long); - - VAL_BYTE_BYTE_BINARY(cmp_byte); - VAL_WORD_WORD_BINARY(cmp_word); - VAL_LONG_LONG_BINARY(cmp_long); - - VAL_BYTE_UNARY(daa_byte); - VAL_BYTE_UNARY(das_byte); /* Fails for 0x9A (out of range anyway) */ - - VAL_BYTE_UNARY(dec_byte); - VAL_WORD_UNARY(dec_word); - VAL_LONG_UNARY(dec_long); - - VAL_BYTE_UNARY(inc_byte); - VAL_WORD_UNARY(inc_word); - VAL_LONG_UNARY(inc_long); - - VAL_BYTE_BYTE_BINARY(or_byte); - VAL_WORD_WORD_BINARY(or_word); - VAL_LONG_LONG_BINARY(or_long); - - VAL_BYTE_UNARY(neg_byte); - VAL_WORD_UNARY(neg_word); - VAL_LONG_UNARY(neg_long); - - VAL_BYTE_UNARY(not_byte); - VAL_WORD_UNARY(not_word); - VAL_LONG_UNARY(not_long); - - VAL_BYTE_ROTATE(rcl_byte); - VAL_WORD_ROTATE(rcl_word); - VAL_LONG_ROTATE(rcl_long); - - VAL_BYTE_ROTATE(rcr_byte); - VAL_WORD_ROTATE(rcr_word); - VAL_LONG_ROTATE(rcr_long); - - VAL_BYTE_ROTATE(rol_byte); - VAL_WORD_ROTATE(rol_word); - VAL_LONG_ROTATE(rol_long); - - VAL_BYTE_ROTATE(ror_byte); - VAL_WORD_ROTATE(ror_word); - VAL_LONG_ROTATE(ror_long); - - VAL_BYTE_ROTATE(shl_byte); - VAL_WORD_ROTATE(shl_word); - VAL_LONG_ROTATE(shl_long); - - VAL_BYTE_ROTATE(shr_byte); - VAL_WORD_ROTATE(shr_word); - VAL_LONG_ROTATE(shr_long); - - VAL_BYTE_ROTATE(sar_byte); - VAL_WORD_ROTATE(sar_word); - VAL_LONG_ROTATE(sar_long); - - VAL_WORD_ROTATE_DBL(shld_word); - VAL_LONG_ROTATE_DBL(shld_long); - - VAL_WORD_ROTATE_DBL(shrd_word); - VAL_LONG_ROTATE_DBL(shrd_long); - - VAL_BYTE_BYTE_BINARY(sbb_byte); - VAL_WORD_WORD_BINARY(sbb_word); - VAL_LONG_LONG_BINARY(sbb_long); - - VAL_BYTE_BYTE_BINARY(sub_byte); - VAL_WORD_WORD_BINARY(sub_word); - VAL_LONG_LONG_BINARY(sub_long); - - VAL_BYTE_BYTE_BINARY(xor_byte); - VAL_WORD_WORD_BINARY(xor_word); - VAL_LONG_LONG_BINARY(xor_long); - - VAL_VOID_BYTE_BINARY(test_byte); - VAL_VOID_WORD_BINARY(test_word); - VAL_VOID_LONG_BINARY(test_long); - - VAL_BYTE_MUL(imul_byte); - VAL_WORD_MUL(imul_word); - VAL_LONG_MUL(imul_long); - - VAL_BYTE_MUL(mul_byte); - VAL_WORD_MUL(mul_word); - VAL_LONG_MUL(mul_long); - - VAL_BYTE_DIV(idiv_byte); - VAL_WORD_DIV(idiv_word); - VAL_LONG_DIV(idiv_long); - - VAL_BYTE_DIV(div_byte); - VAL_WORD_DIV(div_word); - VAL_LONG_DIV(div_long); - - return 0; -} diff --git a/plat/pc86/tests/build.lua b/plat/pc86/tests/build.lua index fe871e450..4550c817c 100644 --- a/plat/pc86/tests/build.lua +++ b/plat/pc86/tests/build.lua @@ -3,5 +3,5 @@ include("tests/plat/build.lua") plat_testsuite { name = "tests", plat = "pc86", - method = "qemu-system-i386" + method = "plat/pc86/emu+pc86emu", }