1 /////////////////////////////////////////////////////////////////////////
2 // $Id: protect_ctrl.cc,v 1.58 2007/03/23 14:50:45 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2001 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #define NEED_CPU_REG_SHORTCUTS 1
31 #define LOG_THIS BX_CPU_THIS_PTR
33 void BX_CPU_C::ARPL_EwGw(bxInstruction_c
*i
)
35 Bit16u op2_16
, op1_16
;
37 if (protected_mode()) {
38 /* op1_16 is a register or memory reference */
40 op1_16
= BX_READ_16BIT_REG(i
->rm());
43 /* pointer, segment address pair */
44 read_RMW_virtual_word(i
->seg(), RMAddr(i
), &op1_16
);
47 op2_16
= BX_READ_16BIT_REG(i
->nnn());
49 if ((op1_16
& 0x03) < (op2_16
& 0x03)) {
50 op1_16
= (op1_16
& 0xfffc) | (op2_16
& 0x03);
51 /* now write back to destination */
54 // if 32bit opsize, then 0xff3f is or'd into
55 // upper 16bits of register
56 Bit32u op1_32
= BX_READ_32BIT_REG(i
->rm());
57 op1_32
= (op1_32
& 0xffff0000) | op1_16
;
59 BX_WRITE_32BIT_REGZ(i
->rm(), op1_32
);
62 BX_WRITE_16BIT_REG(i
->rm(), op1_16
);
66 write_RMW_virtual_word(op1_16
);
75 BX_DEBUG(("ARPL: not recognized in real or virtual-8086 mode"));
80 void BX_CPU_C::LAR_GvEw(bxInstruction_c
*i
)
82 /* for 16 bit operand size mode */
84 bx_descriptor_t descriptor
;
85 bx_selector_t selector
;
86 Bit32u dword1
, dword2
;
88 if (real_mode() || v8086_mode()) {
89 BX_ERROR(("LAR: not recognized in real or virtual-8086 mode"));
95 raw_selector
= BX_READ_16BIT_REG(i
->rm());
98 /* pointer, segment address pair */
99 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
102 /* if selector null, clear ZF and done */
103 if ((raw_selector
& 0xfffc) == 0) {
108 parse_selector(raw_selector
, &selector
);
110 if (!fetch_raw_descriptor2(&selector
, &dword1
, &dword2
)) {
111 /* not within descriptor table */
116 parse_descriptor(dword1
, dword2
, &descriptor
);
118 if (descriptor
.valid
==0) {
123 /* if source selector is visible at CPL & RPL,
124 * within the descriptor table, and of type accepted by LAR instruction,
125 * then load register with segment limit and set ZF
128 if (descriptor
.segment
) { /* normal segment */
129 if (IS_CODE_SEGMENT(descriptor
.type
) && IS_CODE_SEGMENT_CONFORMING(descriptor
.type
)) {
130 /* ignore DPL for conforming segments */
133 if ((descriptor
.dpl
<CPL
) || (descriptor
.dpl
<selector
.rpl
)) {
140 /* masked by 00FxFF00, where x is undefined */
141 BX_WRITE_32BIT_REGZ(i
->nnn(), dword2
& 0x00ffff00);
144 BX_WRITE_16BIT_REG(i
->nnn(), dword2
& 0xff00);
148 else { /* system or gate segment */
149 switch (descriptor
.type
) {
150 case BX_SYS_SEGMENT_AVAIL_286_TSS
:
151 case BX_SYS_SEGMENT_LDT
:
152 case BX_SYS_SEGMENT_BUSY_286_TSS
:
153 case BX_286_CALL_GATE
:
155 #if BX_CPU_LEVEL >= 3
156 case BX_SYS_SEGMENT_AVAIL_386_TSS
:
157 case BX_SYS_SEGMENT_BUSY_386_TSS
:
158 case BX_386_CALL_GATE
:
161 default: /* rest not accepted types to LAR */
162 BX_DEBUG(("lar(): not accepted type"));
167 if ((descriptor
.dpl
<CPL
) || (descriptor
.dpl
<selector
.rpl
)) {
173 /* masked by 00FxFF00, where x is undefined ? */
174 BX_WRITE_32BIT_REGZ(i
->nnn(), dword2
& 0x00ffff00);
177 BX_WRITE_16BIT_REG(i
->nnn(), dword2
& 0xff00);
182 void BX_CPU_C::LSL_GvEw(bxInstruction_c
*i
)
184 /* for 16 bit operand size mode */
187 bx_selector_t selector
;
188 Bit32u dword1
, dword2
;
189 Bit32u descriptor_dpl
;
191 if (real_mode() || v8086_mode()) {
192 BX_ERROR(("LSL: not recognized in real or virtual-8086 mode"));
197 raw_selector
= BX_READ_16BIT_REG(i
->rm());
200 /* pointer, segment address pair */
201 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
204 /* if selector null, clear ZF and done */
205 if ((raw_selector
& 0xfffc) == 0) {
210 parse_selector(raw_selector
, &selector
);
212 if (!fetch_raw_descriptor2(&selector
, &dword1
, &dword2
)) {
213 /* not within descriptor table */
218 descriptor_dpl
= (dword2
>> 13) & 0x03;
220 if ((dword2
& 0x00001000) == 0) { // system segment
221 Bit32u type
= (dword2
>> 8) & 0x0000000f;
223 case BX_SYS_SEGMENT_AVAIL_286_TSS
:
224 case BX_SYS_SEGMENT_BUSY_286_TSS
:
225 case BX_SYS_SEGMENT_LDT
:
226 case BX_SYS_SEGMENT_AVAIL_386_TSS
:
227 case BX_SYS_SEGMENT_BUSY_386_TSS
:
228 limit32
= (dword1
& 0x0000ffff) | (dword2
& 0x000f0000);
229 if (dword2
& 0x00800000)
230 limit32
= (limit32
<< 12) | 0x00000fff;
231 if ((descriptor_dpl
<CPL
) || (descriptor_dpl
<selector
.rpl
)) {
241 else { // data & code segment
242 limit32
= (dword1
& 0x0000ffff) | (dword2
& 0x000f0000);
243 if (dword2
& 0x00800000)
244 limit32
= (limit32
<< 12) | 0x00000fff;
245 if ((dword2
& 0x00000c00) == 0x00000c00) {
246 // conforming code segment, no check done
250 if ((descriptor_dpl
<CPL
) || (descriptor_dpl
<selector
.rpl
)) {
258 /* all checks pass, limit32 is now byte granular, write to op1 */
262 BX_WRITE_32BIT_REGZ(i
->nnn(), limit32
);
265 // chop off upper 16 bits
266 BX_WRITE_16BIT_REG(i
->nnn(), (Bit16u
) limit32
);
270 void BX_CPU_C::SLDT_Ew(bxInstruction_c
*i
)
272 if (real_mode() || v8086_mode()) {
273 BX_ERROR(("SLDT: not recognized in real or virtual-8086 mode"));
277 Bit16u val16
= BX_CPU_THIS_PTR ldtr
.selector
.value
;
280 BX_WRITE_32BIT_REGZ(i
->rm(), val16
);
283 BX_WRITE_16BIT_REG(i
->rm(), val16
);
287 write_virtual_word(i
->seg(), RMAddr(i
), &val16
);
291 void BX_CPU_C::STR_Ew(bxInstruction_c
*i
)
293 if (real_mode() || v8086_mode()) {
294 BX_ERROR(("STR: not recognized in real or virtual-8086 mode"));
298 Bit16u val16
= BX_CPU_THIS_PTR tr
.selector
.value
;
301 BX_WRITE_32BIT_REGZ(i
->rm(), val16
);
304 BX_WRITE_16BIT_REG(i
->rm(), val16
);
308 write_virtual_word(i
->seg(), RMAddr(i
), &val16
);
312 void BX_CPU_C::LLDT_Ew(bxInstruction_c
*i
)
315 bx_descriptor_t descriptor
;
316 bx_selector_t selector
;
318 Bit32u dword1
, dword2
;
320 if (real_mode() || v8086_mode()) {
321 BX_ERROR(("LLDT: not recognized in real or virtual-8086 mode"));
325 /* #GP(0) if the current privilege level is not 0 */
327 BX_ERROR(("LLDT: The current priveledge level is not 0"));
328 exception(BX_GP_EXCEPTION
, 0, 0);
332 raw_selector
= BX_READ_16BIT_REG(i
->rm());
335 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
338 invalidate_prefetch_q();
340 /* if selector is NULL, invalidate and done */
341 if ((raw_selector
& 0xfffc) == 0) {
342 BX_CPU_THIS_PTR ldtr
.selector
.value
= raw_selector
;
343 BX_CPU_THIS_PTR ldtr
.cache
.valid
= 0;
347 /* parse fields in selector */
348 parse_selector(raw_selector
, &selector
);
350 // #GP(selector) if the selector operand does not point into GDT
351 if (selector
.ti
!= 0) {
352 BX_ERROR(("LLDT: selector.ti != 0"));
353 exception(BX_GP_EXCEPTION
, raw_selector
& 0xfffc, 0);
356 /* fetch 2 dwords of descriptor; call handles out of limits checks */
357 fetch_raw_descriptor(&selector
, &dword1
, &dword2
, BX_GP_EXCEPTION
);
358 parse_descriptor(dword1
, dword2
, &descriptor
);
360 #if BX_SUPPORT_X86_64
361 if (BX_CPU_THIS_PTR cpu_mode
== BX_MODE_LONG_64
) {
362 // set upper 32 bits of ldt base
364 access_linear(BX_CPU_THIS_PTR gdtr
.base
+ selector
.index
*8 + 8, 4, 0, BX_READ
, &dword3
);
365 descriptor
.u
.system
.base
|= ((Bit64u
)dword3
<< 32);
366 BX_INFO(("64 bit LDT base = 0x%08x%08x",
367 GET32H(descriptor
.u
.system
.base
), GET32L(descriptor
.u
.system
.base
)));
371 /* if selector doesn't point to an LDT descriptor #GP(selector) */
372 if (descriptor
.valid
== 0 || descriptor
.segment
||
373 descriptor
.type
!= BX_SYS_SEGMENT_LDT
)
375 BX_ERROR(("LLDT: doesn't point to an LDT descriptor!"));
376 exception(BX_GP_EXCEPTION
, raw_selector
& 0xfffc, 0);
379 /* #NP(selector) if LDT descriptor is not present */
380 if (! IS_PRESENT(descriptor
)) {
381 BX_ERROR(("LLDT: LDT descriptor not present!"));
382 exception(BX_NP_EXCEPTION
, raw_selector
& 0xfffc, 0);
385 BX_CPU_THIS_PTR ldtr
.selector
= selector
;
386 BX_CPU_THIS_PTR ldtr
.cache
= descriptor
;
387 BX_CPU_THIS_PTR ldtr
.cache
.valid
= 1;
390 void BX_CPU_C::LTR_Ew(bxInstruction_c
*i
)
392 bx_descriptor_t descriptor
;
393 bx_selector_t selector
;
395 Bit32u dword1
, dword2
;
397 if (real_mode() || v8086_mode()) {
398 BX_ERROR(("LTR: not recognized in real or virtual-8086 mode"));
402 invalidate_prefetch_q();
404 /* #GP(0) if the current privilege level is not 0 */
406 BX_ERROR(("LTR: The current priveledge level is not 0"));
407 exception(BX_GP_EXCEPTION
, 0, 0);
411 raw_selector
= BX_READ_16BIT_REG(i
->rm());
414 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
417 /* if selector is NULL, invalidate and done */
418 if ((raw_selector
& BX_SELECTOR_RPL_MASK
) == 0) {
419 BX_ERROR(("LTR: loading with NULL selector!"));
420 exception(BX_GP_EXCEPTION
, 0, 0);
423 /* parse fields in selector, then check for null selector */
424 parse_selector(raw_selector
, &selector
);
427 BX_ERROR(("LTR: selector.ti != 0"));
428 exception(BX_GP_EXCEPTION
, raw_selector
& 0xfffc, 0);
431 /* fetch 2 dwords of descriptor; call handles out of limits checks */
432 fetch_raw_descriptor(&selector
, &dword1
, &dword2
, BX_GP_EXCEPTION
);
433 parse_descriptor(dword1
, dword2
, &descriptor
);
435 #if BX_SUPPORT_X86_64
436 if (BX_CPU_THIS_PTR cpu_mode
== BX_MODE_LONG_64
) {
437 // set upper 32 bits of tss base
439 access_linear(BX_CPU_THIS_PTR gdtr
.base
+ selector
.index
*8 + 8, 4, 0, BX_READ
, &dword3
);
440 descriptor
.u
.system
.base
|= ((Bit64u
)dword3
<< 32);
441 BX_DEBUG(("64 bit TSS base = 0x%08x%08x",
442 GET32H(descriptor
.u
.system
.base
), GET32L(descriptor
.u
.system
.base
)));
446 /* #GP(selector) if object is not a TSS or is already busy */
447 if (descriptor
.valid
==0 || descriptor
.segment
||
448 (descriptor
.type
!=BX_SYS_SEGMENT_AVAIL_286_TSS
&&
449 descriptor
.type
!=BX_SYS_SEGMENT_AVAIL_386_TSS
))
451 BX_ERROR(("LTR: doesn't point to an available TSS descriptor!"));
452 exception(BX_GP_EXCEPTION
, raw_selector
& 0xfffc, 0);
455 /* #NP(selector) if TSS descriptor is not present */
456 if (! IS_PRESENT(descriptor
)) {
457 BX_ERROR(("LTR: LDT descriptor not present!"));
458 exception(BX_NP_EXCEPTION
, raw_selector
& 0xfffc, 0);
461 BX_CPU_THIS_PTR tr
.selector
= selector
;
462 BX_CPU_THIS_PTR tr
.cache
= descriptor
;
463 BX_CPU_THIS_PTR tr
.cache
.valid
= 1;
464 // tr.cache.type should not have busy bit, or it would not get
465 // through the conditions above.
466 BX_ASSERT((BX_CPU_THIS_PTR tr
.cache
.type
& 2) == 0);
469 dword2
|= 0x00000200; /* set busy bit */
470 access_linear(BX_CPU_THIS_PTR gdtr
.base
+ selector
.index
*8 + 4, 4, 0,
474 void BX_CPU_C::VERR_Ew(bxInstruction_c
*i
)
476 /* for 16 bit operand size mode */
478 bx_descriptor_t descriptor
;
479 bx_selector_t selector
;
480 Bit32u dword1
, dword2
;
482 if (real_mode() || v8086_mode()) {
483 BX_ERROR(("VERR: not recognized in real or virtual-8086 mode"));
488 raw_selector
= BX_READ_16BIT_REG(i
->rm());
491 /* pointer, segment address pair */
492 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
495 /* if selector null, clear ZF and done */
496 if ((raw_selector
& 0xfffc) == 0) {
497 BX_DEBUG(("VERR: null selector"));
502 /* if source selector is visible at CPL & RPL,
503 * within the descriptor table, and of type accepted by VERR instruction,
504 * then load register with segment limit and set ZF */
505 parse_selector(raw_selector
, &selector
);
507 if (!fetch_raw_descriptor2(&selector
, &dword1
, &dword2
)) {
508 /* not within descriptor table */
509 BX_DEBUG(("VERR: not within descriptor table"));
514 parse_descriptor(dword1
, dword2
, &descriptor
);
516 if (descriptor
.segment
==0) { /* system or gate descriptor */
517 BX_DEBUG(("VERR: system descriptor"));
518 clear_ZF(); /* inaccessible */
522 if (descriptor
.valid
==0) {
523 BX_DEBUG(("VERR: valid bit cleared"));
524 clear_ZF(); /* inaccessible */
528 /* normal data/code segment */
529 if (IS_CODE_SEGMENT(descriptor
.type
)) { /* code segment */
530 /* ignore DPL for readable conforming segments */
531 if (IS_CODE_SEGMENT_CONFORMING(descriptor
.type
) &&
532 IS_CODE_SEGMENT_READABLE(descriptor
.type
))
534 BX_DEBUG(("VERR: conforming code, OK"));
535 assert_ZF(); /* accessible */
538 if (!IS_CODE_SEGMENT_READABLE(descriptor
.type
)) {
539 BX_DEBUG(("VERR: code not readable"));
540 clear_ZF(); /* inaccessible */
543 /* readable, non-conforming code segment */
544 if ((descriptor
.dpl
<CPL
) || (descriptor
.dpl
<selector
.rpl
)) {
545 BX_DEBUG(("VERR: non-conforming code not withing priv level"));
546 clear_ZF(); /* inaccessible */
550 assert_ZF(); /* accessible */
552 else { /* data segment */
553 if ((descriptor
.dpl
<CPL
) || (descriptor
.dpl
<selector
.rpl
)) {
554 BX_DEBUG(("VERR: data seg not withing priv level"));
555 clear_ZF(); /* not accessible */
558 assert_ZF(); /* accessible */
562 void BX_CPU_C::VERW_Ew(bxInstruction_c
*i
)
564 /* for 16 bit operand size mode */
566 bx_descriptor_t descriptor
;
567 bx_selector_t selector
;
568 Bit32u dword1
, dword2
;
570 if (real_mode() || v8086_mode()) {
571 BX_ERROR(("VERW: not recognized in real or virtual-8086 mode"));
576 raw_selector
= BX_READ_16BIT_REG(i
->rm());
579 /* pointer, segment address pair */
580 read_virtual_word(i
->seg(), RMAddr(i
), &raw_selector
);
583 /* if selector null, clear ZF and done */
584 if ((raw_selector
& 0xfffc) == 0) {
585 BX_DEBUG(("VERW: null selector"));
590 /* if source selector is visible at CPL & RPL,
591 * within the descriptor table, and of type accepted by VERW instruction,
592 * then load register with segment limit and set ZF */
593 parse_selector(raw_selector
, &selector
);
595 if (!fetch_raw_descriptor2(&selector
, &dword1
, &dword2
)) {
596 /* not within descriptor table */
597 BX_DEBUG(("VERW: not within descriptor table"));
602 parse_descriptor(dword1
, dword2
, &descriptor
);
604 /* rule out system segments & code segments */
605 if (descriptor
.segment
==0 || IS_CODE_SEGMENT(descriptor
.type
)) {
606 BX_DEBUG(("VERW: system seg or code"));
611 if (descriptor
.valid
==0) {
612 BX_DEBUG(("VERW: valid bit cleared"));
618 if (IS_DATA_SEGMENT_WRITEABLE(descriptor
.type
)) { /* writable */
619 if ((descriptor
.dpl
<CPL
) || (descriptor
.dpl
<selector
.rpl
)) {
620 BX_DEBUG(("VERW: writable data seg not within priv level"));
621 clear_ZF(); /* not accessible */
624 assert_ZF(); /* accessible */
628 BX_DEBUG(("VERW: data seg not writable"));
629 clear_ZF(); /* not accessible */
632 void BX_CPU_C::SGDT_Ms(bxInstruction_c
*i
)
634 Bit16u limit_16
= BX_CPU_THIS_PTR gdtr
.limit
;
635 Bit32u base_32
= BX_CPU_THIS_PTR gdtr
.base
;
637 write_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
638 write_virtual_dword(i
->seg(), RMAddr(i
)+2, &base_32
);
641 void BX_CPU_C::SIDT_Ms(bxInstruction_c
*i
)
643 Bit16u limit_16
= BX_CPU_THIS_PTR idtr
.limit
;
644 Bit32u base_32
= BX_CPU_THIS_PTR idtr
.base
;
646 write_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
647 write_virtual_dword(i
->seg(), RMAddr(i
)+2, &base_32
);
650 void BX_CPU_C::LGDT_Ms(bxInstruction_c
*i
)
653 BX_ERROR(("LGDT: not recognized in virtual-8086 mode"));
654 exception(BX_GP_EXCEPTION
, 0, 0);
657 if (!real_mode() && CPL
!=0) {
658 BX_ERROR(("LGDT: CPL!=0 in protected mode"));
659 exception(BX_GP_EXCEPTION
, 0, 0);
662 invalidate_prefetch_q();
664 #if BX_CPU_LEVEL >= 3
669 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
670 read_virtual_dword(i
->seg(), RMAddr(i
) + 2, &base0_31
);
672 BX_CPU_THIS_PTR gdtr
.limit
= limit_16
;
673 BX_CPU_THIS_PTR gdtr
.base
= base0_31
;
678 Bit16u limit_16
, base0_15
;
681 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
682 read_virtual_word(i
->seg(), RMAddr(i
) + 2, &base0_15
);
683 read_virtual_byte(i
->seg(), RMAddr(i
) + 4, &base16_23
);
685 /* ignore high 8 bits */
686 BX_CPU_THIS_PTR gdtr
.limit
= limit_16
;
687 BX_CPU_THIS_PTR gdtr
.base
= (base16_23
<< 16) | base0_15
;
691 void BX_CPU_C::LIDT_Ms(bxInstruction_c
*i
)
694 BX_ERROR(("LIDT: not recognized in virtual-8086 mode"));
695 exception(BX_GP_EXCEPTION
, 0, 0);
698 if (!real_mode() && CPL
!=0) {
699 BX_ERROR(("LIDT: CPL!=0 in protected mode"));
700 exception(BX_GP_EXCEPTION
, 0, 0);
703 invalidate_prefetch_q();
708 #if BX_CPU_LEVEL >= 3
710 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
711 read_virtual_dword(i
->seg(), RMAddr(i
) + 2, &base_32
);
713 BX_CPU_THIS_PTR idtr
.limit
= limit_16
;
714 BX_CPU_THIS_PTR idtr
.base
= base_32
;
719 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
720 read_virtual_dword(i
->seg(), RMAddr(i
) + 2, &base_32
);
722 BX_CPU_THIS_PTR idtr
.limit
= limit_16
;
723 BX_CPU_THIS_PTR idtr
.base
= base_32
& 0x00ffffff; /* ignore upper 8 bits */
727 #if BX_SUPPORT_X86_64
729 void BX_CPU_C::SGDT64_Ms(bxInstruction_c
*i
)
731 Bit16u limit_16
= BX_CPU_THIS_PTR gdtr
.limit
;
732 Bit64u base_64
= BX_CPU_THIS_PTR gdtr
.base
;
734 write_virtual_word (i
->seg(), RMAddr(i
), &limit_16
);
735 write_virtual_qword(i
->seg(), RMAddr(i
)+2, &base_64
);
738 void BX_CPU_C::SIDT64_Ms(bxInstruction_c
*i
)
740 Bit16u limit_16
= BX_CPU_THIS_PTR idtr
.limit
;
741 Bit64u base_64
= BX_CPU_THIS_PTR idtr
.base
;
743 write_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
744 write_virtual_qword(i
->seg(), RMAddr(i
)+2, &base_64
);
747 void BX_CPU_C::LGDT64_Ms(bxInstruction_c
*i
)
749 BX_ASSERT(protected_mode());
751 /* operand might be a register or memory reference */
753 BX_ERROR(("LGDT64_Ms: must be memory reference"));
758 BX_ERROR(("LGDT64_Ms: CPL != 0 in long mode"));
759 exception(BX_GP_EXCEPTION
, 0, 0);
762 invalidate_prefetch_q();
767 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
768 read_virtual_qword(i
->seg(), RMAddr(i
) + 2, &base_64
);
770 BX_CPU_THIS_PTR gdtr
.limit
= limit_16
;
771 BX_CPU_THIS_PTR gdtr
.base
= base_64
;
774 void BX_CPU_C::LIDT64_Ms(bxInstruction_c
*i
)
776 BX_ASSERT(protected_mode());
779 BX_ERROR(("LIDT64_Ms: CPL != 0 in long mode"));
780 exception(BX_GP_EXCEPTION
, 0, 0);
783 invalidate_prefetch_q();
788 read_virtual_word(i
->seg(), RMAddr(i
), &limit_16
);
789 read_virtual_qword(i
->seg(), RMAddr(i
) + 2, &base_64
);
791 BX_CPU_THIS_PTR idtr
.limit
= limit_16
;
792 BX_CPU_THIS_PTR idtr
.base
= base_64
;