1*c88420b3Sdmick /* 2*c88420b3Sdmick * CDDL HEADER START 3*c88420b3Sdmick * 4*c88420b3Sdmick * The contents of this file are subject to the terms of the 5*c88420b3Sdmick * Common Development and Distribution License, Version 1.0 only 6*c88420b3Sdmick * (the "License"). You may not use this file except in compliance 7*c88420b3Sdmick * with the License. 8*c88420b3Sdmick * 9*c88420b3Sdmick * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*c88420b3Sdmick * or http://www.opensolaris.org/os/licensing. 11*c88420b3Sdmick * See the License for the specific language governing permissions 12*c88420b3Sdmick * and limitations under the License. 13*c88420b3Sdmick * 14*c88420b3Sdmick * When distributing Covered Code, include this CDDL HEADER in each 15*c88420b3Sdmick * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*c88420b3Sdmick * If applicable, add the following below this CDDL HEADER, with the 17*c88420b3Sdmick * fields enclosed by brackets "[]" replaced with your own identifying 18*c88420b3Sdmick * information: Portions Copyright [yyyy] [name of copyright owner] 19*c88420b3Sdmick * 20*c88420b3Sdmick * CDDL HEADER END 21*c88420b3Sdmick */ 22*c88420b3Sdmick /* 23*c88420b3Sdmick * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*c88420b3Sdmick * Use is subject to license terms. 25*c88420b3Sdmick */ 26*c88420b3Sdmick 27*c88420b3Sdmick #pragma ident "%Z%%M% %I% %E% SMI" 28*c88420b3Sdmick 29*c88420b3Sdmick /* 30*c88420b3Sdmick * PCI Mechanism 2 primitives 31*c88420b3Sdmick */ 32*c88420b3Sdmick 33*c88420b3Sdmick #include <sys/types.h> 34*c88420b3Sdmick #include <sys/sunddi.h> 35*c88420b3Sdmick #include <sys/pci_impl.h> 36*c88420b3Sdmick #include <sys/pci_cfgspace_impl.h> 37*c88420b3Sdmick 38*c88420b3Sdmick /* 39*c88420b3Sdmick * The "mechanism 2" interface only has 4 bits for device number. To 40*c88420b3Sdmick * hide this implementation detail, we return all ones for accesses to 41*c88420b3Sdmick * devices 16..31. 42*c88420b3Sdmick */ 43*c88420b3Sdmick #define PCI_MAX_DEVS_2 16 44*c88420b3Sdmick 45*c88420b3Sdmick /* 46*c88420b3Sdmick * the PCI LOCAL BUS SPECIFICATION 2.0 does not say that you need to 47*c88420b3Sdmick * save the value of the register and restore them. The Intel chip 48*c88420b3Sdmick * set documentation indicates that you should. 49*c88420b3Sdmick */ 50*c88420b3Sdmick static uint8_t 51*c88420b3Sdmick pci_mech2_config_enable(uchar_t bus, uchar_t function) 52*c88420b3Sdmick { 53*c88420b3Sdmick uint8_t old; 54*c88420b3Sdmick 55*c88420b3Sdmick mutex_enter(&pcicfg_mutex); 56*c88420b3Sdmick old = inb(PCI_CSE_PORT); 57*c88420b3Sdmick 58*c88420b3Sdmick outb(PCI_CSE_PORT, 59*c88420b3Sdmick PCI_MECH2_CONFIG_ENABLE | ((function & PCI_FUNC_MASK) << 1)); 60*c88420b3Sdmick outb(PCI_FORW_PORT, bus); 61*c88420b3Sdmick 62*c88420b3Sdmick return (old); 63*c88420b3Sdmick } 64*c88420b3Sdmick 65*c88420b3Sdmick static void 66*c88420b3Sdmick pci_mech2_config_restore(uint8_t oldstatus) 67*c88420b3Sdmick { 68*c88420b3Sdmick outb(PCI_CSE_PORT, oldstatus); 69*c88420b3Sdmick mutex_exit(&pcicfg_mutex); 70*c88420b3Sdmick } 71*c88420b3Sdmick 72*c88420b3Sdmick uint8_t 73*c88420b3Sdmick pci_mech2_getb(int bus, int device, int function, int reg) 74*c88420b3Sdmick { 75*c88420b3Sdmick uint8_t tmp; 76*c88420b3Sdmick uint8_t val; 77*c88420b3Sdmick 78*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 79*c88420b3Sdmick return (0xff); 80*c88420b3Sdmick 81*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 82*c88420b3Sdmick val = inb(PCI_CADDR2(device, reg)); 83*c88420b3Sdmick pci_mech2_config_restore(tmp); 84*c88420b3Sdmick 85*c88420b3Sdmick return (val); 86*c88420b3Sdmick } 87*c88420b3Sdmick 88*c88420b3Sdmick uint16_t 89*c88420b3Sdmick pci_mech2_getw(int bus, int device, int function, int reg) 90*c88420b3Sdmick { 91*c88420b3Sdmick uint8_t tmp; 92*c88420b3Sdmick uint16_t val; 93*c88420b3Sdmick 94*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 95*c88420b3Sdmick return (0xffff); 96*c88420b3Sdmick 97*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 98*c88420b3Sdmick val = inw(PCI_CADDR2(device, reg)); 99*c88420b3Sdmick pci_mech2_config_restore(tmp); 100*c88420b3Sdmick 101*c88420b3Sdmick return (val); 102*c88420b3Sdmick } 103*c88420b3Sdmick 104*c88420b3Sdmick uint32_t 105*c88420b3Sdmick pci_mech2_getl(int bus, int device, int function, int reg) 106*c88420b3Sdmick { 107*c88420b3Sdmick uint8_t tmp; 108*c88420b3Sdmick uint32_t val; 109*c88420b3Sdmick 110*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 111*c88420b3Sdmick return (0xffffffffu); 112*c88420b3Sdmick 113*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 114*c88420b3Sdmick val = inl(PCI_CADDR2(device, reg)); 115*c88420b3Sdmick pci_mech2_config_restore(tmp); 116*c88420b3Sdmick 117*c88420b3Sdmick return (val); 118*c88420b3Sdmick } 119*c88420b3Sdmick 120*c88420b3Sdmick void 121*c88420b3Sdmick pci_mech2_putb(int bus, int device, int function, int reg, uint8_t val) 122*c88420b3Sdmick { 123*c88420b3Sdmick uint8_t tmp; 124*c88420b3Sdmick 125*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 126*c88420b3Sdmick return; 127*c88420b3Sdmick 128*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 129*c88420b3Sdmick outb(PCI_CADDR2(device, reg), val); 130*c88420b3Sdmick pci_mech2_config_restore(tmp); 131*c88420b3Sdmick } 132*c88420b3Sdmick 133*c88420b3Sdmick void 134*c88420b3Sdmick pci_mech2_putw(int bus, int device, int function, int reg, uint16_t val) 135*c88420b3Sdmick { 136*c88420b3Sdmick uint8_t tmp; 137*c88420b3Sdmick 138*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 139*c88420b3Sdmick return; 140*c88420b3Sdmick 141*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 142*c88420b3Sdmick outw(PCI_CADDR2(device, reg), val); 143*c88420b3Sdmick pci_mech2_config_restore(tmp); 144*c88420b3Sdmick } 145*c88420b3Sdmick 146*c88420b3Sdmick void 147*c88420b3Sdmick pci_mech2_putl(int bus, int device, int function, int reg, uint32_t val) 148*c88420b3Sdmick { 149*c88420b3Sdmick uint8_t tmp; 150*c88420b3Sdmick 151*c88420b3Sdmick if (device >= PCI_MAX_DEVS_2) 152*c88420b3Sdmick return; 153*c88420b3Sdmick 154*c88420b3Sdmick tmp = pci_mech2_config_enable(bus, function); 155*c88420b3Sdmick outl(PCI_CADDR2(device, reg), val); 156*c88420b3Sdmick pci_mech2_config_restore(tmp); 157*c88420b3Sdmick } 158