From 755b01439bab486d3ccb3c6eddccd10aae045f23 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Sun, 13 Dec 2015 16:11:20 -0800 Subject: [PATCH] unix: machine_mem improvements This basically introduces the MICROPY_MACHINE_MEM_GET_READ_ADDR and MICROPY_MACHINE_MEM_GET_WRITE_ADDR macros. If one of them is not defined, then a default identity function is provided. --- extmod/machine_mem.c | 30 ++++++++++++++++++++++++++++-- extmod/machine_mem.h | 17 +++++++++-------- unix/modmachine.c | 6 +----- unix/mpconfigport.h | 2 ++ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index 634ef2f6b5..2c09d752d4 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -25,9 +25,35 @@ */ #include "extmod/machine_mem.h" +#include "py/nlr.h" #if MICROPY_PY_MACHINE +// If you wish to override the functions for mapping the machine_mem read/write +// address, then add a #define for MICROPY_MACHINE_MEM_GET_READ_ADDR and/or +// MICROPY_MACHINE_MEM_GET_WRITE_ADDR in yopur mpconfigport.h. Since the +// prototypes are identical, it is allowable for both of the macros to evaluate +// the to same function. +// +// It is expected that the modmachine.c file for a given port will provide the +// implementations, if the default implementation isn't used. + +#if !defined(MICROPY_MACHINE_MEM_GET_READ_ADDR) || !defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR) +STATIC uintptr_t machine_mem_get_addr(mp_obj_t addr_o, uint align) { + uintptr_t addr = mp_obj_int_get_truncated(addr_o); + if ((addr & (align - 1)) != 0) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align)); + } + return addr; +} +#if !defined(MICROPY_MACHINE_MEM_GET_READ_ADDR) +#define MICROPY_MACHINE_MEM_GET_READ_ADDR machine_mem_get_addr +#endif +#if !defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR) +#define MICROPY_MACHINE_MEM_GET_WRITE_ADDR machine_mem_get_addr +#endif +#endif + STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { (void)kind; machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in); @@ -42,7 +68,7 @@ STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t va return MP_OBJ_NULL; // op not supported } else if (value == MP_OBJ_SENTINEL) { // load - uintptr_t addr = machine_mem_get_read_addr(index, self->elem_size); + uintptr_t addr = MICROPY_MACHINE_MEM_GET_READ_ADDR(index, self->elem_size); uint32_t val; switch (self->elem_size) { case 1: val = (*(uint8_t*)addr); break; @@ -52,7 +78,7 @@ STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t va return mp_obj_new_int(val); } else { // store - uintptr_t addr = machine_mem_get_write_addr(index, self->elem_size); + uintptr_t addr = MICROPY_MACHINE_MEM_GET_WRITE_ADDR(index, self->elem_size); uint32_t val = mp_obj_get_int(value); switch (self->elem_size) { case 1: (*(uint8_t*)addr) = val; break; diff --git a/extmod/machine_mem.h b/extmod/machine_mem.h index aeac0c2a25..fddd7d46c1 100644 --- a/extmod/machine_mem.h +++ b/extmod/machine_mem.h @@ -25,8 +25,8 @@ */ -#ifndef MICROPY_EXTMOD_MACHINE_MEM -#define MICROPY_EXTMOD_MACHINE_MEM +#ifndef __MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H__ +#define __MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H__ #include "py/obj.h" @@ -41,10 +41,11 @@ extern const machine_mem_obj_t machine_mem8_obj; extern const machine_mem_obj_t machine_mem16_obj; extern const machine_mem_obj_t machine_mem32_obj; -// It is expected that a port will provide the following 2 functions. -// We define the prototypes here, but the modmachine.c file for a port should -// provide the implementation -uintptr_t machine_mem_get_read_addr(mp_obj_t addr_o, uint align); -uintptr_t machine_mem_get_write_addr(mp_obj_t addr_o, uint align); +#if defined(MICROPY_MACHINE_MEM_GET_READ_ADDR) +uintptr_t MICROPY_MACHINE_MEM_GET_READ_ADDR(mp_obj_t addr_o, uint align); +#endif +#if defined(MICROPY_MACHINE_MEM_GET_WRITE_ADDR) +uintptr_t MICROPY_MACHINE_MEM_GET_WRITE_ADDR(mp_obj_t addr_o, uint align); +#endif -#endif /* MICROPY_EXTMOD_MACHINE_MEM */ +#endif // __MICROPY_INCLUDED_EXTMOD_MACHINE_MEM_H__ diff --git a/unix/modmachine.c b/unix/modmachine.c index 6039ddfd3d..5c032c3466 100644 --- a/unix/modmachine.c +++ b/unix/modmachine.c @@ -42,7 +42,7 @@ #if MICROPY_PY_MACHINE -uintptr_t machine_mem_get_read_addr(mp_obj_t addr_o, uint align) { +uintptr_t mod_machine_mem_get_addr(mp_obj_t addr_o, uint align) { uintptr_t addr = mp_obj_int_get_truncated(addr_o); if ((addr & (align - 1)) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align)); @@ -72,10 +72,6 @@ uintptr_t machine_mem_get_read_addr(mp_obj_t addr_o, uint align) { return addr; } -uintptr_t machine_mem_get_write_addr(mp_obj_t addr_o, uint align) { - return machine_mem_get_read_addr(addr_o, align); -} - STATIC const mp_rom_map_elem_t machine_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) }, diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h index e2016317db..a20f1c5094 100644 --- a/unix/mpconfigport.h +++ b/unix/mpconfigport.h @@ -108,6 +108,8 @@ #define MICROPY_PY_USELECT (1) #endif #define MICROPY_PY_MACHINE (1) +#define MICROPY_MACHINE_MEM_GET_READ_ADDR mod_machine_mem_get_addr +#define MICROPY_MACHINE_MEM_GET_WRITE_ADDR mod_machine_mem_get_addr // Define to MICROPY_ERROR_REPORTING_DETAILED to get function, etc. // names in exception messages (may require more RAM).