132 lines
4.7 KiB
C#
132 lines
4.7 KiB
C#
using NUnit.Framework;
|
|
using VMdemo.Core;
|
|
using VMdemo.Simulation;
|
|
|
|
namespace VMdemo.Tests.EditMode
|
|
{
|
|
public class Step2AddressSplitTests
|
|
{
|
|
[TestCase(8)]
|
|
[TestCase(16)]
|
|
[TestCase(24)]
|
|
public void AddressGenerator_NextVirtualAddress_StaysWithinRange(int vaBits)
|
|
{
|
|
var generator = new AddressGenerator(vaBits, seed: 7);
|
|
|
|
for (var i = 0; i < 1000; i++)
|
|
{
|
|
var va = generator.NextVirtualAddress();
|
|
Assert.That(va, Is.LessThanOrEqualTo(generator.MaxVirtualAddress));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void AddressGenerator_SameSeed_GeneratesDeterministicSequence()
|
|
{
|
|
var a = new AddressGenerator(24, seed: 99);
|
|
var b = new AddressGenerator(24, seed: 99);
|
|
|
|
for (var i = 0; i < 20; i++)
|
|
{
|
|
Assert.That(a.NextVirtualAddress(), Is.EqualTo(b.NextVirtualAddress()));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void AddressGenerator_DifferentSeed_GeneratesDifferentSequence()
|
|
{
|
|
var a = new AddressGenerator(24, seed: 99);
|
|
var b = new AddressGenerator(24, seed: 100);
|
|
var hasDifference = false;
|
|
|
|
for (var i = 0; i < 20; i++)
|
|
{
|
|
if (a.NextVirtualAddress() != b.NextVirtualAddress())
|
|
{
|
|
hasDifference = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
Assert.IsTrue(hasDifference);
|
|
}
|
|
|
|
[TestCase(0xAFUL, 8, 4, 0xAUL, 0xFUL, 0x2UL, 0x2UL)]
|
|
[TestCase(0xABCDUL, 16, 8, 0xABUL, 0xCDUL, 0xAUL, 0xBUL)]
|
|
[TestCase(0x123456UL, 24, 8, 0x1234UL, 0x56UL, 0x12UL, 0x34UL)]
|
|
public void SplitVirtualAddress_SupportedVaBits_ReturnsExpectedParts(
|
|
ulong va,
|
|
int vaBits,
|
|
int offsetBits,
|
|
ulong expectedVpn,
|
|
ulong expectedOffset,
|
|
ulong expectedL1,
|
|
ulong expectedL2)
|
|
{
|
|
var parts = AddressTranslatorUtils.SplitVirtualAddress(va, vaBits, offsetBits);
|
|
TestContext.WriteLine(AddressTranslatorUtils.FormatSplitResult(va, vaBits, offsetBits, parts));
|
|
|
|
Assert.That(parts.Vpn, Is.EqualTo(expectedVpn));
|
|
Assert.That(parts.Offset, Is.EqualTo(expectedOffset));
|
|
Assert.That(parts.L1Index, Is.EqualTo(expectedL1));
|
|
Assert.That(parts.L2Index, Is.EqualTo(expectedL2));
|
|
}
|
|
|
|
[Test]
|
|
public void SplitVirtualAddress_OddVpnBits_UsesCeilFloorBitSplit()
|
|
{
|
|
const int vaBits = 24;
|
|
const int offsetBits = 5;
|
|
const ulong va = 0xABCDEFUL;
|
|
|
|
var parts = AddressTranslatorUtils.SplitVirtualAddress(va, vaBits, offsetBits);
|
|
AddressTranslatorUtils.GetPageTableBitLayout(vaBits - offsetBits, out var l1Bits, out var l2Bits);
|
|
|
|
Assert.That(l1Bits, Is.EqualTo(10));
|
|
Assert.That(l2Bits, Is.EqualTo(9));
|
|
Assert.That(parts.Vpn, Is.EqualTo(0x55E6FUL));
|
|
Assert.That(parts.Offset, Is.EqualTo(0xFUL));
|
|
Assert.That(parts.L1Index, Is.EqualTo(0x2AFUL));
|
|
Assert.That(parts.L2Index, Is.EqualTo(0x6FUL));
|
|
}
|
|
|
|
[Test]
|
|
public void GetPageTableBitLayout_AlwaysSumsToVpnBits()
|
|
{
|
|
for (var vpnBits = 1; vpnBits <= 63; vpnBits++)
|
|
{
|
|
AddressTranslatorUtils.GetPageTableBitLayout(vpnBits, out var l1Bits, out var l2Bits);
|
|
|
|
Assert.That(l1Bits + l2Bits, Is.EqualTo(vpnBits));
|
|
Assert.That(l1Bits, Is.GreaterThanOrEqualTo(l2Bits));
|
|
Assert.That(l1Bits - l2Bits, Is.LessThanOrEqualTo(1));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void SplitVirtualAddress_AddressOutOfRange_Throws()
|
|
{
|
|
Assert.Throws<System.ArgumentOutOfRangeException>(() =>
|
|
AddressTranslatorUtils.SplitVirtualAddress(0x1_000000UL, 24, 8));
|
|
}
|
|
|
|
[Test]
|
|
public void AddressGenerator_SequentialArrayLoop_FollowsClassicForLoopOrderAndWraps()
|
|
{
|
|
var generator = new AddressGenerator(
|
|
vaBits: 16,
|
|
seed: 7,
|
|
mode: AddressGenerationMode.SequentialArrayLoop,
|
|
arrayLengthBytes: 16,
|
|
arrayElementBytes: 4,
|
|
arrayBaseAddress: 0x20);
|
|
|
|
Assert.That(generator.NextVirtualAddress(), Is.EqualTo(0x20UL));
|
|
Assert.That(generator.NextVirtualAddress(), Is.EqualTo(0x24UL));
|
|
Assert.That(generator.NextVirtualAddress(), Is.EqualTo(0x28UL));
|
|
Assert.That(generator.NextVirtualAddress(), Is.EqualTo(0x2CUL));
|
|
Assert.That(generator.NextVirtualAddress(), Is.EqualTo(0x20UL));
|
|
}
|
|
}
|
|
}
|