feat: (ahci) support multiple AHCI controller
authorMinep <zelong56@gmail.com>
Thu, 10 Nov 2022 18:33:40 +0000 (18:33 +0000)
committerMinep <zelong56@gmail.com>
Thu, 10 Nov 2022 18:33:40 +0000 (18:33 +0000)
feat: (pci) pci device driver auto-binding
refactor: (isrm) change the interrupt vector type to int
fix: (waitq) mitigation of possible race condition in pwait
fix: (sched) expand stack size of dummy process for allowance in the using of kprintf
refactor: (kinit) reserve the higher half space as earlier as possible.

lunaix-os/hal/ahci/ahci.c
lunaix-os/hal/pci.c
lunaix-os/includes/hal/ahci/ahci.h
lunaix-os/includes/hal/ahci/hba.h
lunaix-os/includes/hal/pci.h
lunaix-os/includes/lunaix/isrm.h
lunaix-os/kernel/asm/x86/i386_isrm.c
lunaix-os/kernel/ds/waitq.c
lunaix-os/kernel/k_init.c
lunaix-os/kernel/proc0.c
lunaix-os/kernel/process/sched.c

index f6f27186d9642cdf70e0601532e3a0d38f1150a1..b9bca9594a9ea5da693f8e1f4e1c19158287ff37 100644 (file)
 #define HBA_FIS_SIZE 256
 #define HBA_CLB_SIZE 1024
 
-#define HBA_MY_IE (HBA_PxINTR_DHR | HBA_PxINTR_TFEE)
+#define HBA_MY_IE (HBA_PxINTR_DHR | HBA_PxINTR_TFEE | HBA_PxINTR_OFE)
 
 // #define DO_HBA_FULL_RESET
 
 LOG_MODULE("AHCI")
 
