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