NJU-ProjectN/nemu eb63cf3568dbf4e0c3c6ef462e6ec685550fabbc Merge pull request #76 from rijuyuezhu/master
78 lines
2.4 KiB
C
78 lines
2.4 KiB
C
/***************************************************************************************
|
|
* Copyright (c) 2014-2022 Zihao Yu, Nanjing University
|
|
*
|
|
* NEMU is licensed under Mulan PSL v2.
|
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
|
* You may obtain a copy of Mulan PSL v2 at:
|
|
* http://license.coscl.org.cn/MulanPSL2
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
|
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
|
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
|
*
|
|
* See the Mulan PSL v2 for more details.
|
|
***************************************************************************************/
|
|
|
|
#include "common.h"
|
|
|
|
#if defined(CONFIG_ISA_x86)
|
|
|
|
bool gdb_memcpy_to_qemu(uint32_t, void *, int);
|
|
bool gdb_getregs(union isa_gdb_regs *);
|
|
bool gdb_setregs(union isa_gdb_regs *);
|
|
void difftest_exec(uint64_t n);
|
|
|
|
static uint8_t mbr[] = {
|
|
// start16:
|
|
0xfa, // cli
|
|
0x31, 0xc0, // xorw %ax,%ax
|
|
0x8e, 0xd8, // movw %ax,%ds
|
|
0x8e, 0xc0, // movw %ax,%es
|
|
0x8e, 0xd0, // movw %ax,%ss
|
|
0x0f, 0x01, 0x16, 0x44, 0x7c, // lgdt gdtdesc
|
|
0x0f, 0x20, 0xc0, // movl %cr0,%eax
|
|
0x66, 0x83, 0xc8, 0x01, // orl $CR0_PE,%eax
|
|
0x0f, 0x22, 0xc0, // movl %eax,%cr0
|
|
0xea, 0x1d, 0x7c, 0x08, 0x00, // ljmp $GDT_ENTRY(1),$start32
|
|
|
|
// start32:
|
|
0x66, 0xb8, 0x10, 0x00, // movw $0x10,%ax
|
|
0x8e, 0xd8, // movw %ax, %ds
|
|
0x8e, 0xc0, // movw %ax, %es
|
|
0x8e, 0xd0, // movw %ax, %ss
|
|
0xeb, 0xfe, // jmp 7c27
|
|
0x8d, 0x76, 0x00, // lea 0x0(%esi),%esi
|
|
|
|
// GDT
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x9a, 0xcf, 0x00,
|
|
0xff, 0xff, 0x00, 0x00, 0x00, 0x92, 0xcf, 0x00,
|
|
|
|
// GDT descriptor
|
|
0x17, 0x00, 0x2c, 0x7c, 0x00, 0x00
|
|
};
|
|
|
|
void init_isa() {
|
|
// put the MBR code to QEMU to enable protected mode
|
|
bool ok = gdb_memcpy_to_qemu(0x7c00, mbr, sizeof(mbr));
|
|
assert(ok == 1);
|
|
|
|
union isa_gdb_regs r;
|
|
gdb_getregs(&r);
|
|
|
|
// set cs:eip to 0000:7c00
|
|
r.eip = 0x7c00;
|
|
r.cs = 0x0000;
|
|
ok = gdb_setregs(&r);
|
|
assert(ok == 1);
|
|
|
|
// execute enough instructions to enter protected mode
|
|
difftest_exec(20);
|
|
}
|
|
|
|
#else
|
|
|
|
void init_isa() {
|
|
}
|
|
|
|
#endif
|