Merge Stephen Rothwell's patches

This commit is contained in:
Paul Mackerras 2005-09-28 21:11:41 +10:00
commit 952ecef7a0
48 changed files with 410 additions and 432 deletions

View File

@ -1,4 +1,7 @@
obj-$(CONFIG_PPC_PMAC) += powermac/ ifeq ($(CONFIG_PPC32),y)
obj-$(CONFIG_4xx) += 4xx/ obj-$(CONFIG_PPC_PMAC) += powermac/
obj-$(CONFIG_83xx) += 83xx/ endif
obj-$(CONFIG_85xx) += 85xx/ obj-$(CONFIG_4xx) += 4xx/
obj-$(CONFIG_83xx) += 83xx/
obj-$(CONFIG_85xx) += 85xx/
obj-$(CONFIG_PPC_ISERIES) += iseries/

View File

@ -0,0 +1,7 @@
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
hvcall.o proc.o htab.o iommu.o misc.o
obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
obj-$(CONFIG_IBMVIO) += vio.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_VIOPATH) += viopath.o
obj-$(CONFIG_MODULES) += ksyms.o

View File

@ -1,10 +1,10 @@
/* /*
* iSeries hashtable management. * iSeries hashtable management.
* Derived from pSeries_htab.c * Derived from pSeries_htab.c
* *
* SMP scalability work: * SMP scalability work:
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
@ -18,7 +18,8 @@
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp = { [0 ... 63] = SPIN_LOCK_UNLOCKED}; static spinlock_t iSeries_hlocks[64] __cacheline_aligned_in_smp =
{ [0 ... 63] = SPIN_LOCK_UNLOCKED};
/* /*
* Very primitive algorithm for picking up a lock * Very primitive algorithm for picking up a lock
@ -126,7 +127,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset); hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
if (! (hpte_v & HPTE_V_BOLTED)) { if (! (hpte_v & HPTE_V_BOLTED)) {
HvCallHpt_invalidateSetSwBitsGet(hpte_group + HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0); slot_offset, 0, 0);
iSeries_hunlock(hpte_group); iSeries_hunlock(hpte_group);
return i; return i;
@ -143,9 +144,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
/* /*
* The HyperVisor expects the "flags" argument in this form: * The HyperVisor expects the "flags" argument in this form:
* bits 0..59 : reserved * bits 0..59 : reserved
* bit 60 : N * bit 60 : N
* bits 61..63 : PP2,PP1,PP0 * bits 61..63 : PP2,PP1,PP0
*/ */
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local) unsigned long va, int large, int local)
@ -171,7 +172,7 @@ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
} }
/* /*
* Functions used to find the PTE for a particular virtual address. * Functions used to find the PTE for a particular virtual address.
* Only used during boot when bolting pages. * Only used during boot when bolting pages.
* *
* Input : vpn : virtual page number * Input : vpn : virtual page number
@ -189,7 +190,7 @@ static long iSeries_hpte_find(unsigned long vpn)
* 0x00000000xxxxxxxx : Entry found in primary group, slot x * 0x00000000xxxxxxxx : Entry found in primary group, slot x
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x * 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/ */
slot = HvCallHpt_findValid(&hpte, vpn); slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.v & HPTE_V_VALID) { if (hpte.v & HPTE_V_VALID) {
if (slot < 0) { if (slot < 0) {
slot &= 0x7fffffffffffffff; slot &= 0x7fffffffffffffff;
@ -216,7 +217,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
vsid = get_kernel_vsid(ea); vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff); va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT; vpn = va >> PAGE_SHIFT;
slot = iSeries_hpte_find(vpn); slot = iSeries_hpte_find(vpn);
if (slot == -1) if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n"); panic("updateboltedpp: Could not find page to bolt\n");
HvCallHpt_setPp(slot, newpp); HvCallHpt_setPp(slot, newpp);
@ -234,7 +235,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
iSeries_hlock(slot); iSeries_hlock(slot);
hpte_v = iSeries_hpte_getword0(slot); hpte_v = iSeries_hpte_getword0(slot);
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID)) if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0); HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
@ -249,7 +250,7 @@ void hpte_init_iSeries(void)
ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove; ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init(); htab_finish_init();
} }

View File

@ -1,7 +1,4 @@
/* /*
* arch/ppc64/kernel/hvCall.S
*
*
* This file contains the code to perform calls to the * This file contains the code to perform calls to the
* iSeries LPAR hypervisor * iSeries LPAR hypervisor
* *
@ -16,12 +13,12 @@
.text .text
/* /*
* Hypervisor call * Hypervisor call
* *
* Invoke the iSeries hypervisor via the System Call instruction * Invoke the iSeries hypervisor via the System Call instruction
* Parameters are passed to this routine in registers r3 - r10 * Parameters are passed to this routine in registers r3 - r10
* *
* r3 contains the HV function to be called * r3 contains the HV function to be called
* r4-r10 contain the operands to the hypervisor function * r4-r10 contain the operands to the hypervisor function
* *
@ -41,11 +38,11 @@ _GLOBAL(HvCall7)
mfcr r0 mfcr r0
std r0,-8(r1) std r0,-8(r1)
stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1) stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
/* r0 = 0xffffffffffffffff indicates a hypervisor call */ /* r0 = 0xffffffffffffffff indicates a hypervisor call */
li r0,-1 li r0,-1
/* Invoke the hypervisor */ /* Invoke the hypervisor */
sc sc
@ -55,7 +52,7 @@ _GLOBAL(HvCall7)
mtcrf 0xff,r0 mtcrf 0xff,r0
/* return to caller, return value in r3 */ /* return to caller, return value in r3 */
blr blr
_GLOBAL(HvCall0Ret16) _GLOBAL(HvCall0Ret16)
@ -92,7 +89,5 @@ _GLOBAL(HvCall7Ret16)
ld r0,-8(r1) ld r0,-8(r1)
mtcrf 0xff,r0 mtcrf 0xff,r0
ld r31,-16(r1) ld r31,-16(r1)
blr blr

View File

@ -1,5 +1,4 @@
/* /*
* HvCall.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation * Copyright (C) 2001 Mike Corrigan IBM Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View File

@ -1,5 +1,4 @@
/* /*
* HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation * Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify

View File

@ -1,6 +1,4 @@
/* /*
* arch/ppc64/kernel/iSeries_iommu.c
*
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
* *
* Rewrite, cleanup: * Rewrite, cleanup:
@ -91,15 +89,17 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
*/ */
static struct iommu_table *iommu_table_find(struct iommu_table * tbl) static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
{ {
struct iSeries_Device_Node *dp; struct device_node *dp;
list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) { list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
if ((dp->iommu_table != NULL) && struct iommu_table *it = PCI_DN(dp)->iommu_table;
(dp->iommu_table->it_type == TCE_PCI) &&
(dp->iommu_table->it_offset == tbl->it_offset) && if ((it != NULL) &&
(dp->iommu_table->it_index == tbl->it_index) && (it->it_type == TCE_PCI) &&
(dp->iommu_table->it_size == tbl->it_size)) (it->it_offset == tbl->it_offset) &&
return dp->iommu_table; (it->it_index == tbl->it_index) &&
(it->it_size == tbl->it_size))
return it;
} }
return NULL; return NULL;
} }
@ -113,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
* 2. TCE table per Bus. * 2. TCE table per Bus.
* 3. TCE Table per IOA. * 3. TCE Table per IOA.
*/ */
static void iommu_table_getparms(struct iSeries_Device_Node* dn, static void iommu_table_getparms(struct device_node *dn,
struct iommu_table* tbl) struct iommu_table* tbl)
{ {
struct iommu_table_cb *parms; struct iommu_table_cb *parms;
@ -125,7 +125,7 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
memset(parms, 0, sizeof(*parms)); memset(parms, 0, sizeof(*parms));
parms->itc_busno = ISERIES_BUS(dn); parms->itc_busno = ISERIES_BUS(dn);
parms->itc_slotno = dn->LogicalSlot; parms->itc_slotno = PCI_DN(dn)->LogicalSlot;
parms->itc_virtbus = 0; parms->itc_virtbus = 0;
HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms)); HvCallXm_getTceTableParms(ISERIES_HV_ADDR(parms));
@ -145,18 +145,19 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
} }
void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn) void iommu_devnode_init_iSeries(struct device_node *dn)
{ {
struct iommu_table *tbl; struct iommu_table *tbl;
struct pci_dn *pdn = PCI_DN(dn);
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
iommu_table_getparms(dn, tbl); iommu_table_getparms(dn, tbl);
/* Look for existing tce table */ /* Look for existing tce table */
dn->iommu_table = iommu_table_find(tbl); pdn->iommu_table = iommu_table_find(tbl);
if (dn->iommu_table == NULL) if (pdn->iommu_table == NULL)
dn->iommu_table = iommu_init_table(tbl); pdn->iommu_table = iommu_init_table(tbl);
else else
kfree(tbl); kfree(tbl);
} }

