diff --git a/devices/heathrow.cpp b/devices/heathrow.cpp index 48ff9d0..3bfba98 100644 --- a/devices/heathrow.cpp +++ b/devices/heathrow.cpp @@ -21,7 +21,7 @@ using namespace std; HeathrowIC::HeathrowIC() : PCIDevice("mac-io/heathrow") { this->viacuda = new ViaCuda(); - this->nvram = new NVram(); + this->nvram = new NVram(); } HeathrowIC::~HeathrowIC() @@ -41,17 +41,20 @@ uint32_t HeathrowIC::pci_cfg_read(uint32_t reg_offs, uint32_t size) void HeathrowIC::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { - switch(reg_offs) { + switch (reg_offs) { case CFG_REG_BAR0: // base address register - value = LE2BE(value); + value = LE2BE(value); if (value == 0xFFFFFFFF) { LOG_F(ERROR, "%s err: BAR0 block size determination not \ implemented yet \n", this->name.c_str()); - } else if (value & 1) { + } + else if (value & 1) { LOG_F(ERROR, "%s err: BAR0 I/O space not supported! \n", this->name.c_str()); - } else if (value & 0x06) { + } + else if (value & 0x06) { LOG_F(ERROR, "%s err: BAR0 64-bit I/O space not supported! \n", this->name.c_str()); - } else { + } + else { this->base_addr = value & 0xFFF80000; this->host_instance->pci_register_mmio_region(this->base_addr, 0x80000, this); LOG_F(INFO, "%s base address set to %x \n", this->name.c_str(), this->base_addr); @@ -64,19 +67,19 @@ uint32_t HeathrowIC::read(uint32_t offset, int size) { uint32_t res = 0; - LOG_F(INFO, "%s: reading from offset %x \n", this->name.c_str(), offset); + LOG_F(9, "%s: reading from offset %x \n", this->name.c_str(), offset); unsigned sub_addr = (offset >> 12) & 0x7F; - switch(sub_addr) { + switch (sub_addr) { case 0: res = mio_ctrl_read(offset, size); break; case 8: - LOG_F(INFO, "Attempting to read DMA channel register space \n"); + LOG_F(9, "Attempting to read DMA channel register space \n"); break; case 0x14: - LOG_F(INFO, "Attempting to read AWACS-Screamer register space \n"); + LOG_F(9, "Attempting to read AWACS-Screamer register space \n"); break; case 0x16: case 0x17: @@ -85,7 +88,8 @@ uint32_t HeathrowIC::read(uint32_t offset, int size) default: if (sub_addr >= 0x60) { res = this->nvram->read_byte((offset - 0x60000) >> 4); - } else { + } + else { LOG_F(WARNING, "Attempting to read unmapped I/O space: %x \n", offset); } } @@ -95,19 +99,19 @@ uint32_t HeathrowIC::read(uint32_t offset, int size) void HeathrowIC::write(uint32_t offset, uint32_t value, int size) { - LOG_F(INFO, "%s: writing to offset %x \n", this->name.c_str(), offset); + LOG_F(9, "%s: writing to offset %x \n", this->name.c_str(), offset); unsigned sub_addr = (offset >> 12) & 0x7F; - switch(sub_addr) { + switch (sub_addr) { case 0: mio_ctrl_write(offset, value, size); break; case 8: - LOG_F(INFO, "Attempting to write to DMA channel register space \n"); + LOG_F(9, "Attempting to write to DMA channel register space \n"); break; case 0x14: - LOG_F(INFO, "Attempting to write to AWACS-Screamer register space \n"); + LOG_F(9, "Attempting to write to AWACS-Screamer register space \n"); break; case 0x16: case 0x17: @@ -116,7 +120,8 @@ void HeathrowIC::write(uint32_t offset, uint32_t value, int size) default: if (sub_addr >= 0x60) { this->nvram->write_byte((offset - 0x60000) >> 4, value); - } else { + } + else { LOG_F(WARNING, "Attempting to write to unmapped I/O space: %x \n", offset); } } @@ -126,20 +131,20 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) { uint32_t res = 0; - switch(offset & 0xFF) { + switch (offset & 0xFF) { case 0x24: - LOG_F(INFO, "read from MIO:Int_Mask1 register \n"); + LOG_F(9, "read from MIO:Int_Mask1 register \n"); res = this->int_mask1; break; case 0x28: - LOG_F(INFO, "read from MIO:Int_Clear1 register \n"); + LOG_F(9, "read from MIO:Int_Clear1 register \n"); res = this->int_clear1; break; case 0x34: /* heathrowIDs / HEATHROW_MBCR (Linux): media bay config reg? */ res = 0xF0700000UL; break; case 0x38: - LOG_F(INFO, "read from MIO:Feat_Ctrl register \n"); + LOG_F(9, "read from MIO:Feat_Ctrl register \n"); res = this->feat_ctrl; break; default: @@ -152,21 +157,21 @@ uint32_t HeathrowIC::mio_ctrl_read(uint32_t offset, int size) void HeathrowIC::mio_ctrl_write(uint32_t offset, uint32_t value, int size) { - switch(offset & 0xFF) { + switch (offset & 0xFF) { case 0x24: - LOG_F(INFO, "write %x to MIO:Int_Mask1 register \n", value); + LOG_F(9, "write %x to MIO:Int_Mask1 register \n", value); this->int_mask1 = value; break; case 0x28: - LOG_F(INFO, "write %x to MIO:Int_Clear1 register \n", value); + LOG_F(9, "write %x to MIO:Int_Clear1 register \n", value); this->int_clear1 = value; break; case 0x38: - LOG_F(INFO, "write %x to MIO:Feat_Ctrl register \n", value); + LOG_F(9, "write %x to MIO:Feat_Ctrl register \n", value); this->feat_ctrl = value; break; default: LOG_F(WARNING, "unknown MIO register at %x \n", offset); break; } -} +} \ No newline at end of file diff --git a/devices/mpc106.cpp b/devices/mpc106.cpp index cd45bd6..fd0cf8a 100644 --- a/devices/mpc106.cpp +++ b/devices/mpc106.cpp @@ -115,7 +115,7 @@ void MPC106::pci_write(uint32_t value, uint32_t size) uint32_t MPC106::pci_cfg_read(uint32_t reg_offs, uint32_t size) { #ifdef MPC106_DEBUG - LOG_F(INFO, "read from Grackle register %08X\n", reg_offs); + LOG_F(9, "read from Grackle register %08X\n", reg_offs); #endif switch(size) { @@ -138,7 +138,7 @@ uint32_t MPC106::pci_cfg_read(uint32_t reg_offs, uint32_t size) void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) { #ifdef MPC106_DEBUG - LOG_F(INFO, "write %08X to Grackle register %08X\n", value, reg_offs); + LOG_F(9, "write %08X to Grackle register %08X\n", value, reg_offs); #endif // FIXME: implement write-protection for read-only registers @@ -162,7 +162,7 @@ void MPC106::pci_cfg_write(uint32_t reg_offs, uint32_t value, uint32_t size) if (this->my_pci_cfg_hdr[0xF2] & 8) { #ifdef MPC106_DEBUG - LOG_F(INFO, "MPC106: MCCR1[MEMGO] was set! \n"); + LOG_F(9, "MPC106: MCCR1[MEMGO] was set! \n"); #endif setup_ram(); } diff --git a/devices/viacuda.cpp b/devices/viacuda.cpp index 1be1750..7e9c595 100644 --- a/devices/viacuda.cpp +++ b/devices/viacuda.cpp @@ -23,12 +23,12 @@ ViaCuda::ViaCuda() { /* FIXME: is this the correct VIA initialization? */ - this->via_regs[VIA_A] = 0x80; + this->via_regs[VIA_A] = 0x80; this->via_regs[VIA_DIRB] = 0xFF; this->via_regs[VIA_DIRA] = 0xFF; this->via_regs[VIA_T1LL] = 0xFF; this->via_regs[VIA_T1LH] = 0xFF; - this->via_regs[VIA_IER] = 0x7F; + this->via_regs[VIA_IER] = 0x7F; //PRAM Pre-Initialization this->pram_obj = new NVram("pram.bin", 256); @@ -56,12 +56,12 @@ uint8_t ViaCuda::read(int reg) { uint8_t res; - LOG_F(INFO, "Read VIA reg %x \n", (uint32_t)reg); + LOG_F(9, "Read VIA reg %x \n", (uint32_t)reg); res = this->via_regs[reg & 0xF]; /* reading from some VIA registers triggers special actions */ - switch(reg & 0xF) { + switch (reg & 0xF) { case VIA_B: res = this->via_regs[VIA_B]; break; @@ -78,7 +78,7 @@ uint8_t ViaCuda::read(int reg) void ViaCuda::write(int reg, uint8_t value) { - switch(reg & 0xF) { + switch (reg & 0xF) { case VIA_B: this->via_regs[VIA_B] = value; cuda_write(value); @@ -88,24 +88,24 @@ void ViaCuda::write(int reg, uint8_t value) LOG_F(WARNING, "Attempted read from VIA Port A! \n"); break; case VIA_DIRB: - LOG_F(INFO, "VIA_DIRB = %x \n", (uint32_t)value); + LOG_F(9, "VIA_DIRB = %x \n", (uint32_t)value); this->via_regs[VIA_DIRB] = value; break; case VIA_DIRA: - LOG_F(INFO, "VIA_DIRA = %x \n", (uint32_t)value); + LOG_F(9, "VIA_DIRA = %x \n", (uint32_t)value); this->via_regs[VIA_DIRA] = value; break; case VIA_PCR: - LOG_F(INFO, "VIA_PCR = %x \n", (uint32_t)value); + LOG_F(9, "VIA_PCR = %x \n", (uint32_t)value); this->via_regs[VIA_PCR] = value; break; case VIA_ACR: - LOG_F(INFO, "VIA_ACR = %x \n", (uint32_t)value); + LOG_F(9, "VIA_ACR = %x \n", (uint32_t)value); this->via_regs[VIA_ACR] = value; break; case VIA_IER: this->via_regs[VIA_IER] = (value & 0x80) ? value & 0x7F - : this->via_regs[VIA_IER] & ~value; + : this->via_regs[VIA_IER] & ~value; LOG_F(INFO, "VIA_IER updated to %d \n", (uint32_t)this->via_regs[VIA_IER]); print_enabled_ints(); break; @@ -116,7 +116,7 @@ void ViaCuda::write(int reg, uint8_t value) void ViaCuda::print_enabled_ints() { - vector via_int_src = {"CA2", "CA1", "SR", "CB2", "CB1", "T2", "T1"}; + vector via_int_src = { "CA2", "CA1", "SR", "CB2", "CB1", "T2", "T1" }; for (int i = 0; i < 7; i++) { if (this->via_regs[VIA_IER] & (1 << i)) @@ -148,7 +148,7 @@ void ViaCuda::cuda_write(uint8_t new_state) if (new_tip == this->old_tip && new_byteack == this->old_byteack) return; - LOG_F(INFO, "Cuda state changed! \n"); + LOG_F(9, "Cuda state changed! \n"); this->old_tip = new_tip; this->old_byteack = new_byteack; @@ -167,8 +167,9 @@ void ViaCuda::cuda_write(uint8_t new_state) } this->in_count = 0; - } else { - LOG_F(INFO, "Cuda: enter sync state \n"); + } + else { + LOG_F(9, "Cuda: enter sync state \n"); this->via_regs[VIA_B] &= ~CUDA_TREQ; /* assert TREQ */ this->treq = 0; this->in_count = 0; @@ -176,20 +177,23 @@ void ViaCuda::cuda_write(uint8_t new_state) } assert_sr_int(); /* send dummy byte as idle acknowledge or attention */ - } else { + } + else { if (this->via_regs[VIA_ACR] & 0x10) { /* data transfer: Host --> Cuda */ if (this->in_count < 16) { this->in_buf[this->in_count++] = this->via_regs[VIA_SR]; assert_sr_int(); /* tell the system we've read the data */ - } else { + } + else { LOG_F(WARNING, "Cuda input buffer exhausted! \n"); } - } else { /* data transfer: Cuda --> Host */ + } + else { /* data transfer: Cuda --> Host */ if (this->out_count) { this->via_regs[VIA_SR] = this->out_buf[this->out_pos++]; if (this->out_pos >= this->out_count) { - LOG_F(INFO, "Cuda: sending last byte \n"); + LOG_F(9, "Cuda: sending last byte \n"); this->out_count = 0; this->via_regs[VIA_B] |= CUDA_TREQ; /* negate TREQ */ this->treq = 1; @@ -227,18 +231,17 @@ void ViaCuda::cuda_process_packet() return; } - switch(this->in_buf[0]) { + switch (this->in_buf[0]) { case CUDA_PKT_ADB: - LOG_F(INFO, "Cuda: ADB packet received \n"); + LOG_F(9, "Cuda: ADB packet received \n"); break; case CUDA_PKT_PSEUDO: - LOG_F(INFO, "Cuda: pseudo command packet received \n"); - LOG_F(INFO, "Command: %x \n", (uint32_t)(this->in_buf[1])); - LOG_F(INFO, "Data count: %d \n ", this->in_count); + LOG_F(9, "Cuda: pseudo command packet received \n"); + LOG_F(9, "Command: %x \n", (uint32_t)(this->in_buf[1])); + LOG_F(9, "Data count: %d \n ", this->in_count); for (int i = 0; i < this->in_count; i++) { - LOG_F(INFO, "%x ,", (uint32_t)(this->in_buf[i])); + LOG_F(9, "%x ,", (uint32_t)(this->in_buf[i])); } - LOG_F(INFO, "\n"); cuda_pseudo_command(this->in_buf[1], this->in_count - 2); break; default: @@ -248,7 +251,7 @@ void ViaCuda::cuda_process_packet() void ViaCuda::cuda_pseudo_command(int cmd, int data_count) { - switch(cmd) { + switch (cmd) { case CUDA_READ_PRAM: cuda_response_header(CUDA_PKT_PSEUDO, 0); this->pram_obj->read_byte(this->in_buf[2]); @@ -289,17 +292,18 @@ void ViaCuda::cuda_pseudo_command(int cmd, int data_count) } } -void ViaCuda::i2c_simple_transaction(uint8_t dev_addr, const uint8_t *in_buf, - int in_bytes) +void ViaCuda::i2c_simple_transaction(uint8_t dev_addr, const uint8_t* in_buf, + int in_bytes) { int tr_type = dev_addr & 1; - switch(dev_addr & 0xFE) { + switch (dev_addr & 0xFE) { case 0x50: /* unknown device on the Gossamer board */ if (tr_type) { /* read */ /* send dummy byte for now */ this->out_buf[this->out_count++] = 0xDD; - } else { + } + else { /* ignore writes */ } break; @@ -310,7 +314,7 @@ void ViaCuda::i2c_simple_transaction(uint8_t dev_addr, const uint8_t *in_buf, } void ViaCuda::i2c_comb_transaction(uint8_t dev_addr, uint8_t sub_addr, - uint8_t dev_addr1, const uint8_t *in_buf, int in_bytes) + uint8_t dev_addr1, const uint8_t* in_buf, int in_bytes) { int tr_type = dev_addr1 & 1; @@ -319,7 +323,7 @@ void ViaCuda::i2c_comb_transaction(uint8_t dev_addr, uint8_t sub_addr, return; } - switch(dev_addr1 & 0xFE) { + switch (dev_addr1 & 0xFE) { case 0xAE: /* SDRAM EEPROM, no clue which one */ if (tr_type) { /* read */ if (sub_addr != 2) { @@ -333,7 +337,8 @@ void ViaCuda::i2c_comb_transaction(uint8_t dev_addr, uint8_t sub_addr, this->out_buf[this->out_count++] = 0x0B; /* row address bits per bank */ this->out_buf[this->out_count++] = 0x09; /* col address bits per bank */ this->out_buf[this->out_count++] = 0x02; /* num of RAM banks */ - } else { + } + else { /* ignore writes */ } break; diff --git a/main.cpp b/main.cpp index ca5439d..0c5fc32 100644 --- a/main.cpp +++ b/main.cpp @@ -60,117 +60,135 @@ GossamerID *machine_id; int main(int argc, char **argv) { - loguru::g_preamble_date = false; - loguru::g_preamble_time = false; - loguru::g_preamble_thread = false; - loguru::init(argc, argv); - LOG_SCOPE_FUNCTION(INFO); - uint32_t rom_filesize; - - /* Init virtual CPU and request MPC750 CPU aka G3 */ - ppc_cpu_init(PPC_VER::MPC750); std::cout << "DingusPPC - Prototype 5bf4 (7/14/2019) " << endl; std::cout << "Written by divingkatae, (c) 2019. " << endl; std::cout << "This is not intended for general use. " << endl; std::cout << "Use at your own discretion. " << endl; - LOG_F(INFO, "Checking for ROM file"); - - //Open the ROM File. - ifstream romFile; - - romFile.open("rom.bin", ios::in|ios::binary); - - if (romFile.fail()){ - cerr << "rom.bin not present. Please provide an appropriate ROM file" - << " and restart this program.\n"; - - romFile.close(); - return 1; - } - - //Calculate and validate ROM file size. - romFile.seekg(0, romFile.end); - rom_filesize = (uint32_t) romFile.tellg(); - LOG_F(INFO, "Rom SIZE: %d \n", rom_filesize); - romFile.seekg (0, romFile.beg); - - if (rom_filesize != 0x400000){ - cerr << "Unsupported ROM File size. Expected size is 4 megabytes.\n"; - romFile.close(); - return 1; - } - - char configGrab = 0; - uint32_t configInfoOffset = 0; - - romFile.seekg (0x300082, ios::beg); //This is where the place to get the offset is - romFile.get(configGrab); //just one byte to determine ConfigInfo location - configInfoOffset = (uint32_t)(configGrab & 0xff); - - uint32_t configInfoAddr = 0x300000 + (configInfoOffset << 8) + 0x69; //address to check the identifier string - char memPPCBlock[5]; //First four chars are enough to distinguish between codenames - romFile.seekg (configInfoAddr, ios::beg); - romFile.read(memPPCBlock, 4); - memPPCBlock[4] = 0; - uint32_t rom_id = READ_DWORD_BE_A(memPPCBlock); - - std::string string_test = std::string(memPPCBlock); - - //Just auto-iterate through the list - for (auto iter = PPCMac_ROMIdentity.begin(); iter != PPCMac_ROMIdentity.end(); ){ - - string redo_me = iter->first; - - if (string_test.compare(redo_me) == 0){ - const char* check_me = iter->second.c_str(); - LOG_F(INFO, "The machine is identified as... %s \n", check_me); - romFile.seekg (0x0, ios::beg); - break; - } - else{ - iter++; - } - } - - switch(rom_id) { - case 0x476F7373: { - LOG_F(INFO, "Initialize Gossamer hardware... \n"); - MPC106 *mpc106 = new MPC106(); - mem_ctrl_instance = mpc106; - if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000)) { - LOG_F(ERROR, "Failed to Gossamer hardware... \n"); - delete(mem_ctrl_instance); - romFile.close(); - return 1; - } - machine_id = new GossamerID(0x3d8c); - mpc106->add_mmio_region(0xFF000004, 4096, machine_id); - - heathrow = new HeathrowIC(); - mpc106->pci_register_device(16, heathrow); - cout << "done" << endl; - } - break; - default: - LOG_F(INFO, "This machine not supported yet. \n"); - return 1; - } - - /* Read ROM file content and transfer it to the dedicated ROM region */ - unsigned char *sysrom_mem = new unsigned char[rom_filesize]; - romFile.read ((char *)sysrom_mem, rom_filesize); - mem_ctrl_instance->set_data(0xFFC00000, sysrom_mem, rom_filesize); - romFile.close(); - delete[] sysrom_mem; - if (argc > 1) { string checker = argv[1]; cout << checker << endl; - if ((checker == "1") || (checker == "realtime") || (checker == "/realtime") - || (checker == "-realtime")) { + if ((checker == "1") || (checker == "realtime") || \ + (checker == "-realtime") || (checker == "/realtime")) { + loguru::g_stderr_verbosity = loguru::Verbosity_OFF; + loguru::g_preamble_date = false; + loguru::g_preamble_time = false; + loguru::g_preamble_thread = false; + loguru::init(argc, argv); + loguru::add_file("dingusppc.log", loguru::Append, 0); + //Replace the above line with this for maximum debugging detail: + //loguru::add_file("dingusppc.log", loguru::Append, loguru::Verbosity_MAX); + } + else if ((checker == "debugger") || (checker == "/debugger") || + (checker == "-debugger")) { + loguru::g_preamble_date = false; + loguru::g_preamble_time = false; + loguru::g_preamble_thread = false; + loguru::init(argc, argv); + loguru::g_stderr_verbosity = 0; + } + + uint32_t rom_filesize; + + /* Init virtual CPU and request MPC750 CPU aka G3 */ + ppc_cpu_init(PPC_VER::MPC750); + + + LOG_F(INFO, "Checking for ROM file"); + + //Open the ROM File. + ifstream romFile; + + romFile.open("rom.bin", ios::in|ios::binary); + + if (romFile.fail()){ + cerr << "rom.bin not present. Please provide an appropriate ROM file" + << " and restart this program.\n"; + + romFile.close(); + return 1; + } + + //Calculate and validate ROM file size. + romFile.seekg(0, romFile.end); + rom_filesize = (uint32_t) romFile.tellg(); + LOG_F(INFO, "Rom SIZE: %d \n", rom_filesize); + romFile.seekg (0, romFile.beg); + + if (rom_filesize != 0x400000){ + cerr << "Unsupported ROM File size. Expected size is 4 megabytes.\n"; + romFile.close(); + return 1; + } + + char configGrab = 0; + uint32_t configInfoOffset = 0; + + romFile.seekg (0x300082, ios::beg); //This is where the place to get the offset is + romFile.get(configGrab); //just one byte to determine ConfigInfo location + configInfoOffset = (uint32_t)(configGrab & 0xff); + + uint32_t configInfoAddr = 0x300000 + (configInfoOffset << 8) + 0x69; //address to check the identifier string + char memPPCBlock[5]; //First four chars are enough to distinguish between codenames + romFile.seekg (configInfoAddr, ios::beg); + romFile.read(memPPCBlock, 4); + memPPCBlock[4] = 0; + uint32_t rom_id = READ_DWORD_BE_A(memPPCBlock); + + std::string string_test = std::string(memPPCBlock); + + //Just auto-iterate through the list + for (auto iter = PPCMac_ROMIdentity.begin(); iter != PPCMac_ROMIdentity.end(); ){ + + string redo_me = iter->first; + + if (string_test.compare(redo_me) == 0){ + const char* check_me = iter->second.c_str(); + LOG_F(INFO, "The machine is identified as... %s \n", check_me); + romFile.seekg (0x0, ios::beg); + break; + } + else{ + iter++; + } + } + + switch(rom_id) { + case 0x476F7373: { + LOG_F(INFO, "Initialize Gossamer hardware... \n"); + MPC106 *mpc106 = new MPC106(); + mem_ctrl_instance = mpc106; + if (!mem_ctrl_instance->add_rom_region(0xFFC00000, 0x400000)) { + LOG_F(ERROR, "Failed to Gossamer hardware... \n"); + delete(mem_ctrl_instance); + romFile.close(); + return 1; + } + machine_id = new GossamerID(0x3d8c); + mpc106->add_mmio_region(0xFF000004, 4096, machine_id); + + heathrow = new HeathrowIC(); + mpc106->pci_register_device(16, heathrow); + cout << "done" << endl; + } + break; + default: + LOG_F(INFO, "This machine not supported yet. \n"); + return 1; + } + + /* Read ROM file content and transfer it to the dedicated ROM region */ + unsigned char *sysrom_mem = new unsigned char[rom_filesize]; + romFile.read ((char *)sysrom_mem, rom_filesize); + mem_ctrl_instance->set_data(0xFFC00000, sysrom_mem, rom_filesize); + romFile.close(); + delete[] sysrom_mem; + + + if ((checker == "1") || (checker == "realtime") || \ + (checker == "-realtime") || (checker == "/realtime")) { ppc_exec(); } else if ((checker == "debugger") || (checker == "/debugger") || (checker == "-debugger")) {