Compare commits

...

5 Commits

Author SHA1 Message Date
Bananymous a07cbabcb3 LibC: Define function sizes for setjmp and longjmp
dynamic linking was complaining about these not existing
2024-09-10 16:21:20 +03:00
Bananymous 64a3893f6f Kernel: Add command line option to disable AML parsing
This can be handy if my broken AML parser crashes or hangs while parsing
AML :D
2024-09-10 16:20:24 +03:00
Bananymous eabe759ebf Kernel: Don't require APs that are not started to start :D 2024-09-10 16:19:43 +03:00
Bananymous a4838386e6 Kernel: Remove unnecessary branch from uncanonicalizing addresses 2024-09-10 16:19:16 +03:00
Bananymous c65613901f Kernel: Fix AML aliases and package elements 2024-09-10 16:18:42 +03:00
15 changed files with 41 additions and 85 deletions

View File

@ -37,9 +37,7 @@ namespace Kernel
static constexpr inline uintptr_t uncanonicalize(uintptr_t addr) static constexpr inline uintptr_t uncanonicalize(uintptr_t addr)
{ {
if (addr & 0x0000800000000000) return addr & 0x0000FFFFFFFFFFFF;
return addr & ~0xFFFF000000000000;
return addr;
} }
static constexpr inline uintptr_t canonicalize(uintptr_t addr) static constexpr inline uintptr_t canonicalize(uintptr_t addr)

View File

@ -7,37 +7,8 @@
namespace Kernel::ACPI::AML namespace Kernel::ACPI::AML
{ {
struct Alias final : public AML::NamedObject struct Alias
{ {
BAN::RefPtr<AML::Node> target;
Alias(NameSeg name, BAN::RefPtr<AML::Node> target)
: NamedObject(Node::Type::Alias, name)
, target(target)
{}
BAN::RefPtr<AML::Node> to_underlying() override { return target; }
bool is_scope() const override { return target->is_scope(); }
BAN::RefPtr<AML::Node> convert(uint8_t mask) override
{
ASSERT(target);
return target->convert(mask);
}
BAN::RefPtr<Node> copy() override
{
ASSERT(target);
return target->copy();
}
BAN::RefPtr<AML::Node> store(BAN::RefPtr<AML::Node> node) override
{
ASSERT(target);
return target->store(node);
}
static ParseResult parse(ParseContext& context) static ParseResult parse(ParseContext& context)
{ {
ASSERT(context.aml_data.size() >= 1); ASSERT(context.aml_data.size() >= 1);
@ -59,27 +30,19 @@ namespace Kernel::ACPI::AML
return ParseResult::Success; return ParseResult::Success;
} }
auto alias = MUST(BAN::RefPtr<Alias>::create(alias_string.value().path.back(), source_object->to_underlying())); if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), source_object))
if (!Namespace::root_namespace()->add_named_object(context, alias_string.value(), alias))
return ParseResult::Success; return ParseResult::Success;
#if AML_DEBUG_LEVEL >= 2 #if AML_DEBUG_LEVEL >= 2
alias->debug_print(0); AML_DEBUG_PRINT("Alias \"");
alias_string->debug_print();
AML_DEBUG_PRINT("\" => ");
source_object->debug_print(0);
AML_DEBUG_PRINTLN(""); AML_DEBUG_PRINTLN("");
#endif #endif
return ParseResult::Success; return ParseResult::Success;
} }
void debug_print(int indent) const override
{
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINTLN("Alias {} { ", name);
target->debug_print(indent + 1);
AML_DEBUG_PRINTLN("");
AML_DEBUG_PRINT_INDENT(indent);
AML_DEBUG_PRINT("}");
}
}; };
} }

View File

@ -50,9 +50,6 @@ namespace Kernel::ACPI::AML
switch (destination->type) switch (destination->type)
{ {
case AML::Node::Type::Alias:
static_cast<AML::Alias*>(destination.ptr())->target = source->copy();
return source;
case AML::Node::Type::Name: case AML::Node::Type::Name:
static_cast<AML::Name*>(destination.ptr())->object = source->copy(); static_cast<AML::Name*>(destination.ptr())->object = source->copy();
return source; return source;

View File

@ -67,7 +67,12 @@ namespace Kernel::ACPI::AML
return ParseResult::Failure; return ParseResult::Failure;
} }
auto package_element = package->elements[index]; auto package_element = package->elements[index];
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element->to_underlying())); if (!package_element)
{
AML_ERROR("IndexOp target is null package element");
return ParseResult::Failure;
}
result = MUST(BAN::RefPtr<AML::Reference>::create(package_element));
break; break;
} }
case AML::Node::Type::String: case AML::Node::Type::String:

