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