From 5111556d145675e4eba1a65abf298976358d2b1d Mon Sep 17 00:00:00 2001 From: David Given Date: Thu, 14 Jun 2018 05:53:39 -0700 Subject: [PATCH] Got the emulator to the point where we're hitting the first major emulation bug (the calloc test hangs). --- plat/linuxppc/emu/emu.c | 33 +++++++++++++++++++++++++----- plat/linuxppc/emu/instructions.dat | 8 ++++---- plat/linuxppc/emu/main.c | 13 ++++++++++-- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/plat/linuxppc/emu/emu.c b/plat/linuxppc/emu/emu.c index 0714de8e8..31bb7f1b7 100644 --- a/plat/linuxppc/emu/emu.c +++ b/plat/linuxppc/emu/emu.c @@ -44,6 +44,11 @@ static inline uint32_t ext16(int16_t n) return (n << 16) >> 16; } +static inline uint32_t ext26(int32_t n) +{ + return (n << 6) >> 6; +} + static bool getcr(uint8_t bit) { bit = 31 - bit; /* note PowerPC bit numbering */ @@ -59,7 +64,12 @@ static void setcr(uint8_t bit, bool value) static void setcr0(bool setcr0, uint32_t value) { if (setcr0) - fatal("setcr0 not supported yet"); + { + setcr(0, (int32_t)value < 0); + setcr(1, (int32_t)value > 0); + setcr(2, value == 0); + setcr(3, cpu.xer & (1<<31)); + } } static void mcrf(uint8_t destfield, uint8_t srcfield) @@ -142,6 +152,8 @@ static int32_t divo(int32_t a, int32_t b, bool set_o) if (set_o) fatal("can't use O bit in div yet"); + if (b == 0) + return 0; return a / b; } @@ -150,17 +162,27 @@ static uint32_t divuo(uint32_t a, uint32_t b, bool set_o) if (set_o) fatal("can't use O bit in divu yet"); + if (b == 0) + return 0; return a / b; } static void compares(int32_t a, int32_t b, uint8_t field) { - fatal("compares not supported yet"); + uint8_t bit = field*4; + setcr(bit+0, ab); + setcr(bit+2, a==b); + setcr(bit+3, cpu.xer & (1<<31)); } static void compareu(uint32_t a, uint32_t b, uint8_t field) { - fatal("compareu not supported yet"); + uint8_t bit = field*4; + setcr(bit+0, ab); + setcr(bit+2, a==b); + setcr(bit+3, cpu.xer & (1<<31)); } static uint32_t cntlzw(uint32_t source) @@ -207,11 +229,12 @@ void dump_state(FILE* stream) fprintf(stream, "pc=0x%08x lr=0x%08x ctr=0x%08x xer=0x%08x cr=0x%08x\n", cpu.cia, cpu.lr, cpu.ctr, cpu.xer, cpu.cr); + fprintf(stream, "insn=0x%08x", read_long(cpu.cia)); for (i=0; i<32; i++) { - if ((i % 8) == 7) + if ((i % 4) == 0) fprintf(stream, "\n"); - fprintf(stream, "gpr%d=0x%08x ", i, cpu.gpr[i]); + fprintf(stream, "gpr%02d=0x%08x ", i, cpu.gpr[i]); } fprintf(stream, "\n"); } diff --git a/plat/linuxppc/emu/instructions.dat b/plat/linuxppc/emu/instructions.dat index 34108d4d7..2203f9ccf 100644 --- a/plat/linuxppc/emu/instructions.dat +++ b/plat/linuxppc/emu/instructions.dat @@ -5,10 +5,10 @@ # Branch processor instructions. -<18-->AL branch(0x1f, 0x00, LI<<2, A, L); -<16-->AL branch(BO, BI, BD<<2, A, L); -<19--><16------>L branch(BO, BI, cpu.lr, 1, L); -<19--><528----->L branch(BO, BI, cpu.ctr, 1, L); +<18-->AL branch(0x1f, 0x00, ext26(LI<<2), A, L); +<16-->AL branch(BO, BI, ext16(BD<<2), A, L); +<19--><16------>L branch(BO, BI, cpu.lr, 1, L); +<19--><528----->L branch(BO, BI, cpu.ctr, 1, L); <17-->.................1. system_call(LEV); # Condition register instructions. diff --git a/plat/linuxppc/emu/main.c b/plat/linuxppc/emu/main.c index 21abadbc9..b7ac3e896 100755 --- a/plat/linuxppc/emu/main.c +++ b/plat/linuxppc/emu/main.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -43,6 +44,8 @@ uint32_t entrypoint = RAM_BASE; void fatal(char* fmt, ...) { + static bool guard = false; + va_list ap; va_start(ap, fmt); @@ -51,13 +54,19 @@ void fatal(char* fmt, ...) fprintf(stderr, "\n"); va_end(ap); + if (!guard) + { + guard = true; + dump_state(stderr); + } + exit(EXIT_FAILURE); } static uint32_t transform_address(uint32_t address) { uint32_t a = address - RAM_BASE; - if (a >= RAM_TOP) + if (a >= (RAM_TOP-RAM_BASE)) fatal("address 0x%x out of bounds", address); return a; } @@ -168,7 +177,7 @@ int main(int argc, char* argv[]) for (;;) { - dump_state(stderr); + //dump_state(stderr); single_step(); }