162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2012 Linaro Limited.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef VIRT_H
762306a36Sopenharmony_ci#define VIRT_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <asm/ptrace.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci/*
1262306a36Sopenharmony_ci * Flag indicating that the kernel was not entered in the same mode on every
1362306a36Sopenharmony_ci * CPU.  The zImage loader stashes this value in an SPSR, so we need an
1462306a36Sopenharmony_ci * architecturally defined flag bit here.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci#define BOOT_CPU_MODE_MISMATCH	PSR_N_BIT
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#ifndef __ASSEMBLY__
1962306a36Sopenharmony_ci#include <asm/cacheflush.h>
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#ifdef CONFIG_ARM_VIRT_EXT
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * __boot_cpu_mode records what mode the primary CPU was booted in.
2462306a36Sopenharmony_ci * A correctly-implemented bootloader must start all CPUs in the same mode:
2562306a36Sopenharmony_ci * if it fails to do this, the flag BOOT_CPU_MODE_MISMATCH is set to indicate
2662306a36Sopenharmony_ci * that some CPU(s) were booted in a different mode.
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci * This allows the kernel to flag an error when the secondaries have come up.
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ciextern int __boot_cpu_mode;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic inline void sync_boot_mode(void)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	/*
3562306a36Sopenharmony_ci	 * As secondaries write to __boot_cpu_mode with caches disabled, we
3662306a36Sopenharmony_ci	 * must flush the corresponding cache entries to ensure the visibility
3762306a36Sopenharmony_ci	 * of their writes.
3862306a36Sopenharmony_ci	 */
3962306a36Sopenharmony_ci	sync_cache_r(&__boot_cpu_mode);
4062306a36Sopenharmony_ci}
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#else
4362306a36Sopenharmony_ci#define __boot_cpu_mode	(SVC_MODE)
4462306a36Sopenharmony_ci#define sync_boot_mode()
4562306a36Sopenharmony_ci#endif
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci#ifndef ZIMAGE
4862306a36Sopenharmony_civoid hyp_mode_check(void);
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci/* Reports the availability of HYP mode */
5162306a36Sopenharmony_cistatic inline bool is_hyp_mode_available(void)
5262306a36Sopenharmony_ci{
5362306a36Sopenharmony_ci	return ((__boot_cpu_mode & MODE_MASK) == HYP_MODE &&
5462306a36Sopenharmony_ci		!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH));
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* Check if the bootloader has booted CPUs in different modes */
5862306a36Sopenharmony_cistatic inline bool is_hyp_mode_mismatched(void)
5962306a36Sopenharmony_ci{
6062306a36Sopenharmony_ci	return !!(__boot_cpu_mode & BOOT_CPU_MODE_MISMATCH);
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_cistatic inline bool is_kernel_in_hyp_mode(void)
6462306a36Sopenharmony_ci{
6562306a36Sopenharmony_ci	return false;
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci#else
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* Only assembly code should need those */
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define HVC_SET_VECTORS 0
7562306a36Sopenharmony_ci#define HVC_SOFT_RESTART 1
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ci#endif /* __ASSEMBLY__ */
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci#define HVC_STUB_ERR	0xbadca11
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_ci#endif /* ! VIRT_H */
82