-struct ahci_hba hba;
+struct llist_header ahcis;
 
 static char sata_ifs[][20] = { "Not detected",
                                "SATA I (1.5Gbps)",
@@ -58,20 +58,8 @@ achi_register_ops(struct hba_port* port);
 void
 ahci_register_device(struct hba_device* hbadev);
 
-unsigned int
-ahci_get_port_usage()
-{
-    return hba.ports_bmp;
-}
-
-struct hba_port*
-ahci_get_port(unsigned int index)
-{
-    if (index >= 32) {
-        return 0;
-    }
-    return hba.ports[index];
-}
+void*
+ahci_driver_init(struct pci_device* ahci_dev);
 
 void
 __hba_reset_port(hba_reg_t* port_reg)
@@ -92,9 +80,13 @@ __hba_reset_port(hba_reg_t* port_reg)
 void
 ahci_init()
 {
-    struct pci_device* ahci_dev = pci_get_device_by_class(AHCI_HBA_CLASS);
-    assert_msg(ahci_dev, "AHCI: Not found.");
+    llist_init_head(&ahcis);
+    pci_add_driver("Serial ATA AHCI", AHCI_HBA_CLASS, 0, 0, ahci_driver_init);
+}
 
+void*
+ahci_driver_init(struct pci_device* ahci_dev)
+{
     struct pci_base_addr* bar6 = &ahci_dev->bar[5];
     assert_msg(bar6->type & BAR_TYPE_MMIO, "AHCI: BAR#6 is not MMIO.");
 
@@ -105,30 +97,35 @@ ahci_init()
 
     pci_write_cspace(ahci_dev->cspace_base, PCI_REG_STATUS_CMD, cmd);
 
-    pci_setup_msi(ahci_dev, isrm_ivexalloc(__ahci_hba_isr));
+    int iv = isrm_ivexalloc(__ahci_hba_isr);
+    pci_setup_msi(ahci_dev, iv);
+
+    struct ahci_driver* ahci_drv = vzalloc(sizeof(*ahci_drv));
+    struct ahci_hba* hba = &ahci_drv->hba;
+    ahci_drv->id = iv;
 
-    memset(&hba, 0, sizeof(hba));
+    llist_append(&ahcis, &ahci_drv->ahci_drvs);
 
-    hba.base = (hba_reg_t*)ioremap(bar6->start, bar6->size);
+    hba->base = (hba_reg_t*)ioremap(bar6->start, bar6->size);
 
 #ifdef DO_HBA_FULL_RESET
     // 重置HBA
-    hba.base[HBA_RGHC] |= HBA_RGHC_RESET;
-    wait_until(!(hba.base[HBA_RGHC] & HBA_RGHC_RESET));
+    hba->base[HBA_RGHC] |= HBA_RGHC_RESET;
+    wait_until(!(hba->base[HBA_RGHC] & HBA_RGHC_RESET));
 #endif
 
     // 启用AHCI工作模式,启用中断
-    hba.base[HBA_RGHC] |= HBA_RGHC_ACHI_ENABLE;
-    hba.base[HBA_RGHC] |= HBA_RGHC_INTR_ENABLE;
+    hba->base[HBA_RGHC] |= HBA_RGHC_ACHI_ENABLE;
+    hba->base[HBA_RGHC] |= HBA_RGHC_INTR_ENABLE;
 
     // As per section 3.1.1, this is 0 based value.
-    hba_reg_t cap = hba.base[HBA_RCAP];
-    hba_reg_t pmap = hba.base[HBA_RPI];
+    hba_reg_t cap = hba->base[HBA_RCAP];
+    hba_reg_t pmap = hba->base[HBA_RPI];
 
-    hba.ports_num = (cap & 0x1f) + 1;  // CAP.PI
-    hba.cmd_slots = (cap >> 8) & 0x1f; // CAP.NCS
-    hba.version = hba.base[HBA_RVER];
-    hba.ports_bmp = pmap;
+    hba->ports_num = (cap & 0x1f) + 1;  // CAP.PI
+    hba->cmd_slots = (cap >> 8) & 0x1f; // CAP.NCS
+    hba->version = hba->base[HBA_RVER];
+    hba->ports_bmp = pmap;
 
     /* ------ HBA端口配置 ------ */
     uintptr_t clb_pg_addr, fis_pg_addr, clb_pa, fis_pa;
@@ -141,7 +138,7 @@ ahci_init()
         struct hba_port* port =
           (struct hba_port*)valloc(sizeof(struct hba_port));
         hba_reg_t* port_regs =
-          (hba_reg_t*)(&hba.base[HBA_RPBASE + i * HBA_RPSIZE]);
+          (hba_reg_t*)(&hba->base[HBA_RPBASE + i * HBA_RPSIZE]);
 
 #ifndef DO_HBA_FULL_RESET
         __hba_reset_port(port_regs);
@@ -167,14 +164,15 @@ ahci_init()
         *port = (struct hba_port){ .regs = port_regs,
                                    .ssts = port_regs[HBA_RPxSSTS],
                                    .cmdlst = clb_pg_addr + clbp * HBA_CLB_SIZE,
-                                   .fis = fis_pg_addr + fisp * HBA_FIS_SIZE };
+                                   .fis = fis_pg_addr + fisp * HBA_FIS_SIZE,
+                                   .hba = hba };
 
         /* 初始化端口,并置于就绪状态 */
         port_regs[HBA_RPxCI] = 0;
 
         hba_clear_reg(port_regs[HBA_RPxSERR]);
 
-        hba.ports[i] = port;
+        hba->ports[i] = port;
 
         if (!HBA_RPxSSTS_IF(port->ssts)) {
             continue;
@@ -198,6 +196,8 @@ ahci_init()
 
         ahci_register_device(hbadev);
     }
+
+    return ahci_drv;
 }
 
 void
@@ -212,46 +212,6 @@ ahci_register_device(struct hba_device* hbadev)
     block_mount(bdev, ahci_fsexport);
 }
 
