diff options
author | af <none@none> | 2008-02-01 09:27:00 -0800 |
---|---|---|
committer | af <none@none> | 2008-02-01 09:27:00 -0800 |
commit | 9d6aa6438f3d69f80eb7e494801a38cc7a8c0923 (patch) | |
tree | a2678633651dc8ebe2966b068c7afd0466793712 /usr | |
parent | fb49a0d14105507530a42288b4a7bec770c7b016 (diff) | |
download | illumos-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.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/intel_nb5000/nb5000.h | 33 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/intel_nb5000/nb5000_init.c | 109 |
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(); |