View File

@ -363,4 +363,3 @@ void virt_irq_init(void)
{ {
return; return;
} }

View File

@ -0,0 +1,27 @@
/*
* (C) 2001-2005 PPC 64 Team, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/module.h>
#include <asm/hw_irq.h>
#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(HvCall0);
EXPORT_SYMBOL(HvCall1);
EXPORT_SYMBOL(HvCall2);
EXPORT_SYMBOL(HvCall3);
EXPORT_SYMBOL(HvCall4);
EXPORT_SYMBOL(HvCall5);
EXPORT_SYMBOL(HvCall6);
EXPORT_SYMBOL(HvCall7);
#ifdef CONFIG_SMP
EXPORT_SYMBOL(local_get_flags);
EXPORT_SYMBOL(local_irq_disable);
EXPORT_SYMBOL(local_irq_restore);
#endif

View File

@ -1,4 +1,4 @@
/* /*
* Copyright 2001 Mike Corrigan, IBM Corp * Copyright 2001 Mike Corrigan, IBM Corp
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -29,8 +29,8 @@
#include <asm/iSeries/ItSpCommArea.h> #include <asm/iSeries/ItSpCommArea.h>
/* The HvReleaseData is the root of the information shared between /* The HvReleaseData is the root of the information shared between
* the hypervisor and Linux. * the hypervisor and Linux.
*/ */
struct HvReleaseData hvReleaseData = { struct HvReleaseData hvReleaseData = {
.xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */ .xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void);
extern void performance_monitor_iSeries(void); extern void performance_monitor_iSeries(void);
extern void data_access_slb_iSeries(void); extern void data_access_slb_iSeries(void);
extern void instruction_access_slb_iSeries(void); extern void instruction_access_slb_iSeries(void);
struct ItLpNaca itLpNaca = { struct ItLpNaca itLpNaca = {
.xDesc = 0xd397d581, /* "LpNa" ebcdic */ .xDesc = 0xd397d581, /* "LpNa" ebcdic */
.xSize = 0x0400, /* size of ItLpNaca */ .xSize = 0x0400, /* size of ItLpNaca */
@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = {
.xLoadAreaChunks = 0, /* chunks for load area */ .xLoadAreaChunks = 0, /* chunks for load area */
.xPaseSysCallCRMask = 0, /* PASE mask */ .xPaseSysCallCRMask = 0, /* PASE mask */
.xSlicSegmentTablePtr = 0, /* seg table */ .xSlicSegmentTablePtr = 0, /* seg table */
.xOldLpQueue = { 0 }, /* Old LP Queue */ .xOldLpQueue = { 0 }, /* Old LP Queue */
.xInterruptHdlr = { .xInterruptHdlr = {
(u64)system_reset_iSeries, /* 0x100 System Reset */ (u64)system_reset_iSeries, /* 0x100 System Reset */
(u64)machine_check_iSeries, /* 0x200 Machine Check */ (u64)machine_check_iSeries, /* 0x200 Machine Check */
@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = {
EXPORT_SYMBOL(itLpNaca); EXPORT_SYMBOL(itLpNaca);
/* May be filled in by the hypervisor so cannot end up in the BSS */ /* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data"))); struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
/* May be filled in by the hypervisor so cannot end up in the BSS */ /* May be filled in by the hypervisor so cannot end up in the BSS */
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data"))); struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
.xPVR = 0x3600 .xPVR = 0x3600
} }
}; };
/* Space for Main Store Vpd 27,200 bytes */ /* Space for Main Store Vpd 27,200 bytes */
/* May be filled in by the hypervisor so cannot end up in the BSS */ /* May be filled in by the hypervisor so cannot end up in the BSS */
u64 xMsVpd[3400] __attribute__((__section__(".data"))); u64 xMsVpd[3400] __attribute__((__section__(".data")));
@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = {
26992, /* 7 length of MS VPD */ 26992, /* 7 length of MS VPD */
0, /* 8 */ 0, /* 8 */
sizeof(struct ItLpNaca),/* 9 length of LP Naca */ sizeof(struct ItLpNaca),/* 9 length of LP Naca */
0, /* 10 */ 0, /* 10 */
256, /* 11 length of Recovery Log Buf */ 256, /* 11 length of Recovery Log Buf */
sizeof(struct SpCommArea), /* 12 length of SP Comm Area */ sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
0,0,0, /* 13 - 15 */ 0,0,0, /* 13 - 15 */
@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = {
0,0 /* 24 - 25 */ 0,0 /* 24 - 25 */
}, },
.xSlicVpdAdrs = { /* VPD addresses */ .xSlicVpdAdrs = { /* VPD addresses */
0,0,0, /* 0 - 2 */ 0,0,0, /* 0 - 2 */
&xItExtVpdPanel, /* 3 Extended VPD */ &xItExtVpdPanel, /* 3 Extended VPD */
&paca[0], /* 4 first Paca */ &paca[0], /* 4 first Paca */
0, /* 5 */ 0, /* 5 */

View File

@ -1,5 +1,4 @@
/* /*
* ItLpQueue.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation * Copyright (C) 2001 Mike Corrigan IBM Corporation
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -19,6 +18,7 @@
#include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h> #include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h> #include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/ItLpNaca.h>
/* /*
* The LpQueue is used to pass event data from the hypervisor to * The LpQueue is used to pass event data from the hypervisor to
@ -43,7 +43,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = {
}; };
/* Array of LpEvent handler functions */ /* Array of LpEvent handler functions */
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; static LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
static struct HvLpEvent * get_next_hvlpevent(void) static struct HvLpEvent * get_next_hvlpevent(void)
{ {
@ -199,6 +200,70 @@ void setup_hvlpevent_queue(void)
hvlpevent_queue.xIndex = 0; hvlpevent_queue.xIndex = 0;
} }
/* Register a handler for an LpEvent type */
int HvLpEvent_registerHandler(HvLpEvent_Type eventType, LpEventHandler handler)
{
if (eventType < HvLpEvent_Type_NumTypes) {
lpEventHandler[eventType] = handler;
return 0;
}
return 1;
}
EXPORT_SYMBOL(HvLpEvent_registerHandler);
int HvLpEvent_unregisterHandler(HvLpEvent_Type eventType)
{
might_sleep();
if (eventType < HvLpEvent_Type_NumTypes) {
if (!lpEventHandlerPaths[eventType]) {
lpEventHandler[eventType] = NULL;
/*
* We now sleep until all other CPUs have scheduled.
* This ensures that the deletion is seen by all
* other CPUs, and that the deleted handler isn't
* still running on another CPU when we return.
*/
synchronize_rcu();
return 0;
}
}
return 1;
}
EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
/*
* lpIndex is the partition index of the target partition.
* needed only for VirtualIo, VirtualLan and SessionMgr. Zero
* indicates to use our partition index - for the other types.
*/
int HvLpEvent_openPath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
{
if ((eventType < HvLpEvent_Type_NumTypes) &&
lpEventHandler[eventType]) {
if (lpIndex == 0)
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_openLpEventPath(lpIndex, eventType);
++lpEventHandlerPaths[eventType];
return 0;
}
return 1;
}
int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex)
{
if ((eventType < HvLpEvent_Type_NumTypes) &&
lpEventHandler[eventType] &&
lpEventHandlerPaths[eventType]) {
if (lpIndex == 0)
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_closeLpEventPath(lpIndex, eventType);
--lpEventHandlerPaths[eventType];
return 0;
}
return 1;
}
static int proc_lpevents_show(struct seq_file *m, void *v) static int proc_lpevents_show(struct seq_file *m, void *v)
{ {
int cpu, i; int cpu, i;

View File

@ -1,29 +1,28 @@
/* /*
* mf.c * Copyright (C) 2001 Troy D. Armstrong IBM Corporation
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation * Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation *
* * This modules exists as an interface between a Linux secondary partition
* This modules exists as an interface between a Linux secondary partition * running on an iSeries and the primary partition's Virtual Service
* running on an iSeries and the primary partition's Virtual Service * Processor (VSP) object. The VSP has final authority over powering on/off
* Processor (VSP) object. The VSP has final authority over powering on/off * all partitions in the iSeries. It also provides miscellaneous low-level
* all partitions in the iSeries. It also provides miscellaneous low-level * machine facility type operations.
* machine facility type operations. *
* *
* * This program is free software; you can redistribute it and/or modify
* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by
* it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or
* the Free Software Foundation; either version 2 of the License, or * (at your option) any later version.
* (at your option) any later version. *
* * This program is distributed in the hope that it will be useful,
* This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of
* but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details.
* GNU General Public License for more details. *
* * You should have received a copy of the GNU General Public License
* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
*/
#include <linux/types.h> #include <linux/types.h>
#include <linux/errno.h> #include <linux/errno.h>
@ -42,6 +41,10 @@
#include <asm/iSeries/HvLpConfig.h> #include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/ItLpQueue.h> #include <asm/iSeries/ItLpQueue.h>
#include "setup.h"
extern int piranha_simulator;
/* /*
* This is the structure layout for the Machine Facilites LPAR event * This is the structure layout for the Machine Facilites LPAR event
* flows. * flows.
@ -1279,3 +1282,35 @@ static int __init mf_proc_init(void)
__initcall(mf_proc_init); __initcall(mf_proc_init);
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/*
* Get the RTC from the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
if (piranha_simulator)
return;
mf_get_rtc(rtc_tm);
rtc_tm->tm_mon--;
}
/*
* Set the RTC in the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
int iSeries_set_rtc_time(struct rtc_time *tm)
{
mf_set_rtc(tm);
return 0;
}
void iSeries_get_boot_time(struct rtc_time *tm)
{
if (piranha_simulator)
return;
mf_get_boot_rtc(tm);
tm->tm_mon -= 1;
}

View File

@ -0,0 +1,55 @@
/*
* This file contains miscellaneous low-level functions.
* Copyright (C) 1995-2005 IBM Corp
*
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
* and Paul Mackerras.
* Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
* PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <asm/processor.h>
#include <asm/asm-offsets.h>
.text
/* unsigned long local_save_flags(void) */
_GLOBAL(local_get_flags)
lbz r3,PACAPROCENABLED(r13)
blr
/* unsigned long local_irq_disable(void) */
_GLOBAL(local_irq_disable)
lbz r3,PACAPROCENABLED(r13)
li r4,0
stb r4,PACAPROCENABLED(r13)
blr /* Done */
/* void local_irq_restore(unsigned long flags) */
_GLOBAL(local_irq_restore)
lbz r5,PACAPROCENABLED(r13)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
cmpdi 0,r3,0
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
ld r4,PACALPPACA+LPPACAANYINT(r13)
cmpdi r4,0
beqlr
/*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
sc
blr

View File

@ -1,28 +1,26 @@
/* /*
* iSeries_pci.c
*
* Copyright (C) 2001 Allan Trautman, IBM Corporation * Copyright (C) 2001 Allan Trautman, IBM Corporation
* *
* iSeries specific routines for PCI. * iSeries specific routines for PCI.
* *
* Based on code from pci.c and iSeries_pci.c 32bit * Based on code from pci.c and iSeries_pci.c 32bit
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
@ -43,14 +41,14 @@
#include <asm/iSeries/iSeries_pci.h> #include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/mf.h> #include <asm/iSeries/mf.h>
#include "pci.h" #include <asm/ppc-pci.h>
extern unsigned long io_page_mask; extern unsigned long io_page_mask;
/* /*
* Forward declares of prototypes. * Forward declares of prototypes.
*/ */
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn); static struct device_node *find_Device_Node(int bus, int devfn);
static void scan_PHB_slots(struct pci_controller *Phb); static void scan_PHB_slots(struct pci_controller *Phb);
static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel); static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info); static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
@ -68,7 +66,7 @@ static long Pci_Cfg_Write_Count;
#endif #endif
static long Pci_Error_Count; static long Pci_Error_Count;
static int Pci_Retry_Max = 3; /* Only retry 3 times */ static int Pci_Retry_Max = 3; /* Only retry 3 times */
static int Pci_Error_Flag = 1; /* Set Retry Error on. */ static int Pci_Error_Flag = 1; /* Set Retry Error on. */
static struct pci_ops iSeries_pci_ops; static struct pci_ops iSeries_pci_ops;
@ -87,7 +85,7 @@ static long current_iomm_table_entry;
/* /*
* Lookup Tables. * Lookup Tables.
*/ */
static struct iSeries_Device_Node **iomm_table; static struct device_node **iomm_table;
static u8 *iobar_table; static u8 *iobar_table;
/* /*
@ -179,7 +177,7 @@ static void allocate_device_bars(struct pci_dev *dev)
for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) { for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) {
bar_res = &dev->resource[bar_num]; bar_res = &dev->resource[bar_num];
iomm_table_allocate_entry(dev, bar_num); iomm_table_allocate_entry(dev, bar_num);
} }
} }
/* /*
@ -201,29 +199,35 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
/* /*
* build_device_node(u16 Bus, int SubBus, u8 DevFn) * build_device_node(u16 Bus, int SubBus, u8 DevFn)
*/ */
static struct iSeries_Device_Node *build_device_node(HvBusNumber Bus, static struct device_node *build_device_node(HvBusNumber Bus,
HvSubBusNumber SubBus, int AgentId, int Function) HvSubBusNumber SubBus, int AgentId, int Function)
{ {
struct iSeries_Device_Node *node; struct device_node *node;
struct pci_dn *pdn;
PPCDBG(PPCDBG_BUSWALK, PPCDBG(PPCDBG_BUSWALK,
"-build_device_node 0x%02X.%02X.%02X Function: %02X\n", "-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
Bus, SubBus, AgentId, Function); Bus, SubBus, AgentId, Function);
node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL); node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
if (node == NULL) if (node == NULL)
return NULL; return NULL;
memset(node, 0, sizeof(struct device_node));
memset(node, 0, sizeof(struct iSeries_Device_Node)); pdn = kzalloc(sizeof(*pdn), GFP_KERNEL);
if (pdn == NULL) {
kfree(node);
return NULL;
}
node->data = pdn;
list_add_tail(&node->Device_List, &iSeries_Global_Device_List); list_add_tail(&node->Device_List, &iSeries_Global_Device_List);
#if 0 #if 0
node->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32); pdn->DsaAddr = ((u64)Bus << 48) + ((u64)SubBus << 40) + ((u64)0x10 << 32);
#endif #endif
node->DsaAddr.DsaAddr = 0; pdn->DsaAddr.DsaAddr = 0;
node->DsaAddr.Dsa.busNumber = Bus; pdn->DsaAddr.Dsa.busNumber = Bus;
node->DsaAddr.Dsa.subBusNumber = SubBus; pdn->DsaAddr.Dsa.subBusNumber = SubBus;
node->DsaAddr.Dsa.deviceId = 0x10; pdn->DsaAddr.Dsa.deviceId = 0x10;
node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
return node; return node;
} }
@ -278,28 +282,28 @@ unsigned long __init find_and_init_phbs(void)
/* /*
* iSeries_pcibios_init * iSeries_pcibios_init
* *
* Chance to initialize and structures or variable before PCI Bus walk. * Chance to initialize and structures or variable before PCI Bus walk.
*/ */
void iSeries_pcibios_init(void) void iSeries_pcibios_init(void)
{ {
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n"); PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
iomm_table_initialize(); iomm_table_initialize();
find_and_init_phbs(); find_and_init_phbs();
io_page_mask = -1; io_page_mask = -1;
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n"); PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Exit.\n");
} }
/* /*
* iSeries_pci_final_fixup(void) * iSeries_pci_final_fixup(void)
*/ */
void __init iSeries_pci_final_fixup(void) void __init iSeries_pci_final_fixup(void)
{ {
struct pci_dev *pdev = NULL; struct pci_dev *pdev = NULL;
struct iSeries_Device_Node *node; struct device_node *node;
int DeviceCount = 0; int DeviceCount = 0;
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n"); PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup Entry.\n");
/* Fix up at the device node and pci_dev relationship */ /* Fix up at the device node and pci_dev relationship */
mf_display_src(0xC9000100); mf_display_src(0xC9000100);
@ -313,7 +317,7 @@ void __init iSeries_pci_final_fixup(void)
if (node != NULL) { if (node != NULL) {
++DeviceCount; ++DeviceCount;
pdev->sysdata = (void *)node; pdev->sysdata = (void *)node;
node->PciDev = pdev; PCI_DN(node)->pcidev = pdev;
PPCDBG(PPCDBG_BUSWALK, PPCDBG(PPCDBG_BUSWALK,
"pdev 0x%p <==> DevNode 0x%p\n", "pdev 0x%p <==> DevNode 0x%p\n",
pdev, node); pdev, node);
@ -323,7 +327,7 @@ void __init iSeries_pci_final_fixup(void)
} else } else
printk("PCI: Device Tree not found for 0x%016lX\n", printk("PCI: Device Tree not found for 0x%016lX\n",
(unsigned long)pdev); (unsigned long)pdev);
pdev->irq = node->Irq; pdev->irq = PCI_DN(node)->Irq;
} }
iSeries_activate_IRQs(); iSeries_activate_IRQs();
mf_display_src(0xC9000200); mf_display_src(0xC9000200);
@ -332,24 +336,24 @@ void __init iSeries_pci_final_fixup(void)
void pcibios_fixup_bus(struct pci_bus *PciBus) void pcibios_fixup_bus(struct pci_bus *PciBus)
{ {
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n", PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
PciBus->number); PciBus->number);
} }
void pcibios_fixup_resources(struct pci_dev *pdev) void pcibios_fixup_resources(struct pci_dev *pdev)
{ {
PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev); PPCDBG(PPCDBG_BUSWALK, "fixup_resources pdev %p\n", pdev);
} }
/* /*
* Loop through each node function to find usable EADs bridges. * Loop through each node function to find usable EADs bridges.
*/ */
static void scan_PHB_slots(struct pci_controller *Phb) static void scan_PHB_slots(struct pci_controller *Phb)
{ {
struct HvCallPci_DeviceInfo *DevInfo; struct HvCallPci_DeviceInfo *DevInfo;
HvBusNumber bus = Phb->local_number; /* System Bus */ HvBusNumber bus = Phb->local_number; /* System Bus */
const HvSubBusNumber SubBus = 0; /* EADs is always 0. */ const HvSubBusNumber SubBus = 0; /* EADs is always 0. */
int HvRc = 0; int HvRc = 0;
int IdSel; int IdSel;
const int MaxAgents = 8; const int MaxAgents = 8;
DevInfo = (struct HvCallPci_DeviceInfo*) DevInfo = (struct HvCallPci_DeviceInfo*)
@ -358,10 +362,10 @@ static void scan_PHB_slots(struct pci_controller *Phb)
return; return;
/* /*
* Probe for EADs Bridges * Probe for EADs Bridges
*/ */
for (IdSel = 1; IdSel < MaxAgents; ++IdSel) { for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
ISERIES_HV_ADDR(DevInfo), ISERIES_HV_ADDR(DevInfo),
sizeof(struct HvCallPci_DeviceInfo)); sizeof(struct HvCallPci_DeviceInfo));
if (HvRc == 0) { if (HvRc == 0) {
@ -393,19 +397,19 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
/* Note: hvSubBus and irq is always be 0 at this level! */ /* Note: hvSubBus and irq is always be 0 at this level! */
for (Function = 0; Function < 8; ++Function) { for (Function = 0; Function < 8; ++Function) {
AgentId = ISERIES_PCI_AGENTID(IdSel, Function); AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0); HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0);
if (HvRc == 0) { if (HvRc == 0) {
printk("found device at bus %d idsel %d func %d (AgentId %x)\n", printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
bus, IdSel, Function, AgentId); bus, IdSel, Function, AgentId);
/* Connect EADs: 0x18.00.12 = 0x00 */ /* Connect EADs: 0x18.00.12 = 0x00 */
PPCDBG(PPCDBG_BUSWALK, PPCDBG(PPCDBG_BUSWALK,
"PCI:Connect EADs: 0x%02X.%02X.%02X\n", "PCI:Connect EADs: 0x%02X.%02X.%02X\n",
bus, SubBus, AgentId); bus, SubBus, AgentId);
HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
ISERIES_HV_ADDR(BridgeInfo), ISERIES_HV_ADDR(BridgeInfo),
sizeof(struct HvCallPci_BridgeInfo)); sizeof(struct HvCallPci_BridgeInfo));
if (HvRc == 0) { if (HvRc == 0) {
printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n", printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n",
BridgeInfo->busUnitInfo.deviceType, BridgeInfo->busUnitInfo.deviceType,
BridgeInfo->subBusNumber, BridgeInfo->subBusNumber,
@ -428,7 +432,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
printk("PCI: Invalid Bridge Configuration(0x%02X)", printk("PCI: Invalid Bridge Configuration(0x%02X)",
BridgeInfo->busUnitInfo.deviceType); BridgeInfo->busUnitInfo.deviceType);
} }
} else if (HvRc != 0x000B) } else if (HvRc != 0x000B)
pci_Log_Error("EADs Connect", pci_Log_Error("EADs Connect",
bus, SubBus, AgentId, HvRc); bus, SubBus, AgentId, HvRc);
} }
@ -441,7 +445,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
static int scan_bridge_slot(HvBusNumber Bus, static int scan_bridge_slot(HvBusNumber Bus,
struct HvCallPci_BridgeInfo *BridgeInfo) struct HvCallPci_BridgeInfo *BridgeInfo)
{ {
struct iSeries_Device_Node *node; struct device_node *node;
HvSubBusNumber SubBus = BridgeInfo->subBusNumber; HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
u16 VendorId = 0; u16 VendorId = 0;
int HvRc = 0; int HvRc = 0;
@ -451,16 +455,16 @@ static int scan_bridge_slot(HvBusNumber Bus,
HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function); HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */ /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel); Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
PPCDBG(PPCDBG_BUSWALK, PPCDBG(PPCDBG_BUSWALK,
"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n", "PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
Bus, 0, EADsIdSel, Irq); Bus, 0, EADsIdSel, Irq);
/* /*
* Connect all functions of any device found. * Connect all functions of any device found.
*/ */
for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
for (Function = 0; Function < 8; ++Function) { for (Function = 0; Function < 8; ++Function) {
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function); HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
HvRc = HvCallXm_connectBusUnit(Bus, SubBus, HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
AgentId, Irq); AgentId, Irq);
@ -484,15 +488,15 @@ static int scan_bridge_slot(HvBusNumber Bus,
"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n", "PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
Bus, SubBus, AgentId, VendorId, Irq); Bus, SubBus, AgentId, VendorId, Irq);
HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
PCI_INTERRUPT_LINE, Irq); PCI_INTERRUPT_LINE, Irq);
if (HvRc != 0) if (HvRc != 0)
pci_Log_Error("PciCfgStore Irq Failed!", pci_Log_Error("PciCfgStore Irq Failed!",
Bus, SubBus, AgentId, HvRc); Bus, SubBus, AgentId, HvRc);
++DeviceCount; ++DeviceCount;
node = build_device_node(Bus, SubBus, EADsIdSel, Function); node = build_device_node(Bus, SubBus, EADsIdSel, Function);
node->Irq = Irq; PCI_DN(node)->Irq = Irq;
node->LogicalSlot = BridgeInfo->logicalSlotNumber; PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
} /* for (Function = 0; Function < 8; ++Function) */ } /* for (Function = 0; Function < 8; ++Function) */
} /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */
@ -542,15 +546,16 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio);
/* /*
* Look down the chain to find the matching Device Device * Look down the chain to find the matching Device Device
*/ */
static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn) static struct device_node *find_Device_Node(int bus, int devfn)
{ {
struct list_head *pos; struct list_head *pos;
list_for_each(pos, &iSeries_Global_Device_List) { list_for_each(pos, &iSeries_Global_Device_List) {
struct iSeries_Device_Node *node = struct device_node *node =
list_entry(pos, struct iSeries_Device_Node, Device_List); list_entry(pos, struct device_node, Device_List);
if ((bus == ISERIES_BUS(node)) && (devfn == node->DevFn)) if ((bus == ISERIES_BUS(node)) &&
(devfn == PCI_DN(node)->devfn))
return node; return node;
} }
return NULL; return NULL;
@ -562,12 +567,12 @@ static struct iSeries_Device_Node *find_Device_Node(int bus, int devfn)
* Sanity Check Node PciDev to passed pci_dev * Sanity Check Node PciDev to passed pci_dev
* If none is found, returns a NULL which the client must handle. * If none is found, returns a NULL which the client must handle.
*/ */
static struct iSeries_Device_Node *get_Device_Node(struct pci_dev *pdev) static struct device_node *get_Device_Node(struct pci_dev *pdev)
{ {
struct iSeries_Device_Node *node; struct device_node *node;
node = pdev->sysdata; node = pdev->sysdata;
if (node == NULL || node->PciDev != pdev) if (node == NULL || PCI_DN(node)->pcidev != pdev)
node = find_Device_Node(pdev->bus->number, pdev->devfn); node = find_Device_Node(pdev->bus->number, pdev->devfn);
return node; return node;
} }
@ -595,7 +600,7 @@ static u64 hv_cfg_write_func[4] = {
static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn, static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 *val) int offset, int size, u32 *val)
{ {
struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn; u64 fn;
struct HvCallPci_LoadReturn ret; struct HvCallPci_LoadReturn ret;
@ -607,7 +612,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
} }
fn = hv_cfg_read_func[(size - 1) & 3]; fn = hv_cfg_read_func[(size - 1) & 3];
HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0); HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0);
if (ret.rc != 0) { if (ret.rc != 0) {
*val = ~0; *val = ~0;
@ -625,7 +630,7 @@ static int iSeries_pci_read_config(struct pci_bus *bus, unsigned int devfn,
static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn, static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
int offset, int size, u32 val) int offset, int size, u32 val)
{ {
struct iSeries_Device_Node *node = find_Device_Node(bus->number, devfn); struct device_node *node = find_Device_Node(bus->number, devfn);
u64 fn; u64 fn;
u64 ret; u64 ret;
@ -635,7 +640,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
return PCIBIOS_BAD_REGISTER_NUMBER; return PCIBIOS_BAD_REGISTER_NUMBER;
fn = hv_cfg_write_func[(size - 1) & 3]; fn = hv_cfg_write_func[(size - 1) & 3];
ret = HvCall4(fn, node->DsaAddr.DsaAddr, offset, val, 0); ret = HvCall4(fn, PCI_DN(node)->DsaAddr.DsaAddr, offset, val, 0);
if (ret != 0) if (ret != 0)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
@ -657,14 +662,16 @@ static struct pci_ops iSeries_pci_ops = {
* PCI: Device 23.90 ReadL Retry( 1) * PCI: Device 23.90 ReadL Retry( 1)
* PCI: Device 23.90 ReadL Retry Successful(1) * PCI: Device 23.90 ReadL Retry Successful(1)
*/ */
static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode, static int CheckReturnCode(char *TextHdr, struct device_node *DevNode,
int *retry, u64 ret) int *retry, u64 ret)
{ {
if (ret != 0) { if (ret != 0) {
struct pci_dn *pdn = PCI_DN(DevNode);
++Pci_Error_Count; ++Pci_Error_Count;
(*retry)++; (*retry)++;
printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n",
TextHdr, DevNode->DsaAddr.Dsa.busNumber, DevNode->DevFn, TextHdr, pdn->DsaAddr.Dsa.busNumber, pdn->devfn,
*retry, (int)ret); *retry, (int)ret);
/* /*
* Bump the retry and check for retry count exceeded. * Bump the retry and check for retry count exceeded.
@ -687,14 +694,14 @@ static int CheckReturnCode(char *TextHdr, struct iSeries_Device_Node *DevNode,
* Note: Make sure the passed variable end up on the stack to avoid * Note: Make sure the passed variable end up on the stack to avoid
* the exposure of being device global. * the exposure of being device global.
*/ */
static inline struct iSeries_Device_Node *xlate_iomm_address( static inline struct device_node *xlate_iomm_address(
const volatile void __iomem *IoAddress, const volatile void __iomem *IoAddress,
u64 *dsaptr, u64 *BarOffsetPtr) u64 *dsaptr, u64 *BarOffsetPtr)
{ {
unsigned long OrigIoAddr; unsigned long OrigIoAddr;
unsigned long BaseIoAddr; unsigned long BaseIoAddr;
unsigned long TableIndex; unsigned long TableIndex;
struct iSeries_Device_Node *DevNode; struct device_node *DevNode;
OrigIoAddr = (unsigned long __force)IoAddress; OrigIoAddr = (unsigned long __force)IoAddress;
if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory)) if ((OrigIoAddr < BASE_IO_MEMORY) || (OrigIoAddr >= max_io_memory))
@ -705,7 +712,7 @@ static inline struct iSeries_Device_Node *xlate_iomm_address(
if (DevNode != NULL) { if (DevNode != NULL) {
int barnum = iobar_table[TableIndex]; int barnum = iobar_table[TableIndex];
*dsaptr = DevNode->DsaAddr.DsaAddr | (barnum << 24); *dsaptr = PCI_DN(DevNode)->DsaAddr.DsaAddr | (barnum << 24);
*BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE; *BarOffsetPtr = BaseIoAddr % IOMM_TABLE_ENTRY_SIZE;
} else } else
panic("PCI: Invalid PCI IoAddress detected!\n"); panic("PCI: Invalid PCI IoAddress detected!\n");
@ -727,7 +734,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
struct HvCallPci_LoadReturn ret; struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {
@ -757,7 +764,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
struct HvCallPci_LoadReturn ret; struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {
@ -788,7 +795,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
struct HvCallPci_LoadReturn ret; struct HvCallPci_LoadReturn ret;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {
@ -826,7 +833,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
u64 rc; u64 rc;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {
@ -854,7 +861,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
u64 rc; u64 rc;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {
@ -882,7 +889,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
u64 dsa; u64 dsa;
int retry = 0; int retry = 0;
u64 rc; u64 rc;
struct iSeries_Device_Node *DevNode = struct device_node *DevNode =
xlate_iomm_address(IoAddress, &dsa, &BarOffset); xlate_iomm_address(IoAddress, &dsa, &BarOffset);
if (DevNode == NULL) { if (DevNode == NULL) {

View File

@ -1,5 +1,4 @@
/* /*
* iSeries_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation * Copyright (C) 2001 Kyle A. Lucke IBM Corporation
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen IBM Corporation
* *
@ -68,12 +67,15 @@ static int proc_titantod_show(struct seq_file *m, void *v)
unsigned long tb_ticks = (tb0 - startTb); unsigned long tb_ticks = (tb0 - startTb);
unsigned long titan_jiffies = titan_usec / (1000000/HZ); unsigned long titan_jiffies = titan_usec / (1000000/HZ);
unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ); unsigned long titan_jiff_usec = titan_jiffies * (1000000/HZ);
unsigned long titan_jiff_rem_usec = titan_usec - titan_jiff_usec; unsigned long titan_jiff_rem_usec =
titan_usec - titan_jiff_usec;
unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy; unsigned long tb_jiffies = tb_ticks / tb_ticks_per_jiffy;
unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy; unsigned long tb_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks; unsigned long tb_jiff_rem_ticks = tb_ticks - tb_jiff_ticks;
unsigned long tb_jiff_rem_usec = tb_jiff_rem_ticks / tb_ticks_per_usec; unsigned long tb_jiff_rem_usec =
unsigned long new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec; tb_jiff_rem_ticks / tb_ticks_per_usec;
unsigned long new_tb_ticks_per_jiffy =
(tb_ticks * (1000000/HZ))/titan_usec;
seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec); seq_printf(m, " titan elapsed = %lu uSec\n", titan_usec);
seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks); seq_printf(m, " tb elapsed = %lu ticks\n", tb_ticks);

View File

@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com> * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
* *
* Module name: iSeries_setup.c
*
* Description: * Description:
* Architecture- / platform-specific boot-time initialization code for * Architecture- / platform-specific boot-time initialization code for
* the IBM iSeries LPAR. Adapted from original code by Grant Erickson and * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and
@ -42,7 +40,6 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/time.h> #include <asm/time.h>
#include "iSeries_setup.h"
#include <asm/naca.h> #include <asm/naca.h>
#include <asm/paca.h> #include <asm/paca.h>
#include <asm/cache.h> #include <asm/cache.h>
@ -62,6 +59,8 @@
#include <asm/iSeries/ItVpdAreas.h> #include <asm/iSeries/ItVpdAreas.h>
#include <asm/iSeries/LparMap.h> #include <asm/iSeries/LparMap.h>
#include "setup.h"
extern void hvlog(char *fmt, ...); extern void hvlog(char *fmt, ...);
#ifdef DEBUG #ifdef DEBUG

View File

@ -2,8 +2,6 @@
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com> * Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
* *
* Module name: as400_setup.h
*
* Description: * Description:
* Architecture- / platform-specific boot-time initialization code for * Architecture- / platform-specific boot-time initialization code for
* the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and * the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and

View File

@ -47,17 +47,17 @@
static unsigned long iSeries_smp_message[NR_CPUS]; static unsigned long iSeries_smp_message[NR_CPUS];
void iSeries_smp_message_recv( struct pt_regs * regs ) void iSeries_smp_message_recv(struct pt_regs *regs)
{ {
int cpu = smp_processor_id(); int cpu = smp_processor_id();
int msg; int msg;
if ( num_online_cpus() < 2 ) if (num_online_cpus() < 2)
return; return;
for ( msg = 0; msg < 4; ++msg ) for (msg = 0; msg < 4; msg++)
if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) ) if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
smp_message_recv( msg, regs ); smp_message_recv(msg, regs);
} }
static inline void smp_iSeries_do_message(int cpu, int msg) static inline void smp_iSeries_do_message(int cpu, int msg)
@ -74,8 +74,8 @@ static void smp_iSeries_message_pass(int target, int msg)
smp_iSeries_do_message(target, msg); smp_iSeries_do_message(target, msg);
else { else {
for_each_online_cpu(i) { for_each_online_cpu(i) {
if (target == MSG_ALL_BUT_SELF if ((target == MSG_ALL_BUT_SELF) &&
&& i == smp_processor_id()) (i == smp_processor_id()))
continue; continue;
smp_iSeries_do_message(i, msg); smp_iSeries_do_message(i, msg);
} }
@ -89,7 +89,7 @@ static int smp_iSeries_probe(void)
static void smp_iSeries_kick_cpu(int nr) static void smp_iSeries_kick_cpu(int nr)
{ {
BUG_ON(nr < 0 || nr >= NR_CPUS); BUG_ON((nr < 0) || (nr >= NR_CPUS));
/* Verify that our partition has a processor nr */ /* Verify that our partition has a processor nr */
if (paca[nr].lppaca.dyn_proc_status >= 2) if (paca[nr].lppaca.dyn_proc_status >= 2)

View File

@ -1,5 +1,4 @@
/* -*- linux-c -*- /* -*- linux-c -*-
* arch/ppc64/kernel/viopath.c
* *
* iSeries Virtual I/O Message Path code * iSeries Virtual I/O Message Path code
* *
@ -7,7 +6,7 @@
* Ryan Arnold <ryanarn@us.ibm.com> * Ryan Arnold <ryanarn@us.ibm.com>
* Colin Devilbiss <devilbis@us.ibm.com> * Colin Devilbiss <devilbis@us.ibm.com>
* *
* (C) Copyright 2000-2003 IBM Corporation * (C) Copyright 2000-2005 IBM Corporation
* *
* This code is used by the iSeries virtual disk, cd, * This code is used by the iSeries virtual disk, cd,
* tape, and console to communicate with OS/400 in another * tape, and console to communicate with OS/400 in another

View File

@ -1,6 +1,4 @@
/* /*
* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001.
*
* This code gets the card location of the hardware * This code gets the card location of the hardware
* Copyright (C) 2001 <Allan H Trautman> <IBM Corp> * Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
* Copyright (C) 2005 Stephen Rothwel, IBM Corp * Copyright (C) 2005 Stephen Rothwel, IBM Corp
@ -242,7 +240,7 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
*/ */
void __init iSeries_Device_Information(struct pci_dev *PciDev, int count) void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
{ {
struct iSeries_Device_Node *DevNode = PciDev->sysdata; struct device_node *DevNode = PciDev->sysdata;
u16 bus; u16 bus;
u8 frame; u8 frame;
char card[4]; char card[4];

View File

@ -84,6 +84,7 @@ head-y := arch/ppc64/kernel/head.o
libs-y += arch/ppc64/lib/ libs-y += arch/ppc64/lib/
core-y += arch/ppc64/kernel/ core-y += arch/ppc64/kernel/
core-y += arch/ppc64/mm/ core-y += arch/ppc64/mm/
core-y += arch/powerpc/platforms/
core-$(CONFIG_XMON) += arch/ppc64/xmon/ core-$(CONFIG_XMON) += arch/ppc64/xmon/
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/ drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/

View File

@ -1,88 +0,0 @@
/*
* Copyright 2001 Mike Corrigan IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/system.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/ItLpNaca.h>
/* Array of LpEvent handler functions */
LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes];
/* Register a handler for an LpEvent type */
int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes ) {
lpEventHandler[eventType] = handler;
rc = 0;
}
return rc;
}
int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType )
{
int rc = 1;
might_sleep();
if ( eventType < HvLpEvent_Type_NumTypes ) {
if ( !lpEventHandlerPaths[eventType] ) {
lpEventHandler[eventType] = NULL;
rc = 0;
/* We now sleep until all other CPUs have scheduled. This ensures that
* the deletion is seen by all other CPUs, and that the deleted handler
* isn't still running on another CPU when we return. */
synchronize_rcu();
}
}
return rc;
}
EXPORT_SYMBOL(HvLpEvent_registerHandler);
EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
/* (lpIndex is the partition index of the target partition.
* needed only for VirtualIo, VirtualLan and SessionMgr. Zero
* indicates to use our partition index - for the other types)
*/
int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes &&
lpEventHandler[eventType] ) {
if ( lpIndex == 0 )
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_openLpEventPath( lpIndex, eventType );
++lpEventHandlerPaths[eventType];
rc = 0;
}
return rc;
}
int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex )
{
int rc = 1;
if ( eventType < HvLpEvent_Type_NumTypes &&
lpEventHandler[eventType] &&
lpEventHandlerPaths[eventType] ) {
if ( lpIndex == 0 )
lpIndex = itLpNaca.xLpIndex;
HvCallEvent_closeLpEventPath( lpIndex, eventType );
--lpEventHandlerPaths[eventType];
rc = 0;
}
return rc;
}

View File

@ -16,17 +16,10 @@ obj-y += vdso32/ vdso64/
obj-$(CONFIG_PPC_OF) += of_device.o obj-$(CONFIG_PPC_OF) += of_device.o
pci-obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_irq.o \
iSeries_VpdInfo.o
pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o pci-obj-$(CONFIG_PPC_MULTIPLATFORM) += pci_dn.o pci_direct_iommu.o
obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y) obj-$(CONFIG_PCI) += pci.o pci_iommu.o iomap.o $(pci-obj-y)
obj-$(CONFIG_PPC_ISERIES) += HvCall.o HvLpConfig.o LparData.o \
iSeries_setup.o ItLpQueue.o hvCall.o \
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
iSeries_iommu.o
obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o obj-$(CONFIG_PPC_MULTIPLATFORM) += nvram.o i8259.o prom_init.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \ obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
@ -45,14 +38,12 @@ obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o obj-$(CONFIG_PPC_RTAS) += rtas.o rtas_pci.o
obj-$(CONFIG_RTAS_PROC) += rtas-proc.o obj-$(CONFIG_RTAS_PROC) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_VIOPATH) += viopath.o
obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_LPARCFG) += lparcfg.o
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o obj-$(CONFIG_BOOTX_TEXT) += btext.o
obj-$(CONFIG_HVCS) += hvcserver.o obj-$(CONFIG_HVCS) += hvcserver.o
vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o vio-obj-$(CONFIG_PPC_PSERIES) += pSeries_vio.o
vio-obj-$(CONFIG_PPC_ISERIES) += iSeries_vio.o
obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y) obj-$(CONFIG_IBMVIO) += vio.o $(vio-obj-y)
obj-$(CONFIG_XICS) += xics.o obj-$(CONFIG_XICS) += xics.o
obj-$(CONFIG_MPIC) += mpic.o obj-$(CONFIG_MPIC) += mpic.o
@ -68,7 +59,6 @@ obj-$(CONFIG_U3_DART) += u3_iommu.o
ifdef CONFIG_SMP ifdef CONFIG_SMP
obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o obj-$(CONFIG_PPC_PMAC) += pmac_smp.o smp-tbsync.o
obj-$(CONFIG_PPC_ISERIES) += iSeries_smp.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o obj-$(CONFIG_PPC_PSERIES) += pSeries_smp.o
obj-$(CONFIG_PPC_BPA) += pSeries_smp.o obj-$(CONFIG_PPC_BPA) += pSeries_smp.o
obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o

View File

@ -39,8 +39,8 @@
#include <asm/pmac_feature.h> #include <asm/pmac_feature.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "bpa_iommu.h" #include "bpa_iommu.h"
static inline unsigned long static inline unsigned long

View File

@ -43,8 +43,8 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/nvram.h> #include <asm/nvram.h>
#include <asm/cputable.h> #include <asm/cputable.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "bpa_iic.h" #include "bpa_iic.h"
#include "bpa_iommu.h" #include "bpa_iommu.h"

View File

@ -33,7 +33,7 @@
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/atomic.h> #include <asm/atomic.h>
#include <asm/systemcfg.h> #include <asm/systemcfg.h>
#include "pci.h" #include <asm/ppc-pci.h>
#undef DEBUG #undef DEBUG

View File

@ -1253,7 +1253,7 @@ unrecov_slb:
* *
* On iSeries, the hypervisor must fill in at least one entry before * On iSeries, the hypervisor must fill in at least one entry before
* we get control (with relocate on). The address is give to the hv * we get control (with relocate on). The address is give to the hv
* as a page number (see xLparMap in LparData.c), so this must be at a * as a page number (see xLparMap in lpardata.c), so this must be at a
* fixed address (the linker can't compute (u64)&initial_stab >> * fixed address (the linker can't compute (u64)&initial_stab >>
* PAGE_SHIFT). * PAGE_SHIFT).
*/ */

View File

@ -23,8 +23,7 @@
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG(x...) printk(x) #define DBG(x...) printk(x)

View File

@ -64,44 +64,6 @@ _GLOBAL(get_srr1)
_GLOBAL(get_sp) _GLOBAL(get_sp)
mr r3,r1 mr r3,r1
blr blr
#ifdef CONFIG_PPC_ISERIES
/* unsigned long local_save_flags(void) */
_GLOBAL(local_get_flags)
lbz r3,PACAPROCENABLED(r13)
blr
/* unsigned long local_irq_disable(void) */
_GLOBAL(local_irq_disable)
lbz r3,PACAPROCENABLED(r13)
li r4,0
stb r4,PACAPROCENABLED(r13)
blr /* Done */
/* void local_irq_restore(unsigned long flags) */
_GLOBAL(local_irq_restore)
lbz r5,PACAPROCENABLED(r13)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
cmpdi 0,r3,0
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
ld r4,PACALPPACA+LPPACAANYINT(r13)
cmpdi r4,0
beqlr
/*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
sc
blr
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_IRQSTACKS #ifdef CONFIG_IRQSTACKS
_GLOBAL(call_do_softirq) _GLOBAL(call_do_softirq)

View File

@ -47,7 +47,7 @@
#include <asm/systemcfg.h> #include <asm/systemcfg.h>
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/tce.h> #include <asm/tce.h>
#include "pci.h" #include <asm/ppc-pci.h>
#define DBG(fmt...) #define DBG(fmt...)

View File

@ -29,8 +29,7 @@
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/ppc-pci.h>
#include "pci.h"
static int __initdata s7a_workaround = -1; static int __initdata s7a_workaround = -1;

View File

@ -63,9 +63,9 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/pmc.h> #include <asm/pmc.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/ppc-pci.h>
#include "i8259.h" #include "i8259.h"
#include "pci.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)

View File

@ -31,8 +31,7 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/udbg.h> #include <asm/udbg.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#ifdef DEBUG #ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt) #define DBG(fmt...) udbg_printf(fmt)

View File

@ -27,8 +27,7 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/pmac_feature.h> #include <asm/pmac_feature.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/ppc-pci.h>
#include "pci.h"
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size, static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
dma_addr_t *dma_handle, unsigned int __nocast flag) dma_addr_t *dma_handle, unsigned int __nocast flag)

View File

@ -30,8 +30,7 @@
#include <asm/prom.h> #include <asm/prom.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/pSeries_reconfig.h> #include <asm/pSeries_reconfig.h>
#include <asm/ppc-pci.h>
#include "pci.h"
/* /*
* Traverse_func that inits the PCI fields of the device node. * Traverse_func that inits the PCI fields of the device node.

View File

@ -37,7 +37,7 @@
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
#include <asm/machdep.h> #include <asm/machdep.h>
#include "pci.h" #include <asm/ppc-pci.h>
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/iSeries_pci.h> #include <asm/iSeries/iSeries_pci.h>
@ -61,13 +61,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
} else } else
pdev = to_pci_dev(dev); pdev = to_pci_dev(dev);
#ifdef CONFIG_PPC_ISERIES
return ISERIES_DEVNODE(pdev)->iommu_table;
#endif /* CONFIG_PPC_ISERIES */
#ifdef CONFIG_PPC_MULTIPLATFORM
return PCI_DN(PCI_GET_DN(pdev))->iommu_table; return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
#endif /* CONFIG_PPC_MULTIPLATFORM */
} }

View File

@ -27,8 +27,8 @@
#include <asm/machdep.h> #include <asm/machdep.h>
#include <asm/pmac_feature.h> #include <asm/pmac_feature.h>
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/ppc-pci.h>
#include "pci.h"
#include "pmac.h" #include "pmac.h"
#define DEBUG #define DEBUG

View File

@ -19,7 +19,6 @@
#include <asm/hw_irq.h> #include <asm/hw_irq.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/iSeries/HvCallSc.h>
EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strcpy);
EXPORT_SYMBOL(strncpy); EXPORT_SYMBOL(strncpy);
@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(reloc_offset); EXPORT_SYMBOL(reloc_offset);
#ifdef CONFIG_PPC_ISERIES
EXPORT_SYMBOL(HvCall0);
EXPORT_SYMBOL(HvCall1);
EXPORT_SYMBOL(HvCall2);
EXPORT_SYMBOL(HvCall3);
EXPORT_SYMBOL(HvCall4);
EXPORT_SYMBOL(HvCall5);
EXPORT_SYMBOL(HvCall6);
EXPORT_SYMBOL(HvCall7);
#endif
EXPORT_SYMBOL(_insb); EXPORT_SYMBOL(_insb);
EXPORT_SYMBOL(_outsb); EXPORT_SYMBOL(_outsb);
EXPORT_SYMBOL(_insw); EXPORT_SYMBOL(_insw);
@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
EXPORT_SYMBOL(__flush_icache_range); EXPORT_SYMBOL(__flush_icache_range);
EXPORT_SYMBOL(flush_dcache_range); EXPORT_SYMBOL(flush_dcache_range);
#ifdef CONFIG_SMP
#ifdef CONFIG_PPC_ISERIES
EXPORT_SYMBOL(local_get_flags);
EXPORT_SYMBOL(local_irq_disable);
EXPORT_SYMBOL(local_irq_restore);
#endif
#endif
EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memmove);

