pc98_machdep.c revision 19122
1/*
2 * Copyright (c) KATO Takenori, 1996.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer as
9 *    the first lines of this file unmodified.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include <sys/param.h>
29#include <sys/systm.h>
30#include <sys/vmmeter.h>
31
32#include <vm/vm.h>
33#include <vm/vm_param.h>
34#include <vm/vm_prot.h>
35#include <vm/lock.h>
36#include <vm/vm_kern.h>
37#include <vm/vm_object.h>
38#include <vm/vm_page.h>
39#include <vm/vm_map.h>
40#include <vm/vm_pager.h>
41#include <vm/vm_extern.h>
42
43#include <pc98/pc98/pc98.h>
44#include <i386/isa/isa_device.h>
45
46extern int Maxmem;
47extern int Maxmem_under16M;
48
49static void init_cpu_accel_mem __P((void));
50void pc98_init_dmac __P((void));
51
52#ifdef EPSON_MEMWIN
53static void init_epson_memwin __P((void));
54
55static void init_epson_memwin(void)
56{
57	if (pc98_machine_type & M_EPSON_PC98) {
58		if (Maxmem > 3840) {
59			if (Maxmem == Maxmem_under16M) {
60				Maxmem = 3840;
61				Maxmem_under16M = 3840;
62			} else if (Maxmem_under16M > 3840) {
63				Maxmem_under16M = 3840;
64			}
65		}
66
67		/* Disable 15MB-16MB caching */
68		switch (epson_machine_id) {
69		case 0x34:	/* PC486HX */
70		case 0x35:	/* PC486HG */
71		case 0x3B:	/* PC486HA */
72			/* Cache control start */
73			outb(0x43f, 0x42);
74			outw(0xc40, 0x0033);
75
76			/* Disable 0xF00000-0xFFFFFF */
77			outb(0xc48, 0x49); outb(0xc4c, 0x00);
78			outb(0xc48, 0x48); outb(0xc4c, 0xf0);
79			outb(0xc48, 0x4d); outb(0xc4c, 0x00);
80			outb(0xc48, 0x4c); outb(0xc4c, 0xff);
81			outb(0xc48, 0x4f); outb(0xc4c, 0x00);
82
83			/* Cache control end */
84			outb(0x43f, 0x40);
85			break;
86
87		case 0x2B:	/* PC486GR/GF */
88		case 0x30:	/* PC486P */
89		case 0x31:	/* PC486GRSuper */
90		case 0x32:	/* PC486GR+ */
91		case 0x37:	/* PC486SE */
92		case 0x38:	/* PC486SR */
93			/* Disable 0xF00000-0xFFFFFF */
94			outb(0x43f, 0x42);
95			outb(0x467, 0xe0);
96			outb(0x567, 0xd8);
97
98			outb(0x43f, 0x40);
99			outb(0x467, 0xe0);
100			outb(0x567, 0xe0);
101			break;
102		}
103
104		/* Disable 15MB-16MB RAM and enable memory window */
105		outb(0x43b, inb(0x43b) & 0xfd);	/* clear bit1 */
106	}
107}
108#endif
109
110static void init_cpu_accel_mem(void)
111{
112	u_int target_page;
113	/*
114	 * Certain 'CPU accelerator' supports over 16MB memory on
115	 * the machines whose BIOS doesn't store true size.
116	 * To support this, we don't trust BIOS values if Maxmem < 4096.
117	 */
118	if (Maxmem < 4096) {
119		for (target_page = ptoa(4096);		/* 16MB */
120			 target_page < ptoa(32768);		/* 128MB */
121			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
122			u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
123
124			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
125			invltlb();
126
127			tmp = *(u_int *)CADDR1;
128			/*
129			 * Test for alternating 1's and 0's
130			 */
131			*(volatile u_int *)CADDR1 = 0xaaaaaaaa;
132			if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
133				page_bad = TRUE;
134			}
135			/*
136			 * Test for alternating 0's and 1's
137			 */
138			*(volatile u_int *)CADDR1 = 0x55555555;
139			if (*(volatile u_int *)CADDR1 != 0x55555555) {
140				page_bad = TRUE;
141			}
142			/*
143			 * Test for all 1's
144			 */
145			*(volatile u_int *)CADDR1 = 0xffffffff;
146			if (*(volatile u_int *)CADDR1 != 0xffffffff) {
147				page_bad = TRUE;
148			}
149			/*
150			 * Test for all 0's
151			 */
152			*(volatile u_int *)CADDR1 = 0x0;
153			if (*(volatile u_int *)CADDR1 != 0x0) {
154				/*
155				 * test of page failed
156				 */
157				page_bad = TRUE;
158			}
159			/*
160			 * Restore original value.
161			 */
162			*(u_int *)CADDR1 = tmp;
163			if (page_bad == TRUE) {
164				Maxmem = atop(target_page) + 256;
165			} else
166				break;
167		}
168		*(int *)CMAP1 = 0;
169		invltlb();
170	}
171}
172
173
174void pc98_init_dmac(void)
175{
176	outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
177	outb(0x29, (0x0c | 0));	/* Bank Mode Reg. 16M mode */
178	outb(0x29, (0x0c | 1));	/* Bank Mode Reg. 16M mode */
179	outb(0x29, (0x0c | 2));	/* Bank Mode Reg. 16M mode */
180	outb(0x29, (0x0c | 3));	/* Bank Mode Reg. 16M mode */
181	outb(0x11, 0x50);	/* PC98 must be 0x40 */
182}
183
184
185void pc98_getmemsize(void)
186{
187	unsigned char under16, over16;
188
189	/* available protected memory size under 16MB / 128KB */
190	under16 = PC98_SYSTEM_PARAMETER(0x401);
191	/* available protected memory size over 16MB / 1MB */
192	over16 = PC98_SYSTEM_PARAMETER(0x594);
193	/* add conventional memory size (1024KB / 128KB = 8) */
194	under16 += 8;
195
196	Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE;
197	Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE);
198#ifdef EPSON_MEMWIN
199	init_epson_memwin();
200#endif
201}
202