mirror of
https://github.com/AlexAltea/orbital.git
synced 2024-06-16 03:07:58 -04:00
hardware/liverpool: Separate SAM/SMU into dedicated engines
This commit is contained in:
parent
bc67ad6b8b
commit
1541e6eaad
|
@ -45,8 +45,11 @@ ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware)
|
|||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/aeolia)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/aeolia/uart)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool/gca)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool/gmc)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool/oss)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool/smu)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/hardware/liverpool/sam)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/software)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/software/sbl)
|
||||
ORBITAL_SOURCES_APPEND(${ORBITAL_DIR_SOURCES}/orbital/ui)
|
||||
|
|
|
@ -22,9 +22,8 @@
|
|||
#include "gmc/gmc_7_1_sh_mask.h"
|
||||
#include "oss/oss_2_0_d.h"
|
||||
#include "oss/oss_2_0_sh_mask.h"
|
||||
#include "smu/smu_7_1_2_d.h"
|
||||
#include "smu/smu_7_1_2_sh_mask.h"
|
||||
#include "sam/sam.h"
|
||||
|
||||
constexpr auto GC_MMIO_PCI = OffsetRange(0x0000, 0x100);
|
||||
|
||||
// Logging
|
||||
#define DEBUG_GC 0
|
||||
|
@ -40,7 +39,9 @@ do { \
|
|||
LiverpoolGCDevice::LiverpoolGCDevice(PCIeBus* bus, const LiverpoolGCDeviceConfig& config)
|
||||
: PCIeDevice(bus, config),
|
||||
// Engines
|
||||
gmc(bus->space_mem()), ih(*this, gmc)
|
||||
gmc(bus->space_mem()), ih(*this, gmc),
|
||||
smu(gmc, ih),
|
||||
sam(gmc, ih, smu)
|
||||
{
|
||||
// Define BARs
|
||||
space_bar0 = new MemorySpace(this, 0x4000000, {
|
||||
|
@ -83,8 +84,6 @@ void LiverpoolGCDevice::reset() {
|
|||
header.header_type |= PCI_HEADER_TYPE_MULTI_FUNCTION;
|
||||
|
||||
mmio.fill(0);
|
||||
sam_ix.fill(0);
|
||||
sam_sab_ix.fill(0);
|
||||
}
|
||||
|
||||
U64 LiverpoolGCDevice::bar0_read(U64 addr, U64 size) {
|
||||
|
@ -128,7 +127,8 @@ U64 LiverpoolGCDevice::mmio_read(U64 addr, U64 size) {
|
|||
value = gmc.mmio_read(index);
|
||||
return value;
|
||||
}
|
||||
else if (GMC_MMIO_MC.contains(index)) {
|
||||
else if (GMC_MMIO_VM.contains(index)
|
||||
|| GMC_MMIO_MC.contains(index)) {
|
||||
value = gmc.mmio_read(index);
|
||||
return value;
|
||||
}
|
||||
|
@ -136,6 +136,14 @@ U64 LiverpoolGCDevice::mmio_read(U64 addr, U64 size) {
|
|||
value = ih.mmio_read(index);
|
||||
return value;
|
||||
}
|
||||
else if (SMU_MMIO.contains(index)) {
|
||||
value = smu.mmio_read(index);
|
||||
return value;
|
||||
}
|
||||
else if (SAM_MMIO.contains(index)) {
|
||||
value = sam.mmio_read(index);
|
||||
return value;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
// ACP
|
||||
|
@ -149,25 +157,6 @@ U64 LiverpoolGCDevice::mmio_read(U64 addr, U64 size) {
|
|||
value = 0xFFFFFFFF;
|
||||
break;
|
||||
|
||||
// SMU
|
||||
case mmSMC_IND_INDEX:
|
||||
value = mmio[index];
|
||||
break;
|
||||
case mmSMC_IND_DATA:
|
||||
switch (mmio[mmSMC_IND_INDEX]) {
|
||||
case 0xC2100004:
|
||||
value = 0x2 | 0x1;
|
||||
break;
|
||||
case 0xC0500090:
|
||||
value = 0x1;
|
||||
break;
|
||||
case 0xC0500098:
|
||||
value = 0x1;
|
||||
break;
|
||||
default:
|
||||
value = 0x0;
|
||||
}
|
||||
break;
|
||||
|
||||
// GCA
|
||||
case mmGRBM_GFX_INDEX:
|
||||
|
@ -182,25 +171,6 @@ U64 LiverpoolGCDevice::mmio_read(U64 addr, U64 size) {
|
|||
value = 0;
|
||||
break;
|
||||
|
||||
case mmSAM_IX_DATA:
|
||||
index_ix = mmio[mmSAM_IX_INDEX];
|
||||
DPRINTF("mmSAM_IX_DATA_read { index: %X }", index_ix);
|
||||
value = sam_ix[index_ix];
|
||||
break;
|
||||
case mmSAM_SAB_IX_DATA:
|
||||
index_ix = mmio[mmSAM_SAB_IX_INDEX];
|
||||
DPRINTF("mmSAM_SAB_IX_DATA_read { index: %X }", index_ix);
|
||||
value = sam_sab_ix[index_ix];
|
||||
break;
|
||||
|
||||
// Simple registers
|
||||
case mmSAM_GPR_SCRATCH_0:
|
||||
case mmSAM_GPR_SCRATCH_1:
|
||||
case mmSAM_GPR_SCRATCH_2:
|
||||
case mmSAM_GPR_SCRATCH_3:
|
||||
value = mmio[index];
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTF("index=0x%llX, size=0x%llX", index, size);
|
||||
assert_always("Unimplemented");
|
||||
|
@ -222,39 +192,26 @@ void LiverpoolGCDevice::mmio_write(U64 addr, U64 value, U64 size) {
|
|||
else if (GMC_MMIO_VM.contains(index)) {
|
||||
gmc.mmio_write(index, value);
|
||||
}
|
||||
else if (GMC_MMIO_MC.contains(index)) {
|
||||
else if (GMC_MMIO_VM.contains(index)
|
||||
|| GMC_MMIO_MC.contains(index)) {
|
||||
gmc.mmio_write(index, value);
|
||||
return;
|
||||
}
|
||||
else if (OSS_MMIO_IH.contains(index)) {
|
||||
ih.mmio_write(index, value);
|
||||
return;
|
||||
}
|
||||
else if (SMU_MMIO.contains(index)) {
|
||||
smu.mmio_write(index, value);
|
||||
return;
|
||||
}
|
||||
else if (SAM_MMIO.contains(index)) {
|
||||
sam.mmio_write(index, value);
|
||||
return;
|
||||
}
|
||||
|
||||
// Indirect registers
|
||||
switch (index) {
|
||||
case mmSAM_IX_DATA:
|
||||
switch (mmio[mmSAM_IX_INDEX]) {
|
||||
case ixSAM_IH_CPU_AM32_INT:
|
||||
update_sam(value);
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_ACK:
|
||||
sam_ix[ixSAM_IH_CPU_AM32_INT_STATUS] = 0;
|
||||
break;
|
||||
default:
|
||||
index_ix = mmio[mmSAM_IX_INDEX];
|
||||
DPRINTF("mmSAM_IX_DATA_write { index: %X, value: %llX }", index_ix, value);
|
||||
sam_ix[index_ix] = value;
|
||||
}
|
||||
return;
|
||||
|
||||
case mmSAM_SAB_IX_DATA:
|
||||
switch (mmio[mmSAM_SAB_IX_INDEX]) {
|
||||
default:
|
||||
index_ix = mmio[mmSAM_SAB_IX_INDEX];
|
||||
DPRINTF("mmSAM_SAB_IX_DATA_write { index: %X, value: %llX }", index_ix, value);
|
||||
sam_sab_ix[index_ix] = value;
|
||||
}
|
||||
return;
|
||||
|
||||
case mmMM_DATA:
|
||||
mmio_write(mmio[mmMM_INDEX], value, size);
|
||||
return;
|
||||
|
@ -268,10 +225,6 @@ void LiverpoolGCDevice::mmio_write(U64 addr, U64 value, U64 size) {
|
|||
mmio[mmACP_SOFT_RESET] = (value << 16);
|
||||
break;
|
||||
|
||||
// SMU
|
||||
case mmSMC_IND_INDEX:
|
||||
break;
|
||||
|
||||
// GCA
|
||||
case mmGRBM_GFX_INDEX:
|
||||
case mmRLC_PG_ALWAYS_ON_CU_MASK:
|
||||
|
@ -358,23 +311,3 @@ void LiverpoolGCDevice::mmio_write(U64 addr, U64 value, U64 size) {
|
|||
assert_always("Unimplemented");
|
||||
}
|
||||
}
|
||||
|
||||
void LiverpoolGCDevice::update_sam(U32 value) {
|
||||
U64 query_addr;
|
||||
U64 reply_addr;
|
||||
|
||||
assert(value == 1);
|
||||
query_addr = sam_ix[ixSAM_IH_CPU_AM32_INT_CTX_HIGH];
|
||||
query_addr = sam_ix[ixSAM_IH_CPU_AM32_INT_CTX_LOW] | (query_addr << 32);
|
||||
query_addr &= 0xFFFFFFFFFFFFULL;
|
||||
reply_addr = sam_ix[ixSAM_IH_AM32_CPU_INT_CTX_HIGH];
|
||||
reply_addr = sam_ix[ixSAM_IH_AM32_CPU_INT_CTX_LOW] | (reply_addr << 32);
|
||||
reply_addr &= 0xFFFFFFFFFFFFULL;
|
||||
|
||||
const U16 flags = query_addr >> 48;
|
||||
DPRINTF("flags=0x%llX, query=0x%llX, reply=0x%llX\n", flags, query_addr, reply_addr);
|
||||
|
||||
|
||||
sam_ix[ixSAM_IH_CPU_AM32_INT_STATUS] = 0;// 1;
|
||||
sam_ix[ixSAM_IH_AM32_CPU_INT_STATUS] |= 1;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
// Engines
|
||||
#include "gmc/gmc.h"
|
||||
#include "oss/ih.h"
|
||||
#include "smu/smu.h"
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
|
@ -66,16 +67,9 @@ private:
|
|||
U64 mmio_read(U64 addr, U64 size);
|
||||
void mmio_write(U64 addr, U64 value, U64 size);
|
||||
|
||||
// GMC
|
||||
// Engines
|
||||
GmcDevice gmc;
|
||||
|
||||
// OSS
|
||||
IhDevice ih;
|
||||
|
||||
// SAMU
|
||||
std::unique_ptr<SAMUDevice> sam;
|
||||
std::array<U32, 0x80> sam_ix;
|
||||
std::array<U32, 0x40> sam_sab_ix;
|
||||
|
||||
void update_sam(U32 value);
|
||||
SmuDevice smu;
|
||||
SamDevice sam;
|
||||
};
|
||||
|
|
206
src/orbital/hardware/liverpool/sam/sam.cpp
Normal file
206
src/orbital/hardware/liverpool/sam/sam.cpp
Normal file
|
@ -0,0 +1,206 @@
|
|||
/**
|
||||
* AMD Secure Asset Management Unit (SAMU) device.
|
||||
*
|
||||
* Copyright 2017-2021. Orbital project.
|
||||
* Released under MIT license. Read LICENSE for more details.
|
||||
*
|
||||
* Authors:
|
||||
* - Alexandro Sanchez Bach <alexandro@phi.nz>
|
||||
*/
|
||||
|
||||
#include "sam.h"
|
||||
#include <orbital/hardware/liverpool/gmc/gmc.h>
|
||||
#include <orbital/hardware/liverpool/oss/ih.h>
|
||||
#include <orbital/hardware/liverpool/smu/smu.h>
|
||||
|
||||
// SBL
|
||||
constexpr U32 SBL_INT_UNKA202 = 0xA202;
|
||||
constexpr U32 SBL_INT_UNKA303 = 0xA303;
|
||||
constexpr U32 SBL_INT_SMU_READ = 0xA404;
|
||||
constexpr U32 SBL_INT_SMU_WRITE = 0xA505;
|
||||
|
||||
// Logging
|
||||
#define DEBUG_SAM 1
|
||||
#define DPRINTF(...) \
|
||||
do { \
|
||||
if (DEBUG_SAM) { \
|
||||
fprintf(stderr, "lvp-sam (%s:%d): ", __FUNCTION__, __LINE__); \
|
||||
fprintf(stderr, __VA_ARGS__); \
|
||||
fprintf(stderr, "\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
SamDevice::SamDevice(GmcDevice& gmc, IhDevice& ih, SmuDevice& smu)
|
||||
: Device(nullptr), gmc(gmc), ih(ih), smu(smu) {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SamDevice::reset() {
|
||||
gpr.fill(0);
|
||||
ih_cpu_am32_int_ctx = 0;
|
||||
ih_am32_cpu_int_ctx = 0;
|
||||
|
||||
ix_data.fill(0);
|
||||
sab_ix_data.fill(0);
|
||||
}
|
||||
|
||||
U32 SamDevice::mmio_read(U32 index) {
|
||||
U32 value = 0;
|
||||
|
||||
switch (index) {
|
||||
case mmSAM_IX_INDEX:
|
||||
value = sam_ix_index;
|
||||
break;
|
||||
case mmSAM_IX_DATA:
|
||||
switch (sam_ix_index) {
|
||||
case ixSAM_IH_CPU_AM32_INT_CTX_HIGH:
|
||||
value = ih_cpu_am32_int_ctx_high;
|
||||
break;
|
||||
case ixSAM_IH_CPU_AM32_INT_CTX_LOW:
|
||||
value = ih_cpu_am32_int_ctx_low;
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_CTX_HIGH:
|
||||
value = ih_am32_cpu_int_ctx_high;
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_CTX_LOW:
|
||||
value = ih_am32_cpu_int_ctx_low;
|
||||
break;
|
||||
default:
|
||||
DPRINTF("mmSAM_IX_DATA_read { index: %X }", sam_ix_index);
|
||||
value = ix_data[sam_ix_index];
|
||||
}
|
||||
break;
|
||||
case mmSAM_SAB_IX_INDEX:
|
||||
value = sam_sab_ix_index;
|
||||
break;
|
||||
case mmSAM_SAB_IX_DATA:
|
||||
DPRINTF("mmSAM_SAB_IX_DATA_read { index: %X }", sam_sab_ix_index);
|
||||
value = sab_ix_data[sam_sab_ix_index];
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_0:
|
||||
value = gpr[0];
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_1:
|
||||
value = gpr[1];
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_2:
|
||||
value = gpr[2];
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_3:
|
||||
value = gpr[3];
|
||||
break;
|
||||
default:
|
||||
assert_always("Unimplemented");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void SamDevice::mmio_write(U32 index, U32 value) {
|
||||
switch (index) {
|
||||
case mmSAM_IX_INDEX:
|
||||
sam_ix_index = value;
|
||||
break;
|
||||
case mmSAM_IX_DATA:
|
||||
switch (sam_ix_index) {
|
||||
case ixSAM_IH_CPU_AM32_INT:
|
||||
handle_request(value);
|
||||
break;
|
||||
case ixSAM_IH_CPU_AM32_INT_CTX_HIGH:
|
||||
ih_cpu_am32_int_ctx_high = value;
|
||||
break;
|
||||
case ixSAM_IH_CPU_AM32_INT_CTX_LOW:
|
||||
ih_cpu_am32_int_ctx_low = value;
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_CTX_HIGH:
|
||||
ih_am32_cpu_int_ctx_high = value;
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_CTX_LOW:
|
||||
ih_am32_cpu_int_ctx_low = value;
|
||||
break;
|
||||
case ixSAM_IH_AM32_CPU_INT_ACK:
|
||||
//sam_ix[ixSAM_IH_AM32_CPU_INT_STATUS] = 0;
|
||||
ix_data[ixSAM_IH_CPU_AM32_INT_STATUS] = 0;
|
||||
break;
|
||||
default:
|
||||
DPRINTF("mmSAM_IX_DATA_write { index: %X, value: %llX }", sam_ix_index, value);
|
||||
ix_data[sam_ix_index] = value;
|
||||
}
|
||||
break;
|
||||
case mmSAM_SAB_IX_INDEX:
|
||||
sam_sab_ix_index = value;
|
||||
break;
|
||||
case mmSAM_SAB_IX_DATA:
|
||||
switch (sam_sab_ix_index) {
|
||||
default:
|
||||
DPRINTF("mmSAM_SAB_IX_DATA_write { index: %X, value: %llX }", sam_sab_ix_index, value);
|
||||
ix_data[sam_sab_ix_index] = value;
|
||||
}
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_0:
|
||||
gpr[0] = value;
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_1:
|
||||
gpr[1] = value;
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_2:
|
||||
gpr[2] = value;
|
||||
break;
|
||||
case mmSAM_GPR_SCRATCH_3:
|
||||
gpr[3] = value;
|
||||
break;
|
||||
default:
|
||||
assert_always("Unimplemented");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SamDevice::handle_request(U32 value) {
|
||||
const auto query_addr = ih_cpu_am32_int_ctx & UINT64_C(0xFFFFFFFFFFFF);
|
||||
const auto reply_addr = ih_am32_cpu_int_ctx & UINT64_C(0xFFFFFFFFFFFF);
|
||||
|
||||
assert(value == 1);
|
||||
const U16 flags = ih_cpu_am32_int_flags;
|
||||
DPRINTF("flags=0x%llX, query=0x%llX, reply=0x%llX\n", flags, query_addr, reply_addr);
|
||||
if (flags == 0) {
|
||||
const auto id = gpr[0];
|
||||
switch (id) {
|
||||
case SBL_INT_UNKA202:
|
||||
assert_always("Unimplemented");
|
||||
break;
|
||||
case SBL_INT_UNKA303:
|
||||
assert_always("Unimplemented");
|
||||
break;
|
||||
case SBL_INT_SMU_READ:
|
||||
gpr[2] = smu.smc_read(gpr[1]);
|
||||
gpr[3] = 0;
|
||||
break;
|
||||
case SBL_INT_SMU_WRITE:
|
||||
smu.smc_write(gpr[1], gpr[2]);
|
||||
gpr[3] = 0;
|
||||
break;
|
||||
}
|
||||
ix_data[ixSAM_IH_CPU_AM32_INT_STATUS] = 0;// 1;
|
||||
ix_data[ixSAM_IH_AM32_CPU_INT_STATUS] |= 1;
|
||||
return;
|
||||
}
|
||||
else {
|
||||
#if 0
|
||||
uint32_t command = ldl_le_phys(s->gart.as[15 /*gart->as[SAMU_VMID] */], query_addr);
|
||||
if (command == 0) {
|
||||
liverpool_gc_samu_init(&s->samu, query_addr);
|
||||
}
|
||||
else {
|
||||
liverpool_gc_samu_packet(&s->samu, query_addr, reply_addr);
|
||||
}
|
||||
|
||||
if (command == SAMU_CMD_SERVICE_RAND || command == 0) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ix_data[ixSAM_IH_CPU_AM32_INT_STATUS] = 0;//1
|
||||
ix_data[ixSAM_IH_AM32_CPU_INT_STATUS] |= 1;
|
||||
ih.push_iv(0, IV_SRCID_SAM, 0 /* TODO */);
|
||||
}
|
||||
}
|
|
@ -12,6 +12,16 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <orbital/core.h>
|
||||
#include <orbital/offset_range.h>
|
||||
|
||||
// Forward declarations
|
||||
class GmcDevice;
|
||||
class IhDevice;
|
||||
class SmuDevice;
|
||||
|
||||
constexpr auto SAM_MMIO = OffsetRange(0x8800, 0x20);
|
||||
|
||||
// SAMU
|
||||
#define mmSAM_IX_INDEX 0x00008800
|
||||
#define mmSAM_IX_DATA 0x00008801
|
||||
|
@ -31,6 +41,7 @@
|
|||
#define ixSAM_IH_AM32_CPU_INT_CTX_HIGH 0x00000035
|
||||
#define ixSAM_IH_AM32_CPU_INT_CTX_LOW 0x00000036
|
||||
#define ixSAM_IH_AM32_CPU_INT_ACK 0x00000037
|
||||
#define ixSAM_UNK3E 0x0000003E
|
||||
#define ixSAM_IH_CPU_AM32_INT_STATUS 0x0000004A
|
||||
#define ixSAM_IH_AM32_CPU_INT_STATUS 0x0000004B
|
||||
#define ixSAM_RST_HOST_SOFT_RST_RDY 0x00000051
|
||||
|
@ -126,6 +137,41 @@ struct samu_command_service_rand_t {
|
|||
LE<U08> data[0x10];
|
||||
};
|
||||
|
||||
class SAMUDevice : public Device {
|
||||
class SamDevice : public Device {
|
||||
public:
|
||||
SamDevice(GmcDevice& gmc, IhDevice& ih, SmuDevice& smu);
|
||||
|
||||
void reset();
|
||||
|
||||
U32 mmio_read(U32 index);
|
||||
void mmio_write(U32 index, U32 value);
|
||||
|
||||
private:
|
||||
GmcDevice& gmc;
|
||||
IhDevice& ih;
|
||||
SmuDevice& smu;
|
||||
|
||||
std::array<U32, 4> gpr;
|
||||
std::array<U32, 0x80> ix_data;
|
||||
std::array<U32, 0x40> sab_ix_data;
|
||||
U32 sam_ix_index;
|
||||
U32 sam_sab_ix_index;
|
||||
|
||||
union {
|
||||
LE<U64> ih_cpu_am32_int_ctx;
|
||||
Bitfield<U64, 48, 16> ih_cpu_am32_int_flags;
|
||||
struct {
|
||||
LE<U32> ih_cpu_am32_int_ctx_low;
|
||||
LE<U32> ih_cpu_am32_int_ctx_high;
|
||||
};
|
||||
};
|
||||
union {
|
||||
LE<U64> ih_am32_cpu_int_ctx;
|
||||
struct {
|
||||
LE<U32> ih_am32_cpu_int_ctx_low;
|
||||
LE<U32> ih_am32_cpu_int_ctx_high;
|
||||
};
|
||||
};
|
||||
|
||||
void handle_request(U32 value);
|
||||
};
|
||||
|
|
94
src/orbital/hardware/liverpool/smu/smu.cpp
Normal file
94
src/orbital/hardware/liverpool/smu/smu.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
/**
|
||||
* AMD System Management Unit (SMU) device.
|
||||
*
|
||||
* Copyright 2017-2021. Orbital project.
|
||||
* Released under MIT license. Read LICENSE for more details.
|
||||
*
|
||||
* Authors:
|
||||
* - Alexandro Sanchez Bach <alexandro@phi.nz>
|
||||
*/
|
||||
|
||||
#include "smu.h"
|
||||
#include <orbital/hardware/liverpool/gmc/gmc.h>
|
||||
#include <orbital/hardware/liverpool/oss/ih.h>
|
||||
|
||||
#include "smu_7_1_2_d.h"
|
||||
#include "smu_7_1_2_sh_mask.h"
|
||||
|
||||
SmuDevice::SmuDevice(GmcDevice& gmc, IhDevice& ih)
|
||||
: Device(nullptr), gmc(gmc), ih(ih) {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SmuDevice::reset() {
|
||||
}
|
||||
|
||||
U32 SmuDevice::mmio_read(U32 index) {
|
||||
U32 value = 0;
|
||||
|
||||
switch (index) {
|
||||
case mmSMC_IND_INDEX:
|
||||
value = smc_ix;
|
||||
break;
|
||||
case mmSMC_IND_DATA:
|
||||
value = smc_read(smc_ix);
|
||||
break;
|
||||
default:
|
||||
assert_always("Unimplemented");
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void SmuDevice::mmio_write(U32 index, U32 value) {
|
||||
switch (index) {
|
||||
case mmSMC_IND_INDEX:
|
||||
smc_ix = value;
|
||||
break;
|
||||
case mmSMC_IND_DATA:
|
||||
smc_write(smc_ix, value);
|
||||
break;
|
||||
default:
|
||||
assert_always("Unimplemented");
|
||||
}
|
||||
}
|
||||
|
||||
U32 SmuDevice::smc_read(U32 index) {
|
||||
U32 value = 0;
|
||||
|
||||
switch (index) {
|
||||
case 0xC2100004:
|
||||
value = 0x2 | 0x1;
|
||||
break;
|
||||
case 0xC0500090:
|
||||
value = 0x1;
|
||||
break;
|
||||
case 0xC0500098:
|
||||
value = 0x1;
|
||||
break;
|
||||
case ixCG_DCLK_STATUS:
|
||||
value = 0x1;
|
||||
break;
|
||||
case ixCG_VCLK_STATUS:
|
||||
value = 0x1;
|
||||
break;
|
||||
case ixCG_ECLK_STATUS:
|
||||
value = 0x1;
|
||||
break;
|
||||
case 0xC05000E0:
|
||||
value = 0x1;
|
||||
break;
|
||||
case 0xC05000E8:
|
||||
value = 0x1;
|
||||
break;
|
||||
default:
|
||||
//assert_always("Unimplemented");
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void SmuDevice::smc_write(U32 index, U32 value) {
|
||||
//assert_always("Unimplemented");
|
||||
}
|
39
src/orbital/hardware/liverpool/smu/smu.h
Normal file
39
src/orbital/hardware/liverpool/smu/smu.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* AMD System Management Unit (SMU) device.
|
||||
*
|
||||
* Copyright 2017-2021. Orbital project.
|
||||
* Released under MIT license. Read LICENSE for more details.
|
||||
*
|
||||
* Authors:
|
||||
* - Alexandro Sanchez Bach <alexandro@phi.nz>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <orbital/core.h>
|
||||
#include <orbital/offset_range.h>
|
||||
|
||||
// Forward declarations
|
||||
class GmcDevice;
|
||||
class IhDevice;
|
||||
|
||||
constexpr auto SMU_MMIO = OffsetRange(0x80, 0x40);
|
||||
|
||||
class SmuDevice : public Device {
|
||||
public:
|
||||
SmuDevice(GmcDevice& gmc, IhDevice& ih);
|
||||
|
||||
void reset();
|
||||
|
||||
U32 mmio_read(U32 index);
|
||||
void mmio_write(U32 index, U32 value);
|
||||
|
||||
U32 smc_read(U32 index);
|
||||
void smc_write(U32 index, U32 value);
|
||||
|
||||
private:
|
||||
GmcDevice& gmc;
|
||||
IhDevice& ih;
|
||||
|
||||
U32 smc_ix;
|
||||
};
|
Loading…
Reference in a new issue