utils,proxy: Add basic SIMD register fetch and mutation support

Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
Hector Martin 2021-05-27 22:57:25 +09:00
parent 5d0f6e21f6
commit 77a36a7d34
7 changed files with 118 additions and 10 deletions

View file

@ -486,6 +486,8 @@ class M1N1Proxy:
P_VECTOR = 0x00b
P_GL1_CALL = 0x00c
P_GL2_CALL = 0x00d
P_GET_SIMD_STATE = 0x00e
P_PUT_SIMD_STATE = 0x00f
P_WRITE64 = 0x100
P_WRITE32 = 0x101
@ -698,6 +700,10 @@ class M1N1Proxy:
if len(args) > 4:
raise ValueError("Too many arguments")
return self.request(self.P_GL2_CALL, addr, *args)
def get_simd_state(self, buf):
self.request(self.P_GET_SIMD_STATE, buf)
def put_simd_state(self, buf):
self.request(self.P_PUT_SIMD_STATE, buf)
def write64(self, addr, data):
if addr & 7:

View file

@ -7,6 +7,12 @@ from malloc import Heap
import adt
from contextlib import contextmanager
SIMD_B = Array(32, Array(16, Int8ul))
SIMD_H = Array(32, Array(8, Int16ul))
SIMD_S = Array(32, Array(4, Int32ul))
SIMD_D = Array(32, Array(2, Int64ul))
SIMD_Q = Array(32, BytesInteger(16, swapped=True))
class ProxyUtils(object):
CODE_BUFFER_SIZE = 0x10000
def __init__(self, p, heap_size=1024 * 1024 * 1024):
@ -44,6 +50,10 @@ class ProxyUtils(object):
self.adt_data = None
self.adt = LazyADT(self)
self.simd_buf = self.malloc(32 * 16)
self.simd_type = None
self.simd = None
self.exec_modes = {
None: (self.proxy.call, REGION_RX_EL1),
"el2": (self.proxy.call, REGION_RX_EL1),
@ -208,6 +218,42 @@ class ProxyUtils(object):
finally:
self.proxy.mmu_restore(flags)
def push_simd(self):
if self.simd is not None:
data = self.simd_type.build(self.simd)
self.iface.writemem(self.simd_buf, data)
self.proxy.put_simd_state(self.simd_buf)
self.simd = self.simd_type = None
def get_simd(self, simd_type):
if self.simd is not None and self.simd_type is not simd_type:
data = self.simd_type.build(self.simd)
self.simd = simd_type.parse(data)
self.simd_type = simd_type
elif self.simd is None:
self.proxy.get_simd_state(self.simd_buf)
data = self.iface.readmem(self.simd_buf, 32 * 16)
self.simd = simd_type.parse(data)
self.simd_type = simd_type
return self.simd
@property
def b(self):
return self.get_simd(SIMD_B)
@property
def h(self):
return self.get_simd(SIMD_H)
@property
def s(self):
return self.get_simd(SIMD_S)
@property
def d(self):
return self.get_simd(SIMD_D)
@property
def q(self):
return self.get_simd(SIMD_Q)
class LazyADT:
def __init__(self, utils):
self.__dict__["_utils"] = utils

View file

@ -31,6 +31,14 @@ class HistoryConsole(code.InteractiveConsole):
type, value, tb = sys.exc_info()
traceback.print_exception(type, value, tb)
def runcode(self, code):
super().runcode(code)
if "mon" in self.locals:
self.locals["mon"].poll()
if "u" in self.locals:
self.locals["u"].push_simd()
class ExitConsole(SystemExit):
pass
@ -38,11 +46,6 @@ def run_shell(locals, msg=None, exitmsg=None):
saved_display = sys.displayhook
try:
def display(val):
try:
global mon
mon.poll()
except NameError:
pass
if isinstance(val, int):
builtins._ = val
print(hex(val))
@ -89,7 +92,7 @@ def run_shell(locals, msg=None, exitmsg=None):
if __name__ == "__main__":
from setup import *
locals = __main__.__dict__
locals = dict(__main__.__dict__)
from tgtypes import *

View file

@ -81,6 +81,10 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
reply->retval = el1_call((void *)request->args[0], request->args[1], request->args[2],
request->args[3], request->args[4]);
break;
case P_VECTOR:
next_stage.entry = (generic_func *)request->args[0];
memcpy(next_stage.args, &request->args[1], 4 * sizeof(u64));
return 1;
case P_GL1_CALL:
reply->retval = gl1_call((void *)request->args[0], request->args[1], request->args[2],
request->args[3], request->args[4]);
@ -89,10 +93,12 @@ int proxy_process(ProxyRequest *request, ProxyReply *reply)
reply->retval = gl2_call((void *)request->args[0], request->args[1], request->args[2],
request->args[3], request->args[4]);
break;
case P_VECTOR:
next_stage.entry = (generic_func *)request->args[0];
memcpy(next_stage.args, &request->args[1], 4 * sizeof(u64));
return 1;
case P_GET_SIMD_STATE:
get_simd_state((void *)request->args[0]);
break;
case P_PUT_SIMD_STATE:
put_simd_state((void *)request->args[0]);
break;
case P_WRITE64:
exc_guard = GUARD_SKIP;

View file

@ -20,6 +20,8 @@ typedef enum {
P_VECTOR,
P_GL1_CALL,
P_GL2_CALL,
P_GET_SIMD_STATE,
P_PUT_SIMD_STATE,
P_WRITE64 = 0x100, // Generic register functions
P_WRITE32,

View file

@ -355,6 +355,9 @@ void memcpy16(void *dst, void *src, size_t size);
void memset8(void *dst, u8 value, size_t size);
void memcpy8(void *dst, void *src, size_t size);
void get_simd_state(void *state);
void put_simd_state(void *state);
void hexdump(const void *d, size_t len);
void regdump(u64 addr, size_t len);
int sprintf(char *str, const char *fmt, ...);

View file

@ -93,3 +93,45 @@ memset8:
bne 1b
2:
ret
.globl get_simd_state
.type get_simd_state, @function
get_simd_state:
stp q0, q1, [x0], #32
stp q2, q3, [x0], #32
stp q4, q5, [x0], #32
stp q6, q7, [x0], #32
stp q8, q9, [x0], #32
stp q10, q11, [x0], #32
stp q12, q13, [x0], #32
stp q14, q15, [x0], #32
stp q16, q17, [x0], #32
stp q18, q19, [x0], #32
stp q20, q21, [x0], #32
stp q22, q23, [x0], #32
stp q24, q25, [x0], #32
stp q26, q27, [x0], #32
stp q28, q29, [x0], #32
stp q30, q31, [x0], #32
ret
.globl put_simd_state
.type put_simd_state, @function
put_simd_state:
ldp q0, q1, [x0], #32
ldp q2, q3, [x0], #32
ldp q4, q5, [x0], #32
ldp q6, q7, [x0], #32
ldp q8, q9, [x0], #32
ldp q10, q11, [x0], #32
ldp q12, q13, [x0], #32
ldp q14, q15, [x0], #32
ldp q16, q17, [x0], #32
ldp q18, q19, [x0], #32
ldp q20, q21, [x0], #32
ldp q22, q23, [x0], #32
ldp q24, q25, [x0], #32
ldp q26, q27, [x0], #32
ldp q28, q29, [x0], #32
ldp q30, q31, [x0], #32
ret