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

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

unix.superglobalmegacorp.com

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