Annotation of nono/debugger/debugger_memory.cpp, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.3 ! root        7: //
        !             8: // デバッガのメモリアクセスヘルパー(?)
        !             9: //
1.1       root       10: 
                     11: #include "debugger_private.h"
                     12: 
                     13: // コンストラクタ
                     14: DebuggerMemoryStream::DebuggerMemoryStream(const DebuggerMD *md_,
                     15:        const saddr_t& laddr_, MemoryMode access_mode, MMULookupMode lookup_mode)
                     16: {
                     17:        md = md_;
                     18:        laddr = laddr_;
                     19:        // lookup はここで enum から bool にしておく
                     20:        lookup = static_cast<bool>(lookup_mode);
                     21:        // 物理アドレスの時はこれだけでいいので最初に代入しておく
                     22:        paddr = (uint32)laddr;
                     23: 
                     24:        if (access_mode == MemoryMode::Logical && md->MMUEnabled()) {
                     25:                translate = true;
                     26:                // FormatAddr() なしで Fetch/Peek を実行した場合でも、初回に
                     27:                // アドレス変換を起こさせるため。SetNBreakpoint() で使う。
                     28:                pageover = true;
                     29:        }
                     30: }
                     31: 
                     32: // 現在のアドレスを表示用に整形して str に代入する。
                     33: // アドレス変換でバスエラーが起きたら false を返す。
                     34: bool
                     35: DebuggerMemoryStream::FormatAddr(std::string& str)
                     36: {
                     37:        // ここは pageover に関係なく必ずアドレス変換を行う。
                     38:        // (その結果必ず pageover = false になる)
                     39: 
                     40:        if (translate) {
                     41:                // laddr は論理アドレスなのでアドレス変換する
                     42:                uint64 tmp = md->TranslateAddr(laddr, lookup);
                     43:                pageover = false;
                     44: 
                     45:                // laddr は常に表示
                     46:                str = string_format("%08x", (uint32)laddr);
                     47: 
                     48:                if ((int64)tmp < 0) {
                     49:                        // アドレス変換の結果バスエラーなら false で帰る
                     50:                        str += ":BusErr";
                     51:                        return false;
                     52:                }
                     53: 
                     54:                paddr = (uint32)tmp;
                     55:                if (paddr == (uint32)laddr) {
                     56:                        // PA==VA
                     57:                        str += "=PA";
                     58:                } else {
                     59:                        // PA!=VA
                     60:                        str += string_format(":%08x:", paddr);
                     61:                }
                     62:        } else {
                     63:                // laddr は物理アドレスなのでそのまま
                     64:                paddr = (uint32)laddr;
                     65: 
                     66:                str = string_format("%08x:", paddr);
                     67:        }
                     68: 
                     69:        return true;
                     70: }
                     71: 
                     72: // アドレスをリセットする。
                     73: // (他のパラメータは維持するので、1ワード戻るとかそういう時用)
                     74: void
                     75: DebuggerMemoryStream::ResetAddr(uint32 newaddr)
                     76: {
                     77:        if (((newaddr ^ (uint32)laddr) & 0xffffff00) != 0) {
                     78:                pageover = true;
                     79:        }
                     80:        laddr = newaddr;
                     81:        paddr = newaddr;
                     82: }
                     83: 
                     84: // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。
                     85: #define PRECHECK() do {        \
                     86:        if (__predict_false(pageover)) {        \
                     87:                uint64 tmp = md->TranslateAddr(laddr, lookup);  \
                     88:                if ((int64)tmp < 0) {   \
                     89:                        return (uint64)-2;      \
                     90:                }       \
                     91:                paddr = (uint32)tmp;    \
                     92:                pageover = false;       \
                     93:        }       \
                     94: } while (0)
                     95: 
                     96: // 論理アドレスがページ境界をまたいだかどうか。
                     97: // m68k はページサイズが 256バイト..32KB まで可変だが、いつ変わるか
                     98: // 分からないページサイズマスクを取得することを考えたら、多少の無駄
                     99: // を承知で常に 256 バイトおきにチェックするほうがマシかもしれない。
                    100: #define POSTCHECK() do {       \
                    101:        if (__predict_false(translate && (paddr & 0xff) == 0)) {        \
                    102:                pageover = true;        \
                    103:        }       \
                    104: } while (0)
                    105: 
                    106: 
                    107: // laddr から単位命令語を読み込むが、アドレスは進めない。
                    108: uint64
                    109: DebuggerMemoryStream::PeekInst()
                    110: {
                    111:        uint64 data;
                    112: 
                    113:        assert(((uint32)laddr & (md->inst_bytes - 1)) == 0);
                    114: 
                    115:        PRECHECK();
                    116: 
                    117:        data = 0;
                    118:        for (int i = 0; i < md->inst_bytes; i++) {
                    119:                data <<= 8;
                    120:                data |= vm_phys_peek_8(paddr + i);
                    121:        }
                    122: 
                    123:        return data;
                    124: }
                    125: 
                    126: // laddr から単位命令語を読み込んで、アドレスを進める。
                    127: uint64
                    128: DebuggerMemoryStream::FetchInst()
                    129: {
                    130:        uint64 data;
                    131: 
                    132:        data = PeekInst();
                    133:        laddr += md->inst_bytes;
                    134:        paddr += md->inst_bytes;
                    135: 
                    136:        POSTCHECK();
                    137: 
                    138:        return data;
                    139: }
                    140: 
                    141: // laddr から1バイト読み込んで、アドレスを進める。
                    142: uint64
                    143: DebuggerMemoryStream::Fetch8()
                    144: {
                    145:        uint64 data;
                    146: 
                    147:        PRECHECK();
                    148: 
                    149:        data = vm_phys_peek_8(paddr);
                    150:        laddr++;
                    151:        paddr++;
                    152: 
                    153:        POSTCHECK();
                    154: 
                    155:        return data;
                    156: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.