#ifdef __i386__
#include <i386/pcpu.h>
#else
#ifndef _MACHINE_PCPU_H_
#define _MACHINE_PCPU_H_
#include <machine/_pmap.h>
#include <machine/segments.h>
#include <machine/tss.h>
#define PC_PTI_STACK_SZ 16
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 amd64tss *pc_tssp; \
void *pc_pad0; \
uint64_t pc_kcr3; \
uint64_t pc_ucr3; \
uint64_t pc_saved_ucr3; \
register_t pc_rsp0; \
register_t pc_scratch_rsp; \
register_t pc_scratch_rax; \
u_int pc_apic_id; \
u_int pc_acpi_id; \
\
struct user_segment_descriptor *pc_fs32p; \
\
struct user_segment_descriptor *pc_gs32p; \
\
struct system_segment_descriptor *pc_ldt; \
\
struct system_segment_descriptor *pc_tss; \
u_int pc_cmci_mask; \
uint64_t pc_dbreg[16]; \
uint64_t pc_pti_stack[PC_PTI_STACK_SZ]; \
register_t pc_pti_rsp0; \
int pc_dbreg_cmd; \
u_int pc_vcpu_id; \
uint32_t pc_pcid_next; \
uint32_t pc_pcid_gen; \
uint32_t pc_unused; \
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; \
struct amd64tss pc_common_tss; \
struct user_segment_descriptor pc_gdt[NGDT]; \
void *pc_smp_tlb_pmap; \
uint64_t pc_smp_tlb_addr1; \
uint64_t pc_smp_tlb_addr2; \
uint32_t pc_smp_tlb_gen; \
u_int pc_smp_tlb_op; \
uint64_t pc_ucr3_load_mask; \
u_int pc_small_core; \
u_int pc_pcid_invlpg_workaround; \
struct pmap_pcid pc_kpmap_store; \
char __pad[2900]
#define PC_DBREG_CMD_NONE 0
#define PC_DBREG_CMD_LOAD 1
#ifdef _KERNEL
#define MONITOR_STOPSTATE_RUNNING 0
#define MONITOR_STOPSTATE_STOPPED 1
#define __pcpu_type(name) \
__typeof(((struct pcpu *)0)->name)
#ifdef __SEG_GS
#define get_pcpu() __extension__ ({ \
static struct pcpu __seg_gs *__pc = 0; \
\
__pc->pc_prvspace; \
})
#define __PCPU_PTR(name) __extension__ ({ \
struct pcpu *__pc = get_pcpu(); \
\
&__pc->name; \
})
#define __PCPU_GET(name) __extension__ ({ \
static struct pcpu __seg_gs *__pc = 0; \
\
__pc->name; \
})
#define __PCPU_ADD(name, val) do { \
static struct pcpu __seg_gs *__pc = 0; \
__pcpu_type(name) __val; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4 || sizeof(__val) == 8) { \
__pc->name += __val; \
} else \
*__PCPU_PTR(name) += __val; \
} while (0)
#define __PCPU_SET(name, val) do { \
static struct pcpu __seg_gs *__pc = 0; \
__pcpu_type(name) __val; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4 || sizeof(__val) == 8) { \
__pc->name = __val; \
} else \
*__PCPU_PTR(name) = __val; \
} while (0)
#else
#define __pcpu_offset(name) \
__offsetof(struct pcpu, name)
#define __PCPU_PTR(name) \
(&get_pcpu()->name)
#define __PCPU_GET(name) __extension__ ({ \
__pcpu_type(name) __res; \
struct __s { \
u_char __b[MIN(sizeof(__pcpu_type(name)), 8)]; \
}; \
\
if (sizeof(__res) == 1 || sizeof(__res) == 2 || \
sizeof(__res) == 4 || sizeof(__res) == 8) { \
__asm __volatile("mov %%gs:%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(__pcpu_type(name)), 8)]; \
}; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4 || sizeof(__val) == 8) { \
__asm __volatile("add %1,%%gs:%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(__pcpu_type(name)), 8)]; \
}; \
\
__val = (val); \
if (sizeof(__val) == 1 || sizeof(__val) == 2 || \
sizeof(__val) == 4 || sizeof(__val) == 8) { \
__asm __volatile("mov %1,%%gs:%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("movq %%gs:%c1,%0" \
: "=r" (__pc) \
: "i" (__pcpu_offset(pc_prvspace))); \
__pc; \
})
#endif
#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)
#define zpcpu_offset_cpu(cpu) ((uintptr_t)&__pcpu[0] + UMA_PCPU_ALLOC_SIZE * cpu)
#define zpcpu_base_to_offset(base) (void *)((uintptr_t)(base) - (uintptr_t)&__pcpu[0])
#define zpcpu_offset_to_base(base) (void *)((uintptr_t)(base) + (uintptr_t)&__pcpu[0])
#define zpcpu_sub_protected(base, n) do { \
ZPCPU_ASSERT_PROTECTED(); \
zpcpu_sub(base, n); \
} while (0)
#define zpcpu_set_protected(base, n) do { \
__typeof(*base) __n = (n); \
ZPCPU_ASSERT_PROTECTED(); \
switch (sizeof(*base)) { \
case 4: \
__asm __volatile("movl\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
case 8: \
__asm __volatile("movq\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
default: \
*zpcpu_get(base) = __n; \
} \
} while (0);
#define zpcpu_add(base, n) do { \
__typeof(*base) __n = (n); \
CTASSERT(sizeof(*base) == 4 || sizeof(*base) == 8); \
switch (sizeof(*base)) { \
case 4: \
__asm __volatile("addl\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
case 8: \
__asm __volatile("addq\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
} \
} while (0)
#define zpcpu_add_protected(base, n) do { \
ZPCPU_ASSERT_PROTECTED(); \
zpcpu_add(base, n); \
} while (0)
#define zpcpu_sub(base, n) do { \
__typeof(*base) __n = (n); \
CTASSERT(sizeof(*base) == 4 || sizeof(*base) == 8); \
switch (sizeof(*base)) { \
case 4: \
__asm __volatile("subl\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
case 8: \
__asm __volatile("subq\t%1,%%gs:(%0)" \
: : "r" (base), "ri" (__n) : "memory", "cc"); \
break; \
} \
} while (0);
#endif
#endif
#endif