[haiku-commits] r42585 - in haiku/trunk/src/add-ons/accelerants/radeon_hd: . atombios

  • From: kallisti5@xxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 6 Aug 2011 09:00:50 +0200 (CEST)

Author: kallisti5
Date: 2011-08-06 09:00:49 +0200 (Sat, 06 Aug 2011)
New Revision: 42585
Changeset: https://dev.haiku-os.org/changeset/42585

Modified:
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-names.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp
   haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.h
   haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp
Log:
* more style cleanup
* backport additional bugfixes from drm version
* add logic to detect infinite execution loops
* add a semephore to prevent multiple executions on
  non-thread safe code ( this needs testing )


Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-names.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-names.h 
2011-08-06 05:51:37 UTC (rev 42584)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom-names.h 
2011-08-06 07:00:49 UTC (rev 42585)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2008 Advanced Micro Devices, Inc.  
+ * Copyright 2008 Advanced Micro Devices, Inc.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -27,10 +27,8 @@
 
 #include "atom.h"
 
-#ifdef ATOM_DEBUG
-
 #define ATOM_OP_NAMES_CNT 123
-static char *atom_op_names[ATOM_OP_NAMES_CNT]={
+const char *atom_op_names[ATOM_OP_NAMES_CNT] = {
 "RESERVED", "MOVE_REG", "MOVE_PS", "MOVE_WS", "MOVE_FB", "MOVE_PLL",
 "MOVE_MC", "AND_REG", "AND_PS", "AND_WS", "AND_FB", "AND_PLL", "AND_MC",
 "OR_REG", "OR_PS", "OR_WS", "OR_FB", "OR_PLL", "OR_MC", "SHIFT_LEFT_REG",
@@ -56,7 +54,7 @@
 };
 
 #define ATOM_TABLE_NAMES_CNT 74
-static char *atom_table_names[ATOM_TABLE_NAMES_CNT]={
+const char *atom_table_names[ATOM_TABLE_NAMES_CNT] = {
 "ASIC_Init", "GetDisplaySurfaceSize", "ASIC_RegistersInit",
 "VRAM_BlockVenderDetection", "SetClocksRatio", "MemoryControllerInit",
 "GPIO_PinInit", "MemoryParamAdjust", "DVOEncoderControl",
@@ -85,16 +83,9 @@
 };
 
 #define ATOM_IO_NAMES_CNT 5
-static char *atom_io_names[ATOM_IO_NAMES_CNT]={
+const char *atom_io_names[ATOM_IO_NAMES_CNT] = {
 "MM", "PLL", "MC", "PCIE", "PCIE PORT",
 };
 
-#else
 
-#define ATOM_OP_NAMES_CNT 0
-#define ATOM_TABLE_NAMES_CNT 0
-#define ATOM_IO_NAMES_CNT 0
-
 #endif
-
-#endif

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp     
2011-08-06 05:51:37 UTC (rev 42584)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.cpp     
2011-08-06 07:00:49 UTC (rev 42585)
@@ -69,10 +69,15 @@
        uint32 *ps, *ws;
        int ps_shift;
        uint16 start;
+       uint16 last_jump;
+       uint16 last_jump_count;
+       bool abort;
 } atom_exec_context;
 
 int atom_debug = 0;
-void atom_execute_table(atom_context *ctx, int index, uint32 *params);
+status_t atom_execute_table_locked(atom_context *ctx,
+       int index, uint32 *params);
+status_t atom_execute_table(atom_context *ctx, int index, uint32 *params);
 
 static uint32 atom_arg_mask[8] = {0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000,
        0xFF, 0xFF00, 0xFF0000, 0xFF000000};
@@ -280,7 +285,7 @@
        switch(arg) {
                case ATOM_ARG_REG:
                case ATOM_ARG_ID:
-                       (*ptr)+=2;
+                       (*ptr) += 2;
                        break;
                case ATOM_ARG_PLL:
                case ATOM_ARG_MC:
@@ -290,23 +295,23 @@
                        (*ptr)++;
                        break;
                case ATOM_ARG_IMM:
-               switch(align) {
-                       case ATOM_SRC_DWORD:
-                               (*ptr)+=4;
-                               return;
-                       case ATOM_SRC_WORD0:
-                       case ATOM_SRC_WORD8:
-                       case ATOM_SRC_WORD16:
-                               (*ptr)+=2;
-                               return;
-                       case ATOM_SRC_BYTE0:
-                       case ATOM_SRC_BYTE8:
-                       case ATOM_SRC_BYTE16:
-                       case ATOM_SRC_BYTE24:
-                               (*ptr)++;
-                               return;
-               }
-               return;
+                       switch(align) {
+                               case ATOM_SRC_DWORD:
+                                       (*ptr) += 4;
+                                       return;
+                               case ATOM_SRC_WORD0:
+                               case ATOM_SRC_WORD8:
+                               case ATOM_SRC_WORD16:
+                                       (*ptr) += 2;
+                                       return;
+                               case ATOM_SRC_BYTE0:
+                               case ATOM_SRC_BYTE8:
+                               case ATOM_SRC_BYTE16:
+                               case ATOM_SRC_BYTE24:
+                                       (*ptr)++;
+                                       return;
+                       }
+                       return;
        }
 }
 
@@ -319,6 +324,34 @@
 
 
 static uint32
+atom_get_src_direct(atom_exec_context *ctx, uint8_t align, int *ptr)
+{
+       uint32 val = 0xCDCDCDCD;
+
+       switch (align) {
+               case ATOM_SRC_DWORD:
+                       val = U32(*ptr);
+                       (*ptr) += 4;
+                       break;
+               case ATOM_SRC_WORD0:
+               case ATOM_SRC_WORD8:
+               case ATOM_SRC_WORD16:
+                       val = U16(*ptr);
+                       (*ptr) += 2;
+                       break;
+               case ATOM_SRC_BYTE0:
+               case ATOM_SRC_BYTE8:
+               case ATOM_SRC_BYTE16:
+               case ATOM_SRC_BYTE24:
+                       val = U8(*ptr);
+                       (*ptr)++;
+                       break;
+       }
+       return val;
+}
+
+
+static uint32
 atom_get_dst(atom_exec_context *ctx, int arg, uint8 attr,
        int *ptr, uint32 *saved, int print)
 {
@@ -348,85 +381,92 @@
        saved &= ~atom_arg_mask[align];
        val |= saved;
        switch(arg) {
-       case ATOM_ARG_REG:
-       idx = U16(*ptr);
-       (*ptr)+=2;
-       idx += gctx->reg_block;
-       switch(gctx->io_mode) {
-       case ATOM_IO_MM:
-               if (idx == 0)
-               gctx->card->reg_write(idx, val<<2);
-               else
-               gctx->card->reg_write(idx, val);
-               break;
-       case ATOM_IO_PCI:
-               TRACE("%s: PCI registers are not implemented.\n", __func__);
-               return;
-       case ATOM_IO_SYSIO:
-               TRACE("%s: SYSIO registers are not implemented.\n", __func__);
-               return;
-       default:
-               if (!(gctx->io_mode&0x80)) {
-               TRACE("%s: Bad IO mode.\n", __func__);
-               return;
-               }
-               if (!gctx->iio[gctx->io_mode&0xFF]) {
+               case ATOM_ARG_REG:
+                       idx = U16(*ptr);
+                       (*ptr) += 2;
+                       idx += gctx->reg_block;
+                       switch(gctx->io_mode) {
+                               case ATOM_IO_MM:
+                                       if (idx == 0)
+                                               gctx->card->reg_write(idx, 
val<<2);
+                                       else
+                                               gctx->card->reg_write(idx, val);
+                                       break;
+                               case ATOM_IO_PCI:
+                                       TRACE("%s: PCI registers are not 
implemented.\n",
+                                               __func__);
+                                       return;
+                               case ATOM_IO_SYSIO:
+                                       TRACE("%s: SYSIO registers are not 
implemented.\n",
+                                               __func__);
+                                       return;
+                               default:
+                                       if (!(gctx->io_mode&0x80)) {
+                                               TRACE("%s: Bad IO mode.\n", 
__func__);
+                                               return;
+                                       }
+                                       if (!gctx->iio[gctx->io_mode&0xFF]) {
+                                               TRACE("%s: Undefined indirect 
IO write method %d\n",
+                                                       __func__, gctx->io_mode 
& 0x7F);
+                                               return;
+                                       }
+                                       atom_iio_execute(gctx, 
gctx->iio[gctx->io_mode&0xFF],
+                                               idx, val);
+                       }
+                       break;
+               case ATOM_ARG_PS:
+                       idx = U8(*ptr);
+                       (*ptr)++;
+                       ctx->ps[idx] = B_HOST_TO_LENDIAN_INT32(val);
+                       break;
+               case ATOM_ARG_WS:
+                       idx = U8(*ptr);
+                       (*ptr)++;
+                       switch(idx) {
+                               case ATOM_WS_QUOTIENT:
+                                       gctx->divmul[0] = val;
+                                       break;
+                               case ATOM_WS_REMAINDER:
+                                       gctx->divmul[1] = val;
+                                       break;
+                               case ATOM_WS_DATAPTR:
+                                       gctx->data_block = val;
+                                       break;
+                               case ATOM_WS_SHIFT:
+                                       gctx->shift = val;
+                                       break;
+                               case ATOM_WS_OR_MASK:
+                               case ATOM_WS_AND_MASK:
+                                       break;
+                               case ATOM_WS_FB_WINDOW:
+                                       gctx->fb_base = val;
+                                       break;
+                               case ATOM_WS_ATTRIBUTES:
+                                       gctx->io_attr = val;
+                                       break;
+                               case ATOM_WS_REGPTR:
+                                       gctx->reg_block = val;
+                                       break;
+                               default:
+                                       ctx->ws[idx] = val;
+                       }
+                       break;
+               case ATOM_ARG_FB:
+                       idx = U8(*ptr);
+                       (*ptr)++;
+                       gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
                        return;
-               }
-               atom_iio_execute(gctx, gctx->iio[gctx->io_mode&0xFF], idx, val);
+               case ATOM_ARG_PLL:
+                       idx = U8(*ptr);
+                       (*ptr)++;
+                       gctx->card->pll_write(idx, val);
+                       break;
+               case ATOM_ARG_MC:
+                       idx = U8(*ptr);
+                       (*ptr)++;
+                       gctx->card->mc_write(idx, val);
+                       return;
        }
-       break;
-       case ATOM_ARG_PS:
-       idx = U8(*ptr);
-       (*ptr)++;
-       ctx->ps[idx] = val;
-       break;
-       case ATOM_ARG_WS:
-       idx = U8(*ptr);
-       (*ptr)++;
-       switch(idx) {
-       case ATOM_WS_QUOTIENT:
-               gctx->divmul[0] = val;
-               break;
-       case ATOM_WS_REMAINDER:
-               gctx->divmul[1] = val;
-               break;
-       case ATOM_WS_DATAPTR:
-               gctx->data_block = val;
-               break;
-       case ATOM_WS_SHIFT:
-               gctx->shift = val;
-               break;
-       case ATOM_WS_OR_MASK:
-       case ATOM_WS_AND_MASK:
-               break;
-       case ATOM_WS_FB_WINDOW:
-               gctx->fb_base = val;
-               break;
-       case ATOM_WS_ATTRIBUTES:
-               gctx->io_attr = val;
-               break;
-       default:
-               ctx->ws[idx] = val;
-       }
-       break;
-       case ATOM_ARG_FB:
-       idx = U8(*ptr);
-       (*ptr)++;
-       TRACE("%s: FB access is not implemented.\n", __func__);
-       return;
-       case ATOM_ARG_PLL:
-       idx = U8(*ptr);
-       (*ptr)++;
-       gctx->card->reg_write(PLL_INDEX, idx);
-       gctx->card->reg_write(PLL_DATA, val);
-       break;
-       case ATOM_ARG_MC:
-       idx = U8(*ptr);
-       (*ptr)++;
-       TRACE("%s: MC registers are not implemented.\n", __func__);
-       return;
-       }
 }
 
 
@@ -475,9 +515,20 @@
 atom_op_calltable(atom_exec_context *ctx, int *ptr, int arg)
 {
        int idx = U8((*ptr)++);
-       TRACE("%s: table: %d\n", __func__, idx);
-       if (U16(ctx->ctx->cmd_table + 4 + 2 * idx))
-       atom_execute_table(ctx->ctx, idx, ctx->ps + ctx->ps_shift);
+       status_t result = B_OK;
+
+       if (idx < ATOM_TABLE_NAMES_CNT)
+               TRACE("%s: table: %s (%d)\n", __func__, atom_table_names[idx], 
idx);
+       else
+               TRACE("%s: table: unknown (%d)\n", __func__, idx);
+
+       if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) {
+               result = atom_execute_table_locked(ctx->ctx,
+                       idx, ctx->ps + ctx->ps_shift);
+       }
+
+       if (result != B_OK)
+               ctx->abort = true;
 }
 
 
@@ -558,34 +609,48 @@
 atom_op_jump(atom_exec_context *ctx, int *ptr, int arg)
 {
        int execute = 0, target = U16(*ptr);
-       (*ptr)+=2;
+       (*ptr) += 2;
        switch(arg) {
-       case ATOM_COND_ABOVE:
-       execute = ctx->ctx->cs_above;
-       break;
-       case ATOM_COND_ABOVEOREQUAL:
-       execute = ctx->ctx->cs_above || ctx->ctx->cs_equal;
-       break;
-       case ATOM_COND_ALWAYS:
-       execute = 1;
-       break;
-       case ATOM_COND_BELOW:
-       execute = !(ctx->ctx->cs_above || ctx->ctx->cs_equal);
-       break;
-       case ATOM_COND_BELOWOREQUAL:
-       execute = !ctx->ctx->cs_above;
-       break;
-       case ATOM_COND_EQUAL:
-       execute = ctx->ctx->cs_equal;
-       break;
-       case ATOM_COND_NOTEQUAL:
-       execute = !ctx->ctx->cs_equal;
-       break;
+               case ATOM_COND_ABOVE:
+                       execute = ctx->ctx->cs_above;
+                       break;
+               case ATOM_COND_ABOVEOREQUAL:
+                       execute = ctx->ctx->cs_above || ctx->ctx->cs_equal;
+                       break;
+               case ATOM_COND_ALWAYS:
+                       execute = 1;
+                       break;
+               case ATOM_COND_BELOW:
+                       execute = !(ctx->ctx->cs_above || ctx->ctx->cs_equal);
+                       break;
+               case ATOM_COND_BELOWOREQUAL:
+                       execute = !ctx->ctx->cs_above;
+                       break;
+               case ATOM_COND_EQUAL:
+                       execute = ctx->ctx->cs_equal;
+                       break;
+               case ATOM_COND_NOTEQUAL:
+                       execute = !ctx->ctx->cs_equal;
+                       break;
        }
        TRACE("%s: execute jump: %s; target: 0x%04X\n", __func__,
                execute? "yes" : "no", target);
-       if (execute)
+
+       if (execute) {
+               if (ctx->last_jump == (ctx->start + target)) {
+                       if (ctx->last_jump_count > 128) {
+                               TRACE("%s: DANGER! AtomBIOS stuck in infinite 
loop"
+                                       " for more then 128 jumps... abort!\n", 
__func__);
+                               ctx->abort = true;
+                       } else {
+                               ctx->last_jump_count++;
+                       }
+               } else {
+                       ctx->last_jump = ctx->start + target;
+                       ctx->last_jump_count = 1;
+               }
                *ptr = ctx->start + target;
+       }
 }
 
 
