[SerialICE] Patch set updated for serialice: f4cde8e [2/4] HP DL120G5: let SerialICE run from RAM

Idwer Vollering (vidwer@gmail.com) gerrit at coreboot.org
Mon Jun 30 15:41:22 CEST 2014


Idwer Vollering (vidwer at gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6158

-gerrit

commit f4cde8e0eaea9d6795028e6896ca6e307f3eebc0
Author: Idwer Vollering <vidwer at gmail.com>
Date:   Mon Jun 30 03:58:53 2014 +0200

    [2/4] HP DL120G5: let SerialICE run from RAM
    
    Patches for copying a RAM version of serialice to RAM and compression for fast dumping.
    
    Change-Id: I12d699a1c0a30b5481adca34b3b67019b800c729
    Signed-off-by: Ruud Schramp <schramp at holmes.nl>
    Signed-off-by: Idwer Vollering <vidwer at gmail.com>
---
 SerialICE/Makefile     |   8 +-
 SerialICE/serial.c     |   5 +
 SerialICE/serialice.c  | 382 +++++++++++++++++++++++++++++++++++++++++++++++++
 SerialICE/serialice.ld |  35 ++++-
 SerialICE/start.S      |   3 +
 5 files changed, 430 insertions(+), 3 deletions(-)

diff --git a/SerialICE/Makefile b/SerialICE/Makefile
index e764992..be8d698 100644
--- a/SerialICE/Makefile
+++ b/SerialICE/Makefile
@@ -114,9 +114,13 @@ $(obj)/serialice.rom: $(obj)/serialice.elf
 	$(Q)printf "  OBJCOPY  $(subst $(shell pwd)/,,$(@))\n"
 	$(Q)$(OBJCOPY) -O binary $< $@
 
-$(obj)/serialice.elf: $(obj)/serialice.o $(obj)/start.o $(src)/serialice.ld
+$(obj)/serialice-ram.o: $(SOURCES)
+	$(CC) -O2 "-DVERSION=\"$(VERSION)\" \"RAM\"" -DCOMPRESS -I . -I build/ -I mainboard/ -c serialice.c -o build/serialice-ram.o
+	$(OBJCOPY) --prefix-symbols _ram --prefix-sections .ram build/serialice-ram.o build/serialice-ram.o
+
+$(obj)/serialice.elf: $(obj)/serialice.o $(obj)/start.o $(src)/serialice.ld $(obj)/serialice-ram.o
 	$(Q)printf "  LINK     $(subst $(shell pwd)/,,$(@))\n"
-	$(Q)$(CC) $(LDFLAGS) -o $@ $(obj)/serialice.o $(obj)/start.o
+	$(Q)$(CC) $(LDFLAGS) -o $@ $(obj)/serialice.o $(obj)/serialice-ram.o $(obj)/start.o
 	$(Q)$(NM) $@ | sort -u > $(obj)/serialice.map
 
 $(obj)/serialice.S: $(SOURCES) $(obj)/romcc
diff --git a/SerialICE/serial.c b/SerialICE/serial.c
index 9188deb..56f185c 100644
--- a/SerialICE/serial.c
+++ b/SerialICE/serial.c
@@ -67,6 +67,11 @@ static void sio_putc(u8 data)
 	while (!(inb(SIO_PORT + UART_LSR) & 0x40)) ;
 }
 
