1ae1fae34SPekka Enberg #include "kvm/kvm.h" 2ae1fae34SPekka Enberg 3f3150089SPekka Enberg #include "kvm/util.h" 47fb218bdSPekka Enberg 5ae1fae34SPekka Enberg #include <inttypes.h> 6ae1fae34SPekka Enberg #include <stdint.h> 7ae1fae34SPekka Enberg #include <stdlib.h> 8f3150089SPekka Enberg #include <string.h> 9ae1fae34SPekka Enberg #include <stdio.h> 10ae1fae34SPekka Enberg 11ae1fae34SPekka Enberg static void usage(char *argv[]) 12ae1fae34SPekka Enberg { 1364f06a2bSPekka Enberg fprintf(stderr, " usage: %s [--single-step] [--kernel=]<kernel-image>\n", 145645c7a9SCyrill Gorcunov argv[0]); 15ae1fae34SPekka Enberg exit(1); 16ae1fae34SPekka Enberg } 17ae1fae34SPekka Enberg 18ae1fae34SPekka Enberg int main(int argc, char *argv[]) 19ae1fae34SPekka Enberg { 205645c7a9SCyrill Gorcunov const char *kernel_filename = NULL; 216d1f350dSCyrill Gorcunov const char *kernel_cmdline = NULL; 2264f06a2bSPekka Enberg bool single_step = false; 23ae1fae34SPekka Enberg struct kvm *kvm; 245645c7a9SCyrill Gorcunov int i; 25ae1fae34SPekka Enberg 265645c7a9SCyrill Gorcunov for (i = 1; i < argc; i++) { 275645c7a9SCyrill Gorcunov if (!strncmp("--kernel=", argv[i], 9)) { 285645c7a9SCyrill Gorcunov kernel_filename = &argv[i][9]; 295645c7a9SCyrill Gorcunov continue; 306d1f350dSCyrill Gorcunov } else if (!strncmp("--params=", argv[i], 9)) { 316d1f350dSCyrill Gorcunov kernel_cmdline = &argv[i][9]; 326d1f350dSCyrill Gorcunov continue; 3364f06a2bSPekka Enberg } else if (!strncmp("--single-step", argv[i], 13)) { 3464f06a2bSPekka Enberg single_step = true; 3564f06a2bSPekka Enberg continue; 365645c7a9SCyrill Gorcunov } else { 375645c7a9SCyrill Gorcunov /* any unspecified arg is kernel image */ 385645c7a9SCyrill Gorcunov if (argv[i][0] != '-') 395645c7a9SCyrill Gorcunov kernel_filename = argv[i]; 405645c7a9SCyrill Gorcunov else 415645c7a9SCyrill Gorcunov warning("Unknown option: %s", argv[i]); 425645c7a9SCyrill Gorcunov } 435645c7a9SCyrill Gorcunov } 445645c7a9SCyrill Gorcunov 455645c7a9SCyrill Gorcunov /* at least we should have kernel image passed */ 465645c7a9SCyrill Gorcunov if (!kernel_filename) 47ae1fae34SPekka Enberg usage(argv); 48ae1fae34SPekka Enberg 49ae1fae34SPekka Enberg kvm = kvm__init(); 50ae1fae34SPekka Enberg 51*a1fe6bc5SPekka Enberg kvm__setup_cpuid(kvm); 52*a1fe6bc5SPekka Enberg 536d1f350dSCyrill Gorcunov if (!kvm__load_kernel(kvm, kernel_filename, kernel_cmdline)) 547fb218bdSPekka Enberg die("unable to load kernel %s", kernel_filename); 55ae1fae34SPekka Enberg 567fb218bdSPekka Enberg kvm__reset_vcpu(kvm); 57ae1fae34SPekka Enberg 5864f06a2bSPekka Enberg if (single_step) 59ae1fae34SPekka Enberg kvm__enable_singlestep(kvm); 60ae1fae34SPekka Enberg 61ae1fae34SPekka Enberg for (;;) { 62ae1fae34SPekka Enberg kvm__run(kvm); 63ae1fae34SPekka Enberg 64ae1fae34SPekka Enberg switch (kvm->kvm_run->exit_reason) { 65fe806d65SPekka Enberg case KVM_EXIT_DEBUG: 66fe806d65SPekka Enberg kvm__show_registers(kvm); 67fe806d65SPekka Enberg kvm__show_code(kvm); 68fe806d65SPekka Enberg break; 69ae1fae34SPekka Enberg case KVM_EXIT_IO: 70ae1fae34SPekka Enberg kvm__emulate_io(kvm, 71ae1fae34SPekka Enberg kvm->kvm_run->io.port, 72ae1fae34SPekka Enberg (uint8_t *)kvm->kvm_run + kvm->kvm_run->io.data_offset, 73ae1fae34SPekka Enberg kvm->kvm_run->io.direction, 74ae1fae34SPekka Enberg kvm->kvm_run->io.size, 75ae1fae34SPekka Enberg kvm->kvm_run->io.count); 76ae1fae34SPekka Enberg goto exit_kvm; 77ae1fae34SPekka Enberg break; 78ae1fae34SPekka Enberg default: 79ae1fae34SPekka Enberg goto exit_kvm; 80ae1fae34SPekka Enberg } 81ae1fae34SPekka Enberg } 82ae1fae34SPekka Enberg 83ae1fae34SPekka Enberg exit_kvm: 84ae1fae34SPekka Enberg fprintf(stderr, "KVM exit reason: %" PRIu32 " (\"%s\")\n", 85ae1fae34SPekka Enberg kvm->kvm_run->exit_reason, kvm_exit_reasons[kvm->kvm_run->exit_reason]); 86ae1fae34SPekka Enberg 87ae1fae34SPekka Enberg kvm__show_registers(kvm); 88ae1fae34SPekka Enberg kvm__show_code(kvm); 89ae1fae34SPekka Enberg 90ae1fae34SPekka Enberg return 0; 91ae1fae34SPekka Enberg } 92