Merge pull request #380 from iagocaran/master

tests/pmu: Add load/store completed and instruction/cycle count
pull/381/head
Michael Neuling 2 years ago committed by GitHub
commit bad9a9a2e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,3 @@
TEST=pmu

include ../Makefile.test

@ -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 .

@ -0,0 +1,173 @@
#include <stdint.h>
#include <stdbool.h>

#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;
}

@ -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 = .;
}

Binary file not shown.

@ -0,0 +1,4 @@
Test 01:PASS
Test 02:PASS
Test 03:PASS
Test 04:PASS

@ -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 -

Loading…
Cancel
Save