radeon_hd: AtomBIOS loop failure detection now time based
* If the same call is made for 5 seconds straight, fail. * Resolves random AtomBIOS failures. * AtomBIOS failures now represent *real* bugs :)
This commit is contained in:
@@ -36,10 +36,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* AtomBIOS loop detection
|
/* AtomBIOS loop detection
|
||||||
* Number of repeat AtomBIOS jmp operations
|
* Number of seconds of identical jmp operations
|
||||||
* before bailing due to stuck in a loop
|
* before detecting a fault.
|
||||||
*/
|
*/
|
||||||
#define ATOM_OP_JMP_TIMEOUT 512
|
#define ATOM_OP_JMP_TIMEOUT 5
|
||||||
|
|
||||||
// *** Tracing
|
// *** Tracing
|
||||||
#undef TRACE
|
#undef TRACE
|
||||||
@@ -77,8 +77,9 @@ typedef struct {
|
|||||||
uint32 *ps, *ws;
|
uint32 *ps, *ws;
|
||||||
int ps_shift;
|
int ps_shift;
|
||||||
uint16 start;
|
uint16 start;
|
||||||
uint16 last_jump;
|
uint16 lastJump;
|
||||||
uint16 last_jump_count;
|
uint32 lastJumpCount;
|
||||||
|
bigtime_t jumpStart;
|
||||||
bool abort;
|
bool abort;
|
||||||
} atom_exec_context;
|
} atom_exec_context;
|
||||||
|
|
||||||
@@ -541,7 +542,7 @@ atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
|
|||||||
if (idx < ATOM_TABLE_NAMES_CNT) {
|
if (idx < ATOM_TABLE_NAMES_CNT) {
|
||||||
TRACE("%s: table: %s (%d)\n", __func__, atom_table_names[idx], idx);
|
TRACE("%s: table: %s (%d)\n", __func__, atom_table_names[idx], idx);
|
||||||
} else {
|
} else {
|
||||||
TRACE("%s: table: unknown (%d)\n", __func__, idx);
|
ERROR("%s: table: unknown (%d)\n", __func__, idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) {
|
if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) {
|
||||||
@@ -659,17 +660,20 @@ atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
|
|||||||
execute? "yes" : "no", target);
|
execute? "yes" : "no", target);
|
||||||
|
|
||||||
if (execute) {
|
if (execute) {
|
||||||
if (ctx->last_jump == (ctx->start + target)) {
|
// Time based jmp timeout
|
||||||
if (ctx->last_jump_count > ATOM_OP_JMP_TIMEOUT) {
|
if (ctx->lastJump == (ctx->start + target)) {
|
||||||
ERROR("%s: Error: AtomBIOS stuck in loop for more then %d"
|
bigtime_t loopDuration = system_time() - ctx->jumpStart;
|
||||||
" jumps... abort!\n", __func__, ATOM_OP_JMP_TIMEOUT);
|
if (loopDuration > ATOM_OP_JMP_TIMEOUT * 1000000) {
|
||||||
|
ERROR("%s: Error: AtomBIOS stuck in loop for more then %d "
|
||||||
|
"seconds. (%" B_PRIu32 " identical jmp op's)\n", __func__,
|
||||||
|
ATOM_OP_JMP_TIMEOUT, ctx->lastJumpCount);
|
||||||
ctx->abort = true;
|
ctx->abort = true;
|
||||||
|
} else
|
||||||
|
ctx->lastJumpCount++;
|
||||||
} else {
|
} else {
|
||||||
ctx->last_jump_count++;
|
ctx->jumpStart = system_time();
|
||||||
}
|
ctx->lastJump = ctx->start + target;
|
||||||
} else {
|
ctx->lastJumpCount = 1;
|
||||||
ctx->last_jump = ctx->start + target;
|
|
||||||
ctx->last_jump_count = 1;
|
|
||||||
}
|
}
|
||||||
*ptr = ctx->start + target;
|
*ptr = ctx->start + target;
|
||||||
}
|
}
|
||||||
@@ -1137,8 +1141,10 @@ atom_execute_table_locked(atom_context *ctx, int index, uint32 * params)
|
|||||||
unsigned char op;
|
unsigned char op;
|
||||||
atom_exec_context ectx;
|
atom_exec_context ectx;
|
||||||
|
|
||||||
if (!base)
|
if (!base) {
|
||||||
|
ERROR("%s: BUG: Table called doesn't exist in AtomBIOS!\n", __func__);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
len = CU16(base + ATOM_CT_SIZE_PTR);
|
len = CU16(base + ATOM_CT_SIZE_PTR);
|
||||||
ws = CU8(base + ATOM_CT_WS_PTR);
|
ws = CU8(base + ATOM_CT_WS_PTR);
|
||||||
@@ -1150,8 +1156,9 @@ atom_execute_table_locked(atom_context *ctx, int index, uint32 * params)
|
|||||||
ectx.start = base;
|
ectx.start = base;
|
||||||
ectx.ps = params;
|
ectx.ps = params;
|
||||||
ectx.abort = false;
|
ectx.abort = false;
|
||||||
ectx.last_jump = 0;
|
ectx.lastJump = 0;
|
||||||
ectx.last_jump_count = 0;
|
ectx.lastJumpCount = 0;
|
||||||
|
ectx.jumpStart = 0;
|
||||||
if (ws)
|
if (ws)
|
||||||
ectx.ws = (uint32*)malloc(4 * ws);
|
ectx.ws = (uint32*)malloc(4 * ws);
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user