Idwer Vollering (vidwer@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/6158
-gerrit
commit aeea4ac51fb748bd3ec01cc87019e249ebe9c7c1 Author: Idwer Vollering vidwer@gmail.com Date: Mon Jun 30 02:57:01 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@holmes.nl Signed-off-by: Idwer Vollering vidwer@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: