Fixed to probe extended memory for over 256M or under 64M.

Submitted by:   chi@bd.mbn.or.jp (Chiharu Shibata)
This commit is contained in:
Yoshihiro Takahashi 2000-03-16 12:14:00 +00:00
parent 49c57093b7
commit 2b60363d7f
4 changed files with 267 additions and 213 deletions

View File

@ -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. */

View File

@ -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. */

View File

@ -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)
{
/* 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);
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 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);
/* 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);
/* Cache control end. */
outb(0x43f, 0x40);
break;
/* 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);
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);
/* 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. */
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"

View File

@ -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 *));