summaryrefslogtreecommitdiffstats
path: root/flashbios
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 /flashbios
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 'flashbios')
-rw-r--r--flashbios/Makefile3
-rw-r--r--flashbios/flash_bios_obj.c391
2 files changed, 394 insertions, 0 deletions
diff --git a/flashbios/Makefile b/flashbios/Makefile
new file mode 100644
index 0000000..4fdb4af
--- /dev/null
+++ b/flashbios/Makefile
@@ -0,0 +1,3 @@
+BINS=flash_bios
+include ../gdbus.mk
+include ../rules.mk
diff --git a/flashbios/flash_bios_obj.c b/flashbios/flash_bios_obj.c
new file mode 100644
index 0000000..f865be1
--- /dev/null
+++ b/flashbios/flash_bios_obj.c
@@ -0,0 +1,391 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <sys/types.h>
+#include "interfaces/openbmc_intf.h"
+#include "openbmc.h"
+
+/* ------------------------------------------------------------------------- */
+static const gchar* dbus_object_path = "/org/openbmc/control/flash";
+static const gchar* dbus_name = "org.openbmc.control.Flash";
+static const gchar* FLASHER_BIN = "flasher.exe";
+
+static GDBusObjectManagerServer *manager = NULL;
+
+void
+catch_child(int sig_num)
+{
+ /* when we get here, we know there's a zombie child waiting */
+ int child_status;
+
+ wait(&child_status);
+ printf("flasher exited.\n");
+}
+
+int
+update(Flash* flash, const char* obj_path)
+{
+ pid_t pid;
+ int status=-1;
+ pid = fork();
+ if(pid == 0)
+ {
+ const gchar* path = flash_get_flasher_path(flash);
+ const gchar* name = flash_get_flasher_name(flash);
+ const gchar* inst = flash_get_flasher_instance(flash);
+ const gchar* filename = flash_get_filename(flash);
+ status = execl(path, name, inst, filename, obj_path, NULL);
+ return status;
+ }
+ return 0;
+}
+
+static gboolean
+on_init(Flash *f,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ flash_complete_init(f,invocation);
+
+ //tune flash
+ if(strcmp(flash_get_flasher_instance(f),"bios") == 0)
+ {
+ flash_set_filename(f,"");
+ const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
+ int rc = update(f,obj_path);
+ if(rc==-1)
+ {
+ printf("ERROR FlashControl: Unable to init\n");
+ }
+ sleep(3);
+ rc = update(f,obj_path);
+
+ }
+ return TRUE;
+}
+
+static gboolean
+on_lock(SharedResource *lock,
+ GDBusMethodInvocation *invocation,
+ gchar* name,
+ gpointer user_data)
+{
+ gboolean locked = shared_resource_get_lock(lock);
+ if(locked)
+ {
+ const gchar* name = shared_resource_get_name(lock);
+ printf("ERROR: BIOS Flash is already locked: %s\n",name);
+ }
+ else
+ {
+ printf("Locking BIOS Flash: %s\n",name);
+ shared_resource_set_lock(lock,true);
+ shared_resource_set_name(lock,name);
+ }
+ shared_resource_complete_lock(lock,invocation);
+ return TRUE;
+}
+
+static gboolean
+on_is_locked(SharedResource *lock,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ gboolean locked = shared_resource_get_lock(lock);
+ const gchar* name = shared_resource_get_name(lock);
+ shared_resource_complete_is_locked(lock,invocation,locked,name);
+ return TRUE;
+}
+
+static gboolean
+on_unlock(SharedResource *lock,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ printf("Unlocking BIOS Flash\n");
+ shared_resource_set_lock(lock,false);
+ shared_resource_set_name(lock,"");
+ shared_resource_complete_unlock(lock,invocation);
+ return TRUE;
+}
+
+static gboolean
+on_update_via_tftp(Flash *flash,
+ GDBusMethodInvocation *invocation,
+ gchar* url,
+ gchar* write_file,
+ gpointer user_data)
+{
+ SharedResource *lock = object_get_shared_resource((Object*)user_data);
+ gboolean locked = shared_resource_get_lock(lock);
+ flash_complete_update_via_tftp(flash,invocation);
+ if(locked)
+ {
+ const gchar* name = shared_resource_get_name(lock);
+ printf("BIOS Flash is locked: %s\n",name);
+ }
+ else
+ {
+ printf("Flashing BIOS from TFTP: %s,%s\n",url,write_file);
+ flash_set_filename(flash,write_file);
+ flash_emit_download(flash,url,write_file);
+ flash_set_status(flash,"Downloading");
+ }
+ return TRUE;
+}
+
+static gboolean
+on_error(Flash *flash,
+ GDBusMethodInvocation *invocation,
+ gchar* error_msg,
+ gpointer user_data)
+{
+ SharedResource *lock = object_get_shared_resource((Object*)user_data);
+ shared_resource_get_lock(lock);
+ flash_set_status(flash, error_msg);
+ flash_complete_error(flash,invocation);
+ printf("ERROR: %s. Clearing locks\n",error_msg);
+ shared_resource_set_lock(lock,false);
+ shared_resource_set_name(lock,"");
+
+ return TRUE;
+}
+
+static gboolean
+on_done(Flash *flash,
+ GDBusMethodInvocation *invocation,
+ gpointer user_data)
+{
+ int rc = 0;
+ SharedResource *lock = object_get_shared_resource((Object*)user_data);
+ shared_resource_get_lock(lock);
+ flash_set_status(flash, "Flash Done");
+ flash_complete_done(flash,invocation);
+ printf("Flash Done. Clearing locks\n");
+ shared_resource_set_lock(lock,false);
+ shared_resource_set_name(lock,"");
+ const gchar* filename = flash_get_filename(flash);
+ rc = unlink(filename);
+ if(rc != 0 )
+ {
+ printf("ERROR: Unable to delete file %s (%d)\n",filename,rc);
+ }
+
+ return TRUE;
+}
+
+static gboolean
+on_update(Flash *flash,
+ GDBusMethodInvocation *invocation,
+ gchar* write_file,
+ gpointer user_data)
+{
+ int rc = 0;
+ SharedResource *lock = object_get_shared_resource((Object*)user_data);
+ gboolean locked = shared_resource_get_lock(lock);
+ flash_set_status(flash,"Flashing");
+ flash_complete_update(flash,invocation);
+ if(locked)
+ {
+ const gchar* name = shared_resource_get_name(lock);
+ printf("BIOS Flash is locked: %s\n",name);
+ }
+ else
+ {
+ printf("Flashing BIOS from: %s\n",write_file);
+ flash_set_status(flash, "Flashing");
+ shared_resource_set_lock(lock,true);
+ shared_resource_set_name(lock,dbus_object_path);
+ flash_set_filename(flash,write_file);
+ const gchar* obj_path = g_dbus_object_get_object_path((GDBusObject*)user_data);
+ rc = update(flash,obj_path);
+ if(!rc)
+ {
+ shared_resource_set_lock(lock,false);
+ shared_resource_set_name(lock,"");
+ }
+ }
+ return TRUE;
+}
+
+static void
+on_flash_progress(GDBusConnection* connection,
+ const gchar* sender_name,
+ const gchar* object_path,
+ const gchar* interface_name,
+ const gchar* signal_name,
+ GVariant* parameters,
+ gpointer user_data)
+{
+ Flash *flash = object_get_flash((Object*)user_data);
+ object_get_shared_resource((Object*)user_data);
+ GVariantIter *iter = g_variant_iter_new(parameters);
+ g_variant_iter_next_value(iter);
+ GVariant* v_progress = g_variant_iter_next_value(iter);
+
+ uint8_t progress = g_variant_get_byte(v_progress);
+
+ gchar *s;
+ s = g_strdup_printf("Flashing: %d%%",progress);
+ flash_set_status(flash,s);
+ g_free(s);
+}
+
+static void
+on_bus_acquired(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ ObjectSkeleton *object;
+ cmdline *cmd = user_data;
+ manager = g_dbus_object_manager_server_new(dbus_object_path);
+ int i=0;
+
+ //TODO: don't use fixed buffer
+ char flasher_path[512];
+ memset(flasher_path, '\0', sizeof(flasher_path));
+ gchar *flasher_file = NULL;
+ int c = strlen(cmd->argv[0]);
+ while(c>0)
+ {
+ if(cmd->argv[0][c] == '/')
+ {
+ strncpy(flasher_path,cmd->argv[0],c);
+ flasher_file = g_strdup_printf("%s/%s",flasher_path,FLASHER_BIN);
+ break;
+ }
+ c--;
+ }
+
+ const char* inst[] = {"bios"};
+ for(i=0;i<1;i++)
+ {
+ gchar* s;
+ s = g_strdup_printf("%s/%s",dbus_object_path,inst[i]);
+ object = object_skeleton_new(s);
+ g_free(s);
+
+ Flash* flash = flash_skeleton_new();
+ object_skeleton_set_flash(object, flash);
+ g_object_unref(flash);
+
+ SharedResource* lock = shared_resource_skeleton_new();
+ object_skeleton_set_shared_resource(object, lock);
+ g_object_unref(lock);
+
+ shared_resource_set_lock(lock,false);
+ shared_resource_set_name(lock,"");
+
+ flash_set_flasher_path(flash,flasher_file);
+ flash_set_flasher_name(flash,FLASHER_BIN);
+ flash_set_flasher_instance(flash,inst[i]);
+ //g_free (s);
+
+
+ //define method callbacks here
+ g_signal_connect(lock,
+ "handle-lock",
+ G_CALLBACK(on_lock),
+ NULL); /* user_data */
+ g_signal_connect(lock,
+ "handle-unlock",
+ G_CALLBACK(on_unlock),
+ NULL); /* user_data */
+ g_signal_connect(lock,
+ "handle-is-locked",
+ G_CALLBACK(on_is_locked),
+ NULL); /* user_data */
+
+ g_signal_connect(flash,
+ "handle-update",
+ G_CALLBACK(on_update),
+ object); /* user_data */
+
+ g_signal_connect(flash,
+ "handle-error",
+ G_CALLBACK(on_error),
+ object); /* user_data */
+
+ g_signal_connect(flash,
+ "handle-done",
+ G_CALLBACK(on_done),
+ object); /* user_data */
+
+ g_signal_connect(flash,
+ "handle-update-via-tftp",
+ G_CALLBACK(on_update_via_tftp),
+ object); /* user_data */
+
+ g_signal_connect(flash,
+ "handle-init",
+ G_CALLBACK(on_init),
+ object); /* user_data */
+
+ s = g_strdup_printf("/org/openbmc/control/%s",inst[i]);
+ g_dbus_connection_signal_subscribe(connection,
+ NULL,
+ "org.openbmc.FlashControl",
+ "Progress",
+ s,
+ NULL,
+ G_DBUS_SIGNAL_FLAGS_NONE,
+ (GDBusSignalCallback) on_flash_progress,
+ object,
+ NULL );
+
+ g_free(s);
+
+
+ flash_set_filename(flash,"");
+ /* 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);
+ }
+ g_free(flasher_file);
+}
+
+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);
+
+ //signal(SIGCHLD, catch_child);
+ 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