#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Kernel::ACPI { AML::ParseResult AML::ParseResult::Failure = AML::ParseResult(AML::ParseResult::Result::Failure); AML::ParseResult AML::ParseResult::Success = AML::ParseResult(AML::ParseResult::Result::Success); uint64_t AML::Node::total_node_count = 0; BAN::RefPtr AML::Node::as_buffer() { AML_TODO("Node type {} to buffer", static_cast(type)); return {}; } BAN::RefPtr AML::Node::as_integer() { AML_TODO("Node type {} to integer", static_cast(type)); return {}; } BAN::RefPtr AML::Node::as_string() { AML_TODO("Node type {} to string", static_cast(type)); return {}; } AML::ParseResult AML::parse_object(AML::ParseContext& context) { if (context.aml_data.size() < 1) return ParseResult::Failure; if (static_cast(context.aml_data[0]) == AML::Byte::ExtOpPrefix) { if (context.aml_data.size() < 2) return ParseResult::Failure; switch (static_cast(context.aml_data[1])) { case AML::ExtOp::FieldOp: return AML::Field::parse(context); case AML::ExtOp::IndexFieldOp: return AML::IndexField::parse(context); case AML::ExtOp::BankFieldOp: return AML::BankField::parse(context); case AML::ExtOp::CreateFieldOp: return AML::BufferField::parse(context); case AML::ExtOp::OpRegionOp: return AML::OpRegion::parse(context); case AML::ExtOp::DeviceOp: return AML::Device::parse(context); case AML::ExtOp::MutexOp: case AML::ExtOp::AcquireOp: case AML::ExtOp::ReleaseOp: return AML::Mutex::parse(context); case AML::ExtOp::ProcessorOp: return AML::Processor::parse(context); case AML::ExtOp::PowerResOp: return AML::PowerResource::parse(context); case AML::ExtOp::ThermalZoneOp: return AML::ThermalZone::parse(context); case AML::ExtOp::CondRefOfOp: return AML::Reference::parse(context); case AML::ExtOp::SleepOp: return AML::Sleep::parse(context); case AML::ExtOp::DebugOp: context.aml_data = context.aml_data.slice(2); return ParseResult(AML::Namespace::debug_node); default: break; } AML_TODO("{2H} {2H}", context.aml_data[0], context.aml_data[1]); return ParseResult::Failure; } switch (static_cast(context.aml_data[0])) { case AML::Byte::ZeroOp: case AML::Byte::OneOp: case AML::Byte::OnesOp: case AML::Byte::BytePrefix: case AML::Byte::WordPrefix: case AML::Byte::DWordPrefix: case AML::Byte::QWordPrefix: return AML::Integer::parse(context.aml_data); case AML::Byte::StringPrefix: return AML::String::parse(context); case AML::Byte::Arg0: case AML::Byte::Arg1: case AML::Byte::Arg2: case AML::Byte::Arg3: case AML::Byte::Arg4: case AML::Byte::Arg5: case AML::Byte::Arg6: { uint8_t index = context.aml_data[0] - static_cast(AML::Byte::Arg0); context.aml_data = context.aml_data.slice(1); return ParseResult(context.method_args[index]); } case AML::Byte::Local0: case AML::Byte::Local1: case AML::Byte::Local2: case AML::Byte::Local3: case AML::Byte::Local4: case AML::Byte::Local5: case AML::Byte::Local6: case AML::Byte::Local7: { uint8_t index = context.aml_data[0] - static_cast(AML::Byte::Local0); context.aml_data = context.aml_data.slice(1); return ParseResult(context.method_locals[index]); } case AML::Byte::AddOp: case AML::Byte::AndOp: case AML::Byte::DecrementOp: case AML::Byte::DivideOp: case AML::Byte::IncrementOp: case AML::Byte::LAndOp: case AML::Byte::LEqualOp: case AML::Byte::LGreaterOp: case AML::Byte::LLessOp: case AML::Byte::LNotOp: case AML::Byte::LOrOp: case AML::Byte::ModOp: case AML::Byte::MultiplyOp: case AML::Byte::NandOp: case AML::Byte::NorOp: case AML::Byte::NotOp: case AML::Byte::OrOp: case AML::Byte::ShiftLeftOp: case AML::Byte::ShiftRightOp: case AML::Byte::SubtractOp: case AML::Byte::XorOp: return AML::Expression::parse(context); case AML::Byte::CreateBitFieldOp: case AML::Byte::CreateByteFieldOp: case AML::Byte::CreateWordFieldOp: case AML::Byte::CreateDWordFieldOp: case AML::Byte::CreateQWordFieldOp: return AML::BufferField::parse(context); case AML::Byte::NameOp: return AML::Name::parse(context); case AML::Byte::PackageOp: return AML::Package::parse(context); case AML::Byte::MethodOp: return AML::Method::parse(context); case AML::Byte::BufferOp: return AML::Buffer::parse(context); case AML::Byte::ScopeOp: return AML::Scope::parse(context); case AML::Byte::IfOp: return AML::IfElse::parse(context); case AML::Byte::WhileOp: return AML::While::parse(context); case AML::Byte::StoreOp: return AML::Store::parse(context); case AML::Byte::DerefOfOp: case AML::Byte::RefOfOp: return AML::Reference::parse(context); case AML::Byte::IndexOp: return AML::Index::parse(context); case AML::Byte::NotifyOp: return AML::Notify::parse(context); case AML::Byte::SizeOfOp: return AML::SizeOf::parse(context); case AML::Byte::NoopOp: context.aml_data = context.aml_data.slice(1); return ParseResult::Success; case AML::Byte::ReturnOp: { context.aml_data = context.aml_data.slice(1); auto result = AML::parse_object(context); if (result.success()) return ParseResult(ParseResult::Result::Returned, result.node()); AML_ERROR("Failed to parse return value for method {}", context.scope); return ParseResult::Failure; } default: break; } if (static_cast(context.aml_data[0]) == AML::Byte::RootChar || static_cast(context.aml_data[0]) == AML::Byte::ParentPrefixChar || static_cast(context.aml_data[0]) == AML::Byte::NullName || is_lead_name_char(context.aml_data[0])) { auto name_string = AML::NameString::parse(context.aml_data); if (!name_string.has_value()) return ParseResult::Failure; auto aml_object = Namespace::root_namespace()->find_object(context.scope, name_string.value(), Namespace::FindMode::Normal); if (!aml_object) { AML_ERROR("NameString {} not found in namespace", name_string.value()); return ParseResult::Failure; } if (aml_object->type == AML::Node::Type::Method) { auto* method = static_cast(aml_object.ptr()); BAN::Array, 7> args; for (uint8_t i = 0; i < method->arg_count; i++) { auto arg = AML::parse_object(context); if (!arg.success()) { AML_ERROR("Failed to parse argument {} for method {}", i, name_string.value()); return ParseResult::Failure; } args[i] = MUST(BAN::RefPtr::create(arg.node())); } auto result = method->invoke_with_sync_stack( context.sync_stack, args[0], args[1], args[2], args[3], args[4], args[5], args[6] ); if (!result.has_value()) { AML_ERROR("Failed to evaluate {}", name_string.value()); return ParseResult::Failure; } if (!result.value()) return ParseResult::Success; return ParseResult(result.value()); } return ParseResult(aml_object); } AML_TODO("{2H}", context.aml_data[0]); return ParseResult::Failure; } }