mirror of https://gitlab.com/nakst/essence
centralised list of io ports
This commit is contained in:
parent
411ff15698
commit
e546555787
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
//////////////////////////////////
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue