Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc crash fixes #1080

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/device/r4300/new_dynarec/arm/assem_arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ static void set_jump_target(int addr,u_int target)
{
u_char *ptr=(u_char *)addr;
u_int *ptr2=(u_int *)ptr;
if(ptr==NULL) return;
if(ptr[3]==0xe2) {
assert((target-(u_int)ptr2-8)<1024);
assert((addr&3)==0);
Expand Down Expand Up @@ -2039,6 +2040,7 @@ static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map)
}
static void emit_writeword(int rt, int addr)
{
if(rt<0) return;
u_int offset = addr-(u_int)&g_dev.r4300.new_dynarec_hot_state;
assert(offset<4096);
assem_debug("str %s,fp+%d",regname[rt],offset);
Expand Down Expand Up @@ -2622,6 +2624,7 @@ static void emit_extjump2(int addr, int target, int linker)

static void do_invstub(int n)
{
if(stubs[n][4]==-1) return;
literal_pool(20);
u_int reglist=stubs[n][3];
set_jump_target(stubs[n][1],(int)out);
Expand Down
3 changes: 3 additions & 0 deletions src/device/r4300/new_dynarec/arm64/assem_arm64.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ static void set_jump_target(intptr_t addr,uintptr_t target)
{
u_int *ptr=(u_int *)addr;
intptr_t offset=target-(intptr_t)addr;
if(ptr==NULL) return;

if((*ptr&0xFC000000)==0x14000000) {
assert(offset>=-134217728LL&&offset<134217728LL);
Expand Down Expand Up @@ -2392,6 +2393,7 @@ static void emit_writebyte_indexed_tlb(int rt, int addr, int rs, int map)

static void emit_writeword(int rt, intptr_t addr)
{
if(rt<0) return;
intptr_t offset = addr-(intptr_t)&g_dev.r4300.new_dynarec_hot_state;
assert(offset<16380LL);
assert(offset%4 == 0); /* 4 bytes aligned */
Expand Down Expand Up @@ -3097,6 +3099,7 @@ static void emit_extjump2(intptr_t addr, int target, intptr_t linker)

static void do_invstub(int n)
{
if(stubs[n][4]==-1) return;
literal_pool(20);
u_int reglist=stubs[n][3];
set_jump_target(stubs[n][1],(intptr_t)out);
Expand Down
10 changes: 7 additions & 3 deletions src/device/r4300/new_dynarec/new_dynarec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2813,7 +2813,7 @@ void invalidate_block(u_int block)
{
u_int page;
page=block^0x80000;
if(page>262143&&g_dev.r4300.cp0.tlb.LUT_r[block]) page=(g_dev.r4300.cp0.tlb.LUT_r[block]^0x80000000)>>12;
if(block<0x100000&&page>262143&&g_dev.r4300.cp0.tlb.LUT_r[block]) page=(g_dev.r4300.cp0.tlb.LUT_r[block]^0x80000000)>>12;
if(page>2048) page=2048+(page&2047);
inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
u_int first,last;
Expand Down Expand Up @@ -2869,9 +2869,11 @@ void invalidate_block(u_int block)
#endif

// Don't trap writes
g_dev.r4300.cached_interp.invalid_code[block]=1;
if(block<0x100000) {
g_dev.r4300.cached_interp.invalid_code[block]=1;
}
// If there is a valid TLB entry for this page, remove write protect
if(g_dev.r4300.cp0.tlb.LUT_w[block]) {
if(block<0x100000&&g_dev.r4300.cp0.tlb.LUT_w[block]) {
assert(g_dev.r4300.cp0.tlb.LUT_r[block]==g_dev.r4300.cp0.tlb.LUT_w[block]);
g_dev.r4300.new_dynarec_hot_state.memory_map[block]=((uintptr_t)g_dev.rdram.dram+(uintptr_t)((g_dev.r4300.cp0.tlb.LUT_w[block]&0xFFFFF000)-0x80000000)-(block<<12))>>2;
u_int real_block=g_dev.r4300.cp0.tlb.LUT_w[block]>>12;
Expand Down Expand Up @@ -4270,6 +4272,7 @@ static void loop_preload(signed char pre[],signed char entry[])
// Generate address for load/store instruction
static void address_generation(int i,struct regstat *i_regs,signed char entry[])
{
if(i>=4069) return;
if(itype[i]==LOAD||itype[i]==LOADLR||itype[i]==STORE||itype[i]==STORELR||itype[i]==C1LS) {
int ra=0;
int agr=AGEN1+(i&1);
Expand Down Expand Up @@ -4376,6 +4379,7 @@ static void address_generation(int i,struct regstat *i_regs,signed char entry[])
}
}
// Preload constants for next instruction
if(i+1>=4096) return;
if(itype[i+1]==LOAD||itype[i+1]==LOADLR||itype[i+1]==STORE||itype[i+1]==STORELR||itype[i+1]==C1LS) {
int agr,ra;
#if (NEW_DYNAREC!=NEW_DYNAREC_X86) && (NEW_DYNAREC!=NEW_DYNAREC_X64)
Expand Down
3 changes: 3 additions & 0 deletions src/device/r4300/new_dynarec/x64/assem_x64.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ static const uintptr_t invalidate_block_reg[8] = {
static void set_jump_target(uintptr_t addr,uintptr_t target)
{
u_char *ptr=(u_char *)addr;
if(ptr==NULL) return;
if(*ptr==0x0f)
{
assert(ptr[1]>=0x80&&ptr[1]<=0x8f); // conditional jmp
Expand Down Expand Up @@ -2308,6 +2309,7 @@ static void emit_xchg64(int rs, int rt)
}
static void emit_writeword(int rt, intptr_t addr)
{
if(rt<0) return;
assert((intptr_t)addr-(intptr_t)out>=-2147483648LL&&(intptr_t)addr-(intptr_t)out<2147483647LL);
assem_debug("movl %%%s,%llx",regname[rt],addr);
output_byte(0x89);
Expand Down Expand Up @@ -3026,6 +3028,7 @@ static void emit_extjump2(intptr_t addr, int target, intptr_t linker)

static void do_invstub(int n)
{
if(stubs[n][4]==-1) return;
u_int reglist=stubs[n][3];
set_jump_target(stubs[n][1],(intptr_t)out);
save_regs(reglist);
Expand Down
10 changes: 7 additions & 3 deletions src/device/rcp/ai/ai_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ void read_ai_regs(void* opaque, uint32_t address, uint32_t* value)
ai->last_read = *value;
}
}
else
else if (reg < AI_REGS_COUNT)
{
*value = ai->regs[reg];
}
Expand Down Expand Up @@ -212,11 +212,15 @@ void write_ai_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask
if ((ai->regs[reg]) != (value & mask))
ai->samples_format_changed = 1;

masked_write(&ai->regs[reg], value, mask);
if (reg < AI_REGS_COUNT) {
masked_write(&ai->regs[reg], value, mask);
}
return;
}

masked_write(&ai->regs[reg], value, mask);
if (reg < AI_REGS_COUNT) {
masked_write(&ai->regs[reg], value, mask);
}
}

void ai_end_of_dma_event(void* opaque)
Expand Down
4 changes: 3 additions & 1 deletion src/device/rcp/mi/mi_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,9 @@ void read_mi_regs(void* opaque, uint32_t address, uint32_t* value)
struct mi_controller* mi = (struct mi_controller*)opaque;
uint32_t reg = mi_reg(address);

*value = mi->regs[reg];
if (reg < MI_REGS_COUNT) {
*value = mi->regs[reg];
}
}

void write_mi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
Expand Down
4 changes: 3 additions & 1 deletion src/device/rcp/pi/pi_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ void write_pi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask
return;
}

masked_write(&pi->regs[reg], value, mask);
if (reg < PI_REGS_COUNT) {
masked_write(&pi->regs[reg], value, mask);
}
}

void pi_end_of_dma_event(void* opaque)
Expand Down
16 changes: 12 additions & 4 deletions src/device/rcp/rdp/rdp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ void read_dpc_regs(void* opaque, uint32_t address, uint32_t* value)
struct rdp_core* dp = (struct rdp_core*)opaque;
uint32_t reg = dpc_reg(address);

*value = dp->dpc_regs[reg];
if (reg < DPC_REGS_COUNT) {
*value = dp->dpc_regs[reg];
}
}

void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
Expand All @@ -106,7 +108,9 @@ void write_dpc_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas
return;
}

masked_write(&dp->dpc_regs[reg], value, mask);
if (reg < DPC_REGS_COUNT) {
masked_write(&dp->dpc_regs[reg], value, mask);
}

switch(reg)
{
Expand All @@ -128,15 +132,19 @@ void read_dps_regs(void* opaque, uint32_t address, uint32_t* value)
struct rdp_core* dp = (struct rdp_core*)opaque;
uint32_t reg = dps_reg(address);

*value = dp->dps_regs[reg];
if (reg < DPS_REGS_COUNT) {
*value = dp->dps_regs[reg];
}
}

void write_dps_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
{
struct rdp_core* dp = (struct rdp_core*)opaque;
uint32_t reg = dps_reg(address);

masked_write(&dp->dps_regs[reg], value, mask);
if (reg < DPS_REGS_COUNT) {
masked_write(&dp->dps_regs[reg], value, mask);
}
}

void rdp_interrupt_event(void* opaque)
Expand Down
8 changes: 6 additions & 2 deletions src/device/rcp/ri/ri_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,18 @@ void read_ri_regs(void* opaque, uint32_t address, uint32_t* value)
struct ri_controller* ri = (struct ri_controller*)opaque;
uint32_t reg = ri_reg(address);

*value = ri->regs[reg];
if (reg < RI_REGS_COUNT) {
*value = ri->regs[reg];
}
}

void write_ri_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
{
struct ri_controller* ri = (struct ri_controller*)opaque;
uint32_t reg = ri_reg(address);

masked_write(&ri->regs[reg], value, mask);
if (reg < RI_REGS_COUNT) {
masked_write(&ri->regs[reg], value, mask);
}
}

16 changes: 12 additions & 4 deletions src/device/rcp/rsp/rsp_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,9 @@ void read_rsp_regs(void* opaque, uint32_t address, uint32_t* value)
struct rsp_core* sp = (struct rsp_core*)opaque;
uint32_t reg = rsp_reg(address);

*value = sp->regs[reg];
if (reg < SP_REGS_COUNT) {
*value = sp->regs[reg];
}

if (reg == SP_SEMAPHORE_REG)
{
Expand All @@ -281,7 +283,9 @@ void write_rsp_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mas
return;
}

masked_write(&sp->regs[reg], value, mask);
if (reg < SP_REGS_COUNT) {
masked_write(&sp->regs[reg], value, mask);
}

switch(reg)
{
Expand All @@ -303,7 +307,9 @@ void read_rsp_regs2(void* opaque, uint32_t address, uint32_t* value)
struct rsp_core* sp = (struct rsp_core*)opaque;
uint32_t reg = rsp_reg2(address);

*value = sp->regs2[reg];
if (reg < SP_REGS2_COUNT) {
*value = sp->regs2[reg];
}

if (reg == SP_PC_REG)
*value &= 0xffc;
Expand All @@ -318,7 +324,9 @@ void write_rsp_regs2(void* opaque, uint32_t address, uint32_t value, uint32_t ma
if (reg == SP_PC_REG)
mask &= 0xffc;

masked_write(&sp->regs2[reg], value, mask);
if (reg < SP_REGS2_COUNT) {
masked_write(&sp->regs2[reg], value, mask);
}
}

void do_SP_Task(struct rsp_core* sp)
Expand Down
4 changes: 3 additions & 1 deletion src/device/rcp/si/si_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ void read_si_regs(void* opaque, uint32_t address, uint32_t* value)
struct si_controller* si = (struct si_controller*)opaque;
uint32_t reg = si_reg(address);

*value = si->regs[reg];
if (reg < SI_REGS_COUNT) {
*value = si->regs[reg];
}
}

void write_si_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
Expand Down
8 changes: 6 additions & 2 deletions src/device/rcp/vi/vi_controller.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ void read_vi_regs(void* opaque, uint32_t address, uint32_t* value)
vi->regs[VI_CURRENT_REG] = (vi->regs[VI_CURRENT_REG] & (~1)) | vi->field;
}

*value = vi->regs[reg];
if (reg < VI_REGS_COUNT) {
*value = vi->regs[reg];
}
}

void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask)
Expand Down Expand Up @@ -151,7 +153,9 @@ void write_vi_regs(void* opaque, uint32_t address, uint32_t value, uint32_t mask
return;
}

masked_write(&vi->regs[reg], value, mask);
if (reg < VI_REGS_COUNT) {
masked_write(&vi->regs[reg], value, mask);
}
}

void vi_vertical_interrupt_event(void* opaque)
Expand Down
6 changes: 5 additions & 1 deletion src/device/rdram/rdram.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,9 @@ void read_rdram_regs(void* opaque, uint32_t address, uint32_t* value)
return;
}

*value = rdram->regs[module][reg];
if (reg < RDRAM_REGS_COUNT) {
*value = rdram->regs[module][reg];
}

/* some bits are inverted when read */
if (reg == RDRAM_MODE_REG) {
Expand Down Expand Up @@ -211,6 +213,8 @@ void write_rdram_regs(void* opaque, uint32_t address, uint32_t value, uint32_t m
}
}

/* don't go out-of-bounds */
if (reg >= RDRAM_REGS_COUNT) return;

if (address & RDRAM_BCAST_ADDRESS_MASK) {
for (module = 0; module < modules; ++module) {
Expand Down