/*
 * 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 z_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
 * z_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 z_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 z_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 z_backing_store_location_free(uintptr_t location)
{
	void *slab = location_to_slab(location);

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

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

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

void z_backing_store_page_finalize(struct z_page_frame *pf, uintptr_t location)
{
	z_backing_store_location_free(location);
}

void z_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;
}
