Implement partial support for the RS6K PCI Bridge found on 7025-F40

models.  This code was made possible by assistance from Cory Bajus.

Add code that asks the PCI bridge what it's config base address is, and
use that when wiring up an indirect bridge type.
Move prep's user segment register to 10, because the 7025's PCI config
address is at 11, where the user segment used to be.
Add a battable entry for 0xbf800000 for machines with RS6K bridges.

There is still probably work left to be done before a 7025-F40 is fully
supported.
This commit is contained in:
garbled 2006-05-25 02:11:13 +00:00
parent 830feeb9f3
commit c9e13db63a
7 changed files with 102 additions and 24 deletions

View File

@ -330,6 +330,8 @@ extern PnP_TAG_PACKET *PnP_find_large_vendor_packet(unsigned char *p,
extern PPC_DEVICE *find_nth_pnp_device(const char *devid, int busid, int n);
extern int count_pnp_devices(const char *devid);
extern void pnp_devid_to_string(uint32_t devid, char *s);
extern int pnp_pci_busno(void *, int *bus);
extern int pnp_pci_configbase(void *v, uint32_t *addr, uint32_t *data);
#endif /* __ASSEMBLY__ */
#endif /* ndef _RESIDUAL_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: vmparam.h,v 1.12 2003/02/03 17:10:12 matt Exp $ */
/* $NetBSD: vmparam.h,v 1.13 2006/05/25 02:11:13 garbled Exp $ */
#define USER_SR 11
#define USER_SR 10
#include <powerpc/oea/vmparam.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: pci_machdep.c,v 1.25 2006/04/25 02:19:31 snj Exp $ */
/* $NetBSD: pci_machdep.c,v 1.26 2006/05/25 02:11:13 garbled Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.25 2006/04/25 02:19:31 snj Exp $");
__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.26 2006/05/25 02:11:13 garbled Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -92,7 +92,7 @@ prep_pci_get_chipset_tag(pci_chipset_tag_t pc)
i = pci_chipset_tag_type();
if (i == PCIBridgeIndirect)
if (i == PCIBridgeIndirect || i == PCIBridgeRS6K)
prep_pci_get_chipset_tag_indirect(pc);
else if (i == PCIBridgeDirect)
prep_pci_get_chipset_tag_direct(pc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: prep_pciconf_indirect.c,v 1.5 2005/12/11 12:18:47 christos Exp $ */
/* $NetBSD: prep_pciconf_indirect.c,v 1.6 2006/05/25 02:11:13 garbled Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All rights reserved.
@ -39,7 +39,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: prep_pciconf_indirect.c,v 1.5 2005/12/11 12:18:47 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: prep_pciconf_indirect.c,v 1.6 2006/05/25 02:11:13 garbled Exp $");
#include "opt_openpic.h"
@ -68,8 +68,9 @@ __KERNEL_RCSID(0, "$NetBSD: prep_pciconf_indirect.c,v 1.5 2005/12/11 12:18:47 ch
#include <dev/pci/pcidevs.h>
#define PCI_MODE1_ENABLE 0x80000000UL
#define PCI_MODE1_ADDRESS_REG (PREP_BUS_SPACE_IO + 0xcf8)
#define PCI_MODE1_DATA_REG (PREP_BUS_SPACE_IO + 0xcfc)
extern volatile unsigned char *prep_pci_baseaddr;
extern volatile unsigned char *prep_pci_basedata;
#define PCI_CBIO 0x10
@ -171,9 +172,9 @@ prep_pci_indirect_conf_read(void *v, pcitag_t tag, int reg)
int s;
s = splhigh();
out32rb(PCI_MODE1_ADDRESS_REG, tag | reg);
data = in32rb(PCI_MODE1_DATA_REG);
out32rb(PCI_MODE1_ADDRESS_REG, 0);
out32rb(prep_pci_baseaddr, tag | reg);
data = in32rb(prep_pci_basedata);
out32rb(prep_pci_baseaddr, 0);
splx(s);
return data;
@ -185,8 +186,8 @@ prep_pci_indirect_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
int s;
s = splhigh();
out32rb(PCI_MODE1_ADDRESS_REG, tag | reg);
out32rb(PCI_MODE1_DATA_REG, data);
out32rb(PCI_MODE1_ADDRESS_REG, 0);
out32rb(prep_pci_baseaddr, tag | reg);
out32rb(prep_pci_basedata, data);
out32rb(prep_pci_baseaddr, 0);
splx(s);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.61 2006/05/09 01:18:10 garbled Exp $ */
/* $NetBSD: machdep.c,v 1.62 2006/05/25 02:11:13 garbled Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.61 2006/05/09 01:18:10 garbled Exp $");
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.62 2006/05/25 02:11:13 garbled Exp $");
#include "opt_compat_netbsd.h"
#include "opt_ddb.h"
@ -180,10 +180,13 @@ initppc(u_long startkernel, u_long endkernel, u_int args, void *btinfo)
/*
* Now setup fixed bat registers
* We setup the memory BAT, the IO space BAT, and a special
* BAT for certain machines that have rs6k style PCI bridges
*/
oea_batinit(
PREP_BUS_SPACE_MEM, BAT_BL_256M,
PREP_BUS_SPACE_IO, BAT_BL_256M,
0xbf800000, BAT_BL_8M,
0);
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: platform.c,v 1.16 2006/05/09 03:35:37 garbled Exp $ */
/* $NetBSD: platform.c,v 1.17 2006/05/25 02:11:13 garbled Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.16 2006/05/09 03:35:37 garbled Exp $");
__KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.17 2006/05/25 02:11:13 garbled Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -51,7 +51,8 @@ __KERNEL_RCSID(0, "$NetBSD: platform.c,v 1.16 2006/05/09 03:35:37 garbled Exp $"
#include <powerpc/pio.h>
static int nrofpcidevices = 0;
volatile unsigned char *prep_pci_baseaddr = (unsigned char *)0x80000cf8;
volatile unsigned char *prep_pci_basedata = (unsigned char *)0x80000cfc;
struct pciroutinginfo *pciroutinginfo;
extern void pci_intr_fixup_ibm_6015(int, int, int, int, int *);
@ -263,15 +264,44 @@ pnp_small_pkt(void *v)
return tag_small_count(tag) + 1 /* tag */;
}
/*
* We look to see what kind of bridge this is, and return it. If we have
* 1.1 residual, we also look up the bridge data, and get the config base
* address from it. We set a default sane value for the config base addr
* at initialization, so it shouldn't matter if we can't find one here.
*/
int
pci_chipset_tag_type(void)
{
PPC_DEVICE *dev;
uint32_t addr, data, l;
unsigned char *p;
int size;
dev = find_nth_pnp_device("PNP0A03", 0, 0);
if (dev == NULL)
return PCIBridgeIndirect;
l = be32toh(dev->AllocatedOffset);
p = res->DevicePnPHeap + l;
if (p == NULL)
return PCIBridgeIndirect;
/* gather the pci base address from PNP */
for (; p[0] != END_TAG; p += size) {
if (tag_type(p[0]) == PNP_SMALL)
size = pnp_small_pkt(p);
else {
size = pnp_pci_configbase(p, &addr, &data);
if (addr != 0 && data != 0) {
prep_pci_baseaddr = (unsigned char *)addr;
prep_pci_basedata = (unsigned char *)data;
break;
}
}
}
return dev->DeviceId.Interface;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: residual.c,v 1.10 2006/05/24 16:10:18 garbled Exp $ */
/* $NetBSD: residual.c,v 1.11 2006/05/25 02:11:13 garbled Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: residual.c,v 1.10 2006/05/24 16:10:18 garbled Exp $");
__KERNEL_RCSID(0, "$NetBSD: residual.c,v 1.11 2006/05/25 02:11:13 garbled Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -240,12 +240,54 @@ find_nth_pnp_device(const char *devid, int busid, int n)
}
int
pnp_pci_busno(void *v)
pnp_pci_busno(void *v, int *bus)
{
struct _L4_Pack *pack = v;
struct _L4_PPCPack *p = &pack->L4_Data.L4_PPCPack;
int item, size, tag = *(unsigned char *)v;
unsigned char *q = v;
return(p->PPCData[16]);
item = tag_large_item_name(tag);
size = (q[1] | (q[2] << 8)) + 3 /* tag + length */;
*bus = -1;
if (res->Revision == 0)
return size;
if (item != LargeVendorItem)
return size;
if (p->Type != LV_PCIBridge) /* PCI Bridge type */
return size;
*bus = p->PPCData[16];
return size;
}
/* Get the PCI config base and addr from PNP */
int
pnp_pci_configbase(void *v, uint32_t *addr, uint32_t *data)
{
struct _L4_Pack *pack = v;
struct _L4_PPCPack *p = &pack->L4_Data.L4_PPCPack;
int item, size, tag = *(unsigned char *)v;
unsigned char *q = v;
item = tag_large_item_name(tag);
size = (q[1] | (q[2] << 8)) + 3 /* tag + length */;
/* init to zero so we don't return garbage values */
*addr = 0;
*data = 0;
if (res->Revision == 0)
return size;
if (item != LargeVendorItem)
return size;
if (p->Type != LV_PCIBridge) /* PCI Bridge type */
return size;
*addr = (uint32_t)le64dec(&p->PPCData[0]);
*data = (uint32_t)le64dec(&p->PPCData[8]);
return size;
}
#ifdef RESIDUAL_DATA_DUMP