From: John Tsiombikas Date: Wed, 19 May 2021 22:43:27 +0000 (+0300) Subject: first attempt at setting write-combining with MTRRs. It works, but no X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=retrobench;a=commitdiff_plain;h=56142c5f75e9464ce20f7b9e49e868e3997b76b3 first attempt at setting write-combining with MTRRs. It works, but no detection yet (so will crash on anything < p6), and it fails to detect it already set the correct range from a previous run, and fills up the MTRRs with every subsequent run. --- diff --git a/Makefile.dj b/Makefile.dj index fc59199..00dbd47 100644 --- a/Makefile.dj +++ b/Makefile.dj @@ -2,7 +2,9 @@ src = $(wildcard src/*.c) $(wildcard src/dos/*.c) ssrc = sinlut.s obj = $(src:.c=.o) $(ssrc:.s=.o) dep = $(src:.c=.d) -bin = rbench.exe +coff = rbench +bin = $(coff).exe +bin0 = $(coff)0.exe LUTGEN = tools/lutgen.exe @@ -12,7 +14,12 @@ opt = -O3 -ffast-math inc = -Isrc def = -DNO_STDINT_H -CFLAGS = -pedantic $(warn) $(dbg) $(opt) $(def) $(inc) -MMD +CFLAGS = -pedantic $(warn) $(dbg) $(opt) $(def) $(inc) -fno-strict-aliasing -MMD +LDFLAGS = -Wl,-Map=link.map + +$(bin0): $(bin) + exe2coff $< + copy /b \djgpp\bin\cwsdstr0.exe+$(coff) $@ $(bin): $(obj) $(CC) -o $@ $(obj) $(LDFLAGS) diff --git a/src/dos/gfx.c b/src/dos/gfx.c index c686e35..80d965b 100644 --- a/src/dos/gfx.c +++ b/src/dos/gfx.c @@ -1,12 +1,13 @@ -#include #include #include +#include #include "cdpmi.h" #include "gfx.h" #include "vbe.h" #include "vga.h" #include "util.h" + #define SAME_BPP(a, b) \ ((a) == (b) || ((a) == 16 && (b) == 15) || ((a) == 15 && (b) == 16) || \ ((a) == 32 && (b) == 24) || ((a) == 24 && (b) == 32)) @@ -19,6 +20,9 @@ static void blit_frame_lfb(void *pixels, int vsync); static void blit_frame_banked(void *pixels, int vsync); static uint32_t calc_mask(int sz, int pos); +static void enable_wrcomb(uint32_t addr, int len); +static void print_mtrr(void); + static struct video_mode *vmodes; static int num_vmodes; @@ -222,6 +226,9 @@ void *set_video_mode(int idx, int nbuf) blit_frame = blit_frame_lfb; + print_mtrr(); + enable_wrcomb(vm->fb_addr, fbsize); + } else { vpgaddr[0] = (void*)0xa0000; vpgaddr[1] = 0; @@ -237,6 +244,7 @@ void *set_video_mode(int idx, int nbuf) return 0; } + fflush(stdout); return vpgaddr[0]; } @@ -305,3 +313,160 @@ static uint32_t calc_mask(int sz, int pos) } return mask << pos; } + +#define get_msr(msr, low, high) \ + asm volatile( \ + "\r\trdmsr" \ + : "=a"(low), "=d"(high) \ + : "c"(msr)) + +#define set_msr(msr, low, high) \ + asm volatile( \ + "\r\twrmsr" \ + :: "c"(msr), "a"(low), "d"(high)) + +#define MSR_MTRRCAP 0xfe +#define MSR_MTRRDEFTYPE 0x2ff +#define MSR_MTRRBASE(x) (0x200 | ((x) << 1)) +#define MSR_MTRRMASK(x) (0x201 | ((x) << 1)) +#define MTRRDEF_EN 0x800 +#define MTRRCAP_HAVE_WC 0x400 +#define MTRRMASK_VALID 0x800 + +#define MTRR_WC 1 + +static int get_page_memtype(uint32_t addr, int num_ranges) +{ + int i; + uint32_t rlow, rhigh; + uint32_t base, mask; + + for(i=0; i 0) { + if(get_page_memtype(addr, num_ranges) != MTRR_WC) { + return 0; + } + addr += 4096; + len -= 4096; + } + return 1; +} + +static int alloc_mtrr(int num_ranges) +{ + int i; + uint32_t rlow, rhigh; + + for(i=0; i> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; + mask = ~mask & 0xfffff000; + + printf(" ... mask: %08x\n", (unsigned int)mask); + + disable(); + get_msr(MSR_MTRRDEFTYPE, def, rhigh); + set_msr(MSR_MTRRDEFTYPE, def & ~MTRRDEF_EN, rhigh); + + set_msr(MSR_MTRRBASE(mtrr), addr | MTRR_WC, 0); + set_msr(MSR_MTRRMASK(mtrr), mask | MTRRMASK_VALID, 0); + + set_msr(MSR_MTRRDEFTYPE, def | MTRRDEF_EN, 0); + enable(); +} + +static const char *mtrr_names[] = { "N/A", "W C", "N/A", "N/A", "W T", "W P", "W B" }; + +static const char *mtrr_type_name(int type) +{ + if(type < 0 || type >= sizeof mtrr_names / sizeof *mtrr_names) { + return mtrr_names[0]; + } + return mtrr_names[type]; +} + +static void print_mtrr(void) +{ + int i, num_ranges; + uint32_t rlow, rhigh, base, mask; + + get_msr(MSR_MTRRCAP, rlow, rhigh); + num_ranges = rlow & 0xff; + + for(i=0; i