summaryrefslogtreecommitdiffstats
path: root/sys/boot/sparc64/loader
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-02-23 04:04:30 +0000
committerjake <jake@FreeBSD.org>2002-02-23 04:04:30 +0000
commitc34e322792ebc8e9e7b0774f9c8624d709f9c9f4 (patch)
treeb8f65bd3f3c50b70ddc0b51b0fef6ed8d362143f /sys/boot/sparc64/loader
parent9ee486a3f2ecdda839f097d63899d4fc57b5e767 (diff)
downloadFreeBSD-src-c34e322792ebc8e9e7b0774f9c8624d709f9c9f4.zip
FreeBSD-src-c34e322792ebc8e9e7b0774f9c8624d709f9c9f4.tar.gz
Fix fs support ifdefs. Add tftp support. Add physical and virtual
watchpoint support for debugging (under LOADER_DEBUG). Claim the physical and virtual addresses used to map the kernel from the prom; we map it ourselves behind the scenes though. Add a reboot command. Submitted by: tmm
Diffstat (limited to 'sys/boot/sparc64/loader')
-rw-r--r--sys/boot/sparc64/loader/main.c119
1 files changed, 107 insertions, 12 deletions
diff --git a/sys/boot/sparc64/loader/main.c b/sys/boot/sparc64/loader/main.c
index 15a163f..ab66c99 100644
--- a/sys/boot/sparc64/loader/main.c
+++ b/sys/boot/sparc64/loader/main.c
@@ -23,8 +23,9 @@
#include <sys/linker.h>
#include <machine/asi.h>
-#include <machine/bootinfo.h>
#include <machine/elf.h>
+#include <machine/lsu.h>
+#include <machine/metadata.h>
#include <machine/tte.h>
#include "bootstrap.h"
@@ -56,8 +57,6 @@ static int mmu_mapin(vm_offset_t, vm_size_t);
char __progname[] = "FreeBSD/sparc64 loader";
-vm_offset_t kernelpa; /* Begin of kernel and mod memory. */
-vm_offset_t curkpg; /* (PA) used for on-demand map-in. */
vm_offset_t curkva = 0;
vm_offset_t heapva;
int tlbslot = 63; /* Insert first entry at this TLB slot. XXX */
@@ -90,12 +89,15 @@ struct file_format *file_formats[] = {
0
};
struct fs_ops *file_system[] = {
-#ifdef LOAD_DISK_SUPPORT
+#ifdef LOADER_UFS_SUPPORT
&ufs_fsops,
#endif
-#ifdef LOADER_NET_SUPPORT
+#ifdef LOADER_NFS_SUPPORT
&nfs_fsops,
#endif
+#ifdef LOADER_TFTP_SUPPORT
+ &tftp_fsops,
+#endif
0
};
struct netif_driver *netif_drivers[] = {
@@ -111,6 +113,59 @@ struct console *consoles[] = {
0
};
+#ifdef LOADER_DEBUG
+static int
+watch_phys_set_mask(vm_offset_t pa, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_PWPR, ASI_DMMU, pa & (((2UL << 38) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_PW) & ~LSU_PM_MASK) |
+ (mask << LSU_PM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+static int
+watch_phys_set(vm_offset_t pa, int sz)
+{
+ u_long off;
+
+ off = (u_long)pa & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_phys_set_mask(pa, ((1 << sz) - 1) << off));
+}
+
+
+static int
+watch_virt_set_mask(vm_offset_t va, u_long mask)
+{
+ u_long lsucr;
+
+ stxa(AA_DMMU_VWPR, ASI_DMMU, va & (((2UL << 41) - 1) << 3));
+ lsucr = ldxa(0, ASI_LSU_CTL_REG);
+ lsucr = ((lsucr | LSU_VW) & ~LSU_VM_MASK) |
+ (mask << LSU_VM_SHIFT);
+ stxa(0, ASI_LSU_CTL_REG, lsucr);
+ return (0);
+}
+
+static int
+watch_virt_set(vm_offset_t va, int sz)
+{
+ u_long off;
+
+ off = (u_long)va & 7;
+ /* Test for misaligned watch points. */
+ if (off + sz > 8)
+ return (-1);
+ return (watch_virt_set_mask(va, ((1 << sz) - 1) << off));
+}
+#endif
+
/*
* archsw functions
*/
@@ -170,25 +225,45 @@ elf_exec(struct preloaded_file *fp)
static int
mmu_mapin(vm_offset_t va, vm_size_t len)
{
+ vm_offset_t pa, mva;
if (va + len > curkva)
curkva = va + len;
+ pa = (vm_offset_t)-1;
len += va & PAGE_MASK_4M;
va &= ~PAGE_MASK_4M;
while (len) {
if (dtlb_va_to_pa(va) == (vm_offset_t)-1 ||
itlb_va_to_pa(va) == (vm_offset_t)-1) {
- dtlb_enter(tlbslot, curkpg, va,
+ /* Allocate a physical page, claim the virtual area */
+ if (pa == (vm_offset_t)-1) {
+ pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_4M,
+ PAGE_SIZE_4M);
+ if (pa == (vm_offset_t)-1)
+ panic("out of memory");
+ mva = (vm_offset_t)OF_claim_virt(va,
+ PAGE_SIZE_4M, 0);
+ if (mva != va) {
+ panic("can't claim virtual page "
+ "(wanted %#lx, got %#lx)",
+ va, mva);
+ }
+ /* The mappings may have changed, be paranoid. */
+ continue;
+ }
+ dtlb_enter(tlbslot, pa, va,
TD_V | TD_4M | TD_L | TD_CP | TD_CV | TD_P | TD_W);
- itlb_enter(tlbslot, curkpg, va,
+ itlb_enter(tlbslot, pa, va,
TD_V | TD_4M | TD_L | TD_CP | TD_CV | TD_P | TD_W);
tlbslot--;
- curkpg += PAGE_SIZE_4M;
+ pa = (vm_offset_t)-1;
}
len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len;
va += PAGE_SIZE_4M;
}
+ if (pa != (vm_offset_t)-1)
+ OF_release_phys(pa, PAGE_SIZE_4M);
return 0;
}
@@ -200,9 +275,6 @@ init_heap(void)
if (OF_getprop(pmemh, "available", memslices, sizeof(memslices)) <= 0)
OF_exit();
- /* Reserve 16 MB continuous for kernel and modules. */
- kernelpa = (vm_offset_t)OF_alloc_phys(LOADSZ, 0x400000);
- curkpg = kernelpa;
/* There is no need for continuous physical heap memory. */
heapva = (vm_offset_t)OF_claim((void *)HEAPVA, HEAPSZ, 32);
return heapva;
@@ -272,13 +344,35 @@ main(int (*openfirm)(void *))
printf("%s\n", __progname);
printf("bootpath=\"%s\"\n", bootpath);
printf("loaddev=%s\n", getenv("loaddev"));
- printf("kernelpa=0x%lx\n", curkpg);
/* Give control to the machine independent loader code. */
interact();
return 1;
}
+COMMAND_SET(reboot, "reboot", "reboot the system", command_reboot);
+
+static int
+command_reboot(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; devsw[i] != NULL; ++i)
+ if (devsw[i]->dv_cleanup != NULL)
+ (devsw[i]->dv_cleanup)();
+
+ printf("Rebooting...\n");
+ OF_exit();
+}
+
+/* provide this for panic, as it's not in the startup code */
+void
+exit(int code)
+{
+ OF_exit();
+}
+
+#ifdef LOADER_DEBUG
typedef u_int64_t tte_t;
const char *page_sizes[] = {
@@ -331,3 +425,4 @@ pmap_print_tlb(char which)
pmap_print_tte(tag, tte);
}
}
+#endif
OpenPOWER on IntegriCloud