diff options
author | aiju <devnull@localhost> | 2017-06-17 22:50:03 +0000 |
---|---|---|
committer | aiju <devnull@localhost> | 2017-06-17 22:50:03 +0000 |
commit | 52a3502927870a330f02a9b71cf9710f65f1a58a (patch) | |
tree | 14481a151b6248793029363f83a96749bfc6342b /sys/src | |
parent | 2bb65c40ab0713b011ff758cc2d8bc20e885fe85 (diff) |
vmx(1): support debug instructions
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/vmx/dat.h | 15 | ||||
-rw-r--r-- | sys/src/cmd/vmx/exith.c | 37 | ||||
-rw-r--r-- | sys/src/cmd/vmx/fns.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/vmx/vmx.c | 10 |
4 files changed, 58 insertions, 6 deletions
diff --git a/sys/src/cmd/vmx/dat.h b/sys/src/cmd/vmx/dat.h index 1435150bb..35b69f2b8 100644 --- a/sys/src/cmd/vmx/dat.h +++ b/sys/src/cmd/vmx/dat.h @@ -15,6 +15,17 @@ enum { #define RBX "bx" #define RCX "cx" #define RDX "dx" +#define RBP "bp" +#define RSI "si" +#define RDI "di" +#define R8 "r8" +#define R9 "r9" +#define R10 "r10" +#define R11 "r11" +#define R12 "r12" +#define R13 "r13" +#define R14 "r14" +#define R15 "r15" enum { MMIORD = 0, @@ -72,8 +83,12 @@ struct PCICap { }; enum { + /* irqline argument */ IRQLTOGGLE = -1, IRQLLOHI = -2, + + /* postexc */ + NOERRC = -1, }; typedef struct VgaMode VgaMode; diff --git a/sys/src/cmd/vmx/exith.c b/sys/src/cmd/vmx/exith.c index 19d827170..f68566607 100644 --- a/sys/src/cmd/vmx/exith.c +++ b/sys/src/cmd/vmx/exith.c @@ -75,7 +75,7 @@ iohandler(ExitInfo *ei) isin = (ei->qual & 8) != 0; if((ei->qual & 1<<4) != 0){ vmerror("i/o string instruction not implemented"); - postexc("#ud", 0); + postexc("#ud", NOERRC); return; } if(isin){ @@ -321,6 +321,37 @@ rdwrmsr(ExitInfo *ei) } static void +movdr(ExitInfo *ei) +{ + static char *reg[16] = { + RAX, RCX, RDX, RBX, + RSP, RBP, RSI, RDI, + R8, R9, R10, R11, + R12, R13, R14, R15 + }; + static char *dr[8] = { "dr0", "dr1", "dr2", "dr3", nil, nil, "dr6", "dr7" }; + int q; + + q = ei->qual; + if((q & 6) == 4){ + postexc("#gp", 0); + return; + } + if((q & 16) != 0) + rset(reg[q >> 8 & 15], rget(dr[q & 7])); + else + rset(dr[q & 7], rget(reg[q >> 8 & 15])); + skipinstr(ei); +} + +static void +dbgexc(ExitInfo *ei) +{ + rset("dr6", rget("dr6") | ei->qual); + postexc("#db", NOERRC); +} + +static void hlt(ExitInfo *ei) { if(irqactive == 0) @@ -347,6 +378,8 @@ static ExitType etypes[] = { {"*ack", irqackhand}, {".rdmsr", rdwrmsr}, {".wrmsr", rdwrmsr}, + {".movdr", movdr}, + {"#db", dbgexc}, }; void @@ -391,7 +424,7 @@ processexit(char *msg) } if(*f[0] == '.'){ vmerror("vmx: unknown instruction %s", f[0]+1); - postexc("#ud", 0); + postexc("#ud", NOERRC); return; } if(*f[0] == '*'){ diff --git a/sys/src/cmd/vmx/fns.h b/sys/src/cmd/vmx/fns.h index 231ffcbc4..cff97b0af 100644 --- a/sys/src/cmd/vmx/fns.h +++ b/sys/src/cmd/vmx/fns.h @@ -13,7 +13,7 @@ int ctl(char *, ...); void registermmio(uvlong, uvlong, uvlong (*)(int, uvlong, uvlong)); void irqline(int, int); void irqack(int); -void postexc(char *, u32int); +void postexc(char *, vlong); void vgaresize(void); void uartinit(int, char *); void sendnotif(void (*)(void *), void *); diff --git a/sys/src/cmd/vmx/vmx.c b/sys/src/cmd/vmx/vmx.c index 6671d7946..8e5cd6e18 100644 --- a/sys/src/cmd/vmx/vmx.c +++ b/sys/src/cmd/vmx/vmx.c @@ -318,10 +318,14 @@ mksegment(char *sn) } void -postexc(char *name, u32int) +postexc(char *name, vlong code) { - if(ctl("exc %s", name) < 0) - sysfatal("ctl(postexc): %r"); + if(code >= 0){ + if(ctl("exc %s,%#ux", name, (u32int)code) < 0) + sysfatal("ctl(postexc): %r"); + }else + if(ctl("exc %s", name) < 0) + sysfatal("ctl(postexc): %r"); } void |