#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/user.h>
#include <sys/msgbuf.h>
#include <sys/exec.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#ifdef MULTIPROCESSOR
#include <sys/mplock.h>
#endif
#include <machine/asm.h>
#include <machine/asm_macro.h>
#include <machine/atomic.h>
#include <machine/cmmu.h>
#include <machine/cpu.h>
#include <machine/reg.h>
#ifdef M88100
#include <machine/m88100.h>
#endif
#include <uvm/uvm_extern.h>
#ifdef DDB
#include <machine/db_machdep.h>
#include <ddb/db_extern.h>
#include <ddb/db_interface.h>
#endif
typedef struct {
u_int32_t word_one, word_two;
} m88k_exception_vector_area;
void dumpconf(void);
void dumpsys(void);
void regdump(struct trapframe *f);
void *vector_init(m88k_exception_vector_area *, u_int32_t *, int);
void atomic_init(void);
#ifdef MULTIPROCESSOR
cpuid_t master_cpu;
__cpu_simple_lock_t cmmu_cpu_lock = __SIMPLELOCK_UNLOCKED;
#endif
struct cpu_info m88k_cpus[MAX_CPUS] = {
#ifndef MULTIPROCESSOR
{ .ci_flags = CIF_ALIVE | CIF_PRIMARY }
#endif
};
const struct cmmu_p *cmmu;
int safepri = IPL_NONE;
void
setregs(struct proc *p, struct exec_package *pack, u_long stack,
struct ps_strings *arginfo)
{
struct trapframe *tf = (struct trapframe *)USER_REGS(p);
__asm__ volatile ("fstcr %r0, %fcr0");
__asm__ volatile ("fstcr %r0, %fcr62");
__asm__ volatile ("fstcr %r0, %fcr63");
memset(tf, 0, sizeof *tf);
#ifdef M88110
if (CPU_IS88110) {
tf->tf_epsr = PSR_SFD;
}
#endif
#ifdef M88100
if (CPU_IS88100) {
tf->tf_epsr = PSR_SFD | PSR_SFD2;
}
#endif
#ifdef M88110
if (CPU_IS88110) {
tf->tf_exip = (pack->ep_entry & XIP_ADDR) + 4;
}
#endif
#ifdef M88100
if (CPU_IS88100) {
tf->tf_snip = ((pack->ep_entry + 8) & FIP_ADDR) | FIP_V;
tf->tf_sfip = tf->tf_snip + 4;
}
#endif
tf->tf_r[2] = stack;
tf->tf_r[31] = stack;
}
#ifdef DDB
int longformat = 1;
void
regdump(struct trapframe *f)
{
#define R(i) f->tf_r[i]
printf("R00-05: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
R(0),R(1),R(2),R(3),R(4),R(5));
printf("R06-11: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
R(6),R(7),R(8),R(9),R(10),R(11));
printf("R12-17: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
R(12),R(13),R(14),R(15),R(16),R(17));
printf("R18-23: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
R(18),R(19),R(20),R(21),R(22),R(23));
printf("R24-29: 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",
R(24),R(25),R(26),R(27),R(28),R(29));
printf("R30-31: 0x%08lx 0x%08lx\n",R(30),R(31));
#ifdef M88110
if (CPU_IS88110) {
printf("exip %lx enip %lx\n", f->tf_exip, f->tf_enip);
}
#endif
#ifdef M88100
if (CPU_IS88100) {
printf("sxip %lx snip %lx sfip %lx\n",
f->tf_sxip, f->tf_snip, f->tf_sfip);
}
if (CPU_IS88100 && ISSET(f->tf_dmt0, DMT_VALID)) {
printf("fault type %ld\n", (f->tf_dpfsr >> 16) & 0x7);
dae_print((u_int *)f);
}
if (CPU_IS88100 && longformat != 0) {
printf("fpsr %lx fpcr %lx epsr %lx ssbr %lx\n",
f->tf_fpsr, f->tf_fpcr, f->tf_epsr, f->tf_ssbr);
printf("fpecr %lx fphs1 %lx fpls1 %lx fphs2 %lx fpls2 %lx\n",
f->tf_fpecr, f->tf_fphs1, f->tf_fpls1,
f->tf_fphs2, f->tf_fpls2);
printf("fppt %lx fprh %lx fprl %lx fpit %lx\n",
f->tf_fppt, f->tf_fprh, f->tf_fprl, f->tf_fpit);
printf("vector %ld mask %lx flags %lx scratch1 %lx cpu %p\n",
f->tf_vector, f->tf_mask, f->tf_flags,
f->tf_scratch1, f->tf_cpu);
}
#endif
#ifdef M88110
if (CPU_IS88110 && longformat != 0) {
printf("fpsr %lx fpcr %lx fpecr %lx epsr %lx\n",
f->tf_fpsr, f->tf_fpcr, f->tf_fpecr, f->tf_epsr);
printf("dsap %lx duap %lx dsr %lx dlar %lx dpar %lx\n",
f->tf_dsap, f->tf_duap, f->tf_dsr, f->tf_dlar, f->tf_dpar);
printf("isap %lx iuap %lx isr %lx ilar %lx ipar %lx\n",
f->tf_isap, f->tf_iuap, f->tf_isr, f->tf_ilar, f->tf_ipar);
printf("vector %ld mask %lx flags %lx scratch1 %lx cpu %p\n",
f->tf_vector, f->tf_mask, f->tf_flags,
f->tf_scratch1, f->tf_cpu);
}
#endif
}
#endif
struct cpu_info *
set_cpu_number(cpuid_t number)
{
struct cpu_info *ci;
#ifdef MULTIPROCESSOR
ci = &m88k_cpus[number];
#else
ci = &m88k_cpus[0];
#endif
ci->ci_cpuid = number;
__asm__ volatile ("stcr %0, %%cr17" :: "r" (ci));
flush_pipeline();
return ci;
}
void
signotify(struct proc *p)
{
aston(p);
cpu_unidle(p->p_cpu);
}
#ifdef MULTIPROCESSOR
void
cpu_unidle(struct cpu_info *ci)
{
if (ci != curcpu())
m88k_send_ipi(CI_IPI_NOTIFY, ci->ci_cpuid);
}
#endif
void
need_resched(struct cpu_info *ci)
{
ci->ci_want_resched = 1;
if (ci->ci_curproc != NULL) {
aston(ci->ci_curproc);
if (ci != curcpu())
cpu_unidle(ci);
}
}
void dosoftint(int);
int softpending;
void
dosoftint(int sir)
{
int q, mask;
#ifdef MULTIPROCESSOR
__mp_lock(&kernel_lock);
#endif
for (q = NSOFTINTR - 1; q >= 0; q--) {
mask = 1 << q;
if (mask & sir)
softintr_dispatch(q);
}
#ifdef MULTIPROCESSOR
__mp_unlock(&kernel_lock);
#endif
}
void
softintr(int si)
{
atomic_setbits_int(&softpending, 1 << si);
}
int
spl0()
{
int sir;
int s;
if ((sir = atomic_clear_int(&softpending)) != 0) {
s = setipl(IPL_SOFTINT);
dosoftint(sir);
setipl(IPL_NONE);
} else
s = setipl(IPL_NONE);
return (s);
}
#define EMPTY_BR 0xc0000000
#define NO_OP 0xf4005800
#define BRANCH(FROM, TO) \
(EMPTY_BR | ((((vaddr_t)(TO) - (vaddr_t)(FROM)) >> 2) & 0x03ffffff))
#define SET_VECTOR_88100(NUM, VALUE) \
do { \
vbr[NUM].word_one = NO_OP; \
vbr[NUM].word_two = BRANCH(&vbr[NUM].word_two, VALUE); \
} while (0)
#define SET_VECTOR_88110(NUM, VALUE) \
do { \
vbr[NUM].word_one = BRANCH(&vbr[NUM].word_one, VALUE); \
vbr[NUM].word_two = NO_OP; \
} while (0)
void *
vector_init(m88k_exception_vector_area *vbr, u_int32_t *vector_init_list,
int bootstrap)
{
u_int num;
u_int32_t vec;
#ifdef M88110
if (CPU_IS88110) {
extern void m88110_sigsys(void);
extern void m88110_syscall_handler(void);
extern void m88110_cache_flush_handler(void);
extern void m88110_stepbpt(void);
extern void m88110_userbpt(void);
for (num = 0; (vec = vector_init_list[num]) != 0; num++)
SET_VECTOR_88110(num, vec);
if (bootstrap)
SET_VECTOR_88110(0x03, vector_init_list[num + 1]);
for (; num < 512; num++)
SET_VECTOR_88110(num, m88110_sigsys);
SET_VECTOR_88110(450, m88110_syscall_handler);
SET_VECTOR_88110(451, m88110_cache_flush_handler);
SET_VECTOR_88110(503, vector_init_list[8]);
SET_VECTOR_88110(504, m88110_stepbpt);
SET_VECTOR_88110(511, m88110_userbpt);
}
#endif
#ifdef M88100
if (CPU_IS88100) {
extern void sigsys(void);
extern void syscall_handler(void);
extern void cache_flush_handler(void);
extern void stepbpt(void);
extern void userbpt(void);
for (num = 0; (vec = vector_init_list[num]) != 0; num++)
SET_VECTOR_88100(num, vec);
if (bootstrap)
SET_VECTOR_88100(0x03, vector_init_list[num + 1]);
for (; num < 512; num++)
SET_VECTOR_88100(num, sigsys);
SET_VECTOR_88100(450, syscall_handler);
SET_VECTOR_88100(451, cache_flush_handler);
SET_VECTOR_88100(503, vector_init_list[8]);
SET_VECTOR_88100(504, stepbpt);
SET_VECTOR_88100(511, userbpt);
}
#endif
return vbr;
}
#ifdef MULTIPROCESSOR
void
atomic_init()
{
#if defined(M88100) && defined(M88110)
if (CPU_IS88100) {
extern uint32_t __atomic_lock[];
extern uint32_t __atomic_lock_88100[], __atomic_lock_88100_end[];
extern uint32_t __atomic_unlock[];
extern uint32_t __atomic_unlock_88100[], __atomic_unlock_88100_end[];
uint32_t *s, *e, *d;
d = __atomic_lock;
s = __atomic_lock_88100;
e = __atomic_lock_88100_end;
while (s != e)
*d++ = *s++;
d = __atomic_unlock;
s = __atomic_unlock_88100;
e = __atomic_unlock_88100_end;
while (s != e)
*d++ = *s++;
}
#endif
}
#endif