sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceParser.java
changeset 5 844b047e260d
child 12 ae255c9aa552
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysperfana/perfinvestigator/com.nokia.carbide.cpp.pi.irq/src/com/nokia/carbide/cpp/pi/irq/IrqTraceParser.java	Wed Apr 21 15:14:16 2010 +0300
@@ -0,0 +1,490 @@
+/*
+ * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). 
+ * All rights reserved.
+ * This component and the accompanying materials are made available
+ * under the terms of the License "Eclipse Public License v1.0"
+ * which accompanies this distribution, and is available
+ * at the URL "http://www.eclipse.org/legal/epl-v10.html".
+ *
+ * Initial Contributors:
+ * Nokia Corporation - initial contribution.
+ *
+ * Contributors:
+ *
+ * Description: 
+ *
+ */
+
+package com.nokia.carbide.cpp.pi.irq;
+
+import java.io.*;
+import java.util.*;
+
+import com.nokia.carbide.cpp.internal.pi.model.GenericTrace;
+import com.nokia.carbide.cpp.internal.pi.model.ParsedTraceData;
+import com.nokia.carbide.cpp.internal.pi.model.Parser;
+
+
+/**
+ * Class irq trace parser. 
+ */
+public class IrqTraceParser extends Parser
+{
+//  private String profilerVersion;
+  private Vector completeIrqTrace;
+  private int firstSample,lastSample;
+  private long old_1 = 0;
+  private long old_2 = 0;
+  private long old_3 = 0;
+  private int sampleNum = 0;
+  private int old_irq_lev1 = 0;
+  private int old_irq_lev2 = 0;
+    
+  public IrqTraceParser(/*File irqFile, ProgressBar progressBar*/) throws Exception
+  {
+    this.completeIrqTrace = new Vector();
+  }
+  
+  public ParsedTraceData parse(File f) throws Exception 
+  {
+    
+    if(!f.exists()) //throw new IOException("GFC file does not exist");
+	{
+		setStateOk(false);
+		return null;
+	}
+	else
+    {
+		/*if(progressBar != null) 
+		{
+			setProgressBarString("Analysing IRQ/SWI...");
+		}*/
+		
+		FileInputStream fis = new FileInputStream(f);
+		byte[] data = new byte[(int)f.length()];
+		fis.read(data);
+		//String version = getVersion(data);
+		//System.out.println("IRQ trace version "+version);
+		//profilerVersion = version;
+		ByteArrayInputStream bais = new ByteArrayInputStream(data);
+		DataInputStream dis = new DataInputStream(bais);
+		
+		this.traceVersion = this.getVersion(dis);
+		if (this.traceVersion.indexOf("V1.20") != -1)
+		{
+			// start parsing
+			try
+			{
+				int total = 0;
+				while(true)
+				{
+					total += readEntries(dis);
+					this.sampleNum++;
+					//System.out.println("Sample #"+sampleNum+" "+this.completeIrqTrace.size());
+					//System.out.println("******* Total now "+total+" "+Integer.toHexString(total));
+			  	  	//System.in.read();
+			  	  	//System.in.read();
+				}
+			}
+			catch (EOFException eof)
+			{
+				//eof.printStackTrace();
+			    ParsedTraceData ptd = new ParsedTraceData();
+				ptd.staticData = null;
+				ptd.traceData = this.getTrace();
+				return ptd;
+			}
+			catch (Exception e)
+			{
+				System.out.println("Error in reading IRQ trace file");
+				throw e;				
+			}
+	    }
+		else
+		{
+			System.out.println("Unsupported IRQ version: "+this.traceVersion);
+		    return null;
+		}
+    }
+  	
+  }
+  
+  public String getProfilerVersion()
+  {
+      return this.traceVersion;
+  }
+  
+  private String getVersion(DataInputStream dis) throws IOException
+  {
+  	int length = dis.readUnsignedByte();
+  	byte[] verArray = new byte[length];
+  	dis.read(verArray);
+
+  	String verString = new String(verArray);
+//  	System.out.println("Version string: "+verString);
+	if(verString.indexOf("Bappea") != -1)
+		if(verString.indexOf("IRQ") != -1)
+		{
+  			int index = verString.indexOf("_");
+  			String ver = verString.substring(index,length);
+  			return ver;
+  		}
+	return("Unidentified");
+  }
+  
+  private int readEntries(DataInputStream dis) throws Exception
+  {
+	int b0=0,b1=0,b2=0,b3=0;
+	boolean swi = false;
+  	int read = 0;
+  	//System.out.println("-------------");
+  	b0 = dis.readUnsignedByte();read++;
+  	int length = b0; 
+  	if(length == 0xff)
+  	{
+  		// length encoded in 3 bytes
+  		b1 = dis.readUnsignedByte();read++;
+  		b2 = dis.readUnsignedByte();read++;
+  		b3 = dis.readUnsignedByte();read++;
+  		length = b1;
+  		length |= b2<<8;
+  		length |= b3<<16;
+  		//System.out.println("LONG length "+length);
+  	}
+//  	
+//	System.out.println("SWI len "+Integer.toHexString(b0)+
+//				 " "+Integer.toHexString(b1)+
+//				 " "+Integer.toHexString(b2)+
+//				 " "+Integer.toHexString(b3)+" "+length+" = 0x"+Integer.toHexString(length));
+  	
+  	while(length > 0)
+  	{
+  		int read_val = dis.readUnsignedByte();read++;length--;
+		
+  		//System.out.println("Length "+length);
+  		
+  		int repeat_val = 0;
+  		int header = (read_val & (int)0xff);
+  		int repeat = header>>>6;
+  		
+  		//System.out.println("Header "+Long.toHexString(header)+" "+Long.toBinaryString(header)+" repeat "+repeat);
+  		
+  		if(repeat == 0)
+  		{
+  			repeat_val = 0;
+  			//System.out.println("no repeat "+Long.toHexString(repeat_val));
+  		}
+  		else if(repeat == 1)
+  		{
+  			repeat_val = (header & ((int)0x3F));
+  			
+  			//System.out.println("short repeat "+Long.toHexString(repeat_val));
+  		}
+  		else if(repeat == 2)
+  		{
+  			repeat_val = ((header & ((int)0x3F))<<8) | 
+			(dis.readUnsignedByte());length--;read++;
+  			
+  			//System.out.println("medium repeat"+Long.toHexString(repeat_val));  		
+  		}
+  		else if(repeat == 3)
+  		{
+  			repeat_val = ((header & ((int)0x3F))<<24) | 
+			(dis.readUnsignedByte() << 16) |
+			(dis.readUnsignedByte() << 8) |
+			(dis.readUnsignedByte() );length-=3;read+=3;
+			/*
+			for(int x=0;x<10;x++)
+			{
+				for(int y=0;y<8;y++)
+				{
+					System.out.println(Integer.toHexString(dis.readUnsignedByte()));
+				}
+				System.out.print("\n");
+			}
+			
+			System.in.read();
+			System.in.read();
+			*/
+  		}
+  		
+  		if(repeat_val > 0) 
+  		{
+  			addSwiRepeat(repeat_val);
+  		}
+  		else
+  		{
+  			int bytes_1 = (header & ((int)0x30))>>>4;
+  			int bytes_2 = (header & ((int)0x0C))>>>2;
+  			int bytes_3 = (header & ((int)0x03));
+  			if(bytes_1 == 3) bytes_1 = 4;
+  			if(bytes_2 == 3) bytes_2 = 4;
+  			if(bytes_3 == 3) bytes_3 = 4;
+  			
+  			readSwiEntry(dis,bytes_1,bytes_2,bytes_3);
+  			length-=(bytes_1+bytes_2+bytes_3);
+  			read+=(bytes_1+bytes_2+bytes_3);		
+  		}
+  	}
+  	
+  	if(length == 0)
+  	{
+  		//Sytem.out.println("End of SWI, reading IRQ");
+  	  	b0 = dis.readUnsignedByte();read++;
+  	  	length = b0; 
+  	  	if(length == 0xff)
+  	  	{
+  	  		// length encoded in 3 bytes
+  	  		b1 = dis.readUnsignedByte();read++;
+  	  		b2 = dis.readUnsignedByte();read++;
+  	  		b3 = dis.readUnsignedByte();read++;
+  	  		length = b1;
+  	  		length |= b2<<8;
+  	  		length |= b3<<16;
+  	  		//System.out.println("LONG length "+length);
+  	  	}
+//  		System.out.println("IRQ len "+Integer.toHexString(b0)+
+//				 " "+Integer.toHexString(b1)+
+//				 " "+Integer.toHexString(b2)+
+//				 " "+Integer.toHexString(b3)+" "+length+" = 0x"+Integer.toHexString(length));
+  	  	
+  	  	swi = true;
+  	  	while(length > 0)
+  	  	{
+  	  		//System.out.println("Length "+length);
+  	  		int firstByte = dis.readUnsignedByte();length--;read++;
+  	  		
+  	  		if(firstByte == 0xff)
+  	  		{
+  	  			// this is a repeat of the previous sample
+  	  			int repeat = 	dis.readUnsignedByte() |
+								(dis.readUnsignedByte()<<8) |
+								(dis.readUnsignedByte()<<16);
+  	  			//if(sampleNum == 5918 || sampleNum == 6137 || sampleNum == 7958)
+  	  			//System.out.println(this.sampleNum+" IRQ Repeat of "+repeat+" L1:"+this.old_irq_lev1+" L2:"+this.old_irq_lev2);
+  	  			this.addIrqRepeat(repeat);
+  	  			
+  	  			length-=3;read+=3;
+  	  			
+  	  			if(length > 0)
+  	  			{
+  	  				this.old_irq_lev1 = dis.readUnsignedByte();
+  	  				this.old_irq_lev2 = dis.readUnsignedByte();
+  	  				length-=2; read-=2;
+
+  	  				this.addIrqSample();
+  	  			}
+  	  		}
+  	  		else
+  	  		{
+  	  			this.old_irq_lev1 = firstByte;
+  	  			this.old_irq_lev2 = dis.readUnsignedByte();
+  	  			length--;read++;
+
+  	  			this.addIrqSample();
+  	  		}
+  	  		
+  			//System.out.println(this.sampleNum+" IRQ L1:"+this.old_irq_lev1+" L2:"+this.old_irq_lev2);
+  	  	}
+  	}
+  	else
+  	{
+//  		System.out.println("Parse error "+Integer.toHexString(b0)+
+//  										 " "+Integer.toHexString(b1)+
+//  										 " "+Integer.toHexString(b2)+
+//  										 " "+Integer.toHexString(b3)+" "+swi+" "+read);
+  		
+  		throw new Exception("Parse error "+Integer.toHexString(b0)+
+  										 " "+Integer.toHexString(b1)+
+  										 " "+Integer.toHexString(b2)+
+  										 " "+Integer.toHexString(b3));
+  	}
+
+  	if(length == 0)
+  	{
+  		return read;
+  	}
+  	else
+  	{
+  		throw new Exception("Parse error");
+  	}
+  	
+  }
+     
+  private void readSwiEntry(DataInputStream dis,int b1,int b2,int b3) throws Exception
+  {
+  	//System.out.println("b1: "+b1+" b2:"+b2+" b3:"+b3);
+  
+  	int value = 0;
+  	int fValue = 0;
+  	boolean neg = false;
+	for(int i=0;i<4;i++) 
+	{
+		if(i<b1)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("1:"+fValue); 	
+	this.old_1 += fValue;
+
+	value = 0;
+	fValue = 0;
+	neg = false;
+	for(int i=0;i<4;i++)
+	{
+		if(i<b2)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("2:"+fValue); 	
+	this.old_2 += fValue;
+	
+	value = 0;
+	fValue = 0;
+	neg = false;
+	for(int i=0;i<4;i++) 
+	{
+		if(i<b3)
+		{
+			value = dis.readUnsignedByte();
+			if((value & 0x80) > 0) neg = true;
+			else neg = false;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+		else
+		{
+			if(neg == true) value = 0xff;
+			else value = 0x00;
+			value = (value<<(8*i));
+			fValue |= value;
+			//System.out.println("v"+i+":"+Integer.toHexString(value));
+		}
+	}
+	//if(fValue == -1) System.out.println("3:"+fValue); 	
+	this.old_3 += fValue;
+	
+	this.addSwiSample();
+	/*
+	System.out.println( "#"+this.sampleNum+" "+Integer.toHexString((int)old_1)+
+						" "+Integer.toHexString((int)old_2)+
+						" "+Integer.toHexString((int)old_3)+" "+sfp.getFunctionNameForAddress(((old_3<<32)>>>32)));
+	*/
+ 	return;
+  }
+  
+  private void addSwiSample()
+  {
+	  long temp_1 = ((this.old_1 << 32) >>> 32);
+	  long temp_2 = ((this.old_2 << 32) >>> 32);
+	  long temp_3 = ((this.old_3 << 32) >>> 32)-4;
+	  
+	  IrqSample sample = new IrqSample(this.sampleNum, temp_1, temp_2, temp_3);
+	  /*
+	  String n1 = sfp.getFunctionNameForAddress(temp_3);
+	  
+	  if(n1.indexOf("WaitForAnyRequest") != -1)
+	  {
+		  for(int i=-256;i<256;i++)
+		  {
+			  String n2 = sfp.getFunctionNameForAddress(temp_1+i);
+			  if(n2.indexOf("WaitForAnyRequest") != -1)
+			  {
+				  System.out.print("\n"+i);
+				  
+				  System.out.println("EXEC CALL : "+sfp.getFunctionNameForAddress(temp_3));
+				  System.out.println("Made in : "+sfp.getFunctionNameForAddress(temp_1+i));
+				  break;
+			  }
+		  }
+	  } 
+	  */
+	  this.completeIrqTrace.add(sample);
+  }
+  
+  private void addSwiRepeat(int amount)
+  {
+	  long temp_1 = ((this.old_1 << 32) >>> 32);
+	  long temp_2 = ((this.old_2 << 32) >>> 32);
+	  long temp_3 = ((this.old_3 << 32) >>> 32)-4;
+	  
+	  /*
+	  String n1 = sfp.getFunctionNameForAddress(temp_3);
+	  
+	  if(n1.indexOf("WaitForAnyRequest") != -1)
+	  {
+		  for(int i=-256;i<256;i++)
+		  {
+			  String n2 = sfp.getFunctionNameForAddress(temp_1+i);
+			  if(n2.indexOf("WaitForAnyRequest") != -1)
+			  {
+				  System.out.print("\n"+i);
+				  
+				  System.out.println("EXEC CALL : "+sfp.getFunctionNameForAddress(temp_3));
+				  System.out.println("Made in : "+sfp.getFunctionNameForAddress(temp_1+i));
+				  break;
+			  }
+		  }
+	  } 
+	  */
+	  
+	  IrqSample sample = new IrqSample(this.sampleNum,temp_1,temp_2,temp_3);
+	  sample.repeatCount = amount;
+	  this.completeIrqTrace.add(sample);
+  }
+
+  private void addIrqSample()
+  {
+  	IrqSample sample = new IrqSample(this.sampleNum,this.old_irq_lev1,this.old_irq_lev2);
+  	this.completeIrqTrace.add(sample);
+  }
+  
+  private void addIrqRepeat(int amount)
+  {
+  	  	IrqSample sample = new IrqSample(this.sampleNum,this.old_irq_lev1,this.old_irq_lev2);
+  	  	sample.repeatCount = amount; 
+ 	  	this.completeIrqTrace.add(sample);
+  }
+  
+  private GenericTrace getTrace()
+  {
+  	Enumeration completeEnum = this.completeIrqTrace.elements();
+  	IrqTrace trace = new IrqTrace();
+  	
+  	while(completeEnum.hasMoreElements())
+  	{
+  		IrqSample sample = (IrqSample)completeEnum.nextElement();
+  		trace.addSample(sample);
+  	}
+  	return trace;
+  }
+}
\ No newline at end of file