From 3180b1622147d556cbcbf6654c28e4c227f0ff32 Mon Sep 17 00:00:00 2001 From: nakst <> Date: Tue, 17 Aug 2021 20:13:54 +0100 Subject: [PATCH] make KDevice a kernel object --- apps/system_monitor.cpp | 89 ----------------------------------------- desktop/desktop.cpp | 11 +++++ desktop/os.header | 32 ++++++++++----- drivers/acpi.cpp | 4 +- drivers/ahci.cpp | 4 +- drivers/bga.cpp | 2 +- drivers/esfs2.cpp | 2 +- drivers/ext2.cpp | 2 +- drivers/fat.cpp | 2 +- drivers/hda.cpp | 6 +-- drivers/i8254x.cpp | 2 +- drivers/ide.cpp | 4 +- drivers/iso9660.cpp | 2 +- drivers/nvme.cpp | 4 +- drivers/pci.cpp | 4 +- drivers/ps2.cpp | 6 +-- drivers/svga.cpp | 4 +- drivers/usb_bulk.cpp | 4 +- drivers/usb_hid.cpp | 2 +- drivers/xhci.cpp | 4 +- kernel/audio.cpp | 0 kernel/drivers.cpp | 43 ++++++++++++++++++-- kernel/files.cpp | 9 ++--- kernel/module.h | 24 +++++------ kernel/objects.cpp | 8 ++++ kernel/scheduler.cpp | 8 ++-- kernel/syscall.cpp | 2 +- kernel/windows.cpp | 10 ++--- 28 files changed, 135 insertions(+), 159 deletions(-) delete mode 100644 kernel/audio.cpp diff --git a/apps/system_monitor.cpp b/apps/system_monitor.cpp index a7c1bf2..5df210b 100644 --- a/apps/system_monitor.cpp +++ b/apps/system_monitor.cpp @@ -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 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(); diff --git a/desktop/desktop.cpp b/desktop/desktop.cpp index a3b5a41..14aad05 100644 --- a/desktop/desktop.cpp +++ b/desktop/desktop.cpp @@ -162,6 +162,7 @@ struct { Array installedApplications; Array allApplicationInstances; Array allContainerWindows; + Array connectedDevices; InstalledApplication *fileManager; uint64_t currentDocumentID; HashStore 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. diff --git a/desktop/os.header b/desktop/os.header index ea69d9c..c9e6316 100644 --- a/desktop/os.header +++ b/desktop/os.header @@ -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. diff --git a/drivers/acpi.cpp b/drivers/acpi.cpp index 07be674..c3a3700 100644 --- a/drivers/acpi.cpp +++ b/drivers/acpi.cpp @@ -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(); }); diff --git a/drivers/ahci.cpp b/drivers/ahci.cpp index 15b259b..b841256 100644 --- a/drivers/ahci.cpp +++ b/drivers/ahci.cpp @@ -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; diff --git a/drivers/bga.cpp b/drivers/bga.cpp index 4f3a246..a17579b 100644 --- a/drivers/bga.cpp +++ b/drivers/bga.cpp @@ -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); diff --git a/drivers/esfs2.cpp b/drivers/esfs2.cpp index 3e93832..af4d58e 100644 --- a/drivers/esfs2.cpp +++ b/drivers/esfs2.cpp @@ -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"); diff --git a/drivers/ext2.cpp b/drivers/ext2.cpp index e48e257..b5ee69e 100644 --- a/drivers/ext2.cpp +++ b/drivers/ext2.cpp @@ -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"); diff --git a/drivers/fat.cpp b/drivers/fat.cpp index 30c53c3..5ba837c 100644 --- a/drivers/fat.cpp +++ b/drivers/fat.cpp @@ -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"); diff --git a/drivers/hda.cpp b/drivers/hda.cpp index 868420f..0fb14d4 100644 --- a/drivers/hda.cpp +++ b/drivers/hda.cpp @@ -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; diff --git a/drivers/i8254x.cpp b/drivers/i8254x.cpp index 33cd6bf..36d5f2b 100644 --- a/drivers/i8254x.cpp +++ b/drivers/i8254x.cpp @@ -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) { diff --git a/drivers/ide.cpp b/drivers/ide.cpp index 8f32d8a..2d34f1e 100644 --- a/drivers/ide.cpp +++ b/drivers/ide.cpp @@ -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; diff --git a/drivers/iso9660.cpp b/drivers/iso9660.cpp index 46453b6..1f68b0f 100644 --- a/drivers/iso9660.cpp +++ b/drivers/iso9660.cpp @@ -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"); diff --git a/drivers/nvme.cpp b/drivers/nvme.cpp index a463ec0..5c209fa 100644 --- a/drivers/nvme.cpp +++ b/drivers/nvme.cpp @@ -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; diff --git a/drivers/pci.cpp b/drivers/pci.cpp index 7a581bb..25a4b44 100644 --- a/drivers/pci.cpp +++ b/drivers/pci.cpp @@ -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(); diff --git a/drivers/ps2.cpp b/drivers/ps2.cpp index c2571a2..cad7ffc 100644 --- a/drivers/ps2.cpp +++ b/drivers/ps2.cpp @@ -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" : ""); } diff --git a/drivers/svga.cpp b/drivers/svga.cpp index b436eb8..16ecbf7 100644 --- a/drivers/svga.cpp +++ b/drivers/svga.cpp @@ -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; diff --git a/drivers/usb_bulk.cpp b/drivers/usb_bulk.cpp index 07b2168..e41d881 100644 --- a/drivers/usb_bulk.cpp +++ b/drivers/usb_bulk.cpp @@ -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"); diff --git a/drivers/usb_hid.cpp b/drivers/usb_hid.cpp index 69465da..806e19d 100644 --- a/drivers/usb_hid.cpp +++ b/drivers/usb_hid.cpp @@ -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"); diff --git a/drivers/xhci.cpp b/drivers/xhci.cpp index 171e9c0..5f3e881 100644 --- a/drivers/xhci.cpp +++ b/drivers/xhci.cpp @@ -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; diff --git a/kernel/audio.cpp b/kernel/audio.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/kernel/drivers.cpp b/kernel/drivers.cpp index ed025cc..96c255b 100644 --- a/kernel/drivers.cpp +++ b/kernel/drivers.cpp @@ -17,7 +17,7 @@ Array 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. diff --git a/kernel/files.cpp b/kernel/files.cpp index 679e1fd..e8bd4d2 100644 --- a/kernel/files.cpp +++ b/kernel/files.cpp @@ -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) { diff --git a/kernel/module.h b/kernel/module.h index 4d29167..d4eefb5 100644 --- a/kernel/module.h +++ b/kernel/module.h @@ -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 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 @@ -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. diff --git a/kernel/objects.cpp b/kernel/objects.cpp index 7de68eb..a701ed3 100644 --- a/kernel/objects.cpp +++ b/kernel/objects.cpp @@ -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; diff --git a/kernel/scheduler.cpp b/kernel/scheduler.cpp index c79d698..6774323 100644 --- a/kernel/scheduler.cpp +++ b/kernel/scheduler.cpp @@ -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 allItem; @@ -220,8 +220,8 @@ struct Scheduler { Pool threadPool, processPool, mmSpacePool; LinkedList allThreads; LinkedList allProcesses; - uint64_t nextThreadID; - uint64_t nextProcessID; + EsObjectID nextThreadID; + EsObjectID nextProcessID; size_t activeProcessCount; volatile bool started, panic, shutdown; diff --git a/kernel/syscall.cpp b/kernel/syscall.cpp index d417ee0..2dd82fc 100644 --- a/kernel/syscall.cpp +++ b/kernel/syscall.cpp @@ -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); diff --git a/kernel/windows.cpp b/kernel/windows.cpp index ec2d3c9..250d6fd 100644 --- a/kernel/windows.cpp +++ b/kernel/windows.cpp @@ -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;