[PATCH 2/2] powerpc/pseries: Add support for IO event interrupts

2011-05-05 Thread Tseng-Hui (Frank) Lin

From: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com

This patch adds support for handling IO Event interrupts which come
through at the /event-sources/ibm,io-events device tree node.

The interrupts come through ibm,io-events device tree node are generated
by the firmware to report IO events. The firmware uses the same interrupt
to report multiple types of events for multiple devices. Each device may
have its own event handler. This patch implements a plateform interrupt
handler that is triggered by the IO event interrupts come through
ibm,io-events device tree node, pull in the IO events from RTAS and call
device event handlers registered in the notifier list.

Device event handlers are expected to use atomic_notifier_chain_register()
and atomic_notifier_chain_unregister() to register/unregister their
event handler in pseries_ioei_notifier_list list with IO event interrupt.
Device event handlers are responsible to identify if the event belongs
to the device event handler. The device event handle should return NOTIFY_OK
after the event is handled if the event belongs to the device event handler,
or NOTIFY_DONE otherwise.

Change log:
- Fixed compilation errors
- Fix comments to be docbook compliant
- Fix some code format

Signed-off-by: Tseng-Hui (Frank) Lin th...@us.ibm.com
Signed-off-by: Benjamin Herrenschmidt b...@kernel.crashing.org
---
 arch/powerpc/include/asm/io_event_irq.h   |   54 ++
 arch/powerpc/platforms/pseries/Kconfig|   18 ++
 arch/powerpc/platforms/pseries/Makefile   |1 +
 arch/powerpc/platforms/pseries/io_event_irq.c |  231 +
 4 files changed, 304 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/io_event_irq.h 
b/arch/powerpc/include/asm/io_event_irq.h
new file mode 100644
index 000..b1a9a1b
--- /dev/null
+++ b/arch/powerpc/include/asm/io_event_irq.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010, 2011 Mark Nelson and Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_POWERPC_IO_EVENT_IRQ_H
+#define _ASM_POWERPC_IO_EVENT_IRQ_H
+
+#include linux/types.h
+#include linux/notifier.h
+
+#define PSERIES_IOEI_RPC_MAX_LEN 216
+
+#define PSERIES_IOEI_TYPE_ERR_DETECTED 0x01
+#define PSERIES_IOEI_TYPE_ERR_RECOVERED0x02
+#define PSERIES_IOEI_TYPE_EVENT0x03
+#define PSERIES_IOEI_TYPE_RPC_PASS_THRU0x04
+
+#define PSERIES_IOEI_SUBTYPE_NOT_APP   0x00
+#define PSERIES_IOEI_SUBTYPE_REBALANCE_REQ 0x01
+#define PSERIES_IOEI_SUBTYPE_NODE_ONLINE   0x03
+#define PSERIES_IOEI_SUBTYPE_NODE_OFFLINE  0x04
+#define PSERIES_IOEI_SUBTYPE_DUMP_SIZE_CHANGE  0x05
+#define PSERIES_IOEI_SUBTYPE_TORRENT_IRV_UPDATE0x06
+#define PSERIES_IOEI_SUBTYPE_TORRENT_HFI_CFGED 0x07
+
+#define PSERIES_IOEI_SCOPE_NOT_APP 0x00
+#define PSERIES_IOEI_SCOPE_RIO_HUB 0x36
+#define PSERIES_IOEI_SCOPE_RIO_BRIDGE  0x37
+#define PSERIES_IOEI_SCOPE_PHB 0x38
+#define PSERIES_IOEI_SCOPE_EADS_GLOBAL 0x39
+#define PSERIES_IOEI_SCOPE_EADS_SLOT   0x3A
+#define PSERIES_IOEI_SCOPE_TORRENT_HUB 0x3B
+#define PSERIES_IOEI_SCOPE_SERVICE_PROC0x51
+
+/* Platform Event Log Format, Version 6, data portition of IO event section */
+struct pseries_io_event {
+   uint8_t event_type; /* 0x00 IO-Event Type   */
+   uint8_t rpc_data_len;   /* 0x01 RPC data length */
+   uint8_t scope;  /* 0x02 Error/Event Scope   */
+   uint8_t event_subtype;  /* 0x03 I/O-Event Sub-Type  */
+   uint32_t drc_index; /* 0x04 DRC Index   */
+   uint8_t rpc_data[PSERIES_IOEI_RPC_MAX_LEN];
+   /* 0x08 RPC Data (0-216 bytes,  */
+   /* padded to 4 bytes alignment) */
+};
+
+extern struct atomic_notifier_head pseries_ioei_notifier_list;
+
+#endif /* _ASM_POWERPC_IO_EVENT_IRQ_H */
diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index b044922..71af4c5 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -50,6 +50,24 @@ config SCANLOG
tristate Scanlog dump interface
depends on RTAS_PROC  PPC_PSERIES
 
+config IO_EVENT_IRQ
+   bool IO Event Interrupt support
+   depends on PPC_PSERIES
+   default y
+   help
+ Select this option, if you want to enable support for IO Event
+ interrupts. IO event interrupt is a mechanism provided by RTAS
+ to return information about hardware error and non-error events
+ which may need OS attention. RTAS returns events

[PATCH v3 0/3] powerpc: Add IO event interrupt support

2011-03-14 Thread Tseng-Hui (Frank) Lin

This series of patches adds support for handling IO Event interrupts which
come through at the /event-sources/ibm,io-events device tree node.

Change log from V2:

- rename RTAS general extended event log version 6 structure from
  rtas_error_log_v6ext to rtas_ext_event_log_v6.
- Re-implement interrupt call list with atomic notifier.

platforms/pseries/io_event_irq.c:
- Move IO Event data copy to ioei_interrupt(). Rename ioei_get_event()
  to ioei_find_event().
- Remove unused ioei_call_handlers(), pseries_ioei_register_handler(),
  pseries_ioei_unregister_handler() as the functions are replaced by
  notifier.

Change log from v1:
- Restructure the patch into 3 patches.
  = Move non-IBM specific v6 extended log definition to rtas.h.
  = Move IBM specific v6 extended log definition to pseries_event_log.h
and code to pseries_event_log.c.
- Add CONFIG_PSERIES_EVENT_LOG to pseries Kconfig
- Add CONFIG_IO_EVENT_IRQ to pseries Kconfig

io_events.h:
- Change C++ comments to C format.
- Add definitions for all known type, sub-types, and scopes.
- Change data type of rpc_data from u32 to u8 as the size of rpc_data is
  specified in rpc_field_len in bytes.
- Set maximum length for rpc_data.
- Change ioei_register_isr() and ioei_unregister_isr() declearation to match
  the change in io_events.c file

io_events.c:
- Use pseries_/PSERIES_ prefix for global symbols.
- Change to use list_head for ioei_consumer list.
- Remove scope from handler registeration.
- Change device_initcall() to machine_device_initcall()
- ioei_register_handler():
  = Return -ENODEV if IOEI not supported on the machine.
  = Change use spin_lock() to use spin_lock_irq().
- ioei_unregister_handler():
  = Change use spin_lock() to use spin_lock_irq().
- ioei_call_consumers():
  = Change spin_lock_irqsave() to spin_lock() because we are called from
an interrupt handler.
  = Return IRQ_HANDLED/IRQ_NONE if interrupt is handled/not handled.
  = Print an error message if no one claims the interrupt.
- io_event_interrupt():
  = Change to use rtas_data_buf and RTAS_DATA_BUF_SIZE for rtas_call().
  = Loop calling rtas_call() to pull in multiple events in one interrupt.
  = Split IO event section searching code into ioei_get_event().
- init_ioei_IRQ()
  = Check rtas_token() return code.


Signed-off-by: Mark Nelson ma...@au1.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 1/3] powerpc: Add IO event interrupt support

2011-03-14 Thread Tseng-Hui (Frank) Lin

This patch adds definitions of non-IBM specific v6 extended log definitions to 
rtas.h.

