diff --git a/src/intel_flash.c b/src/intel_flash.c index 1cdb6e0..304e873 100644 --- a/src/intel_flash.c +++ b/src/intel_flash.c @@ -3,6 +3,14 @@ #include "device.h" #include "mem.h" +#define FLASH_IS_BXB 2 +#define FLASH_INVERT 1 + +#define BLOCK_MAIN 0 +#define BLOCK_DATA1 1 +#define BLOCK_DATA2 2 +#define BLOCK_BOOT 3 + enum { CMD_READ_ARRAY = 0xff, @@ -18,55 +26,93 @@ enum typedef struct flash_t { uint8_t command, status; - mem_mapping_t read_mapping, write_mapping; + uint8_t flash_id; + int invert_high_pin; + mem_mapping_t mapping[8], mapping_h[8]; + uint32_t block_start[4], block_end[4], block_len[4]; + uint8_t array[131072]; } flash_t; -static flash_t flash; +static char flash_path[1024]; static uint8_t flash_read(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; -// pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, pc); + if (flash->invert_high_pin) + { + // pclog("flash_read : addr=%08x/%08x val=%02x command=%02x %04x:%08x\n", addr, addr ^ 0x10000, flash->array[(addr ^ 0x10000) & 0x1ffff], flash->command, CS, cpu_state.pc); + addr ^= 0x10000; + if (addr & 0xfff00000) return flash->array[addr & 0x1ffff]; + } + // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, cpu_state.pc); + addr &= 0x1ffff; switch (flash->command) { + case CMD_READ_ARRAY: + default: + return flash->array[addr]; + case CMD_IID: if (addr & 1) - return 0x94; + return flash->flash_id; return 0x89; - - default: - return flash->status; + + case CMD_READ_STATUS: + return flash->status; } } +static uint16_t flash_readw(uint32_t addr, void *p) +{ + flash_t *flash = (flash_t *)p; + addr &= 0x1ffff; + if (flash->invert_high_pin) addr ^= 0x10000; + return *(uint16_t *)&(flash->array[addr]); +} + +static uint32_t flash_readl(uint32_t addr, void *p) +{ + flash_t *flash = (flash_t *)p; + addr &= 0x1ffff; + if (flash->invert_high_pin) addr ^= 0x10000; + return *(uint32_t *)&(flash->array[addr]); +} + static void flash_write(uint32_t addr, uint8_t val, void *p) { flash_t *flash = (flash_t *)p; -// pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, pc); + int i; + // pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, cpu_state.pc); + + if (flash->invert_high_pin) + { + addr ^= 0x10000; + if (addr & 0xfff00000) return; + } + addr &= 0x1ffff; + switch (flash->command) { case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { -// pclog("flash_write: erase %05x\n", addr & 0x1ffff); - if ((addr & 0x1f000) == 0x0d000) - memset(&rom[0x0d000], 0xff, 0x1000); - if ((addr & 0x1f000) == 0x0c000) - memset(&rom[0x0c000], 0xff, 0x1000); - if ((addr & 0x1f000) < 0x0c000 || (addr & 0x1f000) >= 0x10000) - { - memset(rom, 0xff, 0xc000); - memset(&rom[0x10000], 0xff, 0x10000); - } + // pclog("flash_write: erase %05x\n", addr); + + for (i = 0; i < 3; i++) + { + if ((addr >= flash->block_start[i]) && (addr <= flash->block_end[i])) + memset(&(flash->array[flash->block_start[i]]), 0xff, flash->block_len[i]); + } + flash->status = 0x80; } flash->command = CMD_READ_STATUS; break; case CMD_PROGRAM_SETUP: -// pclog("flash_write: program %05x %02x\n", addr & 0x1ffff, val); - if ((addr & 0x1e000) != 0x0e000) - rom[addr & 0x1ffff] = val; + // pclog("flash_write: program %05x %02x\n", addr, val); + if ((addr & 0x1e000) != (flash->block_start[3] & 0x1e000)) + flash->array[addr] = val; flash->command = CMD_READ_STATUS; flash->status = 0x80; break; @@ -77,96 +123,199 @@ static void flash_write(uint32_t addr, uint8_t val, void *p) { case CMD_CLEAR_STATUS: flash->status = 0; - break; - - case CMD_IID: - case CMD_READ_STATUS: - mem_mapping_disable(&bios_mapping[0]); - mem_mapping_disable(&bios_mapping[1]); - mem_mapping_disable(&bios_mapping[2]); - mem_mapping_disable(&bios_mapping[3]); - mem_mapping_disable(&bios_mapping[4]); - mem_mapping_disable(&bios_mapping[5]); - mem_mapping_disable(&bios_mapping[6]); - mem_mapping_disable(&bios_mapping[7]); - mem_mapping_enable(&flash->read_mapping); - break; - - case CMD_READ_ARRAY: - mem_mapping_enable(&bios_mapping[0]); - mem_mapping_enable(&bios_mapping[1]); - mem_mapping_enable(&bios_mapping[2]); - mem_mapping_enable(&bios_mapping[3]); - mem_mapping_enable(&bios_mapping[4]); - mem_mapping_enable(&bios_mapping[5]); - mem_mapping_enable(&bios_mapping[6]); - mem_mapping_enable(&bios_mapping[7]); - mem_mapping_disable(&flash->read_mapping); - break; + break; } } } -void *intel_flash_init() +static void intel_flash_add_mappings(flash_t *flash) +{ + int i = 0; + + for (i = 0; i <= 7; i++) + { + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + ((i << 14) & 0x1ffff), 0, (void *)flash); + } +} + +/* This is for boards which invert the high pin - the flash->array pointers need to pointer invertedly in order for INTERNAL writes to go to the right part of the array. */ +static void intel_flash_add_mappings_inverted(flash_t *flash) +{ + int i = 0; + + for (i = 0; i <= 7; i++) + { + mem_mapping_add(&(flash->mapping[i]), 0xe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), MEM_MAPPING_EXTERNAL, (void *)flash); + mem_mapping_add(&(flash->mapping_h[i]), 0xfffe0000 + (i << 14), 0x04000, flash_read, flash_readw, flash_readl, flash_write, mem_write_nullw, mem_write_nulll, flash->array + (((i << 14) ^ 0x10000) & 0x1ffff), 0, (void *)flash); + } +} + +void *intel_flash_init(uint8_t type) { FILE *f; flash_t *flash = malloc(sizeof(flash_t)); memset(flash, 0, sizeof(flash_t)); + char fpath[1024]; + int i; + + switch(romset) + { + case ROM_REVENGE: + strcpy(flash_path, "roms/revenge/"); + break; + case ROM_ENDEAVOR: + strcpy(flash_path, "roms/endeavor/"); + break; + case ROM_430VX: + strcpy(flash_path, "roms/430vx/"); + break; + default: + fatal("intel_flash_init on unsupported ROM set %i\n", romset); + } + // pclog("Flash init: Path is: %s\n", flash_path); + + flash->flash_id = (type & FLASH_IS_BXB) ? 0x95 : 0x94; + flash->invert_high_pin = (type & FLASH_INVERT); + + /* The block lengths are the same both flash types. */ + flash->block_len[BLOCK_MAIN] = 0x1c000; + flash->block_len[BLOCK_DATA1] = 0x01000; + flash->block_len[BLOCK_DATA2] = 0x01000; + flash->block_len[BLOCK_BOOT] = 0x02000; + + if (type & FLASH_IS_BXB) /* 28F001BX-B */ + { + flash->block_start[BLOCK_MAIN] = 0x04000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1ffff; + flash->block_start[BLOCK_DATA1] = 0x03000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x03fff; + flash->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x04fff; + flash->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x01fff; + } + else /* 28F001BX-T */ + { + flash->block_start[BLOCK_MAIN] = 0x00000; /* MAIN BLOCK */ + flash->block_end[BLOCK_MAIN] = 0x1bfff; + flash->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ + flash->block_end[BLOCK_DATA1] = 0x1cfff; + flash->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ + flash->block_end[BLOCK_DATA2] = 0x1dfff; + flash->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ + flash->block_end[BLOCK_BOOT] = 0x1ffff; + } + + for (i = 0; i < 8; i++) + { + mem_mapping_disable(&bios_mapping[i]); + mem_mapping_disable(&bios_high_mapping[i]); + } + + if (flash->invert_high_pin) + { + memcpy(flash->array, rom + 65536, 65536); + memcpy(flash->array + 65536, rom, 65536); + } + else + { + memcpy(flash->array, rom, 131072); + } + + if (flash->invert_high_pin) + { + intel_flash_add_mappings_inverted(flash); + } + else + { + intel_flash_add_mappings(flash); + } - mem_mapping_add(&flash->read_mapping, - 0xe0000, - 0x20000, - flash_read, NULL, NULL, - NULL, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_add(&flash->write_mapping, - 0xe0000, - 0x20000, - NULL, NULL, NULL, - flash_write, NULL, NULL, - NULL, MEM_MAPPING_EXTERNAL, (void *)flash); - mem_mapping_disable(&flash->read_mapping); flash->command = CMD_READ_ARRAY; flash->status = 0; - - memset(&rom[0xc000], 0, 0x2000); - - f = romfopen("roms/endeavor/oemlogo.bin", "rb"); + + strcpy(fpath, flash_path); + strcat(fpath, "flash.bin"); + f = romfopen(fpath, "rb"); if (f) { - fread(&rom[0xc000], 0x1000, 1, f); + fread(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + fread(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); + fread(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); fclose(f); } - f = romfopen("roms/endeavor/ecsd.bin", "rb"); - if (f) - { - fread(&rom[0xd000], 0x1000, 1, f); - fclose(f); - } - + return flash; } +/* For AMI BIOS'es - Intel 28F001BXT with high address pin inverted. */ +void *intel_flash_bxt_ami_init() +{ + return intel_flash_init(FLASH_INVERT); +} + +/* For Award BIOS'es - Intel 28F001BXT with high address pin not inverted. */ +void *intel_flash_bxt_init() +{ + return intel_flash_init(0); +} + +/* For Acer BIOS'es - Intel 28F001BXB. */ +void *intel_flash_bxb_init() +{ + return intel_flash_init(FLASH_IS_BXB); +} + void intel_flash_close(void *p) { FILE *f; flash_t *flash = (flash_t *)p; - f = romfopen("roms/endeavor/oemlogo.bin", "wb"); - fwrite(&rom[0xc000], 0x1000, 1, f); - fclose(f); - f = romfopen("roms/endeavor/ecsd.bin", "wb"); - fwrite(&rom[0xd000], 0x1000, 1, f); - fclose(f); + char fpath[1024]; + strcpy(fpath, flash_path); + strcat(fpath, "flash.bin"); + f = romfopen(fpath, "wb"); + fwrite(&(flash->array[flash->block_start[BLOCK_MAIN]]), flash->block_len[BLOCK_MAIN], 1, f); + fwrite(&(flash->array[flash->block_start[BLOCK_DATA1]]), flash->block_len[BLOCK_DATA1], 1, f); + fwrite(&(flash->array[flash->block_start[BLOCK_DATA2]]), flash->block_len[BLOCK_DATA2], 1, f); + fclose(f); + free(flash); } -device_t intel_flash_device = +device_t intel_flash_bxt_ami_device = { "Intel 28F001BXT Flash BIOS", 0, - intel_flash_init, + intel_flash_bxt_ami_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +device_t intel_flash_bxt_device = +{ + "Intel 28F001BXT Flash BIOS", + 0, + intel_flash_bxt_init, + intel_flash_close, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +device_t intel_flash_bxb_device = +{ + "Intel 28F001BXB Flash BIOS", + 0, + intel_flash_bxb_init, intel_flash_close, NULL, NULL, diff --git a/src/intel_flash.h b/src/intel_flash.h index 379a8d3..2b4cb14 100644 --- a/src/intel_flash.h +++ b/src/intel_flash.h @@ -1 +1,3 @@ -extern device_t intel_flash_device; +extern device_t intel_flash_bxt_ami_device; +extern device_t intel_flash_bxt_device; +extern device_t intel_flash_bxb_device; diff --git a/src/mem.c b/src/mem.c index 2197fa1..9a397ee 100644 --- a/src/mem.c +++ b/src/mem.c @@ -40,7 +40,7 @@ static mem_mapping_t ram_high_mapping; static mem_mapping_t ram_mid_mapping; static mem_mapping_t ram_remapped_mapping; mem_mapping_t bios_mapping[8]; -static mem_mapping_t bios_high_mapping[8]; +mem_mapping_t bios_high_mapping[8]; static mem_mapping_t romext_mapping; int shadowbios,shadowbios_write; diff --git a/src/mem.h b/src/mem.h index 848468e..c9cf6e6 100644 --- a/src/mem.h +++ b/src/mem.h @@ -101,6 +101,7 @@ void mem_write_nulll(uint32_t addr, uint32_t val, void *p); FILE *romfopen(char *fn, char *mode); mem_mapping_t bios_mapping[8]; +mem_mapping_t bios_high_mapping[8]; typedef struct page_t diff --git a/src/model.c b/src/model.c index a6b069c..0997633 100644 --- a/src/model.c +++ b/src/model.c @@ -377,6 +377,7 @@ void at_batman_init() i430lx_init(); fdc37c665_init(); intel_batman_init(); + device_add(&intel_flash_bxt_ami_device); } void at_endeavor_init() { @@ -387,7 +388,7 @@ void at_endeavor_init() piix_init(7); um8669f_init(); intel_endeavor_init(); - device_add(&intel_flash_device); + device_add(&intel_flash_bxt_ami_device); } void at_i430vx_init() @@ -398,6 +399,7 @@ void at_i430vx_init() i430vx_init(); piix_init(7); um8669f_init(); + device_add(&intel_flash_bxt_device); } void model_init()