Mask bus writes to requested type, etc.

This commit is contained in:
Tyler Stachecki 2014-04-18 13:34:23 -04:00
parent 9098266156
commit 25a6ae8431
24 changed files with 91 additions and 77 deletions

View file

@ -41,13 +41,14 @@ int read_ai_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to the AI MMIO register space.
int write_ai_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_ai_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct ai_controller *ai = (struct ai_controller *) opaque;
unsigned offset = address - AI_REGS_BASE_ADDRESS;
enum ai_register reg = (offset >> 2);
debug_mmio_write(ai, ai_register_mnemonics[reg], *word);
ai->regs[reg] = *word;
debug_mmio_write(ai, ai_register_mnemonics[reg], word, dqm);
ai->regs[reg] &= ~dqm;
ai->regs[reg] |= word;
return 0;
}

View file

@ -32,7 +32,7 @@ struct ai_controller {
int ai_init(struct ai_controller *ai, struct bus_controller *bus);
int read_ai_regs(void *opaque, uint32_t address, uint32_t *word);
int write_ai_regs(void *opaque, uint32_t address, uint32_t *word);
int write_ai_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -90,7 +90,7 @@ int bus_read_word(struct bus_controller *bus,
// Issues a write request to the bus.
int bus_write_word(struct bus_controller *bus,
uint32_t address, uint32_t *word) {
uint32_t address, uint32_t word, uint32_t dqm) {
const struct memory_mapping *node;
if ((node = resolve_mapped_address(bus->map, address)) == NULL) {
@ -99,6 +99,6 @@ int bus_write_word(struct bus_controller *bus,
return 0;
}
return node->on_write(node->instance, address, word);
return node->on_write(node->instance, address, word, dqm);
}

View file

@ -43,7 +43,7 @@ int bus_read_word(struct bus_controller *bus,
uint32_t address, uint32_t *word);
int bus_write_word(struct bus_controller *bus,
uint32_t address, uint32_t *word);
uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -109,7 +109,7 @@ static void fixup(struct memory_map *map, struct memory_map_node *node) {
// Inserts a mapping into the tree.
void map_address_range(struct memory_map *map, uint32_t start, uint32_t length,
void *instance, memory_function on_read, memory_function on_write) {
void *instance, memory_rd_function on_read, memory_wr_function on_write) {
struct memory_map_node *check = map->root;
struct memory_map_node *cur = map->nil;
uint32_t end = start + length - 1;

View file

@ -13,7 +13,8 @@
#include "common.h"
// Callback functions to handle reads/writes.
typedef int (*memory_function)(void *, uint32_t, uint32_t *);
typedef int (*memory_rd_function)(void *, uint32_t, uint32_t *);
typedef int (*memory_wr_function)(void *, uint32_t, uint32_t, uint32_t);
enum memory_map_color {
MEMORY_MAP_BLACK,
@ -23,8 +24,8 @@ enum memory_map_color {
struct memory_mapping {
void *instance;
memory_function on_read;
memory_function on_write;
memory_rd_function on_read;
memory_wr_function on_write;
uint32_t length;
uint32_t start;
@ -54,7 +55,7 @@ void destroy_memory_map(struct memory_map *memory_map);
void map_address_range(struct memory_map *memory_map,
uint32_t start, uint32_t length, void *instance,
memory_function on_read, memory_function on_write);
memory_rd_function on_read, memory_wr_function on_write);
const struct memory_mapping* resolve_mapped_address(
const struct memory_map *memory_map, uint32_t address);

View file

@ -107,10 +107,10 @@ static inline uint32_t byteswap_32(uint32_t word) {
#include <cstdio>
#endif
#define debug_mmio_read(what, mnemonic, val) fprintf(stderr, #what": READ [%s]: 0x%.8X\n", mnemonic, val)
#define debug_mmio_write(what, mnemonic, val) fprintf(stderr, #what": WRITE [%s]: 0x%.8X\n", mnemonic, val)
#define debug_mmio_write(what, mnemonic, val, dqm) fprintf(stderr, #what": WRITE [%s]: 0x%.8X/0x%.8X\n", mnemonic, val, dqm)
#else
#define debug_mmio_read(what, mnemonic, val) do {} while (0)
#define debug_mmio_write(what, mnemonic, val) do {} while (0)
#define debug_mmio_write(what, mnemonic, val, dqm) do {} while (0)
#endif
#endif

View file

@ -46,19 +46,20 @@ int read_pi_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to cartridge ROM.
int write_cart_rom(void *opaque, uint32_t address, uint32_t *word) {
int write_cart_rom(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
assert(0 && "Attempt to write to cart ROM.");
return 0;
}
// Writes a word to the PI MMIO register space.
int write_pi_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_pi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct pi_controller *pi = (struct pi_controller *) opaque;
unsigned offset = address - PI_REGS_BASE_ADDRESS;
enum pi_register reg = (offset >> 2);
debug_mmio_write(pi, pi_register_mnemonics[reg], *word);
pi->regs[reg] = *word;
debug_mmio_write(pi, pi_register_mnemonics[reg], word, dqm);
pi->regs[reg] &= ~dqm;
pi->regs[reg] |= word;
return 0;
}

View file

@ -33,8 +33,8 @@ struct pi_controller {
int pi_init(struct pi_controller *pi, struct bus_controller *bus);
int read_cart_rom(void *opaque, uint32_t address, uint32_t *word);
int read_pi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_cart_rom(void *opaque, uint32_t address, uint32_t *word);
int write_pi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_cart_rom(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_pi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -25,13 +25,14 @@ int read_dp_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to the DP MMIO register space.
int write_dp_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_dp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct rdp *rdp = (struct rdp *) opaque;
uint32_t offset = address - DP_REGS_BASE_ADDRESS;
enum dp_register reg = (offset >> 2);
debug_mmio_write(rdp, dp_register_mnemonics[reg], *word);
rdp->regs[reg] = *word;
debug_mmio_write(rdp, dp_register_mnemonics[reg], word, dqm);
rdp->regs[reg] &= ~dqm;
rdp->regs[reg] |= word;
return 0;
}

View file

@ -13,7 +13,7 @@
#include "common.h"
int read_dp_regs(void *opaque, uint32_t address, uint32_t *word);
int write_dp_regs(void *opaque, uint32_t address, uint32_t *word);
int write_dp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -60,24 +60,26 @@ int read_ri_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to the RDRAM MMIO register space.
int write_rdram_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_rdram_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct ri_controller *ri = (struct ri_controller *) opaque;
unsigned offset = address - RDRAM_REGS_BASE_ADDRESS;
enum rdram_register reg = (offset >> 2);
debug_mmio_write(rdram, rdram_register_mnemonics[reg], *word);
ri->rdram_regs[reg] = *word;
debug_mmio_write(rdram, rdram_register_mnemonics[reg], word, dqm);
ri->rdram_regs[reg] &= ~dqm;
ri->rdram_regs[reg] |= word;
return 0;
}
// Writes a word to the RI MMIO register space.
int write_ri_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_ri_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct ri_controller *ri = (struct ri_controller *) opaque;
unsigned offset = address - RI_REGS_BASE_ADDRESS;
enum ri_register reg = (offset >> 2);
debug_mmio_write(ri, ri_register_mnemonics[reg], *word);
ri->regs[reg] = *word;
debug_mmio_write(ri, ri_register_mnemonics[reg], word, dqm);
ri->regs[reg] &= ~dqm;
ri->regs[reg] |= word;
return 0;
}

View file

@ -45,8 +45,8 @@ struct ri_controller {
int ri_init(struct ri_controller *ri, struct bus_controller *bus);
int read_rdram_regs(void *opaque, uint32_t address, uint32_t *word);
int read_ri_regs(void *opaque, uint32_t address, uint32_t *word);
int write_rdram_regs(void *opaque, uint32_t address, uint32_t *word);
int write_ri_regs(void *opaque, uint32_t address, uint32_t *word);
int write_rdram_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_ri_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -18,11 +18,6 @@ int read_sp_mem(void *opaque, uint32_t address, uint32_t *word) {
return 0;
}
// Writes a word to the SP memory MMIO register space.
int write_sp_mem(void *opaque, uint32_t address, uint32_t *word) {
return 0;
}
// Reads a word from the SP MMIO register space.
int read_sp_regs(void *opaque, uint32_t address, uint32_t *word) {
struct rsp *rsp = (struct rsp *) opaque;
@ -34,17 +29,6 @@ int read_sp_regs(void *opaque, uint32_t address, uint32_t *word) {
return 0;
}
// Writes a word to the SP MMIO register space.
int write_sp_regs(void *opaque, uint32_t address, uint32_t *word) {
struct rsp *rsp = (struct rsp *) opaque;
uint32_t offset = address - SP_REGS_BASE_ADDRESS;
enum sp_register reg = (offset >> 2);
debug_mmio_write(rsp, sp_register_mnemonics[reg], *word);
rsp->regs[reg + SP_REGISTER_OFFSET] = *word;
return 0;
}
// Reads a word from the (high) SP MMIO register space.
int read_sp_regs2(void *opaque, uint32_t address, uint32_t *word) {
struct rsp *rsp = (struct rsp *) opaque;
@ -56,14 +40,32 @@ int read_sp_regs2(void *opaque, uint32_t address, uint32_t *word) {
return 0;
}
// Writes a word to the SP memory MMIO register space.
int write_sp_mem(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
return 0;
}
// Writes a word to the SP MMIO register space.
int write_sp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct rsp *rsp = (struct rsp *) opaque;
uint32_t offset = address - SP_REGS_BASE_ADDRESS;
enum sp_register reg = (offset >> 2);
debug_mmio_write(rsp, sp_register_mnemonics[reg], word, dqm);
rsp->regs[reg + SP_REGISTER_OFFSET] &= ~dqm;
rsp->regs[reg + SP_REGISTER_OFFSET] |= word;
return 0;
}
// Writes a word to the (high) SP MMIO register space.
int write_sp_regs2(void *opaque, uint32_t address, uint32_t *word) {
int write_sp_regs2(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct rsp *rsp = (struct rsp *) opaque;
uint32_t offset = address - SP_REGS2_BASE_ADDRESS;
enum sp_register reg = (offset >> 2) + SP_PC_REG;
debug_mmio_write(rsp, sp_register_mnemonics[reg], *word);
rsp->regs[reg + SP_REGISTER_OFFSET] = *word;
debug_mmio_write(rsp, sp_register_mnemonics[reg], word, dqm);
rsp->regs[reg + SP_REGISTER_OFFSET] &= ~dqm;
rsp->regs[reg + SP_REGISTER_OFFSET] |= word;
return 0;
}

View file

@ -13,11 +13,11 @@
#include "common.h"
int read_sp_mem(void *opaque, uint32_t address, uint32_t *word);
int write_sp_mem(void *opaque, uint32_t address, uint32_t *word);
int read_sp_regs(void *opaque, uint32_t address, uint32_t *word);
int write_sp_regs(void *opaque, uint32_t address, uint32_t *word);
int read_sp_regs2(void *opaque, uint32_t address, uint32_t *word);
int write_sp_regs2(void *opaque, uint32_t address, uint32_t *word);
int write_sp_mem(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_sp_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_sp_regs2(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -12,6 +12,7 @@
#include "bus/address.h"
#include "bus/controller.h"
#include "si/controller.h"
#include <assert.h>
#ifdef DEBUG_MMIO_REGISTER_ACCESS
const char *si_register_mnemonics[NUM_SI_REGISTERS] = {
@ -56,29 +57,28 @@ int read_si_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to PIF RAM.
int write_pif_ram(void unused(*opaque),
uint32_t unused(address), uint32_t unused(*word)) {
assert("Attempt to write to PIF RAM.");
int write_pif_ram(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
assert(0 && "Attempt to write to PIF RAM.");
return -1;
}
// Writes a word to PIF ROM.
int write_pif_rom(void unused(*opaque),
uint32_t unused(address), uint32_t unused(*word)) {
assert("Attempt to write to PIF ROM.");
int write_pif_rom(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
assert(0 && "Attempt to write to PIF ROM.");
return -1;
}
// Writes a word to the SI MMIO register space.
int write_si_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_si_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct si_controller *si = (struct si_controller *) opaque;
unsigned offset = address - SI_REGS_BASE_ADDRESS;
enum si_register reg = (offset >> 2);
debug_mmio_write(si, si_register_mnemonics[reg], *word);
si->regs[reg] = *word;
debug_mmio_write(si, si_register_mnemonics[reg], word, dqm);
si->regs[reg] &= ~dqm;
si->regs[reg] |= word;
return 0;
}

View file

@ -38,9 +38,9 @@ int si_init(struct si_controller *si,
int read_pif_ram(void *opaque, uint32_t address, uint32_t *word);
int read_pif_rom(void *opaque, uint32_t address, uint32_t *word);
int read_si_regs(void *opaque, uint32_t address, uint32_t *word);
int write_pif_ram(void *opaque, uint32_t address, uint32_t *word);
int write_pif_rom(void *opaque, uint32_t address, uint32_t *word);
int write_si_regs(void *opaque, uint32_t address, uint32_t *word);
int write_pif_ram(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_pif_rom(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int write_si_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
#endif

View file

@ -41,13 +41,14 @@ int read_vi_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to the VI MMIO register space.
int write_vi_regs(void *opaque, uint32_t address, uint32_t *word) {
int write_vi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm) {
struct vi_controller *vi = (struct vi_controller *) opaque;
unsigned offset = address - VI_REGS_BASE_ADDRESS;
enum vi_register reg = (offset >> 2);
debug_mmio_write(vi, vi_register_mnemonics[reg], *word);
*word = vi->regs[reg];
debug_mmio_write(vi, vi_register_mnemonics[reg], word, dqm);
vi->regs[reg] &= ~dqm;
vi->regs[reg] |= word;
return 0;
}

View file

@ -31,7 +31,7 @@ struct vi_controller {
};
int read_vi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_vi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_vi_regs(void *opaque, uint32_t address, uint32_t word, uint32_t dqm);
int vi_init(struct vi_controller *vi, struct bus_controller *bus);
#endif

View file

@ -401,11 +401,14 @@ void VR4300_STORE(struct vr4300 *vr4300, uint64_t rs, uint64_t rt) {
struct vr4300_exdc_latch *exdc_latch = &vr4300->pipeline.exdc_latch;
uint32_t iw = rfex_latch->iw;
unsigned request_size = (iw >> 26 & 0x3) + 1;
uint32_t mask = (~0U >> (4 - request_size));
exdc_latch->request.address = rs + (int16_t) iw;
exdc_latch->request.dqm = mask << (iw & 0x3);
exdc_latch->request.type = VR4300_BUS_REQUEST_WRITE;
exdc_latch->request.size = (iw >> 26 & 0x3) + 1;
exdc_latch->request.word = rt;
exdc_latch->request.size = request_size;
exdc_latch->request.word = rt & mask;
}
// Function lookup table.

View file

@ -25,13 +25,14 @@ int read_mi_regs(void *opaque, uint32_t address, uint32_t *word) {
}
// Writes a word to the MI MMIO register space.
int write_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) {
struct vr4300 *vr4300 = (struct vr4300 *) opaque;
uint32_t offset = address - MI_REGS_BASE_ADDRESS;
enum mi_register reg = (offset >> 2);
debug_mmio_write(vr4300, mi_register_mnemonics[reg], *word);
vr4300->mi_regs[reg] = *word;
debug_mmio_write(vr4300, mi_register_mnemonics[reg], word, dqm);
vr4300->mi_regs[reg] &= ~dqm;
vr4300->mi_regs[reg] |= word;
return 0;
}

View file

@ -13,7 +13,7 @@
#include "common.h"
int read_mi_regs(void *opaque, uint32_t address, uint32_t *word);
int write_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);
#endif

View file

@ -155,7 +155,7 @@ static inline int vr4300_dc_stage (struct vr4300 *vr4300) {
// TODO/FIXME: Not accurate.
bus_write_word(vr4300->bus, exdc_latch->request.address,
&exdc_latch->request.word);
exdc_latch->request.word, exdc_latch->request.dqm);
}
}

View file

@ -25,6 +25,7 @@ enum vr4300_bus_request_type {
struct vr4300_bus_request {
uint64_t address;
uint32_t dqm;
uint32_t word;
unsigned size;