Skip to content

Commit f6cc0cd

Browse files
author
N3xoX1
committed
cpu: implement exclusive read/writes
1 parent db140df commit f6cc0cd

6 files changed

Lines changed: 58 additions & 45 deletions

File tree

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,60 @@
11
#include "exclusive_monitor_interface.h"
22

3-
ExclusiveMonitor::ExclusiveMonitor(IMemory & /*memory*/, uint32_t processorCount) :
4-
Dynarmic::ExclusiveMonitor(processorCount)
3+
ExclusiveMonitor::ExclusiveMonitor(IMemory & memory, uint32_t processorCount) :
4+
Dynarmic::ExclusiveMonitor(processorCount),
5+
m_memory(memory)
56
{
67
}
78

8-
uint8_t ExclusiveMonitor::ExclusiveRead8(uint32_t /*coreIndex*/, uint64_t /*addr*/)
9+
uint8_t ExclusiveMonitor::ExclusiveRead8(uint32_t coreIndex, uint64_t addr)
910
{
10-
__debugbreak();
11-
return 0;
11+
return ReadAndMark<uint16_t>(coreIndex, addr, [&]() -> uint32_t { return m_memory.Read8(addr); });
1212
}
1313

14-
uint16_t ExclusiveMonitor::ExclusiveRead16(uint32_t /*coreIndex*/, uint64_t /*addr*/)
14+
uint16_t ExclusiveMonitor::ExclusiveRead16(uint32_t coreIndex, uint64_t addr)
1515
{
16-
__debugbreak();
17-
return 0;
16+
return ReadAndMark<uint16_t>(coreIndex, addr, [&]() -> uint32_t { return m_memory.Read16(addr); });
1817
}
1918

20-
uint32_t ExclusiveMonitor::ExclusiveRead32(uint32_t /*coreIndex*/, uint64_t /*addr*/)
19+
uint32_t ExclusiveMonitor::ExclusiveRead32(uint32_t coreIndex, uint64_t addr)
2120
{
22-
__debugbreak();
23-
return 0;
21+
return ReadAndMark<uint32_t>(coreIndex, addr, [&]() -> uint32_t { return m_memory.Read32(addr); });
2422
}
2523

26-
uint64_t ExclusiveMonitor::ExclusiveRead64(uint32_t /*coreIndex*/, uint64_t /*addr*/)
24+
uint64_t ExclusiveMonitor::ExclusiveRead64(uint32_t coreIndex, uint64_t addr)
2725
{
28-
__debugbreak();
29-
return 0;
26+
return ReadAndMark<uint64_t>(coreIndex, addr, [&]() -> uint64_t { return m_memory.Read64(addr); });
3027
}
3128

32-
void ExclusiveMonitor::ClearExclusive(uint32_t /*coreIndex*/)
29+
void ExclusiveMonitor::ClearExclusive(uint32_t coreIndex)
3330
{
34-
__debugbreak();
31+
ClearProcessor(coreIndex);
3532
}
3633

37-
bool ExclusiveMonitor::ExclusiveWrite8(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint8_t /*value*/)
34+
bool ExclusiveMonitor::ExclusiveWrite8(uint32_t coreIndex, uint64_t addr, uint8_t value)
3835
{
39-
__debugbreak();
40-
return false;
36+
return DoExclusiveOperation<uint8_t>(coreIndex, addr, [&](uint8_t expected) -> bool {
37+
return m_memory.WriteExclusive8(addr, value, expected);
38+
});
4139
}
4240

43-
bool ExclusiveMonitor::ExclusiveWrite16(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint16_t /*value*/)
41+
bool ExclusiveMonitor::ExclusiveWrite16(uint32_t coreIndex, uint64_t addr, uint16_t value)
4442
{
45-
__debugbreak();
46-
return false;
43+
return DoExclusiveOperation<uint16_t>(coreIndex, addr, [&](uint16_t expected) -> bool {
44+
return m_memory.WriteExclusive16(addr, value, expected);
45+
});
4746
}
4847

