import recent kvm-unit-test changes (fixes incorrectly failing push es test)

This commit is contained in:
Fabian 2022-11-22 17:54:34 -06:00
parent fa0a75c927
commit da0845189b
2 changed files with 127 additions and 81 deletions

View file

@ -1077,21 +1077,22 @@ CPU.prototype.load_multiboot = function(buffer)
function() {});
// only for kvm-unit-test
for(let i = 0xE; i <= 0xF; i++)
for(let i = 0; i <= 0xF; i++)
{
this.io.register_write(0x2000 + i, this,
function(value)
function handle_write(value)
{
dbg_log("kvm-unit-test: Set irq " + h(i) + " to " + h(value, 2));
if(value)
{
dbg_log("kvm-unit-test: Set irq " + h(i) + " to " + h(value, 2));
if(value)
{
this.device_raise_irq(i);
}
else
{
this.device_lower_irq(i);
}
});
this.device_raise_irq(i);
}
else
{
this.device_lower_irq(i);
}
}
this.io.register_write(0x2000 + i, this, handle_write, handle_write, handle_write);
}
this.update_state_flags();

View file

@ -77,6 +77,15 @@ static void serial_init(void)
lcr = inb(serial_iobase + 0x03);
lcr &= ~0x80;
outb(lcr, serial_iobase + 0x03);
/* IER: disable interrupts */
outb(0x00, serial_iobase + 0x01);
/* LCR: 8 bits, no parity, one stop bit */
outb(0x03, serial_iobase + 0x03);
/* FCR: disable FIFO queues */
outb(0x00, serial_iobase + 0x02);
/* MCR: RTS, DTR on */
outb(0x03, serial_iobase + 0x04);
}
#endif
@ -115,6 +124,15 @@ static int failed;
static void exit(int code)
{
outb(code, 0xf4);
if (code == 0)
print_serial("--- DONE: 0 ---\n");
else
print_serial("--- DONE: 1 ---\n");
while (1) {
asm volatile("hlt" ::: "memory");
}
}
struct regs {
@ -234,7 +252,7 @@ static void exec_in_big_real_mode(struct insn_desc *insn)
#define R_SP 64
#define R_BP 128
int regs_equal(int ignore)
static int regs_equal(int ignore)
{
const u32 *p1 = &inregs.eax, *p2 = &outregs.eax; // yuck
int i;
@ -271,7 +289,7 @@ static void report(const char *name, u16 regs_ignore, _Bool ok)
); \
extern struct insn_desc insn_##name;
void test_xchg(void)
static void test_xchg(void)
{
MK_INSN(xchg_test1, "xchg %eax,%eax\n\t");
MK_INSN(xchg_test2, "xchg %eax,%ebx\n\t");
@ -316,7 +334,7 @@ void test_xchg(void)
outregs.eax == inregs.esp && outregs.esp == inregs.eax);
}
void test_shld(void)
static void test_shld(void)
{
MK_INSN(shld_test, "shld $8,%edx,%eax\n\t");
@ -326,7 +344,7 @@ void test_shld(void)
report("shld", ~0, outregs.eax == 0xbeef);
}
void test_mov_imm(void)
static void test_mov_imm(void)
{
MK_INSN(mov_r32_imm_1, "mov $1234567890, %eax");
MK_INSN(mov_r16_imm_1, "mov $1234, %ax");
@ -354,7 +372,7 @@ void test_mov_imm(void)
report("mov 5", R_AX, outregs.eax == 0x1234);
}
void test_sub_imm(void)
static void test_sub_imm(void)
{
MK_INSN(sub_r32_imm_1, "mov $1234567890, %eax\n\t" "sub $10, %eax\n\t");
MK_INSN(sub_r16_imm_1, "mov $1234, %ax\n\t" "sub $10, %ax\n\t");
@ -378,7 +396,7 @@ void test_sub_imm(void)
report("sub 4", R_AX, outregs.eax == 0x24);
}
void test_xor_imm(void)
static void test_xor_imm(void)
{
MK_INSN(xor_r32_imm_1, "mov $1234567890, %eax\n\t" "xor $1234567890, %eax\n\t");
MK_INSN(xor_r16_imm_1, "mov $1234, %ax\n\t" "xor $1234, %ax\n\t");
@ -402,7 +420,7 @@ void test_xor_imm(void)
report("xor 4", R_AX, outregs.eax == 0);
}
void test_cmp_imm(void)
static void test_cmp_imm(void)
{
MK_INSN(cmp_test1, "mov $0x34, %al\n\t"
"cmp $0x34, %al\n\t");
@ -427,7 +445,7 @@ void test_cmp_imm(void)
report("cmp 3", ~0, (outregs.eflags & (1<<6)) == 0);
}
void test_add_imm(void)
static void test_add_imm(void)
{
MK_INSN(add_test1, "mov $0x43211234, %eax \n\t"
"add $0x12344321, %eax \n\t");
@ -443,7 +461,7 @@ void test_add_imm(void)
report("add 2", ~0, outregs.eax == 0x33);
}
void test_eflags_insn(void)
static void test_eflags_insn(void)
{
MK_INSN(clc, "clc");
MK_INSN(stc, "stc");
@ -473,7 +491,7 @@ void test_eflags_insn(void)
report("std", ~0, (outregs.eflags & (1 << 10)));
}
void test_io(void)
static void test_io(void)
{
MK_INSN(io_test1, "mov $0xff, %al \n\t"
"out %al, $0xe0 \n\t"
@ -530,7 +548,7 @@ extern void retf(void);
asm ("retf_imm: lretw $10");
extern void retf_imm(void);
void test_call(void)
static void test_call(void)
{
u32 addr;
@ -576,7 +594,7 @@ void test_call(void)
report("retf imm 1", 0, 1);
}
void test_jcc_short(void)
static void test_jcc_short(void)
{
MK_INSN(jnz_short1, "jnz 1f\n\t"
"mov $0x1234, %eax\n\t"
@ -601,7 +619,7 @@ void test_jcc_short(void)
report("jmp short 1", ~0, 1);
}
void test_jcc_near(void)
static void test_jcc_near(void)
{
/* encode near jmp manually. gas will not do it if offsets < 127 byte */
MK_INSN(jnz_near1, ".byte 0x0f, 0x85, 0x06, 0x00\n\t"
@ -624,9 +642,9 @@ void test_jcc_near(void)
report("jmp near 1", 0, 1);
}
void test_long_jmp()
static void test_long_jmp(void)
{
MK_INSN(long_jmp, "call 1f\n\t"
MK_INSN(long_jmp, "calll 1f\n\t"
"jmp 2f\n\t"
"1: jmp $0, $test_function\n\t"
"2:\n\t");
@ -637,7 +655,7 @@ void test_long_jmp()
report("jmp far 1", R_AX, outregs.eax == 0x1234);
}
void test_push_pop()
static void test_push_pop(void)
{
MK_INSN(push32, "mov $0x12345678, %eax\n\t"
"push %eax\n\t"
@ -649,24 +667,24 @@ void test_push_pop()
MK_INSN(push_es, "mov $0x231, %bx\n\t" //Just write a dummy value to see if it gets overwritten
"mov $0x123, %ax\n\t"
"mov %ax, %es\n\t"
"pushl %es\n\t"
"pop %ebx \n\t"
"pushw %es\n\t"
"pop %bx \n\t"
);
MK_INSN(pop_es, "push %eax\n\t"
"popl %es\n\t"
MK_INSN(pop_es, "push %ax\n\t"
"popw %es\n\t"
"mov %es, %bx\n\t"
);
MK_INSN(push_pop_ss, "push %ss\n\t"
MK_INSN(push_pop_ss, "pushw %ss\n\t"
"pushw %ax\n\t"
"popw %ss\n\t"
"mov %ss, %bx\n\t"
"pop %ss\n\t"
"popw %ss\n\t"
);
MK_INSN(push_pop_fs, "push %fs\n\t"
MK_INSN(push_pop_fs, "pushl %fs\n\t"
"pushl %eax\n\t"
"popl %fs\n\t"
"mov %fs, %ebx\n\t"
"pop %fs\n\t"
"popl %fs\n\t"
);
MK_INSN(push_pop_high_esp_bits,
"xor $0x12340000, %esp \n\t"
@ -703,7 +721,7 @@ void test_push_pop()
report("push/pop with high bits set in %esp", R_BX, outregs.ebx == 0x9977);
}
void test_null(void)
static void test_null(void)
{
MK_INSN(null, "");
@ -715,26 +733,26 @@ void test_null(void)
static void test_pusha_popa(void)
{
MK_INSN(pusha, "pusha\n\t"
"pop %edi\n\t"
"pop %esi\n\t"
"pop %ebp\n\t"
"add $4, %esp\n\t"
"pop %ebx\n\t"
"pop %edx\n\t"
"pop %ecx\n\t"
"pop %eax\n\t"
MK_INSN(pusha, "pushal\n\t"
"popl %edi\n\t"
"popl %esi\n\t"
"popl %ebp\n\t"
"addl $4, %esp\n\t"
"popl %ebx\n\t"
"popl %edx\n\t"
"popl %ecx\n\t"
"popl %eax\n\t"
);
MK_INSN(popa, "push %eax\n\t"
"push %ecx\n\t"
"push %edx\n\t"
"push %ebx\n\t"
"push %esp\n\t"
"push %ebp\n\t"
"push %esi\n\t"
"push %edi\n\t"
"popa\n\t"
MK_INSN(popa, "pushl %eax\n\t"
"pushl %ecx\n\t"
"pushl %edx\n\t"
"pushl %ebx\n\t"
"pushl %esp\n\t"
"pushl %ebp\n\t"
"pushl %esi\n\t"
"pushl %edi\n\t"
"popal\n\t"
);
init_inregs(&(struct regs){ .eax = 0, .ebx = 1, .ecx = 2, .edx = 3, .esi = 4, .edi = 5, .ebp = 6 });
@ -746,11 +764,11 @@ static void test_pusha_popa(void)
report("pusha/popa 1", 0, 1);
}
void test_iret()
static void test_iret(void)
{
MK_INSN(iret32, "pushf\n\t"
MK_INSN(iret32, "pushfl\n\t"
"pushl %cs\n\t"
"call 1f\n\t" /* a near call will push eip onto the stack */
"calll 1f\n\t" /* a near call will push eip onto the stack */
"jmp 2f\n\t"
"1: iretl\n\t"
"2:\n\t"
@ -769,7 +787,7 @@ void test_iret()
"orl $0xffc18028, %eax\n\t"
"pushl %eax\n\t"
"pushl %cs\n\t"
"call 1f\n\t"
"calll 1f\n\t"
"jmp 2f\n\t"
"1: iretl\n\t"
"2:\n\t");
@ -801,7 +819,7 @@ void test_iret()
report("iret 4", R_AX, 1);
}
void test_int()
static void test_int(void)
{
init_inregs(NULL);
@ -814,7 +832,27 @@ void test_int()
report("int 1", 0, 1);
}
void test_imul()
static void test_sti_inhibit(void)
{
init_inregs(NULL);
*(u32 *)(0x73 * 4) = 0x1000; /* Store IRQ 11 handler in the IDT */
*(u8 *)(0x1000) = 0xcf; /* 0x1000 contains an IRET instruction */
MK_INSN(sti_inhibit, "cli\n\t"
"movw $0x200b, %dx\n\t"
"movl $1, %eax\n\t"
"outl %eax, %dx\n\t" /* Set IRQ11 */
"movl $0, %eax\n\t"
"outl %eax, %dx\n\t" /* Clear IRQ11 */
"sti\n\t"
"hlt\n\t");
exec_in_big_real_mode(&insn_sti_inhibit);
report("sti inhibit", ~0, 1);
}
static void test_imul(void)
{
MK_INSN(imul8_1, "mov $2, %al\n\t"
"mov $-4, %cx\n\t"
@ -863,7 +901,7 @@ void test_imul()
report("imul 6", R_AX | R_CX | R_DX, outregs.eax == 8);
}
void test_mul()
static void test_mul(void)
{
MK_INSN(mul8, "mov $2, %al\n\t"
"mov $4, %cx\n\t"
@ -889,7 +927,7 @@ void test_mul()
report("mul 3", R_AX | R_CX | R_DX, outregs.eax == 8);
}
void test_div()
static void test_div(void)
{
MK_INSN(div8, "mov $257, %ax\n\t"
"mov $2, %cl\n\t"
@ -917,7 +955,7 @@ void test_div()
outregs.eax == 102 && outregs.edx == 2);
}
void test_idiv()
static void test_idiv(void)
{
MK_INSN(idiv8, "mov $256, %ax\n\t"
"mov $-2, %cl\n\t"
@ -943,7 +981,7 @@ void test_idiv()
report("idiv 3", R_AX | R_CX | R_DX, outregs.eax == (u32)-256);
}
void test_cbw(void)
static void test_cbw(void)
{
MK_INSN(cbw, "mov $0xFE, %eax \n\t"
"cbw\n\t");
@ -959,7 +997,7 @@ void test_cbw(void)
report("cwde 1", ~0, outregs.eax == 0xFFFFFFFE);
}
void test_loopcc(void)
static void test_loopcc(void)
{
MK_INSN(loop, "mov $10, %ecx\n\t"
"1: inc %eax\n\t"
@ -1271,7 +1309,7 @@ static void test_das(void)
report("DAS", ~0, nr_fail == 0);
}
void test_cwd_cdq()
static void test_cwd_cdq(void)
{
/* Sign-bit set */
MK_INSN(cwd_1, "mov $0x8000, %ax\n\t"
@ -1316,14 +1354,14 @@ static struct {
0x10,
};
void test_lds_lss()
static void test_lds_lss(void)
{
init_inregs(&(struct regs){ .ebx = (unsigned long)&desc });
MK_INSN(lds, "push %ds\n\t"
MK_INSN(lds, "pushl %ds\n\t"
"lds (%ebx), %eax\n\t"
"mov %ds, %ebx\n\t"
"pop %ds\n\t");
"popl %ds\n\t");
exec_in_big_real_mode(&insn_lds);
report("lds", R_AX | R_BX,
outregs.eax == (unsigned long)desc.address &&
@ -1336,35 +1374,35 @@ void test_lds_lss()
outregs.eax == (unsigned long)desc.address &&
outregs.ebx == desc.sel);
MK_INSN(lfs, "push %fs\n\t"
MK_INSN(lfs, "pushl %fs\n\t"
"lfs (%ebx), %eax\n\t"
"mov %fs, %ebx\n\t"
"pop %fs\n\t");
"popl %fs\n\t");
exec_in_big_real_mode(&insn_lfs);
report("lfs", R_AX | R_BX,
outregs.eax == (unsigned long)desc.address &&
outregs.ebx == desc.sel);
MK_INSN(lgs, "push %gs\n\t"
MK_INSN(lgs, "pushl %gs\n\t"
"lgs (%ebx), %eax\n\t"
"mov %gs, %ebx\n\t"
"pop %gs\n\t");
"popl %gs\n\t");
exec_in_big_real_mode(&insn_lgs);
report("lgs", R_AX | R_BX,
outregs.eax == (unsigned long)desc.address &&
outregs.ebx == desc.sel);
MK_INSN(lss, "push %ss\n\t"
MK_INSN(lss, "mov %ss, %dx\n\t"
"lss (%ebx), %eax\n\t"
"mov %ss, %ebx\n\t"
"pop %ss\n\t");
"mov %dx, %ss\n\t");
exec_in_big_real_mode(&insn_lss);
report("lss", R_AX | R_BX,
outregs.eax == (unsigned long)desc.address &&
outregs.ebx == desc.sel);
}
void test_jcxz(void)
static void test_jcxz(void)
{
MK_INSN(jcxz1, "jcxz 1f\n\t"
"mov $0x1234, %eax\n\t"
@ -1700,7 +1738,7 @@ static void test_perf_memory_adc(void)
print_serial(" millicycles/emulated ADC instruction\n");
}
void test_dr_mod(void)
static void test_dr_mod(void)
{
MK_INSN(drmod, "movl %ebx, %dr0\n\t"
".byte 0x0f \n\t .byte 0x21 \n\t .byte 0x0\n\t");
@ -1711,7 +1749,7 @@ void test_dr_mod(void)
report("mov dr with mod bits", R_AX | R_BX, outregs.eax == 0xaced);
}
void test_smsw(void)
static void test_smsw(void)
{
MK_INSN(smsw, "movl %cr0, %ebx\n\t"
"movl %ebx, %ecx\n\t"
@ -1726,7 +1764,7 @@ void test_smsw(void)
report("smsw", R_AX | R_BX | R_CX, outregs.eax == outregs.ebx);
}
void test_xadd(void)
static void test_xadd(void)
{
MK_INSN(xadd, "xaddl %eax, %eax\n\t");
@ -1739,6 +1777,10 @@ void test_xadd(void)
void realmode_start(void)
{
// enable interrupts (v86 only)
outb(0, 0x21);
outb(0, 0xa1);
test_null();
test_shld();
@ -1760,6 +1802,7 @@ void realmode_start(void)
test_xchg();
test_iret();
test_int();
test_sti_inhibit();
test_imul();
test_mul();
test_div();
@ -1801,6 +1844,7 @@ void realmode_start(void)
unsigned long long r_gdt[] = { 0, 0x9b000000ffff, 0x93000000ffff };
struct table_descr r_gdt_descr = { sizeof(r_gdt) - 1, &r_gdt };
struct table_descr r_idt_descr = { 0x3ff, 0 };
asm(
".section .init \n\t"
@ -1821,6 +1865,7 @@ asm(
".text \n\t"
"start: \n\t"
"lgdt r_gdt_descr \n\t"
"lidt r_idt_descr \n\t"
"ljmp $8, $1f; 1: \n\t"
".code16gcc \n\t"
"mov $16, %eax \n\t"