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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: memory.c,v 1.5 1999/08/31 06:55:04 davem Exp $
  2.  * memory.c: Prom routine for acquiring various bits of information
  3.  *           about RAM on the machine, both virtual and physical.
  4.  *
  5.  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  6.  * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  7.  */
  8. #include <linux/kernel.h>
  9. #include <linux/init.h>
  10. #include <asm/openprom.h>
  11. #include <asm/oplib.h>
  12. /* This routine, for consistency, returns the ram parameters in the
  13.  * V0 prom memory descriptor format.  I choose this format because I
  14.  * think it was the easiest to work with.  I feel the religious
  15.  * arguments now... ;)  Also, I return the linked lists sorted to
  16.  * prevent paging_init() upset stomach as I have not yet written
  17.  * the pepto-bismol kernel module yet.
  18.  */
  19. struct linux_prom64_registers prom_reg_memlist[64];
  20. struct linux_prom64_registers prom_reg_tmp[64];
  21. struct linux_mlist_p1275 prom_phys_total[64];
  22. struct linux_mlist_p1275 prom_prom_taken[64];
  23. struct linux_mlist_p1275 prom_phys_avail[64];
  24. struct linux_mlist_p1275 *prom_ptot_ptr = prom_phys_total;
  25. struct linux_mlist_p1275 *prom_ptak_ptr = prom_prom_taken;
  26. struct linux_mlist_p1275 *prom_pavl_ptr = prom_phys_avail;
  27. struct linux_mem_p1275 prom_memlist;
  28. /* Internal Prom library routine to sort a linux_mlist_p1275 memory
  29.  * list.  Used below in initialization.
  30.  */
  31. static void __init
  32. prom_sortmemlist(struct linux_mlist_p1275 *thislist)
  33. {
  34. int swapi = 0;
  35. int i, mitr;
  36. unsigned long tmpaddr, tmpsize;
  37. unsigned long lowest;
  38. for(i=0; thislist[i].theres_more != 0; i++) {
  39. lowest = thislist[i].start_adr;
  40. for(mitr = i+1; thislist[mitr-1].theres_more != 0; mitr++)
  41. if(thislist[mitr].start_adr < lowest) {
  42. lowest = thislist[mitr].start_adr;
  43. swapi = mitr;
  44. }
  45. if(lowest == thislist[i].start_adr) continue;
  46. tmpaddr = thislist[swapi].start_adr;
  47. tmpsize = thislist[swapi].num_bytes;
  48. for(mitr = swapi; mitr > i; mitr--) {
  49. thislist[mitr].start_adr = thislist[mitr-1].start_adr;
  50. thislist[mitr].num_bytes = thislist[mitr-1].num_bytes;
  51. }
  52. thislist[i].start_adr = tmpaddr;
  53. thislist[i].num_bytes = tmpsize;
  54. }
  55. }
  56. /* Initialize the memory lists based upon the prom version. */
  57. void __init prom_meminit(void)
  58. {
  59. int node = 0;
  60. unsigned int iter, num_regs;
  61. node = prom_finddevice("/memory");
  62. num_regs = prom_getproperty(node, "available",
  63.     (char *) prom_reg_memlist,
  64.     sizeof(prom_reg_memlist));
  65. num_regs = (num_regs/sizeof(struct linux_prom64_registers));
  66. for(iter=0; iter<num_regs; iter++) {
  67. prom_phys_avail[iter].start_adr =
  68. prom_reg_memlist[iter].phys_addr;
  69. prom_phys_avail[iter].num_bytes =
  70. prom_reg_memlist[iter].reg_size;
  71. prom_phys_avail[iter].theres_more =
  72. &prom_phys_avail[iter+1];
  73. }
  74. prom_phys_avail[iter-1].theres_more = 0x0;
  75. num_regs = prom_getproperty(node, "reg",
  76.     (char *) prom_reg_memlist,
  77.     sizeof(prom_reg_memlist));
  78. num_regs = (num_regs/sizeof(struct linux_prom64_registers));
  79. for(iter=0; iter<num_regs; iter++) {
  80. prom_phys_total[iter].start_adr =
  81. prom_reg_memlist[iter].phys_addr;
  82. prom_phys_total[iter].num_bytes =
  83. prom_reg_memlist[iter].reg_size;
  84. prom_phys_total[iter].theres_more =
  85. &prom_phys_total[iter+1];
  86. }
  87. prom_phys_total[iter-1].theres_more = 0x0;
  88. node = prom_finddevice("/virtual-memory");
  89. num_regs = prom_getproperty(node, "available",
  90.     (char *) prom_reg_memlist,
  91.     sizeof(prom_reg_memlist));
  92. num_regs = (num_regs/sizeof(struct linux_prom64_registers));
  93. /* Convert available virtual areas to taken virtual
  94.  * areas.  First sort, then convert.
  95.  */
  96. for(iter=0; iter<num_regs; iter++) {
  97. prom_prom_taken[iter].start_adr =
  98. prom_reg_memlist[iter].phys_addr;
  99. prom_prom_taken[iter].num_bytes =
  100. prom_reg_memlist[iter].reg_size;
  101. prom_prom_taken[iter].theres_more =
  102. &prom_phys_total[iter+1];
  103. }
  104. prom_prom_taken[iter-1].theres_more = 0x0;
  105. prom_sortmemlist(prom_prom_taken);
  106. /* Finally, convert. */
  107. for(iter=0; iter<num_regs; iter++) {
  108. prom_prom_taken[iter].start_adr =
  109. prom_prom_taken[iter].start_adr +
  110. prom_prom_taken[iter].num_bytes;
  111. prom_prom_taken[iter].num_bytes =
  112. prom_prom_taken[iter+1].start_adr -
  113. prom_prom_taken[iter].start_adr;
  114. }
  115. prom_prom_taken[iter-1].num_bytes =
  116. -1UL - prom_prom_taken[iter-1].start_adr;
  117. /* Sort the other two lists. */
  118. prom_sortmemlist(prom_phys_total);
  119. prom_sortmemlist(prom_phys_avail);
  120. /* Link all the lists into the top-level descriptor. */
  121. prom_memlist.p1275_totphys=&prom_ptot_ptr;
  122. prom_memlist.p1275_prommap=&prom_ptak_ptr;
  123. prom_memlist.p1275_available=&prom_pavl_ptr;
  124. }
  125. /* This returns a pointer to our libraries internal p1275 format
  126.  * memory descriptor.
  127.  */
  128. struct linux_mem_p1275 *
  129. prom_meminfo(void)
  130. {
  131. return &prom_memlist;
  132. }