Bit64s BX_CPU_C::param_restore(bx_param_c *param, Bit64s val) { #else UNUSED(devptr); #endif // !BX_USE_CPU_SMF const char *pname, *segname; bx_segment_reg_t *segment = NULL; pname = param->get_name(); if (!strcmp(pname, "cpu_version")) { if (val != get_cpu_version_information()) { BX_PANIC(("save/restore: CPU version mismatch")); } } else if (!strcmp(pname, "cpuid_std")) { if (val != get_std_cpuid_features()) { BX_PANIC(("save/restore: CPUID mismatch")); } } else if (!strcmp(pname, "cpuid_ext")) { if (val != get_extended_cpuid_features()) { BX_PANIC(("save/restore: CPUID mismatch")); } } else if (!strcmp(pname, "EFLAGS")) { BX_CPU_THIS_PTR setEFlags((Bit32u)val); #if BX_SUPPORT_X86_64 } else if (!strcmp(pname, "EFER")) { BX_CPU_THIS_PTR efer.sce = (val >> 0) & 1; BX_CPU_THIS_PTR efer.lme = (val >> 8) & 1; BX_CPU_THIS_PTR efer.lma = (val >> 10) & 1; BX_CPU_THIS_PTR efer.nxe = (val >> 11) & 1; BX_CPU_THIS_PTR efer.ffxsr = (val >> 14) & 1; #endif } else if (!strcmp(pname, "ar_byte") || !strcmp(pname, "selector")) {
void BX_CPU_C::enter_system_management_mode(void) { invalidate_prefetch_q(); BX_INFO(("Enter to System Management Mode")); // debug(BX_CPU_THIS_PTR prev_rip); BX_CPU_THIS_PTR in_smm = 1; Bit32u saved_state[SMM_SAVE_STATE_MAP_SIZE], n; // reset reserved bits for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) saved_state[n] = 0; // prepare CPU state to be saved in the SMRAM BX_CPU_THIS_PTR smram_save_state(saved_state); bx_phy_address base = BX_CPU_THIS_PTR smbase + 0x10000; // could be optimized with reading of only non-reserved bytes for(n=0;n<SMM_SAVE_STATE_MAP_SIZE;n++) { base -= 4; BX_MEM(0)->writePhysicalPage(BX_CPU_THIS, base, 4, &saved_state[n]); BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, base, 4, BX_WRITE, (Bit8u*)(&saved_state[n])); } BX_CPU_THIS_PTR setEFlags(0x2); // Bit1 is always set BX_CPU_THIS_PTR prev_rip = RIP = 0x00008000; BX_CPU_THIS_PTR dr7 = 0x00000400; // CR0 - PE, EM, TS, and PG flags set to 0; others unmodified BX_CPU_THIS_PTR cr0.set_PE(0); // real mode (bit 0) BX_CPU_THIS_PTR cr0.set_EM(0); // emulate math coprocessor (bit 2) BX_CPU_THIS_PTR cr0.set_TS(0); // no task switch (bit 3) BX_CPU_THIS_PTR cr0.set_PG(0); // paging disabled (bit 31) // paging mode was changed - flush TLB TLB_flush(1); // 1 = Flush Global entries also #if BX_CPU_LEVEL >= 4 BX_CPU_THIS_PTR cr4.setRegister(0); #endif #if BX_SUPPORT_X86_64 BX_CPU_THIS_PTR efer.setRegister(0); #endif parse_selector(BX_CPU_THIS_PTR smbase >> 4, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].selector); BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.dpl = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.segment = 1; /* data/code segment */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.type = BX_DATA_READ_WRITE_ACCESSED; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.base = BX_CPU_THIS_PTR smbase; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit = 0xffff; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.limit_scaled = 0xffffffff; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.avl = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.g = 1; /* page granular */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.d_b = 0; /* 16bit default size */ #if BX_SUPPORT_X86_64 BX_CPU_THIS_PTR sregs[BX_SEG_REG_CS].cache.u.segment.l = 0; /* 16bit default size */ #endif #if BX_SUPPORT_ICACHE BX_CPU_THIS_PTR updateFetchModeMask(); #endif handleCpuModeChange(); #if BX_CPU_LEVEL >= 4 && BX_SUPPORT_ALIGNMENT_CHECK handleAlignmentCheck(); #endif /* DS (Data Segment) and descriptor cache */ parse_selector(0x0000, &BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].selector); BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.valid = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.p = 1; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.dpl = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.segment = 1; /* data/code segment */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.type = BX_DATA_READ_WRITE_ACCESSED; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.base = 0x00000000; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit = 0xffff; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.limit_scaled = 0xffffffff; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.avl = 0; BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.g = 1; /* byte granular */ BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.d_b = 0; /* 16bit default size */ #if BX_SUPPORT_X86_64 BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS].cache.u.segment.l = 0; /* 16bit default size */ #endif // use DS segment as template for the others BX_CPU_THIS_PTR sregs[BX_SEG_REG_SS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]; BX_CPU_THIS_PTR sregs[BX_SEG_REG_ES] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]; BX_CPU_THIS_PTR sregs[BX_SEG_REG_FS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]; BX_CPU_THIS_PTR sregs[BX_SEG_REG_GS] = BX_CPU_THIS_PTR sregs[BX_SEG_REG_DS]; }