/*
 * Copyright (c) 2020 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * RAM-based memory buffer backing store implementation for demo purposes
 */
#include <mmu.h>
#include <string.h>
#include <kernel_arch_interface.h>

/*
 * TODO:
 *
 * This is a demonstration backing store for testing the kernel side of the
 * demand paging feature. In production there are basically two types of
 * backing stores:
 *
 * 1) A large, sparse backing store that is big enough to capture the entire
 *    address space. Implementation of these is very simple; the location
 *    token is just a function of the evicted virtual address and no space
 *    management is necessary. Clean copies of paged-in data pages may be kept
 *    indefinitely.
 *
 * 2) A backing store that has limited storage space, and is not sufficiently
 *    large to hold clean copies of all mapped memory.
 *
 * This backing store is an example of the latter case. However, locations
 * are freed as soon as pages are paged in, in
 * k_mem_paging_backing_store_page_finalize().
 * This implies that all data pages are treated as dirty as
 * Z_PAGE_FRAME_BACKED is never set, even if the data page was paged out before
 * and not modified since then.
 *
 * An optimization a real backing store will want is have
 * k_mem_paging_backing_store_page_finalize() note the storage location of
 * a paged-in data page in a custom field of its associated z_page_frame, and
 * set the Z_PAGE_FRAME_BACKED bit. Invocations of
 * k_mem_paging_backing_store_location_get() will have logic to return
 * the previous clean page location instead of allocating
 * a new one if Z_PAGE_FRAME_BACKED is set.
 *
 * This will, however, require the implementation of a clean page
 * eviction algorithm, to free backing store locations for loaded data pages
 * as the backing store fills up, and clear the Z_PAGE_FRAME_BACKED bit
 * appropriately.
 *
 * All of this logic is local to the backing store implementation; from the
 * core kernel's perspective the only change is that Z_PAGE_FRAME_BACKED
 * starts getting set for certain page frames after a page-in (and possibly
 * cleared at a later time).
 */
static char backing_store[CONFIG_MMU_PAGE_SIZE *
			  CONFIG_BACKING_STORE_RAM_PAGES];
static struct k_mem_slab backing_slabs;
static unsigned int free_slabs;

static void *location_to_slab(uintptr_t location)
{
	__ASSERT(location % CONFIG_MMU_PAGE_SIZE == 0,
		 "unaligned location 0x%lx", location);
	__ASSERT(location <
		 (CONFIG_BACKING_STORE_RAM_PAGES * CONFIG_MMU_PAGE_SIZE),
		 "bad location 0x%lx, past bounds of backing store", location);

	return backing_store + location;
}

static uintptr_t slab_to_location(void *slab)
{
	char *pos = slab;
	uintptr_t offset;

	__ASSERT(pos >= backing_store &&
		 pos < backing_store + ARRAY_SIZE(backing_store),
		 "bad slab pointer %p", slab);
	offset = pos - backing_store;
	__ASSERT(offset % CONFIG_MMU_PAGE_SIZE == 0,
		 "unaligned slab pointer %p", slab);

	return offset;
}

int k_mem_paging_backing_store_location_get(struct z_page_frame *pf,
					    uintptr_t *location,
					    bool page_fault)
{
	int ret;
	void *slab;

	if ((!page_fault && free_slabs == 1) || free_slabs == 0) {
		return -ENOMEM;
	}

	ret = k_mem_slab_alloc(&backing_slabs, &slab, K_NO_WAIT);
	__ASSERT(ret == 0, "slab count mismatch");
	(void)ret;
	*location = slab_to_location(slab);
	free_slabs--;

	return 0;
}

void k_mem_paging_backing_store_location_free(uintptr_t location)
{
	void *slab = location_to_slab(location);

	k_mem_slab_free(&backing_slabs, &slab);
	free_slabs++;
}

void k_mem_paging_backing_store_page_out(uintptr_t location)
{
	(void)memcpy(location_to_slab(location), Z_SCRATCH_PAGE,
		     CONFIG_MMU_PAGE_SIZE);
}

void k_mem_paging_backing_store_page_in(uintptr_t location)
{
	(void)memcpy(Z_SCRATCH_PAGE, location_to_slab(location),
		     CONFIG_MMU_PAGE_SIZE);
}

void k_mem_paging_backing_store_page_finalize(struct z_page_frame *pf,
					      uintptr_t location)
{
	k_mem_paging_backing_store_location_free(location);
}

void k_mem_paging_backing_store_init(void)
{
	k_mem_slab_init(&backing_slabs, backing_store, CONFIG_MMU_PAGE_SIZE,
			CONFIG_BACKING_STORE_RAM_PAGES);
	free_slabs = CONFIG_BACKING_STORE_RAM_PAGES;
}
