#include <ibm/interrupt.h> /* interrupt numbers and hardware vectors */
#include <ibm/ports.h> /* port addresses and magic numbers */
#include <ibm/bios.h> /* BIOS addresses, sizes and magic numbers */
+#include <ibm/cpu.h> /* BIOS addresses, sizes and magic numbers */
#include <minix/config.h>
/* To translate an address in kernel space to a physical address. This is
#define locktimeend(c)
#endif
+#if ENABLE_K_LOCKCHECK
+#define lockcheck if(!(read_cpu_flags() & X86_FLAG_I)) kinfo.relocking++;
+#else
+#define lockcheck
+#endif
+
/* Disable/Enable hardware interrupts. */
-#define lock(c, v) do { intr_disable(); locktimestart(c, v); } while(0)
+#define lock(c, v) do { lockcheck; intr_disable(); locktimestart(c, v); } while(0)
#define unlock(c) do { locktimeend(c); intr_enable(); } while(0)
/* Sizes of memory tables. The boot monitor distinguishes three memory areas,
.define _idle_task ! task executed when there is no work
.define _level0 ! call a function at level 0
.define _read_tsc ! read the cycle counter (Pentium and up)
+.define _read_cpu_flags ! read the cpu flags
! The routines only guarantee to preserve the registers the C compiler
! expects to be preserved (ebx, esi, edi, ebp, esp, segment registers, and
pop ebp
ret
+!*===========================================================================*
+!* read_flags *
+!*===========================================================================*
+! PUBLIC unsigned long read_cpu_flags(void);
+! Read the cycle counter of the CPU. Pentium and up.
+.align 16
+_read_cpu_flags:
+ pushf
+ mov eax, (esp)
+ popf
+ ret
+
/* Check if boot device was loaded with the kernel. */
if (kinfo.bootdev_base > 0)
kprintf("Image of /dev/boot loaded. Size: %u KB.\n", kinfo.bootdev_size);
+
}
_PROTOTYPE( void level0, (void (*func)(void)) );
_PROTOTYPE( void monitor, (void) );
_PROTOTYPE( void read_tsc, (unsigned long *high, unsigned long *low) );
+_PROTOTYPE( unsigned long read_cpu_flags, (void) );
/* mpx*.s */
_PROTOTYPE( void idle_task, (void) );