diff --git a/guest/guest.bin b/guest/guest.bin index 759ecaeecba1bf277b968267be9c0982f1802b7f..3aeb9ac215e6ea70448c7764cd5014a429ca2b56 100755 Binary files a/guest/guest.bin and b/guest/guest.bin differ diff --git a/guest/guest_main.c b/guest/guest_main.c index 33bc27de974708b4b1e4f5f11346cb84772ae144..361192161af060a50c832bc73dded1c9c9c4a26a 100644 --- a/guest/guest_main.c +++ b/guest/guest_main.c @@ -1,4 +1,5 @@ #include <stdint.h> +#include <stdio.h> #include "idt.h" #include "utils.h" #include "pmio.h" @@ -15,6 +16,8 @@ #define timer_sleep timer_sleep_phys #endif +extern uint32_t key; + void timer_sleep_pv(int usec) { hyper_timer_sleep_params_t *timer_sleep_params = (hyper_timer_sleep_params_t*)(SHARED_STORAGE_ADDRESS); timer_sleep_params->us = usec; @@ -66,8 +69,29 @@ void guest_main() { // console_pv("Débloquage du display!\n"); // affichage_pv(400, 300); - console_pv("Attente de 100000\n"); + //console_pv("Attente de 100000\n"); // timer_sleep(10000000); - timer_sleep_phys(10000000); - console_pv("Après attente!!\n"); + //timer_sleep_phys(10000000); + //console_pv("Après attente!!\n"); + + console_pv("Start affichage"); + affichage_pv(600, 400); + + int quit = 0; + + while (quit == 0) + { + if (key != 100000){ + char buffer[100]; + snprintf(buffer, 100, "Key: %d\n", key); + console_pv(buffer); + + if( key == 27){ + quit = 1; + } + + key = 100000; + } + } + } diff --git a/guest/guest_main.o b/guest/guest_main.o index cbc944be68e926c84b77b2cf92e4683f2d3acae0..d0161fb98f957fe75efcbfdb35053beac7cb5745 100644 Binary files a/guest/guest_main.o and b/guest/guest_main.o differ diff --git a/guest/idt.c b/guest/idt.c index f49386dbe0193b45cff65f8ceca1d39a40f5bc0b..2677ac44e718175652dd7d246bcb41434e6f4a06 100644 --- a/guest/idt.c +++ b/guest/idt.c @@ -2,9 +2,14 @@ #include "utils.h" #include "descriptors.h" #include "x86.h" +#include "pmio.h" #define GDT_KERNEL_CODE_SELECTOR 0x08 +// My test +uint32_t key; +// -------- + // Structure of an IDT descriptor. There are 3 types of descriptors: // task-gates, interrupt-gates, trap-gates. // See 5.11 of Intel 64 & IA32 architectures software developer's manual for more details. @@ -53,9 +58,13 @@ static idt_entry_t idt_build_entry(uint16_t selector, uint32_t offset, uint8_t t // Low level handler defined in idt_asm.s void _irq0(); +void _irq1(); // IRQ handler void irq_handler(uint32_t irq_number) { + if (irq_number == 1){ + key = ind(0x60); + } } void idt_init() { @@ -66,6 +75,7 @@ void idt_init() { memset(idt, 0, sizeof(idt)); idt[0] = idt_build_entry(GDT_KERNEL_CODE_SELECTOR, (uint32_t)_irq0, TYPE_INTERRUPT_GATE, DPL_KERNEL); + idt[1] = idt_build_entry(GDT_KERNEL_CODE_SELECTOR, (uint32_t)_irq1, TYPE_INTERRUPT_GATE, DPL_KERNEL); idt_load(&idt_ptr); } diff --git a/guest/idt.d b/guest/idt.d index 65b389da664da9d115cfa6614d0f6b42d29e93bf..b6670f00b83433e857f528888cad2cfd8b325bf2 100644 --- a/guest/idt.d +++ b/guest/idt.d @@ -1 +1 @@ -idt.o: idt.c idt.h utils.h descriptors.h x86.h +idt.o: idt.c idt.h utils.h descriptors.h x86.h pmio.h diff --git a/guest/idt.o b/guest/idt.o index 43d2c0acb517a821f18afa93c9c2cfe0ab72afb9..49136b163198f4506c134f23c97b4a027fc214c0 100644 Binary files a/guest/idt.o and b/guest/idt.o differ diff --git a/guest/idt_asm.o b/guest/idt_asm.o index fcb2a94a593a069eb5c5140768dbe5ef8bbfb6f6..075cc50f013c0946efde3f60635984055d3ac14d 100644 Binary files a/guest/idt_asm.o and b/guest/idt_asm.o differ diff --git a/guest/idt_asm.s b/guest/idt_asm.s index bfd31a8b6510d004419aafdac1ca81559c4adb7a..1f0519f1bd80c7b61d1ac7ddd34b329faf97f0e7 100644 --- a/guest/idt_asm.s +++ b/guest/idt_asm.s @@ -15,6 +15,11 @@ _irq0: push 0 ; put irq number on the stack jmp irq_handler_wrapper +global _irq1 +_irq1: + push 1 ; put irq number on the stack + jmp irq_handler_wrapper + extern irq_handler irq_handler_wrapper: diff --git a/shared/hypercall_params.h b/shared/hypercall_params.h index 4dace22345e09541413bb992b007efb45f40c73b..c009169984ad5d6c72e5b3cb03bc924099319a7a 100644 --- a/shared/hypercall_params.h +++ b/shared/hypercall_params.h @@ -39,4 +39,8 @@ typedef struct { int32_t y ; // y position } __attribute__((packed)) hyper_sprite_position_params_t; +typedef struct { + uint32_t key ; // code of the pressed key +} __attribute__((packed)) hyper_keyboard_params_t; + #endif diff --git a/vmm/peripheriques/disk/disk.c b/vmm/peripheriques/disk/disk.c index bdba16d5d7433fea8c7cc5d1a036d93afa6cbd97..a3a51fc8d28a931de61cc47bd23876bce204164a 100644 --- a/vmm/peripheriques/disk/disk.c +++ b/vmm/peripheriques/disk/disk.c @@ -48,14 +48,14 @@ void disk_store_sector_4(void *addr) { } void disk_store_data(void *addr) { - printf("Storring on id=%ld\n", data_index); + //printf("Storring on id=%ld\n", data_index); buffer_16[data_index] = *(uint16_t *)addr; data_index++; if (data_index == SECTOR_SIZE/2) { stop_loop = true; - printf("Stopping loop after id=%ld\n", data_index); + //printf("Stopping loop after id=%ld\n", data_index); } } @@ -63,7 +63,7 @@ void disk_conclude(void *addr){ hyper_disk_params_t* tmp_params = addr == NULL ? &disk_params : (hyper_disk_params_t*) addr; - printf("Mem: %d\n", mem); + //printf("Mem: %d\n", mem); // Pv not working for some reason // Wrong data writen @@ -95,5 +95,5 @@ void disk_conclude(void *addr){ } fclose(disk); - printf("Storing data\n"); + //printf("Storing data\n"); } \ No newline at end of file diff --git a/vmm/peripheriques/disk/disk.o b/vmm/peripheriques/disk/disk.o index f85163d96494c7e0bc36af65822977ce741f47f3..a66604d41d53db9c4038ced2b648bfd317b5df8c 100644 Binary files a/vmm/peripheriques/disk/disk.o and b/vmm/peripheriques/disk/disk.o differ diff --git a/vmm/peripheriques/gfx_init/gfx_init.c b/vmm/peripheriques/gfx_init/gfx_init.c index afc4a6e5fc4796fa29cea4a71fddc5d6bfd2592c..ced67f4548633c2a73be2f47150dff676a38cb86 100644 --- a/vmm/peripheriques/gfx_init/gfx_init.c +++ b/vmm/peripheriques/gfx_init/gfx_init.c @@ -30,7 +30,7 @@ void gfx_init_conclude(void *addr){ display_width = tmp_params->width; display_height = tmp_params->height; - printf("Initialising display!!! Width: %d, Height: %d\n", display_width, display_height); + //printf("Initialising display!!! Width: %d, Height: %d\n", display_width, display_height); sem_post(&display_sem); } \ No newline at end of file diff --git a/vmm/peripheriques/gfx_init/gfx_init.o b/vmm/peripheriques/gfx_init/gfx_init.o index 73bd6e495105bbe4a8bbbd2bc7db3a95f116bbb1..c2a61831039f091a68e922550ab0a62173e3f8ed 100644 Binary files a/vmm/peripheriques/gfx_init/gfx_init.o and b/vmm/peripheriques/gfx_init/gfx_init.o differ diff --git a/vmm/peripheriques/keyboard/keyboard.c b/vmm/peripheriques/keyboard/keyboard.c new file mode 100644 index 0000000000000000000000000000000000000000..661d9966459b5e32bfadcb4dac602f861cef01d7 --- /dev/null +++ b/vmm/peripheriques/keyboard/keyboard.c @@ -0,0 +1,13 @@ +#include "keyboard.h" + +state_t keyboard_states[] = { + {WRITE_KEY, 0x60, 0, 4, NULL}, + {EMULATE, 0, 0, 0, NULL} +}; + +state_machine_t keyboard_state_machine = { + .current_state = 0, + .states = keyboard_states +}; + +hyper_keyboard_params_t keyboard_params; \ No newline at end of file diff --git a/vmm/peripheriques/keyboard/keyboard.d b/vmm/peripheriques/keyboard/keyboard.d new file mode 100644 index 0000000000000000000000000000000000000000..b0dee2434a82c6a94eb5b9a667ea43ca34c1bf9e --- /dev/null +++ b/vmm/peripheriques/keyboard/keyboard.d @@ -0,0 +1,4 @@ +peripheriques/keyboard/keyboard.o: peripheriques/keyboard/keyboard.c \ + peripheriques/keyboard/keyboard.h \ + peripheriques/keyboard/../state_machine.h \ + peripheriques/keyboard/../../../shared/hypercall_params.h diff --git a/vmm/peripheriques/keyboard/keyboard.h b/vmm/peripheriques/keyboard/keyboard.h new file mode 100644 index 0000000000000000000000000000000000000000..7e0e3aea649443d32c15671df4b1e6512d31a715 --- /dev/null +++ b/vmm/peripheriques/keyboard/keyboard.h @@ -0,0 +1,17 @@ +#ifndef KEYBOARD_H +#define KEYBOARD_H + +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> +#include "../state_machine.h" +#include "../../../shared/hypercall_params.h" + +extern state_t keyboard_states[]; +extern state_machine_t keyboard_state_machine; +extern hyper_keyboard_params_t keyboard_params; + +void timer_store(void *addr); +void timer_conclude(void *addr); + +#endif \ No newline at end of file diff --git a/vmm/peripheriques/keyboard/keyboard.o b/vmm/peripheriques/keyboard/keyboard.o new file mode 100644 index 0000000000000000000000000000000000000000..c679dbac3a8d9ca8e5f3203200c200d62756fd74 Binary files /dev/null and b/vmm/peripheriques/keyboard/keyboard.o differ diff --git a/vmm/peripheriques/peripheriques.c b/vmm/peripheriques/peripheriques.c index 0e02a86d7daa5f1b2f42bc82dcae3121614b068e..8b24ed0ff651378084a8e28d16837d7e5209c062 100644 --- a/vmm/peripheriques/peripheriques.c +++ b/vmm/peripheriques/peripheriques.c @@ -8,25 +8,45 @@ state_machine_t* state_machines[NB_STATE_MACHINE] = { &disk_state_machine, &sprite_content_state_machine, &sprite_visibility_state_machine, - &sprite_position_state_machine + &sprite_position_state_machine, + &keyboard_state_machine }; void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){ - printf("Checking... addr: 0x%lX, size: %d, value: %d\n", addr, size, value); + //printf("Checking... addr: 0x%lX, size: %d, value: %d\n", addr, size, value); for (int i = 0; i < NB_STATE_MACHINE; i++){ - printf("State machine n°%d\n", i); - printf("State machine state: %d\n", state_machines[i]->current_state); + //printf("State machine n°%d\n", i); + //printf("State machine state: %d\n", state_machines[i]->current_state); state_t tmp_state = state_machines[i]->states[state_machines[i]->current_state]; switch (tmp_state.act) { case WRITE: - printf("WRITE\n"); + //printf("WRITE\n"); if(tmp_state.address == addr && tmp_state.size == size){ - printf("Test OK\n"); + //printf("Test OK\n"); *((uint32_t *)addr_p) = (uint32_t)tmp_state.value; - printf("Wrote %ld on 0x%lX\n", tmp_state.value, addr); + //printf("Wrote %ld on 0x%lX\n", tmp_state.value, addr); + state_machines[i]->current_state += 1; + + if(tmp_state.callback != NULL){ + tmp_state.callback(addr_p); + } + } + else{ + state_machines[i]->current_state = 0; + } + break; + case WRITE_KEY: + //printf("WRITE_KEY\n"); + if(tmp_state.address == addr && tmp_state.size == size){ + printf("Test OK\n"); + *((uint32_t *)addr_p) = (uint32_t)keyboard_params.key; + printf("Wrote %d on 0x%lX\n", keyboard_params.key, addr); + + usleep(100000); + state_machines[i]->current_state += 1; if(tmp_state.callback != NULL){ @@ -38,10 +58,10 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){ } break; case STORE: - printf("STORE\n"); + //printf("STORE\n"); if(tmp_state.address == addr && tmp_state.size == size){ - printf("Test OK\n"); + //printf("Test OK\n"); tmp_state.callback(addr_p); state_machines[i]->current_state += 1; } @@ -50,10 +70,10 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){ } break; case STORE_LOOP: - printf("STORE_LOOP\n"); + //printf("STORE_LOOP\n"); if(tmp_state.address == addr && tmp_state.size == size){ - printf("Test OK\n"); + //printf("Test OK\n"); tmp_state.callback(addr_p); if (stop_loop){ state_machines[i]->current_state += 1; @@ -64,9 +84,9 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){ } break; case EQUALS: - printf("EQUALS\n"); + //printf("EQUALS\n"); if(tmp_state.address == addr && tmp_state.size == size && tmp_state.value == value){ - printf("Test OK\n"); + //printf("Test OK\n"); state_machines[i]->current_state += 1; } else{ @@ -77,10 +97,13 @@ void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value){ break; } - printf("State machine state: %d\n", state_machines[i]->current_state); + //cprintf("State machine state: %d\n", state_machines[i]->current_state); if (state_machines[i]->states[state_machines[i]->current_state].act == EMULATE){ - state_machines[i]->states[state_machines[i]->current_state].callback(NULL); + if(state_machines[i]->states[state_machines[i]->current_state].callback != NULL){ + state_machines[i]->states[state_machines[i]->current_state].callback(NULL); + } + state_machines[i]->current_state = 0; } } diff --git a/vmm/peripheriques/peripheriques.d b/vmm/peripheriques/peripheriques.d index c4936e7769b80113c8a7167ad14691b5bb2023e9..9695e3233afdb6988511a341601461f68bf16967 100644 --- a/vmm/peripheriques/peripheriques.d +++ b/vmm/peripheriques/peripheriques.d @@ -14,4 +14,7 @@ peripheriques/peripheriques.o: peripheriques/peripheriques.c \ peripheriques/sprites/visibility/sprite_visibility.h \ peripheriques/sprites/visibility/../sprites.h \ peripheriques/sprites/position/sprite_position.h \ - peripheriques/sprites/position/../sprites.h + peripheriques/sprites/position/../sprites.h \ + peripheriques/keyboard/keyboard.h \ + peripheriques/keyboard/../state_machine.h \ + peripheriques/keyboard/../../../shared/hypercall_params.h diff --git a/vmm/peripheriques/peripheriques.h b/vmm/peripheriques/peripheriques.h index 6aadffaee0faa6f6bf0ff2c9c466818a427defeb..afdc737a5f347afc5e6a31aa2d68ab169b239105 100644 --- a/vmm/peripheriques/peripheriques.h +++ b/vmm/peripheriques/peripheriques.h @@ -10,8 +10,9 @@ #include "sprites/content/sprite_content.h" #include "sprites/visibility/sprite_visibility.h" #include "sprites/position/sprite_position.h" +#include "keyboard/keyboard.h" -#define NB_STATE_MACHINE 6 +#define NB_STATE_MACHINE 7 void check_state(uint64_t addr, uint8_t* addr_p, uint8_t size, uint32_t value); diff --git a/vmm/peripheriques/peripheriques.o b/vmm/peripheriques/peripheriques.o index 9ca211e7e4f8933ade41de2a099d26236cb756f3..b045dc7a1c7766b669542cf895b2918bdb76a653 100644 Binary files a/vmm/peripheriques/peripheriques.o and b/vmm/peripheriques/peripheriques.o differ diff --git a/vmm/peripheriques/sprites/content/sprite_content.c b/vmm/peripheriques/sprites/content/sprite_content.c index a06e216460b1804f23235f9d33805038b88dceba..c0af4624543065c0c037834a2f55acb494899235 100644 --- a/vmm/peripheriques/sprites/content/sprite_content.c +++ b/vmm/peripheriques/sprites/content/sprite_content.c @@ -55,7 +55,5 @@ void sprite_content_store_data(void *addr){ void sprite_content_conclude(void *addr){ - printf("Showing sprite SLOT: %d, WIDTH: %d, HEIGHT: %d\n", sprite_content_params.slot, sprite_content_params.width, sprite_content_params.height); - - usleep(10000000); + //printf("Showing sprite SLOT: %d, WIDTH: %d, HEIGHT: %d\n", sprite_content_params.slot, sprite_content_params.width, sprite_content_params.height); } \ No newline at end of file diff --git a/vmm/peripheriques/sprites/content/sprite_content.o b/vmm/peripheriques/sprites/content/sprite_content.o index e9e2e02761a9eb7a82a11bd22ef6f425f3c630d9..801b11bc51fe37d49bee9156f6a780495c4072f7 100644 Binary files a/vmm/peripheriques/sprites/content/sprite_content.o and b/vmm/peripheriques/sprites/content/sprite_content.o differ diff --git a/vmm/peripheriques/sprites/position/sprite_position.c b/vmm/peripheriques/sprites/position/sprite_position.c index 006319cecf1b5c1e090c0565eaada16dc43fcf75..c26f79905a7ac8fe4c271486a98d32bc7f3d5f8c 100644 --- a/vmm/peripheriques/sprites/position/sprite_position.c +++ b/vmm/peripheriques/sprites/position/sprite_position.c @@ -29,7 +29,5 @@ void sprite_position_store_y(void *addr){ } void sprite_position_conclude(void *addr){ - printf("Showing sprite SLOT: %d, X: %d, Y: %d\n", sprite_position_params.slot, sprite_position_params.x, sprite_position_params.y); - - usleep(10000000); + //printf("Showing sprite SLOT: %d, X: %d, Y: %d\n", sprite_position_params.slot, sprite_position_params.x, sprite_position_params.y); } \ No newline at end of file diff --git a/vmm/peripheriques/sprites/position/sprite_position.o b/vmm/peripheriques/sprites/position/sprite_position.o index f1ee2bb632834dd7f877f619cae4c6eac68171de..9da0a592db38edc142945ab2c8ca888d4ab3b155 100644 Binary files a/vmm/peripheriques/sprites/position/sprite_position.o and b/vmm/peripheriques/sprites/position/sprite_position.o differ diff --git a/vmm/peripheriques/sprites/visibility/sprite_visibility.c b/vmm/peripheriques/sprites/visibility/sprite_visibility.c index 896bdabdc6561469cd37e6c73c70a21fffb2628c..90e20cd64cf31d8350620c51dee9697be02b43fa 100644 --- a/vmm/peripheriques/sprites/visibility/sprite_visibility.c +++ b/vmm/peripheriques/sprites/visibility/sprite_visibility.c @@ -24,7 +24,5 @@ void sprite_visibility_store_toggle(void *addr){ } void sprite_visibility_conclude(void *addr){ - printf("Showing sprite SLOT: %d, VISIBILITY: %d\n", sprite_visibility_params.slot, sprite_visibility_params.toggle); - - usleep(10000000); + //printf("Showing sprite SLOT: %d, VISIBILITY: %d\n", sprite_visibility_params.slot, sprite_visibility_params.toggle); } \ No newline at end of file diff --git a/vmm/peripheriques/sprites/visibility/sprite_visibility.o b/vmm/peripheriques/sprites/visibility/sprite_visibility.o index 4105482dbfb26854589a9df0d65c21e8f5db8f21..f5ec981653ac8bc6357b95cecb080f09f42f3c85 100644 Binary files a/vmm/peripheriques/sprites/visibility/sprite_visibility.o and b/vmm/peripheriques/sprites/visibility/sprite_visibility.o differ diff --git a/vmm/peripheriques/state_machine.h b/vmm/peripheriques/state_machine.h index 11c0fd6d1fa7801f99431ca46c5a7ecbf3b75892..4d4d7c61c5d7684187c09a4d3ed430e6679913e3 100644 --- a/vmm/peripheriques/state_machine.h +++ b/vmm/peripheriques/state_machine.h @@ -7,6 +7,7 @@ typedef enum t_action_t { WRITE, + WRITE_KEY, STORE, STORE_LOOP, EQUALS, diff --git a/vmm/peripheriques/timer/timer.c b/vmm/peripheriques/timer/timer.c index fcc89782d09da30a86692a1cdaa08e20a8c9802c..180c37053065817369270dd147787dfde47fe30b 100644 --- a/vmm/peripheriques/timer/timer.c +++ b/vmm/peripheriques/timer/timer.c @@ -20,6 +20,6 @@ void timer_store(void *addr){ void timer_conclude(void *addr){ hyper_timer_sleep_params_t* tmp_params = addr == NULL ? &timer_params : (hyper_timer_sleep_params_t*) addr; - printf("\nTime: %d\n", tmp_params->us); + // printf("\nTime: %d\n", tmp_params->us); usleep(tmp_params->us); } \ No newline at end of file diff --git a/vmm/peripheriques/timer/timer.o b/vmm/peripheriques/timer/timer.o index 84284c1e7d0cdeab224af08a1a65de8800d67c67..c998ddc48f6a3977b0dd715af3d190061ca4a6fc 100644 Binary files a/vmm/peripheriques/timer/timer.o and b/vmm/peripheriques/timer/timer.o differ diff --git a/vmm/vmm b/vmm/vmm index 97e079146cc757008d6e95c24a2090587129cae2..e8276973c100f06f69b8301a73bf605f2f5b4172 100755 Binary files a/vmm/vmm and b/vmm/vmm differ diff --git a/vmm/vmm.c b/vmm/vmm.c index 6ba03fc7d7bbf571e40be8b73019a14ee6d66bfe..a74227c2ae98878fb77f4fa54c87a8257e51ab17 100644 --- a/vmm/vmm.c +++ b/vmm/vmm.c @@ -20,30 +20,36 @@ #define SECTOR_SIZE 512 -typedef struct t_guest_os_t { - uint8_t* code; +typedef struct t_guest_os_t +{ + uint8_t *code; long codeSize; } guest_os_t; -guest_os_t* readByteCode(char* filePath){ +guest_os_t *readByteCode(char *filePath) +{ FILE *file = fopen(filePath, "rb"); - if (file == NULL) { + if (file == NULL) + { err(1, "fopen"); } - guest_os_t* guest_os = malloc(sizeof(guest_os_t)); + guest_os_t *guest_os = malloc(sizeof(guest_os_t)); fseek(file, 0, SEEK_END); guest_os->codeSize = ftell(file); fseek(file, 0, SEEK_SET); guest_os->code = malloc(guest_os->codeSize); - - fread(guest_os->code, 1, guest_os->codeSize, file); - if (ferror(file)) { + fread(guest_os->code, 1, guest_os->codeSize, file); + + if (ferror(file)) + { err(1, "Error reading file."); - } else { + } + else + { printf("File read successfully.\n"); } @@ -52,13 +58,16 @@ guest_os_t* readByteCode(char* filePath){ return guest_os; } -void write_sector(uint32_t sector_number, const uint8_t *data) { - if (sector_number > MAX_SECTOR_NUM) { +void write_sector(uint32_t sector_number, const uint8_t *data) +{ + if (sector_number > MAX_SECTOR_NUM) + { fprintf(stderr, "Sector number out of range\n"); } - + FILE *disk = fopen(disk_filename, "r+b"); - if (!disk) { + if (!disk) + { perror("Failed to open disk file"); } @@ -66,14 +75,16 @@ void write_sector(uint32_t sector_number, const uint8_t *data) { uint64_t offset = (uint64_t)sector_number * SECTOR_SIZE; // Seek to the sector position - if (fseek(disk, offset, SEEK_SET) != 0) { + if (fseek(disk, offset, SEEK_SET) != 0) + { perror("Seek failed"); fclose(disk); } // Write 512 bytes to the specified sector size_t bytes_written = fwrite(data, 1, SECTOR_SIZE, disk); - if (bytes_written != SECTOR_SIZE) { + if (bytes_written != SECTOR_SIZE) + { perror("Failed to write full sector"); fclose(disk); } @@ -90,47 +101,55 @@ sem_t display_sem; uint32_t display_width, display_height; -static uint32_t read_data(uint8_t *addr, uint8_t size) { +static uint32_t read_data(uint8_t *addr, uint8_t size) +{ uint32_t value; - switch (size) { - case 1: - value = *(uint8_t *)addr; + switch (size) + { + case 1: + value = *(uint8_t *)addr; break; - case 2: - value = *(uint16_t *)addr; + case 2: + value = *(uint16_t *)addr; break; - case 4: - value = *(uint32_t *)addr; + case 4: + value = *(uint32_t *)addr; break; - default: - errx(1, "Unsupported size trying to retrieve data.\n"); + default: + errx(1, "Unsupported size trying to retrieve data.\n"); break; } return value; } -void* vcpu_thread_func(void* args){ - while (1) { - if (ioctl(vcpufd, KVM_RUN, NULL) == -1){ +void *vcpu_thread_func(void *args) +{ + while (1) + { + if (ioctl(vcpufd, KVM_RUN, NULL) == -1) + { err(1, "KVM_RUN"); } - - switch (run->exit_reason) { + + switch (run->exit_reason) + { case KVM_EXIT_HLT: puts("KVM_EXIT_HLT"); return 0; case KVM_EXIT_IO: - printf("KVM_EXIT_IO\n"); - if (run->io.direction == KVM_EXIT_IO_OUT){ - uint32_t value = read_data((uint8_t*) run + run->io.data_offset, run->io.size); - if(run->io.size == 1 && run->io.port == 0xABBA){ - printf("HYPERCALL!!\n"); + // printf("KVM_EXIT_IO\n"); + if (run->io.direction == KVM_EXIT_IO_OUT) + { + uint32_t value = read_data((uint8_t *)run + run->io.data_offset, run->io.size); + if (run->io.size == 1 && run->io.port == 0xABBA) + { + // printf("HYPERCALL!!\n"); switch (value) { case 1: - hyper_console_params_t console_params = *(hyper_console_params_t*)shared_mem; + hyper_console_params_t console_params = *(hyper_console_params_t *)shared_mem; printf("%s", (char *)mem + console_params.msg); break; case 2: @@ -151,10 +170,10 @@ void* vcpu_thread_func(void* args){ gfx_init_conclude(shared_mem); break; case 4: - hyper_disk_params_t disk_params = *(hyper_disk_params_t*)shared_mem; - uint8_t *data_addr = (uint8_t*) mem + disk_params.data; + hyper_disk_params_t disk_params = *(hyper_disk_params_t *)shared_mem; + uint8_t *data_addr = (uint8_t *)mem + disk_params.data; write_sector(disk_params.sector_idx, data_addr); - + disk_conclude(shared_mem); break; case 5: @@ -167,22 +186,26 @@ void* vcpu_thread_func(void* args){ break; } } - else{ - check_state(run->io.port, (uint8_t*) run + run->io.data_offset, run->io.size, value); + else + { + check_state(run->io.port, (uint8_t *)run + run->io.data_offset, run->io.size, value); } } - else if (run->io.direction == KVM_EXIT_IO_IN) { - check_state(run->io.port, (uint8_t*) run + run->io.data_offset, run->io.size, 0); + else if (run->io.direction == KVM_EXIT_IO_IN) + { + check_state(run->io.port, (uint8_t *)run + run->io.data_offset, run->io.size, 0); } break; case KVM_EXIT_MMIO: - printf("KVM_EXIT_MMIO\n"); - if (run->mmio.is_write) { + // printf("KVM_EXIT_MMIO\n"); + if (run->mmio.is_write) + { uint32_t value = read_data((uint8_t *)run->mmio.data, run->mmio.len); check_state(run->mmio.phys_addr, run->mmio.data, run->mmio.len, value); } - else if (!run->mmio.is_write) { + else if (!run->mmio.is_write) + { check_state(run->mmio.phys_addr, run->mmio.data, run->mmio.len, 0); } break; @@ -197,100 +220,135 @@ void* vcpu_thread_func(void* args){ } } -int main(int argc, char **argv){ +int main(int argc, char **argv) +{ - guest_os_t* guest_os = readByteCode(argv[1]); + guest_os_t *guest_os = readByteCode(argv[1]); disk_filename = argv[2]; printf("Disk filename: %s\n", disk_filename); int kvmfd = open("/dev/kvm", O_RDWR | O_CLOEXEC); - if(kvmfd == -1){ + if (kvmfd == -1) + { err(1, "/dev/kvm"); } int version = ioctl(kvmfd, KVM_GET_API_VERSION, NULL); - if(version == -1){ - err (1 , "KVM_GET_API_VERSION") ; - } - if(version != KVM_API_VERSION){ + if (version == -1) + { + err(1, "KVM_GET_API_VERSION"); + } + if (version != KVM_API_VERSION) + { err(1, "Unsupported version of the KVM API"); } int vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0); - if(vmfd == -1){ - err(1, "KVM_CREATE_VM"); + if (vmfd == -1) + { + err(1, "KVM_CREATE_VM"); } uint64_t ram_size = 512 * 4096; - mem = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0) ; - if(!mem){ + mem = mmap(NULL, ram_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (!mem) + { err(1, "Allocating guest memory"); } printf("Size: %ld\n", guest_os->codeSize); memcpy(mem, guest_os->code, guest_os->codeSize); - struct kvm_userspace_memory_region memreg = { + struct kvm_userspace_memory_region memreg = { .slot = 0, .guest_phys_addr = 0, .memory_size = ram_size, .userspace_addr = (uint64_t)mem, - .flags = 0 - }; - if(ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg) == -1){ - err(1 , "KVM_SET_USER_MEMORY_REGION"); + .flags = 0}; + if (ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &memreg) == -1) + { + err(1, "KVM_SET_USER_MEMORY_REGION"); } uint64_t shared_size = 4096; - shared_mem = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0) ; - if(!shared_mem ){ + shared_mem = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (!shared_mem) + { err(1, "Allocating guest memory"); } - struct kvm_userspace_memory_region shared_memreg = { - .slot = 1 , + struct kvm_userspace_memory_region shared_memreg = { + .slot = 1, .guest_phys_addr = 3ULL * 1024 * 1024 * 1024, .memory_size = shared_size, - .userspace_addr = (uint64_t)shared_mem, - .flags = 0 + .userspace_addr = (uint64_t)shared_mem, + .flags = 0}; + if (ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &shared_memreg) == -1) + { + err(1, "KVM_SET_USER_MEMORY_REGION 2"); + } + + if (ioctl(vmfd, KVM_CREATE_IRQCHIP, NULL) < 0) + { + err(1, "KVM_GET_IRQCHIP"); + } + + struct kvm_irqchip irqchip = { + .chip_id = 0, // 0 = PIC1 , 1 = PIC2 , 2 = IOAPIC }; - if(ioctl(vmfd, KVM_SET_USER_MEMORY_REGION, &shared_memreg) == -1){ - err(1 , "KVM_SET_USER_MEMORY_REGION 2"); + + // Retrieve the PIC registers + if (ioctl(vmfd, KVM_GET_IRQCHIP, &irqchip) < 0) + { + err(1, "KVM_GET_IRQCHIP 1"); + } + + irqchip.chip.pic.auto_eoi = 1; + + if (ioctl(vmfd, KVM_SET_IRQCHIP, &irqchip) < 0) + { + err(1, "KVM_SET_IRQCHIP 2"); } vcpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0); - if(vcpufd < 0){ + if (vcpufd < 0) + { err(1, "KVM_CREATE_VCPU"); } int vcpu_mmap_sz = ioctl(kvmfd, KVM_GET_VCPU_MMAP_SIZE, NULL); - if(vcpu_mmap_sz == -1){ + if (vcpu_mmap_sz == -1) + { err(1, "KVM_GET_VCPU_MMAP_SIZE"); } - if(vcpu_mmap_sz < sizeof(struct kvm_run)){ + if (vcpu_mmap_sz < sizeof(struct kvm_run)) + { err(1, "KVM_GET_VCPU_MMAP_SIZE unexpectedly small"); } run = mmap(NULL, vcpu_mmap_sz, PROT_READ | PROT_WRITE, MAP_SHARED, vcpufd, 0); - if(!run){ + if (!run) + { err(1, "mmap vcpu"); } - struct kvm_sregs sregs ; - if(ioctl(vcpufd, KVM_GET_SREGS, &sregs) == -1){ + struct kvm_sregs sregs; + if (ioctl(vcpufd, KVM_GET_SREGS, &sregs) == -1) + { err(1, "KVM_GET_SREGS"); } sregs.cs.base = 0; sregs.cs.selector = 0; - sregs.ds.base = 0; + sregs.ds.base = 0; sregs.ds.selector = 0; sregs.es.base = 0; sregs.es.selector = 0; sregs.ss.base = 0; sregs.ss.selector = 0; - if(ioctl(vcpufd, KVM_SET_SREGS, &sregs) == -1){ + if (ioctl(vcpufd, KVM_SET_SREGS, &sregs) == -1) + { err(1, "KVM_SET_SREGS"); } @@ -300,8 +358,9 @@ int main(int argc, char **argv){ regs.rip = 0; regs.rsp = ram_size; regs.rflags = 0x2; - - if(ioctl(vcpufd, KVM_SET_REGS, ®s) == -1){ + + if (ioctl(vcpufd, KVM_SET_REGS, ®s) == -1) + { err(1, "KVM_SET_REGS"); } @@ -317,7 +376,46 @@ int main(int argc, char **argv){ gfx_context_t *ctxt = gfx_create("Display", display_width, display_height); - if(pthread_join(vcpu_thread, NULL)==-1){ + bool quit = false; + + while (!quit) + { + SDL_Keycode key = gfx_keypressed(); + + if (key != 0) + { + keyboard_params.key = key; + + struct kvm_irq_level irq_level; + irq_level.irq = 1; + + irq_level.level = 1; + if (ioctl(vmfd, KVM_IRQ_LINE, &irq_level) < 0) + { + err(1, "KVM_GET_IRQCHIP UP"); + } + + irq_level.level = 0; + if (ioctl(vmfd, KVM_IRQ_LINE, &irq_level) < 0) + { + err(1, "KVM_GET_IRQCHIP DOWN"); + } + + printf("Stored Key: %d\n", keyboard_params.key); + // sleep(10); + // usleep(10000000); + + if (key == SDLK_ESCAPE) + { + quit = true; + } + } + } + + pthread_cancel(vcpu_thread); + + if (pthread_join(vcpu_thread, NULL) == -1) + { err(1, "pthread_join"); } gfx_destroy(ctxt); diff --git a/vmm/vmm.d b/vmm/vmm.d index 9aaecd3e45d7712578fad8e38507269287475b27..39fc2c3bcc7287dfec18ed13ce9870267b7dfac9 100644 --- a/vmm/vmm.d +++ b/vmm/vmm.d @@ -14,4 +14,7 @@ vmm.o: vmm.c ../shared/hypercall_params.h gfx/gfx.h \ peripheriques/sprites/visibility/sprite_visibility.h \ peripheriques/sprites/visibility/../sprites.h \ peripheriques/sprites/position/sprite_position.h \ - peripheriques/sprites/position/../sprites.h + peripheriques/sprites/position/../sprites.h \ + peripheriques/keyboard/keyboard.h \ + peripheriques/keyboard/../state_machine.h \ + peripheriques/keyboard/../../../shared/hypercall_params.h diff --git a/vmm/vmm.o b/vmm/vmm.o index 4c48b43b41dd8dc4eb5610e5d1083e00fac67519..778c71c6720e4ea5ca446543501f6e961982c3bf 100644 Binary files a/vmm/vmm.o and b/vmm/vmm.o differ