Annotation of nono/vm/mpu88xx0.cpp, revision 1.1.1.6

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: // MPU (m88xx0)
                      8: 
                      9: #include "mpu88xx0.h"
                     10: #include "config.h"
1.1.1.2   root       11: #include "sysctlr.h"
                     12: 
                     13: std::unique_ptr<MPU88200ATC> gMPU88200ATC[2];
1.1       root       14: 
                     15: // コンストラクタ
1.1.1.5   root       16: MPU88xx0Device::MPU88xx0Device(uint32 reset_vector)
1.1       root       17: {
1.1.1.3   root       18:        monitor_size = nnSize(79, 18);
1.1       root       19: 
1.1.1.5   root       20:        cpu.reset(new m88kcpu(reset_vector));
1.1.1.2   root       21: 
1.1.1.4   root       22:        // リセット例外イベントコールバック設定
1.1.1.5   root       23:        event.func = (DeviceCallback_t)&MPU88xx0Device::Callback;
1.1.1.4   root       24: 
1.1.1.2   root       25:        // LUNA88K では CMMU の ID は次のように割り振ってあるようだ。
                     26:        // OpenBSD の sys/arch/luna68k/include/board.h より。
                     27:        //
                     28:        //       Inst Data
                     29:        // CPU#0 ID=7 ID=6
                     30:        // CPU#1 ID=5 ID=4
                     31:        // CPU#2 ID=3 ID=2
                     32:        // CPU#3 ID=1 ID=0
                     33:        //
                     34:        // 厳密にはこれは LUNA88K のハードウェアがどういうコンフィグレーションで
                     35:        // m88200 を使うかなので、ここではなくて vm_luna あたりのほうがいいかも
                     36:        // しれんけど、あまり遠いのも面倒なので、とりあえずこの辺に。
                     37:        // あとマルチプロセッサになったらまたその時考える。
                     38:        cpu->cmmu[0].SetID(7);
                     39:        cpu->cmmu[1].SetID(6);
                     40: 
                     41:        // モニタ用の別オブジェクト
                     42:        gMPU88200ATC[0].reset(new MPU88200ATC(&cpu->cmmu[0]));
                     43:        gMPU88200ATC[1].reset(new MPU88200ATC(&cpu->cmmu[1]));
1.1       root       44: }
                     45: 
                     46: // デストラクタ
                     47: MPU88xx0Device::~MPU88xx0Device()
                     48: {
                     49: }
                     50: 
1.1.1.5   root       51: bool
                     52: MPU88xx0Device::Init()
                     53: {
                     54:        // 親クラス
                     55:        if (inherited::Init() == false) {
                     56:                return false;
                     57:        }
                     58:        // MPU クロックは親 Init() で読み込んで、ここで cpu にセットする
                     59:        cpu->SetClockSpeed(clock_khz);
                     60: 
                     61:        return true;
                     62: }
                     63: 
1.1.1.4   root       64: // リセット例外イベントコールバック
1.1       root       65: void
1.1.1.5   root       66: MPU88xx0Device::Callback(Event& ev)
1.1       root       67: {
1.1.1.5   root       68:        cpu->RequestReset();
1.1       root       69: }
                     70: 
1.1.1.6 ! root       71: // アクセス中の論理アドレスを取得
        !            72: uint32
        !            73: MPU88xx0Device::GetLaddr() const
        !            74: {
        !            75:        m88200 *cmmu = m88200::GetBusMaster();
        !            76:        assert(cmmu);
        !            77:        return cmmu->GetLaddr();
        !            78: }
        !            79: 
        !            80: // アクセス中の物理アドレスを取得
        !            81: uint32
        !            82: MPU88xx0Device::GetPaddr() const
        !            83: {
        !            84:        m88200 *cmmu = m88200::GetBusMaster();
        !            85:        assert(cmmu);
        !            86:        return cmmu->GetPaddr();
        !            87: }
        !            88: 
1.1.1.4   root       89: // アクセスウェイトを加算
                     90: void
1.1.1.5   root       91: MPU88xx0Device::AddCycle(int32 cycle)
1.1.1.4   root       92: {
                     93:        // 今アクセスしてきている(= バスマスターの) CMMU に対して加算する
                     94:        m88200 *cmmu = m88200::GetBusMaster();
                     95:        assert(cmmu);
                     96:        cmmu->AddCycle(cycle);
                     97: }
                     98: 
