blob: 21f7531e5b7c9a710e2a3fc9d4d19fb6d8266717 [file] [edit]
/*
* Copyright (c) 2022-2026, Arm Limited and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef FEAT_DETECT_H
#define FEAT_DETECT_H
/* Function Prototypes */
void detect_arch_features(unsigned int core_pos);
/*
* The `ENABLE_FEAT` mechanism is implemented with a tri-state approach for each
* feature:
* ENABLE_FEAT_xxx = 0 : The feature is disabled statically at compile time.
* ENABLE_FEAT_xxx = 1 : The feature is enabled and must be present in hardware.
* `FEATURE_DETECTION` will panic if feature is not present
* at cold boot.
* ENABLE_FEAT_xxx = 2 : The feature is enabled but dynamically enabled at
* runtime depending on hardware capability.
*
* For better readability, state values are defined with macros:
*/
#define FEAT_STATE_DISABLED 0
#define FEAT_STATE_ALWAYS 1
#define FEAT_STATE_CHECKED 2
/*
* Force inlining to let the compiler optimise away the whole check on
* FEAT_STATE_DISABLED.
*/
#define _CREATE_FEATURE_ID_FIELD(name, idreg, guard, field, min, max, worlds) \
__attribute__((always_inline)) \
static inline unsigned int _read_ ## name ## _id_field(void) \
{ \
return (unsigned int)EXTRACT(field, read_ ## idreg()); \
}
#define _CREATE_FEATURE_PRESENT(name, idreg, guard, field, min, max, worlds) \
__attribute__((always_inline)) \
static inline bool is_ ## name ## _present(void) \
{ \
return (_read_ ## name ## _id_field() >= min) ? true : false; \
}
#define _CREATE_FEATURE_SUPPORTED(name, idreg, guard, field, min, max, worlds) \
__attribute__((always_inline)) \
static inline bool is_ ## name ## _supported(void) \
{ \
if ((guard) == FEAT_STATE_DISABLED) { \
return false; \
} \
if ((guard) == FEAT_STATE_ALWAYS) { \
return true; \
} \
return is_ ## name ## _present(); \
}
#endif /* FEAT_DETECT_H */