On Dec 29, 2017, at 8:01 PM, BALATON Zoltan balaton@eik.bme.hu wrote:
I've tried to implement it the way I've suggested and came up with the patch below, but it does not seem to work. I think this is because the arithmetic in get-msec overflows and does not get the right values. Could it be it works in SLOF because that runs on 64bit? Or is something needed to tell Forth to use 64bit values on PPC32? Any ideas?
Regards, BALATON Zoltan
diff --git a/arch/ppc/qemu/init.c b/arch/ppc/qemu/init.c index b0c0cfc..4c8631a 100644 --- a/arch/ppc/qemu/init.c +++ b/arch/ppc/qemu/init.c @@ -793,6 +793,20 @@ static void adler32(void) RET(s2 << 16 | s1); }
+/*
- Get time base value from CPU
- */
+static void tb_fetch(void) +{
- unsigned long tbl, tbu;
I would change "unsigned long" to uint32_t.
- do {
tbu = mftbu();
tbl = mftb();
- } while (tbu != mftbu());
- DPUSH(((uint64_t)tbu << 32) | tbl);
I suspect this line is the problem. I had a lot of problems trying to do this exact bit operation. I gave up on it and instead did it another way. That patch was sent to the list.
+}
void arch_of_init(void) { @@ -1062,7 +1076,9 @@ arch_of_init(void)
/* Implementation of adler32 word (required by OS 9, BootX) */ bind_func("(adler32)", adler32);
- fword("fixup-tbfreq");
- bind_func("(tb@)", tb_fetch); bind_func("platform-boot", boot); bind_func("(arch-go)", arch_go);
} diff --git a/arch/ppc/qemu/qemu.fs b/arch/ppc/qemu/qemu.fs index d683421..1e3e0cb 100644 --- a/arch/ppc/qemu/qemu.fs +++ b/arch/ppc/qemu/qemu.fs @@ -139,3 +139,34 @@ variable keyboard-phandle 0 keyboard-phandle ! 3drop 0 then ;
+\ ------------------------------------------------------------------------- +\ time base related words +\ -------------------------------------------------------------------------
+1 value tb-frequency
+: fixup-tbfreq
- " /cpus/@0" find-device
- " timebase-frequency" active-package get-package-property IF
- 2drop
- ELSE
- decode-int to tb-frequency 2drop
- THEN
- device-end
+;
+: tb@ ( -- tbval)
- " (tb@)" $find if
- execute
- 20 lshift swap ffffffff and or
- else
- 2drop 0
- then
+;
+: get-msecs ( -- ms ) tb@ d# 1000 * tb-frequency / ; +: get-usecs ( -- us ) tb@ d# 1000000 * tb-frequency / ;
+: ms ( ms-to-wait -- ) get-msecs + BEGIN get-msecs over >= UNTIL drop ; +: us ( us-to-wait -- ) get-usecs + BEGIN get-usecs over >= UNTIL drop ; diff --git a/include/arch/ppc/processor.h b/include/arch/ppc/processor.h index bb03bb1..5e79ba8 100644 --- a/include/arch/ppc/processor.h +++ b/include/arch/ppc/processor.h @@ -462,6 +462,20 @@ static inline void slbmte(unsigned long rs, unsigned long rb) asm volatile("slbmte %0,%1 ; isync" :: "r" (rs), "r" (rb) : "memory"); }
I would replace all the "unsigned long" with uint32_t here.
+static inline unsigned long mftb(void) +{
- unsigned long val;
- asm volatile("mftb %0" : "=r" (val));
- return val;
+}
+static inline unsigned long mftbu(void) +{
- unsigned long val;
- asm volatile("mftbu %0" : "=r" (val));
- return val;
+}
#endif /* !__ASSEMBLER__ */
#endif /* _H_PROCESSOR */