From 42ab9cc60c1199bcfbc59ed4648a111e2871dda4 Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 8 Mar 2011 01:24:42 +0000 Subject: [PATCH] misc QEMU fixes git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3351 42af7a65-404d-4744-a932-0658087f49c3 --- arch/x86/include/i486/arch.h | 38 +++++++++++++++++++++++++++++ arch/x86/src/i486/i486_utils.S | 26 +++++++++++--------- arch/x86/src/i486/up_initialstate.c | 8 ++++++ arch/x86/src/qemu/qemu_vectors.S | 34 +++++++++++++------------- 4 files changed, 77 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/i486/arch.h b/arch/x86/include/i486/arch.h index e2dde5555f..5910f08a15 100755 --- a/arch/x86/include/i486/arch.h +++ b/arch/x86/include/i486/arch.h @@ -163,6 +163,44 @@ static inline uint32_t up_getsp() return regval; } +/* Get segment registers */ + +static inline uint32_t up_getds() +{ + uint32_t regval; + + asm volatile( + "\tmov %%ds, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +static inline uint32_t up_getcs() +{ + uint32_t regval; + + asm volatile( + "\tmov %%cs, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + +static inline uint32_t up_getss() +{ + uint32_t regval; + + asm volatile( + "\tmov %%ss, %0\n" + : "=rm" (regval) + : + : "memory"); + return regval; +} + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/arch/x86/src/i486/i486_utils.S b/arch/x86/src/i486/i486_utils.S index eae168fbd6..9010b5a711 100644 --- a/arch/x86/src/i486/i486_utils.S +++ b/arch/x86/src/i486/i486_utils.S @@ -52,6 +52,8 @@ # define SYMBOL(s) s #endif +#define KSEG 0x10 + /**************************************************************************** * Nasm ****************************************************************************/ @@ -84,12 +86,12 @@ SYMBOL(gdt_flush): mov eax, [esp+4] /* Get the pointer to the GDT, passed as a parameter */ lgdt [eax] /* Load the new GDT pointer */ - mov ax, 0x10 /* 0x10 is the offset in the GDT to our data segment */ - mov ds, ax /* Load all data segment selectors */ - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax + mov $KSEG, ax /* KSEG is the offset in the GDT to our data segment */ + mov ax, ds /* Load all data segment selectors */ + mov ax, es + mov ax, fs + mov ax, gs + mov ax, ss jmp 0x08:.gflush /* 0x08 is the offset to our code segment: Far jump! */ .gflush: ret @@ -135,12 +137,12 @@ SYMBOL(gdt_flush): movl %eax, 4(%esp) /* Get the pointer to the GDT, passed as a parameter */ lgdt (%eax) /* Load the new GDT pointer */ - mov %ax, 0x10 /* 0x10 is the offset in the GDT to our data segment */ - mov %ds, %ax /* Load all data segment selectors */ - mov %es, %ax - mov %fs, %ax - mov %gs, %ax - mov %ss, %ax + mov $KSEG, %ax /* KSEG is the offset in the GDT to our data segment */ + mov %ax, %ds /* Load all data segment selectors */ + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss jmp $0x08, $.Lgflush /* 0x08 is the offset to our code segment: Far jump! */ .Lgflush: ret diff --git a/arch/x86/src/i486/up_initialstate.c b/arch/x86/src/i486/up_initialstate.c index 6e7417d5c3..1a13b89915 100644 --- a/arch/x86/src/i486/up_initialstate.c +++ b/arch/x86/src/i486/up_initialstate.c @@ -93,6 +93,14 @@ void up_initial_state(_TCB *tcb) xcp->regs[REG_EIP] = (uint32_t)tcb->start; + /* Set up the segment registers... assume the same segment as the caller. + * That is not a good assumption in the long run. + */ + + xcp->regs[REG_DS] = up_getds(); + xcp->regs[REG_CS] = up_getcs(); + xcp->regs[REG_SS] = up_getss(); + /* Enable or disable interrupts, based on user configuration. If the IF * bit is set, maskable interrupts will be enabled. */ diff --git a/arch/x86/src/qemu/qemu_vectors.S b/arch/x86/src/qemu/qemu_vectors.S index 6795203e26..55aabaf39a 100755 --- a/arch/x86/src/qemu/qemu_vectors.S +++ b/arch/x86/src/qemu/qemu_vectors.S @@ -408,14 +408,14 @@ isr_common: /* trace 'S' */ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */ - mov %ax, %ds /* Lower 16-bits of eax = ds. */ + mov %ds, %ax /* Lower 16-bits of eax = ds. */ pushl %eax /* Save the data segment descriptor */ - mov %ax, KSEG /* Load the kernel data segment descriptor */ - mov %ds, %ax - mov %es, %ax - mov %fs, %ax - mov %gs, %ax + mov $KSEG, %ax /* Load the kernel data segment descriptor */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs /* The current value of the SP points to the beginning of the state save * structure. Save that on the stack as the input parameter to isr_handler. @@ -446,14 +446,14 @@ irq_common: /* trace 'R' */ pusha /* Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax */ - mov %ax, %ds /* Lower 16-bits of eax = ds. */ + mov %ds, %ax /* Lower 16-bits of eax = ds. */ push %eax /* Save the data segment descriptor */ - mov %ax, KSEG /* Load the kernel data segment descriptor */ - mov %ds, %ax - mov %es, %ax - mov %fs, %ax - mov %gs, %ax + mov $KSEG, %ax /* Load the kernel data segment descriptor */ + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs /* The current value of the SP points to the beginning of the state save * structure. Save that on the stack as the input parameter to irq_handler. @@ -488,13 +488,13 @@ irq_common: .Lnoswitch: pop %ebx /* Reload the original data segment descriptor */ - mov %ds, %bx - mov %es, %bx - mov %fs, %bx - mov %gs, %bx + mov %bx, %ds + mov %bx, %es + mov %bx, %fs + mov %bx, %gs popa /* Pops edi,esi,ebp... */ - add %esp, 8 /* Cleans up the pushed error code and pushed ISR number */ + add $8, %esp /* Cleans up the pushed error code and pushed ISR number */ sti iret /* Pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP */ #ifndef __CYGWIN__