mem.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * This program is free software; you can redistribute it and/or modify it
  3. * under the terms of the GNU General Public License as published by the
  4. * Free Software Foundation; either version 2 of the License, or (at your
  5. * option) any later version.
  6. */
  7. #include <linux/fs.h>
  8. #include <linux/fcntl.h>
  9. #include <linux/mm.h>
  10. #include <asm/bootinfo.h>
  11. #include <loongson.h>
  12. #include <mem.h>
  13. #include <pci.h>
  14. void __init prom_init_memory(void)
  15. {
  16. add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
  17. add_memory_region(memsize << 20, LOONGSON_PCI_MEM_START - (memsize <<
  18. 20), BOOT_MEM_RESERVED);
  19. #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
  20. {
  21. int bit;
  22. bit = fls(memsize + highmemsize);
  23. if (bit != ffs(memsize + highmemsize))
  24. bit += 20;
  25. else
  26. bit = bit + 20 - 1;
  27. /* set cpu window3 to map CPU to DDR: 2G -> 2G */
  28. LOONGSON_ADDRWIN_CPUTODDR(ADDRWIN_WIN3, 0x80000000ul,
  29. 0x80000000ul, (1 << bit));
  30. mmiowb();
  31. }
  32. #endif /* !CONFIG_CPU_SUPPORTS_ADDRWINCFG */
  33. #ifdef CONFIG_64BIT
  34. if (highmemsize > 0)
  35. add_memory_region(LOONGSON_HIGHMEM_START,
  36. highmemsize << 20, BOOT_MEM_RAM);
  37. add_memory_region(LOONGSON_PCI_MEM_END + 1, LOONGSON_HIGHMEM_START -
  38. LOONGSON_PCI_MEM_END - 1, BOOT_MEM_RESERVED);
  39. #endif /* !CONFIG_64BIT */
  40. }
  41. /* override of arch/mips/mm/cache.c: __uncached_access */
  42. int __uncached_access(struct file *file, unsigned long addr)
  43. {
  44. if (file->f_flags & O_DSYNC)
  45. return 1;
  46. return addr >= __pa(high_memory) ||
  47. ((addr >= LOONGSON_MMIO_MEM_START) &&
  48. (addr < LOONGSON_MMIO_MEM_END));
  49. }
  50. #ifdef CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED
  51. #include <linux/pci.h>
  52. #include <linux/sched.h>
  53. #include <asm/current.h>
  54. static unsigned long uca_start, uca_end;
  55. pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
  56. unsigned long size, pgprot_t vma_prot)
  57. {
  58. unsigned long offset = pfn << PAGE_SHIFT;
  59. unsigned long end = offset + size;
  60. if (__uncached_access(file, offset)) {
  61. if (((uca_start && offset) >= uca_start) &&
  62. (end <= uca_end))
  63. return __pgprot((pgprot_val(vma_prot) &
  64. ~_CACHE_MASK) |
  65. _CACHE_UNCACHED_ACCELERATED);
  66. else
  67. return pgprot_noncached(vma_prot);
  68. }
  69. return vma_prot;
  70. }
  71. static int __init find_vga_mem_init(void)
  72. {
  73. struct pci_dev *dev = 0;
  74. struct resource *r;
  75. int idx;
  76. if (uca_start)
  77. return 0;
  78. for_each_pci_dev(dev) {
  79. if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
  80. for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
  81. r = &dev->resource[idx];
  82. if (!r->start && r->end)
  83. continue;
  84. if (r->flags & IORESOURCE_IO)
  85. continue;
  86. if (r->flags & IORESOURCE_MEM) {
  87. uca_start = r->start;
  88. uca_end = r->end;
  89. return 0;
  90. }
  91. }
  92. }
  93. }
  94. return 0;
  95. }
  96. late_initcall(find_vga_mem_init);
  97. #endif /* !CONFIG_CPU_SUPPORTS_UNCACHED_ACCELERATED */