void map_video_bios(void) { v_printf("Mapping VBIOS = %d\n",config.mapped_bios); if (config.mapped_bios) { if (config.vbios_file) { warn("WARN: loading VBIOS %s into mem at %#x (%#X bytes)\n", config.vbios_file, VBIOS_START, VBIOS_SIZE); load_file(config.vbios_file, 0, LINEAR2UNIX(VBIOS_START), VBIOS_SIZE); } else if (config.vbios_copy) { warn("WARN: copying VBIOS from /dev/mem at %#x (%#X bytes)\n", VBIOS_START, VBIOS_SIZE); load_file("/dev/mem", VBIOS_START, LINEAR2UNIX(VBIOS_START), VBIOS_SIZE); } else { warn("WARN: copying VBIOS file from /dev/mem\n"); load_file("/dev/mem", VBIOS_START, LINEAR2UNIX(VBIOS_START), VBIOS_SIZE); } /* copy graphics characters from system BIOS */ load_file("/dev/mem", GFX_CHARS, LINEAR2UNIX(GFX_CHARS), GFXCHAR_SIZE); memcheck_addtype('V', "Video BIOS"); memcheck_reserve('V', VBIOS_START, VBIOS_SIZE); if (!config.vbios_post || config.chipset == VESA) load_file("/dev/mem", 0, (unsigned char *)int_bios_area, sizeof(int_bios_area)); } }
static void r_munprotect(unsigned int addr, unsigned int len, unsigned char *eip) { if (EFLAGS & EFLAGS_DF) addr -= len; if (debug_level('e')>3) dbug_printf("\tR_MUNPROT %08x:%08x %s\n", addr,addr+len,(EFLAGS&EFLAGS_DF?"back":"fwd")); if (LINEAR2UNIX(addr) != MEM_BASE32(addr) && !e_querymark(addr, len)) return; InvalidateNodePage(addr,len,eip,NULL); e_resetpagemarks(addr,len); e_munprotect(addr,len); }
static int vbe_info(unsigned int vbeinfo) { int vbe2 = 0; int i; struct VBE_vi *vbei = LINEAR2UNIX(vbeinfo); size_t size; #ifdef DEBUG_VBE v_printf( "VBE: [0x%02x] vbe_info: es:di = 0x%04x:0x%04x\n", (unsigned) _AL, (unsigned) _ES, (unsigned) _DI ); #endif if(vbei->VBESig == 0x32454256 /* "VBE2" */) vbe2 = 1; #ifdef DEBUG_VBE if(vbe2) v_printf("VBE: [0x%02x] vbe_info: VBE2 info requested\n", (unsigned) _AL); #endif size = vbe2 ? sizeof(*vbei) : offsetof(struct VBE_vi, OEMData); memset(vbei, 0, size); vbei->VBESig = 0x41534556; /* "VESA" */ vbei->VESAVersion = 0x200; /* 2.0 */ vbei->OEMID = MK_FP16(0xc000, vgaemu_bios.prod_name); vbei->Capabilities = 1; /* 6/8 bit switchable DAC */ vbei->ModeList = MK_FP16(0xc000, vgaemu_bios.vbe_mode_list); vbei->Memory = vga.mem.pages >> 4; /* multiples of 64 kbyte */ if(vbe2) { i = 0; vbei->OEMSoftRev = VBE_OEMSoftRev; memcpy(&vbei->OEMData[i], VBE_OEMVendorName, sizeof(VBE_OEMVendorName)); vbei->OEMVendorName = MK_FP16(_ES, _DI + offsetof(struct VBE_vi, OEMData) + i); i += sizeof(VBE_OEMVendorName); memcpy(&vbei->OEMData[i], VBE_OEMProdName, sizeof(VBE_OEMProdName)); vbei->OEMProdName = MK_FP16(_ES, _DI + offsetof(struct VBE_vi, OEMData) + i); i += sizeof(VBE_OEMProdName); memcpy(&vbei->OEMData[i], VBE_OEMProductRev, sizeof(VBE_OEMProductRev)); vbei->OEMProductRev = MK_FP16(_ES, _DI + offsetof(struct VBE_vi, OEMData) + i); } #ifdef DEBUG_VBE v_printf("VBE: [0x%02x] vbe_info: return value 0\n", (unsigned) _AL); #endif return 0; }
/* * Return address of the stub function is passed into eip */ static void m_munprotect(unsigned int addr, unsigned int len, unsigned char *eip) { if (debug_level('e')>3) e_printf("\tM_MUNPROT %08x:%p [%08x]\n", addr,eip,*((int *)(eip-3))); /* if only data in aliased low memory is hit, nothing to do */ if (LINEAR2UNIX(addr) != MEM_BASE32(addr) && !e_querymark(addr, len)) return; /* Always unprotect and clear all code in the pages * for either DPMI data or code. * Maybe the stub was set up before that code was parsed. * Clear that code */ if (debug_level('e')>1 && e_querymark(addr, len)) e_printf("CODE %08x hit in DATA %p patch\n",addr,eip); /* if (UnCpatch((void *)(eip-3))) leavedos_main(0); */ InvalidateNodePage(addr,len,eip,NULL); e_resetpagemarks(addr,len); e_munprotect(addr,len); }
void vbe_pre_init(void) { int i; vga_mode_info *vmi = NULL; unsigned int dos_vga_bios = SEGOFF2LINEAR(0xc000,0x0000); int bios_ptr = (char *) vgaemu_bios_end - (char *) vgaemu_bios_start; static struct { char modes[3]; char reserved1[4]; char scanlines; char character_blocks; char max_active_blocks; short support_flags; short reserved2; char save_function_flags; char reserved3; } vgaemu_bios_functionality_table = { .modes = {0xff,0xe0,0x0f}, /* Modes 0-7, 0dh-0fh, 10h-13h supported */ .scanlines = 7, /* scanlines 200,350,400 supported */ .character_blocks = 2, /* This all corresponds to a real BIOS */ .max_active_blocks = 8, /* See Ralf Brown's interrupt list */ .support_flags = 0xeff, /* INT 10h, AH=1b for documentation */ .save_function_flags=0x3f }; MEMSET_DOS(dos_vga_bios, 0, VBE_BIOS_MAXPAGES << 12); /* one page */ MEMCPY_2DOS(dos_vga_bios, vgaemu_bios_start, bios_ptr); vgaemu_bios.prod_name = (char *) vgaemu_bios_prod_name - (char *) vgaemu_bios_start; if (Video->setmode) { i = (char *) vgaemu_bios_pm_interface_end - (char *) vgaemu_bios_pm_interface; if(i + bios_ptr > (VBE_BIOS_MAXPAGES << 12) - 8) { error("VBE: vbe_init: protected mode interface to large, disabling\n"); vgaemu_bios.vbe_pm_interface_len = vgaemu_bios.vbe_pm_interface = 0; } vgaemu_bios.vbe_pm_interface_len = i; vgaemu_bios.vbe_pm_interface = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vgaemu_bios_pm_interface, i); bios_ptr += i; bios_ptr = (bios_ptr + 3) & ~3; vgaemu_bios.vbe_mode_list = bios_ptr; /* set up video mode list */ for(i = 0x100; i <= vgaemu_bios.vbe_last_mode; i++) { if((vmi = vga_emu_find_mode(i, NULL))) { if(vmi->VESA_mode != -1 && bios_ptr < ((VBE_BIOS_MAXPAGES << 12) - 4)) { WRITE_WORD(dos_vga_bios + bios_ptr, vmi->VESA_mode); bios_ptr += 2; } } } WRITE_WORD(dos_vga_bios + bios_ptr, -1); bios_ptr += 2; /* add fonts */ vgaemu_bios.font_8 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_08, sizeof vga_rom_08); bios_ptr += sizeof vga_rom_08; vgaemu_bios.font_14 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_14, sizeof vga_rom_14); bios_ptr += sizeof vga_rom_14; vgaemu_bios.font_16 = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_16, sizeof vga_rom_16); bios_ptr += sizeof vga_rom_16; vgaemu_bios.font_14_alt = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_14_alt, sizeof vga_rom_14_alt); bios_ptr += sizeof vga_rom_14_alt; vgaemu_bios.font_16_alt = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, vga_rom_16_alt, sizeof vga_rom_16_alt); bios_ptr += sizeof vga_rom_16_alt; } else { /* only support the initial video mode, can't change it */ vgaemu_bios_functionality_table.modes[0] = 1 << video_mode; vgaemu_bios_functionality_table.modes[1] = vgaemu_bios_functionality_table.modes[2] = 0; } vgaemu_bios.functionality = bios_ptr; MEMCPY_2DOS(dos_vga_bios + bios_ptr, &vgaemu_bios_functionality_table, sizeof vgaemu_bios_functionality_table); bios_ptr += sizeof vgaemu_bios_functionality_table; vgaemu_bios.size = bios_ptr; WRITE_BYTE(dos_vga_bios + 2, (bios_ptr + ((1 << 9) - 1)) >> 9); vgaemu_bios.pages = (bios_ptr + ((1 << 12) - 1)) >> 12; if (config.vgaemubios_file) { /* EXPERIMENTAL: load and boot the Bochs BIOS */ int fd = open(config.vgaemubios_file, O_RDONLY); int bytes; if (fd != -1) { bytes = read(fd, LINEAR2UNIX(0xc0000), 65536); close(fd); vgaemu_bios.pages = (bytes + PAGE_SIZE - 1) / PAGE_SIZE; config.vbios_post = 1; } } memcheck_addtype('V', "VGAEMU Video BIOS"); memcheck_reserve('V', dos_vga_bios, vgaemu_bios.pages << 12); if(!config.X_pm_interface) { v_printf("VBE: vbe_init: protected mode interface disabled\n"); } v_printf( "VBE: vbe_init: %d pages for VGA BIOS, vga.mem.base = %p\n", vgaemu_bios.pages, vga.mem.base ); }