pc98_machdep.c revision 22165
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));
51void	pc98_getmemsize __P((void));
52
53#ifdef EPSON_MEMWIN
54static	void init_epson_memwin __P((void));
55
56static void
57init_epson_memwin(void)
58{
59
60	if (pc98_machine_type & M_EPSON_PC98) {
61		if (Maxmem > 3840) {
62			if (Maxmem == Maxmem_under16M) {
63				Maxmem = 3840;
64				Maxmem_under16M = 3840;
65			} else if (Maxmem_under16M > 3840) {
66				Maxmem_under16M = 3840;
67			}
68		}
69
70		/* Disable 15MB-16MB caching. */
71		switch (epson_machine_id) {
72		case 0x34:	/* PC486HX */
73		case 0x35:	/* PC486HG */
74		case 0x3B:	/* PC486HA */
75			/* Cache control start. */
76			outb(0x43f, 0x42);
77			outw(0xc40, 0x0033);
78
79			/* Disable 0xF00000-0xFFFFFF. */
80			outb(0xc48, 0x49);
81			outb(0xc4c, 0x00);
82			outb(0xc48, 0x48);
83			outb(0xc4c, 0xf0);
84			outb(0xc48, 0x4d);
85			outb(0xc4c, 0x00);
86			outb(0xc48, 0x4c);
87			outb(0xc4c, 0xff);
88			outb(0xc48, 0x4f);
89			outb(0xc4c, 0x00);
90
91			/* Cache control end. */
92			outb(0x43f, 0x40);
93			break;
94
95		case 0x2B:	/* PC486GR/GF */
96		case 0x30:	/* PC486P */
97		case 0x31:	/* PC486GRSuper */
98		case 0x32:	/* PC486GR+ */
99		case 0x37:	/* PC486SE */
100		case 0x38:	/* PC486SR */
101			/* Disable 0xF00000-0xFFFFFF. */
102			outb(0x43f, 0x42);
103			outb(0x467, 0xe0);
104			outb(0x567, 0xd8);
105
106			outb(0x43f, 0x40);
107			outb(0x467, 0xe0);
108			outb(0x567, 0xe0);
109			break;
110		}
111
112		/* Disable 15MB-16MB RAM and enable memory window. */
113		outb(0x43b, inb(0x43b) & 0xfd);	/* Clear bit1. */
114	}
115}
116#endif
117
118#ifdef notyet
119static	void init_cpu_accel_mem(void);
120
121static void
122init_cpu_accel_mem(void)
123{
124	u_int target_page;
125	/*
126	 * Certain 'CPU accelerator' supports over 16MB memory on
127	 * the machines whose BIOS doesn't store true size.
128	 * To support this, we don't trust BIOS values if Maxmem < 4096.
129	 */
130	if (Maxmem < 4096) {
131		for (target_page = ptoa(4096);		/* 16MB */
132			 target_page < ptoa(32768);		/* 128MB */
133			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
134			u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
135
136			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
137			invltlb();
138
139			tmp = *(u_int *)CADDR1;
140			/*
141			 * Test for alternating 1's and 0's
142			 */
143			*(volatile u_int *)CADDR1 = 0xaaaaaaaa;
144			if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
145				page_bad = TRUE;
146			}
147			/*
148			 * Test for alternating 0's and 1's
149			 */
150			*(volatile u_int *)CADDR1 = 0x55555555;
151			if (*(volatile u_int *)CADDR1 != 0x55555555) {
152				page_bad = TRUE;
153			}
154			/*
155			 * Test for all 1's
156			 */
157			*(volatile u_int *)CADDR1 = 0xffffffff;
158			if (*(volatile u_int *)CADDR1 != 0xffffffff) {
159				page_bad = TRUE;
160			}
161			/*
162			 * Test for all 0's
163			 */
164			*(volatile u_int *)CADDR1 = 0x0;
165			if (*(volatile u_int *)CADDR1 != 0x0) {
166				/*
167				 * test of page failed
168				 */
169				page_bad = TRUE;
170			}
171			/*
172			 * Restore original value.
173			 */
174			*(u_int *)CADDR1 = tmp;
175			if (page_bad == TRUE) {
176				Maxmem = atop(target_page) + 256;
177			} else
178				break;
179		}
180		*(int *)CMAP1 = 0;
181		invltlb();
182	}
183}
184#endif
185
186void
187pc98_init_dmac(void)
188{
189	outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
190	outb(0x29, (0x0c | 0));	/* Bank Mode Reg. 16M mode */
191	outb(0x29, (0x0c | 1));	/* Bank Mode Reg. 16M mode */
192	outb(0x29, (0x0c | 2));	/* Bank Mode Reg. 16M mode */
193	outb(0x29, (0x0c | 3));	/* Bank Mode Reg. 16M mode */
194	outb(0x11, 0x50);	/* PC98 must be 0x40 */
195}
196
197void
198pc98_getmemsize(void)
199{
200	unsigned char under16, over16;
201
202	/* available protected memory size under 16MB / 128KB */
203	under16 = PC98_SYSTEM_PARAMETER(0x401);
204	/* available protected memory size over 16MB / 1MB */
205	over16 = PC98_SYSTEM_PARAMETER(0x594);
206	/* add conventional memory size (1024KB / 128KB = 8) */
207	under16 += 8;
208
209	Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE;
210	Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE);
211#ifdef EPSON_MEMWIN
212	init_epson_memwin();
213#endif
214}
215