|
|
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
1.1.1.19! root 61: MPUDevice::ResetHard(bool poweron)
! 62: {
! 63: inherited::ResetHard(poweron);
! 64: last_vector = -1;
! 65: }
! 66:
! 67: void
1.1.1.13 root 68: MPUDevice::PowerOff()
69: {
70: scheduler->StopEvent(exec_event);
71: }
72:
1.1.1.19! root 73: int32
! 74: MPUDevice::GetAndResetLastVector()
! 75: {
! 76: auto vector = last_vector;
! 77: last_vector = -1;
! 78: return vector;
! 79: }
! 80:
1.1.1.13 root 81:
82: //
83: // メイン MPU (680x0/88xx0) 共通部
84: //
85:
86: // コンストラクタ
87: MainMPUDevice::MainMPUDevice()
88: : inherited(OBJ_MPU)
89: {
90: }
91:
92: // デストラクタ
93: MainMPUDevice::~MainMPUDevice()
94: {
95: }
96:
97: // 初期化
98: bool
99: MainMPUDevice::Init()
100: {
101: if (inherited::Init() == false) {
102: return false;
103: }
104:
1.1.1.11 root 105: mainbus = GetMainbusDevice();
106: syncer = GetSyncer();
107:
1.1.1.14 root 108: // MPU クロック。
109: // 設定の "mpu-clock" は MHz 単位だが、変数 clock_khz は kHz 単位。
1.1.1.13 root 110: int val;
1.1.1.14 root 111: const ConfigItem& item = gConfig->Find("mpu-clock");
1.1.1.13 root 112: if (item.TryFixedDecimal(&val, 3) == false) {
113: item.Err();
114: return false;
115: }
116: clock_khz = (uint)val;
1.1.1.7 root 117: // 1MHz 未満はエラー。実際 10MHz 未満でもいい気がするけど
1.1.1.5 root 118: if (clock_khz < 1000) {
119: item.Err();
120: return false;
121: }
1.1.1.19! root 122: clock_tsec = 1_msec / clock_khz;
! 123: if (clock_tsec < 1) {
1.1.1.14 root 124: item.Err("Clock speed too high");
125: return false;
126: }
1.1.1.5 root 127:
1.1.1.19! root 128: // キャッシュを無効にするテスト用。
! 129: force_disable_dcache = gConfig->Find("mpu-force-disable-dcache").AsBool();
! 130: force_disable_icache = gConfig->Find("mpu-force-disable-icache").AsBool();
! 131:
1.1.1.13 root 132: scheduler->ConnectMessage(MessageID::MPU_TRACE_MAIN, this,
133: ToMessageCallback(&MainMPUDevice::TraceMessage));
1.1.1.8 root 134:
1.1.1.13 root 135: return true;
1.1.1.9 root 136: }
137:
138: // MPU トレース状態設定要求メッセージ
139: void
1.1.1.13 root 140: MainMPUDevice::TraceMessage(MessageID msgid, uint32 arg)
1.1.1.9 root 141: {
1.1.1.10 root 142: // リセット中は SetTrace しない
143: if (resetting) {
144: return;
145: }
146:
1.1.1.9 root 147: // デバッガから MPU のトレース状態を設定してくれと言われた
148: SetTrace((bool)arg);
149: }
150:
1.1.1.16 root 151: void
152: MainMPUDevice::ChangeState(uint32 new_state)
153: {
154: // new_mode (CPU_STATE_*) と
1.1.1.18 root 155: // NotifyCPUMode() の引数 Syncer::SYNCMODE_CPU_* は
1.1.1.16 root 156: // 実は同じ値なのでそのまま渡してよいことにする。
157: static_assert(CPU_STATE_NORMAL == Syncer::SYNCMODE_CPU_NORMAL, "");
158: static_assert(CPU_STATE_STOP == Syncer::SYNCMODE_CPU_STOP, "");
159: static_assert(CPU_STATE_HALT == Syncer::SYNCMODE_CPU_HALT, "");
160:
161: if (cpu_state != new_state) {
162: cpu_state = new_state;
163: // スケジューラに通知
1.1.1.18 root 164: syncer->NotifyCPUMode(cpu_state);
1.1.1.16 root 165: }
166: }
167:
1.1.1.8 root 168: // Round Mode (モニタ表示用)
169: /*static*/ const char * const
1.1.1.13 root 170: MainMPUDevice::rmstr[4] = {
1.1.1.8 root 171: "Near",
172: "Zero",
173: "Minus",
174: "Plus",
175: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.