-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from weijiew/lab8-plic
add plic and tests.
- Loading branch information
Showing
5 changed files
with
171 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// | ||
// Created by Jie Wei on 2024/4/2. | ||
// | ||
|
||
#include <cstdint> | ||
#include "exception.h" | ||
#include "plic.h" | ||
#include "param.h" | ||
|
||
namespace crvemu { | ||
|
||
uint64_t Plic::load(uint64_t addr, uint64_t size) { | ||
if (size != 32) { | ||
throw Exception(ExceptionType::LoadAccessFault, addr); | ||
} | ||
switch (addr) { | ||
case PLIC_PENDING: | ||
return pending; | ||
case PLIC_SENABLE: | ||
return senable; | ||
case PLIC_SPRIORITY: | ||
return spriority; | ||
case PLIC_SCLAIM: | ||
return sclaim; | ||
default: | ||
return 0; | ||
} | ||
} | ||
|
||
|
||
void Plic::store(uint64_t addr, uint64_t size, uint64_t value) { | ||
if (size != 32) { | ||
throw Exception(ExceptionType::StoreAMOAccessFault, addr); | ||
} | ||
switch (addr) { | ||
case PLIC_PENDING: | ||
pending = value; | ||
break; | ||
case PLIC_SENABLE: | ||
senable = value; | ||
break; | ||
case PLIC_SPRIORITY: | ||
spriority = value; | ||
break; | ||
case PLIC_SCLAIM: | ||
sclaim = value; | ||
break; | ||
default: | ||
break; | ||
} | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// | ||
// Created by Jie Wei on 2024/4/2. | ||
// | ||
|
||
#pragma once | ||
#include <cstdint> | ||
#include "exception.h" | ||
|
||
namespace crvemu { | ||
|
||
// 这个类的设计是为了模拟PLIC的功能,使得在模拟器中可以像在真实硬件中一样处理中断。 | ||
// 这个类的方法提供了对PLIC寄存器的读写操作,这些操作在处理中断时是必需的。 | ||
class Plic { | ||
public: | ||
Plic() : pending(0), senable(0), spriority(0), sclaim(0) {} | ||
|
||
// 读取和写入PLIC的寄存器 | ||
uint64_t load(uint64_t addr, uint64_t size); | ||
void store(uint64_t addr, uint64_t size, uint64_t value); | ||
|
||
private: | ||
uint64_t pending; // 对应PLIC的挂起寄存器 | ||
uint64_t senable; // 对应PLIC的使能寄存器 | ||
uint64_t spriority; // 对应PLIC的优先级寄存器 | ||
uint64_t sclaim; // 对应PLIC的索引寄存器 | ||
}; | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// | ||
// Created by Jie Wei on 2024/4/2. | ||
// | ||
|
||
#include "gtest/gtest.h" | ||
#include "../../src/plic.h" | ||
#include "../../src/param.h" | ||
|
||
namespace crvemu { | ||
|
||
class PlicTest : public ::testing::Test { | ||
protected: | ||
Plic plic; | ||
}; | ||
|
||
TEST_F(PlicTest, LoadStoreTest) { | ||
uint64_t test_value = 123; | ||
|
||
// Test store and load for each register | ||
plic.store(PLIC_PENDING, 32, test_value); | ||
EXPECT_EQ(plic.load(PLIC_PENDING, 32), test_value); | ||
|
||
plic.store(PLIC_SENABLE, 32, test_value); | ||
EXPECT_EQ(plic.load(PLIC_SENABLE, 32), test_value); | ||
|
||
plic.store(PLIC_SPRIORITY, 32, test_value); | ||
EXPECT_EQ(plic.load(PLIC_SPRIORITY, 32), test_value); | ||
|
||
plic.store(PLIC_SCLAIM, 32, test_value); | ||
EXPECT_EQ(plic.load(PLIC_SCLAIM, 32), test_value); | ||
} | ||
|
||
// Test exception throwing when size is not 32 | ||
TEST_F(PlicTest, ExceptionTest) { | ||
EXPECT_THROW(plic.load(PLIC_PENDING, 64), Exception); | ||
EXPECT_THROW(plic.store(PLIC_PENDING, 64, 123), Exception); | ||
} | ||
|
||
// 测试未知寄存器地址的行为 | ||
TEST_F(PlicTest, UnknownAddressTest) { | ||
uint64_t unknown_address = 0xdeadbeef; | ||
EXPECT_NO_THROW(plic.store(unknown_address, 32, 123)); | ||
EXPECT_EQ(plic.load(unknown_address, 32), 0); | ||
} | ||
|
||
//// 测试处理多个中断请求的行为 | ||
//TEST_F(PlicTest, MultipleInterruptsTest) { | ||
// plic.store(PLIC_PENDING, 32, 1); | ||
// plic.store(PLIC_PENDING, 32, 2); | ||
// EXPECT_EQ(plic.load(PLIC_SCLAIM, 32), 1); | ||
// EXPECT_EQ(plic.load(PLIC_SCLAIM, 32), 2); | ||
//} | ||
|
||
//// 测试处理优先级不同的中断请求的行为 | ||
//TEST_F(PlicTest, PriorityTest) { | ||
// plic.store(PLIC_PENDING, 32, 1); | ||
// plic.store(PLIC_SPRIORITY, 32, 1); | ||
// plic.store(PLIC_PENDING, 32, 2); | ||
// plic.store(PLIC_SPRIORITY, 32, 2); | ||
// EXPECT_EQ(plic.load(PLIC_SCLAIM, 32), 2); | ||
// EXPECT_EQ(plic.load(PLIC_SCLAIM, 32), 1); | ||
//} | ||
} // namespace crvemu |