1#pragma once
2
3#include <uacpi/acpi.h>
4#include <uacpi/types.h>
5#include <uacpi/uacpi.h>
6#include <uacpi/internal/dynamic_array.h>
7#include <uacpi/internal/shareable.h>
8#include <uacpi/context.h>
9
10struct uacpi_runtime_context {
11 /*
12 * A local copy of FADT that has been verified & converted to most optimal
13 * format for faster access to the registers.
14 */
15 struct acpi_fadt fadt;
16
17 uacpi_u64 flags;
18
19#ifndef UACPI_BAREBONES_MODE
20 /*
21 * A cached pointer to FACS so that we don't have to look it up in interrupt
22 * contexts as we can't take mutexes.
23 */
24 struct acpi_facs *facs;
25
26 /*
27 * pm1{a,b}_evt_blk split into two registers for convenience
28 */
29 struct acpi_gas pm1a_status_blk;
30 struct acpi_gas pm1b_status_blk;
31 struct acpi_gas pm1a_enable_blk;
32 struct acpi_gas pm1b_enable_blk;
33
34#define UACPI_SLEEP_TYP_INVALID 0xFF
35 uacpi_u8 last_sleep_typ_a;
36 uacpi_u8 last_sleep_typ_b;
37
38 uacpi_u8 s0_sleep_typ_a;
39 uacpi_u8 s0_sleep_typ_b;
40
41 uacpi_bool global_lock_acquired;
42
43#ifndef UACPI_REDUCED_HARDWARE
44 uacpi_bool was_in_legacy_mode;
45 uacpi_bool has_global_lock;
46 uacpi_bool sci_handle_valid;
47 uacpi_handle sci_handle;
48#endif
49 uacpi_u64 opcodes_executed;
50
51 uacpi_u32 loop_timeout_seconds;
52 uacpi_u32 max_call_stack_depth;
53
54 uacpi_u32 global_lock_seq_num;
55
56 /*
57 * These are stored here to protect against stuff like:
58 * - CopyObject(JUNK, \)
59 * - CopyObject(JUNK, \_GL)
60 */
61 uacpi_mutex *global_lock_mutex;
62 uacpi_object *root_object;
63
64#ifndef UACPI_REDUCED_HARDWARE
65 uacpi_handle *global_lock_event;
66 uacpi_handle *global_lock_spinlock;
67 uacpi_bool global_lock_pending;
68#endif
69
70 uacpi_bool bad_timesource;
71 uacpi_u8 init_level;
72#endif // !UACPI_BAREBONES_MODE
73
74#ifndef UACPI_REDUCED_HARDWARE
75 uacpi_bool is_hardware_reduced;
76#endif
77
78 /*
79 * This is a per-table value but we mimic the NT implementation:
80 * treat all other definition blocks as if they were the same revision
81 * as DSDT.
82 */
83 uacpi_bool is_rev1;
84
85 uacpi_u8 log_level;
86};
87
88extern struct uacpi_runtime_context g_uacpi_rt_ctx;
89
90static inline uacpi_bool uacpi_check_flag(uacpi_u64 flag)
91{
92 return (g_uacpi_rt_ctx.flags & flag) == flag;
93}
94
95static inline uacpi_bool uacpi_should_log(enum uacpi_log_level lvl)
96{
97 return lvl <= g_uacpi_rt_ctx.log_level;
98}
99
100static inline uacpi_bool uacpi_is_hardware_reduced(void)
101{
102#ifndef UACPI_REDUCED_HARDWARE
103 return g_uacpi_rt_ctx.is_hardware_reduced;
104#else
105 return UACPI_TRUE;
106#endif
107}
108
109#ifndef UACPI_BAREBONES_MODE
110
111static inline const uacpi_char *uacpi_init_level_to_string(uacpi_u8 lvl)
112{
113 switch (lvl) {
114 case UACPI_INIT_LEVEL_EARLY:
115 return "early";
116 case UACPI_INIT_LEVEL_SUBSYSTEM_INITIALIZED:
117 return "subsystem initialized";
118 case UACPI_INIT_LEVEL_NAMESPACE_LOADED:
119 return "namespace loaded";
120 case UACPI_INIT_LEVEL_NAMESPACE_INITIALIZED:
121 return "namespace initialized";
122 default:
123 return "<invalid>";
124 }
125}
126
127#define UACPI_ENSURE_INIT_LEVEL_AT_LEAST(lvl) \
128 do { \
129 if (uacpi_unlikely(g_uacpi_rt_ctx.init_level < lvl)) { \
130 uacpi_error( \
131 "while evaluating %s: init level %d (%s) is too low, " \
132 "expected at least %d (%s)\n", __FUNCTION__, \
133 g_uacpi_rt_ctx.init_level, \
134 uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
135 uacpi_init_level_to_string(lvl) \
136 ); \
137 return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
138 } \
139 } while (0)
140
141#define UACPI_ENSURE_INIT_LEVEL_IS(lvl) \
142 do { \
143 if (uacpi_unlikely(g_uacpi_rt_ctx.init_level != lvl)) { \
144 uacpi_error( \
145 "while evaluating %s: invalid init level %d (%s), " \
146 "expected %d (%s)\n", __FUNCTION__, \
147 g_uacpi_rt_ctx.init_level, \
148 uacpi_init_level_to_string(g_uacpi_rt_ctx.init_level), lvl, \
149 uacpi_init_level_to_string(lvl) \
150 ); \
151 return UACPI_STATUS_INIT_LEVEL_MISMATCH; \
152 } \
153 } while (0)
154
155#endif // !UACPI_BAREBONES_MODE
156