Change log from V2:
- rename RTAS general extended event log version 6 structure from
  rtas_error_log_v6ext to rtas_ext_event_log_v6.

Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/include/asm/rtas.h |   45 ++-
 1 files changed, 44 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 9a1193e..58625d1 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -158,7 +158,50 @@ struct rtas_error_log {
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];
+   unsigned char buffer[1];/* Start of extended log */
+   /* Variable length.  */
+};
+
+#define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG14
+
+#define RTAS_V6EXT_COMPANY_ID_IBM  (('I'  24) | ('B'  16) | ('M'  8))
+
+/* RTAS general extended event log, Version 6. The extended log starts
+ * from buffer field of struct rtas_error_log defined above.
+ */
+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 */
+   /* Byte 1 */
+   uint32_t :8;/* 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 */
+   /* Byte 3 */
+   uint32_t :8;/* reserved */
+   /* Byte 4-11 */
+   uint8_t reserved[8];/* reserved */
+   /* Byte 12-15 */
+   uint32_t company_id;/* Company ID of the company*/
+   /* that defines the format for  */
+   /* the vendor specific log type */
+   /* Byte 16-end of log */
+   uint8_t vendor_log[1];  /* Start of vendor specific log */
+   /* Variable length. */
 };
 
 /*


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 2/3] powerpc: Add IO event interrupt support

2011-03-14 Thread Tseng-Hui (Frank) Lin

This patch adds IBM specific v6 extended log definition and utilities.

Change log from V2:
- Change the log name from error log to event log.
- Change function name from pseries_elog_find_section() to
  pseries_elog_find_sect_data().

Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/platforms/pseries/Kconfig |5 ++
 arch/powerpc/platforms/pseries/Makefile|1 +
 arch/powerpc/platforms/pseries/pseries_event_log.c |   61 
 arch/powerpc/platforms/pseries/pseries_event_log.h |   50 
 4 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index 5b3da4b..98e5e39 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -47,6 +47,11 @@ config SCANLOG
tristate Scanlog dump interface
depends on RTAS_PROC  PPC_PSERIES
 
+config PSERIES_EVENT_LOG
+   bool
+   depends on PPC_PSERIES  RTAS_ERROR_LOGGING
+   default n
+
 config LPARCFG
bool LPAR Configuration Data
depends on PPC_PSERIES || PPC_ISERIES
diff --git a/arch/powerpc/platforms/pseries/Makefile 
b/arch/powerpc/platforms/pseries/Makefile
index fc52378..07bbf75 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
 obj-$(CONFIG_PHYP_DUMP)+= phyp_dump.o
 obj-$(CONFIG_CMM)  += cmm.o
 obj-$(CONFIG_DTL)  += dtl.o
+obj-$(CONFIG_PSERIES_EVENT_LOG)+= pseries_event_log.o
 
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_SUSPEND)  += suspend.o
diff --git a/arch/powerpc/platforms/pseries/pseries_event_log.c 
b/arch/powerpc/platforms/pseries/pseries_event_log.c
new file mode 100644
index 000..36ad8a1
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_event_log.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2010, 2011 Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * IBM pSerie platform event log specific functions.
+ * All data in this file is in big endian.
+ */
+
+#include linux/kernel.h
+#include linux/types.h
+
+#include asm/rtas.h
+
+#include pseries_event_log.h
+
+/*
+ * Find the size of the data portation of a platform event log section.
+ */
+size_t pseries_elog_sect_data_len(void *sect_data_p)
+{
+   struct pseries_elog_section *p;
+
+   p = container_of(sect_data_p, struct pseries_elog_section, sect_data);
+   return(p-length - offsetof(struct pseries_elog_section, sect_data));
+}
+
+/*
+ * Find data portion of a specific section in RTAS extended event log.
+ * Return:
+ * pointer to the section data of the specified section
+ * NULL if not found
+ */
+void *pseries_elog_find_sect_data(struct rtas_ext_event_log_v6 *v6ext,
+ size_t v6ext_len, uint16_t sect_id)
+{
+   struct pseries_elog_section *sect_p;
+   uint8_t *p, *log_end;
+
+   if ((v6ext_len  sizeof(struct rtas_ext_event_log_v6)) ||
+   (v6ext-log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG) ||
+   (v6ext-company_id != RTAS_V6EXT_COMPANY_ID_IBM))
+   return NULL;
+
+   log_end = (uint8_t *) v6ext + v6ext_len;
+   p = (uint8_t *) v6ext-vendor_log;
+   while (p  log_end) {
+   sect_p = (struct pseries_elog_section *) p;
+   if (sect_p-id == sect_id)
+   return sect_p-sect_data;
+   p += sect_p-length;
+   }
+
+   return NULL;
+}
+
diff --git a/arch/powerpc/platforms/pseries/pseries_event_log.h 
b/arch/powerpc/platforms/pseries/pseries_event_log.h
new file mode 100644
index 000..879f2ed
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_event_log.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010, 2011 Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _PSERIES_PSERIES_EVENT_LOG_H
+#define _PSERIES_PSERIES_EVENT_LOG_H
+
+#include linux/types.h
+
+#include asm/rtas.h
+
+/* Two bytes ASCII section IDs */
+#define PSERIES_ELOG_SECT_ID_PRIV_HDR  (('P'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_USER_HDR  (('U'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_PRIMARY_SRC   (('P'  8) | 'S')
+#define PSERIES_ELOG_SECT_ID_EXTENDED_UH   (('E'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_FAILING_MTMS  (('M'  8) | 'T')
+#define PSERIES_ELOG_SECT_ID_SECONDARY_SRC (('S'  8) | 'S

[PATCH v3 3/3] powerpc: Add IO event interrupt support

2011-03-14 Thread Tseng-Hui (Frank) Lin

This patch adds support for handling IO Event interrupts which come
through at the /event-sources/ibm,io-events device tree node.

The interrupts come through ibm,io-events device tree node are generated
by the firmware to report IO events. The firmware uses the same interrupt
to report multiple types of events for multiple devices. Each device may
have its own event handler. This patch implements a plateform interrupt
handler that is triggered by the IO event interrupts come through
ibm,io-events device tree node, pull in the IO events from RTAS and call
device event handlers registered in the notifier list.

Device event handlers are expected to use atomic_notifier_chain_register()
and atomic_notifier_chain_unregister() to register/unregister their
event handler in pseries_ioei_notifier_list list with IO event interrupt.
Device event handlers are responsible to identify if the event belongs
to the device event handler. The device event handle should return NOTIFY_OK
after the event is handled if the event belongs to the device event handler,
or NOTIFY_DONE otherwise.

Change log from V2:
- Re-implement interrupt call list with atomic notifier.

platforms/pseries/io_event_irq.c:
- Move IO Event data copy to ioei_interrupt(). Rename ioei_get_event()
  to ioei_find_event().
- Remove unused ioei_call_handlers(), pseries_ioei_register_handler(),
  pseries_ioei_unregister_handler() as the functions are replaced by
  notifier.

Signed-off-by: Mark Nelson ma...@au1.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/include/asm/io_event_irq.h   |   54 +++
 arch/powerpc/platforms/pseries/Kconfig|   19 ++
 arch/powerpc/platforms/pseries/Makefile   |1 +
 arch/powerpc/platforms/pseries/io_event_irq.c |  207 +
 4 files changed, 281 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/io_event_irq.h 
b/arch/powerpc/include/asm/io_event_irq.h
new file mode 100644
index 000..cbaef02
--- /dev/null
+++ b/arch/powerpc/include/asm/io_event_irq.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010, 2011 Mark Nelson and Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_POWERPC_IO_EVENT_IRQ_H
+#define _ASM_POWERPC_IO_EVENT_IRQ_H
+
+#include linux/types.h
+#include linux/notifier.h
+
+#define PSERIES_IOEI_RPC_MAX_LEN 216
+
+#define PSERIES_IOEI_TYPE_ERR_DETECTED 0x01
+#define PSERIES_IOEI_TYPE_ERR_RECOVERED0x02
+#define PSERIES_IOEI_TYPE_EVENT0x03
+#define PSERIES_IOEI_TYPE_RPC_PASS_THRU0x04
+
+#define PSERIES_IOEI_SUBTYPE_NOT_APP   0x00
+#define PSERIES_IOEI_SUBTYPE_REBALANCE_REQ 0x01
+#define PSERIES_IOEI_SUBTYPE_NODE_ONLINE   0x03
+#define PSERIES_IOEI_SUBTYPE_NODE_OFFLINE  0x04
+#define PSERIES_IOEI_SUBTYPE_DUMP_SIZE_CHANGE  0x05
+#define PSERIES_IOEI_SUBTYPE_TORRENT_IRV_UPDATE0x06
+#define PSERIES_IOEI_SUBTYPE_TORRENT_HFI_CFGED 0x07
+
+#define PSERIES_IOEI_SCOPE_NOT_APP 0x00
+#define PSERIES_IOEI_SCOPE_RIO_HUB 0x36
+#define PSERIES_IOEI_SCOPE_RIO_BRIDGE  0x37
+#define PSERIES_IOEI_SCOPE_PHB 0x38
+#define PSERIES_IOEI_SCOPE_EADS_GLOBAL 0x39
+#define PSERIES_IOEI_SCOPE_EADS_SLOT   0x3A
+#define PSERIES_IOEI_SCOPE_TORRENT_HUB 0x3B
+#define PSERIES_IOEI_SCOPE_SERVICE_PROC0x51
+
+/* Platform Event Log Format, Version 6, data portition of IO event section */
+struct pseries_io_event_sect_data {
+   uint8_t event_type; /* 0x00 IO-Event Type   */
+   uint8_t rpc_data_len;   /* 0x01 RPC data length */
+   uint8_t scope;  /* 0x02 Error/Event Scope   */
+   uint8_t event_subtype;  /* 0x03 I/O-Event Sub-Type  */
+   uint32_t drc_index; /* 0x04 DRC Index   */
+   uint8_t rpc_data[PSERIES_IOEI_RPC_MAX_LEN];
+   /* 0x08 RPC Data (0-216 bytes,  */
+   /* padded to 4 bytes alignment) */
+};
+
+extern struct atomic_notifier_head pseries_ioei_notifier_list;
+
+#endif /* _ASM_POWERPC_IO_EVENT_IRQ_H */
diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index 5b3da4b..d44af70 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -52,6 +52,25 @@  bool
depends on PPC_PSERIES  RTAS_ERROR_LOGGING
default n

+config IO_EVENT_IRQ
+   bool IO Event Interrupt support
+   depends on PPC_PSERIES
+   select PSERIES_EVENT_LOG
+   default y
+   help
+ Select this option, if you want to enable support

Re: [PATCH v4 2/2] add icswx support

2011-03-04 Thread Tseng-Hui (Frank) Lin
On Fri, 2011-03-04 at 12:02 +1100, Benjamin Herrenschmidt wrote:
 On Wed, 2011-03-02 at 11:20 -0600, Tseng-Hui (Frank) Lin wrote:
 
  +#define CPU_FTR_ICSWX  LONG_ASM_CONST(0x1000)
 
 Do we want a userspace visible feature as well ? Or some other way to
 inform userspace that we support icswx ?
 
Does a user space program really need to know about icswx? Only
coprocessor drivers need to know about icswx. Shouldn't user space
programs talk to the coprocessor drivers instead? 

  index acac35d..b0c2549 100644
  --- a/arch/powerpc/include/asm/mmu-hash64.h
  +++ b/arch/powerpc/include/asm/mmu-hash64.h
  @@ -409,6 +409,14 @@ static inline void 
  subpage_prot_init_new_context(struct mm_struct *mm) { }
   
   typedef unsigned long mm_context_id_t;
   
  +#ifdef CONFIG_ICSWX
 
 CONFIG_PPC_ICSWX please.
 
Will change.

  +/*
  + * Use forward declearation to avoid including linux/spinlock_types.h
  + * which breaks kernel build.
  + */
  +struct spinlock;
  +#endif /* CONFIG_ICSWX */
  +
 
 Yuck. Instead put all your fields into a structure called something
 like struct copro_data, make that a fwd declaration and stick a pointer
 to it in the mm_context.
 
 It then only need to be allocated for processes that try to use copros,
 and the definition of that structure can remain local to whatever header
 you have dedicated for that.
 
Thought about that. However, multiple threads can call use_cop() at the
same time. Without the spinlock being setup in advance, how do I
guarantee allocating struct copro_data and modifying the pointer in the
mm_context to be atomic?

   typedef struct {
  mm_context_id_t id;
  u16 user_psize; /* page size index */
  @@ -423,6 +431,11 @@ typedef struct {
   #ifdef CONFIG_PPC_SUBPAGE_PROT
  struct subpage_prot_table spt;
   #endif /* CONFIG_PPC_SUBPAGE_PROT */
  +#ifdef CONFIG_ICSWX
  +   struct spinlock *cop_lockp; /* guard acop and cop_pid */
  +   unsigned long acop; /* mask of enabled coprocessor types */
  +   unsigned int cop_pid;   /* pid value used with coprocessors */
  +#endif /* CONFIG_ICSWX */
   } mm_context_t;
   
  
  diff --git a/arch/powerpc/include/asm/mmu_context.h 
  b/arch/powerpc/include/asm/mmu_context.h
  index 81fb412..fe0a09a 100644
  --- a/arch/powerpc/include/asm/mmu_context.h
  +++ b/arch/powerpc/include/asm/mmu_context.h
  @@ -32,6 +32,12 @@ extern void __destroy_context(unsigned long context_id);
   extern void mmu_context_init(void);
   #endif
   
  +#ifdef CONFIG_ICSWX
  +extern void switch_cop(struct mm_struct *next);
  +extern int use_cop(unsigned long acop, struct mm_struct *mm);
  +extern void drop_cop(unsigned long acop, struct mm_struct *mm);
  +#endif /* CONFIG_ICSWX */
 
 No need to ifdef declarations.
 
   .../...
 
Will change.

  +
  +#ifdef CONFIG_ICSWX_LAZY_SWITCH
  +static DEFINE_PER_CPU(unsigned long, acop_reg);
  +#define mtspr_acop(val) \
  +   if (__get_cpu_var(acop_reg) != val) { \
  +   get_cpu_var(acop_reg) = val; \
  +   mtspr(SPRN_ACOP, val); \
  +   put_cpu_var(acop_reg); \
  +   }
 
 Why get/put games here since you did a __get in the first place ?
 Doesn't make much sense. This is all inside context switch anyways so
 you just do __ always and don't bother with put.
 
Will change.

  +#else
  +#define mtspr_acop(val) mtspr(SPRN_ACOP, val)
  +#endif /* CONFIG_ICSWX_LAZY_SWITCH */
 
 I'm not sure I totally get the point of having an ifdef here. Can't you
 make it unconditional ? Or do you expect distros to turn that off in
 which case what's the point ?
 
There is only one coprocessor, HFI, using icswx at this moment. The lazy
switching makes sense. However, in the future, if more types of
coprocessors are added, the lazy switching may actually be a bad idea.
This option allows users to turn off the lazy switching.

  +#define COP_PID_NONE 0
  +#define COP_PID_MIN (COP_PID_NONE + 1)
  +#define COP_PID_MAX (0x)
  +
  +static DEFINE_SPINLOCK(mmu_context_acop_lock);
  +static DEFINE_IDA(cop_ida);
  +
  +void switch_cop(struct mm_struct *next)
  +{
  +   mtspr(SPRN_PID, next-context.cop_pid);
  +   mtspr_acop(next-context.acop);
  +}
 
 s/mtspr_acop/set_cpu_acop() instead.
 
Will change.

  +static int new_cop_pid(struct ida *ida, int min_id, int max_id,
  +  spinlock_t *lock)
  +{
  +   int index;
  +   int err;
  +
  +again:
  +   if (!ida_pre_get(ida, GFP_KERNEL))
  +   return -ENOMEM;
  +
  +   spin_lock(lock);
  +   err = ida_get_new_above(ida, min_id, index);
  +   spin_unlock(lock);
  +
  +   if (err == -EAGAIN)
  +   goto again;
  +   else if (err)
  +   return err;
  +
  +   if (index  max_id) {
  +   spin_lock(lock);
  +   ida_remove(ida, index);
  +   spin_unlock(lock);
  +   return -ENOMEM;
  +   }
  +
  +   return index;
  +}
  +
  +/*
  + * Start using a coprocessor.
  + * @acop: mask of coprocessor to be used.
  + * @mm: The mm the coprocessor to associate with. Most

Re: [PATCH v4 2/2] add icswx support

2011-03-04 Thread Tseng-Hui (Frank) Lin
On Sat, 2011-03-05 at 07:26 +1100, Benjamin Herrenschmidt wrote:
 On Fri, 2011-03-04 at 11:29 -0600, Tseng-Hui (Frank) Lin wrote:
  On Fri, 2011-03-04 at 12:02 +1100, Benjamin Herrenschmidt wrote:
   On Wed, 2011-03-02 at 11:20 -0600, Tseng-Hui (Frank) Lin wrote:
   
+#define CPU_FTR_ICSWX  
LONG_ASM_CONST(0x1000)
   
   Do we want a userspace visible feature as well ? Or some other way to
   inform userspace that we support icswx ?
   
  Does a user space program really need to know about icswx? Only
  coprocessor drivers need to know about icswx. Shouldn't user space
  programs talk to the coprocessor drivers instead? 
 
 Well, I don't know how you use icswx on P7+, but on Prism it's
 definitely issued directly by userspace.
 
OK. You've got a point. I wasn't aware of Prism. HFI device driver is
currently the only icswx user on P7. Could you point me to more
information about how Prism uses icswx from user space?

  Thought about that. However, multiple threads can call use_cop() at the
  same time. Without the spinlock being setup in advance, how do I
  guarantee allocating struct copro_data and modifying the pointer in the
  mm_context to be atomic?
 
 You don't need to. You allocate and initialize the structure, and you
 compare  swap the pointer. If somebody beat you, you trash your copy. 
 
Is atomic_cmpxchg() the one to do the trick?

   I'm not sure I totally get the point of having an ifdef here. Can't you
   make it unconditional ? Or do you expect distros to turn that off in
   which case what's the point ?
   
  There is only one coprocessor, HFI, using icswx at this moment. The lazy
  switching makes sense. However, in the future, if more types of
  coprocessors are added, the lazy switching may actually be a bad idea.
  This option allows users to turn off the lazy switching.
 
 No user in real life plays with kernel config options. Care to explain
 why the lazy switching would be a problem ?
 
The lazy switching checks the shadow variable first before setting ACOP
register. This saves mtspr() only if the new value is the same as
current. If there are several coprocessors on the system, the ACOP
register may have to be changed frequently. In that case, the lazy
switching will not save time. In extreme case when the ACOP register
needs to be changed every time, it actually slows down the execution by
the additional shadow variable checking.

  Same concern as above. I need something initialized in advance to
  guarantee allocating memory and updating the pointer are safe when it
  happens in use_cop().
 
 No you don't, see above.
 
 Cheers,
 Ben.
 
 
 ___
 Linuxppc-dev mailing list
 Linuxppc-dev@lists.ozlabs.org
 https://lists.ozlabs.org/listinfo/linuxppc-dev


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v4 2/2] add icswx support

2011-03-04 Thread Tseng-Hui (Frank) Lin
On Sat, 2011-03-05 at 09:40 +1100, Benjamin Herrenschmidt wrote:

  The lazy switching checks the shadow variable first before setting ACOP
  register. This saves mtspr() only if the new value is the same as
  current. If there are several coprocessors on the system, the ACOP
  register may have to be changed frequently. In that case, the lazy
  switching will not save time. In extreme case when the ACOP register
  needs to be changed every time, it actually slows down the execution by
  the additional shadow variable checking.
 
 By how much ? Is it even measurable ?
 
I don't have any measurable numbers. That's why I made it an option in
case people wants to disable it. I do agree that the kernel has so many
options that we should refrain from adding more. If the chance that the
lazy switching slows down the execution is really low, we should just
take out the option. Is there any one has an idea how much the numbers
are?

 Cheers,
 Ben.
 
 
 ___
 Linuxppc-dev mailing list
 Linuxppc-dev@lists.ozlabs.org
 https://lists.ozlabs.org/listinfo/linuxppc-dev


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v4 1/2] add icswx support

2011-03-02 Thread Tseng-Hui (Frank) Lin
Move SPRN_PID declearations in various locations into one place.

Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com

---
 arch/powerpc/include/asm/reg.h   |   10 ++
 arch/powerpc/include/asm/reg_booke.h |3 ---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 125fc1a..bd0d36e 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -170,6 +170,16 @@
 #define SPEFSCR_FRMC   0x0003  /* Embedded FP rounding mode control */
 
 /* Special Purpose Registers (SPRNs)*/
+
+#ifdef CONFIG_40x
+#define SPRN_PID   0x3B1   /* Process ID */
+#else
+#define SPRN_PID   0x030   /* Process ID */
+#ifdef CONFIG_BOOKE
+#define SPRN_PID0  SPRN_PID/* Process ID Register 0 */
+#endif
+#endif
+
 #define SPRN_CTR   0x009   /* Count Register */
 #define SPRN_DSCR  0x11
 #define SPRN_CTRLF 0x088
diff --git a/arch/powerpc/include/asm/reg_booke.h 
b/arch/powerpc/include/asm/reg_booke.h
index e68c69b..86ad812 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -150,8 +150,6 @@
  * or IBM 40x.
  */
 #ifdef CONFIG_BOOKE
-#define SPRN_PID   0x030   /* Process ID */
-#define SPRN_PID0  SPRN_PID/* Process ID Register 0 */
 #define SPRN_CSRR0 0x03A   /* Critical Save and Restore Register 0 */
 #define SPRN_CSRR1 0x03B   /* Critical Save and Restore Register 1 */
 #define SPRN_DEAR  0x03D   /* Data Error Address Register */
@@ -168,7 +166,6 @@
 #define SPRN_TCR   0x154   /* Timer Control Register */
 #endif /* Book E */
 #ifdef CONFIG_40x
-#define SPRN_PID   0x3B1   /* Process ID */
 #define SPRN_DBCR1 0x3BD   /* Debug Control Register 1 */  
 #define SPRN_ESR   0x3D4   /* Exception Syndrome Register */
 #define SPRN_DEAR  0x3D5   /* Data Error Address Register */


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v4 2/2] add icswx support

