[SerialICE] r52 - in trunk: SerialICE qemu-0.11.0 qemu-0.11.0/target-i386

svn at coresystems.de svn at coresystems.de
Thu Nov 19 20:26:19 CET 2009


Author: stepan
Date: 2009-11-19 20:26:18 +0100 (Thu, 19 Nov 2009)
New Revision: 52

Removed:
   trunk/SerialICE/TODO
Modified:
   trunk/SerialICE/README.SHELL
   trunk/SerialICE/io.h
   trunk/SerialICE/serialice.c
   trunk/qemu-0.11.0/serialice.c
   trunk/qemu-0.11.0/serialice.h
   trunk/qemu-0.11.0/target-i386/op_helper.c
Log:
* shell: pass %edi to rdmsr and wrmsr calls (MSR unlock key)
* shell: unify implementations of rdmsr/wrmsr in io.h
* shell: fix cpuid asm() code
* shell: fix up README.SHELL documentation of rdmsr/wrmsr
* shell: drop (unneeded) TODO
* qemu: call rdmsr/wrmsr with %edi
* qemu: use a single command buffer instead of one per command
* add license to header file.


Modified: trunk/SerialICE/README.SHELL
===================================================================
--- trunk/SerialICE/README.SHELL	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/SerialICE/README.SHELL	2009-11-19 19:26:18 UTC (rev 52)
@@ -99,20 +99,20 @@
 5. MSR reads
 
   Syntax:
-  *rc<addr>
+  *rc<addr>.<key>
 
   Example:
-  > *rc000000cd
+  > *rc000000cd.9c5a203a
   00000000.00000933
   >
 
 6. MSR Writes
 
   Syntax:
-  *wc<addr>=<high>.<low>
+  *wc<addr>.<key>=<high>.<low>
 
   Example:
-  > *wc00000000=00000000.00000000
+  > *wc00000000.9c5a203a=00000000.00000000
   >
 
 7. CPUID

Deleted: trunk/SerialICE/TODO
===================================================================
--- trunk/SerialICE/TODO	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/SerialICE/TODO	2009-11-19 19:26:18 UTC (rev 52)
@@ -1,5 +0,0 @@
-
-- Better implementation of AMD style MSRs (with an unlock key in a specific register)
-- CPUID takes ECX as input on some EAX values (See patches/serialice-cpuid-ecx.diff)
-- USB debug console support (theoretical max of ca. 60MBit instead of 115.2KBit)
-

Modified: trunk/SerialICE/io.h
===================================================================
--- trunk/SerialICE/io.h	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/SerialICE/io.h	2009-11-19 19:26:18 UTC (rev 52)
@@ -121,88 +121,71 @@
 
 /* MSR functions */
 
-#ifdef __GNUC__
 typedef struct { u32 lo, hi; } msr_t;
 
-static inline msr_t rdmsr(unsigned index)
+static inline msr_t rdmsr(u32 index, u32 key)
 {
 	msr_t result;
 	__asm__ __volatile__ (
 		"rdmsr"
 		: "=a" (result.lo), "=d" (result.hi)
-		: "c" (index), "D" (0x9c5a203a)
+		: "c" (index), "D" (key)
 	);
 	return result;
 }
 
-static inline void wrmsr(unsigned index, msr_t msr)
+static inline void wrmsr(u32 index, msr_t msr, u32 key)
 {
 	__asm__ __volatile__ (
 		"wrmsr"
 		: /* No outputs */
-		: "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (0x9c5a203a)
+		: "c" (index), "a" (msr.lo), "d" (msr.hi), "D" (key)
 	);
 }
 
-#else
-
-/* Since we use romcc, we're also going to use romcc's builtin functions */
-typedef __builtin_msr_t msr_t;
-
-static inline msr_t rdmsr(unsigned long index)
-{
-	return __builtin_rdmsr(index);
-}
-
-static inline void wrmsr(unsigned long index, msr_t msr)
-{
-	__builtin_wrmsr(index, msr.lo, msr.hi);
-}
-#endif
-
 /* CPUID functions */
 
-static inline unsigned int cpuid_eax(unsigned int op, unsigned op2)
+static inline u32 cpuid_eax(u32 op, u32 op2)
 {
-        unsigned int eax;
+        u32 eax;
 
         __asm__("cpuid"
                 : "=a" (eax)
-                : "0" (op), "2" (op2)
-                : "ebx", "ecx", "edx");
+                : "a" (op), "c" (op2)
+                : "ebx", "edx" );
         return eax;
 }
 
