patch-2.4.19 linux-2.4.19/arch/ppc64/kernel/iSeries_IoMmTable.c
Next file: linux-2.4.19/arch/ppc64/kernel/iSeries_IoMmTable.h
Previous file: linux-2.4.19/arch/ppc64/kernel/i8259.h
Back to the patch index
Back to the overall index
- Lines: 164
- Date:
Fri Aug 2 17:39:43 2002
- Orig file:
linux-2.4.18/arch/ppc64/kernel/iSeries_IoMmTable.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -urN linux-2.4.18/arch/ppc64/kernel/iSeries_IoMmTable.c linux-2.4.19/arch/ppc64/kernel/iSeries_IoMmTable.c
@@ -0,0 +1,163 @@
+/************************************************************************/
+/* This module supports the iSeries I/O Address translation mapping */
+/* 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, December 14, 2000 */
+/* Added Bar table for IoMm performance. */
+/* Ported to ppc64 */
+/* Added dynamic table allocation */
+/* End Change Activity */
+/************************************************************************/
+#include <asm/types.h>
+#include <asm/resource.h>
+#include <linux/pci.h>
+#include <linux/spinlock.h>
+#include <asm/ppcdebug.h>
+#include <asm/flight_recorder.h>
+#include <asm/iSeries/HvCallPci.h>
+#include <asm/iSeries/iSeries_pci.h>
+
+#include "iSeries_IoMmTable.h"
+#include "pci.h"
+
+/*******************************************************************/
+/* Table defines */
+/* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space. */
+/*******************************************************************/
+#define Max_Entries 1024
+unsigned long iSeries_IoMmTable_Entry_Size = 0x0000000000400000;
+unsigned long iSeries_Base_Io_Memory = 0xE000000000000000;
+unsigned long iSeries_Max_Io_Memory = 0xE000000000000000;
+static long iSeries_CurrentIndex = 0;
+
+/*******************************************************************/
+/* Lookup Tables. */
+/*******************************************************************/
+struct iSeries_Device_Node** iSeries_IoMmTable;
+u8* iSeries_IoBarTable;
+
+/*******************************************************************/
+/* Static and Global variables */
+/*******************************************************************/
+static char* iSeriesPciIoText = "iSeries PCI I/O";
+static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED;
+
+/*******************************************************************/
+/* iSeries_IoMmTable_Initialize */
+/*******************************************************************/
+/* Allocates and initalizes the Address Translation Table and Bar */
+/* Tables to get them ready for use. Must be called before any */
+/* I/O space is handed out to the device BARs. */
+/* A follow up method,iSeries_IoMmTable_Status can be called to */
+/* adjust the table after the device BARs have been assiged to */
+/* resize the table. */
+/*******************************************************************/
+void iSeries_IoMmTable_Initialize(void)
+{
+ spin_lock(&iSeriesIoMmTableLock);
+ iSeries_IoMmTable = kmalloc(sizeof(void*)*Max_Entries,GFP_KERNEL);
+ iSeries_IoBarTable = kmalloc(sizeof(u8)*Max_Entries, GFP_KERNEL);
+ spin_unlock(&iSeriesIoMmTableLock);
+ PCIFR("IoMmTable Initialized 0x%p", iSeries_IoMmTable);
+ if(iSeries_IoMmTable == NULL || iSeries_IoBarTable == NULL) {
+ panic("PCI: I/O tables allocation failed.\n");
+ }
+}
+
+/*******************************************************************/
+/* iSeries_IoMmTable_AllocateEntry */
+/*******************************************************************/
+/* Adds pci_dev entry in address translation table */
+/*******************************************************************/
+/* - Allocates the number of entries required in table base on BAR */
+/* size. */
+/* - Allocates starting at iSeries_Base_Io_Memory and increases. */
+/* - The size is round up to be a multiple of entry size. */
+/* - CurrentIndex is incremented to keep track of the last entry. */
+/* - Builds the resource entry for allocated BARs. */
+/*******************************************************************/
+static void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDev, int BarNumber)
+{
+ struct resource* BarResource = &PciDev->resource[BarNumber];
+ long BarSize = pci_resource_len(PciDev,BarNumber);
+ /***********************************************************/
+ /* No space to allocate, quick exit, skip Allocation. */
+ /***********************************************************/
+ if(BarSize == 0) return;
+ /***********************************************************/
+ /* Set Resource values. */
+ /***********************************************************/
+ spin_lock(&iSeriesIoMmTableLock);
+ BarResource->name = iSeriesPciIoText;
+ BarResource->start = iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex;
+ BarResource->start+= iSeries_Base_Io_Memory;
+ BarResource->end = BarResource->start+BarSize-1;
+ /***********************************************************/
+ /* Allocate the number of table entries needed for BAR. */
+ /***********************************************************/
+ while (BarSize > 0 ) {
+ *(iSeries_IoMmTable +iSeries_CurrentIndex) = (struct iSeries_Device_Node*)PciDev->sysdata;
+ *(iSeries_IoBarTable+iSeries_CurrentIndex) = BarNumber;
+ BarSize -= iSeries_IoMmTable_Entry_Size;
+ ++iSeries_CurrentIndex;
+ }
+ iSeries_Max_Io_Memory = (iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex)+iSeries_Base_Io_Memory;
+ spin_unlock(&iSeriesIoMmTableLock);
+}
+
+/*******************************************************************/
+/* iSeries_allocateDeviceBars */
+/*******************************************************************/
+/* - Allocates ALL pci_dev BAR's and updates the resources with the*/
+/* BAR value. BARS with zero length will have the resources */
+/* The HvCallPci_getBarParms is used to get the size of the BAR */
+/* space. It calls iSeries_IoMmTable_AllocateEntry to allocate */
+/* each entry. */
+/* - Loops through The Bar resourses(0 - 5) including the the ROM */
+/* is resource(6). */
+/*******************************************************************/
+void iSeries_allocateDeviceBars(struct pci_dev* PciDev)
+{
+ struct resource* BarResource;
+ int BarNumber;
+ for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) {
+ BarResource = &PciDev->resource[BarNumber];
+ iSeries_IoMmTable_AllocateEntry(PciDev, BarNumber);
+ }
+}
+
+/************************************************************************/
+/* Translates the IoAddress to the device that is mapped to IoSpace. */
+/* This code is inlined, see the iSeries_pci.c file for the replacement.*/
+/************************************************************************/
+struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress)
+{
+ return NULL;
+}
+
+/************************************************************************
+ * Status hook for IoMmTable
+ ************************************************************************/
+void iSeries_IoMmTable_Status(void)
+{
+ PCIFR("IoMmTable......: 0x%p",iSeries_IoMmTable);
+ PCIFR("IoMmTable Range: 0x%p to 0x%p",iSeries_Base_Io_Memory,iSeries_Max_Io_Memory);
+ return;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)