diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-11-30 12:21:34 +1100 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2014-12-01 14:57:44 +1100 |
commit | 9594a715b50c338f1261e88c12c120cf8e5b8bba (patch) | |
tree | 5e5a07267866843ae9b0077122300bc3396ee2e5 | |
parent | 566f139cffdcef5d1ce679cc1a7cfd0c7cde3f78 (diff) | |
download | skiboot-9594a715b50c338f1261e88c12c120cf8e5b8bba.zip skiboot-9594a715b50c338f1261e88c12c120cf8e5b8bba.tar.gz skiboot-9594a715b50c338f1261e88c12c120cf8e5b8bba.tar.bz2 |
Add tweaks to work in Mambo simulator
Mambo doesn't implement various things such as PBA SCOMs, LPC,
ChipTOD, etc... It also provides a special console hook.
This adds detection of Mambo via the /mambo node, and enables
us to boot all the way to Linux.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r-- | asm/misc.S | 19 | ||||
-rw-r--r-- | core/chip.c | 5 | ||||
-rw-r--r-- | core/console.c | 66 | ||||
-rw-r--r-- | core/init.c | 4 | ||||
-rw-r--r-- | core/platform.c | 1 | ||||
-rw-r--r-- | hw/chiptod.c | 11 | ||||
-rw-r--r-- | hw/homer.c | 2 | ||||
-rw-r--r-- | hw/occ.c | 3 | ||||
-rw-r--r-- | hw/slw.c | 6 | ||||
-rw-r--r-- | hw/xscom.c | 10 | ||||
-rw-r--r-- | include/chip.h | 3 | ||||
-rw-r--r-- | include/config.h | 6 | ||||
-rw-r--r-- | include/console.h | 5 |
13 files changed, 123 insertions, 18 deletions
@@ -50,3 +50,22 @@ _mcount: mflr %r4 b __mcount_stack_check #endif + +.global mambo_read +mambo_read: +#define SIM_READ_CONSOLE_CODE 60 + li %r3,SIM_READ_CONSOLE_CODE + .long 0x000eaeb0 + extsw %r3,%r3 + blr + +.global mambo_write +mambo_write: +#define SIM_WRITE_CONSOLE_CODE 0 + li %r6,0 + mr %r5,%r4 + mr %r4,%r3 + li %r3,SIM_WRITE_CONSOLE_CODE + .long 0x000eaeb0 + blr + diff --git a/core/chip.c b/core/chip.c index 272f024..b805fe1 100644 --- a/core/chip.c +++ b/core/chip.c @@ -20,6 +20,7 @@ #include <device.h> static struct proc_chip *chips[MAX_CHIPS]; +bool is_mambo_chip; uint32_t pir_to_chip_id(uint32_t pir) { @@ -66,6 +67,10 @@ void init_chips(void) struct proc_chip *chip; struct dt_node *xn; + /* Detect mambo chip */ + if (dt_find_by_path(dt_root, "/mambo")) + is_mambo_chip = true; + /* We walk the chips based on xscom nodes in the tree */ dt_for_each_compatible(dt_root, xn, "ibm,xscom") { uint32_t id = dt_get_chip_id(xn); diff --git a/core/console.c b/core/console.c index 111d64f..d24a4b4 100644 --- a/core/console.c +++ b/core/console.c @@ -59,20 +59,47 @@ void force_dummy_console(void) dt_add_property(dt_chosen, "sapphire,enable-dummy-console", NULL, 0); } -#ifdef MAMBO_CONSOLE -static void mambo_write(const char *buf, size_t count) + +static int mambo_char = -1; + +static bool mambo_con_poll_read(void) { -#define SIM_WRITE_CONSOLE_CODE 0 - register int c asm("r3") = 0; /* SIM_WRITE_CONSOLE_CODE */ - register unsigned long a1 asm("r4") = (unsigned long)buf; - register unsigned long a2 asm("r5") = count; - register unsigned long a3 asm("r6") = 0; - asm volatile (".long 0x000eaeb0":"=r" (c):"r"(c), "r"(a1), "r"(a2), - "r"(a3)); + if (mambo_char < 0) + mambo_char = mambo_read(); + return mambo_char >= 0; +} + +static size_t mambo_con_read(char *buf, size_t len) +{ + size_t count = 0; + + while(count < len) { + if (!mambo_con_poll_read()) + break; + *(buf++) = mambo_char; + mambo_char = -1; + count++; + } + return count; +} + +static size_t mambo_con_write(const char *buf, size_t len) +{ + mambo_write(buf, len); + return len; +} + +static struct con_ops mambo_con_driver = { + .poll_read = mambo_con_poll_read, + .read = mambo_con_read, + .write = mambo_con_write, +}; + +void enable_mambo_console(void) +{ + prlog(PR_NOTICE, "Enabling Mambo console\n"); + set_console(&mambo_con_driver); } -#else -static void mambo_write(const char *buf __unused, size_t count __unused) { } -#endif /* MAMBO_CONSOLE */ void clear_console(void) { @@ -213,7 +240,9 @@ static size_t inmem_read(char *buf, size_t req) static void write_char(char c) { +#ifdef MAMBO_DEBUG_CONSOLE mambo_write(&c, 1); +#endif inmem_write(c); } @@ -306,6 +335,7 @@ static int64_t dummy_console_read(int64_t term_number, int64_t *length, if (term_number != 0) return OPAL_PARAMETER; *length = read(0, buffer, *length); + opal_update_pending_evt(OPAL_EVENT_CONSOLE_INPUT, 0); return OPAL_SUCCESS; } @@ -313,8 +343,14 @@ opal_call(OPAL_CONSOLE_READ, dummy_console_read, 3); static void dummy_console_poll(void *data __unused) { + bool has_data = false; + lock(&con_lock); + if (con_driver && con_driver->poll_read) + has_data = con_driver->poll_read; if (memcons.in_prod != memcons.in_cons) + has_data = true; + if (has_data) opal_update_pending_evt(OPAL_EVENT_CONSOLE_INPUT, OPAL_EVENT_CONSOLE_INPUT); else @@ -325,6 +361,7 @@ static void dummy_console_poll(void *data __unused) void dummy_console_add_nodes(void) { struct dt_node *con, *consoles; + struct dt_property *p; consoles = dt_new(opal_node, "consoles"); assert(consoles); @@ -338,6 +375,11 @@ void dummy_console_add_nodes(void) dt_add_property_cells(con, "reg", 0); dt_add_property_string(con, "device_type", "serial"); + /* Mambo might have left a crap one, clear it */ + p = __dt_find_property(dt_chosen, "linux,stdout-path"); + if (p) + dt_del_property(dt_chosen, p); + dt_add_property_string(dt_chosen, "linux,stdout-path", "/ibm,opal/consoles/serial@0"); diff --git a/core/init.c b/core/init.c index d8e9d20..6eeaa0d 100644 --- a/core/init.c +++ b/core/init.c @@ -293,7 +293,7 @@ static bool load_kernel(void) } if (!ksize) - printf("Assuming kernel at 0x%p\n", KERNEL_LOAD_BASE); + printf("Assuming kernel at %p\n", KERNEL_LOAD_BASE); printf("INIT: Kernel loaded, size: %zu bytes (0 = unknown preload)\n", ksize); @@ -537,6 +537,8 @@ void __noreturn main_cpu_entry(const void *fdt, u32 master_cpu) * to access chips via that path early on. */ init_chips(); + if (is_mambo_chip) + enable_mambo_console(); xscom_init(); mfsi_init(); diff --git a/core/platform.c b/core/platform.c index 1b0093d..53971e9 100644 --- a/core/platform.c +++ b/core/platform.c @@ -50,6 +50,7 @@ opal_call(OPAL_CEC_REBOOT, opal_cec_reboot, 0); static void generic_platform_init(void) { + force_dummy_console(); fake_rtc_init(); } diff --git a/hw/chiptod.c b/hw/chiptod.c index 865ff82..daa67ef 100644 --- a/hw/chiptod.c +++ b/hw/chiptod.c @@ -19,6 +19,7 @@ */ #include <skiboot.h> #include <chiptod.h> +#include <chip.h> #include <xscom.h> #include <io.h> #include <cpu.h> @@ -528,6 +529,9 @@ static void chiptod_sync_slave(void *data) bool chiptod_wakeup_resync(void) { + if (chiptod_primary < 0) + return 0; + lock(&chiptod_lock); /* Apply base tfmr */ @@ -634,6 +638,9 @@ int chiptod_recover_tb_errors(void) uint64_t tfmr; int rc = 1; + if (chiptod_primary < 0) + return 0; + lock(&chiptod_lock); /* Get fresh copy of TFMR */ @@ -774,6 +781,10 @@ void chiptod_init(u32 master_cpu) struct cpu_thread *cpu0, *cpu; bool sres; + /* Mambo doesn't simulate the chiptod */ + if (is_mambo_chip) + return; + op_display(OP_LOG, OP_MOD_CHIPTOD, 0); if (!chiptod_probe(master_cpu)) { @@ -111,7 +111,7 @@ void homer_init(void) { struct proc_chip *chip; - if (proc_gen != proc_gen_p8) + if (proc_gen != proc_gen_p8 || is_mambo_chip) return; /* @@ -510,6 +510,9 @@ static struct fsp_client fsp_occ_client = { void occ_send_dummy_interrupt(void) { + /* Mambo chip doesn't do this */ + if (is_mambo_chip) + return; xscom_writeme(OCB_OCI_OCCMISC_OR, OCB_OCI_OCIMISC_IRQ | OCB_OCI_OCIMISC_IRQ_OPAL_DUMMY); @@ -513,6 +513,12 @@ static void add_cpu_idle_state_properties(void) return; } + /* Mambo currently misbehaves in nap mode vs. timebase, so let's + * disable idle states + */ + if (is_mambo_chip) + return; + /* * Chose the right state table for the chip * @@ -435,9 +435,15 @@ int xscom_writeme(uint64_t pcb_addr, uint64_t val) static void xscom_init_chip_info(struct proc_chip *chip) { uint64_t val; - int64_t rc; + int64_t rc = 0; - rc = xscom_read(chip->id, 0xf000f, &val); + /* Mambo chip model lacks the f000f register, just make + * something up (Murano DD2.1) + */ + if (is_mambo_chip) + val = 0x221EF04980000000; + else + rc = xscom_read(chip->id, 0xf000f, &val); if (rc) { prerror("XSCOM: Error %lld reading 0xf000f register\n", rc); /* We leave chip type to UNKNOWN */ diff --git a/include/chip.h b/include/chip.h index fb2771e..83671fa 100644 --- a/include/chip.h +++ b/include/chip.h @@ -139,6 +139,9 @@ struct proc_chip { struct list_head i2cms; }; +/* Mambo simplified chip model lacks some features, handle it here */ +extern bool is_mambo_chip; + extern uint32_t pir_to_chip_id(uint32_t pir); extern uint32_t pir_to_core_id(uint32_t pir); extern uint32_t pir_to_thread_id(uint32_t pir); diff --git a/include/config.h b/include/config.h index 78b63fe..2524570 100644 --- a/include/config.h +++ b/include/config.h @@ -52,8 +52,10 @@ //#define OPAL_DEBUG_CONSOLE_IO 1 //#define OPAL_DEBUG_CONSOLE_POLL 1 -/* Enable this for mambo console */ -//#define MAMBO_CONSOLE 1 +/* Enable this to force all writes to the in-memory console to + * be mirrored on the mambo console + */ +//#define MAMBO_DEBUG_CONSOLE 1 /* Enable this to hookup SkiBoot log to the DVS console */ #define DVS_CONSOLE 1 diff --git a/include/console.h b/include/console.h index bbe2444..5b6c5d5 100644 --- a/include/console.h +++ b/include/console.h @@ -50,6 +50,7 @@ extern struct memcons memcons; struct con_ops { size_t (*write)(const char *buf, size_t len); size_t (*read)(char *buf, size_t len); + bool (*poll_read)(void); }; extern struct lock con_lock; @@ -60,6 +61,10 @@ extern bool flush_console(void); extern bool __flush_console(bool flush_to_drivers); extern void set_console(struct con_ops *driver); +extern int mambo_read(void); +extern void mambo_write(const char *buf, size_t count); +extern void enable_mambo_console(void); + ssize_t console_write(bool flush_to_drivers, const void *buf, size_t count); extern void clear_console(void); |