added read_cpuid and MTRR support checking before trying to set them
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 21 May 2021 10:03:03 +0000 (13:03 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 21 May 2021 10:03:03 +0000 (13:03 +0300)
Makefile
Makefile.dj
src/dos/gfx.c
src/rbench.c
src/util.h
src/util_asm.s [new file with mode: 0644]

index cf9cd98..8b45f2f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,9 +1,9 @@
 src = $(wildcard src/*.c)
+ssrc = $(wildcard src/*.s) sinlut.s
 src_x11 = $(wildcard src/x11/*.c)
 src_fbdev = $(wildcard src/fbdev/*.c)
-ssrc = sinlut.s
-obj_x11 = $(src:.c=.o) $(src_x11:.c=.o) $(ssrc:.s=.o)
-obj_fbdev = $(src:.c=.o) $(src_fbdev:.c=.o) $(ssrc:.s=.o)
+obj_x11 = $(src_x11:.c=.o) $(src:.c=.o) $(ssrc:.s=.o)
+obj_fbdev = $(src_fbdev:.c=.o) $(src:.c=.o) $(ssrc:.s=.o)
 dep = $(src:.c=.d) $(src_x11:.c=.d) $(src_fbdev:.c=.d)
 bin_x11 = rbench_x11
 bin_fbdev = rbench_fbdev
@@ -13,7 +13,8 @@ dbg = -g
 opt = -O3 -ffast-math
 inc = -Isrc
 
-CFLAGS = -pedantic $(warn) $(dbg) $(opt) $(inc) -fno-strict-aliasing -MMD
+CFLAGS = -m32 -pedantic $(warn) $(dbg) $(opt) $(inc) -fno-strict-aliasing -MMD
+ASFLAGS = --32
 LDFLAGS_x11 = -L/usr/X11R6/lib -lX11 -lXext
 LDFLAGS_fbdev =
 
@@ -21,10 +22,10 @@ LDFLAGS_fbdev =
 all: $(bin_x11) $(bin_fbdev)
 
 $(bin_x11): $(obj_x11)
-       $(CC) -o $@ $(obj_x11) $(LDFLAGS_x11)
+       $(CC) -o $@ -m32 $(obj_x11) $(LDFLAGS_x11)
 
 $(bin_fbdev): $(obj_fbdev)
-       $(CC) -o $@ $(obj_fbdev) $(LDFLAGS_fbdev)
+       $(CC) -o $@ -m32 $(obj_fbdev) $(LDFLAGS_fbdev)
 
 sinlut.s: tools/lutgen
        tools/lutgen >$@
index 549dfc1..12b2084 100644 (file)
@@ -1,5 +1,5 @@
 src = $(wildcard src/*.c) $(wildcard src/dos/*.c)
-ssrc = sinlut.s
+ssrc = $(wildcard src/*.s) sinlut.s
 obj = $(src:.c=.odj) $(ssrc:.s=.odj)
 dep = $(src:.c=.d)
 coff = rbench
index 80d965b..474a2e1 100644 (file)
@@ -171,6 +171,7 @@ void *set_video_mode(int idx, int nbuf)
 {
        unsigned int mode;
        struct video_mode *vm = vmodes + idx;
+       struct cpuid_info cpu;
 
        if(curmode == vm) return vpgaddr[0];
 
@@ -226,8 +227,10 @@ void *set_video_mode(int idx, int nbuf)
 
                blit_frame = blit_frame_lfb;
 
-               print_mtrr();
-               enable_wrcomb(vm->fb_addr, fbsize);
+               if(read_cpuid(&cpu) != -1 && cpu.feat & CPUID_FEAT_MTRR) {
+                       print_mtrr();
+                       enable_wrcomb(vm->fb_addr, fbsize);
+               }
 
        } else {
                vpgaddr[0] = (void*)0xa0000;
index 34a26c6..a506fe5 100644 (file)
@@ -19,8 +19,47 @@ unsigned int fb_rmask, fb_gmask, fb_bmask;
 void *framebuf;
 unsigned int time_msec;
 
+static const char *cpufeat[] = {
+       "fpu", "vme", "dbgext", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", 0,
+       "sep", "mtrr", "pge", "mca", "cmov", "pat", "pse36", "psn", "clf", 0,
+       "dtes", "acpi", "mmx", "fxsr", "sse", "sse2", "ss", "htt", "tm1", "ia64", "pbe"
+};
+
+static const char *cpufeat2[] = {
+       "sse3", "pclmul", "dtes64", "monitor", "dscpl", "vmx", "smx", "est", "tm2",
+       "ssse3", "cid", 0, "fma", "cx16", "etprd", "pdcm", 0, "pcide", "dca", "sse4.1",
+       "sse4.2", "x2apic", "movbe", "popcnt", 0, "aes", "xsave", "osxsave", "avx"
+};
+
 int init(void)
 {
+       int i;
+       struct cpuid_info cpu;
+
+       if(read_cpuid(&cpu) != -1) {
+               printf("CPUID information:\n");
+               printf("  cpuid blocks: %d\n", (int)cpu.maxidx);
+               printf("  CPU vendor: ");
+               for(i=0; i<12; i++) {
+                       putchar(cpu.vendor[i]);
+               }
+               putchar('\n');
+               printf("  stepping: %u, model: %u, family: %u\n", CPUID_STEPPING(cpu.id),
+                               CPUID_MODEL(cpu.id), CPUID_FAMILY(cpu.id));
+               printf("  features:");
+               for(i=0; i<sizeof cpufeat / sizeof *cpufeat; i++) {
+                       if(cpufeat[i] && (cpu.feat & (1 << i))) {
+                               printf(" %s", cpufeat[i]);
+                       }
+               }
+               for(i=0; i<sizeof cpufeat2 / sizeof *cpufeat2; i++) {
+                       if(cpufeat2[i] && (cpu.feat2 & (1 << i))) {
+                               printf(" %s", cpufeat2[i]);
+                       }
+               }
+               putchar('\n');
+       }
+
        printf("initialized graphics %dx%d %dbpp\n", fb_width, fb_height, fb_bpp);
        printf("  rgb mask: %x %x %x\n", fb_rmask, fb_gmask, fb_bmask);
        printf("  rgb shift: %d %d %d\n", fb_rshift, fb_gshift, fb_bshift);
index 633ccbf..1032520 100644 (file)
@@ -236,4 +236,77 @@ void __inline memset16(void *dest, uint16_t val, int count)
        } while(0)
 #endif
 
+struct cpuid_info {
+       uint32_t maxidx;        /* 0: eax */
+       char vendor[12];        /* 0: ebx, edx, ecx */
+       uint32_t id;            /* 1: eax */
+       uint32_t rsvd0;         /* 1: ebx */
+       uint32_t feat;          /* 1: edx */
+       uint32_t feat2;         /* 1: ecx */
+};
+
+#define CPUID_STEPPING(id)     ((id) & 0xf)
+#define CPUID_MODEL(id)                (((id) >> 4) & 0xf)
+#define CPUID_FAMILY(id)       (((id) >> 8) & 0xf)
+
+#define CPUID_FEAT_FPU                 0x00000001
+#define CPUID_FEAT_VME                 0x00000002
+#define CPUID_FEAT_DBGEXT              0x00000004
+#define CPUID_FEAT_PSE                 0x00000008
+#define CPUID_FEAT_TSC                 0x00000010
+#define CPUID_FEAT_MSR                 0x00000020
+#define CPUID_FEAT_PAE                 0x00000040
+#define CPUID_FEAT_MCE                 0x00000080
+#define CPUID_FEAT_CX8                 0x00000100
+#define CPUID_FEAT_APIC                        0x00000200
+#define CPUID_FEAT_SEP                 0x00000800
+#define CPUID_FEAT_MTRR                        0x00001000
+#define CPUID_FEAT_PGE                 0x00002000
+#define CPUID_FEAT_MCA                 0x00004000
+#define CPUID_FEAT_CMOV                        0x00008000
+#define CPUID_FEAT_PAT                 0x00010000
+#define CPUID_FEAT_PSE36               0x00020000
+#define CPUID_FEAT_PSN                 0x00040000
+#define CPUID_FEAT_CLF                 0x00080000
+#define CPUID_FEAT_DTES                        0x00200000
+#define CPUID_FEAT_ACPI                        0x00400000
+#define CPUID_FEAT_MMX                 0x00800000
+#define CPUID_FEAT_FXSR                        0x01000000
+#define CPUID_FEAT_SSE                 0x02000000
+#define CPUID_FEAT_SSE2                        0x04000000
+#define CPUID_FEAT_SS                  0x08000000
+#define CPUID_FEAT_HTT                 0x10000000
+#define CPUID_FEAT_TM1                 0x20000000
+#define CPUID_FEAT_IA64                        0x40000000
+#define CPUID_FEAT_PBE                 0x80000000
+
+#define CPUID_FEAT2_SSE3               0x00000001
+#define CPUID_FEAT2_PCLMUL             0x00000002
+#define CPUID_FEAT2_DTES64             0x00000004
+#define CPUID_FEAT2_MONITOR            0x00000008
+#define CPUID_FEAT2_DS_CPL             0x00000010
+#define CPUID_FEAT2_VMX                        0x00000020
+#define CPUID_FEAT2_SMX                        0x00000040
+#define CPUID_FEAT2_EST                        0x00000080
+#define CPUID_FEAT2_TM2                        0x00000100
+#define CPUID_FEAT2_SSSE3              0x00000200
+#define CPUID_FEAT2_CID                        0x00000400
+#define CPUID_FEAT2_FMA                        0x00001000
+#define CPUID_FEAT2_CX16               0x00002000
+#define CPUID_FEAT2_ETPRD              0x00004000
+#define CPUID_FEAT2_PDCM               0x00008000
+#define CPUID_FEAT2_PCIDE              0x00020000
+#define CPUID_FEAT2_DCA                        0x00040000
+#define CPUID_FEAT2_SSE41              0x00080000
+#define CPUID_FEAT2_SSE42              0x00100000
+#define CPUID_FEAT2_X2APIC             0x00200000
+#define CPUID_FEAT2_MOVBE              0x00400000
+#define CPUID_FEAT2_POPCNT             0x00800000
+#define CPUID_FEAT2_AES                        0x02000000
+#define CPUID_FEAT2_XSAVE              0x04000000
+#define CPUID_FEAT2_OSXSAVE            0x08000000
+#define CPUID_FEAT2_AVX                        0x10000000
+
+int read_cpuid(struct cpuid_info *info);
+
 #endif /* UTIL_H_ */
diff --git a/src/util_asm.s b/src/util_asm.s
new file mode 100644 (file)
index 0000000..f237cf5
--- /dev/null
@@ -0,0 +1,67 @@
+       .text
+
+       .equ F_ID,      0x200000
+
+       .globl _read_cpuid
+       .globl read_cpuid
+_read_cpuid:
+read_cpuid:
+       # determine if cpuid is available
+       pushf
+       pop %eax
+       mov %eax, %edx  # keep a copy of the original eflags in edx
+       xor $F_ID, %eax
+       push %eax
+       popf
+       pushf
+       pop %eax
+       cmp %eax, %edx
+       jnz 0f
+       # failed to flip ID bit, CPUID not supported
+       mov $-1, %eax
+       ret
+0:
+       push %ebp
+       mov %esp, %ebp
+       push %ebx
+       push %edi
+       sub $8, %esp
+       mov 8(%ebp), %edi
+
+       xor %eax, %eax
+       mov %eax, (%esp)        # current index
+       cpuid
+
+       mov %eax, (%edi)
+       # clamp to the size of our cpuid_info structure
+       cmp $1, %eax
+       jbe 0f
+       mov $1, %eax
+0:     mov %eax, 4(%esp)       # maximum index
+
+       mov %ebx, 4(%edi)
+       mov %edx, 8(%edi)
+       mov %ecx, 12(%edi)
+       add $16, %edi
+
+cpuid_loop:
+       mov (%esp), %eax
+       inc %eax
+       cmp 4(%esp), %eax
+       ja cpuid_done
+       mov %eax, (%esp)
+       cpuid
+       mov %eax, (%edi)
+       mov %ebx, 4(%edi)
+       mov %edx, 8(%edi)
+       mov %ecx, 12(%edi)
+       add $16, %edi
+       jmp cpuid_loop
+
+cpuid_done:
+       add $8, %esp
+       pop %edi
+       pop %ebx
+       pop %ebp
+       xor %eax, %eax
+       ret