Added PCI device detection and a start script.
This commit is contained in:
parent
847bf8c84b
commit
fa6dab4f88
@ -87,6 +87,38 @@ public:
|
|||||||
return append(other);
|
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 reference operator[](size_type pos) noexcept { return _data[pos]; }
|
||||||
[[nodiscard]] constexpr const_reference operator[](size_type pos) const 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);
|
static inline size_type npos = size_type(-1);
|
||||||
};
|
};
|
||||||
using string = basic_string<char>;
|
using string = basic_string<char>;
|
||||||
|
|
||||||
|
template<typename CharT, typename Traits = char_traits<CharT>> // TODO: Allocator
|
||||||
|
constexpr bool operator==(const CharT* cStr, const basic_string<CharT, Traits>& str) noexcept
|
||||||
|
{
|
||||||
|
return str == cStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename CharT, typename Traits = char_traits<CharT>> // TODO: Allocator
|
||||||
|
constexpr bool operator!=(const CharT* cStr, const basic_string<CharT, Traits>& str) noexcept
|
||||||
|
{
|
||||||
|
return str != cStr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_STRING_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_STRING_INCLUDED)
|
||||||
|
8
start.sh
Normal file
8
start.sh
Normal file
@ -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 "$@"
|
@ -41,6 +41,8 @@ isr_sources = Split('''
|
|||||||
any_target_sources = Split('''
|
any_target_sources = Split('''
|
||||||
src/app/main.cpp
|
src/app/main.cpp
|
||||||
|
|
||||||
|
src/drivers/pci.cpp
|
||||||
|
|
||||||
src/libs/psf.cpp
|
src/libs/psf.cpp
|
||||||
|
|
||||||
src/os/draw.cpp
|
src/os/draw.cpp
|
||||||
|
253
targets/_any/include/drivers/pci.hpp
Normal file
253
targets/_any/include/drivers/pci.hpp
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(BAD_APPLE_OS_DRIVERS_PCI_HPP_INCLUDED)
|
||||||
|
#define BAD_APPLE_OS_DRIVERS_PCI_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<Header> 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)
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#define writePortByte(port, value) \
|
#define writePort8(port, value) \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"outb %0, %1" \
|
"outb %0, %1" \
|
||||||
@ -16,7 +16,7 @@
|
|||||||
); \
|
); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define readPortByte(port) \
|
#define readPort8(port) \
|
||||||
[&]() \
|
[&]() \
|
||||||
{ \
|
{ \
|
||||||
std::uint8_t value = 0; \
|
std::uint8_t value = 0; \
|
||||||
@ -28,9 +28,53 @@
|
|||||||
return value; \
|
return value; \
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
#define writePort16(port, value) \
|
||||||
|
{ \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"outw %0, %1" \
|
||||||
|
: \
|
||||||
|
: "a"(static_cast<std::uint16_t>(value)), \
|
||||||
|
"Nd"(static_cast<std::uint16_t>(port)) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define readPort16(port) \
|
||||||
|
[&]() \
|
||||||
|
{ \
|
||||||
|
std::uint16_t value = 0; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"inw %1, %0" \
|
||||||
|
: "=a"(value) \
|
||||||
|
: "Nd"(static_cast<std::uint16_t>(port)) \
|
||||||
|
); \
|
||||||
|
return value; \
|
||||||
|
}()
|
||||||
|
|
||||||
|
#define writePort32(port, value) \
|
||||||
|
{ \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"outl %0, %1" \
|
||||||
|
: \
|
||||||
|
: "a"(static_cast<std::uint32_t>(value)), \
|
||||||
|
"Nd"(static_cast<std::uint16_t>(port)) \
|
||||||
|
); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define readPort32(port) \
|
||||||
|
[&]() \
|
||||||
|
{ \
|
||||||
|
std::uint32_t value = 0; \
|
||||||
|
__asm__ __volatile__( \
|
||||||
|
"inl %1, %0" \
|
||||||
|
: "=a"(value) \
|
||||||
|
: "Nd"(static_cast<std::uint32_t>(port)) \
|
||||||
|
); \
|
||||||
|
return value; \
|
||||||
|
}()
|
||||||
|
|
||||||
inline void ioWait() noexcept
|
inline void ioWait() noexcept
|
||||||
{
|
{
|
||||||
writePortByte(0x80, 0);
|
writePort8(0x80, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !defined(BAD_APPLE_OS_PORT_HPP_INCLUDED)
|
#endif // !defined(BAD_APPLE_OS_PORT_HPP_INCLUDED)
|
||||||
|
@ -19,31 +19,31 @@ inline constexpr std::uint16_t PORT_COM8 = 0x4E8;
|
|||||||
|
|
||||||
[[nodiscard]] inline bool initSerialPort(std::uint16_t port) noexcept
|
[[nodiscard]] inline bool initSerialPort(std::uint16_t port) noexcept
|
||||||
{
|
{
|
||||||
writePortByte(port + 1, 0x00); // Disable all interrupts
|
writePort8(port + 1, 0x00); // Disable all interrupts
|
||||||
writePortByte(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
writePort8(port + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||||
writePortByte(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
writePort8(port + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||||
writePortByte(port + 1, 0x00); // (hi byte)
|
writePort8(port + 1, 0x00); // (hi byte)
|
||||||
writePortByte(port + 3, 0x03); // 8 bits, no parity, one stop bit
|
writePort8(port + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||||
writePortByte(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
writePort8(port + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
|
||||||
writePortByte(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
writePort8(port + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||||
writePortByte(port + 4, 0x1E); // Set in loopback mode, test the serial chip
|
writePort8(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 + 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)
|
// Check if serial is faulty (i.e: not same byte as sent)
|
||||||
if(readPortByte(port + 0) != 0xAE) {
|
if(readPort8(port + 0) != 0xAE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If serial is not faulty set it in normal operation mode
|
// If serial is not faulty set it in normal operation mode
|
||||||
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
// (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
|
||||||
writePortByte(port + 4, 0x0F);
|
writePort8(port + 4, 0x0F);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void serialWrite(std::uint16_t port, std::uint8_t data) noexcept
|
inline void serialWrite(std::uint16_t port, std::uint8_t data) noexcept
|
||||||
{
|
{
|
||||||
while ((readPortByte(port + 5) & 0x20) == 0);
|
while ((readPort8(port + 5) & 0x20) == 0);
|
||||||
writePortByte(port, data);
|
writePort8(port, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void serialWriteString(std::uint16_t port, const char* str) noexcept
|
inline void serialWriteString(std::uint16_t port, const char* str) noexcept
|
||||||
|
@ -1,6 +1,56 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
|
#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<unsigned>(header.baseClass), static_cast<unsigned>(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<unsigned>(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()
|
extern "C" void main()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -11,6 +61,17 @@ extern "C" void main()
|
|||||||
std::printf("> ");
|
std::printf("> ");
|
||||||
std::getline(cmd);
|
std::getline(cmd);
|
||||||
cmd.pop_back(); // pop the \n
|
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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
126
targets/_any/src/drivers/pci.cpp
Normal file
126
targets/_any/src/drivers/pci.cpp
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
|
||||||
|
#include "drivers/pci.hpp"
|
||||||
|
|
||||||
|
#include <bit>
|
||||||
|
#include <cstring>
|
||||||
|
#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<std::uint8_t>(offset & 0xFCu),
|
||||||
|
.function = func,
|
||||||
|
.device = device,
|
||||||
|
.bus = bus,
|
||||||
|
.enable = true
|
||||||
|
};
|
||||||
|
writePort32(PORT_PCI_CONFIG, std::bit_cast<std::uint32_t>(address));
|
||||||
|
return readPort32(PORT_PCI_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename THeader>
|
||||||
|
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<std::uint32_t*>(&outHeader.vendorID) + row, &line, 4);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void enumerateDevice(const Header& header, std::vector<Header>& outHeaders) noexcept;
|
||||||
|
void enumerateBusDevices(std::uint8_t bus, std::vector<Header>& 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<Header>& 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<Header> enumerateDevices() noexcept
|
||||||
|
{
|
||||||
|
Header header = {};
|
||||||
|
if (!getHeader(0, 0, 0, header)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
// also add the controller itself
|
||||||
|
std::vector<Header> 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);
|
||||||
|
}
|
||||||
|
}
|
@ -11,22 +11,22 @@ inline constexpr std::uint8_t PIC_CFG_8086 = 0x01;
|
|||||||
|
|
||||||
void picWriteCmd(std::uint16_t port, std::uint8_t command) noexcept
|
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
|
[[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
|
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
|
[[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
|
[[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
|
void sendEndOfInterrupt(std::uint8_t irq) noexcept
|
||||||
{
|
{
|
||||||
if (irq >= 8) {
|
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
|
void maskIRQ(std::uint8_t irq) noexcept
|
||||||
|
@ -360,7 +360,7 @@ inline bool waitForResponse(unsigned tries = -1) noexcept
|
|||||||
{
|
{
|
||||||
for (unsigned t = 0; t < tries; ++t)
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -369,27 +369,27 @@ inline bool waitForResponse(unsigned tries = -1) noexcept
|
|||||||
|
|
||||||
inline void waitForInputFree() 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
|
inline std::uint8_t cmdWithResponse(std::uint8_t cmd) noexcept
|
||||||
{
|
{
|
||||||
writePortByte(PORT_PS2_STATUS, cmd);
|
writePort8(PORT_PS2_STATUS, cmd);
|
||||||
waitForResponse();
|
waitForResponse();
|
||||||
return readPortByte(PORT_PS2_DATA);
|
return readPort8(PORT_PS2_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void cmdWithData(std::uint8_t cmd, std::uint8_t data) noexcept
|
inline void cmdWithData(std::uint8_t cmd, std::uint8_t data) noexcept
|
||||||
{
|
{
|
||||||
writePortByte(PORT_PS2_STATUS, cmd);
|
writePort8(PORT_PS2_STATUS, cmd);
|
||||||
waitForInputFree();
|
waitForInputFree();
|
||||||
writePortByte(PORT_PS2_DATA, data);
|
writePort8(PORT_PS2_DATA, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sendToFirstDevice(std::uint8_t cmd) noexcept
|
inline void sendToFirstDevice(std::uint8_t cmd) noexcept
|
||||||
{
|
{
|
||||||
waitForInputFree();
|
waitForInputFree();
|
||||||
writePortByte(PORT_PS2_DATA, cmd);
|
writePort8(PORT_PS2_DATA, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void sendToSecondDevice(std::uint8_t cmd) noexcept
|
inline void sendToSecondDevice(std::uint8_t cmd) noexcept
|
||||||
@ -401,11 +401,11 @@ inline void sendToSecondDevice(std::uint8_t cmd) noexcept
|
|||||||
bool initialize() noexcept
|
bool initialize() noexcept
|
||||||
{
|
{
|
||||||
// disable PS2
|
// disable PS2
|
||||||
writePortByte(PORT_PS2_STATUS, PS2_CMD_DISABLE_FIRST);
|
writePort8(PORT_PS2_STATUS, PS2_CMD_DISABLE_FIRST);
|
||||||
writePortByte(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND);
|
writePort8(PORT_PS2_STATUS, PS2_CMD_DISABLE_SECOND);
|
||||||
|
|
||||||
// flush output register
|
// flush output register
|
||||||
readPortByte(PORT_PS2_DATA);
|
readPort8(PORT_PS2_DATA);
|
||||||
|
|
||||||
// read configuration
|
// read configuration
|
||||||
std::uint8_t config = cmdWithResponse(PS2_CMD_READ_CONF_BYTE);
|
std::uint8_t config = cmdWithResponse(PS2_CMD_READ_CONF_BYTE);
|
||||||
@ -432,11 +432,11 @@ bool initialize() noexcept
|
|||||||
bool dualChannel = false;
|
bool dualChannel = false;
|
||||||
if ((config & PS2_CONFIGFLAG_CLOCK_SECOND) != 0) // it may be
|
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;
|
dualChannel = (cmdWithResponse(PS2_CMD_READ_CONF_BYTE) & PS2_CONFIGFLAG_CLOCK_SECOND) == 0;
|
||||||
if (dualChannel)
|
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
|
// enable devices
|
||||||
writePortByte(PORT_PS2_STATUS, PS2_CMD_ENABLE_FIRST);
|
writePort8(PORT_PS2_STATUS, PS2_CMD_ENABLE_FIRST);
|
||||||
if (dualChannel) {
|
if (dualChannel) {
|
||||||
writePortByte(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND);
|
writePort8(PORT_PS2_STATUS, PS2_CMD_ENABLE_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
@ -468,7 +468,7 @@ bool initialize() noexcept
|
|||||||
bool firstOk = false;
|
bool firstOk = false;
|
||||||
while (waitForResponse(10))
|
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) {
|
if (response == PS2_RESPONSE_SELFTEST_FAILED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -483,7 +483,7 @@ bool initialize() noexcept
|
|||||||
bool secondOk = false;
|
bool secondOk = false;
|
||||||
while (waitForResponse(10))
|
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) {
|
if (response == PS2_RESPONSE_SELFTEST_FAILED) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -501,7 +501,7 @@ __attribute__((interrupt))
|
|||||||
void isrKeyboard(InterruptFrame* interruptFrame) noexcept
|
void isrKeyboard(InterruptFrame* interruptFrame) noexcept
|
||||||
{
|
{
|
||||||
(void) interruptFrame;
|
(void) interruptFrame;
|
||||||
const std::uint8_t data = readPortByte(PORT_PS2_DATA);
|
const std::uint8_t data = readPort8(PORT_PS2_DATA);
|
||||||
if (data != 0)
|
if (data != 0)
|
||||||
{
|
{
|
||||||
pushKey(data);
|
pushKey(data);
|
||||||
|
@ -17,9 +17,9 @@ struct InterruptPrinter
|
|||||||
void putchar(char chr) noexcept // NOLINT
|
void putchar(char chr) noexcept // NOLINT
|
||||||
{
|
{
|
||||||
if (chr == '\n') {
|
if (chr == '\n') {
|
||||||
writePortByte(PORT_COM1, '\r');
|
writePort8(PORT_COM1, '\r');
|
||||||
}
|
}
|
||||||
writePortByte(PORT_COM1, static_cast<std::uint8_t>(chr));
|
writePort8(PORT_COM1, static_cast<std::uint8_t>(chr));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -17,21 +17,10 @@ size_t gTerminalColumn = 0;
|
|||||||
size_t gTerminalWidth = 0;
|
size_t gTerminalWidth = 0;
|
||||||
size_t gTerminalHeight = 0;
|
size_t gTerminalHeight = 0;
|
||||||
VgaDoubleColor gTerminalColor = VgaDoubleColor();
|
VgaDoubleColor gTerminalColor = VgaDoubleColor();
|
||||||
// uint16_t* gTerminalBuffer = reinterpret_cast<uint16_t*>(0xB8000);
|
|
||||||
std::vector<VgaCharacter> gTerminalBuffer;
|
std::vector<VgaCharacter> gTerminalBuffer;
|
||||||
psf::Font gTerminalFont;
|
psf::Font gTerminalFont;
|
||||||
std::string gReadBuffer;
|
std::string gReadBuffer;
|
||||||
|
|
||||||
constexpr uint8_t vgaEntryColor(VgaDoubleColor color)
|
|
||||||
{
|
|
||||||
return static_cast<uint8_t>(color.foreground) | static_cast<uint8_t>(color.background) << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
constexpr uint16_t vgaEntry(const unsigned char chr, const VgaDoubleColor color)
|
|
||||||
{
|
|
||||||
return static_cast<uint16_t>(chr) | static_cast<uint16_t>(vgaEntryColor(color) << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
void newline()
|
void newline()
|
||||||
{
|
{
|
||||||
gTerminalColumn = 0;
|
gTerminalColumn = 0;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "os/draw.hpp"
|
#include "os/draw.hpp"
|
||||||
#include "os/serial.hpp"
|
#include "os/serial.hpp"
|
||||||
#include "os/tty.hpp"
|
#include "os/tty.hpp"
|
||||||
|
#include "drivers/pci.hpp"
|
||||||
#include "drivers/pic.hpp"
|
#include "drivers/pic.hpp"
|
||||||
#include "drivers/ps2.hpp"
|
#include "drivers/ps2.hpp"
|
||||||
#include "./x86_64.hpp"
|
#include "./x86_64.hpp"
|
||||||
@ -245,18 +246,6 @@ void kernel_main()
|
|||||||
|
|
||||||
// __enterUsermode(SEGIDX_USER_CODE, SEGIDX_USER_DATA, &tss.rsp0, &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
|
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<unsigned>(event.scancode),
|
|
||||||
event.down ? "true" : "false",
|
|
||||||
event.repeat ? "true" : "false"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user