summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/amd/amdk8/coherent_ht.c185
1 files changed, 124 insertions, 61 deletions
diff --git a/src/northbridge/amd/amdk8/coherent_ht.c b/src/northbridge/amd/amdk8/coherent_ht.c
index aa682c39a0..60f2f0242c 100644
--- a/src/northbridge/amd/amdk8/coherent_ht.c
+++ b/src/northbridge/amd/amdk8/coherent_ht.c
@@ -308,27 +308,90 @@ static void setup_row_direct(u8 source, u8 dest, u8 linkn)
val |= 1<<(linkn+1+8); //for direct connect response route should equal to request table
fill_row(source,dest, val);
}
+static uint8_t get_linkn_first(uint8_t byte)
+{
+ if(byte & 0x02) { byte = 0; }
+ else if(byte & 0x04) { byte = 1; }
+ else if(byte & 0x08) { byte = 2; }
+ return byte;
+}
+static uint8_t get_linkn_last(uint8_t byte)
+{
+ if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
+ if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
+ if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
+ return byte>>4;
+}
+static uint8_t get_linkn_last_count(uint8_t byte)
+{
+ byte &= 0x3f;
+ if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
+ if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
+ if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
+ return byte>>4;
+}
+
#if CONFIG_MAX_CPUS>2
+#if !CROSS_BAR_47_56
static void setup_row_indirect(u8 source, u8 dest, u8 gateway)
+#else
+static void setup_row_indirect(u8 source, u8 dest, u8 gateway, u8 diff)
+#endif
{
//for indirect connection, we need to compute the val from val_s(source, source), and val_g(source, gateway)
uint32_t val_s;
uint32_t val_g;
uint32_t val;
+ uint8_t byte;
#warning "FIXME is it the way to set the RESPONSE TABLE for indirect?"
+#warning "FIXME I don't know how to set BROADCAST TABLE for indirect, 1?"
val_s = get_row(source, source);
val_g = get_row(source, gateway);
val = val_g & 0xff;
val_s >>=16;
val_s &=0xfe;
- if(val_s!=val) { // use another connect as response
+#if !CROSS_BAR_47_56
+ if(((source&1)!=(dest &1)) && (val_s!=val) ) { // use another connect as response
val_s -= val;
-#warning "FIXME I don't know how to set BROADCAST TABLE for indirect, 1?"
+#if CONFIG_MAX_CPUS>4
+ // Some node have two links left
+ byte = val_s;
+ byte = get_linkn_last_count(byte);
+ if((byte>>2)>1) {
+ if(source<dest) {
+ val_s-=link_connection(source, source-2); // - down
+ } else {
+ val_s-=link_connection(source, source+2); // - up
+ }
+ }
+#endif
val |= (1<<16) | (val_s<<8);
} else {
val = val_g; // all the same to gateway
}
+#else
+ if(diff && (val_s!=val) ) { // use another connect as response
+ val_s -= val;
+#if CONFIG_MAX_CPUS>4
+ // Some node have two links left
+ // don't worry we only have (2, (3 as source need to handle
+ byte = val_s;
+ byte = get_linkn_last_count(byte);
+ if((byte>>2)>1) {
+ if(source<dest) {
+ val_s-=link_connection(source, source-2); // -down
+ } else {
+ val_s-=link_connection(source, source+2); // -up
+ }
+ }
+#endif
+ val |= (1<<16) | (val_s<<8);
+ } else {
+ val = val_g; // all the same to gateway
+ }
+
+#endif
fill_row(source, dest, val);
@@ -336,8 +399,13 @@ static void setup_row_indirect(u8 source, u8 dest, u8 gateway)
static void setup_row_indirect_group(const u8 *conn, int num)
{
int i;
- for(i=0; i<num; i+=3) {
- setup_row_indirect(conn[i*3], conn[i*3+1],conn[i*3+2]);
+ for(i=0; i<num; i+=4) {
+#if !CROSS_BAR_47_56
+ setup_row_indirect(conn[i*3], conn[i*3+1],conn[i*3+2]);
+#else
+ setup_row_indirect(conn[i*4], conn[i*4+1],conn[i*4+2], conn[i*4+3]);
+#endif
+
}
}
#endif
@@ -441,29 +509,6 @@ static int optimize_connection_group(const u8 *opt_conn, int num) {
#endif
#if CONFIG_MAX_CPUS > 1
-static uint8_t get_linkn_first(uint8_t byte)
-{
- if(byte & 0x02) { byte = 0; }
- else if(byte & 0x04) { byte = 1; }
- else if(byte & 0x08) { byte = 2; }
- return byte;
-}
-static uint8_t get_linkn_last(uint8_t byte)
-{
- if(byte & 0x02) { byte &= 0x0f; byte |= 0x00; }
- if(byte & 0x04) { byte &= 0x0f; byte |= 0x10; }
- if(byte & 0x08) { byte &= 0x0f; byte |= 0x20; }
- return byte>>4;
-}
-static uint8_t get_linkn_last_count(uint8_t byte)
-{
- byte &= 0x3f;
- if(byte & 0x02) { byte &= 0xcf; byte |= 0x00; byte+=0x40; }
- if(byte & 0x04) { byte &= 0xcf; byte |= 0x10; byte+=0x40; }
- if(byte & 0x08) { byte &= 0xcf; byte |= 0x20; byte+=0x40; }
- return byte>>4;
-}
-
static struct setup_smp_result setup_smp(void)
{
struct setup_smp_result result;
@@ -583,10 +628,17 @@ static struct setup_smp_result setup_smp(void)
/* We found 4 nodes so far. Now setup all nodes for 4p */
/* for indirect we will use clockwise routing */
+#if !CROSS_BAR_47_56
static const u8 conn4_1[] = {
0,3,1,
1,2,3,
};
+#else
+ static const u8 conn4_1[] = {
+ 0,3,1,1,
+ 1,2,3,1,
+ };
+#endif
setup_row_indirect_group(conn4_1, sizeof(conn4_1)/sizeof(conn4_1[0]));
@@ -661,10 +713,17 @@ static struct setup_smp_result setup_smp(void)
setup_row_direct(3,2, byte & 0x3);
/* Set indirect connection to 0, and 1 for indirect we will use clockwise routing */
+#if !CROSS_BAR_47_56
static const u8 conn4_2[] = {
2,1,0,
3,0,2,
};
+#else
+ static const u8 conn4_2[] = {
+ 2,1,0,1,
+ 3,0,2,1,
+ };
+#endif
setup_row_indirect_group(conn4_2, sizeof(conn4_2)/sizeof(conn4_2[0]));
@@ -740,17 +799,22 @@ static struct setup_smp_result setup_smp(void)
/* We found 6 nodes so far. Now setup all nodes for 6p */
static const u8 conn6_1[] = {
+#if !CROSS_BAR_47_56
0, 4, 2,
0, 5, 1,
1, 4, 3,
1, 5, 3,
2, 5, 3,
-#if !CROSS_BAR_47_56
3, 4, 5,
#else
- 3, 4, 2,
+ 0, 4, 2, 0,
+ 0, 5, 1, 1,
+ 1, 4, 3, 1,
+ 1, 5, 3, 0,
+ 2, 5, 3, 0,
+ 3, 4, 2, 0,
#endif
- };
+ };
setup_row_indirect_group(conn6_1, sizeof(conn6_1)/sizeof(conn6_1[0]));
@@ -839,15 +903,14 @@ static struct setup_smp_result setup_smp(void)
5, 2, 4,
5, 1, 3,
#else
-
- 4, 0, 2,
- 4, 1, 2,
- 4, 3, 2,
- 4, 5, 2,
- 5, 0, 3,
- 5, 2, 3,
- 5, 1, 3,
- 5, 4, 3,
+ 4, 0, 2, 0,
+ 4, 1, 2, 0,
+ 4, 3, 2, 0,
+ 4, 5, 2, 0,
+ 5, 0, 3, 0,
+ 5, 2, 3, 0,
+ 5, 1, 3, 0,
+ 5, 4, 3, 0,
#endif
};
@@ -947,14 +1010,14 @@ static struct setup_smp_result setup_smp(void)
// 3, 7, 5,
// 4, 7, 5,
#else
- 0, 6, 2,
-// 0, 7, 2,
- 1, 6, 3,
-// 1, 7, 3,
- 2, 6, 4,
-// 2, 7, 4,
- 3, 6, 5,
-// 3, 7, 5,
+ 0, 6, 2, 0,
+// 0, 7, 2, 0,
+ 1, 6, 3, 0,
+// 1, 7, 3, 0,
+ 2, 6, 4, 0,
+// 2, 7, 4, 0,
+ 3, 6, 5, 0,
+// 3, 7, 5, 0,
#endif
};
@@ -1116,21 +1179,21 @@ static struct setup_smp_result setup_smp(void)
7, 3, 5,
7, 4, 6,
#else
- 0, 7, 2, // restore it
- 1, 7, 3,
- 2, 7, 4,
- 3, 7, 5,
+ 0, 7, 2, 0, // restore it
+ 1, 7, 3, 0,
+ 2, 7, 4, 0,
+ 3, 7, 5, 0,
- 6, 0, 4,
- 6, 1, 4,
- 6, 2, 4,
- 6, 3, 4,
- 7, 0, 4,
- 7, 1, 5,
- 7, 2, 4,
- 7, 3, 5,
- 4, 5, 7,
- 5, 4, 6,
+ 6, 0, 4, 0,
+ 6, 1, 5, 0,
+ 6, 2, 4, 0,
+ 6, 3, 5, 0,
+ 7, 0, 4, 0,
+ 7, 1, 5, 0,
+ 7, 2, 4, 0,
+ 7, 3, 5, 0,
+ 4, 5, 7, 0,
+ 5, 4, 6, 0,
#endif
};