diff options
-rw-r--r-- | arch/x86/include/asm/uv/uv_bau.h | 93 | ||||
-rw-r--r-- | arch/x86/platform/uv/tlb_uv.c | 88 |
2 files changed, 151 insertions, 30 deletions
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h index 8e862aaf0d90..4a46b27ee9a0 100644 --- a/arch/x86/include/asm/uv/uv_bau.h +++ b/arch/x86/include/asm/uv/uv_bau.h | |||
@@ -65,7 +65,7 @@ | |||
65 | * UV2: Bit 19 selects between | 65 | * UV2: Bit 19 selects between |
66 | * (0): 10 microsecond timebase and | 66 | * (0): 10 microsecond timebase and |
67 | * (1): 80 microseconds | 67 | * (1): 80 microseconds |
68 | * we're using 655us, similar to UV1: 65 units of 10us | 68 | * we're using 560us, similar to UV1: 65 units of 10us |
69 | */ | 69 | */ |
70 | #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) | 70 | #define UV1_INTD_SOFT_ACK_TIMEOUT_PERIOD (9UL) |
71 | #define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL) | 71 | #define UV2_INTD_SOFT_ACK_TIMEOUT_PERIOD (15UL) |
@@ -235,10 +235,10 @@ struct bau_msg_payload { | |||
235 | 235 | ||
236 | 236 | ||
237 | /* | 237 | /* |
238 | * Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) | 238 | * UV1 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) |
239 | * see table 4.2.3.0.1 in broacast_assist spec. | 239 | * see table 4.2.3.0.1 in broacast_assist spec. |
240 | */ | 240 | */ |
241 | struct bau_msg_header { | 241 | struct uv1_bau_msg_header { |
242 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ | 242 | unsigned int dest_subnodeid:6; /* must be 0x10, for the LB */ |
243 | /* bits 5:0 */ | 243 | /* bits 5:0 */ |
244 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ | 244 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ |
@@ -318,19 +318,87 @@ struct bau_msg_header { | |||
318 | }; | 318 | }; |
319 | 319 | ||
320 | /* | 320 | /* |
321 | * UV2 Message header: 16 bytes (128 bits) (bytes 0x30-0x3f of descriptor) | ||
322 | * see figure 9-2 of harp_sys.pdf | ||
323 | */ | ||
324 | struct uv2_bau_msg_header { | ||
325 | unsigned int base_dest_nasid:15; /* nasid of the first bit */ | ||
326 | /* bits 14:0 */ /* in uvhub map */ | ||
327 | unsigned int dest_subnodeid:5; /* must be 0x10, for the LB */ | ||
328 | /* bits 19:15 */ | ||
329 | unsigned int rsvd_1:1; /* must be zero */ | ||
330 | /* bit 20 */ | ||
331 | /* Address bits 59:21 */ | ||
332 | /* bits 25:2 of address (44:21) are payload */ | ||
333 | /* these next 24 bits become bytes 12-14 of msg */ | ||
334 | /* bits 28:21 land in byte 12 */ | ||
335 | unsigned int replied_to:1; /* sent as 0 by the source to | ||
336 | byte 12 */ | ||
337 | /* bit 21 */ | ||
338 | unsigned int msg_type:3; /* software type of the | ||
339 | message */ | ||
340 | /* bits 24:22 */ | ||
341 | unsigned int canceled:1; /* message canceled, resource | ||
342 | is to be freed*/ | ||
343 | /* bit 25 */ | ||
344 | unsigned int payload_1:3; /* not currently used */ | ||
345 | /* bits 28:26 */ | ||
346 | |||
347 | /* bits 36:29 land in byte 13 */ | ||
348 | unsigned int payload_2a:3; /* not currently used */ | ||
349 | unsigned int payload_2b:5; /* not currently used */ | ||
350 | /* bits 36:29 */ | ||
351 | |||
352 | /* bits 44:37 land in byte 14 */ | ||
353 | unsigned int payload_3:8; /* not currently used */ | ||
354 | /* bits 44:37 */ | ||
355 | |||
356 | unsigned int rsvd_2:7; /* reserved */ | ||
357 | /* bits 51:45 */ | ||
358 | unsigned int swack_flag:1; /* software acknowledge flag */ | ||
359 | /* bit 52 */ | ||
360 | unsigned int rsvd_3a:3; /* must be zero */ | ||
361 | unsigned int rsvd_3b:8; /* must be zero */ | ||
362 | unsigned int rsvd_3c:8; /* must be zero */ | ||
363 | unsigned int rsvd_3d:3; /* must be zero */ | ||
364 | /* bits 74:53 */ | ||
365 | unsigned int fairness:3; /* usually zero */ | ||
366 | /* bits 77:75 */ | ||
367 | |||
368 | unsigned int sequence:16; /* message sequence number */ | ||
369 | /* bits 93:78 Suppl_A */ | ||
370 | unsigned int chaining:1; /* next descriptor is part of | ||
371 | this activation*/ | ||
372 | /* bit 94 */ | ||
373 | unsigned int multilevel:1; /* multi-level multicast | ||
374 | format */ | ||
375 | /* bit 95 */ | ||
376 | unsigned int rsvd_4:24; /* ordered / source node / | ||
377 | source subnode / aging | ||
378 | must be zero */ | ||
379 | /* bits 119:96 */ | ||
380 | unsigned int command:8; /* message type */ | ||
381 | /* bits 127:120 */ | ||
382 | }; | ||
383 | |||
384 | /* | ||
321 | * The activation descriptor: | 385 | * The activation descriptor: |
322 | * The format of the message to send, plus all accompanying control | 386 | * The format of the message to send, plus all accompanying control |
323 | * Should be 64 bytes | 387 | * Should be 64 bytes |
324 | */ | 388 | */ |
325 | struct bau_desc { | 389 | struct bau_desc { |
326 | struct pnmask distribution; | 390 | struct pnmask distribution; |
327 | /* | 391 | /* |
328 | * message template, consisting of header and payload: | 392 | * message template, consisting of header and payload: |
329 | */ | 393 | */ |
330 | struct bau_msg_header header; | 394 | union bau_msg_header { |
331 | struct bau_msg_payload payload; | 395 | struct uv1_bau_msg_header uv1_hdr; |
396 | struct uv2_bau_msg_header uv2_hdr; | ||
397 | } header; | ||
398 | |||
399 | struct bau_msg_payload payload; | ||
332 | }; | 400 | }; |
333 | /* | 401 | /* UV1: |
334 | * -payload-- ---------header------ | 402 | * -payload-- ---------header------ |
335 | * bytes 0-11 bits 41-56 bits 58-81 | 403 | * bytes 0-11 bits 41-56 bits 58-81 |
336 | * A B (2) C (3) | 404 | * A B (2) C (3) |
@@ -340,6 +408,16 @@ struct bau_desc { | |||
340 | * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector) | 408 | * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector) |
341 | * ------------payload queue----------- | 409 | * ------------payload queue----------- |
342 | */ | 410 | */ |
411 | /* UV2: | ||
412 | * -payload-- ---------header------ | ||
413 | * bytes 0-11 bits 70-78 bits 21-44 | ||
414 | * A B (2) C (3) | ||
415 | * | ||
416 | * A/B/C are moved to: | ||
417 | * A C B | ||
418 | * bytes 0-11 bytes 12-14 bytes 16-17 (byte 15 filled in by hw as vector) | ||
419 | * ------------payload queue----------- | ||
420 | */ | ||
343 | 421 | ||
344 | /* | 422 | /* |
345 | * The payload queue on the destination side is an array of these. | 423 | * The payload queue on the destination side is an array of these. |
@@ -511,6 +589,7 @@ struct bau_control { | |||
511 | short osnode; | 589 | short osnode; |
512 | short uvhub_cpu; | 590 | short uvhub_cpu; |
513 | short uvhub; | 591 | short uvhub; |
592 | short uvhub_version; | ||
514 | short cpus_in_socket; | 593 | short cpus_in_socket; |
515 | short cpus_in_uvhub; | 594 | short cpus_in_uvhub; |
516 | short partition_base_pnode; | 595 | short partition_base_pnode; |
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 | ||