1.1.1.2   root       99: // Interrupt
                    100: void
1.1.1.5   root      101: MPU88xx0Device::Interrupt(int level)
1.1.1.2   root      102: {
1.1.1.5   root      103:        cpu->Interrupt(level);
1.1.1.2   root      104: }
                    105: 
1.1       root      106: // モニター更新
1.1.1.3   root      107: void
                    108: MPU88xx0Device::MonitorUpdate(TextScreen& monitor)
1.1       root      109: {
                    110:        m88100reg reg;
                    111:        int x;
                    112:        int y;
                    113: 
                    114:        monitor.Clear();
                    115: 
                    116:        // ローカルにコピー
                    117:        reg = *cpu;
                    118: 
                    119:        //
                    120:        for (int i = 0; i < countof(reg.r); i++) {
                    121:                monitor.Print((i / 8) * 14, i % 8, "r%-2d:%08x", i, reg.r[i]);
                    122:        }
                    123: 
                    124:        // 制御レジスタ
                    125:        x = 0;
                    126:        y = 9;
1.1.1.2   root      127:        monitor.Print(x, y++,  "pid (cr0):%08x(Arch=$%02x Ver=$%02x MC=%s)",
1.1       root      128:                reg.pid,
                    129:                (reg.pid >> 8) & 0xff,
1.1.1.2   root      130:                (reg.pid >> 1) & 0x7f,
                    131:                (reg.pid & 1) ? "Master" : "Checker");
                    132:        monitor.Print(x, y, "psr (cr1):%08x(", reg.psr);
                    133:        monitor.Puts(x + 19, y, TA::OnOff(reg.psr  & m88100reg::PSR_SUPER), "S");
                    134:        monitor.Puts(x + 21, y,
                    135:                ((reg.psr & m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE"));
                    136:        monitor.Puts(x + 27, y, TA::OnOff(reg.psr  & m88100reg::PSR_SER),  "SER");
                    137:        monitor.Puts(x + 31, y, TA::OnOff(reg.psr  & m88100reg::PSR_C),    "Cy");
                    138:        monitor.Puts(x + 34, y, TA::OnOff(reg.psr  & m88100reg::PSR_SFD1), "SFD1");
                    139:        monitor.Puts(x + 39, y, TA::OnOff(reg.psr  & m88100reg::PSR_MXM),  "MXM");
                    140:        monitor.Puts(x + 43, y, TA::OnOff(reg.psr  & m88100reg::PSR_IND),  "IND");
                    141:        monitor.Puts(x + 47, y, TA::OnOff(reg.psr  & m88100reg::PSR_SFRZ), "SFRZ");
                    142:        monitor.Puts(x + 51, y, ")");
                    143:        y++;
                    144:        monitor.Print(x, y, "epsr(cr2):%08x(", reg.epsr);
                    145:        monitor.Puts(x + 19, y, TA::OnOff(reg.epsr & m88100reg::PSR_SUPER), "S");
                    146:        monitor.Puts(x + 21, y,
                    147:                ((reg.epsr& m88100reg::PSR_BO_LE) ? "BO=LE" : "BO=BE"));
                    148:        monitor.Puts(x + 27, y, TA::OnOff(reg.epsr & m88100reg::PSR_SER),  "SER");
                    149:        monitor.Puts(x + 31, y, TA::OnOff(reg.epsr & m88100reg::PSR_C),    "Cy");
                    150:        monitor.Puts(x + 34, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFD1), "SFD1");
                    151:        monitor.Puts(x + 39, y, TA::OnOff(reg.epsr & m88100reg::PSR_MXM),  "MXM");
                    152:        monitor.Puts(x + 43, y, TA::OnOff(reg.epsr & m88100reg::PSR_IND),  "IND");
                    153:        monitor.Puts(x + 47, y, TA::OnOff(reg.epsr & m88100reg::PSR_SFRZ), "SFRZ");
                    154:        monitor.Puts(x + 51, y, ")");
1.1       root      155: 
1.1.1.2   root      156:        // 制御レジスタ(左中; *IP)
1.1       root      157:        x = 0;
                    158:        y = 12;
                    159:        monitor.Print(x, y + 0, "xip:%08x  opX:%08x(%c%c)",
                    160:                reg.xip, (uint32)reg.opX,
                    161:                cpu->OpIsBusErr(reg.opX) ? 'B' : '-',
                    162:                cpu->OpIsDelay(reg.opX)  ? 'D' : '-');
                    163:        monitor.Print(x, y + 1, "nip:%08x  opF:%08x(%c%c)",
                    164:                reg.nip, (uint32)reg.opF,
                    165:                cpu->OpIsBusErr(reg.opF) ? 'B' : '-',
                    166:                cpu->OpIsDelay(reg.opF)  ? 'D' : '-');
                    167:        monitor.Print(x, y + 2, "fip:%08x", reg.fip);
                    168: 
                    169:        // 制御レジスタ (S*IP)
                    170:        x = 32;
                    171:        for (int i = 0; i < 3; i++) {
                    172:                monitor.Print(x, y + i, "%s(cr%d):%08x:%c%c",
                    173:                        m88100reg::sipname[i], 4 + i,
                    174:                        (reg.cr[4 + i] & m88100reg::SIP_MASK),
                    175:                        (reg.cr[4 + i] & m88100reg::SIP_V) ? 'V' : '-',
                    176:                        (reg.cr[4 + i] & m88100reg::SIP_E) ? 'E' : '-');
                    177:        }
                    178: 
1.1.1.2   root      179:        // 制御レジスタ(右中)
1.1       root      180:        x = 55;
                    181:        y = 9;
                    182:        for (int i = 0; i < 4; i++) {
                    183:                int rn = 17 + i;
1.1.1.4   root      184:                monitor.Print(x, y++, "sr%d(cr%d):%08x", i, rn, reg.cr[rn]);
1.1       root      185:        }
1.1.1.4   root      186:        monitor.Print(x, y++, "ssbr(cr3):%08x", reg.ssbr);
                    187:        monitor.Print(x, y++, "vbr (cr7):%08x", reg.vbr);
1.1       root      188: 
1.1.1.2   root      189:        // MMU レジスタ(下段)
                    190:        y = 15;
                    191:        for (int i = 0; i <= 2; i++) {
                    192:                int dt =  8 + i * 3;
                    193:                int dd =  9 + i * 3;
                    194:                int da = 10 + i * 3;
                    195: 
                    196:                monitor.Print(0, y, "dmt%d(cr%-2d):%04x",
                    197:                        i, dt, (reg.cr[dt] & 0xffff));
                    198:                monitor.Puts(15, y, "(b,s,d,l,rx, s,en  ,w,v)");
                    199:                monitor.Puts(16, y, (reg.cr[dt] & m88100reg::DM_BO)     ? "B" : "-");
                    200:                monitor.Puts(18, y, (reg.cr[dt] & m88100reg::DM_DAS)    ? "S" : "U");
                    201:                monitor.Puts(20, y, (reg.cr[dt] & m88100reg::DM_DOUB1)  ? "D" : "-");
                    202:                monitor.Puts(22, y, (reg.cr[dt] & m88100reg::DM_LOCK)   ? "L" : "-");
                    203:                // カンマが自然に見えるようにここだけカンマも含めて前詰めで出力
                    204:                monitor.Print(25, y, "%d,",
                    205:                        (reg.cr[dt] & m88100reg::DM_DREG_MASK) >> 7);
                    206:                monitor.Puts(28, y, (reg.cr[dt] & m88100reg::DM_SIGNED) ? "S" : "-");
                    207:                uint32 en = (reg.cr[dt] & m88100reg::DM_EN_MASK) >> 2;
                    208:                monitor.Puts(30, y, m88100reg::dmt_en_str[en]);
                    209:                monitor.Puts(35, y, (reg.cr[dt] & m88100reg::DM_WRITE)  ? "W" : "-");
                    210:                monitor.Puts(37, y, (reg.cr[dt] & m88100reg::DM_VALID)  ? "V" : "-");
                    211: 
                    212:                monitor.Print(40, y, "dmd%d(cr%-2d):%08x", i, dd, reg.cr[dd]);
                    213:                monitor.Print(60, y, "dma%d(cr%2d):%08x",  i, da, reg.cr[da]);
                    214:                y++;
                    215:        }
                    216: }
                    217: 
                    218: //
                    219: // {B,P}ATC モニタ
                    220: //
                    221: 
                    222: // コンストラクタ
                    223: MPU88200ATC::MPU88200ATC(m88200 *cmmu_)
                    224: {
                    225:        cmmu = cmmu_;
                    226: 
1.1.1.3   root      227:        monitor_size = nnSize(65, 38);
1.1.1.2   root      228: }
                    229: 
1.1.1.3   root      230: void
                    231: MPU88200ATC::MonitorUpdate(TextScreen& monitor)
1.1.1.2   root      232: {
                    233:        int x;
                    234:        int y;
                    235: 
                    236:        monitor.Clear();
                    237: 
                    238:        monitor.Print(0, 0,  "SAPR  %05x'000 TE=%d      %c%c%c",
                    239:                (cmmu->sapr.addr >> 12) & 0xfffff,
                    240:                 cmmu->sapr.enable ? 1 : 0,
                    241:                (cmmu->sapr.stat & m88200::APR_WT) ? 'T' : '-',
                    242:                (cmmu->sapr.stat & m88200::APR_G)  ? 'G' : '-',
                    243:                (cmmu->sapr.stat & m88200::APR_CI) ? 'C' : '-');
                    244: 
                    245:        monitor.Print(34, 0, "UAPR  %05x'000 TE=%d      %c%c%c",
                    246:                (cmmu->uapr.addr >> 12) & 0xfffff,
                    247:                 cmmu->uapr.enable ? 1 : 0,
                    248:                (cmmu->uapr.stat & m88200::APR_WT) ? 'T' : '-',
                    249:                (cmmu->uapr.stat & m88200::APR_G)  ? 'G' : '-',
                    250:                (cmmu->uapr.stat & m88200::APR_CI) ? 'C' : '-');
                    251: 
                    252:        monitor.Puts(0,  1, "<BATC>");
                    253:        monitor.Puts(0,  2, "No. LBA         PBA       Stat");
                    254:        monitor.Puts(34, 2, "No. LBA         PBA       Stat");
                    255:        x = 0;
                    256:        y = 3;
                    257:        for (int i = 0; i < 10; i++) {
                    258:                m88200BATC& b = cmmu->batc[i];
                    259: 
                    260:                if (i == cmmu->batc.size() / 2) {
                    261:                        x = 34;
                    262:                        y = 3;
                    263:                }
                    264:                if (i < 8) {
                    265:                        monitor.Print(x, y, " %d:", i);
                    266:                } else {
                    267:                        monitor.Print(x, y, "(%d)", i);
                    268:                }
                    269:                if ((b.lba & 1) == 0) {
                    270:                        monitor.Print(x + 4, y, "%c:%04x'0000 %04x'0000 %c%c%c%c",
                    271:                                (b.lba & m88200::BATC_S) ? 'S' : 'U',
                    272:                                b.lba >> 16, b.pba >> 16,
                    273:                                (b.stat & m88200::DESC_WT) ? 'T' : '-',
                    274:                                (b.stat & m88200::DESC_G)  ? 'G' : '-',
                    275:                                (b.stat & m88200::DESC_CI) ? 'C' : '-',
                    276:                                (b.stat & m88200::DESC_WP) ? 'P' : '-');
                    277:                }
                    278:                y++;
                    279:        }
                    280: 
                    281:        monitor.Puts(0,  8, "<PATC>");
                    282:        monitor.Puts(0,  9, "No. LPA         PFA       Stat");
                    283:        monitor.Puts(34, 9, "No. LPA         PFA       Stat");
                    284: 
                    285:        x = 0;
                    286:        y = 10;
                    287:        for (int i = 0; i < cmmu->patc.size(); i++) {
                    288:                m88200PATC& p = cmmu->patc[i];
                    289: 
                    290:                if (i == cmmu->patc.size() / 2) {
                    291:                        x = 34;
                    292:                        y = 10;
                    293:                }
                    294: 
                    295:                monitor.Print(x, y, "%2d:", i);
                    296:                if ((p.lpa & 1) == 0) {
                    297:                        monitor.Print(x + 4,  y, "%c:%05x'000 %05x'000 %c%c%c%c%c",
                    298:                                (p.lpa & m88200::PATC_S) ? 'S' : 'U',
                    299:                                p.lpa >> 12, p.pfa >> 12,
                    300:                                (p.stat & m88200::DESC_WT) ? 'T' : '-',
                    301:                                (p.stat & m88200::DESC_G)  ? 'G' : '-',
                    302:                                (p.stat & m88200::DESC_CI) ? 'C' : '-',
                    303:                                (p.stat & m88200::DESC_WP) ? 'P' : '-',
                    304:                                p.m                        ? 'M' : '-');
                    305:                }
                    306: 
                    307:                y++;
                    308:        }
1.1       root      309: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.