blob: a682da02af69cab3ca1727d44930fe4f75747275 [file] [log] [blame]
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -05001From 04f36ee342ad739e3c3991480f5c5df0d6aeed0e Mon Sep 17 00:00:00 2001
Joel Stanley2b0f7b42016-07-19 23:26:28 +09302From: Oliver O'Halloran <oohall@gmail.com>
3Date: Fri, 24 Jun 2016 17:28:43 +1000
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -05004Subject: [PATCH 06/10] powerpc/boot: Add OPAL console to epapr wrappers
Joel Stanley2b0f7b42016-07-19 23:26:28 +09305
6This patch adds an OPAL console backend to the powerpc boot wrapper so
7that decompression failures inside the wrapper can be reported to the
8user. This is important since it typically indicates data corruption in
9the firmware and other nasty things.
10
11Currently this only works when building a little endian kernel. When
12compiling a 64 bit BE kernel the wrapper is always build 32 bit to be
13compatible with some 32 bit firmwares. BE support will be added at a
14later date. Another limitation of this is that only the "raw" type of
15OPAL console is supported, however machines that provide a hvsi console
16also provide a raw console so this is not an issue in practice.
17
18Actually-written-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
19Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
20Cc: Stewart Smith <stewart@linux.vnet.ibm.com>
21Signed-off-by: Joel Stanley <joel@jms.id.au>
Samuel Mendoza-Jonas7d8f5b92017-10-17 14:16:45 +110022Signed-off-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Joel Stanley2b0f7b42016-07-19 23:26:28 +093023---
24 arch/powerpc/boot/Makefile | 4 +-
25 arch/powerpc/boot/opal-calls.S | 58 +++++++++++++++++++++++++
26 arch/powerpc/boot/opal.c | 97 ++++++++++++++++++++++++++++++++++++++++++
27 arch/powerpc/boot/ops.h | 1 +
28 arch/powerpc/boot/ppc_asm.h | 4 ++
29 arch/powerpc/boot/serial.c | 2 +
30 arch/powerpc/boot/types.h | 10 +++++
31 7 files changed, 174 insertions(+), 2 deletions(-)
32 create mode 100644 arch/powerpc/boot/opal-calls.S
33 create mode 100644 arch/powerpc/boot/opal.c
34
35diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -050036index 57003d1..31eac62 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +093037--- a/arch/powerpc/boot/Makefile
38+++ b/arch/powerpc/boot/Makefile
39@@ -70,7 +70,7 @@ $(addprefix $(obj)/,$(zlib) cuboot-c2k.o gunzip_util.o main.o): \
40 libfdt := fdt.c fdt_ro.c fdt_wip.c fdt_sw.c fdt_rw.c fdt_strerror.c
41 libfdtheader := fdt.h libfdt.h libfdt_internal.h
42
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -050043-$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o \
44+$(addprefix $(obj)/,$(libfdt) libfdt-wrapper.o simpleboot.o epapr.o opal.o \
45 treeboot-akebono.o treeboot-currituck.o treeboot-iss4xx.o): \
Joel Stanley2b0f7b42016-07-19 23:26:28 +093046 $(addprefix $(obj)/,$(libfdtheader))
47
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -050048@@ -79,7 +79,7 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \
Joel Stanley2b0f7b42016-07-19 23:26:28 +093049 ns16550.c serial.c simple_alloc.c div64.S util.S \
50 gunzip_util.c elf_util.c $(zlib) devtree.c stdlib.c \
51 oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \
52- uartlite.c mpc52xx-psc.c
53+ uartlite.c mpc52xx-psc.c opal.c opal-calls.S
54 src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
55 src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
56 src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
57diff --git a/arch/powerpc/boot/opal-calls.S b/arch/powerpc/boot/opal-calls.S
58new file mode 100644
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -050059index 00000000..ff2f1b9
Joel Stanley2b0f7b42016-07-19 23:26:28 +093060--- /dev/null
61+++ b/arch/powerpc/boot/opal-calls.S
62@@ -0,0 +1,58 @@
63+/*
64+ * Copyright (c) 2016 IBM Corporation.
65+ *
66+ * This program is free software; you can redistribute it and/or
67+ * modify it under the terms of the GNU General Public License
68+ * as published by the Free Software Foundation; either version
69+ * 2 of the License, or (at your option) any later version.
70+ */
71+
72+#include "ppc_asm.h"
73+#include "../include/asm/opal-api.h"
74+
75+ .text
76+
77+#define OPAL_CALL(name, token) \
78+ .globl name; \
79+name: \
80+ li r0, token; \
81+ b opal_call;
82+
83+opal_call:
84+ mflr r11
85+ std r11,16(r1)
86+ mfcr r12
87+ stw r12,8(r1)
88+ mr r13,r2
89+
90+ /* Set opal return address */
91+ ld r11,opal_return@got(r2)
92+ mtlr r11
93+ mfmsr r12
94+
95+ /* switch to BE when we enter OPAL */
96+ li r11,MSR_LE
97+ andc r12,r12,r11
98+ mtspr SPRN_HSRR1,r12
99+
100+ /* load the opal call entry point and base */
101+ ld r11,opal@got(r2)
102+ ld r12,8(r11)
103+ ld r2,0(r11)
104+ mtspr SPRN_HSRR0,r12
105+ hrfid
106+
107+opal_return:
108+ FIXUP_ENDIAN
109+ mr r2,r13;
110+ lwz r11,8(r1);
111+ ld r12,16(r1)
112+ mtcr r11;
113+ mtlr r12
114+ blr
115+
116+OPAL_CALL(opal_console_write, OPAL_CONSOLE_WRITE);
117+OPAL_CALL(opal_console_read, OPAL_CONSOLE_READ);
118+OPAL_CALL(opal_console_write_buffer_space, OPAL_CONSOLE_WRITE_BUFFER_SPACE);
119+OPAL_CALL(opal_poll_events, OPAL_POLL_EVENTS);
120+OPAL_CALL(opal_console_flush, OPAL_CONSOLE_FLUSH);
121diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
122new file mode 100644
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500123index 00000000..3a2ce1e
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930124--- /dev/null
125+++ b/arch/powerpc/boot/opal.c
126@@ -0,0 +1,97 @@
127+/*
128+ * Copyright (c) 2016 IBM Corporation.
129+ *
130+ * This program is free software; you can redistribute it and/or
131+ * modify it under the terms of the GNU General Public License
132+ * as published by the Free Software Foundation; either version
133+ * 2 of the License, or (at your option) any later version.
134+ */
135+
136+#include "ops.h"
137+#include "stdio.h"
138+#include "io.h"
139+#include <libfdt.h>
140+#include "../include/asm/opal-api.h"
141+
142+/* Global OPAL struct used by opal-call.S */
143+struct opal {
144+ u64 base;
145+ u64 entry;
146+} opal;
147+
148+static u32 opal_con_id;
149+
150+int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer);
151+int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer);
152+int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length);
153+int64_t opal_console_flush(uint64_t term_number);
154+int64_t opal_poll_events(uint64_t *outstanding_event_mask);
155+
156+static int opal_con_open(void)
157+{
158+ return 0;
159+}
160+
161+static void opal_con_putc(unsigned char c)
162+{
163+ int64_t rc;
164+ uint64_t olen, len;
165+
166+ do {
167+ rc = opal_console_write_buffer_space(opal_con_id, &olen);
168+ len = be64_to_cpu(olen);
169+ if (rc)
170+ return;
171+ opal_poll_events(NULL);
172+ } while (len < 1);
173+
174+
175+ olen = cpu_to_be64(1);
176+ opal_console_write(opal_con_id, &olen, &c);
177+}
178+
179+static void opal_con_close(void)
180+{
181+ opal_console_flush(opal_con_id);
182+}
183+
184+static void opal_init(void)
185+{
186+ void *opal_node;
187+
188+ opal_node = finddevice("/ibm,opal");
189+ if (!opal_node)
190+ return;
191+ if (getprop(opal_node, "opal-base-address", &opal.base, sizeof(u64)) < 0)
192+ return;
193+ opal.base = be64_to_cpu(opal.base);
194+ if (getprop(opal_node, "opal-entry-address", &opal.entry, sizeof(u64)) < 0)
195+ return;
196+ opal.entry = be64_to_cpu(opal.entry);
197+}
198+
199+#ifdef __powerpc64__
200+int opal_console_init(void *devp, struct serial_console_data *scdp)
201+{
202+ opal_init();
203+
204+ if (devp) {
205+ int n = getprop(devp, "reg", &opal_con_id, sizeof(u32));
206+ if (n != sizeof(u32))
207+ return -1;
208+ opal_con_id = be32_to_cpu(opal_con_id);
209+ } else
210+ opal_con_id = 0;
211+
212+ scdp->open = opal_con_open;
213+ scdp->putc = opal_con_putc;
214+ scdp->close = opal_con_close;
215+
216+ return 0;
217+}
218+#else
219+int opal_console_init(void *devp, struct serial_console_data *scdp)
220+{
221+ return -1;
222+}
223+#endif
224diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500225index 5e75e1c..e19b64e 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930226--- a/arch/powerpc/boot/ops.h
227+++ b/arch/powerpc/boot/ops.h
228@@ -89,6 +89,7 @@ int mpsc_console_init(void *devp, struct serial_console_data *scdp);
229 int cpm_console_init(void *devp, struct serial_console_data *scdp);
230 int mpc5200_psc_console_init(void *devp, struct serial_console_data *scdp);
231 int uartlite_console_init(void *devp, struct serial_console_data *scdp);
232+int opal_console_init(void *devp, struct serial_console_data *scdp);
233 void *simple_alloc_init(char *base, unsigned long heap_size,
234 unsigned long granularity, unsigned long max_allocs);
235 extern void flush_cache(void *, unsigned long);
236diff --git a/arch/powerpc/boot/ppc_asm.h b/arch/powerpc/boot/ppc_asm.h
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500237index 35ea60c..b03373d 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930238--- a/arch/powerpc/boot/ppc_asm.h
239+++ b/arch/powerpc/boot/ppc_asm.h
240@@ -61,6 +61,10 @@
241
242 #define SPRN_TBRL 268
243 #define SPRN_TBRU 269
244+#define SPRN_HSRR0 0x13A /* Hypervisor Save/Restore 0 */
245+#define SPRN_HSRR1 0x13B /* Hypervisor Save/Restore 1 */
246+
247+#define MSR_LE 0x0000000000000001
248
249 #define FIXUP_ENDIAN \
250 tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \
251diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500252index 167ee943..e04c1e4 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930253--- a/arch/powerpc/boot/serial.c
254+++ b/arch/powerpc/boot/serial.c
255@@ -132,6 +132,8 @@ int serial_console_init(void)
256 else if (dt_is_compatible(devp, "xlnx,opb-uartlite-1.00.b") ||
257 dt_is_compatible(devp, "xlnx,xps-uartlite-1.00.a"))
258 rc = uartlite_console_init(devp, &serial_cd);
259+ else if (dt_is_compatible(devp, "ibm,opal-console-raw"))
260+ rc = opal_console_init(devp, &serial_cd);
261
262 /* Add other serial console driver calls here */
263
264diff --git a/arch/powerpc/boot/types.h b/arch/powerpc/boot/types.h
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500265index 31393d1..85565a8 100644
Joel Stanley2b0f7b42016-07-19 23:26:28 +0930266--- a/arch/powerpc/boot/types.h
267+++ b/arch/powerpc/boot/types.h
268@@ -12,6 +12,16 @@ typedef short s16;
269 typedef int s32;
270 typedef long long s64;
271
272+/* required for opal-api.h */
273+typedef u8 uint8_t;
274+typedef u16 uint16_t;
275+typedef u32 uint32_t;
276+typedef u64 uint64_t;
277+typedef s8 int8_t;
278+typedef s16 int16_t;
279+typedef s32 int32_t;
280+typedef s64 int64_t;
281+
282 #define min(x,y) ({ \
283 typeof(x) _x = (x); \
284 typeof(y) _y = (y); \
Klaus Heinrich Kiwi49aaa422020-06-24 08:10:42 -0500285--
2861.9.4
287