diff options
author | cognet <cognet@FreeBSD.org> | 2006-01-20 00:46:44 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2006-01-20 00:46:44 +0000 |
commit | f32398d06cd4794224ffe2d76378aab7722ca8c3 (patch) | |
tree | e880c87c395a9286931fa4cf85fbc391d50d7026 | |
parent | 400b5b1afb54d877fd06c32d8d7128328448f0a8 (diff) | |
download | FreeBSD-src-f32398d06cd4794224ffe2d76378aab7722ca8c3.zip FreeBSD-src-f32398d06cd4794224ffe2d76378aab7722ca8c3.tar.gz |
Build a minimal pagetables, with only section mappings, mapped write through,
to speed up the decompression.
-rw-r--r-- | sys/arm/arm/elf_trampoline.c | 57 | ||||
-rw-r--r-- | sys/conf/Makefile.arm | 4 |
2 files changed, 55 insertions, 6 deletions
diff --git a/sys/arm/arm/elf_trampoline.c b/sys/arm/arm/elf_trampoline.c index 1443519..2f6d7d7 100644 --- a/sys/arm/arm/elf_trampoline.c +++ b/sys/arm/arm/elf_trampoline.c @@ -30,6 +30,8 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/inflate.h> #include <machine/elf.h> +#include <machine/pte.h> + #include <stdlib.h> #include "opt_global.h" @@ -204,7 +206,7 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end, { Elf32_Ehdr *eh; Elf32_Phdr phdr[512] /* XXX */, *php; - Elf32_Shdr *shdr; + Elf32_Shdr shdr[512] /* XXX */; int i,j; void *entry_point; int symtabindex = -1; @@ -228,9 +230,6 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end, } /* Save the symbol tables, as there're about to be scratched. */ - lastaddr = roundup(lastaddr, sizeof(long)); - shdr = (Elf_Shdr *)lastaddr; - lastaddr += sizeof(*shdr) * eh->e_shnum; memcpy(shdr, (void *)(kstart + eh->e_shoff), sizeof(*shdr) * eh->e_shnum); if (eh->e_shnum * eh->e_shentsize != 0 && @@ -337,7 +336,51 @@ load_kernel(unsigned int kstart, unsigned int curaddr,unsigned int func_end, extern char func_end[]; extern void *_end; -void __start(void) + +#define PMAP_DOMAIN_KERNEL 15 /* + * Just define it instead of including the + * whole VM headers set. + */ +int __hack; +static __inline void +setup_pagetables(unsigned int pt_addr, vm_paddr_t physstart, vm_paddr_t physend) +{ + unsigned int *pd = (unsigned int *)pt_addr; + vm_paddr_t addr; + int domain = (DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT; + int tmp; + + bzero(pd, L1_TABLE_SIZE); + for (addr = physstart; addr < physend; addr += L1_S_SIZE) + pd[addr >> L1_S_SHIFT] = L1_TYPE_S|L1_S_C|L1_S_AP(AP_KRW)| + L1_S_DOM(PMAP_DOMAIN_KERNEL) | addr; + /* XXX: See below */ + if (0xfff00000 < physstart || 0xfff00000 > physend) + pd[0xfff00000 >> L1_S_SHIFT] = L1_TYPE_S|L1_S_AP(AP_KRW)| + L1_S_DOM(PMAP_DOMAIN_KERNEL)|physstart; + __asm __volatile("mcr p15, 0, %1, c2, c0, 0\n" /* set TTB */ + "mcr p15, 0, %1, c8, c7, 0\n" /* Flush TTB */ + "mcr p15, 0, %2, c3, c0, 0\n" /* Set DAR */ + "mrc p15, 0, %0, c1, c0, 0\n" + "orr %0, %0, #1\n" /* MMU_ENABLE */ + "mcr p15, 0, %0, c1, c0, 0\n" + "mrc p15, 0, %0, c2, c0, 0\n" /* CPWAIT */ + "mov r0, r0\n" + "sub pc, pc, #4\n" : + "=r" (tmp) : "r" (pd), "r" (domain)); + + /* + * XXX: This is the most stupid workaround I've ever wrote. + * For some reason, the KB9202 won't boot the kernel unless + * we access an address which is not in the + * 0x20000000 - 0x20ffffff range. I hope I'll understand + * what's going on later. + */ + __hack = *(volatile int *)0xfffff21c; +} + +void +__start(void) { void *curaddr; void *dst; @@ -348,6 +391,10 @@ void __start(void) curaddr = (void*)((unsigned int)curaddr & 0xfff00000); #ifdef KZIP if (*kernel == 0x1f && kernel[1] == 0x8b) { + int pt_addr = (((int)&_end + KERNSIZE + 0x100) & + ~(L1_TABLE_SIZE - 1)) + L1_TABLE_SIZE; + setup_pagetables(pt_addr, (vm_paddr_t)curaddr, + (vm_paddr_t)curaddr + 0x10000000); /* Gzipped kernel */ dst = inflate_kernel(kernel, &_end); kernel = (char *)&_end; diff --git a/sys/conf/Makefile.arm b/sys/conf/Makefile.arm index a68c123..ffe984b 100644 --- a/sys/conf/Makefile.arm +++ b/sys/conf/Makefile.arm @@ -77,9 +77,11 @@ ${KERNEL_KO}.tramp: ${KERNEL_KO} ${OBJCOPY} ${STRIP_FLAGS} ${KERNEL_KO}.tmp echo "#define KERNNAME \"${KERNEL_KO}.tmp.gz\"" \ >opt_kernname.h + eval $$(stat -s ${KERNEL_KO}.tmp) && \ + echo "#define KERNSIZE $$st_size" >>opt_kernname.h gzip -9 ${KERNEL_KO}.tmp eval $$(stat -s ${KERNEL_KO}.tmp.gz) && \ - echo "#define KERNSIZE $$st_size" >>opt_kernname.h + echo "#define KERNCOMPSIZE $$st_size" >>opt_kernname.h ${CC} -O2 -DKZIP -I. -c $S/kern/inflate.c -o inflate-tramp.o ${CC} -O -nostdlib -I. -Xlinker -T -Xlinker ldscript.$M.tramp \ -DKZIP $S/$M/$M/elf_trampoline.c inflate-tramp.o $S/$M/$M/inckern.S \ |