added dual side flash support
diff --git a/objects/control_host_obj.c b/objects/control_host_obj.c
index 63a8d64..672ef85 100644
--- a/objects/control_host_obj.c
+++ b/objects/control_host_obj.c
@@ -8,12 +8,12 @@
#include "interfaces/openbmc_intf.h"
#include "openbmc.h"
#include "gpio.h"
-
+#include "object_mapper.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 const gchar* dbus_name = "org.openbmc.control.Host";
static GDBusObjectManagerServer *manager = NULL;
@@ -22,6 +22,25 @@
GPIO fsi_enable = (GPIO){ "FSI_ENABLE" };
GPIO cronus_sel = (GPIO){ "CRONUS_SEL" };
+/* 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,
@@ -30,70 +49,123 @@
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)
{
- // TODO: Add error checking
- g_print("Do Boot\n");
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_clk);
rc |= gpio_open(&fsi_data);
rc |= gpio_open(&fsi_enable);
rc |= gpio_open(&cronus_sel);
if (rc!=GPIO_OK) { break; }
-
+
+ //setup dc pins
rc = gpio_write(&cronus_sel,1);
- //putcfam pu 281c 30000000 -p0
- char a[] = "000011111111110101111000111001100111111111111111111111111111101111111111";
- //putcfam pu 281c B0000000 -p0
- char b[] = "000011111111110101111000111000100111111111111111111111111111101101111111";
+ rc |= gpio_write(&fsi_enable,1);
+ rc |= gpio_write(&fsi_clk,1);
+ if (rc!=GPIO_OK) { break; }
- 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);
+ //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;
+
}
- gpio_write(&fsi_data,1); /* Data standby state */
- gpio_clock_cycle(&fsi_clk,5000);
+ rc |= fsi_standby();
+ if (rc!=GPIO_OK) { break; }
+
+ rc = fsi_bitbang(go);
- 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);
+ rc |= gpio_write(&fsi_data,1); /* Data standby state */
+ rc |= 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 */
+ 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)
{
- printf("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
- }
+ 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);
- control_emit_goto_system_state(control,"HOST_BOOTING");
-
control_host_emit_booted(host);
return TRUE;
}
@@ -108,32 +180,39 @@
cmdline *cmd = user_data;
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);
+ gchar *s;
+ s = g_strdup_printf ("%s/%s",dbus_object_path,instance_name);
+ object = object_skeleton_new (s);
+ g_free (s);
- Control* control = control_skeleton_new ();
- object_skeleton_set_control (object, control);
- g_object_unref (control);
+ ControlHost* control_host = control_host_skeleton_new ();
+ object_skeleton_set_control_host (object, control_host);
+ g_object_unref (control_host);
- //define method callbacks here
- g_signal_connect (control_host,
- "handle-boot",
- G_CALLBACK (on_boot),
- object); /* user_data */
+ Control* control = control_skeleton_new ();
+ object_skeleton_set_control (object, control);
+ g_object_unref (control);
- g_signal_connect (control,
- "handle-init",
- G_CALLBACK (on_init),
- NULL); /* user_data */
+ ObjectMapper* mapper = object_mapper_skeleton_new ();
+ object_skeleton_set_object_mapper (object, mapper);
+ g_object_unref (mapper);
- /* Export the object (@manager takes its own reference to @object) */
- g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
- g_object_unref (object);
+ //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_export (manager, G_DBUS_OBJECT_SKELETON (object));
+ g_object_unref (object);
/* Export all objects */
g_dbus_object_manager_server_set_connection (manager, connection);
@@ -142,7 +221,7 @@
gpio_init(connection,&fsi_clk);
gpio_init(connection,&fsi_enable);
gpio_init(connection,&cronus_sel);
-
+ emit_object_added((GDBusObjectManager*)manager);
}
static void