aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform/uv
diff options
context:
space:
mode:
authorCliff Wickman <cpw@sgi.com>2012-01-16 16:17:50 -0500
committerIngo Molnar <mingo@elte.hu>2012-01-17 03:09:51 -0500
commitda87c937e5a2374686edd58df06cfd5050b125fa (patch)
tree22f25f60e1d4d8500b91d66591b0aca4987304d4 /arch/x86/platform/uv
parentf10448689d95b9516c656ccd4078839e656656e7 (diff)
x86/UV2: Fix new UV2 hardware by using native UV2 broadcast mode
Update the use of the Broadcast Assist Unit on SGI Altix UV2 to the use of native UV2 mode on new hardware (not the legacy mode). UV2 native mode has a different format for a broadcast message. We also need quick differentiaton between UV1 and UV2. Signed-off-by: Cliff Wickman <cpw@sgi.com> Link: http://lkml.kernel.org/r/20120116211750.GA5767@sgi.com Cc: <stable@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/platform/uv')
-rw-r--r--arch/x86/platform/uv/tlb_uv.c88
1 files changed, 65 insertions, 23 deletions
diff --git a/arch/x86/platform/uv/tlb_uv.c b/arch/x86/platform/uv/tlb_uv.c
index 5b552198f774..1341a2e06542 100644
--- a/arch/x86/platform/uv/tlb_uv.c
+++ b/arch/x86/platform/uv/tlb_uv.c
@@ -573,7 +573,7 @@ static int wait_completion(struct bau_desc *bau_desc,
573 right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE); 573 right_shift = ((cpu - UV_CPUS_PER_AS) * UV_ACT_STATUS_SIZE);
574 } 574 }
575 575
576 if (is_uv1_hub()) 576 if (bcp->uvhub_version == 1)
577 return uv1_wait_completion(bau_desc, mmr_offset, right_shift, 577 return uv1_wait_completion(bau_desc, mmr_offset, right_shift,
578 bcp, try); 578 bcp, try);
579 else 579 else
@@ -757,15 +757,22 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
757{ 757{
758 int seq_number = 0; 758 int seq_number = 0;
759 int completion_stat = 0; 759 int completion_stat = 0;
760 int uv1 = 0;
760 long try = 0; 761 long try = 0;
761 unsigned long index; 762 unsigned long index;
762 cycles_t time1; 763 cycles_t time1;
763 cycles_t time2; 764 cycles_t time2;
764 struct ptc_stats *stat = bcp->statp; 765 struct ptc_stats *stat = bcp->statp;
765 struct bau_control *hmaster = bcp->uvhub_master; 766 struct bau_control *hmaster = bcp->uvhub_master;
767 struct uv1_bau_msg_header *uv1_hdr = NULL;
768 struct uv2_bau_msg_header *uv2_hdr = NULL;
766 769
767 if (is_uv1_hub()) 770 if (bcp->uvhub_version == 1) {
771 uv1 = 1;
768 uv1_throttle(hmaster, stat); 772 uv1_throttle(hmaster, stat);
773 uv1_hdr = &bau_desc->header.uv1_hdr;
774 } else
775 uv2_hdr = &bau_desc->header.uv2_hdr;
769 776
770 while (hmaster->uvhub_quiesce) 777 while (hmaster->uvhub_quiesce)
771 cpu_relax(); 778 cpu_relax();
@@ -773,14 +780,23 @@ int uv_flush_send_and_wait(struct bau_desc *bau_desc,
773 time1 = get_cycles(); 780 time1 = get_cycles();
774 do { 781 do {
775 if (try == 0) { 782 if (try == 0) {
776 bau_desc->header.msg_type = MSG_REGULAR; 783 if (uv1)
784 uv1_hdr->msg_type = MSG_REGULAR;
785 else
786 uv2_hdr->msg_type = MSG_REGULAR;
777 seq_number = bcp->message_number++; 787 seq_number = bcp->message_number++;
778 } else { 788 } else {
779 bau_desc->header.msg_type = MSG_RETRY; 789 if (uv1)
790 uv1_hdr->msg_type = MSG_RETRY;
791 else
792 uv2_hdr->msg_type = MSG_RETRY;
780 stat->s_retry_messages++; 793 stat->s_retry_messages++;
781 } 794 }
782 795
783 bau_desc->header.sequence = seq_number; 796 if (uv1)
797 uv1_hdr->sequence = seq_number;
798 else
799 uv2_hdr->sequence = seq_number;
784 index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu; 800 index = (1UL << AS_PUSH_SHIFT) | bcp->uvhub_cpu;
785 bcp->send_message = get_cycles(); 801 bcp->send_message = get_cycles();
786 802
@@ -967,7 +983,7 @@ const struct cpumask *uv_flush_tlb_others(const struct cpumask *cpumask,
967 stat->s_ntargself++; 983 stat->s_ntargself++;
968 984
969 bau_desc = bcp->descriptor_base; 985 bau_desc = bcp->descriptor_base;
970 bau_desc += ITEMS_PER_DESC * bcp->uvhub_cpu; 986 bau_desc += (ITEMS_PER_DESC * bcp->uvhub_cpu);
971 bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE); 987 bau_uvhubs_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
972 if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes)) 988 if (set_distrib_bits(flush_mask, bcp, bau_desc, &locals, &remotes))
973 return NULL; 989 return NULL;
@@ -1083,7 +1099,7 @@ static void __init enable_timeouts(void)
1083 */ 1099 */
1084 mmr_image |= (1L << SOFTACK_MSHIFT); 1100 mmr_image |= (1L << SOFTACK_MSHIFT);
1085 if (is_uv2_hub()) { 1101 if (is_uv2_hub()) {
1086 mmr_image |= (1L << UV2_LEG_SHFT); 1102 mmr_image &= ~(1L << UV2_LEG_SHFT);
1087 mmr_image |= (1L << UV2_EXT_SHFT); 1103 mmr_image |= (1L << UV2_EXT_SHFT);
1088 } 1104 }
1089 write_mmr_misc_control(pnode, mmr_image); 1105 write_mmr_misc_control(pnode, mmr_image);
@@ -1432,12 +1448,15 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
1432{ 1448{
1433 int i; 1449 int i;
1434 int cpu; 1450 int cpu;
1451 int uv1 = 0;
1435 unsigned long gpa; 1452 unsigned long gpa;
1436 unsigned long m; 1453 unsigned long m;
1437 unsigned long n; 1454 unsigned long n;
1438 size_t dsize; 1455 size_t dsize;
1439 struct bau_desc *bau_desc; 1456 struct bau_desc *bau_desc;
1440 struct bau_desc *bd2; 1457 struct bau_desc *bd2;
1458 struct uv1_bau_msg_header *uv1_hdr;
1459 struct uv2_bau_msg_header *uv2_hdr;
1441 struct bau_control *bcp; 1460 struct bau_control *bcp;
1442 1461
1443 /* 1462 /*
@@ -1451,6 +1470,8 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
1451 gpa = uv_gpa(bau_desc); 1470 gpa = uv_gpa(bau_desc);
1452 n = uv_gpa_to_gnode(gpa); 1471 n = uv_gpa_to_gnode(gpa);
1453 m = uv_gpa_to_offset(gpa); 1472 m = uv_gpa_to_offset(gpa);
1473 if (is_uv1_hub())
1474 uv1 = 1;
1454 1475
1455 /* the 14-bit pnode */ 1476 /* the 14-bit pnode */
1456 write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m)); 1477 write_mmr_descriptor_base(pnode, (n << UV_DESC_PSHIFT | m));
@@ -1461,21 +1482,33 @@ static void activation_descriptor_init(int node, int pnode, int base_pnode)
1461 */ 1482 */
1462 for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) { 1483 for (i = 0, bd2 = bau_desc; i < (ADP_SZ * ITEMS_PER_DESC); i++, bd2++) {
1463 memset(bd2, 0, sizeof(struct bau_desc)); 1484 memset(bd2, 0, sizeof(struct bau_desc));
1464 bd2->header.swack_flag = 1; 1485 if (uv1) {
1465 /* 1486 uv1_hdr = &bd2->header.uv1_hdr;
1466 * The base_dest_nasid set in the message header is the nasid 1487 uv1_hdr->swack_flag = 1;
1467 * of the first uvhub in the partition. The bit map will 1488 /*
1468 * indicate destination pnode numbers relative to that base. 1489 * The base_dest_nasid set in the message header
1469 * They may not be consecutive if nasid striding is being used. 1490 * is the nasid of the first uvhub in the partition.
1470 */ 1491 * The bit map will indicate destination pnode numbers
1471 bd2->header.base_dest_nasid = UV_PNODE_TO_NASID(base_pnode); 1492 * relative to that base. They may not be consecutive
1472 bd2->header.dest_subnodeid = UV_LB_SUBNODEID; 1493 * if nasid striding is being used.
1473 bd2->header.command = UV_NET_ENDPOINT_INTD; 1494 */
1474 bd2->header.int_both = 1; 1495 uv1_hdr->base_dest_nasid =
1475 /* 1496 UV_PNODE_TO_NASID(base_pnode);
1476 * all others need to be set to zero: 1497 uv1_hdr->dest_subnodeid = UV_LB_SUBNODEID;
1477 * fairness chaining multilevel count replied_to 1498 uv1_hdr->command = UV_NET_ENDPOINT_INTD;
1478 */ 1499 uv1_hdr->int_both = 1;
1500 /*
1501 * all others need to be set to zero:
1502 * fairness chaining multilevel count replied_to
1503 */
1504 } else {
1505 uv2_hdr = &bd2->header.uv2_hdr;
1506 uv2_hdr->swack_flag = 1;
1507 uv2_hdr->base_dest_nasid =
1508 UV_PNODE_TO_NASID(base_pnode);
1509 uv2_hdr->dest_subnodeid = UV_LB_SUBNODEID;
1510 uv2_hdr->command = UV_NET_ENDPOINT_INTD;
1511 }
1479 } 1512 }
1480 for_each_present_cpu(cpu) { 1513 for_each_present_cpu(cpu) {
1481 if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu))) 1514 if (pnode != uv_blade_to_pnode(uv_cpu_to_blade_id(cpu)))
@@ -1728,6 +1761,14 @@ static int scan_sock(struct socket_desc *sdp, struct uvhub_desc *bdp,
1728 bcp->cpus_in_socket = sdp->num_cpus; 1761 bcp->cpus_in_socket = sdp->num_cpus;
1729 bcp->socket_master = *smasterp; 1762 bcp->socket_master = *smasterp;
1730 bcp->uvhub = bdp->uvhub; 1763 bcp->uvhub = bdp->uvhub;
1764 if (is_uv1_hub())
1765 bcp->uvhub_version = 1;
1766 else if (is_uv2_hub())
1767 bcp->uvhub_version = 2;
1768 else {
1769 printk(KERN_EMERG "uvhub version not 1 or 2\n");
1770 return 1;
1771 }
1731 bcp->uvhub_master = *hmasterp; 1772 bcp->uvhub_master = *hmasterp;
1732 bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id; 1773 bcp->uvhub_cpu = uv_cpu_hub_info(cpu)->blade_processor_id;
1733 if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) { 1774 if (bcp->uvhub_cpu >= MAX_CPUS_PER_UVHUB) {
@@ -1867,7 +1908,8 @@ static int __init uv_bau_init(void)
1867 val = 1L << 63; 1908 val = 1L << 63;
1868 write_gmmr_activation(pnode, val); 1909 write_gmmr_activation(pnode, val);
1869 mmr = 1; /* should be 1 to broadcast to both sockets */ 1910 mmr = 1; /* should be 1 to broadcast to both sockets */
1870 write_mmr_data_broadcast(pnode, mmr); 1911 if (!is_uv1_hub())
1912 write_mmr_data_broadcast(pnode, mmr);
1871 } 1913 }
1872 } 1914 }
1873 1915