Home | History | Annotate | Line # | Download | only in boot
      1  1.6  riastrad /*	$NetBSD: pci.c,v 1.6 2022/02/16 23:49:26 riastradh Exp $	*/
      2  1.1  sakamoto 
      3  1.5  kiyohara /*
      4  1.5  kiyohara  * Copyright (C) 1995-1997 Gary Thomas (gdt (at) linuxppc.org)
      5  1.1  sakamoto  * All rights reserved.
      6  1.1  sakamoto  *
      7  1.5  kiyohara  * Adapted from a program by:
      8  1.5  kiyohara  *                                      Steve Sellgren
      9  1.5  kiyohara  *                                      San Francisco Indigo Company
     10  1.5  kiyohara  *                                      sfindigo!sellgren (at) uunet.uu.net
     11  1.5  kiyohara  * Adapted for Moto boxes by:
     12  1.5  kiyohara  *                                      Pat Kane & Mark Scott, 1996
     13  1.5  kiyohara  * Fixed for IBM/PowerStack II          Pat Kane 1997
     14  1.1  sakamoto  *
     15  1.1  sakamoto  * Redistribution and use in source and binary forms, with or without
     16  1.1  sakamoto  * modification, are permitted provided that the following conditions
     17  1.1  sakamoto  * are met:
     18  1.1  sakamoto  * 1. Redistributions of source code must retain the above copyright
     19  1.1  sakamoto  *    notice, this list of conditions and the following disclaimer.
     20  1.1  sakamoto  * 2. Redistributions in binary form must reproduce the above copyright
     21  1.1  sakamoto  *    notice, this list of conditions and the following disclaimer in the
     22  1.1  sakamoto  *    documentation and/or other materials provided with the distribution.
     23  1.1  sakamoto  * 3. All advertising materials mentioning features or use of this software
     24  1.1  sakamoto  *    must display the following acknowledgement:
     25  1.5  kiyohara  *      This product includes software developed by Gary Thomas.
     26  1.5  kiyohara  * 4. The name of the author may not be used to endorse or promote products
     27  1.5  kiyohara  *    derived from this software without specific prior written permission.
     28  1.1  sakamoto  *
     29  1.5  kiyohara  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     30  1.5  kiyohara  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     31  1.5  kiyohara  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     32  1.5  kiyohara  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     33  1.5  kiyohara  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     34  1.5  kiyohara  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     35  1.5  kiyohara  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     36  1.5  kiyohara  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     37  1.5  kiyohara  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     38  1.5  kiyohara  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     39  1.1  sakamoto  */
     40  1.1  sakamoto 
     41  1.5  kiyohara #include <lib/libsa/stand.h>
     42  1.5  kiyohara #include <sys/bswap.h>
     43  1.1  sakamoto #include <dev/pci/pcireg.h>
     44  1.5  kiyohara #include "boot.h"
     45  1.1  sakamoto 
     46  1.5  kiyohara #define NSLOTS 5
     47  1.5  kiyohara #define NPCIREGS  10
     48  1.1  sakamoto 
     49  1.5  kiyohara 
     50  1.5  kiyohara /*
     51  1.5  kiyohara  * should use devfunc number/indirect method to be totally safe on
     52  1.5  kiyohara  * all machines, this works for now on 3 slot Moto boxes
     53  1.5  kiyohara  */
     54  1.5  kiyohara 
     55  1.5  kiyohara #define PCI_CONFIG_SPACE_BASE	0x80800000
     56  1.5  kiyohara #define PCI_CONFIG_SPACE(d, f)	\
     57  1.5  kiyohara 		(u_long *)(PCI_CONFIG_SPACE_BASE | (1 << (d)) | ((f) << 8))
     58  1.5  kiyohara 
     59  1.5  kiyohara struct PCI_ConfigInfo {
     60  1.5  kiyohara 	u_long *config_addr;
     61  1.5  kiyohara 	u_long regs[NPCIREGS];
     62  1.5  kiyohara } PCI_slots [NSLOTS] = {
     63  1.5  kiyohara 	{ PCI_CONFIG_SPACE(11, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
     64  1.5  kiyohara 	{ PCI_CONFIG_SPACE(12, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
     65  1.5  kiyohara 	{ PCI_CONFIG_SPACE(13, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
     66  1.5  kiyohara 	{ PCI_CONFIG_SPACE(14, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
     67  1.5  kiyohara 	{ PCI_CONFIG_SPACE(15, 0), { 0xDE, 0xAD, 0xBE, 0xEF } },
     68  1.5  kiyohara };
     69  1.5  kiyohara 
     70  1.5  kiyohara 
     71  1.5  kiyohara #define DEVID		(PCI_ID_REG >> 2)
     72  1.5  kiyohara #define CMD		(PCI_COMMAND_STATUS_REG >> 2)
     73  1.5  kiyohara #define CLASS		(PCI_CLASS_REG >> 2)
     74  1.5  kiyohara #define BAR_BASE	(PCI_MAPREG_START >> 2)
     75  1.5  kiyohara 
     76  1.5  kiyohara /*
     77  1.5  kiyohara  * The following code modifies the PCI Command register
     78  1.5  kiyohara  * to enable memory and I/O accesses.
     79  1.5  kiyohara  */
     80  1.5  kiyohara void
     81  1.5  kiyohara enablePCI(int slot, int io, int mem, int master)
     82  1.5  kiyohara {
     83  1.5  kiyohara 	volatile u_char *ppci;
     84  1.5  kiyohara 	u_char enable = 0;
     85  1.5  kiyohara 
     86  1.5  kiyohara 	if (io)
     87  1.5  kiyohara 		enable |= PCI_COMMAND_IO_ENABLE;
     88  1.5  kiyohara 	if (mem)
     89  1.5  kiyohara 		enable |= PCI_COMMAND_MEM_ENABLE;
     90  1.5  kiyohara 	if (master)
     91  1.5  kiyohara 		enable |= PCI_COMMAND_MASTER_ENABLE;
     92  1.5  kiyohara 
     93  1.5  kiyohara 	ppci = (u_char *)&PCI_slots[slot].config_addr[CMD];
     94  1.5  kiyohara 	*ppci = enable;
     95  1.6  riastrad 	__asm volatile("eieio" ::: "memory");
     96  1.5  kiyohara }
     97  1.5  kiyohara 
     98  1.5  kiyohara void
     99  1.5  kiyohara scanPCI(void)
    100  1.1  sakamoto {
    101  1.5  kiyohara 	struct PCI_ConfigInfo *pslot;
    102  1.5  kiyohara 	int slt, r;
    103  1.5  kiyohara 
    104  1.5  kiyohara 	for (slt = 0; slt < NSLOTS; slt++) {
    105  1.5  kiyohara 		pslot = &PCI_slots[slt];
    106  1.5  kiyohara 		for (r = 0; r < NPCIREGS; r++)
    107  1.5  kiyohara 			pslot->regs[r] = bswap32(pslot->config_addr[r]);
    108  1.5  kiyohara 	}
    109  1.5  kiyohara }
    110  1.5  kiyohara 
    111  1.5  kiyohara int
    112  1.5  kiyohara findPCIVga(void)
    113  1.5  kiyohara {
    114  1.5  kiyohara 	struct PCI_ConfigInfo *pslot;
    115  1.5  kiyohara 	int theSlot = -1;
    116  1.5  kiyohara 	int highVgaSlot = -1;
    117  1.5  kiyohara 	int slt;
    118  1.5  kiyohara 
    119  1.5  kiyohara 	for (slt = 0; slt < NSLOTS; slt++) {
    120  1.5  kiyohara 		pslot = &PCI_slots[slt];
    121  1.5  kiyohara 		if (pslot->regs[DEVID] != 0xffffffff) {	/* card in slot ? */
    122  1.5  kiyohara 			if (PCI_CLASS(pslot->regs[CLASS]) ==
    123  1.5  kiyohara 			    PCI_CLASS_DISPLAY) {
    124  1.5  kiyohara 				highVgaSlot = slt;
    125  1.5  kiyohara 				if ((pslot->regs[CMD] & 0x03)) { /* did firmware enable it ? */
    126  1.5  kiyohara 					theSlot = slt;
    127  1.5  kiyohara 				}
    128  1.5  kiyohara 			}
    129  1.5  kiyohara 		}
    130  1.5  kiyohara 	}
    131  1.5  kiyohara 	if (theSlot == -1)
    132  1.5  kiyohara 		theSlot = highVgaSlot;
    133  1.1  sakamoto 
    134  1.5  kiyohara 	return theSlot;
    135  1.1  sakamoto }
    136  1.1  sakamoto 
    137  1.5  kiyohara int
    138  1.5  kiyohara PCISlotnum(u_int bus, u_int dev, u_int func)
    139  1.1  sakamoto {
    140  1.5  kiyohara 	u_long *tag;
    141  1.5  kiyohara 	int i;
    142  1.1  sakamoto 
    143  1.5  kiyohara 	if (bus != 0 ||
    144  1.5  kiyohara 	    dev < 11 || dev > 15 ||
    145  1.5  kiyohara 	    func > 7)
    146  1.5  kiyohara 		return -1;
    147  1.5  kiyohara 
    148  1.5  kiyohara 	tag = PCI_CONFIG_SPACE(dev, func);
    149  1.5  kiyohara 	for (i = 0; i < sizeof(PCI_slots) / sizeof(struct PCI_ConfigInfo); i++)
    150  1.5  kiyohara 		if (tag == PCI_slots[i].config_addr)
    151  1.5  kiyohara 			return i;
    152  1.5  kiyohara 	return -1;
    153  1.1  sakamoto }
    154  1.1  sakamoto 
    155  1.5  kiyohara /* return Vendor ID of card in the slot */
    156  1.5  kiyohara int
    157  1.5  kiyohara PCIVendor(int slotnum)
    158  1.1  sakamoto {
    159  1.5  kiyohara 	struct PCI_ConfigInfo *pslot;
    160  1.1  sakamoto 
    161  1.5  kiyohara 	pslot = &PCI_slots[slotnum];
    162  1.1  sakamoto 
    163  1.5  kiyohara 	return pslot->regs[DEVID] & 0xffff;
    164  1.5  kiyohara }
    165  1.1  sakamoto 
    166  1.5  kiyohara /* return mapped address for I/O or Memory */
    167  1.5  kiyohara u_long
    168  1.5  kiyohara PCIAddress(int slotnum, u_int bar, int type)
    169  1.5  kiyohara {
    170  1.5  kiyohara 	struct PCI_ConfigInfo *pslot;
    171  1.2  sakamoto 
    172  1.5  kiyohara 	if (bar >= 6)
    173  1.5  kiyohara 		return 0xffffffff;
    174  1.1  sakamoto 
    175  1.5  kiyohara 	pslot = &PCI_slots[slotnum];
    176  1.1  sakamoto 
    177  1.5  kiyohara 	if (pslot->regs[DEVID] == 0xffffffff ||
    178  1.5  kiyohara 	    PCI_MAPREG_TYPE(pslot->regs[BAR_BASE + bar]) != type)
    179  1.5  kiyohara 		return 0xffffffff;
    180  1.2  sakamoto 
    181  1.5  kiyohara 	return PCI_MAPREG_MEM_ADDR(pslot->regs[BAR_BASE + bar]);
    182  1.5  kiyohara }
    183  1.2  sakamoto 
    184  1.5  kiyohara #ifdef DEBUG
    185  1.5  kiyohara void
    186  1.5  kiyohara printPCIslots(void)
    187  1.5  kiyohara {
    188  1.5  kiyohara 	int i;
    189  1.5  kiyohara 	for (i = 0; i < NSLOTS; i++) {
    190  1.5  kiyohara 		printf("PCI Slot number: %d", i);
    191  1.5  kiyohara 		printf(" Vendor ID: 0x%x\n", PCIVendor(i));
    192  1.1  sakamoto 	}
    193  1.1  sakamoto }
    194  1.5  kiyohara #endif /* DEBUG */
    195