clang-format in src/mem/

This commit is contained in:
Jasmine Iwanek
2022-09-18 17:18:07 -04:00
parent 3fddf4d488
commit 4685da3fca
8 changed files with 2602 additions and 2828 deletions

View File

@@ -30,14 +30,11 @@
#include <86box/nvr.h>
#include <86box/plat.h>
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
enum
{
enum {
BLOCK_MAIN1,
BLOCK_MAIN2,
BLOCK_DATA1,
@@ -46,88 +43,80 @@ enum
BLOCKS_NUM
};
enum
{
CMD_SET_READ = 0x00,
enum {
CMD_SET_READ = 0x00,
CMD_READ_SIGNATURE = 0x90,
CMD_ERASE = 0x20,
CMD_ERASE_CONFIRM = 0x20,
CMD_ERASE_VERIFY = 0xA0,
CMD_PROGRAM = 0x40,
CMD_ERASE = 0x20,
CMD_ERASE_CONFIRM = 0x20,
CMD_ERASE_VERIFY = 0xA0,
CMD_PROGRAM = 0x40,
CMD_PROGRAM_VERIFY = 0xC0,
CMD_RESET = 0xFF
CMD_RESET = 0xFF
};
typedef struct flash_t {
uint8_t command, pad,
pad0, pad1,
*array;
typedef struct flash_t
{
uint8_t command, pad,
pad0, pad1,
*array;
mem_mapping_t mapping, mapping_h[2];
mem_mapping_t mapping, mapping_h[2];
} flash_t;
static char flash_path[1024];
static char flash_path[1024];
static uint8_t
flash_read(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *) p;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
addr &= biosmask;
switch (dev->command) {
case CMD_ERASE_VERIFY:
case CMD_PROGRAM_VERIFY:
case CMD_RESET:
case CMD_SET_READ:
ret = dev->array[addr];
break;
case CMD_ERASE_VERIFY:
case CMD_PROGRAM_VERIFY:
case CMD_RESET:
case CMD_SET_READ:
ret = dev->array[addr];
break;
case CMD_READ_SIGNATURE:
if (addr == 0x00000)
ret = 0x31; /* CATALYST */
else if (addr == 0x00001)
ret = 0xB4; /* 28F010 */
break;
case CMD_READ_SIGNATURE:
if (addr == 0x00000)
ret = 0x31; /* CATALYST */
else if (addr == 0x00001)
ret = 0xB4; /* 28F010 */
break;
}
return ret;
}
static uint16_t
flash_readw(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *)p;
flash_t *dev = (flash_t *) p;
uint16_t *q;
addr &= biosmask;
q = (uint16_t *)&(dev->array[addr]);
q = (uint16_t *) &(dev->array[addr]);
return *q;
}
static uint32_t
flash_readl(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *)p;
flash_t *dev = (flash_t *) p;
uint32_t *q;
addr &= biosmask;
q = (uint32_t *)&(dev->array[addr]);
q = (uint32_t *) &(dev->array[addr]);
return *q;
}
static void
flash_write(uint32_t addr, uint8_t val, void *p)
{
@@ -136,55 +125,51 @@ flash_write(uint32_t addr, uint8_t val, void *p)
addr &= biosmask;
switch (dev->command) {
case CMD_ERASE:
if (val == CMD_ERASE_CONFIRM)
memset(dev->array, 0xff, biosmask + 1);
break;
case CMD_ERASE:
if (val == CMD_ERASE_CONFIRM)
memset(dev->array, 0xff, biosmask + 1);
break;
case CMD_PROGRAM:
dev->array[addr] = val;
break;
case CMD_PROGRAM:
dev->array[addr] = val;
break;
default:
dev->command = val;
break;
default:
dev->command = val;
break;
}
}
static void
flash_writew(uint32_t addr, uint16_t val, void *p)
{
}
static void
flash_writel(uint32_t addr, uint32_t val, void *p)
{
}
static void
catalyst_flash_add_mappings(flash_t *dev)
{
memcpy(dev->array, rom, biosmask + 1);
mem_mapping_add(&dev->mapping, 0xe0000, 0x20000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
mem_mapping_add(&(dev->mapping_h[0]), 0xfffc0000, 0x20000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
mem_mapping_add(&(dev->mapping_h[1]), 0xfffe0000, 0x20000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
}
static void
catalyst_flash_reset(void *priv)
{
@@ -193,11 +178,10 @@ catalyst_flash_reset(void *priv)
dev->command = CMD_RESET;
}
static void *
catalyst_flash_init(const device_t *info)
{
FILE *f;
FILE *f;
flash_t *dev;
dev = malloc(sizeof(flash_t));
@@ -217,19 +201,18 @@ catalyst_flash_init(const device_t *info)
f = nvr_fopen(flash_path, "rb");
if (f) {
(void) !fread(dev->array, 0x20000, 1, f);
fclose(f);
(void) !fread(dev->array, 0x20000, 1, f);
fclose(f);
}
return dev;
}
static void
catalyst_flash_close(void *p)
{
FILE *f;
flash_t *dev = (flash_t *)p;
FILE *f;
flash_t *dev = (flash_t *) p;
f = nvr_fopen(flash_path, "wb");
fwrite(dev->array, 0x20000, 1, f);
@@ -241,17 +224,16 @@ catalyst_flash_close(void *p)
free(dev);
}
const device_t catalyst_flash_device = {
.name = "Catalyst 28F010-D Flash BIOS",
.name = "Catalyst 28F010-D Flash BIOS",
.internal_name = "catalyst_flash",
.flags = DEVICE_PCI,
.local = 0,
.init = catalyst_flash_init,
.close = catalyst_flash_close,
.reset = catalyst_flash_reset,
.flags = DEVICE_PCI,
.local = 0,
.init = catalyst_flash_init,
.close = catalyst_flash_close,
.reset = catalyst_flash_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -24,36 +24,32 @@
#include <86box/86box.h>
#include <86box/i2c.h>
typedef struct {
void *i2c;
uint8_t addr, *data, writable;
void *i2c;
uint8_t addr, *data, writable;
uint32_t addr_mask, addr_register;
uint8_t addr_len, addr_pos;
uint32_t addr_mask, addr_register;
uint8_t addr_len, addr_pos;
} i2c_eeprom_t;
#ifdef ENABLE_I2C_EEPROM_LOG
int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG;
static void
i2c_eeprom_log(const char *fmt, ...)
{
va_list ap;
if (i2c_eeprom_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define i2c_eeprom_log(fmt, ...)
# define i2c_eeprom_log(fmt, ...)
#endif
static uint8_t
i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv)
{
@@ -62,19 +58,18 @@ i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv)
i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr);
if (!read) {
dev->addr_pos = 0;
dev->addr_register = (addr << dev->addr_len) & dev->addr_mask;
dev->addr_pos = 0;
dev->addr_register = (addr << dev->addr_len) & dev->addr_mask;
}
return 1;
}
static uint8_t
i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
{
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
uint8_t ret = dev->data[dev->addr_register];
uint8_t ret = dev->data[dev->addr_register];
i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret);
dev->addr_register++;
@@ -83,33 +78,31 @@ i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
return ret;
}
static uint8_t
i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv)
{
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
if (dev->addr_pos < dev->addr_len) {
dev->addr_register <<= 8;
dev->addr_register |= data;
dev->addr_register &= (1 << dev->addr_len) - 1;
dev->addr_register |= addr << dev->addr_len;
dev->addr_register &= dev->addr_mask;
i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %06X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register);
dev->addr_pos += 8;
dev->addr_register <<= 8;
dev->addr_register |= data;
dev->addr_register &= (1 << dev->addr_len) - 1;
dev->addr_register |= addr << dev->addr_len;
dev->addr_register &= dev->addr_mask;
i2c_eeprom_log("I2C EEPROM %s %02X: write(address, %06X)\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register);
dev->addr_pos += 8;
} else {
i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable);
if (dev->writable)
dev->data[dev->addr_register] = data;
dev->addr_register++;
dev->addr_register &= dev->addr_mask; /* roll-over */
return dev->writable;
i2c_eeprom_log("I2C EEPROM %s %02X: write(%06X, %02X) = %d\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, data, !!dev->writable);
if (dev->writable)
dev->data[dev->addr_register] = data;
dev->addr_register++;
dev->addr_register &= dev->addr_mask; /* roll-over */
return dev->writable;
}
return 1;
}
static void
i2c_eeprom_stop(void *bus, uint8_t addr, void *priv)
{
@@ -120,17 +113,15 @@ i2c_eeprom_stop(void *bus, uint8_t addr, void *priv)
dev->addr_pos = 0;
}
uint8_t
log2i(uint32_t i)
{
uint8_t ret = 0;
while ((i >>= 1))
ret++;
ret++;
return ret;
}
void *
i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable)
{
@@ -140,17 +131,17 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w
/* Round size up to the next power of 2. */
uint32_t pow_size = 1 << log2i(size);
if (pow_size < size)
size = pow_size << 1;
size = pow_size << 1;
size &= 0x7fffff; /* address space limit of 8 MB = 7 bits from I2C address + 16 bits */
i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable);
dev->i2c = i2c;
dev->addr = addr;
dev->data = data;
dev->i2c = i2c;
dev->addr = addr;
dev->data = data;
dev->writable = writable;
dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */
dev->addr_len = (size >= 4096) ? 16 : 8; /* use 16-bit addresses on 24C32 and above */
dev->addr_mask = size - 1;
i2c_sethandler(dev->i2c, dev->addr & ~(dev->addr_mask >> dev->addr_len), (dev->addr_mask >> dev->addr_len) + 1, i2c_eeprom_start, i2c_eeprom_read, i2c_eeprom_write, i2c_eeprom_stop, dev);
@@ -158,7 +149,6 @@ i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t w
return dev;
}
void
i2c_eeprom_close(void *dev_handle)
{

View File

@@ -30,14 +30,11 @@
#include <86box/nvr.h>
#include <86box/plat.h>
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
enum
{
enum {
BLOCK_MAIN1,
BLOCK_MAIN2,
BLOCK_MAIN3,
@@ -48,239 +45,231 @@ enum
BLOCKS_NUM
};
enum
{
CMD_READ_ARRAY = 0xff,
CMD_IID = 0x90,
CMD_READ_STATUS = 0x70,
CMD_CLEAR_STATUS = 0x50,
CMD_ERASE_SETUP = 0x20,
CMD_ERASE_CONFIRM = 0xd0,
CMD_ERASE_SUSPEND = 0xb0,
CMD_PROGRAM_SETUP = 0x40,
enum {
CMD_READ_ARRAY = 0xff,
CMD_IID = 0x90,
CMD_READ_STATUS = 0x70,
CMD_CLEAR_STATUS = 0x50,
CMD_ERASE_SETUP = 0x20,
CMD_ERASE_CONFIRM = 0xd0,
CMD_ERASE_SUSPEND = 0xb0,
CMD_PROGRAM_SETUP = 0x40,
CMD_PROGRAM_SETUP_ALT = 0x10
};
typedef struct flash_t {
uint8_t command, status,
pad, flags,
*array;
typedef struct flash_t
{
uint8_t command, status,
pad, flags,
*array;
uint16_t flash_id, pad16;
uint16_t flash_id, pad16;
uint32_t program_addr,
block_start[BLOCKS_NUM], block_end[BLOCKS_NUM],
block_len[BLOCKS_NUM];
uint32_t program_addr,
block_start[BLOCKS_NUM], block_end[BLOCKS_NUM],
block_len[BLOCKS_NUM];
mem_mapping_t mapping[4], mapping_h[16];
mem_mapping_t mapping[4], mapping_h[16];
} flash_t;
static char flash_path[1024];
static char flash_path[1024];
static uint8_t
flash_read(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *) p;
uint8_t ret = 0xff;
uint8_t ret = 0xff;
if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000;
addr ^= 0x10000;
addr &= biosmask;
switch (dev->command) {
case CMD_READ_ARRAY:
default:
ret = dev->array[addr];
break;
case CMD_READ_ARRAY:
default:
ret = dev->array[addr];
break;
case CMD_IID:
if (addr & 1)
ret = dev->flash_id & 0xff;
else
ret = 0x89;
break;
case CMD_IID:
if (addr & 1)
ret = dev->flash_id & 0xff;
else
ret = 0x89;
break;
case CMD_READ_STATUS:
ret = dev->status;
break;
case CMD_READ_STATUS:
ret = dev->status;
break;
}
return ret;
}
static uint16_t
flash_readw(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *) p;
flash_t *dev = (flash_t *) p;
uint16_t *q;
uint16_t ret = 0xffff;
uint16_t ret = 0xffff;
if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000;
addr ^= 0x10000;
addr &= biosmask;
if (dev->flags & FLAG_WORD)
addr &= 0xfffffffe;
addr &= 0xfffffffe;
q = (uint16_t *)&(dev->array[addr]);
q = (uint16_t *) &(dev->array[addr]);
ret = *q;
if (dev->flags & FLAG_WORD) switch (dev->command) {
case CMD_READ_ARRAY:
default:
break;
if (dev->flags & FLAG_WORD)
switch (dev->command) {
case CMD_READ_ARRAY:
default:
break;
case CMD_IID:
if (addr & 2)
ret = dev->flash_id;
else
ret = 0x0089;
break;
case CMD_IID:
if (addr & 2)
ret = dev->flash_id;
else
ret = 0x0089;
break;
case CMD_READ_STATUS:
ret = dev->status;
break;
}
case CMD_READ_STATUS:
ret = dev->status;
break;
}
return ret;
}
static uint32_t
flash_readl(uint32_t addr, void *p)
{
flash_t *dev = (flash_t *)p;
flash_t *dev = (flash_t *) p;
uint32_t *q;
if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000;
addr ^= 0x10000;
addr &= biosmask;
q = (uint32_t *)&(dev->array[addr]);
q = (uint32_t *) &(dev->array[addr]);
return *q;
}
static void
flash_write(uint32_t addr, uint8_t val, void *p)
{
flash_t *dev = (flash_t *) p;
int i;
int i;
uint32_t bb_mask = biosmask & 0xffffe000;
if (biosmask == 0x7ffff)
bb_mask &= 0xffff8000;
bb_mask &= 0xffff8000;
else if (biosmask == 0x3ffff)
bb_mask &= 0xffffc000;
bb_mask &= 0xffffc000;
if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000;
addr ^= 0x10000;
addr &= biosmask;
switch (dev->command) {
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
dev->status = 0x80;
}
dev->command = CMD_READ_STATUS;
break;
dev->status = 0x80;
}
dev->command = CMD_READ_STATUS;
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
dev->array[addr] = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
dev->array[addr] = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
break;
default:
dev->command = val;
switch (val) {
case CMD_CLEAR_STATUS:
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr;
break;
}
default:
dev->command = val;
switch (val) {
case CMD_CLEAR_STATUS:
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr;
break;
}
}
}
static void
flash_writew(uint32_t addr, uint16_t val, void *p)
{
flash_t *dev = (flash_t *) p;
int i;
int i;
uint32_t bb_mask = biosmask & 0xffffe000;
if (biosmask == 0x7ffff)
bb_mask &= 0xffff8000;
bb_mask &= 0xffff8000;
else if (biosmask == 0x3ffff)
bb_mask &= 0xffffc000;
bb_mask &= 0xffffc000;
if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000;
addr ^= 0x10000;
addr &= biosmask;
if (dev->flags & FLAG_WORD) switch (dev->command) {
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
if (dev->flags & FLAG_WORD)
switch (dev->command) {
case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
}
dev->status = 0x80;
}
dev->command = CMD_READ_STATUS;
break;
dev->status = 0x80;
}
dev->command = CMD_READ_STATUS;
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
*(uint16_t *) (&dev->array[addr]) = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
*(uint16_t *) (&dev->array[addr]) = val;
dev->command = CMD_READ_STATUS;
dev->status = 0x80;
break;
default:
dev->command = val & 0xff;
switch (val) {
case CMD_CLEAR_STATUS:
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr;
break;
}
}
default:
dev->command = val & 0xff;
switch (val) {
case CMD_CLEAR_STATUS:
dev->status = 0;
break;
case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i;
}
break;
case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr;
break;
}
}
}
static void
flash_writel(uint32_t addr, uint32_t val, void *p)
{
@@ -290,70 +279,67 @@ flash_writel(uint32_t addr, uint32_t val, void *p)
#endif
}
static void
intel_flash_add_mappings(flash_t *dev)
{
int max = 2, i = 0;
int max = 2, i = 0;
uint32_t base, fbase;
uint32_t sub = 0x20000;
if (biosmask == 0x7ffff) {
sub = 0x80000;
max = 8;
sub = 0x80000;
max = 8;
} else if (biosmask == 0x3ffff) {
sub = 0x40000;
max = 4;
sub = 0x40000;
max = 4;
}
for (i = 0; i < max; i++) {
if (biosmask == 0x7ffff)
base = 0x80000 + (i << 16);
else if (biosmask == 0x3ffff)
base = 0xc0000 + (i << 16);
else
base = 0xe0000 + (i << 16);
if (biosmask == 0x7ffff)
base = 0x80000 + (i << 16);
else if (biosmask == 0x3ffff)
base = 0xc0000 + (i << 16);
else
base = 0xe0000 + (i << 16);
fbase = base & biosmask;
if (dev->flags & FLAG_INV_A16)
fbase ^= 0x10000;
fbase = base & biosmask;
if (dev->flags & FLAG_INV_A16)
fbase ^= 0x10000;
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
if ((max == 2) || (i >= 2)) {
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
}
mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
if ((max == 2) || (i >= 2)) {
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
}
mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000,
flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
}
}
static void
intel_flash_reset(void *priv)
{
flash_t *dev = (flash_t *) priv;
dev->command = CMD_READ_ARRAY;
dev->status = 0;
dev->status = 0;
}
static void *
intel_flash_init(const device_t *info)
{
FILE *f;
FILE *f;
flash_t *dev;
uint8_t type = info->local & 0xff;
uint8_t type = info->local & 0xff;
dev = malloc(sizeof(flash_t));
memset(dev, 0, sizeof(flash_t));
@@ -369,186 +355,185 @@ intel_flash_init(const device_t *info)
memset(dev->array, 0xff, biosmask + 1);
switch (biosmask) {
case 0x7ffff:
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
else
dev->flash_id =(dev->flags & FLAG_BXB) ? 0x8A : 0x89;
case 0x7ffff:
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
else
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x8A : 0x89;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x20000;
dev->block_len[BLOCK_MAIN3] = 0x20000;
dev->block_len[BLOCK_MAIN4] = 0x18000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x20000;
dev->block_len[BLOCK_MAIN3] = 0x20000;
dev->block_len[BLOCK_MAIN4] = 0x18000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_DATA2] = 0x3ffff;
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_DATA1] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_MAIN3] = 0x79fff;
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
} else {
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x79fff;
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x7bfff;
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x7ffff;
}
break;
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_DATA2] = 0x3ffff;
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_DATA1] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_MAIN3] = 0x79fff;
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_MAIN2] = 0x7bfff;
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_MAIN1] = 0x7ffff;
} else {
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x3ffff;
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x79fff;
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x7bfff;
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x7ffff;
}
break;
case 0x3ffff:
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274;
else
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C;
case 0x3ffff:
if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274;
else
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x18000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x18000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000;
if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */
dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x3ffff;
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x1ffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x07fff;
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x05fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x03fff;
} else { /* 28F002BX-T/28F200BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x37fff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x39fff;
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x3bfff;
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x3ffff;
}
break;
if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */
dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x3ffff;
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x1ffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x07fff;
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x05fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x03fff;
} else { /* 28F002BX-T/28F200BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x37fff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x39fff;
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x3bfff;
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x3ffff;
}
break;
default:
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
default:
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x1c000;
dev->block_len[BLOCK_MAIN2] = 0x00000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x01000;
dev->block_len[BLOCK_DATA2] = 0x01000;
dev->block_len[BLOCK_BOOT] = 0x02000;
/* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x1c000;
dev->block_len[BLOCK_MAIN2] = 0x00000;
dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x01000;
dev->block_len[BLOCK_DATA2] = 0x01000;
dev->block_len[BLOCK_BOOT] = 0x02000;
if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */
dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x02fff;
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x03fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x01fff;
} else { /* 28F001BX-T/28F100BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1bfff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x1cfff;
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x1dfff;
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
}
break;
if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */
dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x02fff;
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x03fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x01fff;
} else { /* 28F001BX-T/28F100BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1bfff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x1cfff;
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x1dfff;
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x1ffff;
}
break;
}
intel_flash_add_mappings(dev);
dev->command = CMD_READ_ARRAY;
dev->status = 0;
dev->status = 0;
f = nvr_fopen(flash_path, "rb");
if (f) {
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
if (dev->block_len[BLOCK_MAIN2])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
if (dev->block_len[BLOCK_MAIN3])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
if (dev->block_len[BLOCK_MAIN4])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
if (dev->block_len[BLOCK_MAIN2])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
if (dev->block_len[BLOCK_MAIN3])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
if (dev->block_len[BLOCK_MAIN4])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
fclose(f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
fclose(f);
}
return dev;
}
static void
intel_flash_close(void *p)
{
FILE *f;
flash_t *dev = (flash_t *)p;
FILE *f;
flash_t *dev = (flash_t *) p;
f = nvr_fopen(flash_path, "wb");
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
if (dev->block_len[BLOCK_MAIN2])
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
if (dev->block_len[BLOCK_MAIN3])
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
if (dev->block_len[BLOCK_MAIN4])
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
@@ -562,43 +547,43 @@ intel_flash_close(void *p)
/* For AMI BIOS'es - Intel 28F001BXT with A16 pin inverted. */
const device_t intel_flash_bxt_ami_device = {
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
.internal_name = "intel_flash_bxt_ami",
.flags = DEVICE_PCI,
.local = FLAG_INV_A16,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
.flags = DEVICE_PCI,
.local = FLAG_INV_A16,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t intel_flash_bxt_device = {
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
.name = "Intel 28F001BXT/28F002BXT/28F004BXT Flash BIOS",
.internal_name = "intel_flash_bxt",
.flags = DEVICE_PCI,
.local = 0,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
.flags = DEVICE_PCI,
.local = 0,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t intel_flash_bxb_device = {
.name = "Intel 28F001BXB/28F002BXB/28F004BXB Flash BIOS",
.name = "Intel 28F001BXB/28F002BXB/28F004BXB Flash BIOS",
.internal_name = "intel_flash_bxb",
.flags = DEVICE_PCI,
.local = FLAG_BXB,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
.flags = DEVICE_PCI,
.local = FLAG_BXB,
.init = intel_flash_init,
.close = intel_flash_close,
.reset = intel_flash_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

File diff suppressed because it is too large Load Diff

View File

@@ -38,35 +38,32 @@
#include <86box/machine.h>
#include <86box/m_xt_xi8088.h>
#ifdef ENABLE_ROM_LOG
int rom_do_log = ENABLE_ROM_LOG;
static void
rom_log(const char *fmt, ...)
{
va_list ap;
if (rom_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define rom_log(fmt, ...)
# define rom_log(fmt, ...)
#endif
void
rom_add_path(const char* path)
rom_add_path(const char *path)
{
char cwd[1024] = { 0 };
rom_path_t* rom_path = &rom_paths;
rom_path_t *rom_path = &rom_paths;
if (rom_paths.path[0] != '\0')
{
if (rom_paths.path[0] != '\0') {
// Iterate to the end of the list.
while (rom_path->next != NULL) {
rom_path = rom_path->next;
@@ -77,7 +74,7 @@ rom_add_path(const char* path)
}
// Save the path, turning it into absolute if needed.
if (!path_abs((char*) path)) {
if (!path_abs((char *) path)) {
plat_getcwd(cwd, sizeof(cwd));
path_slash(cwd);
snprintf(rom_path->path, sizeof(rom_path->path), "%s%s", cwd, path);
@@ -89,13 +86,12 @@ rom_add_path(const char* path)
path_slash(rom_path->path);
}
FILE *
rom_fopen(char *fn, char *mode)
{
char temp[1024];
char temp[1024];
rom_path_t *rom_path;
FILE *fp = NULL;
FILE *fp = NULL;
if (strstr(fn, "roms/") == fn) {
/* Relative path */
@@ -114,11 +110,10 @@ rom_fopen(char *fn, char *mode)
}
}
int
rom_getfile(char *fn, char *s, int size)
{
char temp[1024];
char temp[1024];
rom_path_t *rom_path;
if (strstr(fn, "roms/") == fn) {
@@ -144,7 +139,6 @@ rom_getfile(char *fn, char *s, int size)
}
}
int
rom_present(char *fn)
{
@@ -152,104 +146,99 @@ rom_present(char *fn)
f = rom_fopen(fn, "rb");
if (f != NULL) {
(void)fclose(f);
return(1);
(void) fclose(f);
return (1);
}
return(0);
return (0);
}
uint8_t
rom_read(uint32_t addr, void *priv)
{
rom_t *rom = (rom_t *)priv;
rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE)
rom_log("ROM: read byte from BIOS at %06lX\n", addr);
if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read byte from BIOS at %06lX\n", addr);
#endif
if (addr < rom->mapping.base)
return 0xff;
return 0xff;
if (addr >= (rom->mapping.base + rom->sz))
return 0xff;
return(rom->rom[(addr - rom->mapping.base) & rom->mask]);
return 0xff;
return (rom->rom[(addr - rom->mapping.base) & rom->mask]);
}
uint16_t
rom_readw(uint32_t addr, void *priv)
{
rom_t *rom = (rom_t *)priv;
rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE)
rom_log("ROM: read word from BIOS at %06lX\n", addr);
if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read word from BIOS at %06lX\n", addr);
#endif
if (addr < (rom->mapping.base - 1))
return 0xffff;
return 0xffff;
if (addr >= (rom->mapping.base + rom->sz))
return 0xffff;
return(*(uint16_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]);
return 0xffff;
return (*(uint16_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
}
uint32_t
rom_readl(uint32_t addr, void *priv)
{
rom_t *rom = (rom_t *)priv;
rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE)
rom_log("ROM: read long from BIOS at %06lX\n", addr);
if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read long from BIOS at %06lX\n", addr);
#endif
if (addr < (rom->mapping.base - 3))
return 0xffffffff;
return 0xffffffff;
if (addr >= (rom->mapping.base + rom->sz))
return 0xffffffff;
return(*(uint32_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]);
return 0xffffffff;
return (*(uint32_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
}
int
rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
{
FILE *f = rom_fopen(fn, "rb");
int i;
int i;
if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn);
return(0);
rom_log("ROM: image '%s' not found\n", fn);
return (0);
}
/* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000)
addr = 0;
addr = 0;
else
addr &= 0x03ffff;
addr &= 0x03ffff;
if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading even data\n");
}
for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading od data\n");
}
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading even data\n");
}
for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading od data\n");
}
}
(void)fclose(f);
(void) fclose(f);
return(1);
return (1);
}
/* Load a ROM BIOS from its chips, interleaved mode. */
int
rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
@@ -257,29 +246,28 @@ rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
FILE *f = rom_fopen(fn, "rb");
if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn);
return(0);
rom_log("ROM: image '%s' not found\n", fn);
return (0);
}
/* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000)
addr = 0;
addr = 0;
else
addr &= 0x03ffff;
addr &= 0x03ffff;
if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
if (fread(ptr+addr, 1, sz, f) > sz)
fatal("rom_load_linear(): Error reading data\n");
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
if (fread(ptr + addr, 1, sz, f) > sz)
fatal("rom_load_linear(): Error reading data\n");
}
(void)fclose(f);
(void) fclose(f);
return(1);
return (1);
}
/* Load a ROM BIOS from its chips, linear mode with high bit flipped. */
int
rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
@@ -287,84 +275,80 @@ rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
FILE *f = rom_fopen(fn, "rb");
if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn);
return(0);
rom_log("ROM: image '%s' not found\n", fn);
return (0);
}
/* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000)
{
addr = 0;
}
else
{
addr &= 0x03ffff;
if (addr >= 0x40000) {
addr = 0;
} else {
addr &= 0x03ffff;
}
(void)fseek(f, 0, SEEK_END);
(void) fseek(f, 0, SEEK_END);
if (ftell(f) < sz) {
(void)fclose(f);
return(0);
(void) fclose(f);
return (0);
}
if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n");
if (fread(ptr+addr+0x10000, 1, sz >> 1, f) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
if (fread(ptr+addr, sz >> 1, 1, f) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n");
if (fread(ptr + addr + 0x10000, 1, sz >> 1, f) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
if (fread(ptr + addr, sz >> 1, 1, f) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n");
}
(void)fclose(f);
(void) fclose(f);
return(1);
return (1);
}
/* Load a ROM BIOS from its chips, interleaved mode. */
int
rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr)
{
FILE *fl = rom_fopen(fnl, "rb");
FILE *fh = rom_fopen(fnh, "rb");
int c;
int c;
if (fl == NULL || fh == NULL) {
if (fl == NULL) rom_log("ROM: image '%s' not found\n", fnl);
else (void)fclose(fl);
if (fh == NULL) rom_log("ROM: image '%s' not found\n", fnh);
else (void)fclose(fh);
if (fl == NULL)
rom_log("ROM: image '%s' not found\n", fnl);
else
(void) fclose(fl);
if (fh == NULL)
rom_log("ROM: image '%s' not found\n", fnh);
else
(void) fclose(fh);
return(0);
return (0);
}
/* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000)
{
addr = 0;
}
else
{
addr &= 0x03ffff;
if (addr >= 0x40000) {
addr = 0;
} else {
addr &= 0x03ffff;
}
if (ptr != NULL) {
(void)fseek(fl, off, SEEK_SET);
(void)fseek(fh, off, SEEK_SET);
for (c=0; c<sz; c+=2) {
ptr[addr+c] = fgetc(fl) & 0xff;
ptr[addr+c+1] = fgetc(fh) & 0xff;
}
(void) fseek(fl, off, SEEK_SET);
(void) fseek(fh, off, SEEK_SET);
for (c = 0; c < sz; c += 2) {
ptr[addr + c] = fgetc(fl) & 0xff;
ptr[addr + c + 1] = fgetc(fh) & 0xff;
}
}
(void)fclose(fh);
(void)fclose(fl);
(void) fclose(fh);
(void) fclose(fl);
return(1);
return (1);
}
static int
bios_normalize(int n, int up)
{
@@ -373,38 +357,35 @@ bios_normalize(int n, int up)
/* 0x2000 -> 0x4000; 0x4000 -> 0x4000; 0x6000 -> 0x8000 */
if (up && (n % MEM_GRANULARITY_SIZE))
temp_n += MEM_GRANULARITY_SIZE;
temp_n += MEM_GRANULARITY_SIZE;
return temp_n;
}
static uint8_t *
rom_reset(uint32_t addr, int sz)
{
biosaddr = bios_normalize(addr, 0);
biosmask = bios_normalize(sz, 1) - 1;
if ((biosaddr + biosmask) > 0x000fffff)
biosaddr = 0x000fffff - biosmask;
biosaddr = 0x000fffff - biosmask;
rom_log("Load BIOS: %i bytes at %08X-%08X\n", biosmask + 1, biosaddr, biosaddr + biosmask);
/* If not done yet, allocate a 128KB buffer for the BIOS ROM. */
if (rom != NULL) {
rom_log("ROM allocated, freeing...\n");
free(rom);
rom = NULL;
rom_log("ROM allocated, freeing...\n");
free(rom);
rom = NULL;
}
rom_log("Allocating ROM...\n");
rom = (uint8_t *)malloc(biosmask + 1);
rom = (uint8_t *) malloc(biosmask + 1);
rom_log("Filling ROM with FF's...\n");
memset(rom, 0xff, biosmask + 1);
return rom;
}
uint8_t
bios_read(uint32_t addr, void *priv)
{
@@ -413,12 +394,11 @@ bios_read(uint32_t addr, void *priv)
addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = rom[addr - biosaddr];
ret = rom[addr - biosaddr];
return ret;
}
uint16_t
bios_readw(uint32_t addr, void *priv)
{
@@ -427,12 +407,11 @@ bios_readw(uint32_t addr, void *priv)
addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint16_t *)&rom[addr - biosaddr];
ret = *(uint16_t *) &rom[addr - biosaddr];
return ret;
}
uint32_t
bios_readl(uint32_t addr, void *priv)
{
@@ -441,113 +420,110 @@ bios_readl(uint32_t addr, void *priv)
addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint32_t *)&rom[addr - biosaddr];
ret = *(uint32_t *) &rom[addr - biosaddr];
return ret;
}
static void
bios_add(void)
{
int temp_cpu_type, temp_cpu_16bitbus = 1;
int temp_is286 = 0, temp_is6117 = 0;
if (/*AT && */cpu_s) {
temp_cpu_type = cpu_s->cpu_type;
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC );
temp_is286 = (temp_cpu_type >= CPU_286);
temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi");
if (/*AT && */ cpu_s) {
temp_cpu_type = cpu_s->cpu_type;
temp_cpu_16bitbus = (temp_cpu_type == CPU_286 || temp_cpu_type == CPU_386SX || temp_cpu_type == CPU_486SLC || temp_cpu_type == CPU_IBM386SLC || temp_cpu_type == CPU_IBM486SLC);
temp_is286 = (temp_cpu_type >= CPU_286);
temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi");
}
if (biosmask > 0x1ffff) {
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
bios_read,bios_readw,bios_readl,
NULL,NULL,NULL,
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
bios_read, bios_readw, bios_readl,
NULL, NULL, NULL,
&rom[0x20000], MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(0x0e0000, 0x20000,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
mem_set_mem_state_both(0x0e0000, 0x20000,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} else {
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
bios_read,bios_readw,bios_readl,
NULL,NULL,NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
bios_read, bios_readw, bios_readl,
NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(biosaddr, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
mem_set_mem_state_both(biosaddr, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
}
if (temp_is6117) {
mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1,
bios_read,bios_readw,bios_readl,
NULL,NULL,NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1,
bios_read, bios_readw, bios_readl,
NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} else if (temp_is286) {
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
bios_read,bios_readw,bios_readl,
NULL,NULL,NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0);
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
bios_read, bios_readw, bios_readl,
NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
mem_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS);
}
}
/* These four are for loading the BIOS. */
int
bios_load(char *fn1, char *fn2, uint32_t addr, int sz, int off, int flags)
{
uint8_t ret = 0;
uint8_t ret = 0;
uint8_t *ptr = NULL;
int i, old_sz = sz;
int i, old_sz = sz;
/*
f0000, 65536 = prepare 64k rom starting at f0000, load 64k bios at 0000
fe000, 65536 = prepare 64k rom starting at f0000, load 8k bios at e000
fe000, 49152 = prepare 48k rom starting at f4000, load 8k bios at a000
fe000, 8192 = prepare 16k rom starting at fc000, load 8k bios at 2000
f0000, 65536 = prepare 64k rom starting at f0000, load 64k bios at 0000
fe000, 65536 = prepare 64k rom starting at f0000, load 8k bios at e000
fe000, 49152 = prepare 48k rom starting at f4000, load 8k bios at a000
fe000, 8192 = prepare 16k rom starting at fc000, load 8k bios at 2000
*/
if (!bios_only)
ptr = (flags & FLAG_AUX) ? rom : rom_reset(addr, sz);
ptr = (flags & FLAG_AUX) ? rom : rom_reset(addr, sz);
if (!(flags & FLAG_AUX) && ((addr + sz) > 0x00100000))
sz = 0x00100000 - addr;
sz = 0x00100000 - addr;
#ifdef ENABLE_ROM_LOG
if (!bios_only)
rom_log("%sing %i bytes of %sBIOS starting with ptr[%08X] (ptr = %08X)\n", (bios_only) ? "Check" : "Load", sz, (flags & FLAG_AUX) ? "auxiliary " : "", addr - biosaddr, ptr);
rom_log("%sing %i bytes of %sBIOS starting with ptr[%08X] (ptr = %08X)\n", (bios_only) ? "Check" : "Load", sz, (flags & FLAG_AUX) ? "auxiliary " : "", addr - biosaddr, ptr);
#endif
if (flags & FLAG_INT)
ret = rom_load_interleaved(fn1, fn2, addr - biosaddr, sz, off, ptr);
ret = rom_load_interleaved(fn1, fn2, addr - biosaddr, sz, off, ptr);
else {
if (flags & FLAG_INV)
ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr);
else
ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr);
if (flags & FLAG_INV)
ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr);
else
ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr);
}
if (!bios_only && (flags & FLAG_REP) && (old_sz >= 65536) && (sz < old_sz)) {
old_sz /= sz;
for (i = 0; i < (old_sz - 1); i++) {
rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz);
memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz);
}
old_sz /= sz;
for (i = 0; i < (old_sz - 1); i++) {
rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz);
memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz);
}
}
if (!bios_only && ret && !(flags & FLAG_AUX))
bios_add();
bios_add();
return ret;
}
int
bios_load_linear_combined(char *fn1, char *fn2, int sz, int off)
{
@@ -559,7 +535,6 @@ bios_load_linear_combined(char *fn1, char *fn2, int sz, int off)
return ret;
}
int
bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off)
{
@@ -570,12 +545,11 @@ bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5
ret &= bios_load_aux_linear(fn2, 0x000c0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off);
if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
return ret;
}
int
bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off)
{
@@ -586,12 +560,11 @@ bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *
ret &= bios_load_aux_linear(fn2, 0x000d0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off);
if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
return ret;
}
int
rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags)
{
@@ -602,26 +575,25 @@ rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_
memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */
if (! rom_load_linear(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return(-1);
if (!rom_load_linear(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return (-1);
}
rom->sz = sz;
rom->sz = sz;
rom->mask = mask;
mem_mapping_add(&rom->mapping,
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0);
return (0);
}
int
rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags)
{
@@ -632,26 +604,25 @@ rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off,
memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */
if (! rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return(-1);
if (!rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return (-1);
}
rom->sz = sz;
rom->sz = sz;
rom->mask = mask;
mem_mapping_add(&rom->mapping,
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0);
return (0);
}
int
rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags)
{
@@ -660,21 +631,21 @@ rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, in
memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */
if (! rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return(-1);
if (!rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */
free(rom->rom);
rom->rom = NULL;
return (-1);
}
rom->sz = sz;
rom->sz = sz;
rom->mask = mask;
mem_mapping_add(&rom->mapping,
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
addr, sz,
rom_read, rom_readw, rom_readl,
NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0);
return (0);
}

View File

@@ -29,117 +29,107 @@
#include <86box/mem.h>
#include <86box/smram.h>
static smram_t *base_smram, *last_smram;
static smram_t *base_smram, *last_smram;
static uint8_t use_separate_smram = 0;
static uint8_t smram[0x40000];
static uint8_t use_separate_smram = 0;
static uint8_t smram[0x40000];
#ifdef ENABLE_SMRAM_LOG
int smram_do_log = ENABLE_SMRAM_LOG;
static void
smram_log(const char *fmt, ...)
{
va_list ap;
if (smram_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define smram_log(fmt, ...)
# define smram_log(fmt, ...)
#endif
static uint8_t
smram_read(uint32_t addr, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (new_addr >= (1 << 30))
return mem_read_ram_2gb(new_addr, priv);
return mem_read_ram_2gb(new_addr, priv);
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_ram(new_addr, priv);
return mem_read_ram(new_addr, priv);
else
return dev->mapping.exec[addr - dev->host_base];
return dev->mapping.exec[addr - dev->host_base];
}
static uint16_t
smram_readw(uint32_t addr, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (new_addr >= (1 << 30))
return mem_read_ram_2gbw(new_addr, priv);
return mem_read_ram_2gbw(new_addr, priv);
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_ramw(new_addr, priv);
return mem_read_ramw(new_addr, priv);
else
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
return *(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]);
}
static uint32_t
smram_readl(uint32_t addr, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (new_addr >= (1 << 30))
return mem_read_ram_2gbl(new_addr, priv);
return mem_read_ram_2gbl(new_addr, priv);
else if (!use_separate_smram || (new_addr >= 0xa0000))
return mem_read_raml(new_addr, priv);
return mem_read_raml(new_addr, priv);
else
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
return *(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]);
}
static void
smram_write(uint32_t addr, uint8_t val, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_ram(new_addr, val, priv);
mem_write_ram(new_addr, val, priv);
else
dev->mapping.exec[addr - dev->host_base] = val;
dev->mapping.exec[addr - dev->host_base] = val;
}
static void
smram_writew(uint32_t addr, uint16_t val, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_ramw(new_addr, val, priv);
mem_write_ramw(new_addr, val, priv);
else
*(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
*(uint16_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
}
static void
smram_writel(uint32_t addr, uint32_t val, void *priv)
{
smram_t *dev = (smram_t *) priv;
smram_t *dev = (smram_t *) priv;
uint32_t new_addr = addr - dev->host_base + dev->ram_base;
if (!use_separate_smram || (new_addr >= 0xa0000))
mem_write_raml(new_addr, val, priv);
mem_write_raml(new_addr, val, priv);
else
*(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
*(uint32_t *) &(dev->mapping.exec[addr - dev->host_base]) = val;
}
/* Make a backup copy of host_base and size of all the SMRAM structs, needed so that if
the SMRAM mappings change while in SMM, they will be recalculated on return. */
void
@@ -148,15 +138,14 @@ smram_backup_all(void)
smram_t *temp_smram = base_smram, *next;
while (temp_smram != NULL) {
temp_smram->old_host_base = temp_smram->host_base;
temp_smram->old_size = temp_smram->size;
temp_smram->old_host_base = temp_smram->host_base;
temp_smram->old_size = temp_smram->size;
next = temp_smram->next;
temp_smram = next;
next = temp_smram->next;
temp_smram = next;
}
}
/* Recalculate any mappings, including the backup if returning from SMM. */
void
smram_recalc_all(int ret)
@@ -164,55 +153,54 @@ smram_recalc_all(int ret)
smram_t *temp_smram = base_smram, *next;
if (base_smram == NULL)
return;
return;
if (ret) {
while (temp_smram != NULL) {
if (temp_smram->old_size != 0x00000000)
mem_mapping_recalc(temp_smram->old_host_base, temp_smram->old_size);
temp_smram->old_host_base = temp_smram->old_size = 0x00000000;
while (temp_smram != NULL) {
if (temp_smram->old_size != 0x00000000)
mem_mapping_recalc(temp_smram->old_host_base, temp_smram->old_size);
temp_smram->old_host_base = temp_smram->old_size = 0x00000000;
next = temp_smram->next;
temp_smram = next;
}
next = temp_smram->next;
temp_smram = next;
}
}
temp_smram = base_smram;
while (temp_smram != NULL) {
if (temp_smram->size != 0x00000000)
mem_mapping_recalc(temp_smram->host_base, temp_smram->size);
if (temp_smram->size != 0x00000000)
mem_mapping_recalc(temp_smram->host_base, temp_smram->size);
next = temp_smram->next;
temp_smram = next;
next = temp_smram->next;
temp_smram = next;
}
flushmmucache();
}
/* Delete a SMRAM mapping. */
void
smram_del(smram_t *smr)
{
/* Do a sanity check */
if ((base_smram == NULL) && (last_smram != NULL)) {
fatal("smram_del(): NULL base SMRAM with non-NULL last SMRAM\n");
return;
fatal("smram_del(): NULL base SMRAM with non-NULL last SMRAM\n");
return;
} else if ((base_smram != NULL) && (last_smram == NULL)) {
fatal("smram_del(): Non-NULL base SMRAM with NULL last SMRAM\n");
return;
fatal("smram_del(): Non-NULL base SMRAM with NULL last SMRAM\n");
return;
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
fatal("smram_del(): Base SMRAM with a preceding SMRAM\n");
return;
fatal("smram_del(): Base SMRAM with a preceding SMRAM\n");
return;
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
fatal("smram_del(): Last SMRAM with a following SMRAM\n");
return;
fatal("smram_del(): Last SMRAM with a following SMRAM\n");
return;
}
if (smr == NULL) {
fatal("smram_del(): Invalid SMRAM mapping\n");
return;
fatal("smram_del(): Invalid SMRAM mapping\n");
return;
}
/* Disable the entry. */
@@ -220,20 +208,19 @@ smram_del(smram_t *smr)
/* Zap it from the list. */
if (smr->prev != NULL)
smr->prev->next = smr->next;
smr->prev->next = smr->next;
if (smr->next != NULL)
smr->next->prev = smr->prev;
smr->next->prev = smr->prev;
/* Check if it's the first or the last mapping. */
if (base_smram == smr)
base_smram = smr->next;
base_smram = smr->next;
if (last_smram == smr)
last_smram = smr->prev;
last_smram = smr->prev;
free(smr);
}
/* Add a SMRAM mapping. */
smram_t *
smram_add(void)
@@ -242,63 +229,61 @@ smram_add(void)
/* Do a sanity check */
if ((base_smram == NULL) && (last_smram != NULL)) {
fatal("smram_add(): NULL base SMRAM with non-NULL last SMRAM\n");
return NULL;
fatal("smram_add(): NULL base SMRAM with non-NULL last SMRAM\n");
return NULL;
} else if ((base_smram != NULL) && (last_smram == NULL)) {
fatal("smram_add(): Non-NULL base SMRAM with NULL last SMRAM\n");
return NULL;
fatal("smram_add(): Non-NULL base SMRAM with NULL last SMRAM\n");
return NULL;
} else if ((base_smram != NULL) && (base_smram->prev != NULL)) {
fatal("smram_add(): Base SMRAM with a preceding SMRAM\n");
return NULL;
fatal("smram_add(): Base SMRAM with a preceding SMRAM\n");
return NULL;
} else if ((last_smram != NULL) && (last_smram->next != NULL)) {
fatal("smram_add(): Last SMRAM with a following SMRAM\n");
return NULL;
fatal("smram_add(): Last SMRAM with a following SMRAM\n");
return NULL;
}
temp_smram = (smram_t *) malloc(sizeof(smram_t));
if (temp_smram == NULL) {
fatal("smram_add(): temp_smram malloc failed\n");
return NULL;
fatal("smram_add(): temp_smram malloc failed\n");
return NULL;
}
memset(temp_smram, 0x00, sizeof(smram_t));
memset(&(temp_smram->mapping), 0x00, sizeof(mem_mapping_t));
/* Add struct to the beginning of the list if necessary.*/
if (base_smram == NULL)
base_smram = temp_smram;
base_smram = temp_smram;
/* Add struct to the end of the list.*/
if (last_smram == NULL)
temp_smram->prev = NULL;
else {
temp_smram->prev = last_smram;
last_smram->next = temp_smram;
temp_smram->prev = NULL;
else {
temp_smram->prev = last_smram;
last_smram->next = temp_smram;
}
last_smram = temp_smram;
mem_mapping_add(&(temp_smram->mapping), 0x00000000, 0x00000000,
smram_read,smram_readw,smram_readl,
smram_write,smram_writew,smram_writel,
ram, MEM_MAPPING_SMRAM, temp_smram);
smram_read, smram_readw, smram_readl,
smram_write, smram_writew, smram_writel,
ram, MEM_MAPPING_SMRAM, temp_smram);
smram_set_separate_smram(0);
return temp_smram;
}
/* Set memory state in the specified model (normal or SMM) according to the specified flags,
separately for bus and CPU. */
void
smram_map_ex(int bus, int smm, uint32_t addr, uint32_t size, int is_smram)
{
if (bus)
mem_set_access_smram_bus(smm, addr, size, is_smram);
mem_set_access_smram_bus(smm, addr, size, is_smram);
else
mem_set_access_smram_cpu(smm, addr, size, is_smram);
mem_set_access_smram_cpu(smm, addr, size, is_smram);
}
/* Set memory state in the specified model (normal or SMM) according to the specified flags. */
void
smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
@@ -307,28 +292,26 @@ smram_map(int smm, uint32_t addr, uint32_t size, int is_smram)
smram_map_ex(1, smm, addr, size, is_smram);
}
/* Disable a specific SMRAM mapping. */
void
smram_disable(smram_t *smr)
{
if (smr == NULL) {
fatal("smram_disable(): Invalid SMRAM mapping\n");
return;
fatal("smram_disable(): Invalid SMRAM mapping\n");
return;
}
if (smr->size != 0x00000000) {
smram_map(0, smr->host_base, smr->size, 0);
smram_map(1, smr->host_base, smr->size, 0);
smram_map(0, smr->host_base, smr->size, 0);
smram_map(1, smr->host_base, smr->size, 0);
smr->host_base = smr->ram_base = 0x00000000;
smr->size = 0x00000000;
smr->host_base = smr->ram_base = 0x00000000;
smr->size = 0x00000000;
mem_mapping_disable(&(smr->mapping));
mem_mapping_disable(&(smr->mapping));
}
}
/* Disable all SMRAM mappings. */
void
smram_disable_all(void)
@@ -336,56 +319,54 @@ smram_disable_all(void)
smram_t *temp_smram = base_smram, *next;
while (temp_smram != NULL) {
smram_disable(temp_smram);
smram_disable(temp_smram);
next = temp_smram->next;
temp_smram = next;
next = temp_smram->next;
temp_smram = next;
}
}
/* Enable SMRAM mappings according to flags for both normal and SMM modes, separately for bus
and CPU. */
void
smram_enable_ex(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus)
int flags_normal, int flags_normal_bus, int flags_smm, int flags_smm_bus)
{
if (smr == NULL) {
fatal("smram_add(): Invalid SMRAM mapping\n");
return;
fatal("smram_add(): Invalid SMRAM mapping\n");
return;
}
if ((size != 0x00000000) && (flags_normal || flags_smm)) {
smr->host_base = host_base;
smr->ram_base = ram_base,
smr->size = size;
smr->host_base = host_base;
smr->ram_base = ram_base,
smr->size = size;
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) {
if (smr->ram_base < (1 << 30))
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
else
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
} else {
if (smr->ram_base == 0x00030000)
mem_mapping_set_exec(&(smr->mapping), smram);
else if (smr->ram_base == 0x00040000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x10000);
else if (smr->ram_base == 0x00060000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x20000);
else if (smr->ram_base == 0x00070000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x30000);
}
mem_mapping_set_addr(&(smr->mapping), smr->host_base, smr->size);
if (!use_separate_smram || (smr->ram_base >= 0x000a0000)) {
if (smr->ram_base < (1 << 30))
mem_mapping_set_exec(&(smr->mapping), ram + smr->ram_base);
else
mem_mapping_set_exec(&(smr->mapping), ram2 + smr->ram_base - (1 << 30));
} else {
if (smr->ram_base == 0x00030000)
mem_mapping_set_exec(&(smr->mapping), smram);
else if (smr->ram_base == 0x00040000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x10000);
else if (smr->ram_base == 0x00060000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x20000);
else if (smr->ram_base == 0x00070000)
mem_mapping_set_exec(&(smr->mapping), smram + 0x30000);
}
smram_map_ex(0, 0, host_base, size, flags_normal);
smram_map_ex(1, 0, host_base, size, flags_normal_bus);
smram_map_ex(0, 1, host_base, size, flags_smm);
smram_map_ex(1, 1, host_base, size, flags_smm_bus);
smram_map_ex(0, 0, host_base, size, flags_normal);
smram_map_ex(1, 0, host_base, size, flags_normal_bus);
smram_map_ex(0, 1, host_base, size, flags_smm);
smram_map_ex(1, 1, host_base, size, flags_smm_bus);
} else
smram_disable(smr);
smram_disable(smr);
}
/* Enable SMRAM mappings according to flags for both normal and SMM modes. */
void
smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size, int flags_normal, int flags_smm)
@@ -393,7 +374,6 @@ smram_enable(smram_t *smr, uint32_t host_base, uint32_t ram_base, uint32_t size,
smram_enable_ex(smr, host_base, ram_base, size, flags_normal, flags_normal, flags_smm, flags_smm);
}
/* Checks if a SMRAM mapping is enabled or not. */
int
smram_enabled(smram_t *smr)
@@ -401,27 +381,25 @@ smram_enabled(smram_t *smr)
int ret = 0;
if (smr == NULL)
ret = 0;
ret = 0;
else
ret = (smr->size != 0x00000000);
ret = (smr->size != 0x00000000);
return ret;
}
/* Changes the SMRAM state. */
void
smram_state_change(smram_t *smr, int smm, int flags)
{
if (smr == NULL) {
fatal("smram_tate_change(): Invalid SMRAM mapping\n");
return;
fatal("smram_tate_change(): Invalid SMRAM mapping\n");
return;
}
smram_map(smm, smr->host_base, smr->size, flags);
}
void
smram_set_separate_smram(uint8_t set)
{

View File

@@ -28,58 +28,52 @@
#include <86box/version.h>
#include <86box/machine.h>
#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) -15) : (x))
#define SPD_ROLLUP(x) ((x) >= 16 ? ((x) - 15) : (x))
int spd_present = 0;
spd_t *spd_modules[SPD_MAX_SLOTS];
int spd_present = 0;
spd_t *spd_modules[SPD_MAX_SLOTS];
static const device_t spd_device;
#ifdef ENABLE_SPD_LOG
int spd_do_log = ENABLE_SPD_LOG;
static void
spd_log(const char *fmt, ...)
{
va_list ap;
if (spd_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define spd_log(fmt, ...)
# define spd_log(fmt, ...)
#endif
static void
spd_close(void *priv)
{
spd_log("SPD: close()\n");
for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) {
if (spd_modules[i])
i2c_eeprom_close(spd_modules[i]->eeprom);
if (spd_modules[i])
i2c_eeprom_close(spd_modules[i]->eeprom);
}
spd_present = 0;
}
static void *
spd_init(const device_t *info)
{
spd_log("SPD: init()\n");
for (uint8_t i = 0; i < SPD_MAX_SLOTS; i++) {
if (spd_modules[i])
spd_modules[i]->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + i, spd_modules[i]->data, sizeof(spd_modules[i]->data), 0);
if (spd_modules[i])
spd_modules[i]->eeprom = i2c_eeprom_init(i2c_smbus, SPD_BASE_ADDR + i, spd_modules[i]->data, sizeof(spd_modules[i]->data), 0);
}
spd_present = 1;
@@ -87,7 +81,6 @@ spd_init(const device_t *info)
return &spd_modules;
}
int
comp_ui16_rev(const void *elem1, const void *elem2)
{
@@ -96,123 +89,120 @@ comp_ui16_rev(const void *elem1, const void *elem2)
return ((a > b) ? -1 : ((a < b) ? 1 : 0));
}
void
spd_populate(uint16_t *rows, uint8_t slot_count, uint16_t total_size, uint16_t min_module_size, uint16_t max_module_size, uint8_t enable_asym)
{
uint8_t row, next_empty_row, split, i;
uint8_t row, next_empty_row, split, i;
uint16_t asym;
/* Populate rows with modules in power-of-2 capacities. */
memset(rows, 0, SPD_MAX_SLOTS << 1);
for (row = 0; row < slot_count && total_size; row++) {
/* populate slot */
rows[row] = 1 << log2i(MIN(total_size, max_module_size));
if (total_size >= rows[row]) {
spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]);
total_size -= rows[row];
} else {
rows[row] = 0;
break;
}
/* populate slot */
rows[row] = 1 << log2i(MIN(total_size, max_module_size));
if (total_size >= rows[row]) {
spd_log("SPD: Initial row %d = %d MB\n", row, rows[row]);
total_size -= rows[row];
} else {
rows[row] = 0;
break;
}
}
/* Did we populate all the RAM? */
if (total_size) {
/* Work backwards to add the missing RAM as asymmetric modules if possible. */
if (enable_asym) {
row = slot_count - 1;
do {
asym = (1 << log2i(MIN(total_size, rows[row])));
if (rows[row] + asym <= max_module_size) {
rows[row] += asym;
total_size -= asym;
}
} while ((row-- > 0) && total_size);
}
/* Work backwards to add the missing RAM as asymmetric modules if possible. */
if (enable_asym) {
row = slot_count - 1;
do {
asym = (1 << log2i(MIN(total_size, rows[row])));
if (rows[row] + asym <= max_module_size) {
rows[row] += asym;
total_size -= asym;
}
} while ((row-- > 0) && total_size);
}
if (total_size) /* still not enough */
spd_log("SPD: Not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size);
if (total_size) /* still not enough */
spd_log("SPD: Not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size);
}
/* Populate empty rows by splitting modules... */
split = (total_size == 0); /* ...if possible. */
while (split) {
/* Look for a module to split. */
split = 0;
for (row = 0; row < slot_count; row++) {
if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row]))))
continue; /* no module here, module is too small to be split, or asymmetric module */
/* Look for a module to split. */
split = 0;
for (row = 0; row < slot_count; row++) {
if ((rows[row] < (min_module_size << 1)) || (rows[row] != (1 << log2i(rows[row]))))
continue; /* no module here, module is too small to be split, or asymmetric module */
/* Find next empty row. */
next_empty_row = 0;
for (i = row + 1; i < slot_count && !next_empty_row; i++) {
if (!rows[i])
next_empty_row = i;
}
if (!next_empty_row)
break; /* no empty rows left */
/* Find next empty row. */
next_empty_row = 0;
for (i = row + 1; i < slot_count && !next_empty_row; i++) {
if (!rows[i])
next_empty_row = i;
}
if (!next_empty_row)
break; /* no empty rows left */
/* Split the module into its own row and the next empty row. */
spd_log("SPD: splitting row %d (%d MB) into %d and %d (%d MB each)\n", row, rows[row], row, next_empty_row, rows[row] >> 1);
rows[row] = rows[next_empty_row] = rows[row] >> 1;
split = 1;
break;
}
/* Split the module into its own row and the next empty row. */
spd_log("SPD: splitting row %d (%d MB) into %d and %d (%d MB each)\n", row, rows[row], row, next_empty_row, rows[row] >> 1);
rows[row] = rows[next_empty_row] = rows[row] >> 1;
split = 1;
break;
}
/* Sort rows by descending capacity if any were split. */
if (split)
qsort(rows, slot_count, sizeof(uint16_t), comp_ui16_rev);
/* Sort rows by descending capacity if any were split. */
if (split)
qsort(rows, slot_count, sizeof(uint16_t), comp_ui16_rev);
}
}
static int
spd_write_part_no(char *part_no, char *type, uint16_t size)
{
char size_unit;
if (size >= 1024) {
size_unit = 'G';
size >>= 10;
size_unit = 'G';
size >>= 10;
} else {
size_unit = 'M';
size_unit = 'M';
}
return sprintf(part_no, EMU_NAME "-%s-%03d%c", type, size, size_unit);
}
void
spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
{
uint8_t slot, slot_count, row, i;
uint16_t min_module_size, rows[SPD_MAX_SLOTS], asym;
spd_edo_t *edo_data;
uint8_t slot, slot_count, row, i;
uint16_t min_module_size, rows[SPD_MAX_SLOTS], asym;
spd_edo_t *edo_data;
spd_sdram_t *sdram_data;
/* Determine the minimum module size for this RAM type. */
switch (ram_type) {
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
min_module_size = SPD_MIN_SIZE_EDO;
break;
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
min_module_size = SPD_MIN_SIZE_EDO;
break;
case SPD_TYPE_SDRAM:
min_module_size = SPD_MIN_SIZE_SDRAM;
break;
case SPD_TYPE_SDRAM:
min_module_size = SPD_MIN_SIZE_SDRAM;
break;
default:
spd_log("SPD: unknown RAM type %02X\n", ram_type);
return;
default:
spd_log("SPD: unknown RAM type %02X\n", ram_type);
return;
}
/* Count how many slots are enabled. */
slot_count = 0;
for (slot = 0; slot < SPD_MAX_SLOTS; slot++) {
rows[slot] = 0;
if (slot_mask & (1 << slot))
slot_count++;
rows[slot] = 0;
if (slot_mask & (1 << slot))
slot_count++;
}
/* Populate rows. */
@@ -221,372 +211,367 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size)
/* Register SPD devices and populate their data according to the rows. */
row = 0;
for (slot = 0; (slot < SPD_MAX_SLOTS) && rows[row]; slot++) {
if (!(slot_mask & (1 << slot)))
continue; /* slot disabled */
if (!(slot_mask & (1 << slot)))
continue; /* slot disabled */
spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t));
memset(spd_modules[slot], 0, sizeof(spd_t));
spd_modules[slot]->slot = slot;
spd_modules[slot]->size = rows[row];
spd_modules[slot] = (spd_t *) malloc(sizeof(spd_t));
memset(spd_modules[slot], 0, sizeof(spd_t));
spd_modules[slot]->slot = slot;
spd_modules[slot]->size = rows[row];
/* Determine the second row size, from which the first row size can be obtained. */
asym = rows[row] - (1 << log2i(rows[row])); /* separate the powers of 2 */
if (!asym) /* is the module asymmetric? */
asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */
/* Determine the second row size, from which the first row size can be obtained. */
asym = rows[row] - (1 << log2i(rows[row])); /* separate the powers of 2 */
if (!asym) /* is the module asymmetric? */
asym = rows[row] >> 1; /* symmetric, therefore divide by 2 */
spd_modules[slot]->row1 = rows[row] - asym;
spd_modules[slot]->row2 = asym;
spd_modules[slot]->row1 = rows[row] - asym;
spd_modules[slot]->row2 = asym;
spd_log("SPD: Registering slot %d = row %d = %d MB (%d/%d)\n", slot, row, rows[row], spd_modules[slot]->row1, spd_modules[slot]->row2);
spd_log("SPD: Registering slot %d = row %d = %d MB (%d/%d)\n", slot, row, rows[row], spd_modules[slot]->row1, spd_modules[slot]->row2);
switch (ram_type) {
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
edo_data = &spd_modules[slot]->edo_data;
switch (ram_type) {
case SPD_TYPE_FPM:
case SPD_TYPE_EDO:
edo_data = &spd_modules[slot]->edo_data;
/* EDO SPD is specified by JEDEC and present in some modules, but
most utilities cannot interpret it correctly. SIV32 at least gets
the module capacities right, so it was used as a reference here. */
edo_data->bytes_used = 0x80;
edo_data->spd_size = 0x08;
edo_data->mem_type = ram_type;
edo_data->row_bits = SPD_ROLLUP(7 + log2i(spd_modules[slot]->row1)); /* first row */
edo_data->col_bits = 9;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
edo_data->row_bits |= SPD_ROLLUP(7 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */
}
edo_data->banks = 2;
edo_data->data_width_lsb = 64;
edo_data->signal_level = SPD_SIGNAL_LVTTL;
edo_data->trac = 50;
edo_data->tcac = 13;
edo_data->refresh_rate = SPD_REFRESH_NORMAL;
edo_data->dram_width = 8;
/* EDO SPD is specified by JEDEC and present in some modules, but
most utilities cannot interpret it correctly. SIV32 at least gets
the module capacities right, so it was used as a reference here. */
edo_data->bytes_used = 0x80;
edo_data->spd_size = 0x08;
edo_data->mem_type = ram_type;
edo_data->row_bits = SPD_ROLLUP(7 + log2i(spd_modules[slot]->row1)); /* first row */
edo_data->col_bits = 9;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
edo_data->row_bits |= SPD_ROLLUP(7 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
edo_data->col_bits |= 9 << 4; /* same as first row, but just in case */
}
edo_data->banks = 2;
edo_data->data_width_lsb = 64;
edo_data->signal_level = SPD_SIGNAL_LVTTL;
edo_data->trac = 50;
edo_data->tcac = 13;
edo_data->refresh_rate = SPD_REFRESH_NORMAL;
edo_data->dram_width = 8;
edo_data->spd_rev = 0x12;
for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]);
i < sizeof(edo_data->part_no); i++)
edo_data->part_no[i] = ' '; /* part number should be space-padded */
edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
edo_data->mfg_year = 20;
edo_data->mfg_week = 17;
edo_data->spd_rev = 0x12;
for (i = spd_write_part_no(edo_data->part_no, (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", rows[row]);
i < sizeof(edo_data->part_no); i++)
edo_data->part_no[i] = ' '; /* part number should be space-padded */
edo_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
edo_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
edo_data->mfg_year = 20;
edo_data->mfg_week = 17;
for (i = 0; i < 63; i++)
edo_data->checksum += spd_modules[slot]->data[i];
for (i = 0; i < 129; i++)
edo_data->checksum2 += spd_modules[slot]->data[i];
break;
for (i = 0; i < 63; i++)
edo_data->checksum += spd_modules[slot]->data[i];
for (i = 0; i < 129; i++)
edo_data->checksum2 += spd_modules[slot]->data[i];
break;
case SPD_TYPE_SDRAM:
sdram_data = &spd_modules[slot]->sdram_data;
case SPD_TYPE_SDRAM:
sdram_data = &spd_modules[slot]->sdram_data;
sdram_data->bytes_used = 0x80;
sdram_data->spd_size = 0x08;
sdram_data->mem_type = ram_type;
sdram_data->row_bits = SPD_ROLLUP(6 + log2i(spd_modules[slot]->row1)); /* first row */
sdram_data->col_bits = 9;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
sdram_data->row_bits |= SPD_ROLLUP(6 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */
}
sdram_data->rows = 2;
sdram_data->data_width_lsb = 64;
sdram_data->signal_level = SPD_SIGNAL_LVTTL;
sdram_data->tclk = 0x75; /* 7.5 ns = 133.3 MHz */
sdram_data->tac = 0x10;
sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_REFRESH_NORMAL;
sdram_data->sdram_width = 8;
sdram_data->tccd = 1;
sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8;
sdram_data->banks = 4;
sdram_data->cas = 0x1c; /* CAS 5/4/3 supported */
sdram_data->cslat = sdram_data->we = 0x7f;
sdram_data->dev_attr = SPD_SDR_ATTR_EARLY_RAS | SPD_SDR_ATTR_AUTO_PC | SPD_SDR_ATTR_PC_ALL | SPD_SDR_ATTR_W1R_BURST;
sdram_data->tclk2 = 0xA0; /* 10 ns = 100 MHz */
sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */
sdram_data->tac2 = sdram_data->tac3 = 0x10;
sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) {
/* Utilities interpret bank_density a bit differently on asymmetric modules. */
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 2); /* first row */
sdram_data->bank_density |= 1 << (log2i(spd_modules[slot]->row2 >> 1) - 2); /* second row */
} else {
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */
}
sdram_data->ca_setup = sdram_data->data_setup = 0x15;
sdram_data->ca_hold = sdram_data->data_hold = 0x08;
sdram_data->bytes_used = 0x80;
sdram_data->spd_size = 0x08;
sdram_data->mem_type = ram_type;
sdram_data->row_bits = SPD_ROLLUP(6 + log2i(spd_modules[slot]->row1)); /* first row */
sdram_data->col_bits = 9;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) { /* the upper 4 bits of row_bits/col_bits should be 0 on a symmetric module */
sdram_data->row_bits |= SPD_ROLLUP(6 + log2i(spd_modules[slot]->row2)) << 4; /* second row, if different from first */
sdram_data->col_bits |= 9 << 4; /* same as first row, but just in case */
}
sdram_data->rows = 2;
sdram_data->data_width_lsb = 64;
sdram_data->signal_level = SPD_SIGNAL_LVTTL;
sdram_data->tclk = 0x75; /* 7.5 ns = 133.3 MHz */
sdram_data->tac = 0x10;
sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_REFRESH_NORMAL;
sdram_data->sdram_width = 8;
sdram_data->tccd = 1;
sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8;
sdram_data->banks = 4;
sdram_data->cas = 0x1c; /* CAS 5/4/3 supported */
sdram_data->cslat = sdram_data->we = 0x7f;
sdram_data->dev_attr = SPD_SDR_ATTR_EARLY_RAS | SPD_SDR_ATTR_AUTO_PC | SPD_SDR_ATTR_PC_ALL | SPD_SDR_ATTR_W1R_BURST;
sdram_data->tclk2 = 0xA0; /* 10 ns = 100 MHz */
sdram_data->tclk3 = 0xF0; /* 15 ns = 66.7 MHz */
sdram_data->tac2 = sdram_data->tac3 = 0x10;
sdram_data->trp = sdram_data->trrd = sdram_data->trcd = sdram_data->tras = 1;
if (spd_modules[slot]->row1 != spd_modules[slot]->row2) {
/* Utilities interpret bank_density a bit differently on asymmetric modules. */
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 2); /* first row */
sdram_data->bank_density |= 1 << (log2i(spd_modules[slot]->row2 >> 1) - 2); /* second row */
} else {
sdram_data->bank_density = 1 << (log2i(spd_modules[slot]->row1 >> 1) - 1); /* symmetric module = only one bit is set */
}
sdram_data->ca_setup = sdram_data->data_setup = 0x15;
sdram_data->ca_hold = sdram_data->data_hold = 0x08;
sdram_data->spd_rev = 0x12;
for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]);
i < sizeof(sdram_data->part_no); i++)
sdram_data->part_no[i] = ' '; /* part number should be space-padded */
sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
sdram_data->mfg_year = 20;
sdram_data->mfg_week = 13;
sdram_data->spd_rev = 0x12;
for (i = spd_write_part_no(sdram_data->part_no, "SDR", rows[row]);
i < sizeof(sdram_data->part_no); i++)
sdram_data->part_no[i] = ' '; /* part number should be space-padded */
sdram_data->rev_code[0] = BCD8(EMU_VERSION_MAJ);
sdram_data->rev_code[1] = BCD8(EMU_VERSION_MIN);
sdram_data->mfg_year = 20;
sdram_data->mfg_week = 13;
sdram_data->freq = 100;
sdram_data->features = 0xFF;
sdram_data->freq = 100;
sdram_data->features = 0xFF;
for (i = 0; i < 63; i++)
sdram_data->checksum += spd_modules[slot]->data[i];
for (i = 0; i < 129; i++)
sdram_data->checksum2 += spd_modules[slot]->data[i];
break;
}
for (i = 0; i < 63; i++)
sdram_data->checksum += spd_modules[slot]->data[i];
for (i = 0; i < 129; i++)
sdram_data->checksum2 += spd_modules[slot]->data[i];
break;
}
row++;
row++;
}
device_add(&spd_device);
}
void
spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
{
uint8_t row, dimm, drb, apollo = 0;
uint8_t row, dimm, drb, apollo = 0;
uint16_t size, rows[SPD_MAX_SLOTS];
/* Special case for VIA Apollo Pro family, which jumps from 5F to 56. */
if (reg_max < reg_min) {
apollo = reg_max;
reg_max = reg_min + 7;
apollo = reg_max;
reg_max = reg_min + 7;
}
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
if (!spd_present) {
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
}
/* Write DRBs for each row. */
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
for (row = 0; row <= (reg_max - reg_min); row++) {
dimm = (row >> 1);
size = 0;
dimm = (row >> 1);
size = 0;
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = (row & 1) ? 0 : drb_unit;
else
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = (row & 1) ? 0 : drb_unit;
else
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
/* Determine the DRB register to write. */
drb = reg_min + row;
if (apollo && ((drb & 0xf) < 0xa))
drb = apollo + (drb & 0xf);
/* Determine the DRB register to write. */
drb = reg_min + row;
if (apollo && ((drb & 0xf) < 0xa))
drb = apollo + (drb & 0xf);
/* Write DRB register, adding the previous DRB's value. */
if (row == 0)
regs[drb] = 0;
else if ((apollo) && (drb == apollo))
regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */
else
regs[drb] = regs[drb - 1];
if (size)
regs[drb] += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
/* Write DRB register, adding the previous DRB's value. */
if (row == 0)
regs[drb] = 0;
else if ((apollo) && (drb == apollo))
regs[drb] = regs[drb | 0xf]; /* 5F comes before 56 */
else
regs[drb] = regs[drb - 1];
if (size)
regs[drb] += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
}
}
/* Needed for 430LX. */
void
spd_write_drbs_with_ext(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
{
uint8_t row, dimm, drb;
uint8_t row, dimm, drb;
uint16_t size, row_val = 0, rows[SPD_MAX_SLOTS];
int shift;
int shift;
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
if (!spd_present) {
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
dimm = ((reg_max - reg_min) + 1) >> 1; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
}
/* Write DRBs for each row. */
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
for (row = 0; row <= (reg_max - reg_min); row++) {
dimm = (row >> 1);
size = 0;
dimm = (row >> 1);
size = 0;
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = (row & 1) ? 0 : drb_unit;
else
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = (row & 1) ? 0 : drb_unit;
else
size = (row & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
/* Determine the DRB register to write. */
drb = reg_min + row;
/* Determine the DRB register to write. */
drb = reg_min + row;
/* Write DRB register, adding the previous DRB's value. */
if (row == 0)
row_val = 0;
if (size)
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
regs[drb] = row_val & 0xff;
drb = reg_min + 8 + (row >> 1);
shift = (row & 0x01) << 3;
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
/* Write DRB register, adding the previous DRB's value. */
if (row == 0)
row_val = 0;
if (size)
row_val += size / drb_unit; /* this will intentionally overflow on 440GX with 2 GB */
regs[drb] = row_val & 0xff;
drb = reg_min + 8 + (row >> 1);
shift = (row & 0x01) << 3;
regs[drb] = (((row_val & 0xfff) >> 8) << shift);
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row, size, regs[drb]);
}
}
/* Used by ALi M1531 and M1541/2. */
void
spd_write_drbs_interleaved(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit)
{
uint8_t row, dimm;
uint8_t drb;
uint8_t row, dimm;
uint8_t drb;
uint16_t size, size_acc = 0;
uint16_t rows[SPD_MAX_SLOTS];
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
if (!spd_present) {
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, drb_unit, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
}
/* Write DRBs for each row. */
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
for (row = 0; row <= (reg_max - reg_min); row += 2) {
dimm = (row >> 2);
size = 0;
dimm = (row >> 2);
size = 0;
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = ((row >> 1) & 1) ? 0 : drb_unit;
else
size = ((row >> 1) & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
if (spd_modules[dimm]) {
if (spd_modules[dimm]->row1 < drb_unit) /* hack within a hack: turn a double-sided DIMM that is too small into a single-sided one */
size = ((row >> 1) & 1) ? 0 : drb_unit;
else
size = ((row >> 1) & 1) ? spd_modules[dimm]->row2 : spd_modules[dimm]->row1;
}
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
/* Determine the DRB register to write. */
drb = reg_min + row;
/* Determine the DRB register to write. */
drb = reg_min + row;
/* Calculate previous and new size. */
if (row == 0)
size_acc = 0;
else
size_acc += (size / drb_unit);
/* Calculate previous and new size. */
if (row == 0)
size_acc = 0;
else
size_acc += (size / drb_unit);
/* Write DRB register, adding the previous DRB's value. */
regs[drb] = size_acc & 0xff;
regs[drb + 1] = (regs[drb + 1] & 0xf0) | ((size_acc >> 8) & 0x0f);
/* Write DRB register, adding the previous DRB's value. */
regs[drb] = size_acc & 0xff;
regs[drb + 1] = (regs[drb + 1] & 0xf0) | ((size_acc >> 8) & 0x0f);
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row >> 1, size, regs[drb]);
spd_log("SPD: DRB[%d] = %d MB (%02Xh raw)\n", row >> 1, size, regs[drb]);
}
}
/* This is needed because the ALi M1621 does this stuff completely differently,
as it has DRAM bank registers instead of DRAM row boundary registers. */
void
spd_write_drbs_ali1621(uint8_t *regs, uint8_t reg_min, uint8_t reg_max)
{
uint8_t dimm, drb;
uint8_t dimm, drb;
uint16_t size;
uint16_t rows[SPD_MAX_SLOTS];
/* No SPD: split SIMMs into pairs as if they were "DIMM"s. */
if (!spd_present) {
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
dimm = ((reg_max - reg_min) + 1) >> 2; /* amount of "DIMM"s, also used to determine the maximum "DIMM" size */
spd_populate(rows, dimm, mem_size >> 10, 4, 1 << (log2i((machines[machine].ram.max >> 10) / dimm)), 0);
}
/* Write DRBs for each row. */
spd_log("SPD: Writing DRBs... regs=[%02X:%02X] unit=%d\n", reg_min, reg_max, drb_unit);
for (dimm = 0; dimm <= ((reg_max - reg_min) >> 2); dimm++) {
size = 0;
drb = reg_min + (dimm << 2);
size = 0;
drb = reg_min + (dimm << 2);
regs[drb] = 0xff;
regs[drb + 1] = 0xff;
regs[drb + 2] = 0x00;
regs[drb + 3] = 0xf0;
regs[drb] = 0xff;
regs[drb + 1] = 0xff;
regs[drb + 2] = 0x00;
regs[drb + 3] = 0xf0;
if (spd_modules[dimm] == NULL)
continue;
if (spd_modules[dimm] == NULL)
continue;
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1;
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
if (spd_present) {
/* SPD enabled: use SPD info for this slot, if present. */
size = (spd_modules[dimm]->row1 + spd_modules[dimm]->row2) >> 1;
} else {
/* No SPD: use the values calculated above. */
size = (rows[dimm] >> 1);
}
if (spd_modules[dimm]->row1)
regs[drb + 3] |= 0x06;
if (spd_modules[dimm]->row1)
regs[drb + 3] |= 0x06;
switch (size) {
case 4:
default:
regs[drb + 2] = 0x00;
break;
case 8:
regs[drb + 2] = 0x10;
break;
case 16:
regs[drb + 2] = 0x20;
break;
case 32:
regs[drb + 2] = 0x30;
break;
case 64:
regs[drb + 2] = 0x40;
break;
case 128:
regs[drb + 2] = 0x50;
break;
case 256:
regs[drb + 2] = 0x60;
break;
}
switch (size) {
case 4:
default:
regs[drb + 2] = 0x00;
break;
case 8:
regs[drb + 2] = 0x10;
break;
case 16:
regs[drb + 2] = 0x20;
break;
case 32:
regs[drb + 2] = 0x30;
break;
case 64:
regs[drb + 2] = 0x40;
break;
case 128:
regs[drb + 2] = 0x50;
break;
case 256:
regs[drb + 2] = 0x60;
break;
}
if (spd_modules[dimm]->row2) {
regs[drb + 3] |= 0x01;
regs[drb + 2] |= 0x80;
}
if (spd_modules[dimm]->row2) {
regs[drb + 3] |= 0x01;
regs[drb + 2] |= 0x80;
}
spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]);
spd_log("SPD: DIMM %i: %02X %02X %02X %02X\n", regs[drb], regs[drb + 1], regs[drb + 2], regs[drb + 3]);
}
}
static const device_t spd_device = {
.name = "Serial Presence Detect ROMs",
.name = "Serial Presence Detect ROMs",
.internal_name = "spd",
.flags = DEVICE_ISA,
.local = 0,
.init = spd_init,
.close = spd_close,
.reset = NULL,
.flags = DEVICE_ISA,
.local = 0,
.init = spd_init,
.close = spd_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};

View File

@@ -32,62 +32,57 @@
#include <86box/plat.h>
#include <86box/m_xt_xi8088.h>
typedef struct sst_t {
uint8_t manufacturer, id, has_bbp, is_39,
page_bytes, sdp, bbp_first_8k, bbp_last_8k;
typedef struct sst_t
{
uint8_t manufacturer, id, has_bbp, is_39,
page_bytes, sdp, bbp_first_8k, bbp_last_8k;
int command_state, id_mode,
dirty;
int command_state, id_mode,
dirty;
uint32_t size, mask,
page_mask, page_base,
last_addr;
uint32_t size, mask,
page_mask, page_base,
last_addr;
uint8_t page_buffer[128],
page_dirty[128];
uint8_t *array;
uint8_t page_buffer[128],
page_dirty[128];
uint8_t *array;
mem_mapping_t mapping[8], mapping_h[8];
mem_mapping_t mapping[8], mapping_h[8];
pc_timer_t page_write_timer;
pc_timer_t page_write_timer;
} sst_t;
static char flash_path[1024];
static char flash_path[1024];
#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */
#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */
#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */
#define W_BOOT_BLOCK_PROT 0x40 /* Only W29C020 */
#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */
#define SST_ERASE 0x80 /* Both 29 and 39 */
/* With data 60h on 6th cycle, it's alt. ID */
#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */
#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */
#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */
/* 1st cycle variant only on 39 */
#define SST 0xbf /* SST Manufacturer's ID */
#define SST29EE010 0x0700
#define SST29LE_VE010 0x0800
#define SST29EE020 0x1000
#define SST29LE_VE020 0x1200
#define SST39SF512 0xb400
#define SST39SF010 0xb500
#define SST39SF020 0xb600
#define SST39SF040 0xb700
#define SST_CHIP_ERASE 0x10 /* Both 29 and 39, 6th cycle */
#define SST_SDP_DISABLE 0x20 /* Only 29, Software data protect disable and write - treat as write */
#define SST_SECTOR_ERASE 0x30 /* Only 39, 6th cycle */
#define W_BOOT_BLOCK_PROT 0x40 /* Only W29C020 */
#define SST_SET_ID_MODE_ALT 0x60 /* Only 29, 6th cycle */
#define SST_ERASE 0x80 /* Both 29 and 39 */
/* With data 60h on 6th cycle, it's alt. ID */
#define SST_SET_ID_MODE 0x90 /* Both 29 and 39 */
#define SST_BYTE_PROGRAM 0xa0 /* Both 29 and 39 */
#define SST_CLEAR_ID_MODE 0xf0 /* Both 29 and 39 */
/* 1st cycle variant only on 39 */
#define SST 0xbf /* SST Manufacturer's ID */
#define SST29EE010 0x0700
#define SST29LE_VE010 0x0800
#define SST29EE020 0x1000
#define SST29LE_VE020 0x1200
#define SST39SF512 0xb400
#define SST39SF010 0xb500
#define SST39SF020 0xb600
#define SST39SF040 0xb700
#define WINBOND 0xda /* Winbond Manufacturer's ID */
#define W29C020 0x4500
#define SIZE_512K 0x010000
#define SIZE_1M 0x020000
#define SIZE_2M 0x040000
#define SIZE_4M 0x080000
#define WINBOND 0xda /* Winbond Manufacturer's ID */
#define W29C020 0x4500
#define SIZE_512K 0x010000
#define SIZE_1M 0x020000
#define SIZE_2M 0x040000
#define SIZE_4M 0x080000
static void
sst_sector_erase(sst_t *dev, uint32_t addr)
@@ -95,330 +90,323 @@ sst_sector_erase(sst_t *dev, uint32_t addr)
uint32_t base = addr & (dev->mask & ~0xfff);
if ((base < 0x2000) && (dev->bbp_first_8k & 0x01))
return;
return;
else if ((base >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
return;
return;
memset(&dev->array[base], 0xff, 4096);
dev->dirty = 1;
}
static void
sst_new_command(sst_t *dev, uint32_t addr, uint8_t val)
{
uint32_t base = 0x00000, size = dev->size;
if (dev->command_state == 5) switch (val) {
case SST_CHIP_ERASE:
if (dev->bbp_first_8k & 0x01) {
base += 0x2000;
size -= 0x2000;
}
if (dev->command_state == 5)
switch (val) {
case SST_CHIP_ERASE:
if (dev->bbp_first_8k & 0x01) {
base += 0x2000;
size -= 0x2000;
}
if (dev->bbp_last_8k & 0x01)
size -= 0x2000;
if (dev->bbp_last_8k & 0x01)
size -= 0x2000;
memset(&(dev->array[base]), 0xff, size);
dev->command_state = 0;
break;
memset(&(dev->array[base]), 0xff, size);
dev->command_state = 0;
break;
case SST_SDP_DISABLE:
if (!dev->is_39)
dev->sdp = 0;
dev->command_state = 0;
break;
case SST_SDP_DISABLE:
if (!dev->is_39)
dev->sdp = 0;
dev->command_state = 0;
break;
case SST_SECTOR_ERASE:
if (dev->is_39)
sst_sector_erase(dev, addr);
dev->command_state = 0;
break;
case SST_SECTOR_ERASE:
if (dev->is_39)
sst_sector_erase(dev, addr);
dev->command_state = 0;
break;
case SST_SET_ID_MODE_ALT:
dev->id_mode = 1;
dev->command_state = 0;
break;
case SST_SET_ID_MODE_ALT:
dev->id_mode = 1;
dev->command_state = 0;
break;
default:
dev->command_state = 0;
break;
} else switch (val) {
case SST_ERASE:
dev->command_state = 3;
break;
default:
dev->command_state = 0;
break;
}
else
switch (val) {
case SST_ERASE:
dev->command_state = 3;
break;
case SST_SET_ID_MODE:
dev->id_mode = 1;
dev->command_state = 0;
break;
case SST_SET_ID_MODE:
dev->id_mode = 1;
dev->command_state = 0;
break;
case SST_BYTE_PROGRAM:
if (!dev->is_39) {
dev->sdp = 1;
memset(dev->page_buffer, 0xff, 128);
memset(dev->page_dirty, 0x00, 128);
dev->page_bytes = 0;
dev->last_addr = 0xffffffff;
timer_on_auto(&dev->page_write_timer, 210.0);
}
dev->command_state = 6;
break;
case SST_BYTE_PROGRAM:
if (!dev->is_39) {
dev->sdp = 1;
memset(dev->page_buffer, 0xff, 128);
memset(dev->page_dirty, 0x00, 128);
dev->page_bytes = 0;
dev->last_addr = 0xffffffff;
timer_on_auto(&dev->page_write_timer, 210.0);
}
dev->command_state = 6;
break;
case W_BOOT_BLOCK_PROT:
dev->command_state = dev->has_bbp ? 8 : 0;
break;
case W_BOOT_BLOCK_PROT:
dev->command_state = dev->has_bbp ? 8 : 0;
break;
case SST_CLEAR_ID_MODE:
dev->id_mode = 0;
dev->command_state = 0;
break;
case SST_CLEAR_ID_MODE:
dev->id_mode = 0;
dev->command_state = 0;
break;
default:
dev->command_state = 0;
break;
}
default:
dev->command_state = 0;
break;
}
}
static void
sst_page_write(void *priv)
{
sst_t *dev = (sst_t *) priv;
int i;
int i;
if (dev->last_addr != 0xffffffff) {
dev->page_base = dev->last_addr & dev->page_mask;
for (i = 0; i < 128; i++) {
if (dev->page_dirty[i]) {
if (((dev->page_base + i) < 0x2000) && (dev->bbp_first_8k & 0x01))
continue;
else if (((dev->page_base + i) >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
continue;
dev->page_base = dev->last_addr & dev->page_mask;
for (i = 0; i < 128; i++) {
if (dev->page_dirty[i]) {
if (((dev->page_base + i) < 0x2000) && (dev->bbp_first_8k & 0x01))
continue;
else if (((dev->page_base + i) >= (dev->size - 0x2000)) && (dev->bbp_last_8k & 0x01))
continue;
dev->array[dev->page_base + i] = dev->page_buffer[i];
dev->dirty |= 1;
}
}
dev->array[dev->page_base + i] = dev->page_buffer[i];
dev->dirty |= 1;
}
}
}
dev->page_bytes = 0;
dev->page_bytes = 0;
dev->command_state = 0;
timer_disable(&dev->page_write_timer);
}
static uint8_t
sst_read_id(uint32_t addr, void *p)
{
sst_t *dev = (sst_t *) p;
sst_t *dev = (sst_t *) p;
uint8_t ret = 0x00;
if ((addr & 0xffff) == 0)
ret = dev->manufacturer;
ret = dev->manufacturer;
else if ((addr & 0xffff) == 1)
ret = dev->id;
ret = dev->id;
#ifdef UNKNOWN_FLASH
else if ((addr & 0xffff) == 0x100)
ret = 0x1c;
ret = 0x1c;
else if ((addr & 0xffff) == 0x101)
ret = 0x92;
ret = 0x92;
#endif
else if (dev->has_bbp) {
if (addr == 0x00002)
ret = dev->bbp_first_8k;
else if (addr == 0x3fff2)
ret = dev->bbp_last_8k;
if (addr == 0x00002)
ret = dev->bbp_first_8k;
else if (addr == 0x3fff2)
ret = dev->bbp_last_8k;
}
return ret;
}
static void
sst_buf_write(sst_t *dev, uint32_t addr, uint8_t val)
{
dev->page_buffer[addr & 0x0000007f] = val;
dev->page_dirty[addr & 0x0000007f] = 1;
dev->page_dirty[addr & 0x0000007f] = 1;
dev->page_bytes++;
dev->last_addr = addr;
if (dev->page_bytes >= 128) {
sst_page_write(dev);
sst_page_write(dev);
} else
timer_on_auto(&dev->page_write_timer, 210.0);
timer_on_auto(&dev->page_write_timer, 210.0);
}
static void
sst_write(uint32_t addr, uint8_t val, void *p)
{
sst_t *dev = (sst_t *) p;
switch (dev->command_state) {
case 0:
case 3:
/* 1st and 4th Bus Write Cycle */
if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) {
if (dev->id_mode)
dev->id_mode = 0;
dev->command_state = 0;
} else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa))
dev->command_state++;
else {
if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) {
/* 29 series, software data protection off, start loading the page. */
memset(dev->page_buffer, 0xff, 128);
memset(dev->page_dirty, 0x00, 128);
dev->page_bytes = 0;
dev->command_state = 7;
sst_buf_write(dev, addr, val);
} else
dev->command_state = 0;
}
break;
case 1:
case 4:
/* 2nd and 5th Bus Write Cycle */
if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55))
dev->command_state++;
else
dev->command_state = 0;
break;
case 2:
case 5:
/* 3rd and 6th Bus Write Cycle */
if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) {
/* Sector erase - can be on any address. */
sst_new_command(dev, addr, val);
} else if ((addr & 0x7fff) == 0x5555)
sst_new_command(dev, addr, val);
else
dev->command_state = 0;
break;
case 6:
/* Page Load Cycle (29) / Data Write Cycle (39SF) */
if (dev->is_39) {
dev->command_state = 0;
case 0:
case 3:
/* 1st and 4th Bus Write Cycle */
if ((val == 0xf0) && dev->is_39 && (dev->command_state == 0)) {
if (dev->id_mode)
dev->id_mode = 0;
dev->command_state = 0;
} else if (((addr & 0x7fff) == 0x5555) && (val == 0xaa))
dev->command_state++;
else {
if (!dev->is_39 && !dev->sdp && (dev->command_state == 0)) {
/* 29 series, software data protection off, start loading the page. */
memset(dev->page_buffer, 0xff, 128);
memset(dev->page_dirty, 0x00, 128);
dev->page_bytes = 0;
dev->command_state = 7;
sst_buf_write(dev, addr, val);
} else
dev->command_state = 0;
}
break;
case 1:
case 4:
/* 2nd and 5th Bus Write Cycle */
if (((addr & 0x7fff) == 0x2aaa) && (val == 0x55))
dev->command_state++;
else
dev->command_state = 0;
break;
case 2:
case 5:
/* 3rd and 6th Bus Write Cycle */
if ((dev->command_state == 5) && (val == SST_SECTOR_ERASE)) {
/* Sector erase - can be on any address. */
sst_new_command(dev, addr, val);
} else if ((addr & 0x7fff) == 0x5555)
sst_new_command(dev, addr, val);
else
dev->command_state = 0;
break;
case 6:
/* Page Load Cycle (29) / Data Write Cycle (39SF) */
if (dev->is_39) {
dev->command_state = 0;
dev->array[addr & dev->mask] = val;
dev->dirty = 1;
} else {
dev->command_state++;
sst_buf_write(dev, addr, val);
}
break;
case 7:
if (!dev->is_39)
sst_buf_write(dev, addr, val);
break;
case 8:
if ((addr == 0x00000) && (val == 0x00))
dev->bbp_first_8k = 0xff;
else if ((addr == 0x3ffff) && (val == 0xff))
dev->bbp_last_8k = 0xff;
dev->command_state = 0;
break;
dev->array[addr & dev->mask] = val;
dev->dirty = 1;
} else {
dev->command_state++;
sst_buf_write(dev, addr, val);
}
break;
case 7:
if (!dev->is_39)
sst_buf_write(dev, addr, val);
break;
case 8:
if ((addr == 0x00000) && (val == 0x00))
dev->bbp_first_8k = 0xff;
else if ((addr == 0x3ffff) && (val == 0xff))
dev->bbp_last_8k = 0xff;
dev->command_state = 0;
break;
}
}
static uint8_t
sst_read(uint32_t addr, void *p)
{
sst_t *dev = (sst_t *) p;
sst_t *dev = (sst_t *) p;
uint8_t ret = 0xff;
addr &= 0x000fffff;
if (dev->id_mode)
ret = sst_read_id(addr, p);
ret = sst_read_id(addr, p);
else {
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = dev->array[addr - biosaddr];
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = dev->array[addr - biosaddr];
}
return ret;
}
static uint16_t
sst_readw(uint32_t addr, void *p)
{
sst_t *dev = (sst_t *) p;
sst_t *dev = (sst_t *) p;
uint16_t ret = 0xffff;
addr &= 0x000fffff;
if (dev->id_mode)
ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8);
ret = sst_read(addr, p) | (sst_read(addr + 1, p) << 8);
else {
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint16_t *)&dev->array[addr - biosaddr];
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint16_t *) &dev->array[addr - biosaddr];
}
return ret;
}
static uint32_t
sst_readl(uint32_t addr, void *p)
{
sst_t *dev = (sst_t *) p;
sst_t *dev = (sst_t *) p;
uint32_t ret = 0xffffffff;
addr &= 0x000fffff;
if (dev->id_mode)
ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16);
ret = sst_readw(addr, p) | (sst_readw(addr + 2, p) << 16);
else {
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint32_t *)&dev->array[addr - biosaddr];
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint32_t *) &dev->array[addr - biosaddr];
}
return ret;
}
static void
sst_add_mappings(sst_t *dev)
{
int i = 0, count;
int i = 0, count;
uint32_t base, fbase;
uint32_t root_base;
count = dev->size >> 16;
count = dev->size >> 16;
root_base = 0x100000 - dev->size;
for (i = 0; i < count; i++) {
base = root_base + (i << 16);
fbase = base & biosmask;
base = root_base + (i << 16);
fbase = base & biosmask;
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
if (base >= 0xe0000) {
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
}
if (is6117) {
mem_mapping_add(&(dev->mapping_h[i]), (base | 0x3f00000), 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
} else {
mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev);
}
if (base >= 0xe0000) {
mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
}
if (is6117) {
mem_mapping_add(&(dev->mapping_h[i]), (base | 0x3f00000), 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
} else {
mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000,
sst_read, sst_readw, sst_readl,
sst_write, NULL, NULL,
dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
}
}
}
static void *
sst_init(const device_t *info)
{
FILE *f;
FILE *f;
sst_t *dev = malloc(sizeof(sst_t));
memset(dev, 0, sizeof(sst_t));
@@ -431,48 +419,47 @@ sst_init(const device_t *info)
memset(dev->array, 0xff, biosmask + 1);
dev->manufacturer = info->local & 0xff;
dev->id = (info->local >> 8) & 0xff;
dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020);
dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512);
dev->id = (info->local >> 8) & 0xff;
dev->has_bbp = (dev->manufacturer == WINBOND) && ((info->local & 0xff00) >= W29C020);
dev->is_39 = (dev->manufacturer == SST) && ((info->local & 0xff00) >= SST39SF512);
dev->size = info->local & 0xffff0000;
if ((dev->size == 0x20000) && (strstr(machine_get_internal_name_ex(machine), "xi8088")) && !xi8088_bios_128kb())
dev->size = 0x10000;
dev->size = 0x10000;
dev->mask = dev->size - 1;
dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */
dev->sdp = 1;
dev->mask = dev->size - 1;
dev->page_mask = dev->mask & 0xffffff80; /* Filter out A0-A6. */
dev->sdp = 1;
dev->bbp_first_8k = dev->bbp_last_8k = 0xfe;
sst_add_mappings(dev);
f = nvr_fopen(flash_path, "rb");
if (f) {
if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size)
pclog("Less than %i bytes read from the SST Flash ROM file\n", dev->size);
fclose(f);
if (fread(&(dev->array[0x00000]), 1, dev->size, f) != dev->size)
pclog("Less than %i bytes read from the SST Flash ROM file\n", dev->size);
fclose(f);
} else
dev->dirty = 1; /* It is by definition dirty on creation. */
dev->dirty = 1; /* It is by definition dirty on creation. */
if (!dev->is_39)
timer_add(&dev->page_write_timer, sst_page_write, dev, 0);
timer_add(&dev->page_write_timer, sst_page_write, dev, 0);
return dev;
}
static void
sst_close(void *p)
{
FILE *f;
sst_t *dev = (sst_t *)p;
FILE *f;
sst_t *dev = (sst_t *) p;
if (dev->dirty) {
f = nvr_fopen(flash_path, "wb");
if (f != NULL) {
fwrite(&(dev->array[0x00000]), dev->size, 1, f);
fclose(f);
}
f = nvr_fopen(flash_path, "wb");
if (f != NULL) {
fwrite(&(dev->array[0x00000]), dev->size, 1, f);
fclose(f);
}
}
free(dev->array);
@@ -482,85 +469,85 @@ sst_close(void *p)
}
const device_t sst_flash_29ee010_device = {
.name = "SST 29EE010 Flash BIOS",
.name = "SST 29EE010 Flash BIOS",
.internal_name = "sst_flash_29ee010",
.flags = 0,
.local = SST | SST29EE010 | SIZE_1M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = SST | SST29EE010 | SIZE_1M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t sst_flash_29ee020_device = {
.name = "SST 29EE020 Flash BIOS",
.name = "SST 29EE020 Flash BIOS",
.internal_name = "sst_flash_29ee020",
.flags = 0,
.local = SST | SST29EE020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = SST | SST29EE020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t winbond_flash_w29c020_device = {
.name = "Winbond W29C020 Flash BIOS",
.name = "Winbond W29C020 Flash BIOS",
.internal_name = "winbond_flash_w29c020",
.flags = 0,
.local = WINBOND | W29C020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = WINBOND | W29C020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t sst_flash_39sf010_device = {
.name = "SST 39SF010 Flash BIOS",
.name = "SST 39SF010 Flash BIOS",
.internal_name = "sst_flash_39sf010",
.flags = 0,
.local = SST | SST39SF010 | SIZE_1M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = SST | SST39SF010 | SIZE_1M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t sst_flash_39sf020_device = {
.name = "SST 39SF020 Flash BIOS",
.name = "SST 39SF020 Flash BIOS",
.internal_name = "sst_flash_39sf020",
.flags = 0,
.local = SST | SST39SF020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = SST | SST39SF020 | SIZE_2M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};
const device_t sst_flash_39sf040_device = {
.name = "SST 39SF040 Flash BIOS",
.name = "SST 39SF040 Flash BIOS",
.internal_name = "sst_flash_39sf040",
.flags = 0,
.local = SST | SST39SF040 | SIZE_4M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
.flags = 0,
.local = SST | SST39SF040 | SIZE_4M,
.init = sst_init,
.close = sst_close,
.reset = NULL,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
.force_redraw = NULL,
.config = NULL
};