View File

@ -39,8 +39,7 @@
#include <asm/iommu.h> #include <asm/iommu.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/mpic.h> #include <asm/mpic.h>
#include <asm/ppc-pci.h>
#include "pci.h"
/* RTAS tokens */ /* RTAS tokens */
static int read_pci_config; static int read_pci_config;

View File

@ -43,11 +43,8 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/rtas.h> #include <asm/rtas.h>
#include <asm/iSeries/mf.h>
#include <asm/machdep.h> #include <asm/machdep.h>
extern int piranha_simulator;
/* /*
* We sponge a minor off of the misc major. No need slurping * We sponge a minor off of the misc major. No need slurping
* up another valuable major dev number for this. If you add * up another valuable major dev number for this. If you add
@ -265,40 +262,6 @@ static int rtc_read_proc(char *page, char **start, off_t off,
return len; return len;
} }
#ifdef CONFIG_PPC_ISERIES
/*
* Get the RTC from the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
if (piranha_simulator)
return;
mf_get_rtc(rtc_tm);
rtc_tm->tm_mon--;
}
/*
* Set the RTC in the virtual service processor
* This requires flowing LpEvents to the primary partition
*/
int iSeries_set_rtc_time(struct rtc_time *tm)
{
mf_set_rtc(tm);
return 0;
}
void iSeries_get_boot_time(struct rtc_time *tm)
{
if ( piranha_simulator )
return;
mf_get_boot_rtc(tm);
tm->tm_mon -= 1;
}
#endif
#ifdef CONFIG_PPC_RTAS #ifdef CONFIG_PPC_RTAS
#define MAX_RTC_WAIT 5000 /* 5 sec */ #define MAX_RTC_WAIT 5000 /* 5 sec */
#define RTAS_CLOCK_BUSY (-2) #define RTAS_CLOCK_BUSY (-2)

