Kernel: Simplify AML method invocation API
This commit is contained in:
		
							parent
							
								
									a40ef610a2
								
							
						
					
					
						commit
						49b7467840
					
				| 
						 | 
					@ -11,9 +11,7 @@ namespace Kernel::ACPI::AML
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Method : public AML::Scope
 | 
						struct Method : public AML::Scope
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		using Arguments = BAN::Array<BAN::RefPtr<AML::Register>, 7>;
 | 
							Kernel::Mutex mutex;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		Mutex mutex;
 | 
					 | 
				
			||||||
		uint8_t arg_count;
 | 
							uint8_t arg_count;
 | 
				
			||||||
		bool serialized;
 | 
							bool serialized;
 | 
				
			||||||
		uint8_t sync_level;
 | 
							uint8_t sync_level;
 | 
				
			||||||
| 
						 | 
					@ -64,7 +62,30 @@ namespace Kernel::ACPI::AML
 | 
				
			||||||
			return ParseResult::Success;
 | 
								return ParseResult::Success;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::Optional<BAN::RefPtr<AML::Node>> evaluate(Arguments args, BAN::Vector<uint8_t>& current_sync_stack)
 | 
							BAN::Optional<BAN::RefPtr<AML::Node>> invoke(
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg0 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg1 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg2 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg3 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg4 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg5 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg6 = {}
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								BAN::Vector<uint8_t> sync_stack;
 | 
				
			||||||
 | 
								return invoke_with_sync_stack(sync_stack, arg0, arg1, arg2, arg3, arg4, arg5, arg6);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BAN::Optional<BAN::RefPtr<AML::Node>> invoke_with_sync_stack(
 | 
				
			||||||
 | 
								BAN::Vector<uint8_t>& current_sync_stack,
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg0 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg1 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg2 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg3 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg4 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg5 = {},
 | 
				
			||||||
 | 
								BAN::RefPtr<AML::Node> arg6 = {}
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
 | 
								if (serialized && !current_sync_stack.empty() && sync_level < current_sync_stack.back())
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -75,7 +96,13 @@ namespace Kernel::ACPI::AML
 | 
				
			||||||
			ParseContext context;
 | 
								ParseContext context;
 | 
				
			||||||
			context.aml_data = term_list;
 | 
								context.aml_data = term_list;
 | 
				
			||||||
			context.scope = scope;
 | 
								context.scope = scope;
 | 
				
			||||||
			context.method_args = args;
 | 
								context.method_args[0] = MUST(BAN::RefPtr<AML::Register>::create(arg0));
 | 
				
			||||||
 | 
								context.method_args[1] = MUST(BAN::RefPtr<AML::Register>::create(arg1));
 | 
				
			||||||
 | 
								context.method_args[2] = MUST(BAN::RefPtr<AML::Register>::create(arg2));
 | 
				
			||||||
 | 
								context.method_args[3] = MUST(BAN::RefPtr<AML::Register>::create(arg3));
 | 
				
			||||||
 | 
								context.method_args[4] = MUST(BAN::RefPtr<AML::Register>::create(arg4));
 | 
				
			||||||
 | 
								context.method_args[5] = MUST(BAN::RefPtr<AML::Register>::create(arg5));
 | 
				
			||||||
 | 
								context.method_args[6] = MUST(BAN::RefPtr<AML::Register>::create(arg6));
 | 
				
			||||||
			context.sync_stack = BAN::move(current_sync_stack);
 | 
								context.sync_stack = BAN::move(current_sync_stack);
 | 
				
			||||||
			for (auto& local : context.method_locals)
 | 
								for (auto& local : context.method_locals)
 | 
				
			||||||
				local = MUST(BAN::RefPtr<AML::Register>::create());
 | 
									local = MUST(BAN::RefPtr<AML::Register>::create());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -396,10 +396,7 @@ acpi_release_global_lock:
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			AML::Method::Arguments args;
 | 
								if (!method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(5))).has_value())
 | 
				
			||||||
			args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(5))));
 | 
					 | 
				
			||||||
			BAN::Vector<uint8_t> sync_stack;
 | 
					 | 
				
			||||||
			if (!method->evaluate(args, sync_stack).has_value())
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				dwarnln("Failed to evaluate \\_PTS");
 | 
									dwarnln("Failed to evaluate \\_PTS");
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
| 
						 | 
					@ -482,11 +479,7 @@ acpi_release_global_lock:
 | 
				
			||||||
				dwarnln("Method \\_PIC has {} arguments, expected 1", method->arg_count);
 | 
									dwarnln("Method \\_PIC has {} arguments, expected 1", method->arg_count);
 | 
				
			||||||
				return BAN::Error::from_errno(EINVAL);
 | 
									return BAN::Error::from_errno(EINVAL);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
								method->invoke(MUST(BAN::RefPtr<AML::Integer>::create(mode)));
 | 
				
			||||||
			AML::Method::Arguments args;
 | 
					 | 
				
			||||||
			args[0] = MUST(BAN::RefPtr<AML::Register>::create(MUST(BAN::RefPtr<AML::Integer>::create(mode))));
 | 
					 | 
				
			||||||
			BAN::Vector<uint8_t> sync_stack;
 | 
					 | 
				
			||||||
			method->evaluate(args, sync_stack);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dprintln("Devices are initialized");
 | 
							dprintln("Devices are initialized");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,7 +201,7 @@ namespace Kernel::ACPI
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				auto* method = static_cast<AML::Method*>(aml_object.ptr());
 | 
									auto* method = static_cast<AML::Method*>(aml_object.ptr());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Method::Arguments args;
 | 
									BAN::Array<BAN::RefPtr<AML::Node>, 7> args;
 | 
				
			||||||
				for (uint8_t i = 0; i < method->arg_count; i++)
 | 
									for (uint8_t i = 0; i < method->arg_count; i++)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					auto arg = AML::parse_object(context);
 | 
										auto arg = AML::parse_object(context);
 | 
				
			||||||
| 
						 | 
					@ -213,7 +213,16 @@ namespace Kernel::ACPI
 | 
				
			||||||
					args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
 | 
										args[i] = MUST(BAN::RefPtr<AML::Register>::create(arg.node()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				auto result = method->evaluate(args, context.sync_stack);
 | 
									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())
 | 
									if (!result.has_value())
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					AML_ERROR("Failed to evaluate {}", name_string.value());
 | 
										AML_ERROR("Failed to evaluate {}", name_string.value());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,8 +78,7 @@ namespace Kernel::ACPI
 | 
				
			||||||
			return {};
 | 
								return {};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		BAN::Vector<uint8_t> sync_stack;
 | 
							auto result = method->invoke();
 | 
				
			||||||
		auto result = method->evaluate({}, sync_stack);
 | 
					 | 
				
			||||||
		if (!result.has_value())
 | 
							if (!result.has_value())
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			AML_ERROR("Failed to evaluate method");
 | 
								AML_ERROR("Failed to evaluate method");
 | 
				
			||||||
| 
						 | 
					@ -125,11 +124,7 @@ namespace Kernel::ACPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				BAN::RefPtr<AML::Node> embedded_controller = MUST(BAN::RefPtr<AML::Integer>::create(static_cast<uint64_t>(AML::OpRegion::RegionSpace::EmbeddedController)));
 | 
									BAN::RefPtr<AML::Node> embedded_controller = MUST(BAN::RefPtr<AML::Integer>::create(static_cast<uint64_t>(AML::OpRegion::RegionSpace::EmbeddedController)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Method::Arguments arguments;
 | 
									if (!method->invoke(embedded_controller, AML::Integer::Constants::One).has_value())
 | 
				
			||||||
				arguments[0] = MUST(BAN::RefPtr<AML::Register>::create(embedded_controller));
 | 
					 | 
				
			||||||
				arguments[1] = MUST(BAN::RefPtr<AML::Register>::create(AML::Integer::Constants::One));
 | 
					 | 
				
			||||||
				BAN::Vector<uint8_t> sync_stack;
 | 
					 | 
				
			||||||
				if (!method->evaluate(arguments, sync_stack).has_value())
 | 
					 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					AML_ERROR("Failed to evaluate {}._REG(EmbeddedController, 1), ignoring device", scope->scope);
 | 
										AML_ERROR("Failed to evaluate {}._REG(EmbeddedController, 1), ignoring device", scope->scope);
 | 
				
			||||||
					return false;
 | 
										return false;
 | 
				
			||||||
| 
						 | 
					@ -171,8 +166,7 @@ namespace Kernel::ACPI
 | 
				
			||||||
					return false;
 | 
										return false;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				BAN::Vector<uint8_t> sync_stack;
 | 
									auto result = method->invoke();
 | 
				
			||||||
				auto result = method->evaluate({}, sync_stack);
 | 
					 | 
				
			||||||
				if (!result.has_value())
 | 
									if (!result.has_value())
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					AML_ERROR("Failed to evaluate {}._INI, ignoring device", scope->scope);
 | 
										AML_ERROR("Failed to evaluate {}._INI, ignoring device", scope->scope);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue