page_mm.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #ifndef _M68K_PAGE_MM_H
  2. #define _M68K_PAGE_MM_H
  3. #ifndef __ASSEMBLY__
  4. #include <linux/compiler.h>
  5. #include <asm/module.h>
  6. #define get_user_page(vaddr) __get_free_page(GFP_KERNEL)
  7. #define free_user_page(page, addr) free_page(addr)
  8. /*
  9. * We don't need to check for alignment etc.
  10. */
  11. #ifdef CPU_M68040_OR_M68060_ONLY
  12. static inline void copy_page(void *to, void *from)
  13. {
  14. unsigned long tmp;
  15. __asm__ __volatile__("1:\t"
  16. ".chip 68040\n\t"
  17. "move16 %1@+,%0@+\n\t"
  18. "move16 %1@+,%0@+\n\t"
  19. ".chip 68k\n\t"
  20. "dbra %2,1b\n\t"
  21. : "=a" (to), "=a" (from), "=d" (tmp)
  22. : "0" (to), "1" (from) , "2" (PAGE_SIZE / 32 - 1)
  23. );
  24. }
  25. static inline void clear_page(void *page)
  26. {
  27. unsigned long tmp;
  28. unsigned long *sp = page;
  29. *sp++ = 0;
  30. *sp++ = 0;
  31. *sp++ = 0;
  32. *sp++ = 0;
  33. __asm__ __volatile__("1:\t"
  34. ".chip 68040\n\t"
  35. "move16 %2@+,%0@+\n\t"
  36. ".chip 68k\n\t"
  37. "subqw #8,%2\n\t"
  38. "subqw #8,%2\n\t"
  39. "dbra %1,1b\n\t"
  40. : "=a" (sp), "=d" (tmp)
  41. : "a" (page), "0" (sp),
  42. "1" ((PAGE_SIZE - 16) / 16 - 1));
  43. }
  44. #else
  45. #define clear_page(page) memset((page), 0, PAGE_SIZE)
  46. #define copy_page(to,from) memcpy((to), (from), PAGE_SIZE)
  47. #endif
  48. #define clear_user_page(addr, vaddr, page) \
  49. do { clear_page(addr); \
  50. flush_dcache_page(page); \
  51. } while (0)
  52. #define copy_user_page(to, from, vaddr, page) \
  53. do { copy_page(to, from); \
  54. flush_dcache_page(page); \
  55. } while (0)
  56. extern unsigned long m68k_memoffset;
  57. #ifndef CONFIG_SUN3
  58. #define WANT_PAGE_VIRTUAL
  59. static inline unsigned long ___pa(void *vaddr)
  60. {
  61. unsigned long paddr;
  62. asm (
  63. "1: addl #0,%0\n"
  64. m68k_fixup(%c2, 1b+2)
  65. : "=r" (paddr)
  66. : "0" (vaddr), "i" (m68k_fixup_memoffset));
  67. return paddr;
  68. }
  69. #define __pa(vaddr) ___pa((void *)(long)(vaddr))
  70. static inline void *__va(unsigned long paddr)
  71. {
  72. void *vaddr;
  73. asm (
  74. "1: subl #0,%0\n"
  75. m68k_fixup(%c2, 1b+2)
  76. : "=r" (vaddr)
  77. : "0" (paddr), "i" (m68k_fixup_memoffset));
  78. return vaddr;
  79. }
  80. #else /* !CONFIG_SUN3 */
  81. /* This #define is a horrible hack to suppress lots of warnings. --m */
  82. #define __pa(x) ___pa((unsigned long)(x))
  83. static inline unsigned long ___pa(unsigned long x)
  84. {
  85. if(x == 0)
  86. return 0;
  87. if(x >= PAGE_OFFSET)
  88. return (x-PAGE_OFFSET);
  89. else
  90. return (x+0x2000000);
  91. }
  92. static inline void *__va(unsigned long x)
  93. {
  94. if(x == 0)
  95. return (void *)0;
  96. if(x < 0x2000000)
  97. return (void *)(x+PAGE_OFFSET);
  98. else
  99. return (void *)(x-0x2000000);
  100. }
  101. #endif /* CONFIG_SUN3 */
  102. /*
  103. * NOTE: virtual isn't really correct, actually it should be the offset into the
  104. * memory node, but we have no highmem, so that works for now.
  105. * TODO: implement (fast) pfn<->pgdat_idx conversion functions, this makes lots
  106. * of the shifts unnecessary.
  107. */
  108. #define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
  109. #define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
  110. extern int m68k_virt_to_node_shift;
  111. #ifdef CONFIG_SINGLE_MEMORY_CHUNK
  112. #define __virt_to_node(addr) (&pg_data_map[0])
  113. #else
  114. extern struct pglist_data *pg_data_table[];
  115. static inline __attribute_const__ int __virt_to_node_shift(void)
  116. {
  117. int shift;
  118. asm (
  119. "1: moveq #0,%0\n"
  120. m68k_fixup(%c1, 1b)
  121. : "=d" (shift)
  122. : "i" (m68k_fixup_vnode_shift));
  123. return shift;
  124. }
  125. #define __virt_to_node(addr) (pg_data_table[(unsigned long)(addr) >> __virt_to_node_shift()])
  126. #endif
  127. #define virt_to_page(addr) ({ \
  128. pfn_to_page(virt_to_pfn(addr)); \
  129. })
  130. #define page_to_virt(page) ({ \
  131. pfn_to_virt(page_to_pfn(page)); \
  132. })
  133. #define pfn_to_page(pfn) ({ \
  134. unsigned long __pfn = (pfn); \
  135. struct pglist_data *pgdat; \
  136. pgdat = __virt_to_node((unsigned long)pfn_to_virt(__pfn)); \
  137. pgdat->node_mem_map + (__pfn - pgdat->node_start_pfn); \
  138. })
  139. #define page_to_pfn(_page) ({ \
  140. const struct page *__p = (_page); \
  141. struct pglist_data *pgdat; \
  142. pgdat = &pg_data_map[page_to_nid(__p)]; \
  143. ((__p) - pgdat->node_mem_map) + pgdat->node_start_pfn; \
  144. })
  145. #define virt_addr_valid(kaddr) ((void *)(kaddr) >= (void *)PAGE_OFFSET && (void *)(kaddr) < high_memory)
  146. #define pfn_valid(pfn) virt_addr_valid(pfn_to_virt(pfn))
  147. #endif /* __ASSEMBLY__ */
  148. #endif /* _M68K_PAGE_MM_H */