feat: Intel HDA audio driver, audio streaming syscalls, userspace Music app, fixes and improvements, rudimentary Bluetooth support

This commit is contained in:
2026-03-10 17:14:33 +01:00
parent 807c2602fe
commit 576ad34f95
58 changed files with 11275 additions and 137 deletions
+100 -22
View File
@@ -9,13 +9,18 @@
#include <Hal/Apic/ApicInit.hpp>
#include <Drivers/PS2/PS2Controller.hpp>
#include <Drivers/USB/Xhci.hpp>
#include <Drivers/USB/UsbDevice.hpp>
#include <Drivers/USB/Bluetooth/Bluetooth.hpp>
#include <Drivers/Net/E1000.hpp>
#include <Drivers/Net/E1000E.hpp>
#include <Drivers/Graphics/IntelGPU.hpp>
#include <Drivers/Storage/Ahci.hpp>
#include <Drivers/Audio/IntelHda.hpp>
#include <Pci/Pci.hpp>
#include "Syscall.hpp"
#include <Drivers/Storage/BlockDevice.hpp>
#include <Drivers/Storage/Nvme.hpp>
namespace Montauk {
@@ -92,10 +97,12 @@ namespace Montauk {
auto* dev = Drivers::USB::Xhci::GetDevice(slot);
if (!dev || !dev->Active) continue;
const char* devName = "USB Device";
if (dev->InterfaceClass == 3) {
if (dev->InterfaceClass == Drivers::USB::UsbDevice::CLASS_HID) {
if (dev->InterfaceProtocol == 1) devName = "USB HID Keyboard";
else if (dev->InterfaceProtocol == 2) devName = "USB HID Mouse";
else devName = "USB HID Device";
} else if (dev->InterfaceClass == Drivers::USB::UsbDevice::CLASS_WIRELESS) {
devName = "Bluetooth Adapter";
} else if (dev->InterfaceClass == 8) {
devName = "USB Mass Storage";
} else if (dev->InterfaceClass == 9) {
@@ -129,6 +136,22 @@ namespace Montauk {
}
}
// Audio (category 9)
if (Drivers::Audio::IntelHda::IsInitialized()) {
uint32_t codecId = Drivers::Audio::IntelHda::GetCodecVendorId();
char detail[48];
int p = 0;
p = dl_append(detail, p, "HDA Codec ", 48);
p = dl_append_hex(detail, p, codecId >> 16, 4, 48);
p = dl_append(detail, p, ":", 48);
p = dl_append_hex(detail, p, codecId & 0xFFFF, 4, 48);
add(9, "Intel HDA", detail);
}
if (Drivers::USB::Bluetooth::IsInitialized()) {
add(9, "Bluetooth Audio", "A2DP (SBC)");
}
// Storage (category 7)
if (Drivers::Storage::Ahci::IsInitialized()) {
for (int port = 0; port < 32 && count < maxCount; port++) {
@@ -152,6 +175,27 @@ namespace Montauk {
}
}
if (Drivers::Storage::Nvme::IsInitialized()) {
for (int ns = 0; ns < Drivers::Storage::Nvme::GetNamespaceCount() && count < maxCount; ns++) {
auto* nsInfo = Drivers::Storage::Nvme::GetNamespaceInfo(ns);
if (!nsInfo || !nsInfo->Active) continue;
uint64_t sectors = nsInfo->SectorCount;
uint64_t sizeMB = (sectors * nsInfo->SectorSize) / (1024 * 1024);
uint64_t sizeGB = sizeMB / 1024;
char detail[48];
int p = 0;
if (sizeGB > 0) {
p = dl_append_dec(detail, p, (int)sizeGB, 48);
p = dl_append(detail, p, " GiB, NVMe ns ", 48);
} else {
p = dl_append_dec(detail, p, (int)sizeMB, 48);
p = dl_append(detail, p, " MiB, NVMe ns ", 48);
}
p = dl_append_dec(detail, p, ns, 48);
add(7, nsInfo->Model, detail);
}
}
// PCI devices (category 8)
auto& pciDevs = Pci::GetDevices();
for (int i = 0; i < (int)pciDevs.size() && count < maxCount; i++) {
@@ -174,30 +218,64 @@ namespace Montauk {
return count;
}
static int Sys_DiskInfo(DiskInfo* buf, int port) {
static int Sys_DiskInfo(DiskInfo* buf, int blockDevIndex) {
if (buf == nullptr) return -1;
if (!Drivers::Storage::Ahci::IsInitialized()) return -1;
auto* info = Drivers::Storage::Ahci::GetPortInfo(port);
if (!info) return -1;
auto* bdev = Drivers::Storage::GetBlockDevice(blockDevIndex);
if (!bdev) return -1;
buf->port = info->PortIndex;
buf->type = (uint8_t)info->Type;
buf->sataGen = (uint8_t)info->SataGen;
buf->sectorCount = info->SectorCount;
buf->sectorSizeLog = info->SectorSizeLog;
buf->sectorSizePhys = info->SectorSizePhys;
buf->rpm = info->Rpm;
buf->ncqDepth = info->NcqDepth;
buf->supportsLba48 = info->SupportsLba48 ? 1 : 0;
buf->supportsNcq = info->SupportsNcq ? 1 : 0;
buf->supportsTrim = info->SupportsTrim ? 1 : 0;
buf->supportsSmart = info->SupportsSmart ? 1 : 0;
buf->supportsWriteCache = info->SupportsWriteCache ? 1 : 0;
buf->supportsReadAhead = info->SupportsReadAhead ? 1 : 0;
dl_strcpy(buf->model, info->Model, 41);
dl_strcpy(buf->serial, info->Serial, 21);
dl_strcpy(buf->firmware, info->Firmware, 9);
// Zero the struct first so SATA-specific fields default to 0
for (unsigned i = 0; i < sizeof(DiskInfo); i++)
((uint8_t*)buf)[i] = 0;
buf->port = (uint8_t)blockDevIndex;
buf->sectorCount = bdev->SectorCount;
buf->sectorSizeLog = bdev->SectorSize;
buf->sectorSizePhys = bdev->SectorSize;
dl_strcpy(buf->model, bdev->Model, 41);
// Try to fill AHCI-specific fields if this is an AHCI device
if (Drivers::Storage::Ahci::IsInitialized()) {
for (int p = 0; p < 32; p++) {
auto* info = Drivers::Storage::Ahci::GetPortInfo(p);
if (!info) continue;
// Match by sector count and model name
if (info->SectorCount == bdev->SectorCount &&
info->Model[0] == bdev->Model[0]) {
buf->type = (uint8_t)info->Type;
buf->sataGen = (uint8_t)info->SataGen;
buf->sectorSizeLog = info->SectorSizeLog;
buf->sectorSizePhys = info->SectorSizePhys;
buf->rpm = info->Rpm;
buf->ncqDepth = info->NcqDepth;
buf->supportsLba48 = info->SupportsLba48 ? 1 : 0;
buf->supportsNcq = info->SupportsNcq ? 1 : 0;
buf->supportsTrim = info->SupportsTrim ? 1 : 0;
buf->supportsSmart = info->SupportsSmart ? 1 : 0;
buf->supportsWriteCache = info->SupportsWriteCache ? 1 : 0;
buf->supportsReadAhead = info->SupportsReadAhead ? 1 : 0;
dl_strcpy(buf->serial, info->Serial, 21);
dl_strcpy(buf->firmware, info->Firmware, 9);
break;
}
}
}
// For NVMe devices: set type=3 (NVMe), rpm=1 (SSD)
if (buf->type == 0 && Drivers::Storage::Nvme::IsInitialized()) {
for (int ns = 0; ns < Drivers::Storage::Nvme::GetNamespaceCount(); ns++) {
auto* nsInfo = Drivers::Storage::Nvme::GetNamespaceInfo(ns);
if (!nsInfo) continue;
if (nsInfo->SectorCount == bdev->SectorCount) {
buf->type = 3; // NVMe
buf->rpm = 1; // SSD / non-rotating
break;
}
}
}
// If type is still 0, this block device is not recognized
if (buf->type == 0) return -1;
return 0;
}