Commit 2e45b436 authored by Paul Mackerras's avatar Paul Mackerras

PPC32: remove support for IBM iSeries machines.

All the iSeries machines that can run Linux are 64-bit PowerPC
machines and are now supported by the ppc64 kernel.  Since no-one
is interested in maintaining the iSeries support in the ppc32
kernel, I am removing it.
parent 62b0c735
......@@ -77,9 +77,6 @@ config POWER3
config 8xx
bool "8xx"
config PPC_ISERIES
bool "iSeries"
endchoice
config 4xx
......@@ -105,7 +102,7 @@ config GENERIC_ISA_DMA
config PPC64BRIDGE
bool
depends on PPC_ISERIES || POWER3
depends on POWER3
default y
config ALL_PPC
......@@ -855,8 +852,7 @@ config MCA
config PCI
bool "PCI support" if 4xx || 8260
default y if !4xx && !8260 && !8xx && !APUS && !PPC_ISERIES
default PCI_ISERIES if !4xx && !8260 && !8xx && !APUS && PPC_ISERIES
default y if !4xx && !8260 && !8xx && !APUS
default PCI_PERMEDIA if !4xx && !8260 && !8xx && APUS
default PCI_QSPAN if !4xx && !8260 && 8xx
help
......@@ -880,10 +876,6 @@ config PCI_PERMEDIA
bool "PCI for Permedia2"
depends on !4xx && !8xx && APUS
config PCI_ISERIES
bool "IBM iSeries Native I/O Support"
depends on !4xx && !8260 && !8xx && !APUS && PPC_ISERIES
# only elf supported, a.out is not -- Cort
config KCORE_ELF
bool
......@@ -1423,78 +1415,7 @@ source "drivers/isdn/Kconfig"
source "drivers/video/Kconfig"
menu "iSeries device drivers"
depends on PPC_ISERIES
config VIOCONS
tristate "iSeries Virtual Console Support"
config VIODASD
tristate "iSeries Virtual I/O disk support"
config VIODASD_IDE
bool "iSeries Virtual disk IDE emulation"
depends on VIODASD
config VIOCD
tristate "iSeries Virtual I/O CD support"
config VIOCD_AZTECH
bool "iSeries Virtual CD Aztech emulation"
depends on VIOCD
config VIOTAPE
tristate "iSeries Virtual Tape Support"
config VETH
tristate "iSeries Virtual Ethernet driver support"
config VIOPATH
bool
depends on VIOCONS || VIODASD || VIOTAPE || VIOCD
default y
config CD_NO_IDESCSI
bool
depends on VIOCD=y
default y
---help---
If you have a CD-ROM drive that is neither SCSI nor IDE/ATAPI, say Y
here, otherwise N. Read the CD-ROM-HOWTO, available from
<http://www.linuxdoc.org/docs.html#howto>.
Note that the answer to this question doesn't directly affect the
kernel: saying N will just cause the configurator to skip all
the questions about these CD-ROM drives. If you are unsure what you
have, say Y and find out whether you have one of the following
drives.
For each of these drivers, a file Documentation/cdrom/{driver_name}
exists. Especially in cases where you do not know exactly which kind
of drive you have you should read there. Most of these drivers use a
file drivers/cdrom/{driver_name}.h where you can define your
interface parameters and switch some internal goodies.
All these CD-ROM drivers are also usable as a module ( = code which
can be inserted in and removed from the running kernel whenever you
want). If you want to compile them as module, say M instead of Y and
read <file:Documentation/modules.txt>.
If you want to use any of these CD-ROM drivers, you also have to
answer Y or M to "ISO 9660 CD-ROM file system support" below (this
answer will get "defaulted" for you if you enable any of the Linux
CD-ROM drivers).
config BLK_DEV_IDECD
tristate
depends on VIOCD=y
default y
endmenu
menu "Old CD-ROM drivers (not SCSI, not IDE)"
depends on !PPC_ISERIES
config CD_NO_IDESCSI
bool "Support non-SCSI/IDE/ATAPI CDROM drives"
......@@ -1830,4 +1751,3 @@ endmenu
source "security/Kconfig"
source "crypto/Kconfig"
......@@ -37,7 +37,6 @@ ifdef CONFIG_MORE_COMPILE_OPTIONS
endif
head-y := head.o
head-$(CONFIG_PPC_ISERIES) := iSeries_head.o
head-$(CONFIG_8xx) := head_8xx.o
head-$(CONFIG_4xx) := head_4xx.o
head-$(CONFIG_440) := head_44x.o
......@@ -53,7 +52,6 @@ core-$(CONFIG_4xx) += arch/ppc/platforms/4xx/
core-$(CONFIG_MATH_EMULATION) += arch/ppc/math-emu/
core-$(CONFIG_XMON) += arch/ppc/xmon/
core-$(CONFIG_APUS) += arch/ppc/amiga/
core-$(CONFIG_PPC_ISERIES) += arch/ppc/iSeries/
drivers-$(CONFIG_8xx) += arch/ppc/8xx_io/
drivers-$(CONFIG_4xx) += arch/ppc/4xx_io/
drivers-$(CONFIG_8260) += arch/ppc/8260_io/
......@@ -116,5 +114,4 @@ endif
CLEAN_FILES += include/asm-$(ARCH)/offsets.h.tmp \
include/asm-$(ARCH)/offsets.h \
arch/$(ARCH)/kernel/asm-offsets.s \
arch/$(ARCH)/iSeries/ReleaseData.h
arch/$(ARCH)/kernel/asm-offsets.s
#
# Automatically generated make config: don't edit
#
# CONFIG_UID16 is not set
# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
CONFIG_RWSEM_XCHGADD_ALGORITHM=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
#
# Loadable module support
#
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
#
# Platform support
#
CONFIG_PPC=y
CONFIG_PPC32=y
# CONFIG_6xx is not set
# CONFIG_4xx is not set
# CONFIG_POWER3 is not set
# CONFIG_8xx is not set
CONFIG_PPC_ISERIES=y
CONFIG_PPC64BRIDGE=y
# CONFIG_ALL_PPC is not set
# CONFIG_SMP is not set
#
# General setup
#
CONFIG_HIGHMEM=y
# CONFIG_ISA is not set
# CONFIG_EISA is not set
# CONFIG_SBUS is not set
# CONFIG_MCA is not set
# CONFIG_PCI_ISERIES is not set
# CONFIG_PCI is not set
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
CONFIG_BSD_PROCESS_ACCT=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
CONFIG_BINFMT_MISC=y
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
# CONFIG_CMDLINE_BOOL is not set
#
# Memory Technology Devices (MTD)
#
# CONFIG_MTD is not set
#
# Plug and Play configuration
#
# CONFIG_PNP is not set
# CONFIG_ISAPNP is not set
# CONFIG_PNPBIOS is not set
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_INITRD is not set
#
# Multi-device support (RAID and LVM)
#
# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
# CONFIG_MD_MULTIPATH is not set
# CONFIG_BLK_DEV_LVM is not set
#
# Networking options
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_NETLINK=y
# CONFIG_RTNETLINK is not set
# CONFIG_NETLINK_DEV is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
# CONFIG_IP_PNP_BOOTP is not set
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_MROUTE is not set
# CONFIG_INET_ECN is not set
CONFIG_SYN_COOKIES=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_LLC is not set
# CONFIG_NET_DIVERT is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
#
# QoS and/or fair queueing
#
# CONFIG_NET_SCHED is not set
#
# ATA/IDE/MFM/RLL support
#
# CONFIG_IDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
#
# SCSI support
#
# CONFIG_SCSI is not set
#
# Network device support
#
CONFIG_NETDEVICES=y
#
# ARCnet devices
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
#
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_MYRI_SBUS is not set
# CONFIG_NS83820 is not set
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
#
# Wireless LAN (non-hamradio)
#
# CONFIG_NET_RADIO is not set
#
# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
# CONFIG_SHAPER is not set
#
# Wan interfaces
#
# CONFIG_WAN is not set
#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
#
# IrDA (infrared) support
#
# CONFIG_IRDA is not set
#
# ISDN subsystem
#
# CONFIG_ISDN is not set
#
# Old CD-ROM drivers (not SCSI, not IDE)
#
CONFIG_CD_NO_IDESCSI=y
# CONFIG_AZTCD is not set
# CONFIG_GSCD is not set
# CONFIG_SBPCD is not set
# CONFIG_MCD is not set
# CONFIG_MCDX is not set
# CONFIG_OPTCD is not set
# CONFIG_CM206 is not set
# CONFIG_SJCD is not set
# CONFIG_ISP16_CDI is not set
# CONFIG_CDU31A is not set
# CONFIG_CDU535 is not set
#
# Console drivers
#
# CONFIG_VGA_CONSOLE is not set
#
# Frame-buffer support
#
# CONFIG_FB is not set
#
# iSeries device drivers
#
CONFIG_VIOCONS=y
CONFIG_VIODASD=y
# CONFIG_VIODASD_IDE is not set
CONFIG_VIOCD=y
# CONFIG_VIOCD_AZTECH is not set
CONFIG_VIOTAPE=y
CONFIG_VETH=y
CONFIG_VIOPATH=y
CONFIG_CD_NO_IDESCSI=y
CONFIG_BLK_DEV_IDECD=y
#
# Input core support
#
# CONFIG_INPUT is not set
# CONFIG_INPUT_KEYBDEV is not set
# CONFIG_INPUT_MOUSEDEV is not set
# CONFIG_INPUT_JOYDEV is not set
# CONFIG_INPUT_EVDEV is not set
#
# Macintosh device drivers
#
#
# Character devices
#
# CONFIG_VT is not set
# CONFIG_SERIAL is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
#
# I2C support
#
# CONFIG_I2C is not set
#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
#
# Joysticks
#
# CONFIG_INPUT_GAMEPORT is not set
#
# Input core support is needed for gameports
#
#
# Input core support is needed for joysticks
#
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
# CONFIG_INTEL_RNG is not set
# CONFIG_NVRAM is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
# CONFIG_AGP is not set
# CONFIG_DRM is not set
#
# Multimedia devices
#
# CONFIG_VIDEO_DEV is not set
#
# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AUTOFS4_FS is not set
CONFIG_REISERFS_FS=y
# CONFIG_REISERFS_CHECK is not set
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_JFFS_FS is not set
# CONFIG_JFFS2_FS is not set
CONFIG_CRAMFS=y
# CONFIG_TMPFS is not set
CONFIG_RAMFS=y
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
# CONFIG_MINIX_FS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_NTFS_DEBUG is not set
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
CONFIG_DEVFS_FS=y
CONFIG_DEVFS_MOUNT=y
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UDF_FS is not set
# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
CONFIG_ROOT_NFS=y
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
# CONFIG_NCPFS_STRONG is not set
# CONFIG_NCPFS_NFS_NS is not set
# CONFIG_NCPFS_OS2_NS is not set
# CONFIG_NCPFS_SMALLDOS is not set
# CONFIG_NCPFS_NLS is not set
# CONFIG_NCPFS_EXTRAS is not set
#
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_SMB_NLS is not set
CONFIG_NLS=y
#
# Native Language Support
#
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
# CONFIG_NLS_CODEPAGE_860 is not set
# CONFIG_NLS_CODEPAGE_861 is not set
# CONFIG_NLS_CODEPAGE_862 is not set
# CONFIG_NLS_CODEPAGE_863 is not set
# CONFIG_NLS_CODEPAGE_864 is not set
# CONFIG_NLS_CODEPAGE_865 is not set
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_936 is not set
# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_CODEPAGE_932 is not set
# CONFIG_NLS_CODEPAGE_949 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
# CONFIG_NLS_ISO8859_5 is not set
# CONFIG_NLS_ISO8859_6 is not set
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
# CONFIG_NLS_UTF8 is not set
#
# Sound
#
# CONFIG_SOUND is not set
#
# USB support
#
# CONFIG_USB is not set
#
# Bluetooth support
#
# CONFIG_BT is not set
#
# Kernel hacking
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_KGDB is not set
# CONFIG_XMON is not set
# CONFIG_BDI_SWITCH is not set
/*
* HvCall.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* 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/stddef.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/system.h>
#include <asm/page.h>
#include <asm/iSeries/HvCall.h>
#include <asm/iSeries/HvCallEvent.h>
#ifndef _HVCALLSC_H
#include <asm/iSeries/HvCallSc.h>
#endif
#include <asm/iSeries/LparData.h>
#ifndef _HVTYPES_H
#include <asm/iSeries/HvTypes.h>
#endif
//=====================================================================
// Note that this call takes at MOST one page worth of data
int HvCall_readLogBuffer(HvLpIndex lpIndex, void *buffer, u64 bufLen)
{
struct HvLpBufferList *bufList;
u64 bytesLeft = bufLen;
u64 leftThisPage;
u64 curPtr = (unsigned long) buffer;
u64 retVal;
int npages;
int i;
npages = 0;
while (bytesLeft)
{
npages++;
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft)
bytesLeft = 0;
else
bytesLeft -= leftThisPage;
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
}
if (npages == 0)
return 0;
bufList = (struct HvLpBufferList *)kmalloc(npages * sizeof(struct HvLpBufferList), GFP_ATOMIC);
bytesLeft = bufLen;
curPtr = (unsigned long) buffer;
for(i=0; i<npages; i++)
{
bufList[i].addr = virt_to_absolute(curPtr);
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft)
{
bufList[i].len = bytesLeft;
bytesLeft = 0;
}
else
{
bufList[i].len = leftThisPage;
bytesLeft -= leftThisPage;
}
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
}
retVal = HvCall3(HvCallBaseReadLogBuffer,lpIndex, virt_to_absolute((unsigned long)bufList), bufLen);
kfree(bufList);
return (int)retVal;
}
//=====================================================================
void HvCall_writeLogBuffer(const void *buffer, u64 bufLen)
{
struct HvLpBufferList bufList;
u64 bytesLeft = bufLen;
u64 leftThisPage;
u64 curPtr = (unsigned long) buffer;
while (bytesLeft)
{
bufList.addr = virt_to_absolute( curPtr );
leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr;
if (leftThisPage > bytesLeft)
{
bufList.len = bytesLeft;
bytesLeft = 0;
}
else
{
bufList.len = leftThisPage;
bytesLeft -= leftThisPage;
}
HvCall2(HvCallBaseWriteLogBuffer, virt_to_absolute((unsigned long)&bufList), bufList.len);
curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE;
}
}
/*
* HvLpConfig.c
* Copyright (C) 2001 Kyle A. Lucke, IBM Corporation
*
* 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
*/
#ifndef _HVLPCONFIG_H
#include <asm/iSeries/HvLpConfig.h>
#endif
HvLpIndex HvLpConfig_getLpIndex_outline(void)
{
return HvLpConfig_getLpIndex();
}
/*
* HvLpEvent.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* 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/stddef.h>
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/LparData.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;
if ( eventType < HvLpEvent_Type_NumTypes ) {
if ( !lpEventHandlerPaths[eventType] ) {
lpEventHandler[eventType] = NULL;
rc = 0;
}
}
return rc;
}
// (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;
}
/*
* ItLpQueue.c
* Copyright (C) 2001 Mike Corrigan IBM Corporation
*
* 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/stddef.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/system.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/LparData.h>
static __inline__ int set_inUse( struct ItLpQueue * lpQueue )
{
int t;
u32 * inUseP = &(lpQueue->xInUseWord);
__asm__ __volatile__("\n\
1: lwarx %0,0,%2 \n\
cmpi 0,%0,0 \n\
li %0,0 \n\
bne- 2f \n\
addi %0,%0,1 \n\
stwcx. %0,0,%2 \n\
bne- 1b \n\
2: eieio"
: "=&r" (t), "=m" (lpQueue->xInUseWord)
: "r" (inUseP), "m" (lpQueue->xInUseWord)
: "cc");
return t;
}
static __inline__ void clear_inUse( struct ItLpQueue * lpQueue )
{
lpQueue->xInUseWord = 0;
}
// Array of LpEvent handler functions
extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes];
unsigned long ItLpQueueInProcess = 0;
struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue )
{
struct HvLpEvent * nextLpEvent =
(struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
if ( nextLpEvent->xFlags.xValid ) {
// Set pointer to next potential event
lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 +
LpEventAlign ) /
LpEventAlign ) *
LpEventAlign;
// Wrap to beginning if no room at end
if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr)
lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr;
}
else
nextLpEvent = NULL;
return nextLpEvent;
}
int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue )
{
struct HvLpEvent * nextLpEvent =
(struct HvLpEvent *)lpQueue->xSlicCurEventPtr;
return ( nextLpEvent->xFlags.xValid |
lpQueue->xPlicOverflowIntPending);
}
void ItLpQueue_clearValid( struct HvLpEvent * event )
{
// Clear the valid bit of the event
// Also clear bits within this event that might
// look like valid bits (on 64-byte boundaries)
unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) /
LpEventAlign ) - 1;
switch ( extra ) {
case 3:
((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0;
case 2:
((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0;
case 1:
((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0;
case 0:
}
mb();
event->xFlags.xValid = 0;
}
// No lock is necessary when processing the Lp Queue because a single
// processor is assigned to each lpqueue. Interrupts are disabled
// while processing events.
// Some device drivers' interrupt handlers run with interrupts
// enabled. This requires us to prevent being re-entered here.
// We use the xInUse flag for that.
unsigned lpQueue_proc_count[32] = {};
unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs )
{
unsigned numIntsProcessed = 0;
struct HvLpEvent * nextLpEvent;
// If we have recursed, just return
if ( !set_inUse( lpQueue ) )
return 0;
if (ItLpQueueInProcess == 0)
ItLpQueueInProcess = 1;
else
BUG();
++lpQueue_proc_count[current->processor];
for (;;) {
nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue );
if ( nextLpEvent ) {
// Count events to return to caller
// and count processed events in lpQueue
++numIntsProcessed;
lpQueue->xLpIntCount++;
// Call appropriate handler here, passing
// a pointer to the LpEvent. The handler
// must make a copy of the LpEvent if it
// needs it in a bottom half. (perhaps for
// an ACK)
// Handlers are responsible for ACK processing
// The Hypervisor guarantees that LpEvents will
// only be delivered with types that we have
// registered for, so no type check is necessary
// here!
if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes )
lpQueue->xLpIntCountByType[nextLpEvent->xType]++;
if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes &&
lpEventHandler[nextLpEvent->xType] )
lpEventHandler[nextLpEvent->xType](nextLpEvent, regs);
else
printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType );
ItLpQueue_clearValid( nextLpEvent );
}
else // No more valid events
// If overflow events are pending
// process them
if ( lpQueue->xPlicOverflowIntPending ) {
HvCallEvent_getOverflowLpEvents(
lpQueue->xIndex);
}
else // If nothing left then we are done
break;
}
ItLpQueueInProcess = 0;
mb();
clear_inUse( lpQueue );
return numIntsProcessed;
}
This diff is collapsed.
#
# Makefile for Linux arch/ppc/iSeries source directory
#
export-objs := iSeries_ksyms.o
obj-y += LparData.o ItLpQueue.o HvLpEvent.o HvCall.o mf.o iSeries_proc.o mf_proc.o iSeries_ksyms.o HvLpConfig.o pmc_proc.o rtc.o
obj-$(CONFIG_PCI) += XmPciLpEvent.o iSeries_FlightRecorder.o iSeries_IoMmTable.o iSeries_VpdInfo.o iSeries_fixup.o iSeries_irq.o iSeries_pci.o iSeries_pci_proc.o iSeries_reset_device.o
LparData.c:: ReleaseData.h
ReleaseData.h: $(TOPDIR)/Makefile
/bin/bash ./createReleaseData $(KERNELRELEASE) > $@
clean:
rm -f ReleaseData.h
/*
* File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001.
*
* This module handles PCI interrupt events sent by the AS400 Hypervisor.
*/
#include <linux/pci.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/threads.h>
#include <linux/smp.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/bootmem.h>
#include <linux/blk.h>
#include <linux/ide.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallPci.h>
#include <asm/iSeries/XmPciLpEvent.h>
enum XmPciLpEvent_Subtype {
XmPciLpEvent_BusCreated = 0, // PHB has been created
XmPciLpEvent_BusFailed = 1, // PHB has failed
XmPciLpEvent_BusRecovered = 12, // PHB has been recovered
XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed
XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered
XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt
};
struct XmPciLpEvent_BusInterrupt {
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
};
struct XmPciLpEvent_NodeInterrupt {
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
HvAgentId deviceId;
};
struct XmPciLpEvent {
struct HvLpEvent hvLpEvent;
union {
u64 alignData; // Align on an 8-byte boundary
struct {
u32 fisr;
HvBusNumber busNumber;
HvSubBusNumber subBusNumber;
HvAgentId deviceId;
} slotInterrupt;
struct XmPciLpEvent_BusInterrupt busFailed;
struct XmPciLpEvent_BusInterrupt busRecovered;
struct XmPciLpEvent_BusInterrupt busCreated;
struct XmPciLpEvent_NodeInterrupt nodeFailed;
struct XmPciLpEvent_NodeInterrupt nodeRecovered;
} eventData;
};
static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm);
static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm) {
if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) {
switch( eventParm->xFlags.xFunction ) {
case HvLpEvent_Function_Int:
intReceived( (struct XmPciLpEvent*)eventParm, regsParm );
break;
case HvLpEvent_Function_Ack:
printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n");
break;
default:
printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n",
(int)eventParm->xFlags.xFunction);
break;
};
}
else {
if (event) {
printk(KERN_ERR "XmPciLpEvent.c: unrecognized event type 0x%x\n",
(int)eventParm->xType);
}
else {
printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n");
}
}
}
static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm) {
int irq;
switch (eventParm->hvLpEvent.xSubtype) {
case XmPciLpEvent_SlotInterrupt:
irq = eventParm->hvLpEvent.xCorrelationToken;
/* Dispatch the interrupt handlers for this irq */
ppc_irq_dispatch_handler(regsParm, irq);
HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber,
eventParm->eventData.slotInterrupt.subBusNumber,
eventParm->eventData.slotInterrupt.deviceId);
break;
/* Ignore error recovery events for now */
case XmPciLpEvent_BusCreated:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber);
break;
case XmPciLpEvent_BusFailed:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber);
break;
case XmPciLpEvent_BusRecovered:
printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber);
break;
case XmPciLpEvent_NodeFailed:
printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId);
break;
case XmPciLpEvent_NodeRecovered:
printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId);
break;
default:
printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n",
eventParm->hvLpEvent.xSubtype);
break;
};
}
/* This should be called sometime prior to buswalk (init_IRQ would be good) */
int XmPciLpEvent_init() {
int xRc;
xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler);
if (xRc == 0) {
xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0);
if (xRc != 0) {
printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc);
}
}
else {
printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc);
}
return xRc;
}
#!/bin/bash
####################################################
# Build a hex ebcdic representation of the
# KERNELRELEASE for use in the iSeries
# hvReleaseData structure
####################################################
if [ $# -ne 1 ]
then
echo "Syntax: createReleaseData kernelversion"
exit 1
fi
len=${#1}
rd=''
####################################################
# ReleaseData is maximum of 12 chars
####################################################
if [ $len -gt 12 ]
then
len=12
fi
#for (( i=0 ; $i < $len ; i=$i+1 )) ;
i=0
while (($i<$len));
do
char=${1:$i:1}
case $char in
'a') xchar='0x81';;
'b') xchar='0x82';;
'c') xchar='0x83';;
'd') xchar='0x84';;
'e') xchar='0x85';;
'f') xchar='0x86';;
'g') xchar='0x87';;
'h') xchar='0x88';;
'i') xchar='0x89';;
'j') xchar='0x91';;
'k') xchar='0x92';;
'l') xchar='0x93';;
'm') xchar='0x94';;
'n') xchar='0x95';;
'o') xchar='0x96';;
'p') xchar='0x97';;
'q') xchar='0x98';;
'r') xchar='0x99';;
's') xchar='0xA2';;
't') xchar='0xA3';;
'u') xchar='0xA4';;
'v') xchar='0xA5';;
'w') xchar='0xA6';;
'x') xchar='0xA7';;
'y') xchar='0xA8';;
'z') xchar='0xA9';;
'A') xchar='0xC1';;
'B') xchar='0xC2';;
'C') xchar='0xC3';;
'D') xchar='0xC4';;
'E') xchar='0xC5';;
'F') xchar='0xC6';;
'G') xchar='0xC7';;
'H') xchar='0xC8';;
'I') xchar='0xC9';;
'J') xchar='0xD1';;
'K') xchar='0xD2';;
'L') xchar='0xD3';;
'M') xchar='0xD4';;
'N') xchar='0xD5';;
'O') xchar='0xD6';;
'P') xchar='0xD7';;
'Q') xchar='0xD8';;
'R') xchar='0xD9';;
'S') xchar='0xE2';;
'T') xchar='0xE3';;
'U') xchar='0xE4';;
'V') xchar='0xE5';;
'W') xchar='0xE6';;
'X') xchar='0xE7';;
'Y') xchar='0xE8';;
'Z') xchar='0xE9';;
'0') xchar='0xF0';;
'1') xchar='0xF1';;
'2') xchar='0xF2';;
'3') xchar='0xF3';;
'4') xchar='0xF4';;
'5') xchar='0xF5';;
'6') xchar='0xF6';;
'7') xchar='0xF7';;
'8') xchar='0xF8';;
'9') xchar='0xF9';;
'.') xchar='0x4B';;
'-') xchar='0x60';;
'_') xchar='0x6D';;
'+') xchar='0x4E';;
'@') xchar='0x7C';;
'$') xchar='0x5B';;
'%') xchar='0x6C';;
*) xchar='';;
esac
rd=${rd}${xchar}
if [ $(($i+1)) -lt $len ]
then
rd=${rd}', '
fi
i=$i+1
done
#echo "#define RELEASEDATA { $rd }">ReleaseData.h
echo "#define RELEASEDATA { $rd }"
/************************************************************************/
/* File iSeries_FlightRecorder.c created by Al Trautman on Jan 22 2001. */
/************************************************************************/
/* This code supports the pci interface on the IBM iSeries systems. */
/* Copyright (C) 20yy <Allan H Trautman> <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. */
/* */
/* 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 */
/************************************************************************/
/* Change Activity: */
/* Created, Jan 22, 2001 */
/* Added Time Stamps, April 12, 2001 */
/* End Change Activity */
/************************************************************************/
#include <linux/config.h>
#include <linux/kernel.h>
#include <asm/iSeries/iSeries_FlightRecorder.h>
#include <linux/rtc.h>
#include <asm/iSeries/mf.h>
/************************************************************************/
/* Log entry into buffer, */
/* ->If entry is going to wrap, log "WRAP" and start at the top. */
/************************************************************************/
void iSeries_LogFr_Entry(FlightRecorder* Fr, char* LogText) {
int Residual, TextLen;
if(Fr->StartingPointer > 0) { /* Initialized yet? */
Residual = FlightRecorderSize - (Fr->CurrentPointer - Fr->StartingPointer);
TextLen = strlen(LogText); /* Length of Text */
if(TextLen+16 > Residual) { /* Room for text or need to wrap*/
strcpy(Fr->CurrentPointer,"WRAP");
++Fr->WrapCount; /* Increment Wraps */
Fr->CurrentPointer = Fr->StartingPointer;
}
strcpy(Fr->CurrentPointer,LogText);
Fr->CurrentPointer += TextLen+1;
strcpy(Fr->CurrentPointer,"<=");
}
}
/************************************************************************/
/* Log entry with time */
/************************************************************************/
void iSeries_LogFr_Time(FlightRecorder* Fr, char* LogText) {
struct rtc_time Rtc;
char LogBuffer[256];
mf_getRtc(&Rtc);
sprintf(LogBuffer,"%02d:%02d:%02d %s",
Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec,
LogText);
iSeries_LogFr_Entry(Fr,LogBuffer);
}
/************************************************************************/
/* Log Entry with Date and call Time Log */
/************************************************************************/
void iSeries_LogFr_Date(FlightRecorder* Fr, char* LogText) {
struct rtc_time Rtc;
char LogBuffer[256];
mf_getRtc(&Rtc);
sprintf(LogBuffer,"%02d.%02d.%02d %02d:%02d:%02d %s",
Rtc.tm_year+1900, Rtc.tm_mon, Rtc.tm_mday,
Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec,
LogText);
iSeries_LogFr_Entry(Fr,LogBuffer);
}
/************************************************************************/
/* Initialized the Flight Recorder */
/************************************************************************/
void iSeries_Fr_Initialize(FlightRecorder* Fr, char* Signature) {
if(strlen(Signature) > 16) memcpy(Fr->Signature,Signature,16);
else strcpy(Fr->Signature,Signature);
Fr->StartingPointer = &Fr->Buffer[0];
Fr->CurrentPointer = Fr->StartingPointer;
Fr->logEntry = iSeries_LogFr_Entry;
Fr->logDate = iSeries_LogFr_Date;
Fr->logTime = iSeries_LogFr_Time;
Fr->logEntry(Fr,"FR Initialized."); /* Note, can't use time yet! */
}
This diff is collapsed.
#ifndef _ISERIES_IOMMTABLE_H
#define _ISERIES_IOMMTABLE_H
/************************************************************************/
/* File iSeries_IoMmTable.h created by Allan Trautman on Dec 12 2001. */
/************************************************************************/
/* Interfaces for the write/read Io address translation table. */
/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */
/* */
/* 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 */
/************************************************************************/
/* Change Activity: */
/* Created December 12, 2000 */
/* End Change Activity */
/************************************************************************/
/************************************************************************/
/* iSeries_IoMmTable_Initialize */
/************************************************************************/
/* - Initalizes the Address Translation Table and get it ready for use. */
/* Must be called before any client calls any of the other methods. */
/* */
/* Parameters: None. */
/* */
/* Return: None. */
/************************************************************************/
extern void iSeries_IoMmTable_Initialize(void);
/************************************************************************/
/* iSeries_allocateDeviceBars */
/************************************************************************/
/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */
/* value. BARS with zero length will not have the resources. The */
/* HvCallPci_getBarParms is used to get the size of the BAR space. */
/* It calls as400_IoMmTable_AllocateEntry to allocate each entry. */
/* */
/* Parameters: */
/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */
/* I/O Address. */
/* */
/* Return: */
/* The pci_dev I/O resources updated with pseudo I/O Addresses. */
/************************************************************************/
extern void iSeries_allocateDeviceBars(struct pci_dev* Device);
/************************************************************************/
/* iSeries_IoMmTable_AllocateEntry */
/************************************************************************/
/* - Allocates(adds) the pci_dev entry in the Address Translation Table */
/* and updates the Resources for the device. */
/* */
/* Parameters: */
/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */
/* I/O Address. */
/* */
/* BarNumber = Which Bar to be allocated. */
/* */
/* Return: */
/* The pseudo I/O Address in the resources that will map to the */
/* pci_dev on iSeries_xlateIoMmAddress call. */
/************************************************************************/
extern void iSeries_IoMmTable_AllocateEntry(struct pci_dev* Device, u32 BarNumber);
/************************************************************************/
/* iSeries_xlateIoMmAddress */
/************************************************************************/
/* - Translates an I/O Memory address to pci_dev that has been allocated*/
/* the psuedo I/O Address. */
/* */
/* Parameters: */
/* IoAddress = I/O Memory Address. */
/* */
/* Return: */
/* A pci_dev pointer to the device mapped to the I/O address. */
/************************************************************************/
extern struct pci_dev* iSeries_xlateIoMmAddress(u32* IoAddress);
/************************************************************************/
/* Helper Methods */
/************************************************************************/
extern int iSeries_IoMmTable_Bar(u32 *IoAddress);
extern u32* iSeries_IoMmTable_BarBase(u32* IoAddress);
extern u32 iSeries_IoMmTable_BarOffset(u32* IoAddress);
extern int iSeries_Is_IoMmAddress(unsigned long address);
/************************************************************************/
/* Helper Methods to get TableSize and TableSizeEntry. */
/************************************************************************/
extern u32 iSeries_IoMmTable_TableEntrySize(void);
extern u32 iSeries_IoMmTable_TableSize(void);
#endif /* _ISERIES_IOMMTABLE_H */
This diff is collapsed.
This diff is collapsed.
/************************************************************************/
/* This module supports the iSeries PCI bus interrupt handling */
/* Copyright (C) 20yy <Robert L Holtorf> <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. */
/* */
/* 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 */
/************************************************************************/
/* Change Activity: */
/* Created, December 13, 2000 by Wayne Holm */
/* End Change Activity */
/************************************************************************/
#include <linux/pci.h>
#include <linux/config.h>
#include <linux/init.h>
#include <linux/threads.h>
#include <linux/smp.h>
#include <linux/param.h>
#include <linux/string.h>
#include <linux/bootmem.h>
#include <linux/blk.h>
#include <linux/ide.h>
#include <linux/irq.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <asm/iSeries/HvCallPci.h>
#include <asm/iSeries/HvCallXm.h>
#include <asm/iSeries/iSeries_irq.h>
#include <asm/iSeries/XmPciLpEvent.h>
hw_irq_controller iSeries_IRQ_handler = {
"iSeries irq controller",
iSeries_startup_IRQ, /* startup */
iSeries_shutdown_IRQ, /* shutdown */
iSeries_enable_IRQ, /* enable */
iSeries_disable_IRQ, /* disable */
NULL, /* ack */
iSeries_end_IRQ, /* end */
NULL /* set_affinity */
};
struct iSeries_irqEntry {
u32 dsa;
struct iSeries_irqEntry* next;
};
struct iSeries_irqAnchor {
u8 valid : 1;
u8 reserved : 7;
u16 entryCount;
struct iSeries_irqEntry* head;
};
struct iSeries_irqAnchor iSeries_irqMap[NR_IRQS];
void iSeries_init_irqMap(int irq);
/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */
void __init iSeries_init_IRQ(void)
{
int i;
for (i = 0; i < NR_IRQS; i++) {
irq_desc[i].handler = &iSeries_IRQ_handler;
irq_desc[i].status = 0;
irq_desc[i].status |= IRQ_DISABLED;
irq_desc[i].depth = 1;
iSeries_init_irqMap(i);
}
/* Register PCI event handler and open an event path */
XmPciLpEvent_init();
return;
}
/* Called by iSeries_init_IRQ */
void __init iSeries_init_irqMap(int irq) {
/* Prevent IRQs 0 and 255 from being used. IRQ 0 appears in
uninitialized devices. IRQ 255 appears in the PCI interrupt
line register if a PCI error occurs */
iSeries_irqMap[irq].valid = (irq == 0 || irq == 255)? 0 : 1;
iSeries_irqMap[irq].entryCount = 0;
iSeries_irqMap[irq].head = NULL;
}
/* This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot */
int __init iSeries_allocate_IRQ(HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) {
u8 idsel = (deviceId >> 4);
u8 function = deviceId & 0x0F;
int irq = ((((busNumber-1)*16 + (idsel-1)*8 + function)*9/8) % 254) + 1;
return irq;
}
/* This is called out of iSeries_scan_slot to assign the EADS slot to its IRQ number */
int __init iSeries_assign_IRQ(int irq, HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) {
int rc;
u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId;
struct iSeries_irqEntry* newEntry;
unsigned long flags;
if (irq < 0 || irq >= NR_IRQS)
return -1;
newEntry = kmalloc(sizeof(*newEntry), GFP_KERNEL);
if (newEntry == NULL)
return -ENOMEM;
newEntry->dsa = dsa;
newEntry->next = NULL;
/* Probably not necessary to lock the irq since allocation is only
done during buswalk, but it should not hurt anything except a little
performance */
spin_lock_irqsave(&irq_desc[irq].lock, flags);
if (iSeries_irqMap[irq].valid) {
/* Push the new element onto the irq stack */
newEntry->next = iSeries_irqMap[irq].head;
iSeries_irqMap[irq].head = newEntry;
++iSeries_irqMap[irq].entryCount;
rc = 0;
}
else
rc = -1;
spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
if (rc != 0 && newEntry)
kfree(newEntry);
return rc;
}
/* This is called by iSeries_activate_IRQs */
unsigned int iSeries_startup_IRQ(unsigned int irq) {
struct iSeries_irqEntry* entry;
u32 bus, subBus, deviceId, function, mask;
/* irq should be locked by the caller */
for(entry=iSeries_irqMap[irq].head; entry!=NULL; entry=entry->next) {
bus = (entry->dsa >> 16) & 0xFFFF;
subBus = (entry->dsa >> 8) & 0xFF;
deviceId = entry->dsa & 0xFF;
function = deviceId & 0x0F;
/* Link the IRQ number to the bridge */
HvCallXm_connectBusUnit(bus, subBus, deviceId, irq);
/* Unmask bridge interrupts in the FISR */
mask = 0x01010000 << function;
HvCallPci_unmaskFisr(bus, subBus, deviceId, mask);
}
return 0;
}
/* This is called out of iSeries_fixup to
activate interrupt generation for usable slots */
void __init iSeries_activate_IRQs() {
int irq;
unsigned long flags;
for (irq=0; irq < NR_IRQS; irq++) {
spin_lock_irqsave(&irq_desc[irq].lock, flags);
irq_desc[irq].handler->startup(irq);
spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
}
}
/* this is not called anywhere currently */
void iSeries_shutdown_IRQ(unsigned int irq) {
struct iSeries_irqEntry* entry;
u32 bus, subBus, deviceId, function, mask;
/* irq should be locked by the caller */
for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
bus = (entry->dsa >> 16) & 0xFFFF;
subBus = (entry->dsa >> 8) & 0xFF;
deviceId = entry->dsa & 0xFF;
function = deviceId & 0x0F;
/* Invalidate the IRQ number in the bridge */
HvCallXm_connectBusUnit(bus, subBus, deviceId, 0);
/* Mask bridge interrupts in the FISR */
mask = 0x01010000 << function;
HvCallPci_maskFisr(bus, subBus, deviceId, mask);
}
}
/* This will be called by device drivers (via disable_IRQ to disable
INTA in the bridge interrupt status register */
void iSeries_disable_IRQ(unsigned int irq) {
struct iSeries_irqEntry* entry;
u32 bus, subBus, deviceId, mask;
/* The IRQ has already been locked by the caller */
for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
bus = (entry->dsa >> 16) & 0xFFFF;
subBus = (entry->dsa >> 8) & 0xFF;
deviceId = entry->dsa & 0xFF;
/* Mask secondary INTA */
mask = 0x80000000;
HvCallPci_maskInterrupts(bus, subBus, deviceId, mask);
}
}
/* This will be called by device drivers (via enable_IRQ to enable
INTA in the bridge interrupt status register */
void iSeries_enable_IRQ(unsigned int irq) {
struct iSeries_irqEntry* entry;
u32 bus, subBus, deviceId, mask;
/* The IRQ has already been locked by the caller */
for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) {
bus = (entry->dsa >> 16) & 0xFFFF;
subBus = (entry->dsa >> 8) & 0xFF;
deviceId = entry->dsa & 0xFF;
/* Unmask secondary INTA */
mask = 0x80000000;
HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask);
}
}
/* Need to define this so ppc_irq_dispatch_handler will NOT call
enable_IRQ at the end of interrupt handling. However, this
does nothing because there is not enough information provided
to do the EOI HvCall. This is done by XmPciLpEvent.c */
void iSeries_end_IRQ(unsigned int irq) {
}
/* File iSeries_ksyms.c created by root on Tue Feb 13 2001. */
/* Change Activity: */
/* End Change Activity */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <asm/iSeries/iSeries_dma.h>
#include <asm/iSeries/mf.h>
#include <asm/iSeries/HvCallSc.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/Naca.h>
#include <asm/iSeries/iSeries_proc.h>
#include <asm/iSeries/ItLpNaca.h>
#include <asm/iSeries/HvLpConfig.h>
#include <asm/iSeries/iSeries_io.h>
#include <asm/iSeries/iSeries_FlightRecorder.h>
#include <asm/iSeries/iSeries_pci.h>
#include <asm/iSeries/iSeries_VpdInfo.h>
#include <asm/delay.h>
EXPORT_SYMBOL(HvLpEvent_registerHandler);
EXPORT_SYMBOL(HvLpEvent_unregisterHandler);
EXPORT_SYMBOL(HvLpEvent_openPath);
EXPORT_SYMBOL(HvLpEvent_closePath);
EXPORT_SYMBOL(HvCall1);
EXPORT_SYMBOL(HvCall2);
EXPORT_SYMBOL(HvCall3);
EXPORT_SYMBOL(HvCall4);
EXPORT_SYMBOL(HvCall5);
EXPORT_SYMBOL(HvCall6);
EXPORT_SYMBOL(HvCall7);
EXPORT_SYMBOL(HvCall0);
EXPORT_SYMBOL(HvCall0Ret16);
EXPORT_SYMBOL(HvCall1Ret16);
EXPORT_SYMBOL(HvCall2Ret16);
EXPORT_SYMBOL(HvCall3Ret16);
EXPORT_SYMBOL(HvCall4Ret16);
EXPORT_SYMBOL(HvCall5Ret16);
EXPORT_SYMBOL(HvCall6Ret16);
EXPORT_SYMBOL(HvCall7Ret16);
EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
EXPORT_SYMBOL(virt_to_absolute_outline);
EXPORT_SYMBOL(mf_allocateLpEvents);
EXPORT_SYMBOL(mf_deallocateLpEvents);
EXPORT_SYMBOL(iSeries_proc_callback);
#ifdef CONFIG_PCI
EXPORT_SYMBOL(pci_map_single);
EXPORT_SYMBOL(pci_unmap_single);
EXPORT_SYMBOL(iSeries_Readb);
EXPORT_SYMBOL(iSeries_Readw);
EXPORT_SYMBOL(iSeries_Readl);
EXPORT_SYMBOL(iSeries_Writeb);
EXPORT_SYMBOL(iSeries_Writew);
EXPORT_SYMBOL(iSeries_Writel);
EXPORT_SYMBOL(iSeries_memcpy_fromio);
EXPORT_SYMBOL(iSeries_memcpy_toio);
EXPORT_SYMBOL(iSeries_GetLocationData);
EXPORT_SYMBOL(iSeries_Set_PciTraceFlag);
EXPORT_SYMBOL(iSeries_Get_PciTraceFlag);
EXPORT_SYMBOL(iSeries_Device_Reset_NoIrq);
EXPORT_SYMBOL(iSeries_Device_Reset_Generic);
EXPORT_SYMBOL(iSeries_Device_Reset);
EXPORT_SYMBOL(iSeries_Device_RestoreConfigRegs);
EXPORT_SYMBOL(iSeries_Device_SaveConfigRegs);
EXPORT_SYMBOL(iSeries_Device_ToggleReset);
#endif
This diff is collapsed.
#ifdef CONFIG_PPC_ISERIES
#ifndef _ISERIES_PCI_H
#define _ISERIES_PCI_H
/************************************************************************/
/* File iSeries_pci.h created by Allan Trautman on Tue Jan 9 2001. */
/************************************************************************/
/* Define some useful macros for the iseries pci routines. */
/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */
/* */
/* 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 */
/************************************************************************/
/* Change Activity: */
/* Created December 28, 2000 */
/* Converted to iseries_pci.h Jan 25, 2001 */
/* End Change Activity */
/************************************************************************/
#include <linux/config.h>
#include <asm/iSeries/HvTypes.h>
#include <asm/iSeries/iSeries_FlightRecorder.h>
#include <asm/iSeries/iSeries_pci.h>
/************************************************************************************/
/* Define some useful macros. */
/* These macros started with Wayne, Al renamed and refined. */
/************************************************************************************/
/* Encodes SubBus address(seddddfff), Works only for bridges under EADS 1 and 2. */
/************************************************************************************/
/* #define ISERIES_ENCODE_SUBBUS(eads, bridge, device) \
(0x80 | ((eads-1 & 0x01) << 6) | ((bridge & 0x0F) << 3) | (device & 0x07)) */
#define ISERIES_ENCODE_SUBBUS(e, ef, df) (((0x80 | ((e&0x02)<<5) | ((ef & 0x07)<<3)) & 0xF8) | (df & 0x03)) // Al - Please Review
/************************************************************************************/
/* Combines IdSel and Function into Iseries 4.4 format */
/* For Linux, see PCI_DEVFN(slot,func) in include/linux/pci.h */
/************************************************************************************/
// #define ISERIES_PCI_AGENTID(idsel,func) ((idsel & 0x0F) << 4) | (func & 0x07)
#define ISERIES_PCI_AGENTID(idsel,func) (((idsel & 0x0F) << 4) | (func & 0x0F)) // Al - Please Review
/************************************************************************************/
/* Converts DeviceFunction from Linux 5.3(dddddfff) to Iseries 4.4(dddd0fff) */
/* Converts DeviceFunction from Iseries 4.4(dddd0fff) to Linux 5.3(dddddfff) */
/************************************************************************************/
#define ISERIES_44_FORMAT(devfn53) (((devfn53 & 0xF8) << 1) | (devfn53 & 0x07))
#define ISERIES_53_FORMAT(devfn44) (((devfn44 & 0xF0) >> 1) | (devfn44 & 0x07))
/************************************************************************************/
/* Tests for encoded subbus. */
/************************************************************************************/
#define ISERIES_IS_SUBBUS_ENCODED_IN_DEVFN(devfn) ((devfn & 0x80) == 0x80)
/************************************************************************************/
/* Decodes the Iseries subbus to devfn, ONLY Works for bus 0!! Use Table lookup. */
/************************************************************************************/
/* #define ISERIES_DEVFN_DECODE_SUBBUS(devfn) \
((((devfn & 0x40) >> 1) + 0x20) | ((devfn >> 1) & 0x1C)) */
#define ISERIES_DEVFN_DECODE_SUBBUS(devfn) (((((devfn >> 6 ) & 0x1) + 1) << 5) | (((devfn >> 3) & 0x7) << 2)) // Al - Please Review
/************************************************************************************/
/* Decodes Linux DevFn to Iseries DevFn, bridge device, or function. */
/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h */
/************************************************************************************/
#define ISERIES_DECODE_DEVFN(linuxdevfn) (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07))
#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10))
#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07)
#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7)
#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7)
#define ISERIES_GET_HOSE_HV_BUSNUM(hose) (((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber)
/************************************************************************************/
/* Retreives Iseries Bus and SubBus from GlobalBusMap */
/************************************************************************************/
#define ISERIES_GET_LPAR_BUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVBUSNUMBER_]
#define ISERIES_GET_LPAR_SUBBUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVSUBBUSNUMBER_]
#define ISERIES_ADD_BUS_GLOBALBUSMAP(linuxbus, iseriesbus, iseriessubbus) \
iSeries_GlobalBusMap[linuxbus][_HVBUSNUMBER_] = iseriesbus; \
iSeries_GlobalBusMap[linuxbus][_HVSUBBUSNUMBER_] = iseriessubbus;
/************************************************************************************/
/* Global Bus map */
/* Bus and Subbus index values into the global bus number map array. */
/************************************************************************************/
#define ISERIES_GLOBALBUSMAP_SIZE 256
#define _HVBUSNUMBER_ 0
#define _HVSUBBUSNUMBER_ 1
extern u8 iSeries_GlobalBusMap[ISERIES_GLOBALBUSMAP_SIZE][2];
void iSeries_Initialize_GlobalBusMap(void);
#define pci_assign_all_buses() 1 // Al - NEW
/************************************************************************************/
/* Converts Virtual Address to Real Address for Hypervisor calls */
/************************************************************************************/
#define REALADDR(virtaddr) (0x8000000000000000 | (virt_to_absolute((u32)virtaddr) ))
/************************************************************************************/
/* Define TRUE and FALSE Values for Al */
/************************************************************************************/
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef struct pci_dev pciDev;
/************************************************************************/
/* Routines to build the iSeries_Device for the pci device. */
/************************************************************************/
extern void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr);
extern int build_iSeries_Device_From_IoAddress(iSeries_Device* Device, u32* IoAddress);
extern void iSeries_pci_Initialize(void);
/************************************************************************/
/* Flight Recorder Debug Support */
/************************************************************************/
extern int PciTraceFlag; /* Conditional Trace */
void iSeries_Initialize_FlightRecorder(void);
int iSeries_Set_PciTraceFlag(int Flag); /* Sets flag, return old*/
int iSeries_Get_PciTraceFlag(void); /* Gets Flag. */
void iSeries_DumpDevice(char* Text, iSeries_Device* );
#endif /* _ISERIES_PCI_H */
#endif /*CONFIG_PPC_ISERIES */
This diff is collapsed.
/*
* iSeries_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation
*
* 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
*/
/* Change Activity: */
/* End Change Activity */
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#ifndef _ISERIES_PROC_H
#include <asm/iSeries/iSeries_proc.h>
#endif
static struct proc_dir_entry * iSeries_proc_root = NULL;
static int iSeries_proc_initializationDone = 0;
static spinlock_t iSeries_proc_lock;
struct iSeries_proc_registration
{
struct iSeries_proc_registration *next;
iSeriesProcFunction functionMember;
};
struct iSeries_proc_registration preallocated[16];
#define MYQUEUETYPE(T) struct MYQueue##T
#define MYQUEUE(T) \
MYQUEUETYPE(T) \
{ \
struct T *head; \
struct T *tail; \
}
#define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0)
#define MYQUEUEENQ(q, p) \
do { \
(p)->next = NULL; \
if ((q)->head != NULL) \
{ \
(q)->head->next = (p); \
(q)->head = (p); \
} \
else \
{ \
(q)->tail = (q)->head = (p); \
} \
} while(0)
#define MYQUEUEDEQ(q,p) \
do { \
(p) = (q)->tail; \
if ((p) != NULL) \
{ \
(q)->tail = (p)->next; \
(p)->next = NULL; \
} \
if ((q)->tail == NULL) \
(q)->head = NULL; \
} while(0)
MYQUEUE(iSeries_proc_registration);
typedef MYQUEUETYPE(iSeries_proc_registration) aQueue;
aQueue iSeries_free;
aQueue iSeries_queued;
void iSeries_proc_early_init(void)
{
int i = 0;
unsigned long flags;
iSeries_proc_initializationDone = 0;
spin_lock_init(&iSeries_proc_lock);
MYQUEUECTOR(&iSeries_free);
MYQUEUECTOR(&iSeries_queued);
spin_lock_irqsave(&iSeries_proc_lock, flags);
for (i = 0; i < 16; ++i)
{
MYQUEUEENQ(&iSeries_free, preallocated+i);
}
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
void iSeries_proc_create(void)
{
unsigned long flags;
struct iSeries_proc_registration *reg = NULL;
spin_lock_irqsave(&iSeries_proc_lock, flags);
printk("iSeries_proc: Creating /proc/iSeries\n");
iSeries_proc_root = proc_mkdir("iSeries", 0);
if (!iSeries_proc_root) return;
MYQUEUEDEQ(&iSeries_queued, reg);
while (reg != NULL)
{
(*(reg->functionMember))(iSeries_proc_root);
MYQUEUEDEQ(&iSeries_queued, reg);
}
iSeries_proc_initializationDone = 1;
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
void iSeries_proc_callback(iSeriesProcFunction initFunction)
{
unsigned long flags;
spin_lock_irqsave(&iSeries_proc_lock, flags);
if (iSeries_proc_initializationDone)
{
(*initFunction)(iSeries_proc_root);
}
else
{
struct iSeries_proc_registration *reg = NULL;
MYQUEUEDEQ(&iSeries_free, reg);
if (reg != NULL)
{
// printk("Registering %p in reg %p\n", initFunction, reg);
reg->functionMember = initFunction;
MYQUEUEENQ(&iSeries_queued, reg);
}
else
{
printk("Couldn't get a queue entry\n");
}
}
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
This diff is collapsed.
This diff is collapsed.
/*
* mf_proc.c
* Copyright (C) 2001 Kyle A. Lucke IBM Corporation
*
* 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
*/
/* Change Activity: */
/* End Change Activity */
#ifndef _MF_PROC_H
#include <asm/iSeries/mf_proc.h>
#endif
#ifndef MF_H_INCLUDED
#include <asm/iSeries/mf.h>
#endif
#include <asm/uaccess.h>
static struct proc_dir_entry *mf_proc_root = NULL;
int proc_mf_dump_cmdline
(char *page, char **start, off_t off, int count, int *eof, void *data);
int proc_mf_dump_vmlinux
(char *page, char **start, off_t off, int count, int *eof, void *data);
int proc_mf_dump_side
(char *page, char **start, off_t off, int count, int *eof, void *data);
int proc_mf_change_side
(struct file *file, const char *buffer, unsigned long count, void *data);
int proc_mf_dump_src
(char *page, char **start, off_t off, int count, int *eof, void *data);
int proc_mf_change_src (struct file *file, const char *buffer, unsigned long count, void *data);
int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data);
int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data);
void mf_proc_init(struct proc_dir_entry *iSeries_proc)
{
struct proc_dir_entry *ent = NULL;
struct proc_dir_entry *mf_a = NULL;
struct proc_dir_entry *mf_b = NULL;
struct proc_dir_entry *mf_c = NULL;
struct proc_dir_entry *mf_d = NULL;
mf_proc_root = proc_mkdir("mf", iSeries_proc);
if (!mf_proc_root) return;
mf_a = proc_mkdir("A", mf_proc_root);
if (!mf_a) return;
ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_a);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)0;
ent->read_proc = proc_mf_dump_cmdline;
ent->write_proc = proc_mf_change_cmdline;
ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_a);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)0;
ent->read_proc = proc_mf_dump_vmlinux;
ent->write_proc = proc_mf_change_vmlinux;
mf_b = proc_mkdir("B", mf_proc_root);
if (!mf_b) return;
ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_b);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)1;
ent->read_proc = proc_mf_dump_cmdline;
ent->write_proc = proc_mf_change_cmdline;
ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_b);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)1;
ent->read_proc = proc_mf_dump_vmlinux;
ent->write_proc = proc_mf_change_vmlinux;
mf_c = proc_mkdir("C", mf_proc_root);
if (!mf_c) return;
ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_c);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)2;
ent->read_proc = proc_mf_dump_cmdline;
ent->write_proc = proc_mf_change_cmdline;
ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_c);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)2;
ent->read_proc = proc_mf_dump_vmlinux;
ent->write_proc = proc_mf_change_vmlinux;
mf_d = proc_mkdir("D", mf_proc_root);
if (!mf_d) return;
ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_d);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)3;
ent->read_proc = proc_mf_dump_cmdline;
ent->write_proc = proc_mf_change_cmdline;
ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR, mf_d);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)3;
ent->read_proc = proc_mf_dump_vmlinux;
ent->write_proc = NULL;
ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)0;
ent->read_proc = proc_mf_dump_side;
ent->write_proc = proc_mf_change_side;
ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root);
if (!ent) return;
ent->nlink = 1;
ent->data = (void *)0;
ent->read_proc = proc_mf_dump_src;
ent->write_proc = proc_mf_change_src;
}
int proc_mf_dump_cmdline
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = count;
char *p;
len = mf_getCmdLine(page, &len, (u64)(int)data);
p = page + len - 1;
while ( p > page ) {
if ( (*p == 0) || (*p == ' ') )
--p;
else
break;
}
if ( *p != '\n' ) {
++p;
*p = '\n';
}
++p;
*p = 0;
len = p - page;
len -= off;
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else
len = count;
*start = page + off;
return len;
}
int proc_mf_dump_vmlinux
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int sizeToGet = count;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)(int)data) == 0)
{
if (sizeToGet != 0)
{
*start = page + off;
printk("mf_proc.c: got count %d off %d\n", sizeToGet, (int)off);
return sizeToGet;
}
else
{
printk("mf_proc.c: eof\n");
*eof = 1;
return 0;
}
}
else
{
printk("mf_proc.c: eof\n");
*eof = 1;
return 0;
}
}
int proc_mf_dump_side
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
char mf_current_side = mf_getSide();
len = sprintf(page, "%c\n", mf_current_side);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
if (len>count) len = count;
if (len<0) len = 0;
return len;
}
int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data)
{
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if ((*buffer != 'A') &&
(*buffer != 'B') &&
(*buffer != 'C') &&
(*buffer != 'D'))
{
printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n");
return -EINVAL;
}
mf_setSide(*buffer);
return count;
}
int proc_mf_dump_src
(char *page, char **start, off_t off, int count, int *eof, void *data)
{
int len = 0;
mf_getSrcHistory(page, count);
len = count;
len -= off;
if (len < count) {
*eof = 1;
if (len <= 0)
return 0;
} else
len = count;
*start = page + off;
return len;
}
int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data)
{
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
if ((count < 4) && (count != 1))
{
printk(KERN_ERR "mf_proc: invalid src\n");
return -EINVAL;
}
if ((count == 1) && ((*buffer) == '\0'))
{
mf_clearSrc();
}
else
{
mf_displaySrc(*(u32 *)buffer);
}
return count;
}
int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data)
{
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
mf_setCmdLine(buffer, count, (u64)(int)data);
return count;
}
int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data)
{
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
mf_setVmlinuxChunk(buffer, count, file->f_pos, (u64)(int)data);
file->f_pos += count;
return count;
}
This diff is collapsed.
/*
* Real Time Clock interface for IBM iSeries
*
* Based on rtc.c by Paul Gortmaker
*
* This driver allows use of the real time clock
* from user space. It exports the /dev/rtc
* interface supporting various ioctl() and also the
* /proc/driver/rtc pseudo-file for status information.
*
* iSeries does not support RTC interrupts nor an alarm.
*
* 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.
*
* 1.0 Mike Corrigan: IBM iSeries rtc support
*/
#define RTC_VERSION "1.0"
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
#include <linux/ioport.h>
#include <linux/fcntl.h>
#include <linux/mc146818rtc.h>
#include <linux/init.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/spinlock.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/iSeries/mf.h>
/*
* We sponge a minor off of the misc major. No need slurping
* up another valuable major dev number for this. If you add
* an ioctl, make sure you don't conflict with SPARC's RTC
* ioctls.
*/
static loff_t rtc_llseek(struct file *file, loff_t offset, int origin);
static ssize_t rtc_read(struct file *file, char *buf,
size_t count, loff_t *ppos);
static int rtc_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg);
static void get_rtc_time (struct rtc_time *rtc_tm);
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data);
/*
* If this driver ever becomes modularised, it will be really nice
* to make the epoch retain its value across module reload...
*/
static unsigned long epoch = 1900; /* year corresponding to 0x00 */
static const unsigned char days_in_mo[] =
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
* Now all the various file operations that we export.
*/
static loff_t rtc_llseek(struct file *file, loff_t offset, int origin)
{
return -ESPIPE;
}
static ssize_t rtc_read(struct file *file, char *buf,
size_t count, loff_t *ppos)
{
return -EIO;
}
static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct rtc_time wtime;
switch (cmd) {
case RTC_RD_TIME: /* Read the time/date from RTC */
{
get_rtc_time(&wtime);
break;
}
case RTC_SET_TIME: /* Set the RTC */
{
struct rtc_time rtc_tm;
unsigned char mon, day, hrs, min, sec, leap_yr;
unsigned int yrs;
if (!capable(CAP_SYS_TIME))
return -EACCES;
if (copy_from_user(&rtc_tm, (struct rtc_time*)arg,
sizeof(struct rtc_time)))
return -EFAULT;
yrs = rtc_tm.tm_year;
mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
day = rtc_tm.tm_mday;
hrs = rtc_tm.tm_hour;
min = rtc_tm.tm_min;
sec = rtc_tm.tm_sec;
if (yrs < 70)
return -EINVAL;
leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400));
if ((mon > 12) || (day == 0))
return -EINVAL;
if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr)))
return -EINVAL;
if ((hrs >= 24) || (min >= 60) || (sec >= 60))
return -EINVAL;
if ( yrs > 169 )
return -EINVAL;
mf_setRtc( &rtc_tm );
return 0;
}
case RTC_EPOCH_READ: /* Read the epoch. */
{
return put_user (epoch, (unsigned long *)arg);
}
case RTC_EPOCH_SET: /* Set the epoch. */
{
/*
* There were no RTC clocks before 1900.
*/
if (arg < 1900)
return -EINVAL;
if (!capable(CAP_SYS_TIME))
return -EACCES;
epoch = arg;
return 0;
}
default:
return -EINVAL;
}
return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0;
}
static int rtc_open(struct inode *inode, struct file *file)
{
return 0;
}
static int rtc_release(struct inode *inode, struct file *file)
{
return 0;
}
/*
* The various file operations we support.
*/
static struct file_operations rtc_fops = {
.owner = THIS_MODULE,
.llseek = rtc_llseek,
.read = rtc_read,
.ioctl = rtc_ioctl,
.open = rtc_open,
.release = rtc_release,
};
static struct miscdevice rtc_dev=
{
RTC_MINOR,
"rtc",
&rtc_fops
};
static int __init rtc_init(void)
{
if (misc_register(&rtc_dev))
return -ENODEV;
create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL);
printk(KERN_INFO "iSeries Real Time Clock Driver v" RTC_VERSION "\n");
return 0;
}
static void __exit rtc_exit (void)
{
remove_proc_entry ("driver/rtc", NULL);
misc_deregister(&rtc_dev);
}
module_init(rtc_init);
module_exit(rtc_exit);
/*
* Info exported via "/proc/driver/rtc".
*/
static int rtc_proc_output (char *buf)
{
char *p;
struct rtc_time tm;
p = buf;
get_rtc_time(&tm);
/*
* There is no way to tell if the luser has the RTC set for local
* time or for Universal Standard Time (GMT). Probably local though.
*/
p += sprintf(p,
"rtc_time\t: %02d:%02d:%02d\n"
"rtc_date\t: %04d-%02d-%02d\n"
"rtc_epoch\t: %04lu\n",
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch);
p += sprintf(p,
"DST_enable\t: no\n"
"BCD\t\t: yes\n"
"24hr\t\t: yes\n" );
return p - buf;
}
static int rtc_read_proc(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
int len = rtc_proc_output (page);
if (len <= off+count) *eof = 1;
*start = page + off;
len -= off;
if (len>count) len = count;
if (len<0) len = 0;
return len;
}
static void get_rtc_time(struct rtc_time *rtc_tm)
{
mf_getRtc( rtc_tm );
rtc_tm->tm_mon--;
}
......@@ -13,7 +13,6 @@ endif
HEAD-y := head.o
HEAD-$(CONFIG_40x) := head_4xx.o
HEAD-$(CONFIG_8xx) := head_8xx.o
HEAD-$(CONFIG_PPC_ISERIES) := iSeries_head.o
HEAD-$(CONFIG_6xx) += idle_6xx.o
EXTRA_TARGETS := $(HEAD-y)
......@@ -27,9 +26,7 @@ obj-y := entry.o traps.o irq.o idle.o time.o misc.o \
obj-$(CONFIG_6xx) += l2cr.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PCI) += pci.o
ifneq ($(CONFIG_PPC_ISERIES),y)
obj-$(CONFIG_PCI) += pci-dma.o
endif
obj-$(CONFIG_KGDB) += ppc-stub.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_TAU) += temp.o
......@@ -38,7 +35,6 @@ ifneq ($(CONFIG_MATH_EMULATION),n)
obj-y += softemu8xx.o
endif
endif
obj-$(CONFIG_PPC_ISERIES) += iSeries_misc.o
find_name : find_name.c
$(HOSTCC) $(HOSTCFLAGS) -o find_name find_name.c
......@@ -25,13 +25,6 @@
#include <asm/cputable.h>
#include <asm/thread_info.h>
#ifdef CONFIG_PPC_ISERIES
#include <asm/iSeries/Paca.h>
#include <asm/iSeries/ItLpPaca.h>
#include <asm/iSeries/ItLpQueue.h>
#include <asm/iSeries/HvLpEvent.h>
#endif /* CONFIG_PPC_ISERIES */
#define DEFINE(sym, val) \
asm volatile("\n->" #sym " %0 " #val : : "i" (val))
......@@ -124,35 +117,6 @@ main(void)
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
#ifdef CONFIG_PPC_ISERIES
DEFINE(PACAPROCENABLED, offsetof(struct Paca, xProcEnabled));
DEFINE(PACAPACAINDEX, offsetof(struct Paca, xPacaIndex));
DEFINE(PACAPROCSTART, offsetof(struct Paca, xProcStart));
DEFINE(PACAKSAVE, offsetof(struct Paca, xKsave));
DEFINE(PACASAVEDMSR, offsetof(struct Paca, xSavedMsr));
DEFINE(PACASAVEDLR, offsetof(struct Paca, xSavedLr));
DEFINE(PACACONTEXTOVERFLOW, offsetof(struct Paca, xContextOverflow));
DEFINE(PACAR21, offsetof(struct Paca, xR21));
DEFINE(PACAR22, offsetof(struct Paca, xR22));
DEFINE(PACALPQUEUE, offsetof(struct Paca, lpQueuePtr));
DEFINE(PACALPPACA, offsetof(struct Paca, xLpPaca));
DEFINE(PACA_STRUCT_SIZE, sizeof(struct Paca));
DEFINE(LPREGSAV, offsetof(struct Paca, xRegSav));
DEFINE(PACADEFAULTDECR, offsetof(struct Paca, default_decr));
DEFINE(LPPACAANYINT, offsetof(struct ItLpPaca, xRsvd));
DEFINE(LPPACASRR0, offsetof(struct ItLpPaca, xSavedSrr0));
DEFINE(LPPACASRR1, offsetof(struct ItLpPaca, xSavedSrr1));
DEFINE(LPPACADECRINT, offsetof(struct ItLpPaca, xDecrInt));
DEFINE(LPPACAIPIINT, offsetof(struct ItLpPaca, xIpiCnt));
DEFINE(LPQCUREVENTPTR, offsetof(struct ItLpQueue, xSlicCurEventPtr));
DEFINE(LPQOVERFLOW, offsetof(struct ItLpQueue, xPlicOverflowIntPending));
DEFINE(LPQINUSEWORD, offsetof(struct ItLpQueue, xInUseWord));
DEFINE(LPEVENTFLAGS, offsetof(struct HvLpEvent, xFlags));
DEFINE(CONTEXT, offsetof(struct mm_struct, context));
DEFINE(_SOFTE, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, mq));
DEFINE(PACA_EXT_INTS, offsetof(struct Paca, ext_ints));
#endif /* CONFIG_PPC_ISERIES */
DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
return 0;
}
......@@ -33,7 +33,7 @@ extern void __setup_cpu_8xx(unsigned long offset, int cpu_nr, struct cpu_spec* s
extern void __setup_cpu_generic(unsigned long offset, int cpu_nr, struct cpu_spec* spec);
#define CLASSIC_PPC (!defined(CONFIG_8xx) && !defined(CONFIG_4xx) && \
!defined(CONFIG_POWER3) && !defined(CONFIG_PPC_ISERIES))
!defined(CONFIG_POWER3))
/* This table only contains "desktop" CPUs, it need to be filled with embedded
* ones as well...
......
......@@ -8,7 +8,6 @@
* rewritten by Paul Mackerras.
* Copyright (C) 1996 Paul Mackerras.
* MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
* Adaptations for iSeries Lpar by Mike Corrigan & Dave Boutcher
*
* This file contains the system call entry code, context switch
* code, and exception/interrupt return code for PowerPC.
......@@ -31,14 +30,10 @@
#include <asm/thread_info.h>
#include <asm/ppc_asm.h>
#include <asm/offsets.h>
#ifdef CONFIG_PPC_ISERIES
#include "iSeries_asm.h"
#endif /* CONFIG_PPC_ISERIES */
#undef SHOW_SYSCALLS
#undef SHOW_SYSCALLS_TASK
#ifndef CONFIG_PPC_ISERIES /* iSeries version is in iSeries_head.S */
/*
* This code finishes saving the registers to the exception frame
* and jumps to the appropriate handler for the exception, turning
......@@ -115,7 +110,6 @@ stack_ovf:
mtspr SRR1,r10
SYNC
RFI
#endif /* CONFIG_PPC_ISERIES */
/*
* Handle a system call.
......@@ -384,8 +378,7 @@ ppc_clone:
* On entry, r3 points to the THREAD for the current task, r4
* points to the THREAD for the new task.
*
* This routine is always called with interrupts disabled
* (soft disabled for iSeries).
* This routine is always called with interrupts disabled.
*
* Note: there are two ways to get to the "going out" portion
* of this code; either by coming in via the entry (_switch)
......
/*
* arch/ppc/kernel/iSeries_asm.h
*
* Definitions used by various bits of low-level assembly code on iSeries.
*
* Copyright (C) 2001 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.
*/
#define CHECKLPQUEUE(ra,rb,rc) \
mfspr rb,SPRG1; /* Get Paca address */\
lbz ra,PACALPPACA+LPPACAIPIINT(rb); /* Get IPI int flag */\
cmpi 0,ra,0; /* IPI occurred in hypervisor ? */\
bne 99f; /* If so, skip rest */\
lwz ra,PACALPQUEUE(rb); /* Get LpQueue address */\
cmpi 0,ra,0; /* Does LpQueue exist? */\
beq 99f; /* If not skip rest */\
lbz rb,LPQINUSEWORD(ra); /* Test for LpQueue recursion */\
cmpi 0,rb,1; /* If we are about to recurse */\
beq 99f; /* If so, skip rest */\
lwz rb,LPQCUREVENTPTR(ra); /* Get current LpEvent */\
lbz rb,LPEVENTFLAGS(rb); /* Get Valid bit */\
lbz rc,LPQOVERFLOW(ra); /* Get LpQueue overflow */\
andi. ra,rb,0x0080; /* Isolate Valid bit */\
or. ra,ra,rc; /* 0 == no pending events */\
99:
#define CHECKDECR(ra,rb) \
mfspr rb,SPRG1; /* Get Paca address */\
lbz ra,PACALPPACA+LPPACADECRINT(rb); /* Get DECR int flag */\
cmpi 0,ra,0; /* DECR occurred in hypervisor ? */\
beq 99f; /* If not, skip rest */\
xor ra,ra,ra; \
stb ra,PACALPPACA+LPPACADECRINT(rb); /* Clear DECR int flag */\
99:
#define CHECKANYINT(ra,rb,rc) \
mfspr rb,SPRG1; /* Get Paca address */\
ld ra,PACALPPACA+LPPACAANYINT(rb); /* Get all interrupt flags */\
/* Note use of ld, protected by soft/hard disabled */\
cmpldi 0,ra,0; /* Any interrupt occurred while soft disabled? */\
bne 99f; /* If so, skip rest */\
lwz ra,PACALPQUEUE(rb); /* Get LpQueue address */\
cmpi 0,ra,0; /* Does LpQueue exist? */\
beq 99f; /* If not skip rest */\
lwz rb,LPQINUSEWORD(ra); /* Test for LpQueue recursion */\
cmpi 0,rb,1; /* If we are about to recurse */\
beq 99f; /* If so, skip rest */\
lwz rb,LPQCUREVENTPTR(ra); /* Get current LpEvent */\
lbz rb,LPEVENTFLAGS(rb); /* Get Valid bit */\
lbz rc,LPQOVERFLOW(ra); /* Get LpQueue overflow */\
andi. ra,rb,0x0080; /* Isolate Valid bit */\
or. ra,ra,rc; /* 0 == no pending events */\
99:
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -866,7 +866,7 @@ kgdb_output_string (const char* s, unsigned int count)
return 1;
}
#if defined(CONFIG_6xx) || defined(CONFIG_POWER3) || defined(CONFIG_ISERIES)
#if defined(CONFIG_6xx) || defined(CONFIG_POWER3)
/* This is used on arches which don't have a serial driver that maps
* the ports for us */
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment