tests: Add tests for the PVR

The PVR is a privileged read-only SPR. Test reading and writing in both
supervisor and problem state. In supervisor state reading returns
microwatt's assigned PVR number and writing is a noop. In problem state
both reading and writing cause privileged instruction interrupts.

Signed-off-by: Jordan Niethe <jniethe5@gmail.com>
pull/222/head
Jordan Niethe 5 years ago
parent 17fc77cef2
commit 737ebd92f5

@ -16,6 +16,7 @@
*/ */


#define STACK_TOP 0x2000 #define STACK_TOP 0x2000
#define PVR 287


/* Load an immediate 64-bit value into a register */ /* Load an immediate 64-bit value into a register */
#define LOAD_IMM64(r, e) \ #define LOAD_IMM64(r, e) \
@ -100,3 +101,39 @@ test_addpcis_2:


blr blr


/* Test reading the PVR */
.global test_mfpvr
test_mfpvr:
mflr %r0
std %r0, 16(%r1)
stdu %r1, -32(%r1)

/*
* If r3 happened to already contain PVR_MICROWATT the test
* would succeed even if the PVR is not implemented.
*/
LOAD_IMM64(%r3, 0xdeadbeef)
mfpvr %r3

addi %r1, %r1, 32
ld %r0, 16(%r1)
mtlr %r0

blr

/* Test writing the PVR does nothing */
.global test_mtpvr
test_mtpvr:
mflr %r0
std %r0, 16(%r1)
stdu %r1, -32(%r1)

LOAD_IMM64(%r3, 0xdeadbeef)
mtspr PVR, %r3
mfpvr %r3

addi %r1, %r1, 32
ld %r0, 16(%r1)
mtlr %r0

blr

@ -8,8 +8,12 @@
#define PASS "PASS\n" #define PASS "PASS\n"
#define FAIL "FAIL\n" #define FAIL "FAIL\n"


#define PVR_MICROWATT 0x00630000

extern long test_addpcis_1(void); extern long test_addpcis_1(void);
extern long test_addpcis_2(void); extern long test_addpcis_2(void);
extern long test_mfpvr(void);
extern long test_mtpvr(void);


// i < 100 // i < 100
void print_test_number(int i) void print_test_number(int i)
@ -40,5 +44,19 @@ int main(void)
} else } else
puts(PASS); puts(PASS);


print_test_number(3);
if (test_mfpvr() != PVR_MICROWATT) {
fail = 1;
puts(FAIL);
} else
puts(PASS);

print_test_number(4);
if (test_mtpvr() != PVR_MICROWATT) {
fail = 1;
puts(FAIL);
} else
puts(PASS);

return fail; return fail;
} }

@ -15,6 +15,7 @@ extern int call_with_msr(unsigned long arg, int (*fn)(unsigned long), unsigned l
#define SRR1 27 #define SRR1 27
#define PID 48 #define PID 48
#define PRTBL 720 #define PRTBL 720
#define PVR 287


static inline unsigned long mfspr(int sprnum) static inline unsigned long mfspr(int sprnum)
{ {
@ -186,6 +187,20 @@ int priv_fn_6(unsigned long x)
return 0; return 0;
} }


int priv_fn_7(unsigned long x)
{
mfspr(PVR);
__asm__ volatile("sc");
return 0;
}

int priv_fn_8(unsigned long x)
{
mtspr(PVR, x);
__asm__ volatile("sc");
return 0;
}

int priv_test(int (*fn)(unsigned long)) int priv_test(int (*fn)(unsigned long))
{ {
unsigned long msr; unsigned long msr;
@ -239,6 +254,8 @@ int main(void)
do_test(4, priv_fn_4); do_test(4, priv_fn_4);
do_test(5, priv_fn_5); do_test(5, priv_fn_5);
do_test(6, priv_fn_6); do_test(6, priv_fn_6);
do_test(7, priv_fn_7);
do_test(8, priv_fn_8);


return fail; return fail;
} }

Binary file not shown.

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

Binary file not shown.

@ -4,3 +4,5 @@ test 03:PASS
test 04:PASS test 04:PASS
test 05:PASS test 05:PASS
test 06:PASS test 06:PASS
test 07:PASS
test 08:PASS

Loading…
Cancel
Save