Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 7 Apr 2003 02:15:24 -0700 (PDT)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 28427 for review
Message-ID:  <200304070915.h379FOU9058020@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=28427

Change 28427 by peter@peter_overcee on 2003/04/07 02:15:11

	checkpoint.  we get as far as pmap_bootstrap() from getmemsize().
	ouch.

Affected files ...

.. //depot/projects/hammer/sys/x86_64/x86_64/machdep.c#44 edit

Differences ...

==== //depot/projects/hammer/sys/x86_64/x86_64/machdep.c#44 (text+ko) ====

@@ -736,41 +736,53 @@
  * XXX first should be vm_paddr_t.
  */
 static void
-getmemsize(u_int64_t first)
+getmemsize(caddr_t kmdp, u_int64_t first)
 {
 	int i, physmap_idx, pa_indx;
 	u_int basemem, extmem;
 	vm_paddr_t pa, physmap[PHYSMAP_SIZE];
 	pt_entry_t *pte;
 	char *cp;
-	struct bios_smap *smap;
+	struct bios_smap *smapbase, *smap, *smapend;
+	u_int32_t smapsize;
 
 	bzero(physmap, sizeof(physmap));
 	basemem = 0;
-	smap = 0;
+	physmap_idx = 0;
 
 	/*
-	 * map page 1 R/W into the kernel page table so we can use it
-	 * as a buffer.  The kernel will unmap this page later.
+	 * get memory map from INT 15:E820, kindly supplied by the loader.
+	 *
+	 * subr_module.c says:
+	 * "Consumer may safely assume that size value precedes data."
+	 * ie: an int32_t immediately precedes smap.
 	 */
-	pmap_kenter(KERNBASE + (1 << PAGE_SHIFT), 1 << PAGE_SHIFT);
+	smapbase = MD_FETCH(kmdp, MODINFOMD_SMAP, struct bios_smap *) + KERNBASE;
+	if (smapbase == 0) {
+		printf("no bios smap, winging it\n");
+		goto deep_shit;
+	}
+printf("smapbase: %p\n", smapbase);
+	smapsize = ((u_int32_t *)smapbase)[-1];
+printf("smaplen = 0x%x\n", smapsize);
+	smapend = (struct bios_smap *)((uintptr_t)smapbase + smapsize);
+printf("smapend: %p\n", smapend);
 
-	/*
-	 * get memory map with INT 15:E820
-	 */
-/* #error "smap = fetch from loader metadata" */
-
-	physmap_idx = 0;
-	do {
+	for (smap = smapbase; smap < smapend; smap++) {
 		if (boothowto & RB_VERBOSE)
-			printf("SMAP type=%02x base=%016llx len=%016llx\n",
+			printf("SMAP type=%02x base=%016lx len=%016lx\n",
 			    smap->type, smap->base, smap->length);
 
-		if (smap->type != 0x01)
-			goto next_run;
+		if (smap->type != 0x01) {
+printf("bad type\n");
+			continue;
+		}
 
-		if (smap->length == 0)
-			goto next_run;
+		if (smap->length == 0) {
+printf("bad length\n");
+next_run:
+			continue;
+		}
 
 		for (i = 0; i <= physmap_idx; i += 2) {
 			if (smap->base < physmap[i + 1]) {
@@ -783,7 +795,8 @@
 
 		if (smap->base == physmap[physmap_idx + 1]) {
 			physmap[physmap_idx + 1] += smap->length;
-			goto next_run;
+printf("contiguous\n");
+			continue;
 		}
 
 		physmap_idx += 2;
@@ -794,13 +807,13 @@
 		}
 		physmap[physmap_idx] = smap->base;
 		physmap[physmap_idx + 1] = smap->base + smap->length;
-next_run: ;
-	} while (1 /* XXX more to go */);
-/* #error "while not end of smap table from loader" */
+	}
+printf("MADE IT TO END!!\n");
 
 	/*
 	 * Perform "base memory" related probes & setup based on SMAP
 	 */
+deep_shit:
 	if (basemem == 0) {
 		for (i = 0; i <= physmap_idx; i += 2) {
 			if (physmap[i] == 0x00000000) {
@@ -810,6 +823,11 @@
 		}
 
 		if (basemem == 0) {
+			basemem = rtcin(RTC_BASELO) + (rtcin(RTC_BASEHI) << 8);
+printf("rtc says basemem = %d\n", basemem);
+		}
+
+		if (basemem == 0) {
 			basemem = 640;
 		}
 
@@ -819,29 +837,50 @@
 			basemem = 640;
 		}
 
+#if 0
 		for (pa = trunc_page(basemem * 1024);
 		     pa < ISA_HOLE_START; pa += PAGE_SIZE)
 			pmap_kenter(KERNBASE + pa, pa);
+#endif
 	}
 
 	if (physmap[1] != 0)
 		goto physmap_done;
 
 	/*
-	 * If we failed above, try memory map with INT 15:E801
+	 * Prefer the RTC value for extended memory.
+	 */
+	extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
+printf("rtc says extmem = %d\n", extmem);
+
+	/*
+	 * Special hack for chipsets that still remap the 384k hole when
+	 * there's 16MB of memory - this really confuses people that
+	 * are trying to use bus mastering ISA controllers with the
+	 * "16MB limit"; they only have 16MB, but the remapping puts
+	 * them beyond the limit.
+	 *
+	 * If extended memory is between 15-16MB (16-17MB phys address range),
+	 *	chop it to 15MB.
 	 */
-/* #error "get smap from loader" */
-	else {
-		/*
-		 * Prefer the RTC value for extended memory.
-		 */
-		extmem = rtcin(RTC_EXTLO) + (rtcin(RTC_EXTHI) << 8);
-	}
+	if ((extmem > 15 * 1024) && (extmem < 16 * 1024))
+		extmem = 15 * 1024;
+
+	physmap[0] = 0;
+	physmap[1] = basemem * 1024;
+	physmap_idx = 2;
+	physmap[physmap_idx] = 0x100000;
+	physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
 
 physmap_done:
 	/*
 	 * Now, physmap contains a map of physical memory.
 	 */
+printf("physmap_done\n");
+printf("physmap_idx = %d\n", physmap_idx);
+for (i = 0; i <= physmap_idx; i += 2) {
+	printf("slot %d: 0x%16lx - 0x%16lx\n", i/2, physmap[i], physmap[i + 1]);
+}
 
 	/*
 	 * Maxmem isn't the "maximum memory", it's one larger than the
@@ -855,6 +894,7 @@
 	Maxmem = MAXMEM / 4;
 #endif
 
+printf("checking hw.physmem...\n");
 	/*
 	 * hw.physmem is a size in bytes; we also allow k, m, and g suffixes
 	 * for the appropriate modifiers.  This overrides MAXMEM.
@@ -900,8 +940,10 @@
 	if (atop(physmap[physmap_idx + 1]) < Maxmem)
 		physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem);
 
+printf("about to call pmap_bootstrap...\n\n");
 	/* call pmap initialization to make new kernel address space */
 	pmap_bootstrap(first, 0);
+printf("pmap_bootstrap done...\n");
 
 	/*
 	 * Size up each available chunk of physical memory.
@@ -1029,6 +1071,7 @@
 	phys_avail[pa_indx] -= round_page(MSGBUF_SIZE);
 
 	avail_end = phys_avail[pa_indx];
+printf("getmemsize finished!\n");
 }
 
 static u_int64_t
@@ -1144,7 +1187,6 @@
 	/* Init basic tunables, hz etc */
 	init_param1();
 
-printf("gdt time, ugh\n");
 	/*
 	 * make gdt memory segments
 	 */
@@ -1156,12 +1198,8 @@
 	}
 	ssdtosyssd(&gdt_segs[GPROC0_SEL], (struct system_segment_descriptor *)&gdt[GPROC0_SEL]);
 
-for (x = 0; x < NGDT; x++)
-printf("gdt slot %d: 0x%016lx\n", x, *(long *)&gdt[x]);
-
 	r_gdt.rd_limit = NGDT * sizeof(gdt[0]) - 1;
 	r_gdt.rd_base =  (long) gdt;
-printf("doing lgdt....\n");
 	lgdt(&r_gdt);
 printf("lgdt done\n");
 	pc = &__pcpu;	
@@ -1170,11 +1208,8 @@
 	wrmsr(MSR_FSBASE, (u_int64_t)pc);
 	wrmsr(MSR_GSBASE, (u_int64_t)pc);
 
-printf("pcpu init\n");
 	pcpu_init(pc, 0, sizeof(struct pcpu));
-printf("PCPU_SET(prvspace, pc)\n");
 	PCPU_SET(prvspace, pc);
-printf("PCPU_SET(curthread, &thread0)\n");
 	PCPU_SET(curthread, &thread0);
 
 	/*
@@ -1185,11 +1220,9 @@
 	 *	     must be able to get the icu lock, so it can't be
 	 *	     under witness.
 	 */
-printf("mutex init\n");
 	mutex_init();
 	mtx_init(&clock_lock, "clk", NULL, MTX_SPIN | MTX_RECURSE);
 	mtx_init(&icu_lock, "icu", NULL, MTX_SPIN | MTX_NOWITNESS);
-for(;;);
 
 	/* exceptions */
 	for (x = 0; x < NIDT; x++)
@@ -1242,11 +1275,13 @@
 	r_idt.rd_limit = sizeof(idt0) - 1;
 	r_idt.rd_base = (long) idt;
 	lidt(&r_idt);
+printf("survived lidt!\n");
 
 	/*
 	 * Initialize the console before we print anything out.
 	 */
 	cninit();
+printf("done cninit\n");
 
 #ifdef DEV_ISA
 	isa_defaultirq();
@@ -1270,12 +1305,14 @@
 #endif
 
 	/* make an initial tss so cpu can get interrupt stack on syscall! */
-#if 0
-	PCPU_SET(common_tss.tss_esp0, thread0.td_kstack +
-	    KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb));
-#endif
+	common_tss.tss.tss_rsp0 = thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE - sizeof(struct pcb);
+printf("thread0.td_kstack = %p\n", thread0.td_kstack);
+printf("tss_rsp0 = %p\n", common_tss.tss.tss_rsp0);
+printf("about to ltr\n");
+
 	gsel_tss = GSEL(GPROC0_SEL, SEL_KPL);
 	ltr(gsel_tss);
+printf("survived ltr!\n");
 
 #if 0
 	dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 =
@@ -1294,21 +1331,29 @@
 	dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL);
 #endif
 
-	getmemsize(first);
+printf("calling getmemsize\n");
+	getmemsize(kmdp, first);
+printf("calling init_param2\n");
 	init_param2(physmem);
 
 	/* now running on new page tables, configured,and u/iom is accessible */
 
+printf("map message buffer\n");
 	/* Map the message buffer. */
 	for (off = 0; off < round_page(MSGBUF_SIZE); off += PAGE_SIZE)
 		pmap_kenter((vm_offset_t)msgbufp + off, avail_end + off);
 
+printf("calling msgbufinit\n");
 	msgbufinit(msgbufp, MSGBUF_SIZE);
 
+printf("setup proc0\n");
 	/* setup proc 0's pcb */
 	thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
 	thread0.td_pcb->pcb_cr3 = IdlePML4;
 	thread0.td_frame = &proc0_tf;
+
+printf("HAMMER TIME!!\n");
+printf("HALT\n\n"); for(;;);
 }
 
 void



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304070915.h379FOU9058020>