FPGA開発日記

FPGAというより、コンピュータアーキテクチャかもね! カテゴリ別記事インデックス https://sites.google.com/site/fpgadevelopindex/

GDBリモートデバッグサーバを自作ISSに実装する(continueの実装とトレース)

msyksphinz.hatenablog.com

いよいよプログラムの実行に移る。GDB側からプログラムの実行として、stepかcontinueを実装していく。まずは、continueからだ。 その前に、continueで正確に停止できるように、breakpointの設定を行っていこう。

breakpointの実装

breakpointの実装には、以下のようなパケットが利用される。

Z0,addr,kind

メモリアドレスaddrに対してブレークポイントが設定されることになる。 このパケットを受け取ったら、該当アドレスでPCを停止するようにISSを設定すれば良いのだが、幸いなことにISSブレークポイントの機能は既に実装してある。

    case 'Z' : {
        // Set BreakPoint
        Addr_t break_addr = 0x00;

        if (IsEqualHead (packet_str, "Z0")) {
            int idx;
            for (idx = 3; packet_str[idx] != ',' && idx < packet_str.length(); idx++) {
                break_addr = (break_addr << 4) | Hex (packet_str[idx]);
            }
            if (idx >= packet_str.length()) {
                PutPacket ("E00");
            } else {
                m_env->AddPCBreak (break_addr);
                PutPacket ("OK");
            }
        }
        break;
    }

AddPCBreakでブレークポイントを設定した。

実際にbreakpointを設定すると、きちんとパケットが流れることが確認できた。

(gdb) b main
+Packet : Z0,ffffffff80002810,4                                                                                                        │
<set_pc_break : 80002810>                                                                                                              │

continueの実装

continueは、そのままで以下のようなパケットが送信される。

c

ブレークポイントまで到達すればISS側からトラップ信号を発生させるのだが、その後現在のPCの確認が行われるようだ。 これによりソースコードとのアノテーション処理が行われている。

f:id:msyksphinz:20160123023242p:plain

実際にやってみると、ちゃんとmainの先頭で停止していることが分かる。

   +--core_main.c--------------------------------------------------------------------------------------------------------
   |64      #define get_seed(x) (ee_s16)get_seed_32(x)
   |65      #endif
   |66
   |67      #if (MEM_METHOD==MEM_STATIC)
   |68      ee_u8 static_memblk[TOTAL_DATA_SIZE];
   |69      #endif
   |70      char *mem_name[3] = {"Static","Heap","Stack"};
   |71      /* Function: main
   |72              Main entry routine for the benchmark.
   |73              This function is responsible for the following steps:
   |74
   |75              1 - Initialize input seeds from a source that cannot be determined at compile time.
   |76              2 - Initialize memory block for use.
   |77              3 - Run and time the benchmark.
   |78              4 - Report results, testing the validity of the output if the seeds are known.
   |79
   |80              Arguments:
   |81              1 - first seed  : Any value
   |82              2 - second seed : Must be identical to first for iterations to be identical
   |83              3 - third seed  : Any value, should be at least an order of magnitude less then the input size, but b
   |84              4 - Iterations  : Special, if set to 0, iterations will be automatically determined such that the ben
   |85
   |86      */
   |87
   |88      #if MAIN_HAS_NOARGC
B+>|89      MAIN_RETURN_TYPE main(void) {
   |90              int argc=0;
   |91              char *argv[1];
   |92      #else
   |93      MAIN_RETURN_TYPE main(int argc, char *argv[]) {
   |94      #endif
   |95              ee_u16 i,j=0,num_algorithms=0;
   |96              ee_s16 known_id=-1,total_errors=0;
   |97              ee_u16 seedcrc=0;
   |98              CORE_TICKS total_time;
   |99              core_results results[MULTITHREAD];
   |100     #if (MEM_METHOD==MEM_STACK)
   |101             ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
   |102     #endif
   |103             /* first call any initializations needed */
   |104             portable_init(&(results[0].port), &argc, argv);
   |105             /* First some checks to make sure benchmark will run ok */
   |106             if (sizeof(struct list_head_s)>128) {
   |107                     ee_printf("list_head structure too big for comparable data!\n");
   |108                     return MAIN_RETURN_VAL;
   |109             }
   |110             results[0].seed1=get_seed(1);
   |111             results[0].seed2=get_seed(2);
   |112             results[0].seed3=get_seed(3);
   |113             results[0].iterations=get_seed_32(4);
   |114     #if CORE_DEBUG
   |115             results[0].iterations=1;
   |116     #endif
   +---------------------------------------------------------------------------------------------------------------------
remote Thread <main> In: main

Breakpoint 1, main () at core_main.c:89
(gdb)

次は、step操作を実装していこう。だんだんサマになってきた。