From de1bf10114a3eb87f549b1efc2645853a8332c22 Mon Sep 17 00:00:00 2001 From: Iago Caran Aquino Date: Tue, 19 Jul 2022 17:24:14 -0300 Subject: [PATCH] tests/pmu: Add load/store completed, instruction count and cycle count tests Signed-off-by: Iago Caran Aquino --- tests/pmu/Makefile | 3 + tests/pmu/head.S | 46 ++++++++++ tests/pmu/pmu.c | 173 +++++++++++++++++++++++++++++++++++++ tests/pmu/powerpc.lds | 27 ++++++ tests/test_pmu.bin | Bin 0 -> 6916 bytes tests/test_pmu.console_out | 4 + tests/update_console_tests | 2 +- 7 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 tests/pmu/Makefile create mode 100644 tests/pmu/head.S create mode 100644 tests/pmu/pmu.c create mode 100644 tests/pmu/powerpc.lds create mode 100755 tests/test_pmu.bin create mode 100644 tests/test_pmu.console_out diff --git a/tests/pmu/Makefile b/tests/pmu/Makefile new file mode 100644 index 0000000..2fd6c28 --- /dev/null +++ b/tests/pmu/Makefile @@ -0,0 +1,3 @@ +TEST=pmu + +include ../Makefile.test diff --git a/tests/pmu/head.S b/tests/pmu/head.S new file mode 100644 index 0000000..03cffe4 --- /dev/null +++ b/tests/pmu/head.S @@ -0,0 +1,46 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define STACK_TOP 0x4000 + +/* Load an immediate 64-bit value into a register */ +#define LOAD_IMM64(r, e) \ + lis r,(e)@highest; \ + ori r,r,(e)@higher; \ + rldicr r,r, 32, 31; \ + oris r,r, (e)@h; \ + ori r,r, (e)@l; + + .section ".head","ax" + + /* + * Microwatt currently enters in LE mode at 0x0, so we don't need to + * do any endian fix ups> + */ + . = 0 +.global _start +_start: + b boot_entry + +.global boot_entry +boot_entry: + /* setup stack */ + LOAD_IMM64(%r1, STACK_TOP - 0x100) + LOAD_IMM64(%r12, main) + mtctr %r12, + bctrl + attn // terminate on exit + b . diff --git a/tests/pmu/pmu.c b/tests/pmu/pmu.c new file mode 100644 index 0000000..01bb53b --- /dev/null +++ b/tests/pmu/pmu.c @@ -0,0 +1,173 @@ +#include +#include + +#include "console.h" + + +#define asm __asm__ volatile + +#define MMCR0 795 +#define MMCR1 798 +#define MMCR2 785 +#define MMCRA 786 +#define PMC1 771 +#define PMC2 772 +#define PMC3 773 +#define PMC4 774 +#define PMC5 775 +#define PMC6 776 + +#define MMCR0_FC 0x80000000 // Freeze Counters +#define PMC1SEL_FC 0xFC000000 // Load Completed +#define PMC2SEL_F0 0x00F00000 // Store Completed + +#define TEST "Test " +#define PASS "PASS\n" +#define FAIL "FAIL\n" + +static inline unsigned long mfspr(int sprnum) +{ + unsigned long val; + + asm("mfspr %0,%1" : "=r" ((unsigned long) val) : "i" (sprnum)); + return val; +} + +static inline void mtspr(int sprnum, unsigned long val) +{ + asm("mtspr %0,%1" : : "i" (sprnum), "r" ((unsigned long) val)); +} + +void print_test_number(int i) +{ + puts(TEST); + putchar(48 + i/10); + putchar(48 + i%10); + putchar(':'); +} + +void reset_pmu() { + mtspr(MMCR0, MMCR0_FC); + mtspr(MMCR1, 0); + mtspr(PMC1, 0); + mtspr(PMC2, 0); + mtspr(PMC3, 0); + mtspr(PMC4, 0); + mtspr(PMC5, 0); + mtspr(PMC6, 0); +} + +/* + Sets PMC1 to count finished load instructions + Runs 50 load instructions + Expects PMC1 to be 50 at the end +*/ +int test_load_complete() +{ + reset_pmu(); + unsigned long volatile b = 0; + mtspr(MMCR1, PMC1SEL_FC); + mtspr(MMCR0, 0); + + for(int i = 0; i < 50; i++) + ++b; + + mtspr(MMCR0, MMCR0_FC); + + return mfspr(PMC1) == 50; +} + +/* + Sets PMC2 to count finished store instructions + Runs 50 store instructions + Expects PMC2 to be 50 at the end +*/ +int test_store_complete() +{ + reset_pmu(); + unsigned long volatile b = 0; + mtspr(MMCR1, PMC2SEL_F0); + mtspr(MMCR0, 0); + + for(int i = 0; i < 50; i++) + ++b; + + mtspr(MMCR0, MMCR0_FC); + + return mfspr(PMC2) == 50; +} + +/* + Allow PMC5 to count finished instructions + Runs a loop 50 times + Expects PMC5 to be more than zero at the end +*/ +int test_instruction_complete() +{ + reset_pmu(); + unsigned long volatile b = 0; + mtspr(MMCR0, 0); + + for(int i = 0; i < 50; i++) + ++b; + + mtspr(MMCR0, MMCR0_FC); + + return mfspr(PMC5) > 0; +} + +/* + Allow PMC6 to count cycles + Runs a loop 50 times + Expects PMC6 to be more than zero at the end +*/ +int test_count_cycles() +{ + reset_pmu(); + unsigned long volatile b = 0; + mtspr(MMCR0, 0); + + for(int i = 0; i < 50; i++) + ++b; + + mtspr(MMCR0, MMCR0_FC); + + return mfspr(PMC6) > 0; +} + +int main(void) +{ + int fail = 0; + + console_init(); + + print_test_number(1); + if (test_load_complete() != 1) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + print_test_number(2); + if (test_store_complete() != 1) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + print_test_number(3); + if (test_instruction_complete() == 0) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + print_test_number(4); + if (test_count_cycles() == 0) { + fail = 1; + puts(FAIL); + } else + puts(PASS); + + return fail; +} diff --git a/tests/pmu/powerpc.lds b/tests/pmu/powerpc.lds new file mode 100644 index 0000000..99611ab --- /dev/null +++ b/tests/pmu/powerpc.lds @@ -0,0 +1,27 @@ +SECTIONS +{ + . = 0; + _start = .; + .head : { + KEEP(*(.head)) + } + . = ALIGN(0x1000); + .text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) } + . = ALIGN(0x1000); + .data : { *(.data) *(.data.*) *(.got) *(.toc) } + . = ALIGN(0x80); + __bss_start = .; + .bss : { + *(.dynsbss) + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(.common) + *(.bss.*) + } + . = ALIGN(0x80); + __bss_end = .; + . = . + 0x4000; + __stack_top = .; +} diff --git a/tests/test_pmu.bin b/tests/test_pmu.bin new file mode 100755 index 0000000000000000000000000000000000000000..0791139a6233883ae9596b548fb3218f9a969428 GIT binary patch literal 6916 zcmeHLUu;uV82@hDbzPmK7#@~D;1;TDM~T%JTgU1xf5z4-8*Ggj6Vq8p0C~XZ!>zfO zb%Y0&EU^+|AVK~l+8AOMNOy-}gJ``+mRkopVP$MD0ZKMxtQuYHd)(xSL)I=7@@|M1#FoYX=J$_Y6KY*jsiF z=s{0$JGqD(<~hw#z)`?az)`?az)`?az)`?az)`?az)`?az)|4;pnycmMk;NJmt8(> zMqHks6*uPtB+Y&+g0p@aZ&6ns(!e7(cJ$5oIgjyw{@k_sdwntLi~C8exm26iYAk!# zOrI8`e4K5+yG`til#BmjJ;x{*SA7e=8%Ra|9ib?<$`mP-M_P3J4v{F2B=z#hI`k0w z)9BBjH=&1hnef|#t=V(uoIgO$7lp|1I&??Dy6HlWf^+4OH!#0Nzb#>XcSMJ6N}@=D zeYXW|vgc5~lGhF*Pv(F%C(CZ1W{WEo5r3(;2`lalDXsRH%b3$cV}^8&Da5{5pyScv zUcP7YHDk8u&;O@*O^+RK$796{KXSZE9U6P;GHXdfExmSEWR@E_tc#wa!wR+|C!tQi zM}0~b&IR0a!1Y?V!7AJjlDVE6xH{l2S~#@|chSOmfV+7|Wacc~?ke1Xh2uR`=O_A3 z)R^lN@)}28`z-%nqedvlwyb5-Y_^nTE7@!tEZfJX4RlE=N{cnf{CAbsCV0d-#uynO zs*A?xaEhpTY6a^2GY@I!x63+e{_Woc+xJfzw$(W;>CN|;_1!!bu&~pMScS1ZoN2~S z13$Ky2SPqPkLVJ4;JjOTG*20Mbmpuxc7F~&6Q?A-`+A7d26p;Y`CspW>N`w`i57`& zyib&j2C#2@2SKX%4DKX9tq#}2_9Wg@;HCaC(#Pl6#?iQ=)Rp@+o-@?gj613>D%0Ut zBxo}8AT5RocaN_ZypC;zzOzqva}VO~9aL`^3dUlg)g1JI62Yc0)@6P{gH zd<9RXMmkNKo0LTTf=w}SmD)JpX};G211{#euo*SP9BJE0A$*BO*~Sy=+U`)$S*mVA zQ8H?G;90m)%WJ1%bUGCRCl_K7t&92$e(B!De66_fk7F;`@1lGTni_dcFVvM0()cF; zePsGX{c!z+re?yr5RpXE8_8aaY}30M(|XdI&c^8Lc+z{dCqdqDj`~wW9iy7kSfk1G ztJ+TeiV#1?)l9RlcDLb7r7=I9T}J-!P;69_=*v@+qF)J+FO2U5H0nTAFe^@Z!N?W619EK{w)Ie>N6Pz0PKxaK;rcQ)Ry=XJgZnYT>sCy!U< z4b6|yf9AcaYA)AJ&z^VQmGRJ)>Ui0Yu`AWx%_HuGTl_u8cjZ>)n;w9j zoAlmJ@~A0kWj#(0-W$;;{}iH#k+wC&mZuJ#cAb&34V1d^qc=r7ZzKAazl7kC+bZ-f z^aHS|Y}ndx5c766&}Pgq{Rc6Q-tXVhKwB34CC1GP!8mJvr`>-6<^vD#%kYh%e*u3~ z!b6)8|BUpOzkxR0@TQ(1BX4-_;~T&`^Sv-9#8Gylu?>fjLVpW!gbipRbOrr5Y&ncJ zUA7t#APhnnbN6EW2DmWe(0Dx!eH=C;H_KMSI6H6YW!W$+nP2-IAwFd%S|z{huqlSc awDF^TFB!+&ZUgr@JJBk0PuyMHyMF-G%m{S= literal 0 HcmV?d00001 diff --git a/tests/test_pmu.console_out b/tests/test_pmu.console_out new file mode 100644 index 0000000..2ff5a99 --- /dev/null +++ b/tests/test_pmu.console_out @@ -0,0 +1,4 @@ +Test 01:PASS +Test 02:PASS +Test 03:PASS +Test 04:PASS diff --git a/tests/update_console_tests b/tests/update_console_tests index 4e013aa..b168e8d 100755 --- a/tests/update_console_tests +++ b/tests/update_console_tests @@ -3,7 +3,7 @@ # Script to update console related tests from source # -for i in sc illegal decrementer xics privileged mmu misc modes reservation trace fpu spr_read ; do +for i in sc illegal decrementer xics privileged mmu misc modes pmu reservation trace fpu spr_read ; do cd $i make cd -