Browse Source

Move some of the architecture-specific code into a separate unit.

coderain 5 years ago
parent
commit
fad7052d1e

+ 7 - 7
drivers/acpica/src/osmlxf.c

@@ -100,13 +100,13 @@ ACPI_STATUS AcpiOsReadPort(ACPI_IO_ADDRESS Address, UINT32 *Value, UINT32 Width)
     switch (Width)
     {
     case 8:
-        *Value = inportb(Address);
+        *Value = cpu_read_port_byte(Address);
         break;
     case 16:
-        *Value = inportw(Address);
+        *Value = cpu_read_port_word(Address);
         break;
     case 32:
-        *Value = inportl(Address);
+        *Value = cpu_read_port_dword(Address);
         break;
     default:
         return AE_SUPPORT;
@@ -120,13 +120,13 @@ ACPI_STATUS AcpiOsWritePort(ACPI_IO_ADDRESS Address, UINT32 Value, UINT32 Width)
     switch (Width)
     {
     case 8:
-        outportb(Address, Value);
+        cpu_write_port_byte(Address, Value);
         break;
     case 16:
-        outportw(Address, Value);
+        cpu_write_port_word(Address, Value);
         break;
     case 32:
-        outportl(Address, Value);
+        cpu_write_port_dword(Address, Value);
         break;
     default:
         return AE_SUPPORT;
@@ -325,7 +325,7 @@ dword_t acpica_set_state(power_state_t state)
 
     case POWER_STATE_OFF:
         AcpiEnterSleepStatePrep(ACPI_STATE_S5);
-        disable_ints();
+        cpu_disable_interrupts();
         AcpiEnterSleepState(ACPI_STATE_S5);
         break;
 

+ 15 - 15
drivers/floppy/src/main.c

@@ -75,12 +75,12 @@ static bool_t floppy_fifo_write(byte_t byte)
 
     while (timeout--)
     {
-        byte_t msr = inportb(FLOPPY_MSR);
+        byte_t msr = cpu_read_port_byte(FLOPPY_MSR);
         if (msr & 0x80) break;
         syscall_sleep(1);
     }
 
-    if (timeout != 0) outportb(FLOPPY_FIFO, byte);
+    if (timeout != 0) cpu_write_port_byte(FLOPPY_FIFO, byte);
     else return FALSE;
 
     return TRUE;
@@ -92,12 +92,12 @@ static bool_t floppy_fifo_read(byte_t *byte)
 
     while (timeout--)
     {
-        byte_t msr = inportb(FLOPPY_MSR);
+        byte_t msr = cpu_read_port_byte(FLOPPY_MSR);
         if (msr & 0x80) break;
         syscall_sleep(1);
     }
 
-    if (timeout != 0) *byte = inportb(FLOPPY_FIFO);
+    if (timeout != 0) *byte = cpu_read_port_byte(FLOPPY_FIFO);
     else return FALSE;
 
     return TRUE;
@@ -116,18 +116,18 @@ static word_t floppy_sense_interrupt(void)
 
 static void floppy_select(byte_t drive)
 {
-    byte_t dor = inportb(FLOPPY_DOR);
+    byte_t dor = cpu_read_port_byte(FLOPPY_DOR);
     dor &= 0xFC;
     dor |= drive & 1;
-    outportb(FLOPPY_DOR, dor);
+    cpu_write_port_byte(FLOPPY_DOR, dor);
 }
 
 static void floppy_reset()
 {
     dword_t i;
 
-    outportb(FLOPPY_DOR, 0x00);
-    outportb(FLOPPY_DOR, 0x0C);
+    cpu_write_port_byte(FLOPPY_DOR, 0x00);
+    cpu_write_port_byte(FLOPPY_DOR, 0x0C);
     floppy_wait_irq(NO_TIMEOUT);
 
     for (i = 0; i < 4; i++) floppy_sense_interrupt();
@@ -141,7 +141,7 @@ static void floppy_reset()
     floppy_fifo_write(FLOPPY_SRT << 4 | FLOPPY_HUT);
     floppy_fifo_write(FLOPPY_HLT << 1);
 
-    outportb(FLOPPY_CCR, 0x00);
+    cpu_write_port_byte(FLOPPY_CCR, 0x00);
     floppy_select(0);
 }
 
@@ -161,9 +161,9 @@ static dword_t floppy_motor_thread(void *param)
             }
             else if (floppy_motor_status[i] == FLOPPY_MOTOR_STOPPING)
             {
-                byte_t dor = inportb(FLOPPY_DOR);
+                byte_t dor = cpu_read_port_byte(FLOPPY_DOR);
                 dor &= ~(1 << (4 + i));
-                outportb(FLOPPY_DOR, dor);
+                cpu_write_port_byte(FLOPPY_DOR, dor);
 
                 floppy_motor_status[i] = FLOPPY_MOTOR_STOPPED;
             }
@@ -182,9 +182,9 @@ static void floppy_motor_on(dword_t drive)
 
     if (floppy_motor_status[drive & 1] == FLOPPY_MOTOR_STOPPED)
     {
-        byte_t dor = inportb(FLOPPY_DOR);
+        byte_t dor = cpu_read_port_byte(FLOPPY_DOR);
         dor |= 1 << (4 + (drive & 1));
-        outportb(FLOPPY_DOR, dor);
+        cpu_write_port_byte(FLOPPY_DOR, dor);
 
         syscall_sleep(300);
     }
@@ -228,8 +228,8 @@ static dword_t floppy_init(void)
 {
     init_mutex(&irq_mutex, 0);
 
-    outportb(CMOS_CMD_PORT, CMOS_FLOPPY_REG);
-    byte_t floppy_data = inportb(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_FLOPPY_REG);
+    byte_t floppy_data = cpu_read_port_byte(CMOS_DATA_PORT);
     if (!floppy_data) return ERR_NOTFOUND;
 
     dword_t ret = register_irq_handler(FLOPPY_IRQ, floppy_irq_handler, TRUE);

+ 23 - 23
drivers/ps2/src/main.c

@@ -49,12 +49,12 @@ static inline bool_t poll_and_read(byte_t *byte)
 {
     qword_t end_time = syscall_get_milliseconds() + (qword_t)PS2_TIMEOUT;
 
-    while (!(inportb(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL))
+    while (!(cpu_read_port_byte(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL))
     {
         if (syscall_get_milliseconds() >= end_time) return FALSE;
     }
 
-    *byte = inportb(PS2_DATA_PORT);
+    *byte = cpu_read_port_byte(PS2_DATA_PORT);
     return TRUE;
 }
 
@@ -62,12 +62,12 @@ static inline bool_t poll_and_write(byte_t byte)
 {
     qword_t end_time = syscall_get_milliseconds() + (qword_t)PS2_TIMEOUT;
 
-    while (inportb(PS2_STATUS_PORT) & PS2_INPUT_BUFFER_FULL)
+    while (cpu_read_port_byte(PS2_STATUS_PORT) & PS2_INPUT_BUFFER_FULL)
     {
         if (syscall_get_milliseconds() >= end_time) return FALSE;
     }
 
-    outportb(PS2_DATA_PORT, byte);
+    cpu_write_port_byte(PS2_DATA_PORT, byte);
     return TRUE;
 }
 
@@ -80,16 +80,16 @@ static inline byte_t ps2_send_command(byte_t port, byte_t command, int num_param
 
     while (retries--)
     {
-        inportb(PS2_DATA_PORT);
+        cpu_read_port_byte(PS2_DATA_PORT);
 
-        if (port) outportb(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
+        if (port) cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
         if (!poll_and_write(command)) return PS2_DEVICE_RESPONSE_FAILURE;
 
         va_start(args, num_params);
 
         for (i = 0; i < num_params; i++)
         {
-            if (port) outportb(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
+            if (port) cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
             if (!poll_and_write(va_arg(args, uintptr_t)))
             {
                 va_end(args);
@@ -111,8 +111,8 @@ static void ps2_irq_handler(registers_t *registers, byte_t int_num)
     byte_t port = int_num == PS2_FIRST_IRQ ? 0 : 1;
     release_mutex(&irq_mutex[port]);
 
-    if (!(inportb(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL)) return;
-    byte_t buffer = inportb(PS2_DATA_PORT);
+    if (!(cpu_read_port_byte(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL)) return;
+    byte_t buffer = cpu_read_port_byte(PS2_DATA_PORT);
 
     if (buffer == 0xAA && ps2_devices[port] == NULL)
     {
@@ -238,27 +238,27 @@ static dword_t ps2_init(void)
     byte_t working_ports = 3;
     byte_t buffer;
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_DISABLE_FIRST_PORT);
-    outportb(PS2_CONTROL_PORT, PS2_CMD_DISABLE_SECOND_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_DISABLE_FIRST_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_DISABLE_SECOND_PORT);
 
-    while (inportb(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL) inportb(PS2_DATA_PORT);
+    while (cpu_read_port_byte(PS2_STATUS_PORT) & PS2_OUTPUT_BUFFER_FULL) cpu_read_port_byte(PS2_DATA_PORT);
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_TEST_CONTROLLER);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_TEST_CONTROLLER);
     if (!poll_and_read(&buffer)) return ERR_HARDWARE;
     if (buffer != 0x55) return ERR_HARDWARE;
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_READ_CONFIG);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_READ_CONFIG);
     byte_t config;
     if (!poll_and_read(&config)) return ERR_HARDWARE;
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_WRITE_CONFIG);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_WRITE_CONFIG);
     if (!poll_and_write(1 << 2)) return ERR_HARDWARE;
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_TEST_FIRST_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_TEST_FIRST_PORT);
     if (!poll_and_read(&buffer)) working_ports &= ~(1 << 0);
     if (buffer) working_ports &= ~(1 << 0);
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_TEST_SECOND_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_TEST_SECOND_PORT);
     if (!poll_and_read(&buffer)) working_ports &= ~(1 << 1);
     if (buffer) working_ports &= ~(1 << 1);
     if (!working_ports) return ERR_NOTFOUND;
@@ -280,17 +280,17 @@ static dword_t ps2_init(void)
     }
 
     config |= working_ports;
-    outportb(PS2_CONTROL_PORT, PS2_CMD_WRITE_CONFIG);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_WRITE_CONFIG);
     if (!poll_and_write(config)) return ERR_HARDWARE;
 
-    if (working_ports & (1 << 0)) outportb(PS2_CONTROL_PORT, PS2_CMD_ENABLE_FIRST_PORT);
-    if (working_ports & (1 << 1)) outportb(PS2_CONTROL_PORT, PS2_CMD_ENABLE_SECOND_PORT);
+    if (working_ports & (1 << 0)) cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_ENABLE_FIRST_PORT);
+    if (working_ports & (1 << 1)) cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_ENABLE_SECOND_PORT);
 
     if (working_ports & (1 << 0)) poll_and_write(PS2_DEVICE_CMD_RESET);
 
     if (working_ports & (1 << 1))
     {
-        outportb(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
+        cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_SEND_TO_SECONDARY);
         poll_and_write(PS2_DEVICE_CMD_RESET);
     }
 
@@ -301,8 +301,8 @@ static dword_t ps2_cleanup(void)
 {
     int i;
 
-    outportb(PS2_CONTROL_PORT, PS2_CMD_DISABLE_FIRST_PORT);
-    outportb(PS2_CONTROL_PORT, PS2_CMD_DISABLE_SECOND_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_DISABLE_FIRST_PORT);
+    cpu_write_port_byte(PS2_CONTROL_PORT, PS2_CMD_DISABLE_SECOND_PORT);
 
     unregister_irq_handler(PS2_FIRST_IRQ, &ps2_irq_handler);
     unregister_irq_handler(PS2_SECOND_IRQ, &ps2_irq_handler);

+ 15 - 15
drivers/serial/src/main.c

@@ -49,10 +49,10 @@ static void set_baud_rate(serial_port_t *device, dword_t baud)
     word_t divisor = SERIAL_BAUD_FREQ / baud;
     if (divisor == 0) divisor = 1;
 
-    outportb(device->port + SERIAL_LCR, inportb(device->port + SERIAL_LCR) | SERIAL_DLAB_BIT);
-    outportb(device->port + SERIAL_DLR, divisor & 0xFF);
-    outportb(device->port + SERIAL_DHR, divisor >> 8);
-    outportb(device->port + SERIAL_LCR, inportb(device->port + SERIAL_LCR) & ~SERIAL_DLAB_BIT);
+    cpu_write_port_byte(device->port + SERIAL_LCR, cpu_read_port_byte(device->port + SERIAL_LCR) | SERIAL_DLAB_BIT);
+    cpu_write_port_byte(device->port + SERIAL_DLR, divisor & 0xFF);
+    cpu_write_port_byte(device->port + SERIAL_DHR, divisor >> 8);
+    cpu_write_port_byte(device->port + SERIAL_LCR, cpu_read_port_byte(device->port + SERIAL_LCR) & ~SERIAL_DLAB_BIT);
 }
 
 static void serial_irq_handler(registers_t *regs, byte_t irq_num)
@@ -69,7 +69,7 @@ static void serial_irq_handler(registers_t *regs, byte_t irq_num)
         serial_port_t *device = CONTAINER_OF(get_char_device(name), serial_port_t, header);
         if (!device) continue;
 
-        byte_t status = inportb(device->port + SERIAL_IIR);
+        byte_t status = cpu_read_port_byte(device->port + SERIAL_IIR);
 
         if ((status & 0x07) == 2) release_semaphore(&device->write_mutex, 1);
         else if ((status & 0x07) == 4) release_semaphore(&device->read_mutex, 1);
@@ -107,13 +107,13 @@ static dword_t serial_init(void)
         init_semaphore(&device->write_mutex, 0, 1);
 
         set_baud_rate(device, SERIAL_BAUD_FREQ);
-        outportb(device->port + SERIAL_IER, 0x03);
-        outportb(device->port + SERIAL_FCR,
+        cpu_write_port_byte(device->port + SERIAL_IER, 0x03);
+        cpu_write_port_byte(device->port + SERIAL_FCR,
                  SERIAL_FIFO_ENABLED_BIT
                  | SERIAL_RECV_FIFO_FLUSH_BIT
                  | SERIAL_SEND_FIFO_FLUSH_BIT);
-        outportb(device->port + SERIAL_LCR, 0x03);
-        outportb(device->port + SERIAL_MCR, 0x00);
+        cpu_write_port_byte(device->port + SERIAL_LCR, 0x03);
+        cpu_write_port_byte(device->port + SERIAL_MCR, 0x00);
 
         ret = register_char_device(&device->header);
         if (ret != ERR_SUCCESS) goto cleanup;
@@ -188,7 +188,7 @@ static dword_t serial_read(device_t *device, void *buffer, size_t length, size_t
             break;
         }
 
-        if (!(inportb(serial->port + SERIAL_LSR) & SERIAL_RECV_RDY_BIT))
+        if (!(cpu_read_port_byte(serial->port + SERIAL_LSR) & SERIAL_RECV_RDY_BIT))
         {
             if (wait_semaphore(&serial->read_mutex, 1, (dword_t)-1) == ERR_CANCELED)
             {
@@ -197,7 +197,7 @@ static dword_t serial_read(device_t *device, void *buffer, size_t length, size_t
             }
         }
 
-        ((byte_t*)buffer)[i] = inportb(serial->port + SERIAL_DATA);
+        ((byte_t*)buffer)[i] = cpu_read_port_byte(serial->port + SERIAL_DATA);
     }
 
     return ret;
@@ -218,7 +218,7 @@ static dword_t serial_write(device_t *device, const void *buffer, size_t length,
             break;
         }
 
-        if (!(inportb(serial->port + SERIAL_LSR) & SERIAL_SEND_RDY_BIT))
+        if (!(cpu_read_port_byte(serial->port + SERIAL_LSR) & SERIAL_SEND_RDY_BIT))
         {
             if (wait_semaphore(&serial->write_mutex, 1, (dword_t)-1) == ERR_CANCELED)
             {
@@ -227,7 +227,7 @@ static dword_t serial_write(device_t *device, const void *buffer, size_t length,
             }
         }
 
-        outportb(serial->port + SERIAL_DATA, ((const byte_t*)buffer)[i]);
+        cpu_write_port_byte(serial->port + SERIAL_DATA, ((const byte_t*)buffer)[i]);
     }
 
     return ret;
@@ -242,7 +242,7 @@ static dword_t serial_ioctl(device_t *_device, dword_t control_code, const void
     case IOCTL_CHAR_DEV_CHECK_INPUT:
         if (out_length >= sizeof(size_t))
         {
-            *((size_t*)out_buffer) = (inportb(serial->port + SERIAL_LSR) & SERIAL_RECV_RDY_BIT) ? 1 : 0;
+            *((size_t*)out_buffer) = (cpu_read_port_byte(serial->port + SERIAL_LSR) & SERIAL_RECV_RDY_BIT) ? 1 : 0;
             return ERR_SUCCESS;
         }
         else
@@ -253,7 +253,7 @@ static dword_t serial_ioctl(device_t *_device, dword_t control_code, const void
     case IOCTL_CHAR_DEV_CHECK_OUTPUT:
         if (out_length >= sizeof(size_t))
         {
-            *((size_t*)out_buffer) = (inportb(serial->port + SERIAL_LSR) & SERIAL_SEND_RDY_BIT) ? 1 : 0;
+            *((size_t*)out_buffer) = (cpu_read_port_byte(serial->port + SERIAL_LSR) & SERIAL_SEND_RDY_BIT) ? 1 : 0;
             return ERR_SUCCESS;
         }
         else

+ 5 - 5
drivers/speaker/src/main.c

@@ -44,15 +44,15 @@ static void speaker_on(dword_t frequency)
 {
     dword_t divisor = TIMER_BASE_FREQUENCY / frequency;
 
-    outportb(TIMER_CMD_PORT, TIMER_SQUARE_WAVE(2));
-    outportb(TIMER_CHANNEL_PORT(2), (byte_t) (divisor & 0xFF));
-    outportb(TIMER_CHANNEL_PORT(2), (byte_t) (divisor >> 8));
-    outportb(0x61, inportb(0x61) | 3);
+    cpu_write_port_byte(TIMER_CMD_PORT, TIMER_SQUARE_WAVE(2));
+    cpu_write_port_byte(TIMER_CHANNEL_PORT(2), (byte_t) (divisor & 0xFF));
+    cpu_write_port_byte(TIMER_CHANNEL_PORT(2), (byte_t) (divisor >> 8));
+    cpu_write_port_byte(0x61, cpu_read_port_byte(0x61) | 3);
 }
 
 static void speaker_off()
 {
-    outportb(0x61, inportb(0x61) & 0xFC);
+    cpu_write_port_byte(0x61, cpu_read_port_byte(0x61) & 0xFC);
 }
 
 static dword_t speaker_init(void)

+ 3 - 65
kernel/include/common.h

@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <sdk/defs.h>
+#include <cpu.h>
 
 /* Monolithium-specific Helper Macros */
 #define SEGMENT_RPL(x) ((x) & 0x03)
@@ -43,77 +44,14 @@
 #define DOUBLE_CORNER_RIGHT_DOWN 0xC9
 #define DOUBLE_CORNER_RIGHT_MID  0xCC
 
-#define IO_PORT_FUNCTIONS(s, t) \
-    static inline t inport##s(word_t port) \
-    { \
-        t value; \
-        asm volatile ("in" #s " %1, %0\n" : "=a"(value) : "Nd"(port)); \
-        return value; \
-    } \
-    \
-    static inline void outport##s(word_t port, t value) \
-    { \
-        asm volatile ("out" #s " %0, %1\n" :: "a"(value), "Nd"(port)); \
-    } \
-    \
-    static inline void inportbuf##s(word_t port, t *buffer, size_t size) \
-    { \
-        asm volatile("cld\n" \
-                     "rep; ins" #s "\n" \
-                     :"+D"(buffer), "+c"(size) \
-                     : "d"(port) \
-                     : "cc"); \
-    } \
-    \
-    static inline void outportbuf##s(word_t port, const t *buffer, size_t size) \
-    { \
-        asm volatile("cld\n" \
-                     "rep; outs\n" \
-                     : "+S"(buffer), "+c"(size) \
-                     : "d"(port) \
-                     : "cc"); \
-    }
-
-IO_PORT_FUNCTIONS(b, byte_t)
-IO_PORT_FUNCTIONS(w, word_t)
-IO_PORT_FUNCTIONS(l, dword_t)
-
-static inline bool_t check_ints()
-{
-    dword_t eflags;
-    asm volatile ("pushfl\n"
-                  "popl %0"
-                  : "=g"(eflags));
-    return (eflags & 0x200) != 0 ? TRUE : FALSE;
-}
-
-static inline bool_t enable_ints()
-{
-    bool_t old = check_ints();
-    asm volatile ("sti");
-    return old;
-}
-
-static inline bool_t disable_ints()
-{
-    bool_t old = check_ints();
-    asm volatile ("cli");
-    return old;
-}
-
-static inline void halt()
-{
-    asm volatile ("hlt");
-}
-
 static inline void enable_nmi()
 {
-    outportb(0x70, inportb(0x70) & 0x7F);
+    cpu_write_port_byte(0x70, cpu_read_port_byte(0x70) & 0x7F);
 }
 
 static inline void disable_nmi()
 {
-    outportb(0x70, inportb(0x70) | 0x80);
+    cpu_write_port_byte(0x70, cpu_read_port_byte(0x70) | 0x80);
 }
 
 #endif

+ 238 - 40
kernel/include/cpu.h

@@ -20,47 +20,245 @@
 #ifndef _CPU_H_
 #define _CPU_H_
 
-#include <common.h>
+#include <sdk/defs.h>
 #include <sdk/cpu.h>
 
-#define CPU_FEATURE_FPU   (1 << 0)
-#define CPU_FEATURE_VME   (1 << 1)
-#define CPU_FEATURE_DE    (1 << 2)
-#define CPU_FEATURE_PSE   (1 << 3)
-#define CPU_FEATURE_TSC   (1 << 4)
-#define CPU_FEATURE_MSR   (1 << 5)
-#define CPU_FEATURE_PAE   (1 << 6)
-#define CPU_FEATURE_MCE   (1 << 7)
-#define CPU_FEATURE_CX8   (1 << 8)
-#define CPU_FEATURE_APIC  (1 << 9)
-#define CPU_FEATURE_SEP   (1 << 11)
-#define CPU_FEATURE_MTRR  (1 << 12)
-#define CPU_FEATURE_PGE   (1 << 13)
-#define CPU_FEATURE_MCA   (1 << 14)
-#define CPU_FEATURE_CMOV  (1 << 15)
-#define CPU_FEATURE_PAT   (1 << 16)
-#define CPU_FEATURE_PSE36 (1 << 17)
-#define CPU_FEATURE_PSN   (1 << 18)
-#define CPU_FEATURE_CLFL  (1 << 19)
-#define CPU_FEATURE_DTES  (1 << 21)
-#define CPU_FEATURE_ACPI  (1 << 22)
-#define CPU_FEATURE_MMX   (1 << 23)
-#define CPU_FEATURE_FXSR  (1 << 24)
-#define CPU_FEATURE_SSE   (1 << 25)
-#define CPU_FEATURE_SSE2  (1 << 26)
-#define CPU_FEATURE_SS    (1 << 27)
-#define CPU_FEATURE_HTT   (1 << 28)
-#define CPU_FEATURE_TM1   (1 << 29)
-#define CPU_FEATURE_IA64  (1 << 30)
-#define CPU_FEATURE_PBE   (1 << 31)
-
-extern void cpu_init(void);
-extern void cpu_measure_speed(void);
-extern void fpu_save(byte_t *data);
-extern void fpu_restore(byte_t *data);
-extern void stall(dword_t microseconds);
-
-extern char cpu_vendor[13];
-extern dword_t cpu_features[2];
+#define CPU_CONTROL_FLAG_PE (1 << 0)
+#define CPU_CONTROL_FLAG_MP (1 << 1)
+#define CPU_CONTROL_FLAG_EM (1 << 2)
+#define CPU_CONTROL_FLAG_TS (1 << 3)
+#define CPU_CONTROL_FLAG_ET (1 << 4)
+#define CPU_CONTROL_FLAG_NE (1 << 5)
+#define CPU_CONTROL_FLAG_WP (1 << 16)
+#define CPU_CONTROL_FLAG_AM (1 << 18)
+#define CPU_CONTROL_FLAG_NW (1 << 29)
+#define CPU_CONTROL_FLAG_CD (1 << 30)
+#define CPU_CONTROL_FLAG_PG (1 << 31)
+
+#define CPU_FEATURE_FLAG_VME        (1 << 0)
+#define CPU_FEATURE_FLAG_PVI        (1 << 1)
+#define CPU_FEATURE_FLAG_TSD        (1 << 2)
+#define CPU_FEATURE_FLAG_DE         (1 << 3)
+#define CPU_FEATURE_FLAG_PSE        (1 << 4)
+#define CPU_FEATURE_FLAG_PAE        (1 << 5)
+#define CPU_FEATURE_FLAG_MCE        (1 << 6)
+#define CPU_FEATURE_FLAG_PGE        (1 << 7)
+#define CPU_FEATURE_FLAG_PCE        (1 << 8)
+#define CPU_FEATURE_FLAG_OSXFSR     (1 << 9)
+#define CPU_FEATURE_FLAG_OSXMMEXCPT (1 << 10)
+#define CPU_FEATURE_FLAG_UMIP       (1 << 11)
+#define CPU_FEATURE_FLAG_LA57       (1 << 12)
+#define CPU_FEATURE_FLAG_VMXE       (1 << 13)
+#define CPU_FEATURE_FLAG_SMXE       (1 << 14)
+#define CPU_FEATURE_FLAG_FSGSBASE   (1 << 16)
+#define CPU_FEATURE_FLAG_PCIDE      (1 << 17)
+#define CPU_FEATURE_FLAG_OSXSAVE    (1 << 18)
+#define CPU_FEATURE_FLAG_SMEP       (1 << 20)
+#define CPU_FEATURE_FLAG_SMAP       (1 << 21)
+#define CPU_FEATURE_FLAG_PKE        (1 << 22)
+
+enum
+{
+    FPU_NOT_PRESENT = 0,
+    FPU_LEGACY,
+    FPU_XFSR,
+};
+
+typedef word_t port_t;
+
+#define IO_PORT_FUNCTIONS(type)                                         \
+    static inline type##_t cpu_read_port_##type(port_t port)            \
+    {                                                                   \
+        type##_t value;                                                 \
+        __asm__ volatile ("in %1, %0\n" : "=a"(value) : "Nd"(port));    \
+        return value;                                                   \
+    }                                                                   \
+                                                                        \
+    static inline void cpu_write_port_##type(port_t port, type##_t value) \
+    {                                                                   \
+        __asm__ volatile ("out %0, %1\n" :: "a"(value), "Nd"(port));    \
+    }                                                                   \
+                                                                        \
+    static inline void cpu_read_port_buffer_##type(port_t port, type##_t *buffer, size_t size) \
+    {                                                                   \
+        __asm__ volatile("cld\n"                                        \
+                         "rep; ins\n"                                   \
+                         :"+D"(buffer), "+c"(size)                      \
+                         : "d"(port)                                    \
+                         : "cc");                                       \
+    }                                                                   \
+                                                                        \
+    static inline void cpu_write_port_buffer_##type(port_t port, const type##_t *buffer, size_t size) \
+    {                                                                   \
+        __asm__ volatile("cld\n"                                        \
+                       "rep; outs\n"                                    \
+                       : "+S"(buffer), "+c"(size)                       \
+                       : "d"(port)                                      \
+                       : "cc");                                         \
+    }
+
+IO_PORT_FUNCTIONS(byte)
+IO_PORT_FUNCTIONS(word)
+IO_PORT_FUNCTIONS(dword)
+
+static inline uintptr_t cpu_read_master_control_register(void)
+{
+    uintptr_t value;
+    __asm__ volatile ("movl %%cr0, %0"
+                      : "=r"((dword_t)value) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return value;
+}
+
+static inline void cpu_write_master_control_register(uintptr_t value)
+{
+    __asm__ volatile ("movl %0, %%cr0"
+                      : /* output */
+                      : "r"((dword_t)value) /* input */
+                      : /* clobber */);
+}
+
+static inline uintptr_t cpu_read_faulting_address(void)
+{
+    uintptr_t value;
+    __asm__ volatile ("movl %%cr2, %0"
+                      : "=r"((dword_t)value) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return value;
+}
+
+static inline uintptr_t cpu_read_page_table_register(void)
+{
+     uintptr_t value;
+    __asm__ volatile ("movl %%cr3, %0"
+                      : "=r"((dword_t)value) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return value;
+}
+
+static inline void cpu_write_page_table_register(uintptr_t value)
+{
+    __asm__ volatile ("movl %0, %%cr3"
+                      : /* output */
+                      : "r"((dword_t)value) /* input */
+                      : /* clobber */);
+}
+
+static inline uintptr_t cpu_read_feature_register(void)
+{
+    uintptr_t value;
+    __asm__ volatile ("movl %%cr4, %0"
+                      : "=r"((dword_t)value) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return value;
+}
+
+static inline void cpu_write_feature_register(uintptr_t value)
+{
+    __asm__ volatile ("movl %0, %%cr4"
+                      : /* output */
+                      : "r"((dword_t)value) /* input */
+                      : /* clobber */);
+}
+
+static inline bool_t cpu_enable_interrupts(void)
+{
+    dword_t flags;
+    __asm__ volatile ("pushf\n"
+                      "sti\n"
+                      "pop %0"
+                      : "=g"(flags) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return !!(flags & CPU_STATUS_FLAG_IF);
+}
+
+static inline bool_t cpu_disable_interrupts(void)
+{
+    dword_t flags;
+    __asm__ volatile ("pushf\n"
+                      "cli\n"
+                      "pop %0"
+                      : "=g"(flags) /* output */
+                      : /* input */
+                      : /* clobber */);
+    return !!(flags & CPU_STATUS_FLAG_IF);
+}
+
+static inline void cpu_set_interrupt_table(void *base, word_t size)
+{
+    struct
+    {
+        word_t length;
+        void *base;
+    } __attribute__((__packed__)) idtr = { size - 1, base };
+
+    __asm__ volatile ("lidt %0"
+                      : /* output */
+                      : "m"(idtr) /* input */
+                      : /* clobber */);
+}
+
+static inline void cpu_invalidate_tlb(void *address)
+{
+    __asm__ volatile ("invlpg (%0)"
+                      : /* output */
+                      : "r"(address) /* input */
+                      : "memory" /* clobber */);
+}
+
+static inline void cpu_halt(void)
+{
+    __asm__ volatile ("hlt");
+}
+
+extern int cpu_fpu_present;
+extern byte_t cpu_max_physical_bits;
+
+static inline void cpu_save_fpu_state(void *state)
+{
+    switch (cpu_fpu_present)
+    {
+    case FPU_LEGACY:
+        asm volatile ("fsave %0"
+                      : "=m"(*(byte_t*)state) /* output */
+                      : /* input */
+                      : /* clobber */);
+        break;
+
+    case FPU_XFSR:
+        asm volatile ("fxsave %0"
+                      : "=m"(*(byte_t*)state) /* output */
+                      : /* input */
+                      : /* clobber */);
+        break;
+    }
+}
+
+static inline void cpu_restore_fpu_state(void *state)
+{
+    switch (cpu_fpu_present)
+    {
+    case FPU_LEGACY:
+        asm volatile ("frstor %0"
+                      : /* output */
+                      : "m"(*(byte_t*)state) /* input */
+                      : /* clobber */);
+        break;
+
+    case FPU_XFSR:
+        asm volatile ("fxrstor %0"
+                      : /* output */
+                      : "m"(*(byte_t*)state) /* input */
+                      : /* clobber */);
+        break;
+    }
+}
+
+void cpu_init(void);
 
 #endif

+ 2 - 23
kernel/include/vm86.h

@@ -23,28 +23,7 @@
 #include <common.h>
 #include <thread.h>
 #include <interrupt.h>
-
-#define EFLAGS_VM (1<<17)
-#define EFLAGS_IF (1<<9)
-#define EFLAGS_DF (1<<10)
-#define PREFIX_LOCK (1<<0)
-#define PREFIX_OPSIZE (1<<1)
-#define PREFIX_ADDRSIZE (1<<2)
-#define PREFIX_REP (1<<3)
-#define PREFIX_REPNZ (1<<4)
-#define PREFIX_ES (1<<5)
-#define PREFIX_SS (1<<6)
-#define PREFIX_FS (1<<7)
-#define PREFIX_GS (1<<8)
-
-#define VM86_MEM_START 0x10000
-#define VM86_MEM_END 0x90000
-#define VM86_MEM_PARAGRAPHS ((VM86_MEM_END - VM86_MEM_START) >> 4)
-
-#define VM86_TRAMPOLINE_CS 0x0000
-#define VM86_TRAMPOLINE_IP 0xE000
-#define VM86_TRAMPOLINE_SS 0x0000
-#define VM86_TRAMPOLINE_SP 0xDFFA
+#include <cpu.h>
 
 typedef struct
 {
@@ -52,9 +31,9 @@ typedef struct
     dword_t eip, cs, eflags, esp, ss, es, ds, fs, gs;
 } vm86_registers_t;
 
+void vm86_handler(registers_ext_vm86_t *regs);
 word_t vm86_alloc(word_t size);
 void vm86_free(word_t paragraph);
-void vm86_handler(registers_ext_vm86_t *regs);
 dword_t vm86_interrupt(byte_t number, vm86_registers_t *regs);
 
 #endif

+ 32 - 32
kernel/src/clock.c

@@ -30,18 +30,18 @@ void clock_irq(registers_t *regs, byte_t irq_num)
 {
     bool_t pm = FALSE;
 
-    outportb(CMOS_CMD_PORT, CMOS_RTC_SECONDS_REG);
-    byte_t seconds = inportb(CMOS_DATA_PORT);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_MINUTES_REG);
-    byte_t minutes = inportb(CMOS_DATA_PORT);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_HOURS_REG);
-    byte_t hours = inportb(CMOS_DATA_PORT);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_DAY_REG);
-    byte_t day = inportb(CMOS_DATA_PORT);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_MONTH_REG);
-    byte_t month = inportb(CMOS_DATA_PORT);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_YEAR_REG);
-    byte_t year = inportb(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_SECONDS_REG);
+    byte_t seconds = cpu_read_port_byte(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_MINUTES_REG);
+    byte_t minutes = cpu_read_port_byte(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_HOURS_REG);
+    byte_t hours = cpu_read_port_byte(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_DAY_REG);
+    byte_t day = cpu_read_port_byte(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_MONTH_REG);
+    byte_t month = cpu_read_port_byte(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_YEAR_REG);
+    byte_t year = cpu_read_port_byte(CMOS_DATA_PORT);
 
     if (hours & CLOCK_PM_BIT) pm = TRUE;
     hours &= ~CLOCK_PM_BIT;
@@ -69,8 +69,8 @@ void clock_irq(registers_t *regs, byte_t irq_num)
     clock_current_time.month = month;
     clock_current_time.year = year;
 
-    outportb(CMOS_CMD_PORT, CMOS_RTC_STC_REG);
-    inportb(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_STC_REG);
+    cpu_read_port_byte(CMOS_DATA_PORT);
 }
 
 bool_t clock_check_time(clock_time_t *time)
@@ -163,18 +163,18 @@ sysret_t syscall_clock_set_time(clock_time_t *time)
     clock_current_time.year = safe_time.year;
 
     disable_nmi();
-    outportb(CMOS_CMD_PORT, CMOS_RTC_SECONDS_REG);
-    outportb(CMOS_DATA_PORT, seconds);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_MINUTES_REG);
-    outportb(CMOS_DATA_PORT, minutes);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_HOURS_REG);
-    outportb(CMOS_DATA_PORT, hours);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_DAY_REG);
-    outportb(CMOS_DATA_PORT, day);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_MONTH_REG);
-    outportb(CMOS_DATA_PORT, month);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_YEAR_REG);
-    outportb(CMOS_DATA_PORT, year);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_SECONDS_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, seconds);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_MINUTES_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, minutes);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_HOURS_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, hours);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_DAY_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, day);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_MONTH_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, month);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_YEAR_REG);
+    cpu_write_port_byte(CMOS_DATA_PORT, year);
     enable_nmi();
 
     leave_critical(&critical);
