pc98_machdep.c revision 161129
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 161129 2006-08-09 18:25:07Z imp $ 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#include <sys/bio.h> 42#include <sys/bus.h> 43#include <sys/conf.h> 44#include <geom/geom_disk.h> 45#include <machine/md_var.h> 46#include <pc98/pc98/pc98_machdep.h> 47 48/* 49 * Initialize DMA controller 50 */ 51void 52pc98_init_dmac(void) 53{ 54 outb(0x439, (inb(0x439) & 0xfb)); /* DMA Accsess Control over 1MB */ 55 outb(0x29, (0x0c | 0)); /* Bank Mode Reg. 16M mode */ 56 outb(0x29, (0x0c | 1)); /* Bank Mode Reg. 16M mode */ 57 outb(0x29, (0x0c | 2)); /* Bank Mode Reg. 16M mode */ 58 outb(0x29, (0x0c | 3)); /* Bank Mode Reg. 16M mode */ 59 outb(0x11, 0x50); 60} 61 62#ifdef EPSON_MEMWIN 63/* 64 * Disconnect phisical memory in 15-16MB region. 65 * 66 * EPSON PC-486GR, P, SR, SE, HX, HG and HA only. Other system support 67 * this feature with software DIP switch. 68 */ 69static void 70init_epson_memwin(void) 71{ 72 /* Disable 15MB-16MB caching. */ 73 switch (epson_machine_id) { 74 case EPSON_PC486_HX: 75 case EPSON_PC486_HG: 76 case EPSON_PC486_HA: 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 EPSON_PC486_GR: 98 case EPSON_PC486_P: 99 case EPSON_PC486_GR_SUPER: 100 case EPSON_PC486_GR_PLUS: 101 case EPSON_PC486_SE: 102 case EPSON_PC486_SR: 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#endif 118 119/* 120 * Get physical memory size 121 */ 122unsigned int 123pc98_getmemsize(unsigned int *base, unsigned int *ext) 124{ 125 unsigned int under16, over16; 126 127 /* available conventional memory size */ 128 *base = ((PC98_SYSTEM_PARAMETER(0x501) & 7) + 1) * 128; 129 130 /* available protected memory size under 16MB */ 131 under16 = PC98_SYSTEM_PARAMETER(0x401) * 128 + 1024; 132#ifdef EPSON_MEMWIN 133 if (pc98_machine_type & M_EPSON_PC98) { 134 if (under16 > (15 * 1024)) 135 /* chop under16 memory to 15MB */ 136 under16 = 15 * 1024; 137 init_epson_memwin(); 138 } 139#endif 140 141 /* available protected memory size over 16MB / 1MB */ 142 over16 = PC98_SYSTEM_PARAMETER(0x594); 143 over16 += PC98_SYSTEM_PARAMETER(0x595) * 256; 144 145 if (over16 > 0) 146 *ext = (16 + over16) * 1024 - 1024; 147 else 148 *ext = under16 - 1024; 149 150 return (under16); 151} 152 153/* 154 * Read a geometry information of SCSI HDD from BIOS work area. 155 * 156 * XXX - Before reading BIOS work area, we should check whether 157 * host adapter support it. 158 */ 159int 160scsi_da_bios_params(struct ccb_calc_geometry *ccg) 161{ 162 u_char *tmp; 163 int target; 164 165 target = ccg->ccb_h.target_id; 166 tmp = (u_char *)&PC98_SYSTEM_PARAMETER(0x460 + target*4); 167 if ((PC98_SYSTEM_PARAMETER(0x482) & ((1 << target)&0xff)) != 0) { 168 ccg->secs_per_track = *tmp; 169 ccg->cylinders = ((*(tmp+3)<<8)|*(tmp+2))&0xfff; 170#if 0 171 switch (*(tmp + 3) & 0x30) { 172 case 0x00: 173 disk_parms->secsiz = 256; 174 printf("Warning!: not supported.\n"); 175 break; 176 case 0x10: 177 disk_parms->secsiz = 512; 178 break; 179 case 0x20: 180 disk_parms->secsiz = 1024; 181 break; 182 default: 183 disk_parms->secsiz = 512; 184 printf("Warning!: not supported. But force to 512\n"); 185 break; 186 } 187#endif 188 if (*(tmp+3) & 0x40) { 189 ccg->cylinders += (*(tmp+1)&0xf0)<<8; 190 ccg->heads = *(tmp+1)&0x0f; 191 } else { 192 ccg->heads = *(tmp+1); 193 } 194 return (1); 195 } 196 197 return (0); 198} 199 200/* 201 * Get the geometry of the ATA HDD from the BIOS work area. 202 * 203 * XXX for now, we hack it 204 */ 205void 206pc98_ad_firmware_geom_adjust(device_t dev, struct disk *disk) 207{ 208 off_t totsec = disk->d_mediasize / disk->d_sectorsize; 209 off_t cyl = totsec / disk->d_fwsectors / disk->d_fwheads; 210 211 /* 212 * It is impossible to have more than 65535 cylendars, so if 213 * we have more then try to adjust. This is lame, but it is 214 * only POC. 215 */ 216 if (cyl > 65355) { 217 if (totsec < 17*8*65535) { 218 disk->d_fwsectors = 17; 219 disk->d_fwheads = 8; 220 } else if (totsec < 63*16*65535) { 221 disk->d_fwsectors = 63; 222 disk->d_fwheads = 16; 223 } else if (totsec < 255*16*65535) { 224 disk->d_fwsectors = 255; 225 disk->d_fwheads = 16; 226 } else { 227 disk->d_fwsectors = 255; 228 disk->d_fwheads = 255; 229 } 230 } 231} 232