mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 18:53:52 +08:00
Merge Stephen Rothwell's patches
This commit is contained in:
commit
952ecef7a0
@ -1,4 +1,7 @@
|
||||
obj-$(CONFIG_PPC_PMAC) += powermac/
|
||||
obj-$(CONFIG_4xx) += 4xx/
|
||||
obj-$(CONFIG_83xx) += 83xx/
|
||||
obj-$(CONFIG_85xx) += 85xx/
|
||||
ifeq ($(CONFIG_PPC32),y)
|
||||
obj-$(CONFIG_PPC_PMAC) += powermac/
|
||||
endif
|
||||
obj-$(CONFIG_4xx) += 4xx/
|
||||
obj-$(CONFIG_83xx) += 83xx/
|
||||
obj-$(CONFIG_85xx) += 85xx/
|
||||
obj-$(CONFIG_PPC_ISERIES) += iseries/
|
||||
|
7
arch/powerpc/platforms/iseries/Makefile
Normal file
7
arch/powerpc/platforms/iseries/Makefile
Normal 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
|
@ -1,10 +1,10 @@
|
||||
/*
|
||||
* iSeries hashtable management.
|
||||
* Derived from pSeries_htab.c
|
||||
* Derived from pSeries_htab.c
|
||||
*
|
||||
* SMP scalability work:
|
||||
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -18,7 +18,8 @@
|
||||
#include <asm/abs_addr.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
|
||||
@ -126,7 +127,7 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
|
||||
hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);
|
||||
|
||||
if (! (hpte_v & HPTE_V_BOLTED)) {
|
||||
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
|
||||
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
|
||||
slot_offset, 0, 0);
|
||||
iSeries_hunlock(hpte_group);
|
||||
return i;
|
||||
@ -143,9 +144,9 @@ static long iSeries_hpte_remove(unsigned long hpte_group)
|
||||
|
||||
/*
|
||||
* The HyperVisor expects the "flags" argument in this form:
|
||||
* bits 0..59 : reserved
|
||||
* bit 60 : N
|
||||
* bits 61..63 : PP2,PP1,PP0
|
||||
* bits 0..59 : reserved
|
||||
* bit 60 : N
|
||||
* bits 61..63 : PP2,PP1,PP0
|
||||
*/
|
||||
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
* 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 (slot < 0) {
|
||||
slot &= 0x7fffffffffffffff;
|
||||
@ -216,7 +217,7 @@ static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
|
||||
vsid = get_kernel_vsid(ea);
|
||||
va = (vsid << 28) | (ea & 0x0fffffff);
|
||||
vpn = va >> PAGE_SHIFT;
|
||||
slot = iSeries_hpte_find(vpn);
|
||||
slot = iSeries_hpte_find(vpn);
|
||||
if (slot == -1)
|
||||
panic("updateboltedpp: Could not find page to bolt\n");
|
||||
HvCallHpt_setPp(slot, newpp);
|
||||
@ -234,7 +235,7 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
|
||||
iSeries_hlock(slot);
|
||||
|
||||
hpte_v = iSeries_hpte_getword0(slot);
|
||||
|
||||
|
||||
if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))
|
||||
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
|
||||
|
||||
@ -249,7 +250,7 @@ void hpte_init_iSeries(void)
|
||||
ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
|
||||
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
|
||||
ppc_md.hpte_insert = iSeries_hpte_insert;
|
||||
ppc_md.hpte_remove = iSeries_hpte_remove;
|
||||
ppc_md.hpte_remove = iSeries_hpte_remove;
|
||||
|
||||
htab_finish_init();
|
||||
}
|
@ -1,7 +1,4 @@
|
||||
/*
|
||||
* arch/ppc64/kernel/hvCall.S
|
||||
*
|
||||
*
|
||||
* This file contains the code to perform calls to the
|
||||
* iSeries LPAR hypervisor
|
||||
*
|
||||
@ -16,12 +13,12 @@
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
/*
|
||||
* Hypervisor call
|
||||
*
|
||||
*
|
||||
* Invoke the iSeries hypervisor via the System Call instruction
|
||||
* Parameters are passed to this routine in registers r3 - r10
|
||||
*
|
||||
*
|
||||
* r3 contains the HV function to be called
|
||||
* r4-r10 contain the operands to the hypervisor function
|
||||
*
|
||||
@ -41,11 +38,11 @@ _GLOBAL(HvCall7)
|
||||
mfcr r0
|
||||
std r0,-8(r1)
|
||||
stdu r1,-(STACK_FRAME_OVERHEAD+16)(r1)
|
||||
|
||||
|
||||
/* r0 = 0xffffffffffffffff indicates a hypervisor call */
|
||||
|
||||
|
||||
li r0,-1
|
||||
|
||||
|
||||
/* Invoke the hypervisor */
|
||||
|
||||
sc
|
||||
@ -55,7 +52,7 @@ _GLOBAL(HvCall7)
|
||||
mtcrf 0xff,r0
|
||||
|
||||
/* return to caller, return value in r3 */
|
||||
|
||||
|
||||
blr
|
||||
|
||||
_GLOBAL(HvCall0Ret16)
|
||||
@ -92,7 +89,5 @@ _GLOBAL(HvCall7Ret16)
|
||||
ld r0,-8(r1)
|
||||
mtcrf 0xff,r0
|
||||
ld r31,-16(r1)
|
||||
|
||||
|
||||
blr
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvCall.c
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvLpConfig.c
|
||||
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
@ -1,6 +1,4 @@
|
||||
/*
|
||||
* arch/ppc64/kernel/iSeries_iommu.c
|
||||
*
|
||||
* Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
|
||||
*
|
||||
* 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)
|
||||
{
|
||||
struct iSeries_Device_Node *dp;
|
||||
struct device_node *dp;
|
||||
|
||||
list_for_each_entry(dp, &iSeries_Global_Device_List, Device_List) {
|
||||
if ((dp->iommu_table != NULL) &&
|
||||
(dp->iommu_table->it_type == TCE_PCI) &&
|
||||
(dp->iommu_table->it_offset == tbl->it_offset) &&
|
||||
(dp->iommu_table->it_index == tbl->it_index) &&
|
||||
(dp->iommu_table->it_size == tbl->it_size))
|
||||
return dp->iommu_table;
|
||||
struct iommu_table *it = PCI_DN(dp)->iommu_table;
|
||||
|
||||
if ((it != NULL) &&
|
||||
(it->it_type == TCE_PCI) &&
|
||||
(it->it_offset == tbl->it_offset) &&
|
||||
(it->it_index == tbl->it_index) &&
|
||||
(it->it_size == tbl->it_size))
|
||||
return it;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@ -113,7 +113,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
|
||||
* 2. TCE table per Bus.
|
||||
* 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_cb *parms;
|
||||
@ -125,7 +125,7 @@ static void iommu_table_getparms(struct iSeries_Device_Node* dn,
|
||||
memset(parms, 0, sizeof(*parms));
|
||||
|
||||
parms->itc_busno = ISERIES_BUS(dn);
|
||||
parms->itc_slotno = dn->LogicalSlot;
|
||||
parms->itc_slotno = PCI_DN(dn)->LogicalSlot;
|
||||
parms->itc_virtbus = 0;
|
||||
|
||||
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 pci_dn *pdn = PCI_DN(dn);
|
||||
|
||||
tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);
|
||||
|
||||
iommu_table_getparms(dn, tbl);
|
||||
|
||||
/* Look for existing tce table */
|
||||
dn->iommu_table = iommu_table_find(tbl);
|
||||
if (dn->iommu_table == NULL)
|
||||
dn->iommu_table = iommu_init_table(tbl);
|
||||
pdn->iommu_table = iommu_table_find(tbl);
|
||||
if (pdn->iommu_table == NULL)
|
||||
pdn->iommu_table = iommu_init_table(tbl);
|
||||
else
|
||||
kfree(tbl);
|
||||
}
|
@ -363,4 +363,3 @@ void virt_irq_init(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
27
arch/powerpc/platforms/iseries/ksyms.c
Normal file
27
arch/powerpc/platforms/iseries/ksyms.c
Normal 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
|
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* Copyright 2001 Mike Corrigan, IBM Corp
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@ -29,8 +29,8 @@
|
||||
#include <asm/iSeries/ItSpCommArea.h>
|
||||
|
||||
|
||||
/* The HvReleaseData is the root of the information shared between
|
||||
* the hypervisor and Linux.
|
||||
/* The HvReleaseData is the root of the information shared between
|
||||
* the hypervisor and Linux.
|
||||
*/
|
||||
struct HvReleaseData hvReleaseData = {
|
||||
.xDesc = 0xc8a5d9c4, /* "HvRD" ebcdic */
|
||||
@ -79,7 +79,7 @@ extern void trap_0e_iSeries(void);
|
||||
extern void performance_monitor_iSeries(void);
|
||||
extern void data_access_slb_iSeries(void);
|
||||
extern void instruction_access_slb_iSeries(void);
|
||||
|
||||
|
||||
struct ItLpNaca itLpNaca = {
|
||||
.xDesc = 0xd397d581, /* "LpNa" ebcdic */
|
||||
.xSize = 0x0400, /* size of ItLpNaca */
|
||||
@ -106,7 +106,7 @@ struct ItLpNaca itLpNaca = {
|
||||
.xLoadAreaChunks = 0, /* chunks for load area */
|
||||
.xPaseSysCallCRMask = 0, /* PASE mask */
|
||||
.xSlicSegmentTablePtr = 0, /* seg table */
|
||||
.xOldLpQueue = { 0 }, /* Old LP Queue */
|
||||
.xOldLpQueue = { 0 }, /* Old LP Queue */
|
||||
.xInterruptHdlr = {
|
||||
(u64)system_reset_iSeries, /* 0x100 System Reset */
|
||||
(u64)machine_check_iSeries, /* 0x200 Machine Check */
|
||||
@ -134,7 +134,7 @@ struct ItLpNaca itLpNaca = {
|
||||
EXPORT_SYMBOL(itLpNaca);
|
||||
|
||||
/* 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 */
|
||||
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
|
||||
@ -151,7 +151,7 @@ struct IoHriProcessorVpd xIoHriProcessorVpd[maxPhysicalProcessors] = {
|
||||
.xPVR = 0x3600
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* Space for Main Store Vpd 27,200 bytes */
|
||||
/* May be filled in by the hypervisor so cannot end up in the BSS */
|
||||
u64 xMsVpd[3400] __attribute__((__section__(".data")));
|
||||
@ -197,7 +197,7 @@ struct ItVpdAreas itVpdAreas = {
|
||||
26992, /* 7 length of MS VPD */
|
||||
0, /* 8 */
|
||||
sizeof(struct ItLpNaca),/* 9 length of LP Naca */
|
||||
0, /* 10 */
|
||||
0, /* 10 */
|
||||
256, /* 11 length of Recovery Log Buf */
|
||||
sizeof(struct SpCommArea), /* 12 length of SP Comm Area */
|
||||
0,0,0, /* 13 - 15 */
|
||||
@ -207,7 +207,7 @@ struct ItVpdAreas itVpdAreas = {
|
||||
0,0 /* 24 - 25 */
|
||||
},
|
||||
.xSlicVpdAdrs = { /* VPD addresses */
|
||||
0,0,0, /* 0 - 2 */
|
||||
0,0,0, /* 0 - 2 */
|
||||
&xItExtVpdPanel, /* 3 Extended VPD */
|
||||
&paca[0], /* 4 first Paca */
|
||||
0, /* 5 */
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* ItLpQueue.c
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -19,6 +18,7 @@
|
||||
#include <asm/iSeries/ItLpQueue.h>
|
||||
#include <asm/iSeries/HvLpEvent.h>
|
||||
#include <asm/iSeries/HvCallEvent.h>
|
||||
#include <asm/iSeries/ItLpNaca.h>
|
||||
|
||||
/*
|
||||
* 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 */
|
||||
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)
|
||||
{
|
||||
@ -199,6 +200,70 @@ void setup_hvlpevent_queue(void)
|
||||
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)
|
||||
{
|
||||
int cpu, i;
|
@ -1,29 +1,28 @@
|
||||
/*
|
||||
* mf.c
|
||||
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
|
||||
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
|
||||
*
|
||||
* This modules exists as an interface between a Linux secondary partition
|
||||
* running on an iSeries and the primary partition's Virtual Service
|
||||
* Processor (VSP) object. The VSP has final authority over powering on/off
|
||||
* all partitions in the iSeries. It also provides miscellaneous low-level
|
||||
* machine facility type operations.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
|
||||
* Copyright (C) 2004-2005 Stephen Rothwell IBM Corporation
|
||||
*
|
||||
* This modules exists as an interface between a Linux secondary partition
|
||||
* running on an iSeries and the primary partition's Virtual Service
|
||||
* Processor (VSP) object. The VSP has final authority over powering on/off
|
||||
* all partitions in the iSeries. It also provides miscellaneous low-level
|
||||
* machine facility type operations.
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
@ -42,6 +41,10 @@
|
||||
#include <asm/iSeries/HvLpConfig.h>
|
||||
#include <asm/iSeries/ItLpQueue.h>
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
extern int piranha_simulator;
|
||||
|
||||
/*
|
||||
* This is the structure layout for the Machine Facilites LPAR event
|
||||
* flows.
|
||||
@ -1279,3 +1282,35 @@ static int __init mf_proc_init(void)
|
||||
__initcall(mf_proc_init);
|
||||
|
||||
#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;
|
||||
}
|
55
arch/powerpc/platforms/iseries/misc.S
Normal file
55
arch/powerpc/platforms/iseries/misc.S
Normal 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
|
@ -1,28 +1,26 @@
|
||||
/*
|
||||
* iSeries_pci.c
|
||||
*
|
||||
* Copyright (C) 2001 Allan Trautman, IBM Corporation
|
||||
*
|
||||
* iSeries specific routines for PCI.
|
||||
*
|
||||
*
|
||||
* Based on code from pci.c and iSeries_pci.c 32bit
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
@ -43,14 +41,14 @@
|
||||
#include <asm/iSeries/iSeries_pci.h>
|
||||
#include <asm/iSeries/mf.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
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_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel);
|
||||
static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info);
|
||||
@ -68,7 +66,7 @@ static long Pci_Cfg_Write_Count;
|
||||
#endif
|
||||
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 struct pci_ops iSeries_pci_ops;
|
||||
@ -87,7 +85,7 @@ static long current_iomm_table_entry;
|
||||
/*
|
||||
* Lookup Tables.
|
||||
*/
|
||||
static struct iSeries_Device_Node **iomm_table;
|
||||
static struct device_node **iomm_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) {
|
||||
bar_res = &dev->resource[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)
|
||||
*/
|
||||
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)
|
||||
{
|
||||
struct iSeries_Device_Node *node;
|
||||
struct device_node *node;
|
||||
struct pci_dn *pdn;
|
||||
|
||||
PPCDBG(PPCDBG_BUSWALK,
|
||||
"-build_device_node 0x%02X.%02X.%02X Function: %02X\n",
|
||||
Bus, SubBus, AgentId, Function);
|
||||
|
||||
node = kmalloc(sizeof(struct iSeries_Device_Node), GFP_KERNEL);
|
||||
node = kmalloc(sizeof(struct device_node), GFP_KERNEL);
|
||||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(node, 0, sizeof(struct iSeries_Device_Node));
|
||||
memset(node, 0, sizeof(struct 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);
|
||||
#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
|
||||
node->DsaAddr.DsaAddr = 0;
|
||||
node->DsaAddr.Dsa.busNumber = Bus;
|
||||
node->DsaAddr.Dsa.subBusNumber = SubBus;
|
||||
node->DsaAddr.Dsa.deviceId = 0x10;
|
||||
node->DevFn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
|
||||
pdn->DsaAddr.DsaAddr = 0;
|
||||
pdn->DsaAddr.Dsa.busNumber = Bus;
|
||||
pdn->DsaAddr.Dsa.subBusNumber = SubBus;
|
||||
pdn->DsaAddr.Dsa.deviceId = 0x10;
|
||||
pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function);
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -278,28 +282,28 @@ unsigned long __init find_and_init_phbs(void)
|
||||
|
||||
/*
|
||||
* iSeries_pcibios_init
|
||||
*
|
||||
*
|
||||
* Chance to initialize and structures or variable before PCI Bus walk.
|
||||
*/
|
||||
void iSeries_pcibios_init(void)
|
||||
{
|
||||
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
|
||||
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_init Entry.\n");
|
||||
iomm_table_initialize();
|
||||
find_and_init_phbs();
|
||||
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)
|
||||
{
|
||||
struct pci_dev *pdev = NULL;
|
||||
struct iSeries_Device_Node *node;
|
||||
int DeviceCount = 0;
|
||||
struct device_node *node;
|
||||
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 */
|
||||
mf_display_src(0xC9000100);
|
||||
@ -313,7 +317,7 @@ void __init iSeries_pci_final_fixup(void)
|
||||
if (node != NULL) {
|
||||
++DeviceCount;
|
||||
pdev->sysdata = (void *)node;
|
||||
node->PciDev = pdev;
|
||||
PCI_DN(node)->pcidev = pdev;
|
||||
PPCDBG(PPCDBG_BUSWALK,
|
||||
"pdev 0x%p <==> DevNode 0x%p\n",
|
||||
pdev, node);
|
||||
@ -323,7 +327,7 @@ void __init iSeries_pci_final_fixup(void)
|
||||
} else
|
||||
printk("PCI: Device Tree not found for 0x%016lX\n",
|
||||
(unsigned long)pdev);
|
||||
pdev->irq = node->Irq;
|
||||
pdev->irq = PCI_DN(node)->Irq;
|
||||
}
|
||||
iSeries_activate_IRQs();
|
||||
mf_display_src(0xC9000200);
|
||||
@ -332,24 +336,24 @@ void __init iSeries_pci_final_fixup(void)
|
||||
void pcibios_fixup_bus(struct pci_bus *PciBus)
|
||||
{
|
||||
PPCDBG(PPCDBG_BUSWALK, "iSeries_pcibios_fixup_bus(0x%04X) Entry.\n",
|
||||
PciBus->number);
|
||||
PciBus->number);
|
||||
}
|
||||
|
||||
void pcibios_fixup_resources(struct pci_dev *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)
|
||||
{
|
||||
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. */
|
||||
int HvRc = 0;
|
||||
int IdSel;
|
||||
int IdSel;
|
||||
const int MaxAgents = 8;
|
||||
|
||||
DevInfo = (struct HvCallPci_DeviceInfo*)
|
||||
@ -358,10 +362,10 @@ static void scan_PHB_slots(struct pci_controller *Phb)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Probe for EADs Bridges
|
||||
* Probe for EADs Bridges
|
||||
*/
|
||||
for (IdSel = 1; IdSel < MaxAgents; ++IdSel) {
|
||||
HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
|
||||
HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel,
|
||||
ISERIES_HV_ADDR(DevInfo),
|
||||
sizeof(struct HvCallPci_DeviceInfo));
|
||||
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! */
|
||||
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);
|
||||
if (HvRc == 0) {
|
||||
if (HvRc == 0) {
|
||||
printk("found device at bus %d idsel %d func %d (AgentId %x)\n",
|
||||
bus, IdSel, Function, AgentId);
|
||||
/* Connect EADs: 0x18.00.12 = 0x00 */
|
||||
/* Connect EADs: 0x18.00.12 = 0x00 */
|
||||
PPCDBG(PPCDBG_BUSWALK,
|
||||
"PCI:Connect EADs: 0x%02X.%02X.%02X\n",
|
||||
bus, SubBus, AgentId);
|
||||
HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
|
||||
HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId,
|
||||
ISERIES_HV_ADDR(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",
|
||||
BridgeInfo->busUnitInfo.deviceType,
|
||||
BridgeInfo->subBusNumber,
|
||||
@ -428,7 +432,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
|
||||
printk("PCI: Invalid Bridge Configuration(0x%02X)",
|
||||
BridgeInfo->busUnitInfo.deviceType);
|
||||
}
|
||||
} else if (HvRc != 0x000B)
|
||||
} else if (HvRc != 0x000B)
|
||||
pci_Log_Error("EADs Connect",
|
||||
bus, SubBus, AgentId, HvRc);
|
||||
}
|
||||
@ -441,7 +445,7 @@ static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus,
|
||||
static int scan_bridge_slot(HvBusNumber Bus,
|
||||
struct HvCallPci_BridgeInfo *BridgeInfo)
|
||||
{
|
||||
struct iSeries_Device_Node *node;
|
||||
struct device_node *node;
|
||||
HvSubBusNumber SubBus = BridgeInfo->subBusNumber;
|
||||
u16 VendorId = 0;
|
||||
int HvRc = 0;
|
||||
@ -451,16 +455,16 @@ static int scan_bridge_slot(HvBusNumber Bus,
|
||||
HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function);
|
||||
|
||||
/* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */
|
||||
Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
|
||||
Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel);
|
||||
PPCDBG(PPCDBG_BUSWALK,
|
||||
"PCI:- allocate and assign IRQ 0x%02X.%02X.%02X = 0x%02X\n",
|
||||
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 (Function = 0; Function < 8; ++Function) {
|
||||
for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) {
|
||||
for (Function = 0; Function < 8; ++Function) {
|
||||
HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function);
|
||||
HvRc = HvCallXm_connectBusUnit(Bus, SubBus,
|
||||
AgentId, Irq);
|
||||
@ -484,15 +488,15 @@ static int scan_bridge_slot(HvBusNumber Bus,
|
||||
"PCI:- FoundDevice: 0x%02X.%02X.%02X = 0x%04X, irq %d\n",
|
||||
Bus, SubBus, AgentId, VendorId, Irq);
|
||||
HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId,
|
||||
PCI_INTERRUPT_LINE, Irq);
|
||||
PCI_INTERRUPT_LINE, Irq);
|
||||
if (HvRc != 0)
|
||||
pci_Log_Error("PciCfgStore Irq Failed!",
|
||||
Bus, SubBus, AgentId, HvRc);
|
||||
|
||||
++DeviceCount;
|
||||
node = build_device_node(Bus, SubBus, EADsIdSel, Function);
|
||||
node->Irq = Irq;
|
||||
node->LogicalSlot = BridgeInfo->logicalSlotNumber;
|
||||
PCI_DN(node)->Irq = Irq;
|
||||
PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber;
|
||||
|
||||
} /* for (Function = 0; Function < 8; ++Function) */
|
||||
} /* 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
|
||||
*/
|
||||
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;
|
||||
|
||||
list_for_each(pos, &iSeries_Global_Device_List) {
|
||||
struct iSeries_Device_Node *node =
|
||||
list_entry(pos, struct iSeries_Device_Node, Device_List);
|
||||
struct device_node *node =
|
||||
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 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
|
||||
* 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;
|
||||
if (node == NULL || node->PciDev != pdev)
|
||||
if (node == NULL || PCI_DN(node)->pcidev != pdev)
|
||||
node = find_Device_Node(pdev->bus->number, pdev->devfn);
|
||||
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,
|
||||
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;
|
||||
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];
|
||||
HvCall3Ret16(fn, &ret, node->DsaAddr.DsaAddr, offset, 0);
|
||||
HvCall3Ret16(fn, &ret, PCI_DN(node)->DsaAddr.DsaAddr, offset, 0);
|
||||
|
||||
if (ret.rc != 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,
|
||||
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 ret;
|
||||
|
||||
@ -635,7 +640,7 @@ static int iSeries_pci_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||
|
||||
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)
|
||||
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 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)
|
||||
{
|
||||
if (ret != 0) {
|
||||
struct pci_dn *pdn = PCI_DN(DevNode);
|
||||
|
||||
++Pci_Error_Count;
|
||||
(*retry)++;
|
||||
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);
|
||||
/*
|
||||
* 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
|
||||
* 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,
|
||||
u64 *dsaptr, u64 *BarOffsetPtr)
|
||||
{
|
||||
unsigned long OrigIoAddr;
|
||||
unsigned long BaseIoAddr;
|
||||
unsigned long TableIndex;
|
||||
struct iSeries_Device_Node *DevNode;
|
||||
struct device_node *DevNode;
|
||||
|
||||
OrigIoAddr = (unsigned long __force)IoAddress;
|
||||
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) {
|
||||
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;
|
||||
} else
|
||||
panic("PCI: Invalid PCI IoAddress detected!\n");
|
||||
@ -727,7 +734,7 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
struct HvCallPci_LoadReturn ret;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
||||
@ -757,7 +764,7 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
struct HvCallPci_LoadReturn ret;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
||||
@ -788,7 +795,7 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
struct HvCallPci_LoadReturn ret;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
||||
@ -826,7 +833,7 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
u64 rc;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
||||
@ -854,7 +861,7 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
u64 rc;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
||||
@ -882,7 +889,7 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
|
||||
u64 dsa;
|
||||
int retry = 0;
|
||||
u64 rc;
|
||||
struct iSeries_Device_Node *DevNode =
|
||||
struct device_node *DevNode =
|
||||
xlate_iomm_address(IoAddress, &dsa, &BarOffset);
|
||||
|
||||
if (DevNode == NULL) {
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* iSeries_proc.c
|
||||
* Copyright (C) 2001 Kyle A. Lucke 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 titan_jiffies = titan_usec / (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_jiff_ticks = tb_jiffies * tb_ticks_per_jiffy;
|
||||
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 new_tb_ticks_per_jiffy = (tb_ticks * (1000000/HZ))/titan_usec;
|
||||
unsigned long tb_jiff_rem_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, " tb elapsed = %lu ticks\n", tb_ticks);
|
@ -2,8 +2,6 @@
|
||||
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
|
||||
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
|
||||
*
|
||||
* Module name: iSeries_setup.c
|
||||
*
|
||||
* Description:
|
||||
* Architecture- / platform-specific boot-time initialization code for
|
||||
* the IBM iSeries LPAR. Adapted from original code by Grant Erickson and
|
||||
@ -42,7 +40,6 @@
|
||||
#include <asm/firmware.h>
|
||||
|
||||
#include <asm/time.h>
|
||||
#include "iSeries_setup.h"
|
||||
#include <asm/naca.h>
|
||||
#include <asm/paca.h>
|
||||
#include <asm/cache.h>
|
||||
@ -62,6 +59,8 @@
|
||||
#include <asm/iSeries/ItVpdAreas.h>
|
||||
#include <asm/iSeries/LparMap.h>
|
||||
|
||||
#include "setup.h"
|
||||
|
||||
extern void hvlog(char *fmt, ...);
|
||||
|
||||
#ifdef DEBUG
|
@ -2,8 +2,6 @@
|
||||
* Copyright (c) 2000 Mike Corrigan <mikejc@us.ibm.com>
|
||||
* Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu>
|
||||
*
|
||||
* Module name: as400_setup.h
|
||||
*
|
||||
* Description:
|
||||
* Architecture- / platform-specific boot-time initialization code for
|
||||
* the IBM AS/400 LPAR. Adapted from original code by Grant Erickson and
|
@ -47,17 +47,17 @@
|
||||
|
||||
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 msg;
|
||||
|
||||
if ( num_online_cpus() < 2 )
|
||||
if (num_online_cpus() < 2)
|
||||
return;
|
||||
|
||||
for ( msg = 0; msg < 4; ++msg )
|
||||
if ( test_and_clear_bit( msg, &iSeries_smp_message[cpu] ) )
|
||||
smp_message_recv( msg, regs );
|
||||
for (msg = 0; msg < 4; msg++)
|
||||
if (test_and_clear_bit(msg, &iSeries_smp_message[cpu]))
|
||||
smp_message_recv(msg, regs);
|
||||
}
|
||||
|
||||
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);
|
||||
else {
|
||||
for_each_online_cpu(i) {
|
||||
if (target == MSG_ALL_BUT_SELF
|
||||
&& i == smp_processor_id())
|
||||
if ((target == MSG_ALL_BUT_SELF) &&
|
||||
(i == smp_processor_id()))
|
||||
continue;
|
||||
smp_iSeries_do_message(i, msg);
|
||||
}
|
||||
@ -89,7 +89,7 @@ static int smp_iSeries_probe(void)
|
||||
|
||||
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 */
|
||||
if (paca[nr].lppaca.dyn_proc_status >= 2)
|
@ -1,5 +1,4 @@
|
||||
/* -*- linux-c -*-
|
||||
* arch/ppc64/kernel/viopath.c
|
||||
*
|
||||
* iSeries Virtual I/O Message Path code
|
||||
*
|
||||
@ -7,7 +6,7 @@
|
||||
* Ryan Arnold <ryanarn@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,
|
||||
* tape, and console to communicate with OS/400 in another
|
@ -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
|
||||
* Copyright (C) 2001 <Allan H Trautman> <IBM Corp>
|
||||
* Copyright (C) 2005 Stephen Rothwel, IBM Corp
|
||||
@ -242,7 +240,7 @@ out_free:
|
||||
*/
|
||||
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;
|
||||
u8 frame;
|
||||
char card[4];
|
@ -84,6 +84,7 @@ head-y := arch/ppc64/kernel/head.o
|
||||
libs-y += arch/ppc64/lib/
|
||||
core-y += arch/ppc64/kernel/
|
||||
core-y += arch/ppc64/mm/
|
||||
core-y += arch/powerpc/platforms/
|
||||
core-$(CONFIG_XMON) += arch/ppc64/xmon/
|
||||
drivers-$(CONFIG_OPROFILE) += arch/powerpc/oprofile/
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -16,17 +16,10 @@ obj-y += vdso32/ vdso64/
|
||||
|
||||
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
|
||||
|
||||
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_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_RTAS_PROC) += rtas-proc.o
|
||||
obj-$(CONFIG_SCANLOG) += scanlog.o
|
||||
obj-$(CONFIG_VIOPATH) += viopath.o
|
||||
obj-$(CONFIG_LPARCFG) += lparcfg.o
|
||||
obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o
|
||||
obj-$(CONFIG_BOOTX_TEXT) += btext.o
|
||||
obj-$(CONFIG_HVCS) += hvcserver.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_XICS) += xics.o
|
||||
obj-$(CONFIG_MPIC) += mpic.o
|
||||
@ -68,7 +59,6 @@ obj-$(CONFIG_U3_DART) += u3_iommu.o
|
||||
|
||||
ifdef CONFIG_SMP
|
||||
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_BPA) += pSeries_smp.o
|
||||
obj-$(CONFIG_PPC_MAPLE) += smp-tbsync.o
|
||||
|
@ -39,8 +39,8 @@
|
||||
#include <asm/pmac_feature.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include "bpa_iommu.h"
|
||||
|
||||
static inline unsigned long
|
||||
|
@ -43,8 +43,8 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/nvram.h>
|
||||
#include <asm/cputable.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include "bpa_iic.h"
|
||||
#include "bpa_iommu.h"
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <asm/rtas.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/systemcfg.h>
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#undef DEBUG
|
||||
|
||||
|
@ -1253,7 +1253,7 @@ unrecov_slb:
|
||||
*
|
||||
* 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
|
||||
* 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 >>
|
||||
* PAGE_SHIFT).
|
||||
*/
|
||||
|
@ -23,8 +23,7 @@
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/iommu.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(x...) printk(x)
|
||||
|
@ -64,44 +64,6 @@ _GLOBAL(get_srr1)
|
||||
_GLOBAL(get_sp)
|
||||
mr r3,r1
|
||||
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
|
||||
_GLOBAL(call_do_softirq)
|
||||
|
@ -47,7 +47,7 @@
|
||||
#include <asm/systemcfg.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/tce.h>
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#define DBG(fmt...)
|
||||
|
||||
|
@ -29,8 +29,7 @@
|
||||
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
static int __initdata s7a_workaround = -1;
|
||||
|
||||
|
@ -63,9 +63,9 @@
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/pmc.h>
|
||||
#include <asm/mpic.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#include "i8259.h"
|
||||
#include "pci.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) udbg_printf(fmt)
|
||||
|
@ -31,8 +31,7 @@
|
||||
#include <asm/irq.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/udbg.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DBG(fmt...) udbg_printf(fmt)
|
||||
|
@ -27,8 +27,7 @@
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pmac_feature.h>
|
||||
#include <asm/abs_addr.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
|
||||
dma_addr_t *dma_handle, unsigned int __nocast flag)
|
||||
|
@ -30,8 +30,7 @@
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/pSeries_reconfig.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
/*
|
||||
* Traverse_func that inits the PCI fields of the device node.
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/machdep.h>
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
#include <asm/iSeries/iSeries_pci.h>
|
||||
@ -61,13 +61,7 @@ static inline struct iommu_table *devnode_table(struct device *dev)
|
||||
} else
|
||||
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;
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,8 +27,8 @@
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/pmac_feature.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include "pmac.h"
|
||||
|
||||
#define DEBUG
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <asm/hw_irq.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/iSeries/HvCallSc.h>
|
||||
|
||||
EXPORT_SYMBOL(strcpy);
|
||||
EXPORT_SYMBOL(strncpy);
|
||||
@ -46,17 +45,6 @@ EXPORT_SYMBOL(__strnlen_user);
|
||||
|
||||
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(_outsb);
|
||||
EXPORT_SYMBOL(_insw);
|
||||
@ -77,14 +65,6 @@ EXPORT_SYMBOL(giveup_altivec);
|
||||
EXPORT_SYMBOL(__flush_icache_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(memset);
|
||||
EXPORT_SYMBOL(memmove);
|
||||
|
@ -39,8 +39,7 @@
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/rtas.h>
|
||||
#include <asm/mpic.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
/* RTAS tokens */
|
||||
static int read_pci_config;
|
||||
|
@ -43,11 +43,8 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/rtas.h>
|
||||
|
||||
#include <asm/iSeries/mf.h>
|
||||
#include <asm/machdep.h>
|
||||
|
||||
extern int piranha_simulator;
|
||||
|
||||
/*
|
||||
* We sponge a minor off of the misc major. No need slurping
|
||||
* 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;
|
||||
}
|
||||
|
||||
#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
|
||||
#define MAX_RTC_WAIT 5000 /* 5 sec */
|
||||
#define RTAS_CLOCK_BUSY (-2)
|
||||
|
@ -53,8 +53,7 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/systemcfg.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
/* readdir & getdents */
|
||||
#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
|
||||
|
@ -45,8 +45,7 @@
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/lmb.h>
|
||||
#include <asm/dart.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include <asm/ppc-pci.h>
|
||||
|
||||
extern int iommu_force_on;
|
||||
|
||||
|
@ -6,8 +6,8 @@
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
#ifndef __PPC_KERNEL_PCI_H__
|
||||
#define __PPC_KERNEL_PCI_H__
|
||||
#ifndef _ASM_POWERPC_PPC_PCI_H
|
||||
#define _ASM_POWERPC_PPC_PCI_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
@ -51,4 +51,4 @@ extern unsigned long pci_probe_only;
|
||||
extern unsigned long pci_assign_all_buses;
|
||||
extern int pci_read_irq_line(struct pci_dev *pci_dev);
|
||||
|
||||
#endif /* __PPC_KERNEL_PCI_H__ */
|
||||
#endif /* _ASM_POWERPC_PPC_PCI_H */
|
@ -30,21 +30,19 @@
|
||||
* End Change Activity
|
||||
*/
|
||||
|
||||
#include <asm/iSeries/HvCallPci.h>
|
||||
#include <asm/abs_addr.h>
|
||||
#include <asm/prom.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
|
||||
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_SUBBUS(DevPtr) DevPtr->DsaAddr.Dsa.subBusNumber
|
||||
#define ISERIES_DEVICE(DevPtr) DevPtr->DsaAddr.Dsa.deviceId
|
||||
#define ISERIES_DSA(DevPtr) DevPtr->DsaAddr.DsaAddr
|
||||
#define ISERIES_DEVNODE(PciDev) ((struct iSeries_Device_Node *)PciDev->sysdata)
|
||||
#define ISERIES_BUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.busNumber
|
||||
#define ISERIES_SUBBUS(DevPtr) PCI_DN(DevPtr)->DsaAddr.Dsa.subBusNumber
|
||||
#define ISERIES_DEVNODE(PciDev) ((struct device_node *)PciDev->sysdata)
|
||||
|
||||
#define EADsMaxAgents 7
|
||||
|
||||
@ -67,22 +65,6 @@ struct iSeries_Device_Node;
|
||||
#define ISERIES_HV_ADDR(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);
|
||||
|
||||
#endif /* _ISERIES_64_PCI_H */
|
||||
|
@ -49,6 +49,7 @@ struct iommu_table {
|
||||
};
|
||||
|
||||
struct scatterlist;
|
||||
struct device_node;
|
||||
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
|
||||
@ -70,9 +71,8 @@ extern void iommu_devnode_init_pSeries(struct device_node *dn);
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
|
||||
struct iSeries_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 */
|
||||
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/iSeries/HvCallPci.h>
|
||||
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* 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 pci_dev *pcidev; /* back-pointer to the pci device */
|
||||
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 */
|
||||
};
|
||||
|
||||
|
@ -137,6 +137,9 @@ struct device_node {
|
||||
struct kref kref;
|
||||
unsigned long _flags;
|
||||
void *data;
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
struct list_head Device_List;
|
||||
#endif
|
||||
};
|
||||
|
||||
extern struct device_node *of_chosen;
|
||||
|
Loading…
Reference in New Issue
Block a user