diff --git a/kernel/x86-family/x86-family.cpp b/kernel/x86-family/x86-family.cpp index 7b40a89e..893d98aa 100644 --- a/kernel/x86-family/x86-family.cpp +++ b/kernel/x86-family/x86-family.cpp @@ -22,87 +22,90 @@ *******************************************************************************/ +#include + #include -namespace Sortix +namespace Sortix { +namespace CPU { + +void OutPortB(uint16_t port, uint8_t value) { - namespace CPU - { - void OutPortB(uint16_t Port, uint8_t Value) - { - asm volatile ("outb %1, %0" : : "dN" (Port), "a" (Value)); - } - - void OutPortW(uint16_t Port, uint16_t Value) - { - asm volatile ("outw %1, %0" : : "dN" (Port), "a" (Value)); - } - - void OutPortL(uint16_t Port, uint32_t Value) - { - asm volatile ("outl %1, %0" : : "dN" (Port), "a" (Value)); - } - - uint8_t InPortB(uint16_t Port) - { - uint8_t Result; - asm volatile("inb %1, %0" : "=a" (Result) : "dN" (Port)); - return Result; - } - - uint16_t InPortW(uint16_t Port) - { - uint16_t Result; - asm volatile("inw %1, %0" : "=a" (Result) : "dN" (Port)); - return Result; - } - - uint32_t InPortL(uint16_t Port) - { - uint32_t Result; - asm volatile("inl %1, %0" : "=a" (Result) : "dN" (Port)); - return Result; - } - - void Reboot() - { - // Keyboard interface IO port: data and control. - const uint16_t KEYBOARD_INTERFACE = 0x64; - - // Keyboard IO port. - const uint16_t KEYBOARD_IO = 0x60; - - // Keyboard data is in buffer (output buffer is empty) (bit 0). - const uint8_t KEYBOARD_DATA = (1<<0); - - // User data is in buffer (command buffer is empty) (bit 1). - const uint8_t USER_DATA = (1<<1); - - // Disable interrupts. - asm volatile("cli"); - - // Clear all keyboard buffers (output and command buffers). - uint8_t byte; - do - { - byte = InPortB(KEYBOARD_INTERFACE); - if ( ( byte & KEYBOARD_DATA ) != 0 ) { InPortB(KEYBOARD_IO); } - } while ( ( byte & USER_DATA ) != 0 ); - - // CPU reset command. - uint8_t KEYBOARD_RESET_CPU = 0xFE; - - // Now pulse the CPU reset line and reset. - OutPortB(KEYBOARD_INTERFACE, KEYBOARD_RESET_CPU); - - // If that didn't work, just halt. - asm volatile("hlt"); - } - - void ShutDown() - { - // TODO: Unimplemented, just reboot. - Reboot(); - } - } + asm volatile ("outb %1, %0" : : "dN" (port), "a" (value)); } + +void OutPortW(uint16_t port, uint16_t value) +{ + asm volatile ("outw %1, %0" : : "dN" (port), "a" (value)); +} + +void OutPortL(uint16_t port, uint32_t value) +{ + asm volatile ("outl %1, %0" : : "dN" (port), "a" (value)); +} + +uint8_t InPortB(uint16_t port) +{ + uint8_t result; + asm volatile("inb %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +uint16_t InPortW(uint16_t port) +{ + uint16_t result; + asm volatile("inw %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +uint32_t InPortL(uint16_t port) +{ + uint32_t result; + asm volatile("inl %1, %0" : "=a" (result) : "dN" (port)); + return result; +} + +void Reboot() +{ + // Keyboard interface IO port: data and control. + const uint16_t KEYBOARD_INTERFACE = 0x64; + + // Keyboard IO port. + const uint16_t KEYBOARD_IO = 0x60; + + // Keyboard data is in buffer (output buffer is empty) (bit 0). + const uint8_t KEYBOARD_DATA = 1 << 0; + + // User data is in buffer (command buffer is empty) (bit 1). + const uint8_t USER_DATA = 1 << 1; + + // Disable interrupts. + asm volatile("cli"); + + // Clear all keyboard buffers (output and command buffers). + uint8_t byte; + do + { + byte = InPortB(KEYBOARD_INTERFACE); + if ( byte & KEYBOARD_DATA ) + InPortB(KEYBOARD_IO); + } while ( byte & USER_DATA ); + + // CPU reset command. + uint8_t KEYBOARD_RESET_CPU = 0xFE; + + // Now pulse the CPU reset line and reset. + OutPortB(KEYBOARD_INTERFACE, KEYBOARD_RESET_CPU); + + // If that didn't work, just halt. + asm volatile("hlt"); +} + +void ShutDown() +{ + // TODO: Unimplemented, just reboot. + Reboot(); +} + +} // namespace CPU +} // namespace Sortix diff --git a/kernel/x86-family/x86-family.h b/kernel/x86-family/x86-family.h index b31a262c..6c335bc4 100644 --- a/kernel/x86-family/x86-family.h +++ b/kernel/x86-family/x86-family.h @@ -25,41 +25,48 @@ #ifndef SORTIX_X86_FAMILY_H #define SORTIX_X86_FAMILY_H -namespace Sortix -{ - namespace CPU - { - void OutPortB(uint16_t Port, uint8_t Value); - void OutPortW(uint16_t Port, uint16_t Value); - void OutPortL(uint16_t Port, uint32_t Value); - uint8_t InPortB(uint16_t Port); - uint16_t InPortW(uint16_t Port); - uint32_t InPortL(uint16_t Port); - void Reboot(); - void ShutDown(); - } +#include +#include - const size_t FLAGS_CARRY = (1<<0); // 0x000001 - const size_t FLAGS_RESERVED1 = (1<<1); // 0x000002, read as one - const size_t FLAGS_PARITY = (1<<2); // 0x000004 - const size_t FLAGS_RESERVED2 = (1<<3); // 0x000008 - const size_t FLAGS_AUX = (1<<4); // 0x000010 - const size_t FLAGS_RESERVED3 = (1<<5); // 0x000020 - const size_t FLAGS_ZERO = (1<<6); // 0x000040 - const size_t FLAGS_SIGN = (1<<7); // 0x000080 - const size_t FLAGS_TRAP = (1<<8); // 0x000100 - const size_t FLAGS_INTERRUPT = (1<<9); // 0x000200 - const size_t FLAGS_DIRECTION = (1<<10); // 0x000400 - const size_t FLAGS_OVERFLOW = (1<<11); // 0x000800 - const size_t FLAGS_IOPRIVLEVEL = (1<<12) | (1<<13); - const size_t FLAGS_NESTEDTASK = (1<<14); // 0x004000 - const size_t FLAGS_RESERVED4 = (1<<15); // 0x008000 - const size_t FLAGS_RESUME = (1<<16); // 0x010000 - const size_t FLAGS_VIRTUAL8086 = (1<<17); // 0x020000 - const size_t FLAGS_ALIGNCHECK = (1<<18); // 0x040000 - const size_t FLAGS_VIRTINTR = (1<<19); // 0x080000 - const size_t FLAGS_VIRTINTRPEND = (1<<20); // 0x100000 - const size_t FLAGS_ID = (1<<21); // 0x200000 -} +namespace Sortix { +namespace CPU { + +void OutPortB(uint16_t port, uint8_t value); +void OutPortW(uint16_t port, uint16_t value); +void OutPortL(uint16_t port, uint32_t value); +uint8_t InPortB(uint16_t port); +uint16_t InPortW(uint16_t port); +uint32_t InPortL(uint16_t port); +void Reboot(); +void ShutDown(); + +} // namespace CPU +} // namespace Sortix + +namespace Sortix { + +const size_t FLAGS_CARRY = 1 << 0; // 0x000001 +const size_t FLAGS_RESERVED1 = 1 << 1; // 0x000002, read as one +const size_t FLAGS_PARITY = 1 << 2; // 0x000004 +const size_t FLAGS_RESERVED2 = 1 << 3; // 0x000008 +const size_t FLAGS_AUX = 1 << 4; // 0x000010 +const size_t FLAGS_RESERVED3 = 1 << 5; // 0x000020 +const size_t FLAGS_ZERO = 1 << 6; // 0x000040 +const size_t FLAGS_SIGN = 1 << 7; // 0x000080 +const size_t FLAGS_TRAP = 1 << 8; // 0x000100 +const size_t FLAGS_INTERRUPT = 1 << 9; // 0x000200 +const size_t FLAGS_DIRECTION = 1 << 10; // 0x000400 +const size_t FLAGS_OVERFLOW = 1 << 11; // 0x000800 +const size_t FLAGS_IOPRIVLEVEL = 1 << 12) | 1 << 13; +const size_t FLAGS_NESTEDTASK = 1 << 14; // 0x004000 +const size_t FLAGS_RESERVED4 = 1 << 15; // 0x008000 +const size_t FLAGS_RESUME = 1 << 16; // 0x010000 +const size_t FLAGS_VIRTUAL8086 = 1 << 17; // 0x020000 +const size_t FLAGS_ALIGNCHECK = 1 << 18; // 0x040000 +const size_t FLAGS_VIRTINTR = 1 << 19; // 0x080000 +const size_t FLAGS_VIRTINTRPEND = 1 << 20; // 0x100000 +const size_t FLAGS_ID = 1 << 21; // 0x200000 + +} // namespace Sortix #endif