@@ -186,8 +186,8 @@ void clock_init()
     critical_t critical;
 
     enter_critical(&critical);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_STB_REG);
-    clock_settings = inportb(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_STB_REG);
+    clock_settings = cpu_read_port_byte(CMOS_DATA_PORT);
 
     if ((clock_settings & (CLOCK_ALARM_INT | CLOCK_PERIODIC_INT | CLOCK_UPDATE_INT)) != CLOCK_UPDATE_INT)
     {
@@ -195,13 +195,13 @@ void clock_init()
         clock_settings |= CLOCK_UPDATE_INT;
 
         disable_nmi();
-        outportb(CMOS_CMD_PORT, CMOS_RTC_STB_REG);
-        outportb(CMOS_DATA_PORT, clock_settings);
+        cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_STB_REG);
+        cpu_write_port_byte(CMOS_DATA_PORT, clock_settings);
         enable_nmi();
     }
 
     register_irq_handler(CLOCK_IRQ, &clock_irq, FALSE);
-    outportb(CMOS_CMD_PORT, CMOS_RTC_STC_REG);
-    inportb(CMOS_DATA_PORT);
+    cpu_write_port_byte(CMOS_CMD_PORT, CMOS_RTC_STC_REG);
+    cpu_read_port_byte(CMOS_DATA_PORT);
     leave_critical(&critical);
 }

+ 0 - 153
kernel/src/cpu.asm

@@ -1,153 +0,0 @@
-;
-; cpu.asm
-;
-; Copyright (C) 2016 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
-;
-; This program is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Affero General Public License as
-; published by the Free Software Foundation, either version 3 of the
-; License, or (at your option) any later version.
-;
-; This program is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-; GNU Affero General Public License for more details.
-;
-; You should have received a copy of the GNU Affero General Public License
-; along with this program.  If not, see <http://www.gnu.org/licenses/>.
-;
-
-CPU_FEATURE_FPU         EQU 1 << 0
-CPU_FEATURE_VME         EQU 1 << 1
-CPU_FEATURE_DE          EQU 1 << 2
-CPU_FEATURE_PSE         EQU 1 << 3
-CPU_FEATURE_TSC         EQU 1 << 4
-CPU_FEATURE_MSR         EQU 1 << 5
-CPU_FEATURE_PAE         EQU 1 << 6
-CPU_FEATURE_MCE         EQU 1 << 7
-CPU_FEATURE_CX8         EQU 1 << 8
-CPU_FEATURE_APIC        EQU 1 << 9
-CPU_FEATURE_SEP         EQU 1 << 11
-CPU_FEATURE_MTRR        EQU 1 << 12
-CPU_FEATURE_PGE         EQU 1 << 13
-CPU_FEATURE_MCA         EQU 1 << 14
-CPU_FEATURE_CMOV        EQU 1 << 15
-CPU_FEATURE_PAT         EQU 1 << 16
-CPU_FEATURE_PSE36       EQU 1 << 17
-CPU_FEATURE_PSN         EQU 1 << 18
-CPU_FEATURE_CLFL        EQU 1 << 19
-CPU_FEATURE_DTES        EQU 1 << 21
-CPU_FEATURE_ACPI        EQU 1 << 22
-CPU_FEATURE_MMX         EQU 1 << 23
-CPU_FEATURE_FXSR        EQU 1 << 24
-CPU_FEATURE_SSE         EQU 1 << 25
-CPU_FEATURE_SSE2        EQU 1 << 26
-CPU_FEATURE_SS          EQU 1 << 27
-CPU_FEATURE_HTT         EQU 1 << 28
-CPU_FEATURE_TM1         EQU 1 << 29
-CPU_FEATURE_IA64        EQU 1 << 30
-CPU_FEATURE_PBE         EQU 1 << 31
-
-bits 32
-
-global cpu_init
-global fpu_save
-global fpu_restore
-global cpu_vendor
-global cpu_features
-
-cpu_vendor:   times 16  DB 0
-cpu_features: times 2   DD 0
-
-;********************************************************************************
-; void cpu_init(void)
-;********************************************************************************
-cpu_init:               push ebp
-                        mov ebp, esp
-                        sub esp, 4
-.fpu_check:             mov eax, cr0
-                        and eax, 0xFFFFFFF3
-                        or eax, 0x20
-                        mov cr0, eax
-                        fninit
-                        mov word [ebp - 4], 0xCCCC
-                        fnstsw word [ebp - 4]
-                        cmp word [ebp - 4], 0
-                        jnz .cpuid_check
-                        or byte [cpu_features], 1
-.cpuid_check:           pushfd
-                        pop eax
-                        xor eax, 0x200000
-                        push eax
-                        popfd
-                        pushfd
-                        pop edx
-                        cmp eax, edx
-                        jnz .no_cpuid
-                        xor eax, eax
-                        push ebx
-                        cpuid
-                        mov dword [cpu_vendor], ebx
-                        mov dword [cpu_vendor + 4], edx
-                        mov dword [cpu_vendor + 8], ecx
-                        mov eax, 1
-                        cpuid
-                        mov dword [cpu_features], edx
-                        mov dword [cpu_features + 4], ecx
-                        pop ebx
-.no_cpuid:              leave
-                        ret
-
-;********************************************************************************
-; void fpu_save(byte_t *buffer)
-;********************************************************************************
-fpu_save:               push ebp
-                        mov ebp, esp
-                        sub esp, 512 + 16
-                        push esi
-                        push edi
-                        lea esi, [ebp - 512]
-                        and esi, 0xFFFFFFF0
-                        mov edi, [ebp + 8]
-                        test dword [cpu_features], CPU_FEATURE_FXSR
-                        jz .no_fxr
-                        fxsave [esi]
-                        mov ecx, 128
-                        jmp .copy
-.no_fxr:                fsave [esi]
-                        mov ecx, 27
-.copy:                  cld
-                        rep movsd
-                        pop edi
-                        pop esi
-                        xor eax, eax
-                        leave
-                        ret
-
-;********************************************************************************
-; void fpu_restore(byte_t *buffer)
-;********************************************************************************
-fpu_restore:            push ebp
-                        mov ebp, esp
-                        sub esp, 512 + 16
-                        push esi
-                        push edi
-                        mov esi, [ebp + 8]
-                        lea edi, [ebp - 512]
-                        and edi, 0xFFFFFFF0
-                        mov eax, edi
-                        cld
-                        test dword [cpu_features], CPU_FEATURE_FXSR
-                        jz .no_fxr
-                        mov ecx, 128
-                        rep movsd
-                        fxrstor [eax]
-                        jmp .done
-.no_fxr:                mov ecx, 27
-                        rep movsd
-                        frstor [eax]
-.done:                  pop edi
-                        pop esi
-                        xor eax, eax
-                        leave
-                        ret

