summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIru Cai <mytbk920423@gmail.com>2019-06-13 11:16:28 +0800
committerIru Cai <mytbk920423@gmail.com>2019-11-17 15:10:46 +0800
commit1ba23c53e93beb3c62b0b46c9c5fd6c56338aa3e (patch)
treebc33bcb6fcd4cae5bf3ae4620761eddf41ecdc86
parentd27fd32dd221b45da2c64d13a0faacf93365fdbe (diff)
downloadcoreboot-1ba23c53e93beb3c62b0b46c9c5fd6c56338aa3e.tar.xz
move frag_fffa1e83 to mrc_misc.c, comment some known fields
-rw-r--r--src/northbridge/intel/haswell/mrc_frags.c286
-rw-r--r--src/northbridge/intel/haswell/mrc_misc.c306
2 files changed, 303 insertions, 289 deletions
diff --git a/src/northbridge/intel/haswell/mrc_frags.c b/src/northbridge/intel/haswell/mrc_frags.c
index 9035a0606c..e3fb5ff86c 100644
--- a/src/northbridge/intel/haswell/mrc_frags.c
+++ b/src/northbridge/intel/haswell/mrc_frags.c
@@ -20,292 +20,6 @@ void frag_fffa0ff3(void)
pci_write_config32(PCI_DEV(0, 2, 0), 0x14, 0);
}
-static inline u8 shupd(u8 a, u8 b, int sh)
-{
- a &= (0xff - (1 << sh));
- a |= ((b & 1) << sh);
- return a;
-}
-
-void frag_fffa1e83(void *ebx, void *esi, void *edi);
-void frag_fffa1e83(void *ebx, void *esi, void *edi)
-{
-#ifndef T8
-#undef T8
-#endif
-#define T8(d,s) do { *(u8*)(ebx + d) = *(u8*)(esi + s); } while (0);
-#define SW16(d, s) do { T8(d + 1, s); T8(d, s + 1); } while (0);
-
- u8 tmp;
- uint8_t v = *(u8*)edi;
-
- *(u32*)(ebx + 0x8b) = *(u32*)(esi + 0x4e);
- *(u16*)(ebx + 0x8f) = 0x3e8;
- *(u8*)(ebx + 0x54) = 0;
- T8(0x57, 0x2e);
- T8(0x6d8, 0x2f); T8(0x6d9, 0x30); T8(0x6da, 0x31);
- T8(0x6db, 0x6b);
-
- tmp = *(u8*)(ebx + 0x6dc);
- for (int i = 0; i < 8; i++) {
- tmp = shupd(tmp, *(u8*)(esi + 0x32 + i), i);
- }
- *(u8*)(ebx + 0x6dc) = tmp;
-
- tmp = *(u8*)(ebx + 0x6dd);
- for (int i = 0; i < 8; i++) {
- if (i == 3) continue;
- tmp = shupd(tmp, *(u8*)(esi + 0x3a + i), i);
- }
- *(u8*)(ebx + 0x6dd) = tmp;
-
- tmp = *(u8*)(ebx + 0x6de);
- tmp = shupd(tmp, *(u8*)(esi + 0x42), 0);
- tmp = shupd(tmp, *(u8*)(esi + 0x43), 2);
- tmp = shupd(tmp, *(u8*)(esi + 0x44), 3);
- tmp = shupd(tmp, *(u8*)(esi + 0x47), 6);
- tmp = shupd(tmp, *(u8*)(esi + 0x48), 7);
- *(u8*)(ebx + 0x6de) = tmp;
-
- tmp = *(u8*)(ebx + 0x6df);
- tmp = shupd(tmp, *(u8*)(esi + 0x49), 0);
- tmp = shupd(tmp, *(u8*)(esi + 0x4a), 1);
- tmp = shupd(tmp, *(u8*)(esi + 0x4b), 2);
-
- if (v > 1) {
- tmp = shupd(tmp, *(u8*)(esi + 0x58), 3);
- tmp = shupd(tmp, *(u8*)(esi + 0x59), 4);
- tmp = shupd(tmp, *(u8*)(esi + 0x5a), 5);
- } else {
- tmp = (tmp & 0xe7) | 0x20;
- }
- *(u8*)(ebx + 0x6df) = tmp;
-
- tmp = *(u8*)(ebx + 0x6de);
- if (v > 3) {
- tmp = shupd(tmp, *(u8*)(esi + 0x5c), 1);
- *(u8*)(ebx + 0x6de) = tmp;
-
- for (int i = 0; i < 7; i++) {
- T8(0x91 + i, 0x5d + i);
- }
- } else {
- *(u8*)(ebx + 0x6de) = tmp | 2;
- *(u8*)(ebx + 0x91) = 0xff;
- *(u8*)(ebx + 0x92) = 0x40;
- *(u8*)(ebx + 0x93) = 1;
- *(u8*)(ebx + 0x94) = 1;
- *(u8*)(ebx + 0x95) = 0;
- *(u8*)(ebx + 0x96) = 7;
- *(u8*)(ebx + 0x97) = 0;
- }
-
- if (v > 4) {
- u32 v64 = *(u32*)(esi + 0x64);
- if (v64 > 89999999) {
- *(u32*)(ebx + 0x21) = (v64 / 1000000) * 1000000;
- } else {
- *(u32*)(ebx + 0x21) = 100000000;
- }
- } else {
- *(u32*)(ebx + 0x21) = 100000000;
- }
-
- tmp = *(u8*)(ebx + 0x6df);
- if (v > 5) {
- tmp = shupd(tmp, *(u8*)(esi + 0x6a), 6);
- } else {
- tmp |= 0x40;
- }
- *(u8*)(ebx + 0x6df) = tmp;
-
- if (v > 8) {
- void *p1 = *(void**)(edi + 1);
- *(u32*)(ebx + 0x83) = (*(u32*)(p1 + 0x2b)) >> 0x14;
- T8(0x98, 0x6c); T8(0x99, 0x6d);
- *(u16*)(ebx + 0x9a) = *(u16*)(esi + 0x6e);
- T8(0x9c, 0x70);
- } else {
- *(u32*)(ebx + 0x83) = 4;
- *(u8*)(ebx + 0x98) = 0;
- *(u8*)(ebx + 0x99) = 1;
- *(u16*)(ebx + 0x9a) = 0x30ce;
- *(u8*)(ebx + 0x9c) = 1;
- }
-
- if (v > 9) {
- for (int i = 0; i < 4; i++) {
- T8(0x9d + i, 0x71 + i);
- }
- int is_ult = (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT);
- if (is_ult) {
- T8(0xa1, 0x75);
- }
- for (int i = 0; i < 5; i++) {
- T8(0xa2 + i, 0x76 + i);
- }
- T8(0xa8, 0x7b); T8(0xa7, 0x7c);
- for (int i = 0; i < 5; i++) {
- T8(0xa9 + i, 0x7d + i);
- }
- for (int i = 0; i < 4; i++) {
- T8(0xaf + i, 0x83 + i);
- }
- for (int i = 0; i < 16; i++) {
- T8(0xb4 + i, 0x88 + i);
- }
- /* 0xc4, 0xc5, ..., 0xd6, 0xd7 */
- for (int i = 0; i < 5; i++) {
- SW16(0xc4 + i * 4, 0x98 + i * 2);
- SW16(0xc6 + i * 4, 0xa2 + i * 2);
- }
- T8(0xd8, 0xac); T8(0xd9, 0xad);
- T8(0xdb, 0xaf); T8(0xdc, 0xb0);
- if (is_ult) {
- T8(0xdd, 0xb1); T8(0xde, 0xb2);
- }
- } else {
- int is_ult = (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT);
- *(u8*)(ebx + 0x9d) = 0;
- *(u8*)(ebx + 0x9e) = 0;
- *(u8*)(ebx + 0x9f) = 0;
- *(u8*)(ebx + 0xa0) = 1;
- if (is_ult) {
- *(u8*)(ebx + 0xa1) = 0;
- }
- *(u8*)(ebx + 0xa2) = 0;
- *(u8*)(ebx + 0xa3) = 1;
- *(u8*)(ebx + 0xa4) = 0;
- *(u8*)(ebx + 0xa6) = 3;
- for (int i = 0; i < 5; i++) {
- *(u8*)(ebx + 0xa9) = 0;
- }
- for (int i = 0; i < 4; i++) {
- *(u8*)(ebx + 0xaf) = 0;
- }
- for (int i = 0; i < 2; i++) {
- u8 *b1 = ebx + i * 2;
- *(u8*)(ebx + i + 0xa7) = 0;
- for (int j = 0; j < 4; j++) {
- *(u8*)(b1 + 0xb4 + j * 4) = 0xff;
- }
- for (int j = 0; j < 5; j++) {
- *(u8*)(b1 + 0xc4 + j * 4) = 0;
- }
- for (int j = 0; j < 4; j++) {
- *(u8*)(b1 + 0xb5 + j * 4) = 0xff;
- }
- for (int j = 0; j < 5; j++) {
- *(u8*)(b1 + 0xc5 + j * 4) = 0;
- }
- }
- *(u8*)(ebx + 0xd8) = 1;
- *(u16*)(ebx + 0xd9) = 0x200;
- *(u8*)(ebx + 0xdb) = 0;
- *(u8*)(ebx + 0xdc) = 0x30;
- if (is_ult) {
- *(u8*)(ebx + 0xdd) = 1;
- *(u8*)(ebx + 0xde) = 0x40;
- }
- }
-
- if (v > 10) {
- T8(0x59, 0xc2); T8(0x5a, 0xc3); T8(0x6e5, 0xc4);
- } else {
- *(u8*)(ebx + 0x59) = 1;
- *(u8*)(ebx + 0x5a) = 1;
- *(u8*)(ebx + 0x6e5) = 0;
- }
-
- tmp = *(u8*)(ebx + 0x6dd);
- if (v > 11) {
- tmp = shupd(tmp, *(u8*)(esi + 0xc5), 3);
- } else {
- tmp |= 8;
- }
- *(u8*)(ebx + 0x6dd) = tmp;
-
- tmp = *(u8*)(ebx + 0x6de);
- if (v > 0xe) {
- tmp = shupd(tmp, *(u8*)(esi + 0xc7), 4);
- } else {
- tmp = shupd(tmp, 1, 4);
- }
- *(u8*)(ebx + 0x6de) = tmp;
-
- *(u32*)(ebx + 0x41) = 0;
- *(u8*)(ebx + 0x40) = 0;
- T8(0x56, 0x11);
- T8(0x58, 0x2c);
- T8(0x53, 0);
- T8(0x6e1, 0x52);
-
- if (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT) {
- *(u8*)(ebx + 0x6e3) = 0;
- T8(0x6e2, 0x57);
- }
-
- void *ptr0 = ebx + 0xdf;
- *(u8*)(ebx + 0xe3) = 0;
- for (int i = 0; i < 2; i++) {
- void *ptr1 = ptr0 + i * 0x2fa;
- void *ptr2 = ptr1 + 5;
- tmp = *(u8*)(esi + i + 0x2a);
- if (tmp == 2) {
- *(u32*)(ptr2 + 8) = 0;
- *(u32*)(ptr2 + 0x157) = 1;
- *(u32*)(ptr1 + 5) = 2;
- (*(u8*)(ptr0 + 4))++;
- *(u32*)(ptr2 + 4) = 1;
- } else if (tmp == 3) {
- *(u32*)(ptr2 + 8) = 1;
- *(u32*)(ptr2 + 0x157) = 1;
- *(u32*)(ptr1 + 5) = 1;
- *(u32*)(ptr2 + 4) = 0;
- } else if (tmp != 1) {
- *(u32*)(ptr2 + 8) = 0;
- *(u32*)(ptr2 + 0x157) = 0;
- *(u32*)(ptr1 + 5) = 2;
- (*(u8*)(ptr0 + 4))++;
- *(u32*)(ptr2 + 4) = 2;
- } else { /* tmp == 1 */
- *(u32*)(ptr2 + 8) = 1;
- *(u32*)(ptr2 + 0x157) = 0;
- *(u32*)(ptr1 + 5) = 2;
- (*(u8*)(ptr0 + 4))++;
- *(u32*)(ptr2 + 4) = 1;
- }
- }
-
- u8 *p1 = *(u8**)(edi + 1);
- *(u8*)(ebx + 0x23a) = p1[0];
- *(u8*)(ebx + 0x389) = p1[1];
- *(u8*)(ebx + 0x534) = p1[2];
- *(u8*)(ebx + 0x683) = p1[3];
-}
-
-void copy_spd(void *ebx);
-void copy_spd(void *ebx)
-{
- MRC_PEI *pei = PEI_FROM_PEI_SERVICE(**gpPei);
- struct pei_data *pd = pei->pei_data;
-
- for (int i = 0; i < 2; i++) {
- int idxi = i * 0x2fa;
- for (int j = 0; j < 2; j++) {
- void *edx = ebx + (idxi + j * 0x14f + 0xd0);
- void *ptr = edx + 0x1c;
- if (*(u8*)(edx + 0x16a) == 0xff &&
- *(u32*)(edx + 0x1c) == 0) {
- printk(BIOS_DEBUG, "Copy SPD for Channel %d Dimm %d\n", i, j);
- /* FIXME: looks like mrc.bin only copies channel 0 slot 0??? */
- mrc_memcpy(edx + 0x40, pd->spd_data, 0x100);
- *(u8*)(ptr + 0x14e) = 0;
- }
- }
- }
-}
-
void frag_fffa5d3c(void *bar, uint32_t offset);
void frag_fffa5d3c(void *bar, uint32_t offset)
{
diff --git a/src/northbridge/intel/haswell/mrc_misc.c b/src/northbridge/intel/haswell/mrc_misc.c
index 3f61261255..c93bda0bf5 100644
--- a/src/northbridge/intel/haswell/mrc_misc.c
+++ b/src/northbridge/intel/haswell/mrc_misc.c
@@ -1,5 +1,6 @@
#include <southbridge/intel/lynxpoint/pch.h>
#include <device/pci_ops.h>
+#include <cpu/intel/haswell/haswell.h>
#include "mrc_sku.h"
#include "mrc_misc.h"
#include "mrc_utils.h"
@@ -443,8 +444,299 @@ void __attribute((regparm(3))) fcn_fffc8290(void *, void *, void *,
void *, void *, void *);
void __attribute((regparm(2))) fcn_fffa91af(u32, void *);
void __attribute((regparm(2))) fcn_fffa0020(void *, void *);
-void frag_fffa1e83(void *ebx, void *esi, void *edi);
-void copy_spd(void *ebx);
+
+static inline u8 shupd(u8 a, u8 b, int sh)
+{
+ a &= (0xff - (1 << sh));
+ a |= ((b & 1) << sh);
+ return a;
+}
+
+static void frag_fffa1e83(void *ebx, void *esi, pei_raminit_ppi *ppi)
+{
+#ifndef T8
+#undef T8
+#endif
+#define T8(d,s) do { *(u8*)(ebx + d) = *(u8*)(esi + s); } while (0);
+#define SW16(d, s) do { T8(d + 1, s); T8(d, s + 1); } while (0);
+
+ u8 tmp;
+ uint8_t v = ppi->v;
+
+ *(u32*)(ebx + 0x8b) = *(u32*)(esi + 0x4e);
+ *(u16*)(ebx + 0x8f) = 0x3e8;
+ *(u8*)(ebx + 0x54) = 0;
+ T8(0x57, 0x2e);
+ T8(0x6d8, 0x2f); T8(0x6d9, 0x30); T8(0x6da, 0x31);
+ T8(0x6db, 0x6b);
+
+ tmp = *(u8*)(ebx + 0x6dc);
+ for (int i = 0; i < 8; i++) {
+ tmp = shupd(tmp, *(u8*)(esi + 0x32 + i), i);
+ }
+ *(u8*)(ebx + 0x6dc) = tmp;
+
+ tmp = *(u8*)(ebx + 0x6dd);
+ for (int i = 0; i < 8; i++) {
+ if (i == 3) continue;
+ tmp = shupd(tmp, *(u8*)(esi + 0x3a + i), i);
+ }
+ *(u8*)(ebx + 0x6dd) = tmp;
+
+ tmp = *(u8*)(ebx + 0x6de);
+ tmp = shupd(tmp, *(u8*)(esi + 0x42), 0);
+ tmp = shupd(tmp, *(u8*)(esi + 0x43), 2);
+ tmp = shupd(tmp, *(u8*)(esi + 0x44), 3);
+ tmp = shupd(tmp, *(u8*)(esi + 0x47), 6);
+ tmp = shupd(tmp, *(u8*)(esi + 0x48), 7);
+ *(u8*)(ebx + 0x6de) = tmp;
+
+ tmp = *(u8*)(ebx + 0x6df);
+ tmp = shupd(tmp, *(u8*)(esi + 0x49), 0);
+ tmp = shupd(tmp, *(u8*)(esi + 0x4a), 1);
+ tmp = shupd(tmp, *(u8*)(esi + 0x4b), 2);
+
+ if (v > 1) {
+ tmp = shupd(tmp, *(u8*)(esi + 0x58), 3);
+ tmp = shupd(tmp, *(u8*)(esi + 0x59), 4);
+ tmp = shupd(tmp, *(u8*)(esi + 0x5a), 5);
+ } else {
+ tmp = (tmp & 0xe7) | 0x20;
+ }
+ *(u8*)(ebx + 0x6df) = tmp;
+
+ tmp = *(u8*)(ebx + 0x6de);
+ if (v > 3) {
+ tmp = shupd(tmp, *(u8*)(esi + 0x5c), 1);
+ *(u8*)(ebx + 0x6de) = tmp;
+
+ for (int i = 0; i < 7; i++) {
+ T8(0x91 + i, 0x5d + i);
+ }
+ } else {
+ *(u8*)(ebx + 0x6de) = tmp | 2;
+ *(u8*)(ebx + 0x91) = 0xff;
+ *(u8*)(ebx + 0x92) = 0x40;
+ *(u8*)(ebx + 0x93) = 1;
+ *(u8*)(ebx + 0x94) = 1;
+ *(u8*)(ebx + 0x95) = 0;
+ *(u8*)(ebx + 0x96) = 7;
+ *(u8*)(ebx + 0x97) = 0;
+ }
+
+ if (v > 4) {
+ u32 v64 = *(u32*)(esi + 0x64);
+ if (v64 > 89999999) {
+ *(u32*)(ebx + 0x21) = (v64 / 1000000) * 1000000;
+ } else {
+ *(u32*)(ebx + 0x21) = 100000000;
+ }
+ } else {
+ *(u32*)(ebx + 0x21) = 100000000;
+ }
+
+ tmp = *(u8*)(ebx + 0x6df);
+ if (v > 5) {
+ tmp = shupd(tmp, *(u8*)(esi + 0x6a), 6);
+ } else {
+ tmp |= 0x40;
+ }
+ *(u8*)(ebx + 0x6df) = tmp;
+
+ if (v > 8) {
+ *(u32*)(ebx + 0x83) = ppi->ram_data->ied_region_size >> 0x14;
+ T8(0x98, 0x6c); T8(0x99, 0x6d);
+ *(u16*)(ebx + 0x9a) = *(u16*)(esi + 0x6e);
+ T8(0x9c, 0x70);
+ } else {
+ *(u32*)(ebx + 0x83) = 4;
+ *(u8*)(ebx + 0x98) = 0;
+ *(u8*)(ebx + 0x99) = 1;
+ *(u16*)(ebx + 0x9a) = 0x30ce;
+ *(u8*)(ebx + 0x9c) = 1;
+ }
+
+ if (v > 9) {
+ for (int i = 0; i < 4; i++) {
+ T8(0x9d + i, 0x71 + i);
+ }
+ int is_ult = (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT);
+ if (is_ult) {
+ T8(0xa1, 0x75);
+ }
+ for (int i = 0; i < 5; i++) {
+ T8(0xa2 + i, 0x76 + i);
+ }
+ T8(0xa8, 0x7b); T8(0xa7, 0x7c);
+ for (int i = 0; i < 5; i++) {
+ T8(0xa9 + i, 0x7d + i);
+ }
+ for (int i = 0; i < 4; i++) {
+ T8(0xaf + i, 0x83 + i);
+ }
+ for (int i = 0; i < 16; i++) {
+ T8(0xb4 + i, 0x88 + i);
+ }
+ /* 0xc4, 0xc5, ..., 0xd6, 0xd7 */
+ for (int i = 0; i < 5; i++) {
+ SW16(0xc4 + i * 4, 0x98 + i * 2);
+ SW16(0xc6 + i * 4, 0xa2 + i * 2);
+ }
+ T8(0xd8, 0xac); T8(0xd9, 0xad);
+ T8(0xdb, 0xaf); T8(0xdc, 0xb0);
+ if (is_ult) {
+ T8(0xdd, 0xb1); T8(0xde, 0xb2);
+ }
+ } else {
+ int is_ult = (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT);
+ *(u8*)(ebx + 0x9d) = 0;
+ *(u8*)(ebx + 0x9e) = 0;
+ *(u8*)(ebx + 0x9f) = 0;
+ *(u8*)(ebx + 0xa0) = 1;
+ if (is_ult) {
+ *(u8*)(ebx + 0xa1) = 0;
+ }
+ *(u8*)(ebx + 0xa2) = 0;
+ *(u8*)(ebx + 0xa3) = 1;
+ *(u8*)(ebx + 0xa4) = 0;
+ *(u8*)(ebx + 0xa6) = 3;
+ for (int i = 0; i < 5; i++) {
+ *(u8*)(ebx + 0xa9) = 0;
+ }
+ for (int i = 0; i < 4; i++) {
+ *(u8*)(ebx + 0xaf) = 0;
+ }
+ for (int i = 0; i < 2; i++) {
+ u8 *b1 = ebx + i * 2;
+ *(u8*)(ebx + i + 0xa7) = 0;
+ for (int j = 0; j < 4; j++) {
+ *(u8*)(b1 + 0xb4 + j * 4) = 0xff;
+ }
+ for (int j = 0; j < 5; j++) {
+ *(u8*)(b1 + 0xc4 + j * 4) = 0;
+ }
+ for (int j = 0; j < 4; j++) {
+ *(u8*)(b1 + 0xb5 + j * 4) = 0xff;
+ }
+ for (int j = 0; j < 5; j++) {
+ *(u8*)(b1 + 0xc5 + j * 4) = 0;
+ }
+ }
+ *(u8*)(ebx + 0xd8) = 1;
+ *(u16*)(ebx + 0xd9) = 0x200;
+ *(u8*)(ebx + 0xdb) = 0;
+ *(u8*)(ebx + 0xdc) = 0x30;
+ if (is_ult) {
+ *(u8*)(ebx + 0xdd) = 1;
+ *(u8*)(ebx + 0xde) = 0x40;
+ }
+ }
+
+ if (v > 10) {
+ T8(0x59, 0xc2); T8(0x5a, 0xc3); T8(0x6e5, 0xc4);
+ } else {
+ *(u8*)(ebx + 0x59) = 1;
+ *(u8*)(ebx + 0x5a) = 1;
+ *(u8*)(ebx + 0x6e5) = 0;
+ }
+
+ tmp = *(u8*)(ebx + 0x6dd);
+ if (v > 11) {
+ tmp = shupd(tmp, *(u8*)(esi + 0xc5), 3);
+ } else {
+ tmp |= 8;
+ }
+ *(u8*)(ebx + 0x6dd) = tmp;
+
+ tmp = *(u8*)(ebx + 0x6de);
+ if (v > 0xe) {
+ tmp = shupd(tmp, *(u8*)(esi + 0xc7), 4);
+ } else {
+ tmp = shupd(tmp, 1, 4);
+ }
+ *(u8*)(ebx + 0x6de) = tmp;
+
+ *(u32*)(ebx + 0x41) = 0;
+ *(u8*)(ebx + 0x40) = 0;
+ T8(0x56, 0x11);
+ T8(0x58, 0x2c);
+ T8(0x53, 0);
+ T8(0x6e1, 0x52);
+
+ if (*(u32*)(ebx + 0x2d) == HASWELL_FAMILY_ULT) {
+ *(u8*)(ebx + 0x6e3) = 0;
+ T8(0x6e2, 0x57);
+ }
+
+ void *ptr0 = ebx + 0xdf;
+ *(u8*)(ebx + 0xe3) = 0;
+ for (int i = 0; i < 2; i++) {
+ void *ptr1 = ptr0 + i * 0x2fa;
+ void *ptr2 = ptr1 + 5;
+ /* ram_param + 0x2a: channel i disabled */
+ tmp = *(u8*)(esi + i + 0x2a);
+ printk(BIOS_DEBUG, "dimm_channel%d_disabled = %hhd\n", i, tmp);
+
+ if (tmp == 2) { /* disable DIMM 1 */
+ *(u32*)(ptr2 + 8) = 0;
+ *(u32*)(ptr2 + 0x157) = 1;
+ *(u32*)(ptr1 + 5) = 2;
+ (*(u8*)(ptr0 + 4))++;
+ *(u32*)(ptr2 + 4) = 1;
+ } else if (tmp == 3) { /* disable DIMM 0+1 */
+ *(u32*)(ptr2 + 8) = 1;
+ *(u32*)(ptr2 + 0x157) = 1;
+ *(u32*)(ptr1 + 5) = 1;
+ *(u32*)(ptr2 + 4) = 0;
+ } else if (tmp != 1) { /* 0: enable channel */
+ *(u32*)(ptr2 + 8) = 0;
+ *(u32*)(ptr2 + 0x157) = 0;
+ *(u32*)(ptr1 + 5) = 2;
+ (*(u8*)(ptr0 + 4))++;
+ *(u32*)(ptr2 + 4) = 2;
+ } else { /* tmp == 1: disable DIMM 0 */
+ *(u32*)(ptr2 + 8) = 1;
+ *(u32*)(ptr2 + 0x157) = 0;
+ *(u32*)(ptr1 + 5) = 2;
+ (*(u8*)(ptr0 + 4))++;
+ *(u32*)(ptr2 + 4) = 1;
+ }
+ }
+
+ u8 *spd_addr = ppi->ram_data->spd_addresses;
+
+ printk(BIOS_DEBUG, "SPD addresses:");
+ for (int i = 0; i < 4; i++) {
+ printk(BIOS_DEBUG, " 0x%02hhx", spd_addr[i]);
+ }
+ printk(BIOS_DEBUG, "\n");
+
+ *(u8*)(ebx + 0x23a) = spd_addr[0];
+ *(u8*)(ebx + 0x389) = spd_addr[1];
+ *(u8*)(ebx + 0x534) = spd_addr[2];
+ *(u8*)(ebx + 0x683) = spd_addr[3];
+}
+
+static void copy_spd(void *ebx)
+{
+ MRC_PEI *pei = PEI_FROM_PEI_SERVICE(**gpPei);
+ struct pei_data *pd = pei->pei_data;
+
+ for (int i = 0; i < 2; i++) {
+ int idxi = i * 0x2fa;
+ for (int j = 0; j < 2; j++) {
+ void *edx = ebx + (idxi + j * 0x14f + 0xd0);
+ void *ptr = edx + 0x1c;
+ if (*(u8*)(edx + 0x16a) == 0xff &&
+ *(u32*)(edx + 0x1c) == 0) {
+ printk(BIOS_DEBUG, "Copy SPD for Channel %d Dimm %d\n", i, j);
+ /* FIXME: looks like mrc.bin only copies channel 0 slot 0??? */
+ mrc_memcpy(edx + 0x40, pd->spd_data, 0x100);
+ *(u8*)(ptr + 0x14e) = 0;
+ }
+ }
+ }
+}
int __attribute((regparm(3))) fcn_fffa1d20(int bootmode, int v, void *addr,
EFI_PEI_SERVICES **pps /* not used */, pei_raminit_ppi *ppi);
@@ -478,13 +770,21 @@ int __attribute((regparm(3))) fcn_fffa1d20(int bootmode, int v, void *addr,
}
}
+ /* mchbar: 0xfd8 + 0x67 = 0x103f */
*(u32*)(addr + 0x67) = (u32)ppi->ram_data->mchbar;
+ /* pciexbar: 0x103b */
*(u32*)(addr + 0x63) = (u32)ppi->ram_data->pciexbar;
+ /* smbusbar: 0x1043 */
*(u32*)(addr + 0x6b) = (u32)ppi->ram_data->smbusbar;
+ /* gdxcbar: 0x1047 */
*(u32*)(addr + 0x6f) = (u32)ppi->ram_data->gdxcbar;
+ /* HPET: 0x104b */
*(u32*)(addr + 0x73) = 0xfed00000;
*(u32*)(addr + 0x7b) = *(u16*)(ppi->cfg0);
- *(u32*)(addr + 0x18) = *(u16*)(esi + 1);
+
+ printk(BIOS_DEBUG, "Max DDR3 frequency: %hd\n", *(u16*)(esi + 1));
+
+ *(u32*)(addr + 0x18) = ppi->ram_param->max_ddr3_freq;
*(u32*)(addr + 0x7f) = ppi->ram_data->tseg_size >> 0x14;
*(u32*)(addr + 0x35) = *(u16*)(ppi->cfg0 + 2);
u32 eax = *(u8*)(ppi->cfg0 + 4);