mirror of https://gitlab.com/nakst/essence
started acpi thermal driver
This commit is contained in:
parent
394c545939
commit
214a45cba4
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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.
|
||||
|
|
118
drivers/acpi.cpp
118
drivers/acpi.cpp
|
@ -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";
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -149,3 +149,9 @@ builtin=1
|
|||
parent=Files
|
||||
signature_offset=1080
|
||||
signature=Sï
|
||||
|
||||
; ACPI devices.
|
||||
|
||||
[@driver ACPIThermal]
|
||||
source=drivers/acpi_thermal.cpp
|
||||
builtin=1
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
BIN
res/Theme.dat
BIN
res/Theme.dat
Binary file not shown.
|
@ -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 } },
|
||||
|
|
|
@ -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`
|
||||
|
|
Loading…
Reference in New Issue