2 * x86_64 cpu init and loop
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19 #ifndef TARGET_ARCH_CPU_H
20 #define TARGET_ARCH_CPU_H
22 #include "target_arch.h"
23 #include "signal-common.h"
25 #define TARGET_DEFAULT_CPU_MODEL "qemu64"
27 static inline void target_cpu_init(CPUX86State
*env
,
28 struct target_pt_regs
*regs
)
32 env
->cr
[0] = CR0_PG_MASK
| CR0_WP_MASK
| CR0_PE_MASK
;
33 env
->hflags
|= HF_PE_MASK
| HF_CPL_MASK
;
34 if (env
->features
[FEAT_1_EDX
] & CPUID_SSE
) {
35 env
->cr
[4] |= CR4_OSFXSR_MASK
;
36 env
->hflags
|= HF_OSFXSR_MASK
;
39 /* enable 64 bit mode if possible */
40 if (!(env
->features
[FEAT_8000_0001_EDX
] & CPUID_EXT2_LM
)) {
41 fprintf(stderr
, "The selected x86 CPU does not support 64 bit mode\n");
44 env
->cr
[4] |= CR4_PAE_MASK
;
45 env
->efer
|= MSR_EFER_LMA
| MSR_EFER_LME
;
46 env
->hflags
|= HF_LMA_MASK
;
48 /* flags setup : we activate the IRQs by default as in user mode */
49 env
->eflags
|= IF_MASK
;
52 env
->regs
[R_EAX
] = regs
->rax
;
53 env
->regs
[R_EBX
] = regs
->rbx
;
54 env
->regs
[R_ECX
] = regs
->rcx
;
55 env
->regs
[R_EDX
] = regs
->rdx
;
56 env
->regs
[R_ESI
] = regs
->rsi
;
57 env
->regs
[R_EDI
] = regs
->rdi
;
58 env
->regs
[R_EBP
] = regs
->rbp
;
59 env
->regs
[R_ESP
] = regs
->rsp
;
65 env
->idt
.base
= target_mmap(0, sizeof(uint64_t) * (env
->idt
.limit
+ 1),
66 PROT_READ
| PROT_WRITE
, MAP_ANONYMOUS
| MAP_PRIVATE
, -1, 0);
67 bsd_x86_64_set_idt_base(env
->idt
.base
);
68 bsd_x86_64_set_idt(0, 0);
69 bsd_x86_64_set_idt(1, 0);
70 bsd_x86_64_set_idt(2, 0);
71 bsd_x86_64_set_idt(3, 3);
72 bsd_x86_64_set_idt(4, 3);
73 bsd_x86_64_set_idt(5, 0);
74 bsd_x86_64_set_idt(6, 0);
75 bsd_x86_64_set_idt(7, 0);
76 bsd_x86_64_set_idt(8, 0);
77 bsd_x86_64_set_idt(9, 0);
78 bsd_x86_64_set_idt(10, 0);
79 bsd_x86_64_set_idt(11, 0);
80 bsd_x86_64_set_idt(12, 0);
81 bsd_x86_64_set_idt(13, 0);
82 bsd_x86_64_set_idt(14, 0);
83 bsd_x86_64_set_idt(15, 0);
84 bsd_x86_64_set_idt(16, 0);
85 bsd_x86_64_set_idt(17, 0);
86 bsd_x86_64_set_idt(18, 0);
87 bsd_x86_64_set_idt(19, 0);
88 bsd_x86_64_set_idt(0x80, 3);
91 env
->gdt
.base
= target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES
,
92 PROT_READ
| PROT_WRITE
, MAP_ANONYMOUS
| MAP_PRIVATE
, -1, 0);
93 env
->gdt
.limit
= sizeof(uint64_t) * TARGET_GDT_ENTRIES
- 1;
94 gdt_table
= g2h_untagged(env
->gdt
.base
);
96 /* 64 bit code segment */
97 bsd_x86_64_write_dt(&gdt_table
[__USER_CS
>> 3], 0, 0xfffff,
98 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
| DESC_S_MASK
| DESC_L_MASK
99 | (3 << DESC_DPL_SHIFT
) | (0xa << DESC_TYPE_SHIFT
));
101 bsd_x86_64_write_dt(&gdt_table
[__USER_DS
>> 3], 0, 0xfffff,
102 DESC_G_MASK
| DESC_B_MASK
| DESC_P_MASK
| DESC_S_MASK
|
103 (3 << DESC_DPL_SHIFT
) | (0x2 << DESC_TYPE_SHIFT
));
105 cpu_x86_load_seg(env
, R_CS
, __USER_CS
);
106 cpu_x86_load_seg(env
, R_SS
, __USER_DS
);
107 cpu_x86_load_seg(env
, R_DS
, 0);
108 cpu_x86_load_seg(env
, R_ES
, 0);
109 cpu_x86_load_seg(env
, R_FS
, 0);
110 cpu_x86_load_seg(env
, R_GS
, 0);
113 static inline void target_cpu_loop(CPUX86State
*env
)
115 CPUState
*cs
= env_cpu(env
);
118 /* target_siginfo_t info; */
122 trapnr
= cpu_exec(cs
);
124 process_queued_cpu_work(cs
);
128 /* syscall from syscall instruction */
129 env
->regs
[R_EAX
] = do_freebsd_syscall(env
,
137 env
->eip
= env
->exception_next_eip
;
138 if (((abi_ulong
)env
->regs
[R_EAX
]) >= (abi_ulong
)(-515)) {
139 env
->regs
[R_EAX
] = -env
->regs
[R_EAX
];
142 env
->eflags
&= ~CC_C
;
147 /* just indicate that signals should be handled asap */
151 cpu_exec_step_atomic(cs
);
155 pc
= env
->segs
[R_CS
].base
+ env
->eip
;
156 fprintf(stderr
, "qemu: 0x%08lx: unhandled CPU exception 0x%x - "
157 "aborting\n", (long)pc
, trapnr
);
160 process_pending_signals(env
);
164 static inline void target_cpu_clone_regs(CPUX86State
*env
, target_ulong newsp
)
167 env
->regs
[R_ESP
] = newsp
;
169 env
->regs
[R_EAX
] = 0;
172 static inline void target_cpu_reset(CPUArchState
*env
)
174 cpu_reset(env_cpu(env
));
177 #endif /* TARGET_ARCH_CPU_H */