#ifndef _MACHINE_PCPU_H_
#define _MACHINE_PCPU_H_
#include <machine/segments.h>
#include <machine/tss.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
struct monitorbuf {
int idle_state;
int stop_state;
char padding[128 - (2 * sizeof(int))];
};
_Static_assert(sizeof(struct monitorbuf) == 128, "2x cache line");
#define PCPU_MD_FIELDS \
struct monitorbuf pc_monitorbuf __aligned(128); \
struct pcpu *pc_prvspace; \
struct pmap *pc_curpmap; \
struct segment_descriptor pc_common_tssd; \
struct segment_descriptor *pc_tss_gdt; \
struct segment_descriptor *pc_fsgs_gdt; \
struct i386tss *pc_common_tssp; \
u_int pc_kesp0; \
u_int pc_trampstk; \
int pc_currentldt; \
u_int pc_acpi_id; \
u_int pc_apic_id; \
int pc_private_tss; \
u_int pc_cmci_mask; \
u_int pc_vcpu_id; \
struct mtx pc_cmap_lock; \
void *pc_cmap_pte1; \
void *pc_cmap_pte2; \
caddr_t pc_cmap_addr1; \
caddr_t pc_cmap_addr2; \
vm_offset_t pc_qmap_addr; \
vm_offset_t pc_copyout_maddr; \
vm_offset_t pc_copyout_saddr; \
struct mtx pc_copyout_mlock; \
struct sx pc_copyout_slock; \
char *pc_copyout_buf; \
vm_offset_t pc_pmap_eh_va; \
caddr_t pc_pmap_eh_ptep; \
uint32_t pc_smp_tlb_done; \
uint32_t pc_ibpb_set; \
void *pc_mds_buf; \
void *pc_mds_buf64; \
uint32_t pc_pad[4]; \
uint8_t pc_mds_tmp[64]; \
u_int pc_ipi_bitmap; \
char __pad[3518]
#ifdef _KERNEL
#define MONITOR_STOPSTATE_RUNNING 0
#define MONITOR_STOPSTATE_STOPPED 1
#define __pcpu_offset(name) \
__offsetof(struct pcpu, name)
#define __pcpu_type(name) \
__typeof(((struct pcpu *)0)->name)
#define __PCPU_PTR(name) \
(&get_pcpu()->name)
#define __PCPU_GET(name) __extension__ ({ \
__pcpu_type(name) __res; \
struct __s { \
u_char __b[MIN(sizeof(__res), 4)]; \
}; \
\
if (sizeof(__res) == 1 || sizeof(__res) == 2 || \
sizeof(__res) == 4) { \
__asm __volatile("mov %%fs:%c1,%0" \
: "=r" (*(struct __s *)(void *)&__res) \
: "i" (__pcpu_offset(name))); \
} else { \
__res = *__PCPU_PTR(name); \
} \
__res; \
})
#define __PCPU_ADD(name, val) do { \
__pcpu_type(name) __val; \
struct __s { \
u_char __b[MIN(sizeof(__val), 4)]; \
}; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4) { \
__asm __volatile("add %1,%%fs:%c0" \
: \
: "i" (__pcpu_offset(name)), \
"r" (*(struct __s *)(void *)&__val) \
: "cc", "memory"); \
} else \
*__PCPU_PTR(name) += __val; \
} while (0)
#define __PCPU_SET(name, val) do { \
__pcpu_type(name) __val; \
struct __s { \
u_char __b[MIN(sizeof(__val), 4)]; \
}; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4) { \
__asm __volatile("mov %1,%%fs:%c0" \
: \
: "i" (__pcpu_offset(name)), \
"r" (*(struct __s *)(void *)&__val) \
: "memory"); \
} else { \
*__PCPU_PTR(name) = __val; \
} \
} while (0)
#define get_pcpu() __extension__ ({ \
struct pcpu *__pc; \
\
__asm __volatile("movl %%fs:%c1,%0" \
: "=r" (__pc) \
: "i" (__pcpu_offset(pc_prvspace))); \
__pc; \
})
#define PCPU_GET(member) __PCPU_GET(pc_ ## member)
#define PCPU_ADD(member, val) __PCPU_ADD(pc_ ## member, val)
#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member)
#define PCPU_SET(member, val) __PCPU_SET(pc_ ## member, val)
#define IS_BSP() (PCPU_GET(cpuid) == 0)
#endif
#endif