summaryrefslogtreecommitdiffstats
path: root/sys/mips
diff options
context:
space:
mode:
authorgonzo <gonzo@FreeBSD.org>2010-01-24 03:10:48 +0000
committergonzo <gonzo@FreeBSD.org>2010-01-24 03:10:48 +0000
commita5fe9358cb74f3a902fb68fdfed0569487e08726 (patch)
treebd1823571c44f22e39855ca1288e119ff138ad82 /sys/mips
parentd184a1dc591e220ab469cf09ad53989e6d347422 (diff)
downloadFreeBSD-src-a5fe9358cb74f3a902fb68fdfed0569487e08726.zip
FreeBSD-src-a5fe9358cb74f3a902fb68fdfed0569487e08726.tar.gz
- Introduce kernel_kseg0_end variable that marks first address in KSEG0
available for use. All data below this address considered to be used by kernel. Along with kernel own data it might be symbol tables prepeared by trampoline code, boot loader service data passed for further analysis by kernel, etc... By default kernel_kseg0_end points to the end of loaded kernel. - Introduce mips_postboot_fixup function. It checks for symbol information copied by ELF trampoline and passes it to KDB
Diffstat (limited to 'sys/mips')
-rw-r--r--sys/mips/include/md_var.h2
-rw-r--r--sys/mips/mips/machdep.c33
2 files changed, 35 insertions, 0 deletions
diff --git a/sys/mips/include/md_var.h b/sys/mips/include/md_var.h
index dbfb451..ab3c3e6 100644
--- a/sys/mips/include/md_var.h
+++ b/sys/mips/include/md_var.h
@@ -44,6 +44,7 @@ extern char sigcode[];
extern int szsigcode, szosigcode;
extern vm_offset_t kstack0;
+extern vm_offset_t kernel_kseg0_end;
void MipsSaveCurFPState(struct thread *);
void fork_trampoline(void);
@@ -69,6 +70,7 @@ void cpu_identify(void);
void mips_cpu_init(void);
void mips_pcpu0_init(void);
void mips_proc0_init(void);
+void mips_postboot_fixup(void);
/* Platform call-downs. */
void platform_identify(void);
diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c
index d31ffce..029c3dc 100644
--- a/sys/mips/mips/machdep.c
+++ b/sys/mips/mips/machdep.c
@@ -85,6 +85,7 @@ __FBSDID("$FreeBSD$");
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpuregs.h>
+#include <machine/elf.h>
#include <machine/hwfunc.h>
#include <machine/intr_machdep.h>
#include <machine/md_var.h>
@@ -151,9 +152,18 @@ extern char MipsTLBMiss[], MipsTLBMissEnd[];
extern char MipsCache[], MipsCacheEnd[];
extern char edata[], end[];
+#ifdef DDB
+extern vm_offset_t ksym_start, ksym_end;
+#endif
u_int32_t bootdev;
struct bootinfo bootinfo;
+/*
+ * First kseg0 address available for use. By default it's equal to &end.
+ * But in some cases there might be additional data placed right after
+ * _end by loader or ELF trampoline.
+ */
+vm_offset_t kernel_kseg0_end = (vm_offset_t)&end;
static void
cpu_startup(void *dummy)
@@ -360,6 +370,29 @@ mips_vector_init(void)
}
/*
+ * Fix kernel_kseg0_end address in case trampoline placed debug sympols
+ * data there
+ */
+void
+mips_postboot_fixup(void)
+{
+#ifdef DDB
+ Elf_Size *trampoline_data = (Elf_Size*)kernel_kseg0_end;
+ Elf_Size symtabsize = 0;
+
+ if (trampoline_data[0] == SYMTAB_MAGIC) {
+ symtabsize = trampoline_data[1];
+ kernel_kseg0_end += 2 * sizeof(Elf_Size);
+ /* start of .symtab */
+ ksym_start = kernel_kseg0_end;
+ kernel_kseg0_end += symtabsize;
+ /* end of .strtab */
+ ksym_end = kernel_kseg0_end;
+ }
+#endif
+}
+
+/*
* Many SoCs have a means to reset the core itself. Others do not, or
* the method is unknown to us. For those cases, we jump to the mips
* reset vector and hope for the best. This works well in practice.
OpenPOWER on IntegriCloud