make KDevice a kernel object

This commit is contained in:
nakst 2021-08-17 20:13:54 +01:00
parent 23bc33d5b9
commit 3180b16221
28 changed files with 135 additions and 159 deletions

View File

@ -14,7 +14,6 @@ struct Instance : EsInstance {
EsPanel *switcher;
EsTextbox *textboxGeneralLog;
EsListView *listViewProcesses;
EsListView *listViewPCIDevices;
EsPanel *panelMemoryStatistics;
int index;
EsCommand commandTerminateProcess;
@ -25,7 +24,6 @@ struct Instance : EsInstance {
#define DISPLAY_PROCESSES (1)
#define DISPLAY_GENERAL_LOG (3)
#define DISPLAY_PCI_DEVICES (6)
#define DISPLAY_MEMORY (12)
EsListViewColumn listViewProcessesColumns[] = {
@ -44,25 +42,6 @@ EsListViewColumn listViewContextSwitchesColumns[] = {
{ EsLiteral("Count"), 0, 150 },
};
EsListViewColumn listViewPCIDevicesColumns[] = {
{ EsLiteral("Driver"), 0, 200 },
{ EsLiteral("Device ID"), 0, 200 },
{ EsLiteral("Class"), 0, 250 },
{ EsLiteral("Subclass"), 0, 250 },
{ EsLiteral("ProgIF"), 0, 150 },
{ EsLiteral("Bus"), 0, 100 },
{ EsLiteral("Slot"), 0, 100 },
{ EsLiteral("Function"), 0, 100 },
{ EsLiteral("Interrupt pin"), 0, 100 },
{ EsLiteral("Interrupt line"), 0, 100 },
{ EsLiteral("BAR0"), 0, 250 },
{ EsLiteral("BAR1"), 0, 250 },
{ EsLiteral("BAR2"), 0, 250 },
{ EsLiteral("BAR3"), 0, 250 },
{ EsLiteral("BAR4"), 0, 250 },
{ EsLiteral("BAR5"), 0, 250 },
};
const EsStyle styleMonospacedTextbox = {
.inherit = ES_STYLE_TEXTBOX_NO_BORDER,
@ -150,8 +129,6 @@ struct ProcessItem {
};
char generalLogBuffer[256 * 1024];
char contextSwitchesBuffer[2 * 1024 * 1024];
EsPCIDevice pciDevices[1024];
Array<ProcessItem> processes;
int64_t selectedPID = -2;
@ -264,11 +241,6 @@ void UpdateDisplay(Instance *instance, int index) {
EsTextboxInsert(instance->textboxGeneralLog, generalLogBuffer, bytes);
EsTextboxEnsureCaretVisible(instance->textboxGeneralLog, false);
EsPanelSwitchTo(instance->switcher, instance->textboxGeneralLog, ES_TRANSITION_NONE);
} else if (index == DISPLAY_PCI_DEVICES) {
size_t count = EsSyscall(ES_SYSCALL_DEBUG_COMMAND, index, (uintptr_t) pciDevices, sizeof(pciDevices) / sizeof(pciDevices[0]), 0);
EsListViewRemoveAll(instance->listViewPCIDevices, 0);
EsListViewInsert(instance->listViewPCIDevices, 0, 0, count);
EsPanelSwitchTo(instance->switcher, instance->listViewPCIDevices, ES_TRANSITION_NONE);
} else if (index == DISPLAY_MEMORY) {
EsMemoryStatistics statistics = {};
EsSyscall(ES_SYSCALL_DEBUG_COMMAND, index, (uintptr_t) &statistics, 0, 0);
@ -361,64 +333,6 @@ int ListViewProcessesCallback(EsElement *element, EsMessage *message) {
return ES_HANDLED;
}
int ListViewPCIDevicesCallback(EsElement *, EsMessage *message) {
if (message->type == ES_MSG_LIST_VIEW_GET_CONTENT) {
int column = message->getContent.column, index = message->getContent.index;
EsPCIDevice *entry = pciDevices + index;
if (column == 0) {
GET_CONTENT("%s", entry->driverNameBytes, entry->driverName);
} else if (column == 1) {
GET_CONTENT("%x", entry->deviceID);
} else if (column == 2) {
const char *string = entry->classCode < sizeof(pciClassCodeStrings) / sizeof(pciClassCodeStrings[0])
? pciClassCodeStrings[entry->classCode] : "Unknown";
GET_CONTENT("%d - %z", entry->classCode, string);
} else if (column == 3) {
const char *string =
entry->classCode == 1 && entry->subclassCode < sizeof(pciSubclassCodeStrings1) / sizeof(const char *)
? pciSubclassCodeStrings1 [entry->subclassCode]
: entry->classCode == 12 && entry->subclassCode < sizeof(pciSubclassCodeStrings12) / sizeof(const char *)
? pciSubclassCodeStrings12[entry->subclassCode] : "";
GET_CONTENT("%d%z%z", entry->subclassCode, *string ? " - " : "", string);
} else if (column == 4) {
const char *string =
entry->classCode == 12 && entry->subclassCode == 3 && entry->progIF / 0x10 < sizeof(pciProgIFStrings12_3) / sizeof(const char *)
? pciProgIFStrings12_3[entry->progIF / 0x10] : "";
GET_CONTENT("%d%z%z", entry->progIF, *string ? " - " : "", string);
} else if (column == 5) {
GET_CONTENT("%d", entry->bus);
} else if (column == 6) {
GET_CONTENT("%d", entry->slot);
} else if (column == 7) {
GET_CONTENT("%d", entry->function);
} else if (column == 8) {
GET_CONTENT("%d", entry->interruptPin);
} else if (column == 9) {
GET_CONTENT("%d", entry->interruptLine);
} else if (column == 10) {
GET_CONTENT("%x, %D", entry->baseAddresses[0], entry->baseAddressesSizes[0]);
} else if (column == 11) {
GET_CONTENT("%x, %D", entry->baseAddresses[1], entry->baseAddressesSizes[1]);
} else if (column == 12) {
GET_CONTENT("%x, %D", entry->baseAddresses[2], entry->baseAddressesSizes[2]);
} else if (column == 13) {
GET_CONTENT("%x, %D", entry->baseAddresses[3], entry->baseAddressesSizes[3]);
} else if (column == 14) {
GET_CONTENT("%x, %D", entry->baseAddresses[4], entry->baseAddressesSizes[4]);
} else if (column == 15) {
GET_CONTENT("%x, %D", entry->baseAddresses[5], entry->baseAddressesSizes[5]);
} else {
EsAssert(false);
}
return ES_HANDLED;
}
return 0;
}
void AddTab(EsElement *toolbar, uintptr_t index, const char *label, bool asDefault = false) {
EsButton *button = EsButtonCreate(toolbar, ES_BUTTON_RADIOBOX, 0, label);
button->userData.u = index;
@ -471,8 +385,6 @@ void ProcessApplicationMessage(EsMessage *message) {
AddListView(&instance->listViewProcesses, switcher, ListViewProcessesCallback,
listViewProcessesColumns, sizeof(listViewProcessesColumns), ES_LIST_VIEW_SINGLE_SELECT);
AddListView(&instance->listViewPCIDevices, switcher, ListViewPCIDevicesCallback,
listViewPCIDevicesColumns, sizeof(listViewPCIDevicesColumns), ES_FLAGS_DEFAULT);
instance->panelMemoryStatistics = EsPanelCreate(switcher,
ES_CELL_FILL | ES_PANEL_TABLE | ES_PANEL_HORIZONTAL | ES_PANEL_V_SCROLL_AUTO, &stylePanelMemoryStatistics);
@ -481,7 +393,6 @@ void ProcessApplicationMessage(EsMessage *message) {
EsElement *toolbar = EsWindowGetToolbar(window);
AddTab(toolbar, DISPLAY_PROCESSES, "Processes", true);
AddTab(toolbar, DISPLAY_GENERAL_LOG, "System log");
AddTab(toolbar, DISPLAY_PCI_DEVICES, "PCI devices");
AddTab(toolbar, DISPLAY_MEMORY, "Memory");
} else if (message->type == ES_MSG_INSTANCE_DESTROY) {
processes.Free();

View File

@ -162,6 +162,7 @@ struct {
Array<InstalledApplication *> installedApplications;
Array<ApplicationInstance *> allApplicationInstances;
Array<ContainerWindow *> allContainerWindows;
Array<EsMessageDevice> connectedDevices;
InstalledApplication *fileManager;
uint64_t currentDocumentID;
HashStore<uint64_t, OpenDocument> openDocuments;
@ -1912,6 +1913,16 @@ void DesktopMessage(EsMessage *message) {
EsMessagePostRemote(instance->processHandle, message);
}
}
} else if (message->type == ES_MSG_DEVICE_CONNECTED) {
desktop.connectedDevices.Add(message->device);
} else if (message->type == ES_MSG_DEVICE_DISCONNECTED) {
for (uintptr_t i = 0; i < desktop.connectedDevices.Length(); i++) {
if (desktop.connectedDevices[i].id == message->device.id) {
EsHandleClose(desktop.connectedDevices[i].handle);
desktop.connectedDevices.Delete(i);
break;
}
}
} else if (message->type == ES_MSG_SET_SCREEN_RESOLUTION) {
if (desktop.setupDesktopUIComplete) {
DesktopSetup(); // Refresh desktop UI.

View File

@ -28,6 +28,7 @@ type_name uint64_t EsAudioDeviceID;
type_name uint16_t EsFontFamily;
type_name uint64_t EsTimer;
type_name int64_t EsListViewIndex;
type_name uint64_t EsObjectID;
define ES_SCANCODE_A (0x04)
define ES_SCANCODE_B (0x05)
@ -957,6 +958,8 @@ enum EsMessageType {
ES_MSG_REGISTER_FILE_SYSTEM = 0x4804
ES_MSG_UNREGISTER_FILE_SYSTEM = 0x4805
ES_MSG_DESKTOP = 0x4806
ES_MSG_DEVICE_CONNECTED = 0x4807
ES_MSG_DEVICE_DISCONNECTED = 0x4808
// Messages sent from Desktop to application instances:
ES_MSG_TAB_INSPECT_UI = 0x4A01
@ -1148,7 +1151,7 @@ struct EsBatchCall {
struct EsThreadInformation {
EsHandle handle;
uint64_t tid;
EsObjectID tid;
}
struct EsProcessInformation {
@ -1206,7 +1209,7 @@ struct EsCrashReason {
struct EsProcessState {
EsCrashReason crashReason;
uint64_t id;
EsObjectID id;
uint8_t executableState;
uint8_t flags;
}
@ -1412,7 +1415,7 @@ struct EsAnalogInput {
};
struct EsGameControllerState {
uint64_t id;
EsObjectID id;
uint8_t buttonCount, analogCount; // Number of buttons and analog inputs.
uint8_t directionalPad; // Directions given from 0-7, starting at up, going clockwise. 15 indicates unpressed.
uint32_t buttons; // Bitset of pressed buttons.
@ -1483,7 +1486,7 @@ struct EsVolumeInformation {
char label[64];
uint8_t labelBytes;
uint8_t driveType;
uint64_t id;
EsObjectID id;
EsFileOffset spaceTotal;
EsFileOffset spaceUsed;
};
@ -1685,7 +1688,7 @@ struct EsMessageProcessCrash {
};
struct EsMessageDesktop {
uint64_t windowID;
EsObjectID windowID;
EsHandle buffer;
size_t bytes;
};
@ -1702,7 +1705,7 @@ struct EsMessageCreateInstance {
};
struct EsMessageTabOperation {
uint64_t id;
EsObjectID id;
EsHandle handle;
union { size_t bytes; bool isSource; };
EsError error;
@ -1720,10 +1723,16 @@ struct EsMessageRegisterFileSystem {
};
struct EsMessageUnregisterFileSystem {
uint64_t id;
EsObjectID id;
EsMountPoint *mountPoint;
};
struct EsMessageDevice {
EsObjectID id;
EsHandle handle;
EsDeviceType type;
};
// Message structure.
struct EsMessageUser {
@ -1795,6 +1804,7 @@ struct EsMessage {
EsMessageTabOperation tabOperation;
EsMessageRegisterFileSystem registerFileSystem;
EsMessageUnregisterFileSystem unregisterFileSystem;
EsMessageDevice device;
};
}
@ -1810,7 +1820,7 @@ struct EsThreadEventLogEntry {
uint8_t expressionBytes;
uint8_t event;
uint16_t line;
uint64_t objectID, threadID;
EsObjectID objectID, threadID;
};
struct EsMemoryStatistics {
@ -1928,14 +1938,14 @@ function void _EsPathAnnouncePathMoved(EsInstance *instance, STRING oldPath, STR
function EsError EsProcessCreate(EsProcessCreationArguments *arguments, EsProcessInformation *information);
function int EsProcessGetExitStatus(EsHandle process);
function uintptr_t EsProcessGetID(EsHandle process);
function EsObjectID EsProcessGetID(EsHandle process);
function void EsProcessGetState(EsHandle process, EsProcessState *state);
function EsHandle EsProcessOpen(uint64_t pid);
function EsHandle EsProcessOpen(EsObjectID pid);
function void EsProcessPause(EsHandle process, bool resume);
function void EsProcessTerminate(EsHandle process, int status);
function void EsProcessTerminateCurrent();
function EsError EsThreadCreate(EsThreadEntryFunction entryFunction, EsThreadInformation *information, EsGeneric argument);
function uint64_t EsThreadGetID(EsHandle thread); // TODO Make this 64-bit.
function EsObjectID EsThreadGetID(EsHandle thread); // TODO Make this 64-bit.
function void EsThreadTerminate(EsHandle thread);
// Memory.

View File

@ -663,7 +663,7 @@ void ACPIInitialise2() {
if (AE_OK == AcpiEnableEvent(ACPI_EVENT_POWER_BUTTON, 0)
&& AE_OK == AcpiInstallFixedEventHandler(ACPI_EVENT_POWER_BUTTON, ACPIPowerButtonPressed, nullptr)) {
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice), ES_DEVICE_OTHER);
KDeviceCreate("ACPI power button", acpi.computer, sizeof(KDevice));
}
void *result;
@ -695,7 +695,7 @@ void KPS2SafeToInitialise() {
}
static void DeviceAttach(KDevice *parentDevice) {
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER);
acpi.computer = KDeviceCreate("ACPI computer", parentDevice, sizeof(KDevice));
#ifndef SERIAL_STARTUP
KThreadCreate("InitACPI", [] (uintptr_t) { ACPIInitialise2(); });

View File

@ -827,7 +827,7 @@ void AHCIController::Initialise() {
for (uintptr_t i = 0; i < MAX_PORTS; i++) {
if (!ports[i].connected) continue;
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive), ES_DEVICE_BLOCK);
AHCIDrive *device = (AHCIDrive *) KDeviceCreate("AHCI drive", this, sizeof(AHCIDrive));
if (!device) {
KernelLog(LOG_ERROR, "AHCI", "allocation failure", "Could not create device for port %d.\n", i);
@ -863,7 +863,7 @@ void AHCIController::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController), ES_DEVICE_CONTROLLER);
AHCIController *device = (AHCIController *) KDeviceCreate("AHCI controller", parent, sizeof(AHCIController));
if (!device) return;
device->pci = parent;

View File

@ -29,7 +29,7 @@ void BGADebugClearScreen() {
void BGADeviceAttached(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay), ES_DEVICE_GRAPHICS_TARGET);
BGADisplay *device = (BGADisplay *) KDeviceCreate("BGA", parent, sizeof(BGADisplay));
if (!device) return;
parent->EnableFeatures(K_PCI_FEATURE_IO_PORT_ACCESS | K_PCI_FEATURE_MEMORY_SPACE_ACCESS | K_PCI_FEATURE_BAR_0);

View File

@ -1953,7 +1953,7 @@ static void Unmount(KFileSystem *fileSystem) {
}
static void Register(KDevice *_parent) {
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", _parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
Volume *volume = (Volume *) KDeviceCreate("EssenceFS", _parent, sizeof(Volume));
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "EsFS", "allocation failure", "Register - Could not allocate file system.\n");

View File

@ -593,7 +593,7 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
Volume *volume = (Volume *) KDeviceCreate("ext2", parent, sizeof(Volume));
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "Ext2", "allocate error", "Could not initialise volume.\n");

View File

@ -454,7 +454,7 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
Volume *volume = (Volume *) KDeviceCreate("FAT", parent, sizeof(Volume));
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "FAT", "allocate error", "DeviceAttach - Could not initialise volume.\n");

View File

@ -286,7 +286,7 @@ static void HDAControllerExploreFunctionGroup(HDAController *controller, uint32_
uint32_t widgetType = ES_EXTRACT_BITS(widgetCapabilities, 23, 20);
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget), ES_DEVICE_AUDIO);
HDAWidget *widget = (HDAWidget *) KDeviceCreate("HD Audio widget", controller, sizeof(HDAWidget));
widget->codec = codec;
widget->node = j;
widget->functionGroup = functionGroupNode;
@ -369,7 +369,7 @@ static void HDAControllerExploreFunctionGroup(HDAController *controller, uint32_
}
}
// TODO Register the device with the audio subsystem.
KDeviceSendConnectedMessage(widget, ES_DEVICE_AUDIO);
}
}
}
@ -382,7 +382,7 @@ static void HDAControllerDestroy(KDevice *_controller) {
}
static void HDAControllerAttach(KDevice *_parent) {
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController), ES_DEVICE_CONTROLLER);
HDAController *controller = (HDAController *) KDeviceCreate("HD Audio controller", _parent, sizeof(HDAController));
if (!controller) {
return;

View File

@ -469,7 +469,7 @@ void Controller::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller), ES_DEVICE_NETWORK_CARD);
Controller *device = (Controller *) KDeviceCreate("I8254x", parent, sizeof(Controller));
if (!device) return;
device->shutdown = [] (KDevice *device) {

View File

@ -551,7 +551,7 @@ void ATAController::Initialise() {
for (uintptr_t i = 0; i < ATA_DRIVES; i++) {
if (sectorCount[i]) {
// Register the drive.
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive), ES_DEVICE_BLOCK);
ATADrive *device = (ATADrive *) KDeviceCreate("IDE drive", this, sizeof(ATADrive));
if (!device) {
KernelLog(LOG_ERROR, "IDE", "allocation failure", "Could not create device for drive %d.\n", i);
@ -585,7 +585,7 @@ static void DeviceAttach(KDevice *_parent) {
return;
}
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController), ES_DEVICE_CONTROLLER);
ATAController *device = (ATAController *) KDeviceCreate("IDE controller", parent, sizeof(ATAController));
if (!device) return;
ataController = device;
device->pci = parent;

View File

@ -488,7 +488,7 @@ static void Close(KNode *node) {
}
static void DeviceAttach(KDevice *parent) {
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume), ES_DEVICE_FILE_SYSTEM);
Volume *volume = (Volume *) KDeviceCreate("ISO9660", parent, sizeof(Volume));
if (!volume || !FSFileSystemInitialise(volume)) {
KernelLog(LOG_ERROR, "ISO9660", "allocate error", "DeviceAttach - Could not initialise volume.\n");

View File

@ -792,7 +792,7 @@ void NVMeController::Initialise() {
KernelLog(LOG_INFO, "NVMe", "namespace identified", "Identifier namespace %d with sectors of size %D, and a capacity of %D.%z\n",
nsid, sectorBytes, capacity, readOnly ? " The namespace is read-only." : "");
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive), ES_DEVICE_BLOCK);
NVMeDrive *device = (NVMeDrive *) KDeviceCreate("NVMe namespace", this, sizeof(NVMeDrive));
if (!device) {
KernelLog(LOG_ERROR, "NVMe", "allocation failure", "Could not create device for namespace %d.\n", nsid);
@ -849,7 +849,7 @@ void NVMeController::Shutdown() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController), ES_DEVICE_CONTROLLER);
NVMeController *device = (NVMeController *) KDeviceCreate("NVMe controller", parent, sizeof(NVMeController));
if (!device) return;
device->pci = parent;

View File

@ -433,7 +433,7 @@ void PCIController::EnumerateFunction(int bus, int device, int function, int *bu
uint32_t deviceClass = ReadConfig(bus, device, function, 0x08);
uint32_t interruptInformation = ReadConfig(bus, device, function, 0x3C);
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice), ES_DEVICE_PCI_FUNCTION);
KPCIDevice *pciDevice = (KPCIDevice *) KDeviceCreate("PCI function", this, sizeof(KPCIDevice));
if (!pciDevice) return;
pciDevice->classCode = (deviceClass >> 24) & 0xFF;
@ -537,7 +537,7 @@ static void DeviceAttach(KDevice *parent) {
return;
}
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController), ES_DEVICE_CONTROLLER);
pci = (PCIController *) KDeviceCreate("PCI controller", parent, sizeof(PCIController));
if (pci) {
pci->Enumerate();

View File

@ -550,9 +550,9 @@ void PS2::Initialise(KDevice *parentDevice) {
registeredIRQs = true;
}
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice), ES_DEVICE_CONTROLLER);
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice), ES_DEVICE_HID);
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice), ES_DEVICE_HID);
KDevice *controller = KDeviceCreate("PS/2 controller", parentDevice, sizeof(KDevice));
KDeviceCreate("PS/2 keyboard", controller, sizeof(KDevice));
if (channels == 2) KDeviceCreate("PS/2 mouse", controller, sizeof(KDevice));
KernelLog(LOG_INFO, "PS/2", "controller initialised", "Setup PS/2 controller%z.\n", channels == 2 ? ", with a mouse" : "");
}

View File

@ -103,7 +103,7 @@ void InitialiseVBE(KDevice *parent) {
}
}
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VBE", parent, sizeof(KGraphicsTarget));
linearBuffer = (uint8_t *) MMMapPhysical(MMGetKernelSpace(), vbeMode->bufferPhysical,
vbeMode->bytesPerScanlineLinear * vbeMode->heightPixels, MM_REGION_WRITE_COMBINING);
@ -267,7 +267,7 @@ void InitialiseVGA(KDevice *parent) {
ProcessorIn8(VGA_INSTAT_READ);
ProcessorOut8(VGA_AC_INDEX, 0x20);
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget), ES_DEVICE_GRAPHICS_TARGET);
KGraphicsTarget *target = (KGraphicsTarget *) KDeviceCreate("VGA", parent, sizeof(KGraphicsTarget));
target->screenWidth = VGA_SCREEN_WIDTH;
target->screenHeight = VGA_SCREEN_HEIGHT;
target->updateScreen = VGAUpdateScreen;

View File

@ -185,7 +185,7 @@ void Device::Initialise() {
// Register the drive.
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive), ES_DEVICE_BLOCK);
Drive *drive = (Drive *) KDeviceCreate("USB bulk drive", this, sizeof(Drive));
if (!drive) {
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not create drive for LUN %d.\n", i);
@ -206,7 +206,7 @@ void Device::Initialise() {
}
static void DeviceAttach(KDevice *parent) {
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device), ES_DEVICE_OTHER);
Device *device = (Device *) KDeviceCreate("USB bulk", parent, sizeof(Device));
if (!device) {
KernelLog(LOG_ERROR, "USBBulk", "allocation failure", "Could not allocate device structure.\n");

View File

@ -719,7 +719,7 @@ static void DeviceDestroy(KDevice *_device) {
}
static void DeviceAttach(KDevice *parent) {
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice), ES_DEVICE_HID);
HIDDevice *device = (HIDDevice *) KDeviceCreate("USB HID", parent, sizeof(HIDDevice));
if (!device) {
KernelLog(LOG_ERROR, "USBHID", "allocation failure", "Could not allocate HIDDevice structure.\n");

View File

@ -849,7 +849,7 @@ void XHCIController::OnPortEnable(uintptr_t port) {
// Register the device with USB subsystem.
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice), ES_DEVICE_USB);
XHCIDevice *device = (XHCIDevice *) KDeviceCreate("XHCI device", this, sizeof(XHCIDevice));
ports[port].device = device;
device->port = port;
device->controlTransfer = ControlTransferWrapper;
@ -1255,7 +1255,7 @@ void XHCIController::Initialise() {
static void DeviceAttach(KDevice *_parent) {
KPCIDevice *parent = (KPCIDevice *) _parent;
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController), ES_DEVICE_CONTROLLER);
XHCIController *device = (XHCIController *) KDeviceCreate("XHCI controller", parent, sizeof(XHCIController));
if (!device) return;
device->pci = parent;

