aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-05-19 21:01:28 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-06-04 23:19:59 -0400
commit4926616c77435e735c59288f838e7761baec4a6c (patch)
treea9dd2f673b9bdc1de9530b49232d7beb85ebd0f8
parent26c88f930141f0d9e7673af2332ada67b7e8865a (diff)
powerpc/powernv: Add calls to support little endian host
When running as a powernv "host" system on P8, we need to switch the endianness of interrupt handlers. This does it via the appropriate call to the OPAL firmware which may result in just switching HID0:HILE but depending on the processor version might need to do a few more things. This call must be done early before any other processor has been brought out of firmware. Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> Signed-off-by: Andy Whitcroft <apw@canonical.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r--arch/powerpc/include/asm/opal.h7
-rw-r--r--arch/powerpc/platforms/powernv/opal-wrappers.S1
-rw-r--r--arch/powerpc/platforms/powernv/opal.c22
3 files changed, 30 insertions, 0 deletions
diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 81720ff59a10..ea8bba7b66bd 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -154,6 +154,7 @@ extern int opal_enter_rtas(struct rtas_args *args,
154#define OPAL_LPC_READ 67 154#define OPAL_LPC_READ 67
155#define OPAL_LPC_WRITE 68 155#define OPAL_LPC_WRITE 68
156#define OPAL_RETURN_CPU 69 156#define OPAL_RETURN_CPU 69
157#define OPAL_REINIT_CPUS 70
157#define OPAL_ELOG_READ 71 158#define OPAL_ELOG_READ 71
158#define OPAL_ELOG_WRITE 72 159#define OPAL_ELOG_WRITE 72
159#define OPAL_ELOG_ACK 73 160#define OPAL_ELOG_ACK 73
@@ -725,6 +726,11 @@ struct OpalIoPhb3ErrorData {
725 uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS]; 726 uint64_t pestB[OPAL_PHB3_NUM_PEST_REGS];
726}; 727};
727 728
729enum {
730 OPAL_REINIT_CPUS_HILE_BE = (1 << 0),
731 OPAL_REINIT_CPUS_HILE_LE = (1 << 1),
732};
733
728typedef struct oppanel_line { 734typedef struct oppanel_line {
729 const char * line; 735 const char * line;
730 uint64_t line_len; 736 uint64_t line_len;
@@ -849,6 +855,7 @@ int64_t opal_pci_next_error(uint64_t phb_id, uint64_t *first_frozen_pe,
849 uint16_t *pci_error_type, uint16_t *severity); 855 uint16_t *pci_error_type, uint16_t *severity);
850int64_t opal_pci_poll(uint64_t phb_id); 856int64_t opal_pci_poll(uint64_t phb_id);
851int64_t opal_return_cpu(void); 857int64_t opal_return_cpu(void);
858int64_t opal_reinit_cpus(uint64_t flags);
852 859
853int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val); 860int64_t opal_xscom_read(uint32_t gcid, uint64_t pcb_addr, __be64 *val);
854int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val); 861int64_t opal_xscom_write(uint32_t gcid, uint64_t pcb_addr, uint64_t val);
diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
index b5ebc545a373..4abbff22a61f 100644
--- a/arch/powerpc/platforms/powernv/opal-wrappers.S
+++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
@@ -124,6 +124,7 @@ OPAL_CALL(opal_xscom_write, OPAL_XSCOM_WRITE);
124OPAL_CALL(opal_lpc_read, OPAL_LPC_READ); 124OPAL_CALL(opal_lpc_read, OPAL_LPC_READ);
125OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE); 125OPAL_CALL(opal_lpc_write, OPAL_LPC_WRITE);
126OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU); 126OPAL_CALL(opal_return_cpu, OPAL_RETURN_CPU);
127OPAL_CALL(opal_reinit_cpus, OPAL_REINIT_CPUS);
127OPAL_CALL(opal_read_elog, OPAL_ELOG_READ); 128OPAL_CALL(opal_read_elog, OPAL_ELOG_READ);
128OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK); 129OPAL_CALL(opal_send_ack_elog, OPAL_ELOG_ACK);
129OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE); 130OPAL_CALL(opal_get_elog_size, OPAL_ELOG_SIZE);
diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
index 360ad80c754c..539243e9dc23 100644
--- a/arch/powerpc/platforms/powernv/opal.c
+++ b/arch/powerpc/platforms/powernv/opal.c
@@ -57,6 +57,21 @@ static DEFINE_SPINLOCK(opal_notifier_lock);
57static uint64_t last_notified_mask = 0x0ul; 57static uint64_t last_notified_mask = 0x0ul;
58static atomic_t opal_notifier_hold = ATOMIC_INIT(0); 58static atomic_t opal_notifier_hold = ATOMIC_INIT(0);
59 59
60static void opal_reinit_cores(void)
61{
62 /* Do the actual re-init, This will clobber all FPRs, VRs, etc...
63 *
64 * It will preserve non volatile GPRs and HSPRG0/1. It will
65 * also restore HIDs and other SPRs to their original value
66 * but it might clobber a bunch.
67 */
68#ifdef __BIG_ENDIAN__
69 opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);
70#else
71 opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE);
72#endif
73}
74
60int __init early_init_dt_scan_opal(unsigned long node, 75int __init early_init_dt_scan_opal(unsigned long node,
61 const char *uname, int depth, void *data) 76 const char *uname, int depth, void *data)
62{ 77{
@@ -96,6 +111,13 @@ int __init early_init_dt_scan_opal(unsigned long node,
96 printk("OPAL V1 detected !\n"); 111 printk("OPAL V1 detected !\n");
97 } 112 }
98 113
114 /* Reinit all cores with the right endian */
115 opal_reinit_cores();
116
117 /* Restore some bits */
118 if (cur_cpu_spec->cpu_restore)
119 cur_cpu_spec->cpu_restore();
120
99 return 1; 121 return 1;
100} 122}
101 123