summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcognet <cognet@FreeBSD.org>2006-01-20 00:46:44 +0000
committercognet <cognet@FreeBSD.org>2006-01-20 00:46:44 +0000
commitf32398d06cd4794224ffe2d76378aab7722ca8c3 (patch)
treee880c87c395a9286931fa4cf85fbc391d50d7026
parent400b5b1afb54d877fd06c32d8d7128328448f0a8 (diff)
downloadFreeBSD-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.c57
-rw-r--r--sys/conf/Makefile.arm4
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 \
OpenPOWER on IntegriCloud