#ifndef _SH_CPU_H_
#define _SH_CPU_H_
#include <sh/psl.h>
#include <sh/frame.h>
#ifdef _KERNEL
#include <machine/intr.h>
#include <sys/clockintr.h>
#include <sys/sched.h>
struct cpu_info {
struct proc *ci_curproc;
struct schedstate_percpu ci_schedstate;
u_int32_t ci_randseed;
#ifdef DIAGNOSTIC
int ci_mutex_level;
#endif
#ifdef GPROF
struct gmonparam *ci_gmon;
struct clockintr ci_gmonclock;
#endif
int ci_want_resched;
int ci_idepth;
struct clockqueue ci_queue;
char ci_panicbuf[512];
};
extern struct cpu_info cpu_info_store;
#define curcpu() (&cpu_info_store)
#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)
#define CPU_BUSY_CYCLE() __asm volatile ("" ::: "memory")
struct clockframe {
int ssr;
int spc;
};
#define CLKF_USERMODE(cf) (!KERNELMODE((cf)->ssr))
#define CLKF_PC(cf) ((cf)->spc)
#define CLKF_INTR(cf) (curcpu()->ci_idepth > 1)
#define PROC_PC(p) ((p)->p_md.md_regs->tf_spc)
#define PROC_STACK(p) ((p)->p_md.md_regs->tf_r15)
void need_resched(struct cpu_info *);
#define clear_resched(ci) (ci)->ci_want_resched = 0
#define need_proftick(p) aston(p)
#define signotify(p) aston(p)
#define aston(p) ((p)->p_md.md_astpending = 1)
#define DELAY(x) delay(x)
#define cpu_idle_enter() do { } while (0)
#define cpu_idle_cycle() __asm volatile("sleep")
#define cpu_idle_leave() do { } while (0)
#endif
#define SH3_PHYS_MASK 0x1fffffff
#define SH3_P0SEG_BASE 0x00000000
#define SH3_P0SEG_END 0x7fffffff
#define SH3_P1SEG_BASE 0x80000000
#define SH3_P1SEG_END 0x9fffffff
#define SH3_P2SEG_BASE 0xa0000000
#define SH3_P2SEG_END 0xbfffffff
#define SH3_P3SEG_BASE 0xc0000000
#define SH3_P3SEG_END 0xdfffffff
#define SH3_P4SEG_BASE 0xe0000000
#define SH3_P4SEG_END 0xffffffff
#define SH3_P1SEG_TO_PHYS(x) ((uint32_t)(x) & SH3_PHYS_MASK)
#define SH3_P2SEG_TO_PHYS(x) ((uint32_t)(x) & SH3_PHYS_MASK)
#define SH3_PHYS_TO_P1SEG(x) ((uint32_t)(x) | SH3_P1SEG_BASE)
#define SH3_PHYS_TO_P2SEG(x) ((uint32_t)(x) | SH3_P2SEG_BASE)
#define SH3_P1SEG_TO_P2SEG(x) ((uint32_t)(x) | 0x20000000)
#define SH3_P2SEG_TO_P1SEG(x) ((uint32_t)(x) & ~0x20000000)
#ifdef _KERNEL
#ifndef __lint__
#define RUN_P2 \
do { \
register uint32_t r0 asm("r0"); \
uint32_t pc; \
__asm volatile( \
" mov.l 1f, %1 ;" \
" mova 2f, %0 ;" \
" or %0, %1 ;" \
" jmp @%1 ;" \
" nop ;" \
" .align 2 ;" \
"1: .long 0x20000000;" \
"2:;" \
: "=r"(r0), "=r"(pc)); \
} while (0)
#define RUN_P1 \
do { \
register uint32_t r0 asm("r0"); \
uint32_t pc; \
__asm volatile( \
" mov.l 1f, %1 ;" \
" mova 2f, %0 ;" \
" nop ;" \
" and %0, %1 ;" \
" nop ;" \
" nop ;" \
" nop ;" \
" nop ;" \
" jmp @%1 ;" \
" nop ;" \
" .align 2 ;" \
"1: .long ~0x20000000;" \
"2:;" \
: "=r"(r0), "=r"(pc)); \
} while (0)
#define PAD_P1_SWITCH __asm volatile ("nop;nop;nop;nop;nop;nop;nop;nop;")
#else
#define RUN_P2 do {} while ( 0)
#define RUN_P1 do {} while ( 0)
#define PAD_P1_SWITCH do {} while ( 0)
#endif
#endif
#if defined(SH4)
#define SH4_PVR_ADDR 0xff000030
#define SH4_PVR (*(volatile uint32_t *) SH4_PVR_ADDR)
#define SH4_PRR_ADDR 0xff000044
#define SH4_PRR (*(volatile uint32_t *) SH4_PRR_ADDR)
#define SH4_PVR_MASK 0xffffff00
#define SH4_PVR_SH7750 0x04020500
#define SH4_PVR_SH7750S 0x04020600
#define SH4_PVR_SH775xR 0x04050000
#define SH4_PVR_SH7751 0x04110000
#define SH4_PRR_MASK 0xfffffff0
#define SH4_PRR_7750R 0x00000100
#define SH4_PRR_7751R 0x00000110
#endif
#include <machine/cputypes.h>
#ifdef _KERNEL
void sh_cpu_init(int, int);
void sh_startup(void);
__dead void cpu_reset(void);
void _cpu_spin(uint32_t);
void delay(int);
struct pcb;
void savectx(struct pcb *);
struct fpreg;
void fpu_save(struct fpreg *);
void fpu_restore(struct fpreg *);
u_int cpu_dump(int (*)(dev_t, daddr_t, caddr_t, size_t), daddr_t *);
u_int cpu_dumpsize(void);
void dumpconf(void);
void dumpsys(void);
unsigned int cpu_rnd_messybits(void);
static inline u_long
intr_disable(void)
{
return (u_long)_cpu_intr_suspend();
}
static inline void
intr_restore(u_long s)
{
_cpu_intr_resume((int)s);
}
#endif
#endif