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

View File

@@ -24,36 +24,32 @@
#include <86box/86box.h> #include <86box/86box.h>
#include <86box/i2c.h> #include <86box/i2c.h>
typedef struct { typedef struct {
void *i2c; void *i2c;
uint8_t addr, *data, writable; uint8_t addr, *data, writable;
uint32_t addr_mask, addr_register; uint32_t addr_mask, addr_register;
uint8_t addr_len, addr_pos; uint8_t addr_len, addr_pos;
} i2c_eeprom_t; } i2c_eeprom_t;
#ifdef ENABLE_I2C_EEPROM_LOG #ifdef ENABLE_I2C_EEPROM_LOG
int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG; int i2c_eeprom_do_log = ENABLE_I2C_EEPROM_LOG;
static void static void
i2c_eeprom_log(const char *fmt, ...) i2c_eeprom_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (i2c_eeprom_do_log) { if (i2c_eeprom_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define i2c_eeprom_log(fmt, ...) # define i2c_eeprom_log(fmt, ...)
#endif #endif
static uint8_t static uint8_t
i2c_eeprom_start(void *bus, uint8_t addr, uint8_t read, void *priv) 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); i2c_eeprom_log("I2C EEPROM %s %02X: start()\n", i2c_getbusname(dev->i2c), dev->addr);
if (!read) { if (!read) {
dev->addr_pos = 0; dev->addr_pos = 0;
dev->addr_register = (addr << dev->addr_len) & dev->addr_mask; dev->addr_register = (addr << dev->addr_len) & dev->addr_mask;
} }
return 1; return 1;
} }
static uint8_t static uint8_t
i2c_eeprom_read(void *bus, uint8_t addr, void *priv) i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
{ {
i2c_eeprom_t *dev = (i2c_eeprom_t *) 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); i2c_eeprom_log("I2C EEPROM %s %02X: read(%06X) = %02X\n", i2c_getbusname(dev->i2c), dev->addr, dev->addr_register, ret);
dev->addr_register++; dev->addr_register++;
@@ -83,33 +78,31 @@ i2c_eeprom_read(void *bus, uint8_t addr, void *priv)
return ret; return ret;
} }
static uint8_t static uint8_t
i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv) i2c_eeprom_write(void *bus, uint8_t addr, uint8_t data, void *priv)
{ {
i2c_eeprom_t *dev = (i2c_eeprom_t *) priv; i2c_eeprom_t *dev = (i2c_eeprom_t *) priv;
if (dev->addr_pos < dev->addr_len) { if (dev->addr_pos < dev->addr_len) {
dev->addr_register <<= 8; dev->addr_register <<= 8;
dev->addr_register |= data; dev->addr_register |= data;
dev->addr_register &= (1 << dev->addr_len) - 1; dev->addr_register &= (1 << dev->addr_len) - 1;
dev->addr_register |= addr << dev->addr_len; dev->addr_register |= addr << dev->addr_len;
dev->addr_register &= dev->addr_mask; 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); 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_pos += 8;
} else { } 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); 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) if (dev->writable)
dev->data[dev->addr_register] = data; dev->data[dev->addr_register] = data;
dev->addr_register++; dev->addr_register++;
dev->addr_register &= dev->addr_mask; /* roll-over */ dev->addr_register &= dev->addr_mask; /* roll-over */
return dev->writable; return dev->writable;
} }
return 1; return 1;
} }
static void static void
i2c_eeprom_stop(void *bus, uint8_t addr, void *priv) 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; dev->addr_pos = 0;
} }
uint8_t uint8_t
log2i(uint32_t i) log2i(uint32_t i)
{ {
uint8_t ret = 0; uint8_t ret = 0;
while ((i >>= 1)) while ((i >>= 1))
ret++; ret++;
return ret; return ret;
} }
void * void *
i2c_eeprom_init(void *i2c, uint8_t addr, uint8_t *data, uint32_t size, uint8_t writable) 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. */ /* Round size up to the next power of 2. */
uint32_t pow_size = 1 << log2i(size); uint32_t pow_size = 1 << log2i(size);
if (pow_size < 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 */ 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); i2c_eeprom_log("I2C EEPROM %s %02X: init(%d, %d)\n", i2c_getbusname(i2c), addr, size, writable);
dev->i2c = i2c; dev->i2c = i2c;
dev->addr = addr; dev->addr = addr;
dev->data = data; dev->data = data;
dev->writable = writable; 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; 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); 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; return dev;
} }
void void
i2c_eeprom_close(void *dev_handle) i2c_eeprom_close(void *dev_handle)
{ {

View File

@@ -30,14 +30,11 @@
#include <86box/nvr.h> #include <86box/nvr.h>
#include <86box/plat.h> #include <86box/plat.h>
#define FLAG_WORD 4
#define FLAG_BXB 2
#define FLAG_INV_A16 1
#define FLAG_WORD 4 enum {
#define FLAG_BXB 2
#define FLAG_INV_A16 1
enum
{
BLOCK_MAIN1, BLOCK_MAIN1,
BLOCK_MAIN2, BLOCK_MAIN2,
BLOCK_MAIN3, BLOCK_MAIN3,
@@ -48,239 +45,231 @@ enum
BLOCKS_NUM BLOCKS_NUM
}; };
enum enum {
{ CMD_READ_ARRAY = 0xff,
CMD_READ_ARRAY = 0xff, CMD_IID = 0x90,
CMD_IID = 0x90, CMD_READ_STATUS = 0x70,
CMD_READ_STATUS = 0x70, CMD_CLEAR_STATUS = 0x50,
CMD_CLEAR_STATUS = 0x50, CMD_ERASE_SETUP = 0x20,
CMD_ERASE_SETUP = 0x20, CMD_ERASE_CONFIRM = 0xd0,
CMD_ERASE_CONFIRM = 0xd0, CMD_ERASE_SUSPEND = 0xb0,
CMD_ERASE_SUSPEND = 0xb0, CMD_PROGRAM_SETUP = 0x40,
CMD_PROGRAM_SETUP = 0x40,
CMD_PROGRAM_SETUP_ALT = 0x10 CMD_PROGRAM_SETUP_ALT = 0x10
}; };
typedef struct flash_t {
uint8_t command, status,
pad, flags,
*array;
typedef struct flash_t uint16_t flash_id, pad16;
{
uint8_t command, status,
pad, flags,
*array;
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, mem_mapping_t mapping[4], mapping_h[16];
block_start[BLOCKS_NUM], block_end[BLOCKS_NUM],
block_len[BLOCKS_NUM];
mem_mapping_t mapping[4], mapping_h[16];
} flash_t; } flash_t;
static char flash_path[1024];
static char flash_path[1024];
static uint8_t static uint8_t
flash_read(uint32_t addr, void *p) flash_read(uint32_t addr, void *p)
{ {
flash_t *dev = (flash_t *) p; flash_t *dev = (flash_t *) p;
uint8_t ret = 0xff; uint8_t ret = 0xff;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000; addr ^= 0x10000;
addr &= biosmask; addr &= biosmask;
switch (dev->command) { switch (dev->command) {
case CMD_READ_ARRAY: case CMD_READ_ARRAY:
default: default:
ret = dev->array[addr]; ret = dev->array[addr];
break; break;
case CMD_IID: case CMD_IID:
if (addr & 1) if (addr & 1)
ret = dev->flash_id & 0xff; ret = dev->flash_id & 0xff;
else else
ret = 0x89; ret = 0x89;
break; break;
case CMD_READ_STATUS: case CMD_READ_STATUS:
ret = dev->status; ret = dev->status;
break; break;
} }
return ret; return ret;
} }
static uint16_t static uint16_t
flash_readw(uint32_t addr, void *p) flash_readw(uint32_t addr, void *p)
{ {
flash_t *dev = (flash_t *) p; flash_t *dev = (flash_t *) p;
uint16_t *q; uint16_t *q;
uint16_t ret = 0xffff; uint16_t ret = 0xffff;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000; addr ^= 0x10000;
addr &= biosmask; addr &= biosmask;
if (dev->flags & FLAG_WORD) if (dev->flags & FLAG_WORD)
addr &= 0xfffffffe; addr &= 0xfffffffe;
q = (uint16_t *)&(dev->array[addr]); q = (uint16_t *) &(dev->array[addr]);
ret = *q; ret = *q;
if (dev->flags & FLAG_WORD) switch (dev->command) { if (dev->flags & FLAG_WORD)
case CMD_READ_ARRAY: switch (dev->command) {
default: case CMD_READ_ARRAY:
break; default:
break;
case CMD_IID: case CMD_IID:
if (addr & 2) if (addr & 2)
ret = dev->flash_id; ret = dev->flash_id;
else else
ret = 0x0089; ret = 0x0089;
break; break;
case CMD_READ_STATUS: case CMD_READ_STATUS:
ret = dev->status; ret = dev->status;
break; break;
} }
return ret; return ret;
} }
static uint32_t static uint32_t
flash_readl(uint32_t addr, void *p) flash_readl(uint32_t addr, void *p)
{ {
flash_t *dev = (flash_t *)p; flash_t *dev = (flash_t *) p;
uint32_t *q; uint32_t *q;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000; addr ^= 0x10000;
addr &= biosmask; addr &= biosmask;
q = (uint32_t *)&(dev->array[addr]); q = (uint32_t *) &(dev->array[addr]);
return *q; return *q;
} }
static void static void
flash_write(uint32_t addr, uint8_t val, void *p) flash_write(uint32_t addr, uint8_t val, void *p)
{ {
flash_t *dev = (flash_t *) p; flash_t *dev = (flash_t *) p;
int i; int i;
uint32_t bb_mask = biosmask & 0xffffe000; uint32_t bb_mask = biosmask & 0xffffe000;
if (biosmask == 0x7ffff) if (biosmask == 0x7ffff)
bb_mask &= 0xffff8000; bb_mask &= 0xffff8000;
else if (biosmask == 0x3ffff) else if (biosmask == 0x3ffff)
bb_mask &= 0xffffc000; bb_mask &= 0xffffc000;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000; addr ^= 0x10000;
addr &= biosmask; addr &= biosmask;
switch (dev->command) { switch (dev->command) {
case CMD_ERASE_SETUP: case CMD_ERASE_SETUP:
if (val == CMD_ERASE_CONFIRM) { if (val == CMD_ERASE_CONFIRM) {
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[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]); memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[i]);
} }
dev->status = 0x80; dev->status = 0x80;
} }
dev->command = CMD_READ_STATUS; dev->command = CMD_READ_STATUS;
break; break;
case CMD_PROGRAM_SETUP: case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT: case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr)) if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
dev->array[addr] = val; dev->array[addr] = val;
dev->command = CMD_READ_STATUS; dev->command = CMD_READ_STATUS;
dev->status = 0x80; dev->status = 0x80;
break; break;
default: default:
dev->command = val; dev->command = val;
switch (val) { switch (val) {
case CMD_CLEAR_STATUS: case CMD_CLEAR_STATUS:
dev->status = 0; dev->status = 0;
break; break;
case CMD_ERASE_SETUP: case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i; dev->program_addr = i;
} }
break; break;
case CMD_PROGRAM_SETUP: case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT: case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr; dev->program_addr = addr;
break; break;
} }
} }
} }
static void static void
flash_writew(uint32_t addr, uint16_t val, void *p) flash_writew(uint32_t addr, uint16_t val, void *p)
{ {
flash_t *dev = (flash_t *) p; flash_t *dev = (flash_t *) p;
int i; int i;
uint32_t bb_mask = biosmask & 0xffffe000; uint32_t bb_mask = biosmask & 0xffffe000;
if (biosmask == 0x7ffff) if (biosmask == 0x7ffff)
bb_mask &= 0xffff8000; bb_mask &= 0xffff8000;
else if (biosmask == 0x3ffff) else if (biosmask == 0x3ffff)
bb_mask &= 0xffffc000; bb_mask &= 0xffffc000;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
addr ^= 0x10000; addr ^= 0x10000;
addr &= biosmask; addr &= biosmask;
if (dev->flags & FLAG_WORD) switch (dev->command) { if (dev->flags & FLAG_WORD)
case CMD_ERASE_SETUP: switch (dev->command) {
if (val == CMD_ERASE_CONFIRM) { case CMD_ERASE_SETUP:
for (i = 0; i < 6; i++) { if (val == CMD_ERASE_CONFIRM) {
if ((i == dev->program_addr) && (addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) for (i = 0; i < 6; i++) {
memset(&(dev->array[dev->block_start[i]]), 0xff, dev->block_len[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->status = 0x80;
} }
dev->command = CMD_READ_STATUS; dev->command = CMD_READ_STATUS;
break; break;
case CMD_PROGRAM_SETUP: case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT: case CMD_PROGRAM_SETUP_ALT:
if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr)) if (((addr & bb_mask) != (dev->block_start[6] & bb_mask)) && (addr == dev->program_addr))
*(uint16_t *) (&dev->array[addr]) = val; *(uint16_t *) (&dev->array[addr]) = val;
dev->command = CMD_READ_STATUS; dev->command = CMD_READ_STATUS;
dev->status = 0x80; dev->status = 0x80;
break; break;
default: default:
dev->command = val & 0xff; dev->command = val & 0xff;
switch (val) { switch (val) {
case CMD_CLEAR_STATUS: case CMD_CLEAR_STATUS:
dev->status = 0; dev->status = 0;
break; break;
case CMD_ERASE_SETUP: case CMD_ERASE_SETUP:
for (i = 0; i < 7; i++) { for (i = 0; i < 7; i++) {
if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i])) if ((addr >= dev->block_start[i]) && (addr <= dev->block_end[i]))
dev->program_addr = i; dev->program_addr = i;
} }
break; break;
case CMD_PROGRAM_SETUP: case CMD_PROGRAM_SETUP:
case CMD_PROGRAM_SETUP_ALT: case CMD_PROGRAM_SETUP_ALT:
dev->program_addr = addr; dev->program_addr = addr;
break; break;
} }
} }
} }
static void static void
flash_writel(uint32_t addr, uint32_t val, void *p) 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 #endif
} }
static void static void
intel_flash_add_mappings(flash_t *dev) intel_flash_add_mappings(flash_t *dev)
{ {
int max = 2, i = 0; int max = 2, i = 0;
uint32_t base, fbase; uint32_t base, fbase;
uint32_t sub = 0x20000; uint32_t sub = 0x20000;
if (biosmask == 0x7ffff) { if (biosmask == 0x7ffff) {
sub = 0x80000; sub = 0x80000;
max = 8; max = 8;
} else if (biosmask == 0x3ffff) { } else if (biosmask == 0x3ffff) {
sub = 0x40000; sub = 0x40000;
max = 4; max = 4;
} }
for (i = 0; i < max; i++) { for (i = 0; i < max; i++) {
if (biosmask == 0x7ffff) if (biosmask == 0x7ffff)
base = 0x80000 + (i << 16); base = 0x80000 + (i << 16);
else if (biosmask == 0x3ffff) else if (biosmask == 0x3ffff)
base = 0xc0000 + (i << 16); base = 0xc0000 + (i << 16);
else else
base = 0xe0000 + (i << 16); base = 0xe0000 + (i << 16);
fbase = base & biosmask; fbase = base & biosmask;
if (dev->flags & FLAG_INV_A16) if (dev->flags & FLAG_INV_A16)
fbase ^= 0x10000; fbase ^= 0x10000;
memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000); memcpy(&dev->array[fbase], &rom[base & biosmask], 0x10000);
if ((max == 2) || (i >= 2)) { if ((max == 2) || (i >= 2)) {
mem_mapping_add(&(dev->mapping[i]), base, 0x10000, mem_mapping_add(&(dev->mapping[i]), base, 0x10000,
flash_read, flash_readw, flash_readl, flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel, flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); 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, mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000,
flash_read, flash_readw, flash_readl, flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel, flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); 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, mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000,
flash_read, flash_readw, flash_readl, flash_read, flash_readw, flash_readl,
flash_write, flash_writew, flash_writel, flash_write, flash_writew, flash_writel,
dev->array + fbase, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, (void *) dev); dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev);
} }
} }
static void static void
intel_flash_reset(void *priv) intel_flash_reset(void *priv)
{ {
flash_t *dev = (flash_t *) priv; flash_t *dev = (flash_t *) priv;
dev->command = CMD_READ_ARRAY; dev->command = CMD_READ_ARRAY;
dev->status = 0; dev->status = 0;
} }
static void * static void *
intel_flash_init(const device_t *info) intel_flash_init(const device_t *info)
{ {
FILE *f; FILE *f;
flash_t *dev; flash_t *dev;
uint8_t type = info->local & 0xff; uint8_t type = info->local & 0xff;
dev = malloc(sizeof(flash_t)); dev = malloc(sizeof(flash_t));
memset(dev, 0, 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); memset(dev->array, 0xff, biosmask + 1);
switch (biosmask) { switch (biosmask) {
case 0x7ffff: case 0x7ffff:
if (dev->flags & FLAG_WORD) if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470; dev->flash_id = (dev->flags & FLAG_BXB) ? 0x4471 : 0x4470;
else else
dev->flash_id =(dev->flags & FLAG_BXB) ? 0x8A : 0x89; dev->flash_id = (dev->flags & FLAG_BXB) ? 0x8A : 0x89;
/* The block lengths are the same both flash types. */ /* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000; dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x20000; dev->block_len[BLOCK_MAIN2] = 0x20000;
dev->block_len[BLOCK_MAIN3] = 0x20000; dev->block_len[BLOCK_MAIN3] = 0x20000;
dev->block_len[BLOCK_MAIN4] = 0x18000; dev->block_len[BLOCK_MAIN4] = 0x18000;
dev->block_len[BLOCK_DATA1] = 0x02000; dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000; dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000; dev->block_len[BLOCK_BOOT] = 0x04000;
if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */ if (dev->flags & FLAG_BXB) { /* 28F004BX-T/28F400BX-B */
dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_BOOT] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_BOOT] = 0x1ffff; dev->block_end[BLOCK_BOOT] = 0x1ffff;
dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_DATA2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_DATA2] = 0x3ffff; dev->block_end[BLOCK_DATA2] = 0x3ffff;
dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_DATA1] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_DATA1] = 0x5ffff; dev->block_end[BLOCK_DATA1] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff; dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_MAIN3] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_MAIN3] = 0x79fff; dev->block_end[BLOCK_MAIN3] = 0x79fff;
dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_MAIN2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_MAIN2] = 0x7bfff; dev->block_end[BLOCK_MAIN2] = 0x7bfff;
dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */ dev->block_start[BLOCK_MAIN1] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_MAIN1] = 0x7ffff; dev->block_end[BLOCK_MAIN1] = 0x7ffff;
} else { } else {
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff; dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x3ffff; dev->block_end[BLOCK_MAIN2] = 0x3ffff;
dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_MAIN3] = 0x40000; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0x5ffff; dev->block_end[BLOCK_MAIN3] = 0x5ffff;
dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0x60000; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0x77fff; dev->block_end[BLOCK_MAIN4] = 0x77fff;
dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_DATA1] = 0x78000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x79fff; dev->block_end[BLOCK_DATA1] = 0x79fff;
dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_DATA2] = 0x7a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x7bfff; dev->block_end[BLOCK_DATA2] = 0x7bfff;
dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */ dev->block_start[BLOCK_BOOT] = 0x7c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x7ffff; dev->block_end[BLOCK_BOOT] = 0x7ffff;
} }
break; break;
case 0x3ffff: case 0x3ffff:
if (dev->flags & FLAG_WORD) if (dev->flags & FLAG_WORD)
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274; dev->flash_id = (dev->flags & FLAG_BXB) ? 0x2275 : 0x2274;
else else
dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C; dev->flash_id = (dev->flags & FLAG_BXB) ? 0x7D : 0x7C;
/* The block lengths are the same both flash types. */ /* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x20000; dev->block_len[BLOCK_MAIN1] = 0x20000;
dev->block_len[BLOCK_MAIN2] = 0x18000; dev->block_len[BLOCK_MAIN2] = 0x18000;
dev->block_len[BLOCK_MAIN3] = 0x00000; dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000; dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x02000; dev->block_len[BLOCK_DATA1] = 0x02000;
dev->block_len[BLOCK_DATA2] = 0x02000; dev->block_len[BLOCK_DATA2] = 0x02000;
dev->block_len[BLOCK_BOOT] = 0x04000; dev->block_len[BLOCK_BOOT] = 0x04000;
if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */ if (dev->flags & FLAG_BXB) { /* 28F002BX-B/28F200BX-B */
dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_MAIN1] = 0x20000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x3ffff; dev->block_end[BLOCK_MAIN1] = 0x3ffff;
dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_MAIN2] = 0x08000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x1ffff; dev->block_end[BLOCK_MAIN2] = 0x1ffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff; dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff; dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_DATA1] = 0x06000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x07fff; dev->block_end[BLOCK_DATA1] = 0x07fff;
dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_DATA2] = 0x04000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x05fff; dev->block_end[BLOCK_DATA2] = 0x05fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x03fff; dev->block_end[BLOCK_BOOT] = 0x03fff;
} else { /* 28F002BX-T/28F200BX-T */ } else { /* 28F002BX-T/28F200BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff; dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_MAIN2] = 0x20000; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0x37fff; dev->block_end[BLOCK_MAIN2] = 0x37fff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff; dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff; dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_DATA1] = 0x38000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x39fff; dev->block_end[BLOCK_DATA1] = 0x39fff;
dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_DATA2] = 0x3a000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x3bfff; dev->block_end[BLOCK_DATA2] = 0x3bfff;
dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */ dev->block_start[BLOCK_BOOT] = 0x3c000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x3ffff; dev->block_end[BLOCK_BOOT] = 0x3ffff;
} }
break; break;
default: default:
dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94; dev->flash_id = (type & FLAG_BXB) ? 0x95 : 0x94;
/* The block lengths are the same both flash types. */ /* The block lengths are the same both flash types. */
dev->block_len[BLOCK_MAIN1] = 0x1c000; dev->block_len[BLOCK_MAIN1] = 0x1c000;
dev->block_len[BLOCK_MAIN2] = 0x00000; dev->block_len[BLOCK_MAIN2] = 0x00000;
dev->block_len[BLOCK_MAIN3] = 0x00000; dev->block_len[BLOCK_MAIN3] = 0x00000;
dev->block_len[BLOCK_MAIN4] = 0x00000; dev->block_len[BLOCK_MAIN4] = 0x00000;
dev->block_len[BLOCK_DATA1] = 0x01000; dev->block_len[BLOCK_DATA1] = 0x01000;
dev->block_len[BLOCK_DATA2] = 0x01000; dev->block_len[BLOCK_DATA2] = 0x01000;
dev->block_len[BLOCK_BOOT] = 0x02000; dev->block_len[BLOCK_BOOT] = 0x02000;
if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */ if (dev->flags & FLAG_BXB) { /* 28F001BX-B/28F100BX-B */
dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_MAIN1] = 0x04000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1ffff; dev->block_end[BLOCK_MAIN1] = 0x1ffff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff; dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff; dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff; dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_DATA1] = 0x02000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x02fff; dev->block_end[BLOCK_DATA1] = 0x02fff;
dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_DATA2] = 0x03000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x03fff; dev->block_end[BLOCK_DATA2] = 0x03fff;
dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */ dev->block_start[BLOCK_BOOT] = 0x00000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x01fff; dev->block_end[BLOCK_BOOT] = 0x01fff;
} else { /* 28F001BX-T/28F100BX-T */ } else { /* 28F001BX-T/28F100BX-T */
dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */ dev->block_start[BLOCK_MAIN1] = 0x00000; /* MAIN BLOCK 1 */
dev->block_end[BLOCK_MAIN1] = 0x1bfff; dev->block_end[BLOCK_MAIN1] = 0x1bfff;
dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */ dev->block_start[BLOCK_MAIN2] = 0xfffff; /* MAIN BLOCK 2 */
dev->block_end[BLOCK_MAIN2] = 0xfffff; dev->block_end[BLOCK_MAIN2] = 0xfffff;
dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */ dev->block_start[BLOCK_MAIN3] = 0xfffff; /* MAIN BLOCK 3 */
dev->block_end[BLOCK_MAIN3] = 0xfffff; dev->block_end[BLOCK_MAIN3] = 0xfffff;
dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */ dev->block_start[BLOCK_MAIN4] = 0xfffff; /* MAIN BLOCK 4 */
dev->block_end[BLOCK_MAIN4] = 0xfffff; dev->block_end[BLOCK_MAIN4] = 0xfffff;
dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */ dev->block_start[BLOCK_DATA1] = 0x1c000; /* DATA AREA 1 BLOCK */
dev->block_end[BLOCK_DATA1] = 0x1cfff; dev->block_end[BLOCK_DATA1] = 0x1cfff;
dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */ dev->block_start[BLOCK_DATA2] = 0x1d000; /* DATA AREA 2 BLOCK */
dev->block_end[BLOCK_DATA2] = 0x1dfff; dev->block_end[BLOCK_DATA2] = 0x1dfff;
dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */ dev->block_start[BLOCK_BOOT] = 0x1e000; /* BOOT BLOCK */
dev->block_end[BLOCK_BOOT] = 0x1ffff; dev->block_end[BLOCK_BOOT] = 0x1ffff;
} }
break; break;
} }
intel_flash_add_mappings(dev); intel_flash_add_mappings(dev);
dev->command = CMD_READ_ARRAY; dev->command = CMD_READ_ARRAY;
dev->status = 0; dev->status = 0;
f = nvr_fopen(flash_path, "rb"); f = nvr_fopen(flash_path, "rb");
if (f) { if (f) {
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
if (dev->block_len[BLOCK_MAIN2]) if (dev->block_len[BLOCK_MAIN2])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f); (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
if (dev->block_len[BLOCK_MAIN3]) if (dev->block_len[BLOCK_MAIN3])
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f); (void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
if (dev->block_len[BLOCK_MAIN4]) 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_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_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f); (void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
fclose(f); fclose(f);
} }
return dev; return dev;
} }
static void static void
intel_flash_close(void *p) intel_flash_close(void *p)
{ {
FILE *f; FILE *f;
flash_t *dev = (flash_t *)p; flash_t *dev = (flash_t *) p;
f = nvr_fopen(flash_path, "wb"); f = nvr_fopen(flash_path, "wb");
fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f); fwrite(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
if (dev->block_len[BLOCK_MAIN2]) 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]) 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]) 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_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
fwrite(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 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. */ /* For AMI BIOS'es - Intel 28F001BXT with A16 pin inverted. */
const device_t intel_flash_bxt_ami_device = { 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", .internal_name = "intel_flash_bxt_ami",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = FLAG_INV_A16, .local = FLAG_INV_A16,
.init = intel_flash_init, .init = intel_flash_init,
.close = intel_flash_close, .close = intel_flash_close,
.reset = intel_flash_reset, .reset = intel_flash_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t intel_flash_bxt_device = { 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", .internal_name = "intel_flash_bxt",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = 0, .local = 0,
.init = intel_flash_init, .init = intel_flash_init,
.close = intel_flash_close, .close = intel_flash_close,
.reset = intel_flash_reset, .reset = intel_flash_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = NULL .config = NULL
}; };
const device_t intel_flash_bxb_device = { 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", .internal_name = "intel_flash_bxb",
.flags = DEVICE_PCI, .flags = DEVICE_PCI,
.local = FLAG_BXB, .local = FLAG_BXB,
.init = intel_flash_init, .init = intel_flash_init,
.close = intel_flash_close, .close = intel_flash_close,
.reset = intel_flash_reset, .reset = intel_flash_reset,
{ .available = NULL }, { .available = NULL },
.speed_changed = NULL, .speed_changed = NULL,
.force_redraw = NULL, .force_redraw = NULL,
.config = 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/machine.h>
#include <86box/m_xt_xi8088.h> #include <86box/m_xt_xi8088.h>
#ifdef ENABLE_ROM_LOG #ifdef ENABLE_ROM_LOG
int rom_do_log = ENABLE_ROM_LOG; int rom_do_log = ENABLE_ROM_LOG;
static void static void
rom_log(const char *fmt, ...) rom_log(const char *fmt, ...)
{ {
va_list ap; va_list ap;
if (rom_do_log) { if (rom_do_log) {
va_start(ap, fmt); va_start(ap, fmt);
pclog_ex(fmt, ap); pclog_ex(fmt, ap);
va_end(ap); va_end(ap);
} }
} }
#else #else
#define rom_log(fmt, ...) # define rom_log(fmt, ...)
#endif #endif
void void
rom_add_path(const char* path) rom_add_path(const char *path)
{ {
char cwd[1024] = { 0 }; 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. // Iterate to the end of the list.
while (rom_path->next != NULL) { while (rom_path->next != NULL) {
rom_path = rom_path->next; rom_path = rom_path->next;
@@ -77,7 +74,7 @@ rom_add_path(const char* path)
} }
// Save the path, turning it into absolute if needed. // Save the path, turning it into absolute if needed.
if (!path_abs((char*) path)) { if (!path_abs((char *) path)) {
plat_getcwd(cwd, sizeof(cwd)); plat_getcwd(cwd, sizeof(cwd));
path_slash(cwd); path_slash(cwd);
snprintf(rom_path->path, sizeof(rom_path->path), "%s%s", cwd, path); 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); path_slash(rom_path->path);
} }
FILE * FILE *
rom_fopen(char *fn, char *mode) rom_fopen(char *fn, char *mode)
{ {
char temp[1024]; char temp[1024];
rom_path_t *rom_path; rom_path_t *rom_path;
FILE *fp = NULL; FILE *fp = NULL;
if (strstr(fn, "roms/") == fn) { if (strstr(fn, "roms/") == fn) {
/* Relative path */ /* Relative path */
@@ -114,11 +110,10 @@ rom_fopen(char *fn, char *mode)
} }
} }
int int
rom_getfile(char *fn, char *s, int size) rom_getfile(char *fn, char *s, int size)
{ {
char temp[1024]; char temp[1024];
rom_path_t *rom_path; rom_path_t *rom_path;
if (strstr(fn, "roms/") == fn) { if (strstr(fn, "roms/") == fn) {
@@ -144,7 +139,6 @@ rom_getfile(char *fn, char *s, int size)
} }
} }
int int
rom_present(char *fn) rom_present(char *fn)
{ {
@@ -152,104 +146,99 @@ rom_present(char *fn)
f = rom_fopen(fn, "rb"); f = rom_fopen(fn, "rb");
if (f != NULL) { if (f != NULL) {
(void)fclose(f); (void) fclose(f);
return(1); return (1);
} }
return(0); return (0);
} }
uint8_t uint8_t
rom_read(uint32_t addr, void *priv) rom_read(uint32_t addr, void *priv)
{ {
rom_t *rom = (rom_t *)priv; rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE #ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE) if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read byte from BIOS at %06lX\n", addr); rom_log("ROM: read byte from BIOS at %06lX\n", addr);
#endif #endif
if (addr < rom->mapping.base) if (addr < rom->mapping.base)
return 0xff; return 0xff;
if (addr >= (rom->mapping.base + rom->sz)) if (addr >= (rom->mapping.base + rom->sz))
return 0xff; return 0xff;
return(rom->rom[(addr - rom->mapping.base) & rom->mask]); return (rom->rom[(addr - rom->mapping.base) & rom->mask]);
} }
uint16_t uint16_t
rom_readw(uint32_t addr, void *priv) rom_readw(uint32_t addr, void *priv)
{ {
rom_t *rom = (rom_t *)priv; rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE #ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE) if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read word from BIOS at %06lX\n", addr); rom_log("ROM: read word from BIOS at %06lX\n", addr);
#endif #endif
if (addr < (rom->mapping.base - 1)) if (addr < (rom->mapping.base - 1))
return 0xffff; return 0xffff;
if (addr >= (rom->mapping.base + rom->sz)) if (addr >= (rom->mapping.base + rom->sz))
return 0xffff; return 0xffff;
return(*(uint16_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]); return (*(uint16_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
} }
uint32_t uint32_t
rom_readl(uint32_t addr, void *priv) rom_readl(uint32_t addr, void *priv)
{ {
rom_t *rom = (rom_t *)priv; rom_t *rom = (rom_t *) priv;
#ifdef ROM_TRACE #ifdef ROM_TRACE
if (rom->mapping.base==ROM_TRACE) if (rom->mapping.base == ROM_TRACE)
rom_log("ROM: read long from BIOS at %06lX\n", addr); rom_log("ROM: read long from BIOS at %06lX\n", addr);
#endif #endif
if (addr < (rom->mapping.base - 3)) if (addr < (rom->mapping.base - 3))
return 0xffffffff; return 0xffffffff;
if (addr >= (rom->mapping.base + rom->sz)) if (addr >= (rom->mapping.base + rom->sz))
return 0xffffffff; return 0xffffffff;
return(*(uint32_t *)&rom->rom[(addr - rom->mapping.base) & rom->mask]); return (*(uint32_t *) &rom->rom[(addr - rom->mapping.base) & rom->mask]);
} }
int int
rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) rom_load_linear_oddeven(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr)
{ {
FILE *f = rom_fopen(fn, "rb"); FILE *f = rom_fopen(fn, "rb");
int i; int i;
if (f == NULL) { if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn); rom_log("ROM: image '%s' not found\n", fn);
return(0); return (0);
} }
/* Make sure we only look at the base-256K offset. */ /* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000) if (addr >= 0x40000)
addr = 0; addr = 0;
else else
addr &= 0x03ffff; addr &= 0x03ffff;
if (ptr != NULL) { if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1) if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n"); fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
for (i = 0; i < (sz >> 1); i++) { for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1) if (fread(ptr + (addr + (i << 1)), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading even data\n"); fatal("rom_load_linear(): Error reading even data\n");
} }
for (i = 0; i < (sz >> 1); i++) { for (i = 0; i < (sz >> 1); i++) {
if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1) if (fread(ptr + (addr + (i << 1) + 1), 1, 1, f) != 1)
fatal("rom_load_linear(): Error reading od data\n"); 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. */ /* Load a ROM BIOS from its chips, interleaved mode. */
int int
rom_load_linear(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) 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"); FILE *f = rom_fopen(fn, "rb");
if (f == NULL) { if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn); rom_log("ROM: image '%s' not found\n", fn);
return(0); return (0);
} }
/* Make sure we only look at the base-256K offset. */ /* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000) if (addr >= 0x40000)
addr = 0; addr = 0;
else else
addr &= 0x03ffff; addr &= 0x03ffff;
if (ptr != NULL) { if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1) if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear(): Error seeking to the beginning of the file\n"); fatal("rom_load_linear(): Error seeking to the beginning of the file\n");
if (fread(ptr+addr, 1, sz, f) > sz) if (fread(ptr + addr, 1, sz, f) > sz)
fatal("rom_load_linear(): Error reading data\n"); 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. */ /* Load a ROM BIOS from its chips, linear mode with high bit flipped. */
int int
rom_load_linear_inverted(char *fn, uint32_t addr, int sz, int off, uint8_t *ptr) 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"); FILE *f = rom_fopen(fn, "rb");
if (f == NULL) { if (f == NULL) {
rom_log("ROM: image '%s' not found\n", fn); rom_log("ROM: image '%s' not found\n", fn);
return(0); return (0);
} }
/* Make sure we only look at the base-256K offset. */ /* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000) if (addr >= 0x40000) {
{ addr = 0;
addr = 0; } else {
} addr &= 0x03ffff;
else
{
addr &= 0x03ffff;
} }
(void)fseek(f, 0, SEEK_END); (void) fseek(f, 0, SEEK_END);
if (ftell(f) < sz) { if (ftell(f) < sz) {
(void)fclose(f); (void) fclose(f);
return(0); return (0);
} }
if (ptr != NULL) { if (ptr != NULL) {
if (fseek(f, off, SEEK_SET) == -1) if (fseek(f, off, SEEK_SET) == -1)
fatal("rom_load_linear_inverted(): Error seeking to the beginning of the file\n"); 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)) 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"); fatal("rom_load_linear_inverted(): Error reading the upper half of the data\n");
if (fread(ptr+addr, sz >> 1, 1, f) > (sz >> 1)) if (fread(ptr + addr, sz >> 1, 1, f) > (sz >> 1))
fatal("rom_load_linear_inverted(): Error reading the lower half of the data\n"); 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. */ /* Load a ROM BIOS from its chips, interleaved mode. */
int int
rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr) rom_load_interleaved(char *fnl, char *fnh, uint32_t addr, int sz, int off, uint8_t *ptr)
{ {
FILE *fl = rom_fopen(fnl, "rb"); FILE *fl = rom_fopen(fnl, "rb");
FILE *fh = rom_fopen(fnh, "rb"); FILE *fh = rom_fopen(fnh, "rb");
int c; int c;
if (fl == NULL || fh == NULL) { if (fl == NULL || fh == NULL) {
if (fl == NULL) rom_log("ROM: image '%s' not found\n", fnl); if (fl == NULL)
else (void)fclose(fl); rom_log("ROM: image '%s' not found\n", fnl);
if (fh == NULL) rom_log("ROM: image '%s' not found\n", fnh); else
else (void)fclose(fh); (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. */ /* Make sure we only look at the base-256K offset. */
if (addr >= 0x40000) if (addr >= 0x40000) {
{ addr = 0;
addr = 0; } else {
} addr &= 0x03ffff;
else
{
addr &= 0x03ffff;
} }
if (ptr != NULL) { if (ptr != NULL) {
(void)fseek(fl, off, SEEK_SET); (void) fseek(fl, off, SEEK_SET);
(void)fseek(fh, off, SEEK_SET); (void) fseek(fh, off, SEEK_SET);
for (c=0; c<sz; c+=2) { for (c = 0; c < sz; c += 2) {
ptr[addr+c] = fgetc(fl) & 0xff; ptr[addr + c] = fgetc(fl) & 0xff;
ptr[addr+c+1] = fgetc(fh) & 0xff; ptr[addr + c + 1] = fgetc(fh) & 0xff;
} }
} }
(void)fclose(fh); (void) fclose(fh);
(void)fclose(fl); (void) fclose(fl);
return(1); return (1);
} }
static int static int
bios_normalize(int n, int up) bios_normalize(int n, int up)
{ {
@@ -373,38 +357,35 @@ bios_normalize(int n, int up)
/* 0x2000 -> 0x4000; 0x4000 -> 0x4000; 0x6000 -> 0x8000 */ /* 0x2000 -> 0x4000; 0x4000 -> 0x4000; 0x6000 -> 0x8000 */
if (up && (n % MEM_GRANULARITY_SIZE)) if (up && (n % MEM_GRANULARITY_SIZE))
temp_n += MEM_GRANULARITY_SIZE; temp_n += MEM_GRANULARITY_SIZE;
return temp_n; return temp_n;
} }
static uint8_t * static uint8_t *
rom_reset(uint32_t addr, int sz) rom_reset(uint32_t addr, int sz)
{ {
biosaddr = bios_normalize(addr, 0); biosaddr = bios_normalize(addr, 0);
biosmask = bios_normalize(sz, 1) - 1; biosmask = bios_normalize(sz, 1) - 1;
if ((biosaddr + biosmask) > 0x000fffff) 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); 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 not done yet, allocate a 128KB buffer for the BIOS ROM. */
if (rom != NULL) { if (rom != NULL) {
rom_log("ROM allocated, freeing...\n"); rom_log("ROM allocated, freeing...\n");
free(rom); free(rom);
rom = NULL; rom = NULL;
} }
rom_log("Allocating ROM...\n"); 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"); rom_log("Filling ROM with FF's...\n");
memset(rom, 0xff, biosmask + 1); memset(rom, 0xff, biosmask + 1);
return rom; return rom;
} }
uint8_t uint8_t
bios_read(uint32_t addr, void *priv) bios_read(uint32_t addr, void *priv)
{ {
@@ -413,12 +394,11 @@ bios_read(uint32_t addr, void *priv)
addr &= 0x000fffff; addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = rom[addr - biosaddr]; ret = rom[addr - biosaddr];
return ret; return ret;
} }
uint16_t uint16_t
bios_readw(uint32_t addr, void *priv) bios_readw(uint32_t addr, void *priv)
{ {
@@ -427,12 +407,11 @@ bios_readw(uint32_t addr, void *priv)
addr &= 0x000fffff; addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint16_t *)&rom[addr - biosaddr]; ret = *(uint16_t *) &rom[addr - biosaddr];
return ret; return ret;
} }
uint32_t uint32_t
bios_readl(uint32_t addr, void *priv) bios_readl(uint32_t addr, void *priv)
{ {
@@ -441,113 +420,110 @@ bios_readl(uint32_t addr, void *priv)
addr &= 0x000fffff; addr &= 0x000fffff;
if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask))) if ((addr >= biosaddr) && (addr <= (biosaddr + biosmask)))
ret = *(uint32_t *)&rom[addr - biosaddr]; ret = *(uint32_t *) &rom[addr - biosaddr];
return ret; return ret;
} }
static void static void
bios_add(void) bios_add(void)
{ {
int temp_cpu_type, temp_cpu_16bitbus = 1; int temp_cpu_type, temp_cpu_16bitbus = 1;
int temp_is286 = 0, temp_is6117 = 0; int temp_is286 = 0, temp_is6117 = 0;
if (/*AT && */cpu_s) { if (/*AT && */ cpu_s) {
temp_cpu_type = cpu_s->cpu_type; 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_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_is286 = (temp_cpu_type >= CPU_286);
temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi"); temp_is6117 = !strcmp(cpu_f->manufacturer, "ALi");
} }
if (biosmask > 0x1ffff) { if (biosmask > 0x1ffff) {
/* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */ /* 256k+ BIOS'es only have low mappings at E0000-FFFFF. */
mem_mapping_add(&bios_mapping, 0xe0000, 0x20000, mem_mapping_add(&bios_mapping, 0xe0000, 0x20000,
bios_read,bios_readw,bios_readl, bios_read, bios_readw, bios_readl,
NULL,NULL,NULL, NULL, NULL, NULL,
&rom[0x20000], MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); &rom[0x20000], MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(0x0e0000, 0x20000, mem_set_mem_state_both(0x0e0000, 0x20000,
MEM_READ_ROMCS | MEM_WRITE_ROMCS); MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} else { } else {
mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1, mem_mapping_add(&bios_mapping, biosaddr, biosmask + 1,
bios_read,bios_readw,bios_readl, bios_read, bios_readw, bios_readl,
NULL,NULL,NULL, NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(biosaddr, biosmask + 1, mem_set_mem_state_both(biosaddr, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS); MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} }
if (temp_is6117) { if (temp_is6117) {
mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1, mem_mapping_add(&bios_high_mapping, biosaddr | 0x03f00000, biosmask + 1,
bios_read,bios_readw,bios_readl, bios_read, bios_readw, bios_readl,
NULL,NULL,NULL, NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); rom, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, 0);
mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1, mem_set_mem_state_both(biosaddr | 0x03f00000, biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS); MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} else if (temp_is286) { } else if (temp_is286) {
mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1, mem_mapping_add(&bios_high_mapping, biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
bios_read,bios_readw,bios_readl, bios_read, bios_readw, bios_readl,
NULL,NULL,NULL, NULL, NULL, NULL,
rom, MEM_MAPPING_EXTERNAL|MEM_MAPPING_ROM|MEM_MAPPING_ROMCS, 0); 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_set_mem_state_both(biosaddr | (temp_cpu_16bitbus ? 0x00f00000 : 0xfff00000), biosmask + 1,
MEM_READ_ROMCS | MEM_WRITE_ROMCS); MEM_READ_ROMCS | MEM_WRITE_ROMCS);
} }
} }
/* These four are for loading the BIOS. */ /* These four are for loading the BIOS. */
int int
bios_load(char *fn1, char *fn2, uint32_t addr, int sz, int off, int flags) 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; 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 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, 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, 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 fe000, 8192 = prepare 16k rom starting at fc000, load 8k bios at 2000
*/ */
if (!bios_only) 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)) if (!(flags & FLAG_AUX) && ((addr + sz) > 0x00100000))
sz = 0x00100000 - addr; sz = 0x00100000 - addr;
#ifdef ENABLE_ROM_LOG #ifdef ENABLE_ROM_LOG
if (!bios_only) 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 #endif
if (flags & FLAG_INT) 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 { else {
if (flags & FLAG_INV) if (flags & FLAG_INV)
ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr); ret = rom_load_linear_inverted(fn1, addr - biosaddr, sz, off, ptr);
else else
ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr); ret = rom_load_linear(fn1, addr - biosaddr, sz, off, ptr);
} }
if (!bios_only && (flags & FLAG_REP) && (old_sz >= 65536) && (sz < old_sz)) { if (!bios_only && (flags & FLAG_REP) && (old_sz >= 65536) && (sz < old_sz)) {
old_sz /= sz; old_sz /= sz;
for (i = 0; i < (old_sz - 1); i++) { for (i = 0; i < (old_sz - 1); i++) {
rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz); rom_log("Copying ptr[%08X] to ptr[%08X]\n", addr - biosaddr, i * sz);
memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz); memcpy(&(ptr[i * sz]), &(ptr[addr - biosaddr]), sz);
} }
} }
if (!bios_only && ret && !(flags & FLAG_AUX)) if (!bios_only && ret && !(flags & FLAG_AUX))
bios_add(); bios_add();
return ret; return ret;
} }
int int
bios_load_linear_combined(char *fn1, char *fn2, int sz, int off) 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; return ret;
} }
int int
bios_load_linear_combined2(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off) 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(fn2, 0x000c0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off); ret &= bios_load_aux_linear(fn4, 0x000e0000, sz - 196608, off);
if (fn5 != NULL) if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0); ret &= bios_load_aux_linear(fn5, 0x000ec000, 16384, 0);
return ret; return ret;
} }
int int
bios_load_linear_combined2_ex(char *fn1, char *fn2, char *fn3, char *fn4, char *fn5, int sz, int off) 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(fn2, 0x000d0000, 65536, off);
ret &= bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off); ret &= bios_load_aux_linear(fn4, 0x000f0000, sz - 196608, off);
if (fn5 != NULL) if (fn5 != NULL)
ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0); ret &= bios_load_aux_linear(fn5, 0x000fc000, 16384, 0);
return ret; return ret;
} }
int int
rom_init(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) 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); memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */ /* Load the image file into the buffer. */
if (! rom_load_linear(fn, addr, sz, off, rom->rom)) { if (!rom_load_linear(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */ /* Nope.. clean up. */
free(rom->rom); free(rom->rom);
rom->rom = NULL; rom->rom = NULL;
return(-1); return (-1);
} }
rom->sz = sz; rom->sz = sz;
rom->mask = mask; rom->mask = mask;
mem_mapping_add(&rom->mapping, mem_mapping_add(&rom->mapping,
addr, sz, addr, sz,
rom_read, rom_readw, rom_readl, rom_read, rom_readw, rom_readl,
NULL, NULL, NULL, NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom); rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0); return (0);
} }
int int
rom_init_oddeven(rom_t *rom, char *fn, uint32_t addr, int sz, int mask, int off, uint32_t flags) 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); memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */ /* Load the image file into the buffer. */
if (! rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) { if (!rom_load_linear_oddeven(fn, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */ /* Nope.. clean up. */
free(rom->rom); free(rom->rom);
rom->rom = NULL; rom->rom = NULL;
return(-1); return (-1);
} }
rom->sz = sz; rom->sz = sz;
rom->mask = mask; rom->mask = mask;
mem_mapping_add(&rom->mapping, mem_mapping_add(&rom->mapping,
addr, sz, addr, sz,
rom_read, rom_readw, rom_readl, rom_read, rom_readw, rom_readl,
NULL, NULL, NULL, NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom); rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0); return (0);
} }
int int
rom_init_interleaved(rom_t *rom, char *fnl, char *fnh, uint32_t addr, int sz, int mask, int off, uint32_t flags) 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); memset(rom->rom, 0xff, sz);
/* Load the image file into the buffer. */ /* Load the image file into the buffer. */
if (! rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) { if (!rom_load_interleaved(fnl, fnh, addr, sz, off, rom->rom)) {
/* Nope.. clean up. */ /* Nope.. clean up. */
free(rom->rom); free(rom->rom);
rom->rom = NULL; rom->rom = NULL;
return(-1); return (-1);
} }
rom->sz = sz; rom->sz = sz;
rom->mask = mask; rom->mask = mask;
mem_mapping_add(&rom->mapping, mem_mapping_add(&rom->mapping,
addr, sz, addr, sz,
rom_read, rom_readw, rom_readl, rom_read, rom_readw, rom_readl,
NULL, NULL, NULL, NULL, NULL, NULL,
rom->rom, flags | MEM_MAPPING_ROM_WS, rom); rom->rom, flags | MEM_MAPPING_ROM_WS, rom);
return(0); return (0);
} }

View File

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

View File

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

View File

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