qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] minor x86-64 corrections
@ 2005-01-21 20:33 Filip Navara
  2005-01-21 21:44 ` Fabrice Bellard
  0 siblings, 1 reply; 5+ messages in thread
From: Filip Navara @ 2005-01-21 20:33 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 390 bytes --]

Changelog:

2005-01-21 Filip Navara <navaraf@reactos.com>

* Add support for CR8 register.
* Don't throw exception when assigning zero to SS register
in 64-bit mode.

BTW, the callgate support for x86-64 in long mode is broken. See "AMD64 
Architecture Programmer’s Manual Volume 3: General-Purpose and System 
Instructions", page 90. Anybody cares to fix it?

Regards,
Filip

[-- Attachment #2: qemu-64-1.patch --]
[-- Type: text/plain, Size: 3834 bytes --]

Index: hw/apic.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/apic.c,v
retrieving revision 1.1
diff -u -r1.1 apic.c
--- hw/apic.c	3 Jan 2005 23:27:31 -0000	1.1
+++ hw/apic.c	21 Jan 2005 20:13:30 -0000
@@ -100,6 +100,18 @@
     return s->apicbase;
 }
 
+void cpu_set_apic_tpr(CPUState *env, uint8_t val)
+{
+    APICState *s = env->apic_state;
+    s->tpr = val;
+}
+
+uint8_t cpu_get_apic_tpr(CPUState *env)
+{
+    APICState *s = env->apic_state;
+    return s->tpr;
+}
+
 /* return -1 if no bit is set */
 static int get_highest_priority_int(uint32_t *tab)
 {
Index: target-i386/exec.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.20
diff -u -r1.20 exec.h
--- target-i386/exec.h	8 Jan 2005 18:58:29 -0000	1.20
+++ target-i386/exec.h	21 Jan 2005 20:23:30 -0000
@@ -167,6 +167,8 @@
 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 
                              int is_write, int is_user, int is_softmmu);
+void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
+uint8_t cpu_get_apic_tpr(CPUX86State *env);
 void tlb_fill(target_ulong addr, int is_write, int is_user, 
               void *retaddr);
 void __hidden cpu_lock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.40
diff -u -r1.40 helper.c
--- target-i386/helper.c	16 Jan 2005 23:35:43 -0000	1.40
+++ target-i386/helper.c	21 Jan 2005 20:13:30 -0000
@@ -1454,8 +1454,13 @@
     selector &= 0xffff;
     if ((selector & 0xfffc) == 0) {
         /* null selector case */
-        if (seg_reg == R_SS)
+        if (seg_reg == R_SS) {
+#ifdef TARGET_X86_64
+            if (env->hflags & HF_CS64_MASK)
+                return;
+#endif
             raise_exception_err(EXCP0D_GPF, 0);
+        }
         cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
     } else {
         
@@ -2156,6 +2161,11 @@
     case 4:
         cpu_x86_update_cr4(env, T0);
         break;
+#ifdef TARGET_X86_64
+    case 8:
+        cpu_set_apic_tpr(env, (T0 & 0xf) << 4);
+        break;
+#endif
     default:
         env->cr[reg] = T0;
         break;
Index: target-i386/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/op.c,v
retrieving revision 1.28
diff -u -r1.28 op.c
--- target-i386/op.c	9 Jan 2005 00:07:04 -0000	1.28
+++ target-i386/op.c	21 Jan 2005 20:13:30 -0000
@@ -1198,6 +1198,11 @@
     helper_movl_crN_T0(PARAM1);
 }
 
+void OPPROTO op_movtl_T0_cr7(void)
+{
+    T0 = (cpu_get_apic_tpr(env) & 0xf) >> 4;
+}
+
 /* DR registers access */
 void OPPROTO op_movl_drN_T0(void)
 {
Index: target-i386/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/translate.c,v
retrieving revision 1.41
diff -u -r1.41 translate.c
--- target-i386/translate.c	16 Jan 2005 01:07:28 -0000	1.41
+++ target-i386/translate.c	21 Jan 2005 20:13:30 -0000
@@ -5641,7 +5641,19 @@
                     gen_op_mov_reg_T0[ot][rm]();
                 }
                 break;
-                /* XXX: add CR8 for x86_64 */
+#ifdef TARGET_X86_64
+            case 8:
+                if (b & 2) {
+                    gen_op_mov_TN_reg[ot][0][rm]();
+                    gen_op_movl_crN_T0(reg);
+                    gen_jmp_im(s->pc - s->cs_base);
+                    gen_eob(s);
+                } else {
+                    gen_op_movtl_T0_cr7();
+                    gen_op_mov_reg_T0[ot][rm]();
+                }
+                break;
+#endif
             default:
                 goto illegal_op;
             }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] minor x86-64 corrections
  2005-01-21 20:33 [Qemu-devel] [PATCH] minor x86-64 corrections Filip Navara
@ 2005-01-21 21:44 ` Fabrice Bellard
  2005-01-21 22:07   ` Filip Navara
  0 siblings, 1 reply; 5+ messages in thread
From: Fabrice Bellard @ 2005-01-21 21:44 UTC (permalink / raw)
  To: qemu-devel

Filip Navara wrote:
> Changelog:
> 
> 2005-01-21 Filip Navara <navaraf@reactos.com>
> 
> * Add support for CR8 register.
> * Don't throw exception when assigning zero to SS register
> in 64-bit mode.
> 
> BTW, the callgate support for x86-64 in long mode is broken. See "AMD64 
> Architecture Programmer’s Manual Volume 3: General-Purpose and System 
> Instructions", page 90. Anybody cares to fix it?

No time yet. It would be interesting to find the problem for the Linux 
user code too.

> --- target-i386/helper.c	16 Jan 2005 23:35:43 -0000	1.40
> +++ target-i386/helper.c	21 Jan 2005 20:13:30 -0000
> @@ -1454,8 +1454,13 @@
>      selector &= 0xffff;
>      if ((selector & 0xfffc) == 0) {
>          /* null selector case */
> -        if (seg_reg == R_SS)
> +        if (seg_reg == R_SS) {
> +#ifdef TARGET_X86_64
> +            if (env->hflags & HF_CS64_MASK)
> +                return;
> +#endif
>              raise_exception_err(EXCP0D_GPF, 0);
> +        }
>          cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);

Maybe the SS segment cache should be set to zero ?

> +void OPPROTO op_movtl_T0_cr7(void)
> +{
> +    T0 = (cpu_get_apic_tpr(env) & 0xf) >> 4;
> +}

Why do you call it cr7 ?

Fabrice.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] minor x86-64 corrections
  2005-01-21 21:44 ` Fabrice Bellard