View File

@ -53,8 +53,7 @@
#include <asm/time.h> #include <asm/time.h>
#include <asm/mmu_context.h> #include <asm/mmu_context.h>
#include <asm/systemcfg.h> #include <asm/systemcfg.h>
#include <asm/ppc-pci.h>
#include "pci.h"
/* readdir & getdents */ /* readdir & getdents */
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))

View File

@ -45,8 +45,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/lmb.h> #include <asm/lmb.h>
#include <asm/dart.h> #include <asm/dart.h>
#include <asm/ppc-pci.h>
#include "pci.h"
extern int iommu_force_on; extern int iommu_force_on;

View File

@ -6,8 +6,8 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
*/ */
#ifndef __PPC_KERNEL_PCI_H__ #ifndef _ASM_POWERPC_PPC_PCI_H
#define __PPC_KERNEL_PCI_H__ #define _ASM_POWERPC_PPC_PCI_H
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/pci-bridge.h> #include <asm/pci-bridge.h>
@ -51,4 +51,4 @@ extern unsigned long pci_probe_only;
extern unsigned long pci_assign_all_buses; extern unsigned long pci_assign_all_buses;
extern int pci_read_irq_line(struct pci_dev *pci_dev); extern int pci_read_irq_line(struct pci_dev *pci_dev);
#endif /* __PPC_KERNEL_PCI_H__ */ #endif /* _ASM_POWERPC_PPC_PCI_H */

