xref: /openbmc/skeleton/bmcctl/control_bmc_obj.c (revision 40a360c2)
1 #include <stdint.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #include <sys/stat.h>
8 #include <sys/mman.h>
9 #include "interfaces/openbmc_intf.h"
10 #include "openbmc.h"
11 #include "gpio.h"
12 
13 /* ------------------------------------------------------------------------- */
14 static const gchar* dbus_object_path = "/org/openbmc/control";
15 static const gchar* instance_name = "bmc0";
16 static const gchar* dbus_name = "org.openbmc.control.Bmc";
17 
18 //this probably should come from some global SOC config
19 
20 #define LPC_BASE		(off_t)0x1e789000
21 #define LPC_HICR6		0x80
22 #define LPC_HICR7		0x88
23 #define LPC_HICR8		0x8c
24 #define SPI_BASE		(off_t)0x1e630000
25 #define SCU_BASE		(off_t)0x1e780000
26 #define UART_BASE		(off_t)0x1e783000
27 #define COM_BASE		(off_t)0x1e789000
28 #define COM_BASE2		(off_t)0x1e789100
29 #define GPIO_BASE		(off_t)0x1e6e2000
30 
31 static GDBusObjectManagerServer *manager = NULL;
32 
33 void*
34 memmap(int mem_fd,off_t base)
35 {
36 	void* bmcreg;
37 	bmcreg = mmap(NULL, getpagesize(),
38 			PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, base);
39 
40 	if(bmcreg == MAP_FAILED) {
41 		printf("ERROR: Unable to map LPC register memory");
42 		exit(1);
43 	}
44 	return bmcreg;
45 }
46 
47 void
48 reg_init()
49 {
50 	g_print("BMC init\n");
51 	// BMC init done here
52 
53 	void *bmcreg;
54 	int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
55 	if(mem_fd < 0) {
56 		printf("ERROR: Unable to open /dev/mem");
57 		exit(1);
58 	}
59 
60 	bmcreg = memmap(mem_fd,LPC_BASE);
61 	devmem(bmcreg+LPC_HICR6,0x00000500); //Enable LPC FWH cycles, Enable LPC to AHB bridge
62 	devmem(bmcreg+LPC_HICR7,0x30000E00); //32M PNOR
63 	devmem(bmcreg+LPC_HICR8,0xFE0001FF);
64 
65 	//flash controller
66 	bmcreg = memmap(mem_fd,SPI_BASE);
67 	devmem(bmcreg+0x00,0x00000003);
68 	devmem(bmcreg+0x04,0x00002404);
69 
70 	//UART
71 
72 	bmcreg = memmap(mem_fd,UART_BASE);
73 	devmem(bmcreg+0x00,0x00000000);  //Set Baud rate divisor -> 13 (Baud 115200)
74 	devmem(bmcreg+0x04,0x00000000);  //Set Baud rate divisor -> 13 (Baud 115200)
75 	devmem(bmcreg+0x08,0x000000c1);  //Disable Parity, 1 stop bit, 8 bits
76 	bmcreg = memmap(mem_fd,COM_BASE);
77 	devmem(bmcreg+0x9C,0x00000000);  //Set UART routing
78 
79 	bmcreg = memmap(mem_fd,SCU_BASE);
80 	devmem(bmcreg+0x00,0x13008CE7);
81 	devmem(bmcreg+0x04,0x0370E677);
82 	devmem(bmcreg+0x20,0xDF48F7FF);
83 	devmem(bmcreg+0x24,0xC738F202);
84 
85 
86 	//GPIO
87 	bmcreg = memmap(mem_fd,GPIO_BASE);
88 	devmem(bmcreg+0x84,0x00fff0c0);  //Enable UART1
89 	devmem(bmcreg+0x70,0x120CE406);
90 	devmem(bmcreg+0x80,0xCB000000);
91 	devmem(bmcreg+0x88,0x01C000FF);
92 	devmem(bmcreg+0x8c,0xC1C000FF);
93 	devmem(bmcreg+0x90,0x003FA009);
94 
95 	bmcreg = memmap(mem_fd,COM_BASE);
96 	devmem(bmcreg+0x170,0x00000042);
97 	devmem(bmcreg+0x174,0x00004000);
98 
99 
100 	close(mem_fd);
101 }
102 
103 static gboolean
104 on_init(Control *control,
105 		GDBusMethodInvocation *invocation,
106 		gpointer user_data)
107 {
108 	//#ifdef __arm__
109 	//reg_init();
110 	//#endif
111 	control_complete_init(control,invocation);
112 	//control_emit_goto_system_state(control,"BMC_STARTING");
113 	return TRUE;
114 }
115 
116 static gboolean
117 on_warm_reset(ControlBmc *bmc,
118 		GDBusMethodInvocation *invocation,
119 		gpointer user_data)
120 {
121 	GError *err = NULL;
122 	/* Wait a while before reboot, so the caller can be responded.
123 	 * Note that g_spawn_command_line_async() cannot parse ';' as
124 	 * a command separator. Need to use 'sh -c' to let shell parse it.
125 	 */
126 	gchar *reboot_command = "/bin/sh -c 'sleep 3;reboot'";
127 
128 	g_spawn_command_line_async(reboot_command, &err);
129 	if(err != NULL) {
130 		fprintf(stderr, "warmReset() error: %s\n", err->message);
131 		g_error_free(err);
132 	}
133 
134 	control_bmc_complete_warm_reset(bmc, invocation);
135 	return TRUE;
136 }
137 
138 gboolean
139 go(gpointer user_data)
140 {
141 	cmdline *cmd = user_data;
142 	Control* control = object_get_control((Object*)cmd->user_data);
143 #ifdef __arm__
144 	reg_init();
145 #endif
146 	control_emit_goto_system_state(control,"BMC_STARTING");
147 
148 	//g_main_loop_quit(cmd->loop);
149 	return FALSE;
150 }
151 
152 static void
153 on_bus_acquired(GDBusConnection *connection,
154 		const gchar *name,
155 		gpointer user_data)
156 {
157 	ObjectSkeleton *object;
158 	cmdline *cmd = user_data;
159 	manager = g_dbus_object_manager_server_new(dbus_object_path);
160 
161 	gchar *s;
162 	s = g_strdup_printf("%s/%s",dbus_object_path,instance_name);
163 	object = object_skeleton_new(s);
164 	g_free(s);
165 
166 	ControlBmc* control_bmc = control_bmc_skeleton_new();
167 	object_skeleton_set_control_bmc(object, control_bmc);
168 	g_object_unref(control_bmc);
169 
170 	Control* control = control_skeleton_new();
171 	object_skeleton_set_control(object, control);
172 	g_object_unref(control);
173 
174 	//define method callbacks here
175 	g_signal_connect(control,
176 			"handle-init",
177 			G_CALLBACK(on_init),
178 			NULL); /* user_data */
179 
180 
181 	g_signal_connect(control_bmc,
182 			"handle-warm-reset",
183 			G_CALLBACK(on_warm_reset),
184 			NULL); /* user_data */
185 
186 	/* Export the object (@manager takes its own reference to @object) */
187 	g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
188 	g_object_unref(object);
189 
190 	/* Export all objects */
191 	g_dbus_object_manager_server_set_connection(manager, connection);
192 
193 	//TODO:  This is a bad hack to wait for object to be on bus
194 	//sleep(1);
195 	cmd->user_data = object;
196 	//g_idle_add(go,cmd);
197 }
198 
199 static void
200 on_name_acquired(GDBusConnection *connection,
201 		const gchar *name,
202 		gpointer user_data)
203 {
204 }
205 
206 static void
207 on_name_lost(GDBusConnection *connection,
208 		const gchar *name,
209 		gpointer user_data)
210 {
211 }
212 
213 /*----------------------------------------------------------------*/
214 /* Main Event Loop                                                */
215 
216 gint
217 main(gint argc, gchar *argv[])
218 {
219 	GMainLoop *loop;
220 	cmdline cmd;
221 	cmd.argc = argc;
222 	cmd.argv = argv;
223 
224 	guint id;
225 	loop = g_main_loop_new(NULL, FALSE);
226 	cmd.loop = loop;
227 
228 	id = g_bus_own_name(DBUS_TYPE,
229 			dbus_name,
230 			G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
231 			G_BUS_NAME_OWNER_FLAGS_REPLACE,
232 			on_bus_acquired,
233 			on_name_acquired,
234 			on_name_lost,
235 			&cmd,
236 			NULL);
237 
238 	g_main_loop_run(loop);
239 
240 	g_bus_unown_name(id);
241 	g_main_loop_unref(loop);
242 	return 0;
243 }
244