2 /* low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
4 * Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
5 * Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <asm/assembly.h>
24 #include <linux/init.h>
25 #include <linux/linkage.h>
29 #endif /* CONFIG_64BIT */
31 #define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
32 #define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
33 #define MFDIAG_1(gr) .word 0x142008A0 + gr
34 #define MFDIAG_2(gr) .word 0x144008A0 + gr
35 #define STDIAG(dr) .word 0x14000AA0 + dr*0x200000
36 #define SFDIAG(dr) .word 0x14000BA0 + dr*0x200000
37 #define DR2_SLOW_RET 53
41 ; Enable the performance counters
43 ; The coprocessor only needs to be enabled when
44 ; starting/stopping the coprocessor with the pmenb/pmdis.
48 ENTRY(perf_intrigue_enable_perf_counters)
50 .callinfo frame=0,NO_CALLS
53 ldi 0x20,%r25 ; load up perfmon bit
54 mfctl ccr,%r26 ; get coprocessor register
55 or %r25,%r26,%r26 ; set bit
56 mtctl %r26,ccr ; turn on performance coprocessor
57 pmenb ; enable performance monitor
58 ssm 0,0 ; dummy op to ensure completion
60 andcm %r26,%r25,%r26 ; clear bit now
61 mtctl %r26,ccr ; turn off performance coprocessor
62 nop ; NOPs as specified in ERS
73 ENDPROC(perf_intrigue_enable_perf_counters)
75 ENTRY(perf_intrigue_disable_perf_counters)
77 .callinfo frame=0,NO_CALLS
79 ldi 0x20,%r25 ; load up perfmon bit
80 mfctl ccr,%r26 ; get coprocessor register
81 or %r25,%r26,%r26 ; set bit
82 mtctl %r26,ccr ; turn on performance coprocessor
83 pmdis ; disable performance monitor
84 ssm 0,0 ; dummy op to ensure completion
85 andcm %r26,%r25,%r26 ; clear bit now
87 mtctl %r26,ccr ; turn off performance coprocessor
90 ENDPROC(perf_intrigue_disable_perf_counters)
92 ;***********************************************************************
94 ;* Name: perf_rdr_shift_in_W
97 ;* This routine shifts data in from the RDR in arg0 and returns
98 ;* the result in ret0. If the RDR is <= 64 bits in length, it
99 ;* is shifted shifted backup immediately. This is to compensate
100 ;* for RDR10 which has bits that preclude PDC stack operations
101 ;* when they are in the wrong state.
104 ;* arg0 : rdr to be read
105 ;* arg1 : bit length of rdr
108 ;* ret0 = next 64 bits of rdr data from staging register
111 ;* arg0 : rdr to be read
112 ;* arg1 : bit length of rdr
113 ;* %r24 - original DR2 value
118 ;* ret0 = RDR data (right justified)
120 ;***********************************************************************
122 ENTRY(perf_rdr_shift_in_W)
124 .callinfo frame=0,NO_CALLS
127 ; read(shift in) the RDR.
130 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
131 ; shifting is done, from or to, remote diagnose registers.
134 depdi,z 1,DR2_SLOW_RET,1,%r29
137 MTDIAG_2 (29) ; set DR2_SLOW_RET
145 ; Cacheline start (32-byte cacheline)
150 extrd,u arg1,63,6,%r1 ; setup shift amount by bits to move
153 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
154 blr %r1,%r0 ; branch to 8-instruction sequence
158 ; Cacheline start (32-byte cacheline)
167 shrpd ret0,%r0,%sar,%r1
168 MTDIAG_1 (1) ; mtdiag %dr1, %r1
171 b,n perf_rdr_shift_in_W_leave
182 b,n perf_rdr_shift_in_W_leave
186 ; RDR 2 read sequence
191 shrpd ret0,%r0,%sar,%r1
195 b,n perf_rdr_shift_in_W_leave
198 ; RDR 3 read sequence
200 b,n perf_rdr_shift_in_W_leave
210 ; RDR 4 read sequence
217 b,n perf_rdr_shift_in_W_leave
222 ; RDR 5 read sequence
229 b,n perf_rdr_shift_in_W_leave
234 ; RDR 6 read sequence
241 b,n perf_rdr_shift_in_W_leave
246 ; RDR 7 read sequence
248 b,n perf_rdr_shift_in_W_leave
258 ; RDR 8 read sequence
260 b,n perf_rdr_shift_in_W_leave
270 ; RDR 9 read sequence
272 b,n perf_rdr_shift_in_W_leave
282 ; RDR 10 read sequence
287 shrpd ret0,%r0,%sar,%r1
291 b,n perf_rdr_shift_in_W_leave
294 ; RDR 11 read sequence
299 shrpd ret0,%r0,%sar,%r1
303 b,n perf_rdr_shift_in_W_leave
306 ; RDR 12 read sequence
308 b,n perf_rdr_shift_in_W_leave
318 ; RDR 13 read sequence
325 b,n perf_rdr_shift_in_W_leave
330 ; RDR 14 read sequence
335 shrpd ret0,%r0,%sar,%r1
339 b,n perf_rdr_shift_in_W_leave
342 ; RDR 15 read sequence
350 b,n perf_rdr_shift_in_W_leave
354 ; RDR 16 read sequence
361 b,n perf_rdr_shift_in_W_leave
366 ; RDR 17 read sequence
371 shrpd ret0,%r0,%sar,%r1
375 b,n perf_rdr_shift_in_W_leave
378 ; RDR 18 read sequence
383 shrpd ret0,%r0,%sar,%r1
387 b,n perf_rdr_shift_in_W_leave
390 ; RDR 19 read sequence
392 b,n perf_rdr_shift_in_W_leave
402 ; RDR 20 read sequence
409 b,n perf_rdr_shift_in_W_leave
414 ; RDR 21 read sequence
421 b,n perf_rdr_shift_in_W_leave
426 ; RDR 22 read sequence
433 b,n perf_rdr_shift_in_W_leave
438 ; RDR 23 read sequence
445 b,n perf_rdr_shift_in_W_leave
450 ; RDR 24 read sequence
457 b,n perf_rdr_shift_in_W_leave
462 ; RDR 25 read sequence
469 b,n perf_rdr_shift_in_W_leave
474 ; RDR 26 read sequence
479 shrpd ret0,%r0,%sar,%r1
483 b,n perf_rdr_shift_in_W_leave
486 ; RDR 27 read sequence
491 shrpd ret0,%r0,%sar,%r1
495 b,n perf_rdr_shift_in_W_leave
498 ; RDR 28 read sequence
505 b,n perf_rdr_shift_in_W_leave
510 ; RDR 29 read sequence
517 b,n perf_rdr_shift_in_W_leave
522 ; RDR 30 read sequence
527 shrpd ret0,%r0,%sar,%r1
531 b,n perf_rdr_shift_in_W_leave
534 ; RDR 31 read sequence
549 perf_rdr_shift_in_W_leave:
552 MTDIAG_2 (24) ; restore DR2
554 ENDPROC(perf_rdr_shift_in_W)
557 ;***********************************************************************
559 ;* Name: perf_rdr_shift_out_W
562 ;* This routine moves data to the RDR's. The double-word that
563 ;* arg1 points to is loaded and moved into the staging register.
564 ;* Then the STDIAG instruction for the RDR # in arg0 is called
565 ;* to move the data to the RDR.
569 ;* arg1 = 64-bit value to write
570 ;* %r24 - DR2 | DR2_SLOW_RET
571 ;* %r23 - original DR2 value
578 ;***********************************************************************
580 ENTRY(perf_rdr_shift_out_W)
582 .callinfo frame=0,NO_CALLS
585 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
586 ; shifting is done, from or to, the remote diagnose registers.
589 depdi,z 1,DR2_SLOW_RET,1,%r24
592 MTDIAG_2 (24) ; set DR2_SLOW_RET
593 MTDIAG_1 (25) ; data to the staging register
594 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
595 blr %r1,%r0 ; branch to 8-instruction sequence
599 ; RDR 0 write sequence
601 sync ; RDR 0 write sequence
605 b,n perf_rdr_shift_out_W_leave
611 ; RDR 1 write sequence
617 b,n perf_rdr_shift_out_W_leave
623 ; RDR 2 write sequence
629 b,n perf_rdr_shift_out_W_leave
635 ; RDR 3 write sequence
641 b,n perf_rdr_shift_out_W_leave
647 ; RDR 4 write sequence
653 b,n perf_rdr_shift_out_W_leave
659 ; RDR 5 write sequence
665 b,n perf_rdr_shift_out_W_leave
671 ; RDR 6 write sequence
677 b,n perf_rdr_shift_out_W_leave
683 ; RDR 7 write sequence
689 b,n perf_rdr_shift_out_W_leave
695 ; RDR 8 write sequence
701 b,n perf_rdr_shift_out_W_leave
707 ; RDR 9 write sequence
713 b,n perf_rdr_shift_out_W_leave
719 ; RDR 10 write sequence
726 b,n perf_rdr_shift_out_W_leave
731 ; RDR 11 write sequence
738 b,n perf_rdr_shift_out_W_leave
743 ; RDR 12 write sequence
749 b,n perf_rdr_shift_out_W_leave
755 ; RDR 13 write sequence
761 b,n perf_rdr_shift_out_W_leave
767 ; RDR 14 write sequence
773 b,n perf_rdr_shift_out_W_leave
779 ; RDR 15 write sequence
785 b,n perf_rdr_shift_out_W_leave
791 ; RDR 16 write sequence
797 b,n perf_rdr_shift_out_W_leave
803 ; RDR 17 write sequence
809 b,n perf_rdr_shift_out_W_leave
815 ; RDR 18 write sequence
821 b,n perf_rdr_shift_out_W_leave
827 ; RDR 19 write sequence
833 b,n perf_rdr_shift_out_W_leave
839 ; RDR 20 write sequence
845 b,n perf_rdr_shift_out_W_leave
851 ; RDR 21 write sequence
857 b,n perf_rdr_shift_out_W_leave
863 ; RDR 22 write sequence
869 b,n perf_rdr_shift_out_W_leave
875 ; RDR 23 write sequence
881 b,n perf_rdr_shift_out_W_leave
887 ; RDR 24 write sequence
893 b,n perf_rdr_shift_out_W_leave
899 ; RDR 25 write sequence
905 b,n perf_rdr_shift_out_W_leave
911 ; RDR 26 write sequence
918 b,n perf_rdr_shift_out_W_leave
923 ; RDR 27 write sequence
930 b,n perf_rdr_shift_out_W_leave
935 ; RDR 28 write sequence
941 b,n perf_rdr_shift_out_W_leave
947 ; RDR 29 write sequence
953 b,n perf_rdr_shift_out_W_leave
959 ; RDR 30 write sequence
965 b,n perf_rdr_shift_out_W_leave
971 ; RDR 31 write sequence
977 b,n perf_rdr_shift_out_W_leave
982 perf_rdr_shift_out_W_leave:
985 MTDIAG_2 (23) ; restore DR2
987 ENDPROC(perf_rdr_shift_out_W)
990 ;***********************************************************************
992 ;* Name: rdr_shift_in_U
995 ;* This routine shifts data in from the RDR in arg0 and returns
996 ;* the result in ret0. If the RDR is <= 64 bits in length, it
997 ;* is shifted shifted backup immediately. This is to compensate
998 ;* for RDR10 which has bits that preclude PDC stack operations
999 ;* when they are in the wrong state.
1002 ;* arg0 : rdr to be read
1003 ;* arg1 : bit length of rdr
1006 ;* ret0 = next 64 bits of rdr data from staging register
1009 ;* arg0 : rdr to be read
1010 ;* arg1 : bit length of rdr
1011 ;* %r24 - original DR2 value
1012 ;* %r23 - DR2 | DR2_SLOW_RET
1015 ;***********************************************************************
1017 ENTRY(perf_rdr_shift_in_U)
1019 .callinfo frame=0,NO_CALLS
1022 ; read(shift in) the RDR.
1024 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1025 ; shifting is done, from or to, remote diagnose registers.
1027 depdi,z 1,DR2_SLOW_RET,1,%r29
1030 MTDIAG_2 (29) ; set DR2_SLOW_RET
1038 ; Start of next 32-byte cacheline
1043 extrd,u arg1,63,6,%r1
1046 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1047 blr %r1,%r0 ; branch to 8-instruction sequence
1051 ; Start of next 32-byte cacheline
1053 SFDIAG (0) ; RDR 0 read sequence
1056 shrpd ret0,%r0,%sar,%r1
1060 b,n perf_rdr_shift_in_U_leave
1062 SFDIAG (1) ; RDR 1 read sequence
1065 shrpd ret0,%r0,%sar,%r1
1069 b,n perf_rdr_shift_in_U_leave
1071 sync ; RDR 2 read sequence
1076 b,n perf_rdr_shift_in_U_leave
1080 sync ; RDR 3 read sequence
1085 b,n perf_rdr_shift_in_U_leave
1089 sync ; RDR 4 read sequence
1094 b,n perf_rdr_shift_in_U_leave
1098 sync ; RDR 5 read sequence
1103 b,n perf_rdr_shift_in_U_leave
1107 sync ; RDR 6 read sequence
1112 b,n perf_rdr_shift_in_U_leave
1116 sync ; RDR 7 read sequence
1121 b,n perf_rdr_shift_in_U_leave
1125 b,n perf_rdr_shift_in_U_leave
1134 SFDIAG (9) ; RDR 9 read sequence
1137 shrpd ret0,%r0,%sar,%r1
1141 b,n perf_rdr_shift_in_U_leave
1143 SFDIAG (10) ; RDR 10 read sequence
1146 shrpd ret0,%r0,%sar,%r1
1150 b,n perf_rdr_shift_in_U_leave
1152 SFDIAG (11) ; RDR 11 read sequence
1155 shrpd ret0,%r0,%sar,%r1
1159 b,n perf_rdr_shift_in_U_leave
1161 SFDIAG (12) ; RDR 12 read sequence
1164 shrpd ret0,%r0,%sar,%r1
1168 b,n perf_rdr_shift_in_U_leave
1170 SFDIAG (13) ; RDR 13 read sequence
1173 shrpd ret0,%r0,%sar,%r1
1177 b,n perf_rdr_shift_in_U_leave
1179 SFDIAG (14) ; RDR 14 read sequence
1182 shrpd ret0,%r0,%sar,%r1
1186 b,n perf_rdr_shift_in_U_leave
1188 SFDIAG (15) ; RDR 15 read sequence
1191 shrpd ret0,%r0,%sar,%r1
1195 b,n perf_rdr_shift_in_U_leave
1197 sync ; RDR 16 read sequence
1202 b,n perf_rdr_shift_in_U_leave
1206 SFDIAG (17) ; RDR 17 read sequence
1209 shrpd ret0,%r0,%sar,%r1
1213 b,n perf_rdr_shift_in_U_leave
1215 SFDIAG (18) ; RDR 18 read sequence
1218 shrpd ret0,%r0,%sar,%r1
1222 b,n perf_rdr_shift_in_U_leave
1224 b,n perf_rdr_shift_in_U_leave
1233 sync ; RDR 20 read sequence
1238 b,n perf_rdr_shift_in_U_leave
1242 sync ; RDR 21 read sequence
1247 b,n perf_rdr_shift_in_U_leave
1251 sync ; RDR 22 read sequence
1256 b,n perf_rdr_shift_in_U_leave
1260 sync ; RDR 23 read sequence
1265 b,n perf_rdr_shift_in_U_leave
1269 sync ; RDR 24 read sequence
1274 b,n perf_rdr_shift_in_U_leave
1278 sync ; RDR 25 read sequence
1283 b,n perf_rdr_shift_in_U_leave
1287 SFDIAG (26) ; RDR 26 read sequence
1290 shrpd ret0,%r0,%sar,%r1
1294 b,n perf_rdr_shift_in_U_leave
1296 SFDIAG (27) ; RDR 27 read sequence
1299 shrpd ret0,%r0,%sar,%r1
1303 b,n perf_rdr_shift_in_U_leave
1305 sync ; RDR 28 read sequence
1310 b,n perf_rdr_shift_in_U_leave
1314 b,n perf_rdr_shift_in_U_leave
1323 SFDIAG (30) ; RDR 30 read sequence
1326 shrpd ret0,%r0,%sar,%r1
1330 b,n perf_rdr_shift_in_U_leave
1332 SFDIAG (31) ; RDR 31 read sequence
1335 shrpd ret0,%r0,%sar,%r1
1339 b,n perf_rdr_shift_in_U_leave
1342 perf_rdr_shift_in_U_leave:
1345 MTDIAG_2 (24) ; restore DR2
1347 ENDPROC(perf_rdr_shift_in_U)
1349 ;***********************************************************************
1351 ;* Name: rdr_shift_out_U
1354 ;* This routine moves data to the RDR's. The double-word that
1355 ;* arg1 points to is loaded and moved into the staging register.
1356 ;* Then the STDIAG instruction for the RDR # in arg0 is called
1357 ;* to move the data to the RDR.
1360 ;* arg0 = rdr target
1361 ;* arg1 = buffer pointer
1367 ;* arg0 = rdr target
1368 ;* arg1 = buffer pointer
1369 ;* %r24 - DR2 | DR2_SLOW_RET
1370 ;* %r23 - original DR2 value
1372 ;***********************************************************************
1374 ENTRY(perf_rdr_shift_out_U)
1376 .callinfo frame=0,NO_CALLS
1380 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1381 ; shifting is done, from or to, the remote diagnose registers.
1384 depdi,z 1,DR2_SLOW_RET,1,%r24
1387 MTDIAG_2 (24) ; set DR2_SLOW_RET
1389 MTDIAG_1 (25) ; data to the staging register
1390 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1391 blr %r1,%r0 ; branch to 8-instruction sequence
1395 ; 32-byte cachline aligned
1398 sync ; RDR 0 write sequence
1402 b,n perf_rdr_shift_out_U_leave
1407 sync ; RDR 1 write sequence
1411 b,n perf_rdr_shift_out_U_leave
1416 sync ; RDR 2 write sequence
1420 b,n perf_rdr_shift_out_U_leave
1425 sync ; RDR 3 write sequence
1429 b,n perf_rdr_shift_out_U_leave
1434 sync ; RDR 4 write sequence
1438 b,n perf_rdr_shift_out_U_leave
1443 sync ; RDR 5 write sequence
1447 b,n perf_rdr_shift_out_U_leave
1452 sync ; RDR 6 write sequence
1456 b,n perf_rdr_shift_out_U_leave
1461 sync ; RDR 7 write sequence
1465 b,n perf_rdr_shift_out_U_leave
1470 sync ; RDR 8 write sequence
1474 b,n perf_rdr_shift_out_U_leave
1479 sync ; RDR 9 write sequence
1483 b,n perf_rdr_shift_out_U_leave
1488 sync ; RDR 10 write sequence
1492 b,n perf_rdr_shift_out_U_leave
1497 sync ; RDR 11 write sequence
1501 b,n perf_rdr_shift_out_U_leave
1506 sync ; RDR 12 write sequence
1510 b,n perf_rdr_shift_out_U_leave
1515 sync ; RDR 13 write sequence
1519 b,n perf_rdr_shift_out_U_leave
1524 sync ; RDR 14 write sequence
1528 b,n perf_rdr_shift_out_U_leave
1533 sync ; RDR 15 write sequence
1537 b,n perf_rdr_shift_out_U_leave
1542 sync ; RDR 16 write sequence
1546 b,n perf_rdr_shift_out_U_leave
1551 sync ; RDR 17 write sequence
1555 b,n perf_rdr_shift_out_U_leave
1560 sync ; RDR 18 write sequence
1564 b,n perf_rdr_shift_out_U_leave
1569 sync ; RDR 19 write sequence
1573 b,n perf_rdr_shift_out_U_leave
1578 sync ; RDR 20 write sequence
1582 b,n perf_rdr_shift_out_U_leave
1587 sync ; RDR 21 write sequence
1591 b,n perf_rdr_shift_out_U_leave
1596 sync ; RDR 22 write sequence
1600 b,n perf_rdr_shift_out_U_leave
1605 sync ; RDR 23 write sequence
1609 b,n perf_rdr_shift_out_U_leave
1614 sync ; RDR 24 write sequence
1618 b,n perf_rdr_shift_out_U_leave
1623 sync ; RDR 25 write sequence
1627 b,n perf_rdr_shift_out_U_leave
1632 sync ; RDR 26 write sequence
1636 b,n perf_rdr_shift_out_U_leave
1641 sync ; RDR 27 write sequence
1645 b,n perf_rdr_shift_out_U_leave
1650 sync ; RDR 28 write sequence
1654 b,n perf_rdr_shift_out_U_leave
1659 sync ; RDR 29 write sequence
1663 b,n perf_rdr_shift_out_U_leave
1668 sync ; RDR 30 write sequence
1672 b,n perf_rdr_shift_out_U_leave
1677 sync ; RDR 31 write sequence
1681 b,n perf_rdr_shift_out_U_leave
1686 perf_rdr_shift_out_U_leave:
1689 MTDIAG_2 (23) ; restore DR2
1691 ENDPROC(perf_rdr_shift_out_U)