/*
 * Copyright (c) 2007 Apple Inc. All rights reserved.
 */
/*
 * FILE_ID: thread_status.h
 */


#ifndef _ARM_THREAD_STATUS_H_
#define _ARM_THREAD_STATUS_H_

#include <mach/arm/_structs.h>
#include <mach/message.h>
#include <mach/arm/thread_state.h>

/*
 *    Support for determining the state of a thread
 */


/*
 * Flavors
 */
#define ARM_THREAD_STATE        1
#define ARM_UNIFIED_THREAD_STATE ARM_THREAD_STATE
#define ARM_VFP_STATE           2
#define ARM_EXCEPTION_STATE     3
#define ARM_DEBUG_STATE         4 /* pre-armv8 */
#define THREAD_STATE_NONE       5
#define ARM_THREAD_STATE64      6
#define ARM_EXCEPTION_STATE64   7
// ARM_THREAD_STATE_LAST (legacy) 8
#define ARM_THREAD_STATE32      9

/* API */
#define ARM_DEBUG_STATE32       14
#define ARM_DEBUG_STATE64       15
#define ARM_NEON_STATE          16
#define ARM_NEON_STATE64        17


#define VALID_THREAD_STATE_FLAVOR(x)\
((x == ARM_THREAD_STATE)        ||  \
 (x == ARM_VFP_STATE)           ||  \
 (x == ARM_EXCEPTION_STATE)     ||  \
 (x == ARM_DEBUG_STATE)         ||  \
 (x == THREAD_STATE_NONE)       ||  \
 (x == ARM_THREAD_STATE32)      ||  \
 (x == ARM_THREAD_STATE64)      ||  \
 (x == ARM_EXCEPTION_STATE64)   ||  \
 (x == ARM_NEON_STATE)      ||  \
 (x == ARM_NEON_STATE64)        ||  \
 (x == ARM_DEBUG_STATE32)       ||  \
 (x == ARM_DEBUG_STATE64))

struct arm_state_hdr {
    uint32_t flavor;
    uint32_t count;
};
typedef struct arm_state_hdr arm_state_hdr_t;

typedef _STRUCT_ARM_THREAD_STATE        arm_thread_state_t;
typedef _STRUCT_ARM_THREAD_STATE        arm_thread_state32_t;
typedef _STRUCT_ARM_THREAD_STATE64      arm_thread_state64_t;

struct arm_unified_thread_state {
    arm_state_hdr_t ash;
    union {
        arm_thread_state32_t ts_32;
        arm_thread_state64_t ts_64;
    } uts;
};
#define ts_32   uts.ts_32
#define ts_64   uts.ts_64
typedef struct arm_unified_thread_state arm_unified_thread_state_t;

#define ARM_THREAD_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_thread_state_t)/sizeof(uint32_t)))
#define ARM_THREAD_STATE32_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_thread_state32_t)/sizeof(uint32_t)))
#define ARM_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_thread_state64_t)/sizeof(uint32_t)))
#define ARM_UNIFIED_THREAD_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_unified_thread_state_t)/sizeof(uint32_t)))


typedef _STRUCT_ARM_VFP_STATE           arm_vfp_state_t;
typedef _STRUCT_ARM_NEON_STATE          arm_neon_state_t;
typedef _STRUCT_ARM_NEON_STATE          arm_neon_state32_t;
typedef _STRUCT_ARM_NEON_STATE64        arm_neon_state64_t;

typedef _STRUCT_ARM_EXCEPTION_STATE     arm_exception_state_t;
typedef _STRUCT_ARM_EXCEPTION_STATE     arm_exception_state32_t;
typedef _STRUCT_ARM_EXCEPTION_STATE64   arm_exception_state64_t;

typedef _STRUCT_ARM_DEBUG_STATE32       arm_debug_state32_t;
typedef _STRUCT_ARM_DEBUG_STATE64       arm_debug_state64_t;

/*
 * Otherwise not ARM64 kernel and we must preserve legacy ARM definitions of
 * arm_debug_state for binary compatability of userland consumers of this file.
 */
#if defined(__arm__)
typedef _STRUCT_ARM_DEBUG_STATE         arm_debug_state_t;
#elif defined(__arm64__)
typedef _STRUCT_ARM_LEGACY_DEBUG_STATE      arm_debug_state_t;
#else
#error Undefined architecture
#endif

#define ARM_VFP_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_vfp_state_t)/sizeof(uint32_t)))

#define ARM_EXCEPTION_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_exception_state_t)/sizeof(uint32_t)))

#define ARM_EXCEPTION_STATE64_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_exception_state64_t)/sizeof(uint32_t)))

#define ARM_DEBUG_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_debug_state_t)/sizeof(uint32_t)))

#define ARM_DEBUG_STATE32_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_debug_state32_t)/sizeof(uint32_t)))

#define ARM_DEBUG_STATE64_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_debug_state64_t)/sizeof(uint32_t)))

#define ARM_NEON_STATE_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_neon_state_t)/sizeof(uint32_t)))

#define ARM_NEON_STATE64_COUNT ((mach_msg_type_number_t) \
   (sizeof (arm_neon_state64_t)/sizeof(uint32_t)))

#define MACHINE_THREAD_STATE        ARM_THREAD_STATE
#define MACHINE_THREAD_STATE_COUNT  ARM_UNIFIED_THREAD_STATE_COUNT



/*
 * Largest state on this machine:
 */
#define THREAD_MACHINE_STATE_MAX    THREAD_STATE_MAX


#endif    /* _ARM_THREAD_STATUS_H_ */
