aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-19 13:44:59 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2011-09-20 02:09:54 -0400
commitdaea1175a9f0f70eab5b33e2827d57ba8c686816 (patch)
treeaac48bd8bdfb9c7ee8e3e5058aea07e04e105da3 /arch
parent6e35d5dac0c83ebb616ff3b9c2d6155c9a9ccb86 (diff)
powerpc/powernv: Support for OPAL console
This adds a udbg and an hvc console backend for supporting a console using the OPAL console interfaces. On OPAL v1 we have hvc0 mapped to whatever console the system was configured for (network or hvsi serial port) via the service processor. On OPAL v2 we have hvcN mapped to the Nth console provided by OPAL which generally corresponds to: hvc0 : network console (raw protocol) hvc1 : serial port S1 (hvsi) hvc2 : serial port S2 (hvsi) Note: At this point, early debug console only works with OPAL v1 and shouldn't be enabled in a normal kernel. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/Kconfig.debug31
-rw-r--r--arch/powerpc/include/asm/opal.h5
-rw-r--r--arch/powerpc/include/asm/udbg.h2
-rw-r--r--arch/powerpc/kernel/head_64.S14
-rw-r--r--arch/powerpc/kernel/udbg.c4
-rw-r--r--arch/powerpc/platforms/powernv/opal.c31
-rw-r--r--arch/powerpc/platforms/powernv/setup.c14
7 files changed, 81 insertions, 20 deletions
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 06eb62b0fd90..1b8a9c905cf7 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -265,8 +265,27 @@ config PPC_EARLY_DEBUG_PS3GELIC
265 Select this to enable early debugging for the PlayStation3 via 265 Select this to enable early debugging for the PlayStation3 via
266 UDP broadcasts sent out through the Ethernet port. 266 UDP broadcasts sent out through the Ethernet port.
267 267
268config PPC_EARLY_DEBUG_OPAL_RAW
269 bool "OPAL raw console"
270 depends on HVC_OPAL
271 help
272 Select this to enable early debugging for the PowerNV platform
273 using a "raw" console
274
275config PPC_EARLY_DEBUG_OPAL_HVSI
276 bool "OPAL hvsi console"
277 depends on HVC_OPAL
278 help
279 Select this to enable early debugging for the PowerNV platform
280 using an "hvsi" console
281
268endchoice 282endchoice
269 283
284config PPC_EARLY_DEBUG_OPAL
285 def_bool y
286 depends on PPC_EARLY_DEBUG_OPAL_RAW || PPC_EARLY_DEBUG_OPAL_HVSI
287
288
270config PPC_EARLY_DEBUG_HVSI_VTERMNO 289config PPC_EARLY_DEBUG_HVSI_VTERMNO
271 hex "vterm number to use with early debug HVSI" 290 hex "vterm number to use with early debug HVSI"
272 depends on PPC_EARLY_DEBUG_LPAR_HVSI 291 depends on PPC_EARLY_DEBUG_LPAR_HVSI
@@ -275,6 +294,18 @@ config PPC_EARLY_DEBUG_HVSI_VTERMNO
275 You probably want 0x30000000 for your first serial port and 294 You probably want 0x30000000 for your first serial port and
276 0x30000001 for your second one 295 0x30000001 for your second one
277 296
297config PPC_EARLY_DEBUG_OPAL_VTERMNO
298 hex "vterm number to use with OPAL early debug"
299 depends on PPC_EARLY_DEBUG_OPAL
300 default "0"
301 help
302 This correspond to which /dev/hvcN you want to use for early
303 debug.
304
305 On OPAL v1 (takeover) this should always be 0
306 On OPAL v2, this will be 0 for network console and 1 or 2 for
307 the machine built-in serial ports.
308
278config PPC_EARLY_DEBUG_44x_PHYSLOW 309config PPC_EARLY_DEBUG_44x_PHYSLOW
279 hex "Low 32 bits of early debug UART physical address" 310 hex "Low 32 bits of early debug UART physical address"
280 depends on PPC_EARLY_DEBUG_44x 311 depends on PPC_EARLY_DEBUG_44x
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index c7a3202d10a0..749de00a02d5 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -425,6 +425,11 @@ extern void hvc_opal_init_early(void);
425extern int early_init_dt_scan_opal(unsigned long node, const char *uname, 425extern int early_init_dt_scan_opal(unsigned long node, const char *uname,
426 int depth, void *data); 426 int depth, void *data);
427 427
428extern int opal_get_chars(uint32_t vtermno, char *buf, int count);
429extern int opal_put_chars(uint32_t vtermno, const char *buf, int total_len);
430
431extern void hvc_opal_init_early(void);
432
428#endif /* __ASSEMBLY__ */ 433#endif /* __ASSEMBLY__ */
429 434
430#endif /* __OPAL_H */ 435#endif /* __OPAL_H */
diff --git a/arch/powerpc/include/asm/udbg.h b/arch/powerpc/include/asm/udbg.h
index 7cf796fa03f2..6587ec7bc6ec 100644
--- a/arch/powerpc/include/asm/udbg.h
+++ b/arch/powerpc/include/asm/udbg.h
@@ -55,6 +55,8 @@ extern void __init udbg_init_cpm(void);
55extern void __init udbg_init_usbgecko(void); 55extern void __init udbg_init_usbgecko(void);
56extern void __init udbg_init_wsp(void); 56extern void __init udbg_init_wsp(void);
57extern void __init udbg_init_ps3gelic(void); 57extern void __init udbg_init_ps3gelic(void);
58extern void __init udbg_init_debug_opal_raw(void);
59extern void __init udbg_init_debug_opal_hvsi(void);
58 60
59#endif /* __KERNEL__ */ 61#endif /* __KERNEL__ */
60#endif /* _ASM_POWERPC_UDBG_H */ 62#endif /* _ASM_POWERPC_UDBG_H */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index dea8191253d2..06c7251c1bf7 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -53,7 +53,8 @@
53 * 2. The kernel is entered at __start 53 * 2. The kernel is entered at __start
54 * -or- For OPAL entry: 54 * -or- For OPAL entry:
55 * 1. The MMU is off, processor in HV mode, primary CPU enters at 0 55 * 1. The MMU is off, processor in HV mode, primary CPU enters at 0
56 * with device-tree in gpr3 56 * with device-tree in gpr3. We also get OPAL base in r8 and
57 * entry in r9 for debugging purposes
57 * 2. Secondary processors enter at 0x60 with PIR in gpr3 58 * 2. Secondary processors enter at 0x60 with PIR in gpr3
58 * 59 *
59 * For iSeries: 60 * For iSeries:
@@ -335,6 +336,11 @@ _GLOBAL(__start_initialization_multiplatform)
335 /* Save parameters */ 336 /* Save parameters */
336 mr r31,r3 337 mr r31,r3
337 mr r30,r4 338 mr r30,r4
339#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
340 /* Save OPAL entry */
341 mr r28,r8
342 mr r29,r9
343#endif
338 344
339#ifdef CONFIG_PPC_BOOK3E 345#ifdef CONFIG_PPC_BOOK3E
340 bl .start_initialization_book3e 346 bl .start_initialization_book3e
@@ -711,6 +717,12 @@ _INIT_STATIC(start_here_multiplatform)
711 bdnz 3b 717 bdnz 3b
7124: 7184:
713 719
720#ifdef CONFIG_PPC_EARLY_DEBUG_OPAL
721 /* Setup OPAL entry */
722 std r28,0(r11);
723 std r29,8(r11);
724#endif
725
714#ifndef CONFIG_PPC_BOOK3E 726#ifndef CONFIG_PPC_BOOK3E
715 mfmsr r6 727 mfmsr r6
716 ori r6,r6,MSR_RI 728 ori r6,r6,MSR_RI
diff --git a/arch/powerpc/kernel/udbg.c b/arch/powerpc/kernel/udbg.c
index 5b3e98e03158..35f948203ec5 100644
--- a/arch/powerpc/kernel/udbg.c
+++ b/arch/powerpc/kernel/udbg.c
@@ -69,6 +69,10 @@ void __init udbg_early_init(void)
69 udbg_init_wsp(); 69 udbg_init_wsp();
70#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC) 70#elif defined(CONFIG_PPC_EARLY_DEBUG_PS3GELIC)
71 udbg_init_ps3gelic(); 71 udbg_init_ps3gelic();
72#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_RAW)
73 udbg_init_debug_opal_raw();
74#elif defined(CONFIG_PPC_EARLY_DEBUG_OPAL_HVSI)
75 udbg_init_debug_opal_hvsi();
72#endif 76#endif
73 77
74#ifdef CONFIG_PPC_EARLY_DEBUG 78#ifdef CONFIG_PPC_EARLY_DEBUG
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 8d5510784cc2..7887733b9b31 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -67,7 +67,7 @@ int opal_get_chars(uint32_t vtermno, char *buf, int count)
67 u64 evt; 67 u64 evt;
68 68
69 if (!opal.entry) 69 if (!opal.entry)
70 return 0; 70 return -ENODEV;
71 opal_poll_events(&evt); 71 opal_poll_events(&evt);
72 if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0) 72 if ((evt & OPAL_EVENT_CONSOLE_INPUT) == 0)
73 return 0; 73 return 0;
@@ -81,31 +81,38 @@ int opal_get_chars(uint32_t vtermno, char *buf, int count)
81int opal_put_chars(uint32_t vtermno, const char *data, int total_len) 81int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
82{ 82{
83 int written = 0; 83 int written = 0;
84 s64 len, rc = OPAL_BUSY; 84 s64 len, rc;
85 unsigned long flags; 85 unsigned long flags;
86 u64 evt; 86 u64 evt;
87 87
88 if (!opal.entry) 88 if (!opal.entry)
89 return 0; 89 return -ENODEV;
90 90
91 /* We want put_chars to be atomic to avoid mangling of hvsi 91 /* We want put_chars to be atomic to avoid mangling of hvsi
92 * packets. To do that, we first test for room and return 92 * packets. To do that, we first test for room and return
93 * -EAGAIN if there isn't enough 93 * -EAGAIN if there isn't enough.
94 *
95 * Unfortunately, opal_console_write_buffer_space() doesn't
96 * appear to work on opal v1, so we just assume there is
97 * enough room and be done with it
94 */ 98 */
95 spin_lock_irqsave(&opal_write_lock, flags); 99 spin_lock_irqsave(&opal_write_lock, flags);
96 rc = opal_console_write_buffer_space(vtermno, &len); 100 if (firmware_has_feature(FW_FEATURE_OPALv2)) {
97 if (rc || len < total_len) { 101 rc = opal_console_write_buffer_space(vtermno, &len);
98 spin_unlock_irqrestore(&opal_write_lock, flags); 102 if (rc || len < total_len) {
99 /* Closed -> drop characters */ 103 spin_unlock_irqrestore(&opal_write_lock, flags);
100 if (rc) 104 /* Closed -> drop characters */
101 return total_len; 105 if (rc)
102 opal_poll_events(&evt); 106 return total_len;
103 return -EAGAIN; 107 opal_poll_events(&evt);
108 return -EAGAIN;
109 }
104 } 110 }
105 111
106 /* We still try to handle partial completions, though they 112 /* We still try to handle partial completions, though they
107 * should no longer happen. 113 * should no longer happen.
108 */ 114 */
115 rc = OPAL_BUSY;
109 while(total_len > 0 && (rc == OPAL_BUSY || 116 while(total_len > 0 && (rc == OPAL_BUSY ||
110 rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) { 117 rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
111 len = total_len; 118 len = total_len;
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index b6e5ff85cc6f..07ba1ecd1807 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -29,17 +29,12 @@
29#include <asm/machdep.h> 29#include <asm/machdep.h>
30#include <asm/firmware.h> 30#include <asm/firmware.h>
31#include <asm/xics.h> 31#include <asm/xics.h>
32#include <asm/opal.h>
32 33
33#include "powernv.h" 34#include "powernv.h"
34 35
35static void __init pnv_setup_arch(void) 36static void __init pnv_setup_arch(void)
36{ 37{
37 /* Force console to hvc for now until we have sorted out the
38 * real console situation for the platform. This will make
39 * hvc_udbg work at least.
40 */
41 add_preferred_console("hvc", 0, NULL);
42
43 /* Initialize SMP */ 38 /* Initialize SMP */
44 pnv_smp_init(); 39 pnv_smp_init();
45 40
@@ -55,7 +50,12 @@ static void __init pnv_setup_arch(void)
55 50
56static void __init pnv_init_early(void) 51static void __init pnv_init_early(void)
57{ 52{
58 /* XXX IOMMU */ 53#ifdef CONFIG_HVC_OPAL
54 if (firmware_has_feature(FW_FEATURE_OPAL))
55 hvc_opal_init_early();
56 else
57#endif
58 add_preferred_console("hvc", 0, NULL);
59} 59}
60 60
61static void __init pnv_init_IRQ(void) 61static void __init pnv_init_IRQ(void)