iSeries_IoMmTable.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:9k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /************************************************************************/
  2. /* This module supports the iSeries I/O Address translation mapping     */
  3. /* Copyright (C) 20yy  <Allan H Trautman> <IBM Corp>                    */
  4. /*                                                                      */
  5. /* This program is free software; you can redistribute it and/or modify */
  6. /* it under the terms of the GNU General Public License as published by */
  7. /* the Free Software Foundation; either version 2 of the License, or    */
  8. /* (at your option) any later version.                                  */
  9. /*                                                                      */
  10. /* This program is distributed in the hope that it will be useful,      */ 
  11. /* but WITHOUT ANY WARRANTY; without even the implied warranty of       */
  12. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        */
  13. /* GNU General Public License for more details.                         */
  14. /*                                                                      */
  15. /* You should have received a copy of the GNU General Public License    */ 
  16. /* along with this program; if not, write to the:                       */
  17. /* Free Software Foundation, Inc.,                                      */ 
  18. /* 59 Temple Place, Suite 330,                                          */ 
  19. /* Boston, MA  02111-1307  USA                                          */
  20. /************************************************************************/
  21. /* Change Activity:                                                     */
  22. /*   Created, December 14, 2000                                         */
  23. /*   Added Bar table for IoMm performance.                              */
  24. /*   Ported to ppc64                                                    */
  25. /*   Added dynamic table allocation                                     */
  26. /* End Change Activity                                                  */
  27. /************************************************************************/
  28. #include <asm/types.h>
  29. #include <asm/resource.h>
  30. #include <linux/pci.h>
  31. #include <linux/spinlock.h>
  32. #include <asm/ppcdebug.h>
  33. #include <asm/flight_recorder.h>
  34. #include <asm/iSeries/HvCallPci.h>
  35. #include <asm/iSeries/iSeries_pci.h>
  36. #include "iSeries_IoMmTable.h"
  37. #include "pci.h"
  38. /*******************************************************************/
  39. /* Table defines                                                   */
  40. /* Each Entry size is 4 MB * 1024 Entries = 4GB I/O address space. */
  41. /*******************************************************************/
  42. #define Max_Entries 1024
  43. unsigned long iSeries_IoMmTable_Entry_Size = 0x0000000000400000; 
  44. unsigned long iSeries_Base_Io_Memory       = 0xE000000000000000;
  45. unsigned long iSeries_Max_Io_Memory        = 0xE000000000000000;
  46. static   long iSeries_CurrentIndex         = 0;
  47. /*******************************************************************/
  48. /* Lookup Tables.                                                  */
  49. /*******************************************************************/
  50. struct iSeries_Device_Node** iSeries_IoMmTable;
  51. u8*                          iSeries_IoBarTable;
  52. /*******************************************************************/
  53. /* Static and Global variables                                     */
  54. /*******************************************************************/
  55. static char*      iSeriesPciIoText     = "iSeries PCI I/O";
  56. static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED;
  57. /*******************************************************************/
  58. /* iSeries_IoMmTable_Initialize                                    */
  59. /*******************************************************************/
  60. /* Allocates and initalizes the Address Translation Table and Bar  */
  61. /* Tables to get them ready for use.  Must be called before any    */
  62. /* I/O space is handed out to the device BARs.                     */
  63. /* A follow up method,iSeries_IoMmTable_Status can be called to    */
  64. /* adjust the table after the device BARs have been assiged to     */
  65. /* resize the table.                                               */
  66. /*******************************************************************/
  67. void iSeries_IoMmTable_Initialize(void)
  68. {
  69. spin_lock(&iSeriesIoMmTableLock);
  70. iSeries_IoMmTable  = kmalloc(sizeof(void*)*Max_Entries,GFP_KERNEL);
  71. iSeries_IoBarTable = kmalloc(sizeof(u8)*Max_Entries,   GFP_KERNEL);
  72. spin_unlock(&iSeriesIoMmTableLock);
  73. PCIFR("IoMmTable Initialized 0x%p",  iSeries_IoMmTable);
  74. if(iSeries_IoMmTable == NULL || iSeries_IoBarTable == NULL) {
  75. panic("PCI: I/O tables allocation failed.n");
  76. }
  77. }
  78. /*******************************************************************/
  79. /* iSeries_IoMmTable_AllocateEntry                                 */
  80. /*******************************************************************/
  81. /* Adds pci_dev entry in address translation table                 */
  82. /*******************************************************************/
  83. /* - Allocates the number of entries required in table base on BAR */
  84. /*   size.                                                         */
  85. /* - Allocates starting at iSeries_Base_Io_Memory and increases.   */
  86. /* - The size is round up to be a multiple of entry size.          */
  87. /* - CurrentIndex is incremented to keep track of the last entry.  */
  88. /* - Builds the resource entry for allocated BARs.                 */
  89. /*******************************************************************/
  90. static void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDev, int BarNumber)
  91. {
  92. struct resource* BarResource = &PciDev->resource[BarNumber];
  93. long             BarSize     = pci_resource_len(PciDev,BarNumber);
  94. /***********************************************************/
  95. /* No space to allocate, quick exit, skip Allocation.      */
  96. /***********************************************************/
  97. if(BarSize == 0) return;
  98. /***********************************************************/
  99. /* Set Resource values.                                    */
  100. /***********************************************************/
  101. spin_lock(&iSeriesIoMmTableLock);
  102. BarResource->name  = iSeriesPciIoText;
  103. BarResource->start = iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex;
  104. BarResource->start+= iSeries_Base_Io_Memory;
  105. BarResource->end   = BarResource->start+BarSize-1;
  106. /***********************************************************/
  107. /* Allocate the number of table entries needed for BAR.    */
  108. /***********************************************************/
  109. while (BarSize > 0 ) {
  110. *(iSeries_IoMmTable +iSeries_CurrentIndex) = (struct iSeries_Device_Node*)PciDev->sysdata;
  111. *(iSeries_IoBarTable+iSeries_CurrentIndex) = BarNumber;
  112. BarSize -= iSeries_IoMmTable_Entry_Size;
  113. ++iSeries_CurrentIndex;
  114. }
  115. iSeries_Max_Io_Memory = (iSeries_IoMmTable_Entry_Size*iSeries_CurrentIndex)+iSeries_Base_Io_Memory;
  116. spin_unlock(&iSeriesIoMmTableLock);
  117. }
  118. /*******************************************************************/
  119. /* iSeries_allocateDeviceBars                                      */
  120. /*******************************************************************/
  121. /* - Allocates ALL pci_dev BAR's and updates the resources with the*/
  122. /*   BAR value.  BARS with zero length will have the resources     */
  123. /*   The HvCallPci_getBarParms is used to get the size of the BAR  */
  124. /*   space.  It calls iSeries_IoMmTable_AllocateEntry to allocate  */
  125. /*   each entry.                                                   */
  126. /* - Loops through The Bar resourses(0 - 5) including the ROM      */
  127. /*   is resource(6).                                               */
  128. /*******************************************************************/
  129. void iSeries_allocateDeviceBars(struct pci_dev* PciDev)
  130. {
  131. struct resource* BarResource;
  132. int              BarNumber;
  133. for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) {
  134. BarResource = &PciDev->resource[BarNumber];
  135. iSeries_IoMmTable_AllocateEntry(PciDev, BarNumber);
  136.      }
  137. }
  138. /************************************************************************/
  139. /* Translates the IoAddress to the device that is mapped to IoSpace.    */
  140. /* This code is inlined, see the iSeries_pci.c file for the replacement.*/
  141. /************************************************************************/
  142. struct iSeries_Device_Node* iSeries_xlateIoMmAddress(void* IoAddress)
  143. {
  144. return NULL;    
  145. }
  146. /************************************************************************
  147.  * Status hook for IoMmTable
  148.  ************************************************************************/
  149. void     iSeries_IoMmTable_Status(void)
  150. {
  151. PCIFR("IoMmTable......: 0x%p",iSeries_IoMmTable);
  152. PCIFR("IoMmTable Range: 0x%p to 0x%p",iSeries_Base_Io_Memory,iSeries_Max_Io_Memory);
  153. return;
  154. }