+static int sio_dataready(void)
+{
+	return ((inb(SIO_PORT + UART_LSR) & 0x01));
+}
+
 static u8 sio_getc(void)
 {
 	u8 val;
diff --git a/SerialICE/serialice.c b/SerialICE/serialice.c
index 56f6dac..a05cdd4 100644
--- a/SerialICE/serialice.c
+++ b/SerialICE/serialice.c
@@ -17,6 +17,24 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#define STACKTOP 0x20000
+
+#ifdef COMPRESS
+
+#define u8 lzf_u8
+#define u16 lzf_u16
+
+#define INIT_HTAB 1
+#define HLOG 13
+#define AVOID_ERRNO 1
+
+#include "lzf/liblzf-3.6/lzf_c.c"
+
+#undef u8
+#undef u16
+
+#endif
+
 #include <types.h>
 #include <serialice.h>
 #include <io.h>
@@ -28,7 +46,281 @@
 /* SIO functions */
 #include "serial.c"
 
+#ifdef COMPRESS
+//Above 1Meg
+#define COMPRESSBUF 0x100000
+//1.1 Meg buffer
+#define COMPRESSBUFSIZE ((512*1024))
+#define COMPRESSBLOCKSIZE ((256*1024))
+
+#define PAGETABLE (COMPRESSBUF+COMPRESSBUFSIZE)
+
+#define PAE
+
+#ifdef PAE
+/* This implementation targets huge (2M pages) */
+
+/* This code assumes the sizeof an long int == 8 */
+
+typedef struct {
+	long long int pagedirptr[512]; //Actually 4, but must be page alligned
+	long long int pagedir[512*4];
+} pagetbl;
+
+void __flush_tlb_global(unsigned int pt)
+{
+/*
+ * Intel CPU features in CR4
+ */
+#define X86_CR4_VME     0x00000001 /* enable vm86 extensions */
+#define X86_CR4_PVI     0x00000002 /* virtual interrupts flag enable */
+#define X86_CR4_TSD     0x00000004 /* disable time stamp at ipl 3 */
+#define X86_CR4_DE      0x00000008 /* enable debugging extensions */
+#define X86_CR4_PSE     0x00000010 /* enable page size extensions */
+#define X86_CR4_PAE     0x00000020 /* enable physical address extensions */
+#define X86_CR4_MCE     0x00000040 /* Machine check enable */
+#define X86_CR4_PGE     0x00000080 /* enable global pages */
+#define X86_CR4_PCE     0x00000100 /* enable performance counters at ipl 3 */
+#define X86_CR4_OSFXSR  0x00000200 /* enable fast FPU save and restore */
+#define X86_CR4_OSXMMEXCPT 0x00000400 /* enable unmasked SSE exceptions */
+#define X86_CR4_VMXE    0x00002000 /* enable VMX virtualization */
+#define X86_CR4_OSXSAVE 0x00040000 /* enable xsave and xrestore */
+
+	do {
+		unsigned int mmu_cr4_features;
+		unsigned int mmu_cr0;
+		long long int local_idt=0;
+
+		__asm__ __volatile__(                                   
+				"lidt %0;                     \n"        
+				:
+				: "m" (local_idt)
+				: "memory");                                    
+		__asm__ __volatile__(                                   
+				"movl %%cr4, %0;                     \n"        
+				"movl %%cr0, %1;                     \n"        
+				: "=&r" (mmu_cr4_features),
+				  "=&r" (mmu_cr0)                                
+				:
+				: "memory");                                    
+
+		mmu_cr4_features = mmu_cr4_features | X86_CR4_PGE | X86_CR4_PSE | X86_CR4_PAE;
+		mmu_cr0 = mmu_cr0 | 0x80000000; //Paging On
+
+		__asm__ __volatile__(                                   
+				"movl %1, %%cr4;  # turn on extensions     \n"        
+				"movl %0, %%cr3;  # Set Pagetable        \n"        
+				"movl %2, %%cr0;  # Enable paging \n"        
+				"ljmp $0x08,$1f\n"        
+				"1:\n"        
+				:
+				: "r" (pt),                                
+				"r" (mmu_cr4_features),
+				"r" (mmu_cr0)                        
+				: "memory");                                    
+	} while (0);
+};
+
+#define _PAGE_BIT_PRESENT       0       /* is present */
+#define _PAGE_BIT_RW            1       /* writeable */
+#define _PAGE_BIT_USER          2       /* userspace addressable */
+#define _PAGE_BIT_PWT           3       /* page write through */
+#define _PAGE_BIT_PCD           4       /* page cache disabled */
+#define _PAGE_BIT_ACCESSED      5       /* was accessed (raised by CPU) */
+#define _PAGE_BIT_DIRTY         6       /* was written to (raised by CPU) */
+#define _PAGE_BIT_PSE           7       /* 4 MB (or 2MB) page */
+#define _PAGE_BIT_PAT           7       /* on 4KB pages */
+#define _PAGE_BIT_GLOBAL        8       /* Global TLB entry PPro+ */
+#define _PAGE_BIT_UNUSED1       9       /* available for programmer */
+#define _PAGE_BIT_IOMAP         10      /* flag used to indicate IO mapping */
+#define _PAGE_BIT_HIDDEN        11      /* hidden by kmemcheck */
+#define _PAGE_BIT_PAT_LARGE     12      /* On 2MB or 1GB pages */
+#define _PAGE_BIT_SPECIAL       _PAGE_BIT_UNUSED1
+#define _PAGE_BIT_CPA_TEST      _PAGE_BIT_UNUSED1
+#define _PAGE_BIT_NX           63       /* No execute: only valid after cpuid check */
+
+int paged_gigabyte;
+
+void enter_pae()
+{
+	u8 windowed_gig; //The area starting at 0x40000000 is a window to a specified gig of memory
+			 //Entering 01 will give a linear view of the lowest
+			 //4G of mem,
+			 //Entering 04 will show the area between 4 and 5G at
+			 //the address 0x40000000
+	windowed_gig=sio_get8();
+	paged_gigabyte=windowed_gig;
+
+	unsigned long long int windowbase= ((unsigned long long int )windowed_gig)*0x40000000L;
+	if (sizeof (long long int)!=8)
+	{
+		sio_putstring("ERROR INT SIZE");
+		return ;
+	};
+	long long int pagenr;
+	pagetbl *PTBL=(pagetbl *) PAGETABLE;
+	PTBL->pagedirptr[0]=0x1 | (long long int) &PTBL->pagedir[0*512] ;
+	PTBL->pagedirptr[1]=0x1 | (long long int) &PTBL->pagedir[1*512] ;
+	PTBL->pagedirptr[2]=0x1 | (long long int) &PTBL->pagedir[2*512] ;
+	PTBL->pagedirptr[3]=0x1 | (long long int) &PTBL->pagedir[3*512] ;
+	for (pagenr=0;pagenr<(4*512);pagenr++)
+		PTBL->pagedir[pagenr]=0x8F | pagenr*(2*1024*1024);
+	for (pagenr=512;pagenr<(2*512);pagenr++)
+		PTBL->pagedir[pagenr]=0x8F | ((pagenr-512) *(2*1024*1024)) | windowbase ;
+//0x8F
+//_PAGE_BIT_PSE _PAGE_BIT_PWT  _PAGE_BIT_USER  _PAGE_BIT_RW _PAGE_BIT_PRESENT 
+	__flush_tlb_global((int) PTBL);
+};
+
+#endif //PAE
+
+
+void *memset(void *s, int c, size_t n)
+{
+	int i;
+	char *ss=(char *) s;
+	for(i=0;i<n;i++)
+	{
+		*ss=c;
+		ss++;
+	};
+};
+
+static void post_putc(u8 c)
+{
+		outb(c,0x80);
+}
+
+static void post_putstring(char *str)
+{
+	while(*str!=0)
+		post_putc(*str++);
+}
+
+static void post_put8(u32 data)
+{
+	int i;
+	for (i=4; i >= 0; i -= 4) {
+		u8 c = (data >> i) & 0xf;
+		if (c > 9)		\
+			c += ('a' - 10);	\
+		else			\
+			c += '0';	\
+		post_putc(c);
+	};
+}
+
+static void post_put32(u32 data)
+{
+	int i;
+	for (i=28; i >= 0; i -= 4) {
+		u8 c = (data >> i) & 0xf;
+		if (c > 9)		\
+			c += ('a' - 10);	\
+		else			\
+			c += '0';	\
+		post_putc(c);
+	};
+}
+
+static void serialice_dump_compressed2(u8 * addr)
+{
+	unsigned int outsize;
+	u8 *data;
+	u32 checksum=0;
+	for(data = addr;data<(addr+COMPRESSBLOCKSIZE);data++)
+		checksum += *data;
+
+	outsize = lzf_compress ((void *) addr,COMPRESSBLOCKSIZE, (void *) COMPRESSBUF, COMPRESSBUFSIZE);
+
+	sio_putstring("COMP");
+	sio_put8((u8) paged_gigabyte);
+	sio_put32((u32) addr);
+	sio_put32((u32) COMPRESSBLOCKSIZE);
+	sio_put32((u32) outsize);
+	sio_put32((u32) checksum);
+	for(data = (u8 *) COMPRESSBUF ;data<(u8 *) (COMPRESSBUF+outsize);data++)
+		sio_putc(*data);
+};
+
+static void serialice_dump_compressed(void)
+{
+	u32 addr;
+	u32 endaddr;
+	addr = sio_get32();
+	sio_getc();	// skip .
+	endaddr = sio_get32();
+	while ((!sio_dataready()) && (addr < endaddr)) {
+		serialice_dump_compressed2((char *) addr);
+		addr+=COMPRESSBLOCKSIZE;
+	};
+};
+
+static void post_dump_compressed2(u8 * addr)
+{
+	unsigned int outsize;
+	u8 *data;
+	u32 checksum=0;
+	for(data = addr;data<(addr+COMPRESSBLOCKSIZE);data++)
+		checksum += *data;
+
+	outsize = lzf_compress ((void *) addr,COMPRESSBLOCKSIZE, (void *) COMPRESSBUF, COMPRESSBUFSIZE);
+
+	post_putstring("COMP");
+	post_put8((u8) paged_gigabyte);
+	post_put32((u32) addr);
+	post_put32((u32) COMPRESSBLOCKSIZE);
+	post_put32((u32) outsize);
+	post_put32((u32) checksum);
+	for(data = (u8 *) COMPRESSBUF ;data<(u8 *) (COMPRESSBUF+outsize);data++)
+		post_putc(*data);
+};
+
+static void post_dump_compressed(void)
+{
+	u32 addr;
+	u32 endaddr;
+	addr = sio_get32();
+	sio_getc();	// skip .
+	endaddr = sio_get32();
+	while ((!sio_dataready()) && (addr < endaddr)) {
+		post_dump_compressed2((char *) addr);
+		addr+=COMPRESSBLOCKSIZE;
+	};
+};
+
 /* Accessor functions */
+static void serialice_dump_post(void)
+{
+	u32 addr;
+
+	// Format:
+	// *rm00000000.w
+	addr = sio_get32();
+	while (!sio_dataready()) {
+	     int b;
+	     for (b=0;b<0x1000;b++)
+	     {
+		outb(read8(addr),0x80);
+		addr++;
+	     };
+	};
+}
+
+#endif
+
+static int serialice_run_from_ram(void)
+{
+/* Copy to ram */
+	__asm__ volatile ("movl $_shadow_dst_begin,%%edi"::);
+	__asm__ volatile ("movl $_shadow_src_begin,%%esi"::);
+	__asm__ volatile ("movl $_shadow_dst_end, %%ecx"::);
+	__asm__ volatile ("subl $_shadow_dst_begin, %%ecx"::);
+	__asm__ volatile ("cld ; rep ; movsb");
+	//STACKTOP
+	__asm__ volatile ("movl $0x20000,%%esp\n\tcall _rammain\n\t"::);
+	return 0;
+}
 
 static void serialice_read_memory(void)
 {
@@ -50,6 +342,68 @@ static void serialice_read_memory(void)
 	}
 }
 
