1 /*
2  * Copyright (c) 2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 /**
8  * @file
9  * @brief Backing store on qemu_x86_tiny for testing
10  *
11  * This uses the "flash" memory area (in DTS) as the backing store
12  * for demand paging. The qemu_x86_tiny.ld linker script puts
13  * the symbols outside of boot and pinned sections into the flash
14  * area, allowing testing of the demand paging mechanism on
15  * code and data.
16  */
17 
18 #include <mmu.h>
19 #include <string.h>
20 #include <kernel_arch_interface.h>
21 #include <zephyr/linker/linker-defs.h>
22 #include <zephyr/sys/util.h>
23 #include <zephyr/kernel/mm/demand_paging.h>
24 
location_to_flash(uintptr_t location)25 void *location_to_flash(uintptr_t location)
26 {
27 	uintptr_t ptr = location;
28 
29 	/* Offset from start of virtual address space */
30 	ptr -= CONFIG_KERNEL_VM_BASE + CONFIG_KERNEL_VM_OFFSET;
31 
32 	/* Translate the offset into address to flash */
33 	ptr += CONFIG_FLASH_BASE_ADDRESS;
34 
35 	__ASSERT_NO_MSG(ptr >= CONFIG_FLASH_BASE_ADDRESS);
36 	__ASSERT_NO_MSG(ptr < (CONFIG_FLASH_BASE_ADDRESS
37 			       + KB(CONFIG_FLASH_SIZE)
38 			       - CONFIG_MMU_PAGE_SIZE));
39 
40 	return UINT_TO_POINTER(ptr);
41 }
42 
k_mem_paging_backing_store_location_get(struct k_mem_page_frame * pf,uintptr_t * location,bool page_fault)43 int k_mem_paging_backing_store_location_get(struct k_mem_page_frame *pf,
44 					    uintptr_t *location,
45 					    bool page_fault)
46 {
47 	/* Simply returns the virtual address */
48 	*location = POINTER_TO_UINT(k_mem_page_frame_to_virt(pf));
49 
50 	return 0;
51 }
52 
k_mem_paging_backing_store_location_free(uintptr_t location)53 void k_mem_paging_backing_store_location_free(uintptr_t location)
54 {
55 	/* Nothing to do */
56 }
57 
k_mem_paging_backing_store_page_out(uintptr_t location)58 void k_mem_paging_backing_store_page_out(uintptr_t location)
59 {
60 	(void)memcpy(location_to_flash(location), K_MEM_SCRATCH_PAGE,
61 		     CONFIG_MMU_PAGE_SIZE);
62 }
63 
k_mem_paging_backing_store_page_in(uintptr_t location)64 void k_mem_paging_backing_store_page_in(uintptr_t location)
65 {
66 	(void)memcpy(K_MEM_SCRATCH_PAGE, location_to_flash(location),
67 		     CONFIG_MMU_PAGE_SIZE);
68 }
69 
k_mem_paging_backing_store_page_finalize(struct k_mem_page_frame * pf,uintptr_t location)70 void k_mem_paging_backing_store_page_finalize(struct k_mem_page_frame *pf,
71 					      uintptr_t location)
72 {
73 	/* Nothing to do */
74 }
75 
k_mem_paging_backing_store_init(void)76 void k_mem_paging_backing_store_init(void)
77 {
78 	/* Nothing to do */
79 }
80