@@ -593,15 +658,15 @@
 atom_op_mask(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8 attr = U8((*ptr)++);
-       uint32 dst, src1, src2, saved;
+       uint32 dst, mask, src, saved;
        int dptr = *ptr;
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       src1 = atom_get_src(ctx, attr, ptr);
-       src2 = atom_get_src(ctx, attr, ptr);
-       dst &= src1;
-       dst |= src2;
+       mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr);
+       src = atom_get_src(ctx, attr, ptr);
+       dst &= mask;
+       dst |= src;
        TRACE("%s: src: 0x%" B_PRIX32 " mask 0x%" B_PRIX32 " is 0x%" B_PRIX32 
"\n",
-               __func__, src1, src2, dst);
+               __func__, src, mask, dst);
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
@@ -612,7 +677,7 @@
        uint8 attr = U8((*ptr)++);
        uint32 src, saved;
        int dptr = *ptr;
-       if (((attr>>3)&7) != ATOM_SRC_DWORD)
+       if (((attr >> 3) & 7) != ATOM_SRC_DWORD)
                atom_get_dst(ctx, arg, attr, ptr, &saved, 0);
        else {
                atom_skip_dst(ctx, arg, attr, ptr);
@@ -665,7 +730,8 @@
 static void
 atom_op_postcard(atom_exec_context *ctx, int *ptr, int arg)
 {
-       TRACE("%s: unimplemented!\n", __func__);
+       uint8 val = U8((*ptr)++);
+       TRACE("%s: POST card output: 0x%" B_PRIX8 "\n", __func__, val);
 }
 
 
@@ -696,11 +762,11 @@
        (*ptr)++;
        TRACE("%s: block: %d\n", __func__, idx);
        if (!idx)
-       ctx->ctx->data_block = 0;
-       else if (idx==255)
-       ctx->ctx->data_block = ctx->start;
+               ctx->ctx->data_block = 0;
+       else if (idx == 255)
+               ctx->ctx->data_block = ctx->start;
        else
-       ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2 * idx);
+               ctx->ctx->data_block = U16(ctx->ctx->data_table + 4 + 2 * idx);
 }
 
 
