svn commit: r276135 - in stable/10/sys: conf i386/i386 pc98/pc98

Takahashi Yoshihiro nyan at FreeBSD.org
Tue Dec 23 12:13:32 UTC 2014


Author: nyan
Date: Tue Dec 23 12:13:31 2014
New Revision: 276135
URL: https://svnweb.freebsd.org/changeset/base/276135

Log:
  MFC: r272492
  
    Merge pc98's machdep.c into i386/i386/machdep.c.

Deleted:
  stable/10/sys/pc98/pc98/machdep.c
Modified:
  stable/10/sys/conf/files.pc98
  stable/10/sys/i386/i386/machdep.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/conf/files.pc98
==============================================================================
--- stable/10/sys/conf/files.pc98	Tue Dec 23 12:04:23 2014	(r276134)
+++ stable/10/sys/conf/files.pc98	Tue Dec 23 12:13:31 2014	(r276135)
@@ -149,6 +149,7 @@ i386/i386/initcpu.c		standard
 i386/i386/io.c			optional io
 i386/i386/k6_mem.c		optional mem
 i386/i386/locore.s		standard	no-obj
+i386/i386/machdep.c		standard
 i386/i386/mem.c			optional mem
 i386/i386/minidump_machdep.c	standard
 i386/i386/mp_clock.c		optional smp
@@ -239,7 +240,6 @@ pc98/pc98/busiosubr.c		standard
 pc98/pc98/canbepm.c		optional canbepm
 pc98/pc98/canbus.c		optional canbus
 pc98/pc98/canbus_if.m		optional canbus
-pc98/pc98/machdep.c		standard
 pc98/pc98/pc98_machdep.c	standard
 #
 # x86 shared code between IA32, AMD64 and PC98 architectures

Modified: stable/10/sys/i386/i386/machdep.c
==============================================================================
--- stable/10/sys/i386/i386/machdep.c	Tue Dec 23 12:04:23 2014	(r276134)
+++ stable/10/sys/i386/i386/machdep.c	Tue Dec 23 12:13:31 2014	(r276135)
@@ -112,7 +112,11 @@ __FBSDID("$FreeBSD$");
 #include <ddb/db_sym.h>
 #endif
 
+#ifdef PC98
+#include <pc98/pc98/pc98_machdep.h>
+#else
 #include <isa/rtc.h>
+#endif
 
 #include <net/netisr.h>
 
@@ -212,6 +216,14 @@ extern vm_offset_t ksym_start, ksym_end;
 int	_udatasel, _ucodesel;
 u_int	basemem;
 
+#ifdef PC98
+int	need_pre_dma_flush;	/* If 1, use wbinvd befor DMA transfer. */
+int	need_post_dma_flush;	/* If 1, use invd after DMA transfer. */
+
+static int	ispc98 = 1;
+SYSCTL_INT(_machdep, OID_AUTO, ispc98, CTLFLAG_RD, &ispc98, 0, "");
+#endif
+
 int cold = 1;
 
 #ifdef COMPAT_43
@@ -258,7 +270,8 @@ cpu_startup(dummy)
 {
 	uintmax_t memsize;
 	char *sysenv;
-	
+
+#ifndef PC98
 	/*
 	 * On MacBooks, we need to disallow the legacy USB circuit to
 	 * generate an SMI# because this can cause several problems,
@@ -284,6 +297,7 @@ cpu_startup(dummy)
 		}
 		freeenv(sysenv);
 	}
+#endif /* !PC98 */
 
 	/*
 	 * Good {morning,afternoon,evening,night}.
@@ -1290,6 +1304,7 @@ SYSCTL_INT(_machdep, OID_AUTO, idle_mwai
 #define	STATE_MWAIT	0x1
 #define	STATE_SLEEPING	0x2
 
+#ifndef PC98
 static void
 cpu_idle_acpi(sbintime_t sbt)
 {
@@ -1308,6 +1323,7 @@ cpu_idle_acpi(sbintime_t sbt)
 		__asm __volatile("sti; hlt");
 	*state = STATE_RUNNING;
 }
+#endif /* !PC98 */
 
 #ifndef XEN
 static void
@@ -1425,7 +1441,7 @@ cpu_probe_amdc1e(void)
 	}
 }
 
-#ifdef XEN
+#if defined(PC98) || defined(XEN)
 void (*cpu_idle_fn)(sbintime_t) = cpu_idle_hlt;
 #else
 void (*cpu_idle_fn)(sbintime_t) = cpu_idle_acpi;
@@ -1513,7 +1529,9 @@ struct {
 	{ cpu_idle_spin, "spin" },
 	{ cpu_idle_mwait, "mwait" },
 	{ cpu_idle_hlt, "hlt" },
+#ifndef PC98
 	{ cpu_idle_acpi, "acpi" },
+#endif
 	{ NULL, NULL }
 };
 
@@ -1530,9 +1548,11 @@ idle_sysctl_available(SYSCTL_HANDLER_ARG
 		if (strstr(idle_tbl[i].id_name, "mwait") &&
 		    (cpu_feature2 & CPUID2_MON) == 0)
 			continue;
+#ifndef PC98
 		if (strcmp(idle_tbl[i].id_name, "acpi") == 0 &&
 		    cpu_idle_hook == NULL)
 			continue;
+#endif
 		p += sprintf(p, "%s%s", p != avail ? ", " : "",
 		    idle_tbl[i].id_name);
 	}
@@ -1567,9 +1587,11 @@ idle_sysctl(SYSCTL_HANDLER_ARGS)
 		if (strstr(idle_tbl[i].id_name, "mwait") &&
 		    (cpu_feature2 & CPUID2_MON) == 0)
 			continue;
+#ifndef PC98
 		if (strcmp(idle_tbl[i].id_name, "acpi") == 0 &&
 		    cpu_idle_hook == NULL)
 			continue;
+#endif
 		if (strcmp(idle_tbl[i].id_name, buf))
 			continue;
 		cpu_idle_fn = idle_tbl[i].id_fn;
@@ -2047,7 +2069,7 @@ sdtossd(sd, ssd)
 	ssd->ssd_gran  = sd->sd_gran;
 }
 
-#ifndef XEN
+#if !defined(PC98) && !defined(XEN)
 static int
 add_smap_entry(struct bios_smap *smap, vm_paddr_t *physmap, int *physmap_idxp)
 {
@@ -2126,7 +2148,9 @@ add_smap_entry(struct bios_smap *smap, v
 	physmap[insert_idx + 1] = smap->base + smap->length;
 	return (1);
 }
+#endif /* !PC98 && !XEN */
 
+#ifndef XEN
 static void
 basemem_setup(void)
 {
@@ -2174,7 +2198,7 @@ basemem_setup(void)
 	for (i = basemem / 4; i < 160; i++)
 		pte[i] = (i << PAGE_SHIFT) | PG_V | PG_RW | PG_U;
 }
-#endif
+#endif /* !XEN */
 
 /*
  * Populate the (physmap) array with base/bound pairs describing the
@@ -2189,6 +2213,271 @@ basemem_setup(void)
  *
  * XXX first should be vm_paddr_t.
  */
+#ifdef PC98
+static void
+getmemsize(int first)
+{
+	int off, physmap_idx, pa_indx, da_indx;
+	u_long physmem_tunable, memtest;
+	vm_paddr_t physmap[PHYSMAP_SIZE];
+	pt_entry_t *pte;
+	quad_t dcons_addr, dcons_size;
+	int i;
+	int pg_n;
+	u_int extmem;
+	u_int under16;
+	vm_paddr_t pa;
+
+	bzero(physmap, sizeof(physmap));
+
+	/* XXX - some of EPSON machines can't use PG_N */
+	pg_n = PG_N;
+	if (pc98_machine_type & M_EPSON_PC98) {
+		switch (epson_machine_id) {
+#ifdef WB_CACHE
+		default:
+#endif
+		case EPSON_PC486_HX:
+		case EPSON_PC486_HG:
+		case EPSON_PC486_HA:
+			pg_n = 0;
+			break;
+		}
+	}
+
+	under16 = pc98_getmemsize(&basemem, &extmem);
+	basemem_setup();
+
+	physmap[0] = 0;
+	physmap[1] = basemem * 1024;
+	physmap_idx = 2;
+	physmap[physmap_idx] = 0x100000;
+	physmap[physmap_idx + 1] = physmap[physmap_idx] + extmem * 1024;
+
+	/*
+	 * Now, physmap contains a map of physical memory.
+	 */
+
+#ifdef SMP
+	/* make hole for AP bootstrap code */
+	physmap[1] = mp_bootaddress(physmap[1]);
+#endif
+
+	/*
+	 * Maxmem isn't the "maximum memory", it's one larger than the
+	 * 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.
+	 */
+	Maxmem = atop(physmap[physmap_idx + 1]);
+
+#ifdef MAXMEM
+	Maxmem = MAXMEM / 4;
+#endif
+
+	if (TUNABLE_ULONG_FETCH("hw.physmem", &physmem_tunable))
+		Maxmem = atop(physmem_tunable);
+
+	/*
+	 * By default keep the memtest enabled.  Use a general name so that
+	 * one could eventually do more with the code than just disable it.
+	 */
+	memtest = 1;
+	TUNABLE_ULONG_FETCH("hw.memtest.tests", &memtest);
+
+	if (atop(physmap[physmap_idx + 1]) != Maxmem &&
+	    (boothowto & RB_VERBOSE))
+		printf("Physical memory use set to %ldK\n", Maxmem * 4);
+
+	/*
+	 * If Maxmem has been increased beyond what the system has detected,
+	 * extend the last memory segment to the new limit.
+	 */ 
+	if (atop(physmap[physmap_idx + 1]) < Maxmem)
+		physmap[physmap_idx + 1] = ptoa((vm_paddr_t)Maxmem);
+
+	/*
+	 * We need to divide chunk if Maxmem is larger than 16MB and
+	 * under 16MB area is not full of memory.
+	 * (1) system area (15-16MB region) is cut off
+	 * (2) extended memory is only over 16MB area (ex. Melco "HYPERMEMORY")
+	 */
+	if ((under16 != 16 * 1024) && (extmem > 15 * 1024)) {
+		/* 15M - 16M region is cut off, so need to divide chunk */
+		physmap[physmap_idx + 1] = under16 * 1024;
+		physmap_idx += 2;
+		physmap[physmap_idx] = 0x1000000;
+		physmap[physmap_idx + 1] = physmap[2] + extmem * 1024;
+	}
+
+	/* call pmap initialization to make new kernel address space */
+	pmap_bootstrap(first);
+
+	/*
+	 * Size up each available chunk of physical memory.
+	 */
+	physmap[0] = PAGE_SIZE;		/* mask off page 0 */
+	pa_indx = 0;
+	da_indx = 1;
+	phys_avail[pa_indx++] = physmap[0];
+	phys_avail[pa_indx] = physmap[0];
+	dump_avail[da_indx] = physmap[0];
+	pte = CMAP3;
+
+	/*
+	 * Get dcons buffer address
+	 */
+	if (getenv_quad("dcons.addr", &dcons_addr) == 0 ||
+	    getenv_quad("dcons.size", &dcons_size) == 0)
+		dcons_addr = 0;
+
+	/*
+	 * physmap is in bytes, so when converting to page boundaries,
+	 * round up the start address and round down the end address.
+	 */
+	for (i = 0; i <= physmap_idx; i += 2) {
+		vm_paddr_t end;
+
+		end = ptoa((vm_paddr_t)Maxmem);
+		if (physmap[i + 1] < end)
+			end = trunc_page(physmap[i + 1]);
+		for (pa = round_page(physmap[i]); pa < end; pa += PAGE_SIZE) {
+			int tmp, page_bad, full;
+			int *ptr = (int *)CADDR3;
+
+			full = FALSE;
+			/*
+			 * block out kernel memory as not available.
+			 */
+			if (pa >= KERNLOAD && pa < first)
+				goto do_dump_avail;
+
+			/*
+			 * block out dcons buffer
+			 */
+			if (dcons_addr > 0
+			    && pa >= trunc_page(dcons_addr)
+			    && pa < dcons_addr + dcons_size)
+				goto do_dump_avail;
+
+			page_bad = FALSE;
+			if (memtest == 0)
+				goto skip_memtest;
+
+			/*
+			 * map page into kernel: valid, read/write,non-cacheable
+			 */
+			*pte = pa | PG_V | PG_RW | pg_n;
+			invltlb();
+
+			tmp = *(int *)ptr;
+			/*
+			 * Test for alternating 1's and 0's
+			 */
+			*(volatile int *)ptr = 0xaaaaaaaa;
+			if (*(volatile int *)ptr != 0xaaaaaaaa)
+				page_bad = TRUE;
+			/*
+			 * Test for alternating 0's and 1's
+			 */
+			*(volatile int *)ptr = 0x55555555;
+			if (*(volatile int *)ptr != 0x55555555)
+				page_bad = TRUE;
+			/*
+			 * Test for all 1's
+			 */
+			*(volatile int *)ptr = 0xffffffff;
+			if (*(volatile int *)ptr != 0xffffffff)
+				page_bad = TRUE;
+			/*
+			 * Test for all 0's
+			 */
+			*(volatile int *)ptr = 0x0;
+			if (*(volatile int *)ptr != 0x0)
+				page_bad = TRUE;
+			/*
+			 * Restore original value.
+			 */
+			*(int *)ptr = tmp;
+
+skip_memtest:
+			/*
+			 * Adjust array of valid/good pages.
+			 */
+			if (page_bad == TRUE)
+				continue;
+			/*
+			 * If this good page is a continuation of the
+			 * previous set of good pages, then just increase
+			 * the end pointer. Otherwise start a new chunk.
+			 * Note that "end" points one higher than end,
+			 * making the range >= start and < end.
+			 * If we're also doing a speculative memory
+			 * test and we at or past the end, bump up Maxmem
+			 * so that we keep going. The first bad page
+			 * will terminate the loop.
+			 */
+			if (phys_avail[pa_indx] == pa) {
+				phys_avail[pa_indx] += PAGE_SIZE;
+			} else {
+				pa_indx++;
+				if (pa_indx == PHYS_AVAIL_ARRAY_END) {
+					printf(
+		"Too many holes in the physical address space, giving up\n");
+					pa_indx--;
+					full = TRUE;
+					goto do_dump_avail;
+				}
+				phys_avail[pa_indx++] = pa;	/* start */
+				phys_avail[pa_indx] = pa + PAGE_SIZE; /* end */
+			}
+			physmem++;
+do_dump_avail:
+			if (dump_avail[da_indx] == pa) {
+				dump_avail[da_indx] += PAGE_SIZE;
+			} else {
+				da_indx++;
+				if (da_indx == DUMP_AVAIL_ARRAY_END) {
+					da_indx--;
+					goto do_next;
+				}
+				dump_avail[da_indx++] = pa;	/* start */
+				dump_avail[da_indx] = pa + PAGE_SIZE; /* end */
+			}
+do_next:
+			if (full)
+				break;
+		}
+	}
+	*pte = 0;
+	invltlb();
+	
+	/*
+	 * XXX
+	 * The last chunk must contain at least one page plus the message
+	 * buffer to avoid complicating other code (message buffer address
+	 * calculation, etc.).
+	 */
+	while (phys_avail[pa_indx - 1] + PAGE_SIZE +
+	    round_page(msgbufsize) >= phys_avail[pa_indx]) {
+		physmem -= atop(phys_avail[pa_indx] - phys_avail[pa_indx - 1]);
+		phys_avail[pa_indx--] = 0;
+		phys_avail[pa_indx--] = 0;
+	}
+
+	Maxmem = atop(phys_avail[pa_indx]);
+
+	/* Trim off space for the message buffer. */
+	phys_avail[pa_indx] -= round_page(msgbufsize);
+
+	/* Map the message buffer. */
+	for (off = 0; off < round_page(msgbufsize); off += PAGE_SIZE)
+		pmap_kenter((vm_offset_t)msgbufp + off, phys_avail[pa_indx] +
+		    off);
+
+	PT_UPDATES_FLUSH();
+}
+#else /* PC98 */
 static void
 getmemsize(int first)
 {
@@ -2597,6 +2886,7 @@ do_next:
 
 	PT_UPDATES_FLUSH();
 }
+#endif /* PC98 */
 
 #ifdef XEN
 #define MTOPSIZE (1<<(14 + PAGE_SHIFT))
@@ -2880,6 +3170,13 @@ init386(first)
 	 */
 	proc_linkup0(&proc0, &thread0);
 
+#ifdef PC98
+	/*
+	 * Initialize DMAC
+	 */
+	pc98_init_dmac();
+#endif
+
 	metadata_missing = 0;
 	if (bootinfo.bi_modulep) {
 		preload_metadata = (caddr_t)bootinfo.bi_modulep + KERNBASE;
@@ -3042,7 +3339,9 @@ init386(first)
 
 #ifdef DEV_ISA
 #ifdef DEV_ATPIC
+#ifndef PC98
 	elcr_probe();
+#endif
 	atpic_startup();
 #else
 	/* Reset and mask the atpics and leave them shut down. */
@@ -3184,6 +3483,7 @@ cpu_pcpu_init(struct pcpu *pcpu, int cpu
 	pcpu->pc_acpi_id = 0xffffffff;
 }
 
+#ifndef PC98
 static int
 smap_sysctl_handler(SYSCTL_HANDLER_ARGS)
 {
@@ -3221,6 +3521,7 @@ smap_sysctl_handler(SYSCTL_HANDLER_ARGS)
 }
 SYSCTL_PROC(_machdep, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD, NULL, 0,
     smap_sysctl_handler, "S,bios_smap_xattr", "Raw BIOS SMAP data");
+#endif /* !PC98 */
 
 void
 spinlock_enter(void)


More information about the svn-src-all mailing list