View File

@ -30,21 +30,19 @@
* End Change Activity * End Change Activity
*/ */
#include <asm/iSeries/HvCallPci.h>
#include <asm/abs_addr.h> #include <asm/abs_addr.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
struct pci_dev; /* For Forward Reference */ struct pci_dev; /* For Forward Reference */
struct iSeries_Device_Node;
/* /*
* Gets iSeries Bus, SubBus, DevFn using iSeries_Device_Node structure * Gets iSeries Bus, SubBus, DevFn using device_node structure
*/ */
#define ISERIES_BUS(DevPtr) DevPtr->DsaAddr.Dsa.busNumber #define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber
#define ISERIES_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber #define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber
#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId #define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata)
#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr
#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata)
#define EADsMaxAgents 7 #define EADsMaxAgents 7
@ -67,22 +65,6 @@ struct iSeries_Device_Node;
#define ISERIES_HV_ADDR(virtaddr) \ #define ISERIES_HV_ADDR(virtaddr) \
(0x8000000000000000 | virt_to_abs(virtaddr)) (0x8000000000000000 | virt_to_abs(virtaddr))
/*
* iSeries Device Information
*/
struct iSeries_Device_Node {
struct list_head Device_List;
struct pci_dev *PciDev;
union HvDsaMap DsaAddr; /* Direct Select Address */
/* busNumber, subBusNumber, */
/* deviceId, barNumber */
int DevFn; /* Linux devfn */
int Irq; /* Assigned IRQ */
int Flags; /* Possible flags(disable/bist)*/
u8 LogicalSlot; /* Hv Slot Index for Tces */
struct iommu_table *iommu_table;/* Device TCE Table */
};
extern void iSeries_Device_Information(struct pci_dev*, int); extern void iSeries_Device_Information(struct pci_dev*, int);
#endif /* _ISERIES_64_PCI_H */ #endif /* _ISERIES_64_PCI_H */

