This patchset came out of the work from a following SPARC64 patchset and contains a basic SPARC64 timer implementation based upon the %tick register.
In addition to this, there is some extra refactoring to enable get-msecs to work across all platforms, and then finally a patch to use this to realise an implementation of the milliseconds CIF service.
Mark Cave-Ayland (5): SPARC64: fixup 100Hz timer interval SPARC64: increment ms counter at obp_tick_pointer on every timer interrupt SPARC64: add basic get-msecs implementation other.fs: rework get-msecs word so it can be shared cross-platform ciface.fs: implement milliseconds service
openbios-devel/arch/sparc64/entry.S | 2 +- openbios-devel/arch/sparc64/openbios.c | 6 ++++++ openbios-devel/arch/sparc64/vectors.S | 20 ++++++++++++++++++-- openbios-devel/forth/device/other.fs | 21 +++++++++------------ openbios-devel/forth/system/ciface.fs | 5 +++-- 5 files changed, 37 insertions(+), 17 deletions(-)
As we are attempting to emulate a 100MHz CPU, then in order to get a 100Hz timer interrupt the cycle interval needs to be 1MHz and not 10MHz.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/entry.S | 2 +- openbios-devel/arch/sparc64/vectors.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/openbios-devel/arch/sparc64/entry.S b/openbios-devel/arch/sparc64/entry.S index 33632b1..d03128a 100644 --- a/openbios-devel/arch/sparc64/entry.S +++ b/openbios-devel/arch/sparc64/entry.S @@ -17,7 +17,7 @@
#define PROM_ADDR 0x1fff0000000 #define CFG_ADDR 0x1fe02000510 -#define HZ 10 * 1000 * 1000 +#define HZ 1 * 1000 * 1000 #define TICK_INT_DIS 0x8000000000000000
.globl entry, _entry diff --git a/openbios-devel/arch/sparc64/vectors.S b/openbios-devel/arch/sparc64/vectors.S index 0e65475..600043a 100644 --- a/openbios-devel/arch/sparc64/vectors.S +++ b/openbios-devel/arch/sparc64/vectors.S @@ -30,7 +30,7 @@ #define PROM_ADDR 0x1fff0000000 #define SER_ADDR 0x1fe020003f8 #define TICK_INT_DIS 0x8000000000000000 -#define TICK_INTERVAL 10*1000*1000 +#define TICK_INTERVAL 1*1000*1000
.section ".text.vectors", "ax" .align 16384
This is in preparation for a get-ms implementation for SPARC64.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/vectors.S | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/openbios-devel/arch/sparc64/vectors.S b/openbios-devel/arch/sparc64/vectors.S index 600043a..927c1cd 100644 --- a/openbios-devel/arch/sparc64/vectors.S +++ b/openbios-devel/arch/sparc64/vectors.S @@ -276,7 +276,7 @@ tl1_resv1f0: BTRAPS(0x1f0) BTRAPS(0x1f8)
.section ".data" .align 8 - .globl tlb_handler_stack_top, tlb_handler_stack_pointer + .globl tlb_handler_stack_top, tlb_handler_stack_pointer, obp_ticks_pointer
! Stack for the tlb MMU trap handlers tlb_handler_stack_bottom: @@ -288,6 +288,10 @@ tlb_handler_stack_top: tlb_handler_stack_pointer: .xword tlb_handler_stack_top
+ ! Pointer to current tick value +obp_ticks_pointer: + .xword 0 + .section ".text", "ax"
spill_32bit: @@ -618,6 +622,18 @@ softint_irq: and %g1, %g2, %g1 brnz,pn %g1, tick_compare_disabled nop + + /* update tick value if pointer set */ + setx obp_ticks_pointer, %g3, %g1 + ldx [%g1], %g3 + brz %g3, tick_rearm + nop + + ldx [%g3], %g1 + add %g1, 10, %g1 ! 100Hz = 10ms + stx %g1, [%g3] + +tick_rearm: set TICK_INTERVAL, %g1 add %g1, %g2, %g1 wr %g1, 0, %tick_cmpr
This is currently based upon the %tick register, although at some point it should be moved to a per-CPU timer.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/arch/sparc64/openbios.c | 6 ++++++ openbios-devel/forth/device/other.fs | 12 ++++++------ 2 files changed, 12 insertions(+), 6 deletions(-)
diff --git a/openbios-devel/arch/sparc64/openbios.c b/openbios-devel/arch/sparc64/openbios.c index 7a76158..9ce3e53 100644 --- a/openbios-devel/arch/sparc64/openbios.c +++ b/openbios-devel/arch/sparc64/openbios.c @@ -561,6 +561,8 @@ static void init_memory(void) PUSH(virt + MEMORY_SIZE); }
+extern volatile uint64_t *obp_ticks_pointer; + static void arch_init( void ) { @@ -572,6 +574,10 @@ arch_init( void ) nvconf_init(); device_end();
+ /* Point to the Forth obp-ticks variable */ + fword("obp-ticks"); + obp_ticks_pointer = cell2pointer(POP()); + bind_func("platform-boot", boot ); bind_func("(go)", go); } diff --git a/openbios-devel/forth/device/other.fs b/openbios-devel/forth/device/other.fs index c033dfc..c67c829 100644 --- a/openbios-devel/forth/device/other.fs +++ b/openbios-devel/forth/device/other.fs @@ -93,21 +93,21 @@ defer (poke)
\ 5.3.7.3 Time
-[IFDEF] CONFIG_SPARC32 +[IFDEF] CONFIG_PPC
-\ OBP tick value updated by timer interrupt -variable obp-ticks +0 value dummy-msecs
: get-msecs ( -- n ) - obp-ticks @ + dummy-msecs dup 1+ to dummy-msecs ;
[ELSE]
-0 value dummy-msecs +\ OBP tick value updated by timer interrupt +variable obp-ticks
: get-msecs ( -- n ) - dummy-msecs dup 1+ to dummy-msecs + obp-ticks @ ;
[THEN]
Rather than mess with [IFDEF]s, just have one implementation which falls back to a simple incrementing dummy counter if a pointer to a real counter hasn't been configured.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/device/other.fs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/openbios-devel/forth/device/other.fs b/openbios-devel/forth/device/other.fs index c67c829..b390073 100644 --- a/openbios-devel/forth/device/other.fs +++ b/openbios-devel/forth/device/other.fs @@ -93,25 +93,22 @@ defer (poke)
\ 5.3.7.3 Time
-[IFDEF] CONFIG_PPC +\ Pointer to OBP tick value updated by timer interrupt +variable obp-ticks
+\ Dummy implementation for platforms without a timer interrupt 0 value dummy-msecs
: get-msecs ( -- n ) - dummy-msecs dup 1+ to dummy-msecs - ; - -[ELSE] - -\ OBP tick value updated by timer interrupt -variable obp-ticks - -: get-msecs ( -- n ) - obp-ticks @ + \ If obp-ticks pointer is set, use it. Otherwise fall back to + \ dummy implementation + obp-ticks @ 0<> if + obp-ticks @ + else + dummy-msecs dup 1+ to dummy-msecs + then ;
-[THEN] - : ms ( n -- ) get-msecs + begin dup get-msecs < until
Now that all platforms have at least some implementation of get-msecs we can just call it in order to implement the milliseconds service.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- openbios-devel/forth/system/ciface.fs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/openbios-devel/forth/system/ciface.fs b/openbios-devel/forth/system/ciface.fs index 727f0a3..1a2f5ee 100644 --- a/openbios-devel/forth/system/ciface.fs +++ b/openbios-devel/forth/system/ciface.fs @@ -296,8 +296,9 @@ external \ 6.3.2.7 Time \ -------------------------------------------------------------
-\ : milliseconds ( -- ms ) ; - +: milliseconds ( -- ms ) + get-msecs +;
\ ------------------------------------------------------------- \ arch?