Get Vendor Name from spd, 3 cases handled DDR3, DDR4 and DDR2, have different formats, always return a valid ptr.
| 325 | // Get Vendor Name from spd, 3 cases handled DDR3, DDR4 and DDR2, |
| 326 | // have different formats, always return a valid ptr. |
| 327 | CONST CHAR8* getVendorName(RAM_SLOT_INFO* slot, UINT8 *spd, UINT32 base, UINT8 slot_num) |
| 328 | { |
| 329 | UINT8 bank = 0; |
| 330 | UINT8 code = 0; |
| 331 | UINT8 parity; |
| 332 | UINT8 testbit; |
| 333 | //UINT8 * spd = (UINT8 *) slot->spd; |
| 334 | if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR4) { // DDR4 |
| 335 | bank = spd[SPD_DDR4_MANUFACTURER_ID_BANK]; |
| 336 | code = spd[SPD_DDR4_MANUFACTURER_ID_CODE]; |
| 337 | parity = bank; |
| 338 | testbit = bank; |
| 339 | for (INTN i=6; i >= 0; i--) { parity ^= (testbit <<= 1); } |
| 340 | if ( (parity & 0x80) == 0 ) { |
| 341 | DBG("Bad parity bank=0x%2hhX code=0x%2hhX\n", bank, code); |
| 342 | } |
| 343 | bank &= 0x7f; |
| 344 | for (UINTN i=0; i < VEN_MAP_SIZE; i++) { |
| 345 | if (bank==vendorMap[i].bank && code==vendorMap[i].code) { |
| 346 | return vendorMap[i].name; |
| 347 | } |
| 348 | } |
| 349 | DBG("Unknown vendor bank=0x%2hhX code=0x%2hhX\n", bank, code); |
| 350 | } else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR3) { // DDR3 |
| 351 | bank = spd[SPD_DDR3_MEMORY_BANK]; // constructors like Patriot use b7=1 |
| 352 | code = spd[SPD_DDR3_MEMORY_CODE]; |
| 353 | parity = bank; |
| 354 | testbit = bank; |
| 355 | for (INTN i=6; i >= 0; i--) { parity ^= (testbit <<= 1); } |
| 356 | if ( (parity & 0x80) == 0 ) { |
| 357 | DBG("Bad parity bank=0x%2hhX code=0x%2hhX\n", bank, code); |
| 358 | } |
| 359 | bank &= 0x7f; |
| 360 | |
| 361 | for (UINTN i=0; i < VEN_MAP_SIZE; i++) { |
| 362 | if (bank==vendorMap[i].bank && code==vendorMap[i].code) { |
| 363 | return vendorMap[i].name; |
| 364 | } |
| 365 | } |
| 366 | } else if (spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR2 || |
| 367 | spd[SPD_MEMORY_TYPE]==SPD_MEMORY_TYPE_SDRAM_DDR) { |
| 368 | if(spd[64]==0x7f) { |
| 369 | UINTN i; |
| 370 | for (i=64; i<72 && spd[i]==0x7f;i++) { |
| 371 | bank++; |
| 372 | READ_SPD(spd, base, slot_num, (UINT8)(i+1)); // prefetch next spd byte to read for next loop |
| 373 | } |
| 374 | READ_SPD(spd, base, slot_num, (UINT8)i); |
| 375 | code = spd[i]; |
| 376 | } else { |
| 377 | code = spd[64]; |
| 378 | bank = 0; |
| 379 | } |
| 380 | for (UINTN i=0; i < VEN_MAP_SIZE; i++) { |
| 381 | if (bank==vendorMap[i].bank && code==vendorMap[i].code) { |
| 382 | return vendorMap[i].name; |
| 383 | } |
| 384 | } |