+ 164 - 0
kernel/src/cpu.c

@@ -0,0 +1,164 @@
+/*
+ * cpu.c
+ *
+ * Copyright (C) 2018 Aleksandar Andrejevic <theflash@sdf.lonestar.org>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cpu.h>
+#include <cpuid.h>
+
+#define CPUID_GET_FEATURE_FLAGS    0x00000001
+#define CPUID_GET_MISC_INFORMATION 0x80000008
+
+#define CPUID_FEATURE_FLAG_ECX_SSE3    (1 << 0)
+#define CPUID_FEATURE_FLAG_ECX_PCLMUL  (1 << 1)
+#define CPUID_FEATURE_FLAG_ECX_DTES64  (1 << 2)
+#define CPUID_FEATURE_FLAG_ECX_MON     (1 << 3)
+#define CPUID_FEATURE_FLAG_ECX_DSCPL   (1 << 4)
+#define CPUID_FEATURE_FLAG_ECX_VMX     (1 << 5)
+#define CPUID_FEATURE_FLAG_ECX_SMX     (1 << 6)
+#define CPUID_FEATURE_FLAG_ECX_EST     (1 << 7)
+#define CPUID_FEATURE_FLAG_ECX_TM2     (1 << 8)
+#define CPUID_FEATURE_FLAG_ECX_SSSE3   (1 << 9)
+#define CPUID_FEATURE_FLAG_ECX_CID     (1 << 10)
+#define CPUID_FEATURE_FLAG_ECX_SDBG    (1 << 11)
+#define CPUID_FEATURE_FLAG_ECX_FMA     (1 << 12)
+#define CPUID_FEATURE_FLAG_ECX_CX16    (1 << 13)
+#define CPUID_FEATURE_FLAG_ECX_ETPRD   (1 << 14)
+#define CPUID_FEATURE_FLAG_ECX_PDCM    (1 << 15)
+#define CPUID_FEATURE_FLAG_ECX_PCID    (1 << 17)
+#define CPUID_FEATURE_FLAG_ECX_DCA     (1 << 18)
+#define CPUID_FEATURE_FLAG_ECX_SSE41   (1 << 19)
+#define CPUID_FEATURE_FLAG_ECX_SSE42   (1 << 20)
+#define CPUID_FEATURE_FLAG_ECX_X2APIC  (1 << 21)
+#define CPUID_FEATURE_FLAG_ECX_MOVBE   (1 << 22)
+#define CPUID_FEATURE_FLAG_ECX_POPCNT  (1 << 23)
+#define CPUID_FEATURE_FLAG_ECX_TSCD    (1 << 24)
+#define CPUID_FEATURE_FLAG_ECX_AES     (1 << 25)
+#define CPUID_FEATURE_FLAG_ECX_XSAVE   (1 << 26)
+#define CPUID_FEATURE_FLAG_ECX_OSXSAVE (1 << 27)
+#define CPUID_FEATURE_FLAG_ECX_AVX     (1 << 28)
+#define CPUID_FEATURE_FLAG_ECX_F16C    (1 << 29)
+#define CPUID_FEATURE_FLAG_ECX_RDRAND  (1 << 30)
+#define CPUID_FEATURE_FLAG_ECX_HV      (1 << 31)
+
+#define CPUID_FEATURE_FLAG_EDX_FPU   (1 << 0)
+#define CPUID_FEATURE_FLAG_EDX_VME   (1 << 1)
+#define CPUID_FEATURE_FLAG_EDX_DE    (1 << 2)
+#define CPUID_FEATURE_FLAG_EDX_PSE   (1 << 3)
+#define CPUID_FEATURE_FLAG_EDX_TSC   (1 << 4)
+#define CPUID_FEATURE_FLAG_EDX_MSR   (1 << 5)
+#define CPUID_FEATURE_FLAG_EDX_PAE   (1 << 6)
+#define CPUID_FEATURE_FLAG_EDX_MCE   (1 << 7)
+#define CPUID_FEATURE_FLAG_EDX_CX8   (1 << 8)
+#define CPUID_FEATURE_FLAG_EDX_APIC  (1 << 9)
+#define CPUID_FEATURE_FLAG_EDX_SEP   (1 << 11)
+#define CPUID_FEATURE_FLAG_EDX_MTRR  (1 << 12)
+#define CPUID_FEATURE_FLAG_EDX_PGE   (1 << 13)
+#define CPUID_FEATURE_FLAG_EDX_MCA   (1 << 14)
+#define CPUID_FEATURE_FLAG_EDX_CMOV  (1 << 15)
+#define CPUID_FEATURE_FLAG_EDX_PAT   (1 << 16)
+#define CPUID_FEATURE_FLAG_EDX_PSE36 (1 << 17)
+#define CPUID_FEATURE_FLAG_EDX_PSN   (1 << 18)
+#define CPUID_FEATURE_FLAG_EDX_CLFL  (1 << 19)
+#define CPUID_FEATURE_FLAG_EDX_DTES  (1 << 21)
+#define CPUID_FEATURE_FLAG_EDX_ACPI  (1 << 22)
+#define CPUID_FEATURE_FLAG_EDX_MMX   (1 << 23)
+#define CPUID_FEATURE_FLAG_EDX_FXSR  (1 << 24)
+#define CPUID_FEATURE_FLAG_EDX_SSE   (1 << 25)
+#define CPUID_FEATURE_FLAG_EDX_SSE2  (1 << 26)
+#define CPUID_FEATURE_FLAG_EDX_SS    (1 << 27)
+#define CPUID_FEATURE_FLAG_EDX_HTT   (1 << 28)
+#define CPUID_FEATURE_FLAG_EDX_TM1   (1 << 29)
+#define CPUID_FEATURE_FLAG_EDX_IA64  (1 << 30)
+#define CPUID_FEATURE_FLAG_EDX_PBE   (1 << 31)
+
+int cpu_fpu_present = FPU_NOT_PRESENT;
+byte_t cpu_max_physical_bits = 32;
+
+static void fpu_init(void)
+{
+    cpu_write_master_control_register(cpu_read_master_control_register() & ~(CPU_CONTROL_FLAG_EM | CPU_CONTROL_FLAG_TS));
+    __asm__ volatile ("fninit");
+}
+
+static void fpu_probe(void)
+{
+    word_t fpu_status = 0xCCCC;
+    __asm__ volatile ("fnstsw %0"
+                        : "=m" (fpu_status) /* output */
+                        : /* input */
+                        : /* clobber */);
+
+    if (fpu_status == 0)
+    {
+        cpu_fpu_present = FPU_LEGACY;
+    }
+    else
+    {
+        cpu_fpu_present = FPU_NOT_PRESENT;
+        cpu_write_master_control_register(cpu_read_master_control_register() | CPU_CONTROL_FLAG_EM);
+    }
+}
+
+void cpu_init(void)
+{
+    unsigned int features[5], address_size_info, cpu_count_info, dummy;
+
+    if (!__get_cpuid(CPUID_GET_FEATURE_FLAGS, &features[0], &features[1], &features[2], &features[3]))
+    {
+        fpu_init();
+        fpu_probe();
+        return;
+    }
+
+    if (features[3] & CPUID_FEATURE_FLAG_EDX_FPU)
+    {
+        fpu_init();
+
+        if (features[3] & CPUID_FEATURE_FLAG_EDX_FXSR)
+        {
+            cpu_write_feature_register(cpu_read_feature_register() | CPU_FEATURE_FLAG_OSXFSR);
+            cpu_fpu_present = FPU_XFSR;
+        }
+        else
+        {
+            cpu_fpu_present = FPU_LEGACY;
+        }
+    }
+
+    if (features[3] & CPUID_FEATURE_FLAG_EDX_PGE)
+    {
+        cpu_write_feature_register(cpu_read_feature_register() | CPU_FEATURE_FLAG_PGE);
+    }
+
+    if (features[3] & CPUID_FEATURE_FLAG_EDX_PSE)
+    {
+        cpu_write_feature_register(cpu_read_feature_register() | CPU_FEATURE_FLAG_PSE);
+    }
+
+    if ((features[3] & CPUID_FEATURE_FLAG_EDX_PAE) || (features[3] & CPUID_FEATURE_FLAG_EDX_PSE36))
+    {
+        /* Don't enable PAE here, it might be disabled on the user's request */
+        cpu_max_physical_bits = 36;
+    }
+
+    if (__get_cpuid(CPUID_GET_MISC_INFORMATION, &address_size_info, &features[4], &cpu_count_info, &dummy))
+    {
+        byte_t physical_bits = address_size_info & 0xFF;
+        if (physical_bits > 36) cpu_max_physical_bits = physical_bits;
+    }
+}

