提交 02bccc77 编写于 作者: P Paul Burton 提交者: Aurelien Jarno

mips_malta: generate SPD EEPROM data at runtime

The SPD EEPROM specifies the amount of memory present in the system and
thus its correct contents can only be known at runtime. Calculating
parts of the data on init allows the data to accurately reflect the
amount of target memory present and allow YAMON to boot with an
arbitrary amount of SDRAM.

Where possible the SPD data will favor indicating 2 banks of SDRAM
rather than 1. For example the default 128MB of target memory will be
represented as 2x64MB banks rather than 1x128MB bank. This allows
versions of MIPS BIOS code (such as YAMON 2.22 and older) to boot
despite a bug preventing them from handling a single bank of SDRAM with
the Galileo GT64120 system controller emulated by QEMU.
Signed-off-by: NPaul Burton <paul.burton@imgtec.com>
Signed-off-by: NLeon Alrae <leon.alrae@imgtec.com>
Signed-off-by: NAurelien Jarno <aurelien@aurel32.net>
上级 a427338b
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "sysemu/blockdev.h" #include "sysemu/blockdev.h"
#include "exec/address-spaces.h" #include "exec/address-spaces.h"
#include "hw/sysbus.h" /* SysBusDevice */ #include "hw/sysbus.h" /* SysBusDevice */
#include "qemu/host-utils.h"
//#define DEBUG_BOARD_INIT //#define DEBUG_BOARD_INIT
...@@ -150,10 +151,10 @@ typedef struct _eeprom24c0x_t eeprom24c0x_t; ...@@ -150,10 +151,10 @@ typedef struct _eeprom24c0x_t eeprom24c0x_t;
static eeprom24c0x_t eeprom = { static eeprom24c0x_t eeprom = {
.contents = { .contents = {
/* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00, /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
/* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01, /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
/* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00, /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
/* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40, /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
/* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00, /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
/* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
...@@ -169,6 +170,56 @@ static eeprom24c0x_t eeprom = { ...@@ -169,6 +170,56 @@ static eeprom24c0x_t eeprom = {
}, },
}; };
static void eeprom_generate(eeprom24c0x_t *eeprom, ram_addr_t ram_size)
{
enum { SDR = 0x4, DDR2 = 0x8 } type;
uint8_t *spd = eeprom->contents;
uint8_t nbanks = 0;
uint16_t density = 0;
int i;
/* work in terms of MB */
ram_size >>= 20;
while ((ram_size >= 4) && (nbanks <= 2)) {
int sz_log2 = MIN(31 - clz32(ram_size), 14);
nbanks++;
density |= 1 << (sz_log2 - 2);
ram_size -= 1 << sz_log2;
}
/* split to 2 banks if possible */
if ((nbanks == 1) && (density > 1)) {
nbanks++;
density >>= 1;
}
if (density & 0xff00) {
density = (density & 0xe0) | ((density >> 8) & 0x1f);
type = DDR2;
} else if (!(density & 0x1f)) {
type = DDR2;
} else {
type = SDR;
}
if (ram_size) {
fprintf(stderr, "Warning: SPD cannot represent final %dMB"
" of SDRAM\n", (int)ram_size);
}
/* fill in SPD memory information */
spd[2] = type;
spd[5] = nbanks;
spd[31] = density;
/* checksum */
spd[63] = 0;
for (i = 0; i < 63; i++) {
spd[63] += spd[i];
}
}
static uint8_t eeprom24c0x_read(void) static uint8_t eeprom24c0x_read(void)
{ {
logout("%u: scl = %u, sda = %u, data = 0x%02x\n", logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
...@@ -862,6 +913,9 @@ void mips_malta_init(QEMUMachineInitArgs *args) ...@@ -862,6 +913,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(ram); vmstate_register_ram_global(ram);
memory_region_add_subregion(system_memory, 0, ram); memory_region_add_subregion(system_memory, 0, ram);
/* generate SPD EEPROM data */
eeprom_generate(&eeprom, ram_size);
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
be = 1; be = 1;
#else #else
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册