Exemple #1
0
void
sh_rtc_set(void *cookie, struct clock_ymdhms *dt)
{
	uint8_t r;

	/* stop clock */
	r = _reg_read_1(SH_(RCR2));
	r |= SH_RCR2_RESET;
	r &= ~SH_RCR2_START;
	_reg_write_1(SH_(RCR2), r);

	/* set time */
	if (CPU_IS_SH3)
		_reg_write_1(SH3_RYRCNT, TOBCD(dt->dt_year % 100));
	else
		_reg_write_2(SH4_RYRCNT, TOBCD(dt->dt_year % 100));
#define	RTCSET(x, y)	_reg_write_1(SH_(R ## x ## CNT), TOBCD(dt->dt_ ## y))
	RTCSET(MON, mon);
	RTCSET(WK, wday);
	RTCSET(DAY, day);
	RTCSET(HR, hour);
	RTCSET(MIN, min);
	RTCSET(SEC, sec);
#undef RTCSET
	/* start clock */
	_reg_write_1(SH_(RCR2), r | SH_RCR2_START);
}
Exemple #2
0
void
cpu_exit(struct proc *p)
{
	if (p->p_md.md_flags & MDP_STEP)
		_reg_write_2(SH_(BBRB), 0);

	pmap_deactivate(p);
	sched_exit(p);
}
/*
 * Jump to reset vector.
 */
void
cpu_reset()
{
	_cpu_exception_suspend();
	_reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);

#ifndef __lint__
	goto *(void *)0xa0000000;
#endif
	/* NOTREACHED */
}
void
machine_reset(void)
{
	_cpu_exception_suspend();
	_reg_write_4(SH_(EXPEVT), EXPEVT_RESET_MANUAL);
	(void)*(volatile uint32_t *)0x80000001;	/* CPU shutdown */

	/*NOTREACHED*/
	for (;;) {
		continue;
	}
}
Exemple #5
0
void
sh_rtc_get(void *cookie, time_t base, struct clock_ymdhms *dt)
{
	int retry = 8;

	/* disable carry interrupt */
	_reg_bclr_1(SH_(RCR1), SH_RCR1_CIE);

	do {
		uint8_t r = _reg_read_1(SH_(RCR1));
		r &= ~SH_RCR1_CF;
		r |= SH_RCR1_AF; /* don't clear alarm flag */
		_reg_write_1(SH_(RCR1), r);

		if (CPU_IS_SH3)
			dt->dt_year = FROMBCD(_reg_read_1(SH3_RYRCNT));
		else
			dt->dt_year = FROMBCD(_reg_read_2(SH4_RYRCNT) & 0x00ff);

		/* read counter */
#define	RTCGET(x, y)	dt->dt_ ## x = FROMBCD(_reg_read_1(SH_(R ## y ## CNT)))
		RTCGET(mon, MON);
		RTCGET(wday, WK);
		RTCGET(day, DAY);
		RTCGET(hour, HR);
		RTCGET(min, MIN);
		RTCGET(sec, SEC);
#undef RTCGET
	} while ((_reg_read_1(SH_(RCR1)) & SH_RCR1_CF) && --retry > 0);

	if (retry == 0) {
		printf("rtc_gettime: couldn't read RTC register.\n");
		memset(dt, 0, sizeof(*dt));
		return;
	}

	dt->dt_year = (dt->dt_year % 100) + 1900;
	if (dt->dt_year < 1970)
		dt->dt_year += 100;
}
Exemple #6
0
/*
 * Prepare context switch from oproc to nproc.
 * This code is used by cpu_switchto.
 */
void
cpu_switch_prepare(struct proc *oproc, struct proc *nproc)
{
	nproc->p_stat = SONPROC;

	if (oproc && (oproc->p_md.md_flags & MDP_STEP))
		_reg_write_2(SH_(BBRB), 0);

	curpcb = nproc->p_md.md_pcb;
	pmap_activate(nproc);

	if (nproc->p_md.md_flags & MDP_STEP) {
		int pm_asid = nproc->p_vmspace->vm_map.pmap->pm_asid;

		_reg_write_2(SH_(BBRB), 0);
		_reg_write_4(SH_(BARB), nproc->p_md.md_regs->tf_spc);
		_reg_write_1(SH_(BASRB), pm_asid);
		_reg_write_1(SH_(BAMRB), 0);
		_reg_write_2(SH_(BRCR), 0x0040);
		_reg_write_2(SH_(BBRB), 0x0014);
	}

	curproc = nproc;
}
Exemple #7
0
void
sh_tlb_set_asid(int asid)
{
	_reg_write_4(SH_(PTEH), asid);
}
Exemple #8
0
void
sh_rtc_init(void *cookie)
{
	/* Make sure to start RTC */
	_reg_write_1(SH_(RCR2), SH_RCR2_ENABLE | SH_RCR2_START);
}
Exemple #9
0
/*
 * Start the clock interrupt.
 */
