pc98_machdep.c revision 22263
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 <scsi/scsiconf.h>
33
34#include <vm/vm.h>
35#include <vm/vm_param.h>
36#include <vm/vm_prot.h>
37#include <vm/lock.h>
38#include <vm/vm_kern.h>
39#include <vm/vm_object.h>
40#include <vm/vm_page.h>
41#include <vm/vm_map.h>
42#include <vm/vm_pager.h>
43#include <vm/vm_extern.h>
44
45#include <pc98/pc98/pc98.h>
46#include <i386/isa/isa_device.h>
47
48extern	int Maxmem;
49extern	int Maxmem_under16M;
50
51static	void init_cpu_accel_mem __P((void));
52void	pc98_init_dmac __P((void));
53void	pc98_getmemsize __P((void));
54
55#ifdef EPSON_MEMWIN
56static	void init_epson_memwin __P((void));
57
58static void
59init_epson_memwin(void)
60{
61
62	if (pc98_machine_type & M_EPSON_PC98) {
63		if (Maxmem > 3840) {
64			if (Maxmem == Maxmem_under16M) {
65				Maxmem = 3840;
66				Maxmem_under16M = 3840;
67			} else if (Maxmem_under16M > 3840) {
68				Maxmem_under16M = 3840;
69			}
70		}
71
72		/* Disable 15MB-16MB caching. */
73		switch (epson_machine_id) {
74		case 0x34:	/* PC486HX */
75		case 0x35:	/* PC486HG */
76		case 0x3B:	/* PC486HA */
77			/* Cache control start. */
78			outb(0x43f, 0x42);
79			outw(0xc40, 0x0033);
80
81			/* Disable 0xF00000-0xFFFFFF. */
82			outb(0xc48, 0x49);
83			outb(0xc4c, 0x00);
84			outb(0xc48, 0x48);
85			outb(0xc4c, 0xf0);
86			outb(0xc48, 0x4d);
87			outb(0xc4c, 0x00);
88			outb(0xc48, 0x4c);
89			outb(0xc4c, 0xff);
90			outb(0xc48, 0x4f);
91			outb(0xc4c, 0x00);
92
93			/* Cache control end. */
94			outb(0x43f, 0x40);
95			break;
96
97		case 0x2B:	/* PC486GR/GF */
98		case 0x30:	/* PC486P */
99		case 0x31:	/* PC486GRSuper */
100		case 0x32:	/* PC486GR+ */
101		case 0x37:	/* PC486SE */
102		case 0x38:	/* PC486SR */
103			/* Disable 0xF00000-0xFFFFFF. */
104			outb(0x43f, 0x42);
105			outb(0x467, 0xe0);
106			outb(0x567, 0xd8);
107
108			outb(0x43f, 0x40);
109			outb(0x467, 0xe0);
110			outb(0x567, 0xe0);
111			break;
112		}
113
114		/* Disable 15MB-16MB RAM and enable memory window. */
115		outb(0x43b, inb(0x43b) & 0xfd);	/* Clear bit1. */
116	}
117}
118#endif
119
120#ifdef notyet
121static	void init_cpu_accel_mem(void);
122
123static void
124init_cpu_accel_mem(void)
125{
126	u_int target_page;
127	/*
128	 * Certain 'CPU accelerator' supports over 16MB memory on
129	 * the machines whose BIOS doesn't store true size.
130	 * To support this, we don't trust BIOS values if Maxmem < 4096.
131	 */
132	if (Maxmem < 4096) {
133		for (target_page = ptoa(4096);		/* 16MB */
134			 target_page < ptoa(32768);		/* 128MB */
135			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
136			u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
137
138			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
139			invltlb();
140
141			tmp = *(u_int *)CADDR1;
142			/*
143			 * Test for alternating 1's and 0's
144			 */
145			*(volatile u_int *)CADDR1 = 0xaaaaaaaa;
146			if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
147				page_bad = TRUE;
148			}
149			/*
150			 * Test for alternating 0's and 1's
151			 */
152			*(volatile u_int *)CADDR1 = 0x55555555;
153			if (*(volatile u_int *)CADDR1 != 0x55555555) {
154				page_bad = TRUE;
155			}
156			/*
157			 * Test for all 1's
158			 */
159			*(volatile u_int *)CADDR1 = 0xffffffff;
160			if (*(volatile u_int *)CADDR1 != 0xffffffff) {
161				page_bad = TRUE;
162			}
163			/*
164			 * Test for all 0's
165			 */
166			*(volatile u_int *)CADDR1 = 0x0;
167			if (*(volatile u_int *)CADDR1 != 0x0) {
168				/*
169				 * test of page failed
170				 */
171				page_bad = TRUE;
172			}
173			/*
174			 * Restore original value.
175			 */
176			*(u_int *)CADDR1 = tmp;
177			if (page_bad == TRUE) {
178				Maxmem = atop(target_page) + 256;
179			} else
180				break;
181		}
182		*(int *)CMAP1 = 0;
183		invltlb();
184	}
185}
186#endif
187
188void
189pc98_init_dmac(void)
190{
191	outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */
192	outb(0x29, (0x0c | 0));	/* Bank Mode Reg. 16M mode */
193	outb(0x29, (0x0c | 1));	/* Bank Mode Reg. 16M mode */
194	outb(0x29, (0x0c | 2));	/* Bank Mode Reg. 16M mode */
195	outb(0x29, (0x0c | 3));	/* Bank Mode Reg. 16M mode */
196	outb(0x11, 0x50);	/* PC98 must be 0x40 */
197}
198
199void
200pc98_getmemsize(void)
201{
202	unsigned char under16, over16;
203
204	/* available protected memory size under 16MB / 128KB */
205	under16 = PC98_SYSTEM_PARAMETER(0x401);
206	/* available protected memory size over 16MB / 1MB */
207	over16 = PC98_SYSTEM_PARAMETER(0x594);
208	/* add conventional memory size (1024KB / 128KB = 8) */
209	under16 += 8;
210
211	Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE;
212	Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE);
213#ifdef EPSON_MEMWIN
214	init_epson_memwin();
215#endif
216}
217
218#include "sd.h"
219
220#if NSD > 0
221/*
222 * XXX copied from sd.c.
223 */
224struct disk_parms {
225	u_char	heads;	/* Number of heads */
226	u_int16_t	cyls;	/* Number of cylinders */
227	u_char	sectors;	/*dubious *//* Number of sectors/track */
228	u_int16_t	secsiz;	/* Number of bytes/sector */
229	u_int32_t	disksize;	/* total number sectors */
230};
231
232int	sd_bios_parms __P((struct disk_parms *, struct scsi_link *));
233
234/*
235 * Read a geometry information of SCSI HDD from BIOS work area.
236 *
237 * XXX - Before reading BIOS work area, we should check whether
238 * host adapter support it.
239 */
240int
241sd_bios_parms(disk_parms, sc_link)
242	struct	disk_parms *disk_parms;
243	struct	scsi_link *sc_link;
244{
245	u_char *tmp;
246
247	tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + sc_link->target*4);
248	if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << sc_link->target)&0xff)) != 0) {
249		disk_parms->sectors = *tmp;
250		disk_parms->cyls = ((*(tmp+3)<<8)|*(tmp+2))&0xfff;
251		switch (*(tmp + 3) & 0x30) {
252		case 0x00:
253			disk_parms->secsiz = 256;
254			printf("Warning!: not supported.\n");
255			break;
256		case 0x10:
257			disk_parms->secsiz = 512;
258			break;
259		case 0x20:
260			disk_parms->secsiz = 1024;
261			break;
262		default:
263			disk_parms->secsiz = 512;
264			printf("Warning!: not supported. But force to 512\n");
265			break;
266		}
267		if (*(tmp+3) & 0x40) {
268			disk_parms->cyls += (*(tmp+1)&0xf0)<<8;
269			disk_parms->heads = *(tmp+1)&0x0f;
270		} else {
271			disk_parms->heads = *(tmp+1);
272		}
273		disk_parms->disksize = disk_parms->sectors * disk_parms->heads *
274									disk_parms->cyls;
275		return 1;
276	}
277	return 0;
278}
279#endif
280