Home | History | Annotate | Download | only in asm
      1 /* SPDX-License-Identifier: GPL-2.0+ */
      2 /*
      3  * Based on acpi.c from coreboot
      4  *
      5  * Copyright (C) 2015, Saket Sinha <saket.sinha89 (at) gmail.com>
      6  * Copyright (C) 2016, Bin Meng <bmeng.cn (at) gmail.com>
      7  */
      8 
      9 #define RSDP_SIG		"RSD PTR "	/* RSDP pointer signature */
     10 #define OEM_ID			"U-BOOT"	/* U-Boot */
     11 #define OEM_TABLE_ID		"U-BOOTBL"	/* U-Boot Table */
     12 #define ASLC_ID			"INTL"		/* Intel ASL Compiler */
     13 
     14 #define ACPI_RSDP_REV_ACPI_1_0	0
     15 #define ACPI_RSDP_REV_ACPI_2_0	2
     16 
     17 /*
     18  * RSDP (Root System Description Pointer)
     19  * Note: ACPI 1.0 didn't have length, xsdt_address, and ext_checksum
     20  */
     21 struct acpi_rsdp {
     22 	char signature[8];	/* RSDP signature */
     23 	u8 checksum;		/* Checksum of the first 20 bytes */
     24 	char oem_id[6];		/* OEM ID */
     25 	u8 revision;		/* 0 for ACPI 1.0, others 2 */
     26 	u32 rsdt_address;	/* Physical address of RSDT (32 bits) */
     27 	u32 length;		/* Total RSDP length (incl. extended part) */
     28 	u64 xsdt_address;	/* Physical address of XSDT (64 bits) */
     29 	u8 ext_checksum;	/* Checksum of the whole table */
     30 	u8 reserved[3];
     31 };
     32 
     33 /* Generic ACPI header, provided by (almost) all tables */
     34 struct acpi_table_header {
     35 	char signature[4];	/* ACPI signature (4 ASCII characters) */
     36 	u32 length;		/* Table length in bytes (incl. header) */
     37 	u8 revision;		/* Table version (not ACPI version!) */
     38 	volatile u8 checksum;	/* To make sum of entire table == 0 */
     39 	char oem_id[6];		/* OEM identification */
     40 	char oem_table_id[8];	/* OEM table identification */
     41 	u32 oem_revision;	/* OEM revision number */
     42 	char aslc_id[4];	/* ASL compiler vendor ID */
     43 	u32 aslc_revision;	/* ASL compiler revision number */
     44 };
     45 
     46 /* A maximum number of 32 ACPI tables ought to be enough for now */
     47 #define MAX_ACPI_TABLES		32
     48 
     49 /* RSDT (Root System Description Table) */
     50 struct acpi_rsdt {
     51 	struct acpi_table_header header;
     52 	u32 entry[MAX_ACPI_TABLES];
     53 };
     54 
     55 /* XSDT (Extended System Description Table) */
     56 struct acpi_xsdt {
     57 	struct acpi_table_header header;
     58 	u64 entry[MAX_ACPI_TABLES];
     59 };
     60 
     61 /* FADT Preferred Power Management Profile */
     62 enum acpi_pm_profile {
     63 	ACPI_PM_UNSPECIFIED = 0,
     64 	ACPI_PM_DESKTOP,
     65 	ACPI_PM_MOBILE,
     66 	ACPI_PM_WORKSTATION,
     67 	ACPI_PM_ENTERPRISE_SERVER,
     68 	ACPI_PM_SOHO_SERVER,
     69 	ACPI_PM_APPLIANCE_PC,
     70 	ACPI_PM_PERFORMANCE_SERVER,
     71 	ACPI_PM_TABLET
     72 };
     73 
     74 /* FADT flags for p_lvl2_lat and p_lvl3_lat */
     75 #define ACPI_FADT_C2_NOT_SUPPORTED	101
     76 #define ACPI_FADT_C3_NOT_SUPPORTED	1001
     77 
     78 /* FADT Boot Architecture Flags */
     79 #define ACPI_FADT_LEGACY_FREE		0x00
     80 #define ACPI_FADT_LEGACY_DEVICES	(1 << 0)
     81 #define ACPI_FADT_8042			(1 << 1)
     82 #define ACPI_FADT_VGA_NOT_PRESENT	(1 << 2)
     83 #define ACPI_FADT_MSI_NOT_SUPPORTED	(1 << 3)
     84 #define ACPI_FADT_NO_PCIE_ASPM_CONTROL	(1 << 4)
     85 
     86 /* FADT Feature Flags */
     87 #define ACPI_FADT_WBINVD		(1 << 0)
     88 #define ACPI_FADT_WBINVD_FLUSH		(1 << 1)
     89 #define ACPI_FADT_C1_SUPPORTED		(1 << 2)
     90 #define ACPI_FADT_C2_MP_SUPPORTED	(1 << 3)
     91 #define ACPI_FADT_POWER_BUTTON		(1 << 4)
     92 #define ACPI_FADT_SLEEP_BUTTON		(1 << 5)
     93 #define ACPI_FADT_FIXED_RTC		(1 << 6)
     94 #define ACPI_FADT_S4_RTC_WAKE		(1 << 7)
     95 #define ACPI_FADT_32BIT_TIMER		(1 << 8)
     96 #define ACPI_FADT_DOCKING_SUPPORTED	(1 << 9)
     97 #define ACPI_FADT_RESET_REGISTER	(1 << 10)
     98 #define ACPI_FADT_SEALED_CASE		(1 << 11)
     99 #define ACPI_FADT_HEADLESS		(1 << 12)
    100 #define ACPI_FADT_SLEEP_TYPE		(1 << 13)
    101 #define ACPI_FADT_PCI_EXPRESS_WAKE	(1 << 14)
    102 #define ACPI_FADT_PLATFORM_CLOCK	(1 << 15)
    103 #define ACPI_FADT_S4_RTC_VALID		(1 << 16)
    104 #define ACPI_FADT_REMOTE_POWER_ON	(1 << 17)
    105 #define ACPI_FADT_APIC_CLUSTER		(1 << 18)
    106 #define ACPI_FADT_APIC_PHYSICAL		(1 << 19)
    107 #define ACPI_FADT_HW_REDUCED_ACPI	(1 << 20)
    108 #define ACPI_FADT_LOW_PWR_IDLE_S0	(1 << 21)
    109 
    110 enum acpi_address_space_type {
    111 	ACPI_ADDRESS_SPACE_MEMORY = 0,	/* System memory */
    112 	ACPI_ADDRESS_SPACE_IO,		/* System I/O */
    113 	ACPI_ADDRESS_SPACE_PCI,		/* PCI config space */
    114 	ACPI_ADDRESS_SPACE_EC,		/* Embedded controller */
    115 	ACPI_ADDRESS_SPACE_SMBUS,	/* SMBus */
    116 	ACPI_ADDRESS_SPACE_PCC = 0x0a,	/* Platform Comm. Channel */
    117 	ACPI_ADDRESS_SPACE_FIXED = 0x7f	/* Functional fixed hardware */
    118 };
    119 
    120 enum acpi_address_space_size {
    121 	ACPI_ACCESS_SIZE_UNDEFINED = 0,
    122 	ACPI_ACCESS_SIZE_BYTE_ACCESS,
    123 	ACPI_ACCESS_SIZE_WORD_ACCESS,
    124 	ACPI_ACCESS_SIZE_DWORD_ACCESS,
    125 	ACPI_ACCESS_SIZE_QWORD_ACCESS
    126 };
    127 
    128 struct acpi_gen_regaddr {
    129 	u8 space_id;	/* Address space ID */
    130 	u8 bit_width;	/* Register size in bits */
    131 	u8 bit_offset;	/* Register bit offset */
    132 	u8 access_size;	/* Access size */
    133 	u32 addrl;	/* Register address, low 32 bits */
    134 	u32 addrh;	/* Register address, high 32 bits */
    135 };
    136 
    137 /* FADT (Fixed ACPI Description Table) */
    138 struct __packed acpi_fadt {
    139 	struct acpi_table_header header;
    140 	u32 firmware_ctrl;
    141 	u32 dsdt;
    142 	u8 res1;
    143 	u8 preferred_pm_profile;
    144 	u16 sci_int;
    145 	u32 smi_cmd;
    146 	u8 acpi_enable;
    147 	u8 acpi_disable;
    148 	u8 s4bios_req;
    149 	u8 pstate_cnt;
    150 	u32 pm1a_evt_blk;
    151 	u32 pm1b_evt_blk;
    152 	u32 pm1a_cnt_blk;
    153 	u32 pm1b_cnt_blk;
    154 	u32 pm2_cnt_blk;
    155 	u32 pm_tmr_blk;
    156 	u32 gpe0_blk;
    157 	u32 gpe1_blk;
    158 	u8 pm1_evt_len;
    159 	u8 pm1_cnt_len;
    160 	u8 pm2_cnt_len;
    161 	u8 pm_tmr_len;
    162 	u8 gpe0_blk_len;
    163 	u8 gpe1_blk_len;
    164 	u8 gpe1_base;
    165 	u8 cst_cnt;
    166 	u16 p_lvl2_lat;
    167 	u16 p_lvl3_lat;
    168 	u16 flush_size;
    169 	u16 flush_stride;
    170 	u8 duty_offset;
    171 	u8 duty_width;
    172 	u8 day_alrm;
    173 	u8 mon_alrm;
    174 	u8 century;
    175 	u16 iapc_boot_arch;
    176 	u8 res2;
    177 	u32 flags;
    178 	struct acpi_gen_regaddr reset_reg;
    179 	u8 reset_value;
    180 	u16 arm_boot_arch;
    181 	u8 minor_revision;
    182 	u32 x_firmware_ctl_l;
    183 	u32 x_firmware_ctl_h;
    184 	u32 x_dsdt_l;
    185 	u32 x_dsdt_h;
    186 	struct acpi_gen_regaddr x_pm1a_evt_blk;
    187 	struct acpi_gen_regaddr x_pm1b_evt_blk;
    188 	struct acpi_gen_regaddr x_pm1a_cnt_blk;
    189 	struct acpi_gen_regaddr x_pm1b_cnt_blk;
    190 	struct acpi_gen_regaddr x_pm2_cnt_blk;
    191 	struct acpi_gen_regaddr x_pm_tmr_blk;
    192 	struct acpi_gen_regaddr x_gpe0_blk;
    193 	struct acpi_gen_regaddr x_gpe1_blk;
    194 };
    195 
    196 /* FACS flags */
    197 #define ACPI_FACS_S4BIOS_F	(1 << 0)
    198 #define ACPI_FACS_64BIT_WAKE_F	(1 << 1)
    199 
    200 /* FACS (Firmware ACPI Control Structure) */
    201 struct acpi_facs {
    202 	char signature[4];		/* "FACS" */
    203 	u32 length;			/* Length in bytes (>= 64) */
    204 	u32 hardware_signature;		/* Hardware signature */
    205 	u32 firmware_waking_vector;	/* Firmware waking vector */
    206 	u32 global_lock;		/* Global lock */
    207 	u32 flags;			/* FACS flags */
    208 	u32 x_firmware_waking_vector_l;	/* X FW waking vector, low */
    209 	u32 x_firmware_waking_vector_h;	/* X FW waking vector, high */
    210 	u8 version;			/* Version 2 */
    211 	u8 res1[3];
    212 	u32 ospm_flags;			/* OSPM enabled flags */
    213 	u8 res2[24];
    214 };
    215 
    216 /* MADT flags */
    217 #define ACPI_MADT_PCAT_COMPAT	(1 << 0)
    218 
    219 /* MADT (Multiple APIC Description Table) */
    220 struct acpi_madt {
    221 	struct acpi_table_header header;
    222 	u32 lapic_addr;			/* Local APIC address */
    223 	u32 flags;			/* Multiple APIC flags */
    224 };
    225 
    226 /* MADT: APIC Structure Type*/
    227 enum acpi_apic_types {
    228 	ACPI_APIC_LAPIC	= 0,		/* Processor local APIC */
    229 	ACPI_APIC_IOAPIC,		/* I/O APIC */
    230 	ACPI_APIC_IRQ_SRC_OVERRIDE,	/* Interrupt source override */
    231 	ACPI_APIC_NMI_SRC,		/* NMI source */
    232 	ACPI_APIC_LAPIC_NMI,		/* Local APIC NMI */
    233 	ACPI_APIC_LAPIC_ADDR_OVERRIDE,	/* Local APIC address override */
    234 	ACPI_APIC_IOSAPIC,		/* I/O SAPIC */
    235 	ACPI_APIC_LSAPIC,		/* Local SAPIC */
    236 	ACPI_APIC_PLATFORM_IRQ_SRC,	/* Platform interrupt sources */
    237 	ACPI_APIC_LX2APIC,		/* Processor local x2APIC */
    238 	ACPI_APIC_LX2APIC_NMI,		/* Local x2APIC NMI */
    239 };
    240 
    241 /* MADT: Processor Local APIC Structure */
    242 
    243 #define LOCAL_APIC_FLAG_ENABLED	(1 << 0)
    244 
    245 struct acpi_madt_lapic {
    246 	u8 type;		/* Type (0) */
    247 	u8 length;		/* Length in bytes (8) */
    248 	u8 processor_id;	/* ACPI processor ID */
    249 	u8 apic_id;		/* Local APIC ID */
    250 	u32 flags;		/* Local APIC flags */
    251 };
    252 
    253 /* MADT: I/O APIC Structure */
    254 struct acpi_madt_ioapic {
    255 	u8 type;		/* Type (1) */
    256 	u8 length;		/* Length in bytes (12) */
    257 	u8 ioapic_id;		/* I/O APIC ID */
    258 	u8 reserved;
    259 	u32 ioapic_addr;	/* I/O APIC address */
    260 	u32 gsi_base;		/* Global system interrupt base */
    261 };
    262 
    263 /* MADT: Interrupt Source Override Structure */
    264 struct __packed acpi_madt_irqoverride {
    265 	u8 type;		/* Type (2) */
    266 	u8 length;		/* Length in bytes (10) */
    267 	u8 bus;			/* ISA (0) */
    268 	u8 source;		/* Bus-relative int. source (IRQ) */
    269 	u32 gsirq;		/* Global system interrupt */
    270 	u16 flags;		/* MPS INTI flags */
    271 };
    272 
    273 /* MADT: Local APIC NMI Structure */
    274 struct __packed acpi_madt_lapic_nmi {
    275 	u8 type;		/* Type (4) */
    276 	u8 length;		/* Length in bytes (6) */
    277 	u8 processor_id;	/* ACPI processor ID */
    278 	u16 flags;		/* MPS INTI flags */
    279 	u8 lint;		/* Local APIC LINT# */
    280 };
    281 
    282 /* MCFG (PCI Express MMIO config space BAR description table) */
    283 struct acpi_mcfg {
    284 	struct acpi_table_header header;
    285 	u8 reserved[8];
    286 };
    287 
    288 struct acpi_mcfg_mmconfig {
    289 	u32 base_address_l;
    290 	u32 base_address_h;
    291 	u16 pci_segment_group_number;
    292 	u8 start_bus_number;
    293 	u8 end_bus_number;
    294 	u8 reserved[4];
    295 };
    296 
    297 /* PM1_CNT bit defines */
    298 #define PM1_CNT_SCI_EN		(1 << 0)
    299 
    300 /* ACPI global NVS structure */
    301 struct acpi_global_nvs;
    302 
    303 /* These can be used by the target port */
    304 
    305 void acpi_fill_header(struct acpi_table_header *header, char *signature);
    306 void acpi_create_fadt(struct acpi_fadt *fadt, struct acpi_facs *facs,
    307 		      void *dsdt);
    308 int acpi_create_madt_lapics(u32 current);
    309 int acpi_create_madt_ioapic(struct acpi_madt_ioapic *ioapic, u8 id,
    310 			    u32 addr, u32 gsi_base);
    311 int acpi_create_madt_irqoverride(struct acpi_madt_irqoverride *irqoverride,
    312 				 u8 bus, u8 source, u32 gsirq, u16 flags);
    313 int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi,
    314 			       u8 cpu, u16 flags, u8 lint);
    315 u32 acpi_fill_madt(u32 current);
    316 int acpi_create_mcfg_mmconfig(struct acpi_mcfg_mmconfig *mmconfig, u32 base,
    317 			      u16 seg_nr, u8 start, u8 end);
    318 u32 acpi_fill_mcfg(u32 current);
    319 void acpi_create_gnvs(struct acpi_global_nvs *gnvs);
    320 /**
    321  * enter_acpi_mode() - enter into ACPI mode
    322  *
    323  * This programs the ACPI-defined PM1_CNT register to enable SCI interrupt
    324  * so that the whole system swiches to ACPI mode.
    325  *
    326  * @pm1_cnt:	PM1_CNT register I/O address
    327  */
    328 void enter_acpi_mode(int pm1_cnt);
    329 ulong write_acpi_tables(ulong start);
    330 
    331 /**
    332  * acpi_get_rsdp_addr() - get ACPI RSDP table address
    333  *
    334  * This routine returns the ACPI RSDP table address in the system memory.
    335  *
    336  * @return:	ACPI RSDP table address
    337  */
    338 ulong acpi_get_rsdp_addr(void);
    339 
    340 /**
    341  * acpi_find_fadt() - find ACPI FADT table in the sytem memory
    342  *
    343  * This routine parses the ACPI table to locate the ACPI FADT table.
    344  *
    345  * @return:	a pointer to the ACPI FADT table in the system memory
    346  */
    347 struct acpi_fadt *acpi_find_fadt(void);
    348 
    349 /**
    350  * acpi_find_wakeup_vector() - find OS installed wake up vector address
    351  *
    352  * This routine parses the ACPI table to locate the wake up vector installed
    353  * by the OS previously.
    354  *
    355  * @return:	wake up vector address installed by the OS
    356  */
    357 void *acpi_find_wakeup_vector(struct acpi_fadt *);
    358