mirror of
https://github.com/AsahiLinux/m1n1
synced 2025-02-16 21:58:27 +00:00
utils,proxy: Add basic SIMD register fetch and mutation support
Signed-off-by: Hector Martin <marcan@marcan.st>
This commit is contained in:
parent
5d0f6e21f6
commit
77a36a7d34
7 changed files with 118 additions and 10 deletions
|
@ -486,6 +486,8 @@ class M1N1Proxy:
|
||||||
P_VECTOR = 0x00b
|
P_VECTOR = 0x00b
|
||||||
P_GL1_CALL = 0x00c
|
P_GL1_CALL = 0x00c
|
||||||
P_GL2_CALL = 0x00d
|
P_GL2_CALL = 0x00d
|
||||||
|
P_GET_SIMD_STATE = 0x00e
|
||||||
|
P_PUT_SIMD_STATE = 0x00f
|
||||||
|
|
||||||
P_WRITE64 = 0x100
|
P_WRITE64 = 0x100
|
||||||
P_WRITE32 = 0x101
|
P_WRITE32 = 0x101
|
||||||
|
@ -698,6 +700,10 @@ class M1N1Proxy:
|
||||||
if len(args) > 4:
|
if len(args) > 4:
|
||||||
raise ValueError("Too many arguments")
|
raise ValueError("Too many arguments")
|
||||||
return self.request(self.P_GL2_CALL, addr, *args)
|
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):
|
def write64(self, addr, data):
|
||||||
if addr & 7:
|
if addr & 7:
|
||||||
|
|
|
@ -7,6 +7,12 @@ from malloc import Heap
|
||||||
import adt
|
import adt
|
||||||
from contextlib import contextmanager
|
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):
|
class ProxyUtils(object):
|
||||||
CODE_BUFFER_SIZE = 0x10000
|
CODE_BUFFER_SIZE = 0x10000
|
||||||
def __init__(self, p, heap_size=1024 * 1024 * 1024):
|
def __init__(self, p, heap_size=1024 * 1024 * 1024):
|
||||||
|
@ -44,6 +50,10 @@ class ProxyUtils(object):
|
||||||
self.adt_data = None
|
self.adt_data = None
|
||||||
self.adt = LazyADT(self)
|
self.adt = LazyADT(self)
|
||||||
|
|
||||||
|
self.simd_buf = self.malloc(32 * 16)
|
||||||
|
self.simd_type = None
|
||||||
|
self.simd = None
|
||||||
|
|
||||||
self.exec_modes = {
|
self.exec_modes = {
|
||||||
None: (self.proxy.call, REGION_RX_EL1),
|
None: (self.proxy.call, REGION_RX_EL1),
|
||||||
"el2": (self.proxy.call, REGION_RX_EL1),
|
"el2": (self.proxy.call, REGION_RX_EL1),
|
||||||
|
@ -208,6 +218,42 @@ class ProxyUtils(object):
|
||||||
finally:
|
finally:
|
||||||
self.proxy.mmu_restore(flags)
|
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:
|
class LazyADT:
|
||||||
def __init__(self, utils):
|
def __init__(self, utils):
|
||||||
self.__dict__["_utils"] = utils
|
self.__dict__["_utils"] = utils
|
||||||
|
|
|
@ -31,6 +31,14 @@ class HistoryConsole(code.InteractiveConsole):
|
||||||
type, value, tb = sys.exc_info()
|
type, value, tb = sys.exc_info()
|
||||||
traceback.print_exception(type, value, tb)
|
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):
|
class ExitConsole(SystemExit):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -38,11 +46,6 @@ def run_shell(locals, msg=None, exitmsg=None):
|
||||||
saved_display = sys.displayhook
|
saved_display = sys.displayhook
|
||||||
try:
|
try:
|
||||||
def display(val):
|
def display(val):
|
||||||
try:
|
|
||||||
global mon
|
|
||||||
mon.poll()
|
|
||||||
except NameError:
|
|
||||||
pass
|
|
||||||
if isinstance(val, int):
|
if isinstance(val, int):
|
||||||
builtins._ = val
|
builtins._ = val
|
||||||
print(hex(val))
|
print(hex(val))
|
||||||
|
@ -89,7 +92,7 @@ def run_shell(locals, msg=None, exitmsg=None):
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from setup import *
|
from setup import *
|
||||||
locals = __main__.__dict__
|
locals = dict(__main__.__dict__)
|
||||||
|
|
||||||
from tgtypes import *
|
from tgtypes import *
|
||||||
|
|
||||||
|
|
14
src/proxy.c
14
src/proxy.c
|
@ -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],
|
reply->retval = el1_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
request->args[3], request->args[4]);
|
request->args[3], request->args[4]);
|
||||||
break;
|
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:
|
case P_GL1_CALL:
|
||||||
reply->retval = gl1_call((void *)request->args[0], request->args[1], request->args[2],
|
reply->retval = gl1_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
request->args[3], request->args[4]);
|
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],
|
reply->retval = gl2_call((void *)request->args[0], request->args[1], request->args[2],
|
||||||
request->args[3], request->args[4]);
|
request->args[3], request->args[4]);
|
||||||
break;
|
break;
|
||||||
case P_VECTOR:
|
case P_GET_SIMD_STATE:
|
||||||
next_stage.entry = (generic_func *)request->args[0];
|
get_simd_state((void *)request->args[0]);
|
||||||
memcpy(next_stage.args, &request->args[1], 4 * sizeof(u64));
|
break;
|
||||||
return 1;
|
case P_PUT_SIMD_STATE:
|
||||||
|
put_simd_state((void *)request->args[0]);
|
||||||
|
break;
|
||||||
|
|
||||||
case P_WRITE64:
|
case P_WRITE64:
|
||||||
exc_guard = GUARD_SKIP;
|
exc_guard = GUARD_SKIP;
|
||||||
|
|
|
@ -20,6 +20,8 @@ typedef enum {
|
||||||
P_VECTOR,
|
P_VECTOR,
|
||||||
P_GL1_CALL,
|
P_GL1_CALL,
|
||||||
P_GL2_CALL,
|
P_GL2_CALL,
|
||||||
|
P_GET_SIMD_STATE,
|
||||||
|
P_PUT_SIMD_STATE,
|
||||||
|
|
||||||
P_WRITE64 = 0x100, // Generic register functions
|
P_WRITE64 = 0x100, // Generic register functions
|
||||||
P_WRITE32,
|
P_WRITE32,
|
||||||
|
|
|
@ -355,6 +355,9 @@ void memcpy16(void *dst, void *src, size_t size);
|
||||||
void memset8(void *dst, u8 value, size_t size);
|
void memset8(void *dst, u8 value, size_t size);
|
||||||
void memcpy8(void *dst, void *src, 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 hexdump(const void *d, size_t len);
|
||||||
void regdump(u64 addr, size_t len);
|
void regdump(u64 addr, size_t len);
|
||||||
int sprintf(char *str, const char *fmt, ...);
|
int sprintf(char *str, const char *fmt, ...);
|
||||||
|
|
|
@ -93,3 +93,45 @@ memset8:
|
||||||
bne 1b
|
bne 1b
|
||||||
2:
|
2:
|
||||||
ret
|
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
|
||||||
|
|
Loading…
Add table
Reference in a new issue