| #include <stdint.h>
|
| #include <stdio.h>
|
| #include <stdlib.h>
|
| #include <string.h>
|
| #include <fcntl.h>
|
| #include <unistd.h>
|
| #include <sys/stat.h>
|
| #include <sys/mman.h>
|
| #include "interfaces/openbmc_intf.h"
|
| #include "openbmc.h"
|
| #include "gpio.h"
|
|
|
| /* ---------------------------------------------------------------------------------------------------- */
|
| static const gchar* dbus_object_path = "/org/openbmc/control";
|
| static const gchar* instance_name = "bmc0";
|
| static const gchar* dbus_name = "org.openbmc.control.Bmc";
|
|
|
| //this probably should come from some global SOC config
|
|
|
| #define LPC_BASE (off_t)0x1e789000
|
| #define LPC_HICR6 0x80
|
| #define LPC_HICR7 0x88
|
| #define LPC_HICR8 0x8c
|
| #define SPI_BASE (off_t)0x1e630000
|
| #define SCU_BASE (off_t)0x1e780000
|
| #define UART_BASE (off_t)0x1e783000
|
| #define COM_BASE (off_t)0x1e789000
|
| #define COM_BASE2 (off_t)0x1e789100
|
| #define GPIO_BASE (off_t)0x1e6e2000
|
|
|
| static GDBusObjectManagerServer *manager = NULL;
|
|
|
| void* memmap(int mem_fd,off_t base)
|
| {
|
| void* bmcreg;
|
| bmcreg = mmap(NULL, getpagesize(),
|
| PROT_READ | PROT_WRITE, MAP_SHARED, mem_fd, base);
|
|
|
| if (bmcreg == MAP_FAILED) {
|
| printf("ERROR: Unable to map LPC register memory");
|
| exit(1);
|
| }
|
| return bmcreg;
|
| }
|
|
|
| void reg_init()
|
| {
|
| g_print("BMC init\n");
|
| // BMC init done here
|
|
|
| void *bmcreg;
|
| int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
| if (mem_fd < 0) {
|
| printf("ERROR: Unable to open /dev/mem");
|
| exit(1);
|
| }
|
|
|
| bmcreg = memmap(mem_fd,LPC_BASE);
|
| devmem(bmcreg+LPC_HICR6,0x00000500); //Enable LPC FWH cycles, Enable LPC to AHB bridge
|
| devmem(bmcreg+LPC_HICR7,0x30000E00); //32M PNOR
|
| devmem(bmcreg+LPC_HICR8,0xFE0001FF);
|
|
|
| //flash controller
|
| bmcreg = memmap(mem_fd,SPI_BASE);
|
| devmem(bmcreg+0x00,0x00000003);
|
| devmem(bmcreg+0x04,0x00002404);
|
|
|
| //UART
|
|
|
| bmcreg = memmap(mem_fd,UART_BASE);
|
| devmem(bmcreg+0x00,0x00000000); //Set Baud rate divisor -> 13 (Baud 115200)
|
| devmem(bmcreg+0x04,0x00000000); //Set Baud rate divisor -> 13 (Baud 115200)
|
| devmem(bmcreg+0x08,0x000000c1); //Disable Parity, 1 stop bit, 8 bits
|
| bmcreg = memmap(mem_fd,COM_BASE);
|
| devmem(bmcreg+0x9C,0x00000000); //Set UART routing
|
|
|
| bmcreg = memmap(mem_fd,SCU_BASE);
|
| devmem(bmcreg+0x00,0x13008CE7);
|
| devmem(bmcreg+0x04,0x0370E677);
|
| devmem(bmcreg+0x20,0xDF48F7FF);
|
| devmem(bmcreg+0x24,0xC738F202);
|
|
|
|
|
| //GPIO
|
| bmcreg = memmap(mem_fd,GPIO_BASE);
|
| devmem(bmcreg+0x84,0x00fff0c0); //Enable UART1
|
| devmem(bmcreg+0x70,0x120CE406);
|
| devmem(bmcreg+0x80,0xCB000000);
|
| devmem(bmcreg+0x88,0x01C000FF);
|
| devmem(bmcreg+0x8c,0xC1C000FF);
|
| devmem(bmcreg+0x90,0x003FA009);
|
|
|
| bmcreg = memmap(mem_fd,COM_BASE);
|
| devmem(bmcreg+0x170,0x00000042);
|
| devmem(bmcreg+0x174,0x00004000);
|
|
|
|
|
| close(mem_fd);
|
| }
|
|
|
| static gboolean
|
| on_init (Control *control,
|
| GDBusMethodInvocation *invocation,
|
| gpointer user_data)
|
| {
|
| //#ifdef __arm__
|
| //reg_init();
|
| //#endif
|
| control_complete_init(control,invocation);
|
| //control_emit_goto_system_state(control,"BMC_STARTING");
|
| return TRUE;
|
| }
|
| |
| static gboolean |
| on_warm_reset (ControlBmc *bmc, |
| GDBusMethodInvocation *invocation, |
| gpointer user_data) |
| { |
| GError *err = NULL; |
| /* Wait a while before reboot, so the caller can be responded. |
| * Note that g_spawn_command_line_async() cannot parse ';' as |
| * a command separator. Need to use 'sh -c' to let shell parse it. |
| */ |
| gchar *reboot_command = "/bin/sh -c 'sleep 3;reboot'"; |
| |
| g_spawn_command_line_async(reboot_command, &err); |
| if (err != NULL) { |
| fprintf(stderr, "warmReset() error: %s\n", err->message); |
| g_error_free(err); |
| } |
| |
| control_bmc_complete_warm_reset(bmc, invocation); |
| return TRUE; |
| } |
| |
| gboolean go(gpointer user_data)
|
| {
|
| cmdline *cmd = user_data;
|
| Control* control = object_get_control((Object*)cmd->user_data);
|
| #ifdef __arm__
|
| reg_init();
|
| #endif
|
| control_emit_goto_system_state(control,"BMC_STARTING");
|
|
|
| //g_main_loop_quit(cmd->loop);
|
| return FALSE;
|
| }
|
| |
| static void |
| on_bus_acquired (GDBusConnection *connection,
|
| const gchar *name,
|
| gpointer user_data)
|
| {
|
| ObjectSkeleton *object;
|
| cmdline *cmd = user_data;
|
| manager = g_dbus_object_manager_server_new (dbus_object_path);
|
|
|
| gchar *s;
|
| s = g_strdup_printf ("%s/%s",dbus_object_path,instance_name);
|
| object = object_skeleton_new (s);
|
| g_free (s);
|
|
|
| ControlBmc* control_bmc = control_bmc_skeleton_new ();
|
| object_skeleton_set_control_bmc (object, control_bmc);
|
| g_object_unref (control_bmc);
|
|
|
| Control* control = control_skeleton_new ();
|
| object_skeleton_set_control (object, control);
|
| g_object_unref (control);
|
|
|
| //define method callbacks here
|
| g_signal_connect (control,
|
| "handle-init",
|
| G_CALLBACK (on_init),
|
| NULL); /* user_data */
|
|
|
| |
| g_signal_connect (control_bmc, |
| "handle-warm-reset", |
| G_CALLBACK (on_warm_reset), |
| NULL); /* user_data */ |
| |
| /* Export the object (@manager takes its own reference to @object) */
|
| g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (object));
|
| g_object_unref (object);
|
|
|
| /* Export all objects */
|
| g_dbus_object_manager_server_set_connection (manager, connection);
|
|
|
| //TODO: This is a bad hack to wait for object to be on bus
|
| //sleep(1);
|
| cmd->user_data = object;
|
| //g_idle_add(go,cmd);
|
| }
|
|
|
|
|
| static void
|
| on_name_acquired (GDBusConnection *connection,
|
| const gchar *name,
|
| gpointer user_data)
|
| {
|
|
|
|
|
| }
|
|
|
| static void
|
| on_name_lost (GDBusConnection *connection,
|
| const gchar *name,
|
| gpointer user_data)
|
| {
|
| }
|
|
|
|
|
| /*----------------------------------------------------------------*/
|
| /* Main Event Loop */
|
|
|
| gint
|
| main (gint argc, gchar *argv[])
|
| {
|
| GMainLoop *loop;
|
| cmdline cmd;
|
| cmd.argc = argc;
|
| cmd.argv = argv;
|
|
|
| guint id;
|
| loop = g_main_loop_new (NULL, FALSE);
|
| cmd.loop = loop;
|
|
|
| id = g_bus_own_name (DBUS_TYPE,
|
| dbus_name,
|
| G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT |
|
| G_BUS_NAME_OWNER_FLAGS_REPLACE,
|
| on_bus_acquired,
|
| on_name_acquired,
|
| on_name_lost,
|
| &cmd,
|
| NULL);
|
|
|
| g_main_loop_run (loop);
|
| |
| g_bus_unown_name (id);
|
| g_main_loop_unref (loop);
|
| return 0;
|
| }
|