blob: 672ef855aba85d23f032b525abf25cbefb9982ec [file] [log] [blame]
Norman Jamesfa2e76e2015-08-26 17:41:20 -05001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <sys/stat.h>
7#include <sys/mman.h>
Norman James362a80f2015-09-14 14:04:39 -05008#include "interfaces/openbmc_intf.h"
Norman James10ff6a32015-08-27 14:24:17 -05009#include "openbmc.h"
10#include "gpio.h"
Norman Jamesf378e3f2015-10-31 17:36:43 -050011#include "object_mapper.h"
Norman Jamesfa2e76e2015-08-26 17:41:20 -050012
13/* ---------------------------------------------------------------------------------------------------- */
Norman James362a80f2015-09-14 14:04:39 -050014static const gchar* dbus_object_path = "/org/openbmc/control";
Norman James8fee6f22015-10-28 12:48:43 -050015static const gchar* instance_name = "host0";
Norman Jamesf378e3f2015-10-31 17:36:43 -050016static const gchar* dbus_name = "org.openbmc.control.Host";
Norman Jamesfa2e76e2015-08-26 17:41:20 -050017
18static GDBusObjectManagerServer *manager = NULL;
Norman Jamesfa2e76e2015-08-26 17:41:20 -050019
20GPIO fsi_data = (GPIO){ "FSI_DATA" };
21GPIO fsi_clk = (GPIO){ "FSI_CLK" };
22GPIO fsi_enable = (GPIO){ "FSI_ENABLE" };
23GPIO cronus_sel = (GPIO){ "CRONUS_SEL" };
24
Norman Jamesf378e3f2015-10-31 17:36:43 -050025/* Bit bang patterns */
26
27//putcfam pu 281c 30000000 -p0 (Primary Side Select)
28static const char* primary = "000011111111110101111000111001100111111111111111111111111111101111111111";
29//putcfam pu 281c B0000000 -p0
30static const char* go = "000011111111110101111000111000100111111111111111111111111111101101111111";
31//putcfam pu 0x281c 30900000 (Golden Side Select)
32static const char* golden = "000011111111110101111000111001100111101101111111111111111111101001111111";
33
34/* Setup attentions */
35//putcfam pu 0x081C 20000000
36static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111";
37//putcfam pu 0x100D 40000000
38static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111";
39//putcfam pu 0x100B FFFFFFFF
40static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111";
41
42
43
Norman James362a80f2015-09-14 14:04:39 -050044static gboolean
45on_init (Control *control,
46 GDBusMethodInvocation *invocation,
47 gpointer user_data)
48{
49 control_complete_init(control,invocation);
50 return TRUE;
51}
Norman Jamesf378e3f2015-10-31 17:36:43 -050052
53int fsi_bitbang(const char* pattern)
54{
55 int rc=GPIO_OK;
56 int i;
57 for(i=0;i<strlen(pattern);i++) {
58 rc = gpio_writec(&fsi_data,pattern[i]);
59 if (rc!=GPIO_OK) { break; }
60 rc = gpio_clock_cycle(&fsi_clk,1);
61 if (rc!=GPIO_OK) { break; }
62 }
63 return rc;
64
65}
66
67int fsi_standby()
68{
69 int rc=GPIO_OK;
70 rc = gpio_write(&fsi_data,1);
71 if (rc!=GPIO_OK) { return rc; }
72 rc = gpio_clock_cycle(&fsi_clk,5000);
73 if (rc!=GPIO_OK) { return rc; }
74 return rc;
75}
76
77
Norman Jamesfa2e76e2015-08-26 17:41:20 -050078static gboolean
79on_boot (ControlHost *host,
80 GDBusMethodInvocation *invocation,
81 gpointer user_data)
82{
Norman James18998182015-10-11 21:54:53 -050083 int rc = GPIO_OK;
84
Norman Jamesf378e3f2015-10-31 17:36:43 -050085 if (control_host_get_debug_mode(host)==1)
86 {
87 g_print("Enabling debug mode; not booting host\n");
88 rc |= gpio_open(&fsi_enable);
89 rc |= gpio_open(&cronus_sel);
90 rc |= gpio_write(&fsi_enable,1);
91 rc |= gpio_write(&cronus_sel,0);
92 if (rc!=GPIO_OK) {
93 g_print("ERROR enabling debug mode: %d\n",rc);
94 }
95 return TRUE;
96 }
97 g_print("Booting host\n");
Norman James362a80f2015-09-14 14:04:39 -050098 Control* control = object_get_control((Object*)user_data);
Norman Jamesfa2e76e2015-08-26 17:41:20 -050099 control_host_complete_boot(host,invocation);
Norman James18998182015-10-11 21:54:53 -0500100 do {
Norman Jamesf378e3f2015-10-31 17:36:43 -0500101 rc = gpio_open(&fsi_clk);
Norman James18998182015-10-11 21:54:53 -0500102 rc |= gpio_open(&fsi_data);
103 rc |= gpio_open(&fsi_enable);
104 rc |= gpio_open(&cronus_sel);
105 if (rc!=GPIO_OK) { break; }
Norman Jamesf378e3f2015-10-31 17:36:43 -0500106
107 //setup dc pins
Norman James18998182015-10-11 21:54:53 -0500108 rc = gpio_write(&cronus_sel,1);
Norman Jamesf378e3f2015-10-31 17:36:43 -0500109 rc |= gpio_write(&fsi_enable,1);
110 rc |= gpio_write(&fsi_clk,1);
111 if (rc!=GPIO_OK) { break; }
Norman James18998182015-10-11 21:54:53 -0500112
Norman Jamesf378e3f2015-10-31 17:36:43 -0500113 //data standy state
114 rc = fsi_standby();
115
116 //clear out pipes
117 rc |= gpio_write(&fsi_data,0);
118 rc |= gpio_clock_cycle(&fsi_clk,256);
119 rc |= gpio_write(&fsi_data,1);
120 rc |= gpio_clock_cycle(&fsi_clk,50);
121 if (rc!=GPIO_OK) { break; }
122
123 rc = fsi_bitbang(attnA);
124 rc |= fsi_standby();
125
126 rc |= fsi_bitbang(attnB);
127 rc |= fsi_standby();
128
129 rc |= fsi_bitbang(attnC);
130 rc |= fsi_standby();
131 if (rc!=GPIO_OK) { break; }
132
133 const gchar* flash_side = control_host_get_flash_side(host);
134 g_print("Using %s side of the bios flash\n",flash_side);
135 if (strcmp(flash_side,"primary")==0) {
136 rc |= fsi_bitbang(primary);
137 } else if (strcmp(flash_side,"golden") == 0) {
138 rc |= fsi_bitbang(golden);
139 } else {
140 g_print("ERROR: Invalid flash side: %s\n",flash_side);
141 rc = 0xff;
142
Norman James18998182015-10-11 21:54:53 -0500143 }
Norman Jamesf378e3f2015-10-31 17:36:43 -0500144 rc |= fsi_standby();
145 if (rc!=GPIO_OK) { break; }
146
147 rc = fsi_bitbang(go);
Norman James18998182015-10-11 21:54:53 -0500148
Norman Jamesf378e3f2015-10-31 17:36:43 -0500149 rc |= gpio_write(&fsi_data,1); /* Data standby state */
150 rc |= gpio_clock_cycle(&fsi_clk,2);
Norman James18998182015-10-11 21:54:53 -0500151
Norman Jamesf378e3f2015-10-31 17:36:43 -0500152 rc |= gpio_write(&fsi_clk,0); /* hold clk low for clock mux */
153 rc |= gpio_write(&fsi_enable,0);
154 rc |= gpio_clock_cycle(&fsi_clk,16);
155 rc |= gpio_write(&fsi_clk,0); /* Data standby state */
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500156
Norman James18998182015-10-11 21:54:53 -0500157 } while(0);
158 if (rc != GPIO_OK)
159 {
Norman Jamesf378e3f2015-10-31 17:36:43 -0500160 g_print("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
161 } else {
162 control_emit_goto_system_state(control,"HOST_BOOTING");
163 }
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500164 gpio_close(&fsi_clk);
165 gpio_close(&fsi_data);
166 gpio_close(&fsi_enable);
167 gpio_close(&cronus_sel);
168
169 control_host_emit_booted(host);
170 return TRUE;
171}
172
173static void
174on_bus_acquired (GDBusConnection *connection,
175 const gchar *name,
176 gpointer user_data)
177{
178 ObjectSkeleton *object;
Norman James362a80f2015-09-14 14:04:39 -0500179 //g_print ("Acquired a message bus connection: %s\n",name);
Norman James10ff6a32015-08-27 14:24:17 -0500180 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500181 manager = g_dbus_object_manager_server_new (dbus_object_path);
Norman James8fee6f22015-10-28 12:48:43 -0500182
Norman Jamesf378e3f2015-10-31 17:36:43 -0500183 gchar *s;
184 s = g_strdup_printf ("%s/%s",dbus_object_path,instance_name);
185 object = object_skeleton_new (s);
186 g_free (s);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500187
Norman Jamesf378e3f2015-10-31 17:36:43 -0500188 ControlHost* control_host = control_host_skeleton_new ();
189 object_skeleton_set_control_host (object, control_host);
190 g_object_unref (control_host);
Norman James362a80f2015-09-14 14:04:39 -0500191
Norman Jamesf378e3f2015-10-31 17:36:43 -0500192 Control* control = control_skeleton_new ();
193 object_skeleton_set_control (object, control);
194 g_object_unref (control);
Norman James362a80f2015-09-14 14:04:39 -0500195
Norman Jamesf378e3f2015-10-31 17:36:43 -0500196 ObjectMapper* mapper = object_mapper_skeleton_new ();
197 object_skeleton_set_object_mapper (object, mapper);
198 g_object_unref (mapper);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500199
Norman Jamesf378e3f2015-10-31 17:36:43 -0500200 //define method callbacks here
201 g_signal_connect (control_host,
202 "handle-boot",
203 G_CALLBACK (on_boot),
204 object); /* user_data */
205 g_signal_connect (control,
206 "handle-init",
207 G_CALLBACK (on_init),
208 NULL); /* user_data */
209
210 control_host_set_debug_mode(control_host,0);
Norman James8aef8932015-11-01 19:36:08 -0600211 control_host_set_flash_side(control_host,"primary");
Norman Jamesf378e3f2015-10-31 17:36:43 -0500212
213 /* Export the object (@manager takes its own reference to @object) */
214 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
215 g_object_unref (object);
Norman James8fee6f22015-10-28 12:48:43 -0500216
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500217 /* Export all objects */
218 g_dbus_object_manager_server_set_connection (manager, connection);
219
220 gpio_init(connection,&fsi_data);
221 gpio_init(connection,&fsi_clk);
222 gpio_init(connection,&fsi_enable);
223 gpio_init(connection,&cronus_sel);
Norman Jamesf378e3f2015-10-31 17:36:43 -0500224 emit_object_added((GDBusObjectManager*)manager);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500225}
226
227static void
228on_name_acquired (GDBusConnection *connection,
229 const gchar *name,
230 gpointer user_data)
231{
Norman James362a80f2015-09-14 14:04:39 -0500232// g_print ("Acquired the name %s\n", name);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500233}
234
235static void
236on_name_lost (GDBusConnection *connection,
237 const gchar *name,
238 gpointer user_data)
239{
Norman James362a80f2015-09-14 14:04:39 -0500240// g_print ("Lost the name %s\n", name);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500241}
242
243gint
244main (gint argc, gchar *argv[])
245{
246 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500247 cmdline cmd;
248 cmd.argc = argc;
249 cmd.argv = argv;
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500250
251 guint id;
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500252 loop = g_main_loop_new (NULL, FALSE);
253
Norman James5e792e32015-10-07 17:36:17 -0500254 id = g_bus_own_name (DBUS_TYPE,
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500255 dbus_name,
256 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
257 G_BUS_NAME_OWNER_FLAGS_REPLACE,
258 on_bus_acquired,
259 on_name_acquired,
260 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500261 &cmd,
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500262 NULL);
263
264 g_main_loop_run (loop);
265
266 g_bus_unown_name (id);
267 g_main_loop_unref (loop);
268 return 0;
269}