// SPDX-License-Identifier: BSD-2-Clause
/*
 * fdt_domain.c - Flat Device Tree Domain helper routines
 *
 * Copyright (c) 2020 Western Digital Corporation or its affiliates.
 *
 * Authors:
 *   Anup Patel <anup.patel@wdc.com>
 */

#include <libfdt.h>
#include <libfdt_env.h>
#include <sbi/sbi_domain.h>
#include <sbi/sbi_error.h>
#include <sbi/sbi_hartmask.h>
#include <sbi/sbi_heap.h>
#include <sbi/sbi_scratch.h>
#include <sbi_utils/fdt/fdt_domain.h>
#include <sbi_utils/fdt/fdt_helper.h>

int fdt_iterate_each_domain(void *fdt, void *opaque,
			    int (*fn)(void *fdt, int domain_offset,
				       void *opaque))
{
	int rc, doffset, poffset;

	if (!fdt || !fn)
		return SBI_EINVAL;

	poffset = fdt_path_offset(fdt, "/chosen");
	if (poffset < 0)
		return 0;
	poffset = fdt_node_offset_by_compatible(fdt, poffset,
						"opensbi,domain,config");
	if (poffset < 0)
		return 0;

	fdt_for_each_subnode(doffset, fdt, poffset) {
		if (fdt_node_check_compatible(fdt, doffset,
					      "opensbi,domain,instance"))
			continue;

		rc = fn(fdt, doffset, opaque);
		if (rc)
			return rc;
	}

	return 0;
}

int fdt_iterate_each_memregion(void *fdt, int domain_offset, void *opaque,
			       int (*fn)(void *fdt, int domain_offset,
					 int region_offset, u32 region_access,
					 void *opaque))
{
	u32 i, rcount;
	int rc, len, region_offset;
	const u32 *regions;

	if (!fdt || (domain_offset < 0) || !fn)
		return SBI_EINVAL;

	if (fdt_node_check_compatible(fdt, domain_offset,
				      "opensbi,domain,instance"))
		return SBI_EINVAL;

	regions = fdt_getprop(fdt, domain_offset, "regions", &len);
	if (!regions)
		return 0;

	rcount = (u32)len / (sizeof(u32) * 2);
	for (i = 0; i < rcount; i++) {
		region_offset = fdt_node_offset_by_phandle(fdt,
						fdt32_to_cpu(regions[2 * i]));
		if (region_offset < 0)
			return region_offset;

		if (fdt_node_check_compatible(fdt, region_offset,
					      "opensbi,domain,memregion"))
			return SBI_EINVAL;

		rc = fn(fdt, domain_offset, region_offset,
			fdt32_to_cpu(regions[(2 * i) + 1]), opaque);
		if (rc)
			return rc;
	}

	return 0;
}

struct __fixup_find_domain_offset_info {
	const char *name;
	int *doffset;
};

static int __fixup_find_domain_offset(void *fdt, int doff, void *p)
{
	struct __fixup_find_domain_offset_info *fdo = p;

	if (!strncmp(fdo->name, fdt_get_name(fdt, doff, NULL), strlen(fdo->name)))
		*fdo->doffset = doff;

	return 0;
}

#define DISABLE_DEVICES_MASK	(SBI_DOMAIN_MEMREGION_READABLE | \
				 SBI_DOMAIN_MEMREGION_WRITEABLE | \
				 SBI_DOMAIN_MEMREGION_EXECUTABLE)

static int __fixup_count_disable_devices(void *fdt, int doff, int roff,
					 u32 perm, void *p)
{
	int len;
	u32 *dcount = p;

	if (perm & DISABLE_DEVICES_MASK)
		return 0;

	len = 0;
	if (fdt_getprop(fdt, roff, "devices", &len))
		*dcount += len / sizeof(u32);

	return 0;
}

static int __fixup_disable_devices(void *fdt, int doff, int roff,
				   u32 raccess, void *p)
{
	int i, len, coff;
	const u32 *devices;

	if (raccess & DISABLE_DEVICES_MASK)
		return 0;

	len = 0;
	devices = fdt_getprop(fdt, roff, "devices", &len);
	if (!devices)
		return 0;
	len = len / sizeof(u32);

	for (i = 0; i < len; i++) {
		coff = fdt_node_offset_by_phandle(fdt,
					fdt32_to_cpu(devices[i]));
		if (coff < 0)
			return coff;

		fdt_setprop_string(fdt, coff, "status", "disabled");
	}

	return 0;
}

