uh save this
This commit is contained in:
		
							parent
							
								
									516329d25c
								
							
						
					
					
						commit
						4334e21878
					
				| @ -8,7 +8,7 @@ lw_project(lcrash | |||||||
| enable_language(ASM) | enable_language(ASM) | ||||||
| 
 | 
 | ||||||
| lw_add_executable(lcrashkern | lw_add_executable(lcrashkern | ||||||
| 	SOURCES main.c cmdline.c util.c lnxboot.c math.c debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c driver/sysbus.c | 	SOURCES main.c cmdline.c util.c lnxboot.c math.c debug/debug.c acpi/acpi.c efi/efi.c efi/guid.c efi/memmap.c gdb/gdb.c pci/pci.c mm/phys.c mm/kmalloc.c mm/virt.c driver/sysbus.c | ||||||
| ) | ) | ||||||
| add_executable(lcrashkernld IMPORTED) | add_executable(lcrashkernld IMPORTED) | ||||||
| set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) | set_property(TARGET lcrashkernld PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lcrash.ld) | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ struct DebugExtendedDebugInformationBlock* DebugEDIB = 0; | |||||||
| struct GdbDataBlock* DebugGDB = (struct GdbDataBlock*)0x100000; | struct GdbDataBlock* DebugGDB = (struct GdbDataBlock*)0x100000; | ||||||
| 
 | 
 | ||||||
