386_common: Optimize I/O permission checking for word and dword operations (based on qemu)

This commit is contained in:
RichardG867
2023-04-22 18:41:42 -03:00
parent 041e916472
commit c076406450
7 changed files with 50 additions and 97 deletions

View File

@@ -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

View File

@@ -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) { \

View File

@@ -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);

View File

@@ -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)

View File

@@ -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; \

View File

@@ -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; \

View File

@@ -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