aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-11-30 12:21:34 +1100
committerStewart Smith <stewart@linux.vnet.ibm.com>2014-12-01 14:57:44 +1100
commit9594a715b50c338f1261e88c12c120cf8e5b8bba (patch)
tree5e5a07267866843ae9b0077122300bc3396ee2e5
parent566f139cffdcef5d1ce679cc1a7cfd0c7cde3f78 (diff)
downloadskiboot-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.S19
-rw-r--r--core/chip.c5
-rw-r--r--core/console.c66
-rw-r--r--core/init.c4
-rw-r--r--core/platform.c1
-rw-r--r--hw/chiptod.c11
-rw-r--r--hw/homer.c2
-rw-r--r--hw/occ.c3
-rw-r--r--hw/slw.c6
-rw-r--r--hw/xscom.c10
-rw-r--r--include/chip.h3
-rw-r--r--include/config.h6
-rw-r--r--include/console.h5
13 files changed, 123 insertions, 18 deletions
diff --git a/asm/misc.S b/asm/misc.S
index 00c7f78..bbabebc 100644
--- a/asm/misc.S
+++ b/asm/misc.S
@@ -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)) {
diff --git a/hw/homer.c b/hw/homer.c
index b8e51c5..6145e25 100644
--- a/hw/homer.c
+++ b/hw/homer.c
@@ -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;
/*
diff --git a/hw/occ.c b/hw/occ.c
index 5b3c3a6..e1eaf30 100644
--- a/hw/occ.c
+++ b/hw/occ.c
@@ -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);
diff --git a/hw/slw.c b/hw/slw.c
index 68228a9..b72a0aa 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -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
*
diff --git a/hw/xscom.c b/hw/xscom.c
index 98cbaec..1698135 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -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);