View File

@ -29,7 +29,6 @@ namespace Kernel::ACPI::AML
enum class Type : uint8_t enum class Type : uint8_t
{ {
None, None,
Alias,
BankFieldElement, BankFieldElement,
Buffer, Buffer,
BufferField, BufferField,

View File

@ -31,7 +31,6 @@ namespace Kernel::ACPI::AML
switch (object->type) switch (object->type)
{ {
case AML::Node::Type::None: case AML::Node::Type::None:
case AML::Node::Type::Alias:
case AML::Node::Type::Name: case AML::Node::Type::Name:
case AML::Node::Type::PackageElement: case AML::Node::Type::PackageElement:
case AML::Node::Type::Reference: case AML::Node::Type::Reference:

View File

@ -84,7 +84,7 @@ namespace Kernel::ACPI::AML
{ {
if (!initialized) if (!initialized)
{ {
AML_ERROR("Trying to store into uninitialized PackageElement"); AML_ERROR("Trying to convert uninitialized PackageElement");
return {}; return {};
} }
if (!resolved && !resolve()) if (!resolved && !resolve())
@ -96,7 +96,7 @@ namespace Kernel::ACPI::AML
{ {
if (!initialized) if (!initialized)
{ {
AML_ERROR("Trying to store into uninitialized PackageElement"); AML_ERROR("Trying to read uninitialized PackageElement");
return {}; return {};
} }
if (!resolved && !resolve()) if (!resolved && !resolve())
@ -108,17 +108,17 @@ namespace Kernel::ACPI::AML
{ {
if (!initialized) if (!initialized)
{ {
AML_ERROR("Trying to store into uninitialized PackageElement"); initialized = true;
return {}; resolved = true;
} }
if (!resolved && !resolve()) if (!resolved && !resolve())
return {}; return {};
ASSERT(element->type != AML::Node::Type::Reference); ASSERT(!element || element->type != AML::Node::Type::Reference);
if (node->type == AML::Node::Type::Reference) if (node->type == AML::Node::Type::Reference)
element = static_cast<AML::Reference*>(element.ptr())->node; element = static_cast<AML::Reference*>(node.ptr())->node;
else else
element = element->copy(); element = node->copy();
return element; return node;
} }
static ParseResult parse(AML::ParseContext& context, BAN::RefPtr<AML::Package> package) static ParseResult parse(AML::ParseContext& context, BAN::RefPtr<AML::Package> package)

View File

@ -22,8 +22,8 @@ namespace Kernel::ACPI::AML
if (!object_result.success()) if (!object_result.success())
return ParseResult::Failure; return ParseResult::Failure;
auto object_node = object_result.node(); auto object_node = object_result.node();
if (object_node && object_node->type == AML::Node::Type::Register) if (object_node)
object_node = static_cast<AML::Register*>(object_node.ptr())->value; object_node = object_node->to_underlying();
if (!object_node) if (!object_node)
{ {
AML_ERROR("SizeOf object is null"); AML_ERROR("SizeOf object is null");

View File

@ -495,25 +495,7 @@ acpi_release_global_lock:
dwarnln("\\_S5 not found"); dwarnln("\\_S5 not found");
return; return;
} }
BAN::RefPtr<AML::Node> s5_evaluated = s5_object; auto s5_evaluated = s5_object->to_underlying();
while (true)
{
bool done = false;
switch (s5_evaluated->type)
{
case AML::Node::Type::Alias:
s5_evaluated = static_cast<AML::Alias*>(s5_evaluated.ptr())->target;
break;
case AML::Node::Type::Name:
s5_evaluated = static_cast<AML::Name*>(s5_evaluated.ptr())->object;
break;
default:
done = true;
break;
}
if (done)
break;
}
if (!s5_evaluated) if (!s5_evaluated)
{ {
dwarnln("Failed to evaluate \\_S5"); dwarnln("Failed to evaluate \\_S5");

View File

@ -159,7 +159,6 @@ namespace Kernel::ACPI
LockGuard _(m_object_mutex); LockGuard _(m_object_mutex);
ASSERT(!object_path.path.empty()); ASSERT(!object_path.path.empty());
ASSERT(object_path.path.back() == object->name);
auto canonical_path = resolve_path(parse_context.scope, object_path, FindMode::ForceAbsolute, false); auto canonical_path = resolve_path(parse_context.scope, object_path, FindMode::ForceAbsolute, false);
ASSERT(canonical_path.has_value()); ASSERT(canonical_path.has_value());

View File

@ -93,6 +93,8 @@ namespace Kernel::ACPI
auto result_integer = result.value() auto result_integer = result.value()
? result.value()->convert(AML::Node::ConvInteger) ? result.value()->convert(AML::Node::ConvInteger)
: BAN::RefPtr<AML::Node>(); : BAN::RefPtr<AML::Node>();
if (!result_integer)
return {};
return static_cast<AML::Integer*>(result_integer.ptr()); return static_cast<AML::Integer*>(result_integer.ptr());
} }

View File

@ -277,6 +277,7 @@ namespace Kernel
memcpy(PageTable::fast_page_as_ptr(), g_ap_init_addr, PAGE_SIZE); memcpy(PageTable::fast_page_as_ptr(), g_ap_init_addr, PAGE_SIZE);
}); });
uint8_t initialized_aps = 0;
for (auto& processor : m_processors) for (auto& processor : m_processors)
{ {
if (processor.apic_id == bsp_id) if (processor.apic_id == bsp_id)
@ -339,15 +340,17 @@ namespace Kernel
udelay(100); udelay(100);
} }
}); });
initialized_aps++;
} }
__atomic_store_n(&g_ap_startup_done[0], 1, __ATOMIC_SEQ_CST); __atomic_store_n(&g_ap_startup_done[0], 1, __ATOMIC_SEQ_CST);
const size_t timeout_ms = SystemTimer::get().ms_since_boot() + 500; const size_t timeout_ms = SystemTimer::get().ms_since_boot() + 500;
while (__atomic_load_n(&g_ap_running_count[0], __ATOMIC_SEQ_CST) < m_processors.size() - 1) while (__atomic_load_n(&g_ap_running_count[0], __ATOMIC_SEQ_CST) < initialized_aps)
{ {
if (SystemTimer::get().ms_since_boot() >= timeout_ms) if (SystemTimer::get().ms_since_boot() >= timeout_ms)
Kernel::panic("Could not start all processors"); Kernel::panic("Could not start all APs ({}/{} started)", g_ap_running_count[0], initialized_aps);
__builtin_ia32_pause(); __builtin_ia32_pause();
} }