View File

View File

@ -17,7 +17,7 @@ Array<KInstalledDriver, K_FIXED> installedDrivers;
void *ResolveKernelSymbol(const char *name, size_t nameBytes);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes, EsDeviceType type) {
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes) {
if (bytes < sizeof(KDevice)) {
KernelPanic("KDeviceCreate - Device structure size is too small (less than KDevice).\n");
}
@ -28,7 +28,9 @@ KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes, Es
device->parent = parent;
device->cDebugName = cDebugName;
device->handles = 2; // One handle for the creator, and another closed when the device is removed (by the parent).
device->type = type;
static EsObjectID previousObjectID = 0;
device->objectID = __sync_add_and_fetch(&previousObjectID, 1);
if (parent) {
KMutexAcquire(&deviceTreeMutex);
@ -112,11 +114,46 @@ void DeviceRemovedRecurse(KDevice *device) {
i--;
}
if (device->flags & K_DEVICE_VISIBLE_TO_USER) {
EsMessage m;
EsMemoryZero(&m, sizeof(m));
m.type = ES_MSG_DEVICE_DISCONNECTED;
m.device.id = device->objectID;
desktopProcess->messageQueue.SendMessage(nullptr, &m);
}
if (device->removed) {
device->removed(device);
}
}
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type) {
KMutexAcquire(&deviceTreeMutex);
if (device->flags & K_DEVICE_VISIBLE_TO_USER) {
KernelPanic("KDeviceSendConnectedMessage - Connected message already sent for device %x.\n", device);
}
device->flags |= K_DEVICE_VISIBLE_TO_USER;
KMutexRelease(&deviceTreeMutex);
KDeviceOpenHandle(device);
EsMessage m;
EsMemoryZero(&m, sizeof(m));
m.type = ES_MSG_DEVICE_CONNECTED;
m.device.id = device->objectID;
m.device.type = type;
m.device.handle = desktopProcess->handleTable.OpenHandle(device, 0, KERNEL_OBJECT_DEVICE);
if (m.device.handle) {
if (!desktopProcess->messageQueue.SendMessage(nullptr, &m)) {
desktopProcess->handleTable.CloseHandle(m.device.handle); // This will check that the handle is still valid.
}
}
}
void KDeviceRemoved(KDevice *device) {
KMutexAcquire(&deviceTreeMutex);
DeviceRemovedRecurse(device);
@ -255,7 +292,7 @@ bool KDeviceAttachByName(KDevice *parentDevice, const char *cName) {
void DeviceRootAttach(KDevice *parentDevice) {
// Load all the root drivers and create their devices.
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice), ES_DEVICE_OTHER), "Root");
KDeviceAttachAll(KDeviceCreate("root", parentDevice, sizeof(KDevice)), "Root");
// Check we have found the drive from which we booted.
// TODO Decide the timeout.

View File

@ -1669,7 +1669,7 @@ void FSPartitionDeviceAccess(KBlockDeviceAccessRequest request) {
}
void FSPartitionDeviceCreate(KBlockDevice *parent, EsFileOffset offset, EsFileOffset sectorCount, unsigned flags, const char *cName) {
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice), ES_DEVICE_BLOCK);
PartitionDevice *child = (PartitionDevice *) KDeviceCreate(cName, parent, sizeof(PartitionDevice));
if (!child) return;
child->parent = parent;
@ -1851,14 +1851,11 @@ void FSFileSystemDeviceRemoved(KDevice *device) {
EsMessage m;
EsMemoryZero(&m, sizeof(EsMessage));
m.type = ES_MSG_UNREGISTER_FILE_SYSTEM;
m.unregisterFileSystem.id = fileSystem->id;
m.unregisterFileSystem.id = fileSystem->objectID;
desktopProcess->messageQueue.SendMessage(nullptr, &m);
}
void FSRegisterFileSystem(KFileSystem *fileSystem) {
static volatile uint64_t id = 1;
fileSystem->id = __sync_fetch_and_add(&id, 1);
fileSystem->removed = FSFileSystemDeviceRemoved;
MMObjectCacheRegister(&fileSystem->cachedDirectoryEntries, FSTrimCachedDirectoryEntry,
@ -1880,6 +1877,8 @@ void FSRegisterFileSystem(KFileSystem *fileSystem) {
desktopProcess->handleTable.CloseHandle(m.registerFileSystem.rootDirectory); // This will check that the handle is still valid.
}
}
KDeviceSendConnectedMessage(fileSystem, ES_DEVICE_FILE_SYSTEM);
}
void FSRegisterBlockDevice(KBlockDevice *device) {

View File

@ -225,6 +225,7 @@ enum KernelObjectType : uint32_t {
KERNEL_OBJECT_DIRECTORY_MONITOR = 0x00000100, // Monitors a directory, sending messages to the owner process.
KERNEL_OBJECT_EVENT_SINK = 0x00002000, // An event sink. Events can be forwarded to it, allowing waiting on many objects.
KERNEL_OBJECT_CONNECTION = 0x00004000, // A network connection.
KERNEL_OBJECT_DEVICE = 0x00008000, // A device.
};
// TODO Rename to KObjectReference and KObjectDereference?
@ -543,19 +544,20 @@ struct KInstalledDriver {
struct KDevice {
const char *cDebugName;
KDevice *parent; // The parent device.
KDevice *parent; // The parent device.
Array<KDevice *, K_FIXED> children; // Child devices.
#define K_DEVICE_REMOVED (1 << 0)
#define K_DEVICE_REMOVED (1 << 0)
#define K_DEVICE_VISIBLE_TO_USER (1 << 1) // A ES_MSG_DEVICE_CONNECTED message was sent to Desktop for this device.
uint8_t flags;
uint16_t type;
uint32_t handles;
EsObjectID objectID;
// These callbacks are called with the deviceTreeMutex locked.
void (*shutdown)(KDevice *device); // Called when the computer is about to shutdown. Optional.
void (*dumpState)(KDevice *device); // Dump the entire state of the device for debugging. Optional.
void (*removed)(KDevice *device); // Called when the device is removed. Called after the children are informed. Optional.
void (*destroy)(KDevice *device); // Called just before the device is destroyed.
// These callbacks are called with the deviceTreeMutex locked, and are all optional.
void (*shutdown)(KDevice *device); // Called when the computer is about to shutdown.
void (*dumpState)(KDevice *device); // Dump the entire state of the device for debugging.
void (*removed)(KDevice *device); // Called when the device is removed. Called after the children are informed.
void (*destroy)(KDevice *device); // Called just before the device is destroyed.
};
struct KDriver {
@ -575,18 +577,17 @@ typedef bool KDriverIsImplementorCallback(KInstalledDriver *driver, KDevice *dev
// - It calls KDeviceAttach on the function device.
// - A suitable driver is found, which creates a device with that as its parent.
bool KDeviceAttach(KDevice *parentDevice, const char *cParentDriver /* match the parent field in the config */, KDriverIsImplementorCallback callback);
// Similar to KDeviceAttach, except it calls `attach` for every driver that matches the parent field.
void KDeviceAttachAll(KDevice *parentDevice, const char *cParentDriver);
// Similar to KDeviceAttach, except it calls `attach` only for the driver matching the provided name. Returns true if the driver was found.
bool KDeviceAttachByName(KDevice *parentDevice, const char *cName);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */, EsDeviceType type);
KDevice *KDeviceCreate(const char *cDebugName, KDevice *parent, size_t bytes /* must be at least the size of a KDevice */);
void KDeviceOpenHandle(KDevice *device);
void KDeviceDestroy(KDevice *device); // Call if initialisation of the device failed. Otherwise use KDeviceCloseHandle.
void KDeviceCloseHandle(KDevice *device); // The device creator is responsible for one handle after the creating it. The device is destroyed once all handles are closed.
void KDeviceRemoved(KDevice *device); // Call when a child device is removed. Must be called only once!
void KDeviceSendConnectedMessage(KDevice *device, EsDeviceType type); // Send a message to Desktop to inform it the device was connected.
#include <bin/kernel_config.h>
@ -885,7 +886,6 @@ struct KFileSystem : KDevice {
KMutex moveMutex;
bool isBootFileSystem, unmounting;
volatile uint64_t totalHandleCount;
uint64_t id;
CCSpace cacheSpace;
MMObjectCache cachedDirectoryEntries, // Directory entries without a loaded node.

View File

@ -245,6 +245,10 @@ bool OpenHandleToObject(void *object, KernelObjectType type, uint32_t flags, boo
hadNoHandles = 0 == __sync_fetch_and_add(&connection->handles, 1);
} break;
case KERNEL_OBJECT_DEVICE: {
KDeviceOpenHandle((KDevice *) object);
} break;
default: {
KernelPanic("OpenHandleToObject - Cannot open object of type %x.\n", type);
} break;
@ -413,6 +417,10 @@ void CloseHandleToObject(void *object, KernelObjectType type, uint32_t flags) {
if (previous == 1) NetConnectionClose(connection);
} break;
case KERNEL_OBJECT_DEVICE: {
KDeviceCloseHandle((KDevice *) object);
} break;
default: {
KernelPanic("CloseHandleToObject - Cannot close object of type %x.\n", type);
} break;

View File

@ -53,7 +53,7 @@ struct Thread {
struct Process *process;
uint64_t id;
EsObjectID id;
volatile uintptr_t cpuTimeSlices;
volatile size_t handles;
int executingProcessorID;
@ -132,7 +132,7 @@ struct Process {
ProcessType type;
// Object management:
uint64_t id;
EsObjectID id;
volatile size_t handles;
LinkedItem<Process> allItem;
@ -220,8 +220,8 @@ struct Scheduler {
Pool threadPool, processPool, mmSpacePool;
LinkedList<Thread> allThreads;
LinkedList<Process> allProcesses;
uint64_t nextThreadID;
uint64_t nextProcessID;
EsObjectID nextThreadID;
EsObjectID nextProcessID;
size_t activeProcessCount;
volatile bool started, panic, shutdown;

View File

@ -824,7 +824,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_VOLUME_GET_INFORMATION) {
information.driveType = fileSystem->block->driveType;
information.spaceUsed = fileSystem->spaceUsed;
information.spaceTotal = fileSystem->spaceTotal;
information.id = fileSystem->id;
information.id = fileSystem->objectID;
SYSCALL_WRITE(argument1, &information, sizeof(EsVolumeInformation));
SYSCALL_RETURN(ES_SUCCESS, false);

View File

@ -12,7 +12,7 @@ struct EmbeddedWindow {
void *volatile apiWindow;
volatile uint32_t handles;
struct Window *container;
uint64_t id;
EsObjectID id;
uint32_t resizeClearColor;
bool closed;
};
@ -43,7 +43,7 @@ struct Window {
void *apiWindow;
EmbeddedWindow *embed;
volatile uint64_t handles;
uint64_t id;
EsObjectID id;
// Location:
EsPoint position;
@ -84,7 +84,7 @@ struct WindowManager {
Window *pressedWindow, *activeWindow, *hoverWindow;
KMutex mutex;
KEvent windowsToCloseEvent;
uint64_t currentWindowID;
EsObjectID currentWindowID;
size_t inspectorWindowCount;
// Cursor:
@ -123,7 +123,7 @@ struct WindowManager {
KMutex gameControllersMutex;
EsGameControllerState gameControllers[ES_GAME_CONTROLLER_MAX_COUNT];
size_t gameControllerCount;
uint64_t gameControllerID;
EsObjectID gameControllerID;
// Flicker-free resizing:
@ -1292,7 +1292,7 @@ void KKeyboardUpdate(uint16_t *keysDown, size_t keysDownCount) {
uint64_t KGameControllerConnect() {
KMutexAcquire(&windowManager.gameControllersMutex);
uint64_t id = ++windowManager.gameControllerID;
EsObjectID id = ++windowManager.gameControllerID;
if (windowManager.gameControllerCount != ES_GAME_CONTROLLER_MAX_COUNT) {
windowManager.gameControllers[windowManager.gameControllerCount++].id = id;