highmem.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. // SPDX-License-Identifier: GPL-2.0
  2. // Copyright (C) 2005-2017 Andes Technology Corporation
  3. #include <linux/export.h>
  4. #include <linux/highmem.h>
  5. #include <linux/sched.h>
  6. #include <linux/smp.h>
  7. #include <linux/interrupt.h>
  8. #include <linux/bootmem.h>
  9. #include <asm/fixmap.h>
  10. #include <asm/tlbflush.h>
  11. void *kmap(struct page *page)
  12. {
  13. unsigned long vaddr;
  14. might_sleep();
  15. if (!PageHighMem(page))
  16. return page_address(page);
  17. vaddr = (unsigned long)kmap_high(page);
  18. return (void *)vaddr;
  19. }
  20. EXPORT_SYMBOL(kmap);
  21. void kunmap(struct page *page)
  22. {
  23. BUG_ON(in_interrupt());
  24. if (!PageHighMem(page))
  25. return;
  26. kunmap_high(page);
  27. }
  28. EXPORT_SYMBOL(kunmap);
  29. void *kmap_atomic(struct page *page)
  30. {
  31. unsigned int idx;
  32. unsigned long vaddr, pte;
  33. int type;
  34. pte_t *ptep;
  35. preempt_disable();
  36. pagefault_disable();
  37. if (!PageHighMem(page))
  38. return page_address(page);
  39. type = kmap_atomic_idx_push();
  40. idx = type + KM_TYPE_NR * smp_processor_id();
  41. vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
  42. pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL);
  43. ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
  44. set_pte(ptep, pte);
  45. __nds32__tlbop_inv(vaddr);
  46. __nds32__mtsr_dsb(vaddr, NDS32_SR_TLB_VPN);
  47. __nds32__tlbop_rwr(pte);
  48. __nds32__isb();
  49. return (void *)vaddr;
  50. }
  51. EXPORT_SYMBOL(kmap_atomic);
  52. void __kunmap_atomic(void *kvaddr)
  53. {
  54. if (kvaddr >= (void *)FIXADDR_START) {
  55. unsigned long vaddr = (unsigned long)kvaddr;
  56. pte_t *ptep;
  57. kmap_atomic_idx_pop();
  58. __nds32__tlbop_inv(vaddr);
  59. __nds32__isb();
  60. ptep = pte_offset_kernel(pmd_off_k(vaddr), vaddr);
  61. set_pte(ptep, 0);
  62. }
  63. pagefault_enable();
  64. preempt_enable();
  65. }
  66. EXPORT_SYMBOL(__kunmap_atomic);