+ 6 - 10
kernel/src/crash.c

@@ -56,7 +56,7 @@ void __attribute__((noreturn)) kernel_crash(const char *message, registers_t *re
 {
     int i;
     word_t *video_mem = (word_t*)(video_initialized ? VIDEO_MEMORY : TEXT_VIDEO_MEMORY);
-    disable_ints();
+    cpu_disable_interrupts();
 
     uintptr_t call_stack[MAX_BACKTRACE];
     int call_count = 0;
@@ -187,14 +187,10 @@ void __attribute__((noreturn)) kernel_crash(const char *message, registers_t *re
 
         log_write(LOG_CRITICAL, ")\n");
 
-        dword_t cr0, cr2, cr3;
-        asm volatile ("movl %%cr0, %0" : "=r"(cr0) ::);
-        asm volatile ("movl %%cr2, %0" : "=r"(cr2) ::);
-        asm volatile ("movl %%cr3, %0" : "=r"(cr3) ::);
-
-        log_write(LOG_CRITICAL, "CR0: 0x%08X\n", cr0);
-        log_write(LOG_CRITICAL, "CR2: 0x%08X\n", cr2);
-        log_write(LOG_CRITICAL, "CR3: 0x%08X\n", cr3);
+        log_write(LOG_CRITICAL, "CR0: 0x%08X\n", cpu_read_master_control_register());
+        log_write(LOG_CRITICAL, "CR2: 0x%08X\n", cpu_read_faulting_address());
+        log_write(LOG_CRITICAL, "CR3: 0x%08X\n", cpu_read_page_table_register());
+        log_write(LOG_CRITICAL, "CR4: 0x%08X\n", cpu_read_feature_register());
     }
     else
     {
@@ -224,6 +220,6 @@ void __attribute__((noreturn)) kernel_crash(const char *message, registers_t *re
         log_write(LOG_CRITICAL, "\n");
     }
 
-    halt();
+    cpu_halt();
     for(;;);
 }

+ 4 - 4
kernel/src/exception.c

@@ -59,7 +59,7 @@ static void raise_exception_internal(thread_t *thread, processor_mode_t mode, ex
         }
         else
         {
-            if (current) enable_ints();
+            if (current) cpu_enable_interrupts();
             terminate_thread_internal(thread, 1);
             ASSERT(!current);
         }
@@ -113,7 +113,7 @@ static void exception_handler(registers_t *regs, byte_t int_num)
         break;
 
     case CPU_EXCEPTION_NM:
-        if (cpu_features[0] & CPU_FEATURE_FPU)
+        if (cpu_fpu_present)
         {
             thread_lazy_fpu();
             return;
@@ -130,7 +130,7 @@ static void exception_handler(registers_t *regs, byte_t int_num)
         return;
 
     case CPU_EXCEPTION_GP:
-        if (regs->eflags & EFLAGS_VM)
+        if (regs->eflags & CPU_STATUS_FLAG_VM)
         {
             vm86_handler((registers_ext_vm86_t*)regs);
             return;
@@ -144,7 +144,7 @@ static void exception_handler(registers_t *regs, byte_t int_num)
         break;
 
     case CPU_EXCEPTION_PF:
-        asm volatile ("movl %%cr2, %0" : "=r"(faulting_address) ::);
+        faulting_address = (void*)cpu_read_faulting_address();
         if (memory_fault_handler(faulting_address, regs)) return;
 
         info.number = EXCEPTION_MEMORY_ACCESS;

+ 5 - 12
kernel/src/interrupt.c

@@ -21,19 +21,12 @@
 #include <segments.h>
 #include <lock.h>
 #include <thread.h>
+#include <cpu.h>
 
 static byte_t isr_stubs[IDT_NUM_INTERRUPTS * ISR_STUB_SIZE];
 static idt_entry_t idt[IDT_NUM_INTERRUPTS];
 static interrupt_handler_t handlers[IDT_NUM_INTERRUPTS];
 
-static inline void lidt(dword_t base, dword_t size)
-{
-    volatile dword_t idtr[2];
-    idtr[0] = size << 16;
-    idtr[1] = base;
-    asm volatile ("lidt (%0)" :: "r"((byte_t*)idtr + 2));
-}
-
 static void idt_main_handler(byte_t interrupt_num, registers_t regs)
 {
     regs.esp += 16;
@@ -47,7 +40,7 @@ static void idt_main_handler(byte_t interrupt_num, registers_t regs)
         thread->in_kernel++;
     }
 
-    if (handlers[interrupt_num].interrupts) enable_ints();
+    if (handlers[interrupt_num].interrupts) cpu_enable_interrupts();
     handlers[interrupt_num].procedure(&regs, interrupt_num);
 
     if (thread)
@@ -59,7 +52,7 @@ static void idt_main_handler(byte_t interrupt_num, registers_t regs)
 
             if (thread->terminated || (thread->frozen > 0))
             {
-                enable_ints();
+                cpu_enable_interrupts();
                 syscall_yield_quantum();
             }
 
@@ -67,7 +60,7 @@ static void idt_main_handler(byte_t interrupt_num, registers_t regs)
         }
     }
 
-    disable_ints();
+    cpu_disable_interrupts();
 }
 
 dword_t set_int_handler(byte_t interrupt_num, isr_proc_t proc, bool_t interrupts, bool_t usermode)
@@ -207,5 +200,5 @@ void interrupt_init(void)
         isr_stubs[offset++] = 0xCF; // iret
     }
 
-    lidt((dword_t)&idt, sizeof(idt));
+    cpu_set_interrupt_table(idt, sizeof(idt));
 }

+ 22 - 21
kernel/src/irq.c

@@ -20,6 +20,7 @@
 #include <irq.h>
 #include <heap.h>
 #include <lock.h>
+#include <cpu.h>
 
 static list_entry_t irq_handlers[MAX_IRQ_COUNT];
 static dword_t irq_alloc_bitmap = 0xFFFFF3FF;
@@ -32,20 +33,20 @@ static void irq_handler(registers_t *regs, byte_t int_num)
 
     if (irq_num == 7)
     {
-        outportb(PRIMARY_PIC_CMD, 0x0B);
+        cpu_write_port_byte(PRIMARY_PIC_CMD, 0x0B);
 
-        byte_t isr = inportb(PRIMARY_PIC_CMD);
+        byte_t isr = cpu_read_port_byte(PRIMARY_PIC_CMD);
         if (!(isr & 0x80)) return;
     }
 
     if (irq_num == 15)
     {
-        outportb(SECONDARY_PIC_CMD, 0x0B);
+        cpu_write_port_byte(SECONDARY_PIC_CMD, 0x0B);
 
-        byte_t isr = inportb(SECONDARY_PIC_CMD);
+        byte_t isr = cpu_read_port_byte(SECONDARY_PIC_CMD);
         if (!(isr & 0x80))
         {
-            outportb(PRIMARY_PIC_CMD, 0x20);
+            cpu_write_port_byte(PRIMARY_PIC_CMD, 0x20);
             return;
         }
     }
