diff --git a/source/kernel/drivers/ide/ide.h b/source/kernel/drivers/ide/ide.h index e7195de..1a1310d 100644 --- a/source/kernel/drivers/ide/ide.h +++ b/source/kernel/drivers/ide/ide.h @@ -56,7 +56,7 @@ inline void TestIDEController(){ int device =1 , function = 1; PCIBusAddress IDEControllerPCIAddress = PCIBusAddress{bus,device, function}; - uint8_t ProgIF = GetProgIF(IDEControllerPCIAddress); + uint8_t ProgIF = PCI::GetProgIF(IDEControllerPCIAddress); printf( "ProgIF: 0x%x\n" ,ProgIF); //CheckProgIF(ProgIF); @@ -66,15 +66,15 @@ inline void TestIDEController(){ uint32_t BAR0,BAR1,BAR2,BAR3, BAR4; - BAR0 = ReadBAR(IDEControllerPCIAddress, 0); + BAR0 = PCI::ReadBAR(IDEControllerPCIAddress, 0); - BAR1 = ReadBAR(IDEControllerPCIAddress, 1); + BAR1 = PCI::ReadBAR(IDEControllerPCIAddress, 1); - BAR2 = ReadBAR(IDEControllerPCIAddress, 2); + BAR2 = PCI::ReadBAR(IDEControllerPCIAddress, 2); - BAR3 = ReadBAR(IDEControllerPCIAddress, 3); + BAR3 = PCI::ReadBAR(IDEControllerPCIAddress, 3); - BAR4 = ReadBAR(IDEControllerPCIAddress, 4); + BAR4 = PCI::ReadBAR(IDEControllerPCIAddress, 4); // All bars are return 0xffffff for some as of yet mysterious reason! printf( "BAR 0: 0x%x\n", BAR0); diff --git a/source/kernel/drivers/pci/pci.cpp b/source/kernel/drivers/pci/pci.cpp index 25c5f45..ba0fade 100644 --- a/source/kernel/drivers/pci/pci.cpp +++ b/source/kernel/drivers/pci/pci.cpp @@ -1,107 +1,66 @@ #include "pci.h" -#define PCI_BUS_ADDR_SHIFT 16 -#define PCI_DEVICE_ADDR_SHIFT 11 -#define PCI_FUNCTION_ADDR_SHIFT 8 -#define PCI_ENABLE_ADDR_SHIFT 31 +void PCI::Scan(){ + + int devicesFound = 0; -const char* GetClassCodeName (uint64_t ClassCode ) { - - switch (ClassCode) - { - case 0x0 : - return "Unclassified"; - break; + printf("Start finding devices, Found: %d devices"); + // loop through all possible busses, devices and their functions; + for( int bus = 0 ; bus < 256 ; bus++) + { + + for(int device = 0; device < 32 ; device ++) + { + int function = 0; - case 0x1: - return "Mass Storage Controller"; - break; + uint64_t DeviceIdentify = PCI::ConfigReadWord(bus, device, function,0x0); + uint32_t DeviceID = GetDevice(bus, device, function) >> 16; - case 0x2: - return "Network Controller"; - break; + if( DeviceID != 0xFFFF){ + PCIBusAddress busAddress = + PCIBusAddress{bus, device, function }; - case 0x3: - return "Display Controller"; - break; + PrintPCIDevice(busAddress); - case 0x4: - return "Multimedia Controller"; - break; + // iterate over the functions if it is a multi function device! + if( PCI::IsMultiFunctionDevice(busAddress) ){ + printf("Multi function device! \n"); + printf("Check remaining Functions\n"); + for ( function = 1 ; function < 8; function++) + { + uint32_t DeviceID = GetDevice(bus, device, function) >> 16; - case 0x5: - return "Memory Controller"; - break; - - case 0x6: - return "Bridge"; - break; + if( DeviceID != 0xFFFF){ + PCIBusAddress busAddress2 = PCIBusAddress{bus, device, function}; + PrintPCIDevice(busAddress2); + devicesFound++; + } + } + + } - case 0x7 : - return "Simple Communication Controller"; - break; - - case 0x8: - return "Base System Peripheral"; - break; - - case 0x9: - return "Input Device Controller"; - break; - - case 0xA: - return "Docking station"; - break; - case 0xB: - return "Processor"; - break; - - case 0xC: - return "Serial Bus Controller"; - break; - - case 0xD: - return "Wireless Controller"; - break; - - case 0xE: - return "Intelligent Controller"; - break; - - case 0xF: - return "Satellite Communication Controller"; - break; - - case 0x10: - return "Encryption Controller"; - break; - - case 0x11: - return "Signal Processing Controller"; - break; - - case 0x12: - return "Processing Accelerator"; - break; - - case 0x13: - return "Non-Essential Instrumentation"; - break; - - default: - return "Unknown"; - break; + + devicesFound++; + } + } + } - + + printf("Found %d PCI devices!\n", devicesFound); } -const char* getVendor( uint32_t VendorID){ +const char* PCI::getClassName (uint8_t ClassCode){ + bool isKnown = (ClassCode < PCI::KnownClassCodes); + return isKnown ? PCI::ClassCodeNames[ClassCode].name : "Unknown ClassCode"; +} + +const char* PCI::getVendor( uint32_t VendorID){ switch (VendorID) { case 0x8086: return "Intel Corporation"; break; - + case 0x10DE: return "NVIDIA Corporation"; break; @@ -129,125 +88,77 @@ const char* getVendor( uint32_t VendorID){ } -uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset){ - outl(CONFIG_ADDRESS , PCIDeviceAddress.getAddress() | offset ); +uint64_t PCI::GetDevice (int bus, int device, int function ){ + return PCI::ConfigReadWord(bus, device, function,0x0); +} + +bool PCI::IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress) +{ + uint32_t header_information = ConfigReadWord(PCIDeviceAddress, 0xC); + return (((header_information>>16) + & 0x80) + >> 7 ); +} + +uint16_t PCI::GetClassCodes( PCIBusAddress& PCIDeviceAddress ){ + return (uint16_t)(ConfigReadWord(PCIDeviceAddress, 0x8) >> 16); +} + +uint8_t PCI::GetHeaderType( PCIBusAddress& PCIDeviceAddress ){ + uint32_t header_information = ConfigReadWord(PCIDeviceAddress , 0xC); + return (uint8_t) ( + ((header_information >> 16) //Get higher half + & 0x00FF) // Select the last two bytes + & 0x7F ); // Mask bit 7 as it indicates if the device is a mulit function device! +} + +uint32_t PCI::ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset){ + uint32_t address; + + address = (uint32_t) ( + ((uint32_t) 1 << PCI_ENABLE_ADDR_SHIFT) | + ((uint32_t)bus << PCI_BUS_ADDR_SHIFT) | + ((uint32_t)device << PCI_DEVICE_ADDR_SHIFT) | + ((uint32_t)func << PCI_FUNCTION_ADDR_SHIFT) | + offset ); + + outl(CONFIG_ADDRESS, address); + + return inl(CONFIG_DATA); } -uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress){ +uint8_t PCI::GetProgIF (PCIBusAddress& PCIDeviceAddress){ uint32_t data = ConfigReadWord(PCIDeviceAddress, 0x8); return ((data >> 8) & 0xFF); } -uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number){ - int offsetToBar = 0x10 + (bar_number* 0x4); - return ConfigReadWord(PCIDeviceAddress, offsetToBar); -} - -uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset){ - uint32_t address; - - address = (uint32_t) ( - ((uint32_t) 1 << PCI_ENABLE_ADDR_SHIFT) | - ((uint32_t)bus << PCI_BUS_ADDR_SHIFT) | - ((uint32_t)device << PCI_DEVICE_ADDR_SHIFT) | - ((uint32_t)func << PCI_FUNCTION_ADDR_SHIFT) | - offset ); - - outl(CONFIG_ADDRESS, address); - - +uint32_t PCI::ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset){ + outl(CONFIG_ADDRESS , PCIDeviceAddress.getAddress() | offset ); return inl(CONFIG_DATA); } -uint8_t GetHeaderType( PCIBusAddress& PCIDeviceAddress ){ - uint32_t header_information = ConfigReadWord(PCIDeviceAddress , 0xC); - return (uint8_t) ( - ((header_information >> 16) //Get higher half - & 0x00FF) // Select the last two bytes - & 0x7F ); // Mask bit 7 as it indicates if the device is a mulit function device! + +uint32_t PCI::ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number){ + int offsetToBar = 0x10 + (bar_number* 0x4); + return ConfigReadWord(PCIDeviceAddress, offsetToBar); } -uint16_t GetClassCodes( PCIBusAddress& PCIDeviceAddress ){ - uint32_t classcodes = ConfigReadWord(PCIDeviceAddress, 0x8); - return (uint16_t)((uint32_t)classcodes >> 16); - -} - -bool IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress){ - uint32_t header_information = ConfigReadWord(PCIDeviceAddress, 0xC); - return (((header_information>>16) - & 0x80) - >> 7 ); -} - -void PrintPCIDeviceInfo (PCIBusAddress& PCIDeviceAddress) +void PCI::PrintPCIDevice (PCIBusAddress& PCIDeviceAddress) { - uint32_t DeviceID = (GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) >> 16); - uint32_t VendorID = GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) & 0xFFFF; + uint32_t DeviceID = (PCI::GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) >> 16); + uint32_t VendorID = PCI::GetDevice(PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function) & 0xFFFF; printf("Device found!\n"); printf("Bus: %d, Device: %d, function: %d \n", PCIDeviceAddress.bus, PCIDeviceAddress.device, PCIDeviceAddress.function); - printf("DeviceID: 0x%x, Vendor: %s\n", - DeviceID - , getVendor(VendorID) ); + printf("DeviceID: 0x%x, Vendor: %s\n", + DeviceID + , PCI::getVendor(VendorID) ); - - - - uint8_t header_type = GetHeaderType(PCIDeviceAddress); + uint8_t header_type = PCI::GetHeaderType(PCIDeviceAddress); printf( "Header type: 0x%x\n", header_type); - uint16_t deviceClasses = GetClassCodes(PCIDeviceAddress); - printf("class: %s, subClass: %d\n\n", GetClassCodeName((deviceClasses >>8)), deviceClasses & 0xFF); + uint16_t deviceClasses = PCI::GetClassCodes(PCIDeviceAddress); -} - -void PCI_Enumerate(){ - - int devicesFound = 0; - - printf("Start finding devices, Found: %d devices"); - // loop through all possible busses, devices and their functions; - for( int bus = 0 ; bus < 256 ; bus++) - { - - for(int device = 0; device < 32 ; device ++) - { - int function = 0; - - uint64_t DeviceIdentify = ConfigReadWord(bus, device, function,0x0); - uint32_t DeviceID = GetDevice(bus, device, function) >> 16; - - if( DeviceID != 0xFFFF){ - PCIBusAddress busAddress = - PCIBusAddress{bus, device, function }; - - PrintPCIDeviceInfo(busAddress); - - // iterate over the functions if it is a multi function device! - if( IsMultiFunctionDevice(busAddress) ){ - printf("Multi function device! \n"); - printf("Check remaining Functions\n"); - for ( function = 1 ; function < 8; function++) - { - uint32_t DeviceID = GetDevice(bus, device, function) >> 16; - - if( DeviceID != 0xFFFF){ - PCIBusAddress busAddress2 = PCIBusAddress{bus, device, function}; - PrintPCIDeviceInfo(busAddress2); - devicesFound++; - } - } - - } - - - devicesFound++; - } - } - - } - - printf("Found %d PCI devices!\n", devicesFound); -} + printf("class: %s, subClass: %d\n\n", PCI::getClassName((deviceClasses >> 8)), deviceClasses & 0xFF); +} \ No newline at end of file diff --git a/source/kernel/drivers/pci/pci.h b/source/kernel/drivers/pci/pci.h index 7e60de4..e46a77e 100644 --- a/source/kernel/drivers/pci/pci.h +++ b/source/kernel/drivers/pci/pci.h @@ -7,30 +7,55 @@ // Configuration Space Access Mechanism #1 #define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed #define CONFIG_DATA 0xCFC // Will do the actual configuration operation +#define PCI_BUS_ADDR_SHIFT 16 +#define PCI_DEVICE_ADDR_SHIFT 11 +#define PCI_FUNCTION_ADDR_SHIFT 8 +#define PCI_ENABLE_ADDR_SHIFT 31 -extern const char* ClassCodeTable [0x13]; +class PCI { +public: + static void Scan(); + static uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset); + static uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress); + static uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number); + static uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset); + static uint8_t GetHeaderType( PCIBusAddress& PCIDeviceAddress ); + static uint16_t GetClassCodes( PCIBusAddress& PCIDeviceAddress ); + static bool IsMultiFunctionDevice(PCIBusAddress& PCIDeviceAddress); + static uint64_t GetDevice (int bus, int device, int function ); -// Note: this could be used to make the api for receiving PCI class codes a bit -// nicer. -struct ClassCodes { - uint8_t ClassCode; - uint8_t DeviceClass; -}__attribute__((packed)); -uint32_t ConfigReadWord (uint8_t bus, uint8_t device, uint8_t func, uint8_t offset); -uint32_t ConfigReadWord ( PCIBusAddress& PCIDeviceAddress , uint8_t offset); + static const char* getClassName (uint8_t ClassCode); + static const char* getVendor( uint32_t VendorID); + static void PrintPCIDevice(PCIBusAddress& PCIDevice); - inline uint64_t GetDevice (int bus, int device, int function ){ - return ConfigReadWord(bus, device, function,0x0); - } +private: + struct ClassCode { + const char* name; + uint8_t code; + }; + static constexpr ClassCode ClassCodeNames []= { + {"Unclassified", 0x0}, + {"MassStorage Controller", 0x1}, + {"Network Controller", 0x2}, + {"Display Controller", 0x3}, + {"Multimedia Controller", 0x4}, + {"Memory Controller", 0x5}, + {"Bridge", 0x6}, + {"Simple Communication Controller", 0x7}, + {"Base System Peripheral", 0x8}, + {"Input Device Controller", 0x9}, + {"Docking Station", 0xA}, + {"Processor", 0xB}, + {"Serial Bus Controller", 0xC}, + { "Wireless Controller", 0xD}, + {"Intelligent Controller", 0xE}, + {"Satellite Communication Controller", 0xF}, + {"Encryption Controller", 0x10}, + {"Signal Processing Controller", 0x11}, + { "Processing Accelerator", 0x12}, + { "Non-Essential Instrumentation", 0x13} + }; + static const uint8_t KnownClassCodes = sizeof(ClassCodeNames) / sizeof(ClassCode); +}; -uint8_t GetHeaderType( PCIBusAddress& PCIDeviceAddress ); - -uint16_t GetClassCodes( PCIBusAddress& PICDeviceAddress ); -const char* getVendor( uint64_t VendorID); -const char* GetClassCodeName (uint64_t ClassCode ); - -uint8_t GetProgIF (PCIBusAddress& PCIDeviceAddress); -void PCI_Enumerate(); - -uint32_t ReadBAR ( PCIBusAddress& PCIDeviceAddress, int bar_number); \ No newline at end of file diff --git a/source/kernel/kernel.cpp b/source/kernel/kernel.cpp index f2d056f..62a3ff0 100644 --- a/source/kernel/kernel.cpp +++ b/source/kernel/kernel.cpp @@ -1,22 +1,16 @@ - -extern "C" -{ - #include "../lib/include/string.h" +/* + Copyright © Nigel Barink 2023 +*/ +extern "C"{ +#include "../lib/include/string.h" } -#include "prekernel/bootstructure.h" - #include "memory/memory.h" -#include "memory/memoryinfo.h" -#include "memory/memory.h" -#include "memory/VirtualMemoryManager.h" #include "memory/KernelHeap.h" #include "memory/gdt/gdtc.h" #include "memory/TaskStateSegment.h" - #include "supervisorterminal/superVisorTerminal.h" -#include "drivers/io/io.h" #include "drivers/vga/VBE.h" #include "drivers/pci/pci.h" #include "drivers/pit/pit.h" @@ -24,59 +18,50 @@ extern "C" #include "drivers/ide/ide.h" #include "terminal/kterm.h" - -#include "prekernel/multiboot.h" -#include "bootinfo.h" - -#include "bootcheck.h" - #include "interrupts/idt.h" -#include "time.h" -#include "cpu.h" #include "serial.h" -#include "time.h" -#include "definitions.h" extern "C" void LoadGlobalDescriptorTable(); - -/* - Copyright © Nigel Barink 2023 -*/ - -extern "C" void kernel_main () +void set_protected_bit() { - /* - * Show a little banner for cuteness - */ - printf("|=== BarinkOS ===|\n"); - startSuperVisorTerminal(); -} + // Set the protected bit of control register 0 + // this will put the CPU into protected mode + // NOTE: This should really be a assembly procedure + // We cant directly write to control register 0 + // therefor we copy the value of control register 0 into eax + // once we are done manipulating the value we write the value in + // eax back to control register 0 -extern "C" void early_main() + asm volatile("mov %cr0, %eax "); + asm volatile("or $1, %eax"); + asm volatile("mov %eax, %cr0"); +} + +extern "C" void kernel () { + init_serial(); kterm_init(); - setup_tss(); initGDT(); initidt(); LoadGlobalDescriptorTable(); flush_tss(); printf("Memory setup complete!\n"); - + // Enable interrupts asm volatile("STI"); + initHeap(); + + pit_initialise(); ACPI::initialize(); - PCI_Enumerate(); + PCI::Scan(); - TestIDEController(); - - initHeap(); + TestIDEController(); printf("Enable Protected mode and jump to kernel main\n"); - // Set the protected bit of control register 0 // this will put the CPU into protected mode @@ -92,6 +77,4 @@ extern "C" void early_main() pit_initialise(); - kernel_main(); - -} +} \ No newline at end of file