fpmem.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

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 Silicon Graphics, Inc.
  8.  * Copyright (C) 2000 by Jack Steiner (steiner@sgi.com)
  9.  */
  10. /*
  11.  * FPROM EFI memory descriptor build routines
  12.  *
  13.  *  - Routines to build the EFI memory descriptor map
  14.  *  - Should also be usable by the SGI SN1 prom to convert
  15.  *    klconfig to efi_memmap
  16.  */
  17. #include <asm/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. #define MD_BANK_SHFT 30
  48. #define TO_NODE(_n, _x) (((long)_n<<33L) | (long)_x)
  49. /*
  50.  * For SN, this may not take an arg and gets the numnodes from 
  51.  * the prom variable or by traversing klcfg or promcfg
  52.  */
  53. int
  54. GetNumNodes(void)
  55. {
  56. return sn_config->nodes;
  57. }
  58. int
  59. GetNumCpus(void)
  60. {
  61. return sn_config->cpus;
  62. }
  63. /* For SN1, get the index th nasid */
  64. int
  65. GetNasid(int index)
  66. {
  67. return sn_memmap[index].nasid ;
  68. }
  69. node_memmap_t
  70. GetMemBankInfo(int index)
  71. {
  72. return sn_memmap[index].node_memmap ;
  73. }
  74. int
  75. IsCpuPresent(int cnode, int cpu)
  76. {
  77. return  sn_memmap[cnode].cpuconfig & (1<<cpu);
  78. }
  79. /*
  80.  * Made this into an explicit case statement so that
  81.  * we can assign specific properties to banks like bank0
  82.  * actually disabled etc.
  83.  */
  84. int
  85. IsBankPresent(int index, node_memmap_t nmemmap)
  86. {
  87. switch (index) {
  88. case 0:return nmemmap.b0;
  89. case 1:return nmemmap.b1;
  90. case 2:return nmemmap.b2;
  91. case 3:return nmemmap.b3;
  92. case 4:return nmemmap.b4;
  93. case 5:return nmemmap.b5;
  94. case 6:return nmemmap.b6;
  95. case 7:return nmemmap.b7;
  96. default:return -1 ;
  97. }
  98. }
  99. int
  100. GetBankSize(int index, node_memmap_t nmemmap)
  101. {
  102.         switch (index) {
  103.                 case 0:
  104.                 case 1:return nmemmap.b01size;
  105.                 case 2:
  106.                 case 3:return nmemmap.b23size;
  107.                 case 4:
  108.                 case 5:return nmemmap.b45size;
  109.                 case 6:
  110.                 case 7:return nmemmap.b67size;
  111.                 default:return -1 ;
  112.         }
  113. }
  114. void
  115. build_mem_desc(efi_memory_desc_t *md, int type, long paddr, long numbytes)
  116. {
  117.         md->type = type;
  118.         md->phys_addr = paddr;
  119.         md->virt_addr = 0;
  120.         md->num_pages = numbytes >> 12;
  121.         md->attribute = EFI_MEMORY_WB;
  122. }
  123. int
  124. build_efi_memmap(void *md, int mdsize)
  125. {
  126. int numnodes = GetNumNodes() ;
  127. int cnode,bank ;
  128. int nasid ;
  129. node_memmap_t membank_info ;
  130. int bsize;
  131. int count = 0 ;
  132. long paddr, hole, numbytes;
  133. for (cnode=0;cnode<numnodes;cnode++) {
  134. nasid = GetNasid(cnode) ;
  135. membank_info = GetMemBankInfo(cnode) ;
  136. for (bank=0;bank<SN1_MAX_BANK_PER_NODE;bank++) {
  137. if (IsBankPresent(bank, membank_info)) {
  138. bsize = GetBankSize(bank, membank_info) ;
  139.                                 paddr = TO_NODE(nasid, (long)bank<<MD_BANK_SHFT);
  140.                                 numbytes = BankSizeBytes(bsize);
  141.                                 /*
  142.                                  * Check for the node 0 hole. Since banks cant
  143.                                  * span the hole, we only need to check if the end of
  144.                                  * the range is the end of the hole.
  145.                                  */
  146.                                 if (paddr+numbytes == NODE0_HOLE_END)
  147.                                         numbytes -= NODE0_HOLE_SIZE;
  148.                                 /*
  149.                                  * UGLY hack - we must skip overr the kernel and
  150.                                  * PROM runtime services but we dont exactly where it is.
  151.                                  * So lets just reserve 0-12MB.
  152.                                  */
  153.                                 if (bank == 0) {
  154. hole = (cnode == 0) ? KERNEL_SIZE : PROMRESERVED_SIZE;
  155. numbytes -= hole;
  156.                                         build_mem_desc(md, EFI_RUNTIME_SERVICES_DATA, paddr, hole);
  157.                                         paddr += hole;
  158.          count++ ;
  159.                                         md += mdsize;
  160.                                 }
  161.                                 build_mem_desc(md, EFI_CONVENTIONAL_MEMORY, paddr, numbytes);
  162.         md += mdsize ;
  163.         count++ ;
  164. }
  165. }
  166. }
  167. return count ;
  168. }
  169. void
  170. build_init(unsigned long args)
  171. {
  172. sn_config = (sn_config_t *) (args);
  173. sn_memmap = (sn_memmap_t *)(args + 8) ; /* SN equiv for this is */
  174. /* init to klconfig start */
  175. }