From a08a53ea4c97940fe83fea3eab27618ac0fb5ed1 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 4 Apr 2014 09:35:13 +0200 Subject: powerpc/le: Enable RTAS events support The current kernel code assumes big endian and parses RTAS events all wrong. The most visible effect is that we cannot honor EPOW events, meaning, for example, we cannot shut down a guest properly from the hypervisor. This new patch is largely inspired by Nathan's work: we get rid of all the bit fields in the RTAS event structures (even the unused ones, for consistency). We also introduce endian safe accessors for the fields used by the kernel (trivial rtas_error_type() accessor added for consistency). Cc: Nathan Fontenot Signed-off-by: Greg Kurz Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/rtas.h | 127 +++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 33 deletions(-) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h index a0e1add..b390f55 100644 --- a/arch/powerpc/include/asm/rtas.h +++ b/arch/powerpc/include/asm/rtas.h @@ -150,19 +150,53 @@ struct rtas_suspend_me_data { #define RTAS_VECTOR_EXTERNAL_INTERRUPT 0x500 struct rtas_error_log { - unsigned long version:8; /* Architectural version */ - unsigned long severity:3; /* Severity level of error */ - unsigned long disposition:2; /* Degree of recovery */ - unsigned long extended:1; /* extended log present? */ - unsigned long /* reserved */ :2; /* Reserved for future use */ - unsigned long initiator:4; /* Initiator of event */ - unsigned long target:4; /* Target of failed operation */ - unsigned long type:8; /* General event or error*/ - unsigned long extended_log_length:32; /* length in bytes */ - unsigned char buffer[1]; /* Start of extended log */ + /* Byte 0 */ + uint8_t byte0; /* Architectural version */ + + /* Byte 1 */ + uint8_t byte1; + /* XXXXXXXX + * XXX 3: Severity level of error + * XX 2: Degree of recovery + * X 1: Extended log present? + * XX 2: Reserved + */ + + /* Byte 2 */ + uint8_t byte2; + /* XXXXXXXX + * XXXX 4: Initiator of event + * XXXX 4: Target of failed operation + */ + uint8_t byte3; /* General event or error*/ + __be32 extended_log_length; /* length in bytes */ + unsigned char buffer[1]; /* Start of extended log */ /* Variable length. */ }; +static inline uint8_t rtas_error_severity(const struct rtas_error_log *elog) +{ + return (elog->byte1 & 0xE0) >> 5; +} + +static inline uint8_t rtas_error_disposition(const struct rtas_error_log *elog) +{ + return (elog->byte1 & 0x18) >> 3; +} + +static inline uint8_t rtas_error_extended(const struct rtas_error_log *elog) +{ + return (elog->byte1 & 0x04) >> 2; +} + +#define rtas_error_type(x) ((x)->byte3) + +static inline +uint32_t rtas_error_extended_log_length(const struct rtas_error_log *elog) +{ + return be32_to_cpu(elog->extended_log_length); +} + #define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG 14 #define RTAS_V6EXT_COMPANY_ID_IBM (('I' << 24) | ('B' << 16) | ('M' << 8)) @@ -172,32 +206,35 @@ struct rtas_error_log { */ struct rtas_ext_event_log_v6 { /* Byte 0 */ - uint32_t log_valid:1; /* 1:Log valid */ - uint32_t unrecoverable_error:1; /* 1:Unrecoverable error */ - uint32_t recoverable_error:1; /* 1:recoverable (correctable */ - /* or successfully retried) */ - uint32_t degraded_operation:1; /* 1:Unrecoverable err, bypassed*/ - /* - degraded operation (e.g. */ - /* CPU or mem taken off-line) */ - uint32_t predictive_error:1; - uint32_t new_log:1; /* 1:"New" log (Always 1 for */ - /* data returned from RTAS */ - uint32_t big_endian:1; /* 1: Big endian */ - uint32_t :1; /* reserved */ + uint8_t byte0; + /* XXXXXXXX + * X 1: Log valid + * X 1: Unrecoverable error + * X 1: Recoverable (correctable or successfully retried) + * X 1: Bypassed unrecoverable error (degraded operation) + * X 1: Predictive error + * X 1: "New" log (always 1 for data returned from RTAS) + * X 1: Big Endian + * X 1: Reserved + */ + /* Byte 1 */ - uint32_t :8; /* reserved */ + uint8_t byte1; /* reserved */ + /* Byte 2 */ - uint32_t powerpc_format:1; /* Set to 1 (indicating log is */ - /* in PowerPC format */ - uint32_t :3; /* reserved */ - uint32_t log_format:4; /* Log format indicator. Define */ - /* format used for byte 12-2047 */ + uint8_t byte2; + /* XXXXXXXX + * X 1: Set to 1 (indicating log is in PowerPC format) + * XXX 3: Reserved + * XXXX 4: Log format used for bytes 12-2047 + */ + /* Byte 3 */ - uint32_t :8; /* reserved */ + uint8_t byte3; /* reserved */ /* Byte 4-11 */ uint8_t reserved[8]; /* reserved */ /* Byte 12-15 */ - uint32_t company_id; /* Company ID of the company */ + __be32 company_id; /* Company ID of the company */ /* that defines the format for */ /* the vendor specific log type */ /* Byte 16-end of log */ @@ -205,6 +242,18 @@ struct rtas_ext_event_log_v6 { /* Variable length. */ }; +static +inline uint8_t rtas_ext_event_log_format(struct rtas_ext_event_log_v6 *ext_log) +{ + return ext_log->byte2 & 0x0F; +} + +static +inline uint32_t rtas_ext_event_company_id(struct rtas_ext_event_log_v6 *ext_log) +{ + return be32_to_cpu(ext_log->company_id); +} + /* pSeries event log format */ /* Two bytes ASCII section IDs */ @@ -227,14 +276,26 @@ struct rtas_ext_event_log_v6 { /* Vendor specific Platform Event Log Format, Version 6, section header */ struct pseries_errorlog { - uint16_t id; /* 0x00 2-byte ASCII section ID */ - uint16_t length; /* 0x02 Section length in bytes */ + __be16 id; /* 0x00 2-byte ASCII section ID */ + __be16 length; /* 0x02 Section length in bytes */ uint8_t version; /* 0x04 Section version */ uint8_t subtype; /* 0x05 Section subtype */ - uint16_t creator_component; /* 0x06 Creator component ID */ + __be16 creator_component; /* 0x06 Creator component ID */ uint8_t data[]; /* 0x08 Start of section data */ }; +static +inline uint16_t pseries_errorlog_id(struct pseries_errorlog *sect) +{ + return be16_to_cpu(sect->id); +} + +static +inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect) +{ + return be16_to_cpu(sect->length); +} + struct pseries_errorlog *get_pseries_errorlog(struct rtas_error_log *log, uint16_t section_id); -- cgit v1.1 From 798af00c4d75cdbed58bfe5c31e721bc0daedd9b Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Fri, 28 Mar 2014 13:36:31 +1100 Subject: powerpc/powernv: Add opal_notifier_unregister() and export to modules opal_notifier_register() is missing a pending "unregister" variant and should be exposed to modules. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index fe2aa0b..6fb5f90 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -892,6 +892,8 @@ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); extern int opal_notifier_register(struct notifier_block *nb); +extern int opal_notifier_unregister(struct notifier_block *nb); + extern int opal_message_notifier_register(enum OpalMessageType msg_type, struct notifier_block *nb); extern void opal_notifier_enable(void); -- cgit v1.1 From bb4398e1de739a13e06589fc04cbb2267ba59800 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 28 Mar 2014 16:33:33 +1100 Subject: powerpc/powernv: Fix endian issues with OPAL async code OPAL defines opal_msg as a big endian struct so we have to byte swap it on little endian builds. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 6fb5f90..fc73661 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -422,9 +422,9 @@ enum OpalSysparamPerm { }; struct opal_msg { - uint32_t msg_type; - uint32_t reserved; - uint64_t params[8]; + __be32 msg_type; + __be32 reserved; + __be64 params[8]; }; struct opal_machine_check_event { -- cgit v1.1 From 9000c17dc0f9c910267d2661225c9d33a227b27e Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 28 Mar 2014 16:34:10 +1100 Subject: powerpc/powernv: Fix endian issues with sensor code One OPAL call and one device tree property needed byte swapping. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index fc73661..a13ab39 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -874,8 +874,7 @@ int64_t opal_get_param(uint64_t token, uint32_t param_id, uint64_t buffer, size_t length); int64_t opal_set_param(uint64_t token, uint32_t param_id, uint64_t buffer, size_t length); -int64_t opal_sensor_read(uint32_t sensor_hndl, int token, - uint32_t *sensor_data); +int64_t opal_sensor_read(uint32_t sensor_hndl, int token, __be32 *sensor_data); /* Internal functions */ extern int early_init_dt_scan_opal(unsigned long node, const char *uname, int depth, void *data); -- cgit v1.1 From bfc36894a48b996eba7e02d8e43093a289c1fb91 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 1 Apr 2014 14:28:19 +1030 Subject: powerpc/powernv: Add OPAL message log interface OPAL provides an in-memory circular buffer containing a message log populated with various runtime messages produced by the firmware. Provide a sysfs interface /sys/firmware/opal/msglog for userspace to view the messages. Signed-off-by: Joel Stanley Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index a13ab39..05f9455 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -730,6 +730,9 @@ typedef struct oppanel_line { /* /sys/firmware/opal */ extern struct kobject *opal_kobj; +/* /ibm,opal */ +extern struct device_node *opal_node; + /* API functions */ int64_t opal_console_write(int64_t term_number, __be64 *length, const uint8_t *buffer); @@ -920,6 +923,7 @@ extern void opal_flash_init(void); extern int opal_elog_init(void); extern void opal_platform_dump_init(void); extern void opal_sys_param_init(void); +extern void opal_msglog_init(void); extern int opal_machine_check(struct pt_regs *regs); extern bool opal_mce_check_early_recovery(struct pt_regs *regs); -- cgit v1.1 From e28b05e7ae8ba09e030ffe891ba154df5791cb76 Mon Sep 17 00:00:00 2001 From: Joel Stanley Date: Tue, 1 Apr 2014 14:28:20 +1030 Subject: powerpc/powernv: Add invalid OPAL call This call will not be understood by OPAL, and cause it to add an error to it's log. Among other things, this is useful for testing the behaviour of the log as it fills up. Signed-off-by: Joel Stanley Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 05f9455..6bd3b18 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -87,6 +87,7 @@ extern int opal_enter_rtas(struct rtas_args *args, #define OPAL_ASYNC_COMPLETION -15 /* API Tokens (in r0) */ +#define OPAL_INVALID_CALL -1 #define OPAL_CONSOLE_WRITE 1 #define OPAL_CONSOLE_READ 2 #define OPAL_RTC_READ 3 @@ -734,6 +735,7 @@ extern struct kobject *opal_kobj; extern struct device_node *opal_node; /* API functions */ +int64_t opal_invalid_call(void); int64_t opal_console_write(int64_t term_number, __be64 *length, const uint8_t *buffer); int64_t opal_console_read(int64_t term_number, __be64 *length, -- cgit v1.1 From f83319d71002aec03bd87bc9aabce5f549680f0a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Fri, 28 Mar 2014 17:01:23 +1100 Subject: powerpc: Add lq/stq emulation Recent CPUs support quad word load and store instructions. Add support to the alignment handler for them. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/emulated_ops.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/emulated_ops.h b/arch/powerpc/include/asm/emulated_ops.h index 4358e30..f00e10e 100644 --- a/arch/powerpc/include/asm/emulated_ops.h +++ b/arch/powerpc/include/asm/emulated_ops.h @@ -54,6 +54,7 @@ extern struct ppc_emulated { #ifdef CONFIG_PPC64 struct ppc_emulated_entry mfdscr; struct ppc_emulated_entry mtdscr; + struct ppc_emulated_entry lq_stq; #endif } ppc_emulated; -- cgit v1.1 From bfd25d72abc62a89f9c9c41417da998adcf2578e Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 25 Mar 2014 11:43:08 +1100 Subject: powerpc/opal: Add missing include next-20140324 currently fails compiling celleb_defconfig with: arch/powerpc/include/asm/opal.h:894:42: error: 'struct notifier_block' declared inside parameter list [-Werror] arch/powerpc/include/asm/opal.h:894:42: error: its scope is only this definition or declaration, which is probably not what you want [-Werror] arch/powerpc/include/asm/opal.h:896:14: error: 'struct notifier_block' declared inside parameter list [-Werror] This is due to a missing include which is added here. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/opal.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc/include') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 6bd3b18..a2efdaa 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -178,6 +178,8 @@ extern int opal_enter_rtas(struct rtas_args *args, #ifndef __ASSEMBLY__ +#include + /* Other enums */ enum OpalVendorApiTokens { OPAL_START_VENDOR_API_RANGE = 1000, OPAL_END_VENDOR_API_RANGE = 1999 -- cgit v1.1