Changeset 864 for trunk

Show
Ignore:
Timestamp:
12/23/09 02:10:17 (2 years ago)
Author:
reyalp
Message:

* Preliminary support for calling event procedures and arbitrary functions. See  http://chdk.wikia.com/wiki/LUA/LUA_Reference/Native_Function_Calls
* add support for byte and word access with peek and poke
* add lib/armutil/libarmutil.a for various arm code that doesn't belong elsewhere.
* move reverse_bytes_order lib/armutil

Location:
trunk
Files:
7 added
7 modified

Legend:

Unmodified
Added
Removed
  • trunk/buildconf.inc

    r851 r864  
    1212OPT_EDGEOVERLAY=1 
    1313OPT_LUA_STRLIB=1 
     14#allow Lua to call arbitrary ROM functions and eventprocs 
     15# WARNING: This is DANGEROUS. e.g. call_event_proc("EraseSectorOfRom",...) 
     16# NOTE: the interface for this may change in the future, to support better support buffers etc 
     17#OPT_LUA_CALL_NATIVE=1 
    1418#OPT_MD_DEBUG=1 
    1519# needs proper fi2.inc in platform/ !!! see http://chdk.setepontos.com/index.php/topic,2995.0.html 
  • trunk/core/Makefile

    r826 r864  
    5353CFLAGS+=-DOPT_MD_DEBUG 
    5454endif  
     55ifdef OPT_LUA_CALL_NATIVE 
     56CFLAGS+=-DOPT_LUA_CALL_NATIVE 
     57endif  
     58 
    5559OBJS=entry.o nothumb.o main.o gui_draw.o gui_menu.o gui_palette.o gui_mbox.o \ 
    5660     gui_fselect.o gui.o kbd.o conf.o \ 
     
    7680          $(topdir)lib/font/libfont.a $(topdir)lib/math/libmath.a \ 
    7781          $(topdir)lib/ubasic/libubasic.a $(topdir)lib/lang/liblang.a \ 
    78           $(topdir)lib/lua/liblua.a 
     82          $(topdir)lib/lua/liblua.a \ 
     83          $(topdir)lib/armutil/libarmutil.a 
    7984        @echo \-\> $@ 
    8085        $(CC) $(CFLAGS) -o $@ --start-group $^  $(LDLIBS) --end-group $(LDFLAGS) $(LDOPTS) 
  • trunk/core/luascript.c

    r847 r864  
    725725} 
    726726 
     727/* 
     728  val=peek(address[,size]) 
     729  return the value found at address in memory, or nil if address or size is invalid 
     730  size is optional 1=byte 2=halfword 4=word. defaults is 4 
     731*/ 
    727732static int luaCB_peek( lua_State* L ) 
    728733{ 
    729   int addr = (luaL_checknumber(L,1)); 
    730   // must be alligned 
    731   if (addr & 0x3) { 
    732         lua_pushnil(L); 
     734  unsigned addr = luaL_checknumber(L,1); 
     735  unsigned size = luaL_optnumber(L, 2, 4); 
     736  switch(size) { 
     737    case 1:  
     738      lua_pushnumber( L, *(unsigned char *)(addr) ); 
     739    break; 
     740    case 2: 
     741      if (addr & 0x1) { 
     742        lua_pushnil(L); 
     743      } 
     744      else { 
     745        lua_pushnumber( L, *(unsigned short *)(addr) ); 
     746      } 
     747    break; 
     748    case 4: 
     749      if (addr & 0x3) { 
     750        lua_pushnil(L); 
     751      } 
     752      else { 
     753        lua_pushnumber( L, *(unsigned *)(addr) ); 
     754      } 
     755    break; 
     756    default: 
     757      lua_pushnil(L); 
     758 
     759  } 
     760  return 1; 
     761} 
     762 
     763/* 
     764  status=poke(address,value[,size]) 
     765  writes value to address in memory 
     766  size is optional 1=byte 2=halfword 4=word. defaults is 4 
     767  returns true, or nil if address or size is invalid 
     768*/ 
     769static int luaCB_poke( lua_State* L ) 
     770{ 
     771  unsigned addr = luaL_checknumber(L,1); 
     772  unsigned val = luaL_checknumber(L,2); 
     773  unsigned size = luaL_optnumber(L, 3, 4); 
     774  int status = 0; 
     775  switch(size) { 
     776    case 1:  
     777        *(unsigned char *)(addr) = (unsigned char)val; 
     778        lua_pushboolean(L,1); 
     779        status=1; 
     780    break; 
     781    case 2: 
     782      if (!(addr & 0x1)) { 
     783        *(unsigned short *)(addr) = (unsigned short)val; 
     784        status=1; 
     785      } 
     786    break; 
     787    case 4: 
     788      if (!(addr & 0x3)) { 
     789        *(unsigned *)(addr) = val; 
     790        status=1; 
     791      } 
     792    break; 
     793  } 
     794  if(status) { 
     795    lua_pushboolean(L,1); 
    733796  } 
    734797  else { 
    735     lua_pushnumber( L, *(unsigned *)(addr) ); 
    736   } 
    737   return 1; 
    738 } 
    739  
    740 static int luaCB_poke( lua_State* L ) 
    741 { 
    742   int addr = (luaL_checknumber(L,1)); 
    743   int val = (luaL_checknumber(L,2)); 
    744   if (addr & 0x3) { 
    745         lua_pushnil(L); 
    746   } 
    747   else { 
    748     *(unsigned *)(addr) = val; 
    749     lua_pushboolean(L,1); 
     798    lua_pushnil(L); 
    750799  } 
    751800  return 1; 
     
    11061155  return 0; 
    11071156} 
     1157 
     1158/* 
     1159pack the lua args into a buffer to pass to the native code calling functions  
     1160currently only handles strings/numbers 
     1161start is the stack index of the first arg 
     1162*/ 
     1163#ifdef OPT_LUA_CALL_NATIVE 
     1164static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf) 
     1165{ 
     1166  unsigned i; 
     1167  unsigned end = lua_gettop(L); 
     1168 
     1169  for(i = start; i <= end; i++,argbuf++) { 
     1170    if (lua_type(L, i) == LUA_TSTRING) { 
     1171        *argbuf=(unsigned)lua_tostring( L, i); 
     1172    } 
     1173    else if (lua_type(L, i) == LUA_TNUMBER) { 
     1174        *argbuf=lua_tonumber( L, i); 
     1175    } 
     1176    else { 
     1177      return 0; 
     1178    } 
     1179  } 
     1180  return 1; 
     1181} 
     1182 
     1183/* 
     1184Native function call interface. Can be used to call canon eventprocs or arbitrary 
     1185pointers. 
     1186 
     1187NOTE: this is preliminary, interface may change in later versions! 
     1188All arguments must be strings or numbers. 
     1189If the function expects to modify it's arguments via a pointer, 
     1190then you must provide a number that is a valid pointer.  
     1191 
     1192You can use the "AllocateMemory" eventproc to obtain buffers. 
     1193 
     1194If the function tries to write to a string passed from lua, Bad Things may happen. 
     1195 
     1196This is potentially dangerous, functions exist which can destroy the onboard firmware. 
     1197*/ 
     1198 
     1199/* 
     1200result=call_func_ptr(ptr,...) 
     1201ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention. 
     1202result: R0 value after the call returns 
     1203NOTE: 
     1204lua does not correctly handle hex constants which would represent a negative number. 
     1205You must use the signed decimal value instead. 
     1206*/ 
     1207static int luaCB_call_func_ptr( lua_State* L) 
     1208{ 
     1209  unsigned *argbuf=NULL; 
     1210  unsigned i; 
     1211  unsigned n_args = lua_gettop(L)-1; 
     1212  void *fptr; 
     1213 
     1214  fptr=(void *)luaL_checknumber( L, 1 ); 
     1215 
     1216  if (n_args) { 
     1217    argbuf=malloc(n_args * 4); 
     1218    if(!argbuf) { 
     1219      return luaL_error( L, "malloc fail" ); 
     1220    } 
     1221    if(!pack_native_args(L, 2, argbuf)) { 
     1222      free(argbuf); 
     1223      return luaL_error( L, "expected string or number" ); 
     1224    } 
     1225  } 
     1226   
     1227  lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) ); 
     1228  free(argbuf); 
     1229  return 1; 
     1230} 
     1231 
     1232/*  
     1233Call an event procedure 
     1234 
     1235result=call_event_proc("EventprocName",...) 
     1236result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found,  
     1237or the eventproc return value (which could also be -1) 
     1238NOTE: 
     1239Many eventprocs are not registered by default, but can be loaded by calling another event proc 
     1240Some useful ones are 
     1241SystemEventInit 
     1242        includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ... 
     1243UI_RegistDebugEventProc 
     1244        includes capture mode functions, PTM_ functions and much more  
     1245RegisterProductTestEvent 
     1246        includes PT_ functions 
     1247 
     1248Others: 
     1249RegisterShootSeqEvent 
     1250RegisterNRTableEvent 
     1251*/ 
     1252 
     1253// grab from lowlevel 
     1254extern unsigned _ExecuteEventProcedure(const char *name,...); 
     1255static int luaCB_call_event_proc( lua_State* L ) 
     1256{ 
     1257  const char *evpname; 
     1258  unsigned *argbuf; 
     1259  unsigned i; 
     1260  unsigned n_args = lua_gettop(L); 
     1261 
     1262  evpname=luaL_checkstring( L, 1 ); 
     1263 
     1264  argbuf=malloc(n_args * 4); 
     1265  if (!argbuf) { 
     1266    return luaL_error( L, "malloc fail" ); 
     1267  } 
     1268 
     1269  // event proc name is first arg 
     1270  *argbuf = (unsigned)evpname; 
     1271   
     1272  if(!pack_native_args(L,2,argbuf+1)) { 
     1273    free(argbuf); 
     1274    return luaL_error( L, "expected string or number" ); 
     1275  } 
     1276   
     1277  lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) ); 
     1278  free(argbuf); 
     1279  return 1; 
     1280} 
     1281 
     1282#endif // OPT_LUA_CALL_NATIVE 
    11081283 
    11091284void register_lua_funcs( lua_State* L ) 
     
    12621437 
    12631438   FUNC(set_record); 
    1264 } 
     1439 
     1440#ifdef OPT_LUA_CALL_NATIVE 
     1441   FUNC(call_event_proc); 
     1442   FUNC(call_func_ptr); 
     1443#endif 
     1444} 
  • trunk/include/lolevel.h

    r838 r864  
    268268extern void _ScreenLock(); 
    269269extern void _SetCurrentCaptureModeType(); 
     270extern unsigned _ExecuteEventProcedure(const char *name,...); 
    270271// known in CHDK as _RefreshPhysicalScreen 
    271272//extern void _ScreenUnLock(); 
  • trunk/include/platform.h

    r847 r864  
    477477void SetScriptMode(unsigned mode); 
    478478 
     479/* 
     480 call C function with argument list created at runtime. 
     481 See lib/armutil/callfunc.S for documentation 
     482*/ 
     483unsigned call_func_ptr(void *func, const unsigned *args, unsigned n_args); 
     484 
    479485#define started() debug_led(1) 
    480486#define finished() debug_led(0) 
  • trunk/lib/Makefile

    r515 r864  
    22include $(topdir)makefile.inc 
    33 
    4 SUBDIRS=font math ubasic lang lua 
     4SUBDIRS=font math ubasic lang lua armutil 
    55 
    66include $(topdir)bottom.inc 
  • trunk/platform/generic/wrappers.c

    r847 r864  
    795795} 
    796796 
    797 void reverse_bytes_order(char* start, int count){ 
    798 // note, we will go to count rounded up to the nearest 32 
    799 asm volatile( 
    800         "ldr    r2, =0xFF00FF\n"        // r2 = mask 
    801         "add    r1, r0, r1\n"           // r1 = start + count 
    802 "LOOP:\n" 
    803         "ldm    r0, {R4-R11}\n"         // load 8 words 
    804          
    805         // out = ((in>>8) & 0xFF00FF) | ((in&0xFF00FF) << 8); 
    806         "mov    r3, r4, lsr #8\n"       // r3 = in >> 8 
    807         "and    r3, r3, r2\n"           // r3 &= 0xFF00FF 
    808         "and    r4, r4, r2\n"           // r4 = in & 0xFF00FF 
    809         "orr    r4, r3, r4, asl #8\n" // out = r3 | (r4 << 8) 
    810  
    811         "mov    r3, r5, lsr #8\n" 
    812         "and    r3, r3, r2\n" 
    813         "and    r5, r5, r2\n" 
    814         "orr    r5, r3, r5, asl #8\n" 
    815  
    816         "mov    r3, r6, lsr #8\n" 
    817         "and    r3, r3, r2\n" 
    818         "and    r6, r6, r2\n" 
    819         "orr    r6, r3, r6, asl #8\n" 
    820  
    821         "mov    r3, r7, lsr #8\n" 
    822         "and    r3, r3, r2\n" 
    823         "and    r7, r7, r2\n" 
    824         "orr    r7, r3, r7, asl #8\n" 
    825  
    826         "mov    r3, r8, lsr #8\n" 
    827         "and    r3, r3, r2\n" 
    828         "and    r8, r8, r2\n" 
    829         "orr    r8, r3, r8, asl #8\n" 
    830  
    831         "mov    r3, r9, lsr #8\n" 
    832         "and    r3, r3, r2\n" 
    833         "and    r9, r9, r2\n" 
    834         "orr    r9, r3, r9, asl #8\n" 
    835  
    836         "mov    r3, r10, lsr #8\n" 
    837         "and    r3, r3, r2\n" 
    838         "and    r10, r10, r2\n" 
    839         "orr    r10, r3, r10, asl #8\n" 
    840  
    841         "mov    r3, r11, lsr #8\n" 
    842         "and    r3, r3, r2\n" 
    843         "and    r11, r11, r2\n" 
    844         "orr    r11, r3, r11, asl #8\n" 
    845  
    846         "stmia  r0!, {r4-r11}\n"        // store and increment 
    847  
    848         "cmp    r0, r1\n" 
    849         "bcc    LOOP\n" 
    850         :::"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10","r11" 
    851  ); 
    852 } 
    853  
    854797#if defined (DNG_EXT_FROM) 
    855798