49-
bool ExclusiveMonitor::ExclusiveWrite32(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint32_t /*value*/)
48+
bool ExclusiveMonitor::ExclusiveWrite32(uint32_t coreIndex, uint64_t addr, uint32_t value)
5049
{
51-
__debugbreak();
52-
return false;
50+
return DoExclusiveOperation<uint32_t>(coreIndex, addr, [&](uint32_t expected) -> bool {
51+
return m_memory.WriteExclusive32(addr, value, expected);
52+
});
5353
}
5454

55-
bool ExclusiveMonitor::ExclusiveWrite64(uint32_t /*coreIndex*/, uint64_t /*addr*/, uint64_t /*value*/)
55+
bool ExclusiveMonitor::ExclusiveWrite64(uint32_t coreIndex, uint64_t addr, uint64_t value)
5656
{
57-
__debugbreak();
58-
return false;
57+
return DoExclusiveOperation<uint64_t>(coreIndex, addr, [&](uint64_t expected) -> bool {
58+
return m_memory.WriteExclusive64(addr , value, expected);
59+
});
5960
}

‎src/nxemu-cpu/exclusive_monitor_interface.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,6 @@ class ExclusiveMonitor :
2727
ExclusiveMonitor() = delete;
2828
ExclusiveMonitor(const ExclusiveMonitor &) = delete;
2929
ExclusiveMonitor & operator=(const ExclusiveMonitor &) = delete;
30+
31+
IMemory & m_memory;
3032
};

‎src/nxemu-module-spec/cpu.h‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,16 @@ __interface IMemory
5555
{
5656
void RasterizerMarkRegionCached(uint64_t vaddr, uint64_t size, bool cached) = 0;
5757
uint8_t * GetPointerSilent(uint64_t vaddr) = 0;
58+
59+
uint8_t Read8(uint64_t addr) = 0;
60+
uint16_t Read16(uint64_t addr) = 0;
61+
uint32_t Read32(uint64_t addr) = 0;
62+
uint64_t Read64(uint64_t addr) = 0;
63+
64+
bool WriteExclusive8(uint64_t addr, uint8_t data, uint8_t expected) = 0;
65+
bool WriteExclusive16(uint64_t addr, uint16_t data, uint16_t expected) = 0;
66+
bool WriteExclusive32(uint64_t addr, uint32_t data, uint32_t expected) = 0;
67+
bool WriteExclusive64(uint64_t addr, uint64_t data, uint64_t expected) = 0;
5868
};
5969

6070
__interface ICpuInfo

‎src/nxemu-os/core/hle/kernel/k_thread.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ u16 KThread::GetUserDisableCount() const {
556556
}
557557

558558
auto& memory = this->GetOwnerProcess()->GetMemory();
559-
return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count));
559+
return memory.Read16((m_tls_address + offsetof(ThreadLocalRegion, disable_count)).GetValue());
560560
}
561561

