started acpi thermal driver

This commit is contained in:
nakst 2021-10-23 12:18:33 +01:00
parent 394c545939
commit 214a45cba4
13 changed files with 281 additions and 65 deletions

View File

@ -401,6 +401,12 @@ void ProcessApplicationMessage(EsMessage *message) {
AddTab(toolbar, DISPLAY_PROCESSES, "Processes", true);
AddTab(toolbar, DISPLAY_GENERAL_LOG, "System log");
AddTab(toolbar, DISPLAY_MEMORY, "Memory");
EsSpacerCreate(toolbar, ES_CELL_H_FILL);
EsButtonOnCommand(EsButtonCreate(toolbar, ES_FLAGS_DEFAULT, 0, "Shutdown"), [] (Instance *, EsElement *, EsCommand *) {
EsSystemShowShutdownDialog();
});
} else if (message->type == ES_MSG_INSTANCE_DESTROY) {
processes.Free();
}

View File

@ -1441,7 +1441,6 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
}
if (state & UI_STATE_INSPECTING) EsPerformanceTimerPush();
double timeChildPaint = 0;
// Get the interpolated style.
@ -1557,8 +1556,6 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
// Paint the children.
// TODO Optimisation: don't paint children overlapped by an opaque sibling.
if (state & UI_STATE_INSPECTING) EsPerformanceTimerPush();
m.type = ES_MSG_PAINT_CHILDREN;
m.painter = painter;
@ -1627,8 +1624,6 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
zOrder.type = ES_MSG_AFTER_Z_ORDER;
EsMessageSend(this, &zOrder);
}
if (state & UI_STATE_INSPECTING) timeChildPaint = EsPerformanceTimerPop() * 1000;
}
// Let the inspector draw some decorations over the element.
@ -1637,11 +1632,6 @@ void EsElement::InternalPaint(EsPainter *painter, int paintFlags) {
InspectorNotifyElementPainted(this, painter);
}
if (state & UI_STATE_INSPECTING) {
double timeTotalPaint = EsPerformanceTimerPop() * 1000;
InspectorNotifyElementEvent(this, "paint", "Paint in %Fms (%Fms with children).", timeTotalPaint - timeChildPaint, timeTotalPaint);
}
*painter = oldPainter;
if (window->visualizePaintSteps && ES_RECT_VALID(window->updateRegionInProgress) && painter->target->forWindowManager) {

View File

@ -2872,9 +2872,9 @@ Array<EsTextRun> TextApplySyntaxHighlighting(const EsTextStyle *baseStyle, int l
// TODO Unicode grapheme/word boundaries.
// TODO Selecting lines with the margin.
struct DocumentLine {
char *GetBuffer(EsTextbox *textbox);
#define GET_BUFFER(line) TextboxGetDocumentLineBuffer(textbox, line)
struct DocumentLine {
int32_t lengthBytes,
lengthWidth,
height,
@ -3295,11 +3295,11 @@ void TextboxUpdateCommands(EsTextbox *textbox, bool noClipboard) {
}
}
char *DocumentLine::GetBuffer(EsTextbox *textbox) {
if (textbox->activeLineIndex == this - textbox->lines.array) {
char *TextboxGetDocumentLineBuffer(EsTextbox *textbox, DocumentLine *line) {
if (textbox->activeLineIndex == line - textbox->lines.array) {
return textbox->activeLine;
} else {
return textbox->data + offset;
return textbox->data + line->offset;
}
}
@ -3358,7 +3358,7 @@ void EsTextboxEnsureCaretVisible(EsTextbox *textbox, bool verticallyCenter) {
int scrollX = textbox->scroll.position[0];
int viewportWidth = bounds.r;
int caretX = TextGetPartialStringWidth(textbox, &textbox->textStyle,
line->GetBuffer(textbox), line->lengthBytes, caret.byte) - scrollX + textbox->insets.l;
GET_BUFFER(line), line->lengthBytes, caret.byte) - scrollX + textbox->insets.l;
if (caretX < textbox->insets.l) {
scrollX += caretX - textbox->insets.l;
@ -3386,7 +3386,7 @@ bool TextboxMoveCaret(EsTextbox *textbox, TextboxCaret *caret, bool right, int m
if (textbox->verticalMotionHorizontalDepth == -1) {
textbox->verticalMotionHorizontalDepth = TextGetPartialStringWidth(textbox, &textbox->textStyle,
textbox->lines[caret->line].GetBuffer(textbox), textbox->lines[caret->line].lengthBytes, caret->byte);
GET_BUFFER(&textbox->lines[caret->line]), textbox->lines[caret->line].lengthBytes, caret->byte);
}
if (right) caret->line++; else caret->line--;
@ -3395,11 +3395,11 @@ bool TextboxMoveCaret(EsTextbox *textbox, TextboxCaret *caret, bool right, int m
DocumentLine *line = &textbox->lines[caret->line];
int pointX = textbox->verticalMotionHorizontalDepth ? textbox->verticalMotionHorizontalDepth - 1 : 0;
ptrdiff_t result = TextGetCharacterAtPoint(textbox, &textbox->textStyle,
line->GetBuffer(textbox), line->lengthBytes, &pointX, ES_TEXT_GET_CHARACTER_AT_POINT_MIDDLE);
GET_BUFFER(line), line->lengthBytes, &pointX, ES_TEXT_GET_CHARACTER_AT_POINT_MIDDLE);
caret->byte = result == -1 ? line->lengthBytes : result;
} else {
CharacterType type = CHARACTER_INVALID;
char *currentLineBuffer = textbox->lines[caret->line].GetBuffer(textbox);
char *currentLineBuffer = GET_BUFFER(&textbox->lines[caret->line]);
if (moveType == MOVE_CARET_WORD && right) goto checkCharacterType;
while (true) {
@ -3409,7 +3409,7 @@ bool TextboxMoveCaret(EsTextbox *textbox, TextboxCaret *caret, bool right, int m
caret->byte = utf8_retreat(currentLineBuffer + caret->byte) - currentLineBuffer;
} else {
caret->byte = textbox->lines[--caret->line].lengthBytes;
currentLineBuffer = textbox->lines[caret->line].GetBuffer(textbox);
currentLineBuffer = GET_BUFFER(&textbox->lines[caret->line]);
}
} else {
break; // We cannot move any further left.
@ -3421,7 +3421,7 @@ bool TextboxMoveCaret(EsTextbox *textbox, TextboxCaret *caret, bool right, int m
} else {
caret->line++;
caret->byte = 0;
currentLineBuffer = textbox->lines[caret->line].GetBuffer(textbox);
currentLineBuffer = GET_BUFFER(&textbox->lines[caret->line]);
}
} else {
break; // We cannot move any further right.
@ -3543,7 +3543,7 @@ void TextboxRefreshVisibleLines(EsTextbox *textbox, bool repaint = true) {
}
line->lengthWidth = TextGetStringWidth(textbox, &textbox->textStyle,
line->GetBuffer(textbox), line->lengthBytes);
GET_BUFFER(line), line->lengthBytes);
if (textbox->longestLine != -1 && line->lengthWidth > textbox->longestLineWidth) {
textbox->longestLine = textbox->firstVisibleLine + i;
@ -4016,7 +4016,7 @@ char *EsTextboxGetContents(EsTextbox *textbox, size_t *_bytes, uint32_t flags) {
}
}
EsMemoryCopy(buffer + position, line->GetBuffer(textbox) + offsetFrom, offsetTo - offsetFrom);
EsMemoryCopy(buffer + position, GET_BUFFER(line) + offsetFrom, offsetTo - offsetFrom);
position += offsetTo - offsetFrom;
if (includeNewline && i != lineTo) {
@ -4058,7 +4058,7 @@ bool EsTextboxFind(EsTextbox *textbox, const char *needle, intptr_t _needleBytes
while (true) {
DocumentLine *line = &textbox->lines[lineIndex];
const char *buffer = line->GetBuffer(textbox);
const char *buffer = GET_BUFFER(line);
size_t bufferBytes = line->lengthBytes;
EsAssert(byteIndex <= bufferBytes); // Invalid find byte offset.
@ -4174,7 +4174,7 @@ bool TextboxFindCaret(EsTextbox *textbox, int positionX, int positionY, bool sec
int pointX = positionX + textbox->scroll.position[0] - textbox->insets.l;
if (pointX < 0) pointX = 0;
ptrdiff_t result = TextGetCharacterAtPoint(textbox, &textbox->textStyle,
line->GetBuffer(textbox), line->lengthBytes,
GET_BUFFER(line), line->lengthBytes,
&pointX, ES_TEXT_GET_CHARACTER_AT_POINT_MIDDLE);
textbox->carets[1].byte = result == -1 ? line->lengthBytes : result;
}
@ -4359,7 +4359,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
if (textbox->syntaxHighlightingLanguage && line->lengthBytes) {
if (textRuns.Length()) textRuns.SetLength(0);
textRuns = TextApplySyntaxHighlighting(&textbox->textStyle, textbox->syntaxHighlightingLanguage,
textbox->syntaxHighlightingColors, textRuns, line->GetBuffer(textbox), line->lengthBytes);
textbox->syntaxHighlightingColors, textRuns, GET_BUFFER(line), line->lengthBytes);
} else {
textRuns.SetLength(2);
textRuns[0].style = textbox->textStyle;
@ -4376,7 +4376,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
if (!textRuns.Length()) {
plan = nullptr;
} else if (textRuns[1].offset) {
plan = EsTextPlanCreate(element, &properties, lineBounds, line->GetBuffer(textbox), textRuns.array, textRuns.Length() - 1);
plan = EsTextPlanCreate(element, &properties, lineBounds, GET_BUFFER(line), textRuns.array, textRuns.Length() - 1);
} else {
textRuns[1].offset = 1; // Make sure that the caret and selection is draw correctly, even on empty lines.
plan = EsTextPlanCreate(element, &properties, lineBounds, " ", textRuns.array, textRuns.Length() - 1);
@ -4467,6 +4467,10 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
textbox->Repaint(true);
verticalMotion = true;
} else if (message->keyboard.scancode == ES_SCANCODE_BACKSPACE || message->keyboard.scancode == ES_SCANCODE_DELETE) {
if (!textbox->editing) {
EsTextboxStartEdit(textbox);
}
if (!TextboxCompareCarets(textbox->carets + 0, textbox->carets + 1)) {
TextboxMoveCaret(textbox, textbox->carets + 1, message->keyboard.scancode == ES_SCANCODE_BACKSPACE ? MOVE_CARET_BACKWARDS : MOVE_CARET_FORWARDS,
ctrl ? MOVE_CARET_WORD : MOVE_CARET_SINGLE);
@ -4495,7 +4499,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
if (inputString && (message->keyboard.modifiers & ~(ES_MODIFIER_SHIFT | ES_MODIFIER_ALT_GR)) == 0) {
if (textbox->smartQuotes && api.global->useSmartQuotes) {
DocumentLine *currentLine = &textbox->lines[textbox->carets[0].line];
const char *buffer = currentLine->GetBuffer(textbox);
const char *buffer = GET_BUFFER(currentLine);
bool left = !textbox->carets[0].byte || buffer[textbox->carets[0].byte - 1] == ' ';
if (inputString[0] == '"' && inputString[1] == 0) {
@ -4511,7 +4515,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
// Copy the indentation from the previous line.
DocumentLine *previousLine = &textbox->lines[textbox->carets[0].line - 1];
const char *buffer = previousLine->GetBuffer(textbox);
const char *buffer = GET_BUFFER(previousLine);
int32_t i = 0;
for (; i < previousLine->lengthBytes; i++) {
@ -4609,7 +4613,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
if (selectionTo - selectionFrom == 7) {
char buffer[7];
EsMemoryCopy(buffer, textbox->lines[textbox->carets[0].line].GetBuffer(textbox) + selectionFrom, 7);
EsMemoryCopy(buffer, GET_BUFFER(&textbox->lines[textbox->carets[0].line]) + selectionFrom, 7);
if (buffer[0] == '#' && EsCRTisxdigit(buffer[1]) && EsCRTisxdigit(buffer[2]) && EsCRTisxdigit(buffer[3])
&& EsCRTisxdigit(buffer[4]) && EsCRTisxdigit(buffer[5]) && EsCRTisxdigit(buffer[6])) {
@ -4662,7 +4666,7 @@ int ProcessTextboxMessage(EsElement *element, EsMessage *message) {
EsElementRepaintForScroll(textbox, message, EsRectangleAdd(element->GetInternalOffset(), element->style->borders));
} else if (message->type == ES_MSG_GET_INSPECTOR_INFORMATION) {
DocumentLine *firstLine = &textbox->lines.First();
EsBufferFormat(message->getContent.buffer, "'%s'", firstLine->lengthBytes, firstLine->GetBuffer(textbox));
EsBufferFormat(message->getContent.buffer, "'%s'", firstLine->lengthBytes, GET_BUFFER(firstLine));
} else if (message->type == ES_MSG_UI_SCALE_CHANGED) {
if (textbox->margin) {
// Force the margin to update its style now, so that its width can be read correctly by TextboxStyleChanged.
@ -4960,6 +4964,8 @@ void EsTextboxEnableSmartQuotes(EsTextbox *textbox, bool enabled) {
textbox->smartQuotes = enabled;
}
#undef GET_BUFFER
// --------------------------------- Text displays.
// TODO Inline images and icons.

View File

@ -1,6 +1,3 @@
// TODO ACPICA initialisation hangs on my computer when SMP is enabled when it tries to write to IO port 0xB2 (power management, generates SMI).
// This is possibly related to the hang when writing to the keyboard controller IO ports that only occurs with SMP enabled.
#define SIGNATURE_RSDP (0x2052545020445352)
#define SIGNATURE_RSDT (0x54445352)
@ -418,6 +415,7 @@ ES_EXTERN_C void AcpiOsReleaseLock(ACPI_SPINLOCK handle, ACPI_CPU_FLAGS flags) {
KSpinlockRelease(spinlock);
}
// TODO Can these arrays be made smaller?
ACPI_OSD_HANDLER acpiInterruptHandlers[256];
void *acpiInterruptContexts[256];
@ -721,6 +719,100 @@ void ACPIEnumeratePRTEntries(ACPI_HANDLE pciBus) {
table = (ACPI_PCI_ROUTING_TABLE *) ((uint8_t *) table + table->Length);
}
}
struct KACPIObject : KDevice {
ACPI_HANDLE handle;
KACPINotificationHandler notificationHandler;
EsGeneric notificationHandlerContext;
};
void ACPINotificationHandler(ACPI_HANDLE, uint32_t value, void *context) {
KernelLog(LOG_INFO, "ACPI", "notification", "Received a notification with value %X.\n", value);
KACPIObject *object = (KACPIObject *) context;
object->notificationHandler(object, value, object->notificationHandlerContext);
}
EsError KACPIObjectSetDeviceNotificationHandler(KACPIObject *object, KACPINotificationHandler handler, EsGeneric context) {
object->notificationHandler = handler;
object->notificationHandlerContext = context;
ACPI_STATUS status = AcpiInstallNotifyHandler(object->handle, ACPI_DEVICE_NOTIFY, ACPINotificationHandler, object);
if (status == AE_OK) return ES_SUCCESS;
else if (status == AE_NO_MEMORY) return ES_ERROR_INSUFFICIENT_RESOURCES;
else return ES_ERROR_UNKNOWN;
}
EsError KACPIObjectEvaluateInteger(KACPIObject *object, const char *pathName, uint64_t *_integer) {
ACPI_BUFFER buffer = {};
buffer.Length = ACPI_ALLOCATE_BUFFER;
ACPI_STATUS status = AcpiEvaluateObject(object->handle, (char *) pathName, nullptr, &buffer);
EsError error = ES_SUCCESS;
if (status == AE_OK) {
ACPI_OBJECT *result = (ACPI_OBJECT *) buffer.Pointer;
if (result->Type == ACPI_TYPE_INTEGER) {
if (_integer) {
*_integer = result->Integer.Value;
}
} else {
error = ES_ERROR_UNKNOWN;
}
ACPI_FREE(buffer.Pointer);
} else if (status == AE_NO_MEMORY) {
error = ES_ERROR_INSUFFICIENT_RESOURCES;
} else if (status == AE_NOT_FOUND) {
error = ES_ERROR_FILE_DOES_NOT_EXIST;
} else {
error = ES_ERROR_UNKNOWN;
}
return error;
}
EsError KACPIObjectEvaluateMethodWithInteger(KACPIObject *object, const char *pathName, uint64_t integer) {
ACPI_OBJECT argument = {};
argument.Type = ACPI_TYPE_INTEGER;
argument.Integer.Value = integer;
ACPI_OBJECT_LIST argumentList = {};
argumentList.Count = 1;
argumentList.Pointer = &argument;
ACPI_STATUS status = AcpiEvaluateObject(object->handle, (char *) pathName, &argumentList, nullptr);
if (status == AE_OK) return ES_SUCCESS;
else if (status == AE_NO_MEMORY) return ES_ERROR_INSUFFICIENT_RESOURCES;
else if (status == AE_NOT_FOUND) return ES_ERROR_FILE_DOES_NOT_EXIST;
else return ES_ERROR_UNKNOWN;
}
ACPI_STATUS ACPIWalkNamespaceCallback(ACPI_HANDLE object, uint32_t depth, void *, void **) {
ACPI_DEVICE_INFO *information;
AcpiGetObjectInfo(object, &information);
char name[5];
EsMemoryCopy(name, &information->Name, 4);
name[4] = 0;
if (information->Type == ACPI_TYPE_DEVICE) {
KernelLog(LOG_INFO, "ACPI", "device object", "Found device object '%z' at depth %d with HID '%z', UID '%z' and address %x.\n",
name, depth,
(information->Valid & ACPI_VALID_HID) ? information->HardwareId.String : "??",
(information->Valid & ACPI_VALID_UID) ? information->UniqueId.String : "??",
(information->Valid & ACPI_VALID_ADR) ? information->Address : 0);
}
if (information->Type == ACPI_TYPE_THERMAL) {
KACPIObject *device = (KACPIObject *) KDeviceCreate("ACPI object", acpi.computer, sizeof(KACPIObject));
if (device) {
device->handle = object;
KDeviceAttachByName(device, "ACPIThermal");
}
}
ACPI_FREE(information);
return AE_OK;
}
#endif
void ACPIInitialise2() {
@ -728,8 +820,6 @@ void ACPIInitialise2() {
AcpiInitializeSubsystem();
AcpiInitializeTables(nullptr, 256, true);
AcpiLoadTables();
ProcessorDisableInterrupts();
ProcessorEnableInterrupts();
AcpiEnableSubsystem(ACPI_FULL_INITIALIZATION);
AcpiInitializeObjects(ACPI_FULL_INITIALIZATION);
@ -739,23 +829,7 @@ void ACPIInitialise2() {
}
void *result;
AcpiGetDevices(nullptr, [] (ACPI_HANDLE object, uint32_t, void *, void **) -> ACPI_STATUS {
ACPI_DEVICE_INFO *information;
AcpiGetObjectInfo(object, &information);
char name[5];
EsMemoryCopy(name, &information->Name, 4);
name[4] = 0;
KernelLog(LOG_INFO, "ACPI", "device object", "Found device object '%z' with HID '%z', UID '%z' and address %x.\n",
name, (information->Valid & ACPI_VALID_HID) ? information->HardwareId.String : "??",
(information->Valid & ACPI_VALID_UID) ? information->UniqueId.String : "??",
(information->Valid & ACPI_VALID_ADR) ? information->Address : 0);
ACPI_FREE(information);
return AE_OK;
}, nullptr, &result);
AcpiWalkNamespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, 10, ACPIWalkNamespaceCallback, nullptr, nullptr, &result);
ACPI_HANDLE pciBus;
char pciBusPath[] = "\\_SB_.PCI0";

98
drivers/acpi_thermal.cpp Normal file
View File

@ -0,0 +1,98 @@
#include <module.h>
// TODO Active cooling.
// TODO Passive cooling.
// TODO Temperature change polling.
// TODO Refresh temperature/thresholds on a separate thread.
struct ACPIThermalZone : KDevice {
KACPIObject *object;
uint64_t criticalThreshold; // Once reached, the system should shutdown as quickly as possible.
uint64_t hotThreshold; // Once reached, the system will likely want to enter sleep mode.
uint64_t passiveThreshold; // Once reached, the passive cooling algorithm (e.g. processor speed throttling) should be enabled.
uint64_t activeThresholds[10]; // Once reached, the given active cooling device (e.g. fan) should be enabled.
uint64_t pollingFrequency; // Recommended polling frequency of temperature, in tenths of a seconds.
uint64_t currentTemperature;
KMutex refreshMutex;
};
static void ACPIThermalRefreshTemperature(EsGeneric context) {
ACPIThermalZone *device = (ACPIThermalZone *) context.p;
KACPIObject *object = device->object;
KMutexAcquire(&device->refreshMutex);
KernelLog(LOG_INFO, "ACPIThermal", "temperature", "Taking temperature reading...\n");
EsError error = KACPIObjectEvaluateInteger(object, "_TMP", &device->currentTemperature);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "temperature", "Current temperature: %d K.\n", device->currentTemperature / 10);
else KernelLog(LOG_ERROR, "ACPIThermal", "temperature", "Unable to read current temperature (%d).\n", error);
// TODO Active cooling.
KMutexRelease(&device->refreshMutex);
}
static void ACPIThermalRefreshThresholds(EsGeneric context) {
ACPIThermalZone *device = (ACPIThermalZone *) context.p;
KACPIObject *object = device->object;
KMutexAcquire(&device->refreshMutex);
KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Taking threshold readings...\n");
EsError error;
error = KACPIObjectEvaluateInteger(object, "_CRT", &device->criticalThreshold);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Critical temperature threshold: %d K.\n", device->criticalThreshold / 10);
error = KACPIObjectEvaluateInteger(object, "_HOT", &device->hotThreshold);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Hot temperature threshold: %d K.\n", device->hotThreshold / 10);
error = KACPIObjectEvaluateInteger(object, "_PSV", &device->passiveThreshold);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Passive temperature threshold: %d K.\n", device->passiveThreshold / 10);
error = KACPIObjectEvaluateInteger(object, "_TZP", &device->passiveThreshold);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Recommended polling frequency: %d s.\n", device->pollingFrequency / 10);
char name[5] = "_AC0";
for (uintptr_t i = 0; i <= 9; i++, name[3]++) {
EsError error = KACPIObjectEvaluateInteger(object, name, &device->activeThresholds[i]);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "threshold", "Active temperature threshold %d: %d K.\n", i, device->activeThresholds[i] / 10);
else break;
}
KMutexRelease(&device->refreshMutex);
ACPIThermalRefreshTemperature(device);
}
static void ACPIThermalDeviceNotificationHandler(KACPIObject *, uint32_t value, EsGeneric context) {
ACPIThermalZone *device = (ACPIThermalZone *) context.p;
if (value == 0x80) {
KRegisterAsyncTask(ACPIThermalRefreshTemperature, device);
} else if (value == 0x81) {
KRegisterAsyncTask(ACPIThermalRefreshThresholds, device);
}
}
static void ACPIThermalDeviceAttach(KDevice *parent) {
KACPIObject *object = (KACPIObject *) parent;
ACPIThermalZone *device = (ACPIThermalZone *) KDeviceCreate("ACPI thermal zone", parent, sizeof(ACPIThermalZone));
if (!device) return;
device->object = object;
KernelLog(LOG_INFO, "ACPIThermal", "device attached", "Found ACPI thermal zone.\n");
ACPIThermalRefreshThresholds(device);
EsError error;
error = KACPIObjectSetDeviceNotificationHandler(object, ACPIThermalDeviceNotificationHandler, device);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "notification handler", "Successfully installed notification handler.\n");
else KernelLog(LOG_ERROR, "ACPIThermal", "notification handler", "Unable to install notification handler (%d).\n", error);
error = KACPIObjectEvaluateMethodWithInteger(object, "_SCP", 0 /* active cooling policy */);
if (error == ES_SUCCESS) KernelLog(LOG_INFO, "ACPIThermal", "cooling policy", "Successfully set active cooling policy.\n");
else KernelLog(LOG_ERROR, "ACPIThermal", "cooling policy", "Unable to set active cooling policy (%d).\n", error);
}
KDriver driverACPIThermal = {
.attach = ACPIThermalDeviceAttach,
};

View File

@ -149,3 +149,9 @@ builtin=1
parent=Files
signature_offset=1080
signature=
; ACPI devices.
[@driver ACPIThermal]
source=drivers/acpi_thermal.cpp
builtin=1

View File

@ -1056,3 +1056,13 @@ void KRegisterNetInterface(NetInterface *interface);
void NetInterfaceReceive(NetInterface *interface, const uint8_t *data, size_t dataBytes, NetPacketType packetType); // NOTE Currently this can be only called on one thread for each NetInterface. (This restriction will hopefully be removed soon.)
void NetInterfaceSetConnected(NetInterface *interface, bool connected); // NOTE This shouldn't be called by more than one thread.
void NetInterfaceShutdown(NetInterface *interface); // NOTE This doesn't do any disconnecting/cancelling of tasks. Currently it only sends a DHCP request to release the IP address, and is expected to be called at the final stages of system shutdown.
// ---------------------------------------------------------------------------------------------------------------
// ACPI.
// ---------------------------------------------------------------------------------------------------------------
struct KACPIObject;
typedef void (*KACPINotificationHandler)(KACPIObject *object, uint32_t value, EsGeneric context);
EsError KACPIObjectEvaluateInteger(KACPIObject *object, const char *pathName, uint64_t *_integer);
EsError KACPIObjectEvaluateMethodWithInteger(KACPIObject *object, const char *pathName, uint64_t integer);
EsError KACPIObjectSetDeviceNotificationHandler(KACPIObject *object, KACPINotificationHandler handler, EsGeneric context);

View File

@ -1848,18 +1848,22 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_DEVICE_CONTROL) {
}
SYSCALL_IMPLEMENT(ES_SYSCALL_DEBUG_COMMAND) {
#ifdef DEBUG_BUILD
if (argument0 == 1) {
ArchResetCPU();
} else if (argument0 == 2) {
KernelPanic("Debug command 2.\n");
} else if (argument0 == 3) {
if (argument0 == 3) {
SYSCALL_PERMISSION(ES_PERMISSION_TAKE_SYSTEM_SNAPSHOT);
// TODO Temporary: moved out of the DEBUG_BUILD block.
extern char kernelLog[];
extern uintptr_t kernelLogPosition;
size_t bytes = kernelLogPosition;
if (argument2 < bytes) bytes = argument2;
EsMemoryCopy((void *) argument1, kernelLog, bytes);
SYSCALL_RETURN(bytes, false);
}
#ifdef DEBUG_BUILD
if (argument0 == 1) {
ArchResetCPU();
} else if (argument0 == 2) {
KernelPanic("Debug command 2.\n");
} else if (argument0 == 4) {
SYSCALL_BUFFER(argument1, 1, 0, false);

View File

@ -10,6 +10,7 @@
#include <assert.h>
#include <string.h>
#include <math.h>
#include <essence.h>
#define MODERN_GL
@ -75,6 +76,9 @@ static void (*glVertexAttribPointer)(GLuint index, GLint size, GLenum type, GLbo
uint32_t framesDrawn;
double lastTime;
float timeMs;
float previousTimeMs;
double lastGLDuration;
double lastDrawBitmapDuration;
int shaderTransform, shaderNormalTransform;
size_t triangleCount, vertexCount;
@ -122,6 +126,13 @@ void Render() {
return;
}
if (previousTimeMs == timeMs) {
return;
}
previousTimeMs = timeMs;
EsPerformanceTimerPush();
glClearColor(0.21f, 0.2f, 0.2f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
#ifdef MODERN_GL
@ -151,13 +162,15 @@ void Render() {
glEnd();
#endif
glFinish();
}
#include <essence.h>
framesDrawn++;
lastGLDuration = EsPerformanceTimerPop();
}
int CanvasCallback(EsElement *element, EsMessage *message) {
if (message->type == ES_MSG_PAINT_BACKGROUND) {
Render();
EsPerformanceTimerPush();
EsRectangle bounds = EsPainterBoundsInset(message->painter);
EsRectangle imageBounds = EsRectangleCenter(bounds, ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
EsDrawBitmap(message->painter, imageBounds, buffer, IMAGE_WIDTH * 4, ES_DRAW_BITMAP_OPAQUE);
@ -165,19 +178,18 @@ int CanvasCallback(EsElement *element, EsMessage *message) {
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.r, bounds.r, bounds.t, bounds.b), 0xFF333336);
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.l, imageBounds.r, bounds.t, imageBounds.t), 0xFF333336);
EsDrawBlock(message->painter, ES_RECT_4(imageBounds.l, imageBounds.r, imageBounds.b, bounds.b), 0xFF333336);
framesDrawn++;
lastDrawBitmapDuration = EsPerformanceTimerPop();
} else if (message->type == ES_MSG_ANIMATE) {
double currentTime = EsTimeStampMs();
if (currentTime - lastTime > 1000.0) {
EsPrint("%d fps\n", framesDrawn);
EsPrint("%d fps (last frame: GL %F s, DrawBitmap %F s)\n", framesDrawn, lastGLDuration, lastDrawBitmapDuration);
lastTime = currentTime;
framesDrawn = 0;
}
message->animate.complete = false;
timeMs += message->animate.deltaMs;
EsRectangle imageBounds = EsRectangleCenter(EsElementGetInsetBounds(element), ES_RECT_2S(IMAGE_WIDTH, IMAGE_HEIGHT));
EsElementRepaint(element, &imageBounds);

Binary file not shown.

Binary file not shown.

View File

@ -260,6 +260,7 @@ typedef struct Option {
Option options[] = {
{ "Driver.ACPI", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.ACPIThermal", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.AHCI", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.BGA", OPTION_TYPE_BOOL, { .b = true } },
{ "Driver.EssenceFS", OPTION_TYPE_BOOL, { .b = true } },

View File

@ -12,10 +12,19 @@ mkdir -p mount/EFI/BOOT
cp bin/uefi mount/EFI/BOOT/BOOTX64.EFI
cp bin/Kernel.esx mount/eskernel.esx
cp bin/uefi_loader mount/esloader.bin
cp bin/iid.dat mount/esiid.dat
if [ $# -eq 2 ]; then
cp bin/iid.dat mount/esiid.dat
fi
umount $1
rmdir mount
if [ $# -eq 1 ]; then
echo Skipping drive copy.
exit 0
fi
SOURCE_OFFSET=`fdisk -l bin/drive | grep 'Linux' | awk '{print $3}'`
SOURCE_COUNT=`fdisk -l bin/drive | grep 'Linux' | awk '{print $5}'`
DESTINATION_COUNT=`blockdev --getsz $2`