#ifndef _MACHINE_CPU_H_
#define _MACHINE_CPU_H_
#define CPU_COMPATIBLE 1
#define CPU_ID_AA64ISAR0 2
#define CPU_ID_AA64ISAR1 3
#define CPU_ID_AA64ISAR2 4
#define CPU_ID_AA64MMFR0 5
#define CPU_ID_AA64MMFR1 6
#define CPU_ID_AA64MMFR2 7
#define CPU_ID_AA64PFR0 8
#define CPU_ID_AA64PFR1 9
#define CPU_ID_AA64SMFR0 10
#define CPU_ID_AA64ZFR0 11
#define CPU_LIDACTION 12
#define CPU_MAXID 13
#define CTL_MACHDEP_NAMES { \
{ 0, 0 }, \
{ "compatible", CTLTYPE_STRING }, \
{ "id_aa64isar0", CTLTYPE_QUAD }, \
{ "id_aa64isar1", CTLTYPE_QUAD }, \
{ "id_aa64isar2", CTLTYPE_QUAD }, \
{ "id_aa64mmfr0", CTLTYPE_QUAD }, \
{ "id_aa64mmfr1", CTLTYPE_QUAD }, \
{ "id_aa64mmfr2", CTLTYPE_QUAD }, \
{ "id_aa64pfr0", CTLTYPE_QUAD }, \
{ "id_aa64pfr1", CTLTYPE_QUAD }, \
{ "id_aa64smfr0", CTLTYPE_QUAD }, \
{ "id_aa64zfr0", CTLTYPE_QUAD }, \
{ "lidaction", CTLTYPE_INT }, \
}
#ifdef _KERNEL
extern uint64_t cpu_id_aa64isar0;
extern uint64_t cpu_id_aa64isar1;
extern uint64_t cpu_id_aa64isar2;
extern uint64_t cpu_id_aa64mmfr0;
extern uint64_t cpu_id_aa64mmfr1;
extern uint64_t cpu_id_aa64mmfr2;
extern uint64_t cpu_id_aa64pfr0;
extern uint64_t cpu_id_aa64pfr1;
extern uint64_t cpu_id_aa64zfr0;
void cpu_identify_cleanup(void);
#include <machine/intr.h>
#include <machine/frame.h>
#include <machine/armreg.h>
#define clockframe trapframe
#define CLKF_USERMODE(frame) ((frame->tf_elr & (1ul << 63)) == 0)
#define CLKF_INTR(frame) (curcpu()->ci_idepth > 1)
#define CLKF_PC(frame) (frame->tf_elr)
#define PROC_PC(p) ((p)->p_addr->u_pcb.pcb_tf->tf_elr)
#define PROC_STACK(p) ((p)->p_addr->u_pcb.pcb_tf->tf_sp)
#include <sys/clockintr.h>
#include <sys/device.h>
#include <sys/sched.h>
#include <sys/srp.h>
#include <uvm/uvm_percpu.h>
#include <sys/xcall.h>
struct cpu_info {
struct device *ci_dev;
struct cpu_info *ci_next;
struct schedstate_percpu ci_schedstate;
u_int32_t ci_cpuid;
uint64_t ci_mpidr;
uint64_t ci_midr;
u_int ci_acpi_proc_id;
int ci_node;
struct cpu_info *ci_self;
#define __HAVE_CPU_TOPOLOGY
u_int32_t ci_cputype;
u_int32_t ci_smt_id;
u_int32_t ci_core_id;
u_int32_t ci_pkg_id;
struct proc *ci_curproc;
struct pcb *ci_curpcb;
struct pmap *ci_curpm;
u_int32_t ci_randseed;
u_int32_t ci_ctrl;
u_int64_t ci_trampoline_vectors;
uint32_t ci_cpl;
uint32_t ci_ipending;
uint32_t ci_idepth;
#ifdef DIAGNOSTIC
int ci_mutex_level;
#endif
int ci_want_resched;
void (*ci_flush_bp)(void);
void (*ci_serror)(void);
uint64_t ci_ttbr1;
vaddr_t ci_el1_stkend;
uint32_t ci_psci_idle_latency;
uint32_t ci_psci_idle_param;
uint32_t ci_psci_suspend_param;
struct opp_table *ci_opp_table;
volatile int ci_opp_idx;
volatile int ci_opp_max;
uint32_t ci_cpu_supply;
uint64_t ci_capacity;
u_long ci_prev_sleep;
u_long ci_last_itime;
#ifdef MULTIPROCESSOR
struct srp_hazard ci_srp_hazards[SRP_HAZARD_NUM];
struct xcall_cpu ci_xcall;
#define __HAVE_UVM_PERCPU
struct uvm_pmr_cache ci_uvm;
volatile int ci_flags;
volatile int ci_ddb_paused;
#define CI_DDB_RUNNING 0
#define CI_DDB_SHOULDSTOP 1
#define CI_DDB_STOPPED 2
#define CI_DDB_ENTERDDB 3
#define CI_DDB_INDDB 4
#endif
#ifdef GPROF
struct gmonparam *ci_gmon;
struct clockintr ci_gmonclock;
#endif
struct clockqueue ci_queue;
char ci_panicbuf[512];
};
#define CPUF_PRIMARY (1<<0)
#define CPUF_AP (1<<1)
#define CPUF_IDENTIFY (1<<2)
#define CPUF_IDENTIFIED (1<<3)
#define CPUF_PRESENT (1<<4)
#define CPUF_GO (1<<5)
#define CPUF_RUNNING (1<<6)
static inline struct cpu_info *
curcpu(void)
{
struct cpu_info *__ci = NULL;
__asm volatile("mrs %0, tpidr_el1" : "=r" (__ci));
return (__ci);
}
extern struct cpu_info cpu_info_primary;
extern struct cpu_info *cpu_info_list;
#ifndef MULTIPROCESSOR
#define cpu_number() 0
#define CPU_IS_PRIMARY(ci) 1
#define CPU_IS_RUNNING(ci) 1
#define CPU_INFO_ITERATOR int
#define CPU_INFO_FOREACH(cii, ci) \
for (cii = 0, ci = curcpu(); ci != NULL; ci = NULL)
#define CPU_INFO_UNIT(ci) 0
#define MAXCPUS 1
#define cpu_unidle(ci)
#else
#define cpu_number() (curcpu()->ci_cpuid)
#define CPU_IS_PRIMARY(ci) ((ci) == &cpu_info_primary)
#define CPU_IS_RUNNING(ci) ((ci)->ci_flags & CPUF_RUNNING)
#define CPU_INFO_ITERATOR int
#define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \
ci != NULL; ci = ci->ci_next)
#define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0)
#define MAXCPUS 256
extern struct cpu_info *cpu_info[MAXCPUS];
void cpu_boot_secondary_processors(void);
#endif
#define CPU_BUSY_CYCLE() __asm volatile("yield" : : : "memory")
#define curpcb curcpu()->ci_curpcb
static inline unsigned int
cpu_rnd_messybits(void)
{
uint64_t val, rval;
__asm volatile("mrs %0, CNTVCT_EL0; rbit %1, %0;"
: "=r" (val), "=r" (rval));
return (val ^ rval);
}
#define aston(p) ((p)->p_md.md_astpending = 1)
#define setsoftast() aston(curcpu()->ci_curproc)
#ifdef MULTIPROCESSOR
void cpu_unidle(struct cpu_info *ci);
#define signotify(p) (aston(p), cpu_unidle((p)->p_cpu))
void cpu_kick(struct cpu_info *);
#else
#define cpu_kick(ci)
#define cpu_unidle(ci)
#define signotify(p) setsoftast()
#endif
void need_resched(struct cpu_info *);
#define clear_resched(ci) ((ci)->ci_want_resched = 0)
#define need_proftick(p) aston(p)
void proc_trampoline(void);
void dumpconf(void);
void svc_handler (trapframe_t *);
static __inline void
restore_daif(uint32_t daif)
{
__asm volatile ("msr daif, %x0":: "r"(daif));
}
static __inline void
enable_irq_daif(void)
{
__asm volatile ("msr daifclr, #3");
}
static __inline void
disable_irq_daif(void)
{
__asm volatile ("msr daifset, #3");
}
static __inline uint32_t
disable_irq_daif_ret(void)
{
uint32_t daif;
__asm volatile ("mrs %x0, daif": "=r"(daif));
__asm volatile ("msr daifset, #3");
return daif;
}
static inline void
intr_enable(void)
{
enable_irq_daif();
}
static inline u_long
intr_disable(void)
{
return disable_irq_daif_ret();
}
static inline void
intr_restore(u_long daif)
{
restore_daif(daif);
}
void cpu_classify(void);
void cpu_halt(void);
int cpu_suspend_primary(void);
void cpu_resume_secondary(struct cpu_info *);
extern void (*cpu_idle_cycle_fcn)(void);
extern void (*cpu_suspend_cycle_fcn)(void);
void cpu_wfi(void);
void delay (unsigned);
#define DELAY(x) delay(x)
#endif
#ifdef MULTIPROCESSOR
#include <sys/mplock.h>
#endif
#endif