summaryrefslogtreecommitdiffstats
path: root/sys/i386
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-12-28 04:48:30 +0000
committerkib <kib@FreeBSD.org>2016-12-28 04:48:30 +0000
commitc500fe201f75cd47504133e46fa0c60a43ec6973 (patch)
tree921f70b9fa0bf557047d9bb853c1ba019e19cb97 /sys/i386
parentc7359d9413c3c0507304ec9530281a7954b3b877 (diff)
downloadFreeBSD-src-c500fe201f75cd47504133e46fa0c60a43ec6973.zip
FreeBSD-src-c500fe201f75cd47504133e46fa0c60a43ec6973.tar.gz
MFC r304957, r304958, r306310 (by bde):
Fix vm86 initialization. MFC r310050: Improve very early trap handling on amd64.
Diffstat (limited to 'sys/i386')
-rw-r--r--sys/i386/i386/machdep.c83
1 files changed, 55 insertions, 28 deletions
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index 89e67a5..9200d00 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -2089,7 +2089,6 @@ getmemsize(int first)
* use that and do not make any VM86 calls.
*/
physmap_idx = 0;
- smapbase = NULL;
kmdp = preload_search_by_type("elf kernel");
if (kmdp == NULL)
kmdp = preload_search_by_type("elf32 kernel");
@@ -2223,6 +2222,9 @@ physmap_done:
* highest page of the physical address space. It should be
* called something like "Maxphyspage". We may adjust this
* based on ``hw.physmem'' and the results of the memory test.
+ *
+ * This is especially confusing when it is much larger than the
+ * memory size and is displayed as "realmem".
*/
Maxmem = atop(physmap[physmap_idx + 1]);
@@ -2428,6 +2430,19 @@ do_next:
}
#endif /* PC98 */
+static void
+i386_kdb_init(void)
+{
+#ifdef DDB
+ db_fetch_ksymtab(bootinfo.bi_symtab, bootinfo.bi_esymtab);
+#endif
+ kdb_init();
+#ifdef KDB
+ if (boothowto & RB_KDB)
+ kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
+#endif
+}
+
register_t
init386(first)
int first;
@@ -2438,6 +2453,7 @@ init386(first)
#ifdef CPU_ENABLE_SSE
struct xstate_hdr *xhdr;
#endif
+ int late_console;
thread0.td_kstack = proc0kstack;
thread0.td_kstack_pages = TD0_KSTACK_PAGES;
@@ -2502,6 +2518,7 @@ init386(first)
first += DPCPU_SIZE;
PCPU_SET(prvspace, pc);
PCPU_SET(curthread, &thread0);
+ /* Non-late cninit() and printf() can be moved up to here. */
/*
* Initialize mutexes.
@@ -2636,20 +2653,17 @@ init386(first)
dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
- vm86_initialize();
- getmemsize(first);
- init_param2(physmem);
-
- /* now running on new page tables, configured,and u/iom is accessible */
-
- /*
- * Initialize the console before we print anything out.
- */
- cninit();
-
- if (metadata_missing)
- printf("WARNING: loader(8) metadata is missing!\n");
+ /* Initialize the tss (except for the final esp0) early for vm86. */
+ PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
+ thread0.td_kstack_pages * PAGE_SIZE - 16);
+ PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
+ gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
+ PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd);
+ PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
+ PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
+ ltr(gsel_tss);
+ /* Initialize the PIC early for vm86 calls. */
#ifdef DEV_ISA
#ifdef DEV_ATPIC
#ifndef PC98
@@ -2671,16 +2685,33 @@ init386(first)
#endif
#endif
-#ifdef DDB
- db_fetch_ksymtab(bootinfo.bi_symtab, bootinfo.bi_esymtab);
-#endif
+ /*
+ * The console and kdb should be initialized even earlier than here,
+ * but some console drivers don't work until after getmemsize().
+ * Default to late console initialization to support these drivers.
+ * This loses mainly printf()s in getmemsize() and early debugging.
+ */
+ late_console = 1;
+ TUNABLE_INT_FETCH("debug.late_console", &late_console);
+ if (!late_console) {
+ cninit();
+ i386_kdb_init();
+ }
- kdb_init();
+ vm86_initialize();
+ getmemsize(first);
+ init_param2(physmem);
-#ifdef KDB
- if (boothowto & RB_KDB)
- kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger");
-#endif
+ /* now running on new page tables, configured,and u/iom is accessible */
+
+ if (late_console)
+ cninit();
+
+ if (metadata_missing)
+ printf("WARNING: loader(8) metadata is missing!\n");
+
+ if (late_console)
+ i386_kdb_init();
msgbufinit(msgbufp, msgbufsize);
#ifdef DEV_NPX
@@ -2701,14 +2732,10 @@ init386(first)
}
#endif
PCPU_SET(curpcb, thread0.td_pcb);
- /* make an initial tss so cpu can get interrupt stack on syscall! */
+ /* Move esp0 in the tss to its final place. */
/* Note: -16 is so we can grow the trapframe if we came from vm86 */
PCPU_SET(common_tss.tss_esp0, (vm_offset_t)thread0.td_pcb - 16);
- PCPU_SET(common_tss.tss_ss0, GSEL(GDATA_SEL, SEL_KPL));
- gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
- PCPU_SET(tss_gdt, &gdt[GPROC0_SEL].sd);
- PCPU_SET(common_tssd, *PCPU_GET(tss_gdt));
- PCPU_SET(common_tss.tss_ioopt, (sizeof (struct i386tss)) << 16);
+ gdt[GPROC0_SEL].sd.sd_type = SDT_SYS386TSS; /* clear busy bit */
ltr(gsel_tss);
/* make a call gate to reenter kernel with */
OpenPOWER on IntegriCloud