-static inline unsigned int cpuid_ebx(unsigned int op, unsigned op2)
+static inline u32 cpuid_ebx(u32 op, u32 op2)
 {
-        unsigned int eax, ebx;
+        u32 eax, ebx;
 
         __asm__("cpuid"
-                : "=a" (eax), "=b" (ebx)
-                : "0" (op), "2" (op2)
-                : "ecx", "edx" );
+                : "=b" (ebx)
+                : "a" (op), "c" (op2)
+                : "edx");
         return ebx;
 }
 
-static inline unsigned int cpuid_ecx(unsigned int op, unsigned int op2)
+static inline u32 cpuid_ecx(u32 op, u32 op2)
 {
-        unsigned int eax, ecx;
+        u32 eax, ecx;
 
         __asm__("cpuid"
-                : "=a" (eax), "=c" (ecx)
-                : "0" (op), "2" (op2)
+                : "=c" (ecx)
+                : "a" (op), "c" (op2)
                 : "ebx", "edx" );
         return ecx;
 }
 
-static inline unsigned int cpuid_edx(unsigned int op, unsigned int op2)
+static inline u32 cpuid_edx(u32 op, u32 op2)
 {
-        unsigned int eax, edx;
+        u32 eax, edx;
 
         __asm__("cpuid"
-                : "=a" (eax), "=d" (edx)
-                : "0" (op), "2" (op2)
-                : "ebx", "ecx");
+                : "=d" (edx)
+                : "a" (op), "c" (op2)
+                : "ebx");
         return edx;
 }
 

Modified: trunk/SerialICE/serialice.c
===================================================================
--- trunk/SerialICE/serialice.c	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/SerialICE/serialice.c	2009-11-19 19:26:18 UTC (rev 52)
@@ -112,16 +112,18 @@
 
 static void serialice_read_msr(void)
 {
-	u32 addr;
+	u32 addr, key;
 	msr_t msr;
 
 	// Format:
-	// *rc00000000
+	// *rc00000000.9c5a203a
 	addr = sio_get32();
+	sio_getc();	   // skip .
+	key = sio_get32(); // key in %edi
 
 	sio_putc('\r'); sio_putc('\n');
 
-	msr = rdmsr(addr);
+	msr = rdmsr(addr, key);
 	sio_put32(msr.hi);
 	sio_putc('.');
 	sio_put32(msr.lo);
@@ -129,18 +131,25 @@
 
 static void serialice_write_msr(void)
 {
-	u32 addr;
+	u32 addr, key;
 	msr_t msr;
 
 	// Format:
-	// *wc00000000=00000000.00000000
+	// *wc00000000.9c5a203a=00000000.00000000
 	addr = sio_get32();
+	sio_getc();	// skip .
+	key = sio_get32(); // read key in %edi
 	sio_getc();	// skip =
 	msr.hi = sio_get32();
 	sio_getc();	// skip .
 	msr.lo = sio_get32();
 
-	wrmsr(addr, msr);
+#ifdef __ROMCC__
+	/* Cheat to avoid register outage */
+	wrmsr(addr, msr, 0x9c5a203a);
+#else
+	wrmsr(addr, msr, key);
+#endif
 }
 
 static void serialice_cpuinfo(void)

Modified: trunk/qemu-0.11.0/serialice.c
===================================================================
--- trunk/qemu-0.11.0/serialice.c	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/qemu-0.11.0/serialice.c	2009-11-19 19:26:18 UTC (rev 52)
@@ -57,6 +57,7 @@
 	int fd;
 #endif
 	char *buffer;
+	char *command;
 } SerialICEState;
 
 static SerialICEState *s;
