Exemple #1
0
void BX_CPU_C::task_switch_load_selector(bx_segment_reg_t *seg,
                 bx_selector_t *selector, Bit16u raw_selector, Bit8u cs_rpl)
{
  bx_descriptor_t descriptor;
  Bit32u dword1, dword2;

  // NULL selector is OK, will leave cache invalid
  if ((raw_selector & 0xfffc) != 0)
  {
    bx_bool good = fetch_raw_descriptor2(selector, &dword1, &dword2);
    if (!good) {
      BX_ERROR(("task_switch(%s): bad selector fetch !", strseg(seg)));
      exception(BX_TS_EXCEPTION, raw_selector & 0xfffc, 0);
    }

    parse_descriptor(dword1, dword2, &descriptor);

    /* AR byte must indicate data or readable code segment else #TS(selector) */
    if (descriptor.segment==0 || (IS_CODE_SEGMENT(descriptor.type) &&
        IS_CODE_SEGMENT_READABLE(descriptor.type) == 0))
    {
      BX_ERROR(("task_switch(%s): not data or readable code !", strseg(seg)));
      exception(BX_TS_EXCEPTION, raw_selector & 0xfffc, 0);
    }

    /* If data or non-conforming code, then both the RPL and the CPL
     * must be less than or equal to DPL in AR byte else #GP(selector) */
    if (IS_DATA_SEGMENT(descriptor.type) ||
        IS_CODE_SEGMENT_NON_CONFORMING(descriptor.type))
    {
      if ((selector->rpl > descriptor.dpl) || (cs_rpl > descriptor.dpl)) {
        BX_ERROR(("load_seg_reg(%s): RPL & CPL must be <= DPL", strseg(seg)));
        exception(BX_TS_EXCEPTION, raw_selector & 0xfffc, 0);
      }
    }

    if (! IS_PRESENT(descriptor)) {
      BX_ERROR(("task_switch(%s): descriptor not present !", strseg(seg)));
      exception(BX_NP_EXCEPTION, raw_selector & 0xfffc, 0);
    }

    // All checks pass, fill in shadow cache
    seg->cache = descriptor;
  }
}
Exemple #2
0
void BX_CPU_C::register_state(void)
{
  unsigned i;
  char cpu_name[10], cpu_title[10], name[10];

  sprintf(cpu_name, "%d", BX_CPU_ID);
  sprintf(cpu_title, "CPU %d", BX_CPU_ID);
  bx_list_c *list = new bx_list_c(SIM->get_param("save_restore.cpu"), 
           cpu_name, cpu_title, 60);

  BXRS_PARAM_SPECIAL32(list, cpu_version, param_save_handler, param_restore_handler);
  BXRS_PARAM_SPECIAL32(list, cpuid_std,   param_save_handler, param_restore_handler);
  BXRS_PARAM_SPECIAL32(list, cpuid_ext,   param_save_handler, param_restore_handler);
  BXRS_DEC_PARAM_SIMPLE(list, cpu_mode);
  BXRS_HEX_PARAM_SIMPLE(list, inhibit_mask);
#if BX_SUPPORT_X86_64
  BXRS_HEX_PARAM_SIMPLE(list, RAX);
  BXRS_HEX_PARAM_SIMPLE(list, RBX);
  BXRS_HEX_PARAM_SIMPLE(list, RCX);
  BXRS_HEX_PARAM_SIMPLE(list, RDX);
  BXRS_HEX_PARAM_SIMPLE(list, RSP);
  BXRS_HEX_PARAM_SIMPLE(list, RBP);
  BXRS_HEX_PARAM_SIMPLE(list, RSI);
  BXRS_HEX_PARAM_SIMPLE(list, RDI);
  BXRS_HEX_PARAM_SIMPLE(list, R8);
  BXRS_HEX_PARAM_SIMPLE(list, R9);
  BXRS_HEX_PARAM_SIMPLE(list, R10);
  BXRS_HEX_PARAM_SIMPLE(list, R11);
  BXRS_HEX_PARAM_SIMPLE(list, R12);
  BXRS_HEX_PARAM_SIMPLE(list, R13);
  BXRS_HEX_PARAM_SIMPLE(list, R14);
  BXRS_HEX_PARAM_SIMPLE(list, R15);
  BXRS_HEX_PARAM_SIMPLE(list, RIP);
#else
  BXRS_HEX_PARAM_SIMPLE(list, EAX);
  BXRS_HEX_PARAM_SIMPLE(list, EBX);
  BXRS_HEX_PARAM_SIMPLE(list, ECX);
  BXRS_HEX_PARAM_SIMPLE(list, EDX);
  BXRS_HEX_PARAM_SIMPLE(list, ESP);
  BXRS_HEX_PARAM_SIMPLE(list, EBP);
  BXRS_HEX_PARAM_SIMPLE(list, ESI);
  BXRS_HEX_PARAM_SIMPLE(list, EDI);
  BXRS_HEX_PARAM_SIMPLE(list, EIP);
#endif
  BXRS_PARAM_SPECIAL32(list, EFLAGS, 
         param_save_handler, param_restore_handler);
#if BX_CPU_LEVEL >= 3
  BXRS_HEX_PARAM_FIELD(list, DR0, dr0);
  BXRS_HEX_PARAM_FIELD(list, DR1, dr1);
  BXRS_HEX_PARAM_FIELD(list, DR2, dr2);
  BXRS_HEX_PARAM_FIELD(list, DR3, dr3);
  BXRS_HEX_PARAM_FIELD(list, DR6, dr6);
  BXRS_HEX_PARAM_FIELD(list, DR7, dr7);
#endif
  BXRS_HEX_PARAM_FIELD(list, CR0, cr0.val32);
  BXRS_HEX_PARAM_FIELD(list, CR2, cr2);
  BXRS_HEX_PARAM_FIELD(list, CR3, cr3);
#if BX_CPU_LEVEL >= 4
  BXRS_HEX_PARAM_FIELD(list, CR4, cr4.val32);
#endif

  for(i=0; i<6; i++) {
    bx_segment_reg_t *segment = &BX_CPU_THIS_PTR sregs[i];
    bx_list_c *sreg = new bx_list_c(list, strseg(segment), 9);
    BXRS_PARAM_SPECIAL16(sreg, selector, 
           param_save_handler, param_restore_handler);
    BXRS_HEX_PARAM_FIELD(sreg, base, segment->cache.u.segment.base);
    BXRS_HEX_PARAM_FIELD(sreg, limit, segment->cache.u.segment.limit);
    BXRS_HEX_PARAM_FIELD(sreg, limit_scaled, segment->cache.u.segment.limit_scaled);
    BXRS_PARAM_SPECIAL8 (sreg, ar_byte, 
           param_save_handler, param_restore_handler);
    BXRS_PARAM_BOOL(sreg, granularity, segment->cache.u.segment.g);
    BXRS_PARAM_BOOL(sreg, d_b, segment->cache.u.segment.d_b);
#if BX_SUPPORT_X86_64
    BXRS_PARAM_BOOL(sreg, l, segment->cache.u.segment.l);
#endif
    BXRS_PARAM_BOOL(sreg, avl, segment->cache.u.segment.avl);
  }

#if BX_CPU_LEVEL >= 2
  BXRS_HEX_PARAM_FIELD(list, GDTR_BASE, BX_CPU_THIS_PTR gdtr.base);
  BXRS_HEX_PARAM_FIELD(list, GDTR_LIMIT, BX_CPU_THIS_PTR gdtr.limit);
  BXRS_HEX_PARAM_FIELD(list, IDTR_BASE, BX_CPU_THIS_PTR idtr.base);
  BXRS_HEX_PARAM_FIELD(list, IDTR_LIMIT, BX_CPU_THIS_PTR idtr.limit);
#endif

  bx_list_c *LDTR = new bx_list_c (list, "LDTR", 7);
  BXRS_PARAM_SPECIAL16(LDTR, selector, param_save_handler, param_restore_handler);
  BXRS_HEX_PARAM_FIELD(LDTR, base,  ldtr.cache.u.system.base);
  BXRS_HEX_PARAM_FIELD(LDTR, limit, ldtr.cache.u.system.limit);
  BXRS_HEX_PARAM_FIELD(LDTR, limit_scaled, ldtr.cache.u.system.limit);
  BXRS_PARAM_SPECIAL8 (LDTR, ar_byte, param_save_handler, param_restore_handler);
  BXRS_PARAM_BOOL(LDTR, granularity, ldtr.cache.u.system.g);
  BXRS_PARAM_BOOL(LDTR, avl, ldtr.cache.u.system.avl);

  bx_list_c *TR = new bx_list_c (list, "TR", 7);
  BXRS_PARAM_SPECIAL16(TR, selector, param_save_handler, param_restore_handler);
  BXRS_HEX_PARAM_FIELD(TR, base,  tr.cache.u.system.base);
  BXRS_HEX_PARAM_FIELD(TR, limit, tr.cache.u.system.limit);
  BXRS_HEX_PARAM_FIELD(TR, limit_scaled, tr.cache.u.system.limit_scaled);
  BXRS_PARAM_SPECIAL8 (TR, ar_byte, param_save_handler, param_restore_handler);
  BXRS_PARAM_BOOL(TR, granularity, tr.cache.u.system.g);
  BXRS_PARAM_BOOL(TR, avl, tr.cache.u.system.avl);

  BXRS_HEX_PARAM_SIMPLE(list, smbase);

#if BX_CPU_LEVEL >= 5
  bx_list_c *MSR = new bx_list_c(list, "msr", 12);

#if BX_SUPPORT_APIC
  BXRS_HEX_PARAM_FIELD(MSR, apicbase, msr.apicbase);
#endif
#if BX_SUPPORT_X86_64
  BXRS_PARAM_SPECIAL32(MSR, EFER, param_save_handler, param_restore_handler);
  BXRS_HEX_PARAM_FIELD(MSR,  star, msr.star);
  BXRS_HEX_PARAM_FIELD(MSR, lstar, msr.lstar);
  BXRS_HEX_PARAM_FIELD(MSR, cstar, msr.cstar);
  BXRS_HEX_PARAM_FIELD(MSR, fmask, msr.fmask);
  BXRS_HEX_PARAM_FIELD(MSR, kernelgsbase, msr.kernelgsbase);
  BXRS_HEX_PARAM_FIELD(MSR, tsc_aux, msr.tsc_aux);
#endif
  BXRS_HEX_PARAM_FIELD(MSR, tsc_last_reset, msr.tsc_last_reset);
#if BX_SUPPORT_SEP
  BXRS_HEX_PARAM_FIELD(MSR, sysenter_cs_msr,  msr.sysenter_cs_msr);
  BXRS_HEX_PARAM_FIELD(MSR, sysenter_esp_msr, msr.sysenter_esp_msr);
  BXRS_HEX_PARAM_FIELD(MSR, sysenter_eip_msr, msr.sysenter_eip_msr);
#endif

#endif

#if BX_SUPPORT_FPU || BX_SUPPORT_MMX
  bx_list_c *fpu = new bx_list_c(list, "FPU", 17);
  BXRS_HEX_PARAM_FIELD(fpu, cwd, the_i387.cwd);
  BXRS_HEX_PARAM_FIELD(fpu, swd, the_i387.swd);
  BXRS_HEX_PARAM_FIELD(fpu, twd, the_i387.twd);
  BXRS_HEX_PARAM_FIELD(fpu, foo, the_i387.foo);
  BXRS_HEX_PARAM_FIELD(fpu, fcs, the_i387.fcs);
  BXRS_HEX_PARAM_FIELD(fpu, fip, the_i387.fip);
  BXRS_HEX_PARAM_FIELD(fpu, fds, the_i387.fds);
  BXRS_HEX_PARAM_FIELD(fpu, fdp, the_i387.fdp);
  for (i=0; i<8; i++) {
    sprintf(name, "st%d", i);
    bx_list_c *STx = new bx_list_c(fpu, name, 8);
    BXRS_HEX_PARAM_FIELD(STx, exp,      the_i387.st_space[i].exp);
    BXRS_HEX_PARAM_FIELD(STx, fraction, the_i387.st_space[i].fraction);
  }
  BXRS_DEC_PARAM_FIELD(fpu, tos, the_i387.tos);
#endif

#if BX_SUPPORT_SSE
  bx_list_c *sse = new bx_list_c(list, "SSE", 2*BX_XMM_REGISTERS+1);
  BXRS_HEX_PARAM_FIELD(sse, mxcsr, mxcsr.mxcsr);
  for (i=0; i<BX_XMM_REGISTERS; i++) {
    sprintf(name, "xmm%02d_hi", i);
    new bx_shadow_num_c(sse, name, &BX_CPU_THIS_PTR xmm[i].xmm64u(1), BASE_HEX);
    sprintf(name, "xmm%02d_lo", i);
    new bx_shadow_num_c(sse, name, &BX_CPU_THIS_PTR xmm[i].xmm64u(0), BASE_HEX);
  }
#endif

#if BX_SUPPORT_APIC
  local_apic.register_state(list);
#endif

  BXRS_PARAM_BOOL(list, EXT, EXT);
  BXRS_PARAM_BOOL(list, async_event, async_event);
  BXRS_PARAM_BOOL(list, INTR, INTR);
  BXRS_PARAM_BOOL(list, smi_pending, smi_pending);
  BXRS_PARAM_BOOL(list, nmi_pending, nmi_pending);
  BXRS_PARAM_BOOL(list, in_smm, in_smm);
  BXRS_PARAM_BOOL(list, nmi_disable, nmi_disable);
  BXRS_PARAM_BOOL(list, trace, trace);
}