]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pc98/pc98/pc98_machdep.c
add -n option to suppress clearing the build tree and add -DNO_CLEAN
[FreeBSD/FreeBSD.git] / sys / pc98 / pc98 / pc98_machdep.c
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$
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 #include <sys/bio.h>
42 #include <sys/bus.h>
43 #include <sys/conf.h>
44 #include <geom/geom_disk.h>
45 #include <machine/md_var.h>
46 #include <pc98/pc98/pc98_machdep.h>
47
48 /*
49  * Initialize DMA controller
50  */
51 void
52 pc98_init_dmac(void)
53 {
54         outb(0x439, (inb(0x439) & 0xfb));       /* DMA Accsess Control over 1MB */
55         outb(0x29, (0x0c | 0));                         /* Bank Mode Reg. 16M mode */
56         outb(0x29, (0x0c | 1));                         /* Bank Mode Reg. 16M mode */
57         outb(0x29, (0x0c | 2));                         /* Bank Mode Reg. 16M mode */
58         outb(0x29, (0x0c | 3));                         /* Bank Mode Reg. 16M mode */
59         outb(0x11, 0x50);
60 }
61
62 #ifdef EPSON_MEMWIN
63 /*
64  * Disconnect phisical memory in 15-16MB region.
65  *
66  * EPSON PC-486GR, P, SR, SE, HX, HG and HA only.  Other system support
67  * this feature with software DIP switch.
68  */
69 static void
70 init_epson_memwin(void)
71 {
72         /* Disable 15MB-16MB caching. */
73         switch (epson_machine_id) {
74         case EPSON_PC486_HX:
75         case EPSON_PC486_HG:
76         case EPSON_PC486_HA:
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 EPSON_PC486_GR:
98         case EPSON_PC486_P:
99         case EPSON_PC486_GR_SUPER:
100         case EPSON_PC486_GR_PLUS:
101         case EPSON_PC486_SE:
102         case EPSON_PC486_SR:
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 #endif
118
119 /*
120  * Get physical memory size
121  */
122 unsigned int
123 pc98_getmemsize(unsigned int *base, unsigned int *ext)
124 {
125         unsigned int under16, over16;
126
127         /* available conventional memory size */
128         *base = ((PC98_SYSTEM_PARAMETER(0x501) & 7) + 1) * 128;
129
130         /* available protected memory size under 16MB */
131         under16 = PC98_SYSTEM_PARAMETER(0x401) * 128 + 1024;
132 #ifdef EPSON_MEMWIN
133         if (pc98_machine_type & M_EPSON_PC98) {
134                 if (under16 > (15 * 1024))
135                         /* chop under16 memory to 15MB */
136                         under16 = 15 * 1024;
137                 init_epson_memwin();
138         }
139 #endif
140
141         /* available protected memory size over 16MB / 1MB */
142         over16  = PC98_SYSTEM_PARAMETER(0x594);
143         over16 += PC98_SYSTEM_PARAMETER(0x595) * 256;
144
145         if (over16 > 0)
146                 *ext = (16 + over16) * 1024 - 1024;
147         else
148                 *ext = under16 - 1024;
149
150         return (under16);
151 }
152
153 /*
154  * Read a geometry information of SCSI HDD from BIOS work area.
155  *
156  * XXX - Before reading BIOS work area, we should check whether
157  * host adapter support it.
158  */
159 int
160 scsi_da_bios_params(struct ccb_calc_geometry *ccg)
161 {
162         u_char *tmp;
163         int     target;
164
165         target = ccg->ccb_h.target_id;
166         tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + target*4);
167         if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << target)&0xff)) != 0) {
168                 ccg->secs_per_track = *tmp;
169                 ccg->cylinders = ((*(tmp+3)<<8)|*(tmp+2))&0xfff;
170 #if 0
171                 switch (*(tmp + 3) & 0x30) {
172                 case 0x00:
173                         disk_parms->secsiz = 256;
174                         printf("Warning!: not supported.\n");
175                         break;
176                 case 0x10:
177                         disk_parms->secsiz = 512;
178                         break;
179                 case 0x20:
180                         disk_parms->secsiz = 1024;
181                         break;
182                 default:
183                         disk_parms->secsiz = 512;
184                         printf("Warning!: not supported. But force to 512\n");
185                         break;
186                 }
187 #endif
188                 if (*(tmp+3) & 0x40) {
189                         ccg->cylinders += (*(tmp+1)&0xf0)<<8;
190                         ccg->heads = *(tmp+1)&0x0f;
191                 } else {
192                         ccg->heads = *(tmp+1);
193                 }
194                 return (1);
195         }
196
197         return (0);
198 }
199
200 /*
201  * Get the geometry of the ATA HDD from the BIOS work area.
202  *
203  * XXX for now, we hack it
204  */
205 void
206 pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk)
207 {
208         off_t totsec = disk->d_mediasize / disk->d_sectorsize;
209         off_t cyl = totsec / disk->d_fwsectors / disk->d_fwheads;
210     
211         /*
212          * It is impossible to have more than 65535 cylendars, so if
213          * we have more then try to adjust.  This is lame, but it is
214          * only POC.
215          */
216         if (cyl > 65355) {
217                 if (totsec < 17*8*65535) {
218                         disk->d_fwsectors = 17;
219                         disk->d_fwheads = 8;
220                 } else if (totsec < 63*16*65535) {
221                         disk->d_fwsectors = 63;
222                         disk->d_fwheads = 16;
223                 } else if (totsec < 255*16*65535) {
224                         disk->d_fwsectors = 255;
225                         disk->d_fwheads = 16;
226                 } else {
227                         disk->d_fwsectors = 255;
228                         disk->d_fwheads = 255;
229                 }
230         }
231 }