diff --git a/bastl/include/string b/bastl/include/string index b26a6d6..603383b 100644 --- a/bastl/include/string +++ b/bastl/include/string @@ -87,6 +87,38 @@ public: return append(other); } + constexpr bool operator==(const basic_string& other) const noexcept + { + if (size() != other.size()) { + return false; + } + for (size_t idx = 0; idx < size(); ++idx) { + if (at(idx) != other.at(idx)) { + return false; + } + } + return true; + } + constexpr bool operator!=(const basic_string& other) const noexcept + { + return !(*this == other); // NOLINT + } + constexpr bool operator==(const value_type* cStr) const noexcept + { + for (value_type chr : *this) + { + if (*cStr == '\0' || chr != *cStr) { + return false; + } + ++cStr; + } + return true; + } + constexpr bool operator!=(const value_type* cStr) const noexcept + { + return !(*this == cStr); // NOLINT + } + [[nodiscard]] constexpr reference operator[](size_type pos) noexcept { return _data[pos]; } [[nodiscard]] constexpr const_reference operator[](size_type pos) const noexcept { return _data[pos]; } @@ -152,6 +184,18 @@ public: static inline size_type npos = size_type(-1); }; using string = basic_string; + +template> // TODO: Allocator +constexpr bool operator==(const CharT* cStr, const basic_string& str) noexcept +{ + return str == cStr; +} + +template> // TODO: Allocator +constexpr bool operator!=(const CharT* cStr, const basic_string& str) noexcept +{ + return str != cStr; +} } #endif // !defined(BAD_APPLE_OS_STRING_INCLUDED) diff --git a/start.sh b/start.sh new file mode 100644 index 0000000..d11276b --- /dev/null +++ b/start.sh @@ -0,0 +1,8 @@ +#!/bin/bash +qemu-system-x86_64 \ + --bios /usr/share/edk2/x64/OVMF.fd \ + -vga virtio \ + -serial stdio \ + -drive if=none,id=stick,format=raw,file=staging/x86_64_iso/fat.img \ + -device nec-usb-xhci,id=xhci \ + -device usb-storage,bus=xhci.0,drive=stick "$@" diff --git a/targets/_any/SConscript b/targets/_any/SConscript index 572d10c..9b2330d 100644 --- a/targets/_any/SConscript +++ b/targets/_any/SConscript @@ -41,6 +41,8 @@ isr_sources = Split(''' any_target_sources = Split(''' src/app/main.cpp + src/drivers/pci.cpp + src/libs/psf.cpp src/os/draw.cpp diff --git a/targets/_any/include/drivers/pci.hpp b/targets/_any/include/drivers/pci.hpp new file mode 100644 index 0000000..94418e3 --- /dev/null +++ b/targets/_any/include/drivers/pci.hpp @@ -0,0 +1,253 @@ + +#pragma once + +#if !defined(BAD_APPLE_OS_DRIVERS_PCI_HPP_INCLUDED) +#define BAD_APPLE_OS_DRIVERS_PCI_HPP_INCLUDED + +#include +#include + +namespace baos::pci +{ +enum class BaseClass : std::uint8_t +{ + UNCLASSIFIED = 0x0, + MASS_STORAGE_CONTROLLER = 0x1, + NETWORK_CONTROLLER = 0x2, + DISPLAY_CONTROLLER = 0x3, + MULTIMEDIA_CONTROLLER = 0x4, + MEMORY_CONTROLLER = 0x5, + BRIDGE = 0x6, + SIMPLE_COMMUNICATION_CONTROLLER = 0x7, + BASE_SYSTEM_PERIPHERAL = 0x8, + INPUT_DEVICE_CONTROLLER = 0x9, + DOCKING_STATION = 0xA, + PROCESSOR = 0xB, + SERIAL_BUS_CONTROLLER = 0xC, + WIRELESS_CONTROLLER = 0xD, + INTELLIGENT_CONTROLLER = 0xE, + SATELLITE_COMMUNICATION_CONTROLLER = 0xF, + ENCRYPTION_CONTROLLER = 0x10, + SIGNAL_PROCESSING_CONTROLLER = 0x11, + PROCESSING_ACCELERATOR = 0x12, + NON_ESSENTIAL_INSTRUMENTATION = 0x13, + CO_PROCESSOR = 0x40, + UNASSIGNED = 0xFF +}; + +enum class SubClass : std::uint8_t +{ + // for 0x1 - Mass Storage Controller + IDE_CONTROLLER = 0x1, + FLOPPY_DISK_CONTROLLER = 0x2, + IPI_BUS_CONTROLLER = 0x3, + RAID_CONTROLLER = 0x4, + ATA_CONTROLLER = 0x5, + SERIAL_ATA_CONTROLLER = 0x6, + SERIAL_ATTACHED_SCSI_CONTROLLER = 0x7, + NON_VOLATILE_MEMORY_CONTROLLER = 0x8, + OTHER = 0x80, + + // for 0x2 - Network Controller + ETHERNET_CONTROLLER = 0x0, + TOKEN_RING_CONTROLLER = 0x1, + FDDI_CONTROLLER = 0x2, + ATM_CONTROLLER = 0x3, + ISDN_CONTROLLER = 0x4, + WORLDFIP_CONTROLLER = 0x5, + PICMG_CONTROLLER = 0x6, + INFIBAND_CONTROLLER = 0x7, + FABRIC_CONTROLLER = 0x8, + + // for 0x3 - Display Controller + VGA_COMPATIBLE_CONTROLLER = 0x0, + XGA_CONTROLLER = 0x1, + NOT_VGA_COMPATIBLE_3D_CONTROLLER = 0x2, + + // for 0x4 - Multimedia Controller + MULTIMEDIA_VIDEO_CONTROLLER = 0x0, + MULTIMEDIA_AUDIO_CONTROLLER = 0x1, + COMPUTER_TELEPHONY_DEVICE = 0x2, + AUDIO_DEVICE = 0x3, + + // for 0x5 - Memory Controller + RAM_CONTROLLER = 0x0, + FLASH_CONTROLLER = 0x1, + + // for 0x6 - Bridge + HOST_BRIDGE = 0x0, + ISA_BRIDGE = 0x1, + EISA_BRIDGE = 0x2, + MCA_BRIDGE = 0x3, + PCI_TO_PCI_BRIDGE = 0x4, + PCMCIA_BRIDGE = 0x5, + NUBUS_BRIDGE = 0x6, + CARDBUS_BRIDGE = 0x7, + RACEWAY_BRIDGE = 0x8, + PCI_TO_PCI_BRIDGE_2 = 0x9, + INFINIBAND_TO_PCI_HOST_BRIDGE = 0xA, + + // for 0x7 - Simple Communication Controller + SERIAL_CONTROLLER = 0x0, + PARALLEL_CONTROLLER = 0x1, + MULTIPORT_SERIAL_CONTROLLER = 0x2, + MODEM = 0x3, + IEEE488_CONTROLLER = 0x4, + SMART_CARD_CONTROLLER = 0x5, + + // for 0x8 - Base System Peripheral + PIC = 0x1, + DMA_CONTROLLER = 0x1, + TIMER = 0x2, + RTC_CONTROLLER = 0x3, + PCI_HOT_PLUG_CONTROLLER = 0x4, + SD_HOST_CONTROLLER = 0x5, + IOMMU = 0x6, + + // for 0x9 - Input Device Controller + KEYBOARD_CONTROLLER = 0x0, + DIGITIZER_PEN = 0x1, + MOUSE_CONTROLLER = 0x2, + SCANNER_CONTROLLER = 0x3, + GAMEPORT_CONTROLLER = 0x4, + + // for 0xA - Docking Station + GENERIC = 0x0, + + // for 0xB - Processor + _386 = 0x0, + _486 = 0x1, + PENTIUM = 0x2, + PENTIUM_PRO = 0x3, + ALPHA = 0x10, + POWERPC = 0x20, + MIPS = 0x30, + CO_PROCESSOR = 0x40, + + // for 0xC - Serial Bus Controller + FIREWIRE_CONTROLLER = 0x0, + ACCESS_BUS_CONTROLLER = 0x1, + SSA = 0x2, + USB_CONTROLLER = 0x3, + FIBRE_CHANNEL = 0x4, + SMBUS_CONTROLLER = 0x5, + INFINIBAND_CONTROLLER = 0x6, + IPMI_INTERFACE = 0x7, + SERCOS_INTERFACE = 0x8, + CANBUS_CONTROLLER = 0x9, + + // for 0xD - Wireless Controller + IRDA_COMPATIBLE_CONTROLLER = 0xD, + CONSUMER_IR_CONTROLLER = 0x1, + RF_CONTROLLER = 0x10, + BLUETOOTH_CONTROLLER = 0x11, + BROADBAND_CONTROLLER = 0x12, + ETHERNET_CONTROLLER_8021A = 0x20, + ETHERNET_CONTROLLER_8021B = 0x21, + + // for 0xE - Intelligent Controller + I20 = 0x0, + + // for 0xF - Satellite Communication Controller + SATELLITE_TV_CONTROLLER = 0x1, + SATELLITE_AUDIO_CONTROLLER = 0x2, + SATELLITE_VOICE_CONTROLLER = 0x3, + SATELLITE_DATA_CONTROLLER = 0x4, + + // for 0x10 - Encryption Controller + NETWORK_AND_COMPUTING_EN_DECRYPTION = 0x0, + ENTERTAINMENT_EN_DECRYPTION = 0x10, + + // for 0x11 - Signal Processing Controller + DPIO_MODULE = 0x0, + PERFORMANCE_COUNTER = 0x1, + COMMUNICATION_SYNCHRONIZER = 0x10, + SIGNAL_PROCESSING_MANAGEMENT = 0x20 +}; + +enum class HeaderType : std::uint8_t +{ + GENERAL_DEVICE = 0x0, + PCI_TO_PCI_BRIDGE = 0x1, + PCI_TO_CARDBUS_BRIDGE = 0x2 +}; + +struct Header +{ + std::uint8_t bus; + std::uint8_t device; + std::uint8_t function; + std::uint8_t pad_; + + std::uint16_t vendorID; + std::uint16_t deviceID; + std::uint16_t command; + std::uint16_t status; + std::uint8_t revisionID; + std::uint8_t progIf; + SubClass subClass; + BaseClass baseClass; + std::uint8_t cacheLineSize; + std::uint8_t latencyTimer; + HeaderType headerType : 7; + bool multiFunction : 1; + std::uint8_t builtinSelfTest; +} __attribute__((packed)); + +struct GeneralDeviceHeader : Header +{ + std::uint32_t bar0; + std::uint32_t bar1; + std::uint32_t bar2; + std::uint32_t bar3; + std::uint32_t bar4; + std::uint32_t bar5; + std::uint32_t cardbusCISPointer; + std::uint16_t subsystemVendorID; + std::uint16_t subsystemID; + std::uint32_t expansionROMBaseAddress; + std::uint8_t capabilitiesPointer; + std::uint64_t reserved : 56; + std::uint8_t interruptLine; + std::uint8_t interruptPIN; + std::uint8_t minGrant; + std::uint8_t maxLatency; +} __attribute__((packed)); + +struct PCIToPCIBridgeHeader : Header +{ + std::uint32_t bar0; + std::uint32_t bar1; + std::uint8_t primaryBusNumber; + std::uint8_t secondaryBusNumber; + std::uint8_t subordinateBusNumber; + std::uint8_t secondaryLatencyTimer; + std::uint8_t ioBase; + std::uint8_t ioLimit; + std::uint16_t secondaryStatus; + std::uint16_t memoryBase; + std::uint16_t memoryLimit; + std::uint16_t prefetchableMemoryBase; + std::uint16_t prefetchableMemoryLimit; + std::uint32_t prefetchableBaseUpper32; + std::uint32_t prefetchableLimitUpper32; + std::uint16_t ioBaseUpper16; + std::uint16_t ioLimitUpper16; + std::uint8_t capbiliityPointer; + std::uint32_t reserved : 24; + std::uint32_t expansionRomBaseAddress; + std::uint8_t interruptLine; + std::uint8_t interruptPin; + std::uint16_t bridgeControl; +} __attribute__((packed)); + +[[nodiscard]] std::vector
enumerateDevices() noexcept; +[[nodiscard]] bool getGeneralDeviceHeader(std::uint8_t bus, std::uint8_t device, std::uint8_t function, GeneralDeviceHeader& outHeader) noexcept; + +[[nodiscard]] inline bool getGeneralDeviceHeader(const Header& header, GeneralDeviceHeader& outHeader) noexcept +{ + return getGeneralDeviceHeader(header.bus, header.device, header.function, outHeader); +} +} + +#endif // !defined(BAD_APPLE_OS_DRIVERS_PCI_HPP_INCLUDED) diff --git a/targets/_any/include/os/port.hpp b/targets/_any/include/os/port.hpp index 8b50c39..d53fae8 100644 --- a/targets/_any/include/os/port.hpp +++ b/targets/_any/include/os/port.hpp @@ -6,7 +6,7 @@ #include -#define writePortByte(port, value) \ +#define writePort8(port, value) \ { \ __asm__ __volatile__( \ "outb %0, %1" \ @@ -16,7 +16,7 @@ ); \ } -#define readPortByte(port) \ +#define readPort8(port) \ [&]() \ { \ std::uint8_t value = 0; \ @@ -28,9 +28,53 @@ return value; \ }() +#define writePort16(port, value) \ +{ \ + __asm__ __volatile__( \ + "outw %0, %1" \ + : \ + : "a"(static_cast(value)), \ + "Nd"(static_cast(port)) \ + ); \ +} + +#define readPort16(port) \ +[&]() \ +{ \ + std::uint16_t value = 0; \ + __asm__ __volatile__( \ + "inw %1, %0" \ + : "=a"(value) \ + : "Nd"(static_cast(port)) \ + ); \ + return value; \ +}() + +#define writePort32(port, value) \ +{ \ + __asm__ __volatile__( \ + "outl %0, %1" \ + : \ + : "a"(static_cast(value)), \ + "Nd"(static_cast(port)) \ + ); \ +} + +#define readPort32(port) \ +[&]() \ +{ \ + std::uint32_t value = 0; \ + __asm__ __volatile__( \ + "inl %1, %0" \ + : "=a"(value) \ + : "Nd"(static_cast(port)) \ + ); \ + return value; \ +}() + inline void ioWait() noexcept { - writePortByte(0x80, 0); + writePort8(0x80, 0); } #endif // !defined(BAD_APPLE_OS_PORT_HPP_INCLUDED) diff --git a/targets/_any/include/os/serial.hpp b/targets/_any/include/os/serial.hpp index 6361eb8..39608df 100644 --- a/targets/_any/include/os/serial.hpp +++ b/targets/_any/include/os/serial.hpp @@ -19,31 +19,31 @@ inline constexpr std::uint16_t PORT_COM8 = 0x4E8; [[nodiscard]] inline bool initSerialPort(std::uint16_t port) noexcept { - writePortByte(port + 1, 0x00); // Disable all interrupts - writePortByte(port + 3, 0x80); // Enable DLAB (set baud rate divisor) - writePortByte(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - writePortByte(port + 1, 0x00); // (hi byte) - writePortByte(port + 3, 0x03); // 8 bits, no parity, one stop bit - writePortByte(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - writePortByte(port + 4, 0x0B); // IRQs enabled, RTS/DSR set - writePortByte(port + 4, 0x1E); // Set in loopback mode, test the serial chip - writePortByte(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) + writePort8(port + 1, 0x00); // Disable all interrupts + writePort8(port + 3, 0x80); // Enable DLAB (set baud rate divisor) + writePort8(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + writePort8(port + 1, 0x00); // (hi byte) + writePort8(port + 3, 0x03); // 8 bits, no parity, one stop bit + writePort8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + writePort8(port + 4, 0x0B); // IRQs enabled, RTS/DSR set + writePort8(port + 4, 0x1E); // Set in loopback mode, test the serial chip + writePort8(port + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) // Check if serial is faulty (i.e: not same byte as sent) - if(readPortByte(port + 0) != 0xAE) { + if(readPort8(port + 0) != 0xAE) { return false; } // If serial is not faulty set it in normal operation mode // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - writePortByte(port + 4, 0x0F); + writePort8(port + 4, 0x0F); return true; } inline void serialWrite(std::uint16_t port, std::uint8_t data) noexcept { - while ((readPortByte(port + 5) & 0x20) == 0); - writePortByte(port, data); + while ((readPort8(port + 5) & 0x20) == 0); + writePort8(port, data); } inline void serialWriteString(std::uint16_t port, const char* str) noexcept diff --git a/targets/_any/src/app/main.cpp b/targets/_any/src/app/main.cpp index d3d49e9..54c0256 100644 --- a/targets/_any/src/app/main.cpp +++ b/targets/_any/src/app/main.cpp @@ -1,6 +1,56 @@ #include +#include "drivers/pci.hpp" +#include "drivers/ps2.hpp" + +namespace +{ +void cmdLspci() noexcept +{ + using namespace baos::pci; + + std::puts("Enumerating PCI devices."); + GeneralDeviceHeader generalDeviceHeader = {}; + for (const Header& header : enumerateDevices()) + { + std::printf("Bus %d, Port %d, Function %d: VendorID: 0x%X, DeviceID: 0x%X, Base Class: 0x%X, Sub Class: 0x%X\n", + header.bus, header.device, header.function, header.vendorID, header.deviceID, + static_cast(header.baseClass), static_cast(header.subClass)); + + if (header.headerType == HeaderType::GENERAL_DEVICE && getGeneralDeviceHeader(header, generalDeviceHeader)) + { + std::printf(" BAR0: 0x%X, BAR1: 0x%X, BAR2: 0x%X\n" + " BAR3: 0x%X, BAR4: 0x%X, BAR5: 0x%X\n" + " Subsystem Vendor ID: 0x%X, Subsystem ID: 0x%X\n", + generalDeviceHeader.bar0, generalDeviceHeader.bar1, generalDeviceHeader.bar2, + generalDeviceHeader.bar3, generalDeviceHeader.bar4, generalDeviceHeader.bar5, + generalDeviceHeader.subsystemVendorID, generalDeviceHeader.subsystemID); + } + } +} + +void cmdShowKeys() noexcept +{ + std::puts("Press CTRL-C to quit."); + while (true) + { + baos::ps2::KeyEvent event; + while (!baos::ps2::readKey(event)); + std::printf( + "Key event: scancode=%s(0x%X), down=%s, repeat=%s\n", + baos::ps2::keyName(event.scancode), + static_cast(event.scancode), + event.down ? "true" : "false", + event.repeat ? "true" : "false" + ); + if (event.scancode == baos::ps2::Scancode::C && baos::ps2::isKeyDown(baos::ps2::Scancode::LEFT_CONTROL)) { + return; + } + } +} +} + extern "C" void main() { @@ -11,6 +61,17 @@ extern "C" void main() std::printf("> "); std::getline(cmd); cmd.pop_back(); // pop the \n - std::printf("Your command: %s\n", cmd.c_str()); + + if (cmd == "lspci") + { + cmdLspci(); + continue; + } + else if (cmd == "show-keys") + { + cmdShowKeys(); + continue; + } + std::printf("Unknown command: %s.\n", cmd.c_str()); } } diff --git a/targets/_any/src/drivers/pci.cpp b/targets/_any/src/drivers/pci.cpp new file mode 100644 index 0000000..6f9b84a --- /dev/null +++ b/targets/_any/src/drivers/pci.cpp @@ -0,0 +1,126 @@ + +#include "drivers/pci.hpp" + +#include +#include +#include "os/port.hpp" + +namespace baos::pci +{ +namespace +{ +inline constexpr std::uint16_t PORT_PCI_CONFIG = 0xCF8; +inline constexpr std::uint16_t PORT_PCI_DATA = 0xCFC; + +std::uint32_t readConfigLine(std::uint8_t bus, std::uint8_t device, std::uint8_t func, std::uint8_t offset) noexcept +{ + struct PciAddress + { + std::uint8_t registerOffset : 8 = 0; + std::uint8_t function : 3 = 0; + std::uint8_t device : 5 = 0; + std::uint8_t bus : 8 = 0; + std::uint8_t reserved : 7 = 0; + bool enable : 1 = 0; + } __attribute__((packed)); + const PciAddress address = { + .registerOffset = static_cast(offset & 0xFCu), + .function = func, + .device = device, + .bus = bus, + .enable = true + }; + writePort32(PORT_PCI_CONFIG, std::bit_cast(address)); + return readPort32(PORT_PCI_DATA); +} + +template +bool getHeader(std::uint8_t bus, std::uint8_t device, std::uint8_t function, THeader& outHeader) noexcept +{ + static_assert(sizeof(THeader) % 4 == 0); + + std::uint32_t line = readConfigLine(bus, device, function, 0x0); + if (line == 0xFFFFFFFF) { + return false; + } + outHeader.bus = bus; + outHeader.device = device; + outHeader.function = function; + + std::memcpy(&outHeader.vendorID, &line, 4); + for (unsigned row = 1; row < sizeof(THeader) / 4; ++row) + { + line = readConfigLine(bus, device, 0, 4 * row); + std::memcpy(reinterpret_cast(&outHeader.vendorID) + row, &line, 4); + } + return true; +} + +void enumerateDevice(const Header& header, std::vector
& outHeaders) noexcept; +void enumerateBusDevices(std::uint8_t bus, std::vector
& outHeaders, std::uint8_t firstDevice = 0) noexcept +{ + Header header = {}; + for (std::uint8_t device = firstDevice; device < 32; ++device) + { + if (!getHeader(bus, device, 0, header)) { + continue; + } + enumerateDevice(header, outHeaders); + if (header.multiFunction) + { + for (std::uint8_t function = 1; function < 8; ++function) + { + if (!getHeader(bus, device, function, header)) { + continue; + } + enumerateDevice(header, outHeaders); + } + } + } +} + +void enumerateDevice(const Header& header, std::vector
& outHeaders) noexcept +{ + outHeaders.push_back(header); + if (header.headerType == HeaderType::PCI_TO_PCI_BRIDGE && header.baseClass == BaseClass::BRIDGE && header.subClass == SubClass::PCI_TO_PCI_BRIDGE) + { + // get the bridge header + PCIToPCIBridgeHeader bridgeHeader = {}; + if (getHeader(header.bus, header.device, header.function, bridgeHeader)) + { + enumerateBusDevices(bridgeHeader.secondaryBusNumber, outHeaders); + } + } +} +} + +std::vector
enumerateDevices() noexcept +{ + Header header = {}; + if (!getHeader(0, 0, 0, header)) { + return {}; + } + // also add the controller itself + std::vector
headers; + + headers.push_back(header); + enumerateBusDevices(0, headers, /* firstDevice = */ 1); + if (header.multiFunction) + { + for (std::uint8_t function = 1; function < 8; ++function) + { + if (!getHeader(0, 0, function, header)) { + continue; + } + headers.push_back(header); + enumerateBusDevices(function, headers); + } + } + return headers; +} + +bool getGeneralDeviceHeader(std::uint8_t bus, std::uint8_t device, std::uint8_t function, GeneralDeviceHeader& outHeader) noexcept +{ + return getHeader(bus, device, function, outHeader); +} +} diff --git a/targets/_any/src/drivers/pic.cpp b/targets/_any/src/drivers/pic.cpp index f53142c..2b49610 100644 --- a/targets/_any/src/drivers/pic.cpp +++ b/targets/_any/src/drivers/pic.cpp @@ -11,22 +11,22 @@ inline constexpr std::uint8_t PIC_CFG_8086 = 0x01; void picWriteCmd(std::uint16_t port, std::uint8_t command) noexcept { - writePortByte(port, command); + writePort8(port, command); } [[nodiscard]] std::uint8_t picReadResponse(std::uint8_t port) noexcept { - return readPortByte(port); + return readPort8(port); } void picWriteData(std::uint16_t port, std::uint8_t data) noexcept { - writePortByte(port + 1, data); + writePort8(port + 1, data); } [[nodiscard]] std::uint8_t picReadData(std::uint16_t port) noexcept { - return readPortByte(port + 1); + return readPort8(port + 1); } [[nodiscard]] std::uint16_t readPICIRQRegisters(std::uint8_t readCommand) noexcept @@ -81,9 +81,9 @@ bool initPICs(std::uint8_t masterOffset, std::uint8_t slaveOffset) noexcept void sendEndOfInterrupt(std::uint8_t irq) noexcept { if (irq >= 8) { - writePortByte(PORT_PIC2, PIC_CMD_EOI); + writePort8(PORT_PIC2, PIC_CMD_EOI); } - writePortByte(PORT_PIC1, PIC_CMD_EOI); + writePort8(PORT_PIC1, PIC_CMD_EOI); } void maskIRQ(std::uint8_t irq) noexcept diff --git a/targets/_any/src/drivers/ps2.cpp b/targets/_any/src/drivers/ps2.cpp index 398d033..ea45d05 100644 --- a/targets/_any/src/drivers/ps2.cpp +++ b/targets/_any/src/drivers/ps2.cpp @@ -360,7 +360,7 @@ inline bool waitForResponse(unsigned tries = -1) noexcept { for (unsigned t = 0; t < tries; ++t) { - if (readPortByte(PORT_PS2_STATUS) & FLAG_PS2_OUTPUT_FULL) { + if (readPort8(PORT_PS2_STATUS) & FLAG_PS2_OUTPUT_FULL) { return true; } } @@ -369,27 +369,27 @@ inline bool waitForResponse(unsigned tries = -1) noexcept inline void waitForInputFree() noexcept { - while (readPortByte(PORT_PS2_STATUS) & FLAG_PS2_INPUT_FULL); + while (readPort8(PORT_PS2_STATUS) & FLAG_PS2_INPUT_FULL); } inline std::uint8_t cmdWithResponse(std::uint8_t cmd) noexcept { - writePortByte(PORT_PS2_STATUS, cmd); + writePort8(PORT_PS2_STATUS, cmd); waitForResponse(); - return readPortByte(PORT_PS2_DATA); + return readPort8(PORT_PS2_DATA); } inline void cmdWithData(std::uint8_t cmd, std::uint8_t data) noexcept { - writePortByte(PORT_PS2_STATUS, cmd); + writePort8(PORT_PS2_STATUS, cmd); waitForInputFree(); - writePortByte(PORT_PS2_DATA, data); + writePort8(PORT_PS2_DATA, data); } inline void sendToFirstDevice(std::uint8_t cmd) noexcept { waitForInputFree(); - writePortByte(PORT_PS2_DATA, cmd); + writePort8(PORT_PS2_DATA, cmd); } inline void sendToSecondDevice(std::uint8_t cmd) noexcept @@ -401,11 +401,11 @@ inline void sendToSecondDevice(std::uint8_t cmd) noexcept bool initialize() noexcept { // disable PS2 - writePortByte(PORT_PS2_STATUS, PS2_CMD_DISABLE_FIRST); - writePortByte(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND); + writePort8(PORT_PS2_STATUS, PS2_CMD_DISABLE_FIRST); + writePort8(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND); // flush output register - readPortByte(PORT_PS2_DATA); + readPort8(PORT_PS2_DATA); // read configuration std::uint8_t config = cmdWithResponse(PS2_CMD_READ_CONF_BYTE); @@ -432,11 +432,11 @@ bool initialize() noexcept bool dualChannel = false; if ((config & PS2_CONFIGFLAG_CLOCK_SECOND) != 0) // it may be { - writePortByte(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND); + writePort8(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND); dualChannel = (cmdWithResponse(PS2_CMD_READ_CONF_BYTE) & PS2_CONFIGFLAG_CLOCK_SECOND) == 0; if (dualChannel) { - writePortByte(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND); + writePort8(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND); } } @@ -451,9 +451,9 @@ bool initialize() noexcept } // enable devices - writePortByte(PORT_PS2_STATUS, PS2_CMD_ENABLE_FIRST); + writePort8(PORT_PS2_STATUS, PS2_CMD_ENABLE_FIRST); if (dualChannel) { - writePortByte(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND); + writePort8(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND); } // enable interrupts @@ -468,7 +468,7 @@ bool initialize() noexcept bool firstOk = false; while (waitForResponse(10)) { - const std::uint8_t response = readPortByte(PORT_PS2_DATA); + const std::uint8_t response = readPort8(PORT_PS2_DATA); if (response == PS2_RESPONSE_SELFTEST_FAILED) { return false; } @@ -483,7 +483,7 @@ bool initialize() noexcept bool secondOk = false; while (waitForResponse(10)) { - const std::uint8_t response = readPortByte(PORT_PS2_DATA); + const std::uint8_t response = readPort8(PORT_PS2_DATA); if (response == PS2_RESPONSE_SELFTEST_FAILED) { return false; } @@ -501,7 +501,7 @@ __attribute__((interrupt)) void isrKeyboard(InterruptFrame* interruptFrame) noexcept { (void) interruptFrame; - const std::uint8_t data = readPortByte(PORT_PS2_DATA); + const std::uint8_t data = readPort8(PORT_PS2_DATA); if (data != 0) { pushKey(data); diff --git a/targets/_any/src/os/interrupt.cpp b/targets/_any/src/os/interrupt.cpp index ebc8dad..517e91d 100644 --- a/targets/_any/src/os/interrupt.cpp +++ b/targets/_any/src/os/interrupt.cpp @@ -17,9 +17,9 @@ struct InterruptPrinter void putchar(char chr) noexcept // NOLINT { if (chr == '\n') { - writePortByte(PORT_COM1, '\r'); + writePort8(PORT_COM1, '\r'); } - writePortByte(PORT_COM1, static_cast(chr)); + writePort8(PORT_COM1, static_cast(chr)); } }; diff --git a/targets/_any/src/os/tty.cpp b/targets/_any/src/os/tty.cpp index 06a974e..4e73e69 100644 --- a/targets/_any/src/os/tty.cpp +++ b/targets/_any/src/os/tty.cpp @@ -17,21 +17,10 @@ size_t gTerminalColumn = 0; size_t gTerminalWidth = 0; size_t gTerminalHeight = 0; VgaDoubleColor gTerminalColor = VgaDoubleColor(); -// uint16_t* gTerminalBuffer = reinterpret_cast(0xB8000); std::vector gTerminalBuffer; psf::Font gTerminalFont; std::string gReadBuffer; -constexpr uint8_t vgaEntryColor(VgaDoubleColor color) -{ - return static_cast(color.foreground) | static_cast(color.background) << 4; -} - -constexpr uint16_t vgaEntry(const unsigned char chr, const VgaDoubleColor color) -{ - return static_cast(chr) | static_cast(vgaEntryColor(color) << 8); -} - void newline() { gTerminalColumn = 0; diff --git a/targets/x86_64/src/kernel/startup.cpp b/targets/x86_64/src/kernel/startup.cpp index 475e517..4ffe780 100644 --- a/targets/x86_64/src/kernel/startup.cpp +++ b/targets/x86_64/src/kernel/startup.cpp @@ -7,6 +7,7 @@ #include "os/draw.hpp" #include "os/serial.hpp" #include "os/tty.hpp" +#include "drivers/pci.hpp" #include "drivers/pic.hpp" #include "drivers/ps2.hpp" #include "./x86_64.hpp" @@ -245,18 +246,6 @@ void kernel_main() // __enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &main); main(); // for now run it in kernel mode, user mode doesn't work yet - while (true) - { - ps2::KeyEvent event; - while (!ps2::readKey(event)); - std::printf( - "Key event: scancode=%s(0x%X), down=%s, repeat=%s\n", - ps2::keyName(event.scancode), - static_cast(event.scancode), - event.down ? "true" : "false", - event.repeat ? "true" : "false" - ); - } }