From 7b3fcbe9a9d336b67b914b842ff656aaafe7d939 Mon Sep 17 00:00:00 2001 From: Tim Newsome Date: Thu, 28 Jul 2016 14:47:12 -0700 Subject: [PATCH] Add tests for virtual priv register. Users can use this register to inspect and change the privilege level of the core. It doesn't make any assumptions about the actual underlying debug mechanism (as opposed to having the user change DCSR directly, which may not exist in all debug implementations). --- debug/gdbserver.py | 52 +++++++++++++++++++++++++++++++++++++++++++ debug/programs/priv.S | 11 +++++++++ 2 files changed, 63 insertions(+) create mode 100644 debug/programs/priv.S diff --git a/debug/gdbserver.py b/debug/gdbserver.py index 83e3c2f..f20630e 100755 --- a/debug/gdbserver.py +++ b/debug/gdbserver.py @@ -466,6 +466,58 @@ class MprvTest(DeleteServer): output = self.gdb.command("p/x *(int*)(((char*)&data)-0x80000000)") self.assertIn("0xbead", output) +class PrivTest(DeleteServer): + def setUp(self): + self.binary = target.compile("programs/priv.S") + self.server = target.server() + self.gdb = gdb() + self.gdb.command("file %s" % self.binary) + self.gdb.command("target extended-remote localhost:%d" % self.server.port) + self.gdb.load() + + misa = self.gdb.p("$misa") + self.supported = set() + if misa & (1<<20): + self.supported.add(0) + if misa & (1<<18): + self.supported.add(1) + if misa & (1<<7): + self.supported.add(2) + self.supported.add(3) + + def test_rw(self): + """Test reading/writing priv.""" + for privilege in range(4): + self.gdb.p("$priv=%d" % privilege) + self.gdb.stepi() + actual = self.gdb.p("$priv") + self.assertIn(actual, self.supported) + if privilege in self.supported: + self.assertEqual(actual, privilege) + + def test_change(self): + """Test that the core's privilege level actually changes.""" + + if 0 not in self.supported: + # TODO: return not applicable + return + + self.gdb.b("main") + self.gdb.c() + + # Machine mode + self.gdb.p("$priv=3") + main = self.gdb.p("$pc") + self.gdb.stepi() + self.assertEqual("%x" % self.gdb.p("$pc"), "%x" % (main+4)) + + # User mode + self.gdb.p("$priv=0") + self.gdb.stepi() + # Should have taken an exception, so be nowhere near main. + pc = self.gdb.p("$pc") + self.assertTrue(pc < main or pc > main + 0x100) + class Target(object): directory = None diff --git a/debug/programs/priv.S b/debug/programs/priv.S new file mode 100644 index 0000000..2d20a65 --- /dev/null +++ b/debug/programs/priv.S @@ -0,0 +1,11 @@ +#include "../../env/encoding.h" + + .global main + + .section .text +main: + # MISA is only readable from machine mode + csrr t0, CSR_MISA + csrr t0, CSR_MISA + csrr t0, CSR_MISA + csrr t0, CSR_MISA -- 2.30.2