/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef CPU_X86_LAPIC_H
#define CPU_X86_LAPIC_H

#include <arch/cpu.h>
#include <cpu/x86/lapic_def.h>
#include <cpu/x86/msr.h>
#include <device/mmio.h>
#include <halt.h>
#include <stdint.h>

static __always_inline uint32_t xapic_read(unsigned int reg)
{
	return read32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg));
}

static __always_inline void xapic_write(unsigned int reg, uint32_t v)
{
	write32((volatile void *)(uintptr_t)(LAPIC_DEFAULT_BASE + reg), v);
}

static __always_inline void xapic_send_ipi(uint32_t icrlow, uint32_t icrhi)
{
	xapic_write(LAPIC_ICR2, icrhi);
	xapic_write(LAPIC_ICR, icrlow);
}

static __always_inline int xapic_busy(void)
{
	return xapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY;
}

static __always_inline uint32_t x2apic_read(unsigned int reg)
{
	uint32_t value, index;
	msr_t msr;

	index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
	msr = rdmsr(index);
	value = msr.lo;
	return value;
}

static __always_inline void x2apic_write(unsigned int reg, uint32_t v)
{
	uint32_t index;
	msr_t msr;

	index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
	msr.hi = 0x0;
	msr.lo = v;
	wrmsr(index, msr);
}

static __always_inline void x2apic_send_ipi(uint32_t icrlow, uint32_t icrhi)
{
	msr_t icr;
	icr.hi = icrhi;
	icr.lo = icrlow;
	wrmsr(X2APIC_MSR_ICR_ADDRESS, icr);
}

static __always_inline bool is_x2apic_mode(void)
{
	if (CONFIG(XAPIC_ONLY))
		return false;

	if (CONFIG(X2APIC_ONLY))
		return true;

	msr_t msr;
	msr = rdmsr(LAPIC_BASE_MSR);
	return ((msr.lo & LAPIC_BASE_X2APIC_ENABLED) == LAPIC_BASE_X2APIC_ENABLED);
}

static __always_inline uint32_t lapic_read(unsigned int reg)
{
	if (is_x2apic_mode())
		return x2apic_read(reg);
	else
		return xapic_read(reg);
}

static __always_inline void lapic_write(unsigned int reg, uint32_t v)
{
	if (is_x2apic_mode())
		x2apic_write(reg, v);
	else
		xapic_write(reg, v);
}

static __always_inline void lapic_update32(unsigned int reg, uint32_t mask, uint32_t or)
{
	if (is_x2apic_mode()) {
		uint32_t index;
		msr_t msr;
		index = X2APIC_MSR_BASE_ADDRESS + (uint32_t)(reg >> 4);
		msr = rdmsr(index);
		msr.lo &= mask;
		msr.lo |= or;
		wrmsr(index, msr);
	} else {
		uint32_t value;
		value = xapic_read(reg);
		value &= mask;
		value |= or;
		xapic_write(reg, value);
	}
}

static __always_inline void lapic_send_ipi(uint32_t icrlow, uint32_t apicid)
{
	if (is_x2apic_mode())
		x2apic_send_ipi(icrlow, apicid);
	else
		xapic_send_ipi(icrlow, SET_LAPIC_DEST_FIELD(apicid));
}

static __always_inline int lapic_busy(void)
{
	if (is_x2apic_mode())
		return 0;
	else
		return xapic_busy();
}

static __always_inline unsigned int initial_lapicid(void)
{
	uint32_t lapicid;
	if (is_x2apic_mode() && cpuid_get_max_func() >= 0xb)
		lapicid = cpuid_ext(0xb, 0).edx;
	else
		lapicid = cpuid_ebx(1) >> 24;
	return lapicid;
}

static __always_inline unsigned int lapicid(void)
{
	uint32_t lapicid = lapic_read(LAPIC_ID);

	/* check x2apic mode and return accordingly */
	if (!is_x2apic_mode())
		lapicid >>= 24;
	return lapicid;
}

static __always_inline void lapic_send_ipi_self(uint32_t icrlow)
{
	int i = 1000;

	/* LAPIC_DEST_SELF does not support all delivery mode -fields. */
	lapic_send_ipi(icrlow, lapicid());

	/* In case of X2APIC force a short delay, to prevent deadlock in a case
	 * the immediately following code acquires some lock, like with printk().
	 */
	const bool x2apic = is_x2apic_mode();

	while (x2apic && i--)
		cpu_relax();
}

static __always_inline void lapic_send_ipi_others(uint32_t icrlow)
{
	lapic_send_ipi(LAPIC_DEST_ALLBUT | icrlow, 0);
}

#if !CONFIG(AP_IN_SIPI_WAIT)
/* If we need to go back to sipi wait, we use the long non-inlined version of
 * this function in lapic_cpu_stop.c
 */
static __always_inline void stop_this_cpu(void)
{
	/* Called by an AP when it is ready to halt and wait for a new task */
	halt();
}
#else
void stop_this_cpu(void);
#endif

void enable_lapic(void);
void enable_lapic_mode(bool try_set_x2apic);
void disable_lapic(void);
void setup_lapic_interrupts(void);

static inline unsigned int early_lapicid(void)
{
	if (!CONFIG(SMP))
		return 0;

	if (!ENV_RAMSTAGE)
		return 0;

	enable_lapic();
	return lapicid();
}

#endif /* CPU_X86_LAPIC_H */
