|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.