562562
void KThread::SetInterruptFlag() {

‎src/nxemu-os/core/memory.cpp‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -892,19 +892,19 @@ const u8* Memory::GetPointer(Common::ProcessAddress vaddr) const {
892892
return impl->GetPointer(vaddr);
893893
}
894894

895-
u8 Memory::Read8(const Common::ProcessAddress addr) {
895+
uint8_t Memory::Read8(uint64_t addr) {
896896
return impl->Read8(addr);
897897
}
898898

899-
u16 Memory::Read16(const Common::ProcessAddress addr) {
899+
uint16_t Memory::Read16(uint64_t addr) {
900900
return impl->Read16(addr);
901901
}
902902

903-
u32 Memory::Read32(const Common::ProcessAddress addr) {
903+
uint32_t Memory::Read32(uint64_t addr) {
904904
return impl->Read32(addr);
905905
}
906906

907-
u64 Memory::Read64(const Common::ProcessAddress addr) {
907+
uint64_t Memory::Read64(uint64_t addr) {
908908
return impl->Read64(addr);
909909
}
910910

@@ -924,19 +924,19 @@ void Memory::Write64(Common::ProcessAddress addr, u64 data) {
924924
impl->Write64(addr, data);
925925
}
926926

927-
bool Memory::WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected) {
927+
bool Memory::WriteExclusive8(uint64_t addr, uint8_t data, uint8_t expected) {
928928
return impl->WriteExclusive8(addr, data, expected);
929929
}
930930

931-
bool Memory::WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected) {
931+
bool Memory::WriteExclusive16(uint64_t addr, uint16_t data, uint16_t expected) {
932932
return impl->WriteExclusive16(addr, data, expected);
933933
}
934934

935-
bool Memory::WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected) {
935+
bool Memory::WriteExclusive32(uint64_t addr, uint32_t data, uint32_t expected) {
936936
return impl->WriteExclusive32(addr, data, expected);
937937
}
938938

939-
bool Memory::WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected) {
939+
bool Memory::WriteExclusive64(uint64_t addr, uint64_t data, uint64_t expected) {
940940
return impl->WriteExclusive64(addr, data, expected);
941941
}
942942

‎src/nxemu-os/core/memory.h‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ class Memory :
175175
*
176176
* @returns the read 8-bit unsigned value.
177177
*/
178-
u8 Read8(Common::ProcessAddress addr);
178+
uint8_t Read8(uint64_t addr) override;
179179

180180
/**
181181
* Reads a 16-bit unsigned value from the current process' address space
@@ -185,7 +185,7 @@ class Memory :
185185
*
186186
* @returns the read 16-bit unsigned value.
187187
*/
188-
u16 Read16(Common::ProcessAddress addr);
188+
uint16_t Read16(uint64_t addr) override;
189189

190190
/**
191191
* Reads a 32-bit unsigned value from the current process' address space
@@ -195,7 +195,7 @@ class Memory :
195195
*
196196
* @returns the read 32-bit unsigned value.
197197
*/
198-
u32 Read32(Common::ProcessAddress addr);
198+
uint32_t Read32(uint64_t addr) override;
199199

200200
/**
201201
* Reads a 64-bit unsigned value from the current process' address space
@@ -205,7 +205,7 @@ class Memory :
205205
*
206206
* @returns the read 64-bit value.
207207
*/
208-
u64 Read64(Common::ProcessAddress addr);
208+
uint64_t Read64(uint64_t addr) override;
209209

210210
/**
211211
* Writes an 8-bit unsigned integer to the given virtual address in
@@ -262,7 +262,7 @@ class Memory :
262262
*
263263
* @post The memory range [addr, sizeof(data)) contains the given data value.
264264
*/
265-
bool WriteExclusive8(Common::ProcessAddress addr, u8 data, u8 expected);
265+
bool WriteExclusive8(uint64_t addr, uint8_t data, uint8_t expected) override;
266266

267267
/**
268268
* Writes a 16-bit unsigned integer to the given virtual address in
@@ -275,7 +275,7 @@ class Memory :
275275
*
276276
* @post The memory range [addr, sizeof(data)) contains the given data value.
277277
*/
278-
bool WriteExclusive16(Common::ProcessAddress addr, u16 data, u16 expected);
278+
bool WriteExclusive16(uint64_t addr, uint16_t data, uint16_t expected) override;
279279

280280
/**
281281
* Writes a 32-bit unsigned integer to the given virtual address in
@@ -288,7 +288,7 @@ class Memory :
288288
*
289289
* @post The memory range [addr, sizeof(data)) contains the given data value.
290290
*/
291-
bool WriteExclusive32(Common::ProcessAddress addr, u32 data, u32 expected);
291+
bool WriteExclusive32(uint64_t addr, uint32_t data, uint32_t expected) override;
292292

293293
/**
294294
* Writes a 64-bit unsigned integer to the given virtual address in
@@ -301,7 +301,7 @@ class Memory :
301301
*
302302
* @post The memory range [addr, sizeof(data)) contains the given data value.
303303
*/
304-
bool WriteExclusive64(Common::ProcessAddress addr, u64 data, u64 expected);
304+
bool WriteExclusive64(uint64_t addr, uint64_t data, uint64_t expected) override;
305305

306306
/**
307307
* Writes a 128-bit unsigned integer to the given virtual address in

0 commit comments

Comments
 (0)