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>
23 #include <linux/linkage.h>
27 #endif /* CONFIG_64BIT */
29 #define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
30 #define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
31 #define MFDIAG_1(gr) .word 0x142008A0 + gr
32 #define MFDIAG_2(gr) .word 0x144008A0 + gr
33 #define STDIAG(dr) .word 0x14000AA0 + dr*0x200000
34 #define SFDIAG(dr) .word 0x14000BA0 + dr*0x200000
35 #define DR2_SLOW_RET 53
39 ; Enable the performance counters
41 ; The coprocessor only needs to be enabled when
42 ; starting/stopping the coprocessor with the pmenb/pmdis.
46 ENTRY(perf_intrigue_enable_perf_counters)
48 .callinfo frame=0,NO_CALLS
51 ldi 0x20,%r25 ; load up perfmon bit
52 mfctl ccr,%r26 ; get coprocessor register
53 or %r25,%r26,%r26 ; set bit
54 mtctl %r26,ccr ; turn on performance coprocessor
55 pmenb ; enable performance monitor
56 ssm 0,0 ; dummy op to ensure completion
58 andcm %r26,%r25,%r26 ; clear bit now
59 mtctl %r26,ccr ; turn off performance coprocessor
60 nop ; NOPs as specified in ERS
71 ENDPROC(perf_intrigue_enable_perf_counters)
73 ENTRY(perf_intrigue_disable_perf_counters)
75 .callinfo frame=0,NO_CALLS
77 ldi 0x20,%r25 ; load up perfmon bit
78 mfctl ccr,%r26 ; get coprocessor register
79 or %r25,%r26,%r26 ; set bit
80 mtctl %r26,ccr ; turn on performance coprocessor
81 pmdis ; disable performance monitor
82 ssm 0,0 ; dummy op to ensure completion
83 andcm %r26,%r25,%r26 ; clear bit now
85 mtctl %r26,ccr ; turn off performance coprocessor
88 ENDPROC(perf_intrigue_disable_perf_counters)
90 ;***********************************************************************
92 ;* Name: perf_rdr_shift_in_W
95 ;* This routine shifts data in from the RDR in arg0 and returns
96 ;* the result in ret0. If the RDR is <= 64 bits in length, it
97 ;* is shifted shifted backup immediately. This is to compensate
98 ;* for RDR10 which has bits that preclude PDC stack operations
99 ;* when they are in the wrong state.
102 ;* arg0 : rdr to be read
103 ;* arg1 : bit length of rdr
106 ;* ret0 = next 64 bits of rdr data from staging register
109 ;* arg0 : rdr to be read
110 ;* arg1 : bit length of rdr
111 ;* %r24 - original DR2 value
116 ;* ret0 = RDR data (right justified)
118 ;***********************************************************************
120 ENTRY(perf_rdr_shift_in_W)
122 .callinfo frame=0,NO_CALLS
125 ; read(shift in) the RDR.
128 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
129 ; shifting is done, from or to, remote diagnose registers.
132 depdi,z 1,DR2_SLOW_RET,1,%r29
135 MTDIAG_2 (29) ; set DR2_SLOW_RET
143 ; Cacheline start (32-byte cacheline)
148 extrd,u arg1,63,6,%r1 ; setup shift amount by bits to move
151 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
152 blr %r1,%r0 ; branch to 8-instruction sequence
156 ; Cacheline start (32-byte cacheline)
165 shrpd ret0,%r0,%sar,%r1
166 MTDIAG_1 (1) ; mtdiag %dr1, %r1
169 b,n perf_rdr_shift_in_W_leave
180 b,n perf_rdr_shift_in_W_leave
184 ; RDR 2 read sequence
189 shrpd ret0,%r0,%sar,%r1
193 b,n perf_rdr_shift_in_W_leave
196 ; RDR 3 read sequence
198 b,n perf_rdr_shift_in_W_leave
208 ; RDR 4 read sequence
215 b,n perf_rdr_shift_in_W_leave
220 ; RDR 5 read sequence
227 b,n perf_rdr_shift_in_W_leave
232 ; RDR 6 read sequence
239 b,n perf_rdr_shift_in_W_leave
244 ; RDR 7 read sequence
246 b,n perf_rdr_shift_in_W_leave
256 ; RDR 8 read sequence
258 b,n perf_rdr_shift_in_W_leave
268 ; RDR 9 read sequence
270 b,n perf_rdr_shift_in_W_leave
280 ; RDR 10 read sequence
285 shrpd ret0,%r0,%sar,%r1
289 b,n perf_rdr_shift_in_W_leave
292 ; RDR 11 read sequence
297 shrpd ret0,%r0,%sar,%r1
301 b,n perf_rdr_shift_in_W_leave
304 ; RDR 12 read sequence
306 b,n perf_rdr_shift_in_W_leave
316 ; RDR 13 read sequence
323 b,n perf_rdr_shift_in_W_leave
328 ; RDR 14 read sequence
333 shrpd ret0,%r0,%sar,%r1
337 b,n perf_rdr_shift_in_W_leave
340 ; RDR 15 read sequence
348 b,n perf_rdr_shift_in_W_leave
352 ; RDR 16 read sequence
359 b,n perf_rdr_shift_in_W_leave
364 ; RDR 17 read sequence
369 shrpd ret0,%r0,%sar,%r1
373 b,n perf_rdr_shift_in_W_leave
376 ; RDR 18 read sequence
381 shrpd ret0,%r0,%sar,%r1
385 b,n perf_rdr_shift_in_W_leave
388 ; RDR 19 read sequence
390 b,n perf_rdr_shift_in_W_leave
400 ; RDR 20 read sequence
407 b,n perf_rdr_shift_in_W_leave
412 ; RDR 21 read sequence
419 b,n perf_rdr_shift_in_W_leave
424 ; RDR 22 read sequence
431 b,n perf_rdr_shift_in_W_leave
436 ; RDR 23 read sequence
443 b,n perf_rdr_shift_in_W_leave
448 ; RDR 24 read sequence
455 b,n perf_rdr_shift_in_W_leave
460 ; RDR 25 read sequence
467 b,n perf_rdr_shift_in_W_leave
472 ; RDR 26 read sequence
477 shrpd ret0,%r0,%sar,%r1
481 b,n perf_rdr_shift_in_W_leave
484 ; RDR 27 read sequence
489 shrpd ret0,%r0,%sar,%r1
493 b,n perf_rdr_shift_in_W_leave
496 ; RDR 28 read sequence
503 b,n perf_rdr_shift_in_W_leave
508 ; RDR 29 read sequence
515 b,n perf_rdr_shift_in_W_leave
520 ; RDR 30 read sequence
525 shrpd ret0,%r0,%sar,%r1
529 b,n perf_rdr_shift_in_W_leave
532 ; RDR 31 read sequence
547 perf_rdr_shift_in_W_leave:
550 MTDIAG_2 (24) ; restore DR2
552 ENDPROC(perf_rdr_shift_in_W)
555 ;***********************************************************************
557 ;* Name: perf_rdr_shift_out_W
560 ;* This routine moves data to the RDR's. The double-word that
561 ;* arg1 points to is loaded and moved into the staging register.
562 ;* Then the STDIAG instruction for the RDR # in arg0 is called
563 ;* to move the data to the RDR.
567 ;* arg1 = 64-bit value to write
568 ;* %r24 - DR2 | DR2_SLOW_RET
569 ;* %r23 - original DR2 value
576 ;***********************************************************************
578 ENTRY(perf_rdr_shift_out_W)
580 .callinfo frame=0,NO_CALLS
583 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
584 ; shifting is done, from or to, the remote diagnose registers.
587 depdi,z 1,DR2_SLOW_RET,1,%r24
590 MTDIAG_2 (24) ; set DR2_SLOW_RET
591 MTDIAG_1 (25) ; data to the staging register
592 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
593 blr %r1,%r0 ; branch to 8-instruction sequence
597 ; RDR 0 write sequence
599 sync ; RDR 0 write sequence
603 b,n perf_rdr_shift_out_W_leave
609 ; RDR 1 write sequence
615 b,n perf_rdr_shift_out_W_leave
621 ; RDR 2 write sequence
627 b,n perf_rdr_shift_out_W_leave
633 ; RDR 3 write sequence
639 b,n perf_rdr_shift_out_W_leave
645 ; RDR 4 write sequence
651 b,n perf_rdr_shift_out_W_leave
657 ; RDR 5 write sequence
663 b,n perf_rdr_shift_out_W_leave
669 ; RDR 6 write sequence
675 b,n perf_rdr_shift_out_W_leave
681 ; RDR 7 write sequence
687 b,n perf_rdr_shift_out_W_leave
693 ; RDR 8 write sequence
699 b,n perf_rdr_shift_out_W_leave
705 ; RDR 9 write sequence
711 b,n perf_rdr_shift_out_W_leave
717 ; RDR 10 write sequence
724 b,n perf_rdr_shift_out_W_leave
729 ; RDR 11 write sequence
736 b,n perf_rdr_shift_out_W_leave
741 ; RDR 12 write sequence
747 b,n perf_rdr_shift_out_W_leave
753 ; RDR 13 write sequence
759 b,n perf_rdr_shift_out_W_leave
765 ; RDR 14 write sequence
771 b,n perf_rdr_shift_out_W_leave
777 ; RDR 15 write sequence
783 b,n perf_rdr_shift_out_W_leave
789 ; RDR 16 write sequence
795 b,n perf_rdr_shift_out_W_leave
801 ; RDR 17 write sequence
807 b,n perf_rdr_shift_out_W_leave
813 ; RDR 18 write sequence
819 b,n perf_rdr_shift_out_W_leave
825 ; RDR 19 write sequence
831 b,n perf_rdr_shift_out_W_leave
837 ; RDR 20 write sequence
843 b,n perf_rdr_shift_out_W_leave
849 ; RDR 21 write sequence
855 b,n perf_rdr_shift_out_W_leave
861 ; RDR 22 write sequence
867 b,n perf_rdr_shift_out_W_leave
873 ; RDR 23 write sequence
879 b,n perf_rdr_shift_out_W_leave
885 ; RDR 24 write sequence
891 b,n perf_rdr_shift_out_W_leave
897 ; RDR 25 write sequence
903 b,n perf_rdr_shift_out_W_leave
909 ; RDR 26 write sequence
916 b,n perf_rdr_shift_out_W_leave
921 ; RDR 27 write sequence
928 b,n perf_rdr_shift_out_W_leave
933 ; RDR 28 write sequence
939 b,n perf_rdr_shift_out_W_leave
945 ; RDR 29 write sequence
951 b,n perf_rdr_shift_out_W_leave
957 ; RDR 30 write sequence
963 b,n perf_rdr_shift_out_W_leave
969 ; RDR 31 write sequence
975 b,n perf_rdr_shift_out_W_leave
980 perf_rdr_shift_out_W_leave:
983 MTDIAG_2 (23) ; restore DR2
985 ENDPROC(perf_rdr_shift_out_W)
988 ;***********************************************************************
990 ;* Name: rdr_shift_in_U
993 ;* This routine shifts data in from the RDR in arg0 and returns
994 ;* the result in ret0. If the RDR is <= 64 bits in length, it
995 ;* is shifted shifted backup immediately. This is to compensate
996 ;* for RDR10 which has bits that preclude PDC stack operations
997 ;* when they are in the wrong state.
1000 ;* arg0 : rdr to be read
1001 ;* arg1 : bit length of rdr
1004 ;* ret0 = next 64 bits of rdr data from staging register
1007 ;* arg0 : rdr to be read
1008 ;* arg1 : bit length of rdr
1009 ;* %r24 - original DR2 value
1010 ;* %r23 - DR2 | DR2_SLOW_RET
1013 ;***********************************************************************
1015 ENTRY(perf_rdr_shift_in_U)
1017 .callinfo frame=0,NO_CALLS
1020 ; read(shift in) the RDR.
1022 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1023 ; shifting is done, from or to, remote diagnose registers.
1025 depdi,z 1,DR2_SLOW_RET,1,%r29
1028 MTDIAG_2 (29) ; set DR2_SLOW_RET
1036 ; Start of next 32-byte cacheline
1041 extrd,u arg1,63,6,%r1
1044 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1045 blr %r1,%r0 ; branch to 8-instruction sequence
1049 ; Start of next 32-byte cacheline
1051 SFDIAG (0) ; RDR 0 read sequence
1054 shrpd ret0,%r0,%sar,%r1
1058 b,n perf_rdr_shift_in_U_leave
1060 SFDIAG (1) ; RDR 1 read sequence
1063 shrpd ret0,%r0,%sar,%r1
1067 b,n perf_rdr_shift_in_U_leave
1069 sync ; RDR 2 read sequence
1074 b,n perf_rdr_shift_in_U_leave
1078 sync ; RDR 3 read sequence
1083 b,n perf_rdr_shift_in_U_leave
1087 sync ; RDR 4 read sequence
1092 b,n perf_rdr_shift_in_U_leave
1096 sync ; RDR 5 read sequence
1101 b,n perf_rdr_shift_in_U_leave
1105 sync ; RDR 6 read sequence
1110 b,n perf_rdr_shift_in_U_leave
1114 sync ; RDR 7 read sequence
1119 b,n perf_rdr_shift_in_U_leave
1123 b,n perf_rdr_shift_in_U_leave
1132 SFDIAG (9) ; RDR 9 read sequence
1135 shrpd ret0,%r0,%sar,%r1
1139 b,n perf_rdr_shift_in_U_leave
1141 SFDIAG (10) ; RDR 10 read sequence
1144 shrpd ret0,%r0,%sar,%r1
1148 b,n perf_rdr_shift_in_U_leave
1150 SFDIAG (11) ; RDR 11 read sequence
1153 shrpd ret0,%r0,%sar,%r1
1157 b,n perf_rdr_shift_in_U_leave
1159 SFDIAG (12) ; RDR 12 read sequence
1162 shrpd ret0,%r0,%sar,%r1
1166 b,n perf_rdr_shift_in_U_leave
1168 SFDIAG (13) ; RDR 13 read sequence
1171 shrpd ret0,%r0,%sar,%r1
1175 b,n perf_rdr_shift_in_U_leave
1177 SFDIAG (14) ; RDR 14 read sequence
1180 shrpd ret0,%r0,%sar,%r1
1184 b,n perf_rdr_shift_in_U_leave
1186 SFDIAG (15) ; RDR 15 read sequence
1189 shrpd ret0,%r0,%sar,%r1
1193 b,n perf_rdr_shift_in_U_leave
1195 sync ; RDR 16 read sequence
1200 b,n perf_rdr_shift_in_U_leave
1204 SFDIAG (17) ; RDR 17 read sequence
1207 shrpd ret0,%r0,%sar,%r1
1211 b,n perf_rdr_shift_in_U_leave
1213 SFDIAG (18) ; RDR 18 read sequence
1216 shrpd ret0,%r0,%sar,%r1
1220 b,n perf_rdr_shift_in_U_leave
1222 b,n perf_rdr_shift_in_U_leave
1231 sync ; RDR 20 read sequence
1236 b,n perf_rdr_shift_in_U_leave
1240 sync ; RDR 21 read sequence
1245 b,n perf_rdr_shift_in_U_leave
1249 sync ; RDR 22 read sequence
1254 b,n perf_rdr_shift_in_U_leave
1258 sync ; RDR 23 read sequence
1263 b,n perf_rdr_shift_in_U_leave
1267 sync ; RDR 24 read sequence
1272 b,n perf_rdr_shift_in_U_leave
1276 sync ; RDR 25 read sequence
1281 b,n perf_rdr_shift_in_U_leave
1285 SFDIAG (26) ; RDR 26 read sequence
1288 shrpd ret0,%r0,%sar,%r1
1292 b,n perf_rdr_shift_in_U_leave
1294 SFDIAG (27) ; RDR 27 read sequence
1297 shrpd ret0,%r0,%sar,%r1
1301 b,n perf_rdr_shift_in_U_leave
1303 sync ; RDR 28 read sequence
1308 b,n perf_rdr_shift_in_U_leave
1312 b,n perf_rdr_shift_in_U_leave
1321 SFDIAG (30) ; RDR 30 read sequence
1324 shrpd ret0,%r0,%sar,%r1
1328 b,n perf_rdr_shift_in_U_leave
1330 SFDIAG (31) ; RDR 31 read sequence
1333 shrpd ret0,%r0,%sar,%r1
1337 b,n perf_rdr_shift_in_U_leave
1340 perf_rdr_shift_in_U_leave:
1343 MTDIAG_2 (24) ; restore DR2
1345 ENDPROC(perf_rdr_shift_in_U)
1347 ;***********************************************************************
1349 ;* Name: rdr_shift_out_U
1352 ;* This routine moves data to the RDR's. The double-word that
1353 ;* arg1 points to is loaded and moved into the staging register.
1354 ;* Then the STDIAG instruction for the RDR # in arg0 is called
1355 ;* to move the data to the RDR.
1358 ;* arg0 = rdr target
1359 ;* arg1 = buffer pointer
1365 ;* arg0 = rdr target
1366 ;* arg1 = buffer pointer
1367 ;* %r24 - DR2 | DR2_SLOW_RET
1368 ;* %r23 - original DR2 value
1370 ;***********************************************************************
1372 ENTRY(perf_rdr_shift_out_U)
1374 .callinfo frame=0,NO_CALLS
1378 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1379 ; shifting is done, from or to, the remote diagnose registers.
1382 depdi,z 1,DR2_SLOW_RET,1,%r24
1385 MTDIAG_2 (24) ; set DR2_SLOW_RET
1387 MTDIAG_1 (25) ; data to the staging register
1388 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1389 blr %r1,%r0 ; branch to 8-instruction sequence
1393 ; 32-byte cachline aligned
1396 sync ; RDR 0 write sequence
1400 b,n perf_rdr_shift_out_U_leave
1405 sync ; RDR 1 write sequence
1409 b,n perf_rdr_shift_out_U_leave
1414 sync ; RDR 2 write sequence
1418 b,n perf_rdr_shift_out_U_leave
1423 sync ; RDR 3 write sequence
1427 b,n perf_rdr_shift_out_U_leave
1432 sync ; RDR 4 write sequence
1436 b,n perf_rdr_shift_out_U_leave
1441 sync ; RDR 5 write sequence
1445 b,n perf_rdr_shift_out_U_leave
1450 sync ; RDR 6 write sequence
1454 b,n perf_rdr_shift_out_U_leave
1459 sync ; RDR 7 write sequence
1463 b,n perf_rdr_shift_out_U_leave
1468 sync ; RDR 8 write sequence
1472 b,n perf_rdr_shift_out_U_leave
1477 sync ; RDR 9 write sequence
1481 b,n perf_rdr_shift_out_U_leave
1486 sync ; RDR 10 write sequence
1490 b,n perf_rdr_shift_out_U_leave
1495 sync ; RDR 11 write sequence
1499 b,n perf_rdr_shift_out_U_leave
1504 sync ; RDR 12 write sequence
1508 b,n perf_rdr_shift_out_U_leave
1513 sync ; RDR 13 write sequence
1517 b,n perf_rdr_shift_out_U_leave
1522 sync ; RDR 14 write sequence
1526 b,n perf_rdr_shift_out_U_leave
1531 sync ; RDR 15 write sequence
1535 b,n perf_rdr_shift_out_U_leave
1540 sync ; RDR 16 write sequence
1544 b,n perf_rdr_shift_out_U_leave
1549 sync ; RDR 17 write sequence
1553 b,n perf_rdr_shift_out_U_leave
1558 sync ; RDR 18 write sequence
1562 b,n perf_rdr_shift_out_U_leave
1567 sync ; RDR 19 write sequence
1571 b,n perf_rdr_shift_out_U_leave
1576 sync ; RDR 20 write sequence
1580 b,n perf_rdr_shift_out_U_leave
1585 sync ; RDR 21 write sequence
1589 b,n perf_rdr_shift_out_U_leave
1594 sync ; RDR 22 write sequence
1598 b,n perf_rdr_shift_out_U_leave
1603 sync ; RDR 23 write sequence
1607 b,n perf_rdr_shift_out_U_leave
1612 sync ; RDR 24 write sequence
1616 b,n perf_rdr_shift_out_U_leave
1621 sync ; RDR 25 write sequence
1625 b,n perf_rdr_shift_out_U_leave
1630 sync ; RDR 26 write sequence
1634 b,n perf_rdr_shift_out_U_leave
1639 sync ; RDR 27 write sequence
1643 b,n perf_rdr_shift_out_U_leave
1648 sync ; RDR 28 write sequence
1652 b,n perf_rdr_shift_out_U_leave
1657 sync ; RDR 29 write sequence
1661 b,n perf_rdr_shift_out_U_leave
1666 sync ; RDR 30 write sequence
1670 b,n perf_rdr_shift_out_U_leave
1675 sync ; RDR 31 write sequence
1679 b,n perf_rdr_shift_out_U_leave
1684 perf_rdr_shift_out_U_leave:
1687 MTDIAG_2 (23) ; restore DR2
1689 ENDPROC(perf_rdr_shift_out_U)