void
cpu_initclocks()
{
	if (sh_clock.pclock == 0)
		panic("No PCLOCK information.");

	/* Set global variables. */
	hz = HZ;
	tick = 1000000 / hz;

	/*
	 * Use TMU channel 0 as hard clock
	 */
	_reg_bclr_1(SH_(TSTR), TSTR_STR0);

	if (sh_clock.flags & SH_CLOCK_NORTC) {
		/* use PCLOCK/16 as TMU0 source */
		_reg_write_2(SH_(TCR0), TCR_UNIE | TCR_TPSC_P16);
	} else {
		/* use RTC clock as TMU0 source */
		_reg_write_2(SH_(TCR0), TCR_UNIE |
		    (CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC));
	}
	sh_clock.hz_cnt = sh_clock.tmuclk / hz - 1;

	_reg_write_4(SH_(TCOR0), sh_clock.hz_cnt);
	_reg_write_4(SH_(TCNT0), sh_clock.hz_cnt);

	intc_intr_establish(SH_INTEVT_TMU0_TUNI0, IST_LEVEL, IPL_CLOCK,
	    CPU_IS_SH3 ? sh3_clock_intr : sh4_clock_intr, NULL, "clock");
	/* start hardclock */
	_reg_bset_1(SH_(TSTR), TSTR_STR0);

	/*
	 * TMU channel 1 is one shot timer for soft interrupts.
	 */
	_reg_write_2(SH_(TCR1), TCR_UNIE | TCR_TPSC_P4);
	_reg_write_4(SH_(TCOR1), 0xffffffff);

	/*
	 * TMU channel 2 is freerunning counter for timecounter.
	 */
	_reg_write_2(SH_(TCR2), TCR_TPSC_P4);
	_reg_write_4(SH_(TCOR2), 0xffffffff);

	/*
	 * Start and initialize timecounter.
	 */
	_reg_bset_1(SH_(TSTR), TSTR_STR2);

	sh_clock.tc.tc_get_timecount = sh_timecounter_get;
	sh_clock.tc.tc_frequency = sh_clock.pclock / 4;
	sh_clock.tc.tc_name = "tmu_pclock_4";
	sh_clock.tc.tc_quality = 100;
	sh_clock.tc.tc_counter_mask = 0xffffffff;
	tc_init(&sh_clock.tc);

	/* Make sure to start RTC */
	if (sh_clock.rtc.init != NULL)
		sh_clock.rtc.init(sh_clock.rtc._cookie);
}
Exemple #10
0
u_int
sh_timecounter_get(struct timecounter *tc)
{
	return 0xffffffff - _reg_read_4(SH_(TCNT2));
}
Exemple #11
0
void
sh_clock_init(int flags, struct rtc_ops *rtc)
{
	uint32_t s, t0, cnt_1s;

	sh_clock.flags = flags;
	if (rtc != NULL)
		sh_clock.rtc = *rtc;	/* structure copy */

	/* Initialize TMU */
	_reg_write_2(SH_(TCR0), 0);
	_reg_write_2(SH_(TCR1), 0);
	_reg_write_2(SH_(TCR2), 0);

	/* Reset RTC alarm and interrupt */
	_reg_write_1(SH_(RCR1), 0);

	/* Stop all counter */
	_reg_write_1(SH_(TSTR), 0);

	/*
	 * Estimate CPU clock.
	 */
	if (sh_clock.flags & SH_CLOCK_NORTC) {
		/* Set TMU channel 0 source to PCLOCK / 16 */
		_reg_write_2(SH_(TCR0), TCR_TPSC_P16);
		sh_clock.tmuclk = sh_clock.pclock / 16;
	} else {
		/* Set TMU channel 0 source to RTC counter clock (16.384kHz) */
		_reg_write_2(SH_(TCR0),
		    CPU_IS_SH3 ? SH3_TCR_TPSC_RTC : SH4_TCR_TPSC_RTC);
		sh_clock.tmuclk = SH_RTC_CLOCK;

		/* Make sure RTC oscillator is enabled */
		_reg_bset_1(SH_(RCR2), SH_RCR2_ENABLE);
	}

	s = _cpu_exception_suspend();
	_cpu_spin(1);	/* load function on cache. */
	TMU_START(0);
	_cpu_spin(10000000);
	t0 = TMU_ELAPSED(0);
	_cpu_exception_resume(s);

	sh_clock.cpucycle_1us = (sh_clock.tmuclk * 10) / t0;

	cnt_1s = ((uint64_t)sh_clock.tmuclk * 10000000 * 10 + t0 / 2) / t0;
	if (CPU_IS_SH4)
		sh_clock.cpuclock = cnt_1s / 2;	/* two-issue */
	else
		sh_clock.cpuclock = cnt_1s;

	/*
	 * Estimate PCLOCK
	 */
	if (sh_clock.pclock == 0) {
		uint32_t t1;

		/* set TMU channel 1 source to PCLOCK / 4 */
		_reg_write_2(SH_(TCR1), TCR_TPSC_P4);
		s = _cpu_exception_suspend();
		_cpu_spin(1);	/* load function on cache. */
		TMU_START(0);
		TMU_START(1);
		_cpu_spin(cnt_1s); /* 1 sec. */
		t0 = TMU_ELAPSED(0);
		t1 = TMU_ELAPSED(1);
		_cpu_exception_resume(s);

		sh_clock.pclock =
		    ((uint64_t)t1 * 4 * SH_RTC_CLOCK + t0 / 2) / t0;
	}

	/* Stop all counters */
	_reg_write_1(SH_(TSTR), 0);

#undef TMU_START
#undef TMU_ELAPSED
}
Exemple #12
0
void
sh_cpu_init(int arch, int product)
{
	/* CPU type */
	cpu_arch = arch;
	cpu_product = product;

#if defined(SH3) && defined(SH4)
	/* Set register addresses */
	sh_devreg_init();
#endif
	/* Cache access ops. */
	sh_cache_init();

	/* MMU access ops. */
	sh_mmu_init();

	/* Hardclock, RTC initialize. */
	machine_clock_init();

	/* ICU initiailze. */
	curcpu()->ci_idepth = -1;
	intc_init();

	/* Exception vector. */
	memcpy(VBR + 0x100, sh_vector_generic,
	    sh_vector_generic_end - sh_vector_generic);
#ifdef SH3
	if (CPU_IS_SH3)
		memcpy(VBR + 0x400, sh3_vector_tlbmiss,
		    sh3_vector_tlbmiss_end - sh3_vector_tlbmiss);
#endif
#ifdef SH4
	if (CPU_IS_SH4)
		memcpy(VBR + 0x400, sh4_vector_tlbmiss,
		    sh4_vector_tlbmiss_end - sh4_vector_tlbmiss);
#endif
	memcpy(VBR + 0x600, sh_vector_interrupt,
	    sh_vector_interrupt_end - sh_vector_interrupt);

	if (!SH_HAS_UNIFIED_CACHE)
		sh_icache_sync_all();

	__asm volatile("ldc %0, vbr" :: "r"(VBR));

	/* kernel stack setup */
	__sh_switch_resume = CPU_IS_SH3 ? sh3_switch_resume : sh4_switch_resume;

	/* Set page size (4KB) */
	uvm_setpagesize();

	/* setup UBC channel A for single-stepping */
#if defined(PTRACE) || defined(DDB)
	_reg_write_2(SH_(BBRA), 0); /* disable channel A */
	_reg_write_2(SH_(BBRB), 0); /* disable channel B */

#ifdef SH3
	if (CPU_IS_SH3) {
		/* A: break after execution, ignore ASID */
		_reg_write_4(SH3_BRCR, (UBC_CTL_A_AFTER_INSN
					| SH3_UBC_CTL_A_MASK_ASID));

		/* A: compare all address bits */
		_reg_write_4(SH3_BAMRA, 0x00000000);
	}
#endif	/* SH3 */

#ifdef SH4
	if (CPU_IS_SH4) {
		/* A: break after execution */
		_reg_write_2(SH4_BRCR, UBC_CTL_A_AFTER_INSN);

		/* A: compare all address bits, ignore ASID */
		_reg_write_1(SH4_BAMRA, SH4_UBC_MASK_NONE | SH4_UBC_MASK_ASID);
	}
#endif	/* SH4 */
#endif
}