diff --git a/shared/hypercall_params.h b/shared/hypercall_params.h
index c1338ad75713eb727bd9cd84166b8768e7454f84..0fdc4399118c6f1150cf747cb070857c822ad86c 100644
--- a/shared/hypercall_params.h
+++ b/shared/hypercall_params.h
@@ -13,6 +13,7 @@
 #define HYPERCALL_CODE_CONSOLE    1
 #define HYPERCALL_CODE_TIMER      2
 #define HYPERCALL_CODE_GFX_INIT   3
+#define HYPERCALL_CODE_IDE        4
 
 #define REG_TIMER_CMD  0x43
 #define REG_TIMER_DATA 0x40
@@ -21,6 +22,10 @@
 #define REG_GFX_INIT_CMD  0x4E700100
 #define REG_GFX_INIT_DATA 0x4E700200
 
+#define REG_IDE_ST    0x1F7
+#define REG_IDE_CMD   0x1F7
+#define REG_IDE_DATA  0x1F0
+
 // --- SHARED STRUCT ---
 
 typedef struct {
@@ -39,6 +44,12 @@ typedef struct {
     uint32_t height;  // vertical resolution in pixels 
 } __attribute__((packed)) hyper_init_gfx_params_t;
 
+typedef struct {
+
+    uint32_t sector_idx;  // sector index ( or number )
+    uint64_t data;        // address of data to write (512 bytes)
+} __attribute__((packed)) hyper_ide_params_t;
+
 // --- FUNCTION ---
 
 // ...
diff --git a/vmm/handler.c b/vmm/handler.c
index 31ef2c42c3efe3a81f9cc6caf12f6658f331a345..5c0b4852cd2c55fe8bb9217b820acdbcda28bbdc 100644
--- a/vmm/handler.c
+++ b/vmm/handler.c
@@ -92,6 +92,7 @@ static state_t *state_check(uint64_t addr, uint8_t size, uint32_t value) {
             break;
 
             case OP_WRITE_STORE:
+            case OP_WRITE_STORE_LOOP:
 
                 if (next_state->addr == addr && next_state->size == size && next_state->callback != NULL)
                     return next_state;
@@ -111,11 +112,6 @@ static void state_compute(state_t *state, uint32_t value) {
 
     switch (state->op) {
 
-        case OP_WRITE_STORE:
-
-            state->callback(&value);
-        break;
-
         case OP_READ_INJECT:
 
             injecte_data((uint8_t *)&state->addr, state->size, state->value);
@@ -123,12 +119,22 @@ static void state_compute(state_t *state, uint32_t value) {
                    state->size * 8, state->addr, state->value);
         break;
 
+        case OP_WRITE_STORE_LOOP:
+
+            if (flag_stop_loop == false)
+                current_state = state - 1; // cancled next +1
+        break;
+
         case OP_EMUL_END:
+        case OP_WRITE_STORE:
         case OP_WRITE_EQUAL:
             // nothing...
         break;
     }
 
+    if (state->callback != NULL)
+        state->callback(&value);
+
     // - check and compute last operation -
     current_state = state + 1;
     if (current_state->op == OP_EMUL_END) {
@@ -162,6 +168,14 @@ static void wrapper_op_gfx_init(uint8_t *shared_buf) {
     op_callback_gfx_init_conclude(p_init_gfx);
 }
 
+static void wrapper_op_ide(uint8_t *shared_buf, uint8_t *mem) {
+
+    hyper_ide_params_t *p_ide = (hyper_ide_params_t *)shared_buf;
+    p_ide->data = p_ide->data + (uint64_t)mem;
+
+    op_callback_ide_condlude(p_ide);
+}
+
 // --- FUNCTION ---
 
 // - VMM EXIT REASON HANDLER -
@@ -170,7 +184,7 @@ void handle_halt(struct kvm_run *run, ...) {
 
     va_list args; va_start(args, run);
 
-    va_arg(args, uint8_t *); va_arg(args, uint8_t *); // skip two first args
+    va_arg(args, uint8_t *); va_arg(args, uint8_t *);  // skip two first args
     bool *done = va_arg(args, bool *);
 
     printf("guest halted\n");
@@ -208,7 +222,6 @@ void handle_pmio(struct kvm_run *run, ...) {
     va_end(args);
 }
 
-// waiting for : uint8_t *shared_buf, uint8_t *mem
 void handle_mmio(struct kvm_run *run, ...) {
 
     if (run->mmio.is_write) {
@@ -241,6 +254,10 @@ void handle_hypercall(uint32_t code, uint8_t *shared_buf, uint8_t *mem) {
             wrapper_op_gfx_init(shared_buf);
         break;
 
+        case HYPERCALL_CODE_IDE:
+            wrapper_op_ide(shared_buf, mem);
+        break;
+
         default:
             errx(1, "Unsupported hypercall code.\n");
         break;
diff --git a/vmm/operation.c b/vmm/operation.c
index e0f3406ac654b9c2ed841f2b3b40813d4eebd417..9a7f6b123c0fb1fa999267e550abc09d72e3703d 100644
--- a/vmm/operation.c
+++ b/vmm/operation.c
@@ -1,10 +1,14 @@
 #include "operation.h"
 
+#include <err.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <unistd.h>
 #include <semaphore.h>
 
+#include "shared/ide_regs.h"
 #include "shared/hypercall_params.h"
 
 // --- DEFINE ---
@@ -18,21 +22,43 @@ state_t STATE_TIMER[] = {
 
 state_t STATE_GFX_INIT[] = {
 
-    { OP_READ_INJECT, REG_GFX_INIT_ST,   0, 4, NULL },
+    { OP_READ_INJECT, REG_GFX_INIT_ST,   0, 1, NULL },
     { OP_WRITE_EQUAL, REG_GFX_INIT_CMD,  5, 4, NULL },
-    { OP_WRITE_STORE, REG_GFX_INIT_DATA, 0, 4, op_callback_gfx_init_store_w},
-    { OP_WRITE_STORE, REG_GFX_INIT_DATA, 0, 4, op_callback_gfx_init_store_h},
-    { OP_EMUL_END,    0,                 0, 0, op_callback_gfx_init_conclude},
+    { OP_WRITE_STORE, REG_GFX_INIT_DATA, 0, 4, op_callback_gfx_init_store_w },
+    { OP_WRITE_STORE, REG_GFX_INIT_DATA, 0, 4, op_callback_gfx_init_store_h },
+    { OP_EMUL_END,    0,                 0, 0, op_callback_gfx_init_conclude },
+};
+
+state_t STATE_IDE[] = {
+
+    { OP_READ_INJECT,      REG_IDE_ST,       0,                1, op_callback_ide_prepare },
+    { OP_WRITE_EQUAL,      REG_IDE_DATA + 2, 1,                1, NULL },
+    { OP_WRITE_STORE,      REG_IDE_DATA + 3, 0,                1, op_callback_ide_store_sector_1 },
+    { OP_WRITE_STORE,      REG_IDE_DATA + 4, 0,                1, op_callback_ide_store_sector_2 },
+    { OP_WRITE_STORE,      REG_IDE_DATA + 5, 0,                1, op_callback_ide_store_sector_3 },
+    { OP_WRITE_STORE,      REG_IDE_DATA + 6, 0,                1, op_callback_ide_store_sector_4 },
+    { OP_WRITE_EQUAL,      REG_IDE_CMD,      0x30,             1, NULL },
+    { OP_READ_INJECT,      REG_IDE_ST,       0,                1, NULL },
+    { OP_WRITE_STORE_LOOP, REG_IDE_DATA,     0,                2, op_callback_ide_store_data },
+    { OP_EMUL_END,         0,                0,                0, op_callback_ide_condlude },
 };
 
 state_t *STATE_ALL_STARTERS[] = {
 
     &STATE_TIMER[0],
     &STATE_GFX_INIT[0],
+    &STATE_IDE[0],
 };
 
+bool flag_stop_loop = false;
+
 static hyper_timer_sleep_params_t param_timer;
 static hyper_init_gfx_params_t param_gfx_init;
+static hyper_ide_params_t param_ide;
+
+// store the index of the actual loop
+static uint32_t loop_ide_data;
+static uint16_t buf_ide_data[MAX_LOOP_IDE_DATA];
 
 // --- STATIC FUNCTION ---
 
@@ -80,3 +106,74 @@ void op_callback_gfx_init_conclude(void *addr) {
     height_gfx = p_gfx_init->height;
     sem_post(&sem_gfx);
 }
+
+void op_callback_ide_prepare(void *addr) {
+
+    flag_stop_loop = false;
+    loop_ide_data = MAX_LOOP_IDE_DATA;
+
+    param_ide.data = (uint64_t)buf_ide_data;
+}
+
+void op_callback_ide_store_sector_1(void *addr) {
+
+    param_ide.sector_idx = *(uint8_t *)addr;
+}
+
+void op_callback_ide_store_sector_2(void *addr) {
+
+    param_ide.sector_idx |= (*(uint8_t *)addr) << 8;
+}
+
+void op_callback_ide_store_sector_3(void *addr) {
+
+    param_ide.sector_idx |= (*(uint8_t *)addr) << 16;
+}
+
+void op_callback_ide_store_sector_4(void *addr) {
+
+    param_ide.sector_idx |= ((*(uint8_t *)addr) & 0x0F) << 24;
+    // TODO: what to do with the mode ?
+}
+
+void op_callback_ide_store_data(void *addr) {
+
+    buf_ide_data[MAX_LOOP_IDE_DATA - loop_ide_data] = *(uint16_t *)addr;
+    loop_ide_data--;
+
+    if (loop_ide_data == 0) {
+
+        flag_stop_loop = true;
+        loop_ide_data = MAX_LOOP_IDE_DATA;
+    }
+}
+
+void op_callback_ide_condlude(void *addr) {
+
+    hyper_ide_params_t *p_ide = (addr == NULL) ? &param_ide : (hyper_ide_params_t *)addr;
+    printf("action : writing on 0x%lx on sector %d\n", p_ide->data, p_ide->sector_idx);
+
+    // check sector range
+    if (p_ide->sector_idx > MAX_SECTOR_NUM) err(1, "IDE sector is out of range");
+
+    FILE *disk = fopen(disk_path, "r+b");
+    if (!disk) err(1, "Failed opening the disk file");
+
+    // calculate the offset for the sector
+    uint64_t offset = (uint64_t)p_ide->sector_idx * SECTOR_SIZE;
+
+    // Seek to the sector position
+    if (fseek(disk, offset, SEEK_SET) != 0) {
+        err(1, "IDE seek failed");
+        fclose(disk);
+    }
+
+    // Write 512 bytes to the specified sector
+    size_t bytes_written = fwrite((void *)p_ide->data, 1, SECTOR_SIZE, disk);
+    if (bytes_written != SECTOR_SIZE) {
+        err(1, "IDE failed to write full sector");
+        fclose(disk);
+    }
+
+    fclose(disk);
+}
diff --git a/vmm/operation.h b/vmm/operation.h
index 05f95d806affcfd172a0a81ef3f42adb544aecf8..ff9af8186e2adc29e4d01d7edbcd150819afc155 100644
--- a/vmm/operation.h
+++ b/vmm/operation.h
@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 #include <unistd.h>
+#include <stdbool.h>
 #include <pthread.h>
 #include <semaphore.h>
 
@@ -13,10 +14,11 @@
 
 typedef enum {
 
-    OP_WRITE_EQUAL,  // Perform a write operation and check if the written value matches the expected value
-    OP_WRITE_STORE,  // Store the written value into a specific location (used in callbacks)
-    OP_READ_INJECT,  // Inject a value into the guest from a specific address
-    OP_EMUL_END,     // End of the state machine, with an callback for completion
+    OP_WRITE_EQUAL,       // Perform a write operation and check if the written value matches the expected value
+    OP_WRITE_STORE,       // Store the written value into a specific location (used in callbacks)
+    OP_WRITE_STORE_LOOP,  // Store the written value into a specific location multiple time
+    OP_READ_INJECT,       // Inject a value into the guest from a specific address
+    OP_EMUL_END,          // End of the state machine, with an callback for completion
 } operation_t;
 
 typedef struct {
@@ -28,10 +30,14 @@ typedef struct {
     void (*callback)(void *addr);   // custom function that would be executed at the end of the state
 } state_t;
 
+extern bool flag_stop_loop;
+
 extern sem_t sem_gfx;
 extern uint32_t width_gfx;
 extern uint32_t height_gfx;
 
+extern char *disk_path;
+
 extern state_t *STATE_ALL_STARTERS[];
 
 extern state_t STATE_TIMER[];
@@ -84,4 +90,18 @@ void op_callback_gfx_init_store_h(void *addr);
  */
 void op_callback_gfx_init_conclude(void *addr);
 
+void op_callback_ide_prepare(void *addr);
+
+void op_callback_ide_store_sector_1(void *addr);
+
+void op_callback_ide_store_sector_2(void *addr);
+
+void op_callback_ide_store_sector_3(void *addr);
+
+void op_callback_ide_store_sector_4(void *addr);
+
+void op_callback_ide_store_data(void *addr);
+
+void op_callback_ide_condlude(void *addr);
+
 #endif // _OPERATION_H_
diff --git a/vmm/vmm_main.c b/vmm/vmm_main.c
index 91771d21bf2628e458287ea9f16f8527b120d4f8..1f5b037214df242b83f3c62fd1ff008454259530 100644
--- a/vmm/vmm_main.c
+++ b/vmm/vmm_main.c
@@ -30,6 +30,8 @@ sem_t sem_gfx;
 uint32_t width_gfx;
 uint32_t height_gfx;
 
+char *disk_path;
+
 static uint8_t *mem, *shared_buf;
 static struct kvm_run *run;
 static int vcpufd;
@@ -67,8 +69,9 @@ int main(int argc, char* argv[])
     int32_t mmap_size;
 
     // -- 0. Handle Args --
-    if (argc != 2) err(1, "Number of args invalide");
+    if (argc != 3) err(1, "Number of args invalide");
     char *file_path = argv[1];
+    disk_path = argv[2];
 
     // -- 1. Create a KVM device --
     kvmfd = open("/dev/kvm", O_RDWR | O_CLOEXEC); // get file descriptor