void BX_CPP_AttrRegparmN(1) BX_CPU_C::RSM(bxInstruction_c *i) { /* If we are not in System Management Mode, then #UD should be generated */ if (! BX_CPU_THIS_PTR smm_mode()) { BX_INFO(("RSM not in System Management Mode !")); UndefinedOpcode(i); } invalidate_prefetch_q(); BX_INFO(("RSM: Resuming from System Management Mode")); BX_CPU_THIS_PTR nmi_disable = 0; 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; 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)->readPhysicalPage(BX_CPU_THIS, base, 4, &saved_state[n]); BX_DBG_PHY_MEMORY_ACCESS(BX_CPU_ID, base, 4, BX_READ, (Bit8u*)(&saved_state[n])); } BX_CPU_THIS_PTR in_smm = 0; // restore the CPU state from SMRAM if (! smram_restore_state(saved_state)) { BX_PANIC(("RSM: Incorrect state when restoring CPU state - shutdown !")); shutdown(); } // debug(RIP); }
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); }
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! }