...
 
Commits (10)
......@@ -6,11 +6,13 @@ list(TRANSFORM MODDIRS REPLACE "/${MODDIR_TAG}$" "")
file(WRITE ${CMAKE_BINARY_DIR}/modules.s ".section .modules, \"a\"\n")
file(APPEND ${CMAKE_BINARY_DIR}/modules.s ".global __modules_start__\n__modules_start__:\n")
add_library(modules-linked STATIC ${CMAKE_BINARY_DIR}/modules.s)
file(GLOB MODINC ${SRCDIR}/modules/include)
foreach(moddir ${MODDIRS})
string(REPLACE "/" "." mod ${moddir})
set(ROOT_${mod} ${SRCDIR}/${moddir})
file(GLOB SRCS_${mod} ${ROOT_${mod}}/*.s ${ROOT_${mod}}/*.c ${ROOT_${mod}}/*.cpp)
add_library(mod_${mod} SHARED ${SRCS_${mod}})
target_include_directories(mod_${mod} PRIVATE ${MODINC})
add_custom_command(
TARGET mod_${mod} POST_BUILD
COMMAND ${CMAKE_LLVM_OBJCOPY} --strip-non-alloc --strip-debug --strip-unneeded libmod_${mod}.so libmod_${mod}.strip.so
......
......@@ -7,6 +7,38 @@
namespace EFI {
const struct EFI::SystemTable *SystemTable = nullptr;
const void *ImageHandle = nullptr;
const void *acpi1 = nullptr, *acpi2 = nullptr;
void load();
Framebuffer fb, *fbPtr = nullptr;
}
const struct EFI::SystemTable *EFI::getSystemTable() { return SystemTable; }
const struct EFI::SystemTable *EFI::getSystemTable() { load(); return SystemTable; }
const void *EFI::getImageHandle() { return ImageHandle; }
const void *EFI::getACPI1Addr() { return acpi1; }
const void *EFI::getACPI2Addr() { return acpi2; }
const struct EFI::Framebuffer *EFI::getFramebuffer() { return fbPtr; }
void EFI::load() {
static bool loaded = false;
if (loaded || !SystemTable) return;
if (SystemTable->ConfigurationTable) {
for (uint64_t i = 0; i < SystemTable->NumberOfTableEntries; i++) {
const EFI::ConfigurationTable *tbl = SystemTable->ConfigurationTable + i;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI1) acpi1 = tbl->VendorTable;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI2) acpi2 = tbl->VendorTable;
}
}
EFI::GraphicsOutput *graphics_output = nullptr;
SystemTable->BootServices->LocateProtocol(
&EFI::GUID_GraphicsOutputProtocol, nullptr,
reinterpret_cast<void**>(&graphics_output));
if (graphics_output) {
fb.base = graphics_output->Mode->FrameBufferBase;
fb.width = graphics_output->Mode->Info->HorizontalResolution;
fb.height = graphics_output->Mode->Info->VerticalResolution;
fb.pixelFormat = graphics_output->Mode->Info->PixelFormat;
fbPtr = &fb;
}
loaded = true;
}
......@@ -332,6 +332,14 @@ namespace EFI {
};
const struct SystemTable *getSystemTable() PURE;
const void *getImageHandle() PURE;
const void *getACPI1Addr() PURE;
const void *getACPI2Addr() PURE;
struct Framebuffer {
void *base;
size_t width, height;
GraphicsPixelFormat pixelFormat;
};
const Framebuffer *getFramebuffer() PURE;
}; // namespace EFI
static inline bool operator ==(const EFI::GUID &lhs, const EFI::GUID &rhs) {
......
......@@ -187,14 +187,10 @@ static Display *getSerialDisplay() { return &serialConsole; }
void Display::setup() {
if (instance != &serialConsole) return;
const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST) { // EFI Framebuffer
EFI::GraphicsOutput *graphics_output = nullptr;
ST->BootServices->LocateProtocol(
&EFI::GUID_GraphicsOutputProtocol, nullptr,
reinterpret_cast<void**>(&graphics_output));
const struct EFI::Framebuffer *fb = EFI::getFramebuffer();
if (fb) { // EFI Framebuffer
PixelFormat pixelFormat;
switch (graphics_output->Mode->Info->PixelFormat) {
switch (fb->pixelFormat) {
case EFI::GRAPHICS_PIXEL_FORMAT_RGBX_8BPP:
pixelFormat = PixelFormatRGBX;
break;
......@@ -204,11 +200,7 @@ void Display::setup() {
default:
return;
}
instance = new FramebufferDisplay(
graphics_output->Mode->FrameBufferBase,
graphics_output->Mode->Info->HorizontalResolution,
graphics_output->Mode->Info->VerticalResolution,
pixelFormat);
instance = new FramebufferDisplay(fb->base, fb->width, fb->height, pixelFormat);
return;
}
......
......@@ -21,6 +21,8 @@ namespace klib {
size_t strlen(const char*, size_t limit = static_cast<size_t>(-1)) PURE;
char* strdup(const char*);
char* strndup(const char*, size_t len);
int strncmp(const char*, const char*, int) PURE;
int strcmp(const char*, const char*) PURE;
inline static uintptr_t __align(uintptr_t base, size_t align) {
......
......@@ -24,6 +24,18 @@ namespace klib {
return r;
}
char* strndup(const char* c, size_t len) {
char* r = new char[len + 1]();
Memory::copy(r, c, len);
r[len] = 0;
return r;
}
int strncmp(const char* a, const char* b, int max) {
size_t i = 0;
while (i < size_t(max) && a[i] != 0 && b[i] != 0 && a[i] == b[i]) { i++; }
return (i < size_t(max)) ? a[i] - b[i] : 0;
}
int strcmp(const char* a, const char* b) {
size_t i = 0;
while (a[i] != 0 && b[i] != 0 && a[i] == b[i]) { i++; }
......
// PhoeniX OS Stub hello module
// Copyright © 2019 Yury Popov a.k.a. PhoeniX
#include "kernmod.hpp"
MODDESC(name, "Driver/PCI");
MODDESC(version, "1.0");
MODDESC(description, "Generic PCI Driver");
MODDESC(requirements, "port/CF8-CFF");
MODDESC(developer, "PhoeniX");
static inline void putl(uint32_t l) {
char buf[11];
int off = 10;
buf[off] = 0;
while (off == 10 || l > 0) {
buf[--off] = '0' + (l % 10);
l /= 10;
}
puts(buf + off);
}
static inline void putx(uint32_t l) {
char buf[9];
int off = 8;
buf[off] = 0;
while (off == 8 || l > 0) {
char c = static_cast<char>(l & 0xF);
buf[--off] = (c < 10) ? ('0' + c) : ('a' + c - 10);
l /= 16;
c = static_cast<char>(l & 0xF);
buf[--off] = (c < 10) ? ('0' + c) : ('a' + c - 10);
l /= 16;
}
puts(buf + off);
}
namespace PCI {
static inline uint32_t readConfig32(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
uint32_t address, value;
address = 0x80000000u |
(uint32_t(bus) << 16) |
(uint32_t(slot) << 11) |
(uint32_t(func) << 8) |
(uint32_t(offset) & 0xFC);
asm volatile(
"mov $0xCF8, %%dx\n"
"outl %%eax, %%dx\n"
"add $4, %%dx\n"
"inl %%dx, %%eax"
:"=a"(value):"a"(address):"dx");
return value;
}
struct Device {
uint16_t vendor, device;
uint16_t command, status;
uint8_t revision, prog_if, subclass, classcode;
uint8_t cache_line_size, latency_timer, header_type, bist;
union {
struct {
uint32_t bar[6];
uint32_t cardbus_cis;
uint16_t subsystem_vendor, subsystem_id;
uint32_t rom_base;
uint8_t caps_ptr, rsvd[3+4];
uint8_t intr_line, intr_pin, min_grant, max_latency;
} __attribute__((packed)) device;
struct {
uint32_t bar[2];
uint8_t prim_bus_num, sec_bus_num, sub_bus_num, sec_latency_timer;
uint8_t iobase, iolimit; uint16_t sec_status;
uint16_t membase, memlim;
uint16_t pref_membase, pref_memlim;
uint32_t pref_membase_u32;
uint32_t pref_memlim_u32;
uint16_t iobase_u16, iolim_u16;
uint8_t caps_ptr, rsvd[3];
uint32_t rom_base;
uint8_t intr_line, intr_pin; uint16_t bridgectl;
} __attribute__((packed)) pcibridge;
struct {
uint32_t cardbus_sock_exca_base;
uint8_t cap_off, rsvd; uint16_t sec_status;
uint8_t pci_bus_num, cardbus_bus_num, sub_bus_num, cardbus_lat_timer;
uint32_t membase0, memlim0;
uint32_t membase1, memlim1;
uint32_t iobase0, iolim0;
uint32_t iobase1, iolim1;
uint8_t intr_line, intr_pin, bridgectl;
uint16_t sub_device, sub_vendor;
uint32_t pccard_base;
} __attribute__((packed)) cardbusbridge;
} __attribute__((packed)) _spec;
template<typename T> static inline T read(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) {
return T(readConfig32(bus, slot, func, offset) >> ((offset & 0x3) * 8));
}
static inline uint8_t getHeaderType(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, header_type));
}
static inline uint16_t getVendorID(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint16_t>(bus, slot, func, offsetof(Device, vendor));
}
static inline uint16_t getDeviceID(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint16_t>(bus, slot, func, offsetof(Device, device));
}
static inline uint8_t getBaseClass(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, classcode));
}
static inline uint8_t getSubClass(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, subclass));
}
static inline uint8_t getProgIf(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, prog_if));
}
static inline uint8_t getRevision(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, revision));
}
static inline uint8_t getSecondaryBus(uint8_t bus, uint8_t slot, uint8_t func) {
return read<uint8_t>(bus, slot, func, offsetof(Device, _spec.pcibridge.sec_bus_num));
}
} __attribute__((packed));
static void provideDevice(uint8_t bus, uint8_t device, uint8_t function) {
uint8_t baseClass = Device::getBaseClass(bus, device, function);
uint8_t subClass = Device::getSubClass(bus, device, function);
uint8_t progIf = Device::getProgIf(bus, device, function);
uint8_t rev = Device::getRevision(bus, device, function);
puts("TODO: Provide device: ");
uint16_t vendorID = Device::getVendorID(bus, device, function);
uint16_t deviceId = Device::getDeviceID(bus, device, function);
putl(bus); puts("."); putl(device); puts("."); putl(function); puts(" => ");
puts("["); putx(uint32_t(baseClass << 8) | subClass); puts("."); putx(progIf); puts("."); putx(rev); puts("]");
putx(vendorID); puts("."); putx(deviceId);
puts("\n");
}
static void scanBus(uint8_t bus);
static void scanFunction(uint8_t bus, uint8_t device, uint8_t function) {
uint8_t baseClass = Device::getBaseClass(bus, device, function);
uint8_t subClass = Device::getSubClass(bus, device, function);
if ((baseClass == 0x06) && (subClass == 0x04)) {
uint8_t secondaryBus = Device::getSecondaryBus(bus, device, function);
scanBus(secondaryBus);
} else {
provideDevice(bus, device, function);
}
}
static void scanDevice(uint8_t bus, uint8_t device) {
uint8_t function = 0;
uint16_t vendorID = Device::getVendorID(bus, device, function);
if (vendorID == 0xFFFF) return;
scanFunction(bus, device, function);
uint8_t headerType = Device::getHeaderType(bus, device, function);
if ((headerType & 0x80) != 0) {
for (function = 1; function < 8; function++) {
if (Device::getVendorID(bus, device, function) != 0xFFFF) {
scanFunction(bus, device, function);
}
}
}
}
static void scanBus(uint8_t bus) {
static uint64_t checked = 0;
if (checked & (1llu << bus)) return;
checked |= (1llu << bus);
for (uint8_t device = 0; device < 32; device++) {
scanDevice(bus, device);
}
}
static void scanAllBuses() {
uint8_t headerType = Device::getHeaderType(0, 0, 0);
if ((headerType & 0x80) == 0) {
scanBus(0);
} else {
for (uint8_t function = 0; function < 8; function++) {
if (Device::getVendorID(0, 0, function) != 0xFFFF) break;
scanBus(function);
}
}
}
} // namespace PCI
void module() {
PCI::scanAllBuses();
exit(0);
}
// PhoeniX OS Stub hello module
// Copyright © 2017 Yury Popov a.k.a. PhoeniX
#define MODDESC(k, v) \
extern const char \
__attribute__((section(".module"))) \
__attribute__((aligned(1))) \
module_ ## k[] = v; \
MODDESC(name, "Test/Hello");
MODDESC(version, "1.0");
MODDESC(description, "Prints \"Hello, world\" text");
MODDESC(requirements, "");
MODDESC(developer, "PhoeniX");
extern "C" { void module(); void puts(const char *); void exit(int); }
void module() {
puts("Hello, ");
puts("world!\n");
exit(0);
}
// PhoeniX OS module includes
// Copyright © 2019 Yury Popov a.k.a. PhoeniX
#include <stdint.h>
#include <stddef.h>
#define MODDESC(k, v) \
extern const char \
__attribute__((section(".module"),aligned(1))) \
module_ ## k[] = v;
extern "C" {
// Syscalls
void puts(const char *);
void exit(int);
// Entry point
void module();
}
......@@ -22,51 +22,57 @@ ACPI* ACPI::getController() {
}
ACPI::ACPI() {
static const void *const ACPI_FIND_START = reinterpret_cast<char*>(0x000e0000);
static const void *const ACPI_FIND_TOP = reinterpret_cast<char*>(0x000fffff);
static const void *const ACPI_FIND_START = reinterpret_cast<const void*>(0x000e0000);
static const void *const ACPI_FIND_TOP = reinterpret_cast<const void*>(0x000fffff);
static const uint64_t ACPI_SIG_RTP_DSR = 0x2052545020445352; // 'RTP DSR '
acpiCpuCount = 0;
activeCpuCount = 1;
if (!(CPU::getFeatures() & CPU::CPUID_FEAT_APIC)) {
acpiCpuCount = 1;
return;
localApicAddr = nullptr;
ioApicAddr = nullptr;
const uint64_t *ptr = nullptr;
if (!ptr && (ptr = static_cast<const uint64_t*>(EFI::getACPI2Addr()))) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);
if ((*ptr != ACPI_SIG_RTP_DSR) || !ParseRsdp(ptr)) ptr = nullptr;
}
if (!ptr && (ptr = static_cast<const uint64_t*>(EFI::getACPI1Addr()))) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);
if ((*ptr != ACPI_SIG_RTP_DSR) || !ParseRsdp(ptr)) ptr = nullptr;
}
if (!ptr) {
ptr = static_cast<const uint64_t*>(ACPI_FIND_START);
const uint64_t *end = static_cast<const uint64_t*>(ACPI_FIND_TOP);
while (ptr < end) {
Pagetable::map(ptr);
Pagetable::map(ptr + 1);
const struct EFI::SystemTable *ST = EFI::getSystemTable();
if (ST && ST->ConfigurationTable) {
const EFI::ConfigurationTable *acpi1 = nullptr, *acpi2 = nullptr;
for (uint64_t i = 0; i < ST->NumberOfTableEntries; i++) {
const EFI::ConfigurationTable *tbl = ST->ConfigurationTable + i;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI1) acpi1 = tbl;
if (tbl->VendorGuid == EFI::GUID_ConfigTableACPI2) acpi2 = tbl;
}
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) break;
bool found = 0;
if (acpi2) {
const uint64_t *ptr =
reinterpret_cast<const uint64_t*>(acpi2->VendorTable);
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) found = 1;
}
if (!found && acpi1) {
const uint64_t *ptr =
reinterpret_cast<const uint64_t*>(acpi1->VendorTable);
if ((*ptr == ACPI_SIG_RTP_DSR) && ParseRsdp(ptr)) found = 1;
ptr += 2;
}
} else {
const uint64_t *p = static_cast<const uint64_t*>(ACPI_FIND_START);
const uint64_t *end = static_cast<const uint64_t*>(ACPI_FIND_TOP);
while (p < end) {
Pagetable::map(p);
Pagetable::map(p + 1);
uint64_t signature = *p;
if (ptr >= end) ptr = nullptr;
}
if ((signature == ACPI_SIG_RTP_DSR) && ParseRsdp(p))
break;
if ((CPU::getFeatures() & CPU::CPUID_FEAT_APIC) && !localApicAddr) {
static const uint32_t msr = 0x1B;
uintptr_t lapic;
asm volatile("rdmsr":"=A"(lapic):"c"(msr));
lapic &= ~0xFFFllu;
localApicAddr = reinterpret_cast<char*>(lapic);
Pagetable::map(localApicAddr);
lapic |= 0x800;
asm volatile("wrmsr"::"a"(uint32_t(lapic)), "d"(uint32_t(lapic >> 32)), "c"(msr));
acpiCpuIds[0] = getLapicID();
acpiCpuCount = 1;
}
p += 2;
}
if (!localApicAddr) {
acpiCpuCount = 1;
return;
}
LapicOut(LAPIC_TMRDIV, 3);
......
......@@ -105,6 +105,7 @@ void Pagetable::init() {
uintptr_t ptbase = 0x600000 + (RAND::get<uintptr_t>() & 0x3FFF000);
pagetable = static_cast<PTE*>(efiAllocatePage(ptbase, ST));
efiMapPage(pagetable, nullptr, ST, 0);
efiMapPage(pagetable, pagetable, ST);
size_t mapSize = 0, entSize = 0;
......
......@@ -15,8 +15,10 @@ class ModuleManager {
static ModuleManager* manager;
void parseInternal();
void parseInitRD();
void loadStream(Stream *stream, bool start = 0);
void loadStream(Stream *stream);
bool parseModuleInfo(ModuleInfo *info, Process *process);
bool bindRequirement(const char *req, Process *process);
bool bindRequirements(const char *reqs, Process *process);
static void init();
public:
......
......@@ -29,6 +29,7 @@ class Process {
uintptr_t entry;
void addPage(uintptr_t vaddr, void* paddr, uint8_t flags);
uintptr_t _aslrCode, _aslrStack;
void *iomap[2];
public:
Process();
......@@ -46,6 +47,7 @@ class Process {
uintptr_t getSymbolByName(const char* name) PURE;
uintptr_t linkLibrary(const char* funcname);
void allowIOPorts(uint16_t min, uint16_t max);
void writeData(uintptr_t address, void* src, size_t size);
void readData(void* dst, uintptr_t address, size_t size) const;
......
......@@ -38,8 +38,92 @@ bool ModuleManager::parseModuleInfo(ModuleInfo *info, Process *process) {
return true;
}
template<typename T> static inline bool readHexChar(char c, T *inout) {
if (c >= '0' && c <= '9') return (*inout = T(*inout << 4) | T(c - '0'), 1);
if (c >= 'a' && c <= 'f') return (*inout = T(*inout << 4) | T(c - 'a' + 10), 1);
if (c >= 'A' && c <= 'F') return (*inout = T(*inout << 4) | T(c - 'A' + 10), 1);
return 0;
}
static inline bool parsePort(const char *str, uint16_t *min, uint16_t *max) {
uint16_t *port = min;
char c;
while ((c = *str++) != 0) {
if (c == '-' && port == min) { port = max; continue; }
if (!readHexChar(c, port)) return 0;
}
if (port == min) *max = *min;
return *max >= *min;
}
enum cpuid_reg { REG_eax, REG_ebx, REG_ecx, REG_edx };
static inline bool parseCPUID(const char *str, uint32_t *func, enum cpuid_reg *reg, uint8_t *bit) {
char c;
while ((c = *str++) != 0 && c != '.') {
if (!readHexChar(c, func)) return 0;
}
if (c != '.') return 0;
switch (*str++) {
case 'a': case 'A': *reg = REG_eax; break;
case 'b': case 'B': *reg = REG_ebx; break;
case 'c': case 'C': *reg = REG_ecx; break;
case 'd': case 'D': *reg = REG_edx; break;
default: return 0;
}
if ((*str++) != '.') return 0;
while ((c = *str++) != 0) {
if (!readHexChar(c, bit)) return 0;
}
return 1;
}
bool ModuleManager::bindRequirement(const char *req, Process *process) {
if (klib::strncmp(req, "port/", 5) == 0) {
uint16_t minport = 0, maxport = 0;
if (!parsePort(req + 5, &minport, &maxport)) return 0;
process->allowIOPorts(minport, maxport);
return 1;
} else if (klib::strncmp(req, "cpuid/", 6) == 0) {
uint32_t func = 0; uint8_t bit = 0; enum cpuid_reg reg;
if (!parseCPUID(req + 6, &func, &reg, &bit)) return 0;
if (func & 0x0000FFFF) {
uint32_t maxfunc = 0;
asm volatile("cpuid":"=a"(maxfunc):"a"(uint32_t(func & 0xFFFF0000)):"ecx", "ebx", "edx");
if (func > maxfunc) return 0;
}
union {
uint32_t regs[4];
struct { uint32_t eax, ebx, ecx, edx; };
} val;
asm volatile("cpuid":"=a"(val.eax), "=b"(val.ebx), "=c"(val.ecx), "=d"(val.edx):"a"(func));
return ((val.regs[reg] >> bit) & 1);
} else {
return 0;
}
}
bool ModuleManager::bindRequirements(const char *reqs, Process *process) {
const char *re;
char *r;
while (*reqs != 0) {
if (*reqs == ';') { reqs++; continue; }
re = reqs;
while (*re != 0 && *re != ';') re++;
r = klib::strndup(reqs, size_t(re - reqs));
reqs = re;
if (!bindRequirement(r, process)) {
printf("Unsatisfied requirement: %s\n", r);
Heap::free(r);
return 0;
}
Heap::free(r);
}
return 1;
}
ModuleManager* ModuleManager::manager = nullptr;
void ModuleManager::loadStream(Stream *stream, bool start) {
void ModuleManager::loadStream(Stream *stream) {
Stream *sub = stream;
Process *process;
size_t size;
......@@ -52,12 +136,17 @@ void ModuleManager::loadStream(Stream *stream, bool start) {
delete process;
break;
}
if (bindRequirements(mod.requirements, process)) {
process->startup();
} else {
delete process;
}
delete mod.name;
delete mod.version;
delete mod.description;
delete mod.requirements;
delete mod.developer;
if (start) process->startup();
sub->seek(ptrdiff_t(size), -1);
if (!stream->eof()) {
Stream *_sub = sub->substream();
......@@ -78,7 +167,7 @@ void ModuleManager::parseInternal() {
if (modules_size > 1) {
MemoryStream ms(mods_start, modules_size);
loadStream(&ms, 1);
loadStream(&ms);
}
}
void ModuleManager::parseInitRD() {
......@@ -91,7 +180,7 @@ void ModuleManager::parseInitRD() {
const char *top = reinterpret_cast<const char*>(uintptr_t(mods[i].end));
size_t length = size_t(top - base);
MemoryStream ms(base, length);
loadStream(&ms, 1);
loadStream(&ms);
}
}
void ModuleManager::init() {
......
......@@ -229,6 +229,20 @@ void Process::addThread(Thread *thread, bool suspended) {
threads.add(thread);
ProcessManager::getManager()->queueThread(this, thread);
}
void Process::allowIOPorts(uint16_t min, uint16_t max) {
for (uint16_t i = 0; i <= (max - min); i++) {
uint16_t port = min + i;
size_t space = port / 8 / 0x1000;
size_t byte = (port / 8) & 0xFFF;
size_t bit = port % 8;
uint8_t *map;
if (!(map = reinterpret_cast<uint8_t*>(iomap[space]))) {
map = reinterpret_cast<uint8_t*>(iomap[space] = Pagetable::alloc());
Memory::fill(map, 0xFF, 0x1000);
}
map[byte] &= ~(1 << bit);
}
}
void Process::startup() {
DTREG gdt = { 0, nullptr };
DTREG idt = { 0, nullptr };
......@@ -264,10 +278,14 @@ void Process::startup() {
GDT::Entry *gdt_ent = reinterpret_cast<GDT::Entry*>(uintptr_t(gdt.addr) + 8 * 3);
GDT::Entry *gdt_top = reinterpret_cast<GDT::Entry*>(uintptr_t(gdt.addr) + gdt.limit);
void *iomap1 = Pagetable::alloc();
void *iomap2 = Pagetable::alloc();
Memory::fill(iomap1, 0xFF, 0x1000);
Memory::fill(iomap2, 0xFF, 0x1000);
if (!iomap[0]) {
iomap[0] = Pagetable::alloc();
Memory::fill(iomap[0], 0xFF, 0x1000);
}
if (!iomap[1]) {
iomap[1] = Pagetable::alloc();
Memory::fill(iomap[1], 0xFF, 0x1000);
}
while (gdt_ent < gdt_top) {
uintptr_t base = gdt_ent->getBase();
......@@ -278,8 +296,8 @@ void Process::startup() {
}
uintptr_t page = base & KB4;
addPage(page, reinterpret_cast<void*>(page), 5);
addPage(page + 0x1000, iomap1, 5);
addPage(page + 0x2000, iomap2, 5);
addPage(page + 0x1000, iomap[0], 5);
addPage(page + 0x2000, iomap[1], 5);
GDT::SystemEntry *sysent = reinterpret_cast<GDT::SystemEntry*>(gdt_ent);
base = sysent->getBase();
......