2011-03-02 Thread Tseng-Hui (Frank) Lin
Icswx is a PowerPC co-processor instruction to send data to a
co-processor. On Book-S processors the LPAR_ID and process ID (PID) of
the owning process are registered in the window context of the
co-processor at initial time. When the icswx instruction is executed,
the L2 generates a cop-reg transaction on PowerBus. The transaction has
no address and the processor does not perform an MMU access to
authenticate the transaction. The coprocessor compares the LPAR_ID and
the PID included in the transaction and the LPAR_ID and PID held in the
window context to determine if the process is authorized to generate the
transaction.

The OS needs to assign a 16-bit PID for the process. This cop-PID needs
to be updated during context switch. The cop-PID needs to be destroied
when the context is destroied.

Change log from V3:
- Rebase to linux/kernel/git/next/linux-next.git 2011-02-28
- Move the SPRN_PID changes into a separate patch.
- (Unchanged) Not to make icswx a cpu_user_feature as the icswx support
  is to be used by coprocessor drivers only.

arch/powerpc/platforms/Kconfig.cputype:
- Add ICSWX_LAZY_SWITCH

arch/powerpc/include/asm/mmu_context.h:
- Call switch_cop() in switch_mm() only if prev or next uses a coprocessor.

arch/powerpc/include/asm/mmu-hash64.h:
- Add cop_lock to mm_context_t
- Rename HASH64_MAX_PID to COP_PID_MAX and move to mmu_context_hash64.c

arch/powerpc/mm/mmu_context_hash64.c:
- Add a comment block to describe the usage of the icswx support code
- Define COP_PID_NONE, COP_PID_MIN, COP_PID_MAX for id allocation
- Define mtspr_acop() to make lazy switching a config option.
- change EXPORT_SYMBOL to EXPORT_SYMBOL_GPL.
- Remove EXPORT_SYMBOL(switch_cop) as it is only used in switch_mm().
- use_cop(): make id allocation code into new new_cop_pid().
- use_cop/drop_cop(): Use cop_lock to guard acop and cop_pid accesses
  between threads in the same process. Init sop_lock in init_new_context().
- Remove unnecessary cpu_has_feature() check from drop_cop() and switch_cop().
- Call drop_cop() instead of destroy_acop() in destroy_context().
- Remove unused destroy_acop() function.

Change log from v2:
- Make the code a CPU feature and return -NODEV if CPU doesn't have
  icswx co-processor instruction.
- Change the goto loop in use_cop() into a do-while loop.
- Change context destroy code into a new destroy_context_acop() function
  and #define it based on CONFIG_ICSWX.
- Remove mmput() from drop_cop().
- Fix some TAB/space problems.

Change log from V1:
- Change 2'nd parameter of use_cop() from struct task_struct *task
  to struct mm_struct *mm.
- Check for mm == current-active_mm before calling mtspr().
- Add a lock to guard acop related operations.
- Check for POWER7 CPU.
- Move the definition of SPRN_PID from reg_booke.h to avoid
  defining SPRN_PID in two different files.
- Rename pid to acop_pid.
- Change function name disuse_cop() to drop_cop().
- Add a comment to describe the two new fields in mm_context_t.
- Moving CONFIG_ICSWX from arch/powerpc/platforms/pseries/Kconfig
  to arch/powerpc/platforms/Kconfig.cputype.

Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com

---
 arch/powerpc/include/asm/cputable.h|4 +-
 arch/powerpc/include/asm/mmu-hash64.h  |   13 +++
 arch/powerpc/include/asm/mmu_context.h |   12 ++
 arch/powerpc/include/asm/reg.h |1 +
 arch/powerpc/mm/mmu_context_hash64.c   |  177 
 arch/powerpc/platforms/Kconfig.cputype |   43 
 6 files changed, 249 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h 
b/arch/powerpc/include/asm/cputable.h
index be3cdf9..c56e2df 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -202,6 +202,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_STCX_CHECKS_ADDRESSLONG_ASM_CONST(0x0200)
 #define CPU_FTR_POPCNTB
LONG_ASM_CONST(0x0400)
 #define CPU_FTR_POPCNTD
LONG_ASM_CONST(0x0800)
+#define CPU_FTR_ICSWX  LONG_ASM_CONST(0x1000)
 
 #ifndef __ASSEMBLY__
 
@@ -421,7 +422,8 @@ extern const char *powerpc_base_platform;
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
-   CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD)
+   CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD | \
+   CPU_FTR_ICSWX)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/mmu-hash64.h 
b/arch/powerpc/include/asm/mmu-hash64.h
index acac35d..b0c2549 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch

Re: [PATCH v2 3/3] powerpc: Add IO event interrupt support

2011-02-08 Thread Tseng-Hui (Frank) Lin
On Tue, 2011-02-08 at 08:46 +1100, Benjamin Herrenschmidt wrote:
 On Mon, 2011-02-07 at 15:40 -0600, Tseng-Hui (Frank) Lin wrote:
   We are -really- re-inventing interrupts and/or notifiers here, which
   I find a tad annoying..
  
  Agree. This is ugly. We could have just used the regular interrupt
  mechanism if the firmware didn't use shared rtas call and interrupt
  to report multiple types of events.
 
 A notifier wouldn't have worked ?

Yes. A notifier should have worked. Will change to use a notifier for
the chain.

 
 Cheers,
 Ben.
 
 
 ___
 Linuxppc-dev mailing list
 Linuxppc-dev@lists.ozlabs.org
 https://lists.ozlabs.org/listinfo/linuxppc-dev


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [PATCH v2 3/3] powerpc: Add IO event interrupt support

2011-02-07 Thread Tseng-Hui (Frank) Lin
On Mon, 2011-02-07 at 16:10 +1100, Benjamin Herrenschmidt wrote:
 On Wed, 2011-01-05 at 16:44 -0600, Tseng-Hui (Frank) Lin wrote:
  This patch adds support for handling IO Event interrupts which come
  through at the /event-sources/ibm,io-events device tree node.
 
  .../...
 
 The previous patches regarding the error log sometimes call it error log
 and sometimes event log. Can you consolidate that ?

Sure. The top level of the RTAS error/event log is for both error and
event. Starting V6 extension, they should be all event.

 
  +int pseries_ioei_register_handler(pseries_ioei_handler_t handler)
  +{
 
 Shouldn't we have a void * to attach with each client so it can put
 its private data there and get them back in the handler ?

Although not used at this moment, this is a good idea. Will add private
data.

 We are -really- re-inventing interrupts and/or notifiers here, which
 I find a tad annoying..

Agree. This is ugly. We could have just used the regular interrupt
mechanism if the firmware didn't use shared rtas call and interrupt
to report multiple types of events.

 
 Cheers,
 Ben.
 
 


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 0/3] powerpc: Add IO event interrupt support

2011-01-05 Thread Tseng-Hui (Frank) Lin

This series of patches adds support for handling IO Event interrupts which
come through at the /event-sources/ibm,io-events device tree node.

Change log from v1:
- Restructure the patch into 3 patches.
  = Move non-IBM specific v6 extended log definition to rtas.h.
  = Move IBM specific v6 extended log definition to pseries_event_log.h
and code to pseries_event_log.c.
- Add CONFIG_PSERIES_EVENT_LOG to pseries Kconfig
- Add CONFIG_IO_EVENT_IRQ to pseries Kconfig

io_events.h:
- Change C++ comments to C format.
- Add definitions for all known type, sub-types, and scopes.
- Change data type of rpc_data from u32 to u8 as the size of rpc_data is
  specified in rpc_field_len in bytes.
- Set maximum length for rpc_data.
- Change ioei_register_isr() and ioei_unregister_isr() declearation to match
  the change in io_events.c file

io_events.c:
- Use pseries_/PSERIES_ prefix for global symbols.
- Change to use list_head for ioei_consumer list.
- Remove scope from handler registeration.
- Change device_initcall() to machine_device_initcall()
- ioei_register_handler():
  = Return -ENODEV if IOEI not supported on the machine.
  = Change use spin_lock() to use spin_lock_irq().
- ioei_unregister_handler():
  = Change use spin_lock() to use spin_lock_irq().
- ioei_call_consumers():
  = Change spin_lock_irqsave() to spin_lock() because we are called from
an interrupt handler.
  = Return IRQ_HANDLED/IRQ_NONE if interrupt is handled/not handled.
  = Print an error message if no one claims the interrupt.
