isa.c revision 294883
1250079Scarl/*- 2250079Scarl * Copyright (c) 1998 Doug Rabson 3289542Scem * All rights reserved. 4250079Scarl * 5250079Scarl * Redistribution and use in source and binary forms, with or without 6250079Scarl * modification, are permitted provided that the following conditions 7250079Scarl * are met: 8250079Scarl * 1. Redistributions of source code must retain the above copyright 9250079Scarl * notice, this list of conditions and the following disclaimer. 10250079Scarl * 2. Redistributions in binary form must reproduce the above copyright 11250079Scarl * notice, this list of conditions and the following disclaimer in the 12250079Scarl * documentation and/or other materials provided with the distribution. 13250079Scarl * 14250079Scarl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15250079Scarl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16250079Scarl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17250079Scarl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18250079Scarl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19250079Scarl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20250079Scarl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21250079Scarl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22250079Scarl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23250079Scarl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24250079Scarl * SUCH DAMAGE. 25250079Scarl */ 26250079Scarl 27250079Scarl#include <sys/cdefs.h> 28250079Scarl__FBSDID("$FreeBSD: head/sys/x86/isa/isa.c 294883 2016-01-27 02:23:54Z jhibbits $"); 29250079Scarl 30250079Scarl/*- 31250079Scarl * Modifications for Intel architecture by Garrett A. Wollman. 32250079Scarl * Copyright 1998 Massachusetts Institute of Technology 33250079Scarl * 34250079Scarl * Permission to use, copy, modify, and distribute this software and 35289774Scem * its documentation for any purpose and without fee is hereby 36250079Scarl * granted, provided that both the above copyright notice and this 37250079Scarl * permission notice appear in all copies, that both the above 38250079Scarl * copyright notice and this permission notice appear in all 39250079Scarl * supporting documentation, and that the name of M.I.T. not be used 40289774Scem * in advertising or publicity pertaining to distribution of the 41289207Scem * software without specific, written prior permission. M.I.T. makes 42250079Scarl * no representations about the suitability of this software for any 43250079Scarl * purpose. It is provided "as is" without express or implied 44250079Scarl * warranty. 45250079Scarl * 46250079Scarl * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS 47250079Scarl * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, 48250079Scarl * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 49250079Scarl * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT 50250079Scarl * SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 51250079Scarl * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 52250079Scarl * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 53250079Scarl * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 54250079Scarl * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 55250079Scarl * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 56250079Scarl * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57250079Scarl * SUCH DAMAGE. 58250079Scarl */ 59250079Scarl 60250079Scarl#include <sys/param.h> 61250079Scarl#include <sys/bus.h> 62250079Scarl#include <sys/kernel.h> 63250079Scarl#include <sys/malloc.h> 64250079Scarl#include <sys/module.h> 65289648Scem#include <machine/bus.h> 66250079Scarl#include <sys/rman.h> 67289539Scem#ifdef PC98 68289648Scem#include <sys/systm.h> 69291032Scem#endif 70250079Scarl 71250079Scarl#include <machine/resource.h> 72250079Scarl 73250079Scarl#include <isa/isavar.h> 74250079Scarl#include <isa/isa_common.h> 75289648Scem 76250079Scarlvoid 77250079Scarlisa_init(device_t dev) 78289610Scem{ 79289610Scem} 80289610Scem 81289610Scem/* 82289610Scem * This implementation simply passes the request up to the parent 83289610Scem * bus, which in our case is the special i386 nexus, substituting any 84289610Scem * configured values if the caller defaulted. We can get away with 85289610Scem * this because there is no special mapping for ISA resources on an Intel 86289610Scem * platform. When porting this code to another architecture, it may be 87289610Scem * necessary to interpose a mapping layer here. 88289610Scem */ 89289610Scemstruct resource * 90289539Scemisa_alloc_resource(device_t bus, device_t child, int type, int *rid, 91289539Scem rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 92289539Scem{ 93289539Scem /* 94289539Scem * Consider adding a resource definition. 95289539Scem */ 96289539Scem int passthrough = (device_get_parent(child) != bus); 97289539Scem int isdefault = (start == 0UL && end == ~0UL); 98255274Scarl struct isa_device* idev = DEVTOISA(child); 99255274Scarl struct resource_list *rl = &idev->id_resources; 100255274Scarl struct resource_list_entry *rle; 101255274Scarl 102250079Scarl if (!passthrough && !isdefault) { 103250079Scarl rle = resource_list_find(rl, type, *rid); 104255274Scarl if (!rle) { 105250079Scarl if (*rid < 0) 106289397Scem return 0; 107250079Scarl switch (type) { 108250079Scarl case SYS_RES_IRQ: 109250079Scarl if (*rid >= ISA_NIRQ) 110250079Scarl return 0; 111250079Scarl break; 112250079Scarl case SYS_RES_DRQ: 113250079Scarl if (*rid >= ISA_NDRQ) 114250079Scarl return 0; 115290679Scem break; 116290679Scem case SYS_RES_MEMORY: 117291280Scem if (*rid >= ISA_NMEM) 118289543Scem return 0; 119289543Scem break; 120289543Scem case SYS_RES_IOPORT: 121289543Scem if (*rid >= ISA_NPORT) 122289543Scem return 0; 123250079Scarl break; 124250079Scarl default: 125250079Scarl return 0; 126250079Scarl } 127250079Scarl resource_list_add(rl, type, *rid, start, end, count); 128250079Scarl } 129250079Scarl } 130250079Scarl 131289546Scem return resource_list_alloc(rl, bus, child, type, rid, 132250079Scarl start, end, count, flags); 133289546Scem} 134250079Scarl 135250079Scarl#ifdef PC98 136289542Scem/* 137289542Scem * Indirection support. The type of bus_space_handle_t is 138289542Scem * defined in sys/i386/include/bus_pc98.h. 139289542Scem */ 140289542Scemstruct resource * 141289542Scemisa_alloc_resourcev(device_t child, int type, int *rid, 142289542Scem bus_addr_t *res, bus_size_t count, u_int flags) 143289542Scem{ 144289542Scem struct isa_device* idev = DEVTOISA(child); 145289542Scem struct resource_list *rl = &idev->id_resources; 146289542Scem 147289542Scem device_t bus = device_get_parent(child); 148289542Scem bus_addr_t start; 149289542Scem bus_space_handle_t bh; 150289546Scem struct resource *re; 151289546Scem struct resource **bsre; 152289546Scem int i, j, k, linear_cnt, ressz, bsrid; 153289546Scem 154289546Scem start = bus_get_resource_start(child, type, *rid); 155289546Scem 156289546Scem linear_cnt = count; 157289546Scem ressz = 1; 158289546Scem for (i = 1; i < count; ++i) { 159289546Scem if (res[i] != res[i - 1] + 1) { 160289546Scem if (i < linear_cnt) 161289546Scem linear_cnt = i; 162289542Scem ++ressz; 163289542Scem } 164289542Scem } 165289542Scem 166289542Scem re = isa_alloc_resource(bus, child, type, rid, 167289542Scem start + res[0], start + res[linear_cnt - 1], 168289542Scem linear_cnt, flags); 169289542Scem if (re == NULL) 170289542Scem return NULL; 171289542Scem 172250079Scarl bsre = malloc(sizeof (struct resource *) * ressz, M_DEVBUF, M_NOWAIT); 173250079Scarl if (bsre == NULL) { 174250079Scarl resource_list_release(rl, bus, child, type, *rid, re); 175289774Scem return NULL; 176250079Scarl } 177250079Scarl bsre[0] = re; 178250079Scarl 179250079Scarl for (i = linear_cnt, k = 1; i < count; i = j, k++) { 180250079Scarl for (j = i + 1; j < count; j++) { 181250079Scarl if (res[j] != res[j - 1] + 1) 182250079Scarl break; 183250079Scarl } 184289546Scem bsrid = *rid + k; 185289546Scem bsre[k] = isa_alloc_resource(bus, child, type, &bsrid, 186289546Scem start + res[i], start + res[j - 1], j - i, flags); 187290683Scem if (bsre[k] == NULL) { 188290683Scem for (k--; k >= 0; k--) 189289546Scem resource_list_release(rl, bus, child, type, 190289546Scem *rid + k, bsre[k]); 191250079Scarl free(bsre, M_DEVBUF); 192289610Scem return NULL; 193289610Scem } 194289610Scem } 195289539Scem 196289542Scem bh = rman_get_bushandle(re); 197289542Scem bh->bsh_res = bsre; 198289542Scem bh->bsh_ressz = ressz; 199289543Scem 200289542Scem return re; 201289542Scem} 202289539Scem 203289539Scemint 204289539Scemisa_load_resourcev(struct resource *re, bus_addr_t *res, bus_size_t count) 205289539Scem{ 206289539Scem 207289542Scem return bus_space_map_load(rman_get_bustag(re), rman_get_bushandle(re), 208289546Scem count, res, 0); 209289546Scem} 210289546Scem#endif /* PC98 */ 211289546Scem 212289542Scemint 213289542Scemisa_release_resource(device_t bus, device_t child, int type, int rid, 214290686Scem struct resource *r) 215290686Scem{ 216289542Scem struct isa_device* idev = DEVTOISA(child); 217289542Scem struct resource_list *rl = &idev->id_resources; 218289542Scem#ifdef PC98 219289546Scem /* 220289542Scem * Indirection support. The type of bus_space_handle_t is 221289542Scem * defined in sys/i386/include/bus_pc98.h. 222289542Scem */ 223289542Scem int i; 224289542Scem bus_space_handle_t bh; 225289542Scem 226289542Scem if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { 227250079Scarl bh = rman_get_bushandle(r); 228250079Scarl if (bh != NULL) { 229289234Scem for (i = 1; i < bh->bsh_ressz; i++) 230289234Scem resource_list_release(rl, bus, child, type, 231289234Scem rid + i, bh->bsh_res[i]); 232289234Scem if (bh->bsh_res != NULL) 233289234Scem free(bh->bsh_res, M_DEVBUF); 234289234Scem } 235289234Scem } 236289234Scem#endif 237289234Scem return resource_list_release(rl, bus, child, type, rid, r); 238289234Scem} 239289234Scem 240289234Scem/* 241289234Scem * On this platform, isa can also attach to the legacy bus. 242289234Scem */ 243289234ScemDRIVER_MODULE(isa, legacy, isa_driver, isa_devclass, 0, 0); 244289234Scem 245289234Scem/* 246289234Scem * Attach the ISA bus to the xenpv bus in order to get syscons. 247289234Scem */ 248289234ScemDRIVER_MODULE(isa, xenpv, isa_driver, isa_devclass, 0, 0); 249255279Scarl