From f3d931aa7cfaf96baef8383b59a8938779541ee7 Mon Sep 17 00:00:00 2001 From: Amlal EL Mahrouss Date: Thu, 15 Aug 2024 18:35:34 +0200 Subject: [IMP] Moved source code into dev/ folder. Signed-off-by: Amlal EL Mahrouss --- dev/Kernel/HALKit/.gitkeep | 0 dev/Kernel/HALKit/64x0/.hgkeep | 0 dev/Kernel/HALKit/64x0/APM/.hgkeep | 0 dev/Kernel/HALKit/64x0/HalVirtualMemory.cxx | 17 + dev/Kernel/HALKit/64x0/MBCI/.gitkeep | 0 dev/Kernel/HALKit/64x0/ReadMe.md | 4 + dev/Kernel/HALKit/AMD64/CPUID.hxx | 81 ++ .../HALKit/AMD64/HalACPIFactoryInterface.cxx | 142 ++ dev/Kernel/HALKit/AMD64/HalAPIC.cxx | 36 + dev/Kernel/HALKit/AMD64/HalBoot.asm | 22 + dev/Kernel/HALKit/AMD64/HalControlRegister.s | 40 + .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx | 76 ++ .../HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx | 198 +++ dev/Kernel/HALKit/AMD64/HalDebugOutput.cxx | 145 ++ dev/Kernel/HALKit/AMD64/HalDebugPort.cxx | 40 + dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cxx | 91 ++ dev/Kernel/HALKit/AMD64/HalHart.cxx | 33 + dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm | 242 ++++ dev/Kernel/HALKit/AMD64/HalKernelMain.cxx | 251 ++++ dev/Kernel/HALKit/AMD64/HalKernelMouse.cxx | 190 +++ dev/Kernel/HALKit/AMD64/HalPageAlloc.cxx | 120 ++ dev/Kernel/HALKit/AMD64/HalPageAlloc.hxx | 92 ++ dev/Kernel/HALKit/AMD64/HalProcessor.cxx | 97 ++ dev/Kernel/HALKit/AMD64/HalRoutines.s | 9 + dev/Kernel/HALKit/AMD64/HalSMPCoreManager.asm | 81 ++ dev/Kernel/HALKit/AMD64/HalScheduler.cxx | 30 + dev/Kernel/HALKit/AMD64/HalTimer.cxx | 14 + dev/Kernel/HALKit/AMD64/HalUtils.asm | 33 + dev/Kernel/HALKit/AMD64/Hypervisor.hxx | 25 + dev/Kernel/HALKit/AMD64/MBCI/.gitkeep | 0 dev/Kernel/HALKit/AMD64/PCI/Database.cxx | 11 + dev/Kernel/HALKit/AMD64/PCI/Device.cxx | 130 ++ dev/Kernel/HALKit/AMD64/PCI/Dma.cxx | 82 ++ dev/Kernel/HALKit/AMD64/PCI/Express.cxx | 11 + dev/Kernel/HALKit/AMD64/PCI/IO.cxx | 7 + dev/Kernel/HALKit/AMD64/PCI/Iterator.cxx | 44 + dev/Kernel/HALKit/AMD64/PCI/PCI.cxx | 7 + dev/Kernel/HALKit/AMD64/Processor.hxx | 348 +++++ dev/Kernel/HALKit/AMD64/ReadMe.md | 4 + dev/Kernel/HALKit/AMD64/Storage/AHCI.cxx | 67 + dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cxx | 38 + dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cxx | 199 +++ dev/Kernel/HALKit/ARM64/.gitkeep | 0 dev/Kernel/HALKit/ARM64/APM/.gitkeep | 0 dev/Kernel/HALKit/ARM64/HalHart.cxx | 29 + dev/Kernel/HALKit/ARM64/HalKernelMain.cxx | 181 +++ dev/Kernel/HALKit/ARM64/HalPageAlloc.hxx | 108 ++ dev/Kernel/HALKit/ARM64/HalPageInternal.S | 5 + dev/Kernel/HALKit/ARM64/HalScheduler.cxx | 31 + dev/Kernel/HALKit/ARM64/HalTimer.cxx | 16 + dev/Kernel/HALKit/ARM64/MBCI/.keepme | 0 dev/Kernel/HALKit/ARM64/Processor.hxx | 56 + dev/Kernel/HALKit/ARM64/ReadMe.md | 3 + dev/Kernel/HALKit/ARM64/Storage/.gitkeep | 0 dev/Kernel/HALKit/ARM64/Storage/HalFlash.cxx | 66 + dev/Kernel/HALKit/AXP/CR.s | 11 + dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp | 0 dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp | 24 + dev/Kernel/HALKit/AXP/HAL.s | 13 + dev/Kernel/HALKit/AXP/Processor.hpp | 7 + dev/Kernel/HALKit/AXP/README | 1 + dev/Kernel/HALKit/AXP/README.TXT | 1 + dev/Kernel/HALKit/AXP/SYSCALL.s | 10 + dev/Kernel/HALKit/AXP/VM.s | 5 + dev/Kernel/HALKit/POWER/.gitkeep | 0 dev/Kernel/HALKit/POWER/APM/.gitkeep | 0 dev/Kernel/HALKit/POWER/HalContextSwitchPowerPC.s | 28 + dev/Kernel/HALKit/POWER/HalHardware.cxx | 19 + dev/Kernel/HALKit/POWER/HalHart.cxx | 25 + dev/Kernel/HALKit/POWER/HalSerialPort.cxx | 27 + dev/Kernel/HALKit/POWER/HalStartSequence.s | 14 + dev/Kernel/HALKit/POWER/HalThread.cxx | 8 + dev/Kernel/HALKit/POWER/HalVirtualMemory.cxx | 51 + dev/Kernel/HALKit/POWER/Hart.hxx | 36 + dev/Kernel/HALKit/POWER/MBCI/.gitkeep | 0 dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cxx | 8 + dev/Kernel/HALKit/POWER/Processor.hxx | 56 + dev/Kernel/HALKit/POWER/ReadMe.md | 4 + dev/Kernel/HALKit/POWER/ppc-cpu.h | 1424 ++++++++++++++++++++ dev/Kernel/HALKit/POWER/ppc-mmu.h | 811 +++++++++++ dev/Kernel/HALKit/RISCV/.keep | 0 dev/Kernel/HALKit/RISCV/APM/.gitkeep | 0 dev/Kernel/HALKit/RISCV/Hart.hxx | 24 + dev/Kernel/HALKit/RISCV/ReadMe.md | 4 + dev/Kernel/HALKit/RISCV/Storage/.gitkeep | 0 dev/Kernel/HALKit/X86S/.gitkeep | 0 dev/Kernel/HALKit/X86S/ACPI/.gitkeep | 0 dev/Kernel/HALKit/X86S/Storage/.gitkeep | 0 dev/Kernel/HALKit/compile_flags.txt | 6 + 89 files changed, 6169 insertions(+) create mode 100644 dev/Kernel/HALKit/.gitkeep create mode 100644 dev/Kernel/HALKit/64x0/.hgkeep create mode 100644 dev/Kernel/HALKit/64x0/APM/.hgkeep create mode 100644 dev/Kernel/HALKit/64x0/HalVirtualMemory.cxx create mode 100644 dev/Kernel/HALKit/64x0/MBCI/.gitkeep create mode 100644 dev/Kernel/HALKit/64x0/ReadMe.md create mode 100644 dev/Kernel/HALKit/AMD64/CPUID.hxx create mode 100644 dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalAPIC.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalBoot.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalControlRegister.s create mode 100644 dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalDebugOutput.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalDebugPort.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalHart.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalKernelMain.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalKernelMouse.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalPageAlloc.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalPageAlloc.hxx create mode 100644 dev/Kernel/HALKit/AMD64/HalProcessor.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalRoutines.s create mode 100644 dev/Kernel/HALKit/AMD64/HalSMPCoreManager.asm create mode 100644 dev/Kernel/HALKit/AMD64/HalScheduler.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalTimer.cxx create mode 100644 dev/Kernel/HALKit/AMD64/HalUtils.asm create mode 100644 dev/Kernel/HALKit/AMD64/Hypervisor.hxx create mode 100644 dev/Kernel/HALKit/AMD64/MBCI/.gitkeep create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Database.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Device.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Dma.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Express.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/IO.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/Iterator.cxx create mode 100644 dev/Kernel/HALKit/AMD64/PCI/PCI.cxx create mode 100644 dev/Kernel/HALKit/AMD64/Processor.hxx create mode 100644 dev/Kernel/HALKit/AMD64/ReadMe.md create mode 100644 dev/Kernel/HALKit/AMD64/Storage/AHCI.cxx create mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cxx create mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cxx create mode 100644 dev/Kernel/HALKit/ARM64/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/HalHart.cxx create mode 100644 dev/Kernel/HALKit/ARM64/HalKernelMain.cxx create mode 100644 dev/Kernel/HALKit/ARM64/HalPageAlloc.hxx create mode 100644 dev/Kernel/HALKit/ARM64/HalPageInternal.S create mode 100644 dev/Kernel/HALKit/ARM64/HalScheduler.cxx create mode 100644 dev/Kernel/HALKit/ARM64/HalTimer.cxx create mode 100644 dev/Kernel/HALKit/ARM64/MBCI/.keepme create mode 100644 dev/Kernel/HALKit/ARM64/Processor.hxx create mode 100644 dev/Kernel/HALKit/ARM64/ReadMe.md create mode 100644 dev/Kernel/HALKit/ARM64/Storage/.gitkeep create mode 100644 dev/Kernel/HALKit/ARM64/Storage/HalFlash.cxx create mode 100644 dev/Kernel/HALKit/AXP/CR.s create mode 100644 dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp create mode 100644 dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp create mode 100644 dev/Kernel/HALKit/AXP/HAL.s create mode 100644 dev/Kernel/HALKit/AXP/Processor.hpp create mode 100644 dev/Kernel/HALKit/AXP/README create mode 100644 dev/Kernel/HALKit/AXP/README.TXT create mode 100644 dev/Kernel/HALKit/AXP/SYSCALL.s create mode 100644 dev/Kernel/HALKit/AXP/VM.s create mode 100644 dev/Kernel/HALKit/POWER/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/HalContextSwitchPowerPC.s create mode 100644 dev/Kernel/HALKit/POWER/HalHardware.cxx create mode 100644 dev/Kernel/HALKit/POWER/HalHart.cxx create mode 100644 dev/Kernel/HALKit/POWER/HalSerialPort.cxx create mode 100644 dev/Kernel/HALKit/POWER/HalStartSequence.s create mode 100644 dev/Kernel/HALKit/POWER/HalThread.cxx create mode 100644 dev/Kernel/HALKit/POWER/HalVirtualMemory.cxx create mode 100644 dev/Kernel/HALKit/POWER/Hart.hxx create mode 100644 dev/Kernel/HALKit/POWER/MBCI/.gitkeep create mode 100644 dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cxx create mode 100644 dev/Kernel/HALKit/POWER/Processor.hxx create mode 100644 dev/Kernel/HALKit/POWER/ReadMe.md create mode 100644 dev/Kernel/HALKit/POWER/ppc-cpu.h create mode 100644 dev/Kernel/HALKit/POWER/ppc-mmu.h create mode 100644 dev/Kernel/HALKit/RISCV/.keep create mode 100644 dev/Kernel/HALKit/RISCV/APM/.gitkeep create mode 100644 dev/Kernel/HALKit/RISCV/Hart.hxx create mode 100644 dev/Kernel/HALKit/RISCV/ReadMe.md create mode 100644 dev/Kernel/HALKit/RISCV/Storage/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/ACPI/.gitkeep create mode 100644 dev/Kernel/HALKit/X86S/Storage/.gitkeep create mode 100644 dev/Kernel/HALKit/compile_flags.txt (limited to 'dev/Kernel/HALKit') diff --git a/dev/Kernel/HALKit/.gitkeep b/dev/Kernel/HALKit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/.hgkeep b/dev/Kernel/HALKit/64x0/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/APM/.hgkeep b/dev/Kernel/HALKit/64x0/APM/.hgkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/HalVirtualMemory.cxx b/dev/Kernel/HALKit/64x0/HalVirtualMemory.cxx new file mode 100644 index 00000000..1b0c9153 --- /dev/null +++ b/dev/Kernel/HALKit/64x0/HalVirtualMemory.cxx @@ -0,0 +1,17 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +/// @brief Flush system TLB, looks like the POWER version, as it acts the same, no specific instruction for that. +/// @note The 88K MMU should be present as well. +EXTERN_C void hal_flush_tlb() +{ + asm volatile("invltlb"); +} diff --git a/dev/Kernel/HALKit/64x0/MBCI/.gitkeep b/dev/Kernel/HALKit/64x0/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/64x0/ReadMe.md b/dev/Kernel/HALKit/64x0/ReadMe.md new file mode 100644 index 00000000..2e72d5bf --- /dev/null +++ b/dev/Kernel/HALKit/64x0/ReadMe.md @@ -0,0 +1,4 @@ +64x0 Hardware Abstraction Layer + +- Supported CPU: ZKA Technologies 64x0 +- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/Kernel/HALKit/AMD64/CPUID.hxx b/dev/Kernel/HALKit/AMD64/CPUID.hxx new file mode 100644 index 00000000..f5ae5bb5 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/CPUID.hxx @@ -0,0 +1,81 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: CPUID.hxx + Purpose: CPUID flags. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +enum +{ + eCPU_FEATURE_ECX_SSE3 = 1 << 0, + eCPU_FEATURE_ECX_PCLMUL = 1 << 1, + eCPU_FEATURE_ECX_DTES64 = 1 << 2, + eCPU_FEATURE_ECX_MONITOR = 1 << 3, + eCPU_FEATURE_ECX_DS_CPL = 1 << 4, + eCPU_FEATURE_ECX_VMX = 1 << 5, + eCPU_FEATURE_ECX_SMX = 1 << 6, + eCPU_FEATURE_ECX_EST = 1 << 7, + eCPU_FEATURE_ECX_TM2 = 1 << 8, + eCPU_FEATURE_ECX_SSSE3 = 1 << 9, + eCPU_FEATURE_ECX_CID = 1 << 10, + eCPU_FEATURE_ECX_SDBG = 1 << 11, + eCPU_FEATURE_ECX_FMA = 1 << 12, + eCPU_FEATURE_ECX_CX16 = 1 << 13, + eCPU_FEATURE_ECX_XTPR = 1 << 14, + eCPU_FEATURE_ECX_PDCM = 1 << 15, + eCPU_FEATURE_ECX_PCID = 1 << 17, + eCPU_FEATURE_ECX_DCA = 1 << 18, + eCPU_FEATURE_ECX_SSE4_1 = 1 << 19, + eCPU_FEATURE_ECX_SSE4_2 = 1 << 20, + eCPU_FEATURE_ECX_X2APIC = 1 << 21, + eCPU_FEATURE_ECX_MOVBE = 1 << 22, + eCPU_FEATURE_ECX_POP3C = 1 << 23, + eCPU_FEATURE_ECX_TSC = 1 << 24, + eCPU_FEATURE_ECX_AES = 1 << 25, + eCPU_FEATURE_ECX_XSAVE = 1 << 26, + eCPU_FEATURE_ECX_OSXSAVE = 1 << 27, + eCPU_FEATURE_ECX_AVX = 1 << 28, + eCPU_FEATURE_ECX_F16C = 1 << 29, + eCPU_FEATURE_ECX_RDRAND = 1 << 30, + eCPU_FEATURE_ECX_HYPERVISOR = 1 << 31, + eCPU_FEATURE_EDX_FPU = 1 << 0, + eCPU_FEATURE_EDX_VME = 1 << 1, + eCPU_FEATURE_EDX_DE = 1 << 2, + eCPU_FEATURE_EDX_PSE = 1 << 3, + eCPU_FEATURE_EDX_TSC = 1 << 4, + eCPU_FEATURE_EDX_MSR = 1 << 5, + eCPU_FEATURE_EDX_PAE = 1 << 6, + eCPU_FEATURE_EDX_MCE = 1 << 7, + eCPU_FEATURE_EDX_CX8 = 1 << 8, + eCPU_FEATURE_EDX_APIC = 1 << 9, + eCPU_FEATURE_EDX_SEP = 1 << 11, + eCPU_FEATURE_EDX_MTRR = 1 << 12, + eCPU_FEATURE_EDX_PGE = 1 << 13, + eCPU_FEATURE_EDX_MCA = 1 << 14, + eCPU_FEATURE_EDX_CMOV = 1 << 15, + eCPU_FEATURE_EDX_PAT = 1 << 16, + eCPU_FEATURE_EDX_PSE36 = 1 << 17, + eCPU_FEATURE_EDX_PSN = 1 << 18, + eCPU_FEATURE_EDX_CLFLUSH = 1 << 19, + eCPU_FEATURE_EDX_DS = 1 << 21, + eCPU_FEATURE_EDX_ACPI = 1 << 22, + eCPU_FEATURE_EDX_MMX = 1 << 23, + eCPU_FEATURE_EDX_FXSR = 1 << 24, + eCPU_FEATURE_EDX_SSE = 1 << 25, + eCPU_FEATURE_EDX_SSE2 = 1 << 26, + eCPU_FEATURE_EDX_SS = 1 << 27, + eCPU_FEATURE_EDX_HTT = 1 << 28, + eCPU_FEATURE_EDX_TM = 1 << 29, + eCPU_FEATURE_EDX_IA64 = 1 << 30, + eCPU_FEATURE_EDX_PBE = 1 << 31 +}; + +typedef long long int hal_cpu_feature_type; \ No newline at end of file diff --git a/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx new file mode 100644 index 00000000..4a9af53b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cxx @@ -0,0 +1,142 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +namespace Kernel +{ + /// Custom to the virtual machine, you'll need to parse the MADT instead. + + void rt_shutdown_acpi_qemu_20(void) + { + HAL::Out16(0xb004, 0x2000); + } + + void rt_shutdown_acpi_qemu_30_plus(void) + { + HAL::Out16(0x604, 0x2000); + } + + void rt_shutdown_acpi_virtualbox(void) + { + HAL::Out16(0x4004, 0x3400); + } + + /// You have to parse the MADT! + + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsdPtr) + : fRsdp(rsdPtr), fEntries(0) + { +#ifdef __DEBUG__ + kcout << "newoskrnl: ACPI: init interface.\r"; +#else + +#endif + } + + Void ACPIFactoryInterface::Shutdown() + { +#ifdef __DEBUG__ + rt_shutdown_acpi_qemu_30_plus(); +#else + +#endif + } + + /// @brief Reboot (shutdowns on qemu.) + /// @return + Void ACPIFactoryInterface::Reboot() + { +#ifdef __DEBUG__ + rt_shutdown_acpi_qemu_30_plus(); +#else + +#endif + } + + /// @brief Finds a descriptor table inside ACPI XSDT. + ErrorOr ACPIFactoryInterface::Find(const char* signature) + { + MUST_PASS(fRsdp); + + if (!signature) + return ErrorOr{-1}; + + if (*signature == 0) + return ErrorOr{-1}; + + RSDP* rsdPtr = reinterpret_cast(this->fRsdp); + + if (rsdPtr->Revision <= 1) + return ErrorOr{-1}; + + RSDT* xsdt = reinterpret_cast(rsdPtr->RsdtAddress); + + Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32); + + /*** + crucial to avoid - overflows. + */ + if (num < 1) + { + /// stop here, we should have entries... + ke_stop(RUNTIME_CHECK_ACPI); + return ErrorOr{-1}; + } + + this->fEntries = num; + + kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; + kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; + kcout << "ACPI: Signature: " << xsdt->Signature << endl; + kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; + + const short cAcpiSignatureLength = 4; + + for (Size index = 0; index < this->fEntries; ++index) + { + SDT* sdt = reinterpret_cast(xsdt->AddressArr[index]); + + kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; + kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; + + for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) + { + if (sdt->Signature[signature_index] != signature[signature_index]) + break; + + if (signature_index == (cAcpiSignatureLength - 1)) + return ErrorOr(reinterpret_cast(xsdt->AddressArr[index])); + } + } + + return ErrorOr{-1}; + } + + /*** + @brief check SDT header + @param checksum the header to checksum + @param len the length of it. +*/ + bool ACPIFactoryInterface::Checksum(const char* checksum, SSizeT len) + { + if (len == 0) + return -1; + + char chr = 0; + + for (int index = 0; index < len; ++index) + { + chr += checksum[index]; + } + + return chr == 0; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalAPIC.cxx b/dev/Kernel/HALKit/AMD64/HalAPIC.cxx new file mode 100644 index 00000000..caa2ce0b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalAPIC.cxx @@ -0,0 +1,36 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +namespace Kernel::HAL +{ + /// @brief Read from APIC controller. + /// @param reg register. + UInt32 APICController::Read(UInt32 reg) noexcept + { + MUST_PASS(this->fApic); + + UInt32 volatile* ioapic = (UInt32 volatile*)this->fApic; + ioapic[0] = (reg & 0xff); + + return ioapic[4]; + } + + /// @brief Write to APIC controller. + /// @param reg register. + /// @param value value. + Void APICController::Write(UInt32 reg, UInt32 value) noexcept + { + MUST_PASS(this->fApic); + + UInt32 volatile* ioapic = (UInt32 volatile*)this->fApic; + + ioapic[0] = (reg & 0xFF); + ioapic[4] = value; + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalBoot.asm b/dev/Kernel/HALKit/AMD64/HalBoot.asm new file mode 100644 index 00000000..8cc3c08f --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalBoot.asm @@ -0,0 +1,22 @@ +;; /* +;; * ======================================================== +;; * +;; * Kernel +;; * Copyright ZKA Technologies., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +;; Global symbol of this unit +[extern hal_init_platform] + +%define kTypeKernel 100 +%define kArchAmd64 122 +%define kHandoverMagic 0xBADCC + +section .ldr + +HandoverMagic: dq kHandoverMagic +HandoverType: dw kTypeKernel diff --git a/dev/Kernel/HALKit/AMD64/HalControlRegister.s b/dev/Kernel/HALKit/AMD64/HalControlRegister.s new file mode 100644 index 00000000..879d35c1 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalControlRegister.s @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +.globl hal_write_cr3 +.globl hal_write_cr0 +.globl hal_read_cr2 +.globl hal_read_cr3 +.globl hal_read_cr0 +.globl hal_flush_tlb + +.text + +hal_flush_tlb: + call hal_read_cr3 + mov %rcx, %rax + call hal_write_cr3 + ret + +hal_read_cr3: + movq %cr3, %rax + ret + +hal_read_cr0: + movq %rax, %cr0 + ret + +hal_read_cr2: + movq %rax, %cr2 + ret + +hal_write_cr3: + movq %cr3, %rdi + ret + +hal_write_cr0: + movq %cr0, %rdi + ret diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx new file mode 100644 index 00000000..88b5db36 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx @@ -0,0 +1,76 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include + +/// @brief Handle GPF fault. +/// @param rsp +EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) +{ + Kernel::ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); +} + +/// @brief Handle page fault. +/// @param rsp +EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) +{ + Kernel::ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); +} + +/// @brief Handle math fault. +/// @param rsp +EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) +{ + Kernel::ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); +} + +/// @brief Handle any generic fault. +/// @param rsp +EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) +{ + Kernel::ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); +} + +/// @brief Handle #UD fault. +/// @param rsp +EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) +{ + Kernel::ke_stop(RUNTIME_CHECK_BAD_BEHAVIOR); +} + +/// @brief Enter syscall from assembly. +/// @param stack the stack pushed from assembly routine. +/// @return nothing. +EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx) +{ + if (rcx <= (kSyscalls.Count() - 1)) + { + Kernel::kcout << "newoskrnl: syscall: enter.\r"; + + if (kSyscalls[rcx].Leak().Leak()->fHooked) + (kSyscalls[rcx].Leak().Leak()->fProc)((Kernel::VoidPtr)rdx); + + Kernel::kcout << "newoskrnl: syscall: exit.\r"; + } +} + +/// @brief Enter kernel call from assembly (DDK only). +/// @param stack the stack pushed from assembly routine. +/// @return nothing. +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx, Kernel::UIntPtr r8, Kernel::UIntPtr r9) +{ + if (rcx <= (kSyscalls.Count() - 1)) + { + Kernel::kcout << "newoskrnl: kerncall: enter.\r"; + + if (kKerncalls[rcx].Leak().Leak()->fHooked) + (kKerncalls[rcx].Leak().Leak()->fProc)((Kernel::VoidPtr)rdx); + + Kernel::kcout << "newoskrnl: kerncall: exit.\r"; + } +} diff --git a/dev/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx b/dev/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx new file mode 100644 index 00000000..6018d20f --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cxx @@ -0,0 +1,198 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include + +// Needed for SMP. // + +#include + +#define kApicSignature "APIC" + +#define kAPIC_ICR_Low 0x300 +#define kAPIC_ICR_High 0x310 +#define kAPIC_SIPI_Vector 0x00500 +#define kAPIC_EIPI_Vector 0x00400 + +#define kAPIC_BASE_MSR 0x1B +#define kAPIC_BASE_MSR_BSP 0x100 +#define kAPIC_BASE_MSR_ENABLE 0x800 + +/// @note: _hal_switch_context is internal + +/////////////////////////////////////////////////////////////////////////////////////// + +//! NOTE: fGSI stands 'Field Global System Interrupt' + +/////////////////////////////////////////////////////////////////////////////////////// + +namespace Kernel::HAL +{ + struct MADT_TABLE; + + EXTERN_C Void _hal_spin_core(Void); + + STATIC Void hal_switch_context(HAL::StackFramePtr stack_frame); + + constexpr Int32 kThreadAPIC = 0; + constexpr Int32 kThreadLAPIC = 1; + constexpr Int32 kThreadIOAPIC = 2; + constexpr Int32 kThreadAPIC64 = 3; + constexpr Int32 kThreadBoot = 4; + + STATIC MADT_TABLE* kSMPBlock = nullptr; + Bool kSMPAware = false; + + STATIC Int32 cSMPInterrupt = 34; + + STATIC VoidPtr kRawMADT = nullptr; + + /* + * + * this is used to store info about the current running thread + * we use this struct to determine if we can use it, or mark it as used or on + * sleep. + * + */ + + struct ProcessorInfoAMD64 final + { + Int32 ThreadType; + UIntPtr JumpAddress; + + struct + { + UInt32 Code; + UInt32 Data; + UInt32 BSS; + } Selector; + }; + + /// @brief Multiple APIC Descriptor Table. + struct MADT_TABLE final : public SDT + { + UInt32 Address; // Madt address + UInt32 Flags; // Madt flags + + struct { + UInt8 Type; + UInt8 Len; + } Records[]; // Records List + }; + + /////////////////////////////////////////////////////////////////////////////////////// + + /// @brief Send start IPI for CPU. + /// @param apicId + /// @param vector + /// @param targetAddress + /// @return + Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + { + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector); + } + + /// @brief Send end IPI for CPU. + /// @param apicId + /// @param vector + /// @param targetAddress + /// @return + Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + { + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24); + Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector); + } + + /// @internal + EXTERN_C Void hal_ap_startup(Void) + { + ke_stop(RUNTIME_CHECK_BOOTSTRAP); + } + + /// @internal + EXTERN_C Void _hal_switch_context(HAL::StackFramePtr stack_frame) + { + hal_switch_context(stack_frame); + } + + constexpr auto cMaxPCBBlocks = cMaxHWThreads; + + struct PROCESS_CONTROL_BLOCK final + { + PROCESS_HEADER_BLOCK* f_Header; + HAL::StackFramePtr f_StackFrame; + } fBlocks[cMaxPCBBlocks] = {0}; + + EXTERN_C HAL::StackFramePtr _hal_leak_current_context(Void) + { + return fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_StackFrame; + } + + STATIC Void hal_switch_context(HAL::StackFramePtr stack_frame) + { + STATIC Semaphore sem; + + constexpr auto cSeconds = 1U; + + HardwareTimer timer(Seconds(cSeconds)); + sem.LockOrWait(&ProcessScheduler::The().Leak().TheCurrent().Leak(), &timer); + + fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_Header = &ProcessScheduler::The().Leak().TheCurrent().Leak(); + fBlocks[ProcessScheduler::The().Leak().TheCurrent().Leak().ProcessId % cMaxPCBBlocks].f_StackFrame = stack_frame; + + sem.Unlock(); + } + + STATIC auto cAPICAddress = 0x0FEC00000; + + STATIC Void cpu_set_apic_base(UIntPtr apic) + { + UInt32 edx = 0; + UInt32 eax = (apic & 0xfffff0000) | kAPIC_BASE_MSR_ENABLE; + + edx = (apic >> 32) & 0x0f; + + hal_set_msr(kAPIC_BASE_MSR, eax, edx); + } + + STATIC UIntPtr cpu_get_apic_base(Void) + { + UInt32 eax, edx; + + hal_get_msr(kAPIC_BASE_MSR, &eax, &edx); + + return (eax & 0xfffff000) | ((UIntPtr)(edx & 0x0f) << 32); + } + + EXTERN_C Void hal_ap_trampoline(Void); + + /// @brief Fetch and enable cores inside main CPU. + /// @param rsdPtr RSD PTR structure. + Void hal_system_get_cores(voidPtr rsdPtr) + { + auto acpi = ACPIFactoryInterface(rsdPtr); + kRawMADT = acpi.Find(kApicSignature).Leak().Leak(); + + kSMPBlock = reinterpret_cast(kRawMADT); + + if (!kSMPBlock) + kSMPAware = false; + + if (kSMPBlock) + { + kSMPAware = true; + } + } +} // namespace Kernel::HAL + +/////////////////////////////////////////////////////////////////////////////////////// diff --git a/dev/Kernel/HALKit/AMD64/HalDebugOutput.cxx b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cxx new file mode 100644 index 00000000..d4e2b435 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cxx @@ -0,0 +1,145 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +namespace Kernel +{ + enum CommStatus + { + kStateInvalid, + kStateReady = 0xCF, + kStateTransmit = 0xFC, + kStateCnt = 3 + }; + + namespace Detail + { + constexpr short PORT = 0x3F8; + + static int kState = kStateInvalid; + + /// @brief Init COM1. + /// @return + bool hal_serial_init() noexcept + { +#ifdef __DEBUG__ + if (kState == kStateReady || kState == kStateTransmit) + return true; + + HAL::Out8(PORT + 1, 0x00); // Disable all interrupts + HAL::Out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + HAL::Out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + HAL::Out8(PORT + 1, 0x00); // (hi byte) + HAL::Out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + HAL::Out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + HAL::Out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + HAL::Out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + HAL::Out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if + // serial returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (HAL::In8(PORT) != 0xAE) + { + ke_stop(RUNTIME_CHECK_HANDSHAKE); + } + + kState = kStateReady; + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + HAL::Out8(Detail::PORT + 4, 0x0F); +#endif // __DEBUG__ + + return true; + } + } // namespace Detail + + EXTERN_C void ke_io_write(const char* bytes) + { +#ifdef __DEBUG__ + Detail::hal_serial_init(); + + if (!bytes || Detail::kState != kStateReady) + return; + if (*bytes == 0) + return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes, 255); + + while (index < len) + { + if (bytes[index] == '\r') + HAL::Out8(Detail::PORT, '\r'); + + HAL::Out8(Detail::PORT, bytes[index] == '\r' ? '\n' : bytes[index]); + ++index; + } + + Detail::kState = kStateReady; +#endif // __DEBUG__ + } + + EXTERN_C void ke_io_read(const char* bytes) + { +#ifdef __DEBUG__ + Detail::hal_serial_init(); + + if (!bytes || Detail::kState != kStateReady) + return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + + ///! TODO: Look on how to wait for the UART to complete. + while (true) + { + auto in = HAL::In8(Detail::PORT); + + ///! If enter pressed then break. + if (in == 0xD) + { + break; + } + + if (in < '0' || in < 'A' || in < 'a') + { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || + in != ':') + { + continue; + } + } + + ((char*)bytes)[index] = in; + + ++index; + } + + ((char*)bytes)[index] = 0; + + Detail::kState = kStateReady; +#endif // __DEBUG__ + } + + TerminalDevice TerminalDevice::The() noexcept + { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; + } + +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalDebugPort.cxx b/dev/Kernel/HALKit/AMD64/HalDebugPort.cxx new file mode 100644 index 00000000..1ea52b8d --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDebugPort.cxx @@ -0,0 +1,40 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +//! @file DebuggerPort.cxx +//! @brief UART debug via packets. + +#include +#include + +// after that we have start of additional data. + +namespace Kernel +{ + void rt_debug_listen(DebuggerPortHeader* theHook) noexcept + { + if (theHook == nullptr) + return; + + for (UInt32 i = 0U; i < kDebugMaxPorts; ++i) + { + HAL::Out16(theHook->fPort[i], kDebugMag0); + HAL::rt_wait_400ns(); + + HAL::Out16(theHook->fPort[i], kDebugMag1); + HAL::rt_wait_400ns(); + + HAL::Out16(theHook->fPort[i], kDebugMag2); + HAL::rt_wait_400ns(); + + HAL::Out16(theHook->fPort[i], kDebugMag3); + HAL::rt_wait_400ns(); + + if (HAL::In16(theHook->fPort[i] != kDebugUnboundPort)) + theHook->fBoundCnt++; + } + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cxx b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cxx new file mode 100644 index 00000000..0339dd7f --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cxx @@ -0,0 +1,91 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +namespace Kernel::HAL +{ + namespace Detail + { + STATIC RegisterGDT kRegGdt; + STATIC HAL::Register64 kRegIdt; + + STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 + kInterruptVectorTable[kKernelIdtSize]; + + STATIC Void RemapPIC(Void) noexcept + { + // Remap PIC. + HAL::Out8(0x20, 0x10 | 0x01); + HAL::Out8(0xA0, 0x10 | 0x01); + + HAL::Out8(0x21, 32); + HAL::Out8(0xA1, 40); + + HAL::Out8(0x21, 4); + HAL::Out8(0xA1, 2); + + HAL::Out8(0x21, 0x01); + HAL::Out8(0xA1, 0x01); + + HAL::Out8(0x21, 0x00); + HAL::Out8(0xA1, 0x00); + } + } // namespace Detail + + /// @brief Loads the provided Global Descriptor Table. + /// @param gdt + /// @return + Void GDTLoader::Load(RegisterGDT& gdt) + { + MUST_PASS(gdt.Base != 0); + + Detail::kRegGdt.Base = gdt.Base; + Detail::kRegGdt.Limit = gdt.Limit; + + hal_load_gdt(Detail::kRegGdt); + } + + Void IDTLoader::Load(Register64& idt) + { + volatile ::Kernel::UIntPtr** baseIdt = (volatile ::Kernel::UIntPtr**)idt.Base; + + MUST_PASS(baseIdt); + + Detail::RemapPIC(); + + for (UInt16 i = 0; i < kKernelIdtSize; ++i) + { + MUST_PASS(baseIdt[i]); + + Detail::kInterruptVectorTable[i].Selector = kGdtCodeSelector; + Detail::kInterruptVectorTable[i].Ist = 0x0; + Detail::kInterruptVectorTable[i].TypeAttributes = kInterruptGate; + Detail::kInterruptVectorTable[i].OffsetLow = ((UIntPtr)baseIdt[i] & __INT16_MAX__); + Detail::kInterruptVectorTable[i].OffsetMid = (((UIntPtr)baseIdt[i] >> 16) & __INT16_MAX__); + Detail::kInterruptVectorTable[i].OffsetHigh = + (((UIntPtr)baseIdt[i] >> 32) & __INT32_MAX__); + + Detail::kInterruptVectorTable[i].Zero = 0x0; + } + + Detail::kRegIdt.Base = reinterpret_cast(Detail::kInterruptVectorTable); + Detail::kRegIdt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * + (kKernelIdtSize - 1); + + hal_load_idt(Detail::kRegIdt); + } + + void GDTLoader::Load(Ref& gdt) + { + GDTLoader::Load(gdt.Leak()); + } + + void IDTLoader::Load(Ref& idt) + { + IDTLoader::Load(idt.Leak()); + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalHart.cxx b/dev/Kernel/HALKit/AMD64/HalHart.cxx new file mode 100644 index 00000000..bc0a485e --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalHart.cxx @@ -0,0 +1,33 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +// bugs = 0 + +namespace Kernel +{ + /// @brief wakes up thread. + /// wakes up thread from hang. + void mp_wakeup_thread(HAL::StackFrame* stack) + { + HAL::rt_cli(); + + rt_do_context_switch(stack); + + HAL::rt_sti(); + } + + /// @brief makes the thread sleep on a loop. + /// hooks and hangs thread to prevent code from executing. + void mp_hang_thread(HAL::StackFrame* stack) + { + while (true) + { + /* nohing, code is spinning */ + } + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm new file mode 100644 index 00000000..093da0db --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -0,0 +1,242 @@ +;; /* +;; * --------------------------------------------------- +;; * +;; * Copyright ZKA Technologies., all rights reserved. +;; * +;; * File: HalInterruptAPI.asm +;; * Purpose: Interrupt routing, redirect raw interrupts into their handlers. +;; * +;; * --------------------------------------------------- +;; */ + +[bits 64] + +%define kInterruptId 0x21 + +%macro IntExp 1 +global __NEW_INT_%1 +__NEW_INT_%1: + cld + + iretq +%endmacro + +%macro IntNormal 1 +global __NEW_INT_%1 +__NEW_INT_%1: + cld + + iretq +%endmacro + +; This file handles the core interrupt table +; Last edited 31/01/24 + +global ke_handle_irq +global kInterruptVectorTable + +extern _hal_handle_mouse +extern idt_handle_gpf +extern idt_handle_pf +extern ke_io_write +extern idt_handle_ud + +section .text + +IntNormal 0 +IntNormal 1 + +IntNormal 2 + +IntNormal 3 +IntNormal 4 +IntNormal 5 + +;; Invalid opcode interrupt +__NEW_INT_6: + cli + + push rax + + mov rcx, rsp + call idt_handle_ud + + pop rax + + sti + iretq + +IntNormal 7 +IntExp 8 +IntNormal 9 +IntExp 10 +IntExp 11 + +IntExp 12 + +__NEW_INT_13: + cli + + push rax + + mov rcx, rsp + call idt_handle_gpf + + pop rax + + sti + iretq + +__NEW_INT_14: + cli + + push rax + + mov rcx, rsp + call idt_handle_pf + + pop rax + + sti + iretq + +IntNormal 15 +IntNormal 16 +IntExp 17 +IntNormal 18 +IntNormal 19 +IntNormal 20 +IntNormal 21 +IntNormal 22 +IntNormal 23 +IntNormal 24 +IntNormal 25 +IntNormal 26 +IntNormal 27 +IntNormal 28 +IntNormal 29 +IntExp 30 + +IntNormal 31 + +IntNormal 32 +IntNormal 34 + +IntNormal 33 +IntNormal 35 +IntNormal 36 +IntNormal 37 +IntNormal 38 +IntNormal 39 +IntNormal 40 +IntNormal 41 +IntNormal 42 +IntNormal 43 + +__NEW_INT_44: + cli + + ;; TODO: CoreEvents dispatch routine. + + push rax + call _hal_handle_mouse + pop rax + + sti + iretq + +IntNormal 45 +IntNormal 46 +IntNormal 47 +IntNormal 48 +IntNormal 49 + +[extern hal_system_call_enter] +[extern hal_kernel_call_enter] + +__NEW_INT_50: + cli + + push rcx + push rdx + push rax + + call hal_system_call_enter + + pop rax + pop rdx + pop rcx + + sti + iretq + +__NEW_INT_51: + cli + + push rcx + push rdx + push r8 + push r9 + push rax + + call hal_kernel_call_enter + + pop rax + pop r9 + pop r8 + pop rdx + pop rcx + + sti + iretq + +IntNormal 52 +IntNormal 53 +IntNormal 54 +IntNormal 55 +IntNormal 56 +IntNormal 57 +IntNormal 58 +IntNormal 59 +IntNormal 60 + +%assign i 61 +%rep 195 + IntNormal i +%assign i i+1 +%endrep + +section .text + +[global hal_load_gdt] + +hal_load_gdt: + lgdt [rcx] + push 0x08 + lea rax, [rel rt_reload_segments] + push rax + retfq +rt_reload_segments: + mov ax, 0x10 + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + ret + +global hal_load_idt + +hal_load_idt: + lidt [rcx] + sti + ret + +section .data + +kInterruptVectorTable: + %assign i 0 + %rep 256 + dq __NEW_INT_%+i + %assign i i+1 + %endrep diff --git a/dev/Kernel/HALKit/AMD64/HalKernelMain.cxx b/dev/Kernel/HALKit/AMD64/HalKernelMain.cxx new file mode 100644 index 00000000..49ddfa6c --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalKernelMain.cxx @@ -0,0 +1,251 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +Kernel::Property cKernelVersion; +Kernel::Property cAutoFormatDisk; + +EXTERN Kernel::Boolean kAllocationInProgress; + +EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; + +struct HEAP_ALLOC_INFO final +{ + Kernel::VoidPtr fThe; + Kernel::Size fTheSz; +}; + +struct PROCESS_BLOCK_INFO final +{ + THREAD_INFORMATION_BLOCK* fTIB; + THREAD_INFORMATION_BLOCK* fGIB; +}; + +struct PROCESS_EXIT_INFO final +{ + STATIC constexpr auto cReasonLen = 512; + + Kernel::Int64 fCode; + Kernel::Char fReason[cReasonLen]; +}; + +namespace Kernel::HAL +{ + /// @brief Gets the system cores using the MADT. + /// @param rsdPtr The 'RSD PTR' data structure. + EXTERN void hal_system_get_cores(Kernel::voidPtr rsdPtr); +} // namespace Kernel::HAL + +/* GDT. */ +STATIC Kernel::HAL::Detail::NewOSGDT cGdt = { + {0, 0, 0, 0x00, 0x00, 0}, // null entry + {0, 0, 0, 0x9a, 0xaf, 0}, // kernel code + {0, 0, 0, 0x92, 0xaf, 0}, // kernel data + {0, 0, 0, 0x00, 0x00, 0}, // null entry + {0, 0, 0, 0x9a, 0xaf, 0}, // user code + {0, 0, 0, 0x92, 0xaf, 0}, // user data +}; + +Kernel::Void hal_real_init(Kernel::Void) noexcept; + +static Kernel::User* cRoot; + +EXTERN_C void hal_init_platform( + Kernel::HEL::HandoverInformationHeader* HandoverHeader) +{ + /* Setup globals. */ + + kHandoverHeader = HandoverHeader; + + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) + { + return; + } + + hal_real_init(); +} + +Kernel::Void hal_real_init(Kernel::Void) noexcept +{ + // reset kAllocationInProgress field to zero. + kAllocationInProgress = false; + + // get page size. + kKernelVirtualSize = kHandoverHeader->f_VirtualSize; + + // get virtual address start (for the heap) + kKernelVirtualStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_VirtualStart)); + + // get physical address start. + kKernelPhysicalStart = reinterpret_cast( + reinterpret_cast(kHandoverHeader->f_PhysicalStart)); + + // Load memory descriptors. + Kernel::HAL::RegisterGDT gdtBase; + + gdtBase.Base = reinterpret_cast(&cGdt); + gdtBase.Limit = sizeof(Kernel::HAL::Detail::NewOSGDT) - 1; + + CONST Kernel::HAL::GDTLoader cGDT; + cGDT.Load(gdtBase); + + // Load IDT now. + + Kernel::HAL::Register64 idtBase; + idtBase.Base = (Kernel::UIntPtr)kInterruptVectorTable; + idtBase.Limit = 0; + + CONST Kernel::HAL::IDTLoader cIDT; + cIDT.Load(idtBase); + + // Register the basic system calls. + + constexpr auto cTlsInterrupt = 0x11; + constexpr auto cTlsInstallInterrupt = 0x12; + constexpr auto cNewInterrupt = 0x13; + constexpr auto cDeleteInterrupt = 0x14; + constexpr auto cExitInterrupt = 0x15; + constexpr auto cLastExitInterrupt = 0x16; + constexpr auto cCatalogOpen = 0x17; + constexpr auto cForkRead = 0x18; + constexpr auto cForkWrite = 0x19; + constexpr auto cCatalogClose = 0x20; + constexpr auto cCatalogRemove = 0x21; + constexpr auto cCatalogCreate = 0x22; + constexpr auto cRebootInterrupt = 0x23; + constexpr auto cShutdownInterrupt = 0x24; + constexpr auto cLPCSendMsg = 0x25; + constexpr auto cLPCOpenMsg = 0x26; + constexpr auto cLPCCloseMsg = 0x27; + + kSyscalls[cTlsInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + if (tls_check_syscall_impl(rdx) == false) + { + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Crash(); + } + }; + + kSyscalls[cNewInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + // get HAC struct. + HEAP_ALLOC_INFO* rdxInf = reinterpret_cast(rdx); + + if (!rdxInf) + return; + + // assign the fThe field with the pointer. + rdxInf->fThe = Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().New(rdxInf->fTheSz); + }; + + kSyscalls[cDeleteInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + // get HAC struct. + HEAP_ALLOC_INFO* rdxInf = reinterpret_cast(rdx); + + if (!rdxInf) + return; + + // delete ptr with sz in mind. + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Delete(rdxInf->fThe, rdxInf->fTheSz); + }; + + kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + PROCESS_BLOCK_INFO* rdxPb = reinterpret_cast(rdx); + + if (!rdxPb) + return; + + // install the fTIB and fGIB. + rt_install_tib(rdxPb->fTIB, rdxPb->fGIB); + }; + + kSyscalls[cExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + PROCESS_EXIT_INFO* rdxEi = reinterpret_cast(rdx); + + if (!rdxEi) + return; + + Kernel::kcout << "newoskrnl: " << rdxEi->fReason << "\r"; + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Exit(rdxEi->fCode); + }; + + kSyscalls[cLastExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + PROCESS_EXIT_INFO* rdxEi = reinterpret_cast(rdx); + + if (!rdxEi) + return; + + rdxEi->fCode = Kernel::sched_get_exit_code(); + }; + + kSyscalls[cRebootInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + Kernel::PowerFactoryInterface pow(kHandoverHeader->f_HardwareTables.f_VendorPtr); + pow.Reboot(); + }; + + kSyscalls[cShutdownInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + Kernel::PowerFactoryInterface pow(kHandoverHeader->f_HardwareTables.f_VendorPtr); + pow.Shutdown(); + }; + + kSyscalls[cTlsInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cDeleteInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cNewInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cExitInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cLastExitInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cShutdownInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cRebootInterrupt].Leak().Leak()->fHooked = true; + + Kernel::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + + Kernel::kcout << "newoskrnl: Creating filesystem and such.\r"; + + auto fs = new Kernel::NewFilesystemManager(); + + MUST_PASS(fs); + MUST_PASS(fs->GetParser()); + + Kernel::NewFilesystemManager::Mount(fs); + + delete fs->GetParser()->CreateCatalog("\\Users\\", 0, kNewFSCatalogKindDir); + + Kernel::kcout << "newoskrnl: Created filesystem and now creating " << kSuperUser << "..." << Kernel::endl; + + cRoot = new Kernel::User(Kernel::RingKind::kRingSuperUser, kSuperUser); + +#ifdef __DEBUG__ + const auto cPassword = "6aa162f3-20f6-4143-92f9-5dd37066aedc"; +#else + const auto cPassword = "password"; +#endif + + Kernel::UserManager::The()->fRootUser = cRoot; + + Kernel::kcout << "newoskrnl: Root is " << kSuperUser << "." << Kernel::endl; + + cRoot->TrySave(cPassword); + + Kernel::UserManager::The()->TryLogIn(cRoot, cPassword); + + Kernel::ke_stop(RUNTIME_CHECK_FAILED); +} diff --git a/dev/Kernel/HALKit/AMD64/HalKernelMouse.cxx b/dev/Kernel/HALKit/AMD64/HalKernelMouse.cxx new file mode 100644 index 00000000..bff5e5ee --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalKernelMouse.cxx @@ -0,0 +1,190 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include + +/// @note forward decl. +EXTERN_C Kernel::Boolean _hal_draw_mouse(); +EXTERN_C Kernel::Void _hal_init_mouse(); + +STATIC Kernel::Int32 kPrevX = 10; +STATIC Kernel::Int32 kPrevY = 10; +STATIC Kernel::Int32 kX = 10; +STATIC Kernel::Int32 kY = 10; +STATIC Kernel::Int32 kMouseCycle = 0; +STATIC Kernel::PS2MouseInterface kMousePS2; +STATIC Kernel::Char kMousePacket[4] = {}; +STATIC Kernel::Boolean kMousePacketReady = false; + +STATIC CGInit(); + +#define kPS2Leftbutton 0b00000001 +#define kPS2Middlebutton 0b00000010 +#define kPS2Rightbutton 0b00000100 +#define kPS2XSign 0b00010000 +#define kPS2YSign 0b00100000 +#define kPS2XOverflow 0b01000000 +#define kPS2YOverflow 0b10000000 + +using namespace Kernel; + +Void hal_handle_mouse() +{ + Kernel::UInt8 data = HAL::In8(0x60); + + switch (kMouseCycle) + { + case 0: + if (kMousePacketReady) + break; + if ((data & 0b00001000) == 0) + break; + kMousePacket[0] = data; + kMouseCycle++; + break; + case 1: + if (kMousePacketReady) + break; + kMousePacket[1] = data; + kMouseCycle++; + break; + case 2: + if (kMousePacketReady) + break; + kMousePacket[2] = data; + kMousePacketReady = true; + kMouseCycle = 0; + break; + } + + // Notify PIC controller that we're done with it's interrupt. + + Kernel::HAL::Out8(0x20, 0x20); + Kernel::HAL::Out8(0xA0, 0x20); +} + +/// @brief Interrupt handler for the mouse. +EXTERN_C Void _hal_handle_mouse() +{ + hal_handle_mouse(); +} + +EXTERN_C Boolean _hal_left_button_pressed() +{ + return kMousePacket[0] & kPS2Leftbutton; +} +EXTERN_C Boolean _hal_right_button_pressed() +{ + return kMousePacket[0] & kPS2Rightbutton; +} +EXTERN_C Boolean _hal_middle_button_pressed() +{ + return kMousePacket[0] & kPS2Middlebutton; +} + +/// @brief Draws the kernel's mouse. +EXTERN_C Boolean _hal_draw_mouse() +{ + if (!kMousePacketReady) + return false; + + bool xNegative, yNegative, xOverflow, yOverflow; + + if (kMousePacket[0] & kPS2XSign) + { + xNegative = true; + } + else + xNegative = false; + + if (kMousePacket[0] & kPS2YSign) + { + yNegative = true; + } + else + yNegative = false; + + if (kMousePacket[0] & kPS2XOverflow) + { + xOverflow = true; + } + else + xOverflow = false; + + if (kMousePacket[0] & kPS2YOverflow) + { + yOverflow = true; + } + else + yOverflow = false; + + if (!xNegative) + { + kX += kMousePacket[1]; + if (xOverflow) + { + kX += 255; + } + } + else + { + kMousePacket[1] = 256 - kMousePacket[1]; + kX -= kMousePacket[1]; + if (xOverflow) + { + kX -= 255; + } + } + + if (!yNegative) + { + kY -= kMousePacket[2]; + if (yOverflow) + { + kY -= 255; + } + } + else + { + kMousePacket[2] = 256 - kMousePacket[2]; + kY += kMousePacket[2]; + if (yOverflow) + { + kY += 255; + } + } + + if (kX < 0) + kX = 0; + if (kX > kHandoverHeader->f_GOP.f_Width - 8) + kX = kHandoverHeader->f_GOP.f_Width - 8; + + if (kY < 0) + kY = 0; + if (kY > kHandoverHeader->f_GOP.f_Height - 16) + kY = kHandoverHeader->f_GOP.f_Height - 16; + + /// Draw mouse here. + + kPrevX = kX; + kPrevY = kY; + + kMousePacketReady = false; + return true; +} + +/// @brief Init kernel mouse. +EXTERN_C Void _hal_init_mouse() +{ + kMousePS2.Init(); + + HAL::Out8(0x21, 0b11111001); + HAL::Out8(0xA1, 0b11101111); +} diff --git a/dev/Kernel/HALKit/AMD64/HalPageAlloc.cxx b/dev/Kernel/HALKit/AMD64/HalPageAlloc.cxx new file mode 100644 index 00000000..0e39a0f1 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalPageAlloc.cxx @@ -0,0 +1,120 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +#define cVMHMagic (0xDEEFD00D) + +#ifdef __NEWOS_AMD64__ +#include +#elif defined(__NEWOS_ARM64__) +#include +#endif + +#include +#include + +Kernel::Boolean kAllocationInProgress = false; + +namespace Kernel +{ + + namespace HAL + { + namespace Detail + { + struct VIRTUAL_MEMORY_HEADER + { + UInt32 Magic; + Boolean Present : 1; + Boolean ReadWrite : 1; + Boolean User : 1; + SizeT Size; + }; + + struct VirtualMemoryHeaderTraits final + { + /// @brief Get next header. + /// @param current + /// @return + VIRTUAL_MEMORY_HEADER* Next(VIRTUAL_MEMORY_HEADER* current) + { + if (current->Magic != cVMHMagic) + current->Size = 8196; + + return current + sizeof(VIRTUAL_MEMORY_HEADER) + current->Size; + } + + /// @brief Get previous header. + /// @param current + /// @return + VIRTUAL_MEMORY_HEADER* Prev(VIRTUAL_MEMORY_HEADER* current) + { + if (current->Magic != cVMHMagic) + current->Size = 8196; + + return current - sizeof(VIRTUAL_MEMORY_HEADER) - current->Size; + } + }; + } // namespace Detail + + /// @brief Allocates a new page of memory. + /// @param sz the size of it. + /// @param rw read/write flag. + /// @param user user flag. + /// @return the page table of it. + STATIC auto hal_try_alloc_new_page(Boolean rw, Boolean user, SizeT size) -> VoidPtr + { + if (kAllocationInProgress) + return nullptr; + + kAllocationInProgress = true; + + //! fetch from the start. + Detail::VIRTUAL_MEMORY_HEADER* vmh_header = reinterpret_cast(kKernelVMTStart); + Detail::VirtualMemoryHeaderTraits traits; + + while (vmh_header->Present && + vmh_header->Magic == cVMHMagic) + { + vmh_header = traits.Next(vmh_header); + } + + vmh_header->Magic = cVMHMagic; + vmh_header->Present = true; + vmh_header->ReadWrite = rw; + vmh_header->User = user; + vmh_header->Size = size; + + kAllocationInProgress = false; + + return reinterpret_cast(vmh_header + sizeof(Detail::VIRTUAL_MEMORY_HEADER)); + } + + /// @brief Allocate a new page to be used by the OS. + /// @param rw read/write bit. + /// @param user user bit. + /// @return + auto hal_alloc_page(Boolean rw, Boolean user, SizeT size) -> VoidPtr + { + kcout << "Waiting now..."; + + // Wait for a ongoing allocation to complete. + while (kAllocationInProgress) + { + (void)0; + } + + kcout << ", done waiting, allocating...\r"; + + if (size == 0) + ++size; + + // allocate new page. + return hal_try_alloc_new_page(rw, user, size); + } + } // namespace HAL +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalPageAlloc.hxx b/dev/Kernel/HALKit/AMD64/HalPageAlloc.hxx new file mode 100644 index 00000000..30cb7911 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalPageAlloc.hxx @@ -0,0 +1,92 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#pragma once + +/** --------------------------------------------------- + + * THIS FILE CONTAINS CODE FOR X86_64 PAGING. + +------------------------------------------------------- */ + +#include + +#ifndef kPTEMax +#define kPTEMax (0x200) +#endif //! kPTEMax + +#ifndef kPTEAlign +#define kPTEAlign (0x1000) +#endif //! kPTEAlign + +#ifndef kPTESize +#define kPTESize (0x1000) +#endif // !kPTESize + +#ifndef kAlign +#define kAlign __BIGGEST_ALIGNMENT__ +#endif // !kAlign + +EXTERN_C void hal_flush_tlb(); +EXTERN_C void hal_write_cr3(Kernel::UIntPtr pde); +EXTERN_C void hal_write_cr0(Kernel::UIntPtr bit); + +EXTERN_C Kernel::UIntPtr hal_read_cr0(); // @brief CPU control register. +EXTERN_C Kernel::UIntPtr hal_read_cr2(); // @brief Fault address. +EXTERN_C Kernel::UIntPtr hal_read_cr3(); // @brief Page table. + +namespace Kernel::HAL +{ + struct PACKED PageTable64 final + { + bool Present : 1; + bool Rw : 1; + bool User : 1; + bool Wt : 1; + bool Cache : 1; + bool Accessed : 1; + Kernel::Int32 Reserved : 6; + Kernel::UInt64 PhysicalAddress : 36; + Kernel::Int32 Reserved1 : 15; + bool ExecDisable : 1; + }; + + namespace Detail + { + enum class ControlRegisterBits + { + ProtectedModeEnable = 0, + MonitorCoProcessor = 1, + Emulation = 2, + TaskSwitched = 3, + ExtensionType = 4, + NumericError = 5, + WriteProtect = 16, + AlignementMask = 18, + NotWriteThrough = 29, + CacheDisable = 30, + PageEnable = 31, + }; + + inline UInt8 control_register_cast(ControlRegisterBits reg) + { + return static_cast(reg); + } + } // namespace Detail + + struct PageDirectory64 final + { + PageTable64 ALIGN(kPTEAlign) Pte[kPTEMax]; + }; + + VoidPtr hal_alloc_page(Boolean rw, Boolean user, SizeT size); +} // namespace Kernel::HAL + +namespace Kernel +{ + typedef HAL::PageTable64 PTE; + typedef HAL::PageDirectory64 PDE; +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalProcessor.cxx b/dev/Kernel/HALKit/AMD64/HalProcessor.cxx new file mode 100644 index 00000000..367e9314 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalProcessor.cxx @@ -0,0 +1,97 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +/** + * @file Processor.cpp + * @brief This file is about processor specific functions (in/out/cli/std...) + */ + +namespace Kernel::HAL +{ + Void Out8(UInt16 port, UInt8 value) + { + asm volatile("outb %%al, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + Void Out16(UInt16 port, UInt16 value) + { + asm volatile("outw %%ax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + Void Out32(UInt16 port, UInt32 value) + { + asm volatile("outl %%eax, %1" + : + : "a"(value), "Nd"(port) + : "memory"); + } + + UInt8 In8(UInt16 port) + { + UInt8 value = 0UL; + asm volatile("inb %1, %%al" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + UInt16 In16(UInt16 port) + { + UInt16 value = 0UL; + asm volatile("inw %1, %%ax" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + UInt32 In32(UInt16 port) + { + UInt32 value = 0UL; + asm volatile("inl %1, %%eax" + : "=a"(value) + : "Nd"(port) + : "memory"); + + return value; + } + + Void rt_halt() + { + asm volatile("hlt"); + } + + Void rt_cli() + { + asm volatile("cli"); + } + + Void rt_sti() + { + asm volatile("sti"); + } + + Void rt_cld() + { + asm volatile("cld"); + } + + Void rt_std() + { + asm volatile("std"); + } +} // namespace Kernel::HAL diff --git a/dev/Kernel/HALKit/AMD64/HalRoutines.s b/dev/Kernel/HALKit/AMD64/HalRoutines.s new file mode 100644 index 00000000..d794882d --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalRoutines.s @@ -0,0 +1,9 @@ +.globl rt_wait_400ns + +.section .text +rt_wait_400ns: + jmp .loop + .loop: + jmp .loop2 + .loop2: + ret diff --git a/dev/Kernel/HALKit/AMD64/HalSMPCoreManager.asm b/dev/Kernel/HALKit/AMD64/HalSMPCoreManager.asm new file mode 100644 index 00000000..3c53d49d --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalSMPCoreManager.asm @@ -0,0 +1,81 @@ +;; /* +;; * ======================================================== +;; * +;; * Kernel +;; * Copyright ZKA Technologies., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +[global rt_get_current_context] +[global rt_do_context_switch] +[global _hal_spin_core] +[extern _hal_switch_context] +[extern _hal_leak_current_context] + +section .text + +;; writes to rdx the stackframe inside rcx. +;; rcx: Stack Pointer +;; rdx: SMP core address. +rt_do_context_switch: + push rax + call _hal_switch_context + pop rax + + ;; Now grab newly allocated process's stack frame. + + push rax + call _hal_leak_current_context + mov rax, r9 + pop rax + + ;; Take care of context switching within AP. + + mov r9, rax + + mov rbp, [r9 + (8 * 5)] + mov rsp, [r9 + (8 * 6)] + + mov gs, [r9 + (8 * 19)] + mov fs, [r9 + (8 * 20)] + + mov rcx, [r9 + (8 * 3)] + mov rdx, [r9 + (8 * 4)] + mov rbx, [r9 + (8 * 7)] + mov rax, [r9 + (8 * 8)] + movq xmm0, [r9 + (8 * 9)] + movq xmm1, [r9 + (8 * 10)] + + mov r8, [r9 + (8 * 11)] + mov r10, [r9 + (8 * 13)] + mov r11, [r9 + (8 * 14)] + mov r12, [r9 + (8 * 15)] + mov r13, [r9 + (8 * 16)] + mov r14, [r9 + (8 * 17)] + mov r15, [r9 + (8 * 18)] + + fldcw word [r9 + (8 * 21)] + + mov r9, [r9 + (8 * 12)] + + retfq + +;; gets the current stack frame. +rt_get_current_context: + push rax + + call _hal_leak_current_context + + mov rax, r9 + pop rax + + mov r9, rax + + retfq + +_hal_spin_core: + jmp $ + ret diff --git a/dev/Kernel/HALKit/AMD64/HalScheduler.cxx b/dev/Kernel/HALKit/AMD64/HalScheduler.cxx new file mode 100644 index 00000000..d3094c4b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalScheduler.cxx @@ -0,0 +1,30 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +using namespace Kernel; +Void PROCESS_HEADER_BLOCK::SetEntrypoint(UIntPtr& imageStart) noexcept +{ + if (imageStart == 0) + this->Crash(); + + this->StackFrame->BP = imageStart; + this->StackFrame->SP = this->StackFrame->BP; +} + +namespace Kernel +{ + bool rt_check_stack(HAL::StackFramePtr stackPtr) + { + if (!stackPtr) + return false; + if (stackPtr->BP == 0 || stackPtr->SP == 0) + return false; + + return true; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/HalTimer.cxx b/dev/Kernel/HALKit/AMD64/HalTimer.cxx new file mode 100644 index 00000000..ff65a4a1 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalTimer.cxx @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: HalTimer.cxx + Purpose: HAL timer + + Revision History: + + 07/07/24: Added file (amlel) + +------------------------------------------- */ + +#include \ No newline at end of file diff --git a/dev/Kernel/HALKit/AMD64/HalUtils.asm b/dev/Kernel/HALKit/AMD64/HalUtils.asm new file mode 100644 index 00000000..5b4da821 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/HalUtils.asm @@ -0,0 +1,33 @@ +;; /* +;; * ======================================================== +;; * +;; * Kernel +;; * Copyright ZKA Technologies., all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +[global rt_install_tib] + +section .text + +;; changed: rs, fs +;; expected: rcx, rdx + +rt_install_tib: + mov rcx, gs ;; TIB -> Thread Information Block + mov rdx, fs ;; PIB -> Process Information Block + ret + +;; //////////////////////////////////////////////////// ;; + +[extern cBspDone] +[extern kApicMadtAddressesCount] +[extern hal_ap_startup] +[global hal_ap_trampoline] + +hal_ap_trampoline: +hal_ap_trampoline_1: + jmp hal_ap_startup diff --git a/dev/Kernel/HALKit/AMD64/Hypervisor.hxx b/dev/Kernel/HALKit/AMD64/Hypervisor.hxx new file mode 100644 index 00000000..7871288f --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Hypervisor.hxx @@ -0,0 +1,25 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#pragma once + +#include + +namespace Kernel +{ + MAKE_STRING_ENUM(HYPERVISOR) + ENUM_STRING(Qemu, "TCGTCGTCGTCG"); + ENUM_STRING(KVM, " KVMKVMKVM "); + ENUM_STRING(VMWare, "VMwareVMware"); + ENUM_STRING(VirtualBox, "VBoxVBoxVBox"); + ENUM_STRING(Xen, "XenVMMXenVMM"); + ENUM_STRING(Microsoft, "Microsoft Hv"); + ENUM_STRING(Parallels, " prl hyperv "); + ENUM_STRING(ParallelsAlt, " lrpepyh vr "); + ENUM_STRING(Bhyve, "bhyve bhyve "); + ENUM_STRING(Qnx, " QNXQVMBSQG "); + END_STRING_ENUM() +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/MBCI/.gitkeep b/dev/Kernel/HALKit/AMD64/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/AMD64/PCI/Database.cxx b/dev/Kernel/HALKit/AMD64/PCI/Database.cxx new file mode 100644 index 00000000..971d43f9 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Database.cxx @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +namespace Kernel +{ +} diff --git a/dev/Kernel/HALKit/AMD64/PCI/Device.cxx b/dev/Kernel/HALKit/AMD64/PCI/Device.cxx new file mode 100644 index 00000000..214a640a --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Device.cxx @@ -0,0 +1,130 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +Kernel::UInt NewOSPCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) +{ + Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | + ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | + (bar & 0xFC); + + Kernel::HAL::Out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, + target); + + return Kernel::HAL::In32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigData); +} + +void NewOSPCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun) +{ + Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) | + ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) | + (bar & ~3); + + Kernel::HAL::Out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress, + target); +} + +namespace Kernel::PCI +{ + Device::Device(UShort bus, UShort device, UShort func, UShort bar) + : fBus(bus), fDevice(device), fFunction(func), fBar(bar) + { + } + + Device::~Device() + { + } + + UInt Device::Read(UInt bar, Size sz) + { + NewOSPCISetCfgTarget(bar, fBus, fDevice, fFunction); + + if (sz == 4) + return HAL::In32((UShort)PciConfigKind::ConfigData + (fBar & 3)); + if (sz == 2) + return HAL::In16((UShort)PciConfigKind::ConfigData + (fBar & 3)); + if (sz == 1) + return HAL::In8((UShort)PciConfigKind::ConfigData + (fBar & 3)); + + return 0xFFFF; + } + + void Device::Write(UInt bar, UIntPtr data, Size sz) + { + NewOSPCISetCfgTarget(bar, fBus, fDevice, fFunction); + + if (sz == 4) + HAL::Out32((UShort)PciConfigKind::ConfigData + (fBar & 3), (UInt)data); + if (sz == 2) + HAL::Out16((UShort)PciConfigKind::ConfigData + (fBar & 3), (UShort)data); + if (sz == 1) + HAL::Out8((UShort)PciConfigKind::ConfigData + (fBar & 3), (UChar)data); + } + + UShort Device::DeviceId() + { + return (UShort)(NewOSPCIReadRaw(0x0 >> 16, fBus, fDevice, fFunction)); + } + + UShort Device::VendorId() + { + return (UShort)(NewOSPCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); + } + + UShort Device::InterfaceId() + { + return (UShort)(NewOSPCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16); + } + + UChar Device::Class() + { + return (UChar)(NewOSPCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24); + } + + UChar Device::Subclass() + { + return (UChar)(NewOSPCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16); + } + + UChar Device::ProgIf() + { + return (UChar)(NewOSPCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8); + } + + UChar Device::HeaderType() + { + return (UChar)(NewOSPCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16); + } + + void Device::EnableMmio() + { + bool enable = Read(0x04, sizeof(UChar)) | (1 << 1); + Write(0x04, enable, sizeof(UShort)); + } + + void Device::BecomeBusMaster() + { + bool enable = Read(0x04, sizeof(UShort)) | (1 << 2); + Write(0x04, enable, sizeof(UShort)); + } + + UShort Device::Vendor() + { + UShort vendor = VendorId(); + + if (vendor != (UShort)PciConfigKind::Invalid) + fDevice = (UShort)Read(0x0, sizeof(UShort)); + + return fDevice; + } + + Device::operator bool() + { + return VendorId() != (UShort)PciConfigKind::Invalid; + } +} // namespace Kernel::PCI diff --git a/dev/Kernel/HALKit/AMD64/PCI/Dma.cxx b/dev/Kernel/HALKit/AMD64/PCI/Dma.cxx new file mode 100644 index 00000000..bf1730d8 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Dma.cxx @@ -0,0 +1,82 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +namespace Kernel +{ + DMAWrapper::operator bool() + { + return fAddress; + } + + bool DMAWrapper::operator!() + { + return !fAddress; + } + + Boolean DMAWrapper::Check(UIntPtr offset) const + { + if (!fAddress) + return false; + if (offset == 0) + return true; + + kcout << "[DMAWrapper::IsIn] Checking offset..\n"; + return reinterpret_cast(fAddress) >= offset; + } + + bool DMAWrapper::Write(const UIntPtr& bit, const UIntPtr& offset) + { + if (!fAddress) + return false; + + kcout << "[DMAWrapper::Write] Writing at address..\n"; + + auto addr = + (volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); + *addr = bit; + + return true; + } + + UIntPtr DMAWrapper::Read(const UIntPtr& offset) + { + kcout << "[DMAWrapper::Read] checking fAddress..\n"; + if (!fAddress) + return 0; + + kcout << "[DMAWrapper::Read] Reading fAddress..\n"; + return *(volatile UIntPtr*)(reinterpret_cast(fAddress) + offset); + ; + } + + UIntPtr DMAWrapper::operator[](const UIntPtr& offset) + { + return this->Read(offset); + } + + OwnPtr> DMAFactory::Construct(OwnPtr& dma) + { + if (!dma) + return {}; + + OwnPtr> dmaOwnPtr = + make_ptr, char*>(reinterpret_cast(dma->fAddress)); + + if (!dmaOwnPtr) + return {}; + + kcout << "Returning the new OwnPtr>!\r"; + return dmaOwnPtr; + } + + DMAWrapper& DMAWrapper::operator=(voidPtr Ptr) + { + fAddress = Ptr; + return *this; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/AMD64/PCI/Express.cxx b/dev/Kernel/HALKit/AMD64/PCI/Express.cxx new file mode 100644 index 00000000..6a926827 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Express.cxx @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +namespace Kernel +{ +} diff --git a/dev/Kernel/HALKit/AMD64/PCI/IO.cxx b/dev/Kernel/HALKit/AMD64/PCI/IO.cxx new file mode 100644 index 00000000..ea91c7b7 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/IO.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/AMD64/PCI/Iterator.cxx b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cxx new file mode 100644 index 00000000..47b16462 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cxx @@ -0,0 +1,44 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +#define PCI_ITERATOR_FIND_AND_UNWRAP(DEV, SZ) \ + if (DEV.Leak().Leak()) \ + return *DEV.Leak().Leak(); + +namespace Kernel::PCI +{ + Iterator::Iterator(const Types::PciDeviceKind& type) + { + // probe devices. + for (int bus = 0; bus < NEWOS_BUS_COUNT; ++bus) + { + for (int device = 0; device < NEWOS_DEVICE_COUNT; ++device) + { + for (int function = 0; function < NEWOS_FUNCTION_COUNT; ++function) + { + Device dev(bus, device, function, 0); + + if (dev.Class() == (UChar)type) + { + *fDevices[bus].Leak().Leak() = dev; + } + } + } + } + } + + Iterator::~Iterator() + { + } + + Ref Iterator::operator[](const Size& sz) + { + PCI_ITERATOR_FIND_AND_UNWRAP(fDevices[sz], sz); + return {}; + } +} // namespace Kernel::PCI diff --git a/dev/Kernel/HALKit/AMD64/PCI/PCI.cxx b/dev/Kernel/HALKit/AMD64/PCI/PCI.cxx new file mode 100644 index 00000000..59e3b06e --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/PCI/PCI.cxx @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include diff --git a/dev/Kernel/HALKit/AMD64/Processor.hxx b/dev/Kernel/HALKit/AMD64/Processor.hxx new file mode 100644 index 00000000..d80a2834 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Processor.hxx @@ -0,0 +1,348 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: Prcoessor.hxx + Purpose: AMD64 processor abstraction. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include +#include + +EXTERN_C +{ +#include +} + +#ifdef kCPUBackendName +#undef kCPUBackendName +#endif // ifdef kCPUBackendName + +#define kCPUBackendName "AMD64" + +#define kSyscallRoute 0x32 + +#define IsActiveLow(FLG) (FLG & 2) +#define IsLevelTriggered(FLG) (FLG & 8) + +#define kInterruptGate (0x8E) +#define kTrapGate (0xEF) +#define kTaskGate (0b10001100) +#define kGdtCodeSelector (0x08) +#define kGdtUserCodeSelector (0x10) +#define cHeapStartOffset (0x80000000) + +namespace Kernel +{ + namespace Detail::AMD64 + { + struct PACKED InterruptDescriptorAMD64 final + { + UInt16 OffsetLow; // offset bits 0..15 + UInt16 Selector; // a code segment selector in GDT or LDT + UInt8 + Ist; // bits 0..2 holds Interrupt Stack Table offset, rest of bits zero. + UInt8 TypeAttributes; // gate type, dpl, and p fields + UInt16 OffsetMid; // offset bits 16..31 + UInt32 OffsetHigh; // offset bits 32..63 + UInt32 Zero; // reserved + }; + } // namespace Detail::AMD64 +} // namespace Kernel + +namespace Kernel::HAL +{ + /// @brief Virtual memory flags. + enum + { + eFlagsUser, + eFlagsRw, + eFlagsExecDisable + }; + + /// @brief Map address to PDE. + /// @param pde a valid page directory. + /// @param phys_addr a valid phyiscal address. + /// @param virt_addr a valid virtual address. + /// @param flags the flags to put on the page. + inline Int32 ke_map_address(PDE* pde, UIntPtr phys_addr, UIntPtr virt_addr, UInt32 flags) + { + UInt16 pml4_index = (virt_addr >> 39) & 0x1FF; + + if (pde && !pde->Pte[pml4_index].Present) + { + pde->Pte[pml4_index].Present = true; + + pde->Pte[pml4_index].PhysicalAddress = phys_addr; + pde->Pte[pml4_index].Rw = flags & eFlagsRw; + pde->Pte[pml4_index].User = flags & eFlagsUser; + pde->Pte[pml4_index].ExecDisable = flags & eFlagsExecDisable; + + kcout << "PTE is present now.\r"; + + return 0; + } + else + { + kcout << "PM is already present.\r"; + + kcout << "PhysicalAddress: " << hex_number(pde->Pte[pml4_index].PhysicalAddress); + kcout << "\r"; + + kcout << "User: " << (pde->Pte[pml4_index].User ? "true" : "false") << "\r"; + kcout << "RW: " << (pde->Pte[pml4_index].Rw ? "true" : "false") << "\r"; + + return 0; + } + + return 1; + } + + /// @brief Map address to PDE. + /// @param pde + /// @param phys_addr + /// @param virt_addr + /// @param flags + inline Void ke_unmap_address(PDE* pde, UIntPtr phys_addr, UIntPtr virt_addr, UInt32 flags) + { + UInt16 pml4_index = (virt_addr >> 39) & 0x1FF; + + if (pde->Pte[pml4_index].Present) + { + pde->Pte[pml4_index].Present = false; + pde->Pte[pml4_index].PhysicalAddress = 0; + pde->Pte[pml4_index].Rw = 0; + pde->Pte[pml4_index].User = 0; + pde->Pte[pml4_index].ExecDisable = 0; + } + } + + EXTERN_C UChar In8(UInt16 port); + EXTERN_C UShort In16(UInt16 port); + EXTERN_C UInt In32(UInt16 port); + + EXTERN_C void Out16(UShort port, UShort byte); + EXTERN_C void Out8(UShort port, UChar byte); + EXTERN_C void Out32(UShort port, UInt byte); + + EXTERN_C void rt_wait_400ns(); + EXTERN_C void rt_halt(); + EXTERN_C void rt_cli(); + EXTERN_C void rt_sti(); + EXTERN_C void rt_cld(); + EXTERN_C void rt_std(); + + struct PACKED Register64 final + { + UShort Limit; + UIntPtr Base; + }; + + struct PACKED RegisterGDT final + { + UShort Limit; + UIntPtr Base; + }; + + using RawRegister = UInt64; + + using InterruptId = UShort; /* For each element in the IVT */ + using InterruptTrapKind = UIntPtr(UIntPtr sp); + + typedef UIntPtr Reg; + + /// @brief Stack frame (as retrieved from assembly.) + struct PACKED StackFrame final + { + Reg IntNum, Exception; + Reg A0, A2, BP, SP, A3, A4, A5, A6; + Reg R8, R9, R10, R11, R12, R13, R14, R15; + Reg Gs, Fs; + Reg ControlWord; + }; + + typedef StackFrame* StackFramePtr; + + class InterruptDescriptor final + { + public: + UShort Offset; + UShort Selector; + UChar Ist; + UChar Atrributes; + + UShort SecondOffset; + UInt ThirdOffset; + UInt Zero; + + operator bool() + { + return Offset != 0xFFFF; + } + }; + + using InterruptDescriptorArray = Array; + + class SegmentDescriptor final + { + public: + UInt16 Base; + UInt8 BaseMiddle; + UInt8 BaseHigh; + + UShort Limit; + UChar Gran; + UChar AccessByte; + }; + + /*** + * @brief Segment Boolean operations + */ + class SegmentDescriptorComparator final + { + public: + Bool IsValid(SegmentDescriptor& seg) + { + return seg.Base > seg.Limit; + } + + Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight) + { + return seg.Base == segRight.Base && seg.Limit == segRight.Limit; + } + }; + + using SegmentArray = Array; + + class GDTLoader final + { + public: + static Void Load(RegisterGDT& gdt); + static Void Load(Ref& gdt); + }; + + class IDTLoader final + { + public: + static Void Load(Register64& idt); + static Void Load(Ref& idt); + }; + + Void hal_system_get_cores(VoidPtr rsdPtr); + Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); + Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); + + /// @brief Do a cpuid to check if MSR exists on CPU. + /// @retval true it does exists. + /// @retval false it doesn't. + inline Bool hal_has_msr() noexcept + { + static UInt32 eax, unused, edx; // eax, edx + + __get_cpuid(1, &eax, &unused, &unused, &edx); + + // edx returns the flag for MSR (which is 1 shifted to 5.) + return edx & (1 << 5); + } + + /// @brief Get Model-specific register. + /// @param msr MSR + /// @param lo low byte + /// @param hi high byte + inline Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept + { + if (!lo || !hi) + return; + + asm volatile("rdmsr" + : "=a"(*lo), "=d"(*hi) + : "c"(msr)); + } + + /// @brief Set Model-specific register. + /// @param msr MSR + /// @param lo low byte + /// @param hi high byte + inline Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept + { + asm volatile("wrmsr" + : + : "a"(lo), "d"(hi), "c"(msr)); + } + + /// @brief Processor specific namespace. + namespace Detail + { + /** + @brief Global descriptor table entry, either null, code or data. + */ + + struct PACKED NewOSGDTRecord final + { + UInt16 Limit0; + UInt16 Base0; + UInt8 Base1; + UInt8 AccessByte; + UInt8 Limit1_Flags; + UInt8 Base2; + }; + + struct PACKED ALIGN(0x1000) NewOSGDT final + { + NewOSGDTRecord Null; + NewOSGDTRecord KernCode; + NewOSGDTRecord KernData; + NewOSGDTRecord UserNull; + NewOSGDTRecord UserCode; + NewOSGDTRecord UserData; + }; + } // namespace Detail + + class APICController + { + public: + explicit APICController(VoidPtr base) + : fApic(base) + { + } + + ~APICController() = default; + + NEWOS_COPY_DEFAULT(APICController); + + public: + UInt32 Read(UInt32 reg) noexcept; + Void Write(UInt32 reg, UInt32 value) noexcept; + + private: + VoidPtr fApic{nullptr}; + }; +} // namespace Kernel::HAL + +EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp); +EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp); + +EXTERN_C Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr); +EXTERN_C Kernel::Void hal_load_gdt(Kernel::HAL::RegisterGDT ptr); + +/// @brief Maximum size of the IDT. +#define kKernelIdtSize 0x100 +#define kKernelInterruptId 0x32 + +inline Kernel::VoidPtr kKernelVMTStart = (Kernel::VoidPtr)cHeapStartOffset; +inline Kernel::VoidPtr kKernelVirtualStart = nullptr; +inline Kernel::UIntPtr kKernelVirtualSize = 0UL; + +inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; diff --git a/dev/Kernel/HALKit/AMD64/ReadMe.md b/dev/Kernel/HALKit/AMD64/ReadMe.md new file mode 100644 index 00000000..0be48c77 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/ReadMe.md @@ -0,0 +1,4 @@ +AMD64 Hardware Abstraction Layer + +- Supported CPU: AMD64 CPU +- Supported Firmware: EDK 2 \ No newline at end of file diff --git a/dev/Kernel/HALKit/AMD64/Storage/AHCI.cxx b/dev/Kernel/HALKit/AMD64/Storage/AHCI.cxx new file mode 100644 index 00000000..0974c240 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/AHCI.cxx @@ -0,0 +1,67 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +/** + * @file AHCI.cxx + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) + * @brief AHCI driver. + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) ZKA Technologies + * + */ + +#include +#include + +#ifdef __AHCI__ +enum +{ + kSATAProgIfAHCI = 0x01, + kSATASubClass = 0x06 +}; + +static Kernel::PCI::Device kAhciDevice; + +/// @brief Initializes an AHCI disk. +/// @param PortsImplemented the amount of port that have been detected. +/// @return +Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) +{ + using namespace Kernel; + + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); + for (SizeT devIndex = 0; devIndex < NEWOS_BUS_COUNT; ++devIndex) + { + if (iterator[devIndex].Leak().Subclass() == kSATASubClass && + iterator[devIndex].Leak().ProgIf() == kSATAProgIfAHCI) + { + iterator[devIndex].Leak().EnableMmio(); /// enable the memory i/o for this ahci device. + kAhciDevice = iterator[devIndex].Leak(); /// and then leak the reference. + + kcout << "newoskrnl: [PCI] Found AHCI controller.\r"; + + return true; + } + } + + return false; +} + +Kernel::Boolean drv_std_detected(Kernel::Void) +{ + return kAhciDevice.DeviceId() != 0xFFFF; +} + +Kernel::Void drv_std_read(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size) +{ +} + +Kernel::Void drv_std_write(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size) +{ +} +#endif // __AHCI__ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cxx b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cxx new file mode 100644 index 00000000..49d10a7e --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cxx @@ -0,0 +1,38 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +/** + * @file ATA-DMA.cxx + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) + * @brief ATA driver (DMA mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) ZKA Technologies + * + */ + +#include + +#include +#include + +using namespace Kernel; + +EXTERN_C Int32 kPRDTTransferStatus; +STATIC PRDT kPRDT; + +#ifdef __ATA_DMA__ + +#ifdef __ATA_PIO__ +#error !!! You cant have both PIO and DMA enabled! !!! +#endif /* ifdef __ATA_PIO__ */ + +#ifdef __AHCI__ +#error !!! You cant have both ATA and AHCI enabled! !!! +#endif /* ifdef __AHCI__ */ + +#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cxx b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cxx new file mode 100644 index 00000000..c1cdd013 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cxx @@ -0,0 +1,199 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +/** + * @file ATA-PIO.cxx + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) + * @brief ATA driver (PIO mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) ZKA Technologies + * + */ + +#include +#include + +#ifdef __ATA_PIO__ + +using namespace Kernel; +using namespace Kernel::HAL; + +/// bugs: 0 + +#define kATADataLen 256 + +static Boolean kATADetected = false; +static Int32 kATADeviceType = kATADeviceCount; +static Char kATAData[kATADataLen] = {0}; + +Boolean drv_std_wait_io(UInt16 IO) +{ + for (int i = 0; i < 4; i++) + In8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto statRdy = In8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + return false; + + if (!(statRdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_std_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + Out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + Out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) +{ + UInt16 IO = Bus; + + drv_std_select(IO); + + Kernel::kcout << "newoskrnl: Initializing drive...\r"; + +ATAInit_Retry: + // Bus init, NEIN bit. + Out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good + + auto statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + { + Kernel::kcout << "newoskrnl: Failing drive...\r"; + + return false; + } + + if ((statRdy & ATA_SR_BSY)) + { + kcout << "Retrying..."; + goto ATAInit_Retry; + } + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + /// fetch serial info + /// model, speed, number of sectors... + + drv_std_wait_io(IO); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) + { + kATAData[indexData] = In16(IO + ATA_REG_DATA); + } + + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; + + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + Kernel::kcout << "newoskrnl: Create ATA module.\r"; + + return true; +} + +Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + Lba /= SectorSz; + + drv_std_wait_io(IO); + drv_std_select(IO); + + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + /// Compute sector count. + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz / (SectorSz / 2)); + + Out8(IO + ATA_REG_LBA0, (Lba)); + Out8(IO + ATA_REG_LBA1, (Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + Buf[IndexOff] = In16(IO + ATA_REG_DATA); + drv_std_wait_io(IO); + } + + drv_std_wait_io(IO); +} + +Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + Lba /= SectorSz; + + drv_std_wait_io(IO); + drv_std_select(IO); + + /// Compute sector count. + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz / (SectorSz / 2)); + + Out8(IO + ATA_REG_LBA0, (Lba)); + Out8(IO + ATA_REG_LBA1, (Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (Lba) >> 16); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + Out16(IO + ATA_REG_DATA, Buf[IndexOff]); + drv_std_wait_io(IO); + } + + drv_std_wait_io(IO); +} + +/// @brief is ATA detected? +Boolean drv_std_detected(Void) +{ + return kATADetected; +} + +/*** + @brief Getter, gets the number of sectors inside the drive. +*/ +Kernel::SizeT drv_std_get_sector_count() +{ + return (kATAData[61] << 16) | kATAData[60]; +} + +/// @brief Get the drive size. +Kernel::SizeT drv_std_get_drv_size() +{ + return drv_std_get_sector_count() * kATASectorSize; +} + +#endif /* ifdef __ATA_PIO__ */ diff --git a/dev/Kernel/HALKit/ARM64/.gitkeep b/dev/Kernel/HALKit/ARM64/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/APM/.gitkeep b/dev/Kernel/HALKit/ARM64/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/HalHart.cxx b/dev/Kernel/HALKit/ARM64/HalHart.cxx new file mode 100644 index 00000000..d2a91bf3 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalHart.cxx @@ -0,0 +1,29 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +// bugs = 0 + +namespace Kernel +{ + /// @brief wakes up thread. + /// wakes up thread from hang. + void mp_wakeup_thread(HAL::StackFrame* stack) + { + rt_do_context_switch(stack); + } + + /// @brief makes the thread sleep on a loop. + /// hooks and hangs thread to prevent code from executing. + void mp_hang_thread(HAL::StackFrame* stack) + { + while (true) + { + /* nohing, code is spinning */ + } + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalKernelMain.cxx b/dev/Kernel/HALKit/ARM64/HalKernelMain.cxx new file mode 100644 index 00000000..ef955ba7 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalKernelMain.cxx @@ -0,0 +1,181 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KERNEL_INIT(X) \ + X; \ + Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP); + +/// @brief This symbol is the kernel main symbol. +EXTERN_C void KeMain(); + +EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; + +struct PACKED HeapAllocInfo final +{ + Kernel::VoidPtr fThe; + Kernel::Size fTheSz; +}; + +struct PACKED ProcessBlockInfo final +{ + THREAD_INFORMATION_BLOCK* fTIB; + THREAD_INFORMATION_BLOCK* fPIB; +}; + +struct PACKED ProcessExitInfo final +{ + STATIC constexpr auto cReasonLen = 512; + + Kernel::Int64 fCode; + Kernel::Char fReason[cReasonLen]; +}; + +EXTERN_C void hal_init_platform( + Kernel::HEL::HandoverInformationHeader* HandoverHeader) +{ + /* Setup globals. */ + + kHandoverHeader = HandoverHeader; + + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) + { + return; + } + + kKernelVirtualSize = HandoverHeader->f_VirtualSize; + kKernelVirtualStart = reinterpret_cast( + reinterpret_cast(HandoverHeader->f_VirtualStart) + cHeapStartOffset); + + kKernelPhysicalStart = HandoverHeader->f_PhysicalStart; + + // Register the basic SCI functions. + + constexpr auto cSerialAlertInterrupt = 0x10; + constexpr auto cTlsInterrupt = 0x11; + constexpr auto cTlsInstallInterrupt = 0x12; + constexpr auto cNewInterrupt = 0x13; + constexpr auto cDeleteInterrupt = 0x14; + constexpr auto cExitInterrupt = 0x15; + constexpr auto cLastExitInterrupt = 0x16; + constexpr auto cCatalogOpen = 0x17; + constexpr auto cForkRead = 0x18; + constexpr auto cForkWrite = 0x19; + constexpr auto cCatalogClose = 0x20; + constexpr auto cCatalogRemove = 0x21; + constexpr auto cCatalogCreate = 0x22; + constexpr auto cRebootInterrupt = 0x23; + constexpr auto cShutdownInterrupt = 0x24; + constexpr auto cLPCSendMsg = 0x25; + constexpr auto cLPCOpenMsg = 0x26; + constexpr auto cLPCCloseMsg = 0x27; + constexpr auto cLPCSanitizeMsg = 0x28; + + kSyscalls[cSerialAlertInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + const char* msg = (const char*)rdx; + Kernel::kcout << "Kernel: " << msg << "\r"; + }; + + kSyscalls[cTlsInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + if (tls_check_syscall_impl(rdx) == false) + { + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Crash(); + } + }; + + kSyscalls[cLPCSanitizeMsg].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + Kernel::ipc_sanitize_packet(reinterpret_cast(rdx)); + }; + + kSyscalls[cNewInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + // get HAC struct. + HeapAllocInfo* rdxInf = reinterpret_cast(rdx); + + if (!rdxInf) + return; + + // assign the fThe field with the pointer. + rdxInf->fThe = Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().New(rdxInf->fTheSz); + }; + + kSyscalls[cDeleteInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + // get HAC struct. + HeapAllocInfo* rdxInf = reinterpret_cast(rdx); + + if (!rdxInf) + return; + + // delete ptr with sz in mind. + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Delete(rdxInf->fThe, rdxInf->fTheSz); + }; + + kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + ProcessBlockInfo* rdxPb = reinterpret_cast(rdx); + + if (!rdxPb) + return; + + // install the fTIB and fPIB. + rt_install_tib(rdxPb->fTIB, rdxPb->fPIB); + }; + + kSyscalls[cExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + ProcessExitInfo* rdxEi = reinterpret_cast(rdx); + + if (!rdxEi) + return; + + Kernel::kcout << "newoskrnl: " << rdxEi->fReason << "\r"; + Kernel::ProcessScheduler::The().Leak().TheCurrent().Leak().Exit(rdxEi->fCode); + }; + + kSyscalls[cLastExitInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + ProcessExitInfo* rdxEi = reinterpret_cast(rdx); + + if (!rdxEi) + return; + + rdxEi->fCode = Kernel::sched_get_exit_code(); + }; + + kSyscalls[cRebootInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + Kernel::ACPIFactoryInterface acpi(kHandoverHeader->f_HardwareTables.f_VendorPtr); + acpi.Reboot(); + }; + + kSyscalls[cShutdownInterrupt].Leak().Leak()->fProc = [](Kernel::VoidPtr rdx) -> void { + Kernel::ACPIFactoryInterface acpi(kHandoverHeader->f_HardwareTables.f_VendorPtr); + acpi.Shutdown(); + }; + + kSyscalls[cSerialAlertInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cTlsInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cTlsInstallInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cDeleteInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cNewInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cExitInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cLastExitInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cShutdownInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cRebootInterrupt].Leak().Leak()->fHooked = true; + kSyscalls[cLPCSanitizeMsg].Leak().Leak()->fHooked = true; + + KERNEL_INIT(KeMain()); +} diff --git a/dev/Kernel/HALKit/ARM64/HalPageAlloc.hxx b/dev/Kernel/HALKit/ARM64/HalPageAlloc.hxx new file mode 100644 index 00000000..ef3b6db1 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalPageAlloc.hxx @@ -0,0 +1,108 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#pragma once + +/** --------------------------------------------------- + + * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. + +------------------------------------------------------- */ + +#include + +#ifndef kPTEMax +#define kPTEMax (0x200) +#endif //! kPTEMax + +#ifndef kPTEAlign +#define kPTEAlign (0x1000) +#endif //! kPTEAlign + +#ifndef kPTESize +#define kPTESize (0x1000) +#endif // !kPTESize + +//! short format address range + +#define c16KBPage 0b000 +#define c8KBPage 0b001 +#define c4KBPage 0b010 +#define c2KBPage 0b011 +#define c1KBPage 0b100 +#define c512BPage 0b101 +#define c256BPage 0b110 +#define c128BPage 0b111 + +/// Long format address range + +#define cPageMAll \ + { \ + 0b000, 0b000 \ + } +#define cPageMToMax(M) \ + { \ + M, 0b000 \ + } +#define cPageMaxToM(M) \ + { \ + 0b000, M \ + } +#define cPageMToN(M, N) \ + { \ + M, N \ + } + +namespace Kernel::HAL +{ + struct PACKED LongDescLevel3 final + { + Boolean Present : 1; + Boolean Rw : 1; + UInt16 Lpat : 9; + UInt32 Address : 27; + UInt32 Sbzp : 12; + UInt32 UPat : 11; + }; + + namespace Detail + { + enum class ControlRegisterBits + { + ProtectedModeEnable = 0, + MonitorCoProcessor = 1, + Emulation = 2, + TaskSwitched = 3, + ExtensionType = 4, + NumericError = 5, + WriteProtect = 16, + AlignementMask = 18, + NotWriteThrough = 29, + CacheDisable = 30, + PageEnable = 31, + }; + + inline UInt8 control_register_cast(ControlRegisterBits reg) + { + return static_cast(reg); + } + } // namespace Detail + + struct PageDirectory64 final + { + LongDescLevel3 ALIGN(kPTEAlign) Pte[kPTEMax]; + }; + + VoidPtr hal_alloc_page(Boolean rw, Boolean user, SizeT size); +} // namespace Kernel::HAL + +namespace Kernel +{ + typedef HAL::LongDescLevel3 PTE; + typedef HAL::PageDirectory64 PDE; +} // namespace Kernel + +EXTERN_C void hal_flush_tlb(); diff --git a/dev/Kernel/HALKit/ARM64/HalPageInternal.S b/dev/Kernel/HALKit/ARM64/HalPageInternal.S new file mode 100644 index 00000000..8fcf40ff --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalPageInternal.S @@ -0,0 +1,5 @@ +.text + +hal_flush_tlb: + tlbi + ret diff --git a/dev/Kernel/HALKit/ARM64/HalScheduler.cxx b/dev/Kernel/HALKit/ARM64/HalScheduler.cxx new file mode 100644 index 00000000..51cbfe4b --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalScheduler.cxx @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include + +using namespace Kernel; + +Void PROCESS_HEADER_BLOCK::SetEntrypoint(UIntPtr& imageStart) noexcept +{ + if (imageStart == 0) + this->Crash(); + + this->StackFrame->BP = imageStart; + this->StackFrame->SP = this->StackFrame->BP; +} + +namespace Kernel +{ + bool rt_check_stack(HAL::StackFramePtr stackPtr) + { + if (!stackPtr) + return false; + if (stackPtr->BP == 0 || stackPtr->SP == 0) + return false; + + return true; + } +} // namespace Kernel diff --git a/dev/Kernel/HALKit/ARM64/HalTimer.cxx b/dev/Kernel/HALKit/ARM64/HalTimer.cxx new file mode 100644 index 00000000..ef907e4f --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/HalTimer.cxx @@ -0,0 +1,16 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: HalTimer.cxx + Purpose: HAL timer + + Revision History: + + 07/07/24: Added file (amlel) + +------------------------------------------- */ + +#include + +struct TimerInfoStruct; diff --git a/dev/Kernel/HALKit/ARM64/MBCI/.keepme b/dev/Kernel/HALKit/ARM64/MBCI/.keepme new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/Processor.hxx b/dev/Kernel/HALKit/ARM64/Processor.hxx new file mode 100644 index 00000000..16e9ec8c --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/Processor.hxx @@ -0,0 +1,56 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#pragma once + +#include +#include +#include +#include + +#ifdef kCPUBackendName +#undef kCPUBackendName +#endif // ifdef kCPUBackendName + +#define kPTESize 512 /* 64-bit PT */ + +#define kCPUBackendName "ARMv8" + +#ifdef __ZETA_MACHINE__ +#define cHeapStartOffset (0x10000000) +#else +#error !!! please provide that macro. !!! +#endif + +namespace Kernel::HAL +{ + struct PACKED Register64 final + { + UShort Limit; + UIntPtr Base; + }; + + typedef UIntPtr Reg; + typedef Register64 Register; + + /// @note let's keep the same name as AMD64 HAL. + struct PACKED StackFrame final + { + Reg IntNum, Exception; + Reg A0, A2, BP, SP, A3, A4, A5, A6; + Reg R8, R9, R10, R11, R12, R13, R14, R15; + Reg Gs, Fs; + }; + + typedef StackFrame* StackFramePtr; +} // namespace Kernel::HAL + +inline Kernel::VoidPtr kKernelVirtualStart = (Kernel::VoidPtr)cHeapStartOffset; +inline Kernel::UIntPtr kKernelVirtualSize = 0UL; + +inline Kernel::VoidPtr kKernelPhysicalStart = nullptr; + +#include diff --git a/dev/Kernel/HALKit/ARM64/ReadMe.md b/dev/Kernel/HALKit/ARM64/ReadMe.md new file mode 100644 index 00000000..c51229f2 --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/ReadMe.md @@ -0,0 +1,3 @@ +# ARM64 Hardware Abstraction Layer + +- Supported Firmware: CoreBoot/EDK/OpenMobileBoot diff --git a/dev/Kernel/HALKit/ARM64/Storage/.gitkeep b/dev/Kernel/HALKit/ARM64/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cxx b/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cxx new file mode 100644 index 00000000..cc7802cb --- /dev/null +++ b/dev/Kernel/HALKit/ARM64/Storage/HalFlash.cxx @@ -0,0 +1,66 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +/// @file Flash.cxx +/// @brief Flash memory builtin. + +#ifdef __FLASH_MEM__ + +#define cMaxFlash (4U) + +namespace Kernel +{ + /// /:\\BRIDGE\\FLSH\\1 + constexpr auto cFlashBridgeMagic = "FLSH"; + constexpr auto cFlashBridgeRevision = 1; + + STATIC const Boolean kFlashEnabled = No; + STATIC SizeT kFlashSize[cMaxFlash] = {}; + STATIC SizeT kFlashSectorSz[cMaxFlash] = {}; + + /// @brief Enable flash memory builtin. + STATIC Void drv_enable_flash(Int32 slot); + + /// @brief Disable flash memory builtin. + STATIC Void drv_disable_flash(Int32 slot); + + /// @brief get sector count. + /// @return drive sector count. + SizeT drv_std_get_sector_count(Int32 slot) + { + if (slot > cMaxFlash) + return 0; + + return kFlashSectorSz[slot]; + } + + /// @brief get device size. + /// @return drive size + SizeT drv_std_get_drv_size(Int32 slot) + { + if (slot > cMaxFlash) + return 0; + + return kFlashSize[slot]; + } + + /// @brief Enable flash memory at slot. + STATIC Void drv_enable_flash(Int32 arg) + { + kcout << "newoskrnl: enabled hardware.\r"; + } + + /// @brief Disable flash memory at slot. + STATIC Void drv_disable_flash(Int32 arg) + { + kcout << "newoskrnl: disabled hardware.\r"; + } +} // namespace Kernel + +#endif // if __FLASH_MEM__ (Bridge) diff --git a/dev/Kernel/HALKit/AXP/CR.s b/dev/Kernel/HALKit/AXP/CR.s new file mode 100644 index 00000000..4d68257d --- /dev/null +++ b/dev/Kernel/HALKit/AXP/CR.s @@ -0,0 +1,11 @@ +.globl read_lr1 +.globl read_lr0 + +.section .text + read_lr0: + movq %r30, %cr3 + ret + + hal_read_cr0: + movq %r30, %cr0 + ret \ No newline at end of file diff --git a/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp new file mode 100644 index 00000000..9d20a0f3 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +/// @brief Internal call for syscall, to work with C++. +/// @param stack +/// @return nothing. +EXTERN_C void rt_syscall_handle(Kernel::HAL::StackFrame* stack) +{ + if (stack->Rcx <= (kSyscalls.Count() - 1)) + { + Kernel::kcout << "newoskrnl: syscall: enter.\r"; + + if (kSyscalls[stack->Rcx].Leak().Leak().fHooked) + (kSyscalls[stack->Rcx].Leak().Leak().fProc)(stack); + + Kernel::kcout << "newoskrnl: syscall: exit.\r"; + } +} diff --git a/dev/Kernel/HALKit/AXP/HAL.s b/dev/Kernel/HALKit/AXP/HAL.s new file mode 100644 index 00000000..0178527f --- /dev/null +++ b/dev/Kernel/HALKit/AXP/HAL.s @@ -0,0 +1,13 @@ +.globl rt_wait_400ns + +.section .text +rt_wait_400ns: + jmp .L +.L: + jmp .L2 + wtint ;; wait for interrupt +.L2: + + ret + + diff --git a/dev/Kernel/HALKit/AXP/Processor.hpp b/dev/Kernel/HALKit/AXP/Processor.hpp new file mode 100644 index 00000000..25a434a0 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/Processor.hpp @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#pragma once \ No newline at end of file diff --git a/dev/Kernel/HALKit/AXP/README b/dev/Kernel/HALKit/AXP/README new file mode 100644 index 00000000..91e7b134 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/README @@ -0,0 +1 @@ +This is for DEC Alpha. diff --git a/dev/Kernel/HALKit/AXP/README.TXT b/dev/Kernel/HALKit/AXP/README.TXT new file mode 100644 index 00000000..d4ef257d --- /dev/null +++ b/dev/Kernel/HALKit/AXP/README.TXT @@ -0,0 +1 @@ +An toy HAL to test the kernel portability. diff --git a/dev/Kernel/HALKit/AXP/SYSCALL.s b/dev/Kernel/HALKit/AXP/SYSCALL.s new file mode 100644 index 00000000..19cab808 --- /dev/null +++ b/dev/Kernel/HALKit/AXP/SYSCALL.s @@ -0,0 +1,10 @@ +.section .text +system_handle_user_call: + .cfi_startproc + + push %r0 + jmp %r1 + mov %r30, %r2 + + .cfi_endproc + retsys \ No newline at end of file diff --git a/dev/Kernel/HALKit/AXP/VM.s b/dev/Kernel/HALKit/AXP/VM.s new file mode 100644 index 00000000..7024086b --- /dev/null +++ b/dev/Kernel/HALKit/AXP/VM.s @@ -0,0 +1,5 @@ +.global hal_flush_tlb + +.section .text +hal_flush_tlb: + swppal \ No newline at end of file diff --git a/dev/Kernel/HALKit/POWER/.gitkeep b/dev/Kernel/HALKit/POWER/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/APM/.gitkeep b/dev/Kernel/HALKit/POWER/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/HalContextSwitchPowerPC.s b/dev/Kernel/HALKit/POWER/HalContextSwitchPowerPC.s new file mode 100644 index 00000000..fc47ba49 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalContextSwitchPowerPC.s @@ -0,0 +1,28 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +.align 4 +.type name, @function +.text +.globl rt_do_context_switch + +/* r3 (3) = assigner stack, r4 (4) = assignee stack */ +rt_do_context_switch: + lwz 0(%4), 0(%3) + lwz 4(%4), 4(%3) + lwz 8(%4), 8(%3) + lwz 12(%4), 12(%3) + lwz 14(%4), 14(%3) + lwz 18(%4), 18(%3) + lwz 22(%4), 22(%3) + lwz 24(%4), 24(%3) + lwz 28(%4), 28(%3) + lwz 32(%4), 32(%3) + lwz 34(%4), 34(%3) + lwz 38(%4), 38(%3) + + /* we are done here, the assignee should start executing code now. */ + blr diff --git a/dev/Kernel/HALKit/POWER/HalHardware.cxx b/dev/Kernel/HALKit/POWER/HalHardware.cxx new file mode 100644 index 00000000..9fb841c8 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalHardware.cxx @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +namespace Kernel +{ + namespace HAL + { + UIntPtr hal_alloc_page(bool rw, bool user) + { + return 0; + } + } // namespace HAL +} // namespace Kernel diff --git a/dev/Kernel/HALKit/POWER/HalHart.cxx b/dev/Kernel/HALKit/POWER/HalHart.cxx new file mode 100644 index 00000000..8327b8e0 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalHart.cxx @@ -0,0 +1,25 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; + +/// @brief wakes up thread. +/// wakes up thread from hang. +void mp_wakeup_thread(HAL::StackFramePtr stack) +{ + NEWOS_UNUSED(stack); +} + +/// @brief makes thread sleep. +/// hooks and hangs thread to prevent code from executing. +void mp_hang_thread(HAL::StackFramePtr stack) +{ + NEWOS_UNUSED(stack); +} diff --git a/dev/Kernel/HALKit/POWER/HalSerialPort.cxx b/dev/Kernel/HALKit/POWER/HalSerialPort.cxx new file mode 100644 index 00000000..c8d49c0c --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalSerialPort.cxx @@ -0,0 +1,27 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +using namespace Kernel; + +/// @brief Writes to COM1. +/// @param bytes +void ke_io_write(const Char* bytes) +{ + if (!bytes) + return; + + SizeT index = 0; + SizeT len = rt_string_len(bytes, 255); + + while (index < len) + { + // TODO + ++index; + } +} diff --git a/dev/Kernel/HALKit/POWER/HalStartSequence.s b/dev/Kernel/HALKit/POWER/HalStartSequence.s new file mode 100644 index 00000000..68110f8d --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalStartSequence.s @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +.globl __ImageStart +.extern hal_init_platform +.align 4 +.text + +__ImageStart: + bl hal_init_platform + blr diff --git a/dev/Kernel/HALKit/POWER/HalThread.cxx b/dev/Kernel/HALKit/POWER/HalThread.cxx new file mode 100644 index 00000000..3e2f1703 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalThread.cxx @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include diff --git a/dev/Kernel/HALKit/POWER/HalVirtualMemory.cxx b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cxx new file mode 100644 index 00000000..589c2cda --- /dev/null +++ b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cxx @@ -0,0 +1,51 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include + +#include +#include + +/// @note refer to the SoC documentation. + +using namespace Kernel; + +Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7) +{ + mtspr(MAS0, mas0); + mtspr(MAS1, mas1); + mtspr(MAS2, mas2); + mtspr(MAS3, mas3); + mtspr(MAS7, mas7); + + hal_flush_tlb(); +} + +Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, UInt8 esel, UInt8 tsize, UInt8 iprot) +{ + if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1)) + { + // this mmu-version does not allow odd tsize values + return false; + } + + UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0); + UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize); + UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge); + UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms); + UInt32 mas7 = FSL_BOOKE_MAS7(rpn); + + hal_write_tlb(mas0, mas1, mas2, mas3, mas7); + + return true; +} + +/// @brief Flush TLB +EXTERN_C void hal_flush_tlb() +{ + asm volatile("isync;tlbwe;msync;isync"); +} diff --git a/dev/Kernel/HALKit/POWER/Hart.hxx b/dev/Kernel/HALKit/POWER/Hart.hxx new file mode 100644 index 00000000..02020320 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/Hart.hxx @@ -0,0 +1,36 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: Hart.hxx + Purpose: POWER hardware threads. + + Revision History: + + 14/04/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +struct HAL_HARDWARE_THREAD; + +/// @brief hardware thread indentification type. +typedef Kernel::Int32 PPCHartType; + +/// @brief Hardware thread information structure. +typedef struct HAL_HARDWARE_THREAD +{ + Kernel::UIntPtr fStartAddress; + Kernel::UInt8 fPrivleged : 1; + Kernel::UInt32 fPageFlags; + PPCHartType fIdentNumber; +} HAL_HARDWARE_THREAD; + +/// @brief Set PC to specific hart. +/// @param hart the hart +/// @param epc the pc. +/// @return +EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc); diff --git a/dev/Kernel/HALKit/POWER/MBCI/.gitkeep b/dev/Kernel/HALKit/POWER/MBCI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cxx b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cxx new file mode 100644 index 00000000..3e2f1703 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cxx @@ -0,0 +1,8 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include +#include diff --git a/dev/Kernel/HALKit/POWER/Processor.hxx b/dev/Kernel/HALKit/POWER/Processor.hxx new file mode 100644 index 00000000..4b03af4b --- /dev/null +++ b/dev/Kernel/HALKit/POWER/Processor.hxx @@ -0,0 +1,56 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + Purpose: POWER processor header. + +------------------------------------------- */ + +#pragma once + +#include +#include + +#define NoOp() asm volatile("mr 0, 0") +#define kHalPPCAlignment __attribute__((aligned(4))) + +namespace Kernel::HAL +{ + typedef UIntPtr Reg; + + /// @brief Stack frame (as retrieved from assembly.) + struct PACKED StackFrame final + { + Reg IntNum, Exception; + Reg A0, A2, BP, SP, A3, A4, A5, A6; + Reg R8, R9, R10, R11, R12, R13, R14, R15; + Reg Gs, Fs; + }; + + typedef StackFrame* StackFramePtr; + + inline void rt_halt() + { + while (true) + { + NoOp(); // no oop. + } + } + + inline void rt_cli() + { + NoOp(); // no oop + } +} // namespace Kernel::HAL + +EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp); +EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp); + +/// @brief Set TLB. +Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn, Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts, Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot); + +/// @brief Write TLB. +Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2, Kernel::UInt32 mas3, Kernel::UInt32 mas7); + +/// @brief Flush TLB. +EXTERN_C Kernel::Void hal_flush_tlb(); diff --git a/dev/Kernel/HALKit/POWER/ReadMe.md b/dev/Kernel/HALKit/POWER/ReadMe.md new file mode 100644 index 00000000..a9751581 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/ReadMe.md @@ -0,0 +1,4 @@ +POWER Hardware Abstraction Layer + +- Supported CPU: POWER +- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/Kernel/HALKit/POWER/ppc-cpu.h b/dev/Kernel/HALKit/POWER/ppc-cpu.h new file mode 100644 index 00000000..46979e5f --- /dev/null +++ b/dev/Kernel/HALKit/POWER/ppc-cpu.h @@ -0,0 +1,1424 @@ +#ifndef __ASM_PPC_PROCESSOR_H +#define __ASM_PPC_PROCESSOR_H + +/// ! @note The Zeta cpu is based on the e500 with 64-bit extensions, much like the 970. + +/* + * Default implementation of macro that returns current + * instruction pointer ("program counter"). + */ +#define current_text_addr() ({ __label__ _l; _l: &&_l; }) + +#define AAA_HACK_DISABLE +#ifdef AAA_HACK_DISABLE +/* warning this is just to make the compiler shut up.. It does not + match the definition in ptrace.h. So dont use this code. */ +struct pt_regs +{ + unsigned long nip; +}; + +#else +#include +#include +#endif + +/* Machine State Register (MSR) Fields */ + +#ifdef CONFIG_PPC64BRIDGE +#define MSR_SF (1 << 63) +#define MSR_ISF (1 << 61) +#endif /* CONFIG_PPC64BRIDGE */ +#define MSR_UCLE (1 << 26) /* User-mode cache lock enable (e500) */ +#define MSR_VEC (1 << 25) /* Enable AltiVec(74xx) */ +#define MSR_SPE (1 << 25) /* Enable SPE(e500) */ +#define MSR_POW (1 << 18) /* Enable Power Management */ +#define MSR_WE (1 << 18) /* Wait State Enable */ +#define MSR_TGPR (1 << 17) /* TLB Update registers in use */ +#define MSR_CE (1 << 17) /* Critical Interrupt Enable */ +#define MSR_ILE (1 << 16) /* Interrupt Little Endian */ +#define MSR_EE (1 << 15) /* External Interrupt Enable */ +#define MSR_PR (1 << 14) /* Problem State / Privilege Level */ +#define MSR_FP (1 << 13) /* Floating Point enable */ +#define MSR_ME (1 << 12) /* Machine Check Enable */ +#define MSR_FE0 (1 << 11) /* Floating Exception mode 0 */ +#define MSR_SE (1 << 10) /* Single Step */ +#define MSR_DWE (1 << 10) /* Debug Wait Enable (4xx) */ +#define MSR_UBLE (1 << 10) /* BTB lock enable (e500) */ +#define MSR_BE (1 << 9) /* Branch Trace */ +#define MSR_DE (1 << 9) /* Debug Exception Enable */ +#define MSR_FE1 (1 << 8) /* Floating Exception mode 1 */ +#define MSR_IP (1 << 6) /* Exception prefix 0x000/0xFFF */ +#define MSR_IR (1 << 5) /* Instruction Relocate */ +#define MSR_IS (1 << 5) /* Book E Instruction space */ +#define MSR_DR (1 << 4) /* Data Relocate */ +#define MSR_DS (1 << 4) /* Book E Data space */ +#define MSR_PE (1 << 3) /* Protection Enable */ +#define MSR_PX (1 << 2) /* Protection Exclusive Mode */ +#define MSR_PMM (1 << 2) /* Performance monitor mark bit (e500) */ +#define MSR_RI (1 << 1) /* Recoverable Exception */ +#define MSR_LE (1 << 0) /* Little Endian */ + +#ifdef CONFIG_APUS_FAST_EXCEPT +#define MSR_ MSR_ME | MSR_IP | MSR_RI +#else +#define MSR_ MSR_ME | MSR_RI +#endif +#ifndef CONFIG_E500 +#define MSR_KERNEL MSR_ | MSR_IR | MSR_DR +#else +#define MSR_KERNEL MSR_ME +#endif + +/* Floating Point Status and Control Register (FPSCR) Fields */ + +#define FPSCR_FX 0x80000000 /* FPU exception summary */ +#define FPSCR_FEX 0x40000000 /* FPU enabled exception summary */ +#define FPSCR_VX 0x20000000 /* Invalid operation summary */ +#define FPSCR_OX 0x10000000 /* Overflow exception summary */ +#define FPSCR_UX 0x08000000 /* Underflow exception summary */ +#define FPSCR_ZX 0x04000000 /* Zero-devide exception summary */ +#define FPSCR_XX 0x02000000 /* Inexact exception summary */ +#define FPSCR_VXSNAN 0x01000000 /* Invalid op for SNaN */ +#define FPSCR_VXISI 0x00800000 /* Invalid op for Inv - Inv */ +#define FPSCR_VXIDI 0x00400000 /* Invalid op for Inv / Inv */ +#define FPSCR_VXZDZ 0x00200000 /* Invalid op for Zero / Zero */ +#define FPSCR_VXIMZ 0x00100000 /* Invalid op for Inv * Zero */ +#define FPSCR_VXVC 0x00080000 /* Invalid op for Compare */ +#define FPSCR_FR 0x00040000 /* Fraction rounded */ +#define FPSCR_FI 0x00020000 /* Fraction inexact */ +#define FPSCR_FPRF 0x0001f000 /* FPU Result Flags */ +#define FPSCR_FPCC 0x0000f000 /* FPU Condition Codes */ +#define FPSCR_VXSOFT 0x00000400 /* Invalid op for software request */ +#define FPSCR_VXSQRT 0x00000200 /* Invalid op for square root */ +#define FPSCR_VXCVI 0x00000100 /* Invalid op for integer convert */ +#define FPSCR_VE 0x00000080 /* Invalid op exception enable */ +#define FPSCR_OE 0x00000040 /* IEEE overflow exception enable */ +#define FPSCR_UE 0x00000020 /* IEEE underflow exception enable */ +#define FPSCR_ZE 0x00000010 /* IEEE zero divide exception enable */ +#define FPSCR_XE 0x00000008 /* FP inexact exception enable */ +#define FPSCR_NI 0x00000004 /* FPU non IEEE-Mode */ +#define FPSCR_RN 0x00000003 /* FPU rounding control */ + +/* Special Purpose Registers (SPRNs)*/ + +/* PPC440 Architecture is BOOK-E */ +#ifdef CONFIG_440 +#define CONFIG_BOOKE +#endif + +#define SPRN_CCR0 0x3B3 /* Core Configuration Register 0 */ +#ifdef CONFIG_BOOKE +#define SPRN_CCR1 0x378 /* Core Configuration Register for 440 only */ +#endif +#define SPRN_CDBCR 0x3D7 /* Cache Debug Control Register */ +#define SPRN_CTR 0x009 /* Count Register */ +#define SPRN_DABR 0x3F5 /* Data Address Breakpoint Register */ +#ifndef CONFIG_BOOKE +#define SPRN_DAC1 0x3F6 /* Data Address Compare 1 */ +#define SPRN_DAC2 0x3F7 /* Data Address Compare 2 */ +#else +#define SPRN_DAC1 0x13C /* Book E Data Address Compare 1 */ +#define SPRN_DAC2 0x13D /* Book E Data Address Compare 2 */ +#endif /* CONFIG_BOOKE */ +#define SPRN_DAR 0x013 /* Data Address Register */ +#define SPRN_DBAT0L 0x219 /* Data BAT 0 Lower Register */ +#define SPRN_DBAT0U 0x218 /* Data BAT 0 Upper Register */ +#define SPRN_DBAT1L 0x21B /* Data BAT 1 Lower Register */ +#define SPRN_DBAT1U 0x21A /* Data BAT 1 Upper Register */ +#define SPRN_DBAT2L 0x21D /* Data BAT 2 Lower Register */ +#define SPRN_DBAT2U 0x21C /* Data BAT 2 Upper Register */ +#define SPRN_DBAT3L 0x21F /* Data BAT 3 Lower Register */ +#define SPRN_DBAT3U 0x21E /* Data BAT 3 Upper Register */ +#define SPRN_DBAT4L 0x239 /* Data BAT 4 Lower Register */ +#define SPRN_DBAT4U 0x238 /* Data BAT 4 Upper Register */ +#define SPRN_DBAT5L 0x23B /* Data BAT 5 Lower Register */ +#define SPRN_DBAT5U 0x23A /* Data BAT 5 Upper Register */ +#define SPRN_DBAT6L 0x23D /* Data BAT 6 Lower Register */ +#define SPRN_DBAT6U 0x23C /* Data BAT 6 Upper Register */ +#define SPRN_DBAT7L 0x23F /* Data BAT 7 Lower Register */ +#define SPRN_DBAT7U 0x23E /* Data BAT 7 Lower Register */ +#define SPRN_DBCR 0x3F2 /* Debug Control Regsiter */ +#define DBCR_EDM 0x80000000 +#define DBCR_IDM 0x40000000 +#define DBCR_RST(x) (((x) & 0x3) << 28) +#define DBCR_RST_NONE 0 +#define DBCR_RST_CORE 1 +#define DBCR_RST_CHIP 2 +#define DBCR_RST_SYSTEM 3 +#define DBCR_IC 0x08000000 /* Instruction Completion Debug Evnt */ +#define DBCR_BT 0x04000000 /* Branch Taken Debug Event */ +#define DBCR_EDE 0x02000000 /* Exception Debug Event */ +#define DBCR_TDE 0x01000000 /* TRAP Debug Event */ +#define DBCR_FER 0x00F80000 /* First Events Remaining Mask */ +#define DBCR_FT 0x00040000 /* Freeze Timers on Debug Event */ +#define DBCR_IA1 0x00020000 /* Instr. Addr. Compare 1 Enable */ +#define DBCR_IA2 0x00010000 /* Instr. Addr. Compare 2 Enable */ +#define DBCR_D1R 0x00008000 /* Data Addr. Compare 1 Read Enable */ +#define DBCR_D1W 0x00004000 /* Data Addr. Compare 1 Write Enable */ +#define DBCR_D1S(x) (((x) & 0x3) << 12) /* Data Adrr. Compare 1 Size */ +#define DAC_BYTE 0 +#define DAC_HALF 1 +#define DAC_WORD 2 +#define DAC_QUAD 3 +#define DBCR_D2R 0x00000800 /* Data Addr. Compare 2 Read Enable */ +#define DBCR_D2W 0x00000400 /* Data Addr. Compare 2 Write Enable */ +#define DBCR_D2S(x) (((x) & 0x3) << 8) /* Data Addr. Compare 2 Size */ +#define DBCR_SBT 0x00000040 /* Second Branch Taken Debug Event */ +#define DBCR_SED 0x00000020 /* Second Exception Debug Event */ +#define DBCR_STD 0x00000010 /* Second Trap Debug Event */ +#define DBCR_SIA 0x00000008 /* Second IAC Enable */ +#define DBCR_SDA 0x00000004 /* Second DAC Enable */ +#define DBCR_JOI 0x00000002 /* JTAG Serial Outbound Int. Enable */ +#define DBCR_JII 0x00000001 /* JTAG Serial Inbound Int. Enable */ +#ifndef CONFIG_BOOKE +#define SPRN_DBCR0 0x3F2 /* Debug Control Register 0 */ +#else +#define SPRN_DBCR0 0x134 /* Book E Debug Control Register 0 */ +#endif /* CONFIG_BOOKE */ +#ifndef CONFIG_BOOKE +#define SPRN_DBCR1 0x3BD /* Debug Control Register 1 */ +#define SPRN_DBSR 0x3F0 /* Debug Status Register */ +#else +#define SPRN_DBCR1 0x135 /* Book E Debug Control Register 1 */ +#ifdef CONFIG_BOOKE +#define SPRN_DBDR 0x3f3 /* Debug Data Register */ +#endif +#define SPRN_DBSR 0x130 /* Book E Debug Status Register */ +#define DBSR_IC 0x08000000 /* Book E Instruction Completion */ +#define DBSR_TIE 0x01000000 /* Book E Trap Instruction Event */ +#endif /* CONFIG_BOOKE */ +#define SPRN_DCCR 0x3FA /* Data Cache Cacheability Register */ +#define DCCR_NOCACHE 0 /* Noncacheable */ +#define DCCR_CACHE 1 /* Cacheable */ +#ifndef CONFIG_BOOKE +#define SPRN_DCDBTRL 0x39c /* Data Cache Debug Tag Register Low */ +#define SPRN_DCDBTRH 0x39d /* Data Cache Debug Tag Register High */ +#endif +#define SPRN_DCMP 0x3D1 /* Data TLB Compare Register */ +#define SPRN_DCWR 0x3BA /* Data Cache Write-thru Register */ +#define DCWR_COPY 0 /* Copy-back */ +#define DCWR_WRITE 1 /* Write-through */ +#ifndef CONFIG_BOOKE +#define SPRN_DEAR 0x3D5 /* Data Error Address Register */ +#else +#define SPRN_DEAR 0x03D /* Book E Data Error Address Register */ +#endif /* CONFIG_BOOKE */ +#define SPRN_DEC 0x016 /* Decrement Register */ +#define SPRN_DMISS 0x3D0 /* Data TLB Miss Register */ +#ifdef CONFIG_BOOKE +#define SPRN_DNV0 0x390 /* Data Cache Normal Victim 0 */ +#define SPRN_DNV1 0x391 /* Data Cache Normal Victim 1 */ +#define SPRN_DNV2 0x392 /* Data Cache Normal Victim 2 */ +#define SPRN_DNV3 0x393 /* Data Cache Normal Victim 3 */ +#endif +#define SPRN_DSISR 0x012 /* Data Storage Interrupt Status Register */ +#ifdef CONFIG_BOOKE +#define SPRN_DTV0 0x394 /* Data Cache Transient Victim 0 */ +#define SPRN_DTV1 0x395 /* Data Cache Transient Victim 1 */ +#define SPRN_DTV2 0x396 /* Data Cache Transient Victim 2 */ +#define SPRN_DTV3 0x397 /* Data Cache Transient Victim 3 */ +#define SPRN_DVLIM 0x398 /* Data Cache Victim Limit */ +#endif +#define SPRN_EAR 0x11A /* External Address Register */ +#ifndef CONFIG_BOOKE +#define SPRN_ESR 0x3D4 /* Exception Syndrome Register */ +#else +#define SPRN_ESR 0x03E /* Book E Exception Syndrome Register */ +#endif /* CONFIG_BOOKE */ +#define ESR_IMCP 0x80000000 /* Instr. Machine Check - Protection */ +#define ESR_IMCN 0x40000000 /* Instr. Machine Check - Non-config */ +#define ESR_IMCB 0x20000000 /* Instr. Machine Check - Bus error */ +#define ESR_IMCT 0x10000000 /* Instr. Machine Check - Timeout */ +#define ESR_PIL 0x08000000 /* Program Exception - Illegal */ +#define ESR_PPR 0x04000000 /* Program Exception - Priveleged */ +#define ESR_PTR 0x02000000 /* Program Exception - Trap */ +#define ESR_DST 0x00800000 /* Storage Exception - Data miss */ +#define ESR_DIZ 0x00400000 /* Storage Exception - Zone fault */ +#define SPRN_EVPR 0x3D6 /* Exception Vector Prefix Register */ +#define SPRN_HASH1 0x3D2 /* Primary Hash Address Register */ +#define SPRN_HASH2 0x3D3 /* Secondary Hash Address Resgister */ +#define SPRN_HID0 0x3F0 /* Hardware Implementation Register 0 */ + +#define HID0_ICE_SHIFT 15 +#define HID0_DCE_SHIFT 14 +#define HID0_DLOCK_SHIFT 12 + +#define HID0_EMCP (1 << 31) /* Enable Machine Check pin */ +#define HID0_EBA (1 << 29) /* Enable Bus Address Parity */ +#define HID0_EBD (1 << 28) /* Enable Bus Data Parity */ +#define HID0_SBCLK (1 << 27) +#define HID0_EICE (1 << 26) +#define HID0_ECLK (1 << 25) +#define HID0_PAR (1 << 24) +#define HID0_DOZE (1 << 23) +#define HID0_NAP (1 << 22) +#define HID0_SLEEP (1 << 21) +#define HID0_DPM (1 << 20) +#define HID0_ICE (1 << HID0_ICE_SHIFT) /* Instruction Cache Enable */ +#define HID0_DCE (1 << HID0_DCE_SHIFT) /* Data Cache Enable */ +#define HID0_TBEN (1 << 14) /* Time Base Enable */ +#define HID0_ILOCK (1 << 13) /* Instruction Cache Lock */ +#define HID0_DLOCK (1 << HID0_DLOCK_SHIFT) /* Data Cache Lock */ +#define HID0_ICFI (1 << 11) /* Instr. Cache Flash Invalidate */ +#define HID0_DCFI (1 << 10) /* Data Cache Flash Invalidate */ +#define HID0_DCI HID0_DCFI +#define HID0_SPD (1 << 9) /* Speculative disable */ +#define HID0_ENMAS7 (1 << 7) /* Enable MAS7 Update for 36-bit phys */ +#define HID0_SGE (1 << 7) /* Store Gathering Enable */ +#define HID0_SIED HID_SGE /* Serial Instr. Execution [Disable] */ +#define HID0_DCFA (1 << 6) /* Data Cache Flush Assist */ +#define HID0_BTIC (1 << 5) /* Branch Target Instruction Cache Enable */ +#define HID0_ABE (1 << 3) /* Address Broadcast Enable */ +#define HID0_BHTE (1 << 2) /* Branch History Table Enable */ +#define HID0_BTCD (1 << 1) /* Branch target cache disable */ +#define SPRN_HID1 0x3F1 /* Hardware Implementation Register 1 */ +#define HID1_RFXE (1 << 17) /* Read Fault Exception Enable */ +#define HID1_ASTME (1 << 13) /* Address bus streaming mode */ +#define HID1_ABE (1 << 12) /* Address broadcast enable */ +#define HID1_MBDD (1 << 6) /* optimized sync instruction */ +#define SPRN_IABR 0x3F2 /* Instruction Address Breakpoint Register */ +#ifndef CONFIG_BOOKE +#define SPRN_IAC1 0x3F4 /* Instruction Address Compare 1 */ +#define SPRN_IAC2 0x3F5 /* Instruction Address Compare 2 */ +#else +#define SPRN_IAC1 0x138 /* Book E Instruction Address Compare 1 */ +#define SPRN_IAC2 0x139 /* Book E Instruction Address Compare 2 */ +#endif /* CONFIG_BOOKE */ +#define SPRN_IBAT0L 0x211 /* Instruction BAT 0 Lower Register */ +#define SPRN_IBAT0U 0x210 /* Instruction BAT 0 Upper Register */ +#define SPRN_IBAT1L 0x213 /* Instruction BAT 1 Lower Register */ +#define SPRN_IBAT1U 0x212 /* Instruction BAT 1 Upper Register */ +#define SPRN_IBAT2L 0x215 /* Instruction BAT 2 Lower Register */ +#define SPRN_IBAT2U 0x214 /* Instruction BAT 2 Upper Register */ +#define SPRN_IBAT3L 0x217 /* Instruction BAT 3 Lower Register */ +#define SPRN_IBAT3U 0x216 /* Instruction BAT 3 Upper Register */ +#define SPRN_IBAT4L 0x231 /* Instruction BAT 4 Lower Register */ +#define SPRN_IBAT4U 0x230 /* Instruction BAT 4 Upper Register */ +#define SPRN_IBAT5L 0x233 /* Instruction BAT 5 Lower Register */ +#define SPRN_IBAT5U 0x232 /* Instruction BAT 5 Upper Register */ +#define SPRN_IBAT6L 0x235 /* Instruction BAT 6 Lower Register */ +#define SPRN_IBAT6U 0x234 /* Instruction BAT 6 Upper Register */ +#define SPRN_IBAT7L 0x237 /* Instruction BAT 7 Lower Register */ +#define SPRN_IBAT7U 0x236 /* Instruction BAT 7 Upper Register */ +#define SPRN_ICCR 0x3FB /* Instruction Cache Cacheability Register */ +#define ICCR_NOCACHE 0 /* Noncacheable */ +#define ICCR_CACHE 1 /* Cacheable */ +#define SPRN_ICDBDR 0x3D3 /* Instruction Cache Debug Data Register */ +#ifdef CONFIG_BOOKE +#define SPRN_ICDBTRL 0x39e /* instruction cache debug tag register low */ +#define SPRN_ICDBTRH 0x39f /* instruction cache debug tag register high */ +#endif +#define SPRN_ICMP 0x3D5 /* Instruction TLB Compare Register */ +#define SPRN_ICTC 0x3FB /* Instruction Cache Throttling Control Reg */ +#define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ +#define SPRN_IMMR 0x27E /* Internal Memory Map Register */ +#ifdef CONFIG_BOOKE +#define SPRN_INV0 0x370 /* Instruction Cache Normal Victim 0 */ +#define SPRN_INV1 0x371 /* Instruction Cache Normal Victim 1 */ +#define SPRN_INV2 0x372 /* Instruction Cache Normal Victim 2 */ +#define SPRN_INV3 0x373 /* Instruction Cache Normal Victim 3 */ +#define SPRN_ITV0 0x374 /* Instruction Cache Transient Victim 0 */ +#define SPRN_ITV1 0x375 /* Instruction Cache Transient Victim 1 */ +#define SPRN_ITV2 0x376 /* Instruction Cache Transient Victim 2 */ +#define SPRN_ITV3 0x377 /* Instruction Cache Transient Victim 3 */ +#define SPRN_IVLIM 0x399 /* Instruction Cache Victim Limit */ +#endif +#define SPRN_LDSTCR 0x3F8 /* Load/Store Control Register */ +#define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ +#define SPRN_LR 0x008 /* Link Register */ +#define SPRN_MBAR 0x137 /* System memory base address */ +#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ +#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ +#ifdef CONFIG_BOOKE +#define SPRN_MMUCR 0x3b2 /* MMU Control Register */ +#endif +#define SPRN_PBL1 0x3FC /* Protection Bound Lower 1 */ +#define SPRN_PBL2 0x3FE /* Protection Bound Lower 2 */ +#define SPRN_PBU1 0x3FD /* Protection Bound Upper 1 */ +#define SPRN_PBU2 0x3FF /* Protection Bound Upper 2 */ +#ifndef CONFIG_BOOKE +#define SPRN_PID 0x3B1 /* Process ID */ +#define SPRN_PIR 0x3FF /* Processor Identification Register */ +#else +#define SPRN_PID 0x030 /* Book E Process ID */ +#define SPRN_PIR 0x11E /* Book E Processor Identification Register */ +#endif /* CONFIG_BOOKE */ +#define SPRN_PIT 0x3DB /* Programmable Interval Timer */ +#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */ +#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */ +#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */ +#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */ +#define SPRN_PVR 0x11F /* Processor Version Register */ +#define SPRN_RPA 0x3D6 /* Required Physical Address Register */ +#ifdef CONFIG_BOOKE +#define SPRN_RSTCFG 0x39b /* Reset Configuration */ +#endif +#define SPRN_SDA 0x3BF /* Sampled Data Address Register */ +#define SPRN_SDR1 0x019 /* MMU Hash Base Register */ +#define SPRN_SGR 0x3B9 /* Storage Guarded Register */ +#define SGR_NORMAL 0 +#define SGR_GUARDED 1 +#define SPRN_SIA 0x3BB /* Sampled Instruction Address Register */ +#define SPRN_SPRG0 0x110 /* Special Purpose Register General 0 */ +#define SPRN_SPRG1 0x111 /* Special Purpose Register General 1 */ +#define SPRN_SPRG2 0x112 /* Special Purpose Register General 2 */ +#define SPRN_SPRG3 0x113 /* Special Purpose Register General 3 */ +#define SPRN_SPRG4 0x114 /* Special Purpose Register General 4 */ +#define SPRN_SPRG5 0x115 /* Special Purpose Register General 5 */ +#define SPRN_SPRG6 0x116 /* Special Purpose Register General 6 */ +#define SPRN_SPRG7 0x117 /* Special Purpose Register General 7 */ +#define SPRN_SRR0 0x01A /* Save/Restore Register 0 */ +#define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ +#define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ +#define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */ + +#ifdef CONFIG_BOOKE +#define SPRN_SVR 0x3FF /* System Version Register */ +#else +#define SPRN_SVR 0x11E /* System Version Register */ +#endif +#define SPRN_TBHI 0x3DC /* Time Base High */ +#define SPRN_TBHU 0x3CC /* Time Base High User-mode */ +#define SPRN_TBLO 0x3DD /* Time Base Low */ +#define SPRN_TBLU 0x3CD /* Time Base Low User-mode */ +#define SPRN_TBRL 0x10C /* Time Base Read Lower Register */ +#define SPRN_TBRU 0x10D /* Time Base Read Upper Register */ +#define SPRN_TBWL 0x11C /* Time Base Write Lower Register */ +#define SPRN_TBWU 0x11D /* Time Base Write Upper Register */ +#ifndef CONFIG_BOOKE +#define SPRN_TCR 0x3DA /* Timer Control Register */ +#else +#define SPRN_TCR 0x154 /* Book E Timer Control Register */ +#endif /* CONFIG_BOOKE */ +#ifdef CONFIG_E500MC +#define TCR_WP(x) (((64 - x) & 0x3) << 30) | \ + (((64 - x) & 0x3c) << 15) /* WDT Period 2^x clocks*/ +#else +#define TCR_WP(x) (((x) & 0x3) << 30) /* WDT Period */ +#define WP_2_17 0 /* 2^17 clocks */ +#define WP_2_21 1 /* 2^21 clocks */ +#define WP_2_25 2 /* 2^25 clocks */ +#define WP_2_29 3 /* 2^29 clocks */ +#endif /* CONFIG_E500 */ +#define TCR_WRC(x) (((x) & 0x3) << 28) /* WDT Reset Control */ +#define WRC_NONE 0 /* No reset will occur */ +#define WRC_CORE 1 /* Core reset will occur */ +#define WRC_CHIP 2 /* Chip reset will occur */ +#define WRC_SYSTEM 3 /* System reset will occur */ +#define TCR_WIE 0x08000000 /* WDT Interrupt Enable */ +#define TCR_PIE 0x04000000 /* PIT Interrupt Enable */ +#define TCR_FP(x) (((x) & 0x3) << 24) /* FIT Period */ +#define FP_2_9 0 /* 2^9 clocks */ +#define FP_2_13 1 /* 2^13 clocks */ +#define FP_2_17 2 /* 2^17 clocks */ +#define FP_2_21 3 /* 2^21 clocks */ +#define TCR_FIE 0x00800000 /* FIT Interrupt Enable */ +#define TCR_ARE 0x00400000 /* Auto Reload Enable */ +#define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ +#define THRM1_TIN (1 << 0) +#define THRM1_TIV (1 << 1) +#define THRM1_THRES (0x7f << 2) +#define THRM1_TID (1 << 29) +#define THRM1_TIE (1 << 30) +#define THRM1_V (1 << 31) +#define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ +#define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ +#define THRM3_E (1 << 31) +#define SPRN_TLBMISS 0x3D4 /* 980 7450 TLB Miss Register */ +#ifndef CONFIG_BOOKE +#define SPRN_TSR 0x3D8 /* Timer Status Register */ +#else +#define SPRN_TSR 0x150 /* Book E Timer Status Register */ +#endif /* CONFIG_BOOKE */ +#define TSR_ENW 0x80000000 /* Enable Next Watchdog */ +#define TSR_WIS 0x40000000 /* WDT Interrupt Status */ +#define TSR_WRS(x) (((x) & 0x3) << 28) /* WDT Reset Status */ +#define WRS_NONE 0 /* No WDT reset occurred */ +#define WRS_CORE 1 /* WDT forced core reset */ +#define WRS_CHIP 2 /* WDT forced chip reset */ +#define WRS_SYSTEM 3 /* WDT forced system reset */ +#define TSR_PIS 0x08000000 /* PIT Interrupt Status */ +#define TSR_FIS 0x04000000 /* FIT Interrupt Status */ +#define SPRN_UMMCR0 0x3A8 /* User Monitor Mode Control Register 0 */ +#define SPRN_UMMCR1 0x3AC /* User Monitor Mode Control Register 0 */ +#define SPRN_UPMC1 0x3A9 /* User Performance Counter Register 1 */ +#define SPRN_UPMC2 0x3AA /* User Performance Counter Register 2 */ +#define SPRN_UPMC3 0x3AD /* User Performance Counter Register 3 */ +#define SPRN_UPMC4 0x3AE /* User Performance Counter Register 4 */ +#define SPRN_USIA 0x3AB /* User Sampled Instruction Address Register */ +#define SPRN_XER 0x001 /* Fixed Point Exception Register */ +#define SPRN_ZPR 0x3B0 /* Zone Protection Register */ + +/* Book E definitions */ +#define SPRN_DECAR 0x036 /* Decrementer Auto Reload Register */ +#define SPRN_CSRR0 0x03A /* Critical SRR0 */ +#define SPRN_CSRR1 0x03B /* Critical SRR0 */ +#define SPRN_IVPR 0x03F /* Interrupt Vector Prefix Register */ +#define SPRN_USPRG0 0x100 /* User Special Purpose Register General 0 */ +#define SPRN_SPRG4R 0x104 /* Special Purpose Register General 4 Read */ +#define SPRN_SPRG5R 0x105 /* Special Purpose Register General 5 Read */ +#define SPRN_SPRG6R 0x106 /* Special Purpose Register General 6 Read */ +#define SPRN_SPRG7R 0x107 /* Special Purpose Register General 7 Read */ +#define SPRN_SPRG4W 0x114 /* Special Purpose Register General 4 Write */ +#define SPRN_SPRG5W 0x115 /* Special Purpose Register General 5 Write */ +#define SPRN_SPRG6W 0x116 /* Special Purpose Register General 6 Write */ +#define SPRN_SPRG7W 0x117 /* Special Purpose Register General 7 Write */ +#define SPRN_DBCR2 0x136 /* Debug Control Register 2 */ +#define SPRN_IAC3 0x13A /* Instruction Address Compare 3 */ +#define SPRN_IAC4 0x13B /* Instruction Address Compare 4 */ +#define SPRN_DVC1 0x13E /* Data Value Compare Register 1 */ +#define SPRN_DVC2 0x13F /* Data Value Compare Register 2 */ +#define SPRN_IVOR0 0x190 /* Interrupt Vector Offset Register 0 */ +#define SPRN_IVOR1 0x191 /* Interrupt Vector Offset Register 1 */ +#define SPRN_IVOR2 0x192 /* Interrupt Vector Offset Register 2 */ +#define SPRN_IVOR3 0x193 /* Interrupt Vector Offset Register 3 */ +#define SPRN_IVOR4 0x194 /* Interrupt Vector Offset Register 4 */ +#define SPRN_IVOR5 0x195 /* Interrupt Vector Offset Register 5 */ +#define SPRN_IVOR6 0x196 /* Interrupt Vector Offset Register 6 */ +#define SPRN_IVOR7 0x197 /* Interrupt Vector Offset Register 7 */ +#define SPRN_IVOR8 0x198 /* Interrupt Vector Offset Register 8 */ +#define SPRN_IVOR9 0x199 /* Interrupt Vector Offset Register 9 */ +#define SPRN_IVOR10 0x19a /* Interrupt Vector Offset Register 10 */ +#define SPRN_IVOR11 0x19b /* Interrupt Vector Offset Register 11 */ +#define SPRN_IVOR12 0x19c /* Interrupt Vector Offset Register 12 */ +#define SPRN_IVOR13 0x19d /* Interrupt Vector Offset Register 13 */ +#define SPRN_IVOR14 0x19e /* Interrupt Vector Offset Register 14 */ +#define SPRN_IVOR15 0x19f /* Interrupt Vector Offset Register 15 */ +#define SPRN_IVOR38 0x1b0 /* Interrupt Vector Offset Register 38 */ +#define SPRN_IVOR39 0x1b1 /* Interrupt Vector Offset Register 39 */ +#define SPRN_IVOR40 0x1b2 /* Interrupt Vector Offset Register 40 */ +#define SPRN_IVOR41 0x1b3 /* Interrupt Vector Offset Register 41 */ +#define SPRN_GIVOR2 0x1b8 /* Guest Interrupt Vector Offset Register 2 */ +#define SPRN_GIVOR3 0x1b9 /* Guest Interrupt Vector Offset Register 3 */ +#define SPRN_GIVOR4 0x1ba /* Guest Interrupt Vector Offset Register 4 */ +#define SPRN_GIVOR8 0x1bb /* Guest Interrupt Vector Offset Register 8 */ +#define SPRN_GIVOR13 0x1bc /* Guest Interrupt Vector Offset Register 13 */ +#define SPRN_GIVOR14 0x1bd /* Guest Interrupt Vector Offset Register 14 */ + +/* e500 definitions */ +#define SPRN_L1CFG0 0x203 /* L1 Cache Configuration Register 0 */ +#define SPRN_L1CFG1 0x204 /* L1 Cache Configuration Register 1 */ +#define SPRN_L2CFG0 0x207 /* L2 Cache Configuration Register 0 */ +#define SPRN_L1CSR0 0x3f2 /* L1 Data Cache Control and Status Register 0 */ +#define L1CSR0_CPE 0x00010000 /* Data Cache Parity Enable */ +#define L1CSR0_CUL 0x00000400 /* (D-)Cache Unable to Lock */ +#define L1CSR0_DCLFR 0x00000100 /* D-Cache Lock Flash Reset */ +#define L1CSR0_DCFI 0x00000002 /* Data Cache Flash Invalidate */ +#define L1CSR0_DCE 0x00000001 /* Data Cache Enable */ +#define SPRN_L1CSR1 0x3f3 /* L1 Instruction Cache Control and Status Register 1 */ +#define L1CSR1_CPE 0x00010000 /* Instruction Cache Parity Enable */ +#define L1CSR1_ICUL 0x00000400 /* I-Cache Unable to Lock */ +#define L1CSR1_ICLFR 0x00000100 /* I-Cache Lock Flash Reset */ +#define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ +#define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ +#define SPRN_L1CSR2 0x25e /* L1 Data Cache Control and Status Register 2 */ +#define L1CSR2_DCWS 0x40000000 /* Data Cache Write Shadow */ +#define SPRN_L2CSR0 0x3f9 /* L2 Data Cache Control and Status Register 0 */ +#define L2CSR0_L2E 0x80000000 /* L2 Cache Enable */ +#define L2CSR0_L2PE 0x40000000 /* L2 Cache Parity/ECC Enable */ +#define L2CSR0_L2WP 0x1c000000 /* L2 I/D Way Partioning */ +#define L2CSR0_L2CM 0x03000000 /* L2 Cache Coherency Mode */ +#define L2CSR0_L2FI 0x00200000 /* L2 Cache Flash Invalidate */ +#define L2CSR0_L2IO 0x00100000 /* L2 Cache Instruction Only */ +#define L2CSR0_L2DO 0x00010000 /* L2 Cache Data Only */ +#define L2CSR0_L2REP 0x00003000 /* L2 Line Replacement Algo */ + +/* e6500 */ +#define L2CSR0_L2REP_SPLRUAGE 0x00000000 /* L2REP Streaming PLRU with Aging */ +#define L2CSR0_L2REP_FIFO 0x00001000 /* L2REP FIFO */ +#define L2CSR0_L2REP_SPLRU 0x00002000 /* L2REP Streaming PLRU */ +#define L2CSR0_L2REP_PLRU 0x00003000 /* L2REP PLRU */ + +#define L2CSR0_L2REP_MODE L2CSR0_L2REP_SPLRUAGE + +#define L2CSR0_L2FL 0x00000800 /* L2 Cache Flush */ +#define L2CSR0_L2LFC 0x00000400 /* L2 Cache Lock Flash Clear */ +#define L2CSR0_L2LOA 0x00000080 /* L2 Cache Lock Overflow Allocate */ +#define L2CSR0_L2LO 0x00000020 /* L2 Cache Lock Overflow */ +#define SPRN_L2CSR1 0x3fa /* L2 Data Cache Control and Status Register 1 */ + +#define SPRN_TLB0CFG 0x2B0 /* TLB 0 Config Register */ +#define SPRN_TLB1CFG 0x2B1 /* TLB 1 Config Register */ +#define TLBnCFG_NENTRY_MASK 0x00000fff +#define SPRN_TLB0PS 0x158 /* TLB 0 Page Size Register */ +#define SPRN_TLB1PS 0x159 /* TLB 1 Page Size Register */ +#define SPRN_MMUCSR0 0x3f4 /* MMU control and status register 0 */ +#define SPRN_MMUCFG 0x3F7 /* MMU Configuration Register */ +#define MMUCFG_MAVN 0x00000003 /* MMU Architecture Version Number */ +#define MMUCFG_MAVN_V1 0x00000000 /* v1.0 */ +#define MMUCFG_MAVN_V2 0x00000001 /* v2.0 */ +#define SPRN_MAS0 0x270 /* MMU Assist Register 0 */ +#define SPRN_MAS1 0x271 /* MMU Assist Register 1 */ +#define SPRN_MAS2 0x272 /* MMU Assist Register 2 */ +#define SPRN_MAS3 0x273 /* MMU Assist Register 3 */ +#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */ +#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */ +#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */ +#define SPRN_MAS7 0x3B0 /* MMU Assist Register 7 */ +#define SPRN_MAS8 0x155 /* MMU Assist Register 8 */ + +#define SPRN_IVOR32 0x210 /* Interrupt Vector Offset Register 32 */ +#define SPRN_IVOR33 0x211 /* Interrupt Vector Offset Register 33 */ +#define SPRN_IVOR34 0x212 /* Interrupt Vector Offset Register 34 */ +#define SPRN_IVOR35 0x213 /* Interrupt Vector Offset Register 35 */ +#define SPRN_IVOR36 0x214 /* Interrupt Vector Offset Register 36 */ +#define SPRN_IVOR37 0x215 /* Interrupt Vector Offset Register 37 */ +#define SPRN_SPEFSCR 0x200 /* SPE & Embedded FP Status & Control */ + +#define SPRN_MCSRR0 0x23a /* Machine Check Save and Restore Register 0 */ +#define SPRN_MCSRR1 0x23b /* Machine Check Save and Restore Register 1 */ +#define SPRN_BUCSR 0x3f5 /* Branch Control and Status Register */ +#define BUCSR_STAC_EN 0x01000000 /* Segment target addr cache enable */ +#define BUCSR_LS_EN 0x00400000 /* Link stack enable */ +#define BUCSR_BBFI 0x00000200 /* Branch buffer flash invalidate */ +#define BUCSR_BPEN 0x00000001 /* Branch prediction enable */ +#define BUCSR_ENABLE (BUCSR_STAC_EN | BUCSR_LS_EN | BUCSR_BBFI | BUCSR_BPEN) +#define SPRN_BBEAR 0x201 /* Branch Buffer Entry Address Register */ +#define SPRN_BBTAR 0x202 /* Branch Buffer Target Address Register */ +#define SPRN_PID1 0x279 /* Process ID Register 1 */ +#define SPRN_PID2 0x27a /* Process ID Register 2 */ +#define SPRN_MCSR 0x23c /* Machine Check Syndrome register */ +#define SPRN_MCAR 0x23d /* Machine Check Address register */ +#define MCSR_MCS 0x80000000 /* Machine Check Summary */ +#define MCSR_IB 0x40000000 /* Instruction PLB Error */ +#if defined(CONFIG_440) +#define MCSR_DRB 0x20000000 /* Data Read PLB Error */ +#define MCSR_DWB 0x10000000 /* Data Write PLB Error */ +#else +#define MCSR_DB 0x20000000 /* Data PLB Error */ +#endif /* defined(CONFIG_440) */ +#define MCSR_TLBP 0x08000000 /* TLB Parity Error */ +#define MCSR_ICP 0x04000000 /* I-Cache Parity Error */ +#define MCSR_DCSP 0x02000000 /* D-Cache Search Parity Error */ +#define MCSR_DCFP 0x01000000 /* D-Cache Flush Parity Error */ +#define MCSR_IMPE 0x00800000 /* Imprecise Machine Check Exception */ +#define ESR_ST 0x00800000 /* Store Operation */ + +#if defined(CONFIG_MPC86xx) +#define SPRN_MSSCR0 0x3f6 +#define SPRN_MSSSR0 0x3f7 +#endif + +#define SPRN_HDBCR0 0x3d0 +#define SPRN_HDBCR1 0x3d1 +#define SPRN_HDBCR2 0x3d2 +#define SPRN_HDBCR3 0x3d3 +#define SPRN_HDBCR4 0x3d4 +#define SPRN_HDBCR5 0x3d5 +#define SPRN_HDBCR6 0x3d6 +#define SPRN_HDBCR7 0x277 +#define SPRN_HDBCR8 0x278 + +/* Short-hand versions for a number of the above SPRNs */ + +#define CTR SPRN_CTR /* Counter Register */ +#define DAR SPRN_DAR /* Data Address Register */ +#define DABR SPRN_DABR /* Data Address Breakpoint Register */ +#define DAC1 SPRN_DAC1 /* Data Address Register 1 */ +#define DAC2 SPRN_DAC2 /* Data Address Register 2 */ +#define DBAT0L SPRN_DBAT0L /* Data BAT 0 Lower Register */ +#define DBAT0U SPRN_DBAT0U /* Data BAT 0 Upper Register */ +#define DBAT1L SPRN_DBAT1L /* Data BAT 1 Lower Register */ +#define DBAT1U SPRN_DBAT1U /* Data BAT 1 Upper Register */ +#define DBAT2L SPRN_DBAT2L /* Data BAT 2 Lower Register */ +#define DBAT2U SPRN_DBAT2U /* Data BAT 2 Upper Register */ +#define DBAT3L SPRN_DBAT3L /* Data BAT 3 Lower Register */ +#define DBAT3U SPRN_DBAT3U /* Data BAT 3 Upper Register */ +#define DBAT4L SPRN_DBAT4L /* Data BAT 4 Lower Register */ +#define DBAT4U SPRN_DBAT4U /* Data BAT 4 Upper Register */ +#define DBAT5L SPRN_DBAT5L /* Data BAT 5 Lower Register */ +#define DBAT5U SPRN_DBAT5U /* Data BAT 5 Upper Register */ +#define DBAT6L SPRN_DBAT6L /* Data BAT 6 Lower Register */ +#define DBAT6U SPRN_DBAT6U /* Data BAT 6 Upper Register */ +#define DBAT7L SPRN_DBAT7L /* Data BAT 7 Lower Register */ +#define DBAT7U SPRN_DBAT7U /* Data BAT 7 Upper Register */ +#define DBCR0 SPRN_DBCR0 /* Debug Control Register 0 */ +#define DBCR1 SPRN_DBCR1 /* Debug Control Register 1 */ +#define DBSR SPRN_DBSR /* Debug Status Register */ +#define DCMP SPRN_DCMP /* Data TLB Compare Register */ +#define DEC SPRN_DEC /* Decrement Register */ +#define DMISS SPRN_DMISS /* Data TLB Miss Register */ +#define DSISR SPRN_DSISR /* Data Storage Interrupt Status Register */ +#define EAR SPRN_EAR /* External Address Register */ +#define ESR SPRN_ESR /* Exception Syndrome Register */ +#define HASH1 SPRN_HASH1 /* Primary Hash Address Register */ +#define HASH2 SPRN_HASH2 /* Secondary Hash Address Register */ +#define HID0 SPRN_HID0 /* Hardware Implementation Register 0 */ +#define HID1 SPRN_HID1 /* Hardware Implementation Register 1 */ +#define IABR SPRN_IABR /* Instruction Address Breakpoint Register */ +#define IAC1 SPRN_IAC1 /* Instruction Address Register 1 */ +#define IAC2 SPRN_IAC2 /* Instruction Address Register 2 */ +#define IBAT0L SPRN_IBAT0L /* Instruction BAT 0 Lower Register */ +#define IBAT0U SPRN_IBAT0U /* Instruction BAT 0 Upper Register */ +#define IBAT1L SPRN_IBAT1L /* Instruction BAT 1 Lower Register */ +#define IBAT1U SPRN_IBAT1U /* Instruction BAT 1 Upper Register */ +#define IBAT2L SPRN_IBAT2L /* Instruction BAT 2 Lower Register */ +#define IBAT2U SPRN_IBAT2U /* Instruction BAT 2 Upper Register */ +#define IBAT3L SPRN_IBAT3L /* Instruction BAT 3 Lower Register */ +#define IBAT3U SPRN_IBAT3U /* Instruction BAT 3 Upper Register */ +#define IBAT4L SPRN_IBAT4L /* Instruction BAT 4 Lower Register */ +#define IBAT4U SPRN_IBAT4U /* Instruction BAT 4 Upper Register */ +#define IBAT5L SPRN_IBAT5L /* Instruction BAT 5 Lower Register */ +#define IBAT5U SPRN_IBAT5U /* Instruction BAT 5 Upper Register */ +#define IBAT6L SPRN_IBAT6L /* Instruction BAT 6 Lower Register */ +#define IBAT6U SPRN_IBAT6U /* Instruction BAT 6 Upper Register */ +#define IBAT7L SPRN_IBAT7L /* Instruction BAT 7 Lower Register */ +#define IBAT7U SPRN_IBAT7U /* Instruction BAT 7 Lower Register */ +#define ICMP SPRN_ICMP /* Instruction TLB Compare Register */ +#define IMISS SPRN_IMISS /* Instruction TLB Miss Register */ +#define IMMR SPRN_IMMR /* PPC 860/821 Internal Memory Map Register */ +#define LDSTCR SPRN_LDSTCR /* Load/Store Control Register */ +#define L2CR SPRN_L2CR /* PPC 750 L2 control register */ +#define LR SPRN_LR +#define MBAR SPRN_MBAR /* System memory base address */ +#if defined(CONFIG_MPC86xx) +#define MSSCR0 SPRN_MSSCR0 +#endif +#if defined(CONFIG_E500) || defined(CONFIG_MPC86xx) +#define PIR SPRN_PIR +#endif +#define SVR SPRN_SVR /* System-On-Chip Version Register */ +#define PVR SPRN_PVR /* Processor Version */ +#define RPA SPRN_RPA /* Required Physical Address Register */ +#define SDR1 SPRN_SDR1 /* MMU hash base register */ +#define SPR0 SPRN_SPRG0 /* Supervisor Kernel Registers */ +#define SPR1 SPRN_SPRG1 +#define SPR2 SPRN_SPRG2 +#define SPR3 SPRN_SPRG3 +#define SPRG0 SPRN_SPRG0 +#define SPRG1 SPRN_SPRG1 +#define SPRG2 SPRN_SPRG2 +#define SPRG3 SPRN_SPRG3 +#define SPRG4 SPRN_SPRG4 +#define SPRG5 SPRN_SPRG5 +#define SPRG6 SPRN_SPRG6 +#define SPRG7 SPRN_SPRG7 +#define SRR0 SPRN_SRR0 /* Save and Restore Register 0 */ +#define SRR1 SPRN_SRR1 /* Save and Restore Register 1 */ +#define SRR2 SPRN_SRR2 /* Save and Restore Register 2 */ +#define SRR3 SPRN_SRR3 /* Save and Restore Register 3 */ +#define SVR SPRN_SVR /* System Version Register */ +#define TBRL SPRN_TBRL /* Time Base Read Lower Register */ +#define TBRU SPRN_TBRU /* Time Base Read Upper Register */ +#define TBWL SPRN_TBWL /* Time Base Write Lower Register */ +#define TBWU SPRN_TBWU /* Time Base Write Upper Register */ +#define TCR SPRN_TCR /* Timer Control Register */ +#define TSR SPRN_TSR /* Timer Status Register */ +#define ICTC 1019 +#define THRM1 SPRN_THRM1 /* Thermal Management Register 1 */ +#define THRM2 SPRN_THRM2 /* Thermal Management Register 2 */ +#define THRM3 SPRN_THRM3 /* Thermal Management Register 3 */ +#define XER SPRN_XER + +#define DECAR SPRN_DECAR +#define CSRR0 SPRN_CSRR0 +#define CSRR1 SPRN_CSRR1 +#define IVPR SPRN_IVPR +#define USPRG0 SPRN_USPRG +#define SPRG4R SPRN_SPRG4R +#define SPRG5R SPRN_SPRG5R +#define SPRG6R SPRN_SPRG6R +#define SPRG7R SPRN_SPRG7R +#define SPRG4W SPRN_SPRG4W +#define SPRG5W SPRN_SPRG5W +#define SPRG6W SPRN_SPRG6W +#define SPRG7W SPRN_SPRG7W +#define DEAR SPRN_DEAR +#define DBCR2 SPRN_DBCR2 +#define IAC3 SPRN_IAC3 +#define IAC4 SPRN_IAC4 +#define DVC1 SPRN_DVC1 +#define DVC2 SPRN_DVC2 +#define IVOR0 SPRN_IVOR0 +#define IVOR1 SPRN_IVOR1 +#define IVOR2 SPRN_IVOR2 +#define IVOR3 SPRN_IVOR3 +#define IVOR4 SPRN_IVOR4 +#define IVOR5 SPRN_IVOR5 +#define IVOR6 SPRN_IVOR6 +#define IVOR7 SPRN_IVOR7 +#define IVOR8 SPRN_IVOR8 +#define IVOR9 SPRN_IVOR9 +#define IVOR10 SPRN_IVOR10 +#define IVOR11 SPRN_IVOR11 +#define IVOR12 SPRN_IVOR12 +#define IVOR13 SPRN_IVOR13 +#define IVOR14 SPRN_IVOR14 +#define IVOR15 SPRN_IVOR15 +#define IVOR32 SPRN_IVOR32 +#define IVOR33 SPRN_IVOR33 +#define IVOR34 SPRN_IVOR34 +#define IVOR35 SPRN_IVOR35 +#define MCSRR0 SPRN_MCSRR0 +#define MCSRR1 SPRN_MCSRR1 +#define L1CSR0 SPRN_L1CSR0 +#define L1CSR1 SPRN_L1CSR1 +#define L1CSR2 SPRN_L1CSR2 +#define L1CFG0 SPRN_L1CFG0 +#define L1CFG1 SPRN_L1CFG1 +#define L2CFG0 SPRN_L2CFG0 +#define L2CSR0 SPRN_L2CSR0 +#define L2CSR1 SPRN_L2CSR1 +#define MCSR SPRN_MCSR +#define MMUCSR0 SPRN_MMUCSR0 +#define BUCSR SPRN_BUCSR +#define PID0 SPRN_PID +#define PID1 SPRN_PID1 +#define PID2 SPRN_PID2 +#define MAS0 SPRN_MAS0 +#define MAS1 SPRN_MAS1 +#define MAS2 SPRN_MAS2 +#define MAS3 SPRN_MAS3 +#define MAS4 SPRN_MAS4 +#define MAS5 SPRN_MAS5 +#define MAS6 SPRN_MAS6 +#define MAS7 SPRN_MAS7 +#define MAS8 SPRN_MAS8 + +#if defined(CONFIG_4xx) || defined(CONFIG_44x) || defined(CONFIG_MPC85xx) +#define DAR_DEAR DEAR +#else +#define DAR_DEAR DAR +#endif + +/* Device Control Registers */ + +#define DCRN_BEAR 0x090 /* Bus Error Address Register */ +#define DCRN_BESR 0x091 /* Bus Error Syndrome Register */ +#define BESR_DSES 0x80000000 /* Data-Side Error Status */ +#define BESR_DMES 0x40000000 /* DMA Error Status */ +#define BESR_RWS 0x20000000 /* Read/Write Status */ +#define BESR_ETMASK 0x1C000000 /* Error Type */ +#define ET_PROT 0 +#define ET_PARITY 1 +#define ET_NCFG 2 +#define ET_BUSERR 4 +#define ET_BUSTO 6 +#define DCRN_DMACC0 0x0C4 /* DMA Chained Count Register 0 */ +#define DCRN_DMACC1 0x0CC /* DMA Chained Count Register 1 */ +#define DCRN_DMACC2 0x0D4 /* DMA Chained Count Register 2 */ +#define DCRN_DMACC3 0x0DC /* DMA Chained Count Register 3 */ +#define DCRN_DMACR0 0x0C0 /* DMA Channel Control Register 0 */ +#define DCRN_DMACR1 0x0C8 /* DMA Channel Control Register 1 */ +#define DCRN_DMACR2 0x0D0 /* DMA Channel Control Register 2 */ +#define DCRN_DMACR3 0x0D8 /* DMA Channel Control Register 3 */ +#define DCRN_DMACT0 0x0C1 /* DMA Count Register 0 */ +#define DCRN_DMACT1 0x0C9 /* DMA Count Register 1 */ +#define DCRN_DMACT2 0x0D1 /* DMA Count Register 2 */ +#define DCRN_DMACT3 0x0D9 /* DMA Count Register 3 */ +#define DCRN_DMADA0 0x0C2 /* DMA Destination Address Register 0 */ +#define DCRN_DMADA1 0x0CA /* DMA Destination Address Register 1 */ +#define DCRN_DMADA2 0x0D2 /* DMA Destination Address Register 2 */ +#define DCRN_DMADA3 0x0DA /* DMA Destination Address Register 3 */ +#define DCRN_DMASA0 0x0C3 /* DMA Source Address Register 0 */ +#define DCRN_DMASA1 0x0CB /* DMA Source Address Register 1 */ +#define DCRN_DMASA2 0x0D3 /* DMA Source Address Register 2 */ +#define DCRN_DMASA3 0x0DB /* DMA Source Address Register 3 */ +#define DCRN_DMASR 0x0E0 /* DMA Status Register */ +#define DCRN_EXIER 0x042 /* External Interrupt Enable Register */ +#define EXIER_CIE 0x80000000 /* Critical Interrupt Enable */ +#define EXIER_SRIE 0x08000000 /* Serial Port Rx Int. Enable */ +#define EXIER_STIE 0x04000000 /* Serial Port Tx Int. Enable */ +#define EXIER_JRIE 0x02000000 /* JTAG Serial Port Rx Int. Enable */ +#define EXIER_JTIE 0x01000000 /* JTAG Serial Port Tx Int. Enable */ +#define EXIER_D0IE 0x00800000 /* DMA Channel 0 Interrupt Enable */ +#define EXIER_D1IE 0x00400000 /* DMA Channel 1 Interrupt Enable */ +#define EXIER_D2IE 0x00200000 /* DMA Channel 2 Interrupt Enable */ +#define EXIER_D3IE 0x00100000 /* DMA Channel 3 Interrupt Enable */ +#define EXIER_E0IE 0x00000010 /* External Interrupt 0 Enable */ +#define EXIER_E1IE 0x00000008 /* External Interrupt 1 Enable */ +#define EXIER_E2IE 0x00000004 /* External Interrupt 2 Enable */ +#define EXIER_E3IE 0x00000002 /* External Interrupt 3 Enable */ +#define EXIER_E4IE 0x00000001 /* External Interrupt 4 Enable */ +#define DCRN_EXISR 0x040 /* External Interrupt Status Register */ +#define DCRN_IOCR 0x0A0 /* Input/Output Configuration Register */ +#define IOCR_E0TE 0x80000000 +#define IOCR_E0LP 0x40000000 +#define IOCR_E1TE 0x20000000 +#define IOCR_E1LP 0x10000000 +#define IOCR_E2TE 0x08000000 +#define IOCR_E2LP 0x04000000 +#define IOCR_E3TE 0x02000000 +#define IOCR_E3LP 0x01000000 +#define IOCR_E4TE 0x00800000 +#define IOCR_E4LP 0x00400000 +#define IOCR_EDT 0x00080000 +#define IOCR_SOR 0x00040000 +#define IOCR_EDO 0x00008000 +#define IOCR_2XC 0x00004000 +#define IOCR_ATC 0x00002000 +#define IOCR_SPD 0x00001000 +#define IOCR_BEM 0x00000800 +#define IOCR_PTD 0x00000400 +#define IOCR_ARE 0x00000080 +#define IOCR_DRC 0x00000020 +#define IOCR_RDM(x) (((x) & 0x3) << 3) +#define IOCR_TCS 0x00000004 +#define IOCR_SCS 0x00000002 +#define IOCR_SPC 0x00000001 + +/* System-On-Chip Version Register */ + +/* System-On-Chip Version Register (SVR) field extraction */ + +#define SVR_VER(svr) (((svr) >> 16) & 0xFFFF) /* Version field */ +#define SVR_REV(svr) (((svr) >> 0) & 0xFF) /* Revision field */ + +#define SVR_CID(svr) (((svr) >> 28) & 0x0F) /* Company or manufacturer ID */ +#define SVR_SOCOP(svr) (((svr) >> 22) & 0x3F) /* SOC integration options */ +#define SVR_SID(svr) (((svr) >> 16) & 0x3F) /* SOC ID */ +#define SVR_PROC(svr) (((svr) >> 12) & 0x0F) /* Process revision field */ +#define SVR_MFG(svr) (((svr) >> 8) & 0x0F) /* Manufacturing revision */ +#define SVR_MJREV(svr) (((svr) >> 4) & 0x0F) /* Major SOC design revision indicator */ +#define SVR_MNREV(svr) (((svr) >> 0) & 0x0F) /* Minor SOC design revision indicator */ + +/* Processor Version Register */ + +/* Processor Version Register (PVR) field extraction */ + +#define PVR_VER(pvr) (((pvr) >> 16) & 0xFFFF) /* Version field */ +#define PVR_REV(pvr) (((pvr) >> 0) & 0xFFFF) /* Revison field */ + +/* + * AMCC has further subdivided the standard ppc 16-bit version and + * revision subfields of the PVR for the ppc 403s into the following: + */ + +#define PVR_FAM(pvr) (((pvr) >> 20) & 0xFFF) /* Family field */ +#define PVR_MEM(pvr) (((pvr) >> 16) & 0xF) /* Member field */ +#define PVR_CORE(pvr) (((pvr) >> 12) & 0xF) /* Core field */ +#define PVR_CFG(pvr) (((pvr) >> 8) & 0xF) /* Configuration field */ +#define PVR_MAJ(pvr) (((pvr) >> 4) & 0xF) /* Major revision field */ +#define PVR_MIN(pvr) (((pvr) >> 0) & 0xF) /* Minor revision field */ + +/* e600 core PVR fields */ + +#define PVR_E600_VER(pvr) (((pvr) >> 15) & 0xFFFF) /* Version/type */ +#define PVR_E600_TECH(pvr) (((pvr) >> 12) & 0xF) /* Technology */ +#define PVR_E600_MAJ(pvr) (((pvr) >> 8) & 0xF) /* Major revision */ +#define PVR_E600_MIN(pvr) (((pvr) >> 0) & 0xFF) /* Minor revision */ + +/* Processor Version Numbers */ + +#define PVR_403GA 0x00200000 +#define PVR_403GB 0x00200100 +#define PVR_403GC 0x00200200 +#define PVR_403GCX 0x00201400 +#define PVR_405GP 0x40110000 +#define PVR_405GP_RB 0x40110040 +#define PVR_405GP_RC 0x40110082 +#define PVR_405GP_RD 0x401100C4 +#define PVR_405GP_RE 0x40110145 /* same as pc405cr rev c */ +#define PVR_405EP_RA 0x51210950 +#define PVR_405GPR_RB 0x50910951 +#define PVR_405EZ_RA 0x41511460 +#define PVR_405EXR2_RA 0x12911471 /* 405EXr rev A/B without Security */ +#define PVR_405EX1_RA 0x12911477 /* 405EX rev A/B with Security */ +#define PVR_405EXR1_RC 0x1291147B /* 405EXr rev C with Security */ +#define PVR_405EXR2_RC 0x12911479 /* 405EXr rev C without Security */ +#define PVR_405EX1_RC 0x1291147F /* 405EX rev C with Security */ +#define PVR_405EX2_RC 0x1291147D /* 405EX rev C without Security */ +#define PVR_405EXR1_RD 0x12911472 /* 405EXr rev D with Security */ +#define PVR_405EXR2_RD 0x12911470 /* 405EXr rev D without Security */ +#define PVR_405EX1_RD 0x12911475 /* 405EX rev D with Security */ +#define PVR_405EX2_RD 0x12911473 /* 405EX rev D without Security */ +#define PVR_440GP_RB 0x40120440 +#define PVR_440GP_RC 0x40120481 +#define PVR_440EP_RA 0x42221850 +#define PVR_440EP_RB 0x422218D3 /* 440EP rev B and 440GR rev A have same PVR */ +#define PVR_440EP_RC 0x422218D4 /* 440EP rev C and 440GR rev B have same PVR */ +#define PVR_440GR_RA 0x422218D3 /* 440EP rev B and 440GR rev A have same PVR */ +#define PVR_440GR_RB 0x422218D4 /* 440EP rev C and 440GR rev B have same PVR */ +#define PVR_440EPX1_RA 0x216218D0 /* 440EPX rev A with Security / Kasumi */ +#define PVR_440EPX2_RA 0x216218D4 /* 440EPX rev A without Security / Kasumi */ +#define PVR_440GRX1_RA 0x216218D0 /* 440GRX rev A with Security / Kasumi */ +#define PVR_440GRX2_RA 0x216218D4 /* 440GRX rev A without Security / Kasumi */ +#define PVR_440GX_RA 0x51B21850 +#define PVR_440GX_RB 0x51B21851 +#define PVR_440GX_RC 0x51B21892 +#define PVR_440GX_RF 0x51B21894 +#define PVR_405EP_RB 0x51210950 +#define PVR_440SP_6_RAB 0x53221850 /* 440SP rev A&B with RAID 6 support enabled */ +#define PVR_440SP_RAB 0x53321850 /* 440SP rev A&B without RAID 6 support */ +#define PVR_440SP_6_RC 0x53221891 /* 440SP rev C with RAID 6 support enabled */ +#define PVR_440SP_RC 0x53321891 /* 440SP rev C without RAID 6 support */ +#define PVR_440SPe_6_RA 0x53421890 /* 440SPe rev A with RAID 6 support enabled */ +#define PVR_440SPe_RA 0x53521890 /* 440SPe rev A without RAID 6 support */ +#define PVR_440SPe_6_RB 0x53421891 /* 440SPe rev B with RAID 6 support enabled */ +#define PVR_440SPe_RB 0x53521891 /* 440SPe rev B without RAID 6 support */ +#define PVR_460EX_SE_RA 0x130218A2 /* 460EX rev A with Security Engine */ +#define PVR_460EX_RA 0x130218A3 /* 460EX rev A without Security Engine */ +#define PVR_460EX_RB 0x130218A4 /* 460EX rev B with and without Sec Eng*/ +#define PVR_460GT_SE_RA 0x130218A0 /* 460GT rev A with Security Engine */ +#define PVR_460GT_RA 0x130218A1 /* 460GT rev A without Security Engine */ +#define PVR_460GT_RB 0x130218A5 /* 460GT rev B with and without Sec Eng*/ +#define PVR_460SX_RA 0x13541800 /* 460SX rev A */ +#define PVR_460SX_RA_V1 0x13541801 /* 460SX rev A Variant 1 Security disabled */ +#define PVR_460GX_RA 0x13541802 /* 460GX rev A */ +#define PVR_460GX_RA_V1 0x13541803 /* 460GX rev A Variant 1 Security disabled */ +#define PVR_APM821XX_RA 0x12C41C80 /* APM821XX rev A */ +#define PVR_601 0x00010000 +#define PVR_602 0x00050000 +#define PVR_603 0x00030000 +#define PVR_603e 0x00060000 +#define PVR_603ev 0x00070000 +#define PVR_603r 0x00071000 +#define PVR_604 0x00040000 +#define PVR_604e 0x00090000 +#define PVR_604r 0x000A0000 +#define PVR_620 0x00140000 +#define PVR_740 0x00080000 +#define PVR_750 PVR_740 +#define PVR_740P 0x10080000 +#define PVR_750P PVR_740P +#define PVR_7400 0x000C0000 +#define PVR_7410 0x800C0000 +#define PVR_7450 0x80000000 + +#define PVR_85xx 0x80200000 +#define PVR_85xx_REV1 (PVR_85xx | 0x0010) +#define PVR_85xx_REV2 (PVR_85xx | 0x0020) +#define PVR_VER_E500_V1 0x8020 +#define PVR_VER_E500_V2 0x8021 +#define PVR_VER_E500MC 0x8023 +#define PVR_VER_E5500 0x8024 +#define PVR_VER_E6500 0x8040 + +#define PVR_86xx 0x80040000 + +#define PVR_VIRTEX5 0x7ff21912 + +/* + * For the 8xx processors, all of them report the same PVR family for + * the ppc core. The various versions of these processors must be + * differentiated by the version number in the Communication Processor + * Module (CPM). + */ +#define PVR_821 0x00500000 +#define PVR_823 PVR_821 +#define PVR_850 PVR_821 +#define PVR_860 PVR_821 +#define PVR_7400 0x000C0000 +#define PVR_8240 0x00810100 + +/* + * PowerQUICC II family processors report different PVR values depending + * on silicon process (HiP3, HiP4, HiP7, etc.) + */ +#define PVR_8260 PVR_8240 +#define PVR_8260_HIP3 0x00810101 +#define PVR_8260_HIP4 0x80811014 +#define PVR_8260_HIP7 0x80822011 +#define PVR_8260_HIP7R1 0x80822013 +#define PVR_8260_HIP7RA 0x80822014 + +/* + * MPC 52xx + */ +#define PVR_5200 0x80822011 +#define PVR_5200B 0x80822014 + +/* + * 405EX/EXr CHIP_21 Errata + */ +#ifdef CONFIG_SYS_4xx_CHIP_21_405EX_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C PVR_405EX1_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D PVR_405EX1_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D 0x0 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EX_NO_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C PVR_405EX2_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D PVR_405EX2_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D 0x1 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EXr_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C PVR_405EXR1_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D PVR_405EXR1_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D 0x2 +#endif + +#ifdef CONFIG_SYS_4xx_CHIP_21_405EXr_NO_SECURITY +#define CONFIG_SYS_4xx_CHIP_21_ERRATA +#define CONFIG_405EX_CHIP21_PVR_REV_C PVR_405EXR2_RC +#define CONFIG_405EX_CHIP21_PVR_REV_D PVR_405EXR2_RD +#define CONFIG_405EX_CHIP21_ECID3_REV_D 0x3 +#endif + +/* + * System Version Register + */ + +/* System Version Register (SVR) field extraction */ + +#define SVR_SUBVER(svr) (((svr) >> 8) & 0xFF) /* Process/MFG sub-version */ + +#define SVR_FAM(svr) (((svr) >> 20) & 0xFFF) /* Family field */ +#define SVR_MEM(svr) (((svr) >> 16) & 0xF) /* Member field */ + +#ifdef CONFIG_MPC8536 +#define SVR_MAJ(svr) (((svr) >> 4) & 0x7) /* Major revision field*/ +#else +#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ +#endif +#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ + +/* Some parts define SVR[0:23] as the SOC version */ +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC w/o E bit*/ + +/* whether MPC8xxxE (i.e. has SEC) */ +#if defined(CONFIG_MPC85xx) +#define IS_E_PROCESSOR(svr) (svr & 0x80000) +#else +#if defined(CONFIG_MPC83xx) +#define IS_E_PROCESSOR(spridr) (!(spridr & 0x00010000)) +#endif +#endif + +#define IS_SVR_REV(svr, maj, min) \ + ((SVR_MAJ(svr) == maj) && (SVR_MIN(svr) == min)) + +/* + * SVR_SOC_VER() Version Values + */ + +#define SVR_8533 0x803400 +#define SVR_8535 0x803701 +#define SVR_8536 0x803700 +#define SVR_8540 0x803000 +#define SVR_8541 0x807200 +#define SVR_8543 0x803200 +#define SVR_8544 0x803401 +#define SVR_8545 0x803102 +#define SVR_8547 0x803101 +#define SVR_8548 0x803100 +#define SVR_8555 0x807100 +#define SVR_8560 0x807000 +#define SVR_8567 0x807501 +#define SVR_8568 0x807500 +#define SVR_8569 0x808000 +#define SVR_8572 0x80E000 +#define SVR_P1010 0x80F100 +#define SVR_P1011 0x80E500 +#define SVR_P1012 0x80E501 +#define SVR_P1013 0x80E700 +#define SVR_P1014 0x80F101 +#define SVR_P1017 0x80F700 +#define SVR_P1020 0x80E400 +#define SVR_P1021 0x80E401 +#define SVR_P1022 0x80E600 +#define SVR_P1023 0x80F600 +#define SVR_P1024 0x80E402 +#define SVR_P1025 0x80E403 +#define SVR_P2010 0x80E300 +#define SVR_P2020 0x80E200 +#define SVR_P2040 0x821000 +#define SVR_P2041 0x821001 +#define SVR_P3041 0x821103 +#define SVR_P4040 0x820100 +#define SVR_P4080 0x820000 +#define SVR_P5010 0x822100 +#define SVR_P5020 0x822000 +#define SVR_P5021 0X820500 +#define SVR_P5040 0x820400 +#define SVR_T4240 0x824000 +#define SVR_T4120 0x824001 +#define SVR_T4160 0x824100 +#define SVR_T4080 0x824102 +#define SVR_C291 0x850000 +#define SVR_C292 0x850020 +#define SVR_C293 0x850030 +#define SVR_B4860 0X868000 +#define SVR_G4860 0x868001 +#define SVR_B4460 0x868003 +#define SVR_B4440 0x868100 +#define SVR_G4440 0x868101 +#define SVR_B4420 0x868102 +#define SVR_B4220 0x868103 +#define SVR_T1040 0x852000 +#define SVR_T1041 0x852001 +#define SVR_T1042 0x852002 +#define SVR_T1020 0x852100 +#define SVR_T1021 0x852101 +#define SVR_T1022 0x852102 +#define SVR_T1024 0x854000 +#define SVR_T1023 0x854100 +#define SVR_T1014 0x854400 +#define SVR_T1013 0x854500 +#define SVR_T2080 0x853000 +#define SVR_T2081 0x853100 + +#define SVR_8610 0x80A000 +#define SVR_8641 0x809000 +#define SVR_8641D 0x809001 + +#define SVR_9130 0x860001 +#define SVR_9131 0x860000 +#define SVR_9132 0x861000 +#define SVR_9232 0x861400 + +#define SVR_Unknown 0xFFFFFF + +#define _GLOBAL(n) \ + .globl n; \ + n: + +/* Macros for setting and retrieving special purpose registers */ + +#define stringify(s) tostring(s) +#define tostring(s) #s + +#define mfdcr(rn) ({unsigned int rval; \ + asm volatile("mfdcr %0," stringify(rn) \ + : "=r" (rval)); rval; }) +#define mtdcr(rn, v) asm volatile("mtdcr " stringify(rn) ",%0" \ + : \ + : "r"(v)) + +#define mfmsr() ({unsigned int rval; \ + asm volatile("mfmsr %0" : "=r" (rval)); rval; }) +#define mtmsr(v) asm volatile("mtmsr %0" \ + : \ + : "r"(v)) + +#define mfspr(rn) ({unsigned int rval; \ + asm volatile("mfspr %0," stringify(rn) \ + : "=r" (rval)); rval; }) +#define mtspr(rn, v) asm volatile("mtspr " stringify(rn) ",%0" \ + : \ + : "r"(v)) + +#define tlbie(v) asm volatile("tlbie %0 \n sync" \ + : \ + : "r"(v)) + +/* Segment Registers */ + +#define SR0 0 +#define SR1 1 +#define SR2 2 +#define SR3 3 +#define SR4 4 +#define SR5 5 +#define SR6 6 +#define SR7 7 +#define SR8 8 +#define SR9 9 +#define SR10 10 +#define SR11 11 +#define SR12 12 +#define SR13 13 +#define SR14 14 +#define SR15 15 + +#ifndef __ASSEMBLY__ + +#include + +struct cpu_type +{ + char name[15]; + uint32_t soc_ver; + uint32_t num_cores; + uint32_t mask; /* which cpu(s) actually exist */ +#ifdef CONFIG_HETROGENOUS_CLUSTERS + uint32_t dsp_num_cores; + uint32_t dsp_mask; /* which DSP cpu(s) actually exist */ +#endif +}; + +struct cpu_type* identify_cpu(uint32_t ver); +int fixup_cpu(void); + +int fsl_qoriq_core_to_cluster(unsigned int core); +int fsl_qoriq_dsp_core_to_cluster(unsigned int core); + +#if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) +#define CPU_TYPE_ENTRY(n, v, nc) \ + { \ + .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), \ + .mask = (1 << (nc)) - 1 \ + } +#define CPU_TYPE_ENTRY_MASK(n, v, nc, m) \ + { \ + .name = #n, .soc_ver = SVR_##v, .num_cores = (nc), .mask = (m) \ + } +#else +#if defined(CONFIG_MPC83xx) +#define CPU_TYPE_ENTRY(x) \ + { \ + #x, SPR_##x \ + } +#endif +#endif + +#ifndef CONFIG_MACH_SPECIFIC +extern int _machine; +extern int have_of; +#endif /* CONFIG_MACH_SPECIFIC */ + +/* what kind of prep workstation we are */ +extern int _prep_type; +/* + * This is used to identify the board type from a given PReP board + * vendor. Board revision is also made available. + */ +extern unsigned char ucSystemType; +extern unsigned char ucBoardRev; +extern unsigned char ucBoardRevMaj, ucBoardRevMin; + +struct task_struct; +void start_thread(struct pt_regs* regs, unsigned long nip, unsigned long sp); +void release_thread(struct task_struct*); + +/* + * Create a new Kernel thread. + */ +extern long kernel_thread(int (*fn)(void*), void* arg, unsigned long flags); + +/* + * Bus types + */ +#define EISA_bus 0 +#define EISA_bus__is_a_macro /* for versions in ksyms.c */ +#define MCA_bus 0 +#define MCA_bus__is_a_macro /* for versions in ksyms.c */ + +/* Lazy FPU handling on uni-processor */ +extern struct task_struct* last_task_used_math; +extern struct task_struct* last_task_used_altivec; + +/* + * this is the minimum allowable io space due to the location + * of the io areas on prep (first one at 0x80000000) but + * as soon as I get around to remapping the io areas with the BATs + * to match the mac we can raise this. -- Cort + */ +#define TASK_SIZE (0x80000000UL) + +/* This decides where the Kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 8 * 3) + +typedef struct +{ + unsigned long seg; +} mm_segment_t; + +struct thread_struct +{ + unsigned long ksp; /* Kernel stack pointer */ + unsigned long wchan; /* Event task is sleeping on */ + struct pt_regs* regs; /* Pointer to saved register state */ + mm_segment_t fs; /* for get_fs() validation */ + void* pgdir; /* root of page-table tree */ + signed long last_syscall; + double fpr[32]; /* Complete floating point set */ + unsigned long fpscr_pad; /* fpr ... fpscr must be contiguous */ + unsigned long fpscr; /* Floating point status */ +#ifdef CONFIG_ALTIVEC + vector128 vr[32]; /* Complete AltiVec set */ + vector128 vscr; /* AltiVec status */ + unsigned long vrsave; +#endif /* CONFIG_ALTIVEC */ +}; + +#define INIT_SP (sizeof(init_stack) + (unsigned long)&init_stack) + +#define INIT_THREAD \ + { \ + INIT_SP, /* ksp */ \ + 0, /* wchan */ \ + (struct pt_regs*)INIT_SP - 1, /* regs */ \ + KERNEL_DS, /*fs*/ \ + swapper_pg_dir, /* pgdir */ \ + 0, /* last_syscall */ \ + {0}, 0, 0 \ + } + +/* + * Note: the vm_start and vm_end fields here should *not* + * be in Kernel space. (Could vm_end == vm_start perhaps?) + */ +#define INIT_MMAP \ + { \ + &init_mm, 0, 0x1000, NULL, \ + PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, \ + 1, NULL, NULL \ + } + +/* + * Return saved PC of a blocked thread. For now, this is the "user" PC + */ +static inline unsigned long thread_saved_pc(struct thread_struct* t) +{ + return (t->regs) ? t->regs->nip : 0; +} + +#define copy_segments(tsk, mm) \ + do \ + { \ + } while (0) +#define release_segments(mm) \ + do \ + { \ + } while (0) +#define forget_segments() \ + do \ + { \ + } while (0) + +unsigned long get_wchan(struct task_struct* p); + +#define KSTK_EIP(tsk) ((tsk)->thread.regs->nip) +#define KSTK_ESP(tsk) ((tsk)->thread.regs->gpr[1]) + +/* + * NOTE! The task struct and the stack go together + */ +#define THREAD_SIZE (2 * PAGE_SIZE) +#define alloc_task_struct() \ + ((struct task_struct*)__get_free_pages(GFP_KERNEL, 1)) +#define free_task_struct(p) free_pages((unsigned long)(p), 1) +#define get_task_struct(tsk) atomic_inc(&mem_map[MAP_NR(tsk)].count) + +/* in process.c - for early bootup debug -- Cort */ +int ll_printk(const char*, ...); +void ll_puts(const char*); + +#define init_task (init_task_union.task) +#define init_stack (init_task_union.stack) + +/* In misc.c */ +void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); + +#endif /* ndef ASSEMBLY*/ + +#ifdef CONFIG_MACH_SPECIFIC +#if defined(CONFIG_8xx) +#define _machine _MACH_8xx +#define have_of 0 +#elif defined(CONFIG_WALNUT) +#define _machine _MACH_walnut +#define have_of 0 +#elif defined(CONFIG_MPC8260) +#define _machine _MACH_8260 +#define have_of 0 +#else +#error "Machine not defined correctly" +#endif +#endif /* CONFIG_MACH_SPECIFIC */ + +#if defined(CONFIG_MPC85xx) || defined(CONFIG_440) +#define EPAPR_MAGIC (0x45504150) +#else +#define EPAPR_MAGIC (0x65504150) +#endif + +#endif /* __ASM_PPC_PROCESSOR_H */ diff --git a/dev/Kernel/HALKit/POWER/ppc-mmu.h b/dev/Kernel/HALKit/POWER/ppc-mmu.h new file mode 100644 index 00000000..8e4b3595 --- /dev/null +++ b/dev/Kernel/HALKit/POWER/ppc-mmu.h @@ -0,0 +1,811 @@ + +#ifndef _PPC_MMU_H_ +#define _PPC_MMU_H_ + +#ifndef __ASSEMBLY__ + +#include + +/* Hardware Page Table Entry */ +typedef struct _PTE +{ +#ifdef CONFIG_PPC64BRIDGE + unsigned long long vsid : 52; + unsigned long api : 5; + unsigned long : 5; + unsigned long h : 1; + unsigned long v : 1; + unsigned long long rpn : 52; +#else /* CONFIG_PPC64BRIDGE */ + unsigned long v : 1; /* Entry is valid */ + unsigned long vsid : 24; /* Virtual segment identifier */ + unsigned long h : 1; /* Hash algorithm indicator */ + unsigned long api : 6; /* Abbreviated page index */ + unsigned long rpn : 20; /* Real (physical) page number */ +#endif /* CONFIG_PPC64BRIDGE */ + unsigned long : 3; /* Unused */ + unsigned long r : 1; /* Referenced */ + unsigned long c : 1; /* Changed */ + unsigned long w : 1; /* Write-thru cache mode */ + unsigned long i : 1; /* Cache inhibited */ + unsigned long m : 1; /* Memory coherence */ + unsigned long g : 1; /* Guarded */ + unsigned long : 1; /* Unused */ + unsigned long pp : 2; /* Page protection */ +} PTE; + +/* Values for PP (assumes Ks=0, Kp=1) */ +#define PP_RWXX 0 /* Supervisor read/write, User none */ +#define PP_RWRX 1 /* Supervisor read/write, User read */ +#define PP_RWRW 2 /* Supervisor read/write, User read/write */ +#define PP_RXRX 3 /* Supervisor read, User read */ + +/* Segment Register */ +typedef struct _SEGREG +{ + unsigned long t : 1; /* Normal or I/O type */ + unsigned long ks : 1; /* Supervisor 'key' (normally 0) */ + unsigned long kp : 1; /* User 'key' (normally 1) */ + unsigned long n : 1; /* No-execute */ + unsigned long : 4; /* Unused */ + unsigned long vsid : 24; /* Virtual Segment Identifier */ +} SEGREG; + +/* Block Address Translation (BAT) Registers */ +typedef struct _P601_BATU +{ /* Upper part of BAT for 601 processor */ + unsigned long bepi : 15; /* Effective page index (virtual address) */ + unsigned long : 8; /* unused */ + unsigned long w : 1; + unsigned long i : 1; /* Cache inhibit */ + unsigned long m : 1; /* Memory coherence */ + unsigned long ks : 1; /* Supervisor key (normally 0) */ + unsigned long kp : 1; /* User key (normally 1) */ + unsigned long pp : 2; /* Page access protections */ +} P601_BATU; + +typedef struct _BATU +{ /* Upper part of BAT (all except 601) */ +#ifdef CONFIG_PPC64BRIDGE + unsigned long long bepi : 47; +#else /* CONFIG_PPC64BRIDGE */ + unsigned long bepi : 15; /* Effective page index (virtual address) */ +#endif /* CONFIG_PPC64BRIDGE */ + unsigned long : 4; /* Unused */ + unsigned long bl : 11; /* Block size mask */ + unsigned long vs : 1; /* Supervisor valid */ + unsigned long vp : 1; /* User valid */ +} BATU; + +typedef struct _P601_BATL +{ /* Lower part of BAT for 601 processor */ + unsigned long brpn : 15; /* Real page index (physical address) */ + unsigned long : 10; /* Unused */ + unsigned long v : 1; /* Valid bit */ + unsigned long bl : 6; /* Block size mask */ +} P601_BATL; + +typedef struct _BATL +{ /* Lower part of BAT (all except 601) */ +#ifdef CONFIG_PPC64BRIDGE + unsigned long long brpn : 47; +#else /* CONFIG_PPC64BRIDGE */ + unsigned long brpn : 15; /* Real page index (physical address) */ +#endif /* CONFIG_PPC64BRIDGE */ + unsigned long : 10; /* Unused */ + unsigned long w : 1; /* Write-thru cache */ + unsigned long i : 1; /* Cache inhibit */ + unsigned long m : 1; /* Memory coherence */ + unsigned long g : 1; /* Guarded (MBZ in IBAT) */ + unsigned long : 1; /* Unused */ + unsigned long pp : 2; /* Page access protections */ +} BATL; + +typedef struct _BAT +{ + BATU batu; /* Upper register */ + BATL batl; /* Lower register */ +} BAT; + +typedef struct _P601_BAT +{ + P601_BATU batu; /* Upper register */ + P601_BATL batl; /* Lower register */ +} P601_BAT; + +/* + * Simulated two-level MMU. This structure is used by the Kernel + * to keep track of MMU mappings and is used to update/maintain + * the hardware HASH table which is really a cache of mappings. + * + * The simulated structures mimic the hardware available on other + * platforms, notably the 80x86 and 680x0. + */ + +typedef struct _pte +{ + unsigned long page_num : 20; + unsigned long flags : 12; /* Page flags (some unused bits) */ +} pte; + +#define PD_SHIFT (10 + 12) /* Page directory */ +#define PD_MASK 0x02FF +#define PT_SHIFT (12) /* Page Table */ +#define PT_MASK 0x02FF +#define PG_SHIFT (12) /* Page Entry */ + +/* MMU context */ + +typedef struct _MMU_context +{ + SEGREG segs[16]; /* Segment registers */ + pte** pmap; /* Two-level page-map structure */ +} MMU_context; + +extern void _tlbie(unsigned long va); /* invalidate a TLB entry */ +extern void _tlbia(void); /* invalidate all TLB entries */ + +#ifdef CONFIG_ADDR_MAP +extern void init_addr_map(void); +#endif + +typedef enum +{ + IBAT0 = 0, + IBAT1, + IBAT2, + IBAT3, + DBAT0, + DBAT1, + DBAT2, + DBAT3, +#ifdef CONFIG_HIGH_BATS + IBAT4, + IBAT5, + IBAT6, + IBAT7, + DBAT4, + DBAT5, + DBAT6, + DBAT7 +#endif +} ppc_bat_t; + +extern int read_bat(ppc_bat_t bat, unsigned long* upper, unsigned long* lower); +extern int write_bat(ppc_bat_t bat, unsigned long upper, unsigned long lower); +extern void print_bats(void); + +#endif /* __ASSEMBLY__ */ + +#define BATU_VS 0x00000002 +#define BATU_VP 0x00000001 +#define BATU_INVALID 0x00000000 + +#define BATL_WRITETHROUGH 0x00000040 +#define BATL_CACHEINHIBIT 0x00000020 +#define BATL_MEMCOHERENCE 0x00000010 +#define BATL_GUARDEDSTORAGE 0x00000008 +#define BATL_NO_ACCESS 0x00000000 + +#define BATL_PP_MSK 0x00000003 +#define BATL_PP_00 0x00000000 /* No access */ +#define BATL_PP_01 0x00000001 /* Read-only */ +#define BATL_PP_10 0x00000002 /* Read-write */ +#define BATL_PP_11 0x00000003 + +#define BATL_PP_NO_ACCESS BATL_PP_00 +#define BATL_PP_RO BATL_PP_01 +#define BATL_PP_RW BATL_PP_10 + +/* BAT Block size values */ +#define BATU_BL_128K 0x00000000 +#define BATU_BL_256K 0x00000004 +#define BATU_BL_512K 0x0000000c +#define BATU_BL_1M 0x0000001c +#define BATU_BL_2M 0x0000003c +#define BATU_BL_4M 0x0000007c +#define BATU_BL_8M 0x000000fc +#define BATU_BL_16M 0x000001fc +#define BATU_BL_32M 0x000003fc +#define BATU_BL_64M 0x000007fc +#define BATU_BL_128M 0x00000ffc +#define BATU_BL_256M 0x00001ffc + +/* Block lengths for processors that support extended block length */ +#ifdef HID0_XBSEN +#define BATU_BL_512M 0x00003ffc +#define BATU_BL_1G 0x00007ffc +#define BATU_BL_2G 0x0000fffc +#define BATU_BL_4G 0x0001fffc +#define BATU_BL_MAX BATU_BL_4G +#else +#define BATU_BL_MAX BATU_BL_256M +#endif + +/* BAT Access Protection */ +#define BPP_XX 0x00 /* No access */ +#define BPP_RX 0x01 /* Read only */ +#define BPP_RW 0x02 /* Read/write */ + +/* Macros to get values from BATs, once data is in the BAT register format */ +#define BATU_VALID(x) (x & 0x3) +#define BATU_VADDR(x) (x & 0xfffe0000) +#define BATL_PADDR(x) ((phys_addr_t)((x & 0xfffe0000) | ((x & 0x0e00ULL) << 24) | ((x & 0x04ULL) << 30))) +#define BATU_SIZE(x) (1ULL << (fls((x & BATU_BL_MAX) >> 2) + 17)) + +/* bytes into BATU_BL */ +#define TO_BATU_BL(x) \ + (uint32_t)((((1ull << __ilog2_u64((uint64_t)x)) / (128 * 1024)) - 1) * 4) + +/* Used to set up SDR1 register */ +#define HASH_TABLE_SIZE_64K 0x00010000 +#define HASH_TABLE_SIZE_128K 0x00020000 +#define HASH_TABLE_SIZE_256K 0x00040000 +#define HASH_TABLE_SIZE_512K 0x00080000 +#define HASH_TABLE_SIZE_1M 0x00100000 +#define HASH_TABLE_SIZE_2M 0x00200000 +#define HASH_TABLE_SIZE_4M 0x00400000 +#define HASH_TABLE_MASK_64K 0x000 +#define HASH_TABLE_MASK_128K 0x001 +#define HASH_TABLE_MASK_256K 0x003 +#define HASH_TABLE_MASK_512K 0x007 +#define HASH_TABLE_MASK_1M 0x00F +#define HASH_TABLE_MASK_2M 0x01F +#define HASH_TABLE_MASK_4M 0x03F + +/* Control/status registers for the MPC8xx. + * A write operation to these registers causes serialized access. + * During software tablewalk, the registers used perform mask/shift-add + * operations when written/read. A TLB entry is created when the Mx_RPN + * is written, and the contents of several registers are used to + * create the entry. + */ +#define MI_CTR 784 /* Instruction TLB control register */ +#define MI_GPM 0x80000000 /* Set domain manager mode */ +#define MI_PPM 0x40000000 /* Set subpage protection */ +#define MI_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ +#define MI_RSV4I 0x08000000 /* Reserve 4 TLB entries */ +#define MI_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ +#define MI_IDXMASK 0x00001f00 /* TLB index to be loaded */ +#define MI_RESETVAL 0x00000000 /* Value of register at reset */ + +/* These are the Ks and Kp from the ppc books. For proper operation, + * Ks = 0, Kp = 1. + */ +#define MI_AP 786 +#define MI_Ks 0x80000000 /* Should not be set */ +#define MI_Kp 0x40000000 /* Should always be set */ + +/* The effective page number register. When read, contains the information + * about the last instruction TLB miss. When MI_RPN is written, bits in + * this register are used to create the TLB entry. + */ +#define MI_EPN 787 +#define MI_EPNMASK 0xfffff000 /* Effective page number for entry */ +#define MI_EVALID 0x00000200 /* Entry is valid */ +#define MI_ASIDMASK 0x0000000f /* ASID match value */ + /* Reset value is undefined */ + +/* A "level 1" or "segment" or whatever you want to call it register. + * For the instruction TLB, it contains bits that get loaded into the + * TLB entry when the MI_RPN is written. + */ +#define MI_TWC 789 +#define MI_APG 0x000001e0 /* Access protection group (0) */ +#define MI_GUARDED 0x00000010 /* Guarded storage */ +#define MI_PSMASK 0x0000000c /* Mask of page size bits */ +#define MI_PS8MEG 0x0000000c /* 8M page size */ +#define MI_PS512K 0x00000004 /* 512K page size */ +#define MI_PS4K_16K 0x00000000 /* 4K or 16K page size */ +#define MI_SVALID 0x00000001 /* Segment entry is valid */ + /* Reset value is undefined */ + +/* Real page number. Defined by the pte. Writing this register + * causes a TLB entry to be created for the instruction TLB, using + * additional information from the MI_EPN, and MI_TWC registers. + */ +#define MI_RPN 790 + +/* Define an RPN value for mapping Kernel memory to large virtual + * pages for boot initialization. This has real page number of 0, + * large page size, shared page, cache enabled, and valid. + * Also mark all subpages valid and write access. + */ +#define MI_BOOTINIT 0x000001fd + +#define MD_CTR 792 /* Data TLB control register */ +#define MD_GPM 0x80000000 /* Set domain manager mode */ +#define MD_PPM 0x40000000 /* Set subpage protection */ +#define MD_CIDEF 0x20000000 /* Set cache inhibit when MMU dis */ +#define MD_WTDEF 0x10000000 /* Set writethrough when MMU dis */ +#define MD_RSV4I 0x08000000 /* Reserve 4 TLB entries */ +#define MD_TWAM 0x04000000 /* Use 4K page hardware assist */ +#define MD_PPCS 0x02000000 /* Use MI_RPN prob/priv state */ +#define MD_IDXMASK 0x00001f00 /* TLB index to be loaded */ +#define MD_RESETVAL 0x04000000 /* Value of register at reset */ + +#define M_CASID 793 /* Address space ID (context) to match */ +#define MC_ASIDMASK 0x0000000f /* Bits used for ASID value */ + +/* These are the Ks and Kp from the ppc books. For proper operation, + * Ks = 0, Kp = 1. + */ +#define MD_AP 794 +#define MD_Ks 0x80000000 /* Should not be set */ +#define MD_Kp 0x40000000 /* Should always be set */ + +/* The effective page number register. When read, contains the information + * about the last instruction TLB miss. When MD_RPN is written, bits in + * this register are used to create the TLB entry. + */ +#define MD_EPN 795 +#define MD_EPNMASK 0xfffff000 /* Effective page number for entry */ +#define MD_EVALID 0x00000200 /* Entry is valid */ +#define MD_ASIDMASK 0x0000000f /* ASID match value */ + /* Reset value is undefined */ + +/* The pointer to the base address of the first level page table. + * During a software tablewalk, reading this register provides the address + * of the entry associated with MD_EPN. + */ +#define M_TWB 796 +#define M_L1TB 0xfffff000 /* Level 1 table base address */ +#define M_L1INDX 0x00000ffc /* Level 1 index, when read */ + /* Reset value is undefined */ + +/* A "level 1" or "segment" or whatever you want to call it register. + * For the data TLB, it contains bits that get loaded into the TLB entry + * when the MD_RPN is written. It is also provides the hardware assist + * for finding the PTE address during software tablewalk. + */ +#define MD_TWC 797 +#define MD_L2TB 0xfffff000 /* Level 2 table base address */ +#define MD_L2INDX 0xfffffe00 /* Level 2 index (*pte), when read */ +#define MD_APG 0x000001e0 /* Access protection group (0) */ +#define MD_GUARDED 0x00000010 /* Guarded storage */ +#define MD_PSMASK 0x0000000c /* Mask of page size bits */ +#define MD_PS8MEG 0x0000000c /* 8M page size */ +#define MD_PS512K 0x00000004 /* 512K page size */ +#define MD_PS4K_16K 0x00000000 /* 4K or 16K page size */ +#define MD_WT 0x00000002 /* Use writethrough page attribute */ +#define MD_SVALID 0x00000001 /* Segment entry is valid */ + /* Reset value is undefined */ + +/* Real page number. Defined by the pte. Writing this register + * causes a TLB entry to be created for the data TLB, using + * additional information from the MD_EPN, and MD_TWC registers. + */ +#define MD_RPN 798 + +/* This is a temporary storage register that could be used to save + * a processor working register during a tablewalk. + */ +#define M_TW 799 + +/* + * At present, all ppc 400-class processors share a similar TLB + * architecture. The instruction and data sides share a unified, + * 64-entry, fully-associative TLB which is maintained totally under + * software control. In addition, the instruction side has a + * hardware-managed, 4-entry, fully- associative TLB which serves as a + * first level to the shared TLB. These two TLBs are known as the UTLB + * and ITLB, respectively. + */ + +#define PPC4XX_TLB_SIZE 64 + +/* + * TLB entries are defined by a "high" tag portion and a "low" data + * portion. On all architectures, the data portion is 32-bits. + * + * TLB entries are managed entirely under software control by reading, + * writing, and searchoing using the 4xx-specific tlbre, tlbwr, and tlbsx + * instructions. + */ + +/* + * FSL Book-E support + */ + +#define MAS0_TLBSEL_MSK 0x30000000 +#define MAS0_TLBSEL(x) (((x) << 28) & MAS0_TLBSEL_MSK) +#define MAS0_ESEL_MSK 0x0FFF0000 +#define MAS0_ESEL(x) (((x) << 16) & MAS0_ESEL_MSK) +#define MAS0_NV(x) ((x) & 0x00000FFF) + +#define MAS1_VALID 0x80000000 +#define MAS1_IPROT 0x40000000 +#define MAS1_TID(x) (((x) << 16) & 0x3FFF0000) +#define MAS1_TS 0x00001000 +#define MAS1_TSIZE(x) (((x) << 7) & 0x00000F80) +#define TSIZE_TO_BYTES(x) (1ULL << ((x) + 10)) + +#define MAS2_EPN 0xFFFFF000 +#define MAS2_X0 0x00000040 +#define MAS2_X1 0x00000020 +#define MAS2_W 0x00000010 +#define MAS2_I 0x00000008 +#define MAS2_M 0x00000004 +#define MAS2_G 0x00000002 +#define MAS2_E 0x00000001 + +#define MAS3_RPN 0xFFFFF000 +#define MAS3_U0 0x00000200 +#define MAS3_U1 0x00000100 +#define MAS3_U2 0x00000080 +#define MAS3_U3 0x00000040 +#define MAS3_UX 0x00000020 +#define MAS3_SX 0x00000010 +#define MAS3_UW 0x00000008 +#define MAS3_SW 0x00000004 +#define MAS3_UR 0x00000002 +#define MAS3_SR 0x00000001 + +#define MAS4_TLBSELD(x) MAS0_TLBSEL(x) +#define MAS4_TIDDSEL 0x000F0000 +#define MAS4_TSIZED(x) MAS1_TSIZE(x) +#define MAS4_X0D 0x00000040 +#define MAS4_X1D 0x00000020 +#define MAS4_WD 0x00000010 +#define MAS4_ID 0x00000008 +#define MAS4_MD 0x00000004 +#define MAS4_GD 0x00000002 +#define MAS4_ED 0x00000001 + +#define MAS6_SPID0 0x3FFF0000 +#define MAS6_SPID1 0x00007FFE +#define MAS6_SAS 0x00000001 +#define MAS6_SPID MAS6_SPID0 + +#define MAS7_RPN 0xFFFFFFFF + +#define FSL_BOOKE_MAS0(tlbsel, esel, nv) \ + (MAS0_TLBSEL(tlbsel) | MAS0_ESEL(esel) | MAS0_NV(nv)) +#define FSL_BOOKE_MAS1(v, iprot, tid, ts, tsize) \ + ((((v) << 31) & MAS1_VALID) | \ + (((iprot) << 30) & MAS1_IPROT) | \ + (MAS1_TID(tid)) | \ + (((ts) << 12) & MAS1_TS) | \ + (MAS1_TSIZE(tsize))) +#define FSL_BOOKE_MAS2(epn, wimge) \ + (((epn) & MAS3_RPN) | (wimge)) +#define FSL_BOOKE_MAS3(rpn, user, perms) \ + (((rpn) & MAS3_RPN) | (user) | (perms)) +#define FSL_BOOKE_MAS7(rpn) \ + (((uint64_t)(rpn)) >> 32) + +#define BOOKE_PAGESZ_1K 0 +#define BOOKE_PAGESZ_2K 1 +#define BOOKE_PAGESZ_4K 2 +#define BOOKE_PAGESZ_8K 3 +#define BOOKE_PAGESZ_16K 4 +#define BOOKE_PAGESZ_32K 5 +#define BOOKE_PAGESZ_64K 6 +#define BOOKE_PAGESZ_128K 7 +#define BOOKE_PAGESZ_256K 8 +#define BOOKE_PAGESZ_512K 9 +#define BOOKE_PAGESZ_1M 10 +#define BOOKE_PAGESZ_2M 11 +#define BOOKE_PAGESZ_4M 12 +#define BOOKE_PAGESZ_8M 13 +#define BOOKE_PAGESZ_16M 14 +#define BOOKE_PAGESZ_32M 15 +#define BOOKE_PAGESZ_64M 16 +#define BOOKE_PAGESZ_128M 17 +#define BOOKE_PAGESZ_256M 18 +#define BOOKE_PAGESZ_512M 19 +#define BOOKE_PAGESZ_1G 20 +#define BOOKE_PAGESZ_2G 21 +#define BOOKE_PAGESZ_4G 22 +#define BOOKE_PAGESZ_8G 23 +#define BOOKE_PAGESZ_16GB 24 +#define BOOKE_PAGESZ_32GB 25 +#define BOOKE_PAGESZ_64GB 26 +#define BOOKE_PAGESZ_128GB 27 +#define BOOKE_PAGESZ_256GB 28 +#define BOOKE_PAGESZ_512GB 29 +#define BOOKE_PAGESZ_1TB 30 +#define BOOKE_PAGESZ_2TB 31 + +#define TLBIVAX_ALL 4 +#define TLBIVAX_TLB0 0 +#define TLBIVAX_TLB1 8 + +#ifdef CONFIG_E500 +#ifndef __ASSEMBLY__ +extern void set_tlb(uint8_t tlb, uint32_t epn, uint64_t rpn, uint8_t perms, uint8_t wimge, uint8_t ts, uint8_t esel, uint8_t tsize, uint8_t iprot); +extern void disable_tlb(uint8_t esel); +extern void invalidate_tlb(uint8_t tlb); +extern void init_tlbs(void); +extern int find_tlb_idx(void* addr, uint8_t tlbsel); +extern void init_used_tlb_cams(void); +extern int find_free_tlbcam(void); +extern void print_tlbcam(void); + +extern unsigned int setup_ddr_tlbs(unsigned int memsize_in_meg); +extern void clear_ddr_tlbs(unsigned int memsize_in_meg); + +enum tlb_map_type +{ + TLB_MAP_RAM, + TLB_MAP_IO, +}; + +extern uint64_t tlb_map_range(ulong_t v_addr, phys_addr_t p_addr, uint64_t size, enum tlb_map_type map_type); + +extern void write_tlb(uint32_t _mas0, uint32_t _mas1, uint32_t _mas2, uint32_t _mas3, uint32_t _mas7); + +#define SET_TLB_ENTRY(_tlb, _epn, _rpn, _perms, _wimge, _ts, _esel, _sz, _iprot) \ + { \ + .mas0 = FSL_BOOKE_MAS0(_tlb, _esel, 0), \ + .mas1 = FSL_BOOKE_MAS1(1, _iprot, 0, _ts, _sz), \ + .mas2 = FSL_BOOKE_MAS2(_epn, _wimge), \ + .mas3 = FSL_BOOKE_MAS3(_rpn, 0, _perms), \ + .mas7 = FSL_BOOKE_MAS7(_rpn), \ + } + +struct fsl_e_tlb_entry +{ + uint32_t mas0; + uint32_t mas1; + uint32_t mas2; + uint32_t mas3; + uint32_t mas7; +}; + +extern struct fsl_e_tlb_entry tlb_table[]; +extern int num_tlb_entries; +#endif +#endif + +#ifdef CONFIG_E300 +#define LAWAR_EN 0x80000000 +#define LAWAR_SIZE 0x0000003F + +#define LAWAR_TRGT_IF_PCI 0x00000000 +#define LAWAR_TRGT_IF_PCI1 0x00000000 +#define LAWAR_TRGT_IF_PCIX 0x00000000 +#define LAWAR_TRGT_IF_PCI2 0x00100000 +#define LAWAR_TRGT_IF_PCIE1 0x00200000 +#define LAWAR_TRGT_IF_PCIE2 0x00100000 +#define LAWAR_TRGT_IF_PCIE3 0x00300000 +#define LAWAR_TRGT_IF_LBC 0x00400000 +#define LAWAR_TRGT_IF_CCSR 0x00800000 +#define LAWAR_TRGT_IF_DDR_INTERLEAVED 0x00B00000 +#define LAWAR_TRGT_IF_RIO 0x00c00000 +#define LAWAR_TRGT_IF_DDR 0x00f00000 +#define LAWAR_TRGT_IF_DDR1 0x00f00000 +#define LAWAR_TRGT_IF_DDR2 0x01600000 + +#define LAWAR_SIZE_BASE 0xa +#define LAWAR_SIZE_4K (LAWAR_SIZE_BASE + 1) +#define LAWAR_SIZE_8K (LAWAR_SIZE_BASE + 2) +#define LAWAR_SIZE_16K (LAWAR_SIZE_BASE + 3) +#define LAWAR_SIZE_32K (LAWAR_SIZE_BASE + 4) +#define LAWAR_SIZE_64K (LAWAR_SIZE_BASE + 5) +#define LAWAR_SIZE_128K (LAWAR_SIZE_BASE + 6) +#define LAWAR_SIZE_256K (LAWAR_SIZE_BASE + 7) +#define LAWAR_SIZE_512K (LAWAR_SIZE_BASE + 8) +#define LAWAR_SIZE_1M (LAWAR_SIZE_BASE + 9) +#define LAWAR_SIZE_2M (LAWAR_SIZE_BASE + 10) +#define LAWAR_SIZE_4M (LAWAR_SIZE_BASE + 11) +#define LAWAR_SIZE_8M (LAWAR_SIZE_BASE + 12) +#define LAWAR_SIZE_16M (LAWAR_SIZE_BASE + 13) +#define LAWAR_SIZE_32M (LAWAR_SIZE_BASE + 14) +#define LAWAR_SIZE_64M (LAWAR_SIZE_BASE + 15) +#define LAWAR_SIZE_128M (LAWAR_SIZE_BASE + 16) +#define LAWAR_SIZE_256M (LAWAR_SIZE_BASE + 17) +#define LAWAR_SIZE_512M (LAWAR_SIZE_BASE + 18) +#define LAWAR_SIZE_1G (LAWAR_SIZE_BASE + 19) +#define LAWAR_SIZE_2G (LAWAR_SIZE_BASE + 20) +#define LAWAR_SIZE_4G (LAWAR_SIZE_BASE + 21) +#define LAWAR_SIZE_8G (LAWAR_SIZE_BASE + 22) +#define LAWAR_SIZE_16G (LAWAR_SIZE_BASE + 23) +#define LAWAR_SIZE_32G (LAWAR_SIZE_BASE + 24) +#endif + +#ifdef CONFIG_440 +/* General */ +#define TLB_VALID 0x00000200 + +/* Supported page sizes */ + +#define SZ_1K 0x00000000 +#define SZ_4K 0x00000010 +#define SZ_16K 0x00000020 +#define SZ_64K 0x00000030 +#define SZ_256K 0x00000040 +#define SZ_1M 0x00000050 +#define SZ_16M 0x00000070 +#define SZ_256M 0x00000090 + +/* Storage attributes */ +#define SA_W 0x00000800 /* Write-through */ +#define SA_I 0x00000400 /* Caching inhibited */ +#define SA_M 0x00000200 /* Memory coherence */ +#define SA_G 0x00000100 /* Guarded */ +#define SA_E 0x00000080 /* Endian */ +/* Some additional macros for combinations often used */ +#define SA_IG (SA_I | SA_G) + +/* Access control */ +#define AC_X 0x00000024 /* Execute */ +#define AC_W 0x00000012 /* Write */ +#define AC_R 0x00000009 /* Read */ +/* Some additional macros for combinations often used */ +#define AC_RW (AC_R | AC_W) +#define AC_RWX (AC_R | AC_W | AC_X) + +/* Some handy macros */ + +#define EPN(e) ((e) & 0xfffffc00) +#define TLB0(epn, sz) ((EPN((epn)) | (sz) | TLB_VALID)) +#define TLB1(rpn, erpn) (((rpn) & 0xfffffc00) | (erpn)) +#define TLB2(a) ((a) & 0x00000fbf) + +#define tlbtab_start \ + mflr r1; \ + bl 0f; + +#define tlbtab_end \ + .long 0, 0, 0; \ + 0 : mflr r0; \ + mtlr r1; \ + blr; + +#define tlbentry(epn, sz, rpn, erpn, attr) \ + .long TLB0(epn, sz), TLB1(rpn, erpn), TLB2(attr) + +/*----------------------------------------------------------------------------+ +| TLB specific defines. ++----------------------------------------------------------------------------*/ +#define TLB_256MB_ALIGN_MASK 0xFF0000000ULL +#define TLB_16MB_ALIGN_MASK 0xFFF000000ULL +#define TLB_1MB_ALIGN_MASK 0xFFFF00000ULL +#define TLB_256KB_ALIGN_MASK 0xFFFFC0000ULL +#define TLB_64KB_ALIGN_MASK 0xFFFFF0000ULL +#define TLB_16KB_ALIGN_MASK 0xFFFFFC000ULL +#define TLB_4KB_ALIGN_MASK 0xFFFFFF000ULL +#define TLB_1KB_ALIGN_MASK 0xFFFFFFC00ULL +#define TLB_256MB_SIZE 0x10000000 +#define TLB_16MB_SIZE 0x01000000 +#define TLB_1MB_SIZE 0x00100000 +#define TLB_256KB_SIZE 0x00040000 +#define TLB_64KB_SIZE 0x00010000 +#define TLB_16KB_SIZE 0x00004000 +#define TLB_4KB_SIZE 0x00001000 +#define TLB_1KB_SIZE 0x00000400 + +#define TLB_WORD0_EPN_MASK 0xFFFFFC00 +#define TLB_WORD0_EPN_ENCODE(n) (((unsigned long)(n)) & 0xFFFFFC00) +#define TLB_WORD0_EPN_DECODE(n) (((unsigned long)(n)) & 0xFFFFFC00) +#define TLB_WORD0_V_MASK 0x00000200 +#define TLB_WORD0_V_ENABLE 0x00000200 +#define TLB_WORD0_V_DISABLE 0x00000000 +#define TLB_WORD0_TS_MASK 0x00000100 +#define TLB_WORD0_TS_1 0x00000100 +#define TLB_WORD0_TS_0 0x00000000 +#define TLB_WORD0_SIZE_MASK 0x000000F0 +#define TLB_WORD0_SIZE_1KB 0x00000000 +#define TLB_WORD0_SIZE_4KB 0x00000010 +#define TLB_WORD0_SIZE_16KB 0x00000020 +#define TLB_WORD0_SIZE_64KB 0x00000030 +#define TLB_WORD0_SIZE_256KB 0x00000040 +#define TLB_WORD0_SIZE_1MB 0x00000050 +#define TLB_WORD0_SIZE_16MB 0x00000070 +#define TLB_WORD0_SIZE_256MB 0x00000090 +#define TLB_WORD0_TPAR_MASK 0x0000000F +#define TLB_WORD0_TPAR_ENCODE(n) ((((unsigned long)(n)) & 0x0F) << 0) +#define TLB_WORD0_TPAR_DECODE(n) ((((unsigned long)(n)) >> 0) & 0x0F) + +#define TLB_WORD1_RPN_MASK 0xFFFFFC00 +#define TLB_WORD1_RPN_ENCODE(n) (((unsigned long)(n)) & 0xFFFFFC00) +#define TLB_WORD1_RPN_DECODE(n) (((unsigned long)(n)) & 0xFFFFFC00) +#define TLB_WORD1_PAR1_MASK 0x00000300 +#define TLB_WORD1_PAR1_ENCODE(n) ((((unsigned long)(n)) & 0x03) << 8) +#define TLB_WORD1_PAR1_DECODE(n) ((((unsigned long)(n)) >> 8) & 0x03) +#define TLB_WORD1_PAR1_0 0x00000000 +#define TLB_WORD1_PAR1_1 0x00000100 +#define TLB_WORD1_PAR1_2 0x00000200 +#define TLB_WORD1_PAR1_3 0x00000300 +#define TLB_WORD1_ERPN_MASK 0x0000000F +#define TLB_WORD1_ERPN_ENCODE(n) ((((unsigned long)(n)) & 0x0F) << 0) +#define TLB_WORD1_ERPN_DECODE(n) ((((unsigned long)(n)) >> 0) & 0x0F) + +#define TLB_WORD2_PAR2_MASK 0xC0000000 +#define TLB_WORD2_PAR2_ENCODE(n) ((((unsigned long)(n)) & 0x03) << 30) +#define TLB_WORD2_PAR2_DECODE(n) ((((unsigned long)(n)) >> 30) & 0x03) +#define TLB_WORD2_PAR2_0 0x00000000 +#define TLB_WORD2_PAR2_1 0x40000000 +#define TLB_WORD2_PAR2_2 0x80000000 +#define TLB_WORD2_PAR2_3 0xC0000000 +#define TLB_WORD2_U0_MASK 0x00008000 +#define TLB_WORD2_U0_ENABLE 0x00008000 +#define TLB_WORD2_U0_DISABLE 0x00000000 +#define TLB_WORD2_U1_MASK 0x00004000 +#define TLB_WORD2_U1_ENABLE 0x00004000 +#define TLB_WORD2_U1_DISABLE 0x00000000 +#define TLB_WORD2_U2_MASK 0x00002000 +#define TLB_WORD2_U2_ENABLE 0x00002000 +#define TLB_WORD2_U2_DISABLE 0x00000000 +#define TLB_WORD2_U3_MASK 0x00001000 +#define TLB_WORD2_U3_ENABLE 0x00001000 +#define TLB_WORD2_U3_DISABLE 0x00000000 +#define TLB_WORD2_W_MASK 0x00000800 +#define TLB_WORD2_W_ENABLE 0x00000800 +#define TLB_WORD2_W_DISABLE 0x00000000 +#define TLB_WORD2_I_MASK 0x00000400 +#define TLB_WORD2_I_ENABLE 0x00000400 +#define TLB_WORD2_I_DISABLE 0x00000000 +#define TLB_WORD2_M_MASK 0x00000200 +#define TLB_WORD2_M_ENABLE 0x00000200 +#define TLB_WORD2_M_DISABLE 0x00000000 +#define TLB_WORD2_G_MASK 0x00000100 +#define TLB_WORD2_G_ENABLE 0x00000100 +#define TLB_WORD2_G_DISABLE 0x00000000 +#define TLB_WORD2_E_MASK 0x00000080 +#define TLB_WORD2_E_ENABLE 0x00000080 +#define TLB_WORD2_E_DISABLE 0x00000000 +#define TLB_WORD2_UX_MASK 0x00000020 +#define TLB_WORD2_UX_ENABLE 0x00000020 +#define TLB_WORD2_UX_DISABLE 0x00000000 +#define TLB_WORD2_UW_MASK 0x00000010 +#define TLB_WORD2_UW_ENABLE 0x00000010 +#define TLB_WORD2_UW_DISABLE 0x00000000 +#define TLB_WORD2_UR_MASK 0x00000008 +#define TLB_WORD2_UR_ENABLE 0x00000008 +#define TLB_WORD2_UR_DISABLE 0x00000000 +#define TLB_WORD2_SX_MASK 0x00000004 +#define TLB_WORD2_SX_ENABLE 0x00000004 +#define TLB_WORD2_SX_DISABLE 0x00000000 +#define TLB_WORD2_SW_MASK 0x00000002 +#define TLB_WORD2_SW_ENABLE 0x00000002 +#define TLB_WORD2_SW_DISABLE 0x00000000 +#define TLB_WORD2_SR_MASK 0x00000001 +#define TLB_WORD2_SR_ENABLE 0x00000001 +#define TLB_WORD2_SR_DISABLE 0x00000000 + +/*----------------------------------------------------------------------------+ +| Following instructions are not available in Book E mode of the GNU assembler. ++----------------------------------------------------------------------------*/ +#define DCCCI(ra, rb) .long 0x7c000000 | \ + (ra << 16) | (rb << 11) | (454 << 1) + +#define ICCCI(ra, rb) .long 0x7c000000 | \ + (ra << 16) | (rb << 11) | (966 << 1) + +#define DCREAD(rt, ra, rb) .long 0x7c000000 | (rt << 21) | (ra << 16) | (rb << 11) | (486 << 1) + +#define ICREAD(ra, rb) .long 0x7c000000 | \ + (ra << 16) | (rb << 11) | (998 << 1) + +#define TLBSX(rt, ra, rb) .long 0x7c000000 | (rt << 21) | (ra << 16) | (rb << 11) | (914 << 1) + +#define TLBWE(rs, ra, ws) .long 0x7c000000 | (rs << 21) | (ra << 16) | (ws << 11) | (978 << 1) + +#define TLBRE(rt, ra, ws) .long 0x7c000000 | (rt << 21) | (ra << 16) | (ws << 11) | (946 << 1) + +#define TLBSXDOT(rt, ra, rb) .long 0x7c000001 | (rt << 21) | (ra << 16) | (rb << 11) | (914 << 1) + +#define MSYNC .long 0x7c000000 | \ + (598 << 1) + +#define MBAR_INST .long 0x7c000000 | \ + (854 << 1) + +#ifndef __ASSEMBLY__ +/* Prototypes */ +void mttlb1(unsigned long index, unsigned long value); +void mttlb2(unsigned long index, unsigned long value); +void mttlb3(unsigned long index, unsigned long value); +unsigned long mftlb1(unsigned long index); +unsigned long mftlb2(unsigned long index); +unsigned long mftlb3(unsigned long index); + +void program_tlb(uint64_t phys_addr, uint32_t virt_addr, uint32_t size, uint32_t tlb_word2_i_value); +void remove_tlb(uint32_t vaddr, uint32_t size); +void change_tlb(uint32_t vaddr, uint32_t size, uint32_t tlb_word2_i_value); +#endif /* __ASSEMBLY__ */ + +#endif /* CONFIG_440 */ +#endif /* _PPC_MMU_H_ */ diff --git a/dev/Kernel/HALKit/RISCV/.keep b/dev/Kernel/HALKit/RISCV/.keep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/RISCV/APM/.gitkeep b/dev/Kernel/HALKit/RISCV/APM/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/RISCV/Hart.hxx b/dev/Kernel/HALKit/RISCV/Hart.hxx new file mode 100644 index 00000000..0f5e021e --- /dev/null +++ b/dev/Kernel/HALKit/RISCV/Hart.hxx @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: Hart.hxx + Purpose: RISC-V hardware threads. + + Revision History: + + 30/01/24: Added file (amlel) + +------------------------------------------- */ + +#pragma once + +#include + +typedef Kernel::Int32 Rv64HartType; + +/// @brief Set PC to specific hart. +/// @param hart the hart +/// @param epc the pc. +/// @return +EXTERN_C Kernel::Void hal_set_pc_to_hart(Rv64HartType hart, Kernel::VoidPtr epc); diff --git a/dev/Kernel/HALKit/RISCV/ReadMe.md b/dev/Kernel/HALKit/RISCV/ReadMe.md new file mode 100644 index 00000000..b099aa31 --- /dev/null +++ b/dev/Kernel/HALKit/RISCV/ReadMe.md @@ -0,0 +1,4 @@ +RISCV64 Hardware Abstraction Layer + +- Supported CPU: RISCV64 +- Supported Firmware: CoreBoot \ No newline at end of file diff --git a/dev/Kernel/HALKit/RISCV/Storage/.gitkeep b/dev/Kernel/HALKit/RISCV/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/.gitkeep b/dev/Kernel/HALKit/X86S/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/ACPI/.gitkeep b/dev/Kernel/HALKit/X86S/ACPI/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/X86S/Storage/.gitkeep b/dev/Kernel/HALKit/X86S/Storage/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/dev/Kernel/HALKit/compile_flags.txt b/dev/Kernel/HALKit/compile_flags.txt new file mode 100644 index 00000000..26779833 --- /dev/null +++ b/dev/Kernel/HALKit/compile_flags.txt @@ -0,0 +1,6 @@ +-nostdlib +-ffreestanding +-std=c++20 +-I./ +-I../ +-D__NEWOS_AMD64__ -- cgit v1.2.3