| ... | @@ -580,16 +580,7 @@ pub const TestContext = struct { | ... | @@ -580,16 +580,7 @@ pub const TestContext = struct { |
| 580 | } else { | 580 | } else { |
| 581 | std.debug.panic("SPU_2 has no native OS, check the test!", .{}); | 581 | std.debug.panic("SPU_2 has no native OS, check the test!", .{}); |
| 582 | } | 582 | } |
| 583 | var output = std.ArrayList(u8).init(allocator); | 583 | |
| 584 | // defer output.deinit(); | | |
| 585 | const uart = struct { | | |
| 586 | fn in(_out: usize) !u8 { | | |
| 587 | return error.not_implemented; | | |
| 588 | } | | |
| 589 | fn out(_output: usize, val: u8) !void { | | |
| 590 | try @intToPtr(*std.ArrayList(u8), _output).append(val); | | |
| 591 | } | | |
| 592 | }; | | |
| 593 | var interpreter = std.spu.interpreter(struct { | 584 | var interpreter = std.spu.interpreter(struct { |
| 594 | RAM: [0x10000]u8 = undefined, | 585 | RAM: [0x10000]u8 = undefined, |
| 595 | | 586 | |
| ... | @@ -611,14 +602,59 @@ pub const TestContext = struct { | ... | @@ -611,14 +602,59 @@ pub const TestContext = struct { |
| 611 | .bus = .{}, | 602 | .bus = .{}, |
| 612 | }; | 603 | }; |
| 613 | | 604 | |
| 614 | //defer interpreter.deinit(allocator); | 605 | { |
| 615 | std.debug.print("TODO implement SPU-II test loader\n", .{}); | 606 | var load_node = update_node.start("load", null); |
| 616 | std.process.exit(1); | 607 | load_node.activate(); |
| | 608 | defer load_node.end(); |
| | 609 | |
| | 610 | var file = try tmp.dir.openFile(bin_name, .{ .read = true }); |
| | 611 | defer file.close(); |
| | 612 | |
| | 613 | const header = try std.elf.readHeader(file); |
| | 614 | var iterator = header.program_header_iterator(file); |
| | 615 | |
| | 616 | var none_loaded = true; |
| | 617 | |
| | 618 | while (try iterator.next()) |phdr| { |
| | 619 | if (phdr.p_type != std.elf.PT_LOAD) { |
| | 620 | std.debug.print("Encountered unexpected ELF program header: type {}\n", .{phdr.p_type}); |
| | 621 | std.process.exit(1); |
| | 622 | } |
| | 623 | if (phdr.p_paddr != phdr.p_vaddr) { |
| | 624 | std.debug.print("Physical address does not match virtual address in ELF header!\n", .{}); |
| | 625 | std.process.exit(1); |
| | 626 | } |
| | 627 | if (phdr.p_filesz != phdr.p_memsz) { |
| | 628 | std.debug.print("Physical size does not match virtual size in ELF header!\n", .{}); |
| | 629 | std.process.exit(1); |
| | 630 | } |
| | 631 | if ((try file.pread(interpreter.bus.RAM[phdr.p_paddr .. phdr.p_paddr + phdr.p_filesz], phdr.p_offset)) != phdr.p_filesz) { |
| | 632 | std.debug.print("Read less than expected from ELF file!", .{}); |
| | 633 | std.process.exit(1); |
| | 634 | } |
| | 635 | std.log.scoped(.spu2_test).debug("Loaded 0x{x} bytes to 0x{x:0<4}\n", .{ phdr.p_filesz, phdr.p_paddr }); |
| | 636 | none_loaded = false; |
| | 637 | } |
| | 638 | if (none_loaded) { |
| | 639 | std.debug.print("No data found in ELF file!\n", .{}); |
| | 640 | std.process.exit(1); |
| | 641 | } |
| | 642 | } |
| | 643 | |
| | 644 | var exec_node = update_node.start("execute", null); |
| | 645 | exec_node.activate(); |
| | 646 | defer exec_node.end(); |
| | 647 | |
| 617 | // TODO: loop detection? Solve the halting problem? fork() and limit by wall clock? | 648 | // TODO: loop detection? Solve the halting problem? fork() and limit by wall clock? |
| 618 | // Limit by emulated cycles? | 649 | // Limit by emulated cycles? |
| 619 | // while (!interpreter.undefined0) { | 650 | while (!interpreter.undefined0) { |
| 620 | // try interpreter.ExecuteBlock(100); | 651 | const pre_ip = interpreter.ip; |
| 621 | // } | 652 | try interpreter.ExecuteBlock(1); |
| | 653 | if (pre_ip == interpreter.ip) { |
| | 654 | std.debug.print("Infinite loop detected in SPU II test!\n", .{}); |
| | 655 | std.process.exit(1); |
| | 656 | } |
| | 657 | } |
| 622 | } | 658 | } |
| 623 | } | 659 | } |
| 624 | var exec_result = x: { | 660 | var exec_result = x: { |