2 /* low-level asm for "intrigue" (PA8500-8700 CPU perf counters)
4 * Copyright (C) 2001 Randolph Chung <tausq at parisc-linux.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <linux/config.h>
22 #include <asm/assembly.h>
28 #define MTDIAG_1(gr) .word 0x14201840 + gr*0x10000
29 #define MTDIAG_2(gr) .word 0x14401840 + gr*0x10000
30 #define MFDIAG_1(gr) .word 0x142008A0 + gr
31 #define MFDIAG_2(gr) .word 0x144008A0 + gr
32 #define STDIAG(dr) .word 0x14000AA0 + dr*0x200000
33 #define SFDIAG(dr) .word 0x14000BA0 + dr*0x200000
34 #define DR2_SLOW_RET 53
38 ; Enable the performance counters
40 ; The coprocessor only needs to be enabled when
41 ; starting/stopping the coprocessor with the pmenb/pmdis.
46 .export perf_intrigue_enable_perf_counters,code
47 perf_intrigue_enable_perf_counters:
49 .callinfo frame=0,NO_CALLS
52 ldi 0x20,%r25 ; load up perfmon bit
53 mfctl ccr,%r26 ; get coprocessor register
54 or %r25,%r26,%r26 ; set bit
55 mtctl %r26,ccr ; turn on performance coprocessor
56 pmenb ; enable performance monitor
57 ssm 0,0 ; dummy op to ensure completion
59 andcm %r26,%r25,%r26 ; clear bit now
60 mtctl %r26,ccr ; turn off performance coprocessor
61 nop ; NOPs as specified in ERS
73 .export perf_intrigue_disable_perf_counters,code
74 perf_intrigue_disable_perf_counters:
76 .callinfo frame=0,NO_CALLS
78 ldi 0x20,%r25 ; load up perfmon bit
79 mfctl ccr,%r26 ; get coprocessor register
80 or %r25,%r26,%r26 ; set bit
81 mtctl %r26,ccr ; turn on performance coprocessor
82 pmdis ; disable performance monitor
83 ssm 0,0 ; dummy op to ensure completion
84 andcm %r26,%r25,%r26 ; clear bit now
86 mtctl %r26,ccr ; turn off performance coprocessor
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 .export perf_rdr_shift_in_W,code
123 .callinfo frame=0,NO_CALLS
126 ; read(shift in) the RDR.
129 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
130 ; shifting is done, from or to, remote diagnose registers.
133 depdi,z 1,DR2_SLOW_RET,1,%r29
136 MTDIAG_2 (29) ; set DR2_SLOW_RET
144 ; Cacheline start (32-byte cacheline)
149 extrd,u arg1,63,6,%r1 ; setup shift amount based on bits to move
152 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
153 blr %r1,%r0 ; branch to 8-instruction sequence
157 ; Cacheline start (32-byte cacheline)
166 shrpd ret0,%r0,%sar,%r1
167 MTDIAG_1 (1) ; mtdiag %dr1, %r1
170 b,n perf_rdr_shift_in_W_leave
181 b,n perf_rdr_shift_in_W_leave
185 ; RDR 2 read sequence
190 shrpd ret0,%r0,%sar,%r1
194 b,n perf_rdr_shift_in_W_leave
197 ; RDR 3 read sequence
199 b,n perf_rdr_shift_in_W_leave
209 ; RDR 4 read sequence
216 b,n perf_rdr_shift_in_W_leave
221 ; RDR 5 read sequence
228 b,n perf_rdr_shift_in_W_leave
233 ; RDR 6 read sequence
240 b,n perf_rdr_shift_in_W_leave
245 ; RDR 7 read sequence
247 b,n perf_rdr_shift_in_W_leave
257 ; RDR 8 read sequence
259 b,n perf_rdr_shift_in_W_leave
269 ; RDR 9 read sequence
271 b,n perf_rdr_shift_in_W_leave
281 ; RDR 10 read sequence
286 shrpd ret0,%r0,%sar,%r1
290 b,n perf_rdr_shift_in_W_leave
293 ; RDR 11 read sequence
298 shrpd ret0,%r0,%sar,%r1
302 b,n perf_rdr_shift_in_W_leave
305 ; RDR 12 read sequence
307 b,n perf_rdr_shift_in_W_leave
317 ; RDR 13 read sequence
324 b,n perf_rdr_shift_in_W_leave
329 ; RDR 14 read sequence
334 shrpd ret0,%r0,%sar,%r1
338 b,n perf_rdr_shift_in_W_leave
341 ; RDR 15 read sequence
343 sync ; RDR 15 read sequence
349 b,n perf_rdr_shift_in_W_leave
353 ; RDR 16 read sequence
355 sync ; RDR 16 read sequence
360 b,n perf_rdr_shift_in_W_leave
365 ; RDR 17 read sequence
370 shrpd ret0,%r0,%sar,%r1
374 b,n perf_rdr_shift_in_W_leave
377 ; RDR 18 read sequence
382 shrpd ret0,%r0,%sar,%r1
386 b,n perf_rdr_shift_in_W_leave
389 ; RDR 19 read sequence
391 b,n perf_rdr_shift_in_W_leave
401 ; RDR 20 read sequence
408 b,n perf_rdr_shift_in_W_leave
413 ; RDR 21 read sequence
420 b,n perf_rdr_shift_in_W_leave
425 ; RDR 22 read sequence
432 b,n perf_rdr_shift_in_W_leave
437 ; RDR 23 read sequence
444 b,n perf_rdr_shift_in_W_leave
449 ; RDR 24 read sequence
456 b,n perf_rdr_shift_in_W_leave
461 ; RDR 25 read sequence
468 b,n perf_rdr_shift_in_W_leave
473 ; RDR 26 read sequence
478 shrpd ret0,%r0,%sar,%r1
482 b,n perf_rdr_shift_in_W_leave
485 ; RDR 27 read sequence
490 shrpd ret0,%r0,%sar,%r1
494 b,n perf_rdr_shift_in_W_leave
497 ; RDR 28 read sequence
504 b,n perf_rdr_shift_in_W_leave
509 ; RDR 29 read sequence
516 b,n perf_rdr_shift_in_W_leave
521 ; RDR 30 read sequence
526 shrpd ret0,%r0,%sar,%r1
530 b,n perf_rdr_shift_in_W_leave
533 ; RDR 31 read sequence
548 perf_rdr_shift_in_W_leave:
551 MTDIAG_2 (24) ; restore DR2
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. *
566 ;* arg0 = rdr number *
567 ;* arg1 = 64-bit value to write *
568 ;* %r24 - DR2 | DR2_SLOW_RET *
569 ;* %r23 - original DR2 value *
576 ;************************************************************************
578 .export perf_rdr_shift_out_W,code
579 perf_rdr_shift_out_W:
581 .callinfo frame=0,NO_CALLS
584 ; NOTE: The PCX-W ERS states that DR2_SLOW_RET must be set before any
585 ; shifting is done, from or to, the remote diagnose registers.
588 depdi,z 1,DR2_SLOW_RET,1,%r24
591 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
989 ;**************************** CHRIS ***********************************
991 ;************************************************************************
993 ;* Name: rdr_shift_in_U *
996 ;* This routine shifts data in from the RDR in arg0 and returns *
997 ;* the result in ret0. If the RDR is <= 64 bits in length, it *
998 ;* is shifted shifted backup immediately. This is to compensate *
999 ;* for RDR10 which has bits that preclude PDC stack operations *
1000 ;* when they are in the wrong state. *
1003 ;* arg0 : rdr to be read *
1004 ;* arg1 : bit length of rdr *
1007 ;* ret0 = next 64 bits of rdr data from staging register *
1009 ;* Register usage: *
1010 ;* arg0 : rdr to be read *
1011 ;* arg1 : bit length of rdr *
1012 ;* %r24 - original DR2 value *
1013 ;* %r23 - DR2 | DR2_SLOW_RET *
1016 ;************************************************************************
1018 .export perf_rdr_shift_in_U,code
1019 perf_rdr_shift_in_U:
1021 .callinfo frame=0,NO_CALLS
1024 ; read(shift in) the RDR.
1026 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1027 ; shifting is done, from or to, remote diagnose registers.
1029 depdi,z 1,DR2_SLOW_RET,1,%r29
1032 MTDIAG_2 (29) ; set DR2_SLOW_RET
1040 ; Start of next 32-byte cacheline
1045 extrd,u arg1,63,6,%r1
1048 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1049 blr %r1,%r0 ; branch to 8-instruction sequence
1053 ; Start of next 32-byte cacheline
1055 SFDIAG (0) ; RDR 0 read sequence
1058 shrpd ret0,%r0,%sar,%r1
1062 b,n perf_rdr_shift_in_U_leave
1064 SFDIAG (1) ; RDR 1 read sequence
1067 shrpd ret0,%r0,%sar,%r1
1071 b,n perf_rdr_shift_in_U_leave
1073 sync ; RDR 2 read sequence
1078 b,n perf_rdr_shift_in_U_leave
1082 sync ; RDR 3 read sequence
1087 b,n perf_rdr_shift_in_U_leave
1091 sync ; RDR 4 read sequence
1096 b,n perf_rdr_shift_in_U_leave
1100 sync ; RDR 5 read sequence
1105 b,n perf_rdr_shift_in_U_leave
1109 sync ; RDR 6 read sequence
1114 b,n perf_rdr_shift_in_U_leave
1118 sync ; RDR 7 read sequence
1123 b,n perf_rdr_shift_in_U_leave
1127 b,n perf_rdr_shift_in_U_leave
1136 SFDIAG (9) ; RDR 9 read sequence
1139 shrpd ret0,%r0,%sar,%r1
1143 b,n perf_rdr_shift_in_U_leave
1145 SFDIAG (10) ; RDR 10 read sequence
1148 shrpd ret0,%r0,%sar,%r1
1152 b,n perf_rdr_shift_in_U_leave
1154 SFDIAG (11) ; RDR 11 read sequence
1157 shrpd ret0,%r0,%sar,%r1
1161 b,n perf_rdr_shift_in_U_leave
1163 SFDIAG (12) ; RDR 12 read sequence
1166 shrpd ret0,%r0,%sar,%r1
1170 b,n perf_rdr_shift_in_U_leave
1172 SFDIAG (13) ; RDR 13 read sequence
1175 shrpd ret0,%r0,%sar,%r1
1179 b,n perf_rdr_shift_in_U_leave
1181 SFDIAG (14) ; RDR 14 read sequence
1184 shrpd ret0,%r0,%sar,%r1
1188 b,n perf_rdr_shift_in_U_leave
1190 SFDIAG (15) ; RDR 15 read sequence
1193 shrpd ret0,%r0,%sar,%r1
1197 b,n perf_rdr_shift_in_U_leave
1199 sync ; RDR 16 read sequence
1204 b,n perf_rdr_shift_in_U_leave
1208 SFDIAG (17) ; RDR 17 read sequence
1211 shrpd ret0,%r0,%sar,%r1
1215 b,n perf_rdr_shift_in_U_leave
1217 SFDIAG (18) ; RDR 18 read sequence
1220 shrpd ret0,%r0,%sar,%r1
1224 b,n perf_rdr_shift_in_U_leave
1226 b,n perf_rdr_shift_in_U_leave
1235 sync ; RDR 20 read sequence
1240 b,n perf_rdr_shift_in_U_leave
1244 sync ; RDR 21 read sequence
1249 b,n perf_rdr_shift_in_U_leave
1253 sync ; RDR 22 read sequence
1258 b,n perf_rdr_shift_in_U_leave
1262 sync ; RDR 23 read sequence
1267 b,n perf_rdr_shift_in_U_leave
1271 sync ; RDR 24 read sequence
1276 b,n perf_rdr_shift_in_U_leave
1280 sync ; RDR 25 read sequence
1285 b,n perf_rdr_shift_in_U_leave
1289 SFDIAG (26) ; RDR 26 read sequence
1292 shrpd ret0,%r0,%sar,%r1
1296 b,n perf_rdr_shift_in_U_leave
1298 SFDIAG (27) ; RDR 27 read sequence
1301 shrpd ret0,%r0,%sar,%r1
1305 b,n perf_rdr_shift_in_U_leave
1307 sync ; RDR 28 read sequence
1312 b,n perf_rdr_shift_in_U_leave
1316 b,n perf_rdr_shift_in_U_leave
1325 SFDIAG (30) ; RDR 30 read sequence
1328 shrpd ret0,%r0,%sar,%r1
1332 b,n perf_rdr_shift_in_U_leave
1334 SFDIAG (31) ; RDR 31 read sequence
1337 shrpd ret0,%r0,%sar,%r1
1341 b,n perf_rdr_shift_in_U_leave
1344 perf_rdr_shift_in_U_leave:
1347 MTDIAG_2 (24) ; restore DR2
1350 ;************************************************************************
1352 ;* Name: rdr_shift_out_U *
1355 ;* This routine moves data to the RDR's. The double-word that *
1356 ;* arg1 points to is loaded and moved into the staging register. *
1357 ;* Then the STDIAG instruction for the RDR # in arg0 is called *
1358 ;* to move the data to the RDR. *
1361 ;* arg0 = rdr target *
1362 ;* arg1 = buffer pointer *
1367 ;* Register usage: *
1368 ;* arg0 = rdr target *
1369 ;* arg1 = buffer pointer *
1370 ;* %r24 - DR2 | DR2_SLOW_RET *
1371 ;* %r23 - original DR2 value *
1373 ;************************************************************************
1375 .export perf_rdr_shift_out_U,code
1376 perf_rdr_shift_out_U:
1378 .callinfo frame=0,NO_CALLS
1382 ; NOTE: The PCX-U ERS states that DR2_SLOW_RET must be set before any
1383 ; shifting is done, from or to, the remote diagnose registers.
1386 depdi,z 1,DR2_SLOW_RET,1,%r24
1389 MTDIAG_2 (24) ; set DR2_SLOW_RET
1391 MTDIAG_1 (25) ; data to the staging register
1392 shladd arg0,2,%r0,%r1 ; %r1 = 4 * RDR number
1393 blr %r1,%r0 ; branch to 8-instruction sequence
1397 ; 32-byte cachline aligned
1400 sync ; RDR 0 write sequence
1404 b,n perf_rdr_shift_out_U_leave
1409 sync ; RDR 1 write sequence
1413 b,n perf_rdr_shift_out_U_leave
1418 sync ; RDR 2 write sequence
1422 b,n perf_rdr_shift_out_U_leave
1427 sync ; RDR 3 write sequence
1431 b,n perf_rdr_shift_out_U_leave
1436 sync ; RDR 4 write sequence
1440 b,n perf_rdr_shift_out_U_leave
1445 sync ; RDR 5 write sequence
1449 b,n perf_rdr_shift_out_U_leave
1454 sync ; RDR 6 write sequence
1458 b,n perf_rdr_shift_out_U_leave
1463 sync ; RDR 7 write sequence
1467 b,n perf_rdr_shift_out_U_leave
1472 sync ; RDR 8 write sequence
1476 b,n perf_rdr_shift_out_U_leave
1481 sync ; RDR 9 write sequence
1485 b,n perf_rdr_shift_out_U_leave
1490 sync ; RDR 10 write sequence
1494 b,n perf_rdr_shift_out_U_leave
1499 sync ; RDR 11 write sequence
1503 b,n perf_rdr_shift_out_U_leave
1508 sync ; RDR 12 write sequence
1512 b,n perf_rdr_shift_out_U_leave
1517 sync ; RDR 13 write sequence
1521 b,n perf_rdr_shift_out_U_leave
1526 sync ; RDR 14 write sequence
1530 b,n perf_rdr_shift_out_U_leave
1535 sync ; RDR 15 write sequence
1539 b,n perf_rdr_shift_out_U_leave
1544 sync ; RDR 16 write sequence
1548 b,n perf_rdr_shift_out_U_leave
1553 sync ; RDR 17 write sequence
1557 b,n perf_rdr_shift_out_U_leave
1562 sync ; RDR 18 write sequence
1566 b,n perf_rdr_shift_out_U_leave
1571 sync ; RDR 19 write sequence
1575 b,n perf_rdr_shift_out_U_leave
1580 sync ; RDR 20 write sequence
1584 b,n perf_rdr_shift_out_U_leave
1589 sync ; RDR 21 write sequence
1593 b,n perf_rdr_shift_out_U_leave
1598 sync ; RDR 22 write sequence
1602 b,n perf_rdr_shift_out_U_leave
1607 sync ; RDR 23 write sequence
1611 b,n perf_rdr_shift_out_U_leave
1616 sync ; RDR 24 write sequence
1620 b,n perf_rdr_shift_out_U_leave
1625 sync ; RDR 25 write sequence
1629 b,n perf_rdr_shift_out_U_leave
1634 sync ; RDR 26 write sequence
1638 b,n perf_rdr_shift_out_U_leave
1643 sync ; RDR 27 write sequence
1647 b,n perf_rdr_shift_out_U_leave
1652 sync ; RDR 28 write sequence
1656 b,n perf_rdr_shift_out_U_leave
1661 sync ; RDR 29 write sequence
1665 b,n perf_rdr_shift_out_U_leave
1670 sync ; RDR 30 write sequence
1674 b,n perf_rdr_shift_out_U_leave
1679 sync ; RDR 31 write sequence
1683 b,n perf_rdr_shift_out_U_leave
1688 perf_rdr_shift_out_U_leave:
1691 MTDIAG_2 (23) ; restore DR2