pc98_machdep.c revision 17350
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_device.h>
44
45extern int Maxmem;
46extern int Maxmem_under16M;
47
48void init_cpu_accel_mem __P((void));
49void init_pc98_dmac __P((void));
50
51#ifdef EPSON_MEMWIN
52void init_epson_memwin __P((void));
53
54void init_epson_memwin(void)
55{
56	if (pc98_machine_type & M_EPSON_PC98) {
57		if (Maxmem > 3840) {
58			if (Maxmem == Maxmem_under16M) {
59				Maxmem = 3840;
60				Maxmem_under16M = 3840;
61			} else if (Maxmem_under16M > 3840) {
62				Maxmem_under16M = 3840;
63			}
64		}
65
66		/* Disable 15MB-16MB caching */
67		switch (epson_machine_id) {
68		case 0x34:	/* PC486HX */
69		case 0x35:	/* PC486HG */
70		case 0x3B:	/* PC486HA */
71			/* Cache control start */
72			outb(0x43f, 0x42);
73			outw(0xc40, 0x0033);
74
75			/* Disable 0xF00000-0xFFFFFF */
76			outb(0xc48, 0x49); outb(0xc4c, 0x00);
77			outb(0xc48, 0x48); outb(0xc4c, 0xf0);
78			outb(0xc48, 0x4d); outb(0xc4c, 0x00);
79			outb(0xc48, 0x4c); outb(0xc4c, 0xff);
80			outb(0xc48, 0x4f); outb(0xc4c, 0x00);
81
82			/* Cache control end */
83			outb(0x43f, 0x40);
84			break;
85
86		case 0x2B:	/* PC486GR/GF */
87		case 0x30:	/* PC486P */
88		case 0x31:	/* PC486GRSuper */
89		case 0x32:	/* PC486GR+ */
90		case 0x37:	/* PC486SE */
91		case 0x38:	/* PC486SR */
92			/* Disable 0xF00000-0xFFFFFF */
93			outb(0x43f, 0x42);
94			outb(0x467, 0xe0);
95			outb(0x567, 0xd8);
96
97			outb(0x43f, 0x40);
98			outb(0x467, 0xe0);
99			outb(0x567, 0xe0);
100			break;
101		}
102
103		/* Disable 15MB-16MB RAM and enable memory window */
104		outb(0x43b, inb(0x43b) & 0xfd);	/* clear bit1 */
105	}
106}
107#endif
108
109void init_cpu_accel_mem(void)
110{
111	int target_page;
112	/*
113	 * Certain 'CPU accelerator' supports over 16MB memory on
114	 * the machines whose BIOS doesn't store true size.
115	 * To support this, we don't trust BIOS values if Maxmem < 4096.
116	 */
117	if (Maxmem < 4096) {
118		for (target_page = ptoa(4096);		/* 16MB */
119			 target_page < ptoa(32768);		/* 128MB */
120			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
121			int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
122
123			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
124			pmap_update();
125
126			tmp = *(int *)CADDR1;
127			/*
128			 * Test for alternating 1's and 0's
129			 */
130			*(volatile int *)CADDR1 = 0xaaaaaaaa;
131			if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
132				page_bad = TRUE;
133			}
134			/*
135			 * Test for alternating 0's and 1's
136			 */
137			*(volatile int *)CADDR1 = 0x55555555;
138			if (*(volatile int *)CADDR1 != 0x55555555) {
139				page_bad = TRUE;
140			}
141			/*
142			 * Test for all 1's
143			 */
144			*(volatile int *)CADDR1 = 0xffffffff;
145			if (*(volatile int *)CADDR1 != 0xffffffff) {
146				page_bad = TRUE;
147			}
148			/*
149			 * Test for all 0's
150			 */
151			*(volatile int *)CADDR1 = 0x0;
152			if (*(volatile int *)CADDR1 != 0x0) {
153				/*
154				 * test of page failed
155				 */
156				page_bad = TRUE;
157			}
158			/*
159			 * Restore original value.
160			 */
161			*(int *)CADDR1 = tmp;
162			if (page_bad == TRUE) {
163				if (target_page > ptoa(4096))
164					Maxmem = atop(target_page);
165				else
166					Maxmem = OrigMaxmem;
167
168				break;
169			}
170		}
171		*(int *)CMAP1 = 0;
172		pmap_update();
173
174		/* XXX */
175		if (Maxmem > 3840) {
176			Maxmem_under16M = 3840;
177			if (Maxmem < 4096) {
178				Maxmem = 3840;
179			}
180		}
181	}
182}
183
184int dma_init_flag = 1;	/* dummy */
185
186void init_pc98_dmac(void)
187{
188	outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
189	outb(0x29, (0x0c | 0));	/* Bank Mode Reg. 16M mode */
190	outb(0x29, (0x0c | 1));	/* Bank Mode Reg. 16M mode */
191	outb(0x29, (0x0c | 2));	/* Bank Mode Reg. 16M mode */
192	outb(0x29, (0x0c | 3));	/* Bank Mode Reg. 16M mode */
193	outb(0x11, 0x50);	/* PC98 must be 0x40 */
194}
195/*
196 * Copyright (c) KATO Takenori, 1996.  All rights reserved.
197 *
198 * Redistribution and use in source and binary forms, with or without
199 * modification, are permitted provided that the following conditions
200 * are met:
201 * 1. Redistributions of source code must retain the above copyright
202 *    notice, this list of conditions and the following disclaimer as
203 *    the first lines of this file unmodified.
204 * 2. Redistributions in binary form must reproduce the above copyright
205 *    notice, this list of conditions and the following disclaimer in the
206 *    documentation and/or other materials provided with the distribution.
207 * 3. The name of the author may not be used to endorse or promote products
208 *    derived from this software without specific prior written permission.
209 *
210 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
211 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
212 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
213 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
214 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
215 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
216 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
217 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
218 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
219 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
220 */
221
222#include <sys/param.h>
223#include <sys/systm.h>
224#include <sys/vmmeter.h>
225
226#include <vm/vm.h>
227#include <vm/vm_param.h>
228#include <vm/vm_prot.h>
229#include <vm/lock.h>
230#include <vm/vm_kern.h>
231#include <vm/vm_object.h>
232#include <vm/vm_page.h>
233#include <vm/vm_map.h>
234#include <vm/vm_pager.h>
235#include <vm/vm_extern.h>
236
237#include <pc98/pc98/pc98_device.h>
238
239extern int Maxmem;
240extern int Maxmem_under16M;
241
242void init_cpu_accel_mem __P((void));
243void init_pc98_dmac __P((void));
244
245#ifdef EPSON_MEMWIN
246void init_epson_memwin __P((void));
247
248void init_epson_memwin(void)
249{
250	if (pc98_machine_type & M_EPSON_PC98) {
251		if (Maxmem > 3840) {
252			if (Maxmem == Maxmem_under16M) {
253				Maxmem = 3840;
254				Maxmem_under16M = 3840;
255			} else if (Maxmem_under16M > 3840) {
256				Maxmem_under16M = 3840;
257			}
258		}
259
260		/* Disable 15MB-16MB caching */
261		switch (epson_machine_id) {
262		case 0x34:	/* PC486HX */
263		case 0x35:	/* PC486HG */
264		case 0x3B:	/* PC486HA */
265			/* Cache control start */
266			outb(0x43f, 0x42);
267			outw(0xc40, 0x0033);
268
269			/* Disable 0xF00000-0xFFFFFF */
270			outb(0xc48, 0x49); outb(0xc4c, 0x00);
271			outb(0xc48, 0x48); outb(0xc4c, 0xf0);
272			outb(0xc48, 0x4d); outb(0xc4c, 0x00);
273			outb(0xc48, 0x4c); outb(0xc4c, 0xff);
274			outb(0xc48, 0x4f); outb(0xc4c, 0x00);
275
276			/* Cache control end */
277			outb(0x43f, 0x40);
278			break;
279
280		case 0x2B:	/* PC486GR/GF */
281		case 0x30:	/* PC486P */
282		case 0x31:	/* PC486GRSuper */
283		case 0x32:	/* PC486GR+ */
284		case 0x37:	/* PC486SE */
285		case 0x38:	/* PC486SR */
286			/* Disable 0xF00000-0xFFFFFF */
287			outb(0x43f, 0x42);
288			outb(0x467, 0xe0);
289			outb(0x567, 0xd8);
290
291			outb(0x43f, 0x40);
292			outb(0x467, 0xe0);
293			outb(0x567, 0xe0);
294			break;
295		}
296
297		/* Disable 15MB-16MB RAM and enable memory window */
298		outb(0x43b, inb(0x43b) & 0xfd);	/* clear bit1 */
299	}
300}
301#endif
302
303void init_cpu_accel_mem(void)
304{
305	int target_page;
306	/*
307	 * Certain 'CPU accelerator' supports over 16MB memory on
308	 * the machines whose BIOS doesn't store true size.
309	 * To support this, we don't trust BIOS values if Maxmem < 4096.
310	 */
311	if (Maxmem < 4096) {
312		for (target_page = ptoa(4096);		/* 16MB */
313			 target_page < ptoa(32768);		/* 128MB */
314			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
315			int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
316
317			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
318			pmap_update();
319
320			tmp = *(int *)CADDR1;
321			/*
322			 * Test for alternating 1's and 0's
323			 */
324			*(volatile int *)CADDR1 = 0xaaaaaaaa;
325			if (*(volatile int *)CADDR1 != 0xaaaaaaaa) {
326				page_bad = TRUE;
327			}
328			/*
329			 * Test for alternating 0's and 1's
330			 */
331			*(volatile int *)CADDR1 = 0x55555555;
332			if (*(volatile int *)CADDR1 != 0x55555555) {
333				page_bad = TRUE;
334			}
335			/*
336			 * Test for all 1's
337			 */
338			*(volatile int *)CADDR1 = 0xffffffff;
339			if (*(volatile int *)CADDR1 != 0xffffffff) {
340				page_bad = TRUE;
341			}
342			/*
343			 * Test for all 0's
344			 */
345			*(volatile int *)CADDR1 = 0x0;
346			if (*(volatile int *)CADDR1 != 0x0) {
347				/*
348				 * test of page failed
349				 */
350				page_bad = TRUE;
351			}
352			/*
353			 * Restore original value.
354			 */
355			*(int *)CADDR1 = tmp;
356			if (page_bad == TRUE) {
357				if (target_page > ptoa(4096))
358					Maxmem = atop(target_page);
359				else
360					Maxmem = OrigMaxmem;
361
362				break;
363			}
364		}
365		*(int *)CMAP1 = 0;
366		pmap_update();
367
368		/* XXX */
369		if (Maxmem > 3840) {
370			Maxmem_under16M = 3840;
371			if (Maxmem < 4096) {
372				Maxmem = 3840;
373			}
374		}
375	}
376}
377
378int dma_init_flag = 1;	/* dummy */
379
380void init_pc98_dmac(void)
381{
382	outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
383	outb(0x29, (0x0c | 0));	/* Bank Mode Reg. 16M mode */
384	outb(0x29, (0x0c | 1));	/* Bank Mode Reg. 16M mode */
385	outb(0x29, (0x0c | 2));	/* Bank Mode Reg. 16M mode */
386	outb(0x29, (0x0c | 3));	/* Bank Mode Reg. 16M mode */
387	outb(0x11, 0x50);	/* PC98 must be 0x40 */
388}
389