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