centralised list of io ports

This commit is contained in:
nakst 2021-10-24 13:56:17 +01:00
parent 411ff15698
commit e546555787
10 changed files with 177 additions and 173 deletions

View File

@ -1,4 +1,5 @@
#include <module.h>
#include <kernel/x86_64.h>
struct BGADisplay : KGraphicsTarget {
};
@ -38,8 +39,8 @@ void BGADeviceAttached(KDevice *_parent) {
return;
}
ProcessorOut16(0x01CE, 0 /* version */);
uint16_t version = ProcessorIn16(0x01CF);
ProcessorOut16(IO_BGA_INDEX, 0 /* version */);
uint16_t version = ProcessorIn16(IO_BGA_DATA);
KernelLog(LOG_INFO, "BGA", "version", "Detected version %X%X.\n", version >> 8, version);
if (version < 0xB0C0 || version > 0xB0C5) {
@ -48,25 +49,25 @@ void BGADeviceAttached(KDevice *_parent) {
}
// Set the mode.
ProcessorOut16(0x01CE, 4 /* enable */);
ProcessorOut16(0x01CF, 0);
ProcessorOut16(0x01CE, 1 /* x resolution */);
ProcessorOut16(0x01CF, BGA_RESOLUTION_WIDTH);
ProcessorOut16(0x01CE, 2 /* y resolution */);
ProcessorOut16(0x01CF, BGA_RESOLUTION_HEIGHT);
ProcessorOut16(0x01CE, 3 /* bpp */);
ProcessorOut16(0x01CF, 32);
ProcessorOut16(0x01CE, 4 /* enable */);
ProcessorOut16(0x01CF, 0x41 /* linear frame-buffer */);
ProcessorOut16(IO_BGA_INDEX, 4 /* enable */);
ProcessorOut16(IO_BGA_DATA, 0);
ProcessorOut16(IO_BGA_INDEX, 1 /* x resolution */);
ProcessorOut16(IO_BGA_DATA, BGA_RESOLUTION_WIDTH);
ProcessorOut16(IO_BGA_INDEX, 2 /* y resolution */);
ProcessorOut16(IO_BGA_DATA, BGA_RESOLUTION_HEIGHT);
ProcessorOut16(IO_BGA_INDEX, 3 /* bpp */);
ProcessorOut16(IO_BGA_DATA, 32);
ProcessorOut16(IO_BGA_INDEX, 4 /* enable */);
ProcessorOut16(IO_BGA_DATA, 0x41 /* linear frame-buffer */);
// Setup the graphics target.
device->updateScreen = BGAUpdateScreen;
device->debugPutBlock = BGADebugPutBlock;
device->debugClearScreen = BGADebugClearScreen;
ProcessorOut16(0x01CE, 1 /* x resolution */);
device->screenWidth = ProcessorIn16(0x01CF);
ProcessorOut16(0x01CE, 2 /* y resolution */);
device->screenHeight = ProcessorIn16(0x01CF);
ProcessorOut16(IO_BGA_INDEX, 1 /* x resolution */);
device->screenWidth = ProcessorIn16(IO_BGA_DATA);
ProcessorOut16(IO_BGA_INDEX, 2 /* y resolution */);
device->screenHeight = ProcessorIn16(IO_BGA_DATA);
// Register the display.
KernelLog(LOG_INFO, "BGA", "register target",

View File

@ -2,6 +2,7 @@
// TODO Inserting/removing ATAPI devices.
#include <module.h>
#include <kernel/x86_64.h>
#define ATA_BUSES 2
#define ATA_DRIVES (ATA_BUSES * 2)
@ -9,7 +10,7 @@
#define ATA_TIMEOUT (10000)
#define ATAPI_SECTOR_SIZE (2048)
#define ATA_REGISTER(_bus, _reg) (_reg != -1 ? ((_bus ? 0x170 : 0x1F0) + _reg) : (_bus ? 0x376 : 0x3F6))
#define ATA_REGISTER(_bus, _reg) (_reg != -1 ? ((_bus ? IO_ATA_1 : IO_ATA_2) + _reg) : (_bus ? IO_ATA_3 : IO_ATA_4))
#define ATA_IRQ(_bus) (_bus ? 15 : 14)
#define ATA_DATA 0
#define ATA_FEATURES 1

View File

@ -2,13 +2,7 @@
#include <module.h>
#define PCI_CONFIG (0xCF8)
#define PCI_DATA (0xCFC)
struct PCIController : KDevice {
inline uint32_t ReadConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, int size = 32);
inline void WriteConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value, int size = 32);
#define PCI_BUS_DO_NOT_SCAN 0
#define PCI_BUS_SCAN_NEXT 1
#define PCI_BUS_SCANNED 2
@ -174,65 +168,30 @@ void KPCIDevice::WriteBAR64(uintptr_t index, uintptr_t offset, uint64_t value) {
}
}
// Spinlock since some drivers need to access it in IRQs (e.g. ACPICA).
// Also can't be part of PCIController since PCI is initialised after ACPICA.
static KSpinlock configSpaceSpinlock;
static PCIController *pci;
uint32_t KPCIReadConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, int size) {
return pci->ReadConfig(bus, device, function, offset, size);
}
void KPCIWriteConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value, int size) {
pci->WriteConfig(bus, device, function, offset, value, size);
}
uint32_t PCIController::ReadConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, int size) {
KSpinlockAcquire(&configSpaceSpinlock);
EsDefer(KSpinlockRelease(&configSpaceSpinlock));
if (offset & 3) KernelPanic("PCIController::ReadConfig - offset is not 4-byte aligned.");
ProcessorOut32(PCI_CONFIG, (uint32_t) (0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset));
if (size == 8) return ProcessorIn8(PCI_DATA);
if (size == 16) return ProcessorIn16(PCI_DATA);
if (size == 32) return ProcessorIn32(PCI_DATA);
KernelPanic("PCIController::ReadConfig - Invalid size %d.\n", size);
return 0;
}
void PCIController::WriteConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value, int size) {
KSpinlockAcquire(&configSpaceSpinlock);
EsDefer(KSpinlockRelease(&configSpaceSpinlock));
if (offset & 3) KernelPanic("PCIController::WriteConfig - offset is not 4-byte aligned.");
ProcessorOut32(PCI_CONFIG, (uint32_t) (0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset));
if (size == 8) ProcessorOut8(PCI_DATA, value);
else if (size == 16) ProcessorOut16(PCI_DATA, value);
else if (size == 32) ProcessorOut32(PCI_DATA, value);
else KernelPanic("PCIController::WriteConfig - Invalid size %d.\n", size);
}
void KPCIDevice::WriteConfig8(uintptr_t offset, uint8_t value) {
pci->WriteConfig(bus, slot, function, offset, value, 8);
KPCIWriteConfig(bus, slot, function, offset, value, 8);
}
uint8_t KPCIDevice::ReadConfig8(uintptr_t offset) {
return pci->ReadConfig(bus, slot, function, offset, 8);
return KPCIReadConfig(bus, slot, function, offset, 8);
}
void KPCIDevice::WriteConfig16(uintptr_t offset, uint16_t value) {
pci->WriteConfig(bus, slot, function, offset, value, 16);
KPCIWriteConfig(bus, slot, function, offset, value, 16);
}
uint16_t KPCIDevice::ReadConfig16(uintptr_t offset) {
return pci->ReadConfig(bus, slot, function, offset, 16);
return KPCIReadConfig(bus, slot, function, offset, 16);
}
void KPCIDevice::WriteConfig32(uintptr_t offset, uint32_t value) {
pci->WriteConfig(bus, slot, function, offset, value, 32);
KPCIWriteConfig(bus, slot, function, offset, value, 32);
}
uint32_t KPCIDevice::ReadConfig32(uintptr_t offset) {
return pci->ReadConfig(bus, slot, function, offset, 32);
return KPCIReadConfig(bus, slot, function, offset, 32);
}
bool KPCIDevice::EnableSingleInterrupt(KIRQHandler irqHandler, void *context, const char *cOwnerName) {
@ -440,11 +399,11 @@ bool EnumeratePCIDrivers(KInstalledDriver *driver, KDevice *_device) {
}
void PCIController::EnumerateFunction(int bus, int device, int function, int *busesToScan) {
uint32_t deviceID = ReadConfig(bus, device, function, 0x00);
uint32_t deviceID = KPCIReadConfig(bus, device, function, 0x00);
if ((deviceID & 0xFFFF) == 0xFFFF) return;
uint32_t deviceClass = ReadConfig(bus, device, function, 0x08);
uint32_t interruptInformation = ReadConfig(bus, device, function, 0x3C);
uint32_t deviceClass = KPCIReadConfig(bus, device, function, 0x08);
uint32_t interruptInformation = KPCIReadConfig(bus, device, function, 0x3C);
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice));
if (!pciDevice) return;
@ -460,8 +419,8 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
pciDevice->interruptPin = (interruptInformation >> 8) & 0xFF;
pciDevice->interruptLine = (interruptInformation >> 0) & 0xFF;
pciDevice->deviceID = ReadConfig(bus, device, function, 0);
pciDevice->subsystemID = ReadConfig(bus, device, function, 0x2C);
pciDevice->deviceID = KPCIReadConfig(bus, device, function, 0);
pciDevice->subsystemID = KPCIReadConfig(bus, device, function, 0x2C);
for (int i = 0; i < 6; i++) {
pciDevice->baseAddresses[i] = pciDevice->ReadConfig32(0x10 + 4 * i);
@ -485,7 +444,7 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
pciDevice->interruptPin, pciDevice->interruptLine);
if (pciDevice->classCode == 0x06 && pciDevice->subclassCode == 0x04 /* PCI bridge */) {
uint8_t secondaryBus = (ReadConfig(bus, device, function, 0x18) >> 8) & 0xFF;
uint8_t secondaryBus = (KPCIReadConfig(bus, device, function, 0x18) >> 8) & 0xFF;
if (busScanStates[secondaryBus] == PCI_BUS_DO_NOT_SCAN) {
KernelLog(LOG_INFO, "PCI", "PCI bridge", "PCI bridge to bus %d.\n", secondaryBus);
@ -504,13 +463,13 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
}
void PCIController::Enumerate() {
uint32_t baseHeaderType = ReadConfig(0, 0, 0, 0x0C);
uint32_t baseHeaderType = KPCIReadConfig(0, 0, 0, 0x0C);
int baseBuses = (baseHeaderType & 0x80) ? 8 : 1;
int busesToScan = 0;
for (int baseBus = 0; baseBus < baseBuses; baseBus++) {
uint32_t deviceID = ReadConfig(0, 0, baseBus, 0x00);
uint32_t deviceID = KPCIReadConfig(0, 0, baseBus, 0x00);
if ((deviceID & 0xFFFF) == 0xFFFF) continue;
busScanStates[baseBus] = PCI_BUS_SCAN_NEXT;
busesToScan++;
@ -530,10 +489,10 @@ void PCIController::Enumerate() {
busesToScan--;
for (int device = 0; device < 32; device++) {
uint32_t deviceID = ReadConfig(bus, device, 0, 0x00);
uint32_t deviceID = KPCIReadConfig(bus, device, 0, 0x00);
if ((deviceID & 0xFFFF) == 0xFFFF) continue;
uint32_t headerType = (ReadConfig(bus, device, 0, 0x0C) >> 16) & 0xFF;
uint32_t headerType = (KPCIReadConfig(bus, device, 0, 0x0C) >> 16) & 0xFF;
int functions = (headerType & 0x80) ? 8 : 1;
for (int function = 0; function < functions; function++) {

View File

@ -1,6 +1,7 @@
// TODO Scrolling.
#include <module.h>
#include <kernel/x86_64.h>
struct PS2Update {
union {
@ -176,11 +177,6 @@ uint16_t scancodeConversionTable2[] = {
#define PS2_FIRST_IRQ (1)
#define PS2_SECOND_IRQ (12)
// Ports.
#define PS2_PORT_DATA (0x60)
#define PS2_PORT_STATUS (0x64)
#define PS2_PORT_COMMAND (0x64)
// Keyboard commands.
#define PS2_KEYBOARD_RESET (0xFF)
#define PS2_KEYBOARD_ENABLE (0xF4)
@ -217,16 +213,16 @@ void PS2KeyboardUpdated(EsGeneric _update) {
}
void PS2::WaitInputBuffer() {
while (ProcessorIn8(PS2_PORT_STATUS) & PS2_INPUT_FULL);
while (ProcessorIn8(IO_PS2_STATUS) & PS2_INPUT_FULL);
}
bool PS2::PollRead(uint8_t *value, bool forMouse) {
uint8_t status = ProcessorIn8(PS2_PORT_STATUS);
uint8_t status = ProcessorIn8(IO_PS2_STATUS);
if (status & PS2_MOUSE_BYTE && !forMouse) return false;
if (!(status & PS2_MOUSE_BYTE) && forMouse) return false;
if (status & PS2_OUTPUT_FULL) {
*value = ProcessorIn8(PS2_PORT_DATA);
*value = ProcessorIn8(IO_PS2_DATA);
if (*value == 0xE1 && !forMouse) {
KDebugKeyPressed();
@ -382,60 +378,60 @@ bool PS2IRQHandler(uintptr_t interruptIndex, void *) {
void PS2::DisableDevices(unsigned which) {
WaitInputBuffer();
// EsPrint("ps2 first write...\n");
if (which & 1) ProcessorOut8(PS2_PORT_COMMAND, PS2_DISABLE_FIRST);
if (which & 1) ProcessorOut8(IO_PS2_COMMAND, PS2_DISABLE_FIRST);
// EsPrint("ps2 first write end\n");
WaitInputBuffer();
if (which & 2) ProcessorOut8(PS2_PORT_COMMAND, PS2_DISABLE_SECOND);
if (which & 2) ProcessorOut8(IO_PS2_COMMAND, PS2_DISABLE_SECOND);
}
void PS2::EnableDevices(unsigned which) {
WaitInputBuffer();
if (which & 1) ProcessorOut8(PS2_PORT_COMMAND, PS2_ENABLE_FIRST);
if (which & 1) ProcessorOut8(IO_PS2_COMMAND, PS2_ENABLE_FIRST);
WaitInputBuffer();
if (which & 2) ProcessorOut8(PS2_PORT_COMMAND, PS2_ENABLE_SECOND);
if (which & 2) ProcessorOut8(IO_PS2_COMMAND, PS2_ENABLE_SECOND);
}
void PS2::FlushOutputBuffer() {
while (ProcessorIn8(PS2_PORT_STATUS) & PS2_OUTPUT_FULL) {
ProcessorIn8(PS2_PORT_DATA);
while (ProcessorIn8(IO_PS2_STATUS) & PS2_OUTPUT_FULL) {
ProcessorIn8(IO_PS2_DATA);
}
}
void PS2::SendCommand(uint8_t command) {
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, command);
ProcessorOut8(IO_PS2_COMMAND, command);
}
uint8_t PS2::ReadByte(KTimeout *timeout) {
while (!(ProcessorIn8(PS2_PORT_STATUS) & PS2_OUTPUT_FULL) && !timeout->Hit());
return ProcessorIn8(PS2_PORT_DATA);
while (!(ProcessorIn8(IO_PS2_STATUS) & PS2_OUTPUT_FULL) && !timeout->Hit());
return ProcessorIn8(IO_PS2_DATA);
}
void PS2::WriteByte(KTimeout *timeout, uint8_t value) {
while ((ProcessorIn8(PS2_PORT_STATUS) & PS2_INPUT_FULL) && !timeout->Hit());
while ((ProcessorIn8(IO_PS2_STATUS) & PS2_INPUT_FULL) && !timeout->Hit());
if (timeout->Hit()) return;
ProcessorOut8(PS2_PORT_DATA, value);
ProcessorOut8(IO_PS2_DATA, value);
}
bool PS2::SetupKeyboard(KTimeout *timeout) {
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_KEYBOARD_ENABLE);
ProcessorOut8(IO_PS2_DATA, PS2_KEYBOARD_ENABLE);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_KEYBOARD_SCANCODE_SET);
ProcessorOut8(IO_PS2_DATA, PS2_KEYBOARD_SCANCODE_SET);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, 0);
ProcessorOut8(IO_PS2_DATA, 0);
if (ReadByte(timeout) != 0xFA) return false;
scancodeSet = ReadByte(timeout) & 3;
KernelLog(LOG_INFO, "PS/2", "scancode set", "Keyboard reports it is using scancode set %d.\n", scancodeSet);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_KEYBOARD_REPEAT);
ProcessorOut8(IO_PS2_DATA, PS2_KEYBOARD_REPEAT);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, 0);
ProcessorOut8(IO_PS2_DATA, 0);
if (ReadByte(timeout) != 0xFA) return false;
return true;
@ -443,14 +439,14 @@ bool PS2::SetupKeyboard(KTimeout *timeout) {
bool PS2::SetMouseRate(KTimeout *timeout, int rate) {
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_MOUSE_SAMPLE_RATE);
ProcessorOut8(IO_PS2_DATA, PS2_MOUSE_SAMPLE_RATE);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, rate);
ProcessorOut8(IO_PS2_DATA, rate);
if (ReadByte(timeout) != 0xFA) return false;
return true;
}
@ -459,9 +455,9 @@ bool PS2::SetupMouse(KTimeout *timeout) {
// TODO Mouse with scroll wheel detection.
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_MOUSE_RESET);
ProcessorOut8(IO_PS2_DATA, PS2_MOUSE_RESET);
if (ReadByte(timeout) != 0xFA) return false;
if (ReadByte(timeout) != 0xAA) return false;
if (ReadByte(timeout) != 0x00) return false;
@ -469,26 +465,26 @@ bool PS2::SetupMouse(KTimeout *timeout) {
if (!SetMouseRate(timeout, 100)) return false;
if (!SetMouseRate(timeout, 80)) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, 0xF2);
ProcessorOut8(IO_PS2_DATA, 0xF2);
if (ReadByte(timeout) != 0xFA) return false;
mouseType = ReadByte(timeout);
if (!SetMouseRate(timeout, 100)) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_MOUSE_RESOLUTION);
ProcessorOut8(IO_PS2_DATA, PS2_MOUSE_RESOLUTION);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, 3);
ProcessorOut8(IO_PS2_DATA, 3);
if (ReadByte(timeout) != 0xFA) return false;
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_SECOND);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_DATA, PS2_MOUSE_ENABLE);
ProcessorOut8(IO_PS2_DATA, PS2_MOUSE_ENABLE);
if (ReadByte(timeout) != 0xFA) return false;
return true;
@ -515,10 +511,10 @@ void PS2::Initialise(KDevice *parentDevice) {
FlushOutputBuffer();
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_READ_CONFIG);
ProcessorOut8(IO_PS2_COMMAND, PS2_READ_CONFIG);
uint8_t configurationByte = ReadByte(&timeout);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_CONFIG);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_CONFIG);
WriteByte(&timeout, configurationByte & ~(PS2_FIRST_IRQ_MASK | PS2_SECOND_IRQ_MASK | PS2_TRANSLATION));
if (timeout.Hit()) return;
@ -529,7 +525,7 @@ void PS2::Initialise(KDevice *parentDevice) {
if (configurationByte & PS2_SECOND_CLOCK) {
EnableDevices(2);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_READ_CONFIG);
ProcessorOut8(IO_PS2_COMMAND, PS2_READ_CONFIG);
configurationByte = ReadByte(&timeout);
if (!(configurationByte & PS2_SECOND_CLOCK)) {
hasMouse = true;
@ -539,7 +535,7 @@ void PS2::Initialise(KDevice *parentDevice) {
{
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_TEST_FIRST);
ProcessorOut8(IO_PS2_COMMAND, PS2_TEST_FIRST);
uint8_t b = ReadByte(&timeout);
if (b) return;
if (timeout.Hit()) return;
@ -548,7 +544,7 @@ void PS2::Initialise(KDevice *parentDevice) {
if (hasMouse) {
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_TEST_SECOND);
ProcessorOut8(IO_PS2_COMMAND, PS2_TEST_SECOND);
if (!ReadByte(&timeout) && !timeout.Hit()) channels = 2;
}
@ -565,10 +561,10 @@ void PS2::Initialise(KDevice *parentDevice) {
{
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_READ_CONFIG);
ProcessorOut8(IO_PS2_COMMAND, PS2_READ_CONFIG);
uint8_t configurationByte = ReadByte(&timeout);
WaitInputBuffer();
ProcessorOut8(PS2_PORT_COMMAND, PS2_WRITE_CONFIG);
ProcessorOut8(IO_PS2_COMMAND, PS2_WRITE_CONFIG);
WriteByte(&timeout, configurationByte | PS2_FIRST_IRQ_MASK | PS2_SECOND_IRQ_MASK);
}

View File

@ -11,10 +11,10 @@ uint8_t RTCRead(uint8_t index, bool convertFromBCD, bool convertFrom12Hour) {
for (uint8_t i = 0; i < 10; i++) {
// Write the index a few times to delay before reading.
ProcessorOut8(0x70, index);
ProcessorOut8(IO_RTC_INDEX, index);
}
uint8_t value = ProcessorIn8(0x71);
uint8_t value = ProcessorIn8(IO_RTC_DATA);
if (convertFromBCD) {
value = (value >> 4) * 10 + (value & 0xF);

View File

@ -129,28 +129,6 @@ void InitialiseVBE(KDevice *parent) {
#if 0
#define VGA_AC_INDEX 0x3C0
#define VGA_AC_WRITE 0x3C0
#define VGA_AC_READ 0x3C1
#define VGA_MISC_WRITE 0x3C2
#define VGA_MISC_READ 0x3CC
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_DAC_READ_INDEX 0x3C7
#define VGA_DAC_WRITE_INDEX 0x3C8
#define VGA_DAC_DATA 0x3C9
#define VGA_GC_INDEX 0x3CE
#define VGA_GC_DATA 0x3CF
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
#define VGA_INSTAT_READ 0x3DA
uint8_t vgaMode18[] = {
0xE3, 0x03, 0x01, 0x08, 0x00, 0x06, 0x5F, 0x4F,
0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40,
@ -182,8 +160,8 @@ void VGAUpdateScreen(uint8_t *_source, uint8_t *modifiedScanlineBitset, KModifie
for (int plane = 0; plane < 4; plane++) {
uint8_t *source = _source;
ProcessorOut8(VGA_SEQ_INDEX, 2);
ProcessorOut8(VGA_SEQ_DATA, 1 << plane);
ProcessorOut8(IO_VGA_SEQ_INDEX, 2);
ProcessorOut8(IO_VGA_SEQ_DATA, 1 << plane);
for (uintptr_t y_ = 0; y_ < VGA_SCREEN_HEIGHT / 8; y_++) {
if (modifiedScanlineBitset[y_] == 0) {
@ -227,8 +205,8 @@ void VGAUpdateScreen(uint8_t *_source, uint8_t *modifiedScanlineBitset, KModifie
void VGAPutBlock(uintptr_t x, uintptr_t y, bool toggle) {
for (int plane = 0; plane < 4; plane++) {
ProcessorOut8(VGA_SEQ_INDEX, 2);
ProcessorOut8(VGA_SEQ_DATA, 1 << plane);
ProcessorOut8(IO_VGA_SEQ_INDEX, 2);
ProcessorOut8(IO_VGA_SEQ_DATA, 1 << plane);
if (toggle) {
vgaAddress[y * 80 + x / 8] ^= 1 << (7 - (x & 7));
@ -240,8 +218,8 @@ void VGAPutBlock(uintptr_t x, uintptr_t y, bool toggle) {
void VGAClearScreen() {
for (int plane = 0; plane < 4; plane++) {
ProcessorOut8(VGA_SEQ_INDEX, 2);
ProcessorOut8(VGA_SEQ_DATA, 1 << plane);
ProcessorOut8(IO_VGA_SEQ_INDEX, 2);
ProcessorOut8(IO_VGA_SEQ_DATA, 1 << plane);
EsMemoryZero((void *) vgaAddress, VGA_SCREEN_WIDTH / 8 * VGA_SCREEN_HEIGHT);
}
}
@ -253,19 +231,19 @@ void InitialiseVGA(KDevice *parent) {
vgaAddress = (uint8_t *) MMMapPhysical(MMGetKernelSpace(), 0xA0000, 0x10000, MM_REGION_WRITE_COMBINING);
uint8_t *registers = vgaMode18;
ProcessorOut8(VGA_MISC_WRITE, *registers++);
for (int i = 0; i < 5; i++) { ProcessorOut8(VGA_SEQ_INDEX, i); ProcessorOut8(VGA_SEQ_DATA, *registers++); }
ProcessorOut8(VGA_CRTC_INDEX, 0x03);
ProcessorOut8(VGA_CRTC_DATA, ProcessorIn8(VGA_CRTC_DATA) | 0x80);
ProcessorOut8(VGA_CRTC_INDEX, 0x11);
ProcessorOut8(VGA_CRTC_DATA, ProcessorIn8(VGA_CRTC_DATA) & ~0x80);
ProcessorOut8(IO_VGA_MISC_WRITE, *registers++);
for (int i = 0; i < 5; i++) { ProcessorOut8(IO_VGA_SEQ_INDEX, i); ProcessorOut8(IO_VGA_SEQ_DATA, *registers++); }
ProcessorOut8(IO_VGA_CRTC_INDEX, 0x03);
ProcessorOut8(IO_VGA_CRTC_DATA, ProcessorIn8(IO_VGA_CRTC_DATA) | 0x80);
ProcessorOut8(IO_VGA_CRTC_INDEX, 0x11);
ProcessorOut8(IO_VGA_CRTC_DATA, ProcessorIn8(IO_VGA_CRTC_DATA) & ~0x80);
registers[0x03] |= 0x80;
registers[0x11] &= ~0x80;
for (int i = 0; i < 25; i++) { ProcessorOut8(VGA_CRTC_INDEX, i); ProcessorOut8(VGA_CRTC_DATA, *registers++); }
for (int i = 0; i < 9; i++) { ProcessorOut8(VGA_GC_INDEX, i); ProcessorOut8(VGA_GC_DATA, *registers++); }
for (int i = 0; i < 21; i++) { ProcessorIn8(VGA_INSTAT_READ); ProcessorOut8(VGA_AC_INDEX, i); ProcessorOut8(VGA_AC_WRITE, *registers++); }
ProcessorIn8(VGA_INSTAT_READ);
ProcessorOut8(VGA_AC_INDEX, 0x20);
for (int i = 0; i < 25; i++) { ProcessorOut8(IO_VGA_CRTC_INDEX, i); ProcessorOut8(IO_VGA_CRTC_DATA, *registers++); }
for (int i = 0; i < 9; i++) { ProcessorOut8(IO_VGA_GC_INDEX, i); ProcessorOut8(IO_VGA_GC_DATA, *registers++); }
for (int i = 0; i < 21; i++) { ProcessorIn8(IO_VGA_INSTAT_READ); ProcessorOut8(IO_VGA_AC_INDEX, i); ProcessorOut8(IO_VGA_AC_WRITE, *registers++); }
ProcessorIn8(IO_VGA_INSTAT_READ);
ProcessorOut8(IO_VGA_AC_INDEX, 0x20);
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget));
target->screenWidth = VGA_SCREEN_WIDTH;

View File

@ -153,13 +153,12 @@ KSpinlock ipiLock;
#include "files.cpp"
#include "windows.cpp"
#include "networking.cpp"
#include "terminal.cpp"
#ifdef ENABLE_POSIX_SUBSYSTEM
#include "posix.cpp"
#endif
#include "terminal.cpp"
#ifdef IMPLEMENTATION
//////////////////////////////////

View File

@ -664,16 +664,16 @@ uint64_t ArchGetTimeFromPITMs() {
static uint64_t cumulative = 0, last = 0;
if (!started) {
ProcessorOut8(0x43, 0x30);
ProcessorOut8(0x40, 0xFF);
ProcessorOut8(0x40, 0xFF);
ProcessorOut8(IO_PIT_COMMAND, 0x30);
ProcessorOut8(IO_PIT_DATA, 0xFF);
ProcessorOut8(IO_PIT_DATA, 0xFF);
started = true;
last = 0xFFFF;
return 0;
} else {
ProcessorOut8(0x43, 0x00);
uint16_t x = ProcessorIn8(0x40);
x |= (ProcessorIn8(0x40)) << 8;
ProcessorOut8(IO_PIT_COMMAND, 0x00);
uint16_t x = ProcessorIn8(IO_PIT_DATA);
x |= (ProcessorIn8(IO_PIT_DATA)) << 8;
cumulative += last - x;
if (x > last) cumulative += 0x10000;
last = x;
@ -682,14 +682,14 @@ uint64_t ArchGetTimeFromPITMs() {
}
void ArchDelay1Ms() {
ProcessorOut8(0x43, 0x30);
ProcessorOut8(0x40, 0xA9);
ProcessorOut8(0x40, 0x04);
ProcessorOut8(IO_PIT_COMMAND, 0x30);
ProcessorOut8(IO_PIT_DATA, 0xA9);
ProcessorOut8(IO_PIT_DATA, 0x04);
while (true) {
ProcessorOut8(0x43, 0xE2);
ProcessorOut8(IO_PIT_COMMAND, 0xE2);
if (ProcessorIn8(0x40) & (1 << 7)) {
if (ProcessorIn8(IO_PIT_DATA) & (1 << 7)) {
break;
}
}
@ -1307,4 +1307,30 @@ uintptr_t GetBootloaderInformationOffset() {
return bootloaderInformationOffset;
}
// Spinlock since some drivers need to access it in IRQs (e.g. ACPICA).
static KSpinlock pciConfigSpinlock;
uint32_t KPCIReadConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, int size) {
KSpinlockAcquire(&pciConfigSpinlock);
EsDefer(KSpinlockRelease(&pciConfigSpinlock));
if (offset & 3) KernelPanic("KPCIReadConfig - offset is not 4-byte aligned.");
ProcessorOut32(IO_PCI_CONFIG, (uint32_t) (0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset));
if (size == 8) return ProcessorIn8(IO_PCI_DATA);
if (size == 16) return ProcessorIn16(IO_PCI_DATA);
if (size == 32) return ProcessorIn32(IO_PCI_DATA);
KernelPanic("PCIController::ReadConfig - Invalid size %d.\n", size);
return 0;
}
void KPCIWriteConfig(uint8_t bus, uint8_t device, uint8_t function, uint8_t offset, uint32_t value, int size) {
KSpinlockAcquire(&pciConfigSpinlock);
EsDefer(KSpinlockRelease(&pciConfigSpinlock));
if (offset & 3) KernelPanic("KPCIWriteConfig - offset is not 4-byte aligned.");
ProcessorOut32(IO_PCI_CONFIG, (uint32_t) (0x80000000 | (bus << 16) | (device << 11) | (function << 8) | offset));
if (size == 8) ProcessorOut8(IO_PCI_DATA, value);
else if (size == 16) ProcessorOut16(IO_PCI_DATA, value);
else if (size == 32) ProcessorOut32(IO_PCI_DATA, value);
else KernelPanic("PCIController::WriteConfig - Invalid size %d.\n", size);
}
#endif

View File

@ -4,6 +4,50 @@
#define LOW_MEMORY_MAP_START (0xFFFFFE0000000000)
#define LOW_MEMORY_LIMIT (0x100000) // The first 1MB is mapped here.
// --------------------------------- Standardised IO ports.
#define IO_PIC_1_COMMAND (0x0020)
#define IO_PIC_1_DATA (0x0021)
#define IO_PIT_DATA (0x0040)
#define IO_PIT_COMMAND (0x0043)
#define IO_PS2_DATA (0x0060)
#define IO_PC_SPEAKER (0x0061)
#define IO_PS2_STATUS (0x0064)
#define IO_PS2_COMMAND (0x0064)
#define IO_RTC_INDEX (0x0070)
#define IO_RTC_DATA (0x0071)
#define IO_PIC_2_COMMAND (0x00A0)
#define IO_PIC_2_DATA (0x00A1)
#define IO_BGA_INDEX (0x01CE)
#define IO_BGA_DATA (0x01CF)
#define IO_ATA_1 (0x0170) // To 0x0177.
#define IO_ATA_2 (0x01F0) // To 0x01F7.
#define IO_COM_4 (0x02E8) // To 0x02EF.
#define IO_COM_2 (0x02F8) // To 0x02FF.
#define IO_ATA_3 (0x0376)
#define IO_VGA_AC_INDEX (0x03C0)
#define IO_VGA_AC_WRITE (0x03C0)
#define IO_VGA_AC_READ (0x03C1)
#define IO_VGA_MISC_WRITE (0x03C2)
#define IO_VGA_MISC_READ (0x03CC)
#define IO_VGA_SEQ_INDEX (0x03C4)
#define IO_VGA_SEQ_DATA (0x03C5)
#define IO_VGA_DAC_READ_INDEX (0x03C7)
#define IO_VGA_DAC_WRITE_INDEX (0x03C8)
#define IO_VGA_DAC_DATA (0x03C9)
#define IO_VGA_GC_INDEX (0x03CE)
#define IO_VGA_GC_DATA (0x03CF)
#define IO_VGA_CRTC_INDEX (0x03D4)
#define IO_VGA_CRTC_DATA (0x03D5)
#define IO_VGA_INSTAT_READ (0x03DA)
#define IO_COM_3 (0x03E8) // To 0x03EF.
#define IO_ATA_4 (0x03F6)
#define IO_COM_1 (0x03F8) // To 0x03FF.
#define IO_PCI_CONFIG (0x0CF8)
#define IO_PCI_DATA (0x0CFC)
// --------------------------------- Forward declarations.
extern "C" uint64_t ProcessorReadCR3();
extern "C" void gdt_data();

Binary file not shown.