Don't move EBDA while an optionrom is running (CONFIG_THREAD_OPTIONROMS).
authorKevin O'Connor <kevin@koconnor.net>
Sat, 20 Mar 2010 22:17:19 +0000 (18:17 -0400)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 20 Mar 2010 22:17:19 +0000 (18:17 -0400)
Moving the ebda while an optionrom is running could confuse it.  So,
avoid doing that.

src/pmm.c
src/stacks.c
src/types.h
src/util.h

index 0461e4139eb810688531c490f91cc931209568f1..1b90f215f851e49c4ddca7e5bb326f1c31cc509d 100644 (file)
--- a/src/pmm.c
+++ b/src/pmm.c
@@ -74,12 +74,18 @@ relocate_ebda(u32 newebda, u32 oldebda, u8 ebda_size)
 static void
 zonelow_expand(u32 size, u32 align)
 {
-    u32 oldpos = GET_PMMVAR(ZoneLow.cur);
-    u32 newpos = ALIGN_DOWN(oldpos - size, align);
-    u32 bottom = GET_PMMVAR(ZoneLow.bottom);
-    if (newpos >= bottom && newpos <= oldpos)
-        // Space already present.
-        return;
+    u32 oldpos, newpos, bottom;
+    for (;;) {
+        oldpos = GET_PMMVAR(ZoneLow.cur);
+        newpos = ALIGN_DOWN(oldpos - size, align);
+        bottom = GET_PMMVAR(ZoneLow.bottom);
+        if (newpos >= bottom && newpos <= oldpos)
+            // Space already present.
+            return;
+        // Make sure to not move ebda while an optionrom is running.
+        if (likely(!wait_preempt()))
+            break;
+    }
     u16 ebda_seg = get_ebda_seg();
     u32 ebda_pos = (u32)MAKE_FLATPTR(ebda_seg, 0);
     u8 ebda_size = GET_EBDA2(ebda_seg, size);
index c783967cb7d115393aeec897f9e57604499772b2..4a30b3d82ebb43471c5546b972430718d6880bfa 100644 (file)
@@ -297,6 +297,18 @@ finish_preempt(void)
     dprintf(1, "Done preempt - %d checks\n", PreemptCount);
 }
 
+// Check if preemption is on, and wait for it to complete if so.
+int
+wait_preempt(void)
+{
+    if (MODESEGMENT || !CONFIG_THREADS || !CONFIG_THREAD_OPTIONROMS
+        || !CanPreempt)
+        return 0;
+    while (CanPreempt)
+        yield();
+    return 1;
+}
+
 extern void yield_preempt(void);
 #if MODESEGMENT == 0
 // Try to execute 32bit threads.
index 5da299d929c4efc0c414f4d1c695644c481ff7aa..e0133589640ac2140fa0f394f9c98443aa09e818 100644 (file)
@@ -114,6 +114,9 @@ extern void __force_link_error__only_in_16bit(void) __noreturn;
         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
         (type *)( (char *)__mptr - offsetof(type,member) );})
 
+#define likely(x)       __builtin_expect(!!(x), 1)
+#define unlikely(x)     __builtin_expect(!!(x), 0)
+
 #define NULL ((void*)0)
 
 #define __weak __attribute__((weak))
index 7c7c6980d87ab30d0bc2a7346fa73a12e6723680..d2ac08a5917e1d6fe36eabaea3bde9e9a3b627a6 100644 (file)
@@ -216,6 +216,7 @@ void mutex_lock(struct mutex_s *mutex);
 void mutex_unlock(struct mutex_s *mutex);
 void start_preempt(void);
 void finish_preempt(void);
+int wait_preempt(void);
 void check_preempt(void);
 
 // output.c