|
|
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.