@@ -718,23 +784,27 @@
 {
        int port;
        switch(arg) {
-       case ATOM_PORT_ATI:
-       port = U16(*ptr);
-       TRACE("%s: port: %d\n", __func__, port);
-       if (!port)
-               ctx->ctx->io_mode = ATOM_IO_MM;
-       else
-               ctx->ctx->io_mode = ATOM_IO_IIO|port;
-       (*ptr)+=2;
-       break;
-       case ATOM_PORT_PCI:
-       ctx->ctx->io_mode = ATOM_IO_PCI;
-       (*ptr)++;
-       break;
-       case ATOM_PORT_SYSIO:
-       ctx->ctx->io_mode = ATOM_IO_SYSIO;
-       (*ptr)++;
-       break;
+               case ATOM_PORT_ATI:
+                       port = U16(*ptr);
+                       if (port < ATOM_IO_NAMES_CNT) {
+                               TRACE("%s: port: %d (%s)\n", __func__,
+                                       port, atom_io_names[port]);
+                       } else
+                               TRACE("%s: port: %d\n", __func__, port);
+                       if (!port)
+                               ctx->ctx->io_mode = ATOM_IO_MM;
+                       else
+                               ctx->ctx->io_mode = ATOM_IO_IIO | port;
+                       (*ptr) += 2;
+                       break;
+               case ATOM_PORT_PCI:
+                       ctx->ctx->io_mode = ATOM_IO_PCI;
+                       (*ptr)++;
+                       break;
+               case ATOM_PORT_SYSIO:
+                       ctx->ctx->io_mode = ATOM_IO_SYSIO;
+                       (*ptr)++;
+                       break;
        }
 }
 
