These are particularly useful when accessing hardware registers from BE hosts.
Signed-off-by: Mark Cave-Ayland mark.cave-ayland@ilande.co.uk --- libopenbios/init.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+)
diff --git a/libopenbios/init.c b/libopenbios/init.c index aa99608..3ad9505 100644 --- a/libopenbios/init.c +++ b/libopenbios/init.c @@ -15,12 +15,56 @@ */
#include "config.h" +#include "libc/byteorder.h" #include "libopenbios/openbios.h" #include "libopenbios/bindings.h" #include "libopenbios/initprogram.h" #define NO_QEMU_PROTOS #include "arch/common/fw_cfg.h"
+ +/* + * le-w! ( w waddr -- ) + */ + +static void lewstore(void) +{ + u16 *aaddr = (u16 *)cell2pointer(POP()); + const u16 word = POP(); + *aaddr = __cpu_to_le16(word); +} + +/* + * le-l! ( quad qaddr -- ) + */ + +static void lelstore(void) +{ + u32 *aaddr = (u32 *)cell2pointer(POP()); + const u32 longval = POP(); + *aaddr = __cpu_to_le32(longval); +} + +/* + * le-w@ ( waddr -- w ) + */ + +static void lewfetch(void) +{ + const u16 *aaddr = (u16 *)cell2pointer(POP()); + PUSH(__le16_to_cpu(*aaddr)); +} + +/* + * le-l@ ( qaddr -- quad ) + */ + +static void lelfetch(void) +{ + const u32 *aaddr = (u32 *)cell2pointer(POP()); + PUSH(__le32_to_cpu(*aaddr)); +} + void openbios_init( void ) { @@ -36,4 +80,10 @@ openbios_init( void ) // Bind the C implementation of (go) into Forth bind_func("(go)", go); + + // Bind the LE access words + bind_func("le-w!", lewstore); + bind_func("le-l!", lelstore); + bind_func("le-w@", lewfetch); + bind_func("le-l@", lelfetch); }