void fdt_domain_fixup(void *fdt)
{
	u32 i, dcount;
	int err, poffset, doffset;
	struct sbi_domain *dom = sbi_domain_thishart_ptr();
	struct __fixup_find_domain_offset_info fdo;

	/* Remove the domain assignment DT property from CPU DT nodes */
	poffset = fdt_path_offset(fdt, "/cpus");
	if (poffset < 0)
		return;
	fdt_for_each_subnode(doffset, fdt, poffset) {
		err = fdt_parse_hart_id(fdt, doffset, &i);
		if (err)
			continue;

		if (!fdt_node_is_enabled(fdt, doffset))
			continue;

		fdt_nop_property(fdt, doffset, "opensbi-domain");
	}

	/* Skip device disable for root domain */
	if (!dom->index)
		goto skip_device_disable;

	/* Find current domain DT node */
	doffset = -1;
	fdo.name = dom->name;
	fdo.doffset = &doffset;
	fdt_iterate_each_domain(fdt, &fdo, __fixup_find_domain_offset);
	if (doffset < 0)
		goto skip_device_disable;

	/* Count current domain device DT nodes to be disabled */
	dcount = 0;
	fdt_iterate_each_memregion(fdt, doffset, &dcount,
				   __fixup_count_disable_devices);
	if (!dcount)
		goto skip_device_disable;

	/* Expand FDT based on device DT nodes to be disabled */
	err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + dcount * 32);
	if (err < 0)
		return;

	/* Again find current domain DT node */
	doffset = -1;
	fdo.name = dom->name;
	fdo.doffset = &doffset;
	fdt_iterate_each_domain(fdt, &fdo, __fixup_find_domain_offset);
	if (doffset < 0)
		goto skip_device_disable;

	/* Disable device DT nodes for current domain */
	fdt_iterate_each_memregion(fdt, doffset, NULL,
				   __fixup_disable_devices);
skip_device_disable:

	/* Remove the OpenSBI domain config DT node */
	poffset = fdt_path_offset(fdt, "/chosen");
	if (poffset < 0)
		return;
	poffset = fdt_node_offset_by_compatible(fdt, poffset,
						"opensbi,domain,config");
	if (poffset < 0)
		return;
	fdt_nop_node(fdt, poffset);
}

#define FDT_DOMAIN_REGION_MAX_COUNT	16

struct parse_region_data {
	struct sbi_domain *dom;
	u32 region_count;
	u32 max_regions;
};

static int __fdt_parse_region(void *fdt, int domain_offset,
			      int region_offset, u32 region_access,
			      void *opaque)
{
	int len;
	u32 val32;
	u64 val64;
	const u32 *val;
	struct parse_region_data *preg = opaque;
	struct sbi_domain_memregion *region;

	/*
	 * Non-root domains cannot add a region with only M-mode
	 * access permissions. M-mode regions can only be part of
	 * root domain.
	 *
	 * SU permission bits can't be all zeroes when M-mode permission
	 * bits have at least one bit set.
	 */
	if (!(region_access & SBI_DOMAIN_MEMREGION_SU_ACCESS_MASK)
	    && (region_access & SBI_DOMAIN_MEMREGION_M_ACCESS_MASK))
		return SBI_EINVAL;

	/* Find next region of the domain */
	if (preg->max_regions <= preg->region_count)
		return SBI_ENOSPC;
	region = &preg->dom->regions[preg->region_count];

	/* Read "base" DT property */
	val = fdt_getprop(fdt, region_offset, "base", &len);
	if (!val || len != 8)
		return SBI_EINVAL;
	val64 = fdt32_to_cpu(val[0]);
	val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
	region->base = val64;

	/* Read "order" DT property */
	val = fdt_getprop(fdt, region_offset, "order", &len);
	if (!val || len != 4)
		return SBI_EINVAL;
	val32 = fdt32_to_cpu(*val);
	if (val32 < 3 || __riscv_xlen < val32)
		return SBI_EINVAL;
	region->order = val32;

	/* Read "mmio" DT property */
	region->flags = region_access & SBI_DOMAIN_MEMREGION_ACCESS_MASK;
	if (fdt_get_property(fdt, region_offset, "mmio", NULL))
		region->flags |= SBI_DOMAIN_MEMREGION_MMIO;

	preg->region_count++;

	return 0;
}

