gboolean go(gpointer user_data) { cmdline *cmd = user_data; Control* control = object_get_control((Object*)cmd->user_data); #ifdef __arm__ reg_init(); #endif control_emit_goto_system_state(control,"BMC_STARTING"); //g_main_loop_quit(cmd->loop); return FALSE; }
static gboolean on_set_power_state(ControlPower *pwr, GDBusMethodInvocation *invocation, guint state, gpointer user_data) { Control* control = object_get_control((Object*)user_data); if(state > 1) { g_dbus_method_invocation_return_dbus_error(invocation, "org.openbmc.ControlPower.Error.Failed", "Invalid power state"); return TRUE; } // return from method call control_power_complete_set_power_state(pwr,invocation); if(state == control_power_get_state(pwr)) { g_print("Power already at requested state: %d\n",state); } else { int error = 0; do { if(state == 1) { control_emit_goto_system_state(control,"HOST_POWERING_ON"); } else { control_emit_goto_system_state(control,"HOST_POWERING_OFF"); } error = gpio_open(&power_pin); if(error != GPIO_OK) { break; } error = gpio_write(&power_pin,!state); if(error != GPIO_OK) { break; } gpio_close(&power_pin); control_power_set_state(pwr,state); } while(0); if(error != GPIO_OK) { printf("ERROR PowerControl: GPIO set power state (rc=%d)\n",error); } } return TRUE; }
static gboolean on_boot (ControlHost *host, GDBusMethodInvocation *invocation, gpointer user_data) { // TODO: Add error checking g_print("Do Boot\n"); int rc = GPIO_OK; Control* control = object_get_control((Object*)user_data); control_host_complete_boot(host,invocation); do { rc |= gpio_open(&fsi_clk); rc |= gpio_open(&fsi_data); rc |= gpio_open(&fsi_enable); rc |= gpio_open(&cronus_sel); if (rc!=GPIO_OK) { break; } rc = gpio_write(&cronus_sel,1); //putcfam pu 281c 30000000 -p0 char a[] = "000011111111110101111000111001100111111111111111111111111111101111111111"; //putcfam pu 281c B0000000 -p0 char b[] = "000011111111110101111000111000100111111111111111111111111111101101111111"; gpio_write(&fsi_enable,1); gpio_write(&fsi_clk,1); gpio_write(&fsi_data,1); gpio_clock_cycle(&fsi_clk,5000); gpio_write(&fsi_data,0); gpio_clock_cycle(&fsi_clk,256); gpio_write(&fsi_data,1); gpio_clock_cycle(&fsi_clk,50); uint16_t i=0; for(i=0;i<strlen(a);i++) { gpio_writec(&fsi_data,a[i]); gpio_clock_cycle(&fsi_clk,1); } gpio_write(&fsi_data,1); /* Data standby state */ gpio_clock_cycle(&fsi_clk,5000); for(i=0;i<strlen(b);i++) { gpio_writec(&fsi_data,b[i]); gpio_clock_cycle(&fsi_clk,1); } gpio_write(&fsi_data,1); /* Data standby state */ gpio_clock_cycle(&fsi_clk,2); gpio_write(&fsi_clk,0); /* hold clk low for clock mux */ gpio_write(&fsi_enable,0); gpio_clock_cycle(&fsi_clk,16); gpio_write(&fsi_clk,0); /* Data standby state */ } while(0); if (rc != GPIO_OK) { printf("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc); } gpio_close(&fsi_clk); gpio_close(&fsi_data); gpio_close(&fsi_enable); gpio_close(&cronus_sel); control_emit_goto_system_state(control,"HOST_BOOTING"); control_host_emit_booted(host); return TRUE; }
// TODO: Change to interrupt driven instead of polling static gboolean poll_pgood(gpointer user_data) { ControlPower *control_power = object_get_control_power((Object*)user_data); Control* control = object_get_control((Object*)user_data); //send the heartbeat guint poll_int = control_get_poll_interval(control); if(poll_int == 0) { printf("ERROR PowerControl: Poll interval cannot be 0\n"); return FALSE; } //handle timeout time_t current_time = time(NULL); if(difftime(current_time,pgood_timeout_start) > control_power_get_pgood_timeout(control_power) && pgood_timeout_start != 0) { printf("ERROR PowerControl: Pgood poll timeout\n"); // set timeout to 0 so timeout doesn't happen again control_power_set_pgood_timeout(control_power,0); pgood_timeout_start = 0; return TRUE; } uint8_t gpio; int rc = gpio_open(&pgood); rc = gpio_read(&pgood,&gpio); gpio_close(&pgood); if(rc == GPIO_OK) { //if changed, set property and emit signal if(gpio != control_power_get_pgood(control_power)) { control_power_set_pgood(control_power,gpio); if(gpio==0) { control_power_emit_power_lost(control_power); control_emit_goto_system_state(control,"HOST_POWERED_OFF"); rc = gpio_open(&pcie_reset); rc = gpio_write(&pcie_reset,0); gpio_close(&pcie_reset); rc = gpio_open(&usb_reset); rc = gpio_write(&usb_reset,0); gpio_close(&usb_reset); } else { control_power_emit_power_good(control_power); control_emit_goto_system_state(control,"HOST_POWERED_ON"); rc = gpio_open(&pcie_reset); rc = gpio_write(&pcie_reset,1); gpio_close(&pcie_reset); rc = gpio_open(&usb_reset); rc = gpio_write(&usb_reset,1); gpio_close(&usb_reset); } } } else { printf("ERROR PowerControl: GPIO read error (gpio=%s,rc=%d)\n",pgood.name,rc); //return false so poll won't get called anymore return FALSE; } //pgood is not at desired state yet if(gpio != control_power_get_state(control_power) && control_power_get_pgood_timeout(control_power) > 0) { if(pgood_timeout_start == 0 ) { pgood_timeout_start = current_time; } } else { pgood_timeout_start = 0; } return TRUE; }
static gboolean on_boot(ControlHost *host, GDBusMethodInvocation *invocation, gpointer user_data) { int rc = GPIO_OK; GDBusProxy *proxy; GError *error = NULL; GVariant *result = NULL; GDBusConnection *connection = g_dbus_object_manager_server_get_connection(manager); if(control_host_get_debug_mode(host)==1) { g_print("Enabling debug mode; not booting host\n"); rc |= gpio_open(&fsi_enable); rc |= gpio_open(&cronus_sel); rc |= gpio_write(&fsi_enable,1); rc |= gpio_write(&cronus_sel,0); if(rc!=GPIO_OK) { g_print("ERROR enabling debug mode: %d\n",rc); } return TRUE; } g_print("Booting host\n"); Control* control = object_get_control((Object*)user_data); control_host_complete_boot(host,invocation); do { rc = gpio_open(&fsi_clk); rc |= gpio_open(&fsi_data); rc |= gpio_open(&fsi_enable); rc |= gpio_open(&cronus_sel); rc |= gpio_open(&Throttle); rc |= gpio_open(&idbtn); if(rc!=GPIO_OK) { break; } //setup dc pins rc = gpio_write(&cronus_sel,1); rc |= gpio_write(&fsi_enable,1); rc |= gpio_write(&fsi_clk,1); rc |= gpio_write(&Throttle,1); rc |= gpio_write(&idbtn,0); if(rc!=GPIO_OK) { break; } //data standy state rc = fsi_standby(); //clear out pipes rc |= gpio_write(&fsi_data,0); rc |= gpio_clock_cycle(&fsi_clk,256); rc |= gpio_write(&fsi_data,1); rc |= gpio_clock_cycle(&fsi_clk,50); if(rc!=GPIO_OK) { break; } rc = fsi_bitbang(attnA); rc |= fsi_standby(); rc |= fsi_bitbang(attnB); rc |= fsi_standby(); rc |= fsi_bitbang(attnC); rc |= fsi_standby(); if(rc!=GPIO_OK) { break; } const gchar* flash_side = control_host_get_flash_side(host); g_print("Using %s side of the bios flash\n",flash_side); if(strcmp(flash_side,"primary")==0) { rc |= fsi_bitbang(primary); } else if(strcmp(flash_side,"golden") == 0) { rc |= fsi_bitbang(golden); } else { g_print("ERROR: Invalid flash side: %s\n",flash_side); rc = 0xff; } rc |= fsi_standby(); if(rc!=GPIO_OK) { break; } rc = fsi_bitbang(go); rc |= gpio_write(&fsi_data,1); /* Data standby state */ rc |= gpio_clock_cycle(&fsi_clk,2); rc |= gpio_write(&fsi_clk,0); /* hold clk low for clock mux */ rc |= gpio_write(&fsi_enable,0); rc |= gpio_clock_cycle(&fsi_clk,16); rc |= gpio_write(&fsi_clk,0); /* Data standby state */ } while(0); if(rc != GPIO_OK) { g_print("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc); } else { control_emit_goto_system_state(control,"HOST_BOOTING"); } gpio_close(&fsi_clk); gpio_close(&fsi_data); gpio_close(&fsi_enable); gpio_close(&cronus_sel); gpio_close(&Throttle); gpio_close(&idbtn); // Start watchdog with 30s timeout per the OpenPower Host IPMI Spec. // Once the host starts booting, it'll reset and refresh the timer. error = NULL; proxy = g_dbus_proxy_new_sync(connection, G_DBUS_PROXY_FLAGS_NONE, NULL, /* GDBusInterfaceInfo* */ "org.openbmc.watchdog.Host", /* name */ "/org/openbmc/watchdog/host0", /* object path */ "org.openbmc.Watchdog", /* interface name */ NULL, /* GCancellable */ &error); g_assert_no_error(error); if(error) goto exit; // Set watchdog timer to 30s error = NULL; result = g_dbus_proxy_call_sync(proxy, "set", g_variant_new("(i)", 30000), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_assert_no_error(error); if (error) goto exit; if (result) g_variant_unref(result); // Start watchdog timer error = NULL; result = g_dbus_proxy_call_sync(proxy, "start", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); g_assert_no_error(error); if (error) goto exit; control_host_emit_booted(host); exit: if (result) g_variant_unref(result); return TRUE; }