blob: f09e3799f212ae4e9d05e25a82ae72d5b6975ff5 [file] [log] [blame]
Brad Bishop77390492016-04-13 10:47:19 -04001#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/* ------------------------------------------------------------------------- */
14static const gchar* dbus_object_path = "/org/openbmc/control";
15static const gchar* instance_name = "bmc0";
16static const gchar* dbus_name = "org.openbmc.control.Bmc";
17static const gchar* i2c_dev = "/sys/bus/i2c/devices";
18
19//this probably should come from some global SOC config
20
21#define LPC_BASE (off_t)0x1e789000
22#define LPC_HICR6 0x80
23#define LPC_HICR7 0x88
24#define LPC_HICR8 0x8c
25#define SPI_BASE (off_t)0x1e630000
26#define SCU_BASE (off_t)0x1e780000
27#define UART_BASE (off_t)0x1e783000
28#define COM_BASE (off_t)0x1e789000
29#define COM_BASE2 (off_t)0x1e789100
30#define GPIO_BASE (off_t)0x1e6e2000
31
32static GDBusObjectManagerServer *manager = NULL;
33
34void*
35memmap(int mem_fd,off_t base)
36{
37 void* bmcreg;
38 bmcreg = mmap(NULL, getpagesize(),
39 PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, base);
40
41 if(bmcreg == MAP_FAILED) {
42 printf("ERROR: Unable to map LPC register memory");
43 exit(1);
44 }
45 return bmcreg;
46}
47
48void
49reg_init()
50{
51 g_print("BMC init\n");
52 // BMC init done here
53
54 void *bmcreg;
55 int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
56 if(mem_fd < 0) {
57 printf("ERROR: Unable to open /dev/mem");
58 exit(1);
59 }
60
61 bmcreg = memmap(mem_fd,LPC_BASE);
62 devmem(bmcreg+LPC_HICR6,0x00000500); //Enable LPC FWH cycles, Enable LPC to AHB bridge
63 devmem(bmcreg+LPC_HICR7,0x30000C00); //32M PNOR
64 devmem(bmcreg+LPC_HICR8,0xFC0003FF);
65
66 //flash controller
67 bmcreg = memmap(mem_fd,SPI_BASE);
68 devmem(bmcreg+0x00,0x00000003);
69 devmem(bmcreg+0x04,0x00002404);
70
71 //UART
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,0x9e82fce7);
81 //devmem(bmcreg+0x00,0x9f82fce7); // B2?
82 devmem(bmcreg+0x04,0x0370e677);
83
84 // do not modify state of power pin, otherwise
85 // if this is a reboot, host will shutdown
86 uint32_t reg_20 = devmem_read(bmcreg+0x20);
87 reg_20 = reg_20 & 0x00000002;
88 devmem(bmcreg+0x20,0xcfc8f7fd | reg_20);
89 devmem(bmcreg+0x24,0xc738f20a);
90 devmem(bmcreg+0x80,0x0031ffaf);
91
92
93 //GPIO
94 bmcreg = memmap(mem_fd,GPIO_BASE);
95 devmem(bmcreg+0x84,0x00fff0c0); //Enable UART1
96 devmem(bmcreg+0x80,0xCB000000);
97 devmem(bmcreg+0x88,0x01C000FF);
98 devmem(bmcreg+0x8c,0xC1C000FF);
99 devmem(bmcreg+0x90,0x003FA009);
100 devmem(bmcreg+0x88,0x01C0007F);
101
102
103 bmcreg = memmap(mem_fd,COM_BASE);
104 devmem(bmcreg+0x170,0x00000042);
105 devmem(bmcreg+0x174,0x00004000);
106
107 close(mem_fd);
108}
109
110int
111init_i2c_driver(int i2c_bus, const char* device, int address,bool delete)
112{
113 char dev[255];
114 g_print("Initing: device = %s, address = %02x\n",device,address);
115 if(!delete) {
116 sprintf(dev,"%s/i2c-%d/new_device",i2c_dev,i2c_bus);
117 } else {
118 sprintf(dev,"%s/i2c-%d/delete_device",i2c_dev,i2c_bus);
119 }
120 int fd = open(dev, O_WRONLY);
121 if(fd == -1) {
122 g_print("ERROR control_bmc: Unable to open device %s\n",dev);
123 return 1;
124 }
125 if(!delete) {
126 sprintf(dev,"%s 0x%02x",device,address);
127 } else {
128 sprintf(dev,"0x%02x",address);
129 }
130 int rc = write(fd,dev,strlen(dev));
131 close(fd);
132 if(rc != strlen(dev)) {
133 g_print("ERROR control_bmc: Unable to write %s\n",dev);
134 return 2;
135 }
136 return 0;
137}
138
139static gboolean
140on_init(Control *control,
141 GDBusMethodInvocation *invocation,
142 gpointer user_data)
143{
144 control_complete_init(control,invocation);
145
146 return TRUE;
147}
148
149gboolean
150go(gpointer user_data)
151{
152 cmdline *cmd = user_data;
153 Control* control = object_get_control((Object*)cmd->user_data);
154#ifdef __arm__
155 reg_init();
156#endif
157 control_emit_goto_system_state(control,"BMC_STARTING");
158
159 return FALSE;
160}
161
162static void
163on_bus_acquired(GDBusConnection *connection,
164 const gchar *name,
165 gpointer user_data)
166{
167 ObjectSkeleton *object;
168 cmdline *cmd = user_data;
169 manager = g_dbus_object_manager_server_new(dbus_object_path);
170
171 gchar *s;
172 s = g_strdup_printf("%s/%s",dbus_object_path,instance_name);
173 object = object_skeleton_new(s);
174 g_free(s);
175
176 ControlBmc* control_bmc = control_bmc_skeleton_new();
177 object_skeleton_set_control_bmc(object, control_bmc);
178 g_object_unref(control_bmc);
179
180 Control* control = control_skeleton_new();
181 object_skeleton_set_control(object, control);
182 g_object_unref(control);
183
184 //define method callbacks here
185 g_signal_connect(control,
186 "handle-init",
187 G_CALLBACK(on_init),
188 NULL); /* user_data */
189
190 /* Export the object (@manager takes its own reference to @object) */
191 g_dbus_object_manager_server_export(manager, G_DBUS_OBJECT_SKELETON(object));
192 g_object_unref(object);
193
194 /* Export all objects */
195 g_dbus_object_manager_server_set_connection(manager, connection);
196
197 //TODO: This is a bad hack to wait for object to be on bus
198 //sleep(1);
199 cmd->user_data = object;
200 g_idle_add(go,cmd);
201}
202
203static void
204on_name_acquired(GDBusConnection *connection,
205 const gchar *name,
206 gpointer user_data)
207{
208}
209
210static void
211on_name_lost(GDBusConnection *connection,
212 const gchar *name,
213 gpointer user_data)
214{
215}
216
217/*----------------------------------------------------------------*/
218/* Main Event Loop */
219
220gint
221main(gint argc, gchar *argv[])
222{
223 GMainLoop *loop;
224 cmdline cmd;
225 cmd.argc = argc;
226 cmd.argv = argv;
227
228 guint id;
229 loop = g_main_loop_new(NULL, FALSE);
230 cmd.loop = loop;
231
232 id = g_bus_own_name(DBUS_TYPE,
233 dbus_name,
234 G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
235 G_BUS_NAME_OWNER_FLAGS_REPLACE,
236 on_bus_acquired,
237 on_name_acquired,
238 on_name_lost,
239 &cmd,
240 NULL);
241
242 g_main_loop_run(loop);
243
244 g_bus_unown_name(id);
245 g_main_loop_unref(loop);
246 return 0;
247}