mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-06-03 13:29:32 +00:00
Add support for the CUDA_RESTART_SYSTEM command
There are cases where when it's necessary (e.g. given uninitialized NVRAM, the Beige G3 with the 10.2 install CD inserted will update the boot device and restart to boot from it). Restart support was done by wrapping the ppc_exec function in a loop and checking for a restart power off reason. We also need to disconnect all event listeners, since they will be recreated when the machine is re-initialized.
This commit is contained in:
parent
c7d2eb87ac
commit
57e6e90002
|
@ -58,6 +58,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disconnect(int id) {
|
||||||
|
_slots.erase(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void disconnect_all() {
|
||||||
|
_slots.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::map<int, std::function<void(Args...)>> _slots;
|
mutable std::map<int, std::function<void(Args...)>> _slots;
|
||||||
mutable unsigned int _current_id { 0 };
|
mutable unsigned int _current_id { 0 };
|
||||||
|
|
|
@ -94,6 +94,13 @@ public:
|
||||||
_post_signal.connect_method(inst, func);
|
_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:
|
private:
|
||||||
static EventManager* event_manager;
|
static EventManager* event_manager;
|
||||||
EventManager() {}; // private constructor to implement a singleton
|
EventManager() {}; // private constructor to implement a singleton
|
||||||
|
|
|
@ -322,6 +322,8 @@ enum Po_Cause : int {
|
||||||
po_starting_up,
|
po_starting_up,
|
||||||
po_shut_down,
|
po_shut_down,
|
||||||
po_shutting_down,
|
po_shutting_down,
|
||||||
|
po_restarting,
|
||||||
|
po_restart,
|
||||||
po_disassemble_on,
|
po_disassemble_on,
|
||||||
po_disassemble_off,
|
po_disassemble_off,
|
||||||
po_enter_debugger,
|
po_enter_debugger,
|
||||||
|
|
|
@ -458,6 +458,10 @@ void enter_debugger() {
|
||||||
power_off_reason = po_shutting_down;
|
power_off_reason = po_shutting_down;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (power_off_reason == po_restart) {
|
||||||
|
power_off_reason = po_restarting;
|
||||||
|
break;
|
||||||
|
}
|
||||||
power_on = true;
|
power_on = true;
|
||||||
|
|
||||||
if (power_off_reason == po_starting_up) {
|
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/hostevents.h>
|
||||||
#include <core/timermanager.h>
|
#include <core/timermanager.h>
|
||||||
#include <devices/common/adb/adbbus.h>
|
#include <devices/common/adb/adbbus.h>
|
||||||
|
#include <cpu/ppc/ppcemu.h>
|
||||||
#include <devices/common/hwinterrupt.h>
|
#include <devices/common/hwinterrupt.h>
|
||||||
#include <devices/common/viacuda.h>
|
#include <devices/common/viacuda.h>
|
||||||
#include <devices/deviceregistry.h>
|
#include <devices/deviceregistry.h>
|
||||||
|
@ -654,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]));
|
LOG_F(INFO, "Cuda: send %d to PB0", (int)(this->in_buf[2]));
|
||||||
response_header(CUDA_PKT_PSEUDO, 0);
|
response_header(CUDA_PKT_PSEUDO, 0);
|
||||||
break;
|
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_WARM_START:
|
||||||
case CUDA_POWER_DOWN:
|
case CUDA_POWER_DOWN:
|
||||||
case CUDA_MONO_STABLE_RESET:
|
case CUDA_MONO_STABLE_RESET:
|
||||||
case CUDA_RESTART_SYSTEM:
|
|
||||||
/* really kludge temp code */
|
/* really kludge temp code */
|
||||||
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x!", cmd);
|
LOG_F(INFO, "Cuda: Restart/Shutdown signal sent with command 0x%x!", cmd);
|
||||||
//exit(0);
|
//exit(0);
|
||||||
|
|
38
main.cpp
38
main.cpp
|
@ -61,6 +61,8 @@ static string appDescription = string(
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
void run_machine(std::string machine_str, std::string bootrom_path, uint32_t execution_mode);
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
uint32_t execution_mode = interpreter;
|
uint32_t execution_mode = interpreter;
|
||||||
|
@ -166,10 +168,6 @@ int main(int argc, char** argv) {
|
||||||
// initialize global profiler object
|
// initialize global profiler object
|
||||||
gProfilerObj.reset(new Profiler());
|
gProfilerObj.reset(new Profiler());
|
||||||
|
|
||||||
if (MachineFactory::create_machine_for_id(machine_str, bootrom_path) < 0) {
|
|
||||||
goto bail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// graceful handling of fatal errors
|
// graceful handling of fatal errors
|
||||||
loguru::set_fatal_handler([](const loguru::Message& message) {
|
loguru::set_fatal_handler([](const loguru::Message& message) {
|
||||||
// Make sure the reason for the failure is visible (it may have been
|
// 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
|
// redirect SIGABRT to our own handler
|
||||||
signal(SIGABRT, sigabrt_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
|
// set up system wide event polling using
|
||||||
// default Macintosh polling rate of 11 ms
|
// 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();
|
EventManager::get_instance()->poll_events();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -204,15 +222,11 @@ int main(int argc, char** argv) {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_F(ERROR, "Invalid EXECUTION MODE");
|
LOG_F(ERROR, "Invalid EXECUTION MODE");
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bail:
|
|
||||||
LOG_F(INFO, "Cleaning up...");
|
LOG_F(INFO, "Cleaning up...");
|
||||||
|
TimerManager::get_instance()->cancel_timer(event_timer);
|
||||||
|
EventManager::get_instance()->disconnect_handlers();
|
||||||
delete gMachineObj.release();
|
delete gMachineObj.release();
|
||||||
|
|
||||||
cleanup();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user