summaryrefslogtreecommitdiff
path: root/src/include/acpi/acpigen.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/acpi/acpigen.h')
-rw-r--r--src/include/acpi/acpigen.h490
1 files changed, 490 insertions, 0 deletions
diff --git a/src/include/acpi/acpigen.h b/src/include/acpi/acpigen.h
new file mode 100644
index 0000000000..a3c4777afb
--- /dev/null
+++ b/src/include/acpi/acpigen.h
@@ -0,0 +1,490 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/* This file is part of the coreboot project. */
+
+#ifndef LIBACPI_H
+#define LIBACPI_H
+
+#include <stdint.h>
+#include <arch/acpi.h>
+#include <arch/acpi_device.h>
+#include <arch/acpi_pld.h>
+#include <device/pci_type.h>
+
+/* Values that can be returned for ACPI Device _STA method */
+#define ACPI_STATUS_DEVICE_PRESENT (1 << 0)
+#define ACPI_STATUS_DEVICE_ENABLED (1 << 1)
+#define ACPI_STATUS_DEVICE_SHOW_IN_UI (1 << 2)
+#define ACPI_STATUS_DEVICE_STATE_OK (1 << 3)
+
+#define ACPI_STATUS_DEVICE_ALL_OFF 0
+#define ACPI_STATUS_DEVICE_ALL_ON (ACPI_STATUS_DEVICE_PRESENT |\
+ ACPI_STATUS_DEVICE_ENABLED |\
+ ACPI_STATUS_DEVICE_SHOW_IN_UI |\
+ ACPI_STATUS_DEVICE_STATE_OK)
+#define ACPI_STATUS_DEVICE_HIDDEN_ON (ACPI_STATUS_DEVICE_PRESENT |\
+ ACPI_STATUS_DEVICE_ENABLED |\
+ ACPI_STATUS_DEVICE_STATE_OK)
+
+/* ACPI Op/Prefix Codes */
+enum {
+ ZERO_OP = 0x00,
+ ONE_OP = 0x01,
+ ALIAS_OP = 0x06,
+ NAME_OP = 0x08,
+ BYTE_PREFIX = 0x0A,
+ WORD_PREFIX = 0x0B,
+ DWORD_PREFIX = 0x0C,
+ STRING_PREFIX = 0x0D,
+ QWORD_PREFIX = 0x0E,
+ SCOPE_OP = 0x10,
+ BUFFER_OP = 0x11,
+ PACKAGE_OP = 0x12,
+ VARIABLE_PACKAGE_OP = 0x13,
+ METHOD_OP = 0x14,
+ EXTERNAL_OP = 0x15,
+ DUAL_NAME_PREFIX = 0x2E,
+ MULTI_NAME_PREFIX = 0x2F,
+ EXT_OP_PREFIX = 0x5B,
+ MUTEX_OP = 0x01,
+ EVENT_OP = 0x01,
+ SF_RIGHT_OP = 0x10,
+ SF_LEFT_OP = 0x11,
+ COND_REFOF_OP = 0x12,
+ CREATEFIELD_OP = 0x13,
+ LOAD_TABLE_OP = 0x1f,
+ LOAD_OP = 0x20,
+ STALL_OP = 0x21,
+ SLEEP_OP = 0x22,
+ ACQUIRE_OP = 0x23,
+ SIGNAL_OP = 0x24,
+ WAIT_OP = 0x25,
+ RST_OP = 0x26,
+ RELEASE_OP = 0x27,
+ FROM_BCD_OP = 0x28,
+ TO_BCD_OP = 0x29,
+ UNLOAD_OP = 0x2A,
+ REVISON_OP = 0x30,
+ DEBUG_OP = 0x31,
+ FATAL_OP = 0x32,
+ TIMER_OP = 0x33,
+ OPREGION_OP = 0x80,
+ FIELD_OP = 0x81,
+ DEVICE_OP = 0x82,
+ PROCESSOR_OP = 0x83,
+ POWER_RES_OP = 0x84,
+ THERMAL_ZONE_OP = 0x85,
+ INDEX_FIELD_OP = 0x86,
+ BANK_FIELD_OP = 0x87,
+ DATA_REGION_OP = 0x88,
+ ROOT_PREFIX = 0x5C,
+ PARENT_PREFIX = 0x5E,
+ LOCAL0_OP = 0x60,
+ LOCAL1_OP = 0x61,
+ LOCAL2_OP = 0x62,
+ LOCAL3_OP = 0x63,
+ LOCAL4_OP = 0x64,
+ LOCAL5_OP = 0x65,
+ LOCAL6_OP = 0x66,
+ LOCAL7_OP = 0x67,
+ ARG0_OP = 0x68,
+ ARG1_OP = 0x69,
+ ARG2_OP = 0x6A,
+ ARG3_OP = 0x6B,
+ ARG4_OP = 0x6C,
+ ARG5_OP = 0x6D,
+ ARG6_OP = 0x6E,
+ STORE_OP = 0x70,
+ REF_OF_OP = 0x71,
+ ADD_OP = 0x72,
+ CONCATENATE_OP = 0x73,
+ SUBTRACT_OP = 0x74,
+ INCREMENT_OP = 0x75,
+ DECREMENT_OP = 0x76,
+ MULTIPLY_OP = 0x77,
+ DIVIDE_OP = 0x78,
+ SHIFT_LEFT_OP = 0x79,
+ SHIFT_RIGHT_OP = 0x7A,
+ AND_OP = 0x7B,
+ NAND_OP = 0x7C,
+ OR_OP = 0x7D,
+ NOR_OP = 0x7E,
+ XOR_OP = 0x7F,
+ NOT_OP = 0x80,
+ FD_SHIFT_LEFT_BIT_OR = 0x81,
+ FD_SHIFT_RIGHT_BIT_OR = 0x82,
+ DEREF_OP = 0x83,
+ CONCATENATE_TEMP_OP = 0x84,
+ MOD_OP = 0x85,
+ NOTIFY_OP = 0x86,
+ SIZEOF_OP = 0x87,
+ INDEX_OP = 0x88,
+ MATCH_OP = 0x89,
+ CREATE_DWORD_OP = 0x8A,
+ CREATE_WORD_OP = 0x8B,
+ CREATE_BYTE_OP = 0x8C,
+ CREATE_BIT_OP = 0x8D,
+ OBJ_TYPE_OP = 0x8E,
+ CREATE_QWORD_OP = 0x8F,
+ LAND_OP = 0x90,
+ LOR_OP = 0x91,
+ LNOT_OP = 0x92,
+ LEQUAL_OP = 0x93,
+ LGREATER_OP = 0x94,
+ LLESS_OP = 0x95,
+ TO_BUFFER_OP = 0x96,
+ TO_DEC_STRING_OP = 0x97,
+ TO_HEX_STRING_OP = 0x98,
+ TO_INTEGER_OP = 0x99,
+ TO_STRING_OP = 0x9C,
+ CP_OBJ_OP = 0x9D,
+ MID_OP = 0x9E,
+ CONTINUE_OP = 0x9F,
+ IF_OP = 0xA0,
+ ELSE_OP = 0xA1,
+ WHILE_OP = 0xA2,
+ NOOP_OP = 0xA3,
+ RETURN_OP = 0xA4,
+ BREAK_OP = 0xA5,
+ COMMENT_OP = 0xA9,
+ BREAKPIONT_OP = 0xCC,
+ ONES_OP = 0xFF,
+};
+
+#define FIELDLIST_OFFSET(X) { .type = OFFSET, \
+ .name = "",\
+ .bits = X * 8, \
+ }
+#define FIELDLIST_NAMESTR(X, Y) { .type = NAME_STRING, \
+ .name = X, \
+ .bits = Y, \
+ }
+
+#define FIELD_ANYACC 0
+#define FIELD_BYTEACC 1
+#define FIELD_WORDACC 2
+#define FIELD_DWORDACC 3
+#define FIELD_QWORDACC 4
+#define FIELD_BUFFERACC 5
+#define FIELD_NOLOCK (0<<4)
+#define FIELD_LOCK (1<<4)
+#define FIELD_PRESERVE (0<<5)
+#define FIELD_WRITEASONES (1<<5)
+#define FIELD_WRITEASZEROS (2<<5)
+
+enum field_type {
+ OFFSET,
+ NAME_STRING,
+ FIELD_TYPE_MAX,
+};
+
+struct fieldlist {
+ enum field_type type;
+ const char *name;
+ u32 bits;
+};
+
+#define OPREGION(rname, space, offset, len) {.name = rname, \
+ .regionspace = space, \
+ .regionoffset = offset, \
+ .regionlen = len, \
+ }
+
+enum region_space {
+ SYSTEMMEMORY,
+ SYSTEMIO,
+ PCI_CONFIG,
+ EMBEDDEDCONTROL,
+ SMBUS,
+ CMOS,
+ PCIBARTARGET,
+ IPMI,
+ GPIO_REGION,
+ GPSERIALBUS,
+ PCC,
+ FIXED_HARDWARE = 0x7F,
+ REGION_SPACE_MAX,
+};
+
+struct opregion {
+ const char *name;
+ enum region_space regionspace;
+ unsigned long regionoffset;
+ unsigned long regionlen;
+};
+
+#define DSM_UUID(DSM_UUID, DSM_CALLBACKS, DSM_COUNT, DSM_ARG) \
+ { .uuid = DSM_UUID, \
+ .callbacks = DSM_CALLBACKS, \
+ .count = DSM_COUNT, \
+ .arg = DSM_ARG, \
+ }
+
+struct dsm_uuid {
+ const char *uuid;
+ void (**callbacks)(void *);
+ size_t count;
+ void *arg;
+};
+
+/*version 1 has 15 fields, version 2 has 19, and version 3 has 21 */
+enum cppc_fields {
+ CPPC_HIGHEST_PERF, /* can be DWORD */
+ CPPC_NOMINAL_PERF, /* can be DWORD */
+ CPPC_LOWEST_NONL_PERF, /* can be DWORD */
+ CPPC_LOWEST_PERF, /* can be DWORD */
+ CPPC_GUARANTEED_PERF,
+ CPPC_DESIRED_PERF,
+ CPPC_MIN_PERF,
+ CPPC_MAX_PERF,
+ CPPC_PERF_REDUCE_TOLERANCE,
+ CPPC_TIME_WINDOW,
+ CPPC_COUNTER_WRAP, /* can be DWORD */
+ CPPC_REF_PERF_COUNTER,
+ CPPC_DELIVERED_PERF_COUNTER,
+ CPPC_PERF_LIMITED,
+ CPPC_ENABLE, /* can be System I/O */
+ CPPC_MAX_FIELDS_VER_1,
+ CPPC_AUTO_SELECT = /* can be DWORD */
+ CPPC_MAX_FIELDS_VER_1,
+ CPPC_AUTO_ACTIVITY_WINDOW,
+ CPPC_PERF_PREF,
+ CPPC_REF_PERF, /* can be DWORD */
+ CPPC_MAX_FIELDS_VER_2,
+ CPPC_LOWEST_FREQ = /* can be DWORD */
+ CPPC_MAX_FIELDS_VER_2,
+ CPPC_NOMINAL_FREQ, /* can be DWORD */
+ CPPC_MAX_FIELDS_VER_3,
+};
+
+struct cppc_config {
+ u32 version; /* must be 1, 2, or 3 */
+ /*
+ * The generic acpi_addr_t structure is being used, though
+ * anything besides PPC or FFIXED generally requires checking
+ * if the OS has advertised support for it (via _OSC).
+ *
+ * NOTE: some fields permit DWORDs to be used. If you
+ * provide a System Memory register with all zeros (which
+ * represents unsupported) then this will be used as-is.
+ * Otherwise, a System Memory register with a 32-bit
+ * width will be converted into a DWORD field (the value
+ * of which will be the value of 'addrl'. Any other use
+ * of System Memory register is currently undefined.
+ * (i.e., if you have an actual need for System Memory
+ * then you'll need to adjust this kludge).
+ */
+ acpi_addr_t regs[CPPC_MAX_FIELDS_VER_3];
+};
+
+void acpigen_write_return_integer(uint64_t arg);
+void acpigen_write_return_string(const char *arg);
+void acpigen_write_len_f(void);
+void acpigen_pop_len(void);
+void acpigen_set_current(char *curr);
+char *acpigen_get_current(void);
+char *acpigen_write_package(int nr_el);
+void acpigen_write_zero(void);
+void acpigen_write_one(void);
+void acpigen_write_ones(void);
+void acpigen_write_byte(unsigned int data);
+void acpigen_emit_byte(unsigned char data);
+void acpigen_emit_ext_op(uint8_t op);
+void acpigen_emit_word(unsigned int data);
+void acpigen_emit_dword(unsigned int data);
+void acpigen_emit_stream(const char *data, int size);
+void acpigen_emit_string(const char *string);
+void acpigen_emit_namestring(const char *namepath);
+void acpigen_emit_eisaid(const char *eisaid);
+void acpigen_write_word(unsigned int data);
+void acpigen_write_dword(unsigned int data);
+void acpigen_write_qword(uint64_t data);
+void acpigen_write_integer(uint64_t data);
+void acpigen_write_string(const char *string);
+void acpigen_write_name_unicode(const char *name, const char *string);
+void acpigen_write_name(const char *name);
+void acpigen_write_name_zero(const char *name);
+void acpigen_write_name_one(const char *name);
+void acpigen_write_name_string(const char *name, const char *string);
+void acpigen_write_name_dword(const char *name, uint32_t val);
+void acpigen_write_name_qword(const char *name, uint64_t val);
+void acpigen_write_name_byte(const char *name, uint8_t val);
+void acpigen_write_name_integer(const char *name, uint64_t val);
+void acpigen_write_coreboot_hid(enum coreboot_acpi_ids id);
+void acpigen_write_scope(const char *name);
+void acpigen_write_method(const char *name, int nargs);
+void acpigen_write_method_serialized(const char *name, int nargs);
+void acpigen_write_device(const char *name);
+void acpigen_write_PPC(u8 nr);
+void acpigen_write_PPC_NVS(void);
+void acpigen_write_empty_PCT(void);
+void acpigen_write_empty_PTC(void);
+void acpigen_write_PRW(u32 wake, u32 level);
+void acpigen_write_STA(uint8_t status);
+void acpigen_write_TPC(const char *gnvs_tpc_limit);
+void acpigen_write_PSS_package(u32 coreFreq, u32 power, u32 transLat,
+ u32 busmLat, u32 control, u32 status);
+typedef enum { SW_ALL = 0xfc, SW_ANY = 0xfd, HW_ALL = 0xfe } PSD_coord;
+void acpigen_write_PSD_package(u32 domain, u32 numprocs, PSD_coord coordtype);
+void acpigen_write_CST_package_entry(acpi_cstate_t *cstate);
+void acpigen_write_CST_package(acpi_cstate_t *entry, int nentries);
+typedef enum { CSD_HW_ALL = 0xfe } CSD_coord;
+void acpigen_write_CSD_package(u32 domain, u32 numprocs, CSD_coord coordtype,
+ u32 index);
+void acpigen_write_processor(u8 cpuindex, u32 pblock_addr, u8 pblock_len);
+void acpigen_write_processor_package(const char *name,
+ unsigned int first_core,
+ unsigned int core_count);
+void acpigen_write_processor_cnot(const unsigned int number_of_cores);
+void acpigen_write_TSS_package(int entries, acpi_tstate_t *tstate_list);
+void acpigen_write_TSD_package(u32 domain, u32 numprocs, PSD_coord coordtype);
+void acpigen_write_mem32fixed(int readwrite, u32 base, u32 size);
+void acpigen_write_io16(u16 min, u16 max, u8 align, u8 len, u8 decode16);
+void acpigen_write_register_resource(const acpi_addr_t *addr);
+void acpigen_write_resourcetemplate_header(void);
+void acpigen_write_resourcetemplate_footer(void);
+void acpigen_write_mainboard_resource_template(void);
+void acpigen_write_mainboard_resources(const char *scope, const char *name);
+void acpigen_write_irq(u16 mask);
+void acpigen_write_uuid(const char *uuid);
+void acpigen_write_power_res(const char *name, uint8_t level, uint16_t order,
+ const char * const dev_states[], size_t dev_states_count);
+void acpigen_write_sleep(uint64_t sleep_ms);
+void acpigen_write_store(void);
+void acpigen_write_store_ops(uint8_t src, uint8_t dst);
+void acpigen_write_store_op_to_namestr(uint8_t src, const char *dst);
+void acpigen_write_or(uint8_t arg1, uint8_t arg2, uint8_t res);
+void acpigen_write_xor(uint8_t arg1, uint8_t arg2, uint8_t res);
+void acpigen_write_and(uint8_t arg1, uint8_t arg2, uint8_t res);
+void acpigen_write_not(uint8_t arg, uint8_t res);
+void acpigen_write_debug_string(const char *str);
+void acpigen_write_debug_integer(uint64_t val);
+void acpigen_write_debug_op(uint8_t op);
+void acpigen_write_if(void);
+void acpigen_write_if_and(uint8_t arg1, uint8_t arg2);
+void acpigen_write_if_lequal_op_int(uint8_t op, uint64_t val);
+void acpigen_write_if_lequal_namestr_int(const char *namestr, uint64_t val);
+void acpigen_write_else(void);
+void acpigen_write_to_buffer(uint8_t src, uint8_t dst);
+void acpigen_write_to_integer(uint8_t src, uint8_t dst);
+void acpigen_write_byte_buffer(uint8_t *arr, size_t size);
+void acpigen_write_return_byte_buffer(uint8_t *arr, size_t size);
+void acpigen_write_return_singleton_buffer(uint8_t arg);
+void acpigen_write_return_byte(uint8_t arg);
+void acpigen_write_upc(enum acpi_upc_type type);
+void acpigen_write_pld(const struct acpi_pld *pld);
+void acpigen_write_ADR(uint64_t adr);
+void acpigen_write_ADR_pci_devfn(pci_devfn_t devfn);
+void acpigen_write_ADR_pci_device(const struct device *dev);
+/*
+ * Generate ACPI AML code for _DSM method.
+ * This function takes as input uuid for the device, set of callbacks and
+ * argument to pass into the callbacks. Callbacks should ensure that Local0 and
+ * Local1 are left untouched. Use of Local2-Local7 is permitted in callbacks.
+ */
+void acpigen_write_dsm(const char *uuid, void (**callbacks)(void *),
+ size_t count, void *arg);
+void acpigen_write_dsm_uuid_arr(struct dsm_uuid *ids, size_t count);
+
+/*
+ * Generate ACPI AML code for _CPC (Continuous Performance Control).
+ * Execute the package function once to create a global table, then
+ * execute the method function within each processor object to
+ * create a method that points to the global table.
+ */
+void acpigen_write_CPPC_package(const struct cppc_config *config);
+void acpigen_write_CPPC_method(void);
+
+/*
+ * Generate ACPI AML code for _ROM method.
+ * This function takes as input ROM data and ROM length.
+ * The ROM length has to be multiple of 4096 and has to be less
+ * than the current implementation limit of 0x40000.
+ */
+void acpigen_write_rom(void *bios, const size_t length);
+/*
+ * Generate ACPI AML code for OperationRegion
+ * This function takes input region name, region space, region offset & region
+ * length.
+ */
+void acpigen_write_opregion(struct opregion *opreg);
+/*
+ * Generate ACPI AML code for Mutex
+ * This function takes mutex name and initial value.
+ */
+void acpigen_write_mutex(const char *name, const uint8_t flags);
+/*
+ * Generate ACPI AML code for Acquire
+ * This function takes mutex name and privilege value.
+ */
+void acpigen_write_acquire(const char *name, const uint16_t val);
+/*
+ * Generate ACPI AML code for Release
+ * This function takes mutex name.
+ */
+void acpigen_write_release(const char *name);
+/*
+ * Generate ACPI AML code for Field
+ * This function takes input region name, fieldlist, count & flags.
+ */
+void acpigen_write_field(const char *name, const struct fieldlist *l, size_t count,
+ uint8_t flags);
+/*
+ * Generate ACPI AML code for IndexField
+ * This function takes input index name, data name, fieldlist, count & flags.
+ */
+void acpigen_write_indexfield(const char *idx, const char *data,
+ struct fieldlist *l, size_t count, uint8_t flags);
+
+int get_cst_entries(acpi_cstate_t **);
+
+/*
+ * Soc-implemented functions for generating ACPI AML code for GPIO handling. All
+ * these functions are expected to use only Local5, Local6 and Local7
+ * variables. If the functions call into another ACPI method, then there is no
+ * restriction on the use of Local variables. In case of get/read functions,
+ * return value is expected to be stored in Local0 variable.
+ *
+ * All functions return 0 on success and -1 on error.
+ */
+
+/* Generate ACPI AML code to return Rx value of GPIO in Local0. */
+int acpigen_soc_read_rx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to return Tx value of GPIO in Local0. */
+int acpigen_soc_get_tx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to set Tx value of GPIO to 1. */
+int acpigen_soc_set_tx_gpio(unsigned int gpio_num);
+
+/* Generate ACPI AML code to set Tx value of GPIO to 0. */
+int acpigen_soc_clear_tx_gpio(unsigned int gpio_num);
+
+/*
+ * Helper functions for enabling/disabling Tx GPIOs based on the GPIO
+ * polarity. These functions end up calling acpigen_soc_{set,clear}_tx_gpio to
+ * make callbacks into SoC acpigen code.
+ *
+ * Returns 0 on success and -1 on error.
+ */
+int acpigen_enable_tx_gpio(struct acpi_gpio *gpio);
+int acpigen_disable_tx_gpio(struct acpi_gpio *gpio);
+
+/*
+ * Helper function for getting a RX GPIO value based on the GPIO polarity.
+ * The return value is stored in Local0 variable.
+ * This function ends up calling acpigen_soc_get_rx_gpio to make callbacks
+ * into SoC acpigen code
+ */
+void acpigen_get_rx_gpio(struct acpi_gpio *gpio);
+
+/* refer to ACPI 6.4.3.5.3 Word Address Space Descriptor section for details */
+void acpigen_resource_word(u16 res_type, u16 gen_flags, u16 type_flags, u16 gran,
+ u16 range_min, u16 range_max, u16 translation, u16 length);
+/* refer to ACPI 6.4.3.5.2 DWord Address Space Descriptor section for details */
+void acpigen_resource_dword(u16 res_type, u16 gen_flags, u16 type_flags,
+ u32 gran, u32 range_min, u32 range_max, u32 translation, u32 length);
+/* refer to ACPI 6.4.3.5.1 QWord Address Space Descriptor section for details */
+void acpigen_resource_qword(u16 res_type, u16 gen_flags, u16 type_flags,
+ u64 gran, u64 range_min, u64 range_max, u64 translation, u64 length);
+
+#endif