diff options
| -rw-r--r-- | dev/modules/AHCI/AHCI.hxx | 6 | ||||
| -rw-r--r-- | dev/zba/amd64-efi.make | 8 | ||||
| -rw-r--r-- | dev/zba/src/HEL/AMD64/BootATA.cxx | 2 | ||||
| -rw-r--r-- | dev/zba/src/HEL/AMD64/BootMain.cxx | 3 | ||||
| -rw-r--r-- | dev/zka/HALKit/AMD64/PCI/Device.cxx | 20 | ||||
| -rw-r--r-- | dev/zka/HALKit/AMD64/PCI/Iterator.cxx | 4 | ||||
| -rw-r--r-- | dev/zka/HALKit/AMD64/Storage/AHCI.cxx | 105 | ||||
| -rw-r--r-- | dev/zka/KernelKit/PCI/Device.hxx | 6 |
8 files changed, 117 insertions, 37 deletions
diff --git a/dev/modules/AHCI/AHCI.hxx b/dev/modules/AHCI/AHCI.hxx index 084322bb..a48a8c38 100644 --- a/dev/modules/AHCI/AHCI.hxx +++ b/dev/modules/AHCI/AHCI.hxx @@ -261,10 +261,10 @@ typedef struct HbaMem final Kernel::UInt32 Cap2; // 0x24, Host capabilities extended Kernel::UInt32 Bohc; // 0x28, BIOS/OS handoff control and status - Kernel::UInt16 Resv0; - Kernel::UInt32 Resv2; + Kernel::UInt8 Resv0[0xA0 - 0x2C]; + Kernel::UInt8 Vendor[0x100 - 0xA0]; - HbaPort Ports[1]; // 1 ~ 32, 32 is the max ahci devices per controller. + HbaPort Ports[32]; // 1 ~ 32, 32 is the max ahci devices per controller. } HbaMem; typedef struct HbaCmdHeader final diff --git a/dev/zba/amd64-efi.make b/dev/zba/amd64-efi.make index d28c81f1..9ebc8972 100644 --- a/dev/zba/amd64-efi.make +++ b/dev/zba/amd64-efi.make @@ -30,13 +30,11 @@ IMG_2=epm-slave.img IMG_3=epm-master-2.img EMU_FLAGS=-net none -smp 4 -m 8G -M q35 \ - -bios $(BIOS) -device piix3-ide,id=ide \ - -drive id=disk,file=$(IMG),format=raw,if=none \ - -device ide-hd,drive=disk,bus=ide.0 -drive \ + -bios $(BIOS) -drive \ file=fat:rw:src/Root/,index=2,format=raw \ - -drive id=disk_2,file=$(IMG_2),if=none \ + -drive id=disk_2,file=$(IMG),if=none \ -device ahci,id=ahci \ - -device ide-hd,drive=disk_2,bus=ahci.0 -d int + -device ide-hd,drive=disk_2,bus=ahci.0 -serial stdio LD_FLAGS=-e Main --subsystem=10 diff --git a/dev/zba/src/HEL/AMD64/BootATA.cxx b/dev/zba/src/HEL/AMD64/BootATA.cxx index b975da1a..6561c150 100644 --- a/dev/zba/src/HEL/AMD64/BootATA.cxx +++ b/dev/zba/src/HEL/AMD64/BootATA.cxx @@ -83,7 +83,7 @@ ATAInit_Retry: if (statRdy & ATA_SR_ERR) { writer.Write( - L"NEWOSLDR: ATA: Select error, not an IDE based hard-drive.\r"); + L"NEWOSLDR: ATA: error, not an IDE based hard-drive.\r"); return false; } diff --git a/dev/zba/src/HEL/AMD64/BootMain.cxx b/dev/zba/src/HEL/AMD64/BootMain.cxx index 113f2d40..6010d21b 100644 --- a/dev/zba/src/HEL/AMD64/BootMain.cxx +++ b/dev/zba/src/HEL/AMD64/BootMain.cxx @@ -164,6 +164,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, // format the disk. // ---------------------------------------------------- // +#ifdef __AHCI__ if (!partition_factory.IsPartitionValid()) { Boot::BDiskFormatFactory<BootDeviceATA>::BFileDescriptor root; @@ -176,10 +177,12 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, rt_reset_hardware(); } +#endif BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); struct_ptr = new EfiMemoryDescriptor[sz_desc]; + BS->GetMemoryMap(&size_struct_ptr, struct_ptr, &map_key, &sz_desc, &rev_desc); auto cDefaultMemoryMap = 0; // Grab any usable entries. diff --git a/dev/zka/HALKit/AMD64/PCI/Device.cxx b/dev/zka/HALKit/AMD64/PCI/Device.cxx index d83cf660..d55683d5 100644 --- a/dev/zka/HALKit/AMD64/PCI/Device.cxx +++ b/dev/zka/HALKit/AMD64/PCI/Device.cxx @@ -39,9 +39,6 @@ namespace Kernel::PCI Device::Device(UShort bus, UShort device, UShort func, UInt32 bar) : fBus(bus), fDevice(device), fFunction(func), fBar(bar) { - // get bar 0 - auto bar_zero = 0x10 + bar * sizeof(UInt32); - fBar = this->Read(bar_zero, 4); } Device::~Device() = default; @@ -107,21 +104,22 @@ namespace Kernel::PCI return (UChar)(ZKA_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16); } - void Device::EnableMmio() + void Device::EnableMmio(UInt32 bar_in) { - bool enable = Read(0x04, sizeof(UChar)) | (1 << 1); - Write(0x04, enable, sizeof(UShort)); + bool enable = Read(bar_in, sizeof(UChar)) | (1 << 1); + Write(bar_in, enable, sizeof(UShort)); } - void Device::BecomeBusMaster() + void Device::BecomeBusMaster(UInt32 bar_in) { - bool enable = Read(0x04, sizeof(UShort)) | (1 << 2); - Write(0x04, enable, sizeof(UShort)); + bool enable = Read(bar_in, sizeof(UShort)) | (1 << 2); + Write(bar_in, enable, sizeof(UShort)); } - UInt32 Device::Bar() + UInt32 Device::Bar(UInt32 bar_in) { - return fBar; + UInt32 bar = ZKA_PCIReadRaw(bar_in, fBus, fDevice, fFunction); + return bar; } UShort Device::Vendor() diff --git a/dev/zka/HALKit/AMD64/PCI/Iterator.cxx b/dev/zka/HALKit/AMD64/PCI/Iterator.cxx index 8d7e7acf..f0d52c5d 100644 --- a/dev/zka/HALKit/AMD64/PCI/Iterator.cxx +++ b/dev/zka/HALKit/AMD64/PCI/Iterator.cxx @@ -17,7 +17,9 @@ namespace Kernel::PCI { for (int function = 0; function < ZKA_FUNCTION_COUNT; ++function) { - Device dev(bus, device, function, type == Types::PciDeviceKind::MassStorageController ? 5 : 1); + auto bar = 0x00; + + Device dev(bus, device, function, bar); if (dev.Class() == (UChar)type) { diff --git a/dev/zka/HALKit/AMD64/Storage/AHCI.cxx b/dev/zka/HALKit/AMD64/Storage/AHCI.cxx index 315a9996..0a318d6d 100644 --- a/dev/zka/HALKit/AMD64/Storage/AHCI.cxx +++ b/dev/zka/HALKit/AMD64/Storage/AHCI.cxx @@ -17,6 +17,7 @@ #include <modules/AHCI/AHCI.hxx> #include <KernelKit/PCI/Iterator.hxx> +#include <NewKit/Utils.hxx> #ifdef __AHCI__ enum @@ -29,7 +30,7 @@ STATIC Kernel::PCI::Device kAhciDevice; STATIC HbaPort* kAhciPort = nullptr; /// @brief Initializes an AHCI disk. -/// @param PortsImplemented the amount of port that have been detected. +/// @param PortsImplemented the amount of kAhciPort that have been detected. /// @return Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) { @@ -42,14 +43,14 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) if (iterator[devIndex].Leak().Subclass() == kSATASubClass && iterator[devIndex].Leak().ProgIf() == kSATAProgIfAHCI) { - iterator[devIndex].Leak().EnableMmio(); /// enable the memory i/o for this ahci device. - iterator[devIndex].Leak().BecomeBusMaster(); /// become bus master for this ahci device, so that we can control it. + iterator[devIndex].Leak().EnableMmio(0x24); /// enable the memory index_byte/o for this ahci device. + iterator[devIndex].Leak().BecomeBusMaster(0x24); /// become bus master for this ahci device, so that we can control it. kAhciDevice = iterator[devIndex].Leak(); /// and then leak the reference. - HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar(); + HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar(0x24); - UInt32 ports_implemented = mem_ahci->Pi; + Kernel::UInt32 ports_implemented = mem_ahci->Pi; Int32 ahci_index = 0; const auto cMaxAhciDevices = 32; @@ -65,27 +66,26 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) { kcout << "Port is implemented by host.\r"; - UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; - UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; + Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; + Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; - if (mem_ahci->Ports[ahci_index].Sig == cAhciSig && - det == cAhciPresent && - ipm == cAhciIPMActive) + if (mem_ahci->Ports[ahci_index].Sig == cAhciSig) { kcout << "Found AHCI controller.\r"; kcout << "Device is of SATA type.\r"; detected = true; + mem_ahci->Ghc |= (1 << kAhciGHC_AE); + kAhciPort = &mem_ahci->Ports[ahci_index]; - // start command engine. - // drv_start_ahci_engine(); + break; } } ports_implemented >>= 1; - ahci_index++; + ++ahci_index; } return detected; @@ -102,6 +102,85 @@ Kernel::Boolean drv_std_detected(Kernel::Void) Kernel::Void drv_std_read(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size) { + STATIC Kernel::Boolean kSlotIsUsed = No; + + while (kSlotIsUsed) + ; + + kSlotIsUsed = Yes; + + Kernel::Int64 free_slot = 0; + + // Prepare command header. + + HbaCmdHeader* cmd_header = (HbaCmdHeader*)kAhciPort->Clb; + cmd_header += free_slot; + + // Read operation/set entries count. + + cmd_header->Write = No; + cmd_header->Prdtl = (Kernel::UInt16)((Size - 1) >> 4) + 1; // PRDT entries count + + // Prepare command table. + + HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)cmd_header->Ctba; + Kernel::rt_set_memory(cmd_tbl, 0, sizeof(HbaCmdTbl)); + + Kernel::UInt64 size = Size * kAHCISectorSize; + Kernel::Int64 index_byte = 0L; + + for (index_byte = 0; index_byte < cmd_header->Prdtl - 1; index_byte++) + { + cmd_tbl->prdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)Buf; + cmd_tbl->prdtEntries[index_byte].Dbc = (8 * 1024) - 1; // 8KB Buf size + cmd_tbl->prdtEntries[index_byte].InterruptBit = 1; // Interrupt on completion + + Size -= 8 * 1024; + Buf += 4 * 1024; // Move the Buf pointer forward + } + + // Last PRDT entry + cmd_tbl->prdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)Buf; + cmd_tbl->prdtEntries[index_byte].Dbc = Size - 1; // Byte count left + cmd_tbl->prdtEntries[index_byte].InterruptBit = 1; + + // 5. Prepare the command FIS (Frame Information Structure) + FisRegH2D* cmd_fis = (FisRegH2D*)(&cmd_tbl->Cfis); + Kernel::rt_set_memory(cmd_fis, 0, sizeof(FisRegH2D)); + + cmd_fis->FisType = kFISTypeRegH2D; + cmd_fis->CmdOrCtrl = 1; // Command + cmd_fis->Command = kAHCICmdReadDmaEx; + + cmd_fis->Lba0 = (Kernel::UInt8)Lba; + cmd_fis->Lba1 = (Kernel::UInt8)(Lba >> 8); + cmd_fis->Lba2 = (Kernel::UInt8)(Lba >> 16); + cmd_fis->Device = 1 << 6; // LBA mode + + cmd_fis->Lba3 = (Kernel::UInt8)(Lba >> 24); + cmd_fis->Lba4 = (Kernel::UInt8)(Lba >> 32); + cmd_fis->Lba5 = (Kernel::UInt8)(Lba >> 40); + + cmd_fis->CountLow = Size & 0xFF; + cmd_fis->CountHigh = (Size >> 8) & 0xFF; + + // 6. Issue the command by writing to the kAhciPort's command issue register (CI) + kAhciPort->Ci = 1 << free_slot; + + // 7. Wait for the command to complete (simple spinlock, no need for an object here) + while (Yes) + { + if (!(kAhciPort->Ci & (1 << free_slot))) + { + break; // Command has completed + } + if (kAhciPort->Is & (1 << 30)) + { + return; // Error in task file + } + } + + kSlotIsUsed = No; } Kernel::Void drv_std_write(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size) diff --git a/dev/zka/KernelKit/PCI/Device.hxx b/dev/zka/KernelKit/PCI/Device.hxx index 180e7200..bc1b4eb7 100644 --- a/dev/zka/KernelKit/PCI/Device.hxx +++ b/dev/zka/KernelKit/PCI/Device.hxx @@ -60,11 +60,11 @@ namespace Kernel::PCI UChar Subclass(); UChar ProgIf(); UChar HeaderType(); - UInt32 Bar(); + UInt32 Bar(UInt32 bar_in); public: - void EnableMmio(); - void BecomeBusMaster(); // for PCI-DMA, PC-DMA does not need that. + void EnableMmio(UInt32 bar_in); + void BecomeBusMaster(UInt32 bar_in); // for PCI-DMA, PC-DMA does not need that. UShort Vendor(); |
