|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.9 root 7: //
1.1.1.13 root 8: // MPU (共通部分)
1.1.1.9 root 9: //
1.1.1.2 root 10:
1.1.1.11 root 11: // Device
12: // | +-----------+
1.1.1.13 root 13: // +--| MPUDevice | (全 MPU の共通部)
14: // +-----------+
15: // |
16: // | +---------------+
17: // +--| MainMPUDevice | (680x0/88xx0 の共通部)
18: // | +---------------+
19: // | |
20: // | +-- MPU680x0Device
21: // | +-- MPU88xx0Device
22: // |
23: // +-- MPU64180Device
1.1.1.11 root 24:
1.1 root 25: #include "mpu.h"
1.1.1.5 root 26: #include "config.h"
1.1.1.11 root 27: #include "debugger.h"
1.1.1.17 root 28: #include "event.h"
1.1.1.11 root 29: #include "mainbus.h"
1.1.1.9 root 30: #include "scheduler.h"
1.1.1.11 root 31: #include "syncer.h"
1.1 root 32:
1.1.1.13 root 33: //
34: // 全 MPU 共通
35: //
36:
1.1 root 37: // コンストラクタ
1.1.1.13 root 38: MPUDevice::MPUDevice(uint objid_)
39: : inherited(objid_)
1.1 root 40: {
41: }
42:
43: // デストラクタ
44: MPUDevice::~MPUDevice()
45: {
46: }
1.1.1.4 root 47:
1.1.1.11 root 48: // 初期化
1.1.1.5 root 49: bool
50: MPUDevice::Init()
51: {
1.1.1.11 root 52: debugger = GetDebugger();
1.1.1.13 root 53:
1.1.1.17 root 54: auto evman = GetEventManager();
55: exec_event = evman->Regist(this, NULL, "MPU Execute");
1.1.1.13 root 56:
57: return true;
58: }
59:
60: void
61: MPUDevice::PowerOff()
62: {
63: scheduler->StopEvent(exec_event);
64: }
65:
66:
67: //
68: // メイン MPU (680x0/88xx0) 共通部
69: //
70:
71: // コンストラクタ
72: MainMPUDevice::MainMPUDevice()
73: : inherited(OBJ_MPU)
74: {
75: }
76:
77: // デストラクタ
78: MainMPUDevice::~MainMPUDevice()
79: {
80: }
81:
82: // 初期化
83: bool
84: MainMPUDevice::Init()
85: {
86: if (inherited::Init() == false) {
87: return false;
88: }
89:
1.1.1.11 root 90: mainbus = GetMainbusDevice();
91: syncer = GetSyncer();
92:
1.1.1.14 root 93: // MPU クロック。
94: // 設定の "mpu-clock" は MHz 単位だが、変数 clock_khz は kHz 単位。
1.1.1.13 root 95: int val;
1.1.1.14 root 96: const ConfigItem& item = gConfig->Find("mpu-clock");
1.1.1.13 root 97: if (item.TryFixedDecimal(&val, 3) == false) {
98: item.Err();
99: return false;
100: }
101: clock_khz = (uint)val;
1.1.1.7 root 102: // 1MHz 未満はエラー。実際 10MHz 未満でもいい気がするけど
1.1.1.5 root 103: if (clock_khz < 1000) {
104: item.Err();
105: return false;
106: }
1.1.1.9 root 107: clock_nsec = 1000 * 1000 / clock_khz;
1.1.1.14 root 108: if (clock_nsec < 1) {
109: item.Err("Clock speed too high");
110: return false;
111: }
1.1.1.5 root 112:
1.1.1.13 root 113: scheduler->ConnectMessage(MessageID::MPU_TRACE_MAIN, this,
114: ToMessageCallback(&MainMPUDevice::TraceMessage));
1.1.1.8 root 115:
1.1.1.13 root 116: return true;
1.1.1.9 root 117: }
118:
119: // MPU トレース状態設定要求メッセージ
120: void
1.1.1.13 root 121: MainMPUDevice::TraceMessage(MessageID msgid, uint32 arg)
1.1.1.9 root 122: {
1.1.1.10 root 123: // リセット中は SetTrace しない
124: if (resetting) {
125: return;
126: }
127:
1.1.1.9 root 128: // デバッガから MPU のトレース状態を設定してくれと言われた
129: SetTrace((bool)arg);
130: }
131:
1.1.1.16 root 132: void
133: MainMPUDevice::ChangeState(uint32 new_state)
134: {
135: // new_mode (CPU_STATE_*) と
1.1.1.18! root 136: // NotifyCPUMode() の引数 Syncer::SYNCMODE_CPU_* は
1.1.1.16 root 137: // 実は同じ値なのでそのまま渡してよいことにする。
138: static_assert(CPU_STATE_NORMAL == Syncer::SYNCMODE_CPU_NORMAL, "");
139: static_assert(CPU_STATE_STOP == Syncer::SYNCMODE_CPU_STOP, "");
140: static_assert(CPU_STATE_HALT == Syncer::SYNCMODE_CPU_HALT, "");
141:
142: if (cpu_state != new_state) {
143: cpu_state = new_state;
144: // スケジューラに通知
1.1.1.18! root 145: syncer->NotifyCPUMode(cpu_state);
1.1.1.16 root 146: }
147: }
148:
1.1.1.8 root 149: // Round Mode (モニタ表示用)
150: /*static*/ const char * const
1.1.1.13 root 151: MainMPUDevice::rmstr[4] = {
1.1.1.8 root 152: "Near",
153: "Zero",
154: "Minus",
155: "Plus",
156: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.