static int __fdt_parse_domain(void *fdt, int domain_offset, void *opaque)
{
	u32 val32;
	u64 val64;
	const u32 *val;
	struct sbi_domain *dom;
	struct sbi_hartmask *mask;
	struct sbi_hartmask assign_mask;
	struct parse_region_data preg;
	int *cold_domain_offset = opaque;
	struct sbi_domain_memregion *reg;
	int i, err = 0, len, cpus_offset, cpu_offset, doffset;

	dom = sbi_zalloc(sizeof(*dom));
	if (!dom)
		return SBI_ENOMEM;

	dom->regions = sbi_calloc(sizeof(*dom->regions),
				  FDT_DOMAIN_REGION_MAX_COUNT + 1);
	if (!dom->regions) {
		err = SBI_ENOMEM;
		goto fail_free_domain;
	}
	preg.dom = dom;
	preg.region_count = 0;
	preg.max_regions = FDT_DOMAIN_REGION_MAX_COUNT;

	mask = sbi_zalloc(sizeof(*mask));
	if (!mask) {
		err = SBI_ENOMEM;
		goto fail_free_regions;
	}

	/* Read DT node name */
	strncpy(dom->name, fdt_get_name(fdt, domain_offset, NULL),
		    sizeof(dom->name));
	dom->name[sizeof(dom->name) - 1] = '\0';

	/* Setup possible HARTs mask */
	SBI_HARTMASK_INIT(mask);
	dom->possible_harts = mask;
	val = fdt_getprop(fdt, domain_offset, "possible-harts", &len);
	len = len / sizeof(u32);
	if (val && len) {
		for (i = 0; i < len; i++) {
			cpu_offset = fdt_node_offset_by_phandle(fdt,
							fdt32_to_cpu(val[i]));
			if (cpu_offset < 0) {
				err = cpu_offset;
				goto fail_free_all;
			}

			err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
			if (err)
				goto fail_free_all;

			if (!fdt_node_is_enabled(fdt, cpu_offset))
				continue;

			sbi_hartmask_set_hartid(val32, mask);
		}
	}

	/* Setup memregions from DT */
	err = fdt_iterate_each_memregion(fdt, domain_offset, &preg,
					 __fdt_parse_region);
	if (err)
		goto fail_free_all;

	/*
	 * Copy over root domain memregions which don't allow
	 * read, write and execute from lower privilege modes.
	 *
	 * These root domain memregions without read, write,
	 * and execute permissions include:
	 * 1) firmware region protecting the firmware memory
	 * 2) mmio regions protecting M-mode only mmio devices
	 */
	sbi_domain_for_each_memregion(&root, reg) {
		if ((reg->flags & SBI_DOMAIN_MEMREGION_SU_READABLE) ||
		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_WRITABLE) ||
		    (reg->flags & SBI_DOMAIN_MEMREGION_SU_EXECUTABLE))
			continue;
		if (preg.max_regions <= preg.region_count) {
			err = SBI_EINVAL;
			goto fail_free_all;
		}
		memcpy(&dom->regions[preg.region_count++], reg, sizeof(*reg));
	}
	dom->fw_region_inited = root.fw_region_inited;

	/* Read "boot-hart" DT property */
	val32 = -1U;
	val = fdt_getprop(fdt, domain_offset, "boot-hart", &len);
	if (val && len >= 4) {
		cpu_offset = fdt_node_offset_by_phandle(fdt,
							 fdt32_to_cpu(*val));
		if (cpu_offset >= 0 && fdt_node_is_enabled(fdt, cpu_offset))
			fdt_parse_hart_id(fdt, cpu_offset, &val32);
	} else {
		if (domain_offset == *cold_domain_offset)
			val32 = current_hartid();
	}
	dom->boot_hartid = val32;

	/* Read "next-arg1" DT property */
	val64 = 0;
	val = fdt_getprop(fdt, domain_offset, "next-arg1", &len);
	if (val && len >= 8) {
		val64 = fdt32_to_cpu(val[0]);
		val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
	} else {
		if (domain_offset == *cold_domain_offset)
			val64 = sbi_scratch_thishart_ptr()->next_arg1;
	}
	dom->next_arg1 = val64;

	/* Read "next-addr" DT property */
	val64 = 0;
	val = fdt_getprop(fdt, domain_offset, "next-addr", &len);
	if (val && len >= 8) {
		val64 = fdt32_to_cpu(val[0]);
		val64 = (val64 << 32) | fdt32_to_cpu(val[1]);
	} else {
		if (domain_offset == *cold_domain_offset)
			val64 = sbi_scratch_thishart_ptr()->next_addr;
	}
	dom->next_addr = val64;

	/* Read "next-mode" DT property */
	val32 = 0x1;
	val = fdt_getprop(fdt, domain_offset, "next-mode", &len);
	if (val && len >= 4) {
		val32 = fdt32_to_cpu(val[0]);
		if (val32 != 0x0 && val32 != 0x1)
			val32 = 0x1;
	} else {
		if (domain_offset == *cold_domain_offset)
			val32 = sbi_scratch_thishart_ptr()->next_mode;
	}
	dom->next_mode = val32;

	/* Read "system-reset-allowed" DT property */
	if (fdt_get_property(fdt, domain_offset,
			     "system-reset-allowed", NULL))
		dom->system_reset_allowed = true;
	else
		dom->system_reset_allowed = false;

	/* Read "system-suspend-allowed" DT property */
	if (fdt_get_property(fdt, domain_offset,
			     "system-suspend-allowed", NULL))
		dom->system_suspend_allowed = true;
	else
		dom->system_suspend_allowed = false;

	/* Find /cpus DT node */
	cpus_offset = fdt_path_offset(fdt, "/cpus");
	if (cpus_offset < 0) {
		err = cpus_offset;
		goto fail_free_all;
	}

	/* HART to domain assignment mask based on CPU DT nodes */
	sbi_hartmask_clear_all(&assign_mask);
	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
		err = fdt_parse_hart_id(fdt, cpu_offset, &val32);
		if (err)
			continue;

		if (SBI_HARTMASK_MAX_BITS <= val32)
			continue;

		if (!fdt_node_is_enabled(fdt, cpu_offset))
			continue;

		val = fdt_getprop(fdt, cpu_offset, "opensbi-domain", &len);
		if (!val || len < 4) {
			err = SBI_EINVAL;
			goto fail_free_all;
		}

		doffset = fdt_node_offset_by_phandle(fdt, fdt32_to_cpu(*val));
		if (doffset < 0) {
			err = doffset;
			goto fail_free_all;
		}

		if (doffset == domain_offset)
			sbi_hartmask_set_hartid(val32, &assign_mask);
	}

	/* Register the domain */
	err = sbi_domain_register(dom, &assign_mask);
	if (err)
		goto fail_free_all;

	return 0;