-void
-ahci_list_device()
-{
-    kprintf(KINFO "Version: %x; Ports: %d; Slot: %d\n",
-            hba.version,
-            hba.ports_num,
-            hba.cmd_slots);
-    struct hba_port* port;
-    for (size_t i = 0; i < 32; i++) {
-        port = hba.ports[i];
-
-        // 愚蠢的gcc似乎认为 struct hba_port* 不可能为空
-        //  所以将这个非常关键的if给优化掉了。
-        //  这里将指针强制转换为整数,欺骗gcc :)
-        if ((uintptr_t)port == 0) {
-            continue;
-        }
-
-        int device_state = HBA_RPxSSTS_IF(port->ssts);
-
-        kprintf("\t Port %d: %s (%x)\n",
-                i,
-                &sata_ifs[device_state],
-                port->device->flags);
-
-        struct hba_device* dev_info = port->device;
-        if (!device_state || !dev_info) {
-            continue;
-        }
-        kprintf("\t\t capacity: %d KiB\n",
-                (dev_info->max_lba * dev_info->block_size) >> 10);
-        kprintf("\t\t block size: %dB\n", dev_info->block_size);
-        kprintf("\t\t block/sector: %d\n", dev_info->block_per_sec);
-        kprintf("\t\t alignment: %dB\n", dev_info->alignment_offset);
-        kprintf("\t\t capabilities: %x\n", dev_info->capabilities);
-        kprintf("\t\t model: %s\n", &dev_info->model);
-        kprintf("\t\t serial: %s\n", &dev_info->serial_num);
-    }
-}
-
 int
 __get_free_slot(struct hba_port* port)
 {
@@ -259,9 +219,9 @@ __get_free_slot(struct hba_port* port)
     hba_reg_t pxci = port->regs[HBA_RPxCI];
     hba_reg_t free_bmp = pxsact | pxci;
     uint32_t i = 0;
-    for (; i <= hba.cmd_slots && (free_bmp & 0x1); i++, free_bmp >>= 1)
+    for (; i <= port->hba->cmd_slots && (free_bmp & 0x1); i++, free_bmp >>= 1)
         ;
-    return i | -(i > hba.cmd_slots);
+    return i | -(i > port->hba->cmd_slots);
 }
 
 void
@@ -358,6 +318,7 @@ ahci_init_device(struct hba_port* port)
 
     port->device = vzalloc(sizeof(struct hba_device));
     port->device->port = port;
+    port->device->hba = port->hba;
 
     // 在命令表中构建命令FIS
     struct sata_reg_fis* cmd_fis = (struct sata_reg_fis*)cmd_table->command_fis;
index 229335c841d3675364b2bda84ce8ddef836a5f6a..cb7cfe75351ca7ad6e1b48f14298827c7bd70f34 100644 (file)
@@ -11,6 +11,7 @@
 #include <hal/acpi/acpi.h>
 #include <hal/apic.h>
 #include <hal/pci.h>
+#include <klibc/string.h>
 #include <lunaix/fs/twifs.h>
 #include <lunaix/mm/valloc.h>
 #include <lunaix/spike.h>
@@ -18,7 +19,8 @@
 
 LOG_MODULE("PCI")
 
-static struct llist_header pci_devices;
+static DEFINE_LLIST(pci_devices);
+static DEFINE_LLIST(pci_drivers);
 
 void
 pci_probe_msi_info(struct pci_device* device);
@@ -62,17 +64,27 @@ pci_probe_device(int bus, int dev, int funct)
                                    .device_info = reg1,
                                    .intr_info = intr };
 
-    kprintf("dev.%d:%d:%d %x:%x\n",
-            bus,
-            dev,
-            funct,
-            PCI_DEV_VENDOR(reg1),
-            PCI_DEV_DEVID(reg1));
-
     pci_probe_msi_info(device);
     pci_probe_bar_info(device);
 
     llist_append(&pci_devices, &device->dev_chain);
+
+    if (!pci_bind_driver(device)) {
+        kprintf(KWARN "dev.%d:%d:%d %x:%x unknown device\n",
+                bus,
+                dev,
+                funct,
+                PCI_DEV_VENDOR(reg1),
+                PCI_DEV_DEVID(reg1));
+    } else {
+        kprintf("dev.%d:%d:%d %x:%x %s\n",
+                bus,
+                dev,
+                funct,
+                PCI_DEV_VENDOR(reg1),
+                PCI_DEV_DEVID(reg1),
+                device->driver.type->name);
+    }
 }
 
 void
@@ -308,10 +320,51 @@ pci_get_device_by_class(uint32_t class)
     return NULL;
 }
 
