123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- #ifndef KERNEL_INCLUDE_MMU_H
- #define KERNEL_INCLUDE_MMU_H
- #ifdef CONFIG_MMU
- #include <stdint.h>
- #include <sys/slist.h>
- #include <sys/__assert.h>
- #include <sys/util.h>
- #include <sys/mem_manage.h>
- #include <linker/linker-defs.h>
- #define Z_PHYS_RAM_START ((uintptr_t)CONFIG_SRAM_BASE_ADDRESS)
- #define Z_PHYS_RAM_SIZE ((size_t)KB(CONFIG_SRAM_SIZE))
- #define Z_PHYS_RAM_END (Z_PHYS_RAM_START + Z_PHYS_RAM_SIZE)
- #define Z_NUM_PAGE_FRAMES (Z_PHYS_RAM_SIZE / (size_t)CONFIG_MMU_PAGE_SIZE)
- #define Z_VIRT_RAM_START ((uint8_t *)CONFIG_KERNEL_VM_BASE)
- #define Z_VIRT_RAM_SIZE ((size_t)CONFIG_KERNEL_VM_SIZE)
- #define Z_VIRT_RAM_END (Z_VIRT_RAM_START + Z_VIRT_RAM_SIZE)
- #define Z_KERNEL_VIRT_START ((uint8_t *)(&z_mapped_start))
- #define Z_KERNEL_VIRT_END ((uint8_t *)(&z_mapped_end))
- #define Z_KERNEL_VIRT_SIZE (Z_KERNEL_VIRT_END - Z_KERNEL_VIRT_START)
- #define Z_VM_OFFSET ((CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET) - \
- (CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_OFFSET))
- #define Z_BOOT_VIRT_TO_PHYS(virt) ((uintptr_t)(((uint8_t *)virt) - Z_VM_OFFSET))
- #define Z_BOOT_PHYS_TO_VIRT(phys) ((uint8_t *)(((uintptr_t)phys) + Z_VM_OFFSET))
- #ifdef CONFIG_ARCH_MAPS_ALL_RAM
- #define Z_FREE_VM_START Z_BOOT_PHYS_TO_VIRT(Z_PHYS_RAM_END)
- #else
- #define Z_FREE_VM_START Z_KERNEL_VIRT_END
- #endif
- #define Z_PAGE_FRAME_PINNED BIT(0)
- #define Z_PAGE_FRAME_RESERVED BIT(1)
- #define Z_PAGE_FRAME_MAPPED BIT(2)
- #define Z_PAGE_FRAME_BUSY BIT(3)
- #define Z_PAGE_FRAME_BACKED BIT(4)
- struct z_page_frame {
- union {
-
- void *addr;
-
- sys_snode_t node;
- };
-
- uint8_t flags;
-
- } __packed;
- static inline bool z_page_frame_is_pinned(struct z_page_frame *pf)
- {
- return (pf->flags & Z_PAGE_FRAME_PINNED) != 0U;
- }
- static inline bool z_page_frame_is_reserved(struct z_page_frame *pf)
- {
- return (pf->flags & Z_PAGE_FRAME_RESERVED) != 0U;
- }
- static inline bool z_page_frame_is_mapped(struct z_page_frame *pf)
- {
- return (pf->flags & Z_PAGE_FRAME_MAPPED) != 0U;
- }
- static inline bool z_page_frame_is_busy(struct z_page_frame *pf)
- {
- return (pf->flags & Z_PAGE_FRAME_BUSY) != 0U;
- }
- static inline bool z_page_frame_is_backed(struct z_page_frame *pf)
- {
- return (pf->flags & Z_PAGE_FRAME_BACKED) != 0U;
- }
- static inline bool z_page_frame_is_evictable(struct z_page_frame *pf)
- {
- return (!z_page_frame_is_reserved(pf) && z_page_frame_is_mapped(pf) &&
- !z_page_frame_is_pinned(pf) && !z_page_frame_is_busy(pf));
- }
- static inline bool z_page_frame_is_available(struct z_page_frame *page)
- {
- return page->flags == 0U;
- }
- static inline void z_assert_phys_aligned(uintptr_t phys)
- {
- __ASSERT(phys % CONFIG_MMU_PAGE_SIZE == 0U,
- "physical address 0x%lx is not page-aligned", phys);
- (void)phys;
- }
- extern struct z_page_frame z_page_frames[Z_NUM_PAGE_FRAMES];
- static inline uintptr_t z_page_frame_to_phys(struct z_page_frame *pf)
- {
- return (uintptr_t)((pf - z_page_frames) * CONFIG_MMU_PAGE_SIZE) +
- Z_PHYS_RAM_START;
- }
- static inline void *z_page_frame_to_virt(struct z_page_frame *pf)
- {
- return pf->addr;
- }
- static inline bool z_is_page_frame(uintptr_t phys)
- {
- z_assert_phys_aligned(phys);
- return (phys >= Z_PHYS_RAM_START) && (phys < Z_PHYS_RAM_END);
- }
- static inline struct z_page_frame *z_phys_to_page_frame(uintptr_t phys)
- {
- __ASSERT(z_is_page_frame(phys),
- "0x%lx not an SRAM physical address", phys);
- return &z_page_frames[(phys - Z_PHYS_RAM_START) /
- CONFIG_MMU_PAGE_SIZE];
- }
- static inline void z_mem_assert_virtual_region(uint8_t *addr, size_t size)
- {
- __ASSERT((uintptr_t)addr % CONFIG_MMU_PAGE_SIZE == 0U,
- "unaligned addr %p", addr);
- __ASSERT(size % CONFIG_MMU_PAGE_SIZE == 0U,
- "unaligned size %zu", size);
- __ASSERT(addr + size > addr,
- "region %p size %zu zero or wraps around", addr, size);
- __ASSERT(addr >= Z_VIRT_RAM_START && addr + size < Z_VIRT_RAM_END,
- "invalid virtual address region %p (%zu)", addr, size);
- }
- void z_page_frames_dump(void);
- extern size_t z_free_page_count;
- #define Z_PAGE_FRAME_FOREACH(_phys, _pageframe) \
- for (_phys = Z_PHYS_RAM_START, _pageframe = z_page_frames; \
- _phys < Z_PHYS_RAM_END; \
- _phys += CONFIG_MMU_PAGE_SIZE, _pageframe++)
- #ifdef CONFIG_DEMAND_PAGING
- #define Z_VM_RESERVED CONFIG_MMU_PAGE_SIZE
- #define Z_SCRATCH_PAGE ((void *)((uintptr_t)CONFIG_KERNEL_VM_BASE + \
- (uintptr_t)CONFIG_KERNEL_VM_SIZE - \
- CONFIG_MMU_PAGE_SIZE))
- #else
- #define Z_VM_RESERVED 0
- #endif
- #ifdef CONFIG_DEMAND_PAGING
- unsigned long z_num_pagefaults_get(void);
- int z_page_frame_evict(uintptr_t phys);
- bool z_page_fault(void *addr);
- #endif
- #endif
- #endif
|