|  | /* Copyright (c) 2017 Hanhwi Jang | 
|  | * All rights reserved. | 
|  |  | 
|  | * Redistribution and use in source and binary forms, with or without | 
|  | * modification, are permitted provided that the following conditions are | 
|  | * met: redistributions of source code must retain the above copyright | 
|  | * notice, this list of conditions and the following disclaimer; | 
|  | * redistributions in binary form must reproduce the above copyright | 
|  | * notice, this list of conditions and the following disclaimer in the | 
|  | * documentation and/or other materials provided with the distribution; | 
|  | * neither the name of the copyright holders nor the names of its | 
|  | * contributors may be used to endorse or promote products derived from | 
|  | * this software without specific prior written permission. | 
|  |  | 
|  | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 
|  | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 
|  | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 
|  | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 
|  | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 
|  | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 
|  | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|  | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|  | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|  | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 
|  | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|  | * | 
|  | * Authors: Hanhwi Jang | 
|  | */ | 
|  |  | 
|  |  | 
|  | #include <assert.h> | 
|  | #include <lauxlib.h> | 
|  | #include <lua.h> | 
|  | #include <lualib.h> | 
|  | #include <stdlib.h> | 
|  |  | 
|  | #include <gem5/m5ops.h> | 
|  |  | 
|  | #include "m5_mmap.h" | 
|  |  | 
|  | static int | 
|  | do_arm(lua_State *L) | 
|  | { | 
|  | uint64_t address = lua_tointeger(L, 1); | 
|  | m5_arm(address); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_quiesce(lua_State *L) | 
|  | { | 
|  | m5_quiesce(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_quiesce_ns(lua_State *L) | 
|  | { | 
|  | uint64_t ns = lua_tointeger(L, 1); | 
|  | m5_quiesce_ns(ns); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_quiesce_cycle(lua_State *L) | 
|  | { | 
|  | uint64_t cycles = lua_tointeger(L, 1); | 
|  | m5_quiesce_cycle(cycles); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_quiesce_time(lua_State *L) | 
|  | { | 
|  | uint64_t ns = m5_quiesce_time(); | 
|  | lua_pushinteger(L, ns); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_rpns(lua_State *L) | 
|  | { | 
|  | uint64_t ns = m5_rpns(); | 
|  | lua_pushinteger(L, ns); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_wake_cpu(lua_State *L) | 
|  | { | 
|  | uint64_t cpuid = lua_tointeger(L, 1); | 
|  | m5_wake_cpu(cpuid); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_exit(lua_State *L) | 
|  | { | 
|  | uint64_t ns_delay = lua_tointeger(L, 1); | 
|  | m5_exit(ns_delay); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_fail(lua_State *L) | 
|  | { | 
|  | uint64_t ns_delay = lua_tointeger(L, 1); | 
|  | uint64_t code = lua_tointeger(L, 2); | 
|  | m5_fail(ns_delay, code); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_init_param(lua_State *L) | 
|  | { | 
|  | uint64_t key_str1 = lua_tointeger(L, 1); | 
|  | uint64_t key_str2 = lua_tointeger(L, 2); | 
|  | lua_pushinteger(L, m5_init_param(key_str1, key_str2)); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_checkpoint(lua_State *L) | 
|  | { | 
|  | uint64_t delay = lua_tointeger(L, 1); | 
|  | uint64_t period = lua_tointeger(L, 2); | 
|  | m5_checkpoint(delay, period); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_reset_stats(lua_State *L) | 
|  | { | 
|  | uint64_t ns_delay = lua_tointeger(L, 1); | 
|  | uint64_t ns_period = lua_tointeger(L, 2); | 
|  | m5_reset_stats(ns_delay, ns_period); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_dump_stats(lua_State *L) | 
|  | { | 
|  | uint64_t delay = lua_tointeger(L, 1); | 
|  | uint64_t period = lua_tointeger(L, 2); | 
|  | m5_dump_stats(delay, period); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_dump_reset_stats(lua_State *L) | 
|  | { | 
|  | uint64_t delay = lua_tointeger(L, 1); | 
|  | uint64_t period = lua_tointeger(L, 2); | 
|  | m5_dump_reset_stats(delay, period); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_read_file(lua_State *L) | 
|  | { | 
|  | uint64_t len = lua_tointeger(L, 1); | 
|  | uint64_t offset = lua_tointeger(L, 2); | 
|  | char *buf = malloc(len); | 
|  | uint64_t readlen = m5_read_file(buf, len, offset); | 
|  | lua_pushlstring(L, buf, readlen); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_write_file(lua_State *L) | 
|  | { | 
|  | const char* buf = lua_tostring(L, 1); | 
|  | uint64_t len = lua_tointeger(L, 2); | 
|  | assert(len <= lua_strlen(L, 1)); | 
|  | uint64_t offset = lua_tointeger(L, 3); | 
|  | const char *filename = lua_tostring(L, 4); | 
|  | uint64_t w_len = m5_write_file((void *)buf, len, offset, filename); | 
|  | lua_pushinteger(L, w_len); | 
|  | return 1; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_debug_break(lua_State *L) | 
|  | { | 
|  | m5_debug_break(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_switch_cpu(lua_State *L) | 
|  | { | 
|  | m5_switch_cpu(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_dist_toggle_sync(lua_State *L) | 
|  | { | 
|  | m5_dist_toggle_sync(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_add_symbol(lua_State *L) | 
|  | { | 
|  | uint64_t addr = lua_tointeger(L, 1); | 
|  | char *string = (char*) lua_tostring(L, 2); | 
|  | m5_add_symbol(addr, string); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_loadsymbol(lua_State *L) | 
|  | { | 
|  | m5_load_symbol(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_panic(lua_State *L) | 
|  | { | 
|  | m5_panic(); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_work_begin(lua_State *L) | 
|  | { | 
|  | uint64_t workid = lua_tointeger(L, 1); | 
|  | uint64_t threadid = lua_tointeger(L, 2); | 
|  | m5_work_begin(workid, threadid); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static int | 
|  | do_work_end(lua_State *L) | 
|  | { | 
|  | uint64_t workid = lua_tointeger(L, 1); | 
|  | uint64_t threadid = lua_tointeger(L, 2); | 
|  | m5_work_end(workid, threadid); | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | int | 
|  | luaopen_gem5OpLua(lua_State *L) | 
|  | { | 
|  | map_m5_mem(); | 
|  | #define ADD_FUNC(fname) do{                         \ | 
|  | lua_pushcfunction(L, fname);                \ | 
|  | lua_setfield(L, -2, #fname);                \ | 
|  | }while (0) | 
|  |  | 
|  | lua_newtable(L); | 
|  | ADD_FUNC(do_arm); | 
|  | ADD_FUNC(do_quiesce); | 
|  | ADD_FUNC(do_quiesce_ns); | 
|  | ADD_FUNC(do_quiesce_cycle); | 
|  | ADD_FUNC(do_quiesce_time); | 
|  | ADD_FUNC(do_rpns); | 
|  | ADD_FUNC(do_wake_cpu); | 
|  | ADD_FUNC(do_exit); | 
|  | ADD_FUNC(do_fail); | 
|  | ADD_FUNC(do_init_param); | 
|  | ADD_FUNC(do_checkpoint); | 
|  | ADD_FUNC(do_reset_stats); | 
|  | ADD_FUNC(do_dump_stats); | 
|  | ADD_FUNC(do_dump_reset_stats); | 
|  | ADD_FUNC(do_read_file); | 
|  | ADD_FUNC(do_write_file); | 
|  | ADD_FUNC(do_debug_break); | 
|  | ADD_FUNC(do_switch_cpu); | 
|  | ADD_FUNC(do_dist_toggle_sync); | 
|  | ADD_FUNC(do_add_symbol); | 
|  | ADD_FUNC(do_loadsymbol); | 
|  | ADD_FUNC(do_panic); | 
|  | ADD_FUNC(do_work_begin); | 
|  | ADD_FUNC(do_work_end); | 
|  | #undef ADD_FUNC | 
|  | return 1; | 
|  | } |