1*1285115cSWilliam A. Kennington III // Copyright 2021 Google LLC 2*1285115cSWilliam A. Kennington III // 3*1285115cSWilliam A. Kennington III // Licensed under the Apache License, Version 2.0 (the "License"); 4*1285115cSWilliam A. Kennington III // you may not use this file except in compliance with the License. 5*1285115cSWilliam A. Kennington III // You may obtain a copy of the License at 6*1285115cSWilliam A. Kennington III // 7*1285115cSWilliam A. Kennington III // http://www.apache.org/licenses/LICENSE-2.0 8*1285115cSWilliam A. Kennington III // 9*1285115cSWilliam A. Kennington III // Unless required by applicable law or agreed to in writing, software 10*1285115cSWilliam A. Kennington III // distributed under the License is distributed on an "AS IS" BASIS, 11*1285115cSWilliam A. Kennington III // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*1285115cSWilliam A. Kennington III // See the License for the specific language governing permissions and 13*1285115cSWilliam A. Kennington III // limitations under the License. 14*1285115cSWilliam A. Kennington III 15*1285115cSWilliam A. Kennington III /* 16*1285115cSWilliam A. Kennington III * Based off of sdbusplus:/example/calculator-server.cpp 17*1285115cSWilliam A. Kennington III */ 18*1285115cSWilliam A. Kennington III #include <sdbusplus/bus.hpp> 19*1285115cSWilliam A. Kennington III #include <sdbusplus/server.hpp> 20*1285115cSWilliam A. Kennington III #include <xyz/openbmc_project/Control/Power/ACPIPowerState/server.hpp> 21*1285115cSWilliam A. Kennington III 22*1285115cSWilliam A. Kennington III #include <exception> 23*1285115cSWilliam A. Kennington III #include <iostream> 24*1285115cSWilliam A. Kennington III #include <optional> 25*1285115cSWilliam A. Kennington III #include <string> 26*1285115cSWilliam A. Kennington III 27*1285115cSWilliam A. Kennington III constexpr auto hostS5Unit = "host-s5-state.target"; 28*1285115cSWilliam A. Kennington III constexpr auto hostS0Unit = "host-s0-state.target"; 29*1285115cSWilliam A. Kennington III 30*1285115cSWilliam A. Kennington III constexpr auto systemdBusName = "org.freedesktop.systemd1"; 31*1285115cSWilliam A. Kennington III constexpr auto systemdPath = "/org/freedesktop/systemd1"; 32*1285115cSWilliam A. Kennington III constexpr auto systemdInterface = "org.freedesktop.systemd1.Manager"; 33*1285115cSWilliam A. Kennington III 34*1285115cSWilliam A. Kennington III constexpr auto acpiObjPath = 35*1285115cSWilliam A. Kennington III "/xyz/openbmc_project/control/host0/acpi_power_state"; 36*1285115cSWilliam A. Kennington III constexpr auto acpiInterface = 37*1285115cSWilliam A. Kennington III "xyz.openbmc_project.Control.Power.ACPIPowerState"; 38*1285115cSWilliam A. Kennington III 39*1285115cSWilliam A. Kennington III using ACPIPowerStateInherit = sdbusplus::server::object_t< 40*1285115cSWilliam A. Kennington III sdbusplus::xyz::openbmc_project::Control::Power::server::ACPIPowerState>; 41*1285115cSWilliam A. Kennington III 42*1285115cSWilliam A. Kennington III // Pulled and modified from arcadia-leds/poll_gpio.cpp 43*1285115cSWilliam A. Kennington III static void startSystemdUnit(sdbusplus::bus::bus& bus, const std::string& unit) 44*1285115cSWilliam A. Kennington III { 45*1285115cSWilliam A. Kennington III auto method = bus.new_method_call(systemdBusName, systemdPath, 46*1285115cSWilliam A. Kennington III systemdInterface, "StartUnit"); 47*1285115cSWilliam A. Kennington III method.append(unit, "replace"); 48*1285115cSWilliam A. Kennington III bus.call(method); 49*1285115cSWilliam A. Kennington III } 50*1285115cSWilliam A. Kennington III 51*1285115cSWilliam A. Kennington III struct ACPIPowerState : ACPIPowerStateInherit 52*1285115cSWilliam A. Kennington III { 53*1285115cSWilliam A. Kennington III // Keep track of the bus for starting/stopping systemd units 54*1285115cSWilliam A. Kennington III sdbusplus::bus::bus& Bus; 55*1285115cSWilliam A. Kennington III 56*1285115cSWilliam A. Kennington III ACPIPowerState(sdbusplus::bus::bus& bus, const char* path) : 57*1285115cSWilliam A. Kennington III ACPIPowerStateInherit(bus, path), Bus(bus) 58*1285115cSWilliam A. Kennington III {} 59*1285115cSWilliam A. Kennington III 60*1285115cSWilliam A. Kennington III ACPI sysACPIStatus(ACPI value) 61*1285115cSWilliam A. Kennington III { 62*1285115cSWilliam A. Kennington III std::cout << "State change " 63*1285115cSWilliam A. Kennington III << ACPIPowerStateInherit::convertACPIToString(value) 64*1285115cSWilliam A. Kennington III << std::endl; 65*1285115cSWilliam A. Kennington III 66*1285115cSWilliam A. Kennington III switch (value) 67*1285115cSWilliam A. Kennington III { 68*1285115cSWilliam A. Kennington III case ACPI::S5_G2: 69*1285115cSWilliam A. Kennington III std::cout << "Entered S5" << std::endl; 70*1285115cSWilliam A. Kennington III startSystemdUnit(Bus, hostS5Unit); 71*1285115cSWilliam A. Kennington III break; 72*1285115cSWilliam A. Kennington III case ACPI::S0_G0_D0: 73*1285115cSWilliam A. Kennington III std::cout << "Entered S0" << std::endl; 74*1285115cSWilliam A. Kennington III startSystemdUnit(Bus, hostS0Unit); 75*1285115cSWilliam A. Kennington III break; 76*1285115cSWilliam A. Kennington III default: 77*1285115cSWilliam A. Kennington III break; 78*1285115cSWilliam A. Kennington III } 79*1285115cSWilliam A. Kennington III 80*1285115cSWilliam A. Kennington III return ACPIPowerStateInherit::sysACPIStatus(value); 81*1285115cSWilliam A. Kennington III } 82*1285115cSWilliam A. Kennington III }; 83*1285115cSWilliam A. Kennington III 84*1285115cSWilliam A. Kennington III int main() 85*1285115cSWilliam A. Kennington III { 86*1285115cSWilliam A. Kennington III 87*1285115cSWilliam A. Kennington III auto b = sdbusplus::bus::new_default(); 88*1285115cSWilliam A. Kennington III sdbusplus::server::manager_t m{b, acpiObjPath}; 89*1285115cSWilliam A. Kennington III 90*1285115cSWilliam A. Kennington III // Reserve the dbus service for ACPI Power state changes coming from the 91*1285115cSWilliam A. Kennington III // BIOS 92*1285115cSWilliam A. Kennington III b.request_name(acpiInterface); 93*1285115cSWilliam A. Kennington III 94*1285115cSWilliam A. Kennington III ACPIPowerState aps{b, acpiObjPath}; 95*1285115cSWilliam A. Kennington III 96*1285115cSWilliam A. Kennington III // Handle dbus processing forever. 97*1285115cSWilliam A. Kennington III for (;;) 98*1285115cSWilliam A. Kennington III { 99*1285115cSWilliam A. Kennington III b.process_discard(); // discard any unhandled messages 100*1285115cSWilliam A. Kennington III b.wait(); 101*1285115cSWilliam A. Kennington III } 102*1285115cSWilliam A. Kennington III 103*1285115cSWilliam A. Kennington III return 1; 104*1285115cSWilliam A. Kennington III } 105