mm_object.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-11-30 WangXiaoyao the first version
  9. */
  10. #include <rtthread.h>
  11. #include "mm_aspace.h"
  12. #include "mm_fault.h"
  13. #include "mm_page.h"
  14. #include <mmu.h>
  15. #define DBG_TAG "mm.object"
  16. #define DBG_LVL DBG_INFO
  17. #include "rtdbg.h"
  18. static const char *get_name(rt_varea_t varea)
  19. {
  20. return "dummy-mapper";
  21. }
  22. void rt_varea_pgmgr_insert(rt_varea_t varea, void *page_addr)
  23. {
  24. rt_page_t page = rt_page_addr2page(page_addr);
  25. if (varea->frames == NULL)
  26. {
  27. varea->frames = page;
  28. page->next = NULL;
  29. }
  30. else
  31. {
  32. varea->frames->pre = page;
  33. page->next = varea->frames;
  34. varea->frames = page;
  35. }
  36. }
  37. void rt_varea_pgmgr_pop_all(rt_varea_t varea)
  38. {
  39. rt_page_t page = varea->frames;
  40. while (page)
  41. {
  42. rt_page_t next = page->next;
  43. void *pg_va = rt_page_page2addr(page);
  44. rt_pages_free(pg_va, 0);
  45. page = next;
  46. }
  47. }
  48. void rt_varea_pgmgr_pop(rt_varea_t varea, void *vaddr, rt_size_t size)
  49. {
  50. void *vend = (char *)vaddr + size;
  51. while (vaddr != vend)
  52. {
  53. rt_page_t page = rt_page_addr2page(vaddr);
  54. page->pre->next = page->next;
  55. page->next->pre = page->pre;
  56. rt_pages_free(vaddr, 0);
  57. vaddr = (char *)vaddr + ARCH_PAGE_SIZE;
  58. }
  59. }
  60. static void on_page_fault(struct rt_varea *varea, struct rt_aspace_fault_msg *msg)
  61. {
  62. void *page;
  63. page = rt_pages_alloc_ext(0, PAGE_ANY_AVAILABLE);
  64. if (!page)
  65. {
  66. LOG_W("%s: page alloc failed", __func__);
  67. return;
  68. }
  69. msg->response.status = MM_FAULT_STATUS_OK;
  70. msg->response.size = ARCH_PAGE_SIZE;
  71. msg->response.vaddr = page;
  72. rt_varea_pgmgr_insert(varea, page);
  73. }
  74. static void on_varea_open(struct rt_varea *varea)
  75. {
  76. varea->data = NULL;
  77. }
  78. static void on_varea_close(struct rt_varea *varea)
  79. {
  80. }
  81. static void on_page_offload(rt_varea_t varea, void *vaddr, rt_size_t size)
  82. {
  83. rt_varea_pgmgr_pop(varea, vaddr, size);
  84. }
  85. struct rt_mem_obj rt_mm_dummy_mapper = {
  86. .get_name = get_name,
  87. .on_page_fault = on_page_fault,
  88. .hint_free = NULL,
  89. .on_varea_open = on_varea_open,
  90. .on_varea_close = on_varea_close,
  91. .on_page_offload = on_page_offload,
  92. };