cia_pci.c revision 1.3
1/* $OpenBSD: cia_pci.c,v 1.3 1996/07/29 23:00:21 niklas Exp $ */ 2/* $NetBSD: cia_pci.c,v 1.2 1996/04/12 23:37:10 cgd Exp $ */ 3 4/* 5 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 6 * All rights reserved. 7 * 8 * Author: Chris G. Demetriou 9 * 10 * Permission to use, copy, modify and distribute this software and 11 * its documentation is hereby granted, provided that both the copyright 12 * notice and this permission notice appear in all copies of the 13 * software, derivative works or modified versions, and any portions 14 * thereof, and that both notices appear in supporting documentation. 15 * 16 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 17 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 18 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 19 * 20 * Carnegie Mellon requests users of this software to return to 21 * 22 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 23 * School of Computer Science 24 * Carnegie Mellon University 25 * Pittsburgh PA 15213-3890 26 * 27 * any improvements or extensions that they make and grant Carnegie the 28 * rights to redistribute these changes. 29 */ 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/kernel.h> 34#include <sys/device.h> 35#include <vm/vm.h> 36 37#include <dev/pci/pcireg.h> 38#include <dev/pci/pcivar.h> 39#include <alpha/pci/ciareg.h> 40#include <alpha/pci/ciavar.h> 41 42void cia_attach_hook __P((struct device *, struct device *, 43 struct pcibus_attach_args *)); 44int cia_bus_maxdevs __P((void *, int)); 45pcitag_t cia_make_tag __P((void *, int, int, int)); 46void cia_decompose_tag __P((void *, pcitag_t, int *, int *, 47 int *)); 48pcireg_t cia_conf_read __P((void *, pcitag_t, int)); 49void cia_conf_write __P((void *, pcitag_t, int, pcireg_t)); 50 51void 52cia_pci_init(pc, v) 53 pci_chipset_tag_t pc; 54 void *v; 55{ 56 57 pc->pc_conf_v = v; 58 pc->pc_attach_hook = cia_attach_hook; 59 pc->pc_bus_maxdevs = cia_bus_maxdevs; 60 pc->pc_make_tag = cia_make_tag; 61 pc->pc_decompose_tag = cia_decompose_tag; 62 pc->pc_conf_read = cia_conf_read; 63 pc->pc_conf_write = cia_conf_write; 64} 65 66void 67cia_attach_hook(parent, self, pba) 68 struct device *parent, *self; 69 struct pcibus_attach_args *pba; 70{ 71} 72 73int 74cia_bus_maxdevs(cpv, busno) 75 void *cpv; 76 int busno; 77{ 78 79 return 32; 80} 81 82pcitag_t 83cia_make_tag(cpv, b, d, f) 84 void *cpv; 85 int b, d, f; 86{ 87 88 return (b << 16) | (d << 11) | (f << 8); 89} 90 91void 92cia_decompose_tag(cpv, tag, bp, dp, fp) 93 void *cpv; 94 pcitag_t tag; 95 int *bp, *dp, *fp; 96{ 97 98 if (bp != NULL) 99 *bp = (tag >> 16) & 0xff; 100 if (dp != NULL) 101 *dp = (tag >> 11) & 0x1f; 102 if (fp != NULL) 103 *fp = (tag >> 8) & 0x7; 104} 105 106pcireg_t 107cia_conf_read(cpv, tag, offset) 108 void *cpv; 109 pcitag_t tag; 110 int offset; 111{ 112 struct cia_config *ccp = cpv; 113 pcireg_t *datap, data; 114 int s, secondary, ba; 115 int32_t old_haxr2; /* XXX */ 116 117 /* secondary if bus # != 0 */ 118 pci_decompose_tag(&ccp->cc_pc, tag, &secondary, 0, 0); 119 if (secondary) { 120 s = splhigh(); 121 old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */ 122 wbflush(); 123 REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */ 124 wbflush(); 125 } 126 127 datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF | 128 tag << 5UL | /* XXX */ 129 (offset & ~0x03) << 5 | /* XXX */ 130 0 << 5 | /* XXX */ 131 0x3 << 3); /* XXX */ 132 data = (pcireg_t)-1; 133 if (!(ba = badaddr(datap, sizeof *datap))) 134 data = *datap; 135 136 if (secondary) { 137 wbflush(); 138 REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */ 139 wbflush(); 140 splx(s); 141 } 142 143#if 0 144 printf("cia_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p%s\n", tag, reg, 145 data, datap, ba ? " (badaddr)" : ""); 146#endif 147 148 return data; 149} 150 151void 152cia_conf_write(cpv, tag, offset, data) 153 void *cpv; 154 pcitag_t tag; 155 int offset; 156 pcireg_t data; 157{ 158 struct cia_config *ccp = cpv; 159 pcireg_t *datap; 160 int s, secondary; 161 int32_t old_haxr2; /* XXX */ 162 163 /* secondary if bus # != 0 */ 164 pci_decompose_tag(&ccp->cc_pc, tag, &secondary, 0, 0); 165 if (secondary) { 166 s = splhigh(); 167 old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */ 168 wbflush(); 169 REGVAL(CIA_CSRS + 0x480) = old_haxr2 | 0x1; /* XXX */ 170 wbflush(); 171 } 172 173 datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF | 174 tag << 5UL | /* XXX */ 175 (offset & ~0x03) << 5 | /* XXX */ 176 0 << 5 | /* XXX */ 177 0x3 << 3); /* XXX */ 178 *datap = data; 179 180 if (secondary) { 181 wbflush(); 182 REGVAL(CIA_CSRS + 0x480) = old_haxr2; /* XXX */ 183 wbflush(); 184 splx(s); 185 } 186 187#if 0 188 printf("cia_conf_write: tag 0x%lx, reg 0x%lx -> 0x%x @ %p\n", tag, 189 reg, data, datap); 190#endif 191} 192