- io_event_interrupt():
  = Change to use rtas_data_buf and RTAS_DATA_BUF_SIZE for rtas_call().
  = Loop calling rtas_call() to pull in multiple events in one interrupt.
  = Split IO event section searching code into ioei_get_event().
- init_ioei_IRQ()
  = Check rtas_token() return code.


Signed-off-by: Mark Nelson ma...@au1.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 1/3] powerpc: Add v6 extended error log definitions

2011-01-05 Thread Tseng-Hui (Frank) Lin

This patch adds definitions of non-IBM specific v6 extended log definitions to 
rtas.h.

Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/include/asm/rtas.h|   45 -
 1 files changed, 45 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 3d35f8a..181e32a 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -158,7 +158,50 @@ struct rtas_error_log {
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];
+   unsigned char buffer[1];/* Start of extended log */
+   /* Variable length.  */
+};
+
+#define RTAS_V6EXT_LOG_FORMAT_EVENT_LOG14
+
+#define RTAS_V6EXT_COMPANY_ID_IBM  (('I'  24) | ('B'  16) | ('M'  8))
+
+/* RTAS extended error/event log, Version 6. The extended log starts
+ * from buffer field of struct rtas_error_log defined above.
+ */
+struct rtas_error_log_v6ext {
+   /* 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 */
+   /* Byte 1 */
+   uint32_t :8;/* 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 */
+   /* Byte 3 */
+   uint32_t :8;/* reserved */
+   /* Byte 4-11 */
+   uint8_t reserved[8];/* reserved */
+   /* Byte 12-15 */
+   uint32_t company_id;/* Company ID of the company*/
+   /* that defines the format for  */
+   /* the vendor specific log type */
+   /* Byte 16-end of log */
+   uint8_t vendor_log[1];  /* Start of vendor specific log */
+   /* Variable length. */
 };
 
 /*


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v2 2/3] powerpc: add IBM specific v6 extended error log support

2011-01-05 Thread Tseng-Hui (Frank) Lin

This patch adds IBM specific v6 extended log definition and utilities.

Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/platforms/pseries/Kconfig |6 +
 arch/powerpc/platforms/pseries/Makefile|1 +
 arch/powerpc/platforms/pseries/pseries_event_log.c |   62 +
 arch/powerpc/platforms/pseries/pseries_event_log.h |   50 
 4 files changed, 119 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index c667f0f..6f29642 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -37,6 +37,11 @@ config SCANLOG
tristate Scanlog dump interface
depends on RTAS_PROC  PPC_PSERIES
 
+config PSERIES_EVENT_LOG
+   bool
+   depends on PPC_PSERIES  RTAS_ERROR_LOGGING
+   default n
+
 config LPARCFG
bool LPAR Configuration Data
depends on PPC_PSERIES || PPC_ISERIES
@@ -81,3 +86,4 @@ config DTL
  which are accessible through a debugfs file.
 
  Say N if you are unsure.
+
diff --git a/arch/powerpc/platforms/pseries/Makefile 
b/arch/powerpc/platforms/pseries/Makefile
index 046ace9..1cc20ba 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_HCALL_STATS) += hvCall_inst.o
 obj-$(CONFIG_PHYP_DUMP)+= phyp_dump.o
 obj-$(CONFIG_CMM)  += cmm.o
 obj-$(CONFIG_DTL)  += dtl.o
+obj-$(CONFIG_PSERIES_EVENT_LOG)+= pseries_event_log.o
 
 ifeq ($(CONFIG_PPC_PSERIES),y)
 obj-$(CONFIG_SUSPEND)  += suspend.o
diff --git a/arch/powerpc/platforms/pseries/pseries_event_log.c 
b/arch/powerpc/platforms/pseries/pseries_event_log.c
new file mode 100644
index 000..c00837d
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_event_log.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010 Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+/*
+ * IBM pSerie platform event log specific functions.
+ * All data in this file is in big endian.
+ */
+
+#include linux/kernel.h
+#include linux/types.h
+
+#include asm/rtas.h
+
+#include pseries_event_log.h
+
+/*
+ * Find the size of data portation in a platform event log section.
+ */
+size_t pseries_elog_sect_data_len(void *sect_data_p)
+{
+   struct pseries_elog_section *p;
+
+   p = container_of(sect_data_p, struct pseries_elog_section, sect_data);
+   return(p-length - offsetof(struct pseries_elog_section, sect_data));
+}
+
+/*
+ * Find data portion of a specific section in extended error/event log.
+ * Return:
+ * location of section data
+ * NULL if not found
+ */
+void *pseries_elog_find_section(
+   struct rtas_error_log_v6ext *v6ext, size_t v6ext_len,
+   uint16_t sect_id)
+{
+   struct pseries_elog_section *sect_p;
+   uint8_t *p, *log_end;
+
+   if ((v6ext_len  sizeof(struct rtas_error_log_v6ext)) ||
+   (v6ext-log_format != RTAS_V6EXT_LOG_FORMAT_EVENT_LOG) ||
+   (v6ext-company_id != RTAS_V6EXT_COMPANY_ID_IBM))
+   return NULL;
+
+   log_end = (uint8_t *) v6ext + v6ext_len;
+   p = (uint8_t *) v6ext-vendor_log;
+   while (p  log_end) {
+   sect_p = (struct pseries_elog_section *) p;
+   if (sect_p-id == sect_id)
+   return sect_p-sect_data;
+   p += sect_p-length;
+   }
+
+   return NULL;
+}
+
diff --git a/arch/powerpc/platforms/pseries/pseries_event_log.h 
b/arch/powerpc/platforms/pseries/pseries_event_log.h
new file mode 100644
index 000..e7fc452
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/pseries_event_log.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2010 Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _PSERIES_PSERIES_EVENT_LOG_H
+#define _PSERIES_PSERIES_EVENT_LOG_H
+
+#include linux/types.h
+
+#include asm/rtas.h
+
+/* Two bytes ASCII section IDs */
+#define PSERIES_ELOG_SECT_ID_PRIV_HDR  (('P'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_USER_HDR  (('U'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_PRIMARY_SRC   (('P'  8) | 'S')
+#define PSERIES_ELOG_SECT_ID_EXTENDED_UH   (('E'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_FAILING_MTMS  (('M'  8) | 'T')
+#define PSERIES_ELOG_SECT_ID_SECONDARY_SRC (('S'  8) | 'S')
+#define PSERIES_ELOG_SECT_ID_DUMP_LOCATOR  (('D'  8) | 'H')
+#define PSERIES_ELOG_SECT_ID_FW_ERROR  (('S'  8) | 'W

[PATCH v2 3/3] powerpc: Add IO event interrupt support

2011-01-05 Thread Tseng-Hui (Frank) Lin

This patch adds support for handling IO Event interrupts which come
through at the /event-sources/ibm,io-events device tree node.

There is one ibm,io-events interrupt, but this interrupt might be used
for multiple I/O devices, each with their own separate driver. So, we
create a platform interrupt handler that will do the RTAS check-exception
call and then call the driver's interrupt handlers.

So, a driver for a device that uses IO Event interrupts will register
it's interrupt service routine (or interrupt handler) with the platform
code using pseries_ioei_register_isr(). This register function takes
a function pointer to the driver's handler.

A driver can unregister to stop receiving the IO Event interrupts using
pseries_ioei_unregister_isr(), passing it the same function pointer to the
driver's handler the driver was registered with.

The platform code registers ioei_interrupt() as the interrupt handler
for the ibm,io-events interrupt. Upon receiving an IO Event interrupt, it
pulls in the IO event from RTAS and pass the contents of the IO event
to those drivers' handlers that have registered until the IO event is
handled. Since there could be multiple drivers' handlers, drivers' handlers
are responsible to identify who the incoming IO event belongs to by checking
the event type, sub-type, and scope. A driver handler should return
IRQ_HANDLED If the IO event is handled or IRQ_NONE otherwise.

Signed-off-by: Mark Nelson ma...@au1.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin tseng...@us.ibm.com
---
 arch/powerpc/include/asm/io_event_irq.h|   54 
 arch/powerpc/platforms/pseries/Kconfig |   20 ++
 arch/powerpc/platforms/pseries/Makefile|1 +
 arch/powerpc/platforms/pseries/io_event_irq.c  |  260 
 4 files changed, 335 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/io_event_irq.h 
