[OpenBIOS] [PATCH] Add tbu@ and tbl@ words
Programmingkid
programmingkidx at gmail.com
Sat Dec 30 02:49:10 CET 2017
> On Dec 29, 2017, at 8:01 PM, BALATON Zoltan <balaton at 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 */
More information about the OpenBIOS
mailing list