mirror of
https://github.com/dingusdev/dingusppc.git
synced 2025-01-11 05:29:43 +00:00
Merge pull request #62 from mihaip/upstream-cuda-restart
Add support for the CUDA_RESTART_SYSTEM command
This commit is contained in:
commit
3c7ce3de8b
@ -58,6 +58,14 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void disconnect(int id) {
|
||||
_slots.erase(id);
|
||||
}
|
||||
|
||||
void disconnect_all() {
|
||||
_slots.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::map<int, std::function<void(Args...)>> _slots;
|
||||
mutable unsigned int _current_id { 0 };
|
||||
|
@ -94,6 +94,13 @@ public:
|
||||
_post_signal.connect_method(inst, func);
|
||||
}
|
||||
|
||||
void disconnect_handlers() {
|
||||
_window_signal.disconnect_all();
|
||||
_mouse_signal.disconnect_all();
|
||||
_keyboard_signal.disconnect_all();
|
||||
_post_signal.disconnect_all();
|
||||
}
|
||||
|
||||
private:
|
||||
static EventManager* event_manager;
|
||||
EventManager() {}; // private constructor to implement a singleton
|
||||
|
@ -322,6 +322,8 @@ enum Po_Cause : int {
|
||||
po_starting_up,
|
||||
po_shut_down,
|
||||
po_shutting_down,
|
||||
po_restarting,
|
||||
po_restart,
|
||||
po_disassemble_on,
|
||||
po_disassemble_off,
|
||||
po_enter_debugger,
|
||||
|
@ -77,11 +77,11 @@ uint64_t num_entry_replacements = 0; // number of entry replacements
|
||||
#endif // TLB_PROFILING
|
||||
|
||||
/** remember recently used physical memory regions for quicker translation. */
|
||||
AddressMapEntry last_read_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
AddressMapEntry last_write_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
AddressMapEntry last_exec_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
AddressMapEntry last_ptab_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
AddressMapEntry last_dma_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
AddressMapEntry last_read_area;
|
||||
AddressMapEntry last_write_area;
|
||||
AddressMapEntry last_exec_area;
|
||||
AddressMapEntry last_ptab_area;
|
||||
AddressMapEntry last_dma_area;
|
||||
|
||||
/** 601-style block address translation. */
|
||||
static BATResult mpc601_block_address_translation(uint32_t la)
|
||||
@ -2020,6 +2020,12 @@ static void invalidate_tlb_entries(std::array<TLBEntry, N> &tlb) {
|
||||
|
||||
void ppc_mmu_init()
|
||||
{
|
||||
last_read_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
last_write_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
last_exec_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
last_ptab_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
last_dma_area = {0xFFFFFFFF, 0xFFFFFFFF, 0, 0, nullptr, nullptr};
|
||||
|
||||
mmu_exception_handler = ppc_exception_handler;
|
||||
|
||||
if (is_601) {
|
||||
|
@ -458,6 +458,10 @@ void enter_debugger() {
|
||||
power_off_reason = po_shutting_down;
|
||||
break;
|
||||
}
|
||||
if (power_off_reason == po_restart) {
|
||||
power_off_reason = po_restarting;
|
||||
break;
|
||||
}
|
||||
power_on = true;
|
||||
|
||||
if (power_off_reason == po_starting_up) {
|
||||
|
@ -25,6 +25,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
#include <core/hostevents.h>
|
||||
#include <core/timermanager.h>
|
||||
#include <devices/common/adb/adbbus.h>
|
||||
#include <cpu/ppc/ppcemu.h>
|
||||
#include <devices/common/hwinterrupt.h>
|
||||
#include <devices/common/viacuda.h>
|
||||
#include <devices/deviceregistry.h>
|
||||
@ -88,6 +89,26 @@ ViaCuda::ViaCuda() {
|
||||
this->int_ctrl = nullptr;
|
||||
}
|
||||
|
||||
ViaCuda::~ViaCuda()
|
||||
{
|
||||
if (this->sr_timer_on) {
|
||||
TimerManager::get_instance()->cancel_timer(this->sr_timer_id);
|
||||
this->sr_timer_on = false;
|
||||
}
|
||||
if (this->t1_active) {
|
||||
TimerManager::get_instance()->cancel_timer(this->t1_timer_id);
|
||||
this->t1_active = false;
|
||||
}
|
||||
if (this->t2_active) {
|
||||
TimerManager::get_instance()->cancel_timer(this->t2_timer_id);
|
||||
this->t2_active = false;
|
||||
}
|
||||
if (this->treq_timer_id) {
|
||||
TimerManager::get_instance()->cancel_timer(this->treq_timer_id);
|
||||
this->treq_timer_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int ViaCuda::device_postinit()
|
||||
{
|
||||
this->int_ctrl = dynamic_cast<InterruptCtrl*>(
|
||||
@ -342,11 +363,12 @@ void ViaCuda::write(uint8_t new_state) {
|
||||
process_packet();
|
||||
|
||||
// start response transaction
|
||||
TimerManager::get_instance()->add_oneshot_timer(
|
||||
this->treq_timer_id = TimerManager::get_instance()->add_oneshot_timer(
|
||||
USECS_TO_NSECS(13), // delay TREQ assertion for New World
|
||||
[this]() {
|
||||
this->via_regs[VIA_B] &= ~CUDA_TREQ; // assert TREQ
|
||||
this->treq = 0;
|
||||
this->treq_timer_id = 0;
|
||||
});
|
||||
}
|
||||
|
||||
@ -633,10 +655,14 @@ void ViaCuda::pseudo_command(int cmd, int data_count) {
|
||||
LOG_F(INFO, "Cuda: send %d to PB0", (int)(this->in_buf[2]));
|
||||
response_header(CUDA_PKT_PSEUDO, 0);
|
||||
break;
|
||||
case CUDA_RESTART_SYSTEM:
|
||||
LOG_F(INFO, "Cuda: system restart");
|
||||
power_on = false;
|
||||
power_off_reason = po_restart;
|
||||
break;
|
||||
case CUDA_WARM_START:
|
||||
case CUDA_POWER_DOWN:
|
||||
case CUDA_MONO_STABLE_RESET:
|
||||
case CUDA_RESTART_SYSTEM:
|
||||
/* really kludge temp code */
|
||||
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x!", cmd);
|
||||
//exit(0);
|
||||
|
@ -155,7 +155,7 @@ enum {
|
||||
class ViaCuda : public HWComponent, public I2CBus {
|
||||
public:
|
||||
ViaCuda();
|
||||
~ViaCuda() = default;
|
||||
~ViaCuda();
|
||||
|
||||
static std::unique_ptr<HWComponent> create() {
|
||||
return std::unique_ptr<ViaCuda>(new ViaCuda());
|
||||
@ -206,6 +206,7 @@ private:
|
||||
uint8_t old_tip;
|
||||
uint8_t old_byteack;
|
||||
uint8_t treq;
|
||||
uint32_t treq_timer_id = 0;
|
||||
uint8_t in_buf[CUDA_IN_BUF_SIZE];
|
||||
int32_t in_count;
|
||||
uint8_t out_buf[16];
|
||||
|
@ -90,6 +90,14 @@ AMIC::AMIC() : MMIODevice()
|
||||
this->swim3->set_dma_channel(this->floppy_dma.get());
|
||||
}
|
||||
|
||||
AMIC::~AMIC()
|
||||
{
|
||||
if (this->pseudo_vbl_tid) {
|
||||
TimerManager::get_instance()->cancel_timer(this->pseudo_vbl_tid);
|
||||
this->pseudo_vbl_tid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int AMIC::device_postinit()
|
||||
{
|
||||
MemCtrlBase *mem_ctrl = dynamic_cast<MemCtrlBase *>
|
||||
|
@ -275,7 +275,7 @@ enum AMICReg : uint32_t {
|
||||
class AMIC : public MMIODevice, public InterruptCtrl {
|
||||
public:
|
||||
AMIC();
|
||||
~AMIC() = default;
|
||||
~AMIC();
|
||||
|
||||
static std::unique_ptr<HWComponent> create() {
|
||||
return std::unique_ptr<AMIC>(new AMIC());
|
||||
@ -336,7 +336,7 @@ private:
|
||||
uint8_t via2_slot_ifr = 0x7F; // reverse logic
|
||||
uint8_t via2_slot_irq = 0; // normal logic
|
||||
|
||||
uint32_t pseudo_vbl_tid; // ID for the pseudo-VBL timer
|
||||
uint32_t pseudo_vbl_tid = 0; // ID for the pseudo-VBL timer
|
||||
|
||||
// AMIC subdevice instances
|
||||
Sc53C94* scsi;
|
||||
|
@ -19,7 +19,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file Video Conroller base class implementation. */
|
||||
/** @file Video Controller base class implementation. */
|
||||
|
||||
#include <core/timermanager.h>
|
||||
#include <devices/common/hwinterrupt.h>
|
||||
@ -37,6 +37,7 @@ VideoCtrlBase::VideoCtrlBase(int width, int height)
|
||||
|
||||
VideoCtrlBase::~VideoCtrlBase()
|
||||
{
|
||||
this->stop_refresh_task();
|
||||
}
|
||||
|
||||
void VideoCtrlBase::handle_events(const WindowEvent& wnd_event) {
|
||||
@ -110,9 +111,11 @@ void VideoCtrlBase::start_refresh_task() {
|
||||
void VideoCtrlBase::stop_refresh_task() {
|
||||
if (this->refresh_task_id) {
|
||||
TimerManager::get_instance()->cancel_timer(this->refresh_task_id);
|
||||
this->refresh_task_id = 0;
|
||||
}
|
||||
if (this->vbl_end_task_id) {
|
||||
TimerManager::get_instance()->cancel_timer(this->vbl_end_task_id);
|
||||
this->vbl_end_task_id = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
38
main.cpp
38
main.cpp
@ -61,6 +61,8 @@ static string appDescription = string(
|
||||
"\n"
|
||||
);
|
||||
|
||||
void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
uint32_t execution_mode = interpreter;
|
||||
@ -166,10 +168,6 @@ int main(int argc, char** argv) {
|
||||
// initialize global profiler object
|
||||
gProfilerObj.reset(new Profiler());
|
||||
|
||||
if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) {
|
||||
goto bail;
|
||||
}
|
||||
|
||||
// graceful handling of fatal errors
|
||||
loguru::set_fatal_handler([](const loguru::Message& message) {
|
||||
// Make sure the reason for the failure is visible (it may have been
|
||||
@ -187,9 +185,29 @@ int main(int argc, char** argv) {
|
||||
// redirect SIGABRT to our own handler
|
||||
signal(SIGABRT, sigabrt_handler);
|
||||
|
||||
while (true) {
|
||||
run_machine(machine_str, bootrom_path, execution_mode);
|
||||
if (power_off_reason == po_restarting) {
|
||||
LOG_F(INFO, "Restarting...");
|
||||
power_on = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode) {
|
||||
if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// set up system wide event polling using
|
||||
// default Macintosh polling rate of 11 ms
|
||||
TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
|
||||
uint32_t event_timer = TimerManager::get_instance()->add_cyclic_timer(MSECS_TO_NSECS(11), [] {
|
||||
EventManager::get_instance()->poll_events();
|
||||
});
|
||||
|
||||
@ -204,15 +222,11 @@ int main(int argc, char** argv) {
|
||||
break;
|
||||
default:
|
||||
LOG_F(ERROR, "Invalid EXECUTION MODE");
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
bail:
|
||||
LOG_F(INFO, "Cleaning up...");
|
||||
|
||||
TimerManager::get_instance()->cancel_timer(event_timer);
|
||||
EventManager::get_instance()->disconnect_handlers();
|
||||
delete gMachineObj.release();
|
||||
|
||||
cleanup();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user