b/arch/powerpc/include/asm/io_event_irq.h
new file mode 100644
index 000..447f23d
--- /dev/null
+++ b/arch/powerpc/include/asm/io_event_irq.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2010 Mark Nelson and Tseng-Hui (Frank) Lin, IBM Corporation
+ *
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public License
+ *  as published by the Free Software Foundation; either version
+ *  2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _ASM_POWERPC_IO_EVENT_IRQ_H
+#define _ASM_POWERPC_IO_EVENT_IRQ_H
+
+#define PSERIES_IOEI_RPC_MAX_LEN 216
+
+#define PSERIES_IOEI_TYPE_ERR_DETECTED 0x01
+#define PSERIES_IOEI_TYPE_ERR_RECOVERED0x02
+#define PSERIES_IOEI_TYPE_EVENT0x03
+#define PSERIES_IOEI_TYPE_RPC_PASS_THRU0x04
+
+#define PSERIES_IOEI_SUBTYPE_NOT_APP   0x00
+#define PSERIES_IOEI_SUBTYPE_REBALANCE_REQ 0x01
+#define PSERIES_IOEI_SUBTYPE_NODE_ONLINE   0x03
+#define PSERIES_IOEI_SUBTYPE_NODE_OFFLINE  0x04
+#define PSERIES_IOEI_SUBTYPE_DUMP_SIZE_CHANGE  0x05
+#define PSERIES_IOEI_SUBTYPE_TORRENT_IRV_UPDATE0x06
+#define PSERIES_IOEI_SUBTYPE_TORRENT_HFI_CFGED 0x07
+
+#define PSERIES_IOEI_SCOPE_NOT_APP 0x00
+#define PSERIES_IOEI_SCOPE_RIO_HUB 0x36
+#define PSERIES_IOEI_SCOPE_RIO_BRIDGE  0x37
+#define PSERIES_IOEI_SCOPE_PHB 0x38
+#define PSERIES_IOEI_SCOPE_EADS_GLOBAL 0x39
+#define PSERIES_IOEI_SCOPE_EADS_SLOT   0x3A
+#define PSERIES_IOEI_SCOPE_TORRENT_HUB 0x3B
+#define PSERIES_IOEI_SCOPE_SERVICE_PROC0x51
+
+/* Platform Event Log Format, Version 6, data portition of IO event section */
+struct pseries_io_event_sect_data {
+   uint8_t event_type; /* 0x00 IO-Event Type   */
+   uint8_t rpc_data_len;   /* 0x01 RPC data length */
+   uint8_t scope;  /* 0x02 Error/Event Scope   */
+   uint8_t event_subtype;  /* 0x03 I/O-Event Sub-Type  */
+   uint32_t drc_index; /* 0x04 DRC Index   */
+   uint8_t rpc_data[PSERIES_IOEI_RPC_MAX_LEN];
+   /* 0x08 RPC Data (0-216 bytes,  */
+   /* padded to 4 bytes alignment) */
+};
+
+typedef irqreturn_t (*pseries_ioei_handler_t) (struct 
pseries_io_event_sect_data *);
+
+extern int pseries_ioei_register_handler(pseries_ioei_handler_t handler);
+extern int pseries_ioei_unregister_handler(pseries_ioei_handler_t handler);
+
+#endif /* _ASM_POWERPC_IO_EVENT_IRQ_H */
diff --git a/arch/powerpc/platforms/pseries/Kconfig 
b/arch/powerpc/platforms/pseries/Kconfig
index c667f0f..0f36aad 100644
--- a/arch/powerpc/platforms/pseries/Kconfig
+++ b/arch/powerpc/platforms/pseries/Kconfig
@@ -42,6 +42,25 @@  bool
depends on PPC_PSERIES  RTAS_ERROR_LOGGING
default n
 
+config IO_EVENT_IRQ
+   bool IO Event Interrupt support
+   depends on PPC_PSERIES
+   select PSERIES_EVENT_LOG
+   default y
+   help
+ Select this option, if you want to enable

[PATCH v3] add icswx support

2010-10-19 Thread Tseng-Hui (Frank) Lin
icswx is a PowerPC co-processor instruction to send data to a
co-processor. On Book-S processors the LPAR_ID and process ID (PID) of
the owning process are registered in the window context of the
co-processor at initial time. When the icswx instruction is executed,
the L2 generates a cop-reg transaction on PowerBus. The transaction has
no address and the processor does not perform an MMU access to
authenticate the transaction. The coprocessor compares the LPAR_ID and
the PID included in the transaction and the LPAR_ID and PID held in the
window context to determine if the process is authorized to generate the
transaction.

The OS needs to assign a 16-bit PID for the process. This cop-PID needs
to be updated during context switch. The cop-PID needs to be destroyed
when the context is destroyed.

Change log from v2:
- Make the code a CPU feature and return -NODEV if CPU doesn't have
  icswx co-processor instruction.
- Change the goto loop in use_cop() into a do-while loop.
- Change context destroy code into a new destroy_context_acop() function
  and #define it based on CONFIG_ICSWX.
- Remove mmput() from drop_cop().
- Fix some TAB/space problems.

Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com

---
 arch/powerpc/include/asm/cputable.h|4 +-
 arch/powerpc/include/asm/mmu-hash64.h  |5 ++
 arch/powerpc/include/asm/mmu_context.h |6 ++
 arch/powerpc/include/asm/reg.h |   11 +++
 arch/powerpc/include/asm/reg_booke.h   |3 -
 arch/powerpc/mm/mmu_context_hash64.c   |  109

 arch/powerpc/platforms/Kconfig.cputype |   17 +
 7 files changed, 151 insertions(+), 4 deletions(-)

diff --git a/arch/powerpc/include/asm/cputable.h
b/arch/powerpc/include/asm/cputable.h
index 3a40a99..bbb4e2c 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -198,6 +198,7 @@ extern const char *powerpc_base_platform;
 #define CPU_FTR_CP_USE_DCBTZ   LONG_ASM_CONST(0x0040)
 #define CPU_FTR_UNALIGNED_LD_STD   LONG_ASM_CONST(0x0080)
 #define CPU_FTR_ASYM_SMT   LONG_ASM_CONST(0x0100)
+#define CPU_FTR_ICSWX  LONG_ASM_CONST(0x0200)
 
 #ifndef __ASSEMBLY__
 
@@ -413,7 +414,8 @@ extern const char *powerpc_base_platform;
CPU_FTR_MMCRA | CPU_FTR_SMT | \
CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \
-   CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT)
+   CPU_FTR_DSCR | CPU_FTR_SAO  | CPU_FTR_ASYM_SMT | \
+   CPU_FTR_ICSWX)
 #define CPU_FTRS_CELL  (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
diff --git a/arch/powerpc/include/asm/mmu-hash64.h
b/arch/powerpc/include/asm/mmu-hash64.h
index acac35d..6c1ab90 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -423,6 +423,11 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_ICSWX
+   unsigned long acop; /* mask of enabled coprocessor types */
+#define HASH64_MAX_PID (0x)
+   unsigned int acop_pid;  /* pid value used with coprocessors */
+#endif /* CONFIG_ICSWX */
 } mm_context_t;
 
 
diff --git a/arch/powerpc/include/asm/mmu_context.h
b/arch/powerpc/include/asm/mmu_context.h
index 81fb412..88118de 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -80,6 +80,12 @@ static inline void switch_mm(struct mm_struct *prev,
struct mm_struct *next,
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
 
+#ifdef CONFIG_ICSWX
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct mm_struct *mm);
+extern void drop_cop(unsigned long acop, struct mm_struct *mm);
+#endif /* CONFIG_ICSWX */
+
 /*
  * After we have set current-mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index ff0005eec..b86d876 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -170,8 +170,19 @@
 #define SPEFSCR_FRMC   0x0003  /* Embedded FP rounding mode control
*/
 
 /* Special Purpose Registers (SPRNs)*/
+
+#ifdef CONFIG_40x
+#define SPRN_PID   0x3B1   /* Process ID */
+#else
+#define SPRN_PID   0x030   /* Process ID */
+#ifdef CONFIG_BOOKE
+#define SPRN_PID0  SPRN_PID/* Process ID Register 0 */
+#endif
+#endif
+
 #define SPRN_CTR   0x009   /* Count Register */
 #define SPRN_DSCR  0x11
+#define SPRN_ACOP  0x1F/* Available Coprocessor Register */
 #define SPRN_CTRLF 0x088
 #define SPRN_CTRLT 0x098
 #define   CTRL_CT  0xc000

Re: [PATCH] add icswx support v2

2010-10-14 Thread Tseng-Hui (Frank) Lin
On Wed, 2010-10-13 at 11:52 +1100, Michael Neuling wrote:
 In message 1286855108.14049.8.ca...@flin.austin.ibm.com you wrote:
  icswx is a PowerPC co-processor instruction to send data to a
  co-processor. On Book-S processors the LPAR_ID and process ID (PID) of
  the owning process are registered in the window context of the
  co-processor at initial time. When the icswx instruction is executed,
  the L2 generates a cop-reg transaction on PowerBus. The transaction has
  no address and the processor does not perform an MMU access to
  authenticate the transaction. The coprocessor compares the LPAR_ID and
  the PID included in the transaction and the LPAR_ID and PID held in the
  window context to determine if the process is authorized to generate the
  transaction.
  
  This patch adds icswx co-processor instruction support.
 
 Can you describe the ABI a bit?  
 
 How has this changed from version 1?
 

The icswx instruction itself does nothing but generating a cop-req
transaction on PowerBus. The cop-req transaction causes 1 cache
line of data (128 bytes) sent to the co-processor. This provides
a low latency mechanism for sending small amount of data without
the co-processor becoming a master on the PowerBus.

Since the transaction has no address and the processor does not
perform an MMU access to authenticate the transaction, the
co-processor relys on the the LPAR_ID and PID to determine if
the process is authorized to generate the transaction.

The OS needs to assign a 16-bit PID for the process. This
cop-PID needs needs to be updated during context switch. The
cop-PID needs to be destroied when the context is destroied.

Change log from v1:
- Change 2'nd parameter of use_cop() from struct task_struct *task
  to struct mm_struct *mm.
- Check for mm == current-active_mm before calling mtspr().
- Add a lock to guard acop related operations.
- Check for POWER7 CPU.
- Move the definition of SPRN_PID from reg_booke.h to avoid
  defining SPRN_PID in two different files.
- Rename pid to acop_pid.
- Change function name disuse_cop() to drop_cop().
- Add a comment to describe the two new fields in mm_context_t.
- Moving CONFIG_ICSWX from arch/powerpc/platforms/pseries/Kconfig
  to arch/powerpc/platforms/Kconfig.cputype

