Re: [PATCH v2] powerpc/powernv: Platform dump interface

2014-03-26 Thread Vasant Hegde

On 03/25/2014 11:22 AM, Anton Blanchard wrote:

Hi Vasant,


On 02/09/2014 02:50 AM, Anton Blanchard wrote:


Hi Vasant,


+static void free_dump_sg_list(struct opal_sg_list *list)
+{
+   struct opal_sg_list *sg1;
+   while (list) {
+   sg1 = list-next;
+   kfree(list);
+   list = sg1;
+   }
+   list = NULL;
+}
+
+/*
+ * Build dump buffer scatter gather list
+ */
+static struct opal_sg_list *dump_data_to_sglist(void)
+{
+   struct opal_sg_list *sg1, *list = NULL;
+   void *addr;
+   int64_t size;
+
+   addr = dump_record.buffer;
+   size = dump_record.size;
+
+   sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+   if (!sg1)
+   goto nomem;
+
+   list = sg1;
+   sg1-num_entries = 0;
+   while (size  0) {
+   /* Translate virtual address to physical address
*/
+   sg1-entry[sg1-num_entries].data =
+   (void *)(vmalloc_to_pfn(addr) 
PAGE_SHIFT); +
+   if (size  PAGE_SIZE)
+   sg1-entry[sg1-num_entries].length =
PAGE_SIZE;
+   else
+   sg1-entry[sg1-num_entries].length =
size; +
+   sg1-num_entries++;
+   if (sg1-num_entries = SG_ENTRIES_PER_NODE) {
+   sg1-next = kzalloc(PAGE_SIZE,
GFP_KERNEL);
+   if (!sg1-next)
+   goto nomem;
+
+   sg1 = sg1-next;
+   sg1-num_entries = 0;
+   }
+   addr += PAGE_SIZE;
+   size -= PAGE_SIZE;
+   }
+   return list;
+
+nomem:
+   pr_err(%s : Failed to allocate memory\n, __func__);
+   free_dump_sg_list(list);
+   return NULL;
+}
+
+/*
+ * Translate sg list address to absolute
+ */
+static void sglist_to_phy_addr(struct opal_sg_list *list)
+{
+   struct opal_sg_list *sg, *next;
+
+   for (sg = list; sg; sg = next) {
+   next = sg-next;
+   /* Don't translate NULL pointer for last entry */
+   if (sg-next)
+   sg-next = (struct opal_sg_list
*)__pa(sg-next);
+   else
+   sg-next = NULL;
+
+   /* Convert num_entries to length */
+   sg-num_entries =
+   sg-num_entries * sizeof(struct
opal_sg_entry) + 16;
+   }
+}
+
+static void free_dump_data_buf(void)
+{
+   vfree(dump_record.buffer);
+   dump_record.size = 0;
+}




Anton,


This looks identical to the code in opal-flash.c. Considering how
complicated it is, can we put it somewhere common?


Thanks for the review.. Will look into it next week.




Anton,


This doesn't appear to have been fixed in the version that went into
next.



Stewart rewrote dump interface.. That set of patch went into next, not my 
original patch..
Yes.. SG list separation is not yet done.. Never got a chance to look into this 
one.. Will try to

do it soon.

-Vasant


Anton



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

Re: [PATCH v2] powerpc/powernv: Platform dump interface

