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

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

unix.superglobalmegacorp.com

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