xref: /openbmc/linux/arch/s390/boot/physmem_info.c (revision 6e259bc5)
18c37cb7dSVasily Gorbik // SPDX-License-Identifier: GPL-2.0
2f913a660SVasily Gorbik #include <linux/processor.h>
38c37cb7dSVasily Gorbik #include <linux/errno.h>
48c37cb7dSVasily Gorbik #include <linux/init.h>
58c37cb7dSVasily Gorbik #include <asm/physmem_info.h>
6f913a660SVasily Gorbik #include <asm/stacktrace.h>
7f913a660SVasily Gorbik #include <asm/boot_data.h>
88c37cb7dSVasily Gorbik #include <asm/sparsemem.h>
9f913a660SVasily Gorbik #include <asm/sections.h>
10f913a660SVasily Gorbik #include <asm/setup.h>
11f913a660SVasily Gorbik #include <asm/sclp.h>
12f913a660SVasily Gorbik #include <asm/uv.h>
138c37cb7dSVasily Gorbik #include "decompressor.h"
148c37cb7dSVasily Gorbik #include "boot.h"
158c37cb7dSVasily Gorbik 
168c37cb7dSVasily Gorbik struct physmem_info __bootdata(physmem_info);
17f913a660SVasily Gorbik static unsigned int physmem_alloc_ranges;
18f913a660SVasily Gorbik static unsigned long physmem_alloc_pos;
198c37cb7dSVasily Gorbik 
208c37cb7dSVasily Gorbik /* up to 256 storage elements, 1020 subincrements each */
218c37cb7dSVasily Gorbik #define ENTRIES_EXTENDED_MAX						       \
228c37cb7dSVasily Gorbik 	(256 * (1020 / 2) * sizeof(struct physmem_range))
238c37cb7dSVasily Gorbik 
__get_physmem_range_ptr(u32 n)248c37cb7dSVasily Gorbik static struct physmem_range *__get_physmem_range_ptr(u32 n)
258c37cb7dSVasily Gorbik {
268c37cb7dSVasily Gorbik 	if (n < MEM_INLINED_ENTRIES)
278c37cb7dSVasily Gorbik 		return &physmem_info.online[n];
28f913a660SVasily Gorbik 	if (unlikely(!physmem_info.online_extended)) {
29f913a660SVasily Gorbik 		physmem_info.online_extended = (struct physmem_range *)physmem_alloc_range(
30f913a660SVasily Gorbik 			RR_MEM_DETECT_EXTENDED, ENTRIES_EXTENDED_MAX, sizeof(long), 0,
31f913a660SVasily Gorbik 			physmem_alloc_pos, true);
32f913a660SVasily Gorbik 	}
338c37cb7dSVasily Gorbik 	return &physmem_info.online_extended[n - MEM_INLINED_ENTRIES];
348c37cb7dSVasily Gorbik }
358c37cb7dSVasily Gorbik 
368c37cb7dSVasily Gorbik /*
378c37cb7dSVasily Gorbik  * sequential calls to add_physmem_online_range with adjacent memory ranges
388c37cb7dSVasily Gorbik  * are merged together into single memory range.
398c37cb7dSVasily Gorbik  */
add_physmem_online_range(u64 start,u64 end)408c37cb7dSVasily Gorbik void add_physmem_online_range(u64 start, u64 end)
418c37cb7dSVasily Gorbik {
428c37cb7dSVasily Gorbik 	struct physmem_range *range;
438c37cb7dSVasily Gorbik 
448c37cb7dSVasily Gorbik 	if (physmem_info.range_count) {
458c37cb7dSVasily Gorbik 		range = __get_physmem_range_ptr(physmem_info.range_count - 1);
468c37cb7dSVasily Gorbik 		if (range->end == start) {
478c37cb7dSVasily Gorbik 			range->end = end;
488c37cb7dSVasily Gorbik 			return;
498c37cb7dSVasily Gorbik 		}
508c37cb7dSVasily Gorbik 	}
518c37cb7dSVasily Gorbik 
528c37cb7dSVasily Gorbik 	range = __get_physmem_range_ptr(physmem_info.range_count);
538c37cb7dSVasily Gorbik 	range->start = start;
548c37cb7dSVasily Gorbik 	range->end = end;
558c37cb7dSVasily Gorbik 	physmem_info.range_count++;
568c37cb7dSVasily Gorbik }
578c37cb7dSVasily Gorbik 
__diag260(unsigned long rx1,unsigned long rx2)588c37cb7dSVasily Gorbik static int __diag260(unsigned long rx1, unsigned long rx2)
598c37cb7dSVasily Gorbik {
608c37cb7dSVasily Gorbik 	unsigned long reg1, reg2, ry;
618c37cb7dSVasily Gorbik 	union register_pair rx;
628c37cb7dSVasily Gorbik 	psw_t old;
638c37cb7dSVasily Gorbik 	int rc;
648c37cb7dSVasily Gorbik 
658c37cb7dSVasily Gorbik 	rx.even = rx1;
668c37cb7dSVasily Gorbik 	rx.odd	= rx2;
678c37cb7dSVasily Gorbik 	ry = 0x10; /* storage configuration */
688c37cb7dSVasily Gorbik 	rc = -1;   /* fail */
698c37cb7dSVasily Gorbik 	asm volatile(
708c37cb7dSVasily Gorbik 		"	mvc	0(16,%[psw_old]),0(%[psw_pgm])\n"
718c37cb7dSVasily Gorbik 		"	epsw	%[reg1],%[reg2]\n"
728c37cb7dSVasily Gorbik 		"	st	%[reg1],0(%[psw_pgm])\n"
738c37cb7dSVasily Gorbik 		"	st	%[reg2],4(%[psw_pgm])\n"
748c37cb7dSVasily Gorbik 		"	larl	%[reg1],1f\n"
758c37cb7dSVasily Gorbik 		"	stg	%[reg1],8(%[psw_pgm])\n"
768c37cb7dSVasily Gorbik 		"	diag	%[rx],%[ry],0x260\n"
778c37cb7dSVasily Gorbik 		"	ipm	%[rc]\n"
788c37cb7dSVasily Gorbik 		"	srl	%[rc],28\n"
798c37cb7dSVasily Gorbik 		"1:	mvc	0(16,%[psw_pgm]),0(%[psw_old])\n"
808c37cb7dSVasily Gorbik 		: [reg1] "=&d" (reg1),
818c37cb7dSVasily Gorbik 		  [reg2] "=&a" (reg2),
828c37cb7dSVasily Gorbik 		  [rc] "+&d" (rc),
838c37cb7dSVasily Gorbik 		  [ry] "+&d" (ry),
848c37cb7dSVasily Gorbik 		  "+Q" (S390_lowcore.program_new_psw),
858c37cb7dSVasily Gorbik 		  "=Q" (old)
868c37cb7dSVasily Gorbik 		: [rx] "d" (rx.pair),
878c37cb7dSVasily Gorbik 		  [psw_old] "a" (&old),
888c37cb7dSVasily Gorbik 		  [psw_pgm] "a" (&S390_lowcore.program_new_psw)
898c37cb7dSVasily Gorbik 		: "cc", "memory");
908c37cb7dSVasily Gorbik 	return rc == 0 ? ry : -1;
918c37cb7dSVasily Gorbik }
928c37cb7dSVasily Gorbik 
diag260(void)938c37cb7dSVasily Gorbik static int diag260(void)
948c37cb7dSVasily Gorbik {
958c37cb7dSVasily Gorbik 	int rc, i;
968c37cb7dSVasily Gorbik 
978c37cb7dSVasily Gorbik 	struct {
988c37cb7dSVasily Gorbik 		unsigned long start;
998c37cb7dSVasily Gorbik 		unsigned long end;
1008c37cb7dSVasily Gorbik 	} storage_extents[8] __aligned(16); /* VM supports up to 8 extends */
1018c37cb7dSVasily Gorbik 
1028c37cb7dSVasily Gorbik 	memset(storage_extents, 0, sizeof(storage_extents));
1038c37cb7dSVasily Gorbik 	rc = __diag260((unsigned long)storage_extents, sizeof(storage_extents));
1048c37cb7dSVasily Gorbik 	if (rc == -1)
1058c37cb7dSVasily Gorbik 		return -1;
1068c37cb7dSVasily Gorbik 
1078c37cb7dSVasily Gorbik 	for (i = 0; i < min_t(int, rc, ARRAY_SIZE(storage_extents)); i++)
1088c37cb7dSVasily Gorbik 		add_physmem_online_range(storage_extents[i].start, storage_extents[i].end + 1);
1098c37cb7dSVasily Gorbik 	return 0;
1108c37cb7dSVasily Gorbik }
1118c37cb7dSVasily Gorbik 
tprot(unsigned long addr)1128c37cb7dSVasily Gorbik static int tprot(unsigned long addr)
1138c37cb7dSVasily Gorbik {
1148c37cb7dSVasily Gorbik 	unsigned long reg1, reg2;
1158c37cb7dSVasily Gorbik 	int rc = -EFAULT;
1168c37cb7dSVasily Gorbik 	psw_t old;
1178c37cb7dSVasily Gorbik 
1188c37cb7dSVasily Gorbik 	asm volatile(
1198c37cb7dSVasily Gorbik 		"	mvc	0(16,%[psw_old]),0(%[psw_pgm])\n"
1208c37cb7dSVasily Gorbik 		"	epsw	%[reg1],%[reg2]\n"
1218c37cb7dSVasily Gorbik 		"	st	%[reg1],0(%[psw_pgm])\n"
1228c37cb7dSVasily Gorbik 		"	st	%[reg2],4(%[psw_pgm])\n"
1238c37cb7dSVasily Gorbik 		"	larl	%[reg1],1f\n"
1248c37cb7dSVasily Gorbik 		"	stg	%[reg1],8(%[psw_pgm])\n"
1258c37cb7dSVasily Gorbik 		"	tprot	0(%[addr]),0\n"
1268c37cb7dSVasily Gorbik 		"	ipm	%[rc]\n"
1278c37cb7dSVasily Gorbik 		"	srl	%[rc],28\n"
1288c37cb7dSVasily Gorbik 		"1:	mvc	0(16,%[psw_pgm]),0(%[psw_old])\n"
1298c37cb7dSVasily Gorbik 		: [reg1] "=&d" (reg1),
1308c37cb7dSVasily Gorbik 		  [reg2] "=&a" (reg2),
1318c37cb7dSVasily Gorbik 		  [rc] "+&d" (rc),
1328c37cb7dSVasily Gorbik 		  "=Q" (S390_lowcore.program_new_psw.addr),
1338c37cb7dSVasily Gorbik 		  "=Q" (old)
1348c37cb7dSVasily Gorbik 		: [psw_old] "a" (&old),
1358c37cb7dSVasily Gorbik 		  [psw_pgm] "a" (&S390_lowcore.program_new_psw),
1368c37cb7dSVasily Gorbik 		  [addr] "a" (addr)
1378c37cb7dSVasily Gorbik 		: "cc", "memory");
1388c37cb7dSVasily Gorbik 	return rc;
1398c37cb7dSVasily Gorbik }
1408c37cb7dSVasily Gorbik 
search_mem_end(void)1418c37cb7dSVasily Gorbik static unsigned long search_mem_end(void)
1428c37cb7dSVasily Gorbik {
1438c37cb7dSVasily Gorbik 	unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
1448c37cb7dSVasily Gorbik 	unsigned long offset = 0;
1458c37cb7dSVasily Gorbik 	unsigned long pivot;
1468c37cb7dSVasily Gorbik 
1478c37cb7dSVasily Gorbik 	while (range > 1) {
1488c37cb7dSVasily Gorbik 		range >>= 1;
1498c37cb7dSVasily Gorbik 		pivot = offset + range;
1508c37cb7dSVasily Gorbik 		if (!tprot(pivot << 20))
1518c37cb7dSVasily Gorbik 			offset = pivot;
1528c37cb7dSVasily Gorbik 	}
1538c37cb7dSVasily Gorbik 	return (offset + 1) << 20;
1548c37cb7dSVasily Gorbik }
1558c37cb7dSVasily Gorbik 
detect_max_physmem_end(void)156f913a660SVasily Gorbik unsigned long detect_max_physmem_end(void)
1578c37cb7dSVasily Gorbik {
1588c37cb7dSVasily Gorbik 	unsigned long max_physmem_end = 0;
1598c37cb7dSVasily Gorbik 
160f913a660SVasily Gorbik 	if (!sclp_early_get_memsize(&max_physmem_end)) {
161f913a660SVasily Gorbik 		physmem_info.info_source = MEM_DETECT_SCLP_READ_INFO;
162f913a660SVasily Gorbik 	} else {
163f913a660SVasily Gorbik 		max_physmem_end = search_mem_end();
164f913a660SVasily Gorbik 		physmem_info.info_source = MEM_DETECT_BIN_SEARCH;
165f913a660SVasily Gorbik 	}
166f913a660SVasily Gorbik 	return max_physmem_end;
167f913a660SVasily Gorbik }
1688c37cb7dSVasily Gorbik 
detect_physmem_online_ranges(unsigned long max_physmem_end)169f913a660SVasily Gorbik void detect_physmem_online_ranges(unsigned long max_physmem_end)
170f913a660SVasily Gorbik {
1718c37cb7dSVasily Gorbik 	if (!sclp_early_read_storage_info()) {
1728c37cb7dSVasily Gorbik 		physmem_info.info_source = MEM_DETECT_SCLP_STOR_INFO;
1738c37cb7dSVasily Gorbik 	} else if (!diag260()) {
1748c37cb7dSVasily Gorbik 		physmem_info.info_source = MEM_DETECT_DIAG260;
1758c37cb7dSVasily Gorbik 	} else if (max_physmem_end) {
1768c37cb7dSVasily Gorbik 		add_physmem_online_range(0, max_physmem_end);
1778c37cb7dSVasily Gorbik 	}
1788c37cb7dSVasily Gorbik }
1798c37cb7dSVasily Gorbik 
physmem_set_usable_limit(unsigned long limit)1808c37cb7dSVasily Gorbik void physmem_set_usable_limit(unsigned long limit)
1818c37cb7dSVasily Gorbik {
182f913a660SVasily Gorbik 	physmem_info.usable = limit;
183f913a660SVasily Gorbik 	physmem_alloc_pos = limit;
184f913a660SVasily Gorbik }
185f913a660SVasily Gorbik 
die_oom(unsigned long size,unsigned long align,unsigned long min,unsigned long max)186f913a660SVasily Gorbik static void die_oom(unsigned long size, unsigned long align, unsigned long min, unsigned long max)
187f913a660SVasily Gorbik {
188f913a660SVasily Gorbik 	unsigned long start, end, total_mem = 0, total_reserved_mem = 0;
189f913a660SVasily Gorbik 	struct reserved_range *range;
190f913a660SVasily Gorbik 	enum reserved_range_type t;
1918c37cb7dSVasily Gorbik 	int i;
1928c37cb7dSVasily Gorbik 
193f913a660SVasily Gorbik 	decompressor_printk("Linux version %s\n", kernel_version);
194f913a660SVasily Gorbik 	if (!is_prot_virt_guest() && early_command_line[0])
195f913a660SVasily Gorbik 		decompressor_printk("Kernel command line: %s\n", early_command_line);
196f913a660SVasily Gorbik 	decompressor_printk("Out of memory allocating %lx bytes %lx aligned in range %lx:%lx\n",
197f913a660SVasily Gorbik 			    size, align, min, max);
198f913a660SVasily Gorbik 	decompressor_printk("Reserved memory ranges:\n");
199f913a660SVasily Gorbik 	for_each_physmem_reserved_range(t, range, &start, &end) {
200f913a660SVasily Gorbik 		decompressor_printk("%016lx %016lx %s\n", start, end, get_rr_type_name(t));
201f913a660SVasily Gorbik 		total_reserved_mem += end - start;
2028c37cb7dSVasily Gorbik 	}
203f913a660SVasily Gorbik 	decompressor_printk("Usable online memory ranges (info source: %s [%x]):\n",
204f913a660SVasily Gorbik 			    get_physmem_info_source(), physmem_info.info_source);
205f913a660SVasily Gorbik 	for_each_physmem_usable_range(i, &start, &end) {
206f913a660SVasily Gorbik 		decompressor_printk("%016lx %016lx\n", start, end);
207f913a660SVasily Gorbik 		total_mem += end - start;
2088c37cb7dSVasily Gorbik 	}
209f913a660SVasily Gorbik 	decompressor_printk("Usable online memory total: %lx Reserved: %lx Free: %lx\n",
210f913a660SVasily Gorbik 			    total_mem, total_reserved_mem,
211f913a660SVasily Gorbik 			    total_mem > total_reserved_mem ? total_mem - total_reserved_mem : 0);
212f913a660SVasily Gorbik 	print_stacktrace(current_frame_address());
213f913a660SVasily Gorbik 	sclp_early_printk("\n\n -- System halted\n");
214f913a660SVasily Gorbik 	disabled_wait();
215f913a660SVasily Gorbik }
216f913a660SVasily Gorbik 
physmem_reserve(enum reserved_range_type type,unsigned long addr,unsigned long size)217f913a660SVasily Gorbik void physmem_reserve(enum reserved_range_type type, unsigned long addr, unsigned long size)
218f913a660SVasily Gorbik {
219f913a660SVasily Gorbik 	physmem_info.reserved[type].start = addr;
220f913a660SVasily Gorbik 	physmem_info.reserved[type].end = addr + size;
221f913a660SVasily Gorbik }
222f913a660SVasily Gorbik 
physmem_free(enum reserved_range_type type)223f913a660SVasily Gorbik void physmem_free(enum reserved_range_type type)
224f913a660SVasily Gorbik {
225f913a660SVasily Gorbik 	physmem_info.reserved[type].start = 0;
226f913a660SVasily Gorbik 	physmem_info.reserved[type].end = 0;
227f913a660SVasily Gorbik }
228f913a660SVasily Gorbik 
__physmem_alloc_intersects(unsigned long addr,unsigned long size,unsigned long * intersection_start)229f913a660SVasily Gorbik static bool __physmem_alloc_intersects(unsigned long addr, unsigned long size,
230f913a660SVasily Gorbik 				       unsigned long *intersection_start)
231f913a660SVasily Gorbik {
232f913a660SVasily Gorbik 	unsigned long res_addr, res_size;
233f913a660SVasily Gorbik 	int t;
234f913a660SVasily Gorbik 
235f913a660SVasily Gorbik 	for (t = 0; t < RR_MAX; t++) {
236f913a660SVasily Gorbik 		if (!get_physmem_reserved(t, &res_addr, &res_size))
237f913a660SVasily Gorbik 			continue;
238f913a660SVasily Gorbik 		if (intersects(addr, size, res_addr, res_size)) {
239f913a660SVasily Gorbik 			*intersection_start = res_addr;
240f913a660SVasily Gorbik 			return true;
241f913a660SVasily Gorbik 		}
242f913a660SVasily Gorbik 	}
243f913a660SVasily Gorbik 	return ipl_report_certs_intersects(addr, size, intersection_start);
244f913a660SVasily Gorbik }
245f913a660SVasily Gorbik 
__physmem_alloc_range(unsigned long size,unsigned long align,unsigned long min,unsigned long max,unsigned int from_ranges,unsigned int * ranges_left,bool die_on_oom)246f913a660SVasily Gorbik static unsigned long __physmem_alloc_range(unsigned long size, unsigned long align,
247f913a660SVasily Gorbik 					   unsigned long min, unsigned long max,
248f913a660SVasily Gorbik 					   unsigned int from_ranges, unsigned int *ranges_left,
249f913a660SVasily Gorbik 					   bool die_on_oom)
250f913a660SVasily Gorbik {
251f913a660SVasily Gorbik 	unsigned int nranges = from_ranges ?: physmem_info.range_count;
252f913a660SVasily Gorbik 	unsigned long range_start, range_end;
253f913a660SVasily Gorbik 	unsigned long intersection_start;
254f913a660SVasily Gorbik 	unsigned long addr, pos = max;
255f913a660SVasily Gorbik 
256f913a660SVasily Gorbik 	align = max(align, 8UL);
257f913a660SVasily Gorbik 	while (nranges) {
258f913a660SVasily Gorbik 		__get_physmem_range(nranges - 1, &range_start, &range_end, false);
259f913a660SVasily Gorbik 		pos = min(range_end, pos);
260f913a660SVasily Gorbik 
261f913a660SVasily Gorbik 		if (round_up(min, align) + size > pos)
262f913a660SVasily Gorbik 			break;
263f913a660SVasily Gorbik 		addr = round_down(pos - size, align);
264f913a660SVasily Gorbik 		if (range_start > addr) {
265f913a660SVasily Gorbik 			nranges--;
266f913a660SVasily Gorbik 			continue;
267f913a660SVasily Gorbik 		}
268f913a660SVasily Gorbik 		if (__physmem_alloc_intersects(addr, size, &intersection_start)) {
269f913a660SVasily Gorbik 			pos = intersection_start;
270f913a660SVasily Gorbik 			continue;
271f913a660SVasily Gorbik 		}
272f913a660SVasily Gorbik 
273f913a660SVasily Gorbik 		if (ranges_left)
274f913a660SVasily Gorbik 			*ranges_left = nranges;
275f913a660SVasily Gorbik 		return addr;
276f913a660SVasily Gorbik 	}
277f913a660SVasily Gorbik 	if (die_on_oom)
278f913a660SVasily Gorbik 		die_oom(size, align, min, max);
279f913a660SVasily Gorbik 	return 0;
280f913a660SVasily Gorbik }
281f913a660SVasily Gorbik 
physmem_alloc_range(enum reserved_range_type type,unsigned long size,unsigned long align,unsigned long min,unsigned long max,bool die_on_oom)282f913a660SVasily Gorbik unsigned long physmem_alloc_range(enum reserved_range_type type, unsigned long size,
283f913a660SVasily Gorbik 				  unsigned long align, unsigned long min, unsigned long max,
284f913a660SVasily Gorbik 				  bool die_on_oom)
285f913a660SVasily Gorbik {
286f913a660SVasily Gorbik 	unsigned long addr;
287f913a660SVasily Gorbik 
288f913a660SVasily Gorbik 	max = min(max, physmem_alloc_pos);
289f913a660SVasily Gorbik 	addr = __physmem_alloc_range(size, align, min, max, 0, NULL, die_on_oom);
290f913a660SVasily Gorbik 	if (addr)
291f913a660SVasily Gorbik 		physmem_reserve(type, addr, size);
292f913a660SVasily Gorbik 	return addr;
293f913a660SVasily Gorbik }
294f913a660SVasily Gorbik 
physmem_alloc_top_down(enum reserved_range_type type,unsigned long size,unsigned long align)295f913a660SVasily Gorbik unsigned long physmem_alloc_top_down(enum reserved_range_type type, unsigned long size,
296f913a660SVasily Gorbik 				     unsigned long align)
297f913a660SVasily Gorbik {
298f913a660SVasily Gorbik 	struct reserved_range *range = &physmem_info.reserved[type];
299f913a660SVasily Gorbik 	struct reserved_range *new_range;
300f913a660SVasily Gorbik 	unsigned int ranges_left;
301f913a660SVasily Gorbik 	unsigned long addr;
302f913a660SVasily Gorbik 
303f913a660SVasily Gorbik 	addr = __physmem_alloc_range(size, align, 0, physmem_alloc_pos, physmem_alloc_ranges,
304f913a660SVasily Gorbik 				     &ranges_left, true);
305f913a660SVasily Gorbik 	/* if not a consecutive allocation of the same type or first allocation */
306f913a660SVasily Gorbik 	if (range->start != addr + size) {
307f913a660SVasily Gorbik 		if (range->end) {
308f913a660SVasily Gorbik 			physmem_alloc_pos = __physmem_alloc_range(
309f913a660SVasily Gorbik 				sizeof(struct reserved_range), 0, 0, physmem_alloc_pos,
310f913a660SVasily Gorbik 				physmem_alloc_ranges, &ranges_left, true);
311f913a660SVasily Gorbik 			new_range = (struct reserved_range *)physmem_alloc_pos;
312f913a660SVasily Gorbik 			*new_range = *range;
313f913a660SVasily Gorbik 			range->chain = new_range;
314f913a660SVasily Gorbik 			addr = __physmem_alloc_range(size, align, 0, physmem_alloc_pos,
315f913a660SVasily Gorbik 						     ranges_left, &ranges_left, true);
316f913a660SVasily Gorbik 		}
317f913a660SVasily Gorbik 		range->end = addr + size;
318f913a660SVasily Gorbik 	}
319f913a660SVasily Gorbik 	range->start = addr;
320f913a660SVasily Gorbik 	physmem_alloc_pos = addr;
321f913a660SVasily Gorbik 	physmem_alloc_ranges = ranges_left;
322f913a660SVasily Gorbik 	return addr;
3238c37cb7dSVasily Gorbik }
324*6e259bc5SVasily Gorbik 
get_physmem_alloc_pos(void)325*6e259bc5SVasily Gorbik unsigned long get_physmem_alloc_pos(void)
326*6e259bc5SVasily Gorbik {
327*6e259bc5SVasily Gorbik 	return physmem_alloc_pos;
328*6e259bc5SVasily Gorbik }
329