2014-03-24 Thread Anton Blanchard
Hi Vasant,

 On 02/09/2014 02:50 AM, Anton Blanchard wrote:
 
  Hi Vasant,
 
  +static void free_dump_sg_list(struct opal_sg_list *list)
  +{
  +  struct opal_sg_list *sg1;
  +  while (list) {
  +  sg1 = list-next;
  +  kfree(list);
  +  list = sg1;
  +  }
  +  list = NULL;
  +}
  +
  +/*
  + * Build dump buffer scatter gather list
  + */
  +static struct opal_sg_list *dump_data_to_sglist(void)
  +{
  +  struct opal_sg_list *sg1, *list = NULL;
  +  void *addr;
  +  int64_t size;
  +
  +  addr = dump_record.buffer;
  +  size = dump_record.size;
  +
  +  sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
  +  if (!sg1)
  +  goto nomem;
  +
  +  list = sg1;
  +  sg1-num_entries = 0;
  +  while (size  0) {
  +  /* Translate virtual address to physical address
  */
  +  sg1-entry[sg1-num_entries].data =
  +  (void *)(vmalloc_to_pfn(addr) 
  PAGE_SHIFT); +
  +  if (size  PAGE_SIZE)
  +  sg1-entry[sg1-num_entries].length =
  PAGE_SIZE;
  +  else
  +  sg1-entry[sg1-num_entries].length =
  size; +
  +  sg1-num_entries++;
  +  if (sg1-num_entries = SG_ENTRIES_PER_NODE) {
  +  sg1-next = kzalloc(PAGE_SIZE,
  GFP_KERNEL);
  +  if (!sg1-next)
  +  goto nomem;
  +
  +  sg1 = sg1-next;
  +  sg1-num_entries = 0;
  +  }
  +  addr += PAGE_SIZE;
  +  size -= PAGE_SIZE;
  +  }
  +  return list;
  +
  +nomem:
  +  pr_err(%s : Failed to allocate memory\n, __func__);
  +  free_dump_sg_list(list);
  +  return NULL;
  +}
  +
  +/*
  + * Translate sg list address to absolute
  + */
  +static void sglist_to_phy_addr(struct opal_sg_list *list)
  +{
  +  struct opal_sg_list *sg, *next;
  +
  +  for (sg = list; sg; sg = next) {
  +  next = sg-next;
  +  /* Don't translate NULL pointer for last entry */
  +  if (sg-next)
  +  sg-next = (struct opal_sg_list
  *)__pa(sg-next);
  +  else
  +  sg-next = NULL;
  +
  +  /* Convert num_entries to length */
  +  sg-num_entries =
  +  sg-num_entries * sizeof(struct
  opal_sg_entry) + 16;
  +  }
  +}
  +
  +static void free_dump_data_buf(void)
  +{
  +  vfree(dump_record.buffer);
  +  dump_record.size = 0;
  +}
 
 
 Anton,
 
  This looks identical to the code in opal-flash.c. Considering how
  complicated it is, can we put it somewhere common?
 
 Thanks for the review.. Will look into it next week.

This doesn't appear to have been fixed in the version that went into
next.

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

[PATCH v2] powerpc/powernv Platform dump interface

2014-02-25 Thread Stewart Smith
This enables support for userspace to fetch and initiate FSP and
Platform dumps from the service processor (via firmware) through sysfs.

Based on original patch from Vasant Hegde hegdevas...@linux.vnet.ibm.com

Flow:
  - We register for OPAL notification events.
  - OPAL sends new dump available notification.
  - We make information on dump available via sysfs
  - Userspace requests dump contents
  - We retrieve the dump via OPAL interface
  - User copies the dump data
  - userspace sends ack for dump
  - We send ACK to OPAL.

sysfs files:
  - We add the /sys/firmware/opal/dump directory
  - echoing 1 (well, anything, but in future we may support
different dump types) to /sys/firmware/opal/dump/initiate_dump
will initiate a dump.
  - Each dump that we've been notified of gets a directory
in /sys/firmware/opal/dump/ with a name of the dump type and ID (in hex,
as this is what's used elsewhere to identify the dump).
  - Each dump has files: id, type, dump and acknowledge
dump is binary and is the dump itself.
echoing 'ack' to acknowledge (currently any string will do) will
acknowledge the dump and it will soon after disappear from sysfs.

OPAL APIs:
  - opal_dump_init()
  - opal_dump_info()
  - opal_dump_read()
  - opal_dump_ack()
  - opal_dump_resend_notification()

Currently we are only ever notified for one dump at a time (until
the user explicitly acks the current dump, then we get a notification
of the next dump), but this kernel code should just work when OPAL
starts notifying us of all the dumps present.

Changes since v1:
 - Add support for getting dump type from OPAL through new OPAL call
   (falling back to old OPAL_DUMP_INFO call if OPAL_DUMP_INFO2 isn't
supported)
 - use dump type in directory name for dump

Signed-off-by: Stewart Smith stew...@linux.vnet.ibm.com
---
 Documentation/ABI/stable/sysfs-firmware-opal-dump |   41 ++
 arch/powerpc/include/asm/opal.h   |   14 +
 arch/powerpc/platforms/powernv/Makefile   |2 +-
 arch/powerpc/platforms/powernv/opal-dump.c|  530 +
 arch/powerpc/platforms/powernv/opal-wrappers.S|6 +
 arch/powerpc/platforms/powernv/opal.c |2 +
 6 files changed, 594 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-dump
 create mode 100644 arch/powerpc/platforms/powernv/opal-dump.c

diff --git a/Documentation/ABI/stable/sysfs-firmware-opal-dump 
b/Documentation/ABI/stable/sysfs-firmware-opal-dump
new file mode 100644
index 000..32fe7f5
--- /dev/null
+++ b/Documentation/ABI/stable/sysfs-firmware-opal-dump
@@ -0,0 +1,41 @@
+What:  /sys/firmware/opal/dump
+Date:  Feb 2014
+Contact:   Stewart Smith stew...@linux.vnet.ibm.com
+Description:
+   This directory exposes interfaces for interacting with
+   the FSP and platform dumps through OPAL firmware interface.
+
+   This is only for the powerpc/powernv platform.
+
+   initiate_dump:  When '1' is written to it,
+   we will initiate a dump.
+   Read this file for supported commands.
+
+   0xXX-0x:A directory for dump of type 0xXX and
+   id 0x (in hex). The name of this
+   directory should not be relied upon to
+   be in this format, only that it's unique
+   among all dumps. For determining the type
+   and ID of the dump, use the id and type files.
+   Do not rely on any particular size of dump
+   type or dump id.
+
+   Each dump has the following files:
+   id: An ASCII representation of the dump ID
+   in hex (e.g. '0x01')
+   type:   An ASCII representation of the type of
+   dump in the format 0x%x %s with the ID
+   in hex and a description of the dump type
+   (or 'unknown').
+   Type '0x unknown' is used when
+   we could not get the type from firmware.
+   e.g. '0x02 System/Platform Dump'
+   dump:   A binary file containing the dump.
+   The size of the dump is the size of this file.
+   acknowledge:When 'ack' is written to this, we will
+   acknowledge that we've retrieved the
+   dump to the service processor. It will
+   then remove it, making the dump
+   inaccessible.
+   Reading this file will get a list of
+   supported actions.
diff 

Re: [PATCH v2] powerpc/powernv: Platform dump interface

2014-02-12 Thread Vasant Hegde

On 02/09/2014 02:50 AM, Anton Blanchard wrote:


Hi Vasant,


+static void free_dump_sg_list(struct opal_sg_list *list)
+{
+   struct opal_sg_list *sg1;
+   while (list) {
+   sg1 = list-next;
+   kfree(list);
+   list = sg1;
+   }
+   list = NULL;
+}
+
+/*
+ * Build dump buffer scatter gather list
+ */
+static struct opal_sg_list *dump_data_to_sglist(void)
+{
+   struct opal_sg_list *sg1, *list = NULL;
+   void *addr;
+   int64_t size;
+
+   addr = dump_record.buffer;
+   size = dump_record.size;
+
+   sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+   if (!sg1)
+   goto nomem;
+
+   list = sg1;
+   sg1-num_entries = 0;
+   while (size  0) {
+   /* Translate virtual address to physical address */
+   sg1-entry[sg1-num_entries].data =
+   (void *)(vmalloc_to_pfn(addr)  PAGE_SHIFT);
+
+   if (size  PAGE_SIZE)
+   sg1-entry[sg1-num_entries].length =
PAGE_SIZE;
+   else
+   sg1-entry[sg1-num_entries].length = size;
+
+   sg1-num_entries++;
+   if (sg1-num_entries = SG_ENTRIES_PER_NODE) {
+   sg1-next = kzalloc(PAGE_SIZE, GFP_KERNEL);
+   if (!sg1-next)
+   goto nomem;
+
+   sg1 = sg1-next;
+   sg1-num_entries = 0;
+   }
+   addr += PAGE_SIZE;
+   size -= PAGE_SIZE;
+   }
+   return list;
+
+nomem:
+   pr_err(%s : Failed to allocate memory\n, __func__);
+   free_dump_sg_list(list);
+   return NULL;
+}
+
+/*
+ * Translate sg list address to absolute
+ */
+static void sglist_to_phy_addr(struct opal_sg_list *list)
+{
+   struct opal_sg_list *sg, *next;
+
+   for (sg = list; sg; sg = next) {
+   next = sg-next;
+   /* Don't translate NULL pointer for last entry */
+   if (sg-next)
+   sg-next = (struct opal_sg_list
*)__pa(sg-next);
+   else
+   sg-next = NULL;
+
+   /* Convert num_entries to length */
+   sg-num_entries =
+   sg-num_entries * sizeof(struct
opal_sg_entry) + 16;
+   }
+}
+
+static void free_dump_data_buf(void)
+{
+   vfree(dump_record.buffer);
+   dump_record.size = 0;
+}




Anton,


This looks identical to the code in opal-flash.c. Considering how
complicated it is, can we put it somewhere common?


Thanks for the review.. Will look into it next week.

-Vasant



Anton



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


Re: [PATCH v2] powerpc/powernv: Platform dump interface

2014-02-08 Thread Anton Blanchard

Hi Vasant,

 +static void free_dump_sg_list(struct opal_sg_list *list)
 +{
 + struct opal_sg_list *sg1;
 + while (list) {
 + sg1 = list-next;
 + kfree(list);
 + list = sg1;
 + }
 + list = NULL;
 +}
 +
 +/*
 + * Build dump buffer scatter gather list
 + */
 +static struct opal_sg_list *dump_data_to_sglist(void)
 +{
 + struct opal_sg_list *sg1, *list = NULL;
 + void *addr;
 + int64_t size;
 +
 + addr = dump_record.buffer;
 + size = dump_record.size;
 +
 + sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
 + if (!sg1)
 + goto nomem;
 +
 + list = sg1;
 + sg1-num_entries = 0;
 + while (size  0) {
 + /* Translate virtual address to physical address */
 + sg1-entry[sg1-num_entries].data =
 + (void *)(vmalloc_to_pfn(addr)  PAGE_SHIFT);
 +
 + if (size  PAGE_SIZE)
 + sg1-entry[sg1-num_entries].length =
 PAGE_SIZE;
 + else
 + sg1-entry[sg1-num_entries].length = size;
 +
 + sg1-num_entries++;
 + if (sg1-num_entries = SG_ENTRIES_PER_NODE) {
 + sg1-next = kzalloc(PAGE_SIZE, GFP_KERNEL);
 + if (!sg1-next)
 + goto nomem;
 +
 + sg1 = sg1-next;
 + sg1-num_entries = 0;
 + }
 + addr += PAGE_SIZE;
 + size -= PAGE_SIZE;
 + }
 + return list;
 +
 +nomem:
 + pr_err(%s : Failed to allocate memory\n, __func__);
 + free_dump_sg_list(list);
 + return NULL;
 +}
 +
 +/*
 + * Translate sg list address to absolute
 + */
 +static void sglist_to_phy_addr(struct opal_sg_list *list)
 +{
 + struct opal_sg_list *sg, *next;
 +
 + for (sg = list; sg; sg = next) {
 + next = sg-next;
 + /* Don't translate NULL pointer for last entry */
 + if (sg-next)
 + sg-next = (struct opal_sg_list
 *)__pa(sg-next);
 + else
 + sg-next = NULL;
 +
 + /* Convert num_entries to length */
 + sg-num_entries =
 + sg-num_entries * sizeof(struct
 opal_sg_entry) + 16;
 + }
 +}
 +
 +static void free_dump_data_buf(void)
 +{
 + vfree(dump_record.buffer);
 + dump_record.size = 0;
 +}

This looks identical to the code in opal-flash.c. Considering how
complicated it is, can we put it somewhere common?

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


[PATCH v2] powerpc/powernv: Platform dump interface

2014-01-16 Thread Vasant Hegde
This patch adds interface to retrieve FSP and Platform dump.

Flow:
  - We register for OPAL notification events.
  - OPAL sends new dump available notification.
  - We retrieve the dump via OPAL interface and send it to debugfs.
  - User copies the dump data and end ACKs via debugfs.
  - We send ACK to OPAL.

OPAL APIs:
  - opal_dump_init()
  - opal_dump_info()
  - opal_dump_read()
  - opal_dump_ack()
  - opal_dump_resend_notification()

debugfs files:
  We create below dump related files under fsp directory.
- dump: Dump data
- dump_available  : New dump available notification to userspace
- dump_control: ACK dump. Also initiate new FSP dump
- README  : README

Signed-off-by: Vasant Hegde hegdevas...@linux.vnet.ibm.com
---
Ben,
  I have rebased this patch on top of your next branch.

-Vasant

 arch/powerpc/include/asm/opal.h|   12 +
 arch/powerpc/platforms/powernv/Makefile|2 
 arch/powerpc/platforms/powernv/opal-dump.c |  436 
 arch/powerpc/platforms/powernv/opal-wrappers.S |5 
 arch/powerpc/platforms/powernv/opal.c  |2 
 5 files changed, 456 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/platforms/powernv/opal-dump.c

diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
index 9a87b44..0f4c7ff 100644
--- a/arch/powerpc/include/asm/opal.h
+++ b/arch/powerpc/include/asm/opal.h
@@ -154,8 +154,13 @@ extern int opal_enter_rtas(struct rtas_args *args,
 #define OPAL_FLASH_VALIDATE76
 #define OPAL_FLASH_MANAGE  77
 #define OPAL_FLASH_UPDATE  78
+#define OPAL_DUMP_INIT 81
+#define OPAL_DUMP_INFO 82
+#define OPAL_DUMP_READ 83
+#define OPAL_DUMP_ACK  84
 #define OPAL_GET_MSG   85
 #define OPAL_CHECK_ASYNC_COMPLETION86
+#define OPAL_DUMP_RESEND   91
 
 #ifndef __ASSEMBLY__
 
@@ -236,6 +241,7 @@ enum OpalPendingState {
OPAL_EVENT_EPOW = 0x80,
OPAL_EVENT_LED_STATUS   = 0x100,
OPAL_EVENT_PCI_ERROR= 0x200,
+   OPAL_EVENT_DUMP_AVAIL   = 0x400,
OPAL_EVENT_MSG_PENDING  = 0x800,
 };
 
@@ -825,6 +831,11 @@ int64_t opal_lpc_read(uint32_t chip_id, enum 
OpalLPCAddressType addr_type,
 int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
 int64_t opal_manage_flash(uint8_t op);
 int64_t opal_update_flash(uint64_t blk_list);
+int64_t opal_dump_init(uint8_t dump_type);
+int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
+int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
+int64_t opal_dump_ack(uint32_t dump_id);
+int64_t opal_dump_resend_notification(void);
 
 int64_t opal_get_msg(uint64_t buffer, size_t size);
 int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
@@ -859,6 +870,7 @@ extern void opal_get_rtc_time(struct rtc_time *tm);
 extern unsigned long opal_get_boot_time(void);
 extern void opal_nvram_init(void);
 extern void opal_flash_init(void);
+extern void opal_platform_dump_init(void);
 
 extern int opal_machine_check(struct pt_regs *regs);
 
diff --git a/arch/powerpc/platforms/powernv/Makefile 
b/arch/powerpc/platforms/powernv/Makefile
index 8d767fd..3528c11 100644
--- a/arch/powerpc/platforms/powernv/Makefile
+++ b/arch/powerpc/platforms/powernv/Makefile
@@ -1,6 +1,6 @@
 obj-y  += setup.o opal-takeover.o opal-wrappers.o opal.o
 obj-y  += opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
-obj-y  += rng.o
+obj-y  += rng.o opal-dump.o
 
 obj-$(CONFIG_SMP)  += smp.o
 obj-$(CONFIG_PCI)  += pci.o pci-p5ioc2.o pci-ioda.o
diff --git a/arch/powerpc/platforms/powernv/opal-dump.c 
b/arch/powerpc/platforms/powernv/opal-dump.c
new file mode 100644
index 000..4447027
--- /dev/null
+++ b/arch/powerpc/platforms/powernv/opal-dump.c
@@ -0,0 +1,436 @@
+/*
+ * PowerNV OPAL Dump Interface
+ *
+ * Copyright 2013 IBM Corp.
+ *
+ * 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.
+ */
+
+#include linux/kobject.h
+#include linux/debugfs.h
+#include linux/mm.h
+#include linux/slab.h
+#include linux/vmalloc.h
+#include linux/pagemap.h
+#include linux/delay.h
+
+#include asm/opal.h
+
+/* Dump type */
+#define DUMP_TYPE_FSP  0x01
+
+/* Extract failed */
+#define DUMP_NACK_ID   0x00
+
+/* Dump record */
+struct dump_record {
+   uint8_t type;
+   uint32_tid;
+   uint32_tsize;
+   char*buffer;
+};
+static struct dump_record dump_record;
+
+/* Dump available status */
+static u32 dump_avail;
+
+/* Binary blobs */