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.
This commit is contained in:
Dave Hylands 2015-12-13 16:11:20 -08:00 committed by Paul Sokolovsky
parent acaccb37ec
commit 755b01439b
4 changed files with 40 additions and 15 deletions

View File

@ -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;

View File

@ -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__

View File

@ -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) },

View File

@ -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).