@@ -747,16 +817,15 @@
 }
 
 
-static void
-atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
+static void atom_op_shift_left(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8 attr = U8((*ptr)++), shift;
        uint32 saved, dst;
        int dptr = *ptr;
        attr &= 0x38;
-       attr |= atom_def_dst[attr>>3]<<6;
+       attr |= atom_def_dst[attr >> 3] << 6;
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       shift = U8((*ptr)++);
+       shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
        #ifdef ATOM_TRACE
        TRACE("%s: 0x%" B_PRIX32 " << %" B_PRId8 " is 0X%" B_PRIX32 "\n",
                __func__, dst, shift, dst << shift);
@@ -766,25 +835,66 @@
 }
 
 
-static void
-atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
+static void atom_op_shift_right(atom_exec_context *ctx, int *ptr, int arg)
 {
        uint8 attr = U8((*ptr)++), shift;
        uint32 saved, dst;
        int dptr = *ptr;
        attr &= 0x38;
-       attr |= atom_def_dst[attr>>3]<<6;
+       attr |= atom_def_dst[attr >> 3] << 6;
        dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
-       shift = U8((*ptr)++);
+       shift = atom_get_src_direct(ctx, ATOM_SRC_BYTE0, ptr);
        #ifdef ATOM_TRACE
        TRACE("%s: 0x%" B_PRIX32 " >> %" B_PRId8 " is 0X%" B_PRIX32 "\n",
-               __func__, dst, shift, dst >> shift);
+               __func__, dst, shift, dst << shift);
        #endif
        dst >>= shift;
        atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
 }
 
 
