1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2/******************************************************************************
3 *
4 * Module Name: utxfinit - External interfaces for ACPICA initialization
5 *
6 * Copyright (C) 2000 - 2023, Intel Corp.
7 *
8 *****************************************************************************/
9
10#define EXPORT_ACPI_INTERFACES
11
12#include <acpi/acpi.h>
13#include "accommon.h"
14#include "acevents.h"
15#include "acnamesp.h"
16#include "acdebug.h"
17#include "actables.h"
18
19#define _COMPONENT          ACPI_UTILITIES
20ACPI_MODULE_NAME("utxfinit")
21
22/* For acpi_exec only */
23void ae_do_object_overrides(void);
24
25/*******************************************************************************
26 *
27 * FUNCTION:    acpi_initialize_subsystem
28 *
29 * PARAMETERS:  None
30 *
31 * RETURN:      Status
32 *
33 * DESCRIPTION: Initializes all global variables. This is the first function
34 *              called, so any early initialization belongs here.
35 *
36 ******************************************************************************/
37
38acpi_status ACPI_INIT_FUNCTION acpi_initialize_subsystem(void)
39{
40	acpi_status status;
41
42	ACPI_FUNCTION_TRACE(acpi_initialize_subsystem);
43
44	acpi_gbl_startup_flags = ACPI_SUBSYSTEM_INITIALIZE;
45	ACPI_DEBUG_EXEC(acpi_ut_init_stack_ptr_trace());
46
47	/* Initialize the OS-Dependent layer */
48
49	status = acpi_os_initialize();
50	if (ACPI_FAILURE(status)) {
51		ACPI_EXCEPTION((AE_INFO, status, "During OSL initialization"));
52		return_ACPI_STATUS(status);
53	}
54
55	/* Initialize all globals used by the subsystem */
56
57	status = acpi_ut_init_globals();
58	if (ACPI_FAILURE(status)) {
59		ACPI_EXCEPTION((AE_INFO, status,
60				"During initialization of globals"));
61		return_ACPI_STATUS(status);
62	}
63
64	/* Create the default mutex objects */
65
66	status = acpi_ut_mutex_initialize();
67	if (ACPI_FAILURE(status)) {
68		ACPI_EXCEPTION((AE_INFO, status,
69				"During Global Mutex creation"));
70		return_ACPI_STATUS(status);
71	}
72
73	/*
74	 * Initialize the namespace manager and
75	 * the root of the namespace tree
76	 */
77	status = acpi_ns_root_initialize();
78	if (ACPI_FAILURE(status)) {
79		ACPI_EXCEPTION((AE_INFO, status,
80				"During Namespace initialization"));
81		return_ACPI_STATUS(status);
82	}
83
84	/* Initialize the global OSI interfaces list with the static names */
85
86	status = acpi_ut_initialize_interfaces();
87	if (ACPI_FAILURE(status)) {
88		ACPI_EXCEPTION((AE_INFO, status,
89				"During OSI interfaces initialization"));
90		return_ACPI_STATUS(status);
91	}
92
93	return_ACPI_STATUS(AE_OK);
94}
95
96ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_subsystem)
97
98/*******************************************************************************
99 *
100 * FUNCTION:    acpi_enable_subsystem
101 *
102 * PARAMETERS:  flags               - Init/enable Options
103 *
104 * RETURN:      Status
105 *
106 * DESCRIPTION: Completes the subsystem initialization including hardware.
107 *              Puts system into ACPI mode if it isn't already.
108 *
109 ******************************************************************************/
110acpi_status ACPI_INIT_FUNCTION acpi_enable_subsystem(u32 flags)
111{
112	acpi_status status = AE_OK;
113
114	ACPI_FUNCTION_TRACE(acpi_enable_subsystem);
115
116	/*
117	 * The early initialization phase is complete. The namespace is loaded,
118	 * and we can now support address spaces other than Memory, I/O, and
119	 * PCI_Config.
120	 */
121	acpi_gbl_early_initialization = FALSE;
122
123#if (!ACPI_REDUCED_HARDWARE)
124
125	/* Enable ACPI mode */
126
127	if (!(flags & ACPI_NO_ACPI_ENABLE)) {
128		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
129				  "[Init] Going into ACPI mode\n"));
130
131		acpi_gbl_original_mode = acpi_hw_get_mode();
132
133		status = acpi_enable();
134		if (ACPI_FAILURE(status)) {
135			ACPI_WARNING((AE_INFO, "AcpiEnable failed"));
136			return_ACPI_STATUS(status);
137		}
138	}
139
140	/*
141	 * Obtain a permanent mapping for the FACS. This is required for the
142	 * Global Lock and the Firmware Waking Vector
143	 */
144	if (!(flags & ACPI_NO_FACS_INIT)) {
145		status = acpi_tb_initialize_facs();
146		if (ACPI_FAILURE(status)) {
147			ACPI_WARNING((AE_INFO, "Could not map the FACS table"));
148			return_ACPI_STATUS(status);
149		}
150	}
151
152	/*
153	 * Initialize ACPI Event handling (Fixed and General Purpose)
154	 *
155	 * Note1: We must have the hardware and events initialized before we can
156	 * execute any control methods safely. Any control method can require
157	 * ACPI hardware support, so the hardware must be fully initialized before
158	 * any method execution!
159	 *
160	 * Note2: Fixed events are initialized and enabled here. GPEs are
161	 * initialized, but cannot be enabled until after the hardware is
162	 * completely initialized (SCI and global_lock activated) and the various
163	 * initialization control methods are run (_REG, _STA, _INI) on the
164	 * entire namespace.
165	 */
166	if (!(flags & ACPI_NO_EVENT_INIT)) {
167		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
168				  "[Init] Initializing ACPI events\n"));
169
170		status = acpi_ev_initialize_events();
171		if (ACPI_FAILURE(status)) {
172			return_ACPI_STATUS(status);
173		}
174	}
175
176	/*
177	 * Install the SCI handler and Global Lock handler. This completes the
178	 * hardware initialization.
179	 */
180	if (!(flags & ACPI_NO_HANDLER_INIT)) {
181		ACPI_DEBUG_PRINT((ACPI_DB_EXEC,
182				  "[Init] Installing SCI/GL handlers\n"));
183
184		status = acpi_ev_install_xrupt_handlers();
185		if (ACPI_FAILURE(status)) {
186			return_ACPI_STATUS(status);
187		}
188	}
189#endif				/* !ACPI_REDUCED_HARDWARE */
190
191	return_ACPI_STATUS(status);
192}
193
194ACPI_EXPORT_SYMBOL_INIT(acpi_enable_subsystem)
195
196/*******************************************************************************
197 *
198 * FUNCTION:    acpi_initialize_objects
199 *
200 * PARAMETERS:  flags               - Init/enable Options
201 *
202 * RETURN:      Status
203 *
204 * DESCRIPTION: Completes namespace initialization by initializing device
205 *              objects and executing AML code for Regions, buffers, etc.
206 *
207 ******************************************************************************/
208acpi_status ACPI_INIT_FUNCTION acpi_initialize_objects(u32 flags)
209{
210	acpi_status status = AE_OK;
211
212	ACPI_FUNCTION_TRACE(acpi_initialize_objects);
213
214#ifdef ACPI_OBSOLETE_BEHAVIOR
215	/*
216	 * 05/2019: Removed, initialization now happens at both object
217	 * creation and table load time
218	 */
219
220	/*
221	 * Initialize the objects that remain uninitialized. This
222	 * runs the executable AML that may be part of the
223	 * declaration of these objects: operation_regions, buffer_fields,
224	 * bank_fields, Buffers, and Packages.
225	 */
226	if (!(flags & ACPI_NO_OBJECT_INIT)) {
227		status = acpi_ns_initialize_objects();
228		if (ACPI_FAILURE(status)) {
229			return_ACPI_STATUS(status);
230		}
231	}
232#endif
233
234	/*
235	 * Initialize all device/region objects in the namespace. This runs
236	 * the device _STA and _INI methods and region _REG methods.
237	 */
238	if (!(flags & (ACPI_NO_DEVICE_INIT | ACPI_NO_ADDRESS_SPACE_INIT))) {
239		status = acpi_ns_initialize_devices(flags);
240		if (ACPI_FAILURE(status)) {
241			return_ACPI_STATUS(status);
242		}
243	}
244
245	/*
246	 * Empty the caches (delete the cached objects) on the assumption that
247	 * the table load filled them up more than they will be at runtime --
248	 * thus wasting non-paged memory.
249	 */
250	status = acpi_purge_cached_objects();
251
252	acpi_gbl_startup_flags |= ACPI_INITIALIZED_OK;
253	return_ACPI_STATUS(status);
254}
255
256ACPI_EXPORT_SYMBOL_INIT(acpi_initialize_objects)
257