@@ -55,13 +56,13 @@ static void irq_handler(registers_t *regs, byte_t int_num)
     {
         handler = CONTAINER_OF(ptr, irq_handler_t, list);
 
-        enable_ints();
+        cpu_enable_interrupts();
         handler->procedure(regs, irq_num);
-        disable_ints();
+        cpu_disable_interrupts();
     }
 
-    if (irq_num >= 8) outportb(SECONDARY_PIC_CMD, 0x20);
-    outportb(PRIMARY_PIC_CMD, 0x20);
+    if (irq_num >= 8) cpu_write_port_byte(SECONDARY_PIC_CMD, 0x20);
+    cpu_write_port_byte(PRIMARY_PIC_CMD, 0x20);
 }
 
 dword_t register_irq_handler(byte_t irq_num, irq_handler_proc_t handler_proc, bool_t exclusive)
@@ -82,12 +83,12 @@ dword_t register_irq_handler(byte_t irq_num, irq_handler_proc_t handler_proc, bo
         if (irq_num >= 0 && irq_num < 8)
         {
             primary_pic_mask &= ~(1 << irq_num);
-            outportb(PRIMARY_PIC_DATA, primary_pic_mask);
+            cpu_write_port_byte(PRIMARY_PIC_DATA, primary_pic_mask);
         }
         else
         {
             secondary_pic_mask &= ~(1 << (irq_num - 8));
-            outportb(SECONDARY_PIC_DATA, secondary_pic_mask);
+            cpu_write_port_byte(SECONDARY_PIC_DATA, secondary_pic_mask);
         }
     }
     else if (exclusive || CONTAINER_OF(irq_handlers[irq_num].next, irq_handler_t, list)->exclusive)
@@ -150,16 +151,16 @@ void irq_init()
     byte_t i;
 
     primary_pic_mask &= ~(1 << PRIMARY_PIC_CASCADE_IRQ);
-    outportb(PRIMARY_PIC_CMD, 0x11);
-    outportb(SECONDARY_PIC_CMD, 0x11);
-    outportb(PRIMARY_PIC_DATA, PRIMARY_IRQ_INT);
-    outportb(SECONDARY_PIC_DATA, SECONDARY_IRQ_INT);
-    outportb(PRIMARY_PIC_DATA, 1 << PRIMARY_PIC_CASCADE_IRQ);
-    outportb(SECONDARY_PIC_DATA, 1 << SECONDARY_PIC_CASCADE_IRQ);
-    outportb(PRIMARY_PIC_DATA, PIC_8086_MODE);
-    outportb(SECONDARY_PIC_DATA, PIC_8086_MODE);
-    outportb(PRIMARY_PIC_DATA, primary_pic_mask);
-    outportb(SECONDARY_PIC_DATA, secondary_pic_mask);
+    cpu_write_port_byte(PRIMARY_PIC_CMD, 0x11);
+    cpu_write_port_byte(SECONDARY_PIC_CMD, 0x11);
+    cpu_write_port_byte(PRIMARY_PIC_DATA, PRIMARY_IRQ_INT);
+    cpu_write_port_byte(SECONDARY_PIC_DATA, SECONDARY_IRQ_INT);
+    cpu_write_port_byte(PRIMARY_PIC_DATA, 1 << PRIMARY_PIC_CASCADE_IRQ);
+    cpu_write_port_byte(SECONDARY_PIC_DATA, 1 << SECONDARY_PIC_CASCADE_IRQ);
+    cpu_write_port_byte(PRIMARY_PIC_DATA, PIC_8086_MODE);
+    cpu_write_port_byte(SECONDARY_PIC_DATA, PIC_8086_MODE);
+    cpu_write_port_byte(PRIMARY_PIC_DATA, primary_pic_mask);
+    cpu_write_port_byte(SECONDARY_PIC_DATA, secondary_pic_mask);
 
     for (i = 0; i < MAX_IRQ_COUNT; i++)
     {

+ 20 - 20
kernel/src/isa_dma.c

@@ -48,20 +48,20 @@ void isa_dma_read(dword_t channel, void *buffer, word_t count)
     else count--;
 
     lock_acquire(&dma_lock);
-    outportb(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
+    cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
 
-    outportb(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    outportb(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
-    outportb(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
-    outportb(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
 
-    outportb(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    outportb(ISA_DMA_CNT(channel), count & 0xFF);
-    outportb(ISA_DMA_CNT(channel), count >> 8);
+    cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
+    cpu_write_port_byte(ISA_DMA_CNT(channel), count & 0xFF);
+    cpu_write_port_byte(ISA_DMA_CNT(channel), count >> 8);
 
-    outportb(ISA_DMA_MODE_REG(channel), 0x48 | (channel & 3));
+    cpu_write_port_byte(ISA_DMA_MODE_REG(channel), 0x48 | (channel & 3));
 
-    outportb(ISA_DMA_SINGLE_MASK_REG(channel), (channel & 3));
+    cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), (channel & 3));
     lock_release(&dma_lock);
 }
 
@@ -72,19 +72,19 @@ void isa_dma_write(dword_t channel, void *buffer, dword_t count)
     else count--;
 
     lock_acquire(&dma_lock);
-    outportb(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
+    cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), ISA_DMA_MASK_ON | (channel & 3));
 
-    outportb(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    outportb(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
-    outportb(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
-    outportb(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), (dword_t)buffer & 0xFF);
+    cpu_write_port_byte(ISA_DMA_SAR(channel), ((dword_t)buffer >> 8) & 0xFF);
+    cpu_write_port_byte(ISA_DMA_PAR(channel), ((dword_t)buffer >> 16) & 0xFF);
 
-    outportb(ISA_DMA_FF_RESET_REG(channel), 0xFF);
-    outportb(ISA_DMA_CNT(channel), count & 0xFF);
-    outportb(ISA_DMA_CNT(channel), count >> 8);
+    cpu_write_port_byte(ISA_DMA_FF_RESET_REG(channel), 0xFF);
+    cpu_write_port_byte(ISA_DMA_CNT(channel), count & 0xFF);
+    cpu_write_port_byte(ISA_DMA_CNT(channel), count >> 8);
 
-    outportb(ISA_DMA_MODE_REG(channel), 0x44 | (channel & 3));
+    cpu_write_port_byte(ISA_DMA_MODE_REG(channel), 0x44 | (channel & 3));
 
-    outportb(ISA_DMA_SINGLE_MASK_REG(channel), (channel & 3));
+    cpu_write_port_byte(ISA_DMA_SINGLE_MASK_REG(channel), (channel & 3));
     lock_release(&dma_lock);
 }

+ 3 - 4
kernel/src/lock.c

@@ -19,6 +19,7 @@
 
 #include <thread.h>
 #include <lock.h>
+#include <cpu.h>
 
 #define NO_HOLDER ((uintptr_t)0)
 #define MULTIPLE_HOLDERS ((uintptr_t)-1)
@@ -28,17 +29,15 @@
 void enter_critical(critical_t *critical)
 {
     *critical = 0;
-    if (disable_ints()) *critical |= (1 << 0);
+    if (cpu_disable_interrupts()) *critical |= (1 << 0);
     if (scheduler_enabled) *critical |= (1 << 1);
-
-    disable_ints();
     scheduler_enabled = FALSE;
 }
 
 void leave_critical(critical_t *critical)
 {
     if (*critical & (1 << 1)) scheduler_enabled = TRUE;
-    if (*critical & (1 << 0)) enable_ints();
+    if (*critical & (1 << 0)) cpu_enable_interrupts();
 }
 
 void lock_acquire(lock_t *lock)

+ 21 - 35
kernel/src/memory/memory.c

@@ -45,11 +45,6 @@ static DECLARE_LOCK(page_store_lock);
 
 static void *evict_page(void);
 
-static inline void invalidate_tlb(dword_t *addr)
-{
-    asm volatile ("invlpg %0" :: "m"(*addr));
-}
-
 static inline void *alloc_physical_page(void)
 {
     void *page = INVALID_PAGE;
@@ -136,7 +131,7 @@ static dword_t map_page(void *physical, void *virtual, dword_t flags)
         reference_page(table_page);
         page_directory[pd_index] = (dword_t)table_page | PAGE_PRESENT | PAGE_WRITABLE;
 
-        invalidate_tlb(page_table);
+        cpu_invalidate_tlb(page_table);
         for (i = 0; i < PAGE_SIZE / sizeof(dword_t); i++) page_table[i] = 0;
     }
 
@@ -149,7 +144,7 @@ static dword_t map_page(void *physical, void *virtual, dword_t flags)
 
     reference_page((void*)phys_addr);
     page_table[pt_index] = phys_addr | flags | PAGE_PRESENT;
-    invalidate_tlb(virtual);
+    cpu_invalidate_tlb(virtual);
 
 done:
     leave_critical(&critical);
@@ -182,7 +177,7 @@ static dword_t unmap_page(void *virtual)
 
     dereference_page((void*)PAGE_ALIGN(page_table[pt_index]));
     page_table[pt_index] = 0;
-    invalidate_tlb((dword_t*)virt_addr);
+    cpu_invalidate_tlb((dword_t*)virt_addr);
 
     for (i = 0; i < PAGE_SIZE / sizeof(dword_t); i++) if (page_table[i])
     {
@@ -194,7 +189,7 @@ static dword_t unmap_page(void *virtual)
     {
         void *table_page = (void*)PAGE_ALIGN(page_directory[pd_index]);
         page_directory[pd_index] = 0;
-        invalidate_tlb(page_table);
+        cpu_invalidate_tlb(page_table);
 
         if (dereference_page(table_page) == 0)
         {
@@ -246,7 +241,7 @@ static dword_t set_page_flags(void *virtual, dword_t flags)
 
     page_directory[pd_index] |= flags;
     page_table[pt_index] = PAGE_ALIGN(page_table[pt_index]) | flags | PAGE_PRESENT;
-    invalidate_tlb((void*)virt_addr);
+    cpu_invalidate_tlb((void*)virt_addr);
 
 done:
     leave_critical(&critical);
@@ -448,7 +443,7 @@ next:
     }
 
     table[pt_index] = 0;
-    if (space->page_directory == get_page_directory()) invalidate_tlb((void*)address);
+    if (space->page_directory == get_page_directory()) cpu_invalidate_tlb((void*)address);
 
 cleanup:
     if (table) unmap_temporary_page(table);
@@ -824,9 +819,7 @@ void *get_page_directory(void)
 void set_page_directory(void *phys_addr)
 {
     current_page_directory = phys_addr;
-
-    asm volatile ("mov %0, %%eax\n\
-                   mov %%eax, %%cr3" :: "r"(phys_addr));
+    cpu_write_page_table_register((uintptr_t)phys_addr);
 }
 
 void *get_physical_address(void *virtual)
@@ -2264,7 +2257,7 @@ dword_t clone_address_space(memory_address_space_t *original, memory_address_spa
         reference_page((void*)PAGE_ALIGN(original_dir[i]));
         original_dir[i] &= ~PAGE_WRITABLE;
         clone_dir[i] = original_dir[i];
-        if (this_directory) invalidate_tlb((void*)(i << 12));
+        if (this_directory) cpu_invalidate_tlb((void*)(i << 12));
     }
 
     if (!this_directory) unmap_temporary_page(original_dir);
@@ -2391,9 +2384,9 @@ bool_t memory_fault_handler(void *address, registers_t *regs)
 
             if (entry->number != INVALID_STORE_NUMBER)
             {
-                enable_ints();
+                cpu_enable_interrupts();
                 dword_t ret = syscall_read_file(store->file_handle, buffer, (qword_t)entry->number * (qword_t)PAGE_SIZE, PAGE_SIZE, &bytes_read);
-                disable_ints();
+                cpu_disable_interrupts();
 
                 if ((page_directory[pd_index] & PAGE_PRESENT) && (page_table[pt_index] & PAGE_PRESENT))
                 {
@@ -2473,12 +2466,12 @@ bool_t memory_fault_handler(void *address, registers_t *regs)
 
             if (block->section && block->section->file && offset < (qword_t)block->section->size)
             {
-                enable_ints();
+                cpu_enable_interrupts();
                 file_instance_t *file = block->section->file;
                 lock_acquire_shared(&file->global->volume->lock);
                 dword_t ret = file->global->volume->driver->read_file(file, buffer, offset, PAGE_SIZE, &bytes_read);
                 lock_release(&file->global->volume->lock);
-                disable_ints();
+                cpu_disable_interrupts();
                 if (ret != ERR_SUCCESS && ret != ERR_BEYOND) return FALSE;
             }
 
@@ -2545,17 +2538,17 @@ bool_t memory_fault_handler(void *address, registers_t *regs)
                 page_directory[pd_index] = PAGE_ALIGN((dword_t)table_copy)
                                            | PAGE_OFFSET(page_directory[pd_index])
                                            | PAGE_WRITABLE;
-                invalidate_tlb(page_table);
+                cpu_invalidate_tlb(page_table);
             }
             else
             {
                 page_directory[pd_index] |= PAGE_WRITABLE;
-                invalidate_tlb(page_table);
+                cpu_invalidate_tlb(page_table);
 
                 for (i = 0; i < PAGE_SIZE / sizeof(dword_t); i++)
                 {
                     page_table[i] &= ~PAGE_WRITABLE;
-                    invalidate_tlb((void*)((pd_index << 22) | (i << 12)));
+                    cpu_invalidate_tlb((void*)((pd_index << 22) | (i << 12)));
                 }
             }
         }
@@ -2576,12 +2569,12 @@ bool_t memory_fault_handler(void *address, registers_t *regs)
                 page_table[pt_index] = PAGE_ALIGN((dword_t)page_copy)
                                        | PAGE_OFFSET(page_table[pt_index])
                                        | PAGE_WRITABLE;
-                invalidate_tlb((void*)aligned_address);
+                cpu_invalidate_tlb((void*)aligned_address);
             }
             else
             {
                 page_table[pt_index] |= PAGE_WRITABLE;
-                invalidate_tlb((void*)aligned_address);
+                cpu_invalidate_tlb((void*)aligned_address);
             }
         }
 
@@ -2637,7 +2630,7 @@ void memory_init(multiboot_tag_mmap_t *mmap, uintptr_t lowest_physical)
                 {
                     page_directory[pd_index] = start_addr | PAGE_PRESENT | PAGE_WRITABLE | PAGE_GLOBAL;
                     start_addr += PAGE_SIZE;
-                    invalidate_tlb(page_table);
+                    cpu_invalidate_tlb(page_table);
                     memset(page_table, 0, PAGE_SIZE);
                     total_physical_pages++;
                     continue;
@@ -2647,7 +2640,7 @@ void memory_init(multiboot_tag_mmap_t *mmap, uintptr_t lowest_physical)
                 {
                     page_table[pt_index] = start_addr | PAGE_PRESENT | PAGE_WRITABLE | PAGE_GLOBAL;
                     start_addr += PAGE_SIZE;
-                    invalidate_tlb((void*)stack_address);
+                    cpu_invalidate_tlb((void*)stack_address);
                     total_physical_pages++;
                     continue;
                 }
@@ -2671,14 +2664,14 @@ void memory_init(multiboot_tag_mmap_t *mmap, uintptr_t lowest_physical)
         if (!(page_directory[pd_index] & PAGE_PRESENT))
         {
             page_directory[pd_index] = (uintptr_t)alloc_physical_page() | PAGE_PRESENT | PAGE_WRITABLE | PAGE_GLOBAL;
-            invalidate_tlb(page_table);
+            cpu_invalidate_tlb(page_table);
             memset(page_table, 0, PAGE_SIZE);
         }
 
         if (!(page_table[pt_index] & PAGE_PRESENT))
         {
             page_table[pt_index] = (uintptr_t)alloc_physical_page() | PAGE_PRESENT | PAGE_WRITABLE | PAGE_GLOBAL;
-            invalidate_tlb((void*)i);
+            cpu_invalidate_tlb((void*)i);
         }
     }
 
@@ -2743,11 +2736,4 @@ void memory_init(multiboot_tag_mmap_t *mmap, uintptr_t lowest_physical)
 
     for (i = USER_PAGE_START; i <= USER_PAGE_END; i++) page_directory[i] = 0;
     set_page_directory(get_page_directory());
-
-    if (cpu_features[0] & CPU_FEATURE_PGE)
-    {
-        asm volatile ("movl %cr4, %eax\n"
-                      "orl $0x80, %eax\n"
-                      "movl %eax, %cr4\n");
-    }
 }

+ 4 - 4
kernel/src/pci.c

@@ -54,24 +54,24 @@ static inline bool_t pci_device_exists(dword_t bus, dword_t slot, dword_t func)
 
 dword_t pci_read(pci_device_t *device, dword_t reg)
 {
-    outportl(0x0CF8,
+    cpu_write_port_dword(0x0CF8,
              0x80000000
              | ((device->bus & 0xFF) << 16)
              | ((device->slot & 0x1F) << 11)
              | ((device->function & 0x07) << 8)
              | ((reg & 0x3F) << 2));
-    return inportl(0x0CFC);
+    return cpu_read_port_dword(0x0CFC);
 }
 
 void pci_write(pci_device_t *device, dword_t reg, dword_t data)
 {
-    outportl(0x0CF8,
+    cpu_write_port_dword(0x0CF8,
              0x80000000
              | ((device->bus & 0xFF) << 16)
              | ((device->slot & 0x1F) << 11)
              | ((device->function & 0x07) << 8)
              | ((reg & 0x3F) << 2));
-    outportl(0x0CFC, data);
+    cpu_write_port_dword(0x0CFC, data);
 }
 
 list_entry_t *get_pci_device_list_head(void)

+ 7 - 6
kernel/src/power.c

@@ -20,6 +20,7 @@
 #include <power.h>
 #include <syscalls.h>
 #include <user.h>
+#include <cpu.h>
 
 static power_callbacks_t *power_callbacks = NULL;
 
@@ -43,15 +44,15 @@ sysret_t syscall_power_control(power_command_t command)
         if (power_callbacks) power_callbacks->set_state(POWER_STATE_OFF);
 
     case POWER_COMMAND_HALT:
-        disable_ints();
-        halt();
+        cpu_disable_interrupts();
+        cpu_halt();
         break;
 
     case POWER_COMMAND_REBOOT:
-        disable_ints();
-        while (inportb(0x64) & 0x02) continue;
-        outportb(0x64, 0xFE);
-        halt();
+        cpu_disable_interrupts();
+        while (cpu_read_port_byte(0x64) & 0x02) continue;
+        cpu_write_port_byte(0x64, 0xFE);
+        cpu_halt();
         break;
 
     default:

+ 1 - 1
kernel/src/process.c

@@ -339,7 +339,7 @@ sysret_t syscall_create_process(const char *path, dword_t flags, process_params_
     else
     {
         initial_state.regs = *get_current_thread()->last_context;
-        fpu_save(initial_state.fpu_state);
+        cpu_save_fpu_state(initial_state.fpu_state);
         initial_state.regs.eax = CLONE_MAGIC;
     }
 

+ 2 - 2
kernel/src/start.c

@@ -90,7 +90,7 @@ static dword_t __attribute__((__noreturn__)) system_idle_thread(void *param)
     while (TRUE)
     {
         syscall_yield_quantum();
-        halt();
+        cpu_halt();
     }
 }
 
@@ -103,7 +103,7 @@ static void pre_initialization(void)
     irq_init();
     exceptions_init();
     object_init();
-    enable_ints();
+    cpu_enable_interrupts();
 }
 
 static void scan_multiboot_info(multiboot_tag_t *mboot)

+ 4 - 4
kernel/src/thread.c

@@ -241,8 +241,8 @@ thread_t *get_current_thread()
 
 void thread_lazy_fpu(void)
 {
-    if (last_fpu_thread) fpu_save(last_fpu_thread->state.fpu_state);
-    fpu_restore(current_thread->state.fpu_state);
+    if (last_fpu_thread) cpu_save_fpu_state(last_fpu_thread->state.fpu_state);
+    cpu_restore_fpu_state(current_thread->state.fpu_state);
     last_fpu_thread = current_thread;
     asm volatile ("clts");
 }
@@ -586,7 +586,7 @@ sysret_t syscall_query_thread(handle_t handle, thread_info_t info_type, void *bu
                 else
                 {
                     ((thread_state_t*)safe_buffer)->regs = *thread->last_context;
-                    fpu_save(((thread_state_t*)safe_buffer)->fpu_state);
+                    cpu_save_fpu_state(((thread_state_t*)safe_buffer)->fpu_state);
                 }
             }
             else
@@ -702,7 +702,7 @@ sysret_t syscall_set_thread(handle_t handle, thread_info_t info_type, const void
             }
             else
             {
-                fpu_restore(new_state->fpu_state);
+                cpu_restore_fpu_state(new_state->fpu_state);
             }
 
             if (current_thread->tid != thread->tid) leave_critical(&critical);

+ 6 - 6
kernel/src/timer.c

@@ -45,9 +45,9 @@ sysret_t syscall_get_nanoseconds(void)
 
     qword_t result = total_ticks * 1000000ULL;
 
-    outportb(TIMER_CMD_PORT, 0x00);
-    word_t count = inportb(TIMER_CHANNEL_PORT(0));
-    count |= inportb(TIMER_CHANNEL_PORT(0)) << 8;
+    cpu_write_port_byte(TIMER_CMD_PORT, 0x00);
+    word_t count = cpu_read_port_byte(TIMER_CHANNEL_PORT(0));
+    count |= cpu_read_port_byte(TIMER_CHANNEL_PORT(0)) << 8;
     count = -count;
 
     result += (count * 1000ULL) / (qword_t)TIMER_BASE_FREQUENCY;
@@ -65,8 +65,8 @@ void timer_init(void)
     if (value == 0) value = 1;
     if (value >= 65536) value = 0;
 
-    outportb(TIMER_CMD_PORT, TIMER_RATE_GENERATOR(0));
-    outportb(TIMER_CHANNEL_PORT(0), value & 0xFF);
-    outportb(TIMER_CHANNEL_PORT(0), (value >> 8) & 0xFF);
+    cpu_write_port_byte(TIMER_CMD_PORT, TIMER_RATE_GENERATOR(0));
+    cpu_write_port_byte(TIMER_CHANNEL_PORT(0), value & 0xFF);
+    cpu_write_port_byte(TIMER_CHANNEL_PORT(0), (value >> 8) & 0xFF);
     register_irq_handler(TIMER_IRQ, &timer_irq, FALSE);
 }

+ 4 - 4
kernel/src/video.c

@@ -343,10 +343,10 @@ dword_t video_default_control(video_device_t *device,
             video_cursor_location_t *location = (video_cursor_location_t*)in_buffer;
             word_t index = location->row * TEXT_WIDTH + location->column;
 
-            outportb(VGA_CRTC_INDEX, 0x0F);
-            outportb(VGA_CRTC_DATA, (byte_t) (index & 0xFF));
-            outportb(VGA_CRTC_INDEX, 0x0E);
-            outportb(VGA_CRTC_DATA, (byte_t) ((index >> 8) & 0xFF));
+            cpu_write_port_byte(VGA_CRTC_INDEX, 0x0F);
+            cpu_write_port_byte(VGA_CRTC_DATA, (byte_t) (index & 0xFF));
+            cpu_write_port_byte(VGA_CRTC_INDEX, 0x0E);
+            cpu_write_port_byte(VGA_CRTC_DATA, (byte_t) ((index >> 8) & 0xFF));
         }
         else
         {

+ 54 - 35
kernel/src/vm86.c

@@ -24,6 +24,25 @@
 #include <thread.h>
 #include <memory.h>
 
+#define PREFIX_LOCK     (1 << 0)
+#define PREFIX_OPSIZE   (1 << 1)
+#define PREFIX_ADDRSIZE (1 << 2)
+#define PREFIX_REP      (1 << 3)
+#define PREFIX_REPNZ    (1 << 4)
+#define PREFIX_ES       (1 << 5)
+#define PREFIX_SS       (1 << 6)
+#define PREFIX_FS       (1 << 7)
+#define PREFIX_GS       (1 << 8)
+
+#define VM86_MEM_START      0x10000
+#define VM86_MEM_END        0x90000
+#define VM86_MEM_PARAGRAPHS ((VM86_MEM_END - VM86_MEM_START) >> 4)
+
+#define VM86_TRAMPOLINE_CS 0x0000
+#define VM86_TRAMPOLINE_IP 0xE000
+#define VM86_TRAMPOLINE_SS 0x0000
+#define VM86_TRAMPOLINE_SP 0xDFFA
+
 extern void vm86_start(vm86_registers_t input_regs, vm86_registers_t *output_regs);
 
 static bool_t vm86_interrupts = TRUE;
@@ -150,8 +169,8 @@ void vm86_handler(registers_ext_vm86_t *regs)
         {
             for (i = 0; i < count; i++)
             {
-                pokeb(regs->es, regs->edi, inportb(regs->edx));
-                if (!(regs->eflags & EFLAGS_DF)) regs->edi++;
+                pokeb(regs->es, regs->edi, cpu_read_port_byte(regs->edx));
+                if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi++;
                 else regs->edi--;
             }
 
@@ -164,16 +183,16 @@ void vm86_handler(registers_ext_vm86_t *regs)
             {
                 if (!(prefix & PREFIX_OPSIZE))
                 {
-                    pokew(regs->es, regs->edi, inportw(regs->edx));
+                    pokew(regs->es, regs->edi, cpu_read_port_word(regs->edx));
 
-                    if (!(regs->eflags & EFLAGS_DF)) regs->edi += 2;
+                    if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi += 2;
                     else regs->edi -= 2;
                 }
                 else
                 {
-                    pokel(regs->es, regs->edi, inportl(regs->edx));
+                    pokel(regs->es, regs->edi, cpu_read_port_dword(regs->edx));
 
-                    if (!(regs->eflags & EFLAGS_DF)) regs->edi += 4;
+                    if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->edi += 4;
                     else regs->edi -= 4;
                 }
             }
@@ -185,9 +204,9 @@ void vm86_handler(registers_ext_vm86_t *regs)
         {
             for (i = 0; i < count; i++)
             {
-                outportb(regs->edx, peekb(segment, regs->esi));
+                cpu_write_port_byte(regs->edx, peekb(segment, regs->esi));
 
-                if (!(regs->eflags & EFLAGS_DF)) regs->esi++;
+                if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi++;
                 else regs->esi--;
             }
 
@@ -200,16 +219,16 @@ void vm86_handler(registers_ext_vm86_t *regs)
             {
                 if (!(prefix & PREFIX_OPSIZE))
                 {
-                    outportw(regs->edx, peekw(segment, regs->esi));
+                    cpu_write_port_word(regs->edx, peekw(segment, regs->esi));
 
-                    if (!(regs->eflags & EFLAGS_DF)) regs->esi += 2;
+                    if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi += 2;
                     else regs->esi -= 2;
                 }
                 else
                 {
-                    outportl(regs->edx, peekl(segment, regs->esi));
+                    cpu_write_port_dword(regs->edx, peekl(segment, regs->esi));
 
-                    if (!(regs->eflags & EFLAGS_DF)) regs->esi += 4;
+                    if (!(regs->eflags & CPU_STATUS_FLAG_DF)) regs->esi += 4;
                     else regs->esi -= 4;
                 }
             }
@@ -220,10 +239,10 @@ void vm86_handler(registers_ext_vm86_t *regs)
         case 0x9C: // pushf
         {
             operand = regs->eflags;
-            operand &= ~EFLAGS_VM;
+            operand &= ~CPU_STATUS_FLAG_VM;
 
-            if (vm86_interrupts) operand |= EFLAGS_IF;
-            else operand &= ~EFLAGS_IF;
+            if (vm86_interrupts) operand |= CPU_STATUS_FLAG_IF;
+            else operand &= ~CPU_STATUS_FLAG_IF;
 
             if (!(prefix & PREFIX_OPSIZE))
             {
@@ -244,17 +263,17 @@ void vm86_handler(registers_ext_vm86_t *regs)
             if (!(prefix & PREFIX_OPSIZE))
             {
                 regs->eflags &= 0xFFFF0000;
-                regs->eflags |= peekw(regs->ss, regs->esp3) | EFLAGS_VM;
+                regs->eflags |= peekw(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
                 regs->esp3 += 2;
             }
             else
             {
-                regs->eflags = peekl(regs->ss, regs->esp3) | EFLAGS_VM;
+                regs->eflags = peekl(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
                 regs->esp3 += 4;
             }
 
-            vm86_interrupts = (regs->eflags & EFLAGS_IF) ? TRUE : FALSE;
-            regs->eflags |= EFLAGS_IF;
+            vm86_interrupts = (regs->eflags & CPU_STATUS_FLAG_IF) ? TRUE : FALSE;
+            regs->eflags |= CPU_STATUS_FLAG_IF;
 
             break;
         }
@@ -265,7 +284,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
             regs->eip++;
 
             regs->esp3 -= 2;
-            pokew(regs->ss, regs->esp3, (regs->eflags & (~EFLAGS_VM)) | (vm86_interrupts ? EFLAGS_IF : 0));
+            pokew(regs->ss, regs->esp3, (regs->eflags & (~CPU_STATUS_FLAG_VM)) | (vm86_interrupts ? CPU_STATUS_FLAG_IF : 0));
 
             regs->esp3 -= 2;
             pokew(regs->ss, regs->esp3, regs->cs);
@@ -318,11 +337,11 @@ void vm86_handler(registers_ext_vm86_t *regs)
             regs->cs = peekw(regs->ss, regs->esp3);
             regs->esp3 += 2;
 
-            regs->eflags = peekw(regs->ss, regs->esp3) | EFLAGS_VM;
+            regs->eflags = peekw(regs->ss, regs->esp3) | CPU_STATUS_FLAG_VM;
             regs->esp3 += 2;
 
-            vm86_interrupts = (regs->eflags & EFLAGS_IF) ? TRUE : FALSE;
-            regs->eflags |= EFLAGS_IF;
+            vm86_interrupts = (regs->eflags & CPU_STATUS_FLAG_IF) ? TRUE : FALSE;
+            regs->eflags |= CPU_STATUS_FLAG_IF;
 
             break;
         }
@@ -332,7 +351,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
             operand = peekb(regs->cs, regs->eip);
             regs->eip++;
             regs->eax &= 0xFFFFFF00;
-            regs->eax |= inportb(operand & 0xFF) & 0xFF;
+            regs->eax |= cpu_read_port_byte(operand & 0xFF) & 0xFF;
 
             break;
         }
@@ -345,9 +364,9 @@ void vm86_handler(registers_ext_vm86_t *regs)
             if (!(prefix & PREFIX_OPSIZE))
             {
                 regs->eax &= 0xFFFF0000;
-                regs->eax |= inportw(operand & 0xFF) & 0xFFFF;
+                regs->eax |= cpu_read_port_word(operand & 0xFF) & 0xFFFF;
             }
-            else regs->eax = inportl(operand & 0xFF);
+            else regs->eax = cpu_read_port_dword(operand & 0xFF);
 
             break;
         }
@@ -356,7 +375,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
         {
             operand = peekb(regs->cs, regs->eip);
             regs->eip++;
-            outportb(operand & 0xFF, regs->eax & 0xFF);
+            cpu_write_port_byte(operand & 0xFF, regs->eax & 0xFF);
 
             break;
         }
@@ -366,8 +385,8 @@ void vm86_handler(registers_ext_vm86_t *regs)
             operand = peekb(regs->cs, regs->eip);
             regs->eip++;
 
-            if (!(prefix & PREFIX_OPSIZE)) outportw(operand & 0xFF, regs->eax & 0xFFFF);
-            else outportl(operand & 0xFF, regs->eax);
+            if (!(prefix & PREFIX_OPSIZE)) cpu_write_port_word(operand & 0xFF, regs->eax & 0xFFFF);
+            else cpu_write_port_dword(operand & 0xFF, regs->eax);
 
             break;
         }
@@ -375,7 +394,7 @@ void vm86_handler(registers_ext_vm86_t *regs)
         case 0xEC: // in al, dx
         {
             regs->eax &= 0xFFFFFF00;
-            regs->eax |= inportb(regs->edx & 0xFFFF) & 0xFF;
+            regs->eax |= cpu_read_port_byte(regs->edx & 0xFFFF) & 0xFF;
 
             break;
         }
@@ -385,23 +404,23 @@ void vm86_handler(registers_ext_vm86_t *regs)
             if (!(prefix & PREFIX_OPSIZE))
             {
                 regs->eax &= 0xFFFF0000;
-                regs->eax |= inportw(regs->edx & 0xFFFF) & 0xFFFF;
+                regs->eax |= cpu_read_port_word(regs->edx & 0xFFFF) & 0xFFFF;
             }
-            else regs->eax = inportl(regs->edx & 0xFFFF);
+            else regs->eax = cpu_read_port_dword(regs->edx & 0xFFFF);
 
             break;
         }
 
         case 0xEE: // out dx, al
         {
-            outportb(regs->edx & 0xFFFF, regs->eax & 0xFF);
+            cpu_write_port_byte(regs->edx & 0xFFFF, regs->eax & 0xFF);
             break;
         }
 
         case 0xEF: // out dx, (e)ax
         {
-            if (!(prefix & PREFIX_OPSIZE)) outportw(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
-            else outportl(regs->edx & 0xFFFF, regs->eax);
+            if (!(prefix & PREFIX_OPSIZE)) cpu_write_port_word(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
+            else cpu_write_port_dword(regs->edx & 0xFFFF, regs->eax);
 
             break;
         }

+ 19 - 0
sdk/cpu.h

@@ -20,6 +20,25 @@
 #ifndef __MONOLITHIUM_CPU_H__
 #define __MONOLITHIUM_CPU_H__
 
+#define CPU_MAX_FPU_DATA_SIZE 512
+
+#define CPU_STATUS_FLAG_CF  (1 << 0)
+#define CPU_STATUS_FLAG_PF  (1 << 2)
+#define CPU_STATUS_FLAG_AF  (1 << 4)
+#define CPU_STATUS_FLAG_ZF  (1 << 6)
+#define CPU_STATUS_FLAG_SF  (1 << 7)
+#define CPU_STATUS_FLAG_TF  (1 << 8)
+#define CPU_STATUS_FLAG_IF  (1 << 9)
+#define CPU_STATUS_FLAG_DF  (1 << 10)
+#define CPU_STATUS_FLAG_OF  (1 << 11)
+#define CPU_STATUS_FLAG_NT  (1 << 14)
+#define CPU_STATUS_FLAG_RF  (1 << 16)
+#define CPU_STATUS_FLAG_VM  (1 << 17)
+#define CPU_STATUS_FLAG_AC  (1 << 18)
+#define CPU_STATUS_FLAG_VIF (1 << 19)
+#define CPU_STATUS_FLAG_VIP (1 << 20)
+#define CPU_STATUS_FLAG_ID  (1 << 21)
+
 typedef struct
 {
     dword_t data_selector;

+ 1 - 0
sdk/thread.h

@@ -23,6 +23,7 @@
 #define THREAD_CREATE_FROZEN (1 << 0)
 
 #include "defs.h"
+#include "cpu.h"
 
 typedef dword_t (*thread_procedure_t)(void*);