blob: 56b02dedae96af5d6ff69c7bd08197f1b3914e4e [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" };
Ken2fd67f92015-12-09 01:41:23 +080024GPIO Throttle = (GPIO){ "BMC_TROTTLE" };
Norman Jamesfa2e76e2015-08-26 17:41:20 -050025
Norman Jamesf378e3f2015-10-31 17:36:43 -050026/* Bit bang patterns */
27
28//putcfam pu 281c 30000000 -p0 (Primary Side Select)
29static const char* primary = "000011111111110101111000111001100111111111111111111111111111101111111111";
30//putcfam pu 281c B0000000 -p0
31static const char* go = "000011111111110101111000111000100111111111111111111111111111101101111111";
32//putcfam pu 0x281c 30900000 (Golden Side Select)
33static const char* golden = "000011111111110101111000111001100111101101111111111111111111101001111111";
34
35/* Setup attentions */
36//putcfam pu 0x081C 20000000
37static const char* attnA = "000011111111111101111110001001101111111111111111111111111111110001111111";
38//putcfam pu 0x100D 40000000
39static const char* attnB = "000011111111111011111100101001011111111111111111111111111111110001111111";
40//putcfam pu 0x100B FFFFFFFF
41static const char* attnC = "000011111111111011111101001000000000000000000000000000000000001011111111";
42
43
44
Norman James362a80f2015-09-14 14:04:39 -050045static gboolean
46on_init (Control *control,
47 GDBusMethodInvocation *invocation,
48 gpointer user_data)
49{
50 control_complete_init(control,invocation);
51 return TRUE;
52}
Norman Jamesf378e3f2015-10-31 17:36:43 -050053
54int fsi_bitbang(const char* pattern)
55{
56 int rc=GPIO_OK;
57 int i;
58 for(i=0;i<strlen(pattern);i++) {
59 rc = gpio_writec(&fsi_data,pattern[i]);
60 if (rc!=GPIO_OK) { break; }
61 rc = gpio_clock_cycle(&fsi_clk,1);
62 if (rc!=GPIO_OK) { break; }
63 }
64 return rc;
65
66}
67
68int fsi_standby()
69{
70 int rc=GPIO_OK;
71 rc = gpio_write(&fsi_data,1);
72 if (rc!=GPIO_OK) { return rc; }
73 rc = gpio_clock_cycle(&fsi_clk,5000);
74 if (rc!=GPIO_OK) { return rc; }
75 return rc;
76}
77
78
Norman Jamesfa2e76e2015-08-26 17:41:20 -050079static gboolean
80on_boot (ControlHost *host,
81 GDBusMethodInvocation *invocation,
82 gpointer user_data)
83{
Norman James18998182015-10-11 21:54:53 -050084 int rc = GPIO_OK;
85
Norman Jamesf378e3f2015-10-31 17:36:43 -050086 if (control_host_get_debug_mode(host)==1)
87 {
88 g_print("Enabling debug mode; not booting host\n");
89 rc |= gpio_open(&fsi_enable);
90 rc |= gpio_open(&cronus_sel);
91 rc |= gpio_write(&fsi_enable,1);
92 rc |= gpio_write(&cronus_sel,0);
93 if (rc!=GPIO_OK) {
94 g_print("ERROR enabling debug mode: %d\n",rc);
95 }
96 return TRUE;
97 }
98 g_print("Booting host\n");
Norman James362a80f2015-09-14 14:04:39 -050099 Control* control = object_get_control((Object*)user_data);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500100 control_host_complete_boot(host,invocation);
Norman James18998182015-10-11 21:54:53 -0500101 do {
Norman Jamesf378e3f2015-10-31 17:36:43 -0500102 rc = gpio_open(&fsi_clk);
Norman James18998182015-10-11 21:54:53 -0500103 rc |= gpio_open(&fsi_data);
104 rc |= gpio_open(&fsi_enable);
105 rc |= gpio_open(&cronus_sel);
Ken2fd67f92015-12-09 01:41:23 +0800106 rc |= gpio_open(&Throttle);
Norman James18998182015-10-11 21:54:53 -0500107 if (rc!=GPIO_OK) { break; }
Norman Jamesf378e3f2015-10-31 17:36:43 -0500108
109 //setup dc pins
Norman James18998182015-10-11 21:54:53 -0500110 rc = gpio_write(&cronus_sel,1);
Norman Jamesf378e3f2015-10-31 17:36:43 -0500111 rc |= gpio_write(&fsi_enable,1);
112 rc |= gpio_write(&fsi_clk,1);
Ken2fd67f92015-12-09 01:41:23 +0800113 rc |= gpio_write(&Throttle,1);
Norman Jamesf378e3f2015-10-31 17:36:43 -0500114 if (rc!=GPIO_OK) { break; }
Norman James18998182015-10-11 21:54:53 -0500115
Norman Jamesf378e3f2015-10-31 17:36:43 -0500116 //data standy state
117 rc = fsi_standby();
118
119 //clear out pipes
120 rc |= gpio_write(&fsi_data,0);
121 rc |= gpio_clock_cycle(&fsi_clk,256);
122 rc |= gpio_write(&fsi_data,1);
123 rc |= gpio_clock_cycle(&fsi_clk,50);
124 if (rc!=GPIO_OK) { break; }
125
126 rc = fsi_bitbang(attnA);
127 rc |= fsi_standby();
128
129 rc |= fsi_bitbang(attnB);
130 rc |= fsi_standby();
131
132 rc |= fsi_bitbang(attnC);
133 rc |= fsi_standby();
134 if (rc!=GPIO_OK) { break; }
135
136 const gchar* flash_side = control_host_get_flash_side(host);
137 g_print("Using %s side of the bios flash\n",flash_side);
138 if (strcmp(flash_side,"primary")==0) {
139 rc |= fsi_bitbang(primary);
140 } else if (strcmp(flash_side,"golden") == 0) {
141 rc |= fsi_bitbang(golden);
142 } else {
143 g_print("ERROR: Invalid flash side: %s\n",flash_side);
144 rc = 0xff;
145
Norman James18998182015-10-11 21:54:53 -0500146 }
Norman Jamesf378e3f2015-10-31 17:36:43 -0500147 rc |= fsi_standby();
148 if (rc!=GPIO_OK) { break; }
149
150 rc = fsi_bitbang(go);
Norman James18998182015-10-11 21:54:53 -0500151
Norman Jamesf378e3f2015-10-31 17:36:43 -0500152 rc |= gpio_write(&fsi_data,1); /* Data standby state */
153 rc |= gpio_clock_cycle(&fsi_clk,2);
Norman James18998182015-10-11 21:54:53 -0500154
Norman Jamesf378e3f2015-10-31 17:36:43 -0500155 rc |= gpio_write(&fsi_clk,0); /* hold clk low for clock mux */
156 rc |= gpio_write(&fsi_enable,0);
157 rc |= gpio_clock_cycle(&fsi_clk,16);
158 rc |= gpio_write(&fsi_clk,0); /* Data standby state */
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500159
Norman James18998182015-10-11 21:54:53 -0500160 } while(0);
161 if (rc != GPIO_OK)
162 {
Norman Jamesf378e3f2015-10-31 17:36:43 -0500163 g_print("ERROR HostControl: GPIO sequence failed (rc=%d)\n",rc);
164 } else {
165 control_emit_goto_system_state(control,"HOST_BOOTING");
166 }
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500167 gpio_close(&fsi_clk);
168 gpio_close(&fsi_data);
169 gpio_close(&fsi_enable);
170 gpio_close(&cronus_sel);
Ken2fd67f92015-12-09 01:41:23 +0800171 gpio_close(&Throttle);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500172
173 control_host_emit_booted(host);
174 return TRUE;
175}
176
177static void
178on_bus_acquired (GDBusConnection *connection,
179 const gchar *name,
180 gpointer user_data)
181{
182 ObjectSkeleton *object;
Norman James362a80f2015-09-14 14:04:39 -0500183 //g_print ("Acquired a message bus connection: %s\n",name);
Norman James10ff6a32015-08-27 14:24:17 -0500184 cmdline *cmd = user_data;
Norman James10ff6a32015-08-27 14:24:17 -0500185 manager = g_dbus_object_manager_server_new (dbus_object_path);
Norman James8fee6f22015-10-28 12:48:43 -0500186
Norman Jamesf378e3f2015-10-31 17:36:43 -0500187 gchar *s;
188 s = g_strdup_printf ("%s/%s",dbus_object_path,instance_name);
189 object = object_skeleton_new (s);
190 g_free (s);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500191
Norman Jamesf378e3f2015-10-31 17:36:43 -0500192 ControlHost* control_host = control_host_skeleton_new ();
193 object_skeleton_set_control_host (object, control_host);
194 g_object_unref (control_host);
Norman James362a80f2015-09-14 14:04:39 -0500195
Norman Jamesf378e3f2015-10-31 17:36:43 -0500196 Control* control = control_skeleton_new ();
197 object_skeleton_set_control (object, control);
198 g_object_unref (control);
Norman James362a80f2015-09-14 14:04:39 -0500199
Norman Jamesf378e3f2015-10-31 17:36:43 -0500200 ObjectMapper* mapper = object_mapper_skeleton_new ();
201 object_skeleton_set_object_mapper (object, mapper);
202 g_object_unref (mapper);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500203
Norman Jamesf378e3f2015-10-31 17:36:43 -0500204 //define method callbacks here
205 g_signal_connect (control_host,
206 "handle-boot",
207 G_CALLBACK (on_boot),
208 object); /* user_data */
209 g_signal_connect (control,
210 "handle-init",
211 G_CALLBACK (on_init),
212 NULL); /* user_data */
213
214 control_host_set_debug_mode(control_host,0);
215 control_host_set_flash_side(control_host,"primary");
216
217 /* Export the object (@manager takes its own reference to @object) */
218 g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
219 g_object_unref (object);
Norman James8fee6f22015-10-28 12:48:43 -0500220
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500221 /* Export all objects */
222 g_dbus_object_manager_server_set_connection (manager, connection);
223
224 gpio_init(connection,&fsi_data);
225 gpio_init(connection,&fsi_clk);
226 gpio_init(connection,&fsi_enable);
227 gpio_init(connection,&cronus_sel);
Ken2fd67f92015-12-09 01:41:23 +0800228 gpio_init(connection,&Throttle);
Norman Jamesf378e3f2015-10-31 17:36:43 -0500229 emit_object_added((GDBusObjectManager*)manager);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500230}
231
232static void
233on_name_acquired (GDBusConnection *connection,
234 const gchar *name,
235 gpointer user_data)
236{
Norman James362a80f2015-09-14 14:04:39 -0500237// g_print ("Acquired the name %s\n", name);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500238}
239
240static void
241on_name_lost (GDBusConnection *connection,
242 const gchar *name,
243 gpointer user_data)
244{
Norman James362a80f2015-09-14 14:04:39 -0500245// g_print ("Lost the name %s\n", name);
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500246}
247
248gint
249main (gint argc, gchar *argv[])
250{
251 GMainLoop *loop;
Norman James952b38d2015-08-27 21:30:06 -0500252 cmdline cmd;
253 cmd.argc = argc;
254 cmd.argv = argv;
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500255
256 guint id;
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500257 loop = g_main_loop_new (NULL, FALSE);
258
Norman James5e792e32015-10-07 17:36:17 -0500259 id = g_bus_own_name (DBUS_TYPE,
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500260 dbus_name,
261 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
262 G_BUS_NAME_OWNER_FLAGS_REPLACE,
263 on_bus_acquired,
264 on_name_acquired,
265 on_name_lost,
Norman James952b38d2015-08-27 21:30:06 -0500266 &cmd,
Norman Jamesfa2e76e2015-08-26 17:41:20 -0500267 NULL);
268
269 g_main_loop_run (loop);
270
271 g_bus_unown_name (id);
272 g_main_loop_unref (loop);
273 return 0;
274}