All other comments will be addressed in a new patch.

 Patch has been whitespace munged aswell.
 
 More comments below...
 
  
  Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
  Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com
  ---
   arch/powerpc/include/asm/mmu-hash64.h  |5 ++
   arch/powerpc/include/asm/mmu_context.h |6 ++
   arch/powerpc/include/asm/reg.h |   12 
   arch/powerpc/include/asm/reg_booke.h   |3 -
   arch/powerpc/mm/mmu_context_hash64.c   |  105
  
   arch/powerpc/platforms/Kconfig.cputype |   16 +
   6 files changed, 144 insertions(+), 3 deletions(-)
  
  diff --git a/arch/powerpc/include/asm/mmu-hash64.h
  b/arch/powerpc/include/asm/mmu-hash64.h
  index acac35d..6c1ab90 100644
  --- a/arch/powerpc/include/asm/mmu-hash64.h
  +++ b/arch/powerpc/include/asm/mmu-hash64.h
  @@ -423,6 +423,11 @@ typedef struct {
   #ifdef CONFIG_PPC_SUBPAGE_PROT
  struct subpage_prot_table spt;
   #endif /* CONFIG_PPC_SUBPAGE_PROT */
  +#ifdef CONFIG_ICSWX
  +   unsigned long acop; /* mask of enabled coprocessor types */
  +#define HASH64_MAX_PID (0x)
  +   unsigned int acop_pid;  /* pid value used with coprocessors */
  +#endif /* CONFIG_ICSWX */
   } mm_context_t;
   
   
  diff --git a/arch/powerpc/include/asm/mmu_context.h
  b/arch/powerpc/include/asm/mmu_context.h
  index 81fb412..88118de 100644
  --- a/arch/powerpc/include/asm/mmu_context.h
  +++ b/arch/powerpc/include/asm/mmu_context.h
  @@ -80,6 +80,12 @@ static inline void switch_mm(struct mm_struct *prev,
  struct mm_struct *next,
   
   #define deactivate_mm(tsk,mm)  do { } while (0)
   
  +#ifdef CONFIG_ICSWX
  +extern void switch_cop(struct mm_struct *next);
  +extern int use_cop(unsigned long acop, struct mm_struct *mm);
  +extern void drop_cop(unsigned long acop, struct mm_struct *mm);
  +#endif /* CONFIG_ICSWX */
  +
   /*
* After we have set current-mm to a new value, this activates
* the context for the new mm so we see the new mappings.
  diff --git a/arch/powerpc/include/asm/reg.h
  b/arch/powerpc/include/asm/reg.h
  index ff0005eec..9bbf178 100644
  --- a/arch/powerpc/include/asm/reg.h
  +++ b/arch/powerpc/include/asm/reg.h
  @@ -170,8 +170,19 @@
   #define SPEFSCR_FRMC   0x0003  /* Embedded FP rounding mode co
 ntrol
  */
   
   /* Special Purpose Registers (SPRNs)*/
  +
  +#ifdef CONFIG_40x
  +#define SPRN_PID   0x3B1   /* Process ID */
  +#else
  +#defineSPRN_PID0x030   /* Process ID */
  +#ifdef CONFIG_BOOKE
  +#defineSPRN_PID0   SPRN_PID/* Process ID Register 0 */
  +#endif
  +#endif
  +
 
 Why are you moving these definitions?
 
   #define SPRN_CTR   0x009   /* Count Register */
   #define

[PATCH] add icswx support v2

2010-10-11 Thread Tseng-Hui (Frank) Lin
icswx is a PowerPC co-processor instruction to send data to a
co-processor. On Book-S processors the LPAR_ID and process ID (PID) of
the owning process are registered in the window context of the
co-processor at initial time. When the icswx instruction is executed,
the L2 generates a cop-reg transaction on PowerBus. The transaction has
no address and the processor does not perform an MMU access to
authenticate the transaction. The coprocessor compares the LPAR_ID and
the PID included in the transaction and the LPAR_ID and PID held in the
window context to determine if the process is authorized to generate the
transaction.

This patch adds icswx co-processor instruction support.

Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/mmu-hash64.h  |5 ++
 arch/powerpc/include/asm/mmu_context.h |6 ++
 arch/powerpc/include/asm/reg.h |   12 
 arch/powerpc/include/asm/reg_booke.h   |3 -
 arch/powerpc/mm/mmu_context_hash64.c   |  105

 arch/powerpc/platforms/Kconfig.cputype |   16 +
 6 files changed, 144 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h
b/arch/powerpc/include/asm/mmu-hash64.h
index acac35d..6c1ab90 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -423,6 +423,11 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+#ifdef CONFIG_ICSWX
+   unsigned long acop; /* mask of enabled coprocessor types */
+#define HASH64_MAX_PID (0x)
+   unsigned int acop_pid;  /* pid value used with coprocessors */
+#endif /* CONFIG_ICSWX */
 } mm_context_t;
 
 
