mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-20 21:17:58 -04:00
Extract all VR4300 interfaces to interface.h
This commit is contained in:
parent
1854ee7236
commit
9ddfa25c77
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
46
vr4300/cpu.c
46
vr4300/cpu.c
|
@ -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);
|
||||
}
|
||||
|
|
21
vr4300/cpu.h
21
vr4300/cpu.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue