Beispiel #1
0
void smi_init() {
	smram_state_t smram;
	pci_driver_t **driver;
	
	smram = smram_save_state();
	smram_tseg_set_state(SMRAM_TSEG_OPEN);

	outputf("NetWatch running");

	/* Turn on the SMIs we want */
	smi_disable();
	
	eth_init();
	
	crc32_init();
	
	/* After everything is initialized, load drivers. */
	for (driver = drivers; *driver; driver++)
	{
		outputf("Probing driver: %s", (*driver)->name);
		if (pci_probe_driver(*driver))
			output("Found a card");
	}
	outputf("Driver probe complete");
	
	/* Load in fonts. */
	text_init();

	smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler);
	smi_enable_event(SMI_EVENT_FAST_TIMER);

	smi_register_handler(SMI_EVENT_DEVTRAP_KBC, kbc_handler);
	smi_enable_event(SMI_EVENT_DEVTRAP_KBC);
	
	smi_register_handler(SMI_EVENT_GBL_RLS, gbl_rls_handler);
	smi_enable_event(SMI_EVENT_GBL_RLS);

	smi_enable();
	
	vga_flush_imm(1);
	
	smram_restore_state(smram);
}
Beispiel #2
0
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];
}
Beispiel #3
0
void c_start(unsigned int magic, struct mb_info *mbinfo)
{
	struct mod_info *mods = mbinfo->mods;
	smram_state_t old_smramc;
	struct info_section * info;
	int i;
	
	void (*realmode)() = (void (*)()) 0x4000;
	
	show_cursor();
	outputf("NetWatch loader");
	
	if (magic != MULTIBOOT_LOADER_MAGIC)
		panic("Bootloader was not multiboot compliant; cannot continue.");
	
	for (i = 0; i < mbinfo->mod_cnt; i++)
	{
		outputf("Module found:");
		outputf("  Start: %08x", (unsigned long) mods[i].mod_start);
		outputf("  Size: %08x", (unsigned long)mods[i].mod_end - (unsigned long)mods[i].mod_start);
		outputf("  Name: %s", mods[i].mod_string);
	}

	if (mbinfo->mod_cnt != 1)
		panic("Expected exactly one module; cannot continue.");
	outputf("Current SMRAMC state is: %02x", (unsigned char)smram_save_state());
	outputf("Current SMI state is: %08x", inl(0x830));	// XXX ICH2 specific
	
	smi_disable();
	
	/* Open the SMRAM aperture and load our ELF. */
	old_smramc = smram_save_state();

	if (smram_aseg_set_state(SMRAM_ASEG_OPEN) != 0)
		panic("Opening SMRAM failed; cannot load ELF.");

	load_elf(mods[0].mod_start, (unsigned long)mods[0].mod_end - (unsigned long)mods[0].mod_start);

	info = (struct info_section *)0x10000;
	if (info->signature != INFO_SIGNATURE)
	{
		smram_restore_state(old_smramc);		/* Restore so that video ram is touchable again. */
		panic("Info section signature mismatch.");
	}

	info->firstrun();
	smram_restore_state(old_smramc);
	
	outputf("New SMRAMC state is: %02x", (unsigned char)smram_save_state());

	puts("Waiting for a bit before returning to real mode...");
	for (i=0; i<0x500000; i++)
	{
		if ((i % 0x100000) == 0)
			puts(".");
		inb(0x80);
	}
	puts("\n");

	outputf("Now returning to real mode.");
	memcpy((void *)0x4000, _binary_realmode_bin_start, (int)&_binary_realmode_bin_size);
	realmode();	// goodbye!
}