1 /* 2 * 3 * Copyright (c) 2018 Intel Corporation 4 * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd 5 * Written by Samuel Ortiz, Shameer Kolothum 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms and conditions of the GNU General Public License, 9 * version 2 or later, as published by the Free Software Foundation. 10 * 11 * The ACPI Generic Event Device (GED) is a hardware-reduced specific 12 * device[ACPI v6.1 Section 5.6.9] that handles all platform events, 13 * including the hotplug ones. Generic Event Device allows platforms 14 * to handle interrupts in ACPI ASL statements. It follows a very 15 * similar approach like the _EVT method from GPIO events. All 16 * interrupts are listed in _CRS and the handler is written in _EVT 17 * method. Here, we use a single interrupt for the GED device, relying 18 * on IO memory region to communicate the type of device affected by 19 * the interrupt. This way, we can support up to 32 events with a 20 * unique interrupt. 21 * 22 * Here is an example. 23 * 24 * Device (\_SB.GED) 25 * { 26 * Name (_HID, "ACPI0013") 27 * Name (_UID, Zero) 28 * Name (_CRS, ResourceTemplate () 29 * { 30 * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, ) 31 * { 32 * 0x00000029, 33 * } 34 * }) 35 * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04) 36 * Field (EREG, DWordAcc, NoLock, WriteAsZeros) 37 * { 38 * ESEL, 32 39 * } 40 * 41 * Method (_EVT, 1, Serialized) // _EVT: Event 42 * { 43 * Local0 = ESEL // ESEL = IO memory region which specifies the 44 * // device type. 45 * If (((Local0 & One) == One)) 46 * { 47 * MethodEvent1() 48 * } 49 * If ((Local0 & 0x2) == 0x2) 50 * { 51 * MethodEvent2() 52 * } 53 * ... 54 * } 55 * } 56 * 57 */ 58 59 #ifndef HW_ACPI_GENERIC_EVENT_DEVICE_H 60 #define HW_ACPI_GENERIC_EVENT_DEVICE_H 61 62 #include "hw/sysbus.h" 63 #include "hw/acpi/memory_hotplug.h" 64 #include "hw/acpi/ghes.h" 65 #include "hw/acpi/cpu.h" 66 #include "qom/object.h" 67 68 #define ACPI_POWER_BUTTON_DEVICE "PWRB" 69 70 #define TYPE_ACPI_GED "acpi-ged" 71 OBJECT_DECLARE_SIMPLE_TYPE(AcpiGedState, ACPI_GED) 72 73 #define ACPI_GED_EVT_SEL_OFFSET 0x0 74 #define ACPI_GED_EVT_SEL_LEN 0x4 75 76 #define ACPI_GED_REG_SLEEP_CTL 0x00 77 #define ACPI_GED_REG_SLEEP_STS 0x01 78 #define ACPI_GED_REG_RESET 0x02 79 #define ACPI_GED_REG_COUNT 0x03 80 81 /* ACPI_GED_REG_RESET value for reset*/ 82 #define ACPI_GED_RESET_VALUE 0x42 83 84 /* [ACPI 5.0 Chapter 4.8.3.7] Sleep Control and Status Register */ 85 #define ACPI_GED_SLP_TYP_POS 0x2 /* SLP_TYPx Bit Offset */ 86 #define ACPI_GED_SLP_TYP_MASK 0x07 /* SLP_TYPx 3-bit mask */ 87 #define ACPI_GED_SLP_TYP_S5 0x05 /* System _S5 State (Soft Off) */ 88 #define ACPI_GED_SLP_EN 0x20 /* SLP_EN write-only bit */ 89 90 #define GED_DEVICE "GED" 91 #define AML_GED_EVT_REG "EREG" 92 #define AML_GED_EVT_SEL "ESEL" 93 #define AML_GED_EVT_CPU_SCAN_METHOD "\\_SB.GED.CSCN" 94 95 /* 96 * Platforms need to specify the GED event bitmap 97 * to describe what kind of events they want to support 98 * through GED. 99 */ 100 #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 101 #define ACPI_GED_PWR_DOWN_EVT 0x2 102 #define ACPI_GED_NVDIMM_HOTPLUG_EVT 0x4 103 #define ACPI_GED_CPU_HOTPLUG_EVT 0x8 104 105 typedef struct GEDState { 106 MemoryRegion evt; 107 MemoryRegion regs; 108 uint32_t sel; 109 } GEDState; 110 111 struct AcpiGedState { 112 SysBusDevice parent_obj; 113 MemHotplugState memhp_state; 114 MemoryRegion container_memhp; 115 CPUHotplugState cpuhp_state; 116 MemoryRegion container_cpuhp; 117 GEDState ged_state; 118 uint32_t ged_event_bitmap; 119 qemu_irq irq; 120 AcpiGhesState ghes_state; 121 }; 122 123 void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev, 124 uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base); 125 void acpi_dsdt_add_power_button(Aml *scope); 126 127 #endif 128