Merge pull request #3268 from 86Box/feature/checkio_optimize
386_common: Optimize I/O permission checking for word and dword operations
This commit is contained in:
@@ -1427,25 +1427,26 @@ x86illegal(void)
|
||||
}
|
||||
|
||||
int
|
||||
checkio(uint32_t port)
|
||||
checkio(uint32_t port, int mask)
|
||||
{
|
||||
uint16_t t;
|
||||
uint8_t d;
|
||||
|
||||
cpl_override = 1;
|
||||
t = readmemw(tr.base, 0x66);
|
||||
cpl_override = 0;
|
||||
|
||||
if (cpu_state.abrt)
|
||||
if (cpu_state.abrt) {
|
||||
cpl_override = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((t + (port >> 3UL)) > tr.limit)
|
||||
return 1;
|
||||
if ((t + (port >> 3UL) + 1) > tr.limit) {
|
||||
cpl_override = 0;
|
||||
return mask;
|
||||
}
|
||||
|
||||
cpl_override = 1;
|
||||
d = readmembl(tr.base + t + (port >> 3));
|
||||
t = readmemwl(tr.base + t + (port >> 3));
|
||||
cpl_override = 0;
|
||||
return d & (1 << (port & 7));
|
||||
return (t >> (port & 7)) & mask;
|
||||
}
|
||||
|
||||
#ifdef OLD_DIVEXCP
|
||||
|
@@ -97,11 +97,11 @@
|
||||
if (writelookup2[(uint32_t) ((s) + (a)) >> 12] == (uintptr_t) LOOKUP_INV || (s) == 0xFFFFFFFF || (((s) + (a)) & 3)) \
|
||||
do_mmutranslate((s) + (a), b, 4, 1)
|
||||
|
||||
int checkio(uint32_t port);
|
||||
int checkio(uint32_t port, int mask);
|
||||
|
||||
#define check_io_perm(port) \
|
||||
#define check_io_perm(port, size) \
|
||||
if (msw & 1 && ((CPL > IOPL) || (cpu_state.eflags & VM_FLAG))) { \
|
||||
int tempi = checkio(port); \
|
||||
int tempi = checkio(port, (1 << size) - 1); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
if (tempi) { \
|
||||
|
@@ -642,7 +642,7 @@ extern void cpu_CPUID(void);
|
||||
extern void cpu_RDMSR(void);
|
||||
extern void cpu_WRMSR(void);
|
||||
|
||||
extern int checkio(uint32_t port);
|
||||
extern int checkio(uint32_t port, int mask);
|
||||
extern void codegen_block_end(void);
|
||||
extern void codegen_reset(void);
|
||||
extern void cpu_set_edx(void);
|
||||
|
@@ -2,7 +2,7 @@ static int
|
||||
opIN_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port, 1);
|
||||
AL = inb(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
|
||||
@@ -14,8 +14,7 @@ static int
|
||||
opIN_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port, 2);
|
||||
AX = inw(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 1, 0, 0, 0, 0);
|
||||
@@ -27,10 +26,7 @@ static int
|
||||
opIN_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
check_io_perm(port, 4);
|
||||
EAX = inl(port);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 2, -1, 0, 1, 0, 0, 0);
|
||||
@@ -43,7 +39,7 @@ static int
|
||||
opOUT_AL_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port, 1);
|
||||
outb(port, AL);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
|
||||
@@ -57,8 +53,7 @@ static int
|
||||
opOUT_AX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port, 2);
|
||||
outw(port, AX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 1, 0, 0);
|
||||
@@ -70,10 +65,7 @@ static int
|
||||
opOUT_EAX_imm(uint32_t fetchdat)
|
||||
{
|
||||
uint16_t port = (uint16_t) getbytef();
|
||||
check_io_perm(port);
|
||||
check_io_perm(port + 1);
|
||||
check_io_perm(port + 2);
|
||||
check_io_perm(port + 3);
|
||||
check_io_perm(port, 4);
|
||||
outl(port, EAX);
|
||||
CLOCK_CYCLES(10);
|
||||
PREFETCH_RUN(10, 2, -1, 0, 0, 0, 1, 0);
|
||||
@@ -85,7 +77,7 @@ opOUT_EAX_imm(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
AL = inb(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
|
||||
@@ -96,8 +88,7 @@ opIN_AL_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
AX = inw(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 1, 0, 0, 0, 0);
|
||||
@@ -108,10 +99,7 @@ opIN_AX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opIN_EAX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
EAX = inl(DX);
|
||||
CLOCK_CYCLES(12);
|
||||
PREFETCH_RUN(12, 1, -1, 0, 1, 0, 0, 0);
|
||||
@@ -123,7 +111,7 @@ opIN_EAX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_AL_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
outb(DX, AL);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
|
||||
@@ -134,8 +122,7 @@ opOUT_AL_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_AX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
outw(DX, AX);
|
||||
CLOCK_CYCLES(11);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 1, 0, 0);
|
||||
@@ -146,10 +133,7 @@ opOUT_AX_DX(uint32_t fetchdat)
|
||||
static int
|
||||
opOUT_EAX_DX(uint32_t fetchdat)
|
||||
{
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
outl(DX, EAX);
|
||||
PREFETCH_RUN(11, 1, -1, 0, 0, 0, 1, 0);
|
||||
if (nmi && nmi_enable && nmi_mask)
|
||||
|
@@ -9,7 +9,7 @@
|
||||
uint8_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX, 1); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
high_page = 0; \
|
||||
do_mmut_wb(es, DEST_REG, &addr64); \
|
||||
@@ -48,8 +48,7 @@
|
||||
uint16_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX, 2); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_ww(es, DEST_REG, addr64a); \
|
||||
@@ -88,10 +87,7 @@
|
||||
uint32_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX + 2); \
|
||||
check_io_perm(DX + 3); \
|
||||
check_io_perm(DX, 4); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_wl(es, DEST_REG, addr64a); \
|
||||
@@ -132,7 +128,7 @@
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX, 1); \
|
||||
outb(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG--; \
|
||||
@@ -163,8 +159,7 @@
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX, 2); \
|
||||
outw(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 2; \
|
||||
@@ -195,10 +190,7 @@
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX + 2); \
|
||||
check_io_perm(DX + 3); \
|
||||
check_io_perm(DX, 4); \
|
||||
outl(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 4; \
|
||||
|
@@ -7,7 +7,7 @@
|
||||
uint8_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX, 1); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG); \
|
||||
high_page = 0; \
|
||||
do_mmut_wb(es, DEST_REG, &addr64); \
|
||||
@@ -40,8 +40,7 @@
|
||||
uint16_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX, 2); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 1UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_ww(es, DEST_REG, addr64a); \
|
||||
@@ -74,10 +73,7 @@
|
||||
uint32_t temp; \
|
||||
\
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es); \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX + 2); \
|
||||
check_io_perm(DX + 3); \
|
||||
check_io_perm(DX, 4); \
|
||||
CHECK_WRITE(&cpu_state.seg_es, DEST_REG, DEST_REG + 3UL); \
|
||||
high_page = 0; \
|
||||
do_mmut_wl(es, DEST_REG, addr64a); \
|
||||
@@ -112,7 +108,7 @@
|
||||
temp = readmemb(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX, 1); \
|
||||
outb(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG--; \
|
||||
@@ -137,8 +133,7 @@
|
||||
temp = readmemw(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX, 2); \
|
||||
outw(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 2; \
|
||||
@@ -163,10 +158,7 @@
|
||||
temp = readmeml(cpu_state.ea_seg->base, SRC_REG); \
|
||||
if (cpu_state.abrt) \
|
||||
return 1; \
|
||||
check_io_perm(DX); \
|
||||
check_io_perm(DX + 1); \
|
||||
check_io_perm(DX + 2); \
|
||||
check_io_perm(DX + 3); \
|
||||
check_io_perm(DX, 4); \
|
||||
outl(DX, temp); \
|
||||
if (cpu_state.flags & D_FLAG) \
|
||||
SRC_REG -= 4; \
|
||||
|
@@ -804,7 +804,7 @@ opINSB_a16(uint32_t fetchdat)
|
||||
addr64 = 0x00000000;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
CHECK_WRITE(&cpu_state.seg_es, DI, DI);
|
||||
high_page = 0;
|
||||
do_mmut_wb(es, DI, &addr64);
|
||||
@@ -830,7 +830,7 @@ opINSB_a32(uint32_t fetchdat)
|
||||
addr64 = 0x00000000;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
high_page = 0;
|
||||
CHECK_WRITE(&cpu_state.seg_es, EDI, EDI);
|
||||
do_mmut_wb(es, EDI, &addr64);
|
||||
@@ -857,8 +857,7 @@ opINSW_a16(uint32_t fetchdat)
|
||||
addr64a[0] = addr64a[1] = 0x00000000;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
CHECK_WRITE(&cpu_state.seg_es, DI, DI + 1UL);
|
||||
high_page = 0;
|
||||
do_mmut_ww(es, DI, addr64a);
|
||||
@@ -885,8 +884,7 @@ opINSW_a32(uint32_t fetchdat)
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
high_page = 0;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 1UL);
|
||||
do_mmut_ww(es, EDI, addr64a);
|
||||
if (cpu_state.abrt)
|
||||
@@ -912,10 +910,7 @@ opINSL_a16(uint32_t fetchdat)
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
CHECK_WRITE(&cpu_state.seg_es, DI, DI + 3UL);
|
||||
high_page = 0;
|
||||
do_mmut_wl(es, DI, addr64a);
|
||||
@@ -941,10 +936,7 @@ opINSL_a32(uint32_t fetchdat)
|
||||
addr64a[0] = addr64a[1] = addr64a[2] = addr64a[3] = 0x00000000;
|
||||
|
||||
SEG_CHECK_WRITE(&cpu_state.seg_es);
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
CHECK_WRITE(&cpu_state.seg_es, EDI, EDI + 3UL);
|
||||
high_page = 0;
|
||||
do_mmut_wl(es, DI, addr64a);
|
||||
@@ -973,7 +965,7 @@ opOUTSB_a16(uint32_t fetchdat)
|
||||
temp = readmemb(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
SI--;
|
||||
else
|
||||
@@ -993,7 +985,7 @@ opOUTSB_a32(uint32_t fetchdat)
|
||||
temp = readmemb(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX, 1);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
ESI--;
|
||||
else
|
||||
@@ -1014,8 +1006,7 @@ opOUTSW_a16(uint32_t fetchdat)
|
||||
temp = readmemw(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
SI -= 2;
|
||||
else
|
||||
@@ -1035,8 +1026,7 @@ opOUTSW_a32(uint32_t fetchdat)
|
||||
temp = readmemw(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX, 2);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
ESI -= 2;
|
||||
else
|
||||
@@ -1057,10 +1047,7 @@ opOUTSL_a16(uint32_t fetchdat)
|
||||
temp = readmeml(cpu_state.ea_seg->base, SI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
SI -= 4;
|
||||
else
|
||||
@@ -1080,10 +1067,7 @@ opOUTSL_a32(uint32_t fetchdat)
|
||||
temp = readmeml(cpu_state.ea_seg->base, ESI);
|
||||
if (cpu_state.abrt)
|
||||
return 1;
|
||||
check_io_perm(DX);
|
||||
check_io_perm(DX + 1);
|
||||
check_io_perm(DX + 2);
|
||||
check_io_perm(DX + 3);
|
||||
check_io_perm(DX, 4);
|
||||
if (cpu_state.flags & D_FLAG)
|
||||
ESI -= 4;
|
||||
else
|
||||
|
Reference in New Issue
Block a user