/* 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_RELOC,
	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
