1*ebb62075SSamuel Ortiz /* 2*ebb62075SSamuel Ortiz * 3*ebb62075SSamuel Ortiz * Copyright (c) 2018 Intel Corporation 4*ebb62075SSamuel Ortiz * Copyright (c) 2019 Huawei Technologies R & D (UK) Ltd 5*ebb62075SSamuel Ortiz * Written by Samuel Ortiz, Shameer Kolothum 6*ebb62075SSamuel Ortiz * 7*ebb62075SSamuel Ortiz * This program is free software; you can redistribute it and/or modify it 8*ebb62075SSamuel Ortiz * under the terms and conditions of the GNU General Public License, 9*ebb62075SSamuel Ortiz * version 2 or later, as published by the Free Software Foundation. 10*ebb62075SSamuel Ortiz * 11*ebb62075SSamuel Ortiz * The ACPI Generic Event Device (GED) is a hardware-reduced specific 12*ebb62075SSamuel Ortiz * device[ACPI v6.1 Section 5.6.9] that handles all platform events, 13*ebb62075SSamuel Ortiz * including the hotplug ones. Generic Event Device allows platforms 14*ebb62075SSamuel Ortiz * to handle interrupts in ACPI ASL statements. It follows a very 15*ebb62075SSamuel Ortiz * similar approach like the _EVT method from GPIO events. All 16*ebb62075SSamuel Ortiz * interrupts are listed in _CRS and the handler is written in _EVT 17*ebb62075SSamuel Ortiz * method. Here, we use a single interrupt for the GED device, relying 18*ebb62075SSamuel Ortiz * on IO memory region to communicate the type of device affected by 19*ebb62075SSamuel Ortiz * the interrupt. This way, we can support up to 32 events with a 20*ebb62075SSamuel Ortiz * unique interrupt. 21*ebb62075SSamuel Ortiz * 22*ebb62075SSamuel Ortiz * Here is an example. 23*ebb62075SSamuel Ortiz * 24*ebb62075SSamuel Ortiz * Device (\_SB.GED) 25*ebb62075SSamuel Ortiz * { 26*ebb62075SSamuel Ortiz * Name (_HID, "ACPI0013") 27*ebb62075SSamuel Ortiz * Name (_UID, Zero) 28*ebb62075SSamuel Ortiz * Name (_CRS, ResourceTemplate () 29*ebb62075SSamuel Ortiz * { 30*ebb62075SSamuel Ortiz * Interrupt (ResourceConsumer, Edge, ActiveHigh, Exclusive, ,, ) 31*ebb62075SSamuel Ortiz * { 32*ebb62075SSamuel Ortiz * 0x00000029, 33*ebb62075SSamuel Ortiz * } 34*ebb62075SSamuel Ortiz * }) 35*ebb62075SSamuel Ortiz * OperationRegion (EREG, SystemMemory, 0x09080000, 0x04) 36*ebb62075SSamuel Ortiz * Field (EREG, DWordAcc, NoLock, WriteAsZeros) 37*ebb62075SSamuel Ortiz * { 38*ebb62075SSamuel Ortiz * ESEL, 32 39*ebb62075SSamuel Ortiz * } 40*ebb62075SSamuel Ortiz * 41*ebb62075SSamuel Ortiz * Method (_EVT, 1, Serialized) // _EVT: Event 42*ebb62075SSamuel Ortiz * { 43*ebb62075SSamuel Ortiz * Local0 = ESEL // ESEL = IO memory region which specifies the 44*ebb62075SSamuel Ortiz * // device type. 45*ebb62075SSamuel Ortiz * If (((Local0 & One) == One)) 46*ebb62075SSamuel Ortiz * { 47*ebb62075SSamuel Ortiz * MethodEvent1() 48*ebb62075SSamuel Ortiz * } 49*ebb62075SSamuel Ortiz * If ((Local0 & 0x2) == 0x2) 50*ebb62075SSamuel Ortiz * { 51*ebb62075SSamuel Ortiz * MethodEvent2() 52*ebb62075SSamuel Ortiz * } 53*ebb62075SSamuel Ortiz * ... 54*ebb62075SSamuel Ortiz * } 55*ebb62075SSamuel Ortiz * } 56*ebb62075SSamuel Ortiz * 57*ebb62075SSamuel Ortiz */ 58*ebb62075SSamuel Ortiz 59*ebb62075SSamuel Ortiz #ifndef HW_ACPI_GED_H 60*ebb62075SSamuel Ortiz #define HW_ACPI_GED_H 61*ebb62075SSamuel Ortiz 62*ebb62075SSamuel Ortiz #include "hw/sysbus.h" 63*ebb62075SSamuel Ortiz #include "hw/acpi/memory_hotplug.h" 64*ebb62075SSamuel Ortiz 65*ebb62075SSamuel Ortiz #define TYPE_ACPI_GED "acpi-ged" 66*ebb62075SSamuel Ortiz #define ACPI_GED(obj) \ 67*ebb62075SSamuel Ortiz OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED) 68*ebb62075SSamuel Ortiz 69*ebb62075SSamuel Ortiz #define ACPI_GED_EVT_SEL_OFFSET 0x0 70*ebb62075SSamuel Ortiz #define ACPI_GED_EVT_SEL_LEN 0x4 71*ebb62075SSamuel Ortiz 72*ebb62075SSamuel Ortiz #define GED_DEVICE "GED" 73*ebb62075SSamuel Ortiz #define AML_GED_EVT_REG "EREG" 74*ebb62075SSamuel Ortiz #define AML_GED_EVT_SEL "ESEL" 75*ebb62075SSamuel Ortiz 76*ebb62075SSamuel Ortiz /* 77*ebb62075SSamuel Ortiz * Platforms need to specify the GED event bitmap 78*ebb62075SSamuel Ortiz * to describe what kind of events they want to support 79*ebb62075SSamuel Ortiz * through GED. 80*ebb62075SSamuel Ortiz */ 81*ebb62075SSamuel Ortiz #define ACPI_GED_MEM_HOTPLUG_EVT 0x1 82*ebb62075SSamuel Ortiz 83*ebb62075SSamuel Ortiz typedef struct GEDState { 84*ebb62075SSamuel Ortiz MemoryRegion io; 85*ebb62075SSamuel Ortiz uint32_t sel; 86*ebb62075SSamuel Ortiz } GEDState; 87*ebb62075SSamuel Ortiz 88*ebb62075SSamuel Ortiz typedef struct AcpiGedState { 89*ebb62075SSamuel Ortiz SysBusDevice parent_obj; 90*ebb62075SSamuel Ortiz MemHotplugState memhp_state; 91*ebb62075SSamuel Ortiz MemoryRegion container_memhp; 92*ebb62075SSamuel Ortiz GEDState ged_state; 93*ebb62075SSamuel Ortiz uint32_t ged_event_bitmap; 94*ebb62075SSamuel Ortiz qemu_irq irq; 95*ebb62075SSamuel Ortiz } AcpiGedState; 96*ebb62075SSamuel Ortiz 97*ebb62075SSamuel Ortiz void build_ged_aml(Aml *table, const char* name, HotplugHandler *hotplug_dev, 98*ebb62075SSamuel Ortiz uint32_t ged_irq, AmlRegionSpace rs, hwaddr ged_base); 99*ebb62075SSamuel Ortiz 100*ebb62075SSamuel Ortiz #endif 101