summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2000-03-16 12:14:00 +0000
committernyan <nyan@FreeBSD.org>2000-03-16 12:14:00 +0000
commit516636217a60d40789f54127316c929191f7e2c1 (patch)
treef673de301911b85871218054875e01ef617b2592 /sys
parenta16d0e912fcf87486c21f0dc3a8a85abb3020ab4 (diff)
downloadFreeBSD-src-516636217a60d40789f54127316c929191f7e2c1.zip
FreeBSD-src-516636217a60d40789f54127316c929191f7e2c1.tar.gz
Fixed to probe extended memory for over 256M or under 64M.
Submitted by: chi@bd.mbn.or.jp (Chiharu Shibata)
Diffstat (limited to 'sys')
-rw-r--r--sys/pc98/i386/machdep.c141
-rw-r--r--sys/pc98/pc98/machdep.c141
-rw-r--r--sys/pc98/pc98/pc98_machdep.c204
-rw-r--r--sys/pc98/pc98/pc98_machdep.h2
4 files changed, 271 insertions, 217 deletions
diff --git a/sys/pc98/i386/machdep.c b/sys/pc98/i386/machdep.c
index e377848..88b5696 100644
--- a/sys/pc98/i386/machdep.c
+++ b/sys/pc98/i386/machdep.c
@@ -1400,21 +1400,22 @@ sdtossd(sd, ssd)
* Total memory size may be set by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
*/
+#ifdef PC98
static void
-getmemsize_pc98(int first)
+getmemsize(int first)
{
u_int biosbasemem, biosextmem;
u_int pagesinbase, pagesinext;
int pa_indx;
+ int pg_n;
int speculative_mprobe;
#if NNPX > 0
int msize;
#endif
+ unsigned under16;
vm_offset_t target_page;
- pc98_getmemsize();
- biosbasemem = 640; /* 640KB */
- biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
+ pc98_getmemsize(&biosbasemem, &biosextmem, &under16);
#ifdef SMP
/* make hole for AP bootstrap code */
@@ -1422,9 +1423,10 @@ getmemsize_pc98(int first)
#else
pagesinbase = biosbasemem * 1024 / PAGE_SIZE;
#endif
-
pagesinext = biosextmem * 1024 / PAGE_SIZE;
+ Maxmem_under16M = under16 * 1024 / PAGE_SIZE;
+
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
@@ -1440,14 +1442,7 @@ getmemsize_pc98(int first)
* memory probe.
*/
if (Maxmem >= 0x4000)
-#ifdef PC98
- {
- Maxmem = 0x4000; /* XXX */
speculative_mprobe = TRUE;
- }
-#else
- speculative_mprobe = TRUE;
-#endif
else
speculative_mprobe = FALSE;
@@ -1491,36 +1486,111 @@ getmemsize_pc98(int first)
pa_indx++;
}
+ /* 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 0x34: /* PC-486HX */
+ case 0x35: /* PC-486HG */
+ case 0x3B: /* PC-486HA */
+ pg_n = 0;
+ break;
+ }
+ }
+
+ speculative_mprobe = FALSE;
+#ifdef notdef /* XXX - see below */
+ /*
+ * Certain 'CPU accelerator' supports over 16MB memory on the machines
+ * whose BIOS doesn't store true size.
+ * To support this, we don't trust BIOS values if Maxmem < 16MB (0x1000
+ * pages) - which is the largest amount that the OLD PC-98 can report.
+ *
+ * OK: PC-9801NS/R(9.6M)
+ * OK: PC-9801DA(5.6M)+EUD-H(32M)+Cyrix 5x86
+ * OK: PC-9821Ap(14.6M)+EUA-T(8M)+Cyrix 5x86-100
+ * NG: PC-9821Ap(14.6M)+EUA-T(8M)+AMD DX4-100 -> freeze
+ */
+ if (Maxmem < 0x1000) {
+ int tmp, page_bad;
+
+ page_bad = FALSE;
+
+ /*
+ * For Max14.6MB machines, the 0x10f0 page is same as 0x00f0,
+ * which is BIOS ROM, by overlapping.
+ * So, we check that page's ability of writing.
+ */
+ target_page = ptoa(0x10f0);
+
+ /*
+ * map page into kernel: valid, read/write, non-cacheable
+ */
+ *(int *)CMAP1 = PG_V | PG_RW | pg_n | target_page;
+ invltlb();
+
+ tmp = *(int *)CADDR1;
+ /*
+ * Test for alternating 1's and 0's
+ */
+ *(volatile int *)CADDR1 = 0xaaaaaaaa;
+ if (*(volatile int *)CADDR1 != 0xaaaaaaaa)
+ page_bad = TRUE;
+ /*
+ * Test for alternating 0's and 1's
+ */
+ *(volatile int *)CADDR1 = 0x55555555;
+ if (*(volatile int *)CADDR1 != 0x55555555)
+ page_bad = TRUE;
+ /*
+ * Test for all 1's
+ */
+ *(volatile int *)CADDR1 = 0xffffffff;
+ if (*(volatile int *)CADDR1 != 0xffffffff)
+ page_bad = TRUE;
+ /*
+ * Test for all 0's
+ */
+ *(volatile int *)CADDR1 = 0x0;
+ if (*(volatile int *)CADDR1 != 0x0) {
+ /*
+ * test of page failed
+ */
+ page_bad = TRUE;
+ }
+ /*
+ * Restore original value.
+ */
+ *(int *)CADDR1 = tmp;
+
+ /*
+ * Adjust Maxmem if valid/good page.
+ */
+ if (page_bad == FALSE) {
+ /* '+ 2' is needed to make speculative_mprobe sure */
+ Maxmem = 0x1000 + 2;
+ speculative_mprobe = TRUE;
+ }
+ }
+#endif
+
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
int tmp, page_bad;
page_bad = FALSE;
+
/* skip system area */
- if (target_page>=ptoa(Maxmem_under16M) &&
+ if (target_page >= ptoa(Maxmem_under16M) &&
target_page < ptoa(4096))
continue;
/*
* map page into kernel: valid, read/write, non-cacheable
*/
- if (pc98_machine_type & M_EPSON_PC98) {
- switch (epson_machine_id) {
- case 0x34: /* PC-486HX */
- case 0x35: /* PC-486HG */
- case 0x3B: /* PC-486HA */
- *(int *)CMAP1 = PG_V | PG_RW | target_page;
- break;
- default:
-#ifdef WB_CACHE
- *(int *)CMAP1 = PG_V | PG_RW | target_page;
-#else
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
-#endif
- break;
- }
- } else {
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
- }
+ *(int *)CMAP1 = PG_V | PG_RW | pg_n | target_page;
invltlb();
tmp = *(int *)CADDR1;
@@ -1578,7 +1648,7 @@ getmemsize_pc98(int first)
if (phys_avail[pa_indx] == target_page) {
phys_avail[pa_indx] += PAGE_SIZE;
if (speculative_mprobe == TRUE &&
- phys_avail[pa_indx] >= (64*1024*1024))
+ phys_avail[pa_indx] >= (16*1024*1024))
Maxmem++;
} else {
pa_indx++;
@@ -1617,8 +1687,7 @@ getmemsize_pc98(int first)
avail_end = phys_avail[pa_indx];
}
-
-#ifndef PC98
+#else
static void
getmemsize(int first)
{
@@ -2181,11 +2250,7 @@ init386(first)
dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
vm86_initialize();
-#ifdef PC98
- getmemsize_pc98(first);
-#else
getmemsize(first);
-#endif
/* now running on new page tables, configured,and u/iom is accessible */
/* Map the message buffer. */
diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c
index e377848..88b5696 100644
--- a/sys/pc98/pc98/machdep.c
+++ b/sys/pc98/pc98/machdep.c
@@ -1400,21 +1400,22 @@ sdtossd(sd, ssd)
* Total memory size may be set by the kernel environment variable
* hw.physmem or the compile-time define MAXMEM.
*/
+#ifdef PC98
static void
-getmemsize_pc98(int first)
+getmemsize(int first)
{
u_int biosbasemem, biosextmem;
u_int pagesinbase, pagesinext;
int pa_indx;
+ int pg_n;
int speculative_mprobe;
#if NNPX > 0
int msize;
#endif
+ unsigned under16;
vm_offset_t target_page;
- pc98_getmemsize();
- biosbasemem = 640; /* 640KB */
- biosextmem = (Maxmem * PAGE_SIZE - 0x100000)/1024; /* extent memory */
+ pc98_getmemsize(&biosbasemem, &biosextmem, &under16);
#ifdef SMP
/* make hole for AP bootstrap code */
@@ -1422,9 +1423,10 @@ getmemsize_pc98(int first)
#else
pagesinbase = biosbasemem * 1024 / PAGE_SIZE;
#endif
-
pagesinext = biosextmem * 1024 / PAGE_SIZE;
+ Maxmem_under16M = under16 * 1024 / PAGE_SIZE;
+
/*
* Maxmem isn't the "maximum memory", it's one larger than the
* highest page of the physical address space. It should be
@@ -1440,14 +1442,7 @@ getmemsize_pc98(int first)
* memory probe.
*/
if (Maxmem >= 0x4000)
-#ifdef PC98
- {
- Maxmem = 0x4000; /* XXX */
speculative_mprobe = TRUE;
- }
-#else
- speculative_mprobe = TRUE;
-#endif
else
speculative_mprobe = FALSE;
@@ -1491,36 +1486,111 @@ getmemsize_pc98(int first)
pa_indx++;
}
+ /* 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 0x34: /* PC-486HX */
+ case 0x35: /* PC-486HG */
+ case 0x3B: /* PC-486HA */
+ pg_n = 0;
+ break;
+ }
+ }
+
+ speculative_mprobe = FALSE;
+#ifdef notdef /* XXX - see below */
+ /*
+ * Certain 'CPU accelerator' supports over 16MB memory on the machines
+ * whose BIOS doesn't store true size.
+ * To support this, we don't trust BIOS values if Maxmem < 16MB (0x1000
+ * pages) - which is the largest amount that the OLD PC-98 can report.
+ *
+ * OK: PC-9801NS/R(9.6M)
+ * OK: PC-9801DA(5.6M)+EUD-H(32M)+Cyrix 5x86
+ * OK: PC-9821Ap(14.6M)+EUA-T(8M)+Cyrix 5x86-100
+ * NG: PC-9821Ap(14.6M)+EUA-T(8M)+AMD DX4-100 -> freeze
+ */
+ if (Maxmem < 0x1000) {
+ int tmp, page_bad;
+
+ page_bad = FALSE;
+
+ /*
+ * For Max14.6MB machines, the 0x10f0 page is same as 0x00f0,
+ * which is BIOS ROM, by overlapping.
+ * So, we check that page's ability of writing.
+ */
+ target_page = ptoa(0x10f0);
+
+ /*
+ * map page into kernel: valid, read/write, non-cacheable
+ */
+ *(int *)CMAP1 = PG_V | PG_RW | pg_n | target_page;
+ invltlb();
+
+ tmp = *(int *)CADDR1;
+ /*
+ * Test for alternating 1's and 0's
+ */
+ *(volatile int *)CADDR1 = 0xaaaaaaaa;
+ if (*(volatile int *)CADDR1 != 0xaaaaaaaa)
+ page_bad = TRUE;
+ /*
+ * Test for alternating 0's and 1's
+ */
+ *(volatile int *)CADDR1 = 0x55555555;
+ if (*(volatile int *)CADDR1 != 0x55555555)
+ page_bad = TRUE;
+ /*
+ * Test for all 1's
+ */
+ *(volatile int *)CADDR1 = 0xffffffff;
+ if (*(volatile int *)CADDR1 != 0xffffffff)
+ page_bad = TRUE;
+ /*
+ * Test for all 0's
+ */
+ *(volatile int *)CADDR1 = 0x0;
+ if (*(volatile int *)CADDR1 != 0x0) {
+ /*
+ * test of page failed
+ */
+ page_bad = TRUE;
+ }
+ /*
+ * Restore original value.
+ */
+ *(int *)CADDR1 = tmp;
+
+ /*
+ * Adjust Maxmem if valid/good page.
+ */
+ if (page_bad == FALSE) {
+ /* '+ 2' is needed to make speculative_mprobe sure */
+ Maxmem = 0x1000 + 2;
+ speculative_mprobe = TRUE;
+ }
+ }
+#endif
+
for (target_page = avail_start; target_page < ptoa(Maxmem); target_page += PAGE_SIZE) {
int tmp, page_bad;
page_bad = FALSE;
+
/* skip system area */
- if (target_page>=ptoa(Maxmem_under16M) &&
+ if (target_page >= ptoa(Maxmem_under16M) &&
target_page < ptoa(4096))
continue;
/*
* map page into kernel: valid, read/write, non-cacheable
*/
- if (pc98_machine_type & M_EPSON_PC98) {
- switch (epson_machine_id) {
- case 0x34: /* PC-486HX */
- case 0x35: /* PC-486HG */
- case 0x3B: /* PC-486HA */
- *(int *)CMAP1 = PG_V | PG_RW | target_page;
- break;
- default:
-#ifdef WB_CACHE
- *(int *)CMAP1 = PG_V | PG_RW | target_page;
-#else
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
-#endif
- break;
- }
- } else {
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
- }
+ *(int *)CMAP1 = PG_V | PG_RW | pg_n | target_page;
invltlb();
tmp = *(int *)CADDR1;
@@ -1578,7 +1648,7 @@ getmemsize_pc98(int first)
if (phys_avail[pa_indx] == target_page) {
phys_avail[pa_indx] += PAGE_SIZE;
if (speculative_mprobe == TRUE &&
- phys_avail[pa_indx] >= (64*1024*1024))
+ phys_avail[pa_indx] >= (16*1024*1024))
Maxmem++;
} else {
pa_indx++;
@@ -1617,8 +1687,7 @@ getmemsize_pc98(int first)
avail_end = phys_avail[pa_indx];
}
-
-#ifndef PC98
+#else
static void
getmemsize(int first)
{
@@ -2181,11 +2250,7 @@ init386(first)
dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL);
vm86_initialize();
-#ifdef PC98
- getmemsize_pc98(first);
-#else
getmemsize(first);
-#endif
/* now running on new page tables, configured,and u/iom is accessible */
/* Map the message buffer. */
diff --git a/sys/pc98/pc98/pc98_machdep.c b/sys/pc98/pc98/pc98_machdep.c
index 8b3e016..7e2799b 100644
--- a/sys/pc98/pc98/pc98_machdep.c
+++ b/sys/pc98/pc98/pc98_machdep.c
@@ -41,13 +41,6 @@
#include <pc98/pc98/pc98_machdep.h>
-extern int Maxmem;
-extern int Maxmem_under16M;
-
-#ifdef notyet
-static void init_cpu_accel_mem __P((void));
-#endif
-
/*
* Initialize DMA controller
*/
@@ -74,130 +67,50 @@ static void init_epson_memwin __P((void));
static void
init_epson_memwin(void)
{
-
- if (pc98_machine_type & M_EPSON_PC98) {
- if (Maxmem > 3840) {
- if (Maxmem == Maxmem_under16M) {
- Maxmem = 3840;
- Maxmem_under16M = 3840;
- } else if (Maxmem_under16M > 3840) {
- Maxmem_under16M = 3840;
- }
- }
-
- /* Disable 15MB-16MB caching. */
- switch (epson_machine_id) {
- case 0x34: /* PC486HX */
- case 0x35: /* PC486HG */
- case 0x3B: /* PC486HA */
- /* Cache control start. */
- outb(0x43f, 0x42);
- outw(0xc40, 0x0033);
-
- /* Disable 0xF00000-0xFFFFFF. */
- outb(0xc48, 0x49);
- outb(0xc4c, 0x00);
- outb(0xc48, 0x48);
- outb(0xc4c, 0xf0);
- outb(0xc48, 0x4d);
- outb(0xc4c, 0x00);
- outb(0xc48, 0x4c);
- outb(0xc4c, 0xff);
- outb(0xc48, 0x4f);
- outb(0xc4c, 0x00);
-
- /* Cache control end. */
- outb(0x43f, 0x40);
- break;
-
- case 0x2B: /* PC486GR/GF */
- case 0x30: /* PC486P */
- case 0x31: /* PC486GRSuper */
- case 0x32: /* PC486GR+ */
- case 0x37: /* PC486SE */
- case 0x38: /* PC486SR */
- /* Disable 0xF00000-0xFFFFFF. */
- outb(0x43f, 0x42);
- outb(0x467, 0xe0);
- outb(0x567, 0xd8);
-
- outb(0x43f, 0x40);
- outb(0x467, 0xe0);
- outb(0x567, 0xe0);
- break;
- }
-
- /* Disable 15MB-16MB RAM and enable memory window. */
- outb(0x43b, inb(0x43b) & 0xfd); /* Clear bit1. */
+ /* Disable 15MB-16MB caching. */
+ switch (epson_machine_id) {
+ case 0x34: /* PC486HX */
+ case 0x35: /* PC486HG */
+ case 0x3B: /* PC486HA */
+ /* Cache control start. */
+ outb(0x43f, 0x42);
+ outw(0xc40, 0x0033);
+
+ /* Disable 0xF00000-0xFFFFFF. */
+ outb(0xc48, 0x49);
+ outb(0xc4c, 0x00);
+ outb(0xc48, 0x48);
+ outb(0xc4c, 0xf0);
+ outb(0xc48, 0x4d);
+ outb(0xc4c, 0x00);
+ outb(0xc48, 0x4c);
+ outb(0xc4c, 0xff);
+ outb(0xc48, 0x4f);
+ outb(0xc4c, 0x00);
+
+ /* Cache control end. */
+ outb(0x43f, 0x40);
+ break;
+
+ case 0x2B: /* PC486GR/GF */
+ case 0x30: /* PC486P */
+ case 0x31: /* PC486GRSuper */
+ case 0x32: /* PC486GR+ */
+ case 0x37: /* PC486SE */
+ case 0x38: /* PC486SR */
+ /* Disable 0xF00000-0xFFFFFF. */
+ outb(0x43f, 0x42);
+ outb(0x467, 0xe0);
+ outb(0x567, 0xd8);
+
+ outb(0x43f, 0x40);
+ outb(0x467, 0xe0);
+ outb(0x567, 0xe0);
+ break;
}
-}
-#endif
-
-#ifdef notyet
-static void init_cpu_accel_mem(void);
-
-static void
-init_cpu_accel_mem(void)
-{
- u_int target_page;
- /*
- * Certain 'CPU accelerator' supports over 16MB memory on
- * the machines whose BIOS doesn't store true size.
- * To support this, we don't trust BIOS values if Maxmem < 4096.
- */
- if (Maxmem < 4096) {
- for (target_page = ptoa(4096); /* 16MB */
- target_page < ptoa(32768); /* 128MB */
- target_page += 256 * PAGE_SIZE /* 1MB step */) {
- u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
-
- *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
- invltlb();
- tmp = *(u_int *)CADDR1;
- /*
- * Test for alternating 1's and 0's
- */
- *(volatile u_int *)CADDR1 = 0xaaaaaaaa;
- if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
- page_bad = TRUE;
- }
- /*
- * Test for alternating 0's and 1's
- */
- *(volatile u_int *)CADDR1 = 0x55555555;
- if (*(volatile u_int *)CADDR1 != 0x55555555) {
- page_bad = TRUE;
- }
- /*
- * Test for all 1's
- */
- *(volatile u_int *)CADDR1 = 0xffffffff;
- if (*(volatile u_int *)CADDR1 != 0xffffffff) {
- page_bad = TRUE;
- }
- /*
- * Test for all 0's
- */
- *(volatile u_int *)CADDR1 = 0x0;
- if (*(volatile u_int *)CADDR1 != 0x0) {
- /*
- * test of page failed
- */
- page_bad = TRUE;
- }
- /*
- * Restore original value.
- */
- *(u_int *)CADDR1 = tmp;
- if (page_bad == TRUE) {
- Maxmem = atop(target_page) + 256;
- } else
- break;
- }
- *(int *)CMAP1 = 0;
- invltlb();
- }
+ /* Disable 15MB-16MB RAM and enable memory window. */
+ outb(0x43b, inb(0x43b) & 0xfd); /* Clear bit1. */
}
#endif
@@ -205,22 +118,33 @@ init_cpu_accel_mem(void)
* Get physical memory size
*/
void
-pc98_getmemsize(void)
+pc98_getmemsize(unsigned *base, unsigned *ext, unsigned *under16)
{
- unsigned char under16, over16;
+ unsigned int over16;
- /* available protected memory size under 16MB / 128KB */
- under16 = PC98_SYSTEM_PARAMETER(0x401);
- /* available protected memory size over 16MB / 1MB */
- over16 = PC98_SYSTEM_PARAMETER(0x594);
- /* add conventional memory size (1024KB / 128KB = 8) */
- under16 += 8;
+ /* available conventional memory size */
+ *base = ((PC98_SYSTEM_PARAMETER(0x501) & 7) + 1) * 128;
- Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE;
- Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE);
+ /* available protected memory size under 16MB */
+ *under16 = PC98_SYSTEM_PARAMETER(0x401) * 128 + 1024;
#ifdef EPSON_MEMWIN
- init_epson_memwin();
+ if (pc98_machine_type & M_EPSON_PC98) {
+ if (*under16 > (15 * 1024)) {
+ /* chop under16 memory to 15MB */
+ *under16 = 15 * 1024;
+ }
+ init_epson_memwin();
+ }
#endif
+
+ /* available protected memory size over 16MB / 1MB */
+ over16 = PC98_SYSTEM_PARAMETER(0x594);
+ over16 += PC98_SYSTEM_PARAMETER(0x595) * 256;
+
+ *ext = *under16;
+ if (over16 > 0) {
+ *ext = (16 + over16) * 1024;
+ }
}
#include "da.h"
diff --git a/sys/pc98/pc98/pc98_machdep.h b/sys/pc98/pc98/pc98_machdep.h
index b2457c1..ee5c78e 100644
--- a/sys/pc98/pc98/pc98_machdep.h
+++ b/sys/pc98/pc98/pc98_machdep.h
@@ -31,7 +31,7 @@
#define __PC98_PC98_PC98_MACHDEP_H__
void pc98_init_dmac __P((void));
-void pc98_getmemsize __P((void));
+void pc98_getmemsize __P((unsigned *, unsigned *, unsigned *));
struct ccb_calc_geometry;
int scsi_da_bios_params __P((struct ccb_calc_geometry *));
OpenPOWER on IntegriCloud