+static void atom_op_shl(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++), shift;
+       uint32 saved, dst;
+       int dptr = *ptr;
+       uint32 dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
+       shift = atom_get_src(ctx, attr, ptr);
+       #ifdef ATOM_TRACE
+       TRACE("%s: 0x%" B_PRIX32 " << %" B_PRId8 " is 0X%" B_PRIX32 "\n",
+               __func__, dst, shift, dst << shift);
+       #endif
+       dst <<= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
+static void atom_op_shr(atom_exec_context *ctx, int *ptr, int arg)
+{
+       uint8 attr = U8((*ptr)++), shift;
+       uint32 saved, dst;
+       int dptr = *ptr;
+       uint32 dst_align = atom_dst_to_src[(attr >> 3) & 7][(attr >> 6) & 3];
+       dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1);
+       /* op needs to full dst value */
+       dst = saved;
+       shift = atom_get_src(ctx, attr, ptr);
+       #ifdef ATOM_TRACE
+       TRACE("%s: 0x%" B_PRIX32 " >> %" B_PRId8 " is 0X%" B_PRIX32 "\n",
+               __func__, dst, shift, dst << shift);
+       #endif
+       dst >>= shift;
+       dst &= atom_arg_mask[dst_align];
+       dst >>= atom_arg_shift[dst_align];
+       atom_put_dst(ctx, arg, attr, &dptr, dst, saved);
+}
+
+
 static void
 atom_op_sub(atom_exec_context *ctx, int *ptr, int arg)
 {
@@ -813,7 +923,7 @@
        if (U8(*ptr) == ATOM_CASE_MAGIC) {
                (*ptr)++;
                TRACE("%s: switch case\n", __func__);
-               val = atom_get_src(ctx, (attr&0x38)|ATOM_ARG_IMM, ptr);
+               val = atom_get_src(ctx, (attr & 0x38) | ATOM_ARG_IMM, ptr);
                target = U16(*ptr);
                if (val == src) {
                        *ptr = ctx->start + target;
@@ -888,18 +998,18 @@
        { atom_op_or, ATOM_ARG_FB },
        { atom_op_or, ATOM_ARG_PLL },
        { atom_op_or, ATOM_ARG_MC },
-       { atom_op_shl, ATOM_ARG_REG },
-       { atom_op_shl, ATOM_ARG_PS },
-       { atom_op_shl, ATOM_ARG_WS },
-       { atom_op_shl, ATOM_ARG_FB },
-       { atom_op_shl, ATOM_ARG_PLL },
-       { atom_op_shl, ATOM_ARG_MC },
-       { atom_op_shr, ATOM_ARG_REG },
-       { atom_op_shr, ATOM_ARG_PS },
-       { atom_op_shr, ATOM_ARG_WS },
-       { atom_op_shr, ATOM_ARG_FB },
-       { atom_op_shr, ATOM_ARG_PLL },
-       { atom_op_shr, ATOM_ARG_MC },
+       { atom_op_shift_left, ATOM_ARG_REG },
+       { atom_op_shift_left, ATOM_ARG_PS },
+       { atom_op_shift_left, ATOM_ARG_WS },
+       { atom_op_shift_left, ATOM_ARG_FB },
+       { atom_op_shift_left, ATOM_ARG_PLL },
+       { atom_op_shift_left, ATOM_ARG_MC },
+       { atom_op_shift_right, ATOM_ARG_REG },
+       { atom_op_shift_right, ATOM_ARG_PS },
+       { atom_op_shift_right, ATOM_ARG_WS },
+       { atom_op_shift_right, ATOM_ARG_FB },
+       { atom_op_shift_right, ATOM_ARG_PLL },
+       { atom_op_shift_right, ATOM_ARG_MC },
        { atom_op_mul, ATOM_ARG_REG },
        { atom_op_mul, ATOM_ARG_PS },
        { atom_op_mul, ATOM_ARG_WS },
@@ -994,8 +1104,8 @@
 };
 
 
-void
-atom_execute_table(atom_context *ctx, int index, uint32 *params)
+status_t
+atom_execute_table_locked(atom_context *ctx, int index, uint32 * params)
 {
        int base = CU16(ctx->cmd_table + 4 + 2 * index);
        int len, ws, ps, ptr;
@@ -1003,44 +1113,77 @@
        atom_exec_context ectx;
 
        if (!base)
-               return;
+               return B_ERROR;
 
        len = CU16(base + ATOM_CT_SIZE_PTR);
        ws = CU8(base + ATOM_CT_WS_PTR);
        ps = CU8(base + ATOM_CT_PS_PTR) & ATOM_CT_PS_MASK;
        ptr = base + ATOM_CT_CODE_PTR;
 
-       /* reset reg block */
-       ctx->reg_block = 0;
        ectx.ctx = ctx;
        ectx.ps_shift = ps / 4;
        ectx.start = base;
        ectx.ps = params;
+       ectx.abort = false;
+       ectx.last_jump = 0;
+       ectx.last_jump_count = 0;
        if (ws)
                ectx.ws = (uint32*)malloc(4 * ws);
        else
-       ectx.ws = NULL;
+               ectx.ws = NULL;
 
        debug_depth++;
        while (1) {
-       op = CU8(ptr++);
+               op = CU8(ptr++);
+               if (op < ATOM_OP_NAMES_CNT) {
+                       TRACE("%s: %s (0x%" B_PRIX16 ")\n", __func__,
+                               atom_op_names[op], ptr - 1);
+               } else
+                       TRACE("%s: unknown (0x%" B_PRIX16 ")\n", __func__, ptr 
- 1);
 
-       if (op<ATOM_OP_CNT && op > 0)
-               opcode_table[op].func(&ectx, &ptr, opcode_table[op].arg);
-       else
-               break;
+               if (ectx.abort == true) {
+                       TRACE("AtomBios parser was aborted executing (0x%" 
B_PRIX16 ")\n",
+                               ptr - 1);
+                       free(ectx.ws);
+                       return B_ERROR;
+               }
 
-       if (op == ATOM_OP_EOT)
-               break;
+               if (op < ATOM_OP_CNT && op > 0)
+                       opcode_table[op].func(&ectx, &ptr, 
opcode_table[op].arg);
+               else
+                       break;
+
+               if (op == ATOM_OP_EOT)
+                       break;
        }
        debug_depth--;
-       TRACE("<<\n");
 
-       if (ws)
        free(ectx.ws);
+       return B_OK;
 }
 
 
+status_t
+atom_execute_table(atom_context *ctx, int index, uint32 *params)
+{
+       if (acquire_sem_etc(ctx->exec_sem, 1, B_RELATIVE_TIMEOUT, 5000000)
+               != B_NO_ERROR) {
+               TRACE("%s: Timeout to obtain semaphore!\n", __func__);
+               return B_ERROR;
+       }
+       /* reset reg block */
+       ctx->reg_block = 0;
+       /* reset fb window */
+       ctx->fb_base = 0;
+       /* reset io mode */
+       ctx->io_mode = ATOM_IO_MM;
+       status_t result = atom_execute_table_locked(ctx, index, params);
+
+       release_sem(ctx->exec_sem);
+       return result;
+}
+
+
 static int atom_iio_len[] = { 1, 2, 3, 3, 3, 3, 4, 4, 4, 3 };
 
 
@@ -1049,11 +1192,11 @@
 {
        ctx->iio = (uint16*)malloc(2 * 256);
        while (CU8(base) == ATOM_IIO_START) {
-       ctx->iio[CU8(base + 1)] = base + 2;
-       base += 2;
-       while (CU8(base) != ATOM_IIO_END)
-               base += atom_iio_len[CU8(base)];
-       base += 3;
+               ctx->iio[CU8(base + 1)] = base + 2;
+               base += 2;
+               while (CU8(base) != ATOM_IIO_END)
+                       base += atom_iio_len[CU8(base)];
+               base += 3;
        }
 }
 

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.h
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.h       
2011-08-06 05:51:37 UTC (rev 42584)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/atombios/atom.h       
2011-08-06 07:00:49 UTC (rev 42585)
@@ -29,6 +29,7 @@
 
 #include <String.h>
 #include <SupportDefs.h>
+#include <ByteOrder.h>
 
 
 struct card_info {
@@ -131,6 +132,7 @@
        uint32 cmd_table, data_table;
        uint16 *iio;
 
+       sem_id exec_sem;
        uint16 data_block;
        uint32 fb_base;
        uint32 divmul[2];
@@ -145,7 +147,7 @@
 extern int atom_debug;
 
 atom_context *atom_parse(card_info *, void *);
-void atom_execute_table(atom_context *, int, uint32 *);
+status_t atom_execute_table(atom_context *, int, uint32 *);
 int atom_asic_init(atom_context *);
 void atom_destroy(atom_context *);
 

Modified: haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp
===================================================================
--- haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp      2011-08-06 
05:51:37 UTC (rev 42584)
+++ haiku/trunk/src/add-ons/accelerants/radeon_hd/bios.cpp      2011-08-06 
07:00:49 UTC (rev 42585)
@@ -103,7 +103,13 @@
        atom_asic_init(gAtomContext);
                // Post card
 
-       // mutex_init(&rdev->mode_info.atom_context->mutex);
+       if ((gAtomContext->exec_sem = create_sem(1, "AtomBIOS_exec"))
+               < B_NO_ERROR) {
+               TRACE("%s: couldn't create semaphore for AtomBIOS exec 
thread!\n",
+                       __func__);
+               return B_ERROR;
+       }
+
        radeon_bios_init_scratch();
 
        return B_OK;


Other related posts:

  • » [haiku-commits] r42585 - in haiku/trunk/src/add-ons/accelerants/radeon_hd: . atombios - kallisti5