| int DebugInitialize() { | int DebugInitialize() { | ||||||
| 	DebugEDIB = KernelHeapAlloc(sizeof(struct DebugExtendedDebugInformationBlock), 0); | 	DebugEDIB = KernelHeapAlloc(sizeof(struct DebugExtendedDebugInformationBlock), 1, 0); | ||||||
| 	if (DebugEDIB == 0) return -1; | 	if (DebugEDIB == 0) return -1; | ||||||
| 
 | 
 | ||||||
| 	DebugGDB->EDIB = DebugEDIB; | 	DebugGDB->EDIB = DebugEDIB; | ||||||
|  | |||||||
| @ -10,10 +10,10 @@ struct SysbusDevice* SysbusRootDevice = 0; | |||||||
|  * Create a new device description |  * Create a new device description | ||||||
|  */ |  */ | ||||||
| struct SysbusDeviceDescription* SysbusCreateDeviceDescriptionInternal() { | struct SysbusDeviceDescription* SysbusCreateDeviceDescriptionInternal() { | ||||||
| 	struct SysbusDeviceDescription* Description = KernelHeapAlloc(sizeof(struct SysbusDeviceDescription), 0); | 	struct SysbusDeviceDescription* Description = KernelHeapAlloc(sizeof(struct SysbusDeviceDescription), 1, 0); | ||||||
| 
 | 
 | ||||||
| 	Description->DeviceName = 0; | 	Description->DeviceName = 0; | ||||||
| 	Description->Instances = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 0); | 	Description->Instances = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 1, 0); | ||||||
| 	Description->InstanceCount = 0; | 	Description->InstanceCount = 0; | ||||||
| 	Description->InstanceSlots = 4; | 	Description->InstanceSlots = 4; | ||||||
| 	Description->CreateDevice = 0; | 	Description->CreateDevice = 0; | ||||||
| @ -29,7 +29,7 @@ struct SysbusDeviceDescription* SysbusCreateDeviceDescriptionInternal() { | |||||||
| void SysbusAttachChildDeviceInternal(struct SysbusDevice* Parent, struct SysbusDevice* Child) { | void SysbusAttachChildDeviceInternal(struct SysbusDevice* Parent, struct SysbusDevice* Child) { | ||||||
| 	// See if we need to grow the list
 | 	// See if we need to grow the list
 | ||||||
| 	if (Parent->ChildCount >= Parent->ChildSlots) { | 	if (Parent->ChildCount >= Parent->ChildSlots) { | ||||||
| 		struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Parent->ChildSlots * 2, 0); | 		struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Parent->ChildSlots * 2, 1, 0); | ||||||
| 		for (int i = 0; i < Parent->ChildCount; i++) { | 		for (int i = 0; i < Parent->ChildCount; i++) { | ||||||
| 			NewList[i] = Parent->Children[i]; | 			NewList[i] = Parent->Children[i]; | ||||||
| 		} | 		} | ||||||
| @ -59,12 +59,12 @@ struct SysbusDevice* SysbusCreateDeviceInternal( | |||||||
| 	void* DeviceData, | 	void* DeviceData, | ||||||
| 	bool IsRootDevice | 	bool IsRootDevice | ||||||
| ) { | ) { | ||||||
| 	struct SysbusDevice* Device = KernelHeapAlloc(sizeof(struct SysbusDevice), 0); | 	struct SysbusDevice* Device = KernelHeapAlloc(sizeof(struct SysbusDevice), 1, 0); | ||||||
| 	Device->DeviceDescription = Description; | 	Device->DeviceDescription = Description; | ||||||
| 	Device->DeviceName = 0; | 	Device->DeviceName = 0; | ||||||
| 	Device->DeviceData = 0; | 	Device->DeviceData = 0; | ||||||
| 	Device->Parent = Parent; | 	Device->Parent = Parent; | ||||||
| 	Device->Children = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 0); | 	Device->Children = KernelHeapAlloc(sizeof(struct SysbusDevice*) * 4, 1, 0); | ||||||
| 	Device->ChildCount = 0; | 	Device->ChildCount = 0; | ||||||
| 	Device->ChildSlots = 4; | 	Device->ChildSlots = 4; | ||||||
| 
 | 
 | ||||||
| @ -73,7 +73,7 @@ struct SysbusDevice* SysbusCreateDeviceInternal( | |||||||
| 	 | 	 | ||||||
| 	// See if we need to grow the instance list
 | 	// See if we need to grow the instance list
 | ||||||
| 	if (Description->InstanceCount >= Description->InstanceSlots) { | 	if (Description->InstanceCount >= Description->InstanceSlots) { | ||||||
| 		struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Description->InstanceSlots * 2, 0); | 		struct SysbusDevice** NewList = KernelHeapAlloc(sizeof(struct SysbusDevice*) * Description->InstanceSlots * 2, 1, 0); | ||||||
| 		for (int i = 0; i < Description->InstanceCount; i++) { | 		for (int i = 0; i < Description->InstanceCount; i++) { | ||||||
| 			NewList[i] = Description->Instances[i]; | 			NewList[i] = Description->Instances[i]; | ||||||
| 		} | 		} | ||||||
| @ -122,7 +122,5 @@ void SysbusInitialize() { | |||||||
| 	); | 	); | ||||||
| 	SysbusRootDevice->DeviceName = "Lcrash System Bus"; | 	SysbusRootDevice->DeviceName = "Lcrash System Bus"; | ||||||
| 
 | 
 | ||||||
| 	Panic("Failed to initialize system bus"); |  | ||||||
| 
 |  | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ | |||||||
| #include <lcrash/cmdline.h> | #include <lcrash/cmdline.h> | ||||||
| #include <lcrash/debug/debug.h> | #include <lcrash/debug/debug.h> | ||||||
| #include <lcrash/driver/sysbus.h> | #include <lcrash/driver/sysbus.h> | ||||||
|  | #include <lcrash/mm/virt.h> | ||||||
| 
 | 
 | ||||||
| #include "types.h" | #include "types.h" | ||||||
| #include "lnxboot.h" | #include "lnxboot.h" | ||||||
| @ -38,6 +39,9 @@ void entry64(struct boot_params* BootParams) { | |||||||
| 	// Initialize the extended debugging information block
 | 	// Initialize the extended debugging information block
 | ||||||
| 	if (DebugInitialize()) while (1) {} | 	if (DebugInitialize()) while (1) {} | ||||||
| 
 | 
 | ||||||
|  | 	// Initialize the virtual memory manager
 | ||||||
|  | 	VmemInitialize(); | ||||||
|  | 
 | ||||||
| 	// Initialize the system bus
 | 	// Initialize the system bus
 | ||||||
| 	SysbusInitialize(); | 	SysbusInitialize(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -136,11 +136,99 @@ int KernelHeapInitialize() { | |||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void* KernelHeapAlloc(u32 Size, u32 Flags) { | /// Shamelessly copy pasted from function above
 | ||||||
|  | int KernelHeapGrow(struct KernelHeapZone* Zone, u32 Level, u32 Flags) { | ||||||
|  | 	// Allocate
 | ||||||
|  | 	struct PmemAllocation Block; | ||||||
|  | 	if (PmemAllocateBlock(1 << Level, &Block)) return -1; | ||||||
|  | 	 | ||||||
|  | 	// Make the frame block
 | ||||||
|  | 	struct KernelHeapBlock* FrameBlock = Block.Address; | ||||||
|  | 	FrameBlock->Prev = Zone->Last; | ||||||
|  | 	FrameBlock->PrevFree = Zone->LastFree; | ||||||
|  | 	FrameBlock->Size = sizeof(struct KernelHeapFrame); | ||||||
|  | 	FrameBlock->Free = false; | ||||||
|  | 
 | ||||||
|  | 	// Make the frame structure
 | ||||||
|  | 	struct KernelHeapFrame* Frame = Block.Address  | ||||||
|  | 				      + sizeof(struct KernelHeapBlock); | ||||||
|  | 	Frame->Block = Block; | ||||||
|  | 	Frame->Size = 1 << Level; | ||||||
|  | 	Frame->NextFrame = 0; | ||||||
|  | 	Frame->PrevFrame = Zone->LastFrame; | ||||||
|  | 
 | ||||||
|  | 	// Make the root block
 | ||||||
|  | 	struct KernelHeapBlock* RootBlock = (struct KernelHeapBlock*)((void*)Frame + sizeof(struct KernelHeapFrame)); | ||||||
|  | 	RootBlock->Prev = FrameBlock; | ||||||
|  | 	FrameBlock->Next = RootBlock; | ||||||
|  | 	FrameBlock->NextFree = RootBlock; | ||||||
|  | 	RootBlock->Next = 0; | ||||||
|  | 	RootBlock->PrevFree = Zone->LastFree; | ||||||
|  | 	RootBlock->NextFree = 0; | ||||||
|  | 	RootBlock->Free = true; | ||||||
|  | 	RootBlock->Size = (1 << Level) | ||||||
|  | 		    - sizeof(struct KernelHeapBlock) | ||||||
|  | 		    - sizeof(struct KernelHeapFrame) | ||||||
|  | 		    - sizeof(struct KernelHeapBlock); | ||||||
|  | 
 | ||||||
|  | 	// Fill out the rest of the zone
 | ||||||
|  | 	Zone->LastFrame->NextFrame = Frame; | ||||||
|  | 	Zone->LastFrame = Frame; | ||||||
|  | 	Zone->Last->Next = FrameBlock; | ||||||
|  | 	for (struct KernelHeapBlock* Block = Zone->Last; Block != 0 && Block->NextFree == 0; Block = Block->Prev) Block->NextFree = RootBlock; | ||||||
|  | 	Zone->Last = RootBlock; | ||||||
|  | 
 | ||||||
|  | 	return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void* KernelHeapAllocInternal(u32 Size, u32 Align, u32 Flags, u32 Iteration) { | ||||||
|  | 	u64 AlignMask = 0; | ||||||
|  | 	for (u32 i = 1; i < Align; i <<= 1) AlignMask |= i; | ||||||
|  | 	AlignMask = ~AlignMask; | ||||||
|  | 
 | ||||||
| 	// Find a free block
 | 	// Find a free block
 | ||||||
| 	for (struct KernelHeapZone* Zone = KernelHeapFirst; Zone != 0; Zone = Zone->Next) { | 	for (struct KernelHeapZone* Zone = KernelHeapFirst; Zone != 0; Zone = Zone->Next) { | ||||||
| 		for (struct KernelHeapBlock* Block = Zone->FirstFree; Block != 0; Block = Block->NextFree) { | 		for (struct KernelHeapBlock* Block = Zone->FirstFree; Block != 0; Block = Block->NextFree) { | ||||||
| 			if (Block->Size >= Size) { | 			if (Block->Size >= Size) { | ||||||
|  | 				u64 PaddingSize = 0; | ||||||
|  | 				if (Align > 1) { | ||||||
|  | 					// Align uses memory poorly
 | ||||||
|  | 					if (Block->Prev == 0) continue; | ||||||
|  | 
 | ||||||
|  | 					u64 BlockStart = (uptr)Block + sizeof(struct KernelHeapBlock); | ||||||
|  | 					u64 BlockEnd   = BlockStart + Block->Size; | ||||||
|  | 
 | ||||||
|  | 					if (!(BlockStart < ((BlockStart + Align) & AlignMask) && BlockEnd > ((BlockStart + Align) & AlignMask))) continue; | ||||||
|  | 
 | ||||||
|  | 					PaddingSize = ((BlockStart + Align) & AlignMask) - BlockStart; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				if (PaddingSize > 0) { | ||||||
|  | 					struct KernelHeapBlock* NewBlock = (struct KernelHeapBlock*)((void*)Block + PaddingSize); | ||||||
|  | 					NewBlock->Prev = Block->Prev; | ||||||
|  | 					NewBlock->Next = Block->Next; | ||||||
|  | 					NewBlock->PrevFree = Block->PrevFree; | ||||||
|  | 					NewBlock->NextFree = Block->NextFree; | ||||||
|  | 					NewBlock->Free = Block->Free; | ||||||
|  | 					NewBlock->Size = Block->Size - PaddingSize; | ||||||
|  | 
 | ||||||
|  | 					// This is incredibly slow
 | ||||||
|  | 					struct KernelHeapBlock* Next = Zone->First; | ||||||
|  | 					while (Next != 0) { | ||||||
|  | 						struct KernelHeapBlock* NextNext = Next->Next; | ||||||
|  | 						if (Next->Prev == Block) Next->Prev = NewBlock; | ||||||
|  | 						if (Next->Next == Block) Next->Next = NewBlock; | ||||||
|  | 						if (Next->PrevFree == Block) Next->PrevFree = NewBlock; | ||||||
|  | 						if (Next->NextFree == Block) Next->NextFree = NewBlock; | ||||||
|  | 						Next = NextNext; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					// GOD.
 | ||||||
|  | 					if (NewBlock->Prev != 0) NewBlock->Prev->Size += (uptr)Block + PaddingSize; | ||||||
|  | 
 | ||||||
|  | 					Block = NewBlock; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
| 				s64 SplitSize = (s64)Block->Size - Size - (sizeof(struct KernelHeapBlock) * 2) - 8; | 				s64 SplitSize = (s64)Block->Size - Size - (sizeof(struct KernelHeapBlock) * 2) - 8; | ||||||
| 
 | 
 | ||||||
| 				if (SplitSize > 0) { | 				if (SplitSize > 0) { | ||||||
| @ -179,7 +267,14 @@ void* KernelHeapAlloc(u32 Size, u32 Flags) { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return 0; | 	if (Iteration < 3) { | ||||||
|  | 		KernelHeapGrow(KernelHeapLast, 20, 0); | ||||||
|  | 		return KernelHeapAllocInternal(Size, Align, Flags, Iteration + 1); | ||||||
|  | 	} else return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void* KernelHeapAlloc(u32 Size, u32 Align, u32 Flags) { | ||||||
|  | 	return KernelHeapAllocInternal(Size, Align, Flags, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void KernelHeapFree(void* Address) { | void KernelHeapFree(void* Address) { | ||||||
|  | |||||||
| @ -10,7 +10,7 @@ int KernelHeapInitialize(); | |||||||
| /**
 | /**
 | ||||||
|  * Allocate memory |  * Allocate memory | ||||||
|  */ |  */ | ||||||
| void* KernelHeapAlloc(u32 Size, u32 Flags); | void* KernelHeapAlloc(u32 Size, u32 Align, u32 Flags); | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Free memory |  * Free memory | ||||||
|  | |||||||
							
								
								
									
										74
									
								
								lcrash/mm/virt.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								lcrash/mm/virt.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | |||||||
|  | #include <lcrash/mm/virt.h> | ||||||
|  | 
 | ||||||
|  | #include <lcrash/mm/kmalloc.h> | ||||||
|  | #include <lcrash/debug/debug.h> | ||||||
|  | 
 | ||||||
|  | u64 (*VmemOriginalPML4)[512] = 0; | ||||||
|  | u64 (*VmemPML4)[512] = 0; | ||||||
|  | 
 | ||||||
|  | void VmemInitialize() { | ||||||
|  | 	// Copy control registers
 | ||||||
|  | 	u64 CR3; | ||||||
|  | 	asm ("mov %%cr3, %0" : "=r" (CR3)); | ||||||
|  | 
 | ||||||
|  | 	u64 CR4; | ||||||
|  | 	asm ("mov %%cr4, %0" : "=r" (CR4)); | ||||||
|  | 
 | ||||||
|  | 	if (CR4 & 0x800) Panic("5 Level paging not supported"); | ||||||
|  | 
 | ||||||
|  | 	u64 (*OriginalPML4)[512] = (u64(*)[512])(CR3 & 0x0007fffffffff000); | ||||||
|  | 	u64 (*NewPML4)[512] = KernelHeapAlloc(sizeof(u64) * 512, 0x1000, 0); | ||||||
|  | 
 | ||||||
|  | 	for (int i = 0; i < 512; i++) { | ||||||
|  | 		if ((*OriginalPML4)[i] & 1) { | ||||||
|  | 			u64 (*OriginalPDPT)[512] = (u64(*)[512])(((*OriginalPML4)[i] & 0x0007fffffffff000)); | ||||||
|  | 			u64 (*NewPDPT)[512] = KernelHeapAlloc(sizeof(u64) * 512, 0x1000, 0); | ||||||
|  | 
 | ||||||
|  | 			for (int j = 0; j < 512; j++) { | ||||||
|  | 				if ((*OriginalPDPT)[j] & 1) { | ||||||
|  | 					u64 (*OriginalPD)[512] = (u64(*)[512])(((*OriginalPDPT)[j] & 0x000ffffffffff000)); | ||||||
|  | 					u64 (*NewPD)[512] = KernelHeapAlloc(sizeof(u64) * 512, 0x1000, 0); | ||||||
|  | 
 | ||||||
|  | 					for (int k = 0; k < 512; k++) { | ||||||
|  | 						if ((*OriginalPD)[k] & 1) { | ||||||
|  | 							u64 (*OriginalPT)[512] = (u64(*)[512])(((*OriginalPD)[k] & 0x000ffffffffff000)); | ||||||
|  | 							u64 (*NewPT)[512] = KernelHeapAlloc(sizeof(u64) * 512, 0x1000, 0); | ||||||
|  | 
 | ||||||
|  | 							if ((s64)NewPT <= 0) Panic("Failed to allocate memory"); | ||||||
|  | 
 | ||||||
|  | 							for (int l = 0; l < 512; l++) { | ||||||
|  | 								//if ((*OriginalPT)[l] & 1) {
 | ||||||
|  | 								//	(*NewPT)[l] = (*OriginalPT)[l];
 | ||||||
|  | 								//} else (*NewPT)[l] = 0;*
 | ||||||
|  | 								(*NewPT)[l] = (*OriginalPT)[l] | 0x87; | ||||||
|  | 							} | ||||||
|  | 
 | ||||||
|  | 							NewPT = (void*)((u64)OriginalPT | 0x87); | ||||||
|  | 
 | ||||||
|  | 							(*NewPD)[k] = (u64)NewPT; | ||||||
|  | 						} else (*NewPD)[k] = 0; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					NewPD = (void*)((uptr)NewPD | (((*OriginalPDPT)[j]) & ~0x0007fffffffff000)); | ||||||
|  | 
 | ||||||
|  | 					(*NewPDPT)[j] = (u64)NewPD; | ||||||
|  | 				} else (*NewPDPT)[j] = 0; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			NewPDPT = (void*)((uptr)NewPDPT | (((*OriginalPML4)[i]) & ~0x0007fffffffff000)); | ||||||
|  | 
 | ||||||
|  | 			(*NewPML4)[i] = (u64)NewPDPT; | ||||||
|  | 		} else (*NewPML4)[i] = 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Save these
 | ||||||
|  | 	VmemOriginalPML4 = OriginalPML4; | ||||||
|  | 	VmemPML4 = NewPML4; | ||||||
|  | 
 | ||||||
|  | 	// Load our new page table
 | ||||||
|  | 	CR3 ^= (u64)VmemOriginalPML4; | ||||||
|  | 	CR3 |= ((u64)VmemPML4) & 0x0007fffffffff000; | ||||||
|  | 	asm volatile ("mov %q0, %%cr3" : : "r" (CR3)); | ||||||
|  | 	 | ||||||
|  | 	Panic("FUCK"); | ||||||
|  | } | ||||||
							
								
								
									
										5
									
								
								lcrash/mm/virt.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								lcrash/mm/virt.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <lcrash/types.h> | ||||||
|  | 
 | ||||||
|  | void VmemInitialize();  | ||||||
| @ -2,22 +2,46 @@ | |||||||
| 
 | 
 | ||||||
| #include <lcrash/acpi/acpi.h> | #include <lcrash/acpi/acpi.h> | ||||||
| #include <lcrash/debug/debug.h> | #include <lcrash/debug/debug.h> | ||||||
|  | #include <lcrash/driver/sysbus.h> | ||||||
| 
 | 
 | ||||||
| bool PciIsPresent   = false; | bool PciIsPresent   = false; | ||||||
| bool PciSupportsECM = false; | bool PciSupportsECM = false; | ||||||
| 
 | 
 | ||||||
| void PciInitialize() { | void* PciBusses[256] = {}; | ||||||
| 	// Try to figure out if we have PCIe
 |  | ||||||
| 	if (AcpiPresent()) { |  | ||||||
| 		struct AcpiMCFG* BridgeTable = AcpiGetTable("MCFG"); |  | ||||||
| 
 | 
 | ||||||
| 		// Guess not
 | void PciScanDevice(u32 Bus, u32 Device) { | ||||||
| 		if (BridgeTable == NULL) goto nopcie; | 	struct PciConfigurationSpaceHeader* DeviceHeader = (struct PciConfigurationSpaceHeader*)(PciBusses[Bus] + Device * 0x800); | ||||||
| 
 | 
 | ||||||
|  | 	// Is a device connected here?
 | ||||||
|  | 	if (DeviceHeader->VendorID != 0xFFFF) { | ||||||
| 		while (1) {} | 		while (1) {} | ||||||
| 	} | 	} | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| nopcie:	Panic("Failed to initialize PCI"); | void PciScanBus(u32 Bus) { | ||||||
|  | 	// Scan bus devices
 | ||||||
|  | 	for (int i = 0; i < 32; i++) PciScanDevice(Bus, i); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void PciInitialize() {	 | ||||||
|  | 	// Try to figure out if we have PCIe
 | ||||||
|  | 	if (!AcpiPresent()) Panic("Failed to initialize PCI");  | ||||||
|  | 	 | ||||||
|  | 	struct AcpiMCFG* BridgeTable = AcpiGetTable("MCFG"); | ||||||
|  | 
 | ||||||
|  | 	// Guess not
 | ||||||
|  | 	if (BridgeTable == NULL) Panic("Failed to find PCI bridge table"); | ||||||
|  | 
 | ||||||
|  | 	// Take our pcie bridges
 | ||||||
|  | 	s32 Length = (BridgeTable->Header.Length - 44) / 16; | ||||||
|  | 	for (int i = 0; i < Length; i++) { | ||||||
|  | 		for (int Bus = BridgeTable->Bridges[i].StartBus; Bus < BridgeTable->Bridges[i].EndBus; Bus++) { | ||||||
|  | 			PciBusses[Bus] = BridgeTable->Bridges[i].Address + (Bus - BridgeTable->Bridges[i].StartBus) * 0x100000; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	// Scan the root bus
 | ||||||
|  | 	PciScanBus(0); | ||||||
| 
 | 
 | ||||||
| 	return; | 	return; | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,6 +2,28 @@ | |||||||
| 
 | 
 | ||||||
| #include <lcrash/types.h> | #include <lcrash/types.h> | ||||||
| 
 | 
 | ||||||
|  | /**
 | ||||||
|  |  * bwaaaaaa, the many ways to touch PCI things | ||||||
|  |  */ | ||||||
|  | struct [[gnu::packed]] PciConfigurationSpaceHeader { | ||||||
|  | 	u16 VendorID; | ||||||
|  | 	u16 DeviceID; | ||||||
|  | 	u16 Status; | ||||||
|  | 	u16 Command; | ||||||
|  | 	u8  RevisionID : 8; | ||||||
|  | 	u32 ClassCode : 24; | ||||||
|  | 	u8  CacheLineSize; | ||||||
|  | 	u8  MasterLatencyTimer; | ||||||
|  | 	u8  HeaderType; | ||||||
|  | 	u8  BIST; | ||||||
|  | 	u8  Reserved[0x20]; | ||||||
|  | 	u8  CapabilitiesPointer; | ||||||
|  | 	u8  Reserved2[7]; | ||||||
|  | 	u8  InterruptLine; | ||||||
|  | 	u8  InterruptPin; | ||||||
|  | 	u8  Reserved3[2]; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Initialize the PCI code. |  * Initialize the PCI code. | ||||||
|  */ |  */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user