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