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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
  8.  */
  9. /*
  10.  * FPROM EFI memory descriptor build routines
  11.  *
  12.  *  - Routines to build the EFI memory descriptor map
  13.  *  - Should also be usable by the SGI SN1 prom to convert
  14.  *    klconfig to efi_memmap
  15.  */
  16. #include <linux/config.h>
  17. #include <linux/efi.h>
  18. #include "fpmem.h"
  19. /*
  20.  * args points to a layout in memory like this
  21.  *
  22.  * 32 bit 32 bit
  23.  *
  24.  *  numnodes numcpus
  25.  *
  26.  * 16 bit   16 bit    32 bit
  27.  * nasid0 cpuconf membankdesc0
  28.  * nasid1 cpuconf membankdesc1
  29.  *    .
  30.  *    .
  31.  *    .
  32.  *    .
  33.  *    .
  34.  */
  35. sn_memmap_t *sn_memmap ;
  36. sn_config_t *sn_config ;
  37. /*
  38.  * There is a hole in the node 0 address space. Dont put it
  39.  * in the memory map
  40.  */
  41. #define NODE0_HOLE_SIZE         (20*MB)
  42. #define NODE0_HOLE_END          (4UL*GB)
  43. #define MB (1024*1024)
  44. #define GB (1024*MB)
  45. #define KERNEL_SIZE (4*MB)
  46. #define PROMRESERVED_SIZE (1*MB)
  47. #ifdef CONFIG_IA64_SGI_SN1
  48. #define PHYS_ADDRESS(_n, _x) (((long)_n<<33L) | (long)_x)
  49. #define MD_BANK_SHFT 30
  50. #else
  51. #define PHYS_ADDRESS(_n, _x) (((long)_n<<38L) | (long)_x | 0x3000000000UL)
  52. #define MD_BANK_SHFT 34
  53. #endif
  54. /*
  55.  * For SN, this may not take an arg and gets the numnodes from 
  56.  * the prom variable or by traversing klcfg or promcfg
  57.  */
  58. int
  59. GetNumNodes(void)
  60. {
  61. return sn_config->nodes;
  62. }
  63. int
  64. GetNumCpus(void)
  65. {
  66. return sn_config->cpus;
  67. }
  68. /* For SN1, get the index th nasid */
  69. int
  70. GetNasid(int index)
  71. {
  72. return sn_memmap[index].nasid ;
  73. }
  74. node_memmap_t
  75. GetMemBankInfo(int index)
  76. {
  77. return sn_memmap[index].node_memmap ;
  78. }
  79. int
  80. IsCpuPresent(int cnode, int cpu)
  81. {
  82. return  sn_memmap[cnode].cpuconfig & (1<<cpu);
  83. }
  84. /*
  85.  * Made this into an explicit case statement so that
  86.  * we can assign specific properties to banks like bank0
  87.  * actually disabled etc.
  88.  */
  89. #ifdef CONFIG_IA64_SGI_SN1
  90. int
  91. IsBankPresent(int index, node_memmap_t nmemmap)
  92. {
  93. switch (index) {
  94. case 0:return nmemmap.b0;
  95. case 1:return nmemmap.b1;
  96. case 2:return nmemmap.b2;
  97. case 3:return nmemmap.b3;
  98. case 4:return nmemmap.b4;
  99. case 5:return nmemmap.b5;
  100. case 6:return nmemmap.b6;
  101. case 7:return nmemmap.b7;
  102. default:return -1 ;
  103. }
  104. }
  105. int
  106. GetBankSize(int index, node_memmap_t nmemmap)
  107. {
  108.         switch (index) {
  109.                 case 0:
  110.                 case 1:return nmemmap.b01size;
  111.                 case 2:
  112.                 case 3:return nmemmap.b23size;
  113.                 case 4:
  114.                 case 5:return nmemmap.b45size;
  115.                 case 6:
  116.                 case 7:return nmemmap.b67size;
  117.                 default:return -1 ;
  118.         }
  119. }
  120. #else
  121. int
  122. IsBankPresent(int index, node_memmap_t nmemmap)
  123. {
  124. switch (index) {
  125. case 0:return BankPresent(nmemmap.b0size);
  126. case 1:return BankPresent(nmemmap.b1size);
  127. case 2:return BankPresent(nmemmap.b2size);
  128. case 3:return BankPresent(nmemmap.b3size);
  129. default:return -1 ;
  130. }
  131. }
  132. int
  133. GetBankSize(int index, node_memmap_t nmemmap)
  134. {
  135. /*
  136.  * Add 2 because there are 4 dimms per bank.
  137.  */
  138.         switch (index) {
  139.                 case 0:return 2 + ((long)nmemmap.b0size + nmemmap.b0dou);
  140.                 case 1:return 2 + ((long)nmemmap.b1size + nmemmap.b1dou);
  141.                 case 2:return 2 + ((long)nmemmap.b2size + nmemmap.b2dou);
  142.                 case 3:return 2 + ((long)nmemmap.b3size + nmemmap.b3dou);
  143.                 default:return -1 ;
  144.         }
  145. }
  146. #endif
  147. void
  148. build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
  149. {
  150.         md->type = type;
  151.         md->phys_addr = paddr;
  152.         md->virt_addr = 0;
  153.         md->num_pages = numbytes >> 12;
  154.         md->attribute = EFI_MEMORY_WB;
  155. }
  156. int
  157. build_efi_memmap(void *md, int mdsize)
  158. {
  159. int numnodes = GetNumNodes() ;
  160. int cnode,bank ;
  161. int nasid ;
  162. node_memmap_t membank_info ;
  163. int bsize;
  164. int count = 0 ;
  165. long paddr, hole, numbytes;
  166. for (cnode=0;cnode<numnodes;cnode++) {
  167. nasid = GetNasid(cnode) ;
  168. membank_info = GetMemBankInfo(cnode) ;
  169. for (bank=0;bank<PLAT_CLUMPS_PER_NODE;bank++) {
  170. if (IsBankPresent(bank, membank_info)) {
  171. bsize = GetBankSize(bank, membank_info) ;
  172.                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
  173.                                 numbytes = BankSizeBytes(bsize);
  174. #ifdef CONFIG_IA64_SGI_SN2
  175. /* 
  176.  * Ignore directory.
  177.  * Shorten memory chunk by 1 page - makes a better
  178.  * testcase & is more like the real PROM.
  179.  */
  180. numbytes = numbytes * 31 / 32;
  181. #endif
  182. numbytes -= 1000;
  183.                                 /*
  184.                                  * Check for the node 0 hole. Since banks cant
  185.                                  * span the hole, we only need to check if the end of
  186.                                  * the range is the end of the hole.
  187.                                  */
  188.                                 if (paddr+numbytes == NODE0_HOLE_END)
  189.                                         numbytes -= NODE0_HOLE_SIZE;
  190.                                 /*
  191.                                  * UGLY hack - we must skip overr the kernel and
  192.                                  * PROM runtime services but we dont exactly where it is.
  193.                                  * So lets just reserve:
  194.  * node 0
  195.  * 0-1MB for PAL
  196.  * 1-4MB for SAL
  197.  * node 1-N
  198.  * 0-1 for SAL
  199.                                  */
  200.                                 if (bank == 0) {
  201. if (cnode == 0) {
  202. hole = 1*1024*1024;
  203. build_mem_desc(md, EFI_PAL_CODE, paddr, hole);
  204. numbytes -= hole;
  205.                                          paddr += hole;
  206.          count++ ;
  207.                                          md += mdsize;
  208. hole = 3*1024*1024;
  209. build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
  210. numbytes -= hole;
  211.                                          paddr += hole;
  212.          count++ ;
  213.                                          md += mdsize;
  214. } else {
  215. hole = PROMRESERVED_SIZE;
  216.                                          build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
  217. numbytes -= hole;
  218.                                          paddr += hole;
  219.          count++ ;
  220.                                          md += mdsize;
  221. }
  222.                                 }
  223.                                 build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
  224.         md += mdsize ;
  225.         count++ ;
  226. }
  227. }
  228. }
  229. return count ;
  230. }
  231. void
  232. build_init(unsigned long args)
  233. {
  234. sn_config = (sn_config_t *) (args);
  235. sn_memmap = (sn_memmap_t *)(args + 8) ; /* SN equiv for this is */
  236. /* init to klconfig start */
  237. }