pc98_machdep.c revision 22263
1/* 2 * Copyright (c) KATO Takenori, 1996. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer as 9 * the first lines of this file unmodified. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <sys/param.h> 29#include <sys/systm.h> 30#include <sys/vmmeter.h> 31 32#include <scsi/scsiconf.h> 33 34#include <vm/vm.h> 35#include <vm/vm_param.h> 36#include <vm/vm_prot.h> 37#include <vm/lock.h> 38#include <vm/vm_kern.h> 39#include <vm/vm_object.h> 40#include <vm/vm_page.h> 41#include <vm/vm_map.h> 42#include <vm/vm_pager.h> 43#include <vm/vm_extern.h> 44 45#include <pc98/pc98/pc98.h> 46#include <i386/isa/isa_device.h> 47 48extern int Maxmem; 49extern int Maxmem_under16M; 50 51static void init_cpu_accel_mem __P((void)); 52void pc98_init_dmac __P((void)); 53void pc98_getmemsize __P((void)); 54 55#ifdef EPSON_MEMWIN 56static void init_epson_memwin __P((void)); 57 58static void 59init_epson_memwin(void) 60{ 61 62 if (pc98_machine_type & M_EPSON_PC98) { 63 if (Maxmem > 3840) { 64 if (Maxmem == Maxmem_under16M) { 65 Maxmem = 3840; 66 Maxmem_under16M = 3840; 67 } else if (Maxmem_under16M > 3840) { 68 Maxmem_under16M = 3840; 69 } 70 } 71 72 /* Disable 15MB-16MB caching. */ 73 switch (epson_machine_id) { 74 case 0x34: /* PC486HX */ 75 case 0x35: /* PC486HG */ 76 case 0x3B: /* PC486HA */ 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 0x2B: /* PC486GR/GF */ 98 case 0x30: /* PC486P */ 99 case 0x31: /* PC486GRSuper */ 100 case 0x32: /* PC486GR+ */ 101 case 0x37: /* PC486SE */ 102 case 0x38: /* PC486SR */ 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} 118#endif 119 120#ifdef notyet 121static void init_cpu_accel_mem(void); 122 123static void 124init_cpu_accel_mem(void) 125{ 126 u_int target_page; 127 /* 128 * Certain 'CPU accelerator' supports over 16MB memory on 129 * the machines whose BIOS doesn't store true size. 130 * To support this, we don't trust BIOS values if Maxmem < 4096. 131 */ 132 if (Maxmem < 4096) { 133 for (target_page = ptoa(4096); /* 16MB */ 134 target_page < ptoa(32768); /* 128MB */ 135 target_page += 256 * PAGE_SIZE /* 1MB step */) { 136 u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem; 137 138 *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page; 139 invltlb(); 140 141 tmp = *(u_int *)CADDR1; 142 /* 143 * Test for alternating 1's and 0's 144 */ 145 *(volatile u_int *)CADDR1 = 0xaaaaaaaa; 146 if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) { 147 page_bad = TRUE; 148 } 149 /* 150 * Test for alternating 0's and 1's 151 */ 152 *(volatile u_int *)CADDR1 = 0x55555555; 153 if (*(volatile u_int *)CADDR1 != 0x55555555) { 154 page_bad = TRUE; 155 } 156 /* 157 * Test for all 1's 158 */ 159 *(volatile u_int *)CADDR1 = 0xffffffff; 160 if (*(volatile u_int *)CADDR1 != 0xffffffff) { 161 page_bad = TRUE; 162 } 163 /* 164 * Test for all 0's 165 */ 166 *(volatile u_int *)CADDR1 = 0x0; 167 if (*(volatile u_int *)CADDR1 != 0x0) { 168 /* 169 * test of page failed 170 */ 171 page_bad = TRUE; 172 } 173 /* 174 * Restore original value. 175 */ 176 *(u_int *)CADDR1 = tmp; 177 if (page_bad == TRUE) { 178 Maxmem = atop(target_page) + 256; 179 } else 180 break; 181 } 182 *(int *)CMAP1 = 0; 183 invltlb(); 184 } 185} 186#endif 187 188void 189pc98_init_dmac(void) 190{ 191 outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */ 192 outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */ 193 outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */ 194 outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */ 195 outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ 196 outb(0x11, 0x50); /* PC98 must be 0x40 */ 197} 198 199void 200pc98_getmemsize(void) 201{ 202 unsigned char under16, over16; 203 204 /* available protected memory size under 16MB / 128KB */ 205 under16 = PC98_SYSTEM_PARAMETER(0x401); 206 /* available protected memory size over 16MB / 1MB */ 207 over16 = PC98_SYSTEM_PARAMETER(0x594); 208 /* add conventional memory size (1024KB / 128KB = 8) */ 209 under16 += 8; 210 211 Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE; 212 Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE); 213#ifdef EPSON_MEMWIN 214 init_epson_memwin(); 215#endif 216} 217 218#include "sd.h" 219 220#if NSD > 0 221/* 222 * XXX copied from sd.c. 223 */ 224struct disk_parms { 225 u_char heads; /* Number of heads */ 226 u_int16_t cyls; /* Number of cylinders */ 227 u_char sectors; /*dubious *//* Number of sectors/track */ 228 u_int16_t secsiz; /* Number of bytes/sector */ 229 u_int32_t disksize; /* total number sectors */ 230}; 231 232int sd_bios_parms __P((struct disk_parms *, struct scsi_link *)); 233 234/* 235 * Read a geometry information of SCSI HDD from BIOS work area. 236 * 237 * XXX - Before reading BIOS work area, we should check whether 238 * host adapter support it. 239 */ 240int 241sd_bios_parms(disk_parms, sc_link) 242 struct disk_parms *disk_parms; 243 struct scsi_link *sc_link; 244{ 245 u_char *tmp; 246 247 tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + sc_link->target*4); 248 if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << sc_link->target)&0xff)) != 0) { 249 disk_parms->sectors = *tmp; 250 disk_parms->cyls = ((*(tmp+3)<<8)|*(tmp+2))&0xfff; 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 if (*(tmp+3) & 0x40) { 268 disk_parms->cyls += (*(tmp+1)&0xf0)<<8; 269 disk_parms->heads = *(tmp+1)&0x0f; 270 } else { 271 disk_parms->heads = *(tmp+1); 272 } 273 disk_parms->disksize = disk_parms->sectors * disk_parms->heads * 274 disk_parms->cyls; 275 return 1; 276 } 277 return 0; 278} 279#endif 280