>From 459a1f682d73988a1b4fb247b4db0ed8c3b7a095 Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
Date: Mon, 18 Oct 2010 18:48:27 -0700
Subject: [PATCH 4/4] Added new function to generate a PTI control header.

This header is sent with every PTI message and is used by the Mobile
Platform Trace Analyzer.

Signed-off-by: Ken Mills <[email protected]>
---
 drivers/misc/pti.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 8c0dff4..f9f33a2 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -28,8 +28,10 @@
  */
 
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/console.h>
 #include <linux/kernel.h>
+#include <linux/hardirq.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
@@ -44,10 +46,12 @@
 #define CHARNAME                       "pti"
 #define MAX_APP_IDS                    256
 #define MAX_OS_IDS                     128
+#define CONTROL_ID                     72   /* control master ID address */
 #define CONSOLE_ID                     73   /* console master ID address */
-#define OS_BASE_ID                     72   /* base OS master ID address */
+#define OS_BASE_ID                     74   /* base OS master ID address */
 #define APP_BASE_ID                    80   /* base App master ID address */
-#define USER_COPY_SIZE 8192 /* 8Kb buffer to copy data from user space */
+#define USER_COPY_SIZE                 8192 /* 8Kb buffer to copy data from 
user space */
+#define CONTROL_FRAME_LEN              32 /* PTI control frame maximum size */
 
 struct pti_tty {
        struct masterchannel *mc;
@@ -76,6 +80,7 @@ static struct tty_driver *pti_tty_driver;
 static struct pti_dev *drv_data;
 
 static unsigned int pti_console_channel;
+static unsigned int pti_control_channel;
 
 #define DTS 0x30               /* offset for last dword of a PTI message */
 
@@ -146,6 +151,61 @@ static void pti_write_to_aperture(struct masterchannel 
*mc, u8 *buf, int len)
 }
 
 /**
+ *  pti_control_frame_built_and_sent() - control frame build and send function.
+ *  @mc: The master / channel structure on which the function built a control
+ *  frame.
+ *
+ *  To be able to post process the PTI contents on host side, a control frame
+ *  is added before sending any PTI content. So the host side knows on
+ *  each PTI frame the name of the thread using a dedicated master / channel.
+ *  This function builds this frame and sends it to a master ID CONTROL_ID.
+ *  The overhead is only 32 bytes since the driver only writes to HW
+ *  in 32 byte chunks.
+ */
+
+static void pti_control_frame_built_and_sent(struct masterchannel *mc)
+{
+       struct masterchannel mccontrol = {.master = CONTROL_ID, .channel = 0};
+       const char *control_format = "%3d %3d %s";
+
+       char comm[sizeof(current->comm)];
+       u8 control_frame[CONTROL_FRAME_LEN];
+
+       if (!in_interrupt())
+               get_task_comm(comm, current);
+       else
+               strcpy(comm, "Interrupt");
+
+       mccontrol.channel = pti_control_channel;
+       pti_control_channel = (pti_control_channel + 1) & 0x7f;
+
+       snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
+               mc->channel, comm);
+       pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
+}
+
+/**
+ *  pti_write_full_frame_to_aperture() - high level function to write to PTI
+ *  @mc: The 'aperture'. It's part of a write address that holds
+ *       a master and channel ID.
+ *  @buf: Data being written to the HW that will ultimately be seen
+ *        in a debugging tool (Fido, Lauterbach).
+ *  @len: Size of buffer.
+ *
+ *  All threads sending data (either console, user space application, ...)
+ *  are calling the high level function to write to PTI meaning that it is
+ *  possible to add a control frame before sending the content.
+ */
+static void pti_write_full_frame_to_aperture(struct masterchannel *mc,
+                                               const unsigned char *buf,
+                                               int len)
+{
+       pti_control_frame_built_and_sent(mc);
+       pti_write_to_aperture(mc, (u8 *)buf, len);
+}
+
+
+/**
  * getID(): Allocate a master and channel ID.
  *
  * @IDarray:
@@ -187,6 +247,8 @@ static struct masterchannel *getID(u8 *IDarray, int 
max_IDS, int baseID)
        IDarray[i] |= mask;
        mc->master = (i>>4)+baseID;
        mc->channel = ((i & 0xf)<<3) + j;
+       /* write new master Id / channel Id allocation to channel control */
+       pti_control_frame_built_and_sent(mc);
        return mc;
 }
 
@@ -381,9 +443,10 @@ static int pti_tty_install(struct tty_driver *driver, 
struct tty_struct *tty)
 {
        int idx = tty->index;
        struct pti_tty *pti_tty_data;
-
        int ret = tty_init_termios(tty);
 
+       pr_debug("%s(%d): Called.\n", __func__, __LINE__);
+
        if (ret == 0) {
                tty_driver_kref_get(driver);
                tty->count++;
@@ -491,8 +554,7 @@ int pti_char_release(struct inode *inode, struct file *filp)
  * @param data: trace data to be written.
  * @param len:  # of byte to write.
  * @param ppose: Not used in this function implementation.
- * @return int : # of bytes written, or error.  -EMSGSIZE is
- *               returned if length is beyond 8k.
+ * @return int : # of bytes written, or error.
  */
 ssize_t pti_char_write(struct file *filp, const char *data, size_t len,
                loff_t *ppose)
@@ -567,7 +629,7 @@ static void pti_console_write(struct console *c, const char 
*buf, unsigned len)
        mc.channel = pti_console_channel;
        pti_console_channel = (pti_console_channel + 1) & 0x7f;
 
-       pti_write_to_aperture(&mc, (u8 *)buf, len);
+       pti_write_full_frame_to_aperture(&mc, buf, len);
 }
 
 static struct tty_driver *pti_console_device(struct console *c, int *index)
@@ -579,6 +641,7 @@ static struct tty_driver *pti_console_device(struct console 
*c, int *index)
 static int pti_console_setup(struct console *c, char *opts)
 {
        pti_console_channel = 0;
+       pti_control_channel = 0;
        return 0;
 }
 
@@ -640,6 +703,7 @@ static const struct tty_port_operations tty_port_ops = {
        .activate = pti_port_activate,
        .shutdown = pti_port_shutdown,
 };
+
 /*
    Note the _probe() call sets everything up and ties the char and tty
    to successfully detecting the PTI device on the pci bus.
-- 
1.7.0.4
From 459a1f682d73988a1b4fb247b4db0ed8c3b7a095 Mon Sep 17 00:00:00 2001
From: Ken Mills <[email protected]>
Date: Mon, 18 Oct 2010 18:48:27 -0700
Subject: [PATCH 4/4] Added new function to generate a PTI control header.

This header is sent with every PTI message and is used by the Mobile
Platform Trace Analyzer.

Signed-off-by: Ken Mills <[email protected]>
---
 drivers/misc/pti.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/drivers/misc/pti.c b/drivers/misc/pti.c
index 8c0dff4..f9f33a2 100644
--- a/drivers/misc/pti.c
+++ b/drivers/misc/pti.c
@@ -28,8 +28,10 @@
  */
 
 #include <linux/init.h>
+#include <linux/sched.h>
 #include <linux/console.h>
 #include <linux/kernel.h>
+#include <linux/hardirq.h>
 #include <linux/module.h>
 #include <linux/tty.h>
 #include <linux/tty_driver.h>
@@ -44,10 +46,12 @@
 #define CHARNAME			"pti"
 #define MAX_APP_IDS			256
 #define MAX_OS_IDS			128
+#define CONTROL_ID			72   /* control master ID address */
 #define CONSOLE_ID			73   /* console master ID address */
-#define OS_BASE_ID			72   /* base OS master ID address */
+#define OS_BASE_ID			74   /* base OS master ID address */
 #define APP_BASE_ID			80   /* base App master ID address */
-#define USER_COPY_SIZE	8192 /* 8Kb buffer to copy data from user space */
+#define USER_COPY_SIZE			8192 /* 8Kb buffer to copy data from user space */
+#define CONTROL_FRAME_LEN 		32 /* PTI control frame maximum size */
 
 struct pti_tty {
 	struct masterchannel *mc;
@@ -76,6 +80,7 @@ static struct tty_driver *pti_tty_driver;
 static struct pti_dev *drv_data;
 
 static unsigned int pti_console_channel;
+static unsigned int pti_control_channel;
 
 #define DTS 0x30		/* offset for last dword of a PTI message */
 
@@ -146,6 +151,61 @@ static void pti_write_to_aperture(struct masterchannel *mc, u8 *buf, int len)
 }
 
 /**
+ *  pti_control_frame_built_and_sent() - control frame build and send function.
+ *  @mc: The master / channel structure on which the function built a control
+ *  frame.
+ *
+ *  To be able to post process the PTI contents on host side, a control frame
+ *  is added before sending any PTI content. So the host side knows on
+ *  each PTI frame the name of the thread using a dedicated master / channel.
+ *  This function builds this frame and sends it to a master ID CONTROL_ID.
+ *  The overhead is only 32 bytes since the driver only writes to HW
+ *  in 32 byte chunks.
+ */
+
+static void pti_control_frame_built_and_sent(struct masterchannel *mc)
+{
+	struct masterchannel mccontrol = {.master = CONTROL_ID, .channel = 0};
+	const char *control_format = "%3d %3d %s";
+
+	char comm[sizeof(current->comm)];
+	u8 control_frame[CONTROL_FRAME_LEN];
+
+	if (!in_interrupt())
+		get_task_comm(comm, current);
+	else
+		strcpy(comm, "Interrupt");
+
+	mccontrol.channel = pti_control_channel;
+	pti_control_channel = (pti_control_channel + 1) & 0x7f;
+
+	snprintf(control_frame, CONTROL_FRAME_LEN, control_format, mc->master,
+		mc->channel, comm);
+	pti_write_to_aperture(&mccontrol, control_frame, strlen(control_frame));
+}
+
+/**
+ *  pti_write_full_frame_to_aperture() - high level function to write to PTI
+ *  @mc: The 'aperture'. It's part of a write address that holds
+ *       a master and channel ID.
+ *  @buf: Data being written to the HW that will ultimately be seen
+ *        in a debugging tool (Fido, Lauterbach).
+ *  @len: Size of buffer.
+ *
+ *  All threads sending data (either console, user space application, ...)
+ *  are calling the high level function to write to PTI meaning that it is
+ *  possible to add a control frame before sending the content.
+ */
+static void pti_write_full_frame_to_aperture(struct masterchannel *mc,
+						const unsigned char *buf,
+						int len)
+{
+	pti_control_frame_built_and_sent(mc);
+	pti_write_to_aperture(mc, (u8 *)buf, len);
+}
+
+
+/**
  * getID(): Allocate a master and channel ID.
  *
  * @IDarray:
@@ -187,6 +247,8 @@ static struct masterchannel *getID(u8 *IDarray, int max_IDS, int baseID)
 	IDarray[i] |= mask;
 	mc->master = (i>>4)+baseID;
 	mc->channel = ((i & 0xf)<<3) + j;
+	/* write new master Id / channel Id allocation to channel control */
+	pti_control_frame_built_and_sent(mc);
 	return mc;
 }
 
@@ -381,9 +443,10 @@ static int pti_tty_install(struct tty_driver *driver, struct tty_struct *tty)
 {
 	int idx = tty->index;
 	struct pti_tty *pti_tty_data;
-
 	int ret = tty_init_termios(tty);
 
+	pr_debug("%s(%d): Called.\n", __func__, __LINE__);
+
 	if (ret == 0) {
 		tty_driver_kref_get(driver);
 		tty->count++;
@@ -491,8 +554,7 @@ int pti_char_release(struct inode *inode, struct file *filp)
  * @param data: trace data to be written.
  * @param len:  # of byte to write.
  * @param ppose: Not used in this function implementation.
- * @return int : # of bytes written, or error.  -EMSGSIZE is
- *               returned if length is beyond 8k.
+ * @return int : # of bytes written, or error.
  */
 ssize_t pti_char_write(struct file *filp, const char *data, size_t len,
 		loff_t *ppose)
@@ -567,7 +629,7 @@ static void pti_console_write(struct console *c, const char *buf, unsigned len)
 	mc.channel = pti_console_channel;
 	pti_console_channel = (pti_console_channel + 1) & 0x7f;
 
-	pti_write_to_aperture(&mc, (u8 *)buf, len);
+	pti_write_full_frame_to_aperture(&mc, buf, len);
 }
 
 static struct tty_driver *pti_console_device(struct console *c, int *index)
@@ -579,6 +641,7 @@ static struct tty_driver *pti_console_device(struct console *c, int *index)
 static int pti_console_setup(struct console *c, char *opts)
 {
 	pti_console_channel = 0;
+	pti_control_channel = 0;
 	return 0;
 }
 
@@ -640,6 +703,7 @@ static const struct tty_port_operations tty_port_ops = {
 	.activate = pti_port_activate,
 	.shutdown = pti_port_shutdown,
 };
+
 /*
    Note the _probe() call sets everything up and ties the char and tty
    to successfully detecting the PTI device on the pci bus.
-- 
1.7.0.4

_______________________________________________
Meego-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel

Reply via email to