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