@ 2005-01-21 22:07   ` Filip Navara
  2005-01-21 22:27     ` Filip Navara
  0 siblings, 1 reply; 5+ messages in thread
From: Filip Navara @ 2005-01-21 22:07 UTC (permalink / raw)
  To: qemu-devel

Fabrice Bellard wrote:

> Filip Navara wrote:
>
>> Changelog:
>>
>> 2005-01-21 Filip Navara <navaraf@reactos.com>
>>
>> * Add support for CR8 register.
>> * Don't throw exception when assigning zero to SS register
>> in 64-bit mode.
>>
>> BTW, the callgate support for x86-64 in long mode is broken. See 
>> "AMD64 Architecture Programmer’s Manual Volume 3: General-Purpose and 
>> System Instructions", page 90. Anybody cares to fix it?
>
>
> No time yet. It would be interesting to find the problem for the Linux 
> user code too.

Ok, I'll try to fix it myself. BTW the same issue is present also in the 
protected mode JMP code.

>> +++ target-i386/helper.c    21 Jan 2005 20:13:30 -0000
>> @@ -1454,8 +1454,13 @@
>>      selector &= 0xffff;
>>      if ((selector & 0xfffc) == 0) {
>>          /* null selector case */
>> -        if (seg_reg == R_SS)
>> +        if (seg_reg == R_SS) {
>> +#ifdef TARGET_X86_64
>> +            if (env->hflags & HF_CS64_MASK)
>> +                return;
>> +#endif
>>              raise_exception_err(EXCP0D_GPF, 0);
>> +        }
>>          cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
>
> --- target-i386/helper.c    16 Jan 2005 23:35:43 -0000    1.40
>
> Maybe the SS segment cache should be set to zero ?

I'm not sure really, but I guess you're right.

MOV documentation:
... "It is possible to move a null segment selector value (0000–0003h) 
into the DS, ES, FS,
or GS register. This action does not cause a general protection fault, 
but a subsequent
reference to such a segment does cause a #GP exception. For more 
information about
segment selectors, see “Segment Selectors and Registers” on page 84." ...

GPF is exception is thrown if ... "The SS register was loaded with a 
null segment selector in non-64-bit mode or while CPL = 3." ...

>> +void OPPROTO op_movtl_T0_cr7(void)
>> +{
>> +    T0 = (cpu_get_apic_tpr(env) & 0xf) >> 4;
>> +}
>
> Why do you call it cr7 ? 

Actually that's a typo.

Filip Navara
navaraf@reactos.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH] minor x86-64 corrections
  2005-01-21 22:07   ` Filip Navara
@ 2005-01-21 22:27     ` Filip Navara
  0 siblings, 0 replies; 5+ messages in thread
From: Filip Navara @ 2005-01-21 22:27 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 782 bytes --]

[snip]

>> Maybe the SS segment cache should be set to zero ?
>
> I'm not sure really, but I guess you're right.
>
> MOV documentation:
> ... "It is possible to move a null segment selector value (0000–0003h) 
> into the DS, ES, FS,
> or GS register. This action does not cause a general protection fault, 
> but a subsequent
> reference to such a segment does cause a #GP exception. For more 
> information about
> segment selectors, see “Segment Selectors and Registers” on page 84." ...
>
> GPF is exception is thrown if ... "The SS register was loaded with a 
> null segment selector in non-64-bit mode or while CPL = 3." ...

I looked at the disassembly and it's called after setting up GDT and 
IDT. Does the attached patch look better?

Regards,
Filip

[-- Attachment #2: qemu-64-1.patch --]
[-- Type: text/plain, Size: 3863 bytes --]

Index: hw/apic.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/apic.c,v
retrieving revision 1.1
diff -u -r1.1 apic.c
--- hw/apic.c	3 Jan 2005 23:27:31 -0000	1.1
+++ hw/apic.c	21 Jan 2005 20:13:30 -0000
@@ -100,6 +100,18 @@
     return s->apicbase;
 }
 
+void cpu_set_apic_tpr(CPUState *env, uint8_t val)
+{
+    APICState *s = env->apic_state;
+    s->tpr = val;
+}
+
+uint8_t cpu_get_apic_tpr(CPUState *env)
+{
+    APICState *s = env->apic_state;
+    return s->tpr;
+}
+
 /* return -1 if no bit is set */
 static int get_highest_priority_int(uint32_t *tab)
 {
Index: target-i386/exec.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.20
diff -u -r1.20 exec.h
--- target-i386/exec.h	8 Jan 2005 18:58:29 -0000	1.20
+++ target-i386/exec.h	21 Jan 2005 20:23:30 -0000
@@ -167,6 +167,8 @@
 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 
                              int is_write, int is_user, int is_softmmu);
+void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
+uint8_t cpu_get_apic_tpr(CPUX86State *env);
 void tlb_fill(target_ulong addr, int is_write, int is_user, 
               void *retaddr);
 void __hidden cpu_lock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.40
