pc98_machdep.c revision 52467
1/*
2 * Copyright (c) KATO Takenori, 1996, 1997.
3 *
4 * All rights reserved.  Unpublished rights reserved under the copyright
5 * laws of Japan.
6 *
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer as
13 *    the first lines of this file unmodified.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. The name of the author may not be used to endorse or promote products
18 *    derived from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 *
31 * $FreeBSD: head/sys/pc98/pc98/pc98_machdep.c 52467 1999-10-24 14:54:12Z nyan $
32 */
33
34#include "opt_pc98.h"
35
36#include <sys/param.h>
37#include <sys/systm.h>
38
39#include <cam/cam.h>
40#include <cam/cam_ccb.h>
41
42#include <pc98/pc98/pc98.h>
43#include <pc98/pc98/pc98_machdep.h>
44
45extern	int Maxmem;
46extern	int Maxmem_under16M;
47
48#ifdef notyet
49static	void init_cpu_accel_mem __P((void));
50#endif
51
52/*
53 * Initialize DMA controller
54 */
55void
56pc98_init_dmac(void)
57{
58	outb(0x439, (inb(0x439) & 0xfb));	/* DMA Accsess Control over 1MB */
59	outb(0x29, (0x0c | 0));				/* Bank Mode Reg. 16M mode */
60	outb(0x29, (0x0c | 1));				/* Bank Mode Reg. 16M mode */
61	outb(0x29, (0x0c | 2));				/* Bank Mode Reg. 16M mode */
62	outb(0x29, (0x0c | 3));				/* Bank Mode Reg. 16M mode */
63	outb(0x11, 0x50);
64}
65
66#ifdef EPSON_MEMWIN
67static	void init_epson_memwin __P((void));
68
69/*
70 * Disconnect phisical memory in 15-16MB region.
71 *
72 * EPSON PC-486GR, P, SR, SE, HX, HG and HA only.  Other system support
73 * this feature with software DIP switch.
74 */
75static void
76init_epson_memwin(void)
77{
78
79	if (pc98_machine_type & M_EPSON_PC98) {
80		if (Maxmem > 3840) {
81			if (Maxmem == Maxmem_under16M) {
82				Maxmem = 3840;
83				Maxmem_under16M = 3840;
84			} else if (Maxmem_under16M > 3840) {
85				Maxmem_under16M = 3840;
86			}
87		}
88
89		/* Disable 15MB-16MB caching. */
90		switch (epson_machine_id) {
91		case 0x34:	/* PC486HX */
92		case 0x35:	/* PC486HG */
93		case 0x3B:	/* PC486HA */
94			/* Cache control start. */
95			outb(0x43f, 0x42);
96			outw(0xc40, 0x0033);
97
98			/* Disable 0xF00000-0xFFFFFF. */
99			outb(0xc48, 0x49);
100			outb(0xc4c, 0x00);
101			outb(0xc48, 0x48);
102			outb(0xc4c, 0xf0);
103			outb(0xc48, 0x4d);
104			outb(0xc4c, 0x00);
105			outb(0xc48, 0x4c);
106			outb(0xc4c, 0xff);
107			outb(0xc48, 0x4f);
108			outb(0xc4c, 0x00);
109
110			/* Cache control end. */
111			outb(0x43f, 0x40);
112			break;
113
114		case 0x2B:	/* PC486GR/GF */
115		case 0x30:	/* PC486P */
116		case 0x31:	/* PC486GRSuper */
117		case 0x32:	/* PC486GR+ */
118		case 0x37:	/* PC486SE */
119		case 0x38:	/* PC486SR */
120			/* Disable 0xF00000-0xFFFFFF. */
121			outb(0x43f, 0x42);
122			outb(0x467, 0xe0);
123			outb(0x567, 0xd8);
124
125			outb(0x43f, 0x40);
126			outb(0x467, 0xe0);
127			outb(0x567, 0xe0);
128			break;
129		}
130
131		/* Disable 15MB-16MB RAM and enable memory window. */
132		outb(0x43b, inb(0x43b) & 0xfd);	/* Clear bit1. */
133	}
134}
135#endif
136
137#ifdef notyet
138static	void init_cpu_accel_mem(void);
139
140static void
141init_cpu_accel_mem(void)
142{
143	u_int target_page;
144	/*
145	 * Certain 'CPU accelerator' supports over 16MB memory on
146	 * the machines whose BIOS doesn't store true size.
147	 * To support this, we don't trust BIOS values if Maxmem < 4096.
148	 */
149	if (Maxmem < 4096) {
150		for (target_page = ptoa(4096);		/* 16MB */
151			 target_page < ptoa(32768);		/* 128MB */
152			 target_page += 256 * PAGE_SIZE	/* 1MB step */) {
153			u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem;
154
155			*(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page;
156			invltlb();
157
158			tmp = *(u_int *)CADDR1;
159			/*
160			 * Test for alternating 1's and 0's
161			 */
162			*(volatile u_int *)CADDR1 = 0xaaaaaaaa;
163			if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) {
164				page_bad = TRUE;
165			}
166			/*
167			 * Test for alternating 0's and 1's
168			 */
169			*(volatile u_int *)CADDR1 = 0x55555555;
170			if (*(volatile u_int *)CADDR1 != 0x55555555) {
171				page_bad = TRUE;
172			}
173			/*
174			 * Test for all 1's
175			 */
176			*(volatile u_int *)CADDR1 = 0xffffffff;
177			if (*(volatile u_int *)CADDR1 != 0xffffffff) {
178				page_bad = TRUE;
179			}
180			/*
181			 * Test for all 0's
182			 */
183			*(volatile u_int *)CADDR1 = 0x0;
184			if (*(volatile u_int *)CADDR1 != 0x0) {
185				/*
186				 * test of page failed
187				 */
188				page_bad = TRUE;
189			}
190			/*
191			 * Restore original value.
192			 */
193			*(u_int *)CADDR1 = tmp;
194			if (page_bad == TRUE) {
195				Maxmem = atop(target_page) + 256;
196			} else
197				break;
198		}
199		*(int *)CMAP1 = 0;
200		invltlb();
201	}
202}
203#endif
204
205/*
206 * Get physical memory size
207 */
208void
209pc98_getmemsize(void)
210{
211	unsigned char under16, over16;
212
213	/* available protected memory size under 16MB / 128KB */
214	under16 = PC98_SYSTEM_PARAMETER(0x401);
215	/* available protected memory size over 16MB / 1MB */
216	over16 = PC98_SYSTEM_PARAMETER(0x594);
217	/* add conventional memory size (1024KB / 128KB = 8) */
218	under16 += 8;
219
220	Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE;
221	Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE);
222#ifdef EPSON_MEMWIN
223	init_epson_memwin();
224#endif
225}
226
227#include "da.h"
228
229/*
230 * Read a geometry information of SCSI HDD from BIOS work area.
231 *
232 * XXX - Before reading BIOS work area, we should check whether
233 * host adapter support it.
234 */
235int
236scsi_da_bios_params(struct ccb_calc_geometry *ccg)
237{
238#if NDA > 0
239	u_char *tmp;
240	int	target;
241	int	bus;
242
243	target = ccg->ccb_h.target_id;
244	bus    = 0;  /* If your really need to know, send a PathInq CCB */
245
246	tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + target*4);
247	if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << target)&0xff)) != 0) {
248		ccg->secs_per_track = *tmp;
249		ccg->cylinders = ((*(tmp+3)<<8)|*(tmp+2))&0xfff;
250#if 0
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#endif
268		if (*(tmp+3) & 0x40) {
269			ccg->cylinders += (*(tmp+1)&0xf0)<<8;
270			ccg->heads = *(tmp+1)&0x0f;
271		} else {
272			ccg->heads = *(tmp+1);
273		}
274		return 1;
275	}
276#endif	/* NDA > 0 */
277	return 0;
278}
279