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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * memory.c: PROM library functions for acquiring/using memory descriptors
  3.  *           given to us from the ARCS firmware.
  4.  *
  5.  * Copyright (C) 1996 by David S. Miller
  6.  * Copyright (C) 1999, 2000, 2001 by Ralf Baechle
  7.  * Copyright (C) 1999, 2000 by Silicon Graphics, Inc.
  8.  *
  9.  * PROM library functions for acquiring/using memory descriptors given to us
  10.  * from the ARCS firmware.  This is only used when CONFIG_ARC_MEMORY is set
  11.  * because on some machines like SGI IP27 the ARC memory configuration data
  12.  * completly bogus and alternate easier to use mechanisms are available.
  13.  */
  14. #include <linux/init.h>
  15. #include <linux/kernel.h>
  16. #include <linux/types.h>
  17. #include <linux/sched.h>
  18. #include <linux/mm.h>
  19. #include <linux/bootmem.h>
  20. #include <linux/swap.h>
  21. #include <asm/sgialib.h>
  22. #include <asm/page.h>
  23. #include <asm/pgtable.h>
  24. #include <asm/bootinfo.h>
  25. #undef DEBUG
  26. struct linux_mdesc * __init
  27. ArcGetMemoryDescriptor(struct linux_mdesc *Current)
  28. {
  29. return (struct linux_mdesc *) ARC_CALL1(get_mdesc, Current);
  30. }
  31. #ifdef DEBUG /* convenient for debugging */
  32. static char *arcs_mtypes[8] = {
  33. "Exception Block",
  34. "ARCS Romvec Page",
  35. "Free/Contig RAM",
  36. "Generic Free RAM",
  37. "Bad Memory",
  38. "Standalone Program Pages",
  39. "ARCS Temp Storage Area",
  40. "ARCS Permanent Storage Area"
  41. };
  42. static char *arc_mtypes[8] = {
  43. "Exception Block",
  44. "SystemParameterBlock",
  45. "FreeMemory",
  46. "Bad Memory",
  47. "LoadedProgram",
  48. "FirmwareTemporary",
  49. "FirmwarePermanent",
  50. "FreeContiguous"
  51. };
  52. #define mtypes(a) (prom_flags & PROM_FLAG_ARCS) ? arcs_mtypes[a.arcs] 
  53. : arc_mtypes[a.arc]
  54. #endif
  55. static inline int memtype_classify_arcs (union linux_memtypes type)
  56. {
  57. switch (type.arcs) {
  58. case arcs_fcontig:
  59. case arcs_free:
  60. return BOOT_MEM_RAM;
  61. case arcs_atmp:
  62. return BOOT_MEM_ROM_DATA;
  63. case arcs_eblock:
  64. case arcs_rvpage:
  65. case arcs_bmem:
  66. case arcs_prog:
  67. case arcs_aperm:
  68. return BOOT_MEM_RESERVED;
  69. default:
  70. BUG();
  71. }
  72. while(1); /* Nuke warning.  */
  73. }
  74. static inline int memtype_classify_arc (union linux_memtypes type)
  75. {
  76. switch (type.arc) {
  77. case arc_free:
  78. case arc_fcontig:
  79. return BOOT_MEM_RAM;
  80. case arc_atmp:
  81. return BOOT_MEM_ROM_DATA;
  82. case arc_eblock:
  83. case arc_rvpage:
  84. case arc_bmem:
  85. case arc_prog:
  86. case arc_aperm:
  87. return BOOT_MEM_RESERVED;
  88. default:
  89. BUG();
  90. }
  91. while(1); /* Nuke warning.  */
  92. }
  93. static int __init prom_memtype_classify (union linux_memtypes type)
  94. {
  95. if (prom_flags & PROM_FLAG_ARCS) /* SGI is ``different'' ...  */
  96. return memtype_classify_arcs(type);
  97. return memtype_classify_arc(type);
  98. }
  99. void __init prom_meminit(void)
  100. {
  101. struct linux_mdesc *p;
  102. #ifdef DEBUG
  103. int i = 0;
  104. prom_printf("ARCS MEMORY DESCRIPTOR dump:n");
  105. i=0;
  106. prom_printf ("i=%dn", i);
  107. p = ArcGetMemoryDescriptor(PROM_NULL_MDESC);
  108. prom_printf ("i=%dn", i);
  109. while(p) {
  110. prom_printf("[%d,%p]: base<%08lx> pages<%08lx> type<%s>n",
  111.     i, p, p->base, p->pages, mtypes(p->type));
  112. p = ArcGetMemoryDescriptor(p);
  113. i++;
  114. }
  115. #endif
  116. p = PROM_NULL_MDESC;
  117. while ((p = ArcGetMemoryDescriptor(p))) {
  118. unsigned long base, size;
  119. long type;
  120. base = p->base << PAGE_SHIFT;
  121. size = p->pages << PAGE_SHIFT;
  122. type = prom_memtype_classify(p->type);
  123. add_memory_region(base, size, type);
  124. }
  125. }
  126. void __init prom_free_prom_memory (void)
  127. {
  128. unsigned long freed = 0;
  129. unsigned long addr;
  130. int i;
  131. for (i = 0; i < boot_mem_map.nr_map; i++) {
  132. if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
  133. continue;
  134. addr = boot_mem_map.map[i].addr;
  135. while (addr < boot_mem_map.map[i].addr
  136.       + boot_mem_map.map[i].size) {
  137. ClearPageReserved(virt_to_page(__va(addr)));
  138. set_page_count(virt_to_page(__va(addr)), 1);
  139. free_page((unsigned long)__va(addr));
  140. addr += PAGE_SIZE;
  141. freed += PAGE_SIZE;
  142. }
  143. }
  144. printk(KERN_INFO "Freeing prom memory: %ldkb freedn", freed >> 10);
  145. }