summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel
diff options
context:
space:
mode:
Diffstat (limited to 'dev/Kernel')
-rw-r--r--dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc20
-rw-r--r--dev/Kernel/HALKit/AMD64/Processor.h2
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA.cc102
-rw-r--r--dev/Kernel/NewKit/KernelPanic.h22
-rw-r--r--dev/Kernel/src/BitMapMgr.cc4
-rw-r--r--dev/Kernel/src/UserProcessScheduler.cc6
6 files changed, 90 insertions, 66 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
index 5c9d221c..ab8c5b97 100644
--- a/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
+++ b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
@@ -23,7 +23,7 @@ namespace Kernel::HAL
{
PDE* fPde{nullptr};
PTE* fPte{nullptr};
- VoidPtr fVAddr{nullptr};
+ VoidPtr fPAddr{nullptr};
} fInternalStore;
Bool fStoreOp{No}; // Store operation is in progress.
@@ -62,7 +62,7 @@ namespace Kernel::HAL
kout << (pte->User ? "User" : "Not User") << endl;
}
- STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, NE_PTE* pt_entry, NE_PDE* pd_entry);
+ STATIC Int32 mmi_map_page_table_entry(UInt32 virtual_address, UInt32 flags, NE_PTE* pt_entry, NE_PDE* pd_entry);
/***********************************************************************************/
/// @brief Maps or allocates a page from virtual_address.
@@ -71,7 +71,7 @@ namespace Kernel::HAL
/// @param flags the flags to put on the page.
/// @return Status code of page manipulation process.
/***********************************************************************************/
- EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags)
+ EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags)
{
if (!virtual_address ||
!flags)
@@ -93,12 +93,6 @@ namespace Kernel::HAL
page_store.fStoreOp = Yes;
- if (page_store.fInternalStore.fVAddr == virtual_address)
- {
- page_store.fStoreOp = No;
- return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte, page_store.fInternalStore.fPde);
- }
-
const auto cPmlEntrySize = 8;
// Read the PML4 entry from memory
@@ -120,14 +114,14 @@ namespace Kernel::HAL
// Lastly, grab the pte entry.
NE_PDE* pde_struct = reinterpret_cast<NE_PDE*>(pt_base);
- return mmi_map_page_table_entry(virtual_address, flags, pde_struct->fEntries[pt_entry], pde_struct);
+ return mmi_map_page_table_entry((UInt32)(UInt64)physical_address, flags, pde_struct->fEntries[pt_entry], pde_struct);
}
/***********************************************************************************/
/// @brief Maps flags for a specific pte.
/// @internal Internal function.
/***********************************************************************************/
- STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, NE_PTE* pt_entry, NE_PDE* pd_entry)
+ STATIC Int32 mmi_map_page_table_entry(UInt32 physical_address, UInt32 flags, NE_PTE* pt_entry, NE_PDE* pd_entry)
{
if (!pt_entry)
return 1;
@@ -149,6 +143,8 @@ namespace Kernel::HAL
else if (flags & ~kMMFlagsUser)
pt_entry->User = false;
+ pt_entry->PhysicalAddress = physical_address;
+
hal_invl_tlb(reinterpret_cast<VoidPtr>(pt_entry));
mmi_page_status(pt_entry);
@@ -159,7 +155,7 @@ namespace Kernel::HAL
page_store.fInternalStore.fPde = pd_entry;
page_store.fInternalStore.fPte = pt_entry;
- page_store.fInternalStore.fVAddr = virtual_address;
+ page_store.fInternalStore.fPAddr = (VoidPtr)(UIntPtr)physical_address;
page_store.fStoreOp = No;
diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h
index 51882606..b95fff74 100644
--- a/dev/Kernel/HALKit/AMD64/Processor.h
+++ b/dev/Kernel/HALKit/AMD64/Processor.h
@@ -319,7 +319,7 @@ namespace Kernel::HAL
/// @param phys_addr point to physical address.
/// @param flags the flags to put on the page.
/// @return Status code of page manip.
- EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags);
+ EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags);
EXTERN_C UInt8 rt_in8(UInt16 port);
EXTERN_C UInt16 rt_in16(UInt16 port);
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
index 7764b55b..b37de7e5 100644
--- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc
@@ -15,6 +15,7 @@
*
*/
+#include "KernelKit/DebugOutput.h"
#include <KernelKit/UserProcessScheduler.h>
#include <KernelKit/LPC.h>
@@ -28,11 +29,11 @@
#define kHBAErrTaskFile (1 << 30)
#define kHBACmdGhc (1 << 31)
-#define kHBACmdAE (1 << 0)
-#define kHBAPxCmdST 0x0001
-#define kHBAPxCmdFre 0x0010
-#define kHBAPxCmdFR 0x4000
-#define kHBAPxCmdCR 0x8000
+#define kHBACmdAE (0x80000000)
+#define kHBAPxCmdST (0x0001)
+#define kHBAPxCmdFre (0x0010)
+#define kHBAPxCmdFR (0x4000)
+#define kHBAPxCmdCR (0x8000)
#define kSATALBAMode (1 << 6)
@@ -46,9 +47,10 @@
#define kSATABar5 (0x24)
STATIC Kernel::PCI::Device kPCIDevice;
-STATIC HbaMem* kSATAPort = nullptr;
+STATIC HbaMem* kSATA = nullptr;
STATIC Kernel::SizeT kSATAPortIdx = 0UL;
STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL;
+STATIC Kernel::Char kCurrentDiskModel[50] = {"UNKNOWN SATA DRIVE"};
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept;
@@ -61,18 +63,28 @@ static Kernel::Void drvi_calculate_disk_geometry() noexcept
{
kCurrentDiskSectorCount = 0UL;
- Kernel::UInt8 identify_data[kib_cast(4)] = {};
+ Kernel::UInt8 identify_data[512] = {};
- drvi_std_input_output<NO, NO, YES>(0, identify_data, 0, kib_cast(4));
+ drvi_std_input_output<NO, NO, YES>(0, identify_data, 0, 512);
kCurrentDiskSectorCount = (identify_data[61] << 16) | identify_data[60];
+ for (int i = 0; i < 20; i++)
+ {
+ kCurrentDiskModel[i * 2] = identify_data[27 + i] >> 8;
+ kCurrentDiskModel[i * 2 + 1] = identify_data[27 + i] & 0xFF;
+ }
+
+ kCurrentDiskModel[40] = '\0';
+
+ kout << "Drive Model: " << kCurrentDiskModel << endl;
+
kout << "Disk Size: " << Kernel::number(drv_get_size()) << endl;
kout << "Highest Disk LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
}
/// @brief Initializes an AHCI disk.
-/// @param PortsImplemented the amount of kSATAPort that have been detected.
+/// @param PortsImplemented the amount of kSATA that have been detected.
/// @return if the disk was successfully initialized or not.
Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
{
@@ -110,14 +122,33 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
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 == kSATASignature && det == 3 && ipm == 1)
+ HAL::mm_map_page(mem_ahci, mem_ahci, HAL::kMMFlagsWr);
+
+ kout << "Virtddr: " << hex_number((UIntPtr)mem_ahci) << endl;
+ kout << "PhysAddr: " << hex_number((UIntPtr)HAL::hal_get_phys_address(mem_ahci)) << endl;
+
+ if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1 &&
+ (mem_ahci->Ports[ahci_index].Ssts & 0xF))
{
kout << "Port is implemented as SATA.\r";
kSATAPortIdx = ahci_index;
- kSATAPort = mem_ahci;
+ kSATA = mem_ahci;
+
+ kSATA->Ports[kSATAPortIdx].Cmd &= ~(kHBAPxCmdST | kHBAPxCmdFre); // Disable command and FIS reception
+
+ while (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
+ ; // Wait for controller to stop
- kSATAPort->Ghc |= kHBACmdAE;
+ kSATA->Ports[kSATAPortIdx].Serr = 0xFFFFFFFF; // Clear errors
+ kSATA->Ports[kSATAPortIdx].Is = 0xFFFFFFFF; // Clear interrupts
+
+ kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; // Re-enable FIS reception
+ kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; // Start command engine
+
+ kSATA->Ghc |= kHBACmdAE; // Enable AHCI mode
+
+ HAL::rt_wait_400ns();
drvi_calculate_disk_geometry();
@@ -153,33 +184,34 @@ static Kernel::Int32 drvi_find_cmd_slot(HbaPort* port) noexcept
{
Kernel::UInt32 slots = port->Ci;
- for (Kernel::Int32 i = 0; i < (kSATAPortCnt); i++)
+ for (Kernel::Int32 i = 0; i < kSATAPortCnt; i++)
{
- if ((slots & 1) == 0)
+ if ((slots & i) == 0)
return i;
slots >>= 1;
}
- return 0;
+ return -1;
}
template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept
{
- auto slot = 0L;
-
- slot = drvi_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]);
+ const Kernel::SizeT slot = drvi_find_cmd_slot(&kSATA->Ports[kSATAPortIdx]);
if (slot == -1)
return;
if (size_buffer > mib_cast(4))
- Kernel::ke_panic(RUNTIME_CHECK_FAILED, "AHCI only supports < 4mb DMA transfers.");
+ Kernel::ke_panic(RUNTIME_CHECK_FAILED, "AHCI only supports < 4mb DMA transfers per PRD.");
+
+ if (!Write)
+ Kernel::rt_set_memory(buffer, 0, size_buffer);
- HbaCmdHeader* command_header = ((HbaCmdHeader*)((Kernel::UInt64)(kSATAPort->Ports[kSATAPortIdx].Clbu) | kSATAPort->Ports[kSATAPortIdx].Clb)) + slot;
+ HbaCmdHeader* command_header = ((HbaCmdHeader*)((Kernel::UInt64)(kSATA->Ports[kSATAPortIdx].Clb)));
- MUST_PASS(command_header);
+ TRY([&command_header]() -> BOOL { return command_header != nullptr; });
command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32);
command_header->Write = Write;
@@ -187,24 +219,19 @@ static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buf
command_header->Atapi = 0;
command_header->Prefetchable = 1;
- HbaCmdTbl* command_table = new HbaCmdTbl();
+ HbaCmdTbl* command_table = ((HbaCmdTbl*)((Kernel::UInt64)(command_header->Ctba)));
Kernel::rt_set_memory(command_table, 0, sizeof(HbaCmdTbl));
MUST_PASS(command_table);
- auto phys_dma_buf = Kernel::HAL::hal_get_phys_address(buffer);
+ auto phys_dma_buf = Kernel::HAL::hal_get_phys_address((Kernel::VoidPtr)buffer);
command_table->Prdt[0].Dba = ((Kernel::UInt32)(Kernel::UInt64)phys_dma_buf & 0xFFFFFFFF);
command_table->Prdt[0].Dbau = (((Kernel::UInt64)phys_dma_buf << 32));
command_table->Prdt[0].Dbc = ((size_buffer)-1);
command_table->Prdt[0].IE = 1;
- auto phys_dma_tbl = Kernel::HAL::hal_get_phys_address(command_table);
-
- command_header->Ctba = ((Kernel::UInt32)(Kernel::UInt64)phys_dma_tbl & 0xFFFFFFFF);
- command_header->Ctbau = ((Kernel::UInt32)((Kernel::UInt64)phys_dma_tbl << 32));
-
FisRegH2D* h2d_fis = (FisRegH2D*)((Kernel::UInt64)&command_table->Cfis);
h2d_fis->FisType = kFISTypeRegH2D;
@@ -228,25 +255,26 @@ static Kernel::Void drvi_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buf
h2d_fis->CountLow = sector_sz & 0xFF;
h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF;
- if (kSATAPort->Is & kHBAErrTaskFile)
+ if (kSATA->Is & kHBAErrTaskFile)
Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component.");
- kSATAPort->Ports[kSATAPortIdx].Ci = (1 << slot);
+ while (kSATA->Ports[kSATAPortIdx].Cmd & (kHBAPxCmdCR | kHBAPxCmdFR))
+ ; // Ensure controller is idle
+
+ kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre;
+ kSATA->Ports[kSATAPortIdx].Ci = (1 << slot);
while (YES)
{
- if (kSATAPort->Ports[kSATAPortIdx].Ci == 0)
+ if (kSATA->Ports[kSATAPortIdx].Ci == 0)
break;
- kout << "PxCI: " << Kernel::hex_number(kSATAPort->Ports[kSATAPortIdx].Ci) << endl;
- kout << "PxCMD: " << Kernel::hex_number(kSATAPort->Ports[kSATAPortIdx].Cmd) << endl;
+ kout << "PxCI: " << Kernel::hex_number(kSATA->Ports[kSATAPortIdx].Ci) << endl;
+ kout << "PxCMD: " << Kernel::hex_number(kSATA->Ports[kSATAPortIdx].Cmd) << endl;
- if (kSATAPort->Is & kHBAErrTaskFile)
+ if (kSATA->Is & kHBAErrTaskFile)
Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component.");
}
-
- delete command_table;
- command_table = nullptr;
}
/***
diff --git a/dev/Kernel/NewKit/KernelPanic.h b/dev/Kernel/NewKit/KernelPanic.h
index 6be17f7d..b27cf258 100644
--- a/dev/Kernel/NewKit/KernelPanic.h
+++ b/dev/Kernel/NewKit/KernelPanic.h
@@ -16,12 +16,22 @@ namespace Kernel
#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG)
+#ifdef TRY
+#undef TRY
+#endif
+
+#define TRY(X) { auto fn = X; if ((fn()) == NO) { MUST_PASS(NO); }}
+
+#ifdef __MUST_PASS
+#undef __MUST_PASS
+#endif
+
#define __MUST_PASS(EXPR, FILE, LINE) \
Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE))
#ifdef __DEBUG__
#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__)
-#define assert(EXPR) MUST_PASS(EXPR, RUNTIME_CHECK_EXPRESSION)
+#define assert(EXPR) MUST_PASS(EXPR)
#else
#define MUST_PASS(EXPR) (Kernel::Void)(EXPR)
#define assert(EXPR) (Kernel::Void)(EXPR)
@@ -55,13 +65,3 @@ namespace Kernel
{
void ke_panic(const Int32& id, const Char* message = nullptr);
} // namespace Kernel
-
-#ifdef TRY
-#undef TRY
-#endif
-
-#define TRY(FN) \
- if (!FN()) \
- { \
- MUST_PASS(false); \
- }
diff --git a/dev/Kernel/src/BitMapMgr.cc b/dev/Kernel/src/BitMapMgr.cc
index b255798b..1fbdb33d 100644
--- a/dev/Kernel/src/BitMapMgr.cc
+++ b/dev/Kernel/src/BitMapMgr.cc
@@ -105,7 +105,7 @@ namespace Kernel
this->GetBitMapStatus(ptr_bit_set);
UInt32 flags = this->MakeMMFlags(wr, user);
- mm_map_page(ptr_bit_set, flags);
+ mm_map_page(ptr_bit_set, ptr_bit_set, flags);
if (biggest_block < size)
biggest_block = size;
@@ -122,7 +122,7 @@ namespace Kernel
this->GetBitMapStatus(ptr_bit_set);
UInt32 flags = this->MakeMMFlags(wr, user);
- mm_map_page(ptr_bit_set, flags);
+ mm_map_page(ptr_bit_set, ptr_bit_set, flags);
if (biggest_block < size)
biggest_block = size;
diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc
index a3955c2c..49a66c94 100644
--- a/dev/Kernel/src/UserProcessScheduler.cc
+++ b/dev/Kernel/src/UserProcessScheduler.cc
@@ -311,7 +311,7 @@ namespace Kernel
flags |= HAL::kMMFlagsWr;
flags |= HAL::kMMFlagsUser;
- HAL::mm_map_page((VoidPtr)process.VMRegister, flags);
+ HAL::mm_map_page((VoidPtr)process.VMRegister, process.VMRegister, flags);
#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
process.StackFrame = new HAL::StackFrame();
@@ -327,7 +327,7 @@ namespace Kernel
flags |= HAL::kMMFlagsWr;
flags |= HAL::kMMFlagsUser;
- HAL::mm_map_page((VoidPtr)process.StackFrame, flags);
+ HAL::mm_map_page((VoidPtr)process.StackFrame, process.StackFrame, flags);
#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
// React according to process kind.
@@ -356,7 +356,7 @@ namespace Kernel
flags |= HAL::kMMFlagsWr;
flags |= HAL::kMMFlagsUser;
- HAL::mm_map_page((VoidPtr)process.StackReserve, flags);
+ HAL::mm_map_page((VoidPtr)process.StackReserve, process.StackReserve, flags);
#endif // __NE_VIRTUAL_MEMORY_SUPPORT__
process.ProcessParentTeam = &mTeam;