// SPDX-License-Identifier: GPL-2.0+
/*
 * Code shared between SPL and U-Boot proper
 *
 * Copyright (c) 2015 Google, Inc
 * Written by Simon Glass <sjg@chromium.org>
 */

#include <common.h>

DECLARE_GLOBAL_DATA_PTR;

/* Unfortunately x86 or ARM can't compile this code as gd cannot be assigned */
#if !defined(CONFIG_X86) && !defined(CONFIG_ARM)
__weak void arch_setup_gd(struct global_data *gd_ptr)
{
	gd = gd_ptr;
}
#endif /* !CONFIG_X86 && !CONFIG_ARM */

/**
 * This function is called after the position of the initial stack is
 * determined in gd->start_addr_sp. Boards can override it to set up
 * stack-checking markers.
 */
__weak void board_init_f_init_stack_protection(void)
{
#if CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE)
	ulong stack_bottom = gd->start_addr_sp -
		CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK);

	/* substact some safety margin (0x20) since stack is in use here */
	memset((void *)stack_bottom, CONFIG_VAL(SYS_STACK_F_CHECK_BYTE),
	       CONFIG_VAL(SIZE_LIMIT_PROVIDE_STACK) - 0x20);
#endif
}

/*
 * Allocate reserved space for use as 'globals' from 'top' address and
 * return 'bottom' address of allocated space
 *
 * Notes:
 *
 * Actual reservation cannot be done from within this function as
 * it requires altering the C stack pointer, so this will be done by
 * the caller upon return from this function.
 *
 * IMPORTANT:
 *
 * Alignment constraints may differ for each 'chunk' allocated. For now:
 *
 * - GD is aligned down on a 16-byte boundary
 *
 *  - the early malloc arena is not aligned, therefore it follows the stack
 *   alignment constraint of the architecture for which we are bulding.
 *
 *  - GD is allocated last, so that the return value of this functions is
 *   both the bottom of the reserved area and the address of GD, should
 *   the calling context need it.
 */

ulong board_init_f_alloc_reserve(ulong top)
{
	/* Reserve early malloc arena */
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
	top -= CONFIG_VAL(SYS_MALLOC_F_LEN);
#endif
	/* LAST : reserve GD (rounded up to a multiple of 16 bytes) */
	top = rounddown(top-sizeof(struct global_data), 16);

	return top;
}

/*
 * Initialize reserved space (which has been safely allocated on the C
 * stack from the C runtime environment handling code).
 *
 * Notes:
 *
 * Actual reservation was done by the caller; the locations from base
 * to base+size-1 (where 'size' is the value returned by the allocation
 * function above) can be accessed freely without risk of corrupting the
 * C runtime environment.
 *
 * IMPORTANT:
 *
 * Upon return from the allocation function above, on some architectures
 * the caller will set gd to the lowest reserved location. Therefore, in
 * this initialization function, the global data MUST be placed at base.
 *
 * ALSO IMPORTANT:
 *
 * On some architectures, gd will already be good when entering this
 * function. On others, it will only be good once arch_setup_gd() returns.
 * Therefore, global data accesses must be done:
 *
 * - through gd_ptr if before the call to arch_setup_gd();
 *
 * - through gd once arch_setup_gd() has been called.
 *
 * Do not use 'gd->' until arch_setup_gd() has been called!
 *
 * IMPORTANT TOO:
 *
 * Initialization for each "chunk" (GD, early malloc arena...) ends with
 * an incrementation line of the form 'base += <some size>'. The last of
 * these incrementations seems useless, as base will not be used any
 * more after this incrementation; but if/when a new "chunk" is appended,
 * this increment will be essential as it will give base right value for
 * this new chunk (which will have to end with its own incrementation
 * statement). Besides, the compiler's optimizer will silently detect
 * and remove the last base incrementation, therefore leaving that last
 * (seemingly useless) incrementation causes no code increase.
 */

void board_init_f_init_reserve(ulong base)
{
	struct global_data *gd_ptr;

	/*
	 * clear GD entirely and set it up.
	 * Use gd_ptr, as gd may not be properly set yet.
	 */

	gd_ptr = (struct global_data *)base;
	/* zero the area */
	memset(gd_ptr, '\0', sizeof(*gd));
	/* set GD unless architecture did it already */
#if !defined(CONFIG_ARM)
	arch_setup_gd(gd_ptr);
#endif
	/* next alloc will be higher by one GD plus 16-byte alignment */
	base += roundup(sizeof(struct global_data), 16);

	/*
	 * record early malloc arena start.
	 * Use gd as it is now properly set for all architectures.
	 */

#if CONFIG_VAL(SYS_MALLOC_F_LEN)
	/* go down one 'early malloc arena' */
	gd->malloc_base = base;
	/* next alloc will be higher by one 'early malloc arena' size */
	base += CONFIG_VAL(SYS_MALLOC_F_LEN);
#endif

	if (CONFIG_IS_ENABLED(SYS_REPORT_STACK_F_USAGE))
		board_init_f_init_stack_protection();
}

/*
 * Board-specific Platform code can reimplement show_boot_progress () if needed
 */
__weak void show_boot_progress(int val) {}
