Kernel: Move ACPI to its own file
This commit is contained in:
		
							parent
							
								
									0cebf248a3
								
							
						
					
					
						commit
						c7286396d8
					
				|  | @ -36,6 +36,7 @@ BUILDDIR=$(abspath build) | ||||||
| KERNEL_OBJS=					\
 | KERNEL_OBJS=					\
 | ||||||
| $(KERNEL_ARCH_OBJS)				\ | $(KERNEL_ARCH_OBJS)				\ | ||||||
| font/prefs.o					\ | font/prefs.o					\ | ||||||
|  | kernel/ACPI.o					\ | ||||||
| kernel/APIC.o					\ | kernel/APIC.o					\ | ||||||
| kernel/build_libc.o				\ | kernel/build_libc.o				\ | ||||||
| kernel/CPUID.o					\ | kernel/CPUID.o					\ | ||||||
|  |  | ||||||
|  | @ -0,0 +1,43 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <BAN/Errors.h> | ||||||
|  | 
 | ||||||
|  | namespace Kernel | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	class ACPI | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		struct SDTHeader | ||||||
|  | 		{ | ||||||
|  | 			uint8_t signature[4]; | ||||||
|  | 			uint32_t length; | ||||||
|  | 			uint8_t revision; | ||||||
|  | 			uint8_t checksum; | ||||||
|  | 			uint8_t oemid[6]; | ||||||
|  | 			uint64_t oem_table_id; | ||||||
|  | 			uint32_t oem_revision; | ||||||
|  | 			uint32_t creator_id; | ||||||
|  | 			uint32_t creator_revision; | ||||||
|  | 		} __attribute__((packed)); | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		static BAN::ErrorOr<void> initialize(); | ||||||
|  | 		static ACPI& get(); | ||||||
|  | 
 | ||||||
|  | 		BAN::ErrorOr<const SDTHeader*> get_header(const char[4]); | ||||||
|  | 		void unmap_header(const SDTHeader*); | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		ACPI() = default; | ||||||
|  | 		BAN::ErrorOr<void> initialize_impl(); | ||||||
|  | 
 | ||||||
|  | 		const SDTHeader* get_header_from_index(size_t); | ||||||
|  | 
 | ||||||
|  | 	private: | ||||||
|  | 		uintptr_t m_header_table = 0; | ||||||
|  | 		uint32_t m_entry_size = 0; | ||||||
|  | 		uint32_t m_entry_count = 0; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,172 @@ | ||||||
|  | #include <BAN/ScopeGuard.h> | ||||||
|  | #include <BAN/StringView.h> | ||||||
|  | #include <kernel/ACPI.h> | ||||||
|  | #include <kernel/MMU.h> | ||||||
|  | 
 | ||||||
|  | #define RSPD_SIZE	20 | ||||||
|  | #define RSPDv2_SIZE	36 | ||||||
|  | 
 | ||||||
