summaryrefslogtreecommitdiffstats
path: root/qemu/roms/seabios/src/stacks.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/seabios/src/stacks.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/seabios/src/stacks.c')
-rw-r--r--qemu/roms/seabios/src/stacks.c763
1 files changed, 0 insertions, 763 deletions
diff --git a/qemu/roms/seabios/src/stacks.c b/qemu/roms/seabios/src/stacks.c
deleted file mode 100644
index ef6a70775..000000000
--- a/qemu/roms/seabios/src/stacks.c
+++ /dev/null
@@ -1,763 +0,0 @@
-// Code for manipulating stack locations.
-//
-// Copyright (C) 2009-2015 Kevin O'Connor <kevin@koconnor.net>
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "biosvar.h" // GET_GLOBAL
-#include "bregs.h" // CR0_PE
-#include "fw/paravirt.h" // PORT_SMI_CMD
-#include "hw/rtc.h" // rtc_use
-#include "list.h" // hlist_node
-#include "malloc.h" // free
-#include "output.h" // dprintf
-#include "romfile.h" // romfile_loadint
-#include "stacks.h" // struct mutex_s
-#include "string.h" // memset
-#include "util.h" // useRTC
-
-#define MAIN_STACK_MAX (1024*1024)
-
-
-/****************************************************************
- * 16bit / 32bit calling
- ****************************************************************/
-
-struct {
- u8 method;
- u8 cmosindex;
- u8 a20;
- u16 ss, fs, gs;
- u32 cr0;
- struct descloc_s gdt;
-} Call16Data VARLOW;
-
-#define C16_BIG 1
-#define C16_SMM 2
-
-int HaveSmmCall32 VARFSEG;
-
-// Backup state in preparation for call32
-static int
-call32_prep(u8 method)
-{
- if (!CONFIG_CALL32_SMM || method != C16_SMM) {
- // Backup cr0
- u32 cr0 = cr0_read();
- if (cr0 & CR0_PE)
- // Called in 16bit protected mode?!
- return -1;
- SET_LOW(Call16Data.cr0, cr0);
-
- // Backup fs/gs and gdt
- SET_LOW(Call16Data.fs, GET_SEG(FS));
- SET_LOW(Call16Data.gs, GET_SEG(GS));
- struct descloc_s gdt;
- sgdt(&gdt);
- SET_LOW(Call16Data.gdt.length, gdt.length);
- SET_LOW(Call16Data.gdt.addr, gdt.addr);
-
- // Enable a20 and backup its previous state
- SET_LOW(Call16Data.a20, set_a20(1));
- }
-
- // Backup ss
- SET_LOW(Call16Data.ss, GET_SEG(SS));
-
- // Backup cmos index register and disable nmi
- u8 cmosindex = inb(PORT_CMOS_INDEX);
- outb(cmosindex | NMI_DISABLE_BIT, PORT_CMOS_INDEX);
- inb(PORT_CMOS_DATA);
- SET_LOW(Call16Data.cmosindex, cmosindex);
-
- SET_LOW(Call16Data.method, method);
- return 0;
-}
-
-// Restore state backed up during call32
-static u8
-call32_post(void)
-{
- u8 method = GET_LOW(Call16Data.method);
- SET_LOW(Call16Data.method, 0);
- SET_LOW(Call16Data.ss, 0);
-
- if (!CONFIG_CALL32_SMM || method != C16_SMM) {
- // Restore a20
- set_a20(GET_LOW(Call16Data.a20));
-
- // Restore gdt and fs/gs
- struct descloc_s gdt;
- gdt.length = GET_LOW(Call16Data.gdt.length);
- gdt.addr = GET_LOW(Call16Data.gdt.addr);
- lgdt(&gdt);
- SET_SEG(FS, GET_LOW(Call16Data.fs));
- SET_SEG(GS, GET_LOW(Call16Data.gs));
-
- // Restore cr0
- u32 cr0_caching = GET_LOW(Call16Data.cr0) & (CR0_CD|CR0_NW);
- if (cr0_caching)
- cr0_mask(CR0_CD|CR0_NW, cr0_caching);
- }
-
- // Restore cmos index register
- outb(GET_LOW(Call16Data.cmosindex), PORT_CMOS_INDEX);
- inb(PORT_CMOS_DATA);
- return method;
-}
-
-// Force next call16() to restore to a pristine cpu environment state
-static void
-call16_override(int big)
-{
- ASSERT32FLAT();
- if (getesp() > BUILD_STACK_ADDR)
- panic("call16_override with invalid stack\n");
- memset(&Call16Data, 0, sizeof(Call16Data));
- if (big) {
- Call16Data.method = C16_BIG;
- Call16Data.a20 = 1;
- } else {
- Call16Data.a20 = !CONFIG_DISABLE_A20;
- }
-}
-
-// 16bit handler code called from call16() / call16_smm()
-u32 VISIBLE16
-call16_helper(u32 eax, u32 edx, u32 (*func)(u32 eax, u32 edx))
-{
- u8 method = call32_post();
- u32 ret = func(eax, edx);
- call32_prep(method);
- return ret;
-}
-
-#define ASM32_SWITCH16 " .pushsection .text.32fseg." UNIQSEC "\n .code16\n"
-#define ASM32_BACK32 " .popsection\n .code32\n"
-#define ASM16_SWITCH32 " .code32\n"
-#define ASM16_BACK16 " .code16gcc\n"
-
-// Call a SeaBIOS C function in 32bit mode using smm trampoline
-static u32
-call32_smm(void *func, u32 eax)
-{
- ASSERT16();
- dprintf(9, "call32_smm %p %x\n", func, eax);
- call32_prep(C16_SMM);
- u32 bkup_esp;
- asm volatile(
- // Backup esp / set esp to flat stack location
- " movl %%esp, %0\n"
- " movl %%ss, %%eax\n"
- " shll $4, %%eax\n"
- " addl %%eax, %%esp\n"
-
- // Transition to 32bit mode, call func, return to 16bit
- " movl $" __stringify(CALL32SMM_CMDID) ", %%eax\n"
- " movl $" __stringify(CALL32SMM_ENTERID) ", %%ecx\n"
- " movl $(" __stringify(BUILD_BIOS_ADDR) " + 1f), %%ebx\n"
- " outb %%al, $" __stringify(PORT_SMI_CMD) "\n"
- " rep; nop\n"
- " hlt\n"
-
- ASM16_SWITCH32
- "1:movl %1, %%eax\n"
- " calll *%2\n"
- " movl %%eax, %1\n"
-
- " movl $" __stringify(CALL32SMM_CMDID) ", %%eax\n"
- " movl $" __stringify(CALL32SMM_RETURNID) ", %%ecx\n"
- " movl $2f, %%ebx\n"
- " outb %%al, $" __stringify(PORT_SMI_CMD) "\n"
- " rep; nop\n"
- " hlt\n"
-
- // Restore esp
- ASM16_BACK16
- "2:movl %0, %%esp\n"
- : "=&r" (bkup_esp), "+r" (eax)
- : "r" (func)
- : "eax", "ecx", "edx", "ebx", "cc", "memory");
- call32_post();
-
- dprintf(9, "call32_smm done %p %x\n", func, eax);
- return eax;
-}
-
-static u32
-call16_smm(u32 eax, u32 edx, void *func)
-{
- ASSERT32FLAT();
- if (!CONFIG_CALL32_SMM)
- return eax;
- func -= BUILD_BIOS_ADDR;
- dprintf(9, "call16_smm %p %x %x\n", func, eax, edx);
- u32 stackoffset = Call16Data.ss << 4;
- asm volatile(
- // Restore esp
- " subl %0, %%esp\n"
-
- // Transition to 16bit mode, call func, return to 32bit
- " movl $" __stringify(CALL32SMM_CMDID) ", %%eax\n"
- " movl $" __stringify(CALL32SMM_RETURNID) ", %%ecx\n"
- " movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%ebx\n"
- " outb %%al, $" __stringify(PORT_SMI_CMD) "\n"
- " rep; nop\n"
- " hlt\n"
-
- ASM32_SWITCH16
- "1:movl %1, %%eax\n"
- " movl %3, %%ecx\n"
- " calll _cfunc16_call16_helper\n"
- " movl %%eax, %1\n"
-
- " movl $" __stringify(CALL32SMM_CMDID) ", %%eax\n"
- " movl $" __stringify(CALL32SMM_ENTERID) ", %%ecx\n"
- " movl $2f, %%ebx\n"
- " outb %%al, $" __stringify(PORT_SMI_CMD) "\n"
- " rep; nop\n"
- " hlt\n"
-
- // Set esp to flat stack location
- ASM32_BACK32
- "2:addl %0, %%esp\n"
- : "+r" (stackoffset), "+r" (eax), "+d" (edx)
- : "r" (func)
- : "eax", "ecx", "ebx", "cc", "memory");
- return eax;
-}
-
-// Call a 32bit SeaBIOS function from a 16bit SeaBIOS function.
-u32 VISIBLE16
-__call32(void *func, u32 eax, u32 errret)
-{
- ASSERT16();
- if (CONFIG_CALL32_SMM && GET_GLOBAL(HaveSmmCall32))
- return call32_smm(func, eax);
- // Jump direclty to 32bit mode - this clobbers the 16bit segment
- // selector registers.
- int ret = call32_prep(C16_BIG);
- if (ret)
- return errret;
- u32 bkup_ss, bkup_esp;
- asm volatile(
- // Backup ss/esp / set esp to flat stack location
- " movl %%ss, %0\n"
- " movl %%esp, %1\n"
- " shll $4, %0\n"
- " addl %0, %%esp\n"
- " shrl $4, %0\n"
-
- // Transition to 32bit mode, call func, return to 16bit
- " movl $(" __stringify(BUILD_BIOS_ADDR) " + 1f), %%edx\n"
- " jmp transition32_nmi_off\n"
- ASM16_SWITCH32
- "1:calll *%3\n"
- " movl $2f, %%edx\n"
- " jmp transition16big\n"
-
- // Restore ds/ss/esp
- ASM16_BACK16
- "2:movl %0, %%ds\n"
- " movl %0, %%ss\n"
- " movl %1, %%esp\n"
- : "=&r" (bkup_ss), "=&r" (bkup_esp), "+a" (eax)
- : "r" (func)
- : "ecx", "edx", "cc", "memory");
- call32_post();
- return eax;
-}
-
-// Call a 16bit SeaBIOS function, restoring the mode from last call32().
-static u32
-call16(u32 eax, u32 edx, void *func)
-{
- ASSERT32FLAT();
- if (getesp() > MAIN_STACK_MAX)
- panic("call16 with invalid stack\n");
- if (CONFIG_CALL32_SMM && Call16Data.method == C16_SMM)
- return call16_smm(eax, edx, func);
-
- extern void transition16big(void);
- extern void transition16(void);
- void *thunk = transition16;
- if (Call16Data.method == C16_BIG || in_post())
- thunk = transition16big;
- func -= BUILD_BIOS_ADDR;
- u32 stackseg = Call16Data.ss;
- asm volatile(
- // Transition to 16bit mode
- " movl $(1f - " __stringify(BUILD_BIOS_ADDR) "), %%edx\n"
- " jmp *%%ecx\n"
- // Setup ss/esp and call func
- ASM32_SWITCH16
- "1:movl %2, %%ecx\n"
- " shll $4, %2\n"
- " movw %%cx, %%ss\n"
- " subl %2, %%esp\n"
- " movw %%cx, %%ds\n"
- " movl %4, %%edx\n"
- " movl %3, %%ecx\n"
- " calll _cfunc16_call16_helper\n"
- // Return to 32bit and restore esp
- " movl $2f, %%edx\n"
- " jmp transition32_nmi_off\n"
- ASM32_BACK32
- "2:addl %2, %%esp\n"
- : "+a" (eax), "+c"(thunk), "+r"(stackseg)
- : "r" (func), "r" (edx)
- : "edx", "cc", "memory");
- return eax;
-}
-
-
-/****************************************************************
- * Extra 16bit stack
- ****************************************************************/
-
-// Space for a stack for 16bit code.
-u8 ExtraStack[BUILD_EXTRA_STACK_SIZE+1] VARLOW __aligned(8);
-u8 *StackPos VARLOW;
-
-// Test if currently on the extra stack
-int
-on_extra_stack(void)
-{
- return MODE16 && GET_SEG(SS) == SEG_LOW && getesp() > (u32)ExtraStack;
-}
-
-// Switch to the extra stack and call a function.
-u32
-__stack_hop(u32 eax, u32 edx, void *func)
-{
- if (on_extra_stack())
- return ((u32 (*)(u32, u32))func)(eax, edx);
- ASSERT16();
- u16 stack_seg = SEG_LOW;
- u32 bkup_ss, bkup_esp;
- asm volatile(
- // Backup current %ss/%esp values.
- "movw %%ss, %w3\n"
- "movl %%esp, %4\n"
- // Copy stack seg to %ds/%ss and set %esp
- "movw %w6, %%ds\n"
- "movw %w6, %%ss\n"
- "movl %5, %%esp\n"
- "pushl %3\n"
- "pushl %4\n"
- // Call func
- "calll *%2\n"
- "popl %4\n"
- "popl %3\n"
- // Restore segments and stack
- "movw %w3, %%ds\n"
- "movw %w3, %%ss\n"
- "movl %4, %%esp"
- : "+a" (eax), "+d" (edx), "+c" (func), "=&r" (bkup_ss), "=&r" (bkup_esp)
- : "m" (StackPos), "r" (stack_seg)
- : "cc", "memory");
- return eax;
-}
-
-// Switch back to original caller's stack and call a function.
-u32
-__stack_hop_back(u32 eax, u32 edx, void *func)
-{
- if (!MODESEGMENT)
- return call16(eax, edx, func);
- if (!MODE16 || !on_extra_stack())
- return ((u32 (*)(u32, u32))func)(eax, edx);
- ASSERT16();
- u16 bkup_ss;
- u32 bkup_stack_pos, temp;
- asm volatile(
- // Backup stack_pos and current %ss/%esp
- "movl %6, %4\n"
- "movw %%ss, %w3\n"
- "movl %%esp, %6\n"
- // Restore original callers' %ss/%esp
- "movl -4(%4), %5\n"
- "movl %5, %%ss\n"
- "movw %%ds:-8(%4), %%sp\n"
- "movl %5, %%ds\n"
- // Call func
- "calll *%2\n"
- // Restore %ss/%esp and stack_pos
- "movw %w3, %%ds\n"
- "movw %w3, %%ss\n"
- "movl %6, %%esp\n"
- "movl %4, %6"
- : "+a" (eax), "+d" (edx), "+c" (func), "=&r" (bkup_ss)
- , "=&r" (bkup_stack_pos), "=&r" (temp), "+m" (StackPos)
- :
- : "cc", "memory");
- return eax;
-}
-
-
-/****************************************************************
- * External 16bit interface calling
- ****************************************************************/
-
-// Far call 16bit code with a specified register state.
-void VISIBLE16
-_farcall16(struct bregs *callregs, u16 callregseg)
-{
- if (need_hop_back()) {
- stack_hop_back(_farcall16, callregs, callregseg);
- return;
- }
- ASSERT16();
- asm volatile(
- "calll __farcall16\n"
- : "+a" (callregs), "+m" (*callregs), "+d" (callregseg)
- :
- : "ebx", "ecx", "esi", "edi", "cc", "memory");
-}
-
-// Invoke external 16bit code.
-void
-farcall16(struct bregs *callregs)
-{
- call16_override(0);
- _farcall16(callregs, 0);
-}
-
-// Invoke external 16bit code in "big real" mode.
-void
-farcall16big(struct bregs *callregs)
-{
- call16_override(1);
- _farcall16(callregs, 0);
-}
-
-// Invoke a 16bit software interrupt.
-void
-__call16_int(struct bregs *callregs, u16 offset)
-{
- callregs->code.offset = offset;
- if (!MODESEGMENT) {
- callregs->code.seg = SEG_BIOS;
- _farcall16((void*)callregs - Call16Data.ss * 16, Call16Data.ss);
- return;
- }
- callregs->code.seg = GET_SEG(CS);
- _farcall16(callregs, GET_SEG(SS));
-}
-
-// Reset the machine
-void
-reset(void)
-{
- extern void reset_vector(void) __noreturn;
- if (!MODE16)
- call16(0, 0, reset_vector);
- reset_vector();
-}
-
-
-/****************************************************************
- * Threads
- ****************************************************************/
-
-// Thread info - stored at bottom of each thread stack - don't change
-// without also updating the inline assembler below.
-struct thread_info {
- void *stackpos;
- struct hlist_node node;
-};
-struct thread_info MainThread VARFSEG = {
- NULL, { &MainThread.node, &MainThread.node.next }
-};
-#define THREADSTACKSIZE 4096
-
-// Check if any threads are running.
-static int
-have_threads(void)
-{
- return (CONFIG_THREADS
- && GET_FLATPTR(MainThread.node.next) != &MainThread.node);
-}
-
-// Return the 'struct thread_info' for the currently running thread.
-struct thread_info *
-getCurThread(void)
-{
- u32 esp = getesp();
- if (esp <= MAIN_STACK_MAX)
- return &MainThread;
- return (void*)ALIGN_DOWN(esp, THREADSTACKSIZE);
-}
-
-static u8 CanInterrupt, ThreadControl;
-
-// Initialize the support for internal threads.
-void
-thread_setup(void)
-{
- CanInterrupt = 1;
- if (! CONFIG_THREADS)
- return;
- ThreadControl = romfile_loadint("etc/threads", 1);
-}
-
-// Should hardware initialization threads run during optionrom execution.
-int
-threads_during_optionroms(void)
-{
- return CONFIG_THREADS && CONFIG_RTC_TIMER && ThreadControl == 2 && in_post();
-}
-
-// Switch to next thread stack.
-static void
-switch_next(struct thread_info *cur)
-{
- struct thread_info *next = container_of(
- cur->node.next, struct thread_info, node);
- if (cur == next)
- // Nothing to do.
- return;
- asm volatile(
- " pushl $1f\n" // store return pc
- " pushl %%ebp\n" // backup %ebp
- " movl %%esp, (%%eax)\n" // cur->stackpos = %esp
- " movl (%%ecx), %%esp\n" // %esp = next->stackpos
- " popl %%ebp\n" // restore %ebp
- " retl\n" // restore pc
- "1:\n"
- : "+a"(cur), "+c"(next)
- :
- : "ebx", "edx", "esi", "edi", "cc", "memory");
-}
-
-// Last thing called from a thread (called on MainThread stack).
-static void
-__end_thread(struct thread_info *old)
-{
- hlist_del(&old->node);
- dprintf(DEBUG_thread, "\\%08x/ End thread\n", (u32)old);
- free(old);
- if (!have_threads())
- dprintf(1, "All threads complete.\n");
-}
-
-// Create a new thread and start executing 'func' in it.
-void
-run_thread(void (*func)(void*), void *data)
-{
- ASSERT32FLAT();
- if (! CONFIG_THREADS || ! ThreadControl)
- goto fail;
- struct thread_info *thread;
- thread = memalign_tmphigh(THREADSTACKSIZE, THREADSTACKSIZE);
- if (!thread)
- goto fail;
-
- dprintf(DEBUG_thread, "/%08x\\ Start thread\n", (u32)thread);
- thread->stackpos = (void*)thread + THREADSTACKSIZE;
- struct thread_info *cur = getCurThread();
- hlist_add_after(&thread->node, &cur->node);
- asm volatile(
- // Start thread
- " pushl $1f\n" // store return pc
- " pushl %%ebp\n" // backup %ebp
- " movl %%esp, (%%edx)\n" // cur->stackpos = %esp
- " movl (%%ebx), %%esp\n" // %esp = thread->stackpos
- " calll *%%ecx\n" // Call func
-
- // End thread
- " movl %%ebx, %%eax\n" // %eax = thread
- " movl 4(%%ebx), %%ebx\n" // %ebx = thread->node.next
- " movl (%5), %%esp\n" // %esp = MainThread.stackpos
- " calll %4\n" // call __end_thread(thread)
- " movl -4(%%ebx), %%esp\n" // %esp = next->stackpos
- " popl %%ebp\n" // restore %ebp
- " retl\n" // restore pc
- "1:\n"
- : "+a"(data), "+c"(func), "+b"(thread), "+d"(cur)
- : "m"(*(u8*)__end_thread), "m"(MainThread)
- : "esi", "edi", "cc", "memory");
- return;
-
-fail:
- func(data);
-}
-
-
-/****************************************************************
- * Thread helpers
- ****************************************************************/
-
-// Low-level irq enable.
-void VISIBLE16
-check_irqs(void)
-{
- if (!MODESEGMENT && !CanInterrupt) {
- // Can't enable interrupts (PIC and/or IVT not yet setup)
- cpu_relax();
- return;
- }
- if (need_hop_back()) {
- stack_hop_back(check_irqs, 0, 0);
- return;
- }
- if (MODE16)
- clock_poll_irq();
- asm volatile("sti ; nop ; rep ; nop ; cli ; cld" : : :"memory");
-}
-
-// Briefly permit irqs to occur.
-void
-yield(void)
-{
- if (MODESEGMENT || !CONFIG_THREADS) {
- check_irqs();
- return;
- }
- struct thread_info *cur = getCurThread();
- if (cur == &MainThread)
- // Permit irqs to fire
- check_irqs();
-
- // Switch to the next thread
- switch_next(cur);
-}
-
-void VISIBLE16
-wait_irq(void)
-{
- if (need_hop_back()) {
- stack_hop_back(wait_irq, 0, 0);
- return;
- }
- asm volatile("sti ; hlt ; cli ; cld": : :"memory");
-}
-
-// Wait for next irq to occur.
-void
-yield_toirq(void)
-{
- if (!CONFIG_HARDWARE_IRQ
- || (!MODESEGMENT && (have_threads() || !CanInterrupt))) {
- // Threads still active or irqs not available - do a yield instead.
- yield();
- return;
- }
- wait_irq();
-}
-
-// Wait for all threads (other than the main thread) to complete.
-void
-wait_threads(void)
-{
- ASSERT32FLAT();
- while (have_threads())
- yield();
-}
-
-void
-mutex_lock(struct mutex_s *mutex)
-{
- ASSERT32FLAT();
- if (! CONFIG_THREADS)
- return;
- while (mutex->isLocked)
- yield();
- mutex->isLocked = 1;
-}
-
-void
-mutex_unlock(struct mutex_s *mutex)
-{
- ASSERT32FLAT();
- if (! CONFIG_THREADS)
- return;
- mutex->isLocked = 0;
-}
-
-
-/****************************************************************
- * Thread preemption
- ****************************************************************/
-
-int CanPreempt VARFSEG;
-static u32 PreemptCount;
-
-// Turn on RTC irqs and arrange for them to check the 32bit threads.
-void
-start_preempt(void)
-{
- if (! threads_during_optionroms())
- return;
- CanPreempt = 1;
- PreemptCount = 0;
- rtc_use();
-}
-
-// Turn off RTC irqs / stop checking for thread execution.
-void
-finish_preempt(void)
-{
- if (! threads_during_optionroms()) {
- yield();
- return;
- }
- CanPreempt = 0;
- rtc_release();
- dprintf(9, "Done preempt - %d checks\n", PreemptCount);
- yield();
-}
-
-// Check if preemption is on, and wait for it to complete if so.
-int
-wait_preempt(void)
-{
- if (MODESEGMENT || !CONFIG_THREADS || !CanPreempt
- || getesp() < MAIN_STACK_MAX)
- return 0;
- while (CanPreempt)
- yield();
- return 1;
-}
-
-// Try to execute 32bit threads.
-void VISIBLE32INIT
-yield_preempt(void)
-{
- PreemptCount++;
- switch_next(&MainThread);
-}
-
-// 16bit code that checks if threads are pending and executes them if so.
-void
-check_preempt(void)
-{
- if (CONFIG_THREADS && GET_GLOBAL(CanPreempt) && have_threads())
- call32(yield_preempt, 0, 0);
-}
-
-
-/****************************************************************
- * call32 helper
- ****************************************************************/
-
-struct call32_params_s {
- void *func;
- u32 eax, edx, ecx;
-};
-
-u32 VISIBLE32FLAT
-call32_params_helper(struct call32_params_s *params)
-{
- return ((u32 (*)(u32, u32, u32))params->func)(
- params->eax, params->edx, params->ecx);
-}
-
-u32
-__call32_params(void *func, u32 eax, u32 edx, u32 ecx, u32 errret)
-{
- ASSERT16();
- struct call32_params_s params = {func, eax, edx, ecx};
- return call32(call32_params_helper, MAKE_FLATPTR(GET_SEG(SS), &params)
- , errret);
-}