From 50439432a85976605dbb18e3cd2161f888d2e17d Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 20 Nov 2024 21:01:31 +0100 Subject: IMP: AHCI-DMA: driver improvements, does complete read now (although nothing returns). ReadMe.md: Update git ssh link. HWTS: Refactor class. DriveMgr: Lots of improvements inside the API. CUSA: Refactor scheduler API too. --- dev/ZBAKit/ReadMe.md | 2 +- dev/ZBAKit/amd64-efi.make | 20 +- dev/ZBAKit/src/HEL/AMD64/BootMain.cc | 6 +- dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc | 12 +- dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc | 307 ++++++++++++------------- dev/ZKAKit/KernelKit/DriveMgr.h | 12 +- dev/ZKAKit/KernelKit/HardwareThreadScheduler.h | 2 +- dev/ZKAKit/KernelKit/UserProcessScheduler.h | 7 +- dev/ZKAKit/NewKit/Macros.h | 2 +- dev/ZKAKit/amd64-efi.make | 2 +- dev/ZKAKit/src/CodeMgr.cc | 15 +- dev/ZKAKit/src/DriveMgr.cc | 70 +++--- dev/ZKAKit/src/HardwareThreadScheduler.cc | 2 +- dev/ZKAKit/src/PEFCodeMgr.cc | 2 +- dev/ZKAKit/src/UserProcessScheduler.cc | 39 ++-- dev/ZKAKit/src/Utils.cc | 5 + 16 files changed, 253 insertions(+), 252 deletions(-) (limited to 'dev') diff --git a/dev/ZBAKit/ReadMe.md b/dev/ZBAKit/ReadMe.md index 02239d3d..14157e7c 100644 --- a/dev/ZBAKit/ReadMe.md +++ b/dev/ZBAKit/ReadMe.md @@ -8,7 +8,7 @@ You need: Start by cloning the repo: ``` -git clone git@bitbucket.org:mahrouss/microKernel.git +git clone git@github.com:ElMahroussLogic/zka-dev.git ``` And then execute: diff --git a/dev/ZBAKit/amd64-efi.make b/dev/ZBAKit/amd64-efi.make index f817f351..254a1ffc 100644 --- a/dev/ZBAKit/amd64-efi.make +++ b/dev/ZBAKit/amd64-efi.make @@ -32,9 +32,7 @@ IMG_3=epm-master-2.img EMU_FLAGS=-net none -smp 1 -m 8G -M q35 \ -bios $(BIOS) -drive \ file=fat:rw:src/Root/,index=2,format=raw \ - -drive id=disk_2,file=$(IMG),if=none \ - -device ahci,id=ahci \ - -device ide-hd,drive=disk_2,bus=ahci.0 -serial stdio -no-shutdown -no-reboot + -serial stdio -no-shutdown -no-reboot LD_FLAGS=-e Main --subsystem=10 @@ -47,7 +45,9 @@ REM_FLAG=-f FLAG_ASM=-f win64 FLAG_GNU=-fshort-wchar -D__EFI_x86_64__ -mno-red-zone -D__NEWOSKRNL__ -D__NEWOSLDR__ \ -DEFI_FUNCTION_WRAPPER -I./ -I../ZKAKit -I../ -c -nostdlib -fno-rtti -fno-exceptions \ - -std=c++20 -D__HAVE_ZKA_APIS__ -DZBA_USE_FB -D__ZKA_AMD64__ -D__ZKA__ + -std=c++20 -D__HAVE_ZKA_APIS__ -DZBA_USE_FB -D__ZKA_AMD64__ -D__ZKA__ + +# -DZKA_AUTO_FORMAT BOOTLOADER=zbaosldr.exe KERNEL=minoskrnl.exe @@ -83,11 +83,15 @@ compile-amd64: $(wildcard src/HEL/AMD64/*.S) \ $(wildcard src/*.cc) -.PHONY: run-efi-amd64 -run-efi-amd64: - $(EMU) $(EMU_FLAGS) +.PHONY: run-efi-amd64-ahci +run-efi-amd64-ahci: + $(EMU) $(EMU_FLAGS) -hdd $(IMG) + +.PHONY: run-efi-amd64-ata +run-efi-amd64-ata: + $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta. +# img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs. .PHONY: epm-img epm-img: qemu-img create -f raw $(IMG) 10G diff --git a/dev/ZBAKit/src/HEL/AMD64/BootMain.cc b/dev/ZBAKit/src/HEL/AMD64/BootMain.cc index b43e0715..cfc02837 100644 --- a/dev/ZBAKit/src/HEL/AMD64/BootMain.cc +++ b/dev/ZBAKit/src/HEL/AMD64/BootMain.cc @@ -155,7 +155,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, mp->GetNumberOfProcessors(mp, &cnt_disabled, &cnt_enabled); #ifdef ZBA_USE_FB - CGDrawString("ZBA (c) EL Mahrouss Logic", 10, 10, RGB(0xFF, 0xFF, 0xFF)); + CGDrawString("ZBA (c) EL Mahrouss Logic.", 10, 10, RGB(0xFF, 0xFF, 0xFF)); CGDrawString((cnt_enabled > 1) ? "SMP detected." : "Single processor configuration detected.", 20, 10, RGB(0xFF, 0xFF, 0xFF)); #endif // ZBA_USE_FB @@ -173,7 +173,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, #ifdef ZKA_AUTO_FORMAT if (!partition_factory.IsPartitionValid()) { - CGDrawString("Formatting EPM disk...", 20, 10, RGB(0xFF, 0xFF, 0xFF)); + CGDrawString("Formatting EPM disk...", 30, 10, RGB(0xFF, 0xFF, 0xFF)); Boot::BDiskFormatFactory::BFileDescriptor root; root.fFileName[0] = kNeFSRoot[0]; @@ -187,7 +187,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr ImageHandle, } else { - CGDrawString("Booting from EPM disk...", 20, 10, RGB(0xFF, 0xFF, 0xFF)); + CGDrawString("Booting from EPM disk...", 30, 10, RGB(0xFF, 0xFF, 0xFF)); } #endif // ZKA_AUTO_FORMAT diff --git a/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc b/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc index aa164eea..9ceefbc2 100644 --- a/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc +++ b/dev/ZKAKit/HALKit/AMD64/HalKernelMain.cc @@ -20,15 +20,8 @@ EXTERN_C Kernel::Char mp_user_switch_proc_stack_begin[]; EXTERN_C Kernel::MainKind __CTOR_LIST__[]; EXTERN_C Kernel::MainKind __DTOR_LIST__[]; -namespace Kernel -{ - EXTERN ProcessID kProcessIDCounter; -} - STATIC Kernel::Void hal_init_cxx_ctors() { - Kernel::kProcessIDCounter = 0UL; - for (Kernel::SizeT index = 0UL; __CTOR_LIST__[index] != __DTOR_LIST__[0]; ++index) { Kernel::MainKind constructor_cxx = (Kernel::MainKind)__CTOR_LIST__[index]; @@ -90,12 +83,15 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { /* Initialize filesystem. */ Kernel::NeFileSystemMgr::Mount(new Kernel::NeFileSystemMgr()); + Kernel::UserProcessHelper::InitScheduler(); const Kernel::Char process_name[] = "Kernel"; Kernel::rtl_create_process([]() -> void { while (Yes) - ; + { + kcout << "Scheduling...\r"; + } }, process_name); diff --git a/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc b/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc index 99e1b4c1..06ba1c6f 100644 --- a/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc +++ b/dev/ZKAKit/HALKit/AMD64/Storage/AHCI-DMA.cc @@ -15,17 +15,29 @@ * */ +#include #include #include #include #include #ifdef __AHCI__ + +#define kAhciCmdTblBase mib_cast(1) // 4M + +#define HBA_PxCMD_ST 0x0001 +#define HBA_PxCMD_FRE 0x0010 +#define HBA_PxCMD_FR 0x4000 +#define HBA_PxCMD_CR 0x8000 + #define kMaxAhciPoll (100000U) #define kCmdOrCtrlCmd 1 #define kCmdOrCtrlCtrl 0 +#define kAhciSRBsy 0x80 +#define kAhciSRDrq 0x08 + enum { kSATAProgIfAHCI = 0x01, @@ -39,68 +51,8 @@ STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; Kernel::Void drv_calculate_disk_geometry() { - // Slot is now used, OS uses slot 0, driver must not use slot 0. - - // Prepare command header. - - HbaCmdHeader* cmd_header = (HbaCmdHeader*)(Kernel::UIntPtr)kAhciPort->Clb; - - // Read operation/set entries count. - - Kernel::UInt16 identify_data[256] = {0}; - Kernel::UInt64 size = 512 - 1; // Adjust size for 512 bytes of data (Dbc should be 511) - - cmd_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); - cmd_header->Prdtl = 1; // 1 PRDT entry - - // Prepare command table. - HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)(Kernel::UIntPtr)cmd_header->Ctba; - - // First PRD entry - cmd_tbl->PrdtEntries[0].Dba = (Kernel::UInt32)(Kernel::UIntPtr)identify_data; - cmd_tbl->PrdtEntries[0].Dbc = size; // Byte count (511 for 512 bytes of data) - cmd_tbl->PrdtEntries[0].InterruptBit = 1; // Set interrupt flag - - // 5. Prepare the command FIS (Frame Information Structure) - FisRegH2D* cmd_fis = (FisRegH2D*)(cmd_tbl->Cfis); - cmd_fis->FisType = kFISTypeRegH2D; - cmd_fis->CmdOrCtrl = kCmdOrCtrlCmd; // Command - cmd_fis->Command = kAHCICmdIdentify; - - // 6. Issue the command by writing to the port's command issue register (CI) - kAhciPort->Ci = 1; // Issue command slot 0 - - // Polling loop for command completion - while (kAhciPort->Ci) - { - // Check for errors in the Task File Data register (PxTFD) - if (kAhciPort->Tfd & (1 << 0)) - { // Error bit - kcout << "Error in task file, can't get disk geometry." << endl; - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); - } - - // If the device is busy, wait - if (kAhciPort->Tfd & (1 << 7)) - { - kcout << "Device is busy, waiting..." << endl; - continue; - } - - // If command completes, clear the PxCI register - if (kAhciPort->Is & (1 << 30)) - { // If an interrupt occurred (device ready) - kcout << "Command completed successfully." << endl; - break; - } - } - - // Retrieve the max LBA value - kCurrentDiskSectorCount = *(Kernel::UIntPtr*)identify_data; - + kCurrentDiskSectorCount = 0UL; kcout << "Max LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl; - - BREAK_POINT(); } /// @brief Initializes an AHCI disk. @@ -120,7 +72,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) if (kAhciDevice.Subclass() == kSATASubClass && kAhciDevice.ProgIf() == kSATAProgIfAHCI) { - kAhciDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device. + kAhciDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device. kAhciDevice.BecomeBusMaster(0x24); // Become bus master for this ahci device, so that we can control it. HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar(0x24); @@ -152,6 +104,65 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) kAhciPort = &mem_ahci->Ports[ahci_index]; + kAhciPort->Cmd &= ~HBA_PxCMD_FRE; + + // Clear FRE (bit4) + kAhciPort->Cmd &= ~HBA_PxCMD_ST; + + // Wait until FR (bit14), CR (bit15) are cleared + while (YES) + { + if (kAhciPort->Cmd & HBA_PxCMD_CR) + continue; + + if (kAhciPort->Cmd & HBA_PxCMD_FR) + continue; + break; + } + + // when it's stopped. + + // do in-between + + kAhciPort->Clb = kAhciCmdTblBase + (ahci_index << 10); + kAhciPort->Clbu = 0; + rt_set_memory((void*)(kAhciPort->Clb), 0, 1024); + + // FIS offset: 32K+256*ahci_index + // FIS entry size = 256 bytes per port + kAhciPort->Fb = kAhciCmdTblBase + (32 << 10) + (ahci_index << 8); + kAhciPort->Fbu = 0; + rt_set_memory((void*)(kAhciPort->Fb), 0, 256); + + // Command table offset: 40K + 8K*ahci_index + // Command table size = 256*32 = 8K per port + HbaCmdHeader* cmdheader = (HbaCmdHeader*)(kAhciPort->Clb); + + for (int i = 0; i < 32; i++) + { + cmdheader[i].Prdtl = 8; // 8 prdt entries per command table + // 256 bytes per command table, 64+16+48+16*8 + // Command table offset: 40K + 8K*ahci_index + cmdheader_index*256 + cmdheader[i].Ctba = kAhciCmdTblBase + (40 << 10) + (ahci_index << 13) + (i << 8); + cmdheader[i].Ctbau = 0; + + rt_set_memory((void*)cmdheader[i].Ctba, 0, 256); + } + + // when it's starting + + // check for bits again, to start it again. + while (YES) + { + if (kAhciPort->Cmd & HBA_PxCMD_FR) + continue; + + break; + } + + kAhciPort->Cmd |= HBA_PxCMD_FRE; + kAhciPort->Cmd |= HBA_PxCMD_ST; + drv_calculate_disk_geometry(); break; @@ -174,138 +185,102 @@ Kernel::Boolean drv_std_detected(Kernel::Void) return kAhciDevice.DeviceId() != 0xFFFF; } -Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) +Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) { - // Slot is now used, OS uses slot 0, driver must not use slot 0. +} - // Prepare command header. +Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_cnt, Kernel::SizeT size_buffer) +{ + kAhciPort->Is = -1; + int port = 0; + Kernel::UInt32 slots = (kAhciPort->Sact | kAhciPort->Ci); - HbaCmdHeader* cmd_header = (HbaCmdHeader*)(Kernel::UIntPtr)kAhciPort->Clb; + for (; port < slots; ++port) + { + if ((slots & 1) == 0) + break; - // Read operation/set entries count. + slots >>= 1; + } - cmd_header->Write = No; - cmd_header->Prdtl = (Kernel::UInt16)((size_buffer - 1) >> 4) + 1; // PRDT entries count + HbaCmdHeader* cmd_hdr = (HbaCmdHeader*)(kAhciPort->Clb); - // Prepare command table. + cmd_hdr += port; + cmd_hdr->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); + cmd_hdr->Write = NO; + cmd_hdr->Prdtl = (Kernel::UInt16)((sector_cnt - 1) >> 4) + 1; - HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)(Kernel::UIntPtr)cmd_header->Ctba; - Kernel::rt_set_memory(cmd_tbl, 0, sizeof(HbaCmdTbl)); + HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)(cmd_hdr->Ctba); + Kernel::rt_set_memory(cmd_tbl, 0, (cmd_hdr->Prdtl - 1) * sizeof(HbaPrdtEntry)); - Kernel::UInt64 size = size * kAHCISectorSize; - Kernel::Int64 index_byte = 0L; + int i = 0; - cmd_tbl->PrdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)buffer; - cmd_tbl->PrdtEntries[index_byte].Dbc = size; // 8KB buffer size - cmd_tbl->PrdtEntries[index_byte].InterruptBit = 1; // Interrupt on completion + for (int i = 0; i < cmd_hdr->Prdtl - 1; i++) + { + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); + cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + cmd_tbl->PrdtEntries[i].InterruptBit = 1; + } - // Last PRDT entry - cmd_tbl->PrdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)buffer; - cmd_tbl->PrdtEntries[index_byte].Dbc = size - 1; // Byte count left - cmd_tbl->PrdtEntries[index_byte].InterruptBit = 1; + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)(Kernel::UInt64)buffer; + cmd_tbl->PrdtEntries[i].Dba = (Kernel::UInt32)((Kernel::UInt64)(buffer) >> 32); + cmd_tbl->PrdtEntries[i].Dbc = size_buffer - 1; // 8K bytes (this value should always be set to 1 less than the actual value) + cmd_tbl->PrdtEntries[i].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 = kCmdOrCtrlCmd; // Command + cmd_fis->CmdOrCtrl = YES; // 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->Lba0 = (Kernel::UInt8)(Kernel::UInt32)lba & 0xFF; + cmd_fis->Lba1 = (Kernel::UInt8)((Kernel::UInt32)lba >> 8); + cmd_fis->Lba2 = (Kernel::UInt8)((Kernel::UInt32)lba >> 16); + cmd_fis->Device = (1 << 6); // LBA mode - cmd_fis->Lba3 = (Kernel::UInt8)(lba >> 24); + cmd_fis->Lba3 = (Kernel::UInt8)((Kernel::UInt32)lba >> 24); cmd_fis->Lba4 = (Kernel::UInt8)(lba >> 32); - cmd_fis->Lba5 = (Kernel::UInt8)(lba >> 40); + cmd_fis->Lba5 = (Kernel::UInt8)((lba >> 32) >> 8); - cmd_fis->CountLow = size & 0xFF; - cmd_fis->CountHigh = (size >> 8) & 0xFF; + cmd_fis->CountLow = sector_cnt & 0xFF; + cmd_fis->CountHigh = (sector_cnt >> 8) & 0xFF; - // 6. Issue the command by writing to the port's command issue register (CI) - kAhciPort->Ci = 1; + Kernel::UInt64 spin = 0UL; - // 7. Wait for the command to complete (simple spinlock, no need for an object here) - while (Yes) + // The below loop waits until the port is no longer busy before issuing a new command + while ((kAhciPort->Tfd & (kAhciSRBsy | kAhciSRDrq)) && spin < kMaxAhciPoll) { - if (!(kAhciPort->Ci & 1)) - { - break; // Command has completed - } - else if (kAhciPort->Is & (1 << 30)) - { - return; // Error in task file - } + spin++; + } + if (spin == 1000000) + { + kcout << "Port is hung\r"; + return; } -} - -Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) -{ - // Prepare command header. - - HbaCmdHeader* cmd_header = (HbaCmdHeader*)(Kernel::UIntPtr)kAhciPort->Clb; - - // Read operation/set entries count. - - cmd_header->Write = Yes; - cmd_header->Prdtl = (Kernel::UInt16)((size_buffer - 1) >> 4) + 1; // PRDT entries count, put in low of prdt. - - // Prepare command table. - - HbaCmdTbl* cmd_tbl = (HbaCmdTbl*)(Kernel::UIntPtr)cmd_header->Ctba; - Kernel::rt_set_memory(cmd_tbl, 0, sizeof(HbaCmdTbl)); - - Kernel::UInt64 size = size * kAHCISectorSize; - Kernel::Int64 index_byte = 0L; - - cmd_tbl->PrdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)buffer; - cmd_tbl->PrdtEntries[index_byte].Dbc = size; // 8KB buffer size - cmd_tbl->PrdtEntries[index_byte].InterruptBit = 1; // Interrupt on completion - - // Last PRDT entry - cmd_tbl->PrdtEntries[index_byte].Dba = (Kernel::UInt32)(Kernel::UIntPtr)buffer; - 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 = kCmdOrCtrlCmd; // 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 port's command issue register (CI) - kAhciPort->Ci = 1; + kAhciPort->Ci = 1 << port; // Issue command - // 7. Wait for the command to complete (simple spinlock, no need for an object here) - while (Yes) + // Wait for completion + while (YES) { - if (!(kAhciPort->Ci & 1)) - { - break; // Command has completed - } - else if (kAhciPort->Is & (1 << 30)) + // In some longer duration reads, it may be helpful to spin on the DPS bit + // in the PxIS port field as well (1 << 5) + if ((kAhciPort->Ci & (1 << port)) == 0) + break; + if (kAhciPort->Is & (1 << 30)) // Task file error { - kcout << "Error in task file. (AHCI Drv)\r"; - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); - return; // Error in task file + kcout << ("Read disk error\r"); + return; } } + + // Check again for the last time. + if (kAhciPort->Is & (1 << 30)) // task file error status + { + kcout << ("Read disk error\r"); + *buffer = 0; + } } /*** @@ -324,4 +299,4 @@ Kernel::SizeT drv_get_size() return drv_get_sector_count() * kAHCISectorSize; } -#endif // __AHCI__ +#endif // ifdef __AHCI__ \ No newline at end of file diff --git a/dev/ZKAKit/KernelKit/DriveMgr.h b/dev/ZKAKit/KernelKit/DriveMgr.h index 4ec45f2f..204e90b2 100644 --- a/dev/ZKAKit/KernelKit/DriveMgr.h +++ b/dev/ZKAKit/KernelKit/DriveMgr.h @@ -56,12 +56,12 @@ namespace Kernel /// @brief Packet drive (StorageKit compilant.) struct DrivePacket final { - Ref fPacketContent; //! packet body. - Char fPacketMime[kDriveNameLen]; //! identify what we're sending. - SizeT fPacketSize; //! packet size - UInt32 fPacketCRC32; //! sanity crc, in case if good is set to false - Boolean fPacketGood; - Lba fLba; + VoidPtr fPacketContent; //! packet body. + Char fPacketMime[kDriveNameLen]; //! identify what we're sending. + SizeT fPacketSize; //! packet size + UInt32 fPacketCRC32; //! sanity crc, in case if good is set to false + Boolean fPacketGood; + Lba fLba; } fPacket; Void (*fInput)(DrivePacket* packetPtr); diff --git a/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h b/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h index eea25bb8..80f68c34 100644 --- a/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h +++ b/dev/ZKAKit/KernelKit/HardwareThreadScheduler.h @@ -130,7 +130,7 @@ namespace Kernel public: /// @brief Returns the amount of threads present in the system. /// @returns SizeT the amount of cores present. - SizeT Count() noexcept; + SizeT Capacity() noexcept; private: Array fThreadList; diff --git a/dev/ZKAKit/KernelKit/UserProcessScheduler.h b/dev/ZKAKit/KernelKit/UserProcessScheduler.h index 19075405..1c9f4a94 100644 --- a/dev/ZKAKit/KernelKit/UserProcessScheduler.h +++ b/dev/ZKAKit/KernelKit/UserProcessScheduler.h @@ -39,7 +39,7 @@ namespace Kernel typedef Int64 ProcessID; //! @brief Local Process name length. - inline constexpr SizeT kProcessNameLen = 4096U; + inline constexpr SizeT kProcessNameLen = 129U; //! @brief Local Process status enum. enum class ProcessStatusKind : Int32 @@ -141,7 +141,7 @@ namespace Kernel ZKA_COPY_DEFAULT(UserProcess); public: - Char Name[kProcessNameLen] = {"Application Process (Unnamed)"}; + Char Name[kProcessNameLen] = {"Process (Unnamed)"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid}; User* Owner{nullptr}; HAL::StackFramePtr StackFrame{nullptr}; @@ -277,7 +277,7 @@ namespace Kernel UserProcessTeam& CurrentTeam(); public: - ProcessID Add(UserProcess* process); + ProcessID Spawn(UserProcess* process); const Bool Remove(ProcessID process_id); const Bool IsUser() override; @@ -306,6 +306,7 @@ namespace Kernel STATIC Bool CanBeScheduled(const UserProcess& process); STATIC ErrorOr TheCurrentPID(); STATIC SizeT StartScheduling(); + STATIC Void InitScheduler(); }; const UInt32& sched_get_exit_code(void) noexcept; diff --git a/dev/ZKAKit/NewKit/Macros.h b/dev/ZKAKit/NewKit/Macros.h index de48144b..afde877e 100644 --- a/dev/ZKAKit/NewKit/Macros.h +++ b/dev/ZKAKit/NewKit/Macros.h @@ -121,7 +121,7 @@ #define BREAK_POINT() asm volatile ("int $3") /// @brief The system page file, located on the mount directory, as mulitple system pages can be mounted. -#define kPageSys "/Mount/syspage.sys" +#define kPageSys "/Disks/syspage.sys" /// @brief The main system driver. #define kStartupSys "/Boot/startup.sys" diff --git a/dev/ZKAKit/amd64-efi.make b/dev/ZKAKit/amd64-efi.make index bf32e1ea..ea3272fa 100644 --- a/dev/ZKAKit/amd64-efi.make +++ b/dev/ZKAKit/amd64-efi.make @@ -6,7 +6,7 @@ CC = x86_64-w64-mingw32-g++ LD = x86_64-w64-mingw32-ld CCFLAGS = -fshort-wchar -c -D__ZKA_AMD64__ -mno-red-zone -fno-rtti -fno-exceptions \ - -std=c++20 -D__ZKA_SUPPORT_NX__ -I../Vendor -D__FSKIT_INCLUDES_NEFS__ \ + -std=c++20 -D__ZKA_SUPPORT_NX__ -O0 -I../Vendor -D__FSKIT_INCLUDES_NEFS__ \ -D__NEWOSKRNL__ -D__HAVE_ZKA_APIS__ -D__FREESTANDING__ -D__ZKA__ -I./ -I../ -I../zba ASM = nasm diff --git a/dev/ZKAKit/src/CodeMgr.cc b/dev/ZKAKit/src/CodeMgr.cc index 08f4976d..5b5d471b 100644 --- a/dev/ZKAKit/src/CodeMgr.cc +++ b/dev/ZKAKit/src/CodeMgr.cc @@ -21,18 +21,19 @@ namespace Kernel if (!main) return No; - static UserProcess proc; + UserProcess* process_hdr = new UserProcess(); kcout << "Setting-up process data...\r"; - proc.Code = reinterpret_cast(main); - proc.Kind = UserProcess::kExectuableKind; - proc.StackSize = kib_cast(16); + process_hdr->Code = reinterpret_cast(main); + process_hdr->Kind = UserProcess::kExectuableKind; + process_hdr->StackSize = kib_cast(16); - rt_set_memory(proc.Name, 0, kProcessNameLen); - rt_copy_memory((VoidPtr)process_name, proc.Name, rt_string_len(process_name)); + rt_set_memory(process_hdr->Name, 0, kProcessNameLen); - ProcessID id = UserProcessScheduler::The().Add(&proc); + ProcessID id = UserProcessScheduler::The().Spawn(process_hdr); + + delete process_hdr; return id; } diff --git a/dev/ZKAKit/src/DriveMgr.cc b/dev/ZKAKit/src/DriveMgr.cc index c79e0948..024d1d76 100644 --- a/dev/ZKAKit/src/DriveMgr.cc +++ b/dev/ZKAKit/src/DriveMgr.cc @@ -33,9 +33,9 @@ namespace Kernel } #ifdef __AHCI__ - drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); + drv_std_read(pckt->fLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); #elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); + drv_std_read(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); #endif } @@ -50,9 +50,9 @@ namespace Kernel } #ifdef __AHCI__ - drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent.Leak(), kAHCISectorSize, pckt->fPacketSize); + drv_std_write(pckt->fLba, (Char*)pckt->fPacketContent, kAHCISectorSize, pckt->fPacketSize); #elif defined(__ATA_PIO__) || defined(__ATA_DMA__) - drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent.Leak(), kATASectorSize, pckt->fPacketSize); + drv_std_write(pckt->fLba, kATAIO, kATAMaster, (Char*)pckt->fPacketContent, kATASectorSize, pckt->fPacketSize); #endif } @@ -66,23 +66,32 @@ namespace Kernel return; } - pckt->fPacketGood = false; + kATAMaster = 0; + kATAIO = 0; #if defined(__ATA_PIO__) || defined(__ATA_DMA__) kATAMaster = true; kATAIO = ATA_PRIMARY_IO; + if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) + { + pckt->fPacketGood = YES; + return; + } + + kATAMaster = false; + kATAIO = ATA_SECONDARY_IO; + if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster)) return; + pckt->fPacketGood = YES; #elif defined(__AHCI__) UInt16 pi = 0; if (!drv_std_init(pi)) return; #endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__) - - pckt->fPacketGood = true; } /// @brief Gets the drive kind (ATA, SCSI, AHCI...) @@ -127,7 +136,7 @@ namespace Kernel { DriveTrait trait; - rt_copy_memory((VoidPtr) "/Mount/NUL:", trait.fName, rt_string_len("/Mount/NUL:")); + rt_copy_memory((VoidPtr) "/Disks/NUL:", trait.fName, rt_string_len("/Disks/NUL:")); trait.fKind = kInvalidStorage; trait.fInput = io_drv_unimplemented; @@ -143,33 +152,39 @@ namespace Kernel namespace Detail { - Void ioi_detect_drive(DriveTrait& trait) + Void ioi_detect_drive(DriveTrait* trait) { - _BOOT_BLOCK_STRUCT block_struct; + static _BOOT_BLOCK_STRUCT block_struct; + + trait->fPacket.fLba = kEPMBaseLba; + trait->fPacket.fPacketSize = sizeof(_BOOT_BLOCK_STRUCT); + trait->fPacket.fPacketContent = &block_struct; - trait.fPacket.fLba = kEPMBaseLba; - trait.fPacket.fPacketSize = sizeof(_BOOT_BLOCK_STRUCT); - trait.fPacket.fPacketContent = &block_struct; + rt_copy_memory((VoidPtr) "fs/detect-packet", trait->fPacket.fPacketMime, + rt_string_len("fs/detect-packet")); - trait.fInit(&trait.fPacket); - io_drv_input(&trait.fPacket); + trait->fInit(&trait->fPacket); - trait.fKind = kMassStorage; + trait->fInput(&trait->fPacket); - if (rt_string_cmp(block_struct.Magic, kEPMMagic, kEPMMagicLength) == 0) + if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait->fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0) { - trait.fKind |= kEPMDrive; + trait->fKind = kMassStorage; + trait->fKind |= kEPMDrive; kcout << "Formatted drive is EPM.\r"; } else { - trait.fKind |= kUnformattedDrive; - kcout << "Formatted drive is blank.\r"; + trait->fKind = kUnformattedDrive; + kcout << "Scheme Found: " << block_struct.Name << endl; + + if (block_struct.Name[0] == 0) + kcout << "Formatted drive is blank.\r"; } - trait.fPacket.fLba = 0; - trait.fPacket.fPacketSize = 0UL; - trait.fPacket.fPacketContent = nullptr; + trait->fPacket.fLba = 0; + trait->fPacket.fPacketSize = 0UL; + trait->fPacket.fPacketContent = nullptr; } } // namespace Detail @@ -179,7 +194,7 @@ namespace Kernel { DriveTrait trait; - rt_copy_memory((VoidPtr) "/Mount/OS:", trait.fName, rt_string_len("/Mount/OS:")); + rt_copy_memory((VoidPtr) "/Disks/OS:", trait.fName, rt_string_len("/Disks/OS:")); trait.fVerify = io_drv_unimplemented; trait.fOutput = io_drv_output; @@ -187,9 +202,12 @@ namespace Kernel trait.fInit = io_drv_init; trait.fDriveKind = io_drv_kind; - Detail::ioi_detect_drive(trait); + kcout << "Detect partiton scheme of: " << trait.fName << ".\r"; - kcout << "Construct: " << trait.fName << ".\r"; + Detail::ioi_detect_drive(&trait); + + while (YES) + ; return trait; } diff --git a/dev/ZKAKit/src/HardwareThreadScheduler.cc b/dev/ZKAKit/src/HardwareThreadScheduler.cc index 47963832..42d3e411 100644 --- a/dev/ZKAKit/src/HardwareThreadScheduler.cc +++ b/dev/ZKAKit/src/HardwareThreadScheduler.cc @@ -192,7 +192,7 @@ namespace Kernel /// @brief Returns the amount of core present. /// @return the number of cores. - SizeT HardwareThreadScheduler::Count() noexcept + SizeT HardwareThreadScheduler::Capacity() noexcept { return fThreadList.Capacity(); } diff --git a/dev/ZKAKit/src/PEFCodeMgr.cc b/dev/ZKAKit/src/PEFCodeMgr.cc index 4aeb3acf..0568b998 100644 --- a/dev/ZKAKit/src/PEFCodeMgr.cc +++ b/dev/ZKAKit/src/PEFCodeMgr.cc @@ -273,7 +273,7 @@ namespace Kernel proc.StackSize = mib_cast(cDefaultStackSizeMib); } - return UserProcessScheduler::The().Add(&proc); + return UserProcessScheduler::The().Spawn(&proc); } } // namespace Utils } // namespace Kernel diff --git a/dev/ZKAKit/src/UserProcessScheduler.cc b/dev/ZKAKit/src/UserProcessScheduler.cc index 3352085d..8694b449 100644 --- a/dev/ZKAKit/src/UserProcessScheduler.cc +++ b/dev/ZKAKit/src/UserProcessScheduler.cc @@ -32,19 +32,13 @@ namespace Kernel /// @brief Exit Code global variable. /***********************************************************************************/ - UInt32 kLastExitCode = 0U; - - /***********************************************************************************/ - /// @brief Process count global variable. - /***********************************************************************************/ - - ProcessID kProcessIDCounter = 0UL; + STATIC UInt32 kLastExitCode = 0U; /***********************************************************************************/ /// @brief User Process scheduler global and external reference of thread scheduler. /***********************************************************************************/ - UserProcessScheduler kProcessScheduler; + STATIC UserProcessScheduler kProcessScheduler; UserProcess::UserProcess(VoidPtr start_image) : Code(start_image) @@ -314,7 +308,6 @@ namespace Kernel mm_delete_heap(reinterpret_cast(this->StackReserve)); this->ProcessId = 0; - --kProcessIDCounter; } /***********************************************************************************/ @@ -323,11 +316,11 @@ namespace Kernel /// @return the process index inside the team. /***********************************************************************************/ - ProcessID UserProcessScheduler::Add(UserProcess* process) + ProcessID UserProcessScheduler::Spawn(UserProcess* process) { if (*process->Name == 0) { - Char process_name[] = "System Process"; + Char process_name[] = "Process (Unnamed)"; rt_copy_memory((VoidPtr)process_name, process->Name, rt_string_len(process_name)); } @@ -378,18 +371,16 @@ namespace Kernel kcout << "Create stack reserve for: " << process->Name << endl; - auto pid = kProcessIDCounter; + auto pid = mTeam.mProcessList.Count(); process->ProcessId = pid; process->Status = ProcessStatusKind::kRunning; process->PTime = (UIntPtr)AffinityKind::kStandard; - mTeam.AsArray().Assign(pid, *process); - - kcout << "Process Name: " << mTeam.AsArray()[pid].Name << endl; - kcout << "PID: " << number(mTeam.AsArray()[pid].ProcessId) << endl; + mTeam.mProcessList.Assign(pid, *process); - ++kProcessIDCounter; + kcout << "Process Name: " << mTeam.mProcessList[pid].Name << endl; + kcout << "PID: " << number(mTeam.mProcessList[pid].ProcessId) << endl; return pid; } @@ -539,7 +530,7 @@ namespace Kernel /***********************************************************************************/ /** - * @brief Start scheduling current AP/Hart/Core. + * @brief Start scheduling current AP. */ /***********************************************************************************/ SizeT UserProcessHelper::StartScheduling() @@ -547,6 +538,16 @@ namespace Kernel return kProcessScheduler.Run(); } + /***********************************************************************************/ + /** + * @brief Initializes the scheduler. + */ + /***********************************************************************************/ + Void UserProcessHelper::InitScheduler() + { + /// TODO: code to init scheduler here. + } + /***********************************************************************************/ /** * \brief Does a context switch in a CPU. @@ -563,7 +564,7 @@ namespace Kernel if (!mm_is_valid_heap(image_ptr)) return No; - for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Count(); ++index) + for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidHart) continue; diff --git a/dev/ZKAKit/src/Utils.cc b/dev/ZKAKit/src/Utils.cc index 3b7bc046..ec8a6944 100644 --- a/dev/ZKAKit/src/Utils.cc +++ b/dev/ZKAKit/src/Utils.cc @@ -215,3 +215,8 @@ EXTERN_C void* memset(void* dst, int c, __SIZE_TYPE__ len) { return Kernel::rt_set_memory(dst, c, len); } + +EXTERN_C __UINT32_TYPE__ memcpy(void* dst, void* src, __SIZE_TYPE__ len) +{ + return Kernel::rt_copy_memory(src, dst, len); +} -- cgit v1.2.3