|  | namespace Kernel | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | 	struct RSDP | ||||||
|  | 	{ | ||||||
|  | 		uint8_t signature[8]; | ||||||
|  | 		uint8_t checksum; | ||||||
|  | 		uint8_t oemid[6]; | ||||||
|  | 		uint8_t revision; | ||||||
|  | 		uint32_t rsdt_address; | ||||||
|  | 
 | ||||||
|  | 		// only in revision >= 2
 | ||||||
|  | 		uint32_t length; | ||||||
|  | 		uint64_t xsdt_address; | ||||||
|  | 		uint8_t extended_checksum; | ||||||
|  | 		uint8_t reserved[3]; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	struct RSDT : public ACPI::SDTHeader | ||||||
|  | 	{ | ||||||
|  | 		uint32_t entries[]; | ||||||
|  | 	} __attribute__((packed)); | ||||||
|  | 
 | ||||||
|  | 	struct XSDT : public ACPI::SDTHeader | ||||||
|  | 	{ | ||||||
|  | 		uint64_t entries[]; | ||||||
|  | 	} __attribute__((packed)); | ||||||
|  | 
 | ||||||
|  | 	static ACPI* s_instance = nullptr; | ||||||
|  | 
 | ||||||
|  | 	BAN::ErrorOr<void> ACPI::initialize() | ||||||
|  | 	{ | ||||||
|  | 		ASSERT(s_instance == nullptr); | ||||||
|  | 		s_instance = new ACPI; | ||||||
|  | 		if (s_instance == nullptr) | ||||||
|  | 			return BAN::Error::from_errno(ENOMEM); | ||||||
|  | 		TRY(s_instance->initialize_impl()); | ||||||
|  | 		return {}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	ACPI& ACPI::get() | ||||||
|  | 	{ | ||||||
|  | 		ASSERT(s_instance != nullptr); | ||||||
|  | 		return *s_instance; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	static bool is_rsdp(uintptr_t rsdp_addr) | ||||||
|  | 	{ | ||||||
|  | 		const RSDP* rsdp = (const RSDP*)rsdp_addr; | ||||||
|  | 
 | ||||||
|  | 		if (memcmp(rsdp->signature, "RSD PTR ", 8) != 0) | ||||||
|  | 			return false; | ||||||
|  | 
 | ||||||
|  | 		{ | ||||||
|  | 			uint8_t checksum = 0; | ||||||
|  | 			for (uint32_t i = 0; i < RSPD_SIZE; i++) | ||||||
|  | 				checksum += ((const uint8_t*)rsdp)[i]; | ||||||
|  | 			if (checksum != 0) | ||||||
|  | 				return false; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (rsdp->revision == 2) | ||||||
|  | 		{ | ||||||
|  | 			uint8_t checksum = 0; | ||||||
|  | 			for (uint32_t i = 0; i < RSPDv2_SIZE; i++) | ||||||
|  | 				checksum += ((const uint8_t*)rsdp)[i]; | ||||||
|  | 			if (checksum != 0) | ||||||
|  | 				return false; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	static const RSDP* locate_rsdp() | ||||||
|  | 	{ | ||||||
|  | 		// Look in main BIOS area below 1 MB
 | ||||||
|  | 		for (uintptr_t addr = 0x000E0000; addr < 0x000FFFFF; addr += 16) | ||||||
|  | 			if (is_rsdp(addr)) | ||||||
|  | 				return (const RSDP*)addr; | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	static bool is_valid_std_header(const ACPI::SDTHeader* header) | ||||||
|  | 	{ | ||||||
|  | 		uint8_t sum = 0; | ||||||
|  | 		for (uint32_t i = 0; i < header->length; i++) | ||||||
|  | 			sum += ((uint8_t*)header)[i]; | ||||||
|  | 		return sum == 0; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	BAN::ErrorOr<void> ACPI::initialize_impl() | ||||||
|  | 	{ | ||||||
|  | 		const RSDP* rsdp = locate_rsdp(); | ||||||
|  | 		if (rsdp == nullptr) | ||||||
|  | 			return BAN::Error::from_c_string("Could not find RSDP"); | ||||||
|  | 
 | ||||||
|  | 		if (rsdp->revision >= 2) | ||||||
|  | 		{ | ||||||
|  | 			const XSDT* xsdt = (const XSDT*)rsdp->xsdt_address; | ||||||
|  | 			MMU::get().allocate_page((uintptr_t)xsdt, MMU::Flags::Present); | ||||||
|  | 			BAN::ScopeGuard _([xsdt] { MMU::get().unallocate_page((uintptr_t)xsdt); }); | ||||||
|  | 
 | ||||||
|  | 			if (memcmp(xsdt->signature, "XSDT", 4) != 0) | ||||||
|  | 				return BAN::Error::from_c_string("XSDT has invalid signature"); | ||||||
|  | 			if (!is_valid_std_header(xsdt)) | ||||||
|  | 				return BAN::Error::from_c_string("XSDT has invalid checksum"); | ||||||
|  | 
 | ||||||
|  | 			m_header_table = (uintptr_t)xsdt->entries; | ||||||
|  | 			m_entry_size = 8; | ||||||
|  | 			m_entry_count = (xsdt->length - sizeof(SDTHeader)) / 8; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			const RSDT* rsdt = (const RSDT*)(uintptr_t)rsdp->rsdt_address; | ||||||
|  | 			MMU::get().allocate_page((uintptr_t)rsdt, MMU::Flags::Present); | ||||||
|  | 			BAN::ScopeGuard _([rsdt] { MMU::get().unallocate_page((uintptr_t)rsdt); }); | ||||||
|  | 
 | ||||||
|  | 			if (memcmp(rsdt->signature, "RSDT", 4) != 0) | ||||||
|  | 				return BAN::Error::from_c_string("RSDT has invalid signature"); | ||||||
|  | 			if (!is_valid_std_header(rsdt)) | ||||||
|  | 				return BAN::Error::from_c_string("RSDT has invalid checksum"); | ||||||
|  | 
 | ||||||
|  | 			m_header_table = (uintptr_t)rsdt->entries; | ||||||
|  | 			m_entry_size = 4; | ||||||
|  | 			m_entry_count = (rsdt->length - sizeof(SDTHeader)) / 4; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		MMU::get().allocate_range(m_header_table, m_entry_count * m_entry_size, MMU::Flags::Present); | ||||||
|  | 
 | ||||||
|  | 		return {}; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	BAN::ErrorOr<const ACPI::SDTHeader*> ACPI::get_header(const char signature[4]) | ||||||
|  | 	{ | ||||||
|  | 		for (uint32_t i = 0; i < m_entry_count; i++) | ||||||
|  | 		{ | ||||||
|  | 			const SDTHeader* header = get_header_from_index(i); | ||||||
|  | 			MMU::get().allocate_range((uintptr_t)header, header->length, MMU::Flags::Present); | ||||||
|  | 			if (!is_valid_std_header(header)) | ||||||
|  | 			{ | ||||||
|  | 				unmap_header(header); | ||||||
|  | 				continue; | ||||||
|  | 			} | ||||||
|  | 			if (memcmp(header->signature, signature, 4) == 0) | ||||||
|  | 				return header; | ||||||
|  | 		} | ||||||
|  | 		return BAN::Error::from_format("Could not find ACPI header '{}'", BAN::StringView(signature, 4)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	void ACPI::unmap_header(const ACPI::SDTHeader* header) | ||||||
|  | 	{ | ||||||
|  | 		MMU::get().unallocate_range((uintptr_t)header, header->length); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	const ACPI::SDTHeader* ACPI::get_header_from_index(size_t index) | ||||||
|  | 	{ | ||||||
|  | 		ASSERT(index < m_entry_count); | ||||||
|  | 		ASSERT(m_entry_size == 4 || m_entry_size == 8); | ||||||
|  | 
 | ||||||
|  | 		uintptr_t header_address = (m_entry_size == 4) ? ((uint32_t*)m_header_table)[index] : ((uint64_t*)m_header_table)[index]; | ||||||
|  | 		return (SDTHeader*)header_address; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| #include <BAN/ScopeGuard.h> | #include <BAN/ScopeGuard.h> | ||||||
| #include <kernel/Debug.h> | #include <kernel/Debug.h> | ||||||
|  | #include <kernel/ACPI.h> | ||||||
| #include <kernel/APIC.h> | #include <kernel/APIC.h> | ||||||
| #include <kernel/CPUID.h> | #include <kernel/CPUID.h> | ||||||
| #include <kernel/IDT.h> | #include <kernel/IDT.h> | ||||||
|  | @ -18,38 +19,8 @@ | ||||||
| 
 | 
 | ||||||
| // https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt-format
 | // https://uefi.org/specs/ACPI/6.5/05_ACPI_Software_Programming_Model.html#multiple-apic-description-table-madt-format
 | ||||||
| 
 | 
 | ||||||
| static constexpr uint32_t RSPD_SIZE		= 20; | struct MADT : public Kernel::ACPI::SDTHeader | ||||||
| static constexpr uint32_t RSPDv2_SIZE	= 36; |  | ||||||
| 
 |  | ||||||
| struct RSDP |  | ||||||
| { | { | ||||||
| 	char		signature[8]; |  | ||||||
| 	uint8_t		checksum; |  | ||||||
| 	char		OEMID[6]; |  | ||||||
| 	uint8_t		revision; |  | ||||||
| 	uint32_t	rsdt_address; |  | ||||||
| 	uint32_t	v2_length; |  | ||||||
| 	uint64_t	v2_xsdt_address; |  | ||||||
| 	uint8_t		v2_extended_checksum; |  | ||||||
| 	uint8_t		v2_reserved[3]; |  | ||||||
| } __attribute__ ((packed)); |  | ||||||
| 
 |  | ||||||
| struct SDTHeader |  | ||||||
| { |  | ||||||
| 	char		signature[4]; |  | ||||||
| 	uint32_t	length; |  | ||||||
| 	uint8_t		revision; |  | ||||||
| 	uint8_t		checksum; |  | ||||||
| 	char		OEMID[6]; |  | ||||||
| 	char		OEM_table_id[8]; |  | ||||||
| 	uint32_t	OEM_revision; |  | ||||||
| 	uint32_t	creator_id; |  | ||||||
| 	uint32_t	creator_revision; |  | ||||||
| } __attribute__((packed)); |  | ||||||
| 
 |  | ||||||
| struct MADT |  | ||||||
| { |  | ||||||
| 	SDTHeader header; |  | ||||||
| 	uint32_t local_apic; | 	uint32_t local_apic; | ||||||
| 	uint32_t flags; | 	uint32_t flags; | ||||||
| } __attribute__((packed)); | } __attribute__((packed)); | ||||||
|  | @ -110,104 +81,6 @@ union RedirectionEntry | ||||||
| 	}; | 	}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static bool is_rsdp(uintptr_t rsdp_addr) |  | ||||||
| { |  | ||||||
| 	const RSDP* rsdp = (const RSDP*)rsdp_addr; |  | ||||||
| 
 |  | ||||||
| 	if (memcmp(rsdp->signature, "RSD PTR ", 8) != 0) |  | ||||||
| 		return false; |  | ||||||
| 
 |  | ||||||
| 	{ |  | ||||||
| 		uint8_t checksum = 0; |  | ||||||
| 		for (uint32_t i = 0; i < RSPD_SIZE; i++) |  | ||||||
| 			checksum += ((uint8_t*)rsdp)[i]; |  | ||||||
| 		if (checksum != 0) |  | ||||||
| 			return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (rsdp->revision == 2) |  | ||||||
| 	{ |  | ||||||
| 		uint8_t checksum = 0; |  | ||||||
| 		for (uint32_t i = 0; i < RSPDv2_SIZE; i++) |  | ||||||
| 			checksum += ((uint8_t*)rsdp)[i]; |  | ||||||
| 		if (checksum != 0) |  | ||||||
| 			return false; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static uintptr_t locate_rsdp() |  | ||||||
| { |  | ||||||
| 	// Look in main BIOS area below 1 MB
 |  | ||||||
| 	for (uintptr_t addr = 0x000E0000; addr < 0x000FFFFF; addr += 16) |  | ||||||
| 		if (is_rsdp(addr)) |  | ||||||
| 			return addr; |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static bool is_valid_std_header(const SDTHeader* header) |  | ||||||
| { |  | ||||||
| 	uint8_t sum = 0; |  | ||||||
| 	for (uint32_t i = 0; i < header->length; i++) |  | ||||||
| 		sum += ((uint8_t*)header)[i]; |  | ||||||
| 	return sum == 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| uintptr_t locate_madt(uintptr_t rsdp_addr) |  | ||||||
| { |  | ||||||
| 	uintptr_t entry_address_base	= 0; |  | ||||||
| 	ptrdiff_t entry_pointer_size	= 0; |  | ||||||
| 	uint32_t entry_count			= 0; |  | ||||||
| 
 |  | ||||||
| 	const RSDP* rsdp = (const RSDP*)rsdp_addr; |  | ||||||
| 	if (rsdp->revision == 2) |  | ||||||
| 	{ |  | ||||||
| 		uintptr_t xsdt_addr = rsdp->v2_xsdt_address; |  | ||||||
| 		MMU::get().allocate_page(xsdt_addr, MMU::Flags::ReadWrite | MMU::Flags::Present); |  | ||||||
| 		entry_address_base = xsdt_addr + sizeof(SDTHeader); |  | ||||||
| 		entry_count = (((const SDTHeader*)xsdt_addr)->length - sizeof(SDTHeader)) / 8; |  | ||||||
| 		entry_pointer_size = 8; |  | ||||||
| 		MMU::get().unallocate_page(xsdt_addr); |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		uintptr_t rsdt_addr = rsdp->rsdt_address; |  | ||||||
| 		MMU::get().allocate_page(rsdt_addr, MMU::Flags::ReadWrite | MMU::Flags::Present); |  | ||||||
| 		entry_address_base = rsdt_addr + sizeof(SDTHeader); |  | ||||||
| 		entry_count = (((const SDTHeader*)rsdt_addr)->length - sizeof(SDTHeader)) / 4; |  | ||||||
| 		entry_pointer_size = 4; |  | ||||||
| 		MMU::get().unallocate_page(rsdt_addr); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	for (uint32_t i = 0; i < entry_count; i++) |  | ||||||
| 	{ |  | ||||||
| 		uintptr_t entry_addr_ptr = entry_address_base + i * entry_pointer_size; |  | ||||||
| 		MMU::get().allocate_page(entry_addr_ptr, MMU::Flags::ReadWrite | MMU::Flags::Present); |  | ||||||
| 
 |  | ||||||
| 		union dummy { uint32_t addr32; uint64_t addr64; } __attribute__((aligned(1), packed)); |  | ||||||
| 
 |  | ||||||
| 		uintptr_t entry_addr;		 |  | ||||||
| 		if (entry_pointer_size == 4) |  | ||||||
| 			entry_addr = ((dummy*)entry_addr_ptr)->addr32; |  | ||||||
| 		else |  | ||||||
| 			entry_addr = ((dummy*)entry_addr_ptr)->addr64; |  | ||||||
| 
 |  | ||||||
| 		MMU::get().allocate_page(entry_addr, MMU::Flags::ReadWrite | MMU::Flags::Present); |  | ||||||
| 
 |  | ||||||
| 		BAN::ScopeGuard _([&]() { |  | ||||||
| 			MMU::get().unallocate_page(entry_addr); |  | ||||||
| 			MMU::get().unallocate_page(entry_addr_ptr); |  | ||||||
| 		}); |  | ||||||
| 
 |  | ||||||
| 		const SDTHeader* entry = (const SDTHeader*)entry_addr; |  | ||||||
| 		if (memcmp(entry->signature, "APIC", 4) == 0 && is_valid_std_header(entry)) |  | ||||||
| 			return entry_addr; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	return 0; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| APIC* APIC::create() | APIC* APIC::create() | ||||||
| { | { | ||||||
| 	uint32_t ecx, edx; | 	uint32_t ecx, edx; | ||||||
|  | @ -218,23 +91,14 @@ APIC* APIC::create() | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	uintptr_t rsdp_addr = locate_rsdp(); | 	auto header_or_error = Kernel::ACPI::get().get_header("APIC"); | ||||||
| 	if (!rsdp_addr) | 	if (header_or_error.is_error()) | ||||||
| 	{ | 	{ | ||||||
| 		dprintln("Could not locate RSDP"); | 		dprintln("{}", header_or_error.error()); | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	uintptr_t madt_addr = locate_madt(rsdp_addr); | 	const MADT* madt = (const MADT*)header_or_error.value(); | ||||||
| 	if (!madt_addr) |  | ||||||
| 	{ |  | ||||||
| 		dprintln("Could not find MADT in RSDP"); |  | ||||||
| 		return nullptr; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	MMU::get().allocate_page(madt_addr, MMU::Flags::ReadWrite | MMU::Flags::Present); |  | ||||||
| 
 |  | ||||||
| 	const MADT* madt = (const MADT*)madt_addr; |  | ||||||
| 
 | 
 | ||||||
| 	APIC* apic = new APIC; | 	APIC* apic = new APIC; | ||||||
| 	apic->m_local_apic = madt->local_apic; | 	apic->m_local_apic = madt->local_apic; | ||||||
|  | @ -242,7 +106,7 @@ APIC* APIC::create() | ||||||
| 		apic->m_irq_overrides[i] = i; | 		apic->m_irq_overrides[i] = i; | ||||||
| 
 | 
 | ||||||
| 	uintptr_t madt_entry_addr = (uintptr_t)madt + sizeof(MADT); | 	uintptr_t madt_entry_addr = (uintptr_t)madt + sizeof(MADT); | ||||||
| 	while (madt_entry_addr < (uintptr_t)madt + madt->header.length) | 	while (madt_entry_addr < (uintptr_t)madt + madt->length) | ||||||
| 	{ | 	{ | ||||||
| 		const MADTEntry* entry = (const MADTEntry*)madt_entry_addr; | 		const MADTEntry* entry = (const MADTEntry*)madt_entry_addr; | ||||||
| 		switch (entry->type) | 		switch (entry->type) | ||||||
|  | @ -274,7 +138,8 @@ APIC* APIC::create() | ||||||
| 		} | 		} | ||||||
| 		madt_entry_addr += entry->length; | 		madt_entry_addr += entry->length; | ||||||
| 	} | 	} | ||||||
| 	MMU::get().unallocate_page((uintptr_t)madt); | 
 | ||||||
|  | 	Kernel::ACPI::get().unmap_header(madt); | ||||||
| 
 | 
 | ||||||
| 	if (apic->m_local_apic == 0 || apic->m_io_apics.empty()) | 	if (apic->m_local_apic == 0 || apic->m_io_apics.empty()) | ||||||
| 	{ | 	{ | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | #include <kernel/ACPI.h> | ||||||
| #include <kernel/Arch.h> | #include <kernel/Arch.h> | ||||||
| #include <kernel/Debug.h> | #include <kernel/Debug.h> | ||||||
| #include <kernel/FS/VirtualFileSystem.h> | #include <kernel/FS/VirtualFileSystem.h> | ||||||
|  | @ -126,6 +127,9 @@ extern "C" void kernel_main() | ||||||
| 	TTY* tty1 = new TTY(terminal_driver); | 	TTY* tty1 = new TTY(terminal_driver); | ||||||
| 	ASSERT(tty1); | 	ASSERT(tty1); | ||||||
| 	 | 	 | ||||||
|  | 	MUST(ACPI::initialize()); | ||||||
|  | 	dprintln("ACPI initialized"); | ||||||
|  | 
 | ||||||
| 	InterruptController::initialize(cmdline.force_pic); | 	InterruptController::initialize(cmdline.force_pic); | ||||||
| 	dprintln("Interrupt controller initialized"); | 	dprintln("Interrupt controller initialized"); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue