[OpenBIOS] [PATCH] Tick counter

Olivier Danet odanet at caramail.com
Tue Feb 11 01:43:38 CET 2014


On 10/02/2014 02:25, Mark Cave-Ayland wrote:
> On 09/02/14 17:24, Olivier Danet wrote:
>> ---------------------------------------------------------------
>
> Hi Olivier,
>
> The basic patch looks like it's a good starting point, however if use 
> the QEMU gdbstub to set a breakpoint on irq_entry14 for the timer 
> interrupt then it never triggers whilst in OpenBIOS.
>
> If I let the boot continue into the Solaris kernel then it does break 
> eventually, which makes me think that the timer initialisation in 
> ob_interrupt_init() needs some extra modifications.
>
> Can you double-check your complete patchset and confirm whether or not 
> there are any changes to the timer mask registers at all?
>
>
> ATB,
>
> Mark.
>

I had tested with NextSTEP, which, afaik, is the only user of this damn 
counter...

In OpenBIOS, the CPU "PSR.PIL" register masked all interrupts.
Here is a version which enable the interrupt level 14, used by the timer.
It is not optimal because the psr_get/set functions are also declared in
arch/sparc32/psr.h, maybe it should be moved to include/arch/sparc32...


Index: arch/sparc32/romvec.c
===================================================================
--- arch/sparc32/romvec.c    (révision 1260)
+++ arch/sparc32/romvec.c    (copie de travail)
@@ -479,6 +479,7 @@
      romvec0.pv_reboot = obp_reboot_handler;
      romvec0.pv_printf = obp_printf_handler;
      romvec0.pv_abort = obp_abort_handler;
+    romvec0.pv_ticks = &obp_ticks;
      romvec0.pv_halt = obp_halt_handler;
      romvec0.pv_synchook = &sync_hook;
      romvec0.pv_v0bootargs = &obp_argp;
Index: arch/sparc32/vectors.S
===================================================================
--- arch/sparc32/vectors.S    (révision 1260)
+++ arch/sparc32/vectors.S    (copie de travail)
@@ -207,6 +207,10 @@
          sethi   %hi(counter_regs), %l7
          ld      [%l7 + %lo(counter_regs)], %l7
          ld      [%l7], %g0
+        sethi   %hi(obp_ticks), %l7
+        ld      [%l7 + %lo(obp_ticks)], %l6
+        add     %l6, 10, %l6
+        st      %l6, [%l7 + %lo(obp_ticks)]
          jmp     %l1
           rett  %l2

Index: drivers/obio.c
===================================================================
--- drivers/obio.c    (révision 1260)
+++ drivers/obio.c    (copie de travail)
@@ -34,6 +34,33 @@
   */
  #define SUN4M_NCPU      4

+static __inline__ unsigned int get_psr(void)
+{
+    unsigned int psr;
+    __asm__ __volatile__(
+        "rd    %%psr, %0\n\t"
+        "nop\n\t"
+        "nop\n\t"
+        "nop\n\t"
+    : "=r" (psr)
+    : /* no inputs */
+    : "memory");
+
+    return psr;
+}
+
+static __inline__ void put_psr(unsigned int new_psr)
+{
+    __asm__ __volatile__(
+        "wr    %0, 0x0, %%psr\n\t"
+        "nop\n\t"
+        "nop\n\t"
+        "nop\n\t"
+    : /* no outputs */
+    : "r" (new_psr)
+    : "memory", "cc");
+}
+
  /* DECLARE data structures for the nodes.  */
  DECLARE_UNNAMED_NODE( ob_obio, INSTALL_OPEN, sizeof(int) );

@@ -261,10 +288,13 @@

  volatile struct sun4m_timer_regs *counter_regs;

+volatile int32_t obp_ticks;
+
  static void
  ob_counter_init(uint64_t base, unsigned long offset)
  {
      int i;
+    uint32_t psr;

      ob_new_obio_device("counter", NULL);

@@ -294,12 +324,18 @@
      fword("property");


+    obp_ticks = 0;
+
      counter_regs = (struct sun4m_timer_regs *)ofmem_map_io(base + 
(uint64_t)offset, sizeof(*counter_regs));
-    counter_regs->cfg = 0xffffffff;
+    counter_regs->cfg = 0xfffffffe;
      counter_regs->l10_timer_limit = 0;
      counter_regs->cpu_timers[0].l14_timer_limit = 0x9c4000; /* see 
comment in obio.h */
      counter_regs->cpu_timers[0].cntrl = 1;

+    psr=get_psr();
+    psr=(psr & ~0xF00) | (13 << 8); /* Enable CPU timer interrupt 
(level 14) */
+    put_psr(psr);
+
      for (i = 0; i < SUN4M_NCPU; i++) {
          PUSH((unsigned long)&counter_regs->cpu_timers[i]);
          fword("encode-int");
Index: drivers/obio.h
===================================================================
--- drivers/obio.h    (révision 1260)
+++ drivers/obio.h    (copie de travail)
@@ -88,7 +88,7 @@
   * Registers of hardware timer in sun4m.
   */
  struct sun4m_timer_percpu {
-    volatile unsigned int l14_timer_limit; /* Initial value is 
0x009c4000 */
+    volatile unsigned int l14_timer_limit; /* Initial value is 
0x009c4000 = 10ms period */
      volatile unsigned int l14_cur_count;
  };

Index: include/drivers/drivers.h
===================================================================
--- include/drivers/drivers.h    (révision 1260)
+++ include/drivers/drivers.h    (copie de travail)
@@ -81,6 +81,7 @@
  extern volatile unsigned char *power_reg;
  extern volatile unsigned int *reset_reg;
  extern volatile struct sun4m_timer_regs *counter_regs;
+extern volatile int32_t obp_ticks;

  void ob_new_obio_device(const char *name, const char *type);
  unsigned long ob_reg(uint64_t base, uint64_t offset, unsigned long 
size, int map);
===================================================================








More information about the OpenBIOS mailing list