1 //
2 // Copyright (c) 2010-2024 Antmicro
3 // Copyright (c) 2011-2015 Realtime Embedded
4 //
5 // This file is licensed under the MIT License.
6 // Full license text is available in 'licenses/MIT.txt'.
7 //
8 using Antmicro.Renode.Core;
9 using Antmicro.Renode.Peripherals.CPU;
10 using Antmicro.Renode.Utilities;
11 using NUnit.Framework;
12 using Moq;
13 using Antmicro.Renode.UnitTests.Mocks;
14 using System.Threading;
15 
16 namespace Antmicro.Renode.UnitTests
17 {
18     [TestFixture]
19     public class MultiCPUTests
20     {
21         [Test]
ShouldEnumerateCPUs()22         public void ShouldEnumerateCPUs()
23         {
24             const int numberOfCpus = 10;
25             var cpus = new ICPU[numberOfCpus];
26             using(var machine = new Machine())
27             {
28                 var sysbus = machine.SystemBus;
29                 for(var i = 0; i < cpus.Length; i++)
30                 {
31                     var mock = new Mock<ICPU>();
32                     mock.Setup(cpu => cpu.Architecture).Returns("mock");  // Required by InitializeInvalidatedAddressesList.
33                     cpus[i] = mock.Object;
34                     sysbus.Register(cpus[i], new CPURegistrationPoint());
35                 }
36                 for(var i = 0; i < cpus.Length; i++)
37                 {
38                     Assert.AreEqual(i, sysbus.GetCPUSlot(cpus[i]));
39                 }
40             }
41         }
42 
43         [Test]
ShouldGuardPeripheralReads([Range(1, 4)] int cpuCount)44         public void ShouldGuardPeripheralReads([Range(1, 4)] int cpuCount)
45         {
46             using(var emulation = new Emulation())
47             using(var machine = new Machine())
48             {
49                 emulation.AddMachine(machine);
50                 var sysbus = machine.SystemBus;
51                 cpuCount.Times(() => sysbus.Register(new ActivelyAskingCPU(machine, 0), new CPURegistrationPoint()));
52                 var peripheral = new ActivelyAskedPeripheral();
53                 sysbus.Register(peripheral, 0.By(1000));
54                 machine.Start();
55                 Thread.Sleep(1000);
56                 machine.Pause();
57                 Assert.IsFalse(peripheral.Failed, "Peripheral was concurrently accessed from multiple CPUs.");
58             }
59         }
60     }
61 }
62 
63