fail_free_all:
	sbi_free(mask);
fail_free_regions:
	sbi_free(dom->regions);
fail_free_domain:
	sbi_free(dom);
	return err;
}

int fdt_domains_populate(void *fdt)
{
	const u32 *val;
	int cold_domain_offset;
	u32 hartid, cold_hartid;
	int err, len, cpus_offset, cpu_offset;

	/* Sanity checks */
	if (!fdt)
		return SBI_EINVAL;

	/* Find /cpus DT node */
	cpus_offset = fdt_path_offset(fdt, "/cpus");
	if (cpus_offset < 0)
		return cpus_offset;

	/* Find coldboot HART domain DT node offset */
	cold_domain_offset = -1;
	cold_hartid = current_hartid();
	fdt_for_each_subnode(cpu_offset, fdt, cpus_offset) {
		err = fdt_parse_hart_id(fdt, cpu_offset, &hartid);
		if (err)
			continue;

		if (hartid != cold_hartid)
			continue;

		if (!fdt_node_is_enabled(fdt, cpu_offset))
			continue;

		val = fdt_getprop(fdt, cpu_offset, "opensbi-domain", &len);
		if (val && len >= 4)
			cold_domain_offset = fdt_node_offset_by_phandle(fdt,
							   fdt32_to_cpu(*val));

		break;
	}

	/* Iterate over each domain in FDT and populate details */
	return fdt_iterate_each_domain(fdt, &cold_domain_offset,
				       __fdt_parse_domain);
}
