1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /* low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
5 * Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
6 * Copyright (C) 2001 Hewlett-Packard (Grant Grundler)
9 #include <asm/assembly.h>
11 #include <linux/init.h>
12 #include <linux/linkage.h>
16 #endif /* CONFIG_64BIT */
18 #define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
19 #define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
20 #define MFDIAG_1(gr) .word 0x142008A0 + gr
21 #define MFDIAG_2(gr) .word 0x144008A0 + gr
22 #define STDIAG(dr) .word 0x14000AA0 + dr*0x200000
23 #define SFDIAG(dr) .word 0x14000BA0 + dr*0x200000
24 #define DR2_SLOW_RET 53
28 ; Enable the performance counters
30 ; The coprocessor only needs to be enabled when
31 ; starting/stopping the coprocessor with the pmenb/pmdis.
35 ENTRY(perf_intrigue_enable_perf_counters)
37 .callinfo frame=0,NO_CALLS
40 ldi 0x20,%r25 ; load up perfmon bit
41 mfctl ccr,%r26 ; get coprocessor register
42 or %r25,%r26,%r26 ; set bit
43 mtctl %r26,ccr ; turn on performance coprocessor
44 pmenb ; enable performance monitor
45 ssm 0,0 ; dummy op to ensure completion
47 andcm %r26,%r25,%r26 ; clear bit now
48 mtctl %r26,ccr ; turn off performance coprocessor
49 nop ; NOPs as specified in ERS
60 ENDPROC(perf_intrigue_enable_perf_counters)
62 ENTRY(perf_intrigue_disable_perf_counters)
64 .callinfo frame=0,NO_CALLS
66 ldi 0x20,%r25 ; load up perfmon bit
67 mfctl ccr,%r26 ; get coprocessor register
68 or %r25,%r26,%r26 ; set bit
69 mtctl %r26,ccr ; turn on performance coprocessor
70 pmdis ; disable performance monitor
71 ssm 0,0 ; dummy op to ensure completion
72 andcm %r26,%r25,%r26 ; clear bit now
74 mtctl %r26,ccr ; turn off performance coprocessor
77 ENDPROC(perf_intrigue_disable_perf_counters)
79 ;***********************************************************************
81 ;* Name: perf_rdr_shift_in_W
84 ;* This routine shifts data in from the RDR in arg0 and returns
85 ;* the result in ret0. If the RDR is <= 64 bits in length, it
86 ;* is shifted shifted backup immediately. This is to compensate
87 ;* for RDR10 which has bits that preclude PDC stack operations
88 ;* when they are in the wrong state.
91 ;* arg0 : rdr to be read
92 ;* arg1 : bit length of rdr
95 ;* ret0 = next 64 bits of rdr data from staging register
98 ;* arg0 : rdr to be read
99 ;* arg1 : bit length of rdr
100 ;* %r24 - original DR2 value
105 ;* ret0 = RDR data (right justified)
107 ;***********************************************************************
109 ENTRY(perf_rdr_shift_in_W)
111 .callinfo frame=0,NO_CALLS
114 ; read(shift in) the RDR.
117 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
118 ; shifting is done, from or to, remote diagnose registers.
121 depdi,z 1,DR2_SLOW_RET,1,%r29
124 MTDIAG_2 (29) ; set DR2_SLOW_RET
132 ; Cacheline start (32-byte cacheline)
137 extrd,u arg1,63,6,%r1 ; setup shift amount by bits to move
140 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
141 blr %r1,%r0 ; branch to 8-instruction sequence
145 ; Cacheline start (32-byte cacheline)
154 shrpd ret0,%r0,%sar,%r1
155 MTDIAG_1 (1) ; mtdiag %dr1, %r1
158 b,n perf_rdr_shift_in_W_leave
169 b,n perf_rdr_shift_in_W_leave
173 ; RDR 2 read sequence
178 shrpd ret0,%r0,%sar,%r1
182 b,n perf_rdr_shift_in_W_leave
185 ; RDR 3 read sequence
187 b,n perf_rdr_shift_in_W_leave
197 ; RDR 4 read sequence
204 b,n perf_rdr_shift_in_W_leave
209 ; RDR 5 read sequence
216 b,n perf_rdr_shift_in_W_leave
221 ; RDR 6 read sequence
228 b,n perf_rdr_shift_in_W_leave
233 ; RDR 7 read sequence
235 b,n perf_rdr_shift_in_W_leave
245 ; RDR 8 read sequence
247 b,n perf_rdr_shift_in_W_leave
257 ; RDR 9 read sequence
259 b,n perf_rdr_shift_in_W_leave
269 ; RDR 10 read sequence
274 shrpd ret0,%r0,%sar,%r1
278 b,n perf_rdr_shift_in_W_leave
281 ; RDR 11 read sequence
286 shrpd ret0,%r0,%sar,%r1
290 b,n perf_rdr_shift_in_W_leave
293 ; RDR 12 read sequence
295 b,n perf_rdr_shift_in_W_leave
305 ; RDR 13 read sequence
312 b,n perf_rdr_shift_in_W_leave
317 ; RDR 14 read sequence
322 shrpd ret0,%r0,%sar,%r1
326 b,n perf_rdr_shift_in_W_leave
329 ; RDR 15 read sequence
337 b,n perf_rdr_shift_in_W_leave
341 ; RDR 16 read sequence
348 b,n perf_rdr_shift_in_W_leave
353 ; RDR 17 read sequence
358 shrpd ret0,%r0,%sar,%r1
362 b,n perf_rdr_shift_in_W_leave
365 ; RDR 18 read sequence
370 shrpd ret0,%r0,%sar,%r1
374 b,n perf_rdr_shift_in_W_leave
377 ; RDR 19 read sequence
379 b,n perf_rdr_shift_in_W_leave
389 ; RDR 20 read sequence
396 b,n perf_rdr_shift_in_W_leave
401 ; RDR 21 read sequence
408 b,n perf_rdr_shift_in_W_leave
413 ; RDR 22 read sequence
420 b,n perf_rdr_shift_in_W_leave
425 ; RDR 23 read sequence
432 b,n perf_rdr_shift_in_W_leave
437 ; RDR 24 read sequence
444 b,n perf_rdr_shift_in_W_leave
449 ; RDR 25 read sequence
456 b,n perf_rdr_shift_in_W_leave
461 ; RDR 26 read sequence
466 shrpd ret0,%r0,%sar,%r1
470 b,n perf_rdr_shift_in_W_leave
473 ; RDR 27 read sequence
478 shrpd ret0,%r0,%sar,%r1
482 b,n perf_rdr_shift_in_W_leave
485 ; RDR 28 read sequence
492 b,n perf_rdr_shift_in_W_leave
497 ; RDR 29 read sequence
504 b,n perf_rdr_shift_in_W_leave
509 ; RDR 30 read sequence
514 shrpd ret0,%r0,%sar,%r1
518 b,n perf_rdr_shift_in_W_leave
521 ; RDR 31 read sequence
536 perf_rdr_shift_in_W_leave:
539 MTDIAG_2 (24) ; restore DR2
541 ENDPROC(perf_rdr_shift_in_W)
544 ;***********************************************************************
546 ;* Name: perf_rdr_shift_out_W
549 ;* This routine moves data to the RDR's. The double-word that
550 ;* arg1 points to is loaded and moved into the staging register.
551 ;* Then the STDIAG instruction for the RDR # in arg0 is called
552 ;* to move the data to the RDR.
556 ;* arg1 = 64-bit value to write
557 ;* %r24 - DR2 | DR2_SLOW_RET
558 ;* %r23 - original DR2 value
565 ;***********************************************************************
567 ENTRY(perf_rdr_shift_out_W)
569 .callinfo frame=0,NO_CALLS
572 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
573 ; shifting is done, from or to, the remote diagnose registers.
576 depdi,z 1,DR2_SLOW_RET,1,%r24
579 MTDIAG_2 (24) ; set DR2_SLOW_RET
580 MTDIAG_1 (25) ; data to the staging register
581 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
582 blr %r1,%r0 ; branch to 8-instruction sequence
586 ; RDR 0 write sequence
588 sync ; RDR 0 write sequence
592 b,n perf_rdr_shift_out_W_leave
598 ; RDR 1 write sequence
604 b,n perf_rdr_shift_out_W_leave
610 ; RDR 2 write sequence
616 b,n perf_rdr_shift_out_W_leave
622 ; RDR 3 write sequence
628 b,n perf_rdr_shift_out_W_leave
634 ; RDR 4 write sequence
640 b,n perf_rdr_shift_out_W_leave
646 ; RDR 5 write sequence
652 b,n perf_rdr_shift_out_W_leave
658 ; RDR 6 write sequence
664 b,n perf_rdr_shift_out_W_leave
670 ; RDR 7 write sequence
676 b,n perf_rdr_shift_out_W_leave
682 ; RDR 8 write sequence
688 b,n perf_rdr_shift_out_W_leave
694 ; RDR 9 write sequence
700 b,n perf_rdr_shift_out_W_leave
706 ; RDR 10 write sequence
713 b,n perf_rdr_shift_out_W_leave
718 ; RDR 11 write sequence
725 b,n perf_rdr_shift_out_W_leave
730 ; RDR 12 write sequence
736 b,n perf_rdr_shift_out_W_leave
742 ; RDR 13 write sequence
748 b,n perf_rdr_shift_out_W_leave
754 ; RDR 14 write sequence
760 b,n perf_rdr_shift_out_W_leave
766 ; RDR 15 write sequence
772 b,n perf_rdr_shift_out_W_leave
778 ; RDR 16 write sequence
784 b,n perf_rdr_shift_out_W_leave
790 ; RDR 17 write sequence
796 b,n perf_rdr_shift_out_W_leave
802 ; RDR 18 write sequence
808 b,n perf_rdr_shift_out_W_leave
814 ; RDR 19 write sequence
820 b,n perf_rdr_shift_out_W_leave
826 ; RDR 20 write sequence
832 b,n perf_rdr_shift_out_W_leave
838 ; RDR 21 write sequence
844 b,n perf_rdr_shift_out_W_leave
850 ; RDR 22 write sequence
856 b,n perf_rdr_shift_out_W_leave
862 ; RDR 23 write sequence
868 b,n perf_rdr_shift_out_W_leave
874 ; RDR 24 write sequence
880 b,n perf_rdr_shift_out_W_leave
886 ; RDR 25 write sequence
892 b,n perf_rdr_shift_out_W_leave
898 ; RDR 26 write sequence
905 b,n perf_rdr_shift_out_W_leave
910 ; RDR 27 write sequence
917 b,n perf_rdr_shift_out_W_leave
922 ; RDR 28 write sequence
928 b,n perf_rdr_shift_out_W_leave
934 ; RDR 29 write sequence
940 b,n perf_rdr_shift_out_W_leave
946 ; RDR 30 write sequence
952 b,n perf_rdr_shift_out_W_leave
958 ; RDR 31 write sequence
964 b,n perf_rdr_shift_out_W_leave
969 perf_rdr_shift_out_W_leave:
972 MTDIAG_2 (23) ; restore DR2
974 ENDPROC(perf_rdr_shift_out_W)
977 ;***********************************************************************
979 ;* Name: rdr_shift_in_U
982 ;* This routine shifts data in from the RDR in arg0 and returns
983 ;* the result in ret0. If the RDR is <= 64 bits in length, it
984 ;* is shifted shifted backup immediately. This is to compensate
985 ;* for RDR10 which has bits that preclude PDC stack operations
986 ;* when they are in the wrong state.
989 ;* arg0 : rdr to be read
990 ;* arg1 : bit length of rdr
993 ;* ret0 = next 64 bits of rdr data from staging register
996 ;* arg0 : rdr to be read
997 ;* arg1 : bit length of rdr
998 ;* %r24 - original DR2 value
999 ;* %r23 - DR2 | DR2_SLOW_RET
1002 ;***********************************************************************
1004 ENTRY(perf_rdr_shift_in_U)
1006 .callinfo frame=0,NO_CALLS
1009 ; read(shift in) the RDR.
1011 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1012 ; shifting is done, from or to, remote diagnose registers.
1014 depdi,z 1,DR2_SLOW_RET,1,%r29
1017 MTDIAG_2 (29) ; set DR2_SLOW_RET
1025 ; Start of next 32-byte cacheline
1030 extrd,u arg1,63,6,%r1
1033 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1034 blr %r1,%r0 ; branch to 8-instruction sequence
1038 ; Start of next 32-byte cacheline
1040 SFDIAG (0) ; RDR 0 read sequence
1043 shrpd ret0,%r0,%sar,%r1
1047 b,n perf_rdr_shift_in_U_leave
1049 SFDIAG (1) ; RDR 1 read sequence
1052 shrpd ret0,%r0,%sar,%r1
1056 b,n perf_rdr_shift_in_U_leave
1058 sync ; RDR 2 read sequence
1063 b,n perf_rdr_shift_in_U_leave
1067 sync ; RDR 3 read sequence
1072 b,n perf_rdr_shift_in_U_leave
1076 sync ; RDR 4 read sequence
1081 b,n perf_rdr_shift_in_U_leave
1085 sync ; RDR 5 read sequence
1090 b,n perf_rdr_shift_in_U_leave
1094 sync ; RDR 6 read sequence
1099 b,n perf_rdr_shift_in_U_leave
1103 sync ; RDR 7 read sequence
1108 b,n perf_rdr_shift_in_U_leave
1112 b,n perf_rdr_shift_in_U_leave
1121 SFDIAG (9) ; RDR 9 read sequence
1124 shrpd ret0,%r0,%sar,%r1
1128 b,n perf_rdr_shift_in_U_leave
1130 SFDIAG (10) ; RDR 10 read sequence
1133 shrpd ret0,%r0,%sar,%r1
1137 b,n perf_rdr_shift_in_U_leave
1139 SFDIAG (11) ; RDR 11 read sequence
1142 shrpd ret0,%r0,%sar,%r1
1146 b,n perf_rdr_shift_in_U_leave
1148 SFDIAG (12) ; RDR 12 read sequence
1151 shrpd ret0,%r0,%sar,%r1
1155 b,n perf_rdr_shift_in_U_leave
1157 SFDIAG (13) ; RDR 13 read sequence
1160 shrpd ret0,%r0,%sar,%r1
1164 b,n perf_rdr_shift_in_U_leave
1166 SFDIAG (14) ; RDR 14 read sequence
1169 shrpd ret0,%r0,%sar,%r1
1173 b,n perf_rdr_shift_in_U_leave
1175 SFDIAG (15) ; RDR 15 read sequence
1178 shrpd ret0,%r0,%sar,%r1
1182 b,n perf_rdr_shift_in_U_leave
1184 sync ; RDR 16 read sequence
1189 b,n perf_rdr_shift_in_U_leave
1193 SFDIAG (17) ; RDR 17 read sequence
1196 shrpd ret0,%r0,%sar,%r1
1200 b,n perf_rdr_shift_in_U_leave
1202 SFDIAG (18) ; RDR 18 read sequence
1205 shrpd ret0,%r0,%sar,%r1
1209 b,n perf_rdr_shift_in_U_leave
1211 b,n perf_rdr_shift_in_U_leave
1220 sync ; RDR 20 read sequence
1225 b,n perf_rdr_shift_in_U_leave
1229 sync ; RDR 21 read sequence
1234 b,n perf_rdr_shift_in_U_leave
1238 sync ; RDR 22 read sequence
1243 b,n perf_rdr_shift_in_U_leave
1247 sync ; RDR 23 read sequence
1252 b,n perf_rdr_shift_in_U_leave
1256 sync ; RDR 24 read sequence
1261 b,n perf_rdr_shift_in_U_leave
1265 sync ; RDR 25 read sequence
1270 b,n perf_rdr_shift_in_U_leave
1274 SFDIAG (26) ; RDR 26 read sequence
1277 shrpd ret0,%r0,%sar,%r1
1281 b,n perf_rdr_shift_in_U_leave
1283 SFDIAG (27) ; RDR 27 read sequence
1286 shrpd ret0,%r0,%sar,%r1
1290 b,n perf_rdr_shift_in_U_leave
1292 sync ; RDR 28 read sequence
1297 b,n perf_rdr_shift_in_U_leave
1301 b,n perf_rdr_shift_in_U_leave
1310 SFDIAG (30) ; RDR 30 read sequence
1313 shrpd ret0,%r0,%sar,%r1
1317 b,n perf_rdr_shift_in_U_leave
1319 SFDIAG (31) ; RDR 31 read sequence
1322 shrpd ret0,%r0,%sar,%r1
1326 b,n perf_rdr_shift_in_U_leave
1329 perf_rdr_shift_in_U_leave:
1332 MTDIAG_2 (24) ; restore DR2
1334 ENDPROC(perf_rdr_shift_in_U)
1336 ;***********************************************************************
1338 ;* Name: rdr_shift_out_U
1341 ;* This routine moves data to the RDR's. The double-word that
1342 ;* arg1 points to is loaded and moved into the staging register.
1343 ;* Then the STDIAG instruction for the RDR # in arg0 is called
1344 ;* to move the data to the RDR.
1347 ;* arg0 = rdr target
1348 ;* arg1 = buffer pointer
1354 ;* arg0 = rdr target
1355 ;* arg1 = buffer pointer
1356 ;* %r24 - DR2 | DR2_SLOW_RET
1357 ;* %r23 - original DR2 value
1359 ;***********************************************************************
1361 ENTRY(perf_rdr_shift_out_U)
1363 .callinfo frame=0,NO_CALLS
1367 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1368 ; shifting is done, from or to, the remote diagnose registers.
1371 depdi,z 1,DR2_SLOW_RET,1,%r24
1374 MTDIAG_2 (24) ; set DR2_SLOW_RET
1376 MTDIAG_1 (25) ; data to the staging register
1377 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1378 blr %r1,%r0 ; branch to 8-instruction sequence
1382 ; 32-byte cachline aligned
1385 sync ; RDR 0 write sequence
1389 b,n perf_rdr_shift_out_U_leave
1394 sync ; RDR 1 write sequence
1398 b,n perf_rdr_shift_out_U_leave
1403 sync ; RDR 2 write sequence
1407 b,n perf_rdr_shift_out_U_leave
1412 sync ; RDR 3 write sequence
1416 b,n perf_rdr_shift_out_U_leave
1421 sync ; RDR 4 write sequence
1425 b,n perf_rdr_shift_out_U_leave
1430 sync ; RDR 5 write sequence
1434 b,n perf_rdr_shift_out_U_leave
1439 sync ; RDR 6 write sequence
1443 b,n perf_rdr_shift_out_U_leave
1448 sync ; RDR 7 write sequence
1452 b,n perf_rdr_shift_out_U_leave
1457 sync ; RDR 8 write sequence
1461 b,n perf_rdr_shift_out_U_leave
1466 sync ; RDR 9 write sequence
1470 b,n perf_rdr_shift_out_U_leave
1475 sync ; RDR 10 write sequence
1479 b,n perf_rdr_shift_out_U_leave
1484 sync ; RDR 11 write sequence
1488 b,n perf_rdr_shift_out_U_leave
1493 sync ; RDR 12 write sequence
1497 b,n perf_rdr_shift_out_U_leave
1502 sync ; RDR 13 write sequence
1506 b,n perf_rdr_shift_out_U_leave
1511 sync ; RDR 14 write sequence
1515 b,n perf_rdr_shift_out_U_leave
1520 sync ; RDR 15 write sequence
1524 b,n perf_rdr_shift_out_U_leave
1529 sync ; RDR 16 write sequence
1533 b,n perf_rdr_shift_out_U_leave
1538 sync ; RDR 17 write sequence
1542 b,n perf_rdr_shift_out_U_leave
1547 sync ; RDR 18 write sequence
1551 b,n perf_rdr_shift_out_U_leave
1556 sync ; RDR 19 write sequence
1560 b,n perf_rdr_shift_out_U_leave
1565 sync ; RDR 20 write sequence
1569 b,n perf_rdr_shift_out_U_leave
1574 sync ; RDR 21 write sequence
1578 b,n perf_rdr_shift_out_U_leave
1583 sync ; RDR 22 write sequence
1587 b,n perf_rdr_shift_out_U_leave
1592 sync ; RDR 23 write sequence
1596 b,n perf_rdr_shift_out_U_leave
1601 sync ; RDR 24 write sequence
1605 b,n perf_rdr_shift_out_U_leave
1610 sync ; RDR 25 write sequence
1614 b,n perf_rdr_shift_out_U_leave
1619 sync ; RDR 26 write sequence
1623 b,n perf_rdr_shift_out_U_leave
1628 sync ; RDR 27 write sequence
1632 b,n perf_rdr_shift_out_U_leave
1637 sync ; RDR 28 write sequence
1641 b,n perf_rdr_shift_out_U_leave
1646 sync ; RDR 29 write sequence
1650 b,n perf_rdr_shift_out_U_leave
1655 sync ; RDR 30 write sequence
1659 b,n perf_rdr_shift_out_U_leave
1664 sync ; RDR 31 write sequence
1668 b,n perf_rdr_shift_out_U_leave
1673 perf_rdr_shift_out_U_leave:
1676 MTDIAG_2 (23) ; restore DR2
1678 ENDPROC(perf_rdr_shift_out_U)