Port-sparc64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: Using %stick where available
Hello,
>>> Michael <macallan%netbsd.org@localhost> wrote
> Hello,
>
> On Nov 7, 2012, at 7:04 AM, Takeshi Nakayama wrote:
>
> >>>> Michael <macallan%netbsd.org@localhost> wrote
> >
> >> Hello,
> >>
> >> the attached patch adds support for the system timer interrupt
> >> present
> >> in UltraSPARC-III and some later II ( like IIe and IIi with on chip
> >> ecache ). It hasn't seen much testing beyond 'works on my Blade
> >> 2500'.
> >> The purpose is to have a timer interrupt / time counter that's
> >> independent of the CPU's clock rate, so we can change it without
> >> worrying about time keeping.
> >
> > It looks ok to me, but as Eric reported it needs some fix.
>
> Yeah, I have no US-IIe hardware so I couldn't test it there, which is
> one of the reasons why I posted the patch here first.
>
> >> + struct cpu_info *ci = curcpu();
> >
> > Replace the following curcpu()s with ci.
>
> Done.
Thanks, but there are some left.
> > I think the following is better for consistency.
> >
> > - long clk;
> > + long clk, sclk;
>
> Yeah, I left it an int because that's what we get from the PROM, but
> you're right, they should be the same type.
>
> >> + sclk = prom_getpropint(findroot(), "stick-frequency", 0);
> >> + ci->ci_system_clockrate[0] = sclk;
> >> + ci->ci_system_clockrate[1] = sclk / 1000000;
> >
> > US-IIe has system tick register, but its implementation is
> > different to US-III one. It can be used via memory mapped system
> > registers, not via ancillary state register (%asr24).
>
> Seriously?
> I expected trouble with US-IIe but not quite like that.
They are described in section 2.3 and 4.3.4 in "UltraSPARC IIe
Processor User's Manual". 64-bit stick register is splited to two
32-bit registers, so using it is more complex.
> > So, I suggest not to use it on US-IIe as below.
> >
> > if (!CPU_IS_HUMMINGBIRD()) {
> > sclk = prom_getpropint(findroot(), "stick-frequency", 0);
> > ci->ci_system_clockrate[0] = sclk;
> > ci->ci_system_clockrate[1] = sclk / 1000000;
> > }
>
> Done, slightly changed to make sure ci_system_clockrate[] is 0 if we
> don't have %stick.
cpu_info structure is zero cleared in alloc_cpuinfo(), but yes
it's more readable to clear it explicitly.
> Attached is the revised patch, thanks for looking at this!
You're welcome. I wrote one more comment, please see below.
> Index: sparc64/clock.c
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/clock.c,v
> retrieving revision 1.106
> diff -u -w -r1.106 clock.c
> --- sparc64/clock.c 4 Sep 2011 12:17:46 -0000 1.106
> +++ sparc64/clock.c 7 Nov 2012 17:26:58 -0000
(snip)
> @@ -338,6 +378,7 @@
> void
> cpu_initclocks(void)
> {
> + struct cpu_info *ci = curcpu();
> #ifndef MULTIPROCESSOR
> int statint, minint;
> #endif
> @@ -361,17 +402,24 @@
> }
>
> /* Make sure we have a sane cpu_clockrate -- we'll need it */
> - if (!curcpu()->ci_cpu_clockrate[0]) {
> + if (!ci->ci_cpu_clockrate[0]) {
> /* Default to 200MHz clock XXXXX */
> - curcpu()->ci_cpu_clockrate[0] = 200000000;
> - curcpu()->ci_cpu_clockrate[1] = 200000000 / 1000000;
> + ci->ci_cpu_clockrate[0] = 200000000;
> + ci->ci_cpu_clockrate[1] = 200000000 / 1000000;
> }
>
> /* Initialize the %tick register */
> settick(0);
>
> + if (ci->ci_system_clockrate[0] == 0) {
> tick_timecounter.tc_frequency = curcpu()->ci_cpu_clockrate[0];
~~~~~~~~
> tc_init(&tick_timecounter);
> + } else {
> + setstick(0);
> + stick_timecounter.tc_frequency =
> + ci->ci_system_clockrate[0];
> + tc_init(&stick_timecounter);
> + }
>
> /*
> * Now handle machines w/o counter-timers.
> @@ -379,13 +427,21 @@
>
> if (!timerreg_4u.t_timer || !timerreg_4u.t_clrintr) {
>
> - aprint_normal("No counter-timer -- using %%tick at %luMHz as "
> - "system clock.\n",
> + if (ci->ci_system_clockrate[0] == 0) {
> + aprint_normal("No counter-timer -- using %%tick "
> + "at %luMHz as system clock.\n",
> (unsigned long)curcpu()->ci_cpu_clockrate[1]);
~~~~~~~~
>
> /* We don't have a counter-timer -- use %tick */
> tickintr_establish(PIL_CLOCK, tickintr);
> + } else {
> + aprint_normal("No counter-timer -- using %%stick "
> + "at %luMHz as system clock.\n",
> + (unsigned long)ci->ci_system_clockrate[1]);
>
> + /* We don't have a counter-timer -- use %stick */
> + stickintr_establish(PIL_CLOCK, stickintr);
> + }
> /* We only have one timer so we have no statclock */
> stathz = 0;
>
(snip)
> Index: sparc64/locore.s
> ===================================================================
> RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/locore.s,v
> retrieving revision 1.341
> diff -u -w -r1.341 locore.s
> --- sparc64/locore.s 17 Mar 2012 22:19:53 -0000 1.341
> +++ sparc64/locore.s 7 Nov 2012 17:26:59 -0000
> @@ -3270,13 +3270,18 @@
> wrpr %g0, PSTATE_KERN|PSTATE_IG, %pstate ! DEBUG
> #endif
> /*
> - * If this is a %tick softint, clear it then call interrupt_vector.
> + * If this is a %tick or %stick softint, clear it then call
> + * interrupt_vector. Only one of them should be enabled at any given
> + * time.
> */
> rd SOFTINT, %g1
> - btst 1, %g1
> + mov 1, %g5
> + sllx %g5, 16, %g3
> + or %g5, %g3, %g5
Only "set 0x1001, %g5" is faster.
> + andcc %g5, %g1, %g5
> bz,pt %icc, 0f
> sethi %hi(CPUINFO_VA+CI_TICK_IH), %g3
> - wr %g0, 1, CLEAR_SOFTINT
> + wr %g0, %g5, CLEAR_SOFTINT
> ba,pt %icc, setup_sparcintr
> LDPTR [%g3 + %lo(CPUINFO_VA+CI_TICK_IH)], %g5
> 0:
(snip)
-- Takeshi Nakayama
Home |
Main Index |
Thread Index |
Old Index