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