+
+#if 0
+
+static void serialice_scan_memory(void)
+{
+	u32 addr;
+
+	// Format:
+	// *dm00000000
+	addr = sio_get32();
+	while (!sio_dataready()) {
+		u8 byte;
+		sio_putc('\r');
+		sio_putc('\n');
+		sio_put32(addr);
+		sio_putc(' ');
+		do {
+			byte=read8(addr);
+			if ((byte>='a') && (byte<'z')) sio_putc(byte);
+			if (byte>='A' && byte<='Z') sio_putc(byte);
+			if (byte>='0' && byte<='9') sio_putc(byte);
+			addr++;
+		} while ((addr & 0x1F) !=0);
+		addr += (0x2000-0x20);
+	};
+
+	sio_putc('\r'); sio_putc('\n');
+}
+
+#endif
+
+static void serialice_dump_memory(void)
+{
+	u32 addr;
+	u32 checksum;
+
+	// Format:
+	// *dm00000000
+	addr = sio_get32();
+	checksum=0;
+	while (!sio_dataready()) {
+		u8 byte;
+		if ( (addr & 0xFFFF) == 0) {
+			sio_putc(checksum);
+			sio_putc(checksum>>8);
+			sio_putc(checksum>>16);
+			sio_putc(checksum>>24);
+			checksum=0;
+			sio_putc('S');
+			sio_putc('T');
+			sio_putc('R');
+			sio_putc('T');
+			sio_put32(addr);
+		};
+		byte=read8(addr);
+		sio_putc(byte);
+		checksum+=byte;
+		addr++;
+	};
+	sio_putc('\r'); sio_putc('\n');
+}
+
 static void serialice_write_memory(void)
 {
 	u8 width;
@@ -207,6 +561,10 @@ int main(void)
 
 	serialice_version();
 
+#ifdef COMPRESS
+	paged_gigabyte=1;
+#endif
+
 	while(1) {
 		u16 c;
 		sio_putstring("\n> ");
@@ -225,6 +583,14 @@ int main(void)
 		case (('w' << 8)|'m'): // Write Memory *wm
 			serialice_write_memory();
 			break;
+		case (('d' << 8)|'m'): // Dump Memory *dm
+			serialice_dump_memory();
+			break;
+#ifdef COMPRESS
+		case (('c' << 8)|'m'): // Dump Memory compressed *cm
+			serialice_dump_compressed();
+			break;
+#endif
 		case (('r' << 8)|'i'): // Read IO *ri
 			serialice_read_io();
 			break;
@@ -240,6 +606,22 @@ int main(void)
 		case (('c' << 8)|'i'): // Read CPUID *ci
 			serialice_cpuinfo();
 			break;
+#ifdef COMPRESS
+		case (('d' << 8)|'p'): // Post Write
+			serialice_dump_post();
+			break;
+		case (('c' << 8)|'p'): // Compressed Post Dump
+			post_dump_compressed();
+			break;
+#endif
+		case (('r' << 8)|'r'): // Post Write
+			serialice_run_from_ram();
+			break;
+#ifdef PAE
+		case (('p' << 8)|'a'): // Post Write
+			enter_pae();
+			break;
+#endif
 		case (('m' << 8)|'b'): // Read mainboard type *mb
 			serialice_mainboard();
 			break;
diff --git a/SerialICE/serialice.ld b/SerialICE/serialice.ld
index f43d9f2..610de12 100644
--- a/SerialICE/serialice.ld
+++ b/SerialICE/serialice.ld
@@ -20,21 +20,39 @@
 OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
 OUTPUT_ARCH(i386)
 
+_PHYS_LOCATION = 0x1000;
+_FLASHSIZE = (2 * 1024 * 1024);
+
 ALIGNED_ROMBASE = 0x100000000 - (ALIGNED_ROMSIZE);
 
 _ROMSIZE = (1024 * 64);
+_FLASHBASE = 0x100000000 - (_FLASHSIZE);
+_ROMCOPY = 0x100000000 - (2 * _ROMSIZE);
 _ROMBASE = 0x100000000 - (_ROMSIZE);
 
 SECTIONS {
+	. = _FLASHBASE ;
+	.empty : {
+		BYTE(0xFF) ;
+		FILL(0xFF) ;
+		. = _FLASHSIZE - (_ROMSIZE * 2) ;
+	}
+	. = _ROMCOPY ;
+	.romcopy : {
+		_shadow_src_begin = . ;
+		_ram_shadow_src_begin = . ;
+	}
 
 	. = ALIGNED_ROMBASE;
 
 	.rom : {
 		. = ALIGNED_ROMSIZE - _ROMSIZE;
 		_main = . ;
+		_ram_rammain = . ;
 		*(.rom.text);
-		*(.text);
 		*(.rom.data);
+
+		*(.text);
 		*(.data);
 		*(.rodata);
 		*(.rodata.*);
@@ -60,9 +78,24 @@ SECTIONS {
 		BYTE(0x00);
 	}
 
+	.shadow _PHYS_LOCATION : AT (_ROMCOPY) {
+		_shadow_dst_begin = . ;
+		_ram_shadow_dst_begin = . ;
+
+		*(.ram.rom.text);
+		*(.ram.text);
+		*(.ram.rom.data);
+		*(.ram.data);
+		*(.ram.rodata);
+		*(.ram.rodata.*);
+		_shadow_dst_end = . ;
+		_ram_shadow_dst_end = . ;
+	}
 	/DISCARD/ : {
 		*(.comment)
 		*(.note.*)
 		*(.note)
+		*(.ram.eh_frame);
+		*(.ram.comment);
 	}
 }
diff --git a/SerialICE/start.S b/SerialICE/start.S
index 2ec0bb3..d926ef5 100644
--- a/SerialICE/start.S
+++ b/SerialICE/start.S
@@ -19,6 +19,9 @@
 
 #include "serialice.h"
 
+	/* messages */
+	.section ".rom.text"
+	.globl	_c_main
 	.code32
 
 _c_main:



More information about the SerialICE mailing list