On Sun, Jan 22, 2012 at 10:04:33PM +0100, Rudolf Marek wrote:
Hello,
Following patch makes seabios friendly to 386/486 CPUs, providing a way how to emulate the CPUID instruction and using TSC only if CPU actually supports the TSC. Otherwise it uses TSC emulation mode which is similar to what is used in Xenomai except we use timer0 here.
Thanks - please see my comments below.
With this patch it is able to run on 486SX class system aka bifferboard together with coreboot.
It would be preferable if this was in two patches - one to check for cpuid and one to check for the tsc.
[...]
--- a/src/biosvar.h +++ b/src/biosvar.h @@ -238,6 +238,10 @@ struct extended_bios_data_area_s {
u16 boot_sequence;
- /* TSC emulation timekeepers */
- u64 tsc_8254;
- int last_tsc_8254;
Can't the existing timer_counter in the BDA be used instead?
[...]
--- a/src/clock.c +++ b/src/clock.c @@ -57,6 +57,24 @@ #define CALIBRATE_COUNT 0x800 // Approx 1.7ms
u32 cpu_khz VAR16VISIBLE; +u8 no_tsc VAR16VISIBLE;
+u64 emulate_tsc(void) {
- int cnt, d;
- u16 ebda_seg = get_ebda_seg();
- u64 ret;
- /* read timer 0 current count */
- ret = GET_EBDA2(ebda_seg, tsc_8254);
- /* readback mode has slightly shifted registers, works on all 8254, readback PIT0 latch */
- outb(PM_SEL_READBACK | 0x10 | 0x2, PORT_PIT_MODE);
BTW, what's the impact of writing to the PORT_PIT_MODE? Will it corrupt the old value? (Not an issue for the patch, as obviously something is better than nothing for your board.)
[...]
- SET_GLOBAL(no_tsc, 0);
FYI - SET_GLOBAL(x,y) is the same as writing "x=y". The macro is only available in 32bit mode, so it's not really any different.
[...]
--- a/src/post.c +++ b/src/post.c @@ -360,6 +360,9 @@ handle_post(void) // Enable CPU caching setcr0(getcr0() & ~(CR0_CD|CR0_NW));
- // Emulate the CPUID if 386/486
- detect_cpuid();
This is too early (can't assign global variables here on QEmu). I suggest you put in maininit() after the malloc_fixup() call.
[...]
--- a/src/util.h +++ b/src/util.h @@ -7,6 +7,10 @@ #define __UTIL_H
#include "types.h" // u32 +#include "biosvar.h" // GET_GLOBAL
+#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0)
These already exist in types.h.
-Kevin