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