diff --git a/hw/i8042.c b/hw/i8042.c index 21a779e..262368e 100644 --- a/hw/i8042.c +++ b/hw/i8042.c @@ -5,6 +5,7 @@ #include "kvm/term.h" #include "kvm/kvm.h" #include "kvm/i8042.h" +#include "kvm/kvm-cpu.h" #include @@ -30,6 +31,7 @@ #define I8042_CMD_AUX_TEST 0xA9 #define I8042_CMD_AUX_DISABLE 0xA7 #define I8042_CMD_AUX_ENABLE 0xA8 +#define I8042_CMD_SYSTEM_RESET 0xFE #define RESPONSE_ACK 0xFA @@ -138,7 +140,7 @@ void kbd_queue(u8 c) kbd_update_irq(); } -static void kbd_write_command(u8 val) +static void kbd_write_command(struct kvm *kvm, u8 val) { switch (val) { case I8042_CMD_CTL_RCTR: @@ -159,6 +161,9 @@ static void kbd_write_command(u8 val) case I8042_CMD_AUX_ENABLE: state.mode &= ~MODE_DISABLE_AUX; break; + case I8042_CMD_SYSTEM_RESET: + kvm_cpu__reboot(); + break; default: break; } @@ -314,7 +319,7 @@ static bool kbd_out(struct ioport *ioport, struct kvm *kvm, u16 port, void *data switch (port) { case I8042_COMMAND_REG: { u8 value = ioport__read8(data); - kbd_write_command(value); + kbd_write_command(kvm, value); break; } case I8042_DATA_REG: { diff --git a/include/kvm/kvm-cpu.h b/include/kvm/kvm-cpu.h index 1eb4a52..95f3f9d 100644 --- a/include/kvm/kvm-cpu.h +++ b/include/kvm/kvm-cpu.h @@ -34,6 +34,7 @@ void kvm_cpu__reset_vcpu(struct kvm_cpu *vcpu); void kvm_cpu__setup_cpuid(struct kvm_cpu *vcpu); void kvm_cpu__enable_singlestep(struct kvm_cpu *vcpu); void kvm_cpu__run(struct kvm_cpu *vcpu); +void kvm_cpu__reboot(void); int kvm_cpu__start(struct kvm_cpu *cpu); void kvm_cpu__show_code(struct kvm_cpu *vcpu); diff --git a/kvm-cpu.c b/kvm-cpu.c index 1fb1c74..f57d42e 100644 --- a/kvm-cpu.c +++ b/kvm-cpu.c @@ -16,6 +16,7 @@ #define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) +extern struct kvm_cpu *kvm_cpus[KVM_NR_CPUS]; extern __thread struct kvm_cpu *current_kvm_cpu; static inline bool is_in_protected_mode(struct kvm_cpu *vcpu) @@ -393,7 +394,7 @@ void kvm_cpu__run(struct kvm_cpu *vcpu) static void kvm_cpu_signal_handler(int signum) { if (signum == SIGKVMEXIT) { - if (current_kvm_cpu->is_running) { + if (current_kvm_cpu && current_kvm_cpu->is_running) { current_kvm_cpu->is_running = false; pthread_kill(pthread_self(), SIGKVMEXIT); } @@ -418,6 +419,11 @@ static void kvm_cpu__handle_coalesced_mmio(struct kvm_cpu *cpu) } } +void kvm_cpu__reboot(void) +{ + pthread_kill(kvm_cpus[0]->thread, SIGKVMEXIT); +} + int kvm_cpu__start(struct kvm_cpu *cpu) { sigset_t sigset; diff --git a/kvm-run.c b/kvm-run.c index 60fc07b..9724e37 100644 --- a/kvm-run.c +++ b/kvm-run.c @@ -570,7 +570,7 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) vidmode = 0; memset(real_cmdline, 0, sizeof(real_cmdline)); - strcpy(real_cmdline, "notsc noapic noacpi pci=conf1"); + strcpy(real_cmdline, "notsc noapic noacpi pci=conf1 reboot=k"); if (vnc || sdl) { strcat(real_cmdline, " video=vesafb console=tty0"); } else @@ -661,17 +661,17 @@ int kvm_cmd_run(int argc, const char **argv, const char *prefix) kvm__init_ram(kvm); + kbd__init(kvm); + if (vnc || sdl) fb = vesa__init(kvm); if (vnc) { - kbd__init(kvm); if (fb) vnc__init(fb); } if (sdl) { - kbd__init(kvm); if (fb) sdl__init(fb); }