diff --git a/arch/powerpc/include/asm/mmu_context.h
b/arch/powerpc/include/asm/mmu_context.h
index 81fb412..88118de 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -80,6 +80,12 @@ static inline void switch_mm(struct mm_struct *prev,
struct mm_struct *next,
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
 
+#ifdef CONFIG_ICSWX
+extern void switch_cop(struct mm_struct *next);
+extern int use_cop(unsigned long acop, struct mm_struct *mm);
+extern void drop_cop(unsigned long acop, struct mm_struct *mm);
+#endif /* CONFIG_ICSWX */
+
 /*
  * After we have set current-mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index ff0005eec..9bbf178 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -170,8 +170,19 @@
 #define SPEFSCR_FRMC   0x0003  /* Embedded FP rounding mode control
*/
 
 /* Special Purpose Registers (SPRNs)*/
+
+#ifdef CONFIG_40x
+#define SPRN_PID   0x3B1   /* Process ID */
+#else
+#defineSPRN_PID0x030   /* Process ID */
+#ifdef CONFIG_BOOKE
+#defineSPRN_PID0   SPRN_PID/* Process ID Register 0 */
+#endif
+#endif
+
 #define SPRN_CTR   0x009   /* Count Register */
 #define SPRN_DSCR  0x11
+#define SPRN_ACOP  0x1F/* Available Coprocessor Register */
 #define SPRN_CTRLF 0x088
 #define SPRN_CTRLT 0x098
 #define   CTRL_CT  0xc000  /* current thread */
@@ -879,6 +890,7 @@
 #define PV_POWER5  0x003A
 #define PV_POWER5p 0x003B
 #define PV_970FX   0x003C
+#define PV_POWER7  0x003F
 #define PV_630 0x0040
 #define PV_630p0x0041
 #define PV_970MP   0x0044
diff --git a/arch/powerpc/include/asm/reg_booke.h
b/arch/powerpc/include/asm/reg_booke.h
index 667a498..5b0c781 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -150,8 +150,6 @@
  * or IBM 40x.
  */
 #ifdef CONFIG_BOOKE
-#define SPRN_PID   0x030   /* Process ID */
-#define SPRN_PID0  SPRN_PID/* Process ID Register 0 */
 #define SPRN_CSRR0 0x03A   /* Critical Save and Restore Register 0 */
 #define SPRN_CSRR1 0x03B   /* Critical Save and Restore Register 1 */
 #define SPRN_DEAR  0x03D   /* Data Error Address Register */
@@ -168,7 +166,6 @@
 #define SPRN_TCR   0x154   /* Timer Control Register */
 #endif /* Book E */
 #ifdef CONFIG_40x
-#define SPRN_PID   0x3B1   /* Process ID */
 #define SPRN_DBCR1 0x3BD   /* Debug Control Register 1 */  
 #define SPRN_ESR   0x3D4   /* Exception Syndrome Register */
 #define SPRN_DEAR  0x3D5   /* Data Error Address Register */
diff --git a/arch/powerpc/mm/mmu_context_hash64.c
b/arch/powerpc/mm/mmu_context_hash64.c
index 2535828..8f432b6 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -18,6 +18,7 @@
 #include linux/mm.h
 #include linux/spinlock.h
 #include linux/idr.h
+#include linux/percpu.h
 #include linux/module.h
 #include linux/gfp.h
 
@@ -26,6 +27,103 @@
 static DEFINE_SPINLOCK(mmu_context_lock);
 static

Re: [PATCH] add icswx support

2010-04-27 Thread Tseng-Hui (Frank) Lin
On Sat, 2010-04-24 at 10:55 +1000, Benjamin Herrenschmidt wrote:
 On Fri, 2010-04-23 at 17:04 -0500, Tseng-Hui (Frank) Lin wrote:
  Add Power7 icswx co-processor instruction support.
 
 Please provide a -much- more detailed explanation of what it is, what it
 does and why it requires hooking into the MMU context switch code. _I_
 know these things but nobody else on the list does which limits the
 ability of people to review your patch.


icswx is a PowerPC co-processor instruction to send data to a 
co-processor. On Book-S processors the LPAR_ID and process ID (PID) of 
the owning process are registered in the window context of the
co-processor at initial time. When the icswx instruction is executed,
the L2 generates a cop-reg transaction on PowerBus. The transaction has
no address and the processor does not perform an MMU access to 
authenticate the transaction. The coprocessor compares the LPAR_ID and
the PID included in the transaction and the LPAR_ID and PID held in the
window context to determine if the process is authorized to generate the
transaction.

  Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
  Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com
  ---
   arch/powerpc/include/asm/mmu-hash64.h  |3 +
   arch/powerpc/include/asm/mmu_context.h |4 ++
   arch/powerpc/include/asm/reg.h |3 +
   arch/powerpc/mm/mmu_context_hash64.c   |   79
  
   4 files changed, 89 insertions(+), 0 deletions(-)
  
  diff --git a/arch/powerpc/include/asm/mmu-hash64.h
  b/arch/powerpc/include/asm/mmu-hash64.h
  index 2102b21..ba5727d 100644
  --- a/arch/powerpc/include/asm/mmu-hash64.h
  +++ b/arch/powerpc/include/asm/mmu-hash64.h
  @@ -421,6 +421,9 @@ typedef struct {
   #ifdef CONFIG_PPC_SUBPAGE_PROT
  struct subpage_prot_table spt;
   #endif /* CONFIG_PPC_SUBPAGE_PROT */
  +   unsigned long acop;
  +#define HASH64_MAX_PID (0x)
  +   unsigned int pid;
 
 Please add a comment as to what those two fields are about, something
 like acop; /* mask of enabled coprocessor types */ and pid /* pid
 value used with coprocessors */ or something like that.
 
   } mm_context_t;
   
  
  diff --git a/arch/powerpc/include/asm/mmu_context.h
  b/arch/powerpc/include/asm/mmu_context.h
  index 26383e0..d6c8841 100644
  --- a/arch/powerpc/include/asm/mmu_context.h
  +++ b/arch/powerpc/include/asm/mmu_context.h
  @@ -78,6 +78,10 @@ static inline void switch_mm(struct mm_struct *prev,
  struct mm_struct *next,
   
   #define deactivate_mm(tsk,mm)  do { } while (0)
   
  +extern void switch_cop(struct mm_struct *next);
  +extern int  use_cop(unsigned long acop, struct task_struct *task);
   ^ remove that space
  +extern void disuse_cop(unsigned long acop, struct mm_struct *mm);
 
 I'd prefer drop or forget :-)
 
  +
   /*
* After we have set current-mm to a new value, this activates
* the context for the new mm so we see the new mappings.
  diff --git a/arch/powerpc/include/asm/reg.h
  b/arch/powerpc/include/asm/reg.h
  index 5572e86..30503f8 100644
  --- a/arch/powerpc/include/asm/reg.h
  +++ b/arch/powerpc/include/asm/reg.h
  @@ -516,6 +516,9 @@
   #define SPRN_SIAR  780
   #define SPRN_SDAR  781
   
  +#define SPRN_ACOP   31
  +#define SPRN_PID48
  +
 
 Remove the definition of SPRN_PID from reg_booke.h to avoid a double
 definition then.
 
   #define SPRN_PA6T_MMCR0 795
   #define   PA6T_MMCR0_EN0   0x0001UL
   #define   PA6T_MMCR0_EN1   0x0002UL
  diff --git a/arch/powerpc/mm/mmu_context_hash64.c
  b/arch/powerpc/mm/mmu_context_hash64.c
  index 2535828..d0a79f6 100644
  --- a/arch/powerpc/mm/mmu_context_hash64.c
  +++ b/arch/powerpc/mm/mmu_context_hash64.c
  @@ -18,6 +18,7 @@
   #include linux/mm.h
   #include linux/spinlock.h
   #include linux/idr.h
  +#include linux/percpu.h
   #include linux/module.h
   #include linux/gfp.h
   
  @@ -25,6 +26,82 @@
   
   static DEFINE_SPINLOCK(mmu_context_lock);
   static DEFINE_IDA(mmu_context_ida);
  +static DEFINE_IDA(cop_ida);
  +
  +/* Lazy switch the ACOP register */
  +static DEFINE_PER_CPU(unsigned long, acop_reg);
  +
  +void switch_cop(struct mm_struct *next)
  +{
  +   mtspr(SPRN_PID, next-context.pid);
  +   if (next-context.pid 
  +   __get_cpu_var(acop_reg) != next-context.acop) {
  +   mtspr(SPRN_ACOP, next-context.acop);
  +   __get_cpu_var(acop_reg) = next-context.acop;
  +   }
  +}
 
 The above doesn't appear to be called anywhere ?
 
  +int use_cop(unsigned long acop, struct task_struct *task)
  +{
  +   int pid;
  +   int err;
  +   struct mm_struct *mm = get_task_mm(task);
  +
  +   if (!mm)
  +   return -EINVAL;
  +
  +   if (!mm-context.pid) {
  +   if (!ida_pre_get(cop_ida, GFP_KERNEL))
  +   return -ENOMEM;
  +again:
  +   spin_lock(mmu_context_lock);
  +   err = ida_get_new_above(cop_ida, 1, pid);
  +   spin_unlock(mmu_context_lock);
  +
  +   if (err == -EAGAIN

[PATCH] add icswx support

2010-04-23 Thread Tseng-Hui (Frank) Lin
Add Power7 icswx co-processor instruction support.

Signed-off-by: Sonny Rao sonny...@linux.vnet.ibm.com
Signed-off-by: Tseng-Hui (Frank) Lin th...@linux.vnet.ibm.com
---
 arch/powerpc/include/asm/mmu-hash64.h  |3 +
 arch/powerpc/include/asm/mmu_context.h |4 ++
 arch/powerpc/include/asm/reg.h |3 +
 arch/powerpc/mm/mmu_context_hash64.c   |   79

 4 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h
b/arch/powerpc/include/asm/mmu-hash64.h
index 2102b21..ba5727d 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -421,6 +421,9 @@ typedef struct {
 #ifdef CONFIG_PPC_SUBPAGE_PROT
struct subpage_prot_table spt;
 #endif /* CONFIG_PPC_SUBPAGE_PROT */
+   unsigned long acop;
+#define HASH64_MAX_PID (0x)
+   unsigned int pid;
 } mm_context_t;
 
 
diff --git a/arch/powerpc/include/asm/mmu_context.h
b/arch/powerpc/include/asm/mmu_context.h
index 26383e0..d6c8841 100644
--- a/arch/powerpc/include/asm/mmu_context.h
+++ b/arch/powerpc/include/asm/mmu_context.h
@@ -78,6 +78,10 @@ static inline void switch_mm(struct mm_struct *prev,
struct mm_struct *next,
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
 
+extern void switch_cop(struct mm_struct *next);
+extern int  use_cop(unsigned long acop, struct task_struct *task);
+extern void disuse_cop(unsigned long acop, struct mm_struct *mm);
+
 /*
  * After we have set current-mm to a new value, this activates
  * the context for the new mm so we see the new mappings.
diff --git a/arch/powerpc/include/asm/reg.h
b/arch/powerpc/include/asm/reg.h
index 5572e86..30503f8 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -516,6 +516,9 @@
 #define SPRN_SIAR  780
 #define SPRN_SDAR  781
 
+#define SPRN_ACOP   31
+#define SPRN_PID48
+
 #define SPRN_PA6T_MMCR0 795
 #define   PA6T_MMCR0_EN0   0x0001UL
 #define   PA6T_MMCR0_EN1   0x0002UL
diff --git a/arch/powerpc/mm/mmu_context_hash64.c
b/arch/powerpc/mm/mmu_context_hash64.c
index 2535828..d0a79f6 100644
--- a/arch/powerpc/mm/mmu_context_hash64.c
+++ b/arch/powerpc/mm/mmu_context_hash64.c
@@ -18,6 +18,7 @@
 #include linux/mm.h
 #include linux/spinlock.h
 #include linux/idr.h
+#include linux/percpu.h
 #include linux/module.h
 #include linux/gfp.h
 
@@ -25,6 +26,82 @@
 
 static DEFINE_SPINLOCK(mmu_context_lock);
 static DEFINE_IDA(mmu_context_ida);
+static DEFINE_IDA(cop_ida);
+
+/* Lazy switch the ACOP register */
+static DEFINE_PER_CPU(unsigned long, acop_reg);
+
+void switch_cop(struct mm_struct *next)
+{
+   mtspr(SPRN_PID, next-context.pid);
+   if (next-context.pid 
+   __get_cpu_var(acop_reg) != next-context.acop) {
+   mtspr(SPRN_ACOP, next-context.acop);
+   __get_cpu_var(acop_reg) = next-context.acop;
+   }
+}
+
+int use_cop(unsigned long acop, struct task_struct *task)
+{
+   int pid;
+   int err;
+   struct mm_struct *mm = get_task_mm(task);
+
+   if (!mm)
+   return -EINVAL;
+
+   if (!mm-context.pid) {
+   if (!ida_pre_get(cop_ida, GFP_KERNEL))
+   return -ENOMEM;
+again:
+   spin_lock(mmu_context_lock);
+   err = ida_get_new_above(cop_ida, 1, pid);
+   spin_unlock(mmu_context_lock);
+
+   if (err == -EAGAIN)
+   goto again;
+   else if (err)
+   return err;
+
+   if (pid  HASH64_MAX_PID) {
+   spin_lock(mmu_context_lock);
+   ida_remove(cop_ida, pid);
+   spin_unlock(mmu_context_lock);
+   return -EBUSY;
+   }
+   mm-context.pid = pid;
+   mtspr(SPRN_PID,  mm-context.pid);
+   }
+   mm-context.acop |= acop;
+
+   get_cpu_var(acop_reg) = mm-context.acop;
+   mtspr(SPRN_ACOP, mm-context.acop);
+   put_cpu_var(acop_reg);
+
+   return mm-context.pid;
+}
+EXPORT_SYMBOL(use_cop);
+
+void disuse_cop(unsigned long acop, struct mm_struct *mm)
+{
+   if (WARN_ON(!mm))
+   return;
+
+   mm-context.acop = ~acop;
+   if (!mm-context.acop) {
+   spin_lock(mmu_context_lock);
+   ida_remove(cop_ida, mm-context.pid);
+   spin_unlock(mmu_context_lock);
+   mm-context.pid = 0;
+   mtspr(SPRN_PID, 0);
+   } else {
+   get_cpu_var(acop_reg) = mm-context.acop;
+   mtspr(SPRN_ACOP, mm-context.acop);
+   put_cpu_var(acop_reg);
+   }
+   mmput(mm);
+}
+EXPORT_SYMBOL(disuse_cop);
 
 /*
  * The proto-VSID space has 2^35 - 1 segments available for user
mappings.
@@ -94,6 +171,8 @@ EXPORT_SYMBOL_GPL(__destroy_context);
 void destroy_context(struct mm_struct *mm)
 {
__destroy_context(mm-context.id);
+   if (mm