aboutsummaryrefslogtreecommitdiff
path: root/hw/mips
diff options
context:
space:
mode:
Diffstat (limited to 'hw/mips')
-rw-r--r--hw/mips/mips_malta.c60
1 files changed, 57 insertions, 3 deletions
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 2edc8e16f5..e06e19d2df 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -47,6 +47,7 @@
#include "sysemu/blockdev.h"
#include "exec/address-spaces.h"
#include "hw/sysbus.h" /* SysBusDevice */
+#include "qemu/host-utils.h"
//#define DEBUG_BOARD_INIT
@@ -150,10 +151,10 @@ typedef struct _eeprom24c0x_t eeprom24c0x_t;
static eeprom24c0x_t eeprom = {
.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,
- /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
- /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
+ /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
+ /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
/* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
/* 00000028: */ 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 = {
},
};
+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)
{
logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
@@ -862,6 +913,9 @@ void mips_malta_init(QEMUMachineInitArgs *args)
vmstate_register_ram_global(ram);
memory_region_add_subregion(system_memory, 0, ram);
+ /* generate SPD EEPROM data */
+ eeprom_generate(&eeprom, ram_size);
+
#ifdef TARGET_WORDS_BIGENDIAN
be = 1;
#else