/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_S390_MEM_DETECT_H
#define _ASM_S390_MEM_DETECT_H

#include <linux/types.h>
#include <asm/page.h>

enum physmem_info_source {
	MEM_DETECT_NONE = 0,
	MEM_DETECT_SCLP_STOR_INFO,
	MEM_DETECT_DIAG260,
	MEM_DETECT_SCLP_READ_INFO,
	MEM_DETECT_BIN_SEARCH
};

struct physmem_range {
	u64 start;
	u64 end;
};

enum reserved_range_type {
	RR_DECOMPRESSOR,
	RR_INITRD,
	RR_VMLINUX,
	RR_AMODE31,
	RR_IPLREPORT,
	RR_CERT_COMP_LIST,
	RR_MEM_DETECT_EXTENDED,
	RR_VMEM,
	RR_MAX
};

struct reserved_range {
	unsigned long start;
	unsigned long end;
	struct reserved_range *chain;
};

/*
 * Storage element id is defined as 1 byte (up to 256 storage elements).
 * In practise only storage element id 0 and 1 are used).
 * According to architecture one storage element could have as much as
 * 1020 subincrements. 255 physmem_ranges are embedded in physmem_info.
 * If more physmem_ranges are required, a block of memory from already
 * known physmem_range is taken (online_extended points to it).
 */
#define MEM_INLINED_ENTRIES 255 /* (PAGE_SIZE - 16) / 16 */

struct physmem_info {
	u32 range_count;
	u8 info_source;
	unsigned long usable;
	struct reserved_range reserved[RR_MAX];
	struct physmem_range online[MEM_INLINED_ENTRIES];
	struct physmem_range *online_extended;
};

extern struct physmem_info physmem_info;

void add_physmem_online_range(u64 start, u64 end);

static inline int __get_physmem_range(u32 n, unsigned long *start,
				      unsigned long *end, bool respect_usable_limit)
{
	if (n >= physmem_info.range_count) {
		*start = 0;
		*end = 0;
		return -1;
	}

	if (n < MEM_INLINED_ENTRIES) {
		*start = (unsigned long)physmem_info.online[n].start;
		*end = (unsigned long)physmem_info.online[n].end;
	} else {
		*start = (unsigned long)physmem_info.online_extended[n - MEM_INLINED_ENTRIES].start;
		*end = (unsigned long)physmem_info.online_extended[n - MEM_INLINED_ENTRIES].end;
	}

	if (respect_usable_limit && physmem_info.usable) {
		if (*start >= physmem_info.usable)
			return -1;
		if (*end > physmem_info.usable)
			*end = physmem_info.usable;
	}
	return 0;
}

/**
 * for_each_physmem_usable_range - early online memory range iterator
 * @i: an integer used as loop variable
 * @p_start: ptr to unsigned long for start address of the range
 * @p_end: ptr to unsigned long for end address of the range
 *
 * Walks over detected online memory ranges below usable limit.
 */
#define for_each_physmem_usable_range(i, p_start, p_end)		\
	for (i = 0; !__get_physmem_range(i, p_start, p_end, true); i++)

/* Walks over all detected online memory ranges disregarding usable limit. */
#define for_each_physmem_online_range(i, p_start, p_end)		\
	for (i = 0; !__get_physmem_range(i, p_start, p_end, false); i++)

static inline const char *get_physmem_info_source(void)
{
	switch (physmem_info.info_source) {
	case MEM_DETECT_SCLP_STOR_INFO:
		return "sclp storage info";
	case MEM_DETECT_DIAG260:
		return "diag260";
	case MEM_DETECT_SCLP_READ_INFO:
		return "sclp read info";
	case MEM_DETECT_BIN_SEARCH:
		return "binary search";
	}
	return "none";
}

#define RR_TYPE_NAME(t) case RR_ ## t: return #t
static inline const char *get_rr_type_name(enum reserved_range_type t)
{
	switch (t) {
	RR_TYPE_NAME(DECOMPRESSOR);
	RR_TYPE_NAME(INITRD);
	RR_TYPE_NAME(VMLINUX);
	RR_TYPE_NAME(AMODE31);
	RR_TYPE_NAME(IPLREPORT);
	RR_TYPE_NAME(CERT_COMP_LIST);
	RR_TYPE_NAME(MEM_DETECT_EXTENDED);
	RR_TYPE_NAME(VMEM);
	default:
		return "UNKNOWN";
	}
}

#define for_each_physmem_reserved_type_range(t, range, p_start, p_end)				\
	for (range = &physmem_info.reserved[t], *p_start = range->start, *p_end = range->end;	\
	     range && range->end; range = range->chain ? __va(range->chain) : NULL,		\
	     *p_start = range ? range->start : 0, *p_end = range ? range->end : 0)

static inline struct reserved_range *__physmem_reserved_next(enum reserved_range_type *t,
							     struct reserved_range *range)
{
	if (!range) {
		range = &physmem_info.reserved[*t];
		if (range->end)
			return range;
	}
	if (range->chain)
		return __va(range->chain);
	while (++*t < RR_MAX) {
		range = &physmem_info.reserved[*t];
		if (range->end)
			return range;
	}
	return NULL;
}

#define for_each_physmem_reserved_range(t, range, p_start, p_end)			\
	for (t = 0, range = __physmem_reserved_next(&t, NULL),			\
	    *p_start = range ? range->start : 0, *p_end = range ? range->end : 0;	\
	     range; range = __physmem_reserved_next(&t, range),			\
	    *p_start = range ? range->start : 0, *p_end = range ? range->end : 0)

static inline unsigned long get_physmem_reserved(enum reserved_range_type type,
						 unsigned long *addr, unsigned long *size)
{
	*addr = physmem_info.reserved[type].start;
	*size = physmem_info.reserved[type].end - physmem_info.reserved[type].start;
	return *size;
}

#endif
