summaryrefslogtreecommitdiffstats
path: root/sys/boot
diff options
context:
space:
mode:
authorkmacy <kmacy@FreeBSD.org>2006-12-18 07:35:14 +0000
committerkmacy <kmacy@FreeBSD.org>2006-12-18 07:35:14 +0000
commitf94653c6cc26525ed3dbe8b0a3e51efc8114d105 (patch)
tree39032dc3325881cc796e8b3f4ccfb5e90ae83146 /sys/boot
parent0e8bee8e995ae69fcaa6d6bf2a5c74fc88c582b9 (diff)
downloadFreeBSD-src-f94653c6cc26525ed3dbe8b0a3e51efc8114d105.zip
FreeBSD-src-f94653c6cc26525ed3dbe8b0a3e51efc8114d105.tar.gz
add an interface for passing the entire kernel size up front to the
loader so that it can memory can be allocated aligned at the beginning of the desired large page
Diffstat (limited to 'sys/boot')
-rw-r--r--sys/boot/common/bootstrap.h2
-rw-r--r--sys/boot/sparc64/loader/main.c51
2 files changed, 52 insertions, 1 deletions
diff --git a/sys/boot/common/bootstrap.h b/sys/boot/common/bootstrap.h
index 862b06c..6ecd235 100644
--- a/sys/boot/common/bootstrap.h
+++ b/sys/boot/common/bootstrap.h
@@ -292,6 +292,8 @@ struct arch_switch
/* Perform ISA byte port I/O (only for systems with ISA) */
int (*arch_isainb)(int port);
void (*arch_isaoutb)(int port, int value);
+ /* Pass in initial kernel memory size */
+ void (*arch_maphint)(vm_offset_t va, size_t len);
};
extern struct arch_switch archsw;
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index b62570d..a351c2c 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -87,6 +87,7 @@ int itlb_slot_max;
/* sun4v */
struct tlb_entry *tlb_store;
+int is_sun4v = 0;
/*
* no direct TLB access on sun4v
* we somewhat arbitrarily declare enough
@@ -249,6 +250,52 @@ sparc64_copyin(const void *src, vm_offset_t dest, size_t len)
return len;
}
+static void
+sparc64_maphint(vm_offset_t va, size_t len)
+{
+ vm_paddr_t pa;
+ vm_offset_t mva;
+ size_t size;
+ int i, ret, free_excess = 0;
+
+ if (!is_sun4v)
+ return;
+
+ if (tlb_store[va >> 22].te_pa != -1)
+ return;
+
+ /* round up to nearest 4MB page */
+ size = (len + PAGE_MASK_4M) & ~PAGE_MASK_4M;
+#if 0
+ pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_256M, PAGE_SIZE_256M);
+
+ if (pa != -1)
+ free_excess = 1;
+ else
+#endif
+ pa = (vm_offset_t)OF_alloc_phys(size, PAGE_SIZE_256M);
+ if (pa == -1)
+ pa = (vm_offset_t)OF_alloc_phys(size, PAGE_SIZE_4M);
+ if (pa == -1)
+ panic("out of memory");
+
+ for (i = 0; i < size; i += PAGE_SIZE_4M) {
+ mva = (vm_offset_t)OF_claim_virt(va + i, PAGE_SIZE_4M, 0);
+ if (mva != (va + i)) {
+ panic("can't claim virtual page "
+ "(wanted %#lx, got %#lx)",
+ va, mva);
+ }
+
+ tlb_store[mva >> 22].te_pa = pa + i;
+ if ((ret = OF_map_phys(-1, PAGE_SIZE_4M, mva, pa + i)) != 0)
+ printf("OF_map_phys failed: %d\n", ret);
+ }
+ if (free_excess)
+ OF_release_phys((vm_offset_t)pa, PAGE_SIZE_256M);
+}
+
+
/*
* other MD functions
*/
@@ -277,7 +324,7 @@ __elfN(exec)(struct preloaded_file *fp)
entry = e->e_entry;
- OF_release(heapva, HEAPSZ);
+ OF_release((void *)heapva, HEAPSZ);
((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware);
@@ -467,6 +514,7 @@ main(int (*openfirm)(void *))
archsw.arch_copyout = ofw_copyout;
archsw.arch_readin = sparc64_readin;
archsw.arch_autoload = sparc64_autoload;
+ archsw.arch_maphint = sparc64_maphint;
init_heap();
setheap((void *)heapva, (void *)(heapva + HEAPSZ));
@@ -480,6 +528,7 @@ main(int (*openfirm)(void *))
if (!strcmp(compatible, "sun4v")) {
printf("\nBooting with sun4v support.\n");
mmu_ops = &mmu_ops_sun4v;
+ is_sun4v = 1;
} else {
printf("\nBooting with sun4u support.\n");
mmu_ops = &mmu_ops_sun4u;
OpenPOWER on IntegriCloud