pc98_machdep.c revision 33715
1119815Smarcel/* 2119815Smarcel * Copyright (c) KATO Takenori, 1996, 1997. 3119815Smarcel * 4119815Smarcel * All rights reserved. Unpublished rights reserved under the copyright 5119815Smarcel * laws of Japan. 6119815Smarcel * 7119815Smarcel * 8119815Smarcel * Redistribution and use in source and binary forms, with or without 9119815Smarcel * modification, are permitted provided that the following conditions 10119815Smarcel * are met: 11119815Smarcel * 1. Redistributions of source code must retain the above copyright 12119815Smarcel * notice, this list of conditions and the following disclaimer as 13119815Smarcel * the first lines of this file unmodified. 14119815Smarcel * 2. Redistributions in binary form must reproduce the above copyright 15119815Smarcel * notice, this list of conditions and the following disclaimer in the 16119815Smarcel * documentation and/or other materials provided with the distribution. 17119815Smarcel * 3. The name of the author may not be used to endorse or promote products 18119815Smarcel * derived from this software without specific prior written permission. 19119815Smarcel * 20119815Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21119815Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22119815Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23119815Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24119815Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25119815Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26119815Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27119815Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28119815Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29119815Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30119815Smarcel */ 31119815Smarcel 32119815Smarcel#include "opt_pc98.h" 33119815Smarcel 34119815Smarcel#include <sys/param.h> 35119815Smarcel#include <sys/systm.h> 36119815Smarcel 37119815Smarcel#include <scsi/scsiconf.h> 38119815Smarcel 39119815Smarcel#include <pc98/pc98/pc98.h> 40119815Smarcel#include <pc98/pc98/pc98_machdep.h> 41119815Smarcel 42122466Sjakeextern int Maxmem; 43122466Sjakeextern int Maxmem_under16M; 44119815Smarcel 45119815Smarcel#ifdef notyet 46119815Smarcelstatic void init_cpu_accel_mem __P((void)); 47119815Smarcel#endif 48119815Smarcel 49119815Smarcel/* 50119815Smarcel * Initialize DMA controller 51119815Smarcel */ 52119815Smarcelvoid 53119815Smarcelpc98_init_dmac(void) 54119815Smarcel{ 55119815Smarcel outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */ 56119815Smarcel outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */ 57119815Smarcel outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */ 58119815Smarcel outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */ 59119815Smarcel outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ 60120452Smarcel outb(0x11, 0x50); 61119815Smarcel} 62119815Smarcel 63119815Smarcel#ifdef EPSON_MEMWIN 64119866Smarcelstatic void init_epson_memwin __P((void)); 65119866Smarcel 66119866Smarcel/* 67119866Smarcel * Disconnect phisical memory in 15-16MB region. 68119866Smarcel * 69119866Smarcel * EPSON PC-486GR, P, SR, SE, HX, HG and HA only. Other system support 70122466Sjake * this feature with software DIP switch. 71122466Sjake */ 72122466Sjakestatic void 73122466Sjakeinit_epson_memwin(void) 74122466Sjake{ 75122466Sjake 76122466Sjake if (pc98_machine_type & M_EPSON_PC98) { 77122466Sjake if (Maxmem > 3840) { 78122466Sjake if (Maxmem == Maxmem_under16M) { 79122466Sjake Maxmem = 3840; 80122466Sjake Maxmem_under16M = 3840; 81122466Sjake } else if (Maxmem_under16M > 3840) { 82122466Sjake Maxmem_under16M = 3840; 83122466Sjake } 84122466Sjake } 85122466Sjake 86122466Sjake /* Disable 15MB-16MB caching. */ 87122466Sjake switch (epson_machine_id) { 88122466Sjake case 0x34: /* PC486HX */ 89119866Smarcel case 0x35: /* PC486HG */ 90119815Smarcel case 0x3B: /* PC486HA */ 91119815Smarcel /* Cache control start. */ 92120009Stmm outb(0x43f, 0x42); 93119815Smarcel outw(0xc40, 0x0033); 94119815Smarcel 95120452Smarcel /* Disable 0xF00000-0xFFFFFF. */ 96119815Smarcel outb(0xc48, 0x49); 97119815Smarcel outb(0xc4c, 0x00); 98119815Smarcel outb(0xc48, 0x48); 99119815Smarcel outb(0xc4c, 0xf0); 100119815Smarcel outb(0xc48, 0x4d); 101119815Smarcel outb(0xc4c, 0x00); 102119815Smarcel outb(0xc48, 0x4c); 103119815Smarcel outb(0xc4c, 0xff); 104119815Smarcel outb(0xc48, 0x4f); 105119815Smarcel outb(0xc4c, 0x00); 106119815Smarcel 107119815Smarcel /* Cache control end. */ 108119815Smarcel outb(0x43f, 0x40); 109119815Smarcel break; 110122466Sjake 111122466Sjake case 0x2B: /* PC486GR/GF */ 112122466Sjake case 0x30: /* PC486P */ 113122466Sjake case 0x31: /* PC486GRSuper */ 114119815Smarcel case 0x32: /* PC486GR+ */ 115122466Sjake case 0x37: /* PC486SE */ 116122466Sjake case 0x38: /* PC486SR */ 117122466Sjake /* Disable 0xF00000-0xFFFFFF. */ 118122466Sjake outb(0x43f, 0x42); 119122466Sjake outb(0x467, 0xe0); 120122466Sjake outb(0x567, 0xd8); 121119815Smarcel 122119815Smarcel outb(0x43f, 0x40); 123119815Smarcel outb(0x467, 0xe0); 124119815Smarcel outb(0x567, 0xe0); 125119815Smarcel break; 126119815Smarcel } 127119815Smarcel 128122466Sjake /* Disable 15MB-16MB RAM and enable memory window. */ 129122466Sjake outb(0x43b, inb(0x43b) & 0xfd); /* Clear bit1. */ 130122466Sjake } 131119815Smarcel} 132119815Smarcel#endif 133119815Smarcel 134119815Smarcel#ifdef notyet 135119815Smarcelstatic void init_cpu_accel_mem(void); 136119815Smarcel 137119815Smarcelstatic void 138119815Smarcelinit_cpu_accel_mem(void) 139119815Smarcel{ 140119815Smarcel u_int target_page; 141120009Stmm /* 142120009Stmm * Certain 'CPU accelerator' supports over 16MB memory on 143119815Smarcel * the machines whose BIOS doesn't store true size. 144119815Smarcel * To support this, we don't trust BIOS values if Maxmem < 4096. 145119815Smarcel */ 146119815Smarcel if (Maxmem < 4096) { 147120452Smarcel for (target_page = ptoa(4096); /* 16MB */ 148120452Smarcel target_page < ptoa(32768); /* 128MB */ 149119815Smarcel target_page += 256 * PAGE_SIZE /* 1MB step */) { 150119815Smarcel u_int tmp, page_bad = FALSE, OrigMaxmem = Maxmem; 151120452Smarcel 152119815Smarcel *(int *)CMAP1 = PG_V | PG_RW | PG_N | target_page; 153120452Smarcel invltlb(); 154120009Stmm 155120452Smarcel tmp = *(u_int *)CADDR1; 156119815Smarcel /* 157120452Smarcel * Test for alternating 1's and 0's 158120452Smarcel */ 159119815Smarcel *(volatile u_int *)CADDR1 = 0xaaaaaaaa; 160119815Smarcel if (*(volatile u_int *)CADDR1 != 0xaaaaaaaa) { 161119815Smarcel page_bad = TRUE; 162119815Smarcel } 163119815Smarcel /* 164119815Smarcel * Test for alternating 0's and 1's 165119815Smarcel */ 166120545Sjake *(volatile u_int *)CADDR1 = 0x55555555; 167120545Sjake if (*(volatile u_int *)CADDR1 != 0x55555555) { 168120545Sjake page_bad = TRUE; 169120545Sjake } 170119815Smarcel /* 171119815Smarcel * Test for all 1's 172119815Smarcel */ 173119815Smarcel *(volatile u_int *)CADDR1 = 0xffffffff; 174119815Smarcel if (*(volatile u_int *)CADDR1 != 0xffffffff) { 175119815Smarcel page_bad = TRUE; 176119815Smarcel } 177119815Smarcel /* 178119815Smarcel * Test for all 0's 179119815Smarcel */ 180119815Smarcel *(volatile u_int *)CADDR1 = 0x0; 181119815Smarcel if (*(volatile u_int *)CADDR1 != 0x0) { 182119815Smarcel /* 183119815Smarcel * test of page failed 184119815Smarcel */ 185119815Smarcel page_bad = TRUE; 186 } 187 /* 188 * Restore original value. 189 */ 190 *(u_int *)CADDR1 = tmp; 191 if (page_bad == TRUE) { 192 Maxmem = atop(target_page) + 256; 193 } else 194 break; 195 } 196 *(int *)CMAP1 = 0; 197 invltlb(); 198 } 199} 200#endif 201 202/* 203 * Get physical memory size 204 */ 205void 206pc98_getmemsize(void) 207{ 208 unsigned char under16, over16; 209 210 /* available protected memory size under 16MB / 128KB */ 211 under16 = PC98_SYSTEM_PARAMETER(0x401); 212 /* available protected memory size over 16MB / 1MB */ 213 over16 = PC98_SYSTEM_PARAMETER(0x594); 214 /* add conventional memory size (1024KB / 128KB = 8) */ 215 under16 += 8; 216 217 Maxmem = Maxmem_under16M = under16 * 128 * 1024 / PAGE_SIZE; 218 Maxmem += (over16 * 1024 * 1024 / PAGE_SIZE); 219#ifdef EPSON_MEMWIN 220 init_epson_memwin(); 221#endif 222} 223 224#include "sd.h" 225 226#if NSD > 0 227/* 228 * XXX copied from sd.c. 229 */ 230struct disk_parms { 231 u_char heads; /* Number of heads */ 232 u_int16_t cyls; /* Number of cylinders */ 233 u_char sectors; /*dubious *//* Number of sectors/track */ 234 u_int16_t secsiz; /* Number of bytes/sector */ 235 u_int32_t disksize; /* total number sectors */ 236}; 237 238/* 239 * Read a geometry information of SCSI HDD from BIOS work area. 240 * 241 * XXX - Before reading BIOS work area, we should check whether 242 * host adapter support it. 243 */ 244int 245sd_bios_parms(disk_parms, sc_link) 246 struct disk_parms *disk_parms; 247 struct scsi_link *sc_link; 248{ 249 u_char *tmp; 250 251 tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + sc_link->target*4); 252 if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << sc_link->target)&0xff)) != 0) { 253 disk_parms->sectors = *tmp; 254 disk_parms->cyls = ((*(tmp+3)<<8)|*(tmp+2))&0xfff; 255 switch (*(tmp + 3) & 0x30) { 256 case 0x00: 257 disk_parms->secsiz = 256; 258 printf("Warning!: not supported.\n"); 259 break; 260 case 0x10: 261 disk_parms->secsiz = 512; 262 break; 263 case 0x20: 264 disk_parms->secsiz = 1024; 265 break; 266 default: 267 disk_parms->secsiz = 512; 268 printf("Warning!: not supported. But force to 512\n"); 269 break; 270 } 271 if (*(tmp+3) & 0x40) { 272 disk_parms->cyls += (*(tmp+1)&0xf0)<<8; 273 disk_parms->heads = *(tmp+1)&0x0f; 274 } else { 275 disk_parms->heads = *(tmp+1); 276 } 277 disk_parms->disksize = disk_parms->sectors * disk_parms->heads * 278 disk_parms->cyls; 279 return 1; 280 } 281 return 0; 282} 283#endif 284