summaryrefslogtreecommitdiffstats
path: root/op-hostctl
diff options
context:
space:
mode:
authorBrad Bishop <bradleyb@fuzziesquirrel.com>2016-05-28 18:41:04 -0400
committerBrad Bishop <bradleyb@fuzziesquirrel.com>2016-06-10 18:06:59 -0400
commit40a360c2a4feef97a8f7041e655b2a42e51e0224 (patch)
tree75dfea3064d7c3243788c72cb9f30e2ce6241dea /op-hostctl
parenta73122191a7aba80f97332687a2e03cfb0336981 (diff)
downloadtalos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.tar.gz
talos-skeleton-40a360c2a4feef97a8f7041e655b2a42e51e0224.zip
Reorganize directory structure
Moving to directory per-application layout. This facilitates building single applications which is useful in the Yocto build environment since different applications satisfy different OpenBMC build requirements. A number of issues are also addressed: - All applications were pulling in libsystemd and the gdbus libs irrespective of whether or not they were needed. - gpio.o duplicated in every application - moved to libopenbmc_intf - Added install target Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
Diffstat (limited to 'op-hostctl')
-rw-r--r--op-hostctl/Makefile3
-rw-r--r--op-hostctl/control_host_obj.c271
2 files changed, 274 insertions, 0 deletions
diff --git a/op-hostctl/Makefile b/op-hostctl/Makefile
new file mode 100644
index 0000000..99f63dc
--- /dev/null
+++ b/op-hostctl/Makefile
@@ -0,0 +1,3 @@
+BINS=control_host
+include ../gdbus.mk
+include ../rules.mk
diff --git a/op-hostctl/control_host_obj.c b/op-hostctl/control_host_obj.c
new file mode 100644
index 0000000..e65f0af
--- /dev/null
+++ b/op-hostctl/control_host_obj.c
@@ -0,0 +1,271 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include "interfaces/openbmc_intf.h"
+#include "openbmc.h"
+#include "gpio.h"
+
+/* ------------------------------------------------------------------------- */
+static const gchar* dbus_object_path = "/org/openbmc/control";
+static const gchar* instance_name = "host0";
+static const gchar* dbus_name = "org.openbmc.control.Host";
+
+static GDBusObjectManagerServer *manager = NULL;
+
+GPIO fsi_data = (GPIO){ "FSI_DATA" };
+GPIO fsi_clk = (GPIO){ "FSI_CLK" };
+GPIO fsi_enable = (GPIO){ "FSI_ENABLE" };
+GPIO cronus_sel = (GPIO){ "CRONUS_SEL" };
+GPIO Throttle = (GPIO){ "BMC_THROTTLE" };
+GPIO idbtn = (GPIO){ "IDBTN" };
+
+/* Bit bang patterns */
+
+//putcfam pu 281c 30000000 -p0 (Primary Side Select)
+static const char* primary = "000011111111110101111000111001100111111111111111111111111111101111111111";
+//putcfam pu 281c B0000000 -p0
+static const char* go = "000011111111110101111000111000100111111111111111111111111111101101111111";
+//putcfam pu 0x281c 30900000 (Golden Side Select)
+static const char* golden = "000011111111110101111000111001100111101101111111111111111111101001111111";
+
+/* Setup attentions */
+//putcfam pu 0x081C 20000000
+static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111";
+//putcfam pu 0x100D 40000000
+static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111";
+//putcfam pu 0x100B FFFFFFFF
+static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111";
+
+
+
+static gboolean
+on_init(Control *control,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ control_complete_init(control,invocation);
+ return TRUE;
+}
+
+int
+fsi_bitbang(const char* pattern)
+{
+ int rc=GPIO_OK;
+ int i;
+ for(i=0;i<strlen(pattern);i++) {
+ rc = gpio_writec(&fsi_data,pattern[i]);
+ if(rc!=GPIO_OK) { break; }
+ rc = gpio_clock_cycle(&fsi_clk,1);
+ if(rc!=GPIO_OK) { break; }
+ }
+ return rc;
+}
+
+int
+fsi_standby()
+{
+ int rc=GPIO_OK;
+ rc = gpio_write(&fsi_data,1);
+ if(rc!=GPIO_OK) { return rc; }
+ rc = gpio_clock_cycle(&fsi_clk,5000);
+ if(rc!=GPIO_OK) { return rc; }
+ return rc;
+}
+
+
+static gboolean
+on_boot(ControlHost *host,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ int rc = GPIO_OK;
+
+ 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);
+
+ control_host_emit_booted(host);
+ return TRUE;
+}
+
+static void
+on_bus_acquired(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ ObjectSkeleton *object;
+ //g_print ("Acquired a message bus connection: %s\n",name);
+ manager = g_dbus_object_manager_server_new(dbus_object_path);
+
+ gchar *s;
+ s = g_strdup_printf("%s/%s",dbus_object_path,instance_name);
+ object = object_skeleton_new(s);
+ g_free(s);
+
+ ControlHost* control_host = control_host_skeleton_new();
+ object_skeleton_set_control_host(object, control_host);
+ g_object_unref(control_host);
+
+ Control* control = control_skeleton_new();
+ object_skeleton_set_control(object, control);
+ g_object_unref(control);
+
+ //define method callbacks here
+ g_signal_connect(control_host,
+ "handle-boot",
+ G_CALLBACK(on_boot),
+ object); /* user_data */
+ g_signal_connect(control,
+ "handle-init",
+ G_CALLBACK(on_init),
+ NULL); /* user_data */
+
+ control_host_set_debug_mode(control_host,0);
+ control_host_set_flash_side(control_host,"primary");
+
+ /* Export the object (@manager takes its own reference to @object) */
+ g_dbus_object_manager_server_set_connection(manager, connection);
+ g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
+ g_object_unref(object);
+
+ gpio_init(connection,&fsi_data);
+ gpio_init(connection,&fsi_clk);
+ gpio_init(connection,&fsi_enable);
+ gpio_init(connection,&cronus_sel);
+ gpio_init(connection,&Throttle);
+ gpio_init(connection,&idbtn);
+}
+
+static void
+on_name_acquired(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ // g_print ("Acquired the name %s\n", name);
+}
+
+static void
+on_name_lost(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ // g_print ("Lost the name %s\n", name);
+}
+
+gint
+main(gint argc, gchar *argv[])
+{
+ GMainLoop *loop;
+ cmdline cmd;
+ cmd.argc = argc;
+ cmd.argv = argv;
+
+ guint id;
+ loop = g_main_loop_new(NULL, FALSE);
+
+ id = g_bus_own_name(DBUS_TYPE,
+ dbus_name,
+ G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
+ G_BUS_NAME_OWNER_FLAGS_REPLACE,
+ on_bus_acquired,
+ on_name_acquired,
+ on_name_lost,
+ &cmd,
+ NULL);
+
+ g_main_loop_run(loop);
+
+ g_bus_unown_name(id);
+ g_main_loop_unref(loop);
+ return 0;
+}
OpenPOWER on IntegriCloud