View File

@ -49,6 +49,7 @@ struct iommu_table {
}; };
struct scatterlist; struct scatterlist;
struct device_node;
#ifdef CONFIG_PPC_MULTIPLATFORM #ifdef CONFIG_PPC_MULTIPLATFORM
@ -70,9 +71,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn);
#ifdef CONFIG_PPC_ISERIES #ifdef CONFIG_PPC_ISERIES
struct iSeries_Device_Node;
/* Creates table for an individual device node */ /* Creates table for an individual device node */
extern void iommu_devnode_init_iSeries(struct iSeries_Device_Node *dn); extern void iommu_devnode_init_iSeries(struct device_node *dn);
#endif /* CONFIG_PPC_ISERIES */ #endif /* CONFIG_PPC_ISERIES */

View File

@ -4,6 +4,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/iSeries/HvCallPci.h>
/* /*
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@ -71,6 +73,14 @@ struct pci_dn {
struct iommu_table *iommu_table; /* for phb's or bridges */ struct iommu_table *iommu_table; /* for phb's or bridges */
struct pci_dev *pcidev; /* back-pointer to the pci device */ struct pci_dev *pcidev; /* back-pointer to the pci device */
struct device_node *node; /* back-pointer to the device_node */ struct device_node *node; /* back-pointer to the device_node */
#ifdef CONFIG_PPC_ISERIES
union HvDsaMap DsaAddr; /* Direct Select Address */
/* busNumber, subBusNumber, */
/* deviceId, barNumber */
int Irq; /* Assigned IRQ */
int Flags; /* Possible flags(disable/bist)*/
u8 LogicalSlot; /* Hv Slot Index for Tces */
#endif
u32 config_space[16]; /* saved PCI config space */ u32 config_space[16]; /* saved PCI config space */
}; };

View File

@ -137,6 +137,9 @@ struct device_node {
struct kref kref; struct kref kref;
unsigned long _flags; unsigned long _flags;
void *data; void *data;
#ifdef CONFIG_PPC_ISERIES
struct list_head Device_List;
#endif
}; };
extern struct device_node *of_chosen; extern struct device_node *of_chosen;