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