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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * memory.c: memory initialisation code.
  3.  *
  4.  * Copyright (C) 1998 Harald Koerfgen, Frieder Streffer and Paul M. Antoine
  5.  * Copyright (C) 2000 Maciej W. Rozycki
  6.  */
  7. #include <linux/init.h>
  8. #include <linux/config.h>
  9. #include <linux/kernel.h>
  10. #include <linux/mm.h>
  11. #include <linux/bootmem.h>
  12. #include <asm/addrspace.h>
  13. #include <asm/page.h>
  14. #include <asm/bootinfo.h>
  15. #include <asm/dec/machtype.h>
  16. #include "prom.h"
  17. typedef struct {
  18. int pagesize;
  19. unsigned char bitmap[0];
  20. } memmap;
  21. extern int (*rex_getbitmap)(memmap *);
  22. #undef PROM_DEBUG
  23. #ifdef PROM_DEBUG
  24. extern int (*prom_printf)(char *, ...);
  25. #endif
  26. volatile unsigned long mem_err = 0; /* So we know an error occurred */
  27. /*
  28.  * Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
  29.  * off the end of real memory.  Only suitable for the 2100/3100's (PMAX).
  30.  */
  31. #define CHUNK_SIZE 0x400000
  32. static void __init pmax_setup_memory_region(void)
  33. {
  34. volatile unsigned char *memory_page, dummy;
  35. char old_handler[0x80];
  36. extern char genexcept_early;
  37. /* Install exception handler */
  38. memcpy(&old_handler, (void *)(KSEG0 + 0x80), 0x80);
  39. memcpy((void *)(KSEG0 + 0x80), &genexcept_early, 0x80);
  40. /* read unmapped and uncached (KSEG1)
  41.  * DECstations have at least 4MB RAM
  42.  * Assume less than 480MB of RAM, as this is max for 5000/2xx
  43.  * FIXME this should be replaced by the first free page!
  44.  */
  45. for (memory_page = (unsigned char *) KSEG1 + CHUNK_SIZE;
  46.      (mem_err== 0) && (memory_page < ((unsigned char *) KSEG1+0x1E000000));
  47.         memory_page += CHUNK_SIZE) {
  48. dummy = *memory_page;
  49. }
  50. memcpy((void *)(KSEG0 + 0x80), &old_handler, 0x80);
  51. add_memory_region(0, (unsigned long)memory_page - KSEG1 - CHUNK_SIZE,
  52.   BOOT_MEM_RAM);
  53. }
  54. /*
  55.  * Use the REX prom calls to get hold of the memory bitmap, and thence
  56.  * determine memory size.
  57.  */
  58. static void __init rex_setup_memory_region(void)
  59. {
  60. int i, bitmap_size;
  61. unsigned long mem_start = 0, mem_size = 0;
  62. memmap *bm;
  63. /* some free 64k */
  64. bm = (memmap *) 0x80028000;
  65. bitmap_size = rex_getbitmap(bm);
  66. for (i = 0; i < bitmap_size; i++) {
  67. /* FIXME: very simplistically only add full sets of pages */
  68. if (bm->bitmap[i] == 0xff)
  69. mem_size += (8 * bm->pagesize);
  70. else if (!mem_size)
  71. mem_start += (8 * bm->pagesize);
  72. else {
  73. add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
  74. mem_start += mem_size + (8 * bm->pagesize);
  75. mem_size = 0;
  76. }
  77. }
  78. if (mem_size)
  79. add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
  80. }
  81. void __init prom_meminit(unsigned int magic)
  82. {
  83. if (magic != REX_PROM_MAGIC)
  84. pmax_setup_memory_region();
  85. else
  86. rex_setup_memory_region();
  87. }
  88. void __init prom_free_prom_memory (void)
  89. {
  90. unsigned long addr, end;
  91. extern char _ftext;
  92. /*
  93.  * Free everything below the kernel itself but leave
  94.  * the first page reserved for the exception handlers.
  95.  */
  96. #if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
  97. /*
  98.  * Leave 128 KB reserved for Lance memory for
  99.  * IOASIC DECstations.
  100.  *
  101.  * XXX: save this address for use in dec_lance.c?
  102.  */
  103. if (IOASIC)
  104. end = __pa(&_ftext) - 0x00020000;
  105. else
  106. #endif
  107. end = __pa(&_ftext);
  108. addr = PAGE_SIZE;
  109. while (addr < end) {
  110. ClearPageReserved(virt_to_page(__va(addr)));
  111. set_page_count(virt_to_page(__va(addr)), 1);
  112. free_page((unsigned long)__va(addr));
  113. addr += PAGE_SIZE;
  114. }
  115. printk("Freeing unused PROM memory: %ldk freedn",
  116.        (end - PAGE_SIZE) >> 10);
  117. }