View File

@ -37,6 +37,7 @@
struct ParsedCommandLine struct ParsedCommandLine
{ {
bool force_pic = false; bool force_pic = false;
bool disable_acpi = false;
bool disable_serial = false; bool disable_serial = false;
bool disable_smp = false; bool disable_smp = false;
bool disable_usb = false; bool disable_usb = false;
@ -82,6 +83,8 @@ static void parse_command_line()
cmdline.disable_smp = true; cmdline.disable_smp = true;
else if (argument == "nousb") else if (argument == "nousb")
cmdline.disable_usb = true; cmdline.disable_usb = true;
else if (argument == "noacpi")
cmdline.disable_acpi = true;
else if (argument == "nodebug") else if (argument == "nodebug")
g_disable_debug = true; g_disable_debug = true;
else if (argument.starts_with("ps2=")) else if (argument.starts_with("ps2="))
@ -220,7 +223,7 @@ static void init2(void*)
dprintln("USBManager initialized"); dprintln("USBManager initialized");
} }
if (ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error()) if (!cmdline.disable_acpi && ACPI::ACPI::get().enter_acpi_mode(InterruptController::get().is_using_apic()).is_error())
dprintln("Failed to enter ACPI mode"); dprintln("Failed to enter ACPI mode");
DevFileSystem::get().initialize_device_updater(); DevFileSystem::get().initialize_device_updater();

View File

@ -13,6 +13,8 @@ setjmp:
ret ret
.size setjmp, . - setjmp
// void longjmp(jmp_buf env, int val) // void longjmp(jmp_buf env, int val)
.global longjmp .global longjmp
longjmp: longjmp:
@ -26,3 +28,5 @@ longjmp:
movl 0(%edx), %esp movl 0(%edx), %esp
movl 4(%edx), %ecx movl 4(%edx), %ecx
jmp *%ecx jmp *%ecx
.size longjmp, . - longjmp

View File

@ -10,6 +10,7 @@ setjmp:
xorq %rax, %rax xorq %rax, %rax
ret ret
.size setjmp, . - setjmp
// void longjmp(jmp_buf env, int val) // void longjmp(jmp_buf env, int val)
.global longjmp .global longjmp
@ -21,3 +22,4 @@ longjmp:
movq 0(%rdi), %rsp movq 0(%rdi), %rsp
movq 8(%rdi), %rcx movq 8(%rdi), %rcx
jmp *%rcx jmp *%rcx
.size longjmp, . - longjmp