diff options
author | nyan <nyan@FreeBSD.org> | 2000-03-16 12:14:00 +0000 |
---|---|---|
committer | nyan <nyan@FreeBSD.org> | 2000-03-16 12:14:00 +0000 |
commit | 516636217a60d40789f54127316c929191f7e2c1 (patch) | |
tree | f673de301911b85871218054875e01ef617b2592 /sys | |
parent | a16d0e912fcf87486c21f0dc3a8a85abb3020ab4 (diff) | |
download | FreeBSD-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.c | 141 | ||||
-rw-r--r-- | sys/pc98/pc98/machdep.c | 141 | ||||
-rw-r--r-- | sys/pc98/pc98/pc98_machdep.c | 204 | ||||
-rw-r--r-- | sys/pc98/pc98/pc98_machdep.h | 2 |
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 *)); |