summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authoraf <none@none>2008-02-01 09:27:00 -0800
committeraf <none@none>2008-02-01 09:27:00 -0800
commit9d6aa6438f3d69f80eb7e494801a38cc7a8c0923 (patch)
treea2678633651dc8ebe2966b068c7afd0466793712 /usr
parentfb49a0d14105507530a42288b4a7bec770c7b016 (diff)
downloadillumos-gate-9d6aa6438f3d69f80eb7e494801a38cc7a8c0923.tar.gz
6647721 intel_nb5000 does not correct initialize on Scorpio
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/i86pc/io/intel_nb5000/dimm_addr.c3
-rw-r--r--usr/src/uts/i86pc/io/intel_nb5000/nb5000.h33
-rw-r--r--usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c109
3 files changed, 108 insertions, 37 deletions
diff --git a/usr/src/uts/i86pc/io/intel_nb5000/dimm_addr.c b/usr/src/uts/i86pc/io/intel_nb5000/dimm_addr.c
index abe0abce9c..e2e83c384c 100644
--- a/usr/src/uts/i86pc/io/intel_nb5000/dimm_addr.c
+++ b/usr/src/uts/i86pc/io/intel_nb5000/dimm_addr.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -34,6 +34,7 @@
#include <sys/fm/protocol.h>
#include <sys/cmn_err.h>
#include <sys/sunddi.h>
+#include <sys/mc_intel.h>
#include "dimm_addr.h"
#include "nb_log.h"
#include "rank.h"
diff --git a/usr/src/uts/i86pc/io/intel_nb5000/nb5000.h b/usr/src/uts/i86pc/io/intel_nb5000/nb5000.h
index 0749980602..459e8ed509 100644
--- a/usr/src/uts/i86pc/io/intel_nb5000/nb5000.h
+++ b/usr/src/uts/i86pc/io/intel_nb5000/nb5000.h
@@ -36,6 +36,7 @@ extern "C" {
#include <sys/cpu_module.h>
#define NB_5000_MAX_MEM_CONTROLLERS 2
+#define NB_MAX_DIMMS_PER_CHANNEL (nb_chipset == INTEL_NB_7300 ? 8 : 4)
#define NB_MEM_BRANCH_SELECT 3
#define NB_MAX_MEM_BRANCH_SELECT 3
#define NB_MEM_RANK_SELECT (nb_chipset == INTEL_NB_7300 ? 7 : 5)
@@ -684,33 +685,33 @@ extern "C" {
(nb_number_memory_controllers == 2) ? \
nb_pci_getl(0, 22, 0, 0x90 + ((reg)*4), 0) : 0
-#define SPCPC_RD(branch) (nb_dimms_per_channel <= 4 ? \
+#define SPCPC_RD(branch) (nb_chipset != INTEL_NB_7300 ? \
(((branch) == 0) ? \
(uint32_t)nb_pci_getb(0, 21, 0, 0x40, 0) : \
(nb_number_memory_controllers == 2) ? \
(uint32_t)nb_pci_getb(0, 22, 0, 0x40, 0) : 0) : \
nb_pci_getl(0, ((branch) == 0) ? 21 : 22, 0, 0x40, 0))
-#define SPCPC_SPARE_ENABLE (nb_dimms_per_channel <= 4 ? 1 : 0x20)
-#define SPCPC_SPRANK(spcpc) (nb_dimms_per_channel <= 4 ? \
+#define SPCPC_SPARE_ENABLE (nb_chipset != INTEL_NB_7300 ? 1 : 0x20)
+#define SPCPC_SPRANK(spcpc) (nb_chipset != INTEL_NB_7300 ? \
(((spcpc) >> 1) & 7) : ((spcpc) & 0xf))
#define SPCPS_RD(branch) ((branch) == 0) ? \
- nb_pci_getb(0, 21, 0, nb_dimms_per_channel <= 4 ? 0x41 : 0x43, 0) : \
+ nb_pci_getb(0, 21, 0, nb_chipset != INTEL_NB_7300 ? 0x41 : 0x43, 0) : \
(nb_number_memory_controllers == 2) ? \
- nb_pci_getb(0, 22, 0, nb_dimms_per_channel <= 4 ? 0x41 : 0x43, 0) : 0
+ nb_pci_getb(0, 22, 0, nb_chipset != INTEL_NB_7300 ? 0x41 : 0x43, 0) : 0
#define SPCPS_WR(branch) \
if ((branch) == 0) { \
- nb_pci_putb(0, 21, 0, nb_dimms_per_channel <= 4 ? 0x41 : 0x43, \
- 0); \
+ nb_pci_putb(0, 21, 0, nb_chipset != INTEL_NB_7300 ? 0x41 : \
+ 0x43, 0); \
} else if (nb_number_memory_controllers == 2) { \
- nb_pci_putb(0, 22, 0, nb_dimms_per_channel <= 4 ? 0x41 : 0x43, \
- 0); \
+ nb_pci_putb(0, 22, 0, nb_chipset != INTEL_NB_7300 ? 0x41 : \
+ 0x43, 0); \
}
-#define SPCPS_SPARE_DEPLOYED (nb_dimms_per_channel <= 4 ? 0x11 : 0x60)
-#define SPCPS_FAILED_RANK(spcps) (nb_dimms_per_channel <= 4 ? \
+#define SPCPS_SPARE_DEPLOYED (nb_chipset != INTEL_NB_7300 ? 0x11 : 0x60)
+#define SPCPS_FAILED_RANK(spcps) (nb_chipset != INTEL_NB_7300 ? \
(((spcps) >> 1) & 7) : ((spcps) & 0xf))
#define UERRCNT_RD(branch) ((branch) == 0) ? \
@@ -819,13 +820,13 @@ extern "C" {
#define PCISTS_WR(val) nb_pci_putw(0, 8, 0, 0x6, val)
#define PCIDEVSTS_WR(val) nb_pci_putw(0, 8, 0, 0x76, val)
-#define RANK_MASK (nb_dimms_per_channel <= 4 ? 7 : 0xf)
-#define CAS_MASK (nb_dimms_per_channel <= 4 ? 0xfff : 0x1fff)
-#define RAS_MASK (nb_dimms_per_channel <= 4 ? 0x7fff : 0xffff)
+#define RANK_MASK (nb_chipset != INTEL_NB_7300 ? 7 : 0xf)
+#define CAS_MASK (nb_chipset != INTEL_NB_7300 ? 0xfff : 0x1fff)
+#define RAS_MASK (nb_chipset != INTEL_NB_7300 ? 0x7fff : 0xffff)
#define BANK_MASK 7
-#define DMIR_RANKS(dimms_per_channel, dmir, rank0, rank1, rank2, rank3) \
- if ((dimms_per_channel) <= 4) { \
+#define DMIR_RANKS(dmir, rank0, rank1, rank2, rank3) \
+ if (nb_chipset != INTEL_NB_7300) { \
rank0 = (dmir) & 3; \
rank1 = ((dmir) >> 3) & 3; \
rank2 = ((dmir) >> 6) & 3; \
diff --git a/usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c b/usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c
index 19812b5b49..68f071aaa0 100644
--- a/usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c
+++ b/usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c
@@ -124,6 +124,23 @@ uint32_t nb5000_docmd_pex = DOCMD_PEX;
int nb_mask_mc_set;
+typedef struct find_dimm_label {
+ void (*label_function)(int, char *, int);
+} find_dimm_label_t;
+
+static void x8450_dimm_label(int, char *, int);
+
+static struct platform_label {
+ const char *sys_vendor; /* SMB_TYPE_SYSTEM vendor prefix */
+ const char *sys_product; /* SMB_TYPE_SYSTEM product prefix */
+ find_dimm_label_t dimm_label;
+ int dimms_per_channel;
+} platform_label[] = {
+ { "SUN MICROSYSTEMS", "SUN BLADE X8450 SERVER MODULE",
+ x8450_dimm_label, 8 },
+ { NULL, NULL, NULL, 0 }
+};
+
static unsigned short
read_spd(int bus)
{
@@ -241,12 +258,15 @@ nb_dimm_init(int channel, int dimm, uint16_t mtr)
int i, t;
int spd_sz;
+ if (MTR_PRESENT(mtr) == 0)
+ return (NULL);
t = read_spd_eeprom(channel, dimm, 2) & 0xf;
if (t != 9)
return (NULL);
dp = kmem_zalloc(sizeof (nb_dimm_t), KM_SLEEP);
+
t = read_spd_eeprom(channel, dimm, 0) & 0xf;
if (t == 1)
spd_sz = 128;
@@ -355,8 +375,7 @@ nb_mc_init()
branch_interleave = 0;
hole_base = 0;
hole_size = 0;
- DMIR_RANKS(nb_dimms_per_channel, dmir, rank0, rank1,
- rank2, rank3);
+ DMIR_RANKS(dmir, rank0, rank1, rank2, rank3);
if (rank0 == rank1)
interleave = 1;
else if (rank0 == rank2)
@@ -453,22 +472,45 @@ memoryarray(smbios_hdl_t *shp, const smbios_struct_t *sp, void *arg)
return (0);
}
-void
+find_dimm_label_t *
find_dimms_per_channel()
{
- if (nb_dimms_per_channel == 0) {
- if (ksmbios != NULL) {
+ struct platform_label *pl;
+ smbios_info_t si;
+ smbios_system_t sy;
+ id_t id;
+ int read_memarray = 1;
+ find_dimm_label_t *rt = NULL;
+
+ if (ksmbios != NULL) {
+ if ((id = smbios_info_system(ksmbios, &sy)) != SMB_ERR &&
+ smbios_info_common(ksmbios, id, &si) != SMB_ERR) {
+ for (pl = platform_label; pl->sys_vendor; pl++) {
+ if (strncmp(pl->sys_vendor,
+ si.smbi_manufacturer,
+ strlen(pl->sys_vendor)) == 0 &&
+ strncmp(pl->sys_product, si.smbi_product,
+ strlen(pl->sys_product)) == 0) {
+ nb_dimms_per_channel =
+ pl->dimms_per_channel;
+ read_memarray = 0;
+ rt = &pl->dimm_label;
+ break;
+ }
+ }
+ }
+ if (read_memarray)
(void) smbios_iter(ksmbios, memoryarray, 0);
+ }
+ if (nb_dimms_per_channel == 0) {
+ if (ndimms) {
nb_dimms_per_channel = ndimms /
(nb_number_memory_controllers * 2);
- }
- if (nb_dimms_per_channel == 0) {
- if (nb_chipset == INTEL_NB_7300)
- nb_dimms_per_channel = 8;
- else
- nb_dimms_per_channel = 4;
+ } else {
+ nb_dimms_per_channel = NB_MAX_DIMMS_PER_CHANNEL;
}
}
+ return (rt);
}
static int
@@ -502,9 +544,18 @@ nb_smbios()
}
static void
-nb_dimms_init()
+x8450_dimm_label(int dimm, char *label, int label_sz)
{
- int i, j, k;
+ int channel = dimm >> 3;
+
+ dimm = dimm & 0x7;
+ (void) snprintf(label, label_sz, "D%d", (dimm * 4) + channel);
+}
+
+static void
+nb_dimms_init(find_dimm_label_t *label_function)
+{
+ int i, j, k, l;
uint16_t mtr;
uint32_t mc, mca;
uint32_t spcpc;
@@ -540,15 +591,30 @@ nb_dimms_init()
dimm_add_geometry(i, j, dimmpp[j]->nbanks,
dimmpp[j]->width, dimmpp[j]->ncolumn,
dimmpp[j]->nrow);
+ if (label_function) {
+ label_function->label_function(
+ (k * nb_dimms_per_channel) + j,
+ dimmpp[j]->label,
+ sizeof (dimmpp[j]->label));
+ }
}
dimmpp[j + nb_dimms_per_channel] =
nb_dimm_init(k + 1, j, mtr);
- if (dimmpp[j + nb_dimms_per_channel])
+ l = j + nb_dimms_per_channel;
+ if (dimmpp[l]) {
+ if (label_function) {
+ label_function->label_function(
+ (k * nb_dimms_per_channel) + l,
+ dimmpp[l]->label,
+ sizeof (dimmpp[l]->label));
+ }
nb_ndimm ++;
+ }
}
dimmpp += nb_dimms_per_channel * 2;
}
- nb_smbios();
+ if (label_function == NULL)
+ nb_smbios();
}
static void
@@ -959,7 +1025,9 @@ nb_mask_mc_reset()
int
nb_dev_init()
{
- find_dimms_per_channel();
+ find_dimm_label_t *label_function_p;
+
+ label_function_p = find_dimms_per_channel();
mutex_init(&nb_mutex, NULL, MUTEX_DRIVER, NULL);
nb_queue = errorq_create("nb_queue", nb_drain, NULL, NB_MAX_ERRORS,
sizeof (nb_logout_t), 1, ERRORQ_VITAL);
@@ -967,11 +1035,11 @@ nb_dev_init()
mutex_destroy(&nb_mutex);
return (EAGAIN);
}
+ nb_int_init();
dimm_init();
- nb_dimms_init();
+ nb_dimms_init(label_function_p);
nb_mc_init();
nb_pex_init();
- nb_int_init();
nb_fbd_init();
nb_fsb_init();
nb_scrubber_enable();
@@ -1009,14 +1077,15 @@ nb_dev_reinit()
nb_dimm_t *dimmp;
nb_dimm_t **old_nb_dimms;
int old_nb_dimms_per_channel;
+ find_dimm_label_t *label_function_p;
old_nb_dimms = nb_dimms;
old_nb_dimms_per_channel = nb_dimms_per_channel;
dimm_fini();
- find_dimms_per_channel();
+ label_function_p = find_dimms_per_channel();
dimm_init();
- nb_dimms_init();
+ nb_dimms_init(label_function_p);
nb_mc_init();
nb_pex_init();
nb_int_init();