From 958413a33d77660748312b24b366b4bd92186cab Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 26 Apr 2020 19:24:15 -0300 Subject: [PATCH] SPD improvements --- src/include/86box/spd.h | 31 ++++++++++++++++--- src/spd.c | 66 ++++++++++++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 18 deletions(-) diff --git a/src/include/86box/spd.h b/src/include/86box/spd.h index 3cbc7a7a3..c2549fe95 100644 --- a/src/include/86box/spd.h +++ b/src/include/86box/spd.h @@ -8,7 +8,7 @@ * * Emulation of SPD (Serial Presence Detect) devices. * - * Version: @(#)spd.h 1.0.0 2020/03/24 + * * * Authors: RichardG, * @@ -19,15 +19,19 @@ #define SPD_BASE_ADDR 0x50 +#define SPD_MAX_SLOTS 8 +#define SPD_DATA_SIZE 256 +#define SPD_TYPE_FPM 0x01 #define SPD_TYPE_EDO 0x02 #define SPD_TYPE_SDRAM 0x04 +#define SPD_MIN_SIZE_EDO 8 #define SPD_MIN_SIZE_SDRAM 8 -#define SPD_SDR_SIGNAL_LVTTL 0x01 +#define SPD_SIGNAL_LVTTL 0x01 -#define SPD_SDR_REFRESH_NORMAL 0x00 +#define SPD_REFRESH_NORMAL 0x00 #define SPD_SDR_REFRESH_SELF 0x80 #define SPD_SDR_BURST_PAGE 0x80 @@ -43,6 +47,24 @@ #define SPD_SDR_ATTR_VCC_HI_5 0x20 +typedef struct _spd_edo_ { + uint8_t bytes_used, spd_size, mem_type, + row_bits, col_bits, banks, + data_width_lsb, data_width_msb, + signal_level, trac, tcac, + config, refresh_rate, + dram_width, ecc_width, + reserved[47], + spd_rev, checksum, + mfg_jedec[8], mfg_loc; + char part_no[18]; + uint8_t rev_code[2], + mfg_year, mfg_week, serial[4], mfg_specific[27], + vendor_specific[2], + other_data[127], + checksum2; +} spd_edo_t; + typedef struct _spd_sdram_ { uint8_t bytes_used, spd_size, mem_type, row_bits, col_bits, rows, @@ -63,7 +85,8 @@ typedef struct _spd_sdram_ { uint8_t rev_code[2], mfg_year, mfg_week, serial[4], mfg_specific[27], freq, features, - other_data[128]; + other_data[127], + checksum2; } spd_sdram_t; diff --git a/src/spd.c b/src/spd.c index ed09c17f9..5b00c1178 100644 --- a/src/spd.c +++ b/src/spd.c @@ -8,7 +8,7 @@ * * Emulation of SPD (Serial Presence Detect) devices. * - * Version: @(#)spd.c 1.0.0 2020/03/24 + * * * Authors: RichardG, * @@ -27,9 +27,6 @@ #include <86box/spd.h> -#define SPD_MAX_SLOTS 8 -#define SPD_DATA_SIZE 256 - #define MIN(a, b) ((a) < (b) ? (a) : (b)) @@ -153,10 +150,16 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) { uint8_t slot, slot_count, vslot, next_empty_vslot, i, split; uint16_t min_module_size, total_size, vslots[SPD_MAX_SLOTS]; + spd_edo_t *edo_data; spd_sdram_t *sdram_data; /* determine the minimum module size for this RAM type */ switch (ram_type) { + case SPD_TYPE_FPM: + case SPD_TYPE_EDO: + min_module_size = SPD_MIN_SIZE_EDO; + break; + case SPD_TYPE_SDRAM: min_module_size = SPD_MIN_SIZE_SDRAM; break; @@ -192,8 +195,8 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) if (total_size > 0) /* did we populate everything? */ spd_log("SPD: not enough RAM slots (%d) to cover memory (%d MB short)\n", slot_count, total_size); - /* populate empty vslots by splitting modules while possible */ - split = 1; + /* populate empty vslots by splitting modules... */ + split = (total_size == 0); /* ...if possible */ while (split) { /* look for a module to split */ split = 0; @@ -229,7 +232,7 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) spd_log("SPD: registering slot %d = vslot %d = %d MB\n", slot, vslot, vslots[vslot]); - spd_devices[slot] = (device_t *)malloc(sizeof(device_t)); + spd_devices[slot] = (device_t *) malloc(sizeof(device_t)); memset(spd_devices[slot], 0, sizeof(device_t)); spd_devices[slot]->name = "Serial Presence Detect ROM"; spd_devices[slot]->local = slot; @@ -237,8 +240,41 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) spd_devices[slot]->close = spd_close; switch (ram_type) { + case SPD_TYPE_FPM: + case SPD_TYPE_EDO: + edo_data = (spd_edo_t *) &spd_data[slot]; + memset(edo_data, 0, sizeof(spd_edo_t)); + + /* FIXME: very little information about EDO SPD is available, + let alone software to interpret it correctly. */ + edo_data->bytes_used = 0x80; + edo_data->spd_size = 0x08; + edo_data->mem_type = ram_type; + edo_data->row_bits = 6 + log2_ui16(vslots[vslot]); + edo_data->col_bits = 9; + edo_data->banks = 2; + edo_data->data_width_lsb = 64; + edo_data->signal_level = SPD_SIGNAL_LVTTL; + edo_data->trac = 50; + edo_data->tcac = 13; + edo_data->refresh_rate = SPD_REFRESH_NORMAL; + edo_data->dram_width = 8; + + edo_data->spd_rev = 0x12; + sprintf(edo_data->part_no, "86Box-%s-%03dM", (ram_type == SPD_TYPE_FPM) ? "FPM" : "EDO", vslots[vslot]); + for (i = strlen(edo_data->part_no); i < sizeof(edo_data->part_no); i++) + edo_data->part_no[i] = ' '; + edo_data->mfg_year = 20; + edo_data->mfg_week = 17; + + for (i = 0; i < 63; i++) + edo_data->checksum += spd_data[slot][i]; + for (i = 0; i < 129; i++) + edo_data->checksum2 += spd_data[slot][i]; + break; + case SPD_TYPE_SDRAM: - sdram_data = (spd_sdram_t *)&spd_data[slot]; + sdram_data = (spd_sdram_t *) &spd_data[slot]; memset(sdram_data, 0, sizeof(spd_sdram_t)); sdram_data->bytes_used = 0x80; @@ -248,12 +284,10 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->col_bits = 9; sdram_data->rows = 2; sdram_data->data_width_lsb = 64; - sdram_data->data_width_msb = 0; - sdram_data->signal_level = SPD_SDR_SIGNAL_LVTTL; + sdram_data->signal_level = SPD_SIGNAL_LVTTL; sdram_data->tclk = 0x75; /* 7.5 ns = 133.3 MHz */ sdram_data->tac = 0x10; - sdram_data->config = 0; - sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_SDR_REFRESH_NORMAL; + sdram_data->refresh_rate = SPD_SDR_REFRESH_SELF | SPD_REFRESH_NORMAL; sdram_data->sdram_width = 8; sdram_data->tccd = 1; sdram_data->burst = SPD_SDR_BURST_PAGE | 1 | 2 | 4 | 8; @@ -267,17 +301,21 @@ spd_register(uint8_t ram_type, uint8_t slot_mask, uint16_t max_module_size) sdram_data->bank_density = 1 << (log2_ui16(vslots[vslot] >> 1) - 2); sdram_data->ca_setup = sdram_data->data_setup = 0x15; sdram_data->ca_hold = sdram_data->data_hold = 0x08; + sdram_data->spd_rev = 0x12; sprintf(sdram_data->part_no, "86Box-SDR-%03dM", vslots[vslot]); for (i = strlen(sdram_data->part_no); i < sizeof(sdram_data->part_no); i++) sdram_data->part_no[i] = ' '; - sdram_data->mfg_year = 0x20; - sdram_data->mfg_week = 0x13; + sdram_data->mfg_year = 20; + sdram_data->mfg_week = 13; + sdram_data->freq = 100; sdram_data->features = 0xFF; for (i = 0; i < 63; i++) sdram_data->checksum += spd_data[slot][i]; + for (i = 0; i < 129; i++) + sdram_data->checksum2 += spd_data[slot][i]; break; }