[SerialICE] Patch set updated for serialice: [2/4] HP DL120G5: let SerialICE run from RAM
Patrick Georgi (pgeorgi@google.com)
gerrit at coreboot.org
Sun Aug 9 22:53:22 CEST 2015
Patrick Georgi (pgeorgi at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6158
-gerrit
commit 44babb97c16b0cf9b93bad49cb69ee90117bfb5c
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 | 36 ++++-
SerialICE/start.S | 3 +
5 files changed, 431 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..3ce23ac 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,25 @@ 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.*);
+ *(.ram.text.startup);
+ _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