hpet; minimal fonts option

This commit is contained in:
nakst 2021-10-23 21:39:02 +01:00
parent e0072ec83b
commit 2e457eb792
7 changed files with 121 additions and 26 deletions

View File

@ -144,12 +144,45 @@ int TestCanvasMessage(EsElement *, EsMessage *message) {
return 0;
}
const uint16_t daysBeforeMonthStart[] = {
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, // Normal year.
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, // Leap year.
};
uint64_t DateToLinear(const EsDateComponents *components) {
uint64_t dayCount = 365 * components->year + daysBeforeMonthStart[components->month - 1] + components->day - 1;
uint16_t year = components->month < 3 ? components->year - 1 : components->year;
dayCount += 1 + year / 4 - year / 100 + year / 400; // Add additional days for leap years, only including this year's if we're past February.
return components->millisecond + 1000 * (components->second + 60 * (components->minute + 60 * (components->hour + 24 * dayCount)));
}
void InitialiseInstance(EsInstance *instance) {
// EsPanel *panel = EsPanelCreate(instance->window, ES_CELL_FILL, ES_STYLE_PANEL_WINDOW_DIVIDER);
// textbox = EsTextboxCreate(panel, ES_CELL_FILL | ES_TEXTBOX_ALLOW_TABS | ES_TEXTBOX_MULTILINE, ES_STYLE_TEXTBOX_NO_BORDER);
// Test();
EsPanel *panel = EsPanelCreate(instance->window, ES_CELL_FILL, &stylePanel);
EsButtonOnCommand(EsButtonCreate(panel, ES_FLAGS_DEFAULT, 0, "Timing"), [] (EsInstance *, EsElement *element, EsCommand *) {
EsDateComponents start, end;
EsDateNowUTC(&start);
EsPerformanceTimerPush();
for (uintptr_t i = 0; i < 50000000; i++) {
EsHeapFree(EsHeapAllocate(10, true));
}
double performanceTime = EsPerformanceTimerPop();
EsDateNowUTC(&end);
char message[4096];
size_t messageBytes = EsStringFormat(message, sizeof(message), "Performance time: %F s.\nScheduler time: %F s.\n",
performanceTime, (DateToLinear(&end) - DateToLinear(&start)) / 1000.0);
EsDialogShow(element->window, "Timing results", -1,
message, messageBytes, ES_ICON_DIALOG_INFORMATION, ES_DIALOG_ALERT_OK_BUTTON);
});
EsButtonCreate(panel, ES_BUTTON_CHECKBOX, 0, "Checkbox");
EsTextboxCreate(panel);

View File

@ -1,9 +1,9 @@
#define SIGNATURE_RSDP (0x2052545020445352)
#define SIGNATURE_RSDT (0x54445352)
#define SIGNATURE_XSDT (0x54445358)
#define SIGNATURE_MADT (0x43495041)
#define SIGNATURE_FADT (0x50434146)
#define SIGNATURE_HPET (0x54455048)
struct RootSystemDescriptorPointer {
uint64_t signature;
@ -91,23 +91,6 @@ struct ACPILapic {
size_t ticksPerMs;
};
void ACPILapic::ArchNextTimer(size_t ms) {
WriteRegister(0x320 >> 2, TIMER_INTERRUPT | (1 << 17));
WriteRegister(0x380 >> 2, ticksPerMs * ms);
}
void ACPILapic::EndOfInterrupt() {
WriteRegister(0xB0 >> 2, 0);
}
uint32_t ACPILapic::ReadRegister(uint32_t reg) {
return address[reg];
}
void ACPILapic::WriteRegister(uint32_t reg, uint32_t value) {
address[reg] = value;
}
struct ACPI {
void Initialise();
void FindRootSystemDescriptorPointer();
@ -132,12 +115,42 @@ struct ACPI {
bool ps2ControllerUnavailable, vgaControllerUnavailable;
uint8_t centuryRegisterIndex;
volatile uint64_t *hpetBaseAddress;
uint64_t hpetPeriod; // 10^-15 seconds.
KDevice *computer;
};
ACPI acpi;
void ACPILapic::ArchNextTimer(size_t ms) {
WriteRegister(0x320 >> 2, TIMER_INTERRUPT | (1 << 17));
WriteRegister(0x380 >> 2, ticksPerMs * ms);
}
void ACPILapic::EndOfInterrupt() {
WriteRegister(0xB0 >> 2, 0);
}
uint32_t ACPILapic::ReadRegister(uint32_t reg) {
return address[reg];
}
void ACPILapic::WriteRegister(uint32_t reg, uint32_t value) {
address[reg] = value;
}
#ifdef ARCH_X86_COMMON
uint64_t ArchGetTimeMs() {
if (acpi.hpetBaseAddress && acpi.hpetPeriod) {
__int128 fsToMs = 1000000000000;
__int128 reading = acpi.hpetBaseAddress[30];
return (uint64_t) (reading * (__int128) acpi.hpetPeriod / fsToMs);
} else {
return ArchGetTimeFromPITMs();
}
}
void ACPI::FindRootSystemDescriptorPointer() {
PhysicalMemoryRegion searchRegions[2];
@ -977,6 +990,29 @@ void ACPI::Initialise() {
}
MMFree(kernelMMSpace, fadt);
} else if (header->signature == SIGNATURE_HPET) {
ACPIDescriptorTable *hpet = (ACPIDescriptorTable *) MMMapPhysical(kernelMMSpace, address, header->length, ES_FLAGS_DEFAULT);
hpet->Check();
if (header->length > 52 && ((uint8_t *) header)[52] == 0) {
uint64_t baseAddress;
EsMemoryCopy(&baseAddress, (uint8_t *) header + 44, sizeof(uint64_t));
KernelLog(LOG_INFO, "ACPI", "HPET", "Found primary HPET with base address %x.\n", baseAddress);
hpetBaseAddress = (uint64_t *) MMMapPhysical(kernelMMSpace, baseAddress, 1024, ES_FLAGS_DEFAULT);
if (hpetBaseAddress) {
hpetBaseAddress[2] |= 1; // Start the main counter.
hpetPeriod = hpetBaseAddress[0] >> 32;
uint8_t revisionID = hpetBaseAddress[0] & 0xFF;
uint64_t initialCount = hpetBaseAddress[30];
KernelLog(LOG_INFO, "ACPI", "HPET", "HPET has period of %d fs, revision ID %d, and initial count %d.\n",
hpetPeriod, revisionID, initialCount);
}
}
MMFree(kernelMMSpace, hpet);
}
MMFree(kernelMMSpace, header);

View File

@ -15,7 +15,8 @@
#define CC_ACTIVE_SECTION_SIZE ((EsFileOffset) 262144)
// Maximum number of active sections on the modified list. If exceeded, writers will wait for it to drop before retrying.
#define CC_MAX_MODIFIED (33554432 / CC_ACTIVE_SECTION_SIZE)
// TODO This should based off the amount of physical memory.
#define CC_MAX_MODIFIED (67108864 / CC_ACTIVE_SECTION_SIZE)
// The size of the kernel's address space used for mapping active sections.
#if defined(ARCH_32)

View File

@ -654,7 +654,9 @@ void ArchCheckAddressInRange(int type, uintptr_t address) {
}
}
uint64_t ArchGetTimeMs() {
uint64_t ArchGetTimeFromPITMs() {
// TODO This isn't working on real hardware, but ArchDelay1Ms is?
// NOTE This will only work if called at least once every 50 ms.
// (The PIT only stores a 16-bit counter, which is depleted every 50 ms.)

View File

@ -27,6 +27,7 @@ NewProcessorStorage AllocateNewProcessorStorage(struct ACPIProcessor *archCPU);
bool HasSSSE3Support();
uintptr_t GetBootloaderInformationOffset();
void ArchDelay1Ms(); // Spin for approximately 1ms. Use only during initialisation. Not thread-safe.
uint64_t ArchGetTimeFromPITMs();
void *ACPIGetRSDP();
uint8_t ACPIGetCenturyRegisterIndex();

View File

@ -56,7 +56,7 @@ BuildFont fonts[] = {
{ "2i", "Inter Extra Light Italic.otf" },
{ "3", "Inter Light.otf" },
{ "3i", "Inter Light Italic.otf" },
{ "4", "Inter Regular.otf" },
{ "4", "Inter Regular.otf", .required = true },
{ "4i", "Inter Regular Italic.otf" },
{ "5", "Inter Medium.otf" },
{ "5i", "Inter Medium Italic.otf" },
@ -72,7 +72,7 @@ BuildFont fonts[] = {
} },
{ "Hack", "Hack License.md", "Mono", "Latn,Grek,Cyrl", (FontFile []) {
{ "4", "Hack Regular.ttf" },
{ "4", "Hack Regular.ttf", .required = true },
{ "4i", "Hack Regular Italic.ttf" },
{ "7", "Hack Bold.ttf" },
{ "7i", "Hack Bold Italic.ttf" },
@ -268,19 +268,39 @@ void Compile(uint32_t flags, int partitionSize, const char *volumeLabel) {
uintptr_t fontIndex = 0;
bool requiredFontsOnly = IsOptionEnabled("BuildCore.RequiredFontsOnly");
while (fonts[fontIndex].files) {
BuildFont *font = fonts + fontIndex;
fprintf(f, "[@font %s]\ncategory=%s\nscripts=%s\nlicense=%s\n", font->name, font->category, font->scripts, font->license);
fontIndex++;
uintptr_t fileIndex = 0;
bool noRequiredFiles = true;
while (font->files[fileIndex].path) {
FontFile *file = font->files + fileIndex;
fprintf(f, ".%s=%s\n", file->type, file->path);
if (font->files[fileIndex].required) {
noRequiredFiles = false;
break;
}
fileIndex++;
}
if (noRequiredFiles) {
continue;
}
fprintf(f, "[@font %s]\ncategory=%s\nscripts=%s\nlicense=%s\n", font->name, font->category, font->scripts, font->license);
fileIndex = 0;
while (font->files[fileIndex].path) {
FontFile *file = font->files + fileIndex;
fileIndex++;
if (requiredFontsOnly && !file->required) continue;
fprintf(f, ".%s=%s\n", file->type, file->path);
}
fprintf(f, "\n");
fontIndex++;
}
if (~flags & COMPILE_SKIP_COMPILE) {

View File

@ -40,6 +40,7 @@ typedef struct ApplicationDependencies {
typedef struct FontFile {
const char *type;
const char *path;
bool required;
} FontFile;
typedef struct BuildFont {
@ -317,6 +318,7 @@ Option options[] = {
{ "Emulator.SerialToFile", OPTION_TYPE_BOOL, { .b = true } },
{ "BuildCore.Verbose", OPTION_TYPE_BOOL, { .b = false } },
{ "BuildCore.NoImportPOSIX", OPTION_TYPE_BOOL, { .b = false } },
{ "BuildCore.RequiredFontsOnly", OPTION_TYPE_BOOL, { .b = false } },
{ "General.first_application", OPTION_TYPE_STRING, { .s = NULL } },
{ "General.wallpaper", OPTION_TYPE_STRING, { .s = NULL } },
{ "General.installation_state", OPTION_TYPE_STRING, { .s = "0" } },