pc98_machdep.c revision 17947
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