Extract all VR4300 interfaces to interface.h

This commit is contained in:
Pavel I. Kryukov 2018-09-09 00:02:30 +03:00 committed by Pavel Kryukov
parent 1854ee7236
commit 9ddfa25c77
9 changed files with 107 additions and 48 deletions

View file

@ -22,7 +22,6 @@
#include "rsp/cpu.h"
#include "rsp/interface.h"
#include "vi/controller.h"
#include "vr4300/cpu.h"
#include "vr4300/interface.h"
#define NUM_MAPPINGS 17

View file

@ -25,8 +25,7 @@
#include "rsp/cpu.h"
#include "thread.h"
#include "vi/controller.h"
#include "vr4300/cpu.h"
#include "vr4300/cp1.h"
#include "vr4300/interface.h"
#include <setjmp.h>
#include <limits.h>
@ -48,6 +47,12 @@ struct cen64_device *device_create(struct cen64_device *device,
const struct controller *controller,
bool no_audio, bool no_video, bool profiling) {
// Allocate memory for VR4300
if ((device->vr4300 = vr4300_alloc()) == NULL) {
debug("create_device: Failed to allocate memory for the VR4300.\n");
return NULL;
}
// Initialize the bus.
device->bus.ai = &device->ai;
device->bus.dd = &device->dd;
@ -58,7 +63,7 @@ struct cen64_device *device_create(struct cen64_device *device,
device->bus.rdp = &device->rdp;
device->bus.rsp = &device->rsp;
device->bus.vr4300 = &device->vr4300;
device->bus.vr4300 = device->vr4300;
// Initialize the bus.
if (bus_init(&device->bus, dd_variant != NULL)) {
@ -118,7 +123,7 @@ struct cen64_device *device_create(struct cen64_device *device,
}
// Initialize the VR4300.
if (vr4300_init(&device->vr4300, &device->bus, profiling)) {
if (vr4300_init(device->vr4300, &device->bus, profiling)) {
debug("create_device: Failed to initialize the VR4300.\n");
return NULL;
}
@ -129,10 +134,11 @@ struct cen64_device *device_create(struct cen64_device *device,
// Cleans up memory allocated for the device.
void device_destroy(struct cen64_device *device, const char *cart_path) {
vr4300_free(device->vr4300);
rsp_destroy(&device->rsp);
// Save profiling data, if any
if (cart_path && device->vr4300.profile_samples) {
if (cart_path && has_profile_samples(device->vr4300)) {
char path[PATH_MAX];
snprintf(path, PATH_MAX, "%s.profile", cart_path);
path[PATH_MAX - 1] = '\0';
@ -145,9 +151,10 @@ void device_destroy(struct cen64_device *device, const char *cart_path) {
uint32_t i;
for (i = 0; i < 8 * 1024 * 1024; i++) {
if (device->vr4300.profile_samples[i] < 10)
uint64_t sample = get_profile_sample(device->vr4300, i);
if (sample < 10)
continue;
fprintf(f, "%x %lu\n", i + 0x80000000, device->vr4300.profile_samples[i]);
fprintf(f, "%x %lu\n", i + 0x80000000, sample);
}
fclose(f);
@ -166,7 +173,7 @@ void device_run(struct cen64_device *device) {
// TODO: Preserve host registers pinned to the device.
saved_fpu_state = fpu_get_state();
vr4300_cp1_init(&device->vr4300);
vr4300_cp1_init(device->vr4300);
rsp_late_init(&device->rsp);
// Spin the device until we return (from setjmp).
@ -229,7 +236,7 @@ CEN64_THREAD_RETURN_TYPE run_vr4300_thread(void *opaque) {
}
for (j = 0; j < 3; j++)
vr4300_cycle(&device->vr4300);
vr4300_cycle(device->vr4300);
}
// Sync up with the RCP thread.
@ -294,7 +301,7 @@ int device_spin(struct cen64_device *device) {
unsigned i;
for (i = 0; i < 2; i++) {
vr4300_cycle(&device->vr4300);
vr4300_cycle(device->vr4300);
rsp_cycle(&device->rsp);
ai_cycle(&device->ai);
pi_cycle(&device->pi);
@ -302,7 +309,7 @@ int device_spin(struct cen64_device *device) {
}
vr4300_cycle(&device->vr4300);
vr4300_cycle(device->vr4300);
}
return 0;
@ -310,10 +317,10 @@ int device_spin(struct cen64_device *device) {
// Continually cycles the device until setjmp returns.
int device_debug_spin(struct cen64_device *device) {
struct vr4300_stats vr4300_stats;
struct vr4300_stats* vr4300_stats = vr4300_stats_alloc();
// Prepare stats, set a breakpoint @ VR4300 IPL vector.
memset(&vr4300_stats, 0, sizeof(vr4300_stats));
netapi_debug_wait(device->debug_sfd, device);
if (setjmp(device->bus.unwind_data))
@ -323,20 +330,21 @@ int device_debug_spin(struct cen64_device *device) {
unsigned i;
for (i = 0; i < 2; i++) {
vr4300_cycle(&device->vr4300);
vr4300_cycle(device->vr4300);
rsp_cycle(&device->rsp);
ai_cycle(&device->ai);
pi_cycle(&device->pi);
vi_cycle(&device->vi);
vr4300_cycle_extra(&device->vr4300, &vr4300_stats);
vr4300_cycle_extra(device->vr4300, vr4300_stats);
}
vr4300_cycle(&device->vr4300);
vr4300_cycle_extra(&device->vr4300, &vr4300_stats);
vr4300_cycle(device->vr4300);
vr4300_cycle_extra(device->vr4300, vr4300_stats);
}
vr4300_stats_free(vr4300_stats);
return 0;
}

View file

@ -25,14 +25,14 @@
#include "rsp/cpu.h"
#include "thread.h"
#include "vi/controller.h"
#include "vr4300/cpu.h"
#include "vr4300/interface.h"
// Only used when passed -nointerface.
extern bool device_exit_requested;
struct cen64_device {
struct bus_controller bus;
struct vr4300 vr4300;
struct vr4300* vr4300;
struct ai_controller ai;
struct dd_controller dd;

View file

@ -23,8 +23,7 @@
#include "device/device.h"
#include "device/netapi.h"
#include "vr4300/cpu.h"
#include "vr4300/pipeline.h"
#include "vr4300/interface.h"
// TODO: Really sloppy.
#ifdef __WIN32__
@ -178,11 +177,11 @@ int netapi_debug_handle_request(int sfd, struct cen64_device *device,
length = sizeof(uint64_t) * 33;
for (i = 0; i < 32; i++) {
u64 = htonll(device->vr4300.regs[i]);
u64 = htonll(vr4300_get_register(device->vr4300, i));
memcpy(data + i * sizeof(u64), &u64, sizeof(u64));
}
u64 = htonll(device->vr4300.pipeline.dcwb_latch.common.pc);
u64 = htonll(vr4300_get_pc(device->vr4300));
memcpy(data + 32 * sizeof(u64), &u64, sizeof(u64));
break;

View file

@ -56,7 +56,5 @@ int VR4300_CP1_SUB(struct vr4300 *vr4300, uint32_t iw, uint64_t fs, uint64_t ft)
int VR4300_CP1_TRUNC_L(struct vr4300 *vr4300, uint32_t iw, uint64_t fs, uint64_t ft);
int VR4300_CP1_TRUNC_W(struct vr4300 *vr4300, uint32_t iw, uint64_t fs, uint64_t ft);
cen64_cold void vr4300_cp1_init(struct vr4300 *vr4300);
#endif

View file

@ -9,6 +9,7 @@
//
#include "common.h"
#include "vr4300/interface.h"
#include "vr4300/cp0.h"
#include "vr4300/cp1.h"
#include "vr4300/cpu.h"
@ -23,6 +24,24 @@ const char *mi_register_mnemonics[NUM_MI_REGISTERS] = {
};
#endif
void vr4300_cycle(struct vr4300 *vr4300) {
struct vr4300_pipeline *pipeline = &vr4300->pipeline;
// Increment counters.
vr4300->regs[VR4300_CP0_REGISTER_COUNT]++;
if ((uint32_t) (vr4300->regs[VR4300_CP0_REGISTER_COUNT] >> 1) ==
(uint32_t) vr4300->regs[VR4300_CP0_REGISTER_COMPARE])
vr4300->regs[VR4300_CP0_REGISTER_CAUSE] |= 0x8000;
// We're stalling for something...
if (pipeline->cycles_to_stall > 0)
pipeline->cycles_to_stall--;
else
vr4300_cycle_(vr4300);
}
// Sets the opaque pointer used for external accesses.
static void vr4300_connect_bus(struct vr4300 *vr4300,
struct bus_controller *bus) {
@ -106,3 +125,30 @@ void vr4300_print_summary(struct vr4300_stats *stats) {
}
}
uint64_t vr4300_get_register(struct vr4300 *vr4300, size_t i) {
return vr4300->regs[i];
}
uint64_t vr4300_get_pc(struct vr4300 *vr4300) {
return vr4300->pipeline.dcwb_latch.common.pc;
}
struct vr4300* vr4300_alloc() {
struct vr4300* ptr = (struct vr4300*)malloc(sizeof(struct vr4300));
memset(ptr, 0, sizeof(struct vr4300));
return ptr;
}
cen64_cold void vr4300_free(struct vr4300* ptr) {
free(ptr);
}
cen64_cold struct vr4300_stats* vr4300_stats_alloc() {
struct vr4300_stats* ptr = (struct vr4300_stats*)malloc(sizeof(struct vr4300_stats));
memset(ptr, 0, sizeof(struct vr4300_stats));
return ptr;
}
cen64_cold void vr4300_stats_free(struct vr4300_stats* ptr) {
free(ptr);
}

View file

@ -117,26 +117,5 @@ cen64_cold void vr4300_print_summary(struct vr4300_stats *stats);
cen64_flatten cen64_hot void vr4300_cycle_(struct vr4300 *vr4300);
cen64_flatten cen64_hot static inline void vr4300_cycle(struct vr4300 *vr4300) {
struct vr4300_pipeline *pipeline = &vr4300->pipeline;
// Increment counters.
vr4300->regs[VR4300_CP0_REGISTER_COUNT]++;
if ((uint32_t) (vr4300->regs[VR4300_CP0_REGISTER_COUNT] >> 1) ==
(uint32_t) vr4300->regs[VR4300_CP0_REGISTER_COMPARE])
vr4300->regs[VR4300_CP0_REGISTER_CAUSE] |= 0x8000;
// We're stalling for something...
if (pipeline->cycles_to_stall > 0)
pipeline->cycles_to_stall--;
else
vr4300_cycle_(vr4300);
}
cen64_cold void vr4300_cycle_extra(struct vr4300 *vr4300, struct vr4300_stats *stats);
#endif

View file

@ -182,3 +182,13 @@ int write_mi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
return 0;
}
int has_profile_samples(struct vr4300 const *vr4300)
{
return vr4300->profile_samples != NULL;
}
uint64_t get_profile_sample(struct vr4300 const *vr4300, size_t i)
{
return vr4300->profile_samples[i];
}

View file

@ -11,7 +11,6 @@
#ifndef __vr4300_interface_h__
#define __vr4300_interface_h__
#include "common.h"
#include "vr4300/cpu.h"
enum rcp_interrupt_mask {
MI_INTR_SP = 0x01,
@ -22,6 +21,24 @@ enum rcp_interrupt_mask {
MI_INTR_DP = 0x20
};
struct vr4300;
struct vr4300_stats;
cen64_cold struct vr4300* vr4300_alloc();
cen64_cold void vr4300_free(struct vr4300*);
cen64_cold struct vr4300_stats* vr4300_stats_alloc();
cen64_cold void vr4300_stats_free(struct vr4300_stats*);
cen64_cold int vr4300_init(struct vr4300 *vr4300, struct bus_controller *bus, bool profiling);
cen64_cold void vr4300_cp1_init(struct vr4300 *vr4300);
cen64_flatten cen64_hot void vr4300_cycle(struct vr4300 *vr4300);
cen64_cold void vr4300_cycle_extra(struct vr4300 *vr4300, struct vr4300_stats *stats);
uint64_t vr4300_get_register(struct vr4300 *vr4300, size_t i);
uint64_t vr4300_get_pc(struct vr4300 *vr4300);
int read_mi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_mi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
@ -31,5 +48,8 @@ void signal_rcp_interrupt(struct vr4300 *vr4300, enum rcp_interrupt_mask mask);
void clear_dd_interrupt(struct vr4300 *vr4300);
void signal_dd_interrupt(struct vr4300 *vr4300);
uint64_t get_profile_sample(struct vr4300 const *vr4300, size_t i);
int has_profile_samples(struct vr4300 const *vr4300);
#endif