+void
+pci_add_driver(const char* name,
+               u32_t class,
+               u32_t vendor,
+               u32_t devid,
+               pci_drv_init init)
+{
+    struct pci_driver* pci_drv = valloc(sizeof(*pci_drv));
+    *pci_drv = (struct pci_driver){ .create_driver = init,
+                                    .dev_info = (vendor << 16) | devid,
+                                    .dev_class = class };
+    if (name) {
+        strncpy(pci_drv->name, name, PCI_DRV_NAME_LEN);
+    }
+
+    llist_append(&pci_drivers, &pci_drv->drivers);
+}
+
+int
+pci_bind_driver(struct pci_device* pci_dev)
+{
+    struct pci_driver *pos, *n;
+    llist_for_each(pos, n, &pci_drivers, drivers)
+    {
+        if (pos->dev_info) {
+            if (pos->dev_info == pci_dev->device_info) {
+                goto check_type;
+            }
+            continue;
+        }
+    check_type:
+        if (pos->dev_class) {
+            if (pos->dev_class == PCI_DEV_CLASS(pci_dev->class_info)) {
+                pci_dev->driver.type = pos;
+                pci_dev->driver.instance = pos->create_driver(pci_dev);
+                return 1;
+            }
+        }
+    }
+    return 0;
+}
+
 void
 pci_init()
 {
-    llist_init_head(&pci_devices);
     acpi_context* acpi = acpi_get_context();
     assert_msg(acpi, "ACPI not initialized.");
     if (acpi->mcfg.alloc_num) {
index ea63a9c19412d3613b376fa90ddd00d568483039..2ed135aba3d00a14f287b2c90a2a7b998337d4cf 100644 (file)
 
 #define AHCI_HBA_CLASS 0x10601
 
+struct ahci_driver
+{
+    struct llist_header ahci_drvs;
+    struct ahci_hba hba;
+    int id;
+};
+
 /**
  * @brief 初始化AHCI与HBA
  *
 void
 ahci_init();
 
-void
-ahci_list_device();
-
-unsigned int
-ahci_get_port_usage();
-
-struct hba_port*
-ahci_get_port(unsigned int index);
-
 void
 ahci_parse_dev_info(struct hba_device* dev_info, uint16_t* data);
 
index c60536d6d14b3707796ad76261c90c60bafc30ee..287f868f4ae66e491f3168cd2b5127cfca233420 100644 (file)
@@ -36,6 +36,7 @@
 #define HBA_PxINTR_DHR (1)
 #define HBA_PxINTR_DPS (1 << 5)
 #define HBA_PxINTR_TFEE (1 << 30)
+#define HBA_PxINTR_OFE (1 << 24)
 #define HBA_PxINTR_IFE (1 << 27)
 #define HBA_PxTFD_ERR (1)
 #define HBA_PxTFD_BSY (1 << 7)
@@ -98,6 +99,7 @@ struct hba_cmdt
 #define HBA_DEV_FATAPI (1 << 1)
 
 struct hba_port;
+struct ahci_hba;
 
 struct hba_device
 {
@@ -119,6 +121,7 @@ struct hba_device
     uint32_t block_per_sec;
     uint32_t capabilities;
     struct hba_port* port;
+    struct ahci_hba* hba;
 
     struct
     {
@@ -147,6 +150,7 @@ struct hba_port
     struct hba_cmd_context cmdctx;
     void* fis;
     struct hba_device* device;
+    struct ahci_hba* hba;
 };
 
 struct ahci_hba
index 95d5fb80f0c17d12b1c1028c1977d1a0dbdd4480..21952f2c6a828e22bb2f3e5ac819eafeb4f163a7 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <hal/io.h>
 #include <lunaix/ds/llist.h>
+#include <lunaix/types.h>
 
 #define PCI_CONFIG_ADDR 0xcf8
 #define PCI_CONFIG_DATA 0xcfc
@@ -58,6 +59,9 @@ typedef unsigned int pci_reg_t;
 
 #define BAR_TYPE_MMIO 0x1
 #define BAR_TYPE_CACHABLE 0x2
+#define PCI_DRV_NAME_LEN 32
+
+struct pci_driver;
 
 struct pci_base_addr
 {
@@ -74,9 +78,25 @@ struct pci_device
     uint32_t cspace_base;
     uint32_t msi_loc;
     uint16_t intr_info;
+    struct
+    {
+        struct pci_driver* type;
+        void* instance;
+    } driver;
     struct pci_base_addr bar[6];
 };
 
+typedef void* (*pci_drv_init)(struct pci_device*);
+
+struct pci_driver
+{
+    struct llist_header drivers;
+    u32_t dev_info;
+    u32_t dev_class;
+    pci_drv_init create_driver;
+    char name[PCI_DRV_NAME_LEN];
+};
+
 // PCI Configuration Space (C-Space) r/w:
 //      Refer to "PCI Local Bus Specification, Rev.3, Section 3.2.2.3.2"
 
@@ -144,4 +164,14 @@ pci_bar_sizing(struct pci_device* dev, uint32_t* bar_out, uint32_t bar_num);
 void
 pci_setup_msi(struct pci_device* device, int vector);
 
+void
+pci_add_driver(const char* name,
+               u32_t class,
+               u32_t vendor,
+               u32_t devid,
+               pci_drv_init init);
+
+int
+pci_bind_driver(struct pci_device* pci_dev);
+
 #endif /* __LUNAIX_PCI_H */
index 32ba31dade920716d872361cca6768cf5776127e..afa8146a457143ea703b3baf154ec423dc13a630 100644 (file)
@@ -25,21 +25,21 @@ void
 isrm_init();
 
 void
-isrm_ivfree(uint32_t iv);
+isrm_ivfree(int iv);
 
-uint32_t
+int
 isrm_ivosalloc(isr_cb handler);
 
-uint32_t
+int
 isrm_ivexalloc(isr_cb handler);
 
-uint32_t
-isrm_bindirq(uint32_t irq, isr_cb irq_handler);
+int
+isrm_bindirq(int irq, isr_cb irq_handler);
 
-uint32_t
-isrm_bindiv(uint32_t iv, isr_cb handler);
+int
+isrm_bindiv(int iv, isr_cb handler);
 
 isr_cb
-isrm_get(uint32_t iv);
+isrm_get(int iv);
 
 #endif /* __LUNAIX_ISRM_H */
index 0a26c3be2a7a55a7286d4fae754d4e97b891ebc2..9c18637157d46f2d9aefdb2c2292ffef169f339b 100644 (file)
@@ -25,7 +25,7 @@ isrm_init()
     }
 }
 
-static inline uint32_t
+static inline int
 __ivalloc_within(size_t a, size_t b, isr_cb handler)
 {
     a = (a - IV_BASE) / 8;
@@ -39,27 +39,27 @@ __ivalloc_within(size_t a, size_t b, isr_cb handler)
             j++;
         }
         iv_bmp[i] |= 1 << j;
-        uint32_t iv = IV_BASE + i * 8 + j;
+        int iv = IV_BASE + i * 8 + j;
         handlers[iv] = handler ? handler : intr_routine_fallback;
         return iv;
     }
     return 0;
 }
 
-uint32_t
+int
 isrm_ivosalloc(isr_cb handler)
 {
     return __ivalloc_within(IV_BASE, IV_EX, handler);
 }
 
-uint32_t
+int
 isrm_ivexalloc(isr_cb handler)
 {
     return __ivalloc_within(IV_EX, IV_MAX, handler);
 }
 
 void
-isrm_ivfree(uint32_t iv)
+isrm_ivfree(int iv)
 {
     assert(iv < 256);
     if (iv >= IV_BASE) {
@@ -68,10 +68,10 @@ isrm_ivfree(uint32_t iv)
     handlers[iv] = intr_routine_fallback;
 }
 
-uint32_t
-isrm_bindirq(uint32_t irq, isr_cb irq_handler)
+int
+isrm_bindirq(int irq, isr_cb irq_handler)
 {
-    uint32_t iv;
+    int iv;
     if (!(iv = isrm_ivexalloc(irq_handler))) {
         panickf("out of IV resource. (irq=%d)", irq);
         return 0; // never reach
@@ -83,8 +83,8 @@ isrm_bindirq(uint32_t irq, isr_cb irq_handler)
     return iv;
 }
 
-uint32_t
-isrm_bindiv(uint32_t iv, isr_cb handler)
+int
+isrm_bindiv(int iv, isr_cb handler)
 {
     assert(iv < 256);
     if (iv >= IV_BASE) {
@@ -94,7 +94,7 @@ isrm_bindiv(uint32_t iv, isr_cb handler)
 }
 
 isr_cb
-isrm_get(uint32_t iv)
+isrm_get(int iv)
 {
     assert(iv < 256);
     return handlers[iv];
index 4b5abfd89055024a75bd4f220c808ef9c0b14e33..7045e36731cfc3db8adf5f68d6f099fa2ef244b8 100644 (file)
@@ -5,6 +5,9 @@
 void
 pwait(waitq_t* queue)
 {
+    // prevent race condition.
+    cpu_disable_interrupt();
+
     waitq_t* current_wq = &__current->waitqueue;
     assert(llist_empty(&current_wq->waiters));
 
@@ -12,6 +15,8 @@ pwait(waitq_t* queue)
 
     block_current();
     sched_yieldk();
+
+    cpu_enable_interrupt();
 }
 
 void
@@ -42,6 +47,7 @@ pwake_all(waitq_t* queue)
     {
         proc = container_of(pos, struct proc_info, waitqueue);
 
+        assert(proc->state == PS_BLOCKED);
         proc->state = PS_READY;
         llist_delete(&pos->waiters);
     }
index d1643b42a71c391f545729f75c78e42273bffa36..53027c988e1c3dc50ce37b22ea4b9751c1eeb70a 100644 (file)
@@ -209,4 +209,9 @@ setup_memory(multiboot_memory_map_t* map, size_t map_size)
     for (uintptr_t i = &__usrtext_start; i < &__usrtext_end; i += PG_SIZE) {
         vmm_set_mapping(PD_REFERENCED, i, V2P(i), PG_PREM_UR, VMAP_NULL);
     }
+
+    // reserve higher half
+    for (size_t i = L1_INDEX(KERNEL_MM_BASE); i < 1023; i++) {
+        assert(vmm_set_mapping(PD_REFERENCED, i << 22, 0, 0, VMAP_NOMAP));
+    }
 }
index 54734f3767adf7c7a91027906f5629bf04bc2e58..1e54e59e6d9ea9531470907bd481f5d4f88ec762 100644 (file)
@@ -177,10 +177,11 @@ init_platform()
 
     // peripherals & chipset features
     ps2_kbd_init();
-    pci_init();
     block_init();
     ahci_init();
 
+    pci_init();
+
     // console
     console_start_flushing();
     console_flush();
@@ -195,11 +196,6 @@ init_platform()
         vmm_del_mapping(PD_REFERENCED, (void*)i);
         pmm_free_page(KERNEL_PID, (void*)i);
     }
-
-    // reserve higher half
-    for (size_t i = L1_INDEX(KERNEL_MM_BASE); i < 1023; i++) {
-        vmm_set_mapping(PD_REFERENCED, i << 22, 0, 0, VMAP_NOMAP);
-    }
 }
 
 void
index 91932ca3dd5d7d4aa3ac3c7c9e170b89cc8d2cb2..f0c0a988c97d59c9f30bdff81266ac7cac4aae44 100644 (file)
@@ -47,6 +47,8 @@ sched_init()
     sched_init_dummy();
 }
 
+#define DUMMY_STACK_SIZE 2048
+
 void
 sched_init_dummy()
 {
@@ -54,28 +56,30 @@ sched_init_dummy()
     // It is a living nightmare!
 
     extern void my_dummy();
-    static char dummy_stack[1024] __attribute__((aligned(16)));
+    static char dummy_stack[DUMMY_STACK_SIZE] __attribute__((aligned(16)));
 
     // memset to 0
     dummy_proc = (struct proc_info){};
-    dummy_proc.intr_ctx =
-      (isr_param){ .registers = { .ds = KDATA_SEG,
-                                  .es = KDATA_SEG,
-                                  .fs = KDATA_SEG,
-                                  .gs = KDATA_SEG,
-                                  .esp = (void*)dummy_stack + 1004 },
-                   .cs = KCODE_SEG,
-                   .eip = (void*)my_dummy,
-                   .ss = KDATA_SEG,
-                   .eflags = cpu_reflags() | 0x0200 };
-
-    *(u32_t*)(&dummy_stack[1020]) = dummy_proc.intr_ctx.eflags;
-    *(u32_t*)(&dummy_stack[1016]) = KCODE_SEG;
-    *(u32_t*)(&dummy_stack[1012]) = dummy_proc.intr_ctx.eip;
+    dummy_proc.intr_ctx = (isr_param){
+        .registers = { .ds = KDATA_SEG,
+                       .es = KDATA_SEG,
+                       .fs = KDATA_SEG,
+                       .gs = KDATA_SEG,
+                       .esp = (void*)dummy_stack + DUMMY_STACK_SIZE - 20 },
+        .cs = KCODE_SEG,
+        .eip = (void*)my_dummy,
+        .ss = KDATA_SEG,
+        .eflags = cpu_reflags() | 0x0200
+    };
+
+    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 4]) = dummy_proc.intr_ctx.eflags;
+    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 8]) = KCODE_SEG;
+    *(u32_t*)(&dummy_stack[DUMMY_STACK_SIZE - 12]) = dummy_proc.intr_ctx.eip;
 
     dummy_proc.page_table = cpu_rcr3();
     dummy_proc.state = PS_READY;
     dummy_proc.parent = &dummy_proc;
+    dummy_proc.pid = KERNEL_PID;
 
     __current = &dummy_proc;
 }