diff --git a/plat/linuxppc/emu/emu.c b/plat/linuxppc/emu/emu.c index b2f5f2844..0714de8e8 100644 --- a/plat/linuxppc/emu/emu.c +++ b/plat/linuxppc/emu/emu.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,6 +6,12 @@ #include #include "emu.h" +#define BO4 (1<<0) +#define BO3 (1<<1) +#define BO2 (1<<2) +#define BO1 (1<<3) +#define BO0 (1<<4) + cpu_t cpu; static inline bool carry(void) @@ -62,17 +69,46 @@ static void mcrf(uint8_t destfield, uint8_t srcfield) static void branch(uint8_t bo, uint8_t bi, uint32_t dest, bool a_bit, bool l_bit) { - fatal("branch not supported yet"); + bool bo0 = bo & BO0; + bool bo1 = bo & BO1; + bool bo2 = bo & BO2; + bool bo3 = bo & BO3; + bool ctr_ok; + bool cond_ok; + + if (!bo2) + cpu.ctr--; + ctr_ok = bo2 || (!!cpu.ctr ^ bo3); + cond_ok = bo0 || (!!(cpu.cr & (1<<(31-bi))) == bo1); + if (ctr_ok && cond_ok) + { + if (a_bit) + cpu.nia = dest; + else + cpu.nia = dest + cpu.cia; + } + if (l_bit) + cpu.lr = cpu.cia + 4; } static void read_multiple(uint32_t address, uint8_t reg) { - fatal("read_multiple not supported yet"); + while (reg != 32) + { + cpu.gpr[reg] = read_long(address); + reg++; + address += 4; + } } static void write_multiple(uint32_t address, uint8_t reg) { - fatal("write_multiple not supported yet"); + while (reg != 32) + { + write_long(address, cpu.gpr[reg]); + reg++; + address += 4; + } } static void read_string(uint32_t address, uint8_t reg, uint8_t bytes) @@ -137,9 +173,16 @@ static uint32_t popcntb(uint32_t source) fatal("popcntb not supported"); } +static uint32_t rotate(uint32_t i, uint32_t shift) +{ + return (i << shift) | (i >> (32-shift)); +} + static uint32_t rlwnm(uint32_t source, uint8_t shift, uint8_t mb, uint8_t me) { - fatal("rlwnm not supported"); + uint8_t masksize = 1 + me - mb; /* me and mb are inclusive */ + uint32_t mask = ((1<AL branch(0x1f, 0x00, LI, A, L); -<16-->AL branch(BO, BI, BD, A, L); +<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); <17-->.................1. system_call(LEV); diff --git a/plat/linuxppc/emu/main.c b/plat/linuxppc/emu/main.c index 3b2ef7676..21abadbc9 100755 --- a/plat/linuxppc/emu/main.c +++ b/plat/linuxppc/emu/main.c @@ -166,7 +166,11 @@ int main(int argc, char* argv[]) cpu.cia = entrypoint; } - fatal("execution unimplemented"); + for (;;) + { + dump_state(stderr); + single_step(); + } return 0; }