diff -u -r1.40 helper.c
--- target-i386/helper.c	16 Jan 2005 23:35:43 -0000	1.40
+++ target-i386/helper.c	21 Jan 2005 22:18:01 -0000
@@ -1454,8 +1454,12 @@
     selector &= 0xffff;
     if ((selector & 0xfffc) == 0) {
         /* null selector case */
-        if (seg_reg == R_SS)
-            raise_exception_err(EXCP0D_GPF, 0);
+        if (seg_reg == R_SS) {
+#ifdef TARGET_X86_64
+            if (!env->hflags & HF_CS64_MASK)
+#endif
+                raise_exception_err(EXCP0D_GPF, 0);
+        }
         cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
     } else {
         
@@ -2156,6 +2160,11 @@
     case 4:
         cpu_x86_update_cr4(env, T0);
         break;
+#ifdef TARGET_X86_64
+    case 8:
+        cpu_set_apic_tpr(env, (T0 & 0xf) << 4);
+        break;
+#endif
     default:
         env->cr[reg] = T0;
         break;
Index: target-i386/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/op.c,v
retrieving revision 1.28
diff -u -r1.28 op.c
--- target-i386/op.c	9 Jan 2005 00:07:04 -0000	1.28
+++ target-i386/op.c	21 Jan 2005 22:09:18 -0000
@@ -1198,6 +1198,11 @@
     helper_movl_crN_T0(PARAM1);
 }
 
+void OPPROTO op_movtl_T0_cr8(void)
+{
+    T0 = (cpu_get_apic_tpr(env) & 0xf) >> 4;
+}
+
 /* DR registers access */
 void OPPROTO op_movl_drN_T0(void)
 {
Index: target-i386/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/translate.c,v
retrieving revision 1.41
diff -u -r1.41 translate.c
--- target-i386/translate.c	16 Jan 2005 01:07:28 -0000	1.41
+++ target-i386/translate.c	21 Jan 2005 22:09:23 -0000
@@ -5641,7 +5641,19 @@
                     gen_op_mov_reg_T0[ot][rm]();
                 }
                 break;
-                /* XXX: add CR8 for x86_64 */
+#ifdef TARGET_X86_64
+            case 8:
+                if (b & 2) {
+                    gen_op_mov_TN_reg[ot][0][rm]();
+                    gen_op_movl_crN_T0(reg);
+                    gen_jmp_im(s->pc - s->cs_base);
+                    gen_eob(s);
+                } else {
+                    gen_op_movtl_T0_cr8();
+                    gen_op_mov_reg_T0[ot][rm]();
+                }
+                break;
+#endif
             default:
                 goto illegal_op;
             }

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [Qemu-devel] [PATCH] minor x86-64 corrections
@ 2005-01-23 10:35 Filip Navara
  0 siblings, 0 replies; 5+ messages in thread
From: Filip Navara @ 2005-01-23 10:35 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 219 bytes --]

Now with fixed typos (CR7 -> CR8, 0xf -> 0xf0)...

Changelog:

2005-01-21 Filip Navara <navaraf@reactos.com>

* Add support for CR8 register.
* Don't throw exception when assigning zero to SS register
in 64-bit mode.



[-- Attachment #2: qemu-64-1.patch --]
[-- Type: text/plain, Size: 3864 bytes --]

Index: hw/apic.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/apic.c,v
retrieving revision 1.1
diff -u -r1.1 apic.c
--- hw/apic.c	3 Jan 2005 23:27:31 -0000	1.1
+++ hw/apic.c	21 Jan 2005 20:13:30 -0000
@@ -100,6 +100,18 @@
     return s->apicbase;
 }
 
+void cpu_set_apic_tpr(CPUState *env, uint8_t val)
+{
+    APICState *s = env->apic_state;
+    s->tpr = val;
+}
+
+uint8_t cpu_get_apic_tpr(CPUState *env)
+{
+    APICState *s = env->apic_state;
+    return s->tpr;
+}
+
 /* return -1 if no bit is set */
 static int get_highest_priority_int(uint32_t *tab)
 {
Index: target-i386/exec.h
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/exec.h,v
retrieving revision 1.20
diff -u -r1.20 exec.h
--- target-i386/exec.h	8 Jan 2005 18:58:29 -0000	1.20
+++ target-i386/exec.h	21 Jan 2005 20:23:30 -0000
@@ -167,6 +167,8 @@
 void cpu_x86_flush_tlb(CPUX86State *env, uint32_t addr);
 int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, 
                              int is_write, int is_user, int is_softmmu);
+void cpu_set_apic_tpr(CPUX86State *env, uint8_t val);
+uint8_t cpu_get_apic_tpr(CPUX86State *env);
 void tlb_fill(target_ulong addr, int is_write, int is_user, 
               void *retaddr);
 void __hidden cpu_lock(void);
Index: target-i386/helper.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/helper.c,v
retrieving revision 1.40
diff -u -r1.40 helper.c
--- target-i386/helper.c	16 Jan 2005 23:35:43 -0000	1.40
+++ target-i386/helper.c	21 Jan 2005 22:18:01 -0000
@@ -1454,8 +1454,12 @@
     selector &= 0xffff;
     if ((selector & 0xfffc) == 0) {
         /* null selector case */
-        if (seg_reg == R_SS)
-            raise_exception_err(EXCP0D_GPF, 0);
+        if (seg_reg == R_SS) {
+#ifdef TARGET_X86_64
+            if (!env->hflags & HF_CS64_MASK)
+#endif
+                raise_exception_err(EXCP0D_GPF, 0);
+        }
         cpu_x86_load_seg_cache(env, seg_reg, selector, 0, 0, 0);
     } else {
         
@@ -2156,6 +2160,11 @@
     case 4:
         cpu_x86_update_cr4(env, T0);
         break;
+#ifdef TARGET_X86_64
+    case 8:
+        cpu_set_apic_tpr(env, (T0 & 0xf) << 4);
+        break;
+#endif
     default:
         env->cr[reg] = T0;
         break;
Index: target-i386/op.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/op.c,v
retrieving revision 1.28
diff -u -r1.28 op.c
--- target-i386/op.c	9 Jan 2005 00:07:04 -0000	1.28
+++ target-i386/op.c	21 Jan 2005 22:09:18 -0000
@@ -1198,6 +1198,11 @@
     helper_movl_crN_T0(PARAM1);
 }
 
+void OPPROTO op_movtl_T0_cr8(void)
+{
+    T0 = (cpu_get_apic_tpr(env) & 0xf0) >> 4;
+}
+
 /* DR registers access */
 void OPPROTO op_movl_drN_T0(void)
 {
Index: target-i386/translate.c
===================================================================
RCS file: /cvsroot/qemu/qemu/target-i386/translate.c,v
retrieving revision 1.41
diff -u -r1.41 translate.c
--- target-i386/translate.c	16 Jan 2005 01:07:28 -0000	1.41
+++ target-i386/translate.c	21 Jan 2005 22:09:23 -0000
@@ -5641,7 +5641,19 @@
                     gen_op_mov_reg_T0[ot][rm]();
                 }
                 break;
-                /* XXX: add CR8 for x86_64 */
+#ifdef TARGET_X86_64
+            case 8:
+                if (b & 2) {
+                    gen_op_mov_TN_reg[ot][0][rm]();
+                    gen_op_movl_crN_T0(reg);
+                    gen_jmp_im(s->pc - s->cs_base);
+                    gen_eob(s);
+                } else {
+                    gen_op_movtl_T0_cr8();
+                    gen_op_mov_reg_T0[ot][rm]();
+                }
+                break;
+#endif
             default:
                 goto illegal_op;
             }

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2005-01-23 10:59 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-21 20:33 [Qemu-devel] [PATCH] minor x86-64 corrections Filip Navara
2005-01-21 21:44 ` Fabrice Bellard
2005-01-21 22:07   ` Filip Navara
2005-01-21 22:27     ` Filip Navara
  -- strict thread matches above, loose matches on Subject: below --
2005-01-23 10:35 Filip Navara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).