@@ -483,15 +484,14 @@
 uint8_t serialice_inb(uint16_t port)
 {
 	uint8_t ret;
-	char command[16];
-
 	uint32_t data;
+
 	if (serialice_io_read_filter(&data, port, 1))
 		return data & 0xff;
 
-	sprintf(command, "*ri%04x.b", port);
+	sprintf(s->command, "*ri%04x.b", port);
 	// command read back: "\n00" (3 characters)
-	serialice_command(command, 3);
+	serialice_command(s->command, 3);
 	ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 
 	serialice_log(LOG_READ|LOG_IO, ret, port, 1);
@@ -502,15 +502,14 @@
 uint16_t serialice_inw(uint16_t port)
 {
 	uint16_t ret;
-	char command[16];
-
 	uint32_t data;
+
 	if (serialice_io_read_filter(&data, port, 1))
 		return data & 0xffff;
 
-	sprintf(command, "*ri%04x.w", port);
+	sprintf(s->command, "*ri%04x.w", port);
 	// command read back: "\n0000" (5 characters)
-	serialice_command(command, 5);
+	serialice_command(s->command, 5);
 	ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 
 	serialice_log(LOG_READ|LOG_IO, ret, port, 2);
@@ -521,15 +520,14 @@
 uint32_t serialice_inl(uint16_t port)
 {
 	uint32_t ret;
-	char command[16];
-
 	uint32_t data;
+
 	if (serialice_io_read_filter(&data, port, 1))
 		return data;
 
-	sprintf(command, "*ri%04x.l", port);
+	sprintf(s->command, "*ri%04x.l", port);
 	// command read back: "\n00000000" (9 characters)
-	serialice_command(command, 9);
+	serialice_command(s->command, 9);
 	ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 
 	serialice_log(LOG_READ|LOG_IO, ret, port, 4);
@@ -539,7 +537,6 @@
 
 void serialice_outb(uint8_t data, uint16_t port)
 {
-	char command[19];
 	uint32_t filtered_data = (uint32_t)data;
 
 	serialice_log(LOG_WRITE|LOG_IO, data, port, 1);
@@ -549,13 +546,12 @@
 	}
 
 	data = (uint8_t)filtered_data;
-	sprintf(command, "*wi%04x.b=%02x", port, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wi%04x.b=%02x", port, data);
+	serialice_command(s->command, 0);
 }
 
 void serialice_outw(uint16_t data, uint16_t port)
 {
-	char command[21];
 	uint32_t filtered_data = (uint32_t)data;
 
 	serialice_log(LOG_WRITE|LOG_IO, data, port, 2);
@@ -565,13 +561,12 @@
 	}
 
 	data = (uint16_t)filtered_data;
-	sprintf(command, "*wi%04x.w=%04x", port, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wi%04x.w=%04x", port, data);
+	serialice_command(s->command, 0);
 }
 
 void serialice_outl(uint32_t data, uint16_t port)
 {
-	char command[25];
 	uint32_t filtered_data = data;
 
 	serialice_log(LOG_WRITE|LOG_IO, data, port, 4);
@@ -581,17 +576,16 @@
 	}
 
 	data = filtered_data;
-	sprintf(command, "*wi%04x.l=%08x", port, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wi%04x.l=%08x", port, data);
+	serialice_command(s->command, 0);
 }
 
 uint8_t serialice_readb(uint32_t addr)
 {
 	uint8_t ret;
-	char command[20];
-	sprintf(command, "*rm%08x.b", addr);
+	sprintf(s->command, "*rm%08x.b", addr);
 	// command read back: "\n00" (3 characters)
-	serialice_command(command, 3);
+	serialice_command(s->command, 3);
 	ret = (uint8_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 	return ret;
 }
@@ -599,10 +593,9 @@
 uint16_t serialice_readw(uint32_t addr)
 {
 	uint16_t ret;
-	char command[20];
-	sprintf(command, "*rm%08x.w", addr);
+	sprintf(s->command, "*rm%08x.w", addr);
 	// command read back: "\n0000" (5 characters)
-	serialice_command(command, 5);
+	serialice_command(s->command, 5);
 	ret = (uint16_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 	return ret;
 }
@@ -610,36 +603,32 @@
 uint32_t serialice_readl(uint32_t addr)
 {
 	uint32_t ret;
-	char command[20];
-	sprintf(command, "*rm%08x.l", addr);
+	sprintf(s->command, "*rm%08x.l", addr);
 	// command read back: "\n00000000" (9 characters)
-	serialice_command(command, 9);
+	serialice_command(s->command, 9);
 	ret = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
 	return ret;
 }
 
 void serialice_writeb(uint8_t data, uint32_t addr)
 {
-	char command[24];
-	sprintf(command, "*wm%08x.b=%02x", addr, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wm%08x.b=%02x", addr, data);
+	serialice_command(s->command, 0);
 }
 
 void serialice_writew(uint16_t data, uint32_t addr)
 {
-	char command[25];
-	sprintf(command, "*wm%08x.w=%04x", addr, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wm%08x.w=%04x", addr, data);
+	serialice_command(s->command, 0);
 }
 
 void serialice_writel(uint32_t data, uint32_t addr)
 {
-	char command[29];
-	sprintf(command, "*wm%08x.l=%08x", addr, data);
-	serialice_command(command, 0);
+	sprintf(s->command, "*wm%08x.l=%08x", addr, data);
+	serialice_command(s->command, 0);
 }
 
-uint64_t serialice_rdmsr(uint32_t addr)
+uint64_t serialice_rdmsr(uint32_t addr, uint32_t key)
 {
 	uint32_t hi, lo;
 	uint64_t ret;
@@ -647,12 +636,10 @@
 
 	filtered = serialice_msr_filter(FILTER_READ, addr, &hi, &lo);
 	if (!filtered) {
-		char command[18];
+		sprintf(s->command, "*rc%08x.%08x", addr, key);
 
-		sprintf(command, "*rc%08x", addr);
-
 		// command read back: "\n00000000.00000000" (18 characters)
-		serialice_command(command, 18);
+		serialice_command(s->command, 18);
 
 		s->buffer[9] = 0; // . -> \0
 		hi = (uint32_t)strtoul(s->buffer + 1, (char **)NULL, 16);
@@ -668,7 +655,7 @@
 	return ret;
 }
 
-void serialice_wrmsr(uint64_t data, uint32_t addr)
+void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key)
 {
 	uint32_t hi, lo;
 	int filtered;
@@ -679,9 +666,8 @@
 	filtered = serialice_msr_filter(FILTER_WRITE, addr, &hi, &lo);
 
 	if (!filtered) {
-		char command[30];
-		sprintf(command, "*wc%08x=%08x.%08x", addr, hi, lo);
-		serialice_command(command, 0);
+		sprintf(s->command, "*wc%08x.%08x=%08x.%08x", addr, key, hi, lo);
+		serialice_command(s->command, 0);
 	}
 
 	serialice_msr_log(LOG_WRITE, addr, hi, lo, filtered);
@@ -699,13 +685,11 @@
 
 	filtered = serialice_cpuid_filter(&ret);
 	if (!filtered) {
-		char command[27];
+		sprintf(s->command, "*ci%08x.%08x", eax, ecx);
 
-		sprintf(command, "*ci%08x.%08x", eax, ecx);
-
 		// command read back: "\n000006f2.00000000.00001234.12340324"
 		// (36 characters)
-		serialice_command(command, 36);
+		serialice_command(s->command, 36);
 
 		s->buffer[9] = 0; // . -> \0
 		s->buffer[18] = 0; // . -> \0
@@ -911,6 +895,7 @@
 #endif
 
 	s->buffer = qemu_mallocz(BUFFER_SIZE);
+	s->command = qemu_mallocz(BUFFER_SIZE);
 
 	printf("SerialICE: Waiting for handshake with target... ");
 
@@ -937,5 +922,8 @@
 void serialice_exit(void)
 {
 	serialice_lua_exit();
+	qemu_free(s->command);
+	qemu_free(s->buffer);
+	qemu_free(s);
 }
 

Modified: trunk/qemu-0.11.0/serialice.h
===================================================================
--- trunk/qemu-0.11.0/serialice.h	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/qemu-0.11.0/serialice.h	2009-11-19 19:26:18 UTC (rev 52)
@@ -1,6 +1,30 @@
-#ifndef HW_SERIALICE_H
-#define HW_SERIALICE_H
+/*
+ * QEMU PC System Emulator
+ *
+ * Copyright (c) 2009 coresystems GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
 
+#ifndef SERIALICE_H
+#define SERIALICE_H
+
 #include "config-host.h"
 
 extern const char *serialice_device;
@@ -25,8 +49,8 @@
 void serialice_writew(uint16_t data, uint32_t addr);
 void serialice_writel(uint32_t data, uint32_t addr);
 
-uint64_t serialice_rdmsr(uint32_t addr);
-void serialice_wrmsr(uint64_t data, uint32_t addr);
+uint64_t serialice_rdmsr(uint32_t addr, uint32_t key);
+void serialice_wrmsr(uint64_t data, uint32_t addr, uint32_t key);
 
 typedef struct {
 	uint32_t eax, ebx, ecx, edx;

Modified: trunk/qemu-0.11.0/target-i386/op_helper.c
===================================================================
--- trunk/qemu-0.11.0/target-i386/op_helper.c	2009-11-19 18:46:51 UTC (rev 51)
+++ trunk/qemu-0.11.0/target-i386/op_helper.c	2009-11-19 19:26:18 UTC (rev 52)
@@ -3078,7 +3078,7 @@
 
 #ifdef CONFIG_SERIALICE
     if (serialice_active) {
-        serialice_wrmsr(val, (uint32_t)ECX);
+        serialice_wrmsr(val, (uint32_t)ECX, (uint32_t)EDI);
         return;
     }
 #endif
@@ -3215,7 +3215,7 @@
 
 #ifdef CONFIG_SERIALICE
     if (serialice_active) {
-	val = serialice_rdmsr((uint32_t)ECX);
+	val = serialice_rdmsr((uint32_t)ECX, (uint32_t)EDI);
         EAX = (uint32_t)(val);
         EDX = (uint32_t)(val >> 32);
 	return;




More information about the SerialICE mailing list