Annotation of nono/vm/pluto.cpp, revision 1.1.1.4

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: 
                      7: #include "pluto.h"
1.1.1.3   root        8: #include "aout.h"
1.1.1.2   root        9: #include "mainapp.h"
1.1.1.3   root       10: #include "mpu680x0.h"
                     11: #include "ram.h"
1.1       root       12: 
                     13: PlutoDevice::PlutoDevice()
                     14: {
                     15:        logname = "pluto";
                     16:        devname = "Pluto";
                     17:        devaddr = 0xeac000;
                     18:        devlen  = 0x2000;
                     19: }
                     20: 
                     21: PlutoDevice::~PlutoDevice()
                     22: {
                     23: }
                     24: 
1.1.1.4 ! root       25: void
        !            26: PlutoDevice::ResetHard()
        !            27: {
        !            28:        // XXX not yet
        !            29:        m_count = 0;
        !            30: }
        !            31: 
1.1.1.3   root       32: // ROM
                     33: /*static*/ const uint16
                     34: PlutoDevice::rom[] = {
                     35:        // ホストファイル起動
                     36:        0x00ea, 0xc004,                 //      .dc.l   _start  ; 起動アドレス
                     37:                                                        //_start:
                     38:        0x2039, 0x00ea, 0xc450, //      move.l  (ROMIO_LOAD),%d0
                     39:        0x6704,                                 //      beq.s   _err
                     40:        0x2040,                                 //      move.l  %d0,%a2
                     41:        0x4ed0,                                 //      jmp             (%a2)
                     42:                                                        //_err:
                     43:        0x43fa, 0x000c,                 //      lea.l   (_errmsg),%a1
                     44:        0x7021, 0x4e4f,                 //      IOCS    B_PRINT
                     45:                                                        //_loop:
                     46:        0x4e72, 0x2600,                 //      stop    #0x2600
                     47:        0x60fa,                                 //      bra.s   _loop
                     48:                                                        //_errmsg:
                     49:        0x2a2a, 0x2043, 0x616e, //      .dc.b   "** Can"
                     50:        0x6e6f, 0x7420, 0x6c6f, //      .dc.b   "not lo"
                     51:        0x6164, 0x2068, 0x6f73, //      .dc.b   "ad hos"
                     52:        0x7420, 0x6669, 0x6c65, //      .dc.b   "t file"
                     53:        0x2e00,                                 //      .dc.b   ".",0
                     54: };
                     55: 
                     56: uint64
                     57: PlutoDevice::Read8(uint32 addr)
                     58: {
                     59:        uint32 offset = addr - devaddr;
                     60:        uint32 data;
                     61: 
                     62:        if (offset < sizeof(rom)) {
                     63:                data = rom[offset / 2];
                     64:                if ((offset & 1) == 0) {
                     65:                        return data >> 8;
                     66:                } else {
                     67:                        return data & 0xff;
                     68:                }
                     69:        }
                     70: 
                     71:        return (uint64)-1;
                     72: }
                     73: 
                     74: uint64
                     75: PlutoDevice::Read16(uint32 addr)
                     76: {
                     77:        uint32 offset = addr - devaddr;
                     78: 
                     79:        if (offset < sizeof(rom)) {
                     80:                return rom[offset / 2];
                     81:        }
                     82: 
                     83:        return (uint64)-1;
                     84: }
                     85: 
                     86: uint64
                     87: PlutoDevice::Read32(uint32 addr)
                     88: {
                     89:        uint32 offset = addr - devaddr;
                     90:        uint32 data;
                     91: 
                     92:        if (offset < sizeof(rom)) {
                     93:                data = rom[offset / 2] << 16;
                     94:                data |= rom[(offset / 2) + 1];
                     95:                return data;
                     96:        }
                     97:        switch (offset) {
                     98:         case 0x450:    // ROMIO_LOAD
                     99:                return ROM_Load();
                    100: 
                    101:         default:
                    102:                break;
                    103:        }
                    104:        return (uint64)-1;
                    105: }
                    106: 
                    107: uint64
                    108: PlutoDevice::Write8(uint32 addr, uint32 data)
                    109: {
                    110:        switch (addr) {
                    111:         case 0xeac403:
                    112:                write_8_benchmark(addr, data);
                    113:                break;
                    114:         default:
                    115:                break;
                    116:        }
                    117:        putlog(0, "未実装バイト書き込み $%06x", addr);
                    118:        return 0;
                    119: }
                    120: 
                    121: uint64
                    122: PlutoDevice::Write16(uint32 addr, uint32 data)
                    123: {
                    124:        putlog(0, "未実装ワード書き込み $%06x", addr);
                    125:        return 0;
                    126: }
                    127: 
                    128: uint64
                    129: PlutoDevice::Peek8(uint32 addr)
                    130: {
                    131:        uint32 offset = addr - devaddr;
                    132:        uint32 data;
                    133: 
                    134:        if (offset < sizeof(rom)) {
                    135:                data = rom[offset / 2];
                    136:                if ((offset & 1) == 0) {
                    137:                        return data >> 8;
                    138:                } else {
                    139:                        return data & 0xff;
                    140:                }
                    141:        }
                    142: 
                    143:        return (uint64)-1;
                    144: }
                    145: 
                    146: //
                    147: // ホストファイル起動
                    148: //
                    149: 
                    150: // -A オプションで指定されたホストファイルをロードする。
                    151: // ロードできればエントリポイントを返す。
                    152: // host_file が指定されている時に呼ぶこと。
                    153: uint32
                    154: PlutoDevice::ROM_Load()
                    155: {
                    156:        assert(gMainApp.host_file);
                    157: 
                    158:        // ホストファイルをロード
                    159:        uint32 entry = gRAM->LoadFile(gMainApp.host_file, AOUT_MID_M68K);
                    160: 
                    161:        if (entry) {
                    162:                // NetBSD/x68k のプライマリブートローダが /boot を読み込む時には
                    163:                // いくつかレジスタ渡しのパラメータがあるので、ここで用意する。
                    164:                // 本当はターゲットが NetBSD/x68k の /boot の時に限定すべきのような
                    165:                // 気もするけど、とりあえず。
                    166:                // 必要なパラメータは
                    167:                // %d6 に bootdev、NetBSD/x68k の場合は
                    168:                // bootdev = $MACULPTT
                    169:                //            ||||||++- major type
                    170:                //            |||||+--- パーティション番号
                    171:                //            ||||+---- SCSI なら LUN、それ以外なら 0
                    172:                //            |||+----- unit (SCSI なら SCSI ID、FD ならドライブ番号)
                    173:                //            ||+------ ctlr (spc0 なら 0 のやつ)
                    174:                //            |+------- adaptor (spc = 1、mha = 2)
                    175:                //            +-------- magic ($a)
                    176:                // major type は fd=2、MemoryDisk=8、sd=4、(st=5、)、cd=7、ne=255。
                    177:                //
                    178:                // %d7 に howto だが今の所使ってないようだ。
                    179: 
                    180:                m68kcpu *cpu = gMPU680x0->GetCPU();
                    181:                RegD(6) = 0xa1000004;
                    182:                RegD(7) = 0;
                    183:        }
                    184: 
                    185:        return entry;
                    186: }
                    187: 
1.1       root      188: // ベンチマーク開始
                    189: void
                    190: PlutoDevice::benchmark_start(uint32 data)
                    191: {
                    192:        m_test_num = data;
                    193: 
                    194:        // テスト番号によってパラメータをセット
                    195:        // #2,#3 は NOP による実行サイクル測定。
                    196:        // #4,#5 は movem によるデータ空間アクセス測定。
                    197:        switch (m_test_num) {
                    198:         case 2:
                    199:         case 3:
                    200:                m_test_name = "NOP";
                    201:                m_inst_len = 2;
                    202:                m_inst_cycle = 2;
                    203:                break;
                    204:         case 4:
                    205:         case 5:
                    206:                m_test_name = "MOVEM";
                    207:                m_inst_len = 8;
                    208:                m_inst_cycle = 244;     // XXX 見直すこと
                    209:                break;
                    210:        }
                    211: 
                    212:        // 測定開始時だけ表示
                    213:        if (m_count == 0) {
                    214:                putlog(0, "ベンチマーク開始");
                    215: 
                    216:                // 命令開始アドレス。この時点で REG_PC は次をさしている
1.1.1.2   root      217:                m_start_addr = gMPU680x0->GetPPC();
1.1       root      218:        }
                    219: 
                    220:        // 測定開始
                    221:        gettimeofday(&m_start, NULL);
                    222: }
                    223: 
                    224: // ベンチマーク終了
                    225: void
                    226: PlutoDevice::benchmark_end()
                    227: {
                    228:        const int SECONDS = 5;  // 測定秒数 [sec]
                    229:        timeval end, result;
                    230:        int t;
                    231:        int num_of_inst;                // 1ループ中の命令セット数
                    232:        double speed;
                    233: 
                    234:        // 測定終了
                    235:        gettimeofday(&end, NULL);
                    236:        m_count++;
                    237: 
                    238:        // 今回1セット分の実行時間 [usec]
                    239:        timersub(&end, &m_start, &result);
                    240: 
                    241:        // 総実行時間
                    242:        timeradd(&result, &m_total, &m_total);
                    243: 
                    244:        // 規定秒数に満たなければ、もう1セット繰り返し。
                    245:        // 次が jmp 命令なのでこの命令を抜けるだけでいい。
                    246:        if (m_total.tv_sec < SECONDS) {
                    247:                return;
                    248:        }
                    249: 
                    250:        // 規定秒数に達していれば、測定終了
                    251:        t = m_total.tv_sec * 1000*1000 + m_total.tv_usec;
                    252:        putlog(0, "ベンチマーク#%d 終了 (%d 回, 計 %d.%03d msec)",
1.1.1.2   root      253:                gMainApp.benchmark_mode, m_count, t / 1000, t % 1000);
1.1       root      254: 
                    255:        // 1ループ中の命令セット数を算出。REG_PPC はこの命令の開始番地
1.1.1.2   root      256:        num_of_inst = (gMPU680x0->GetPPC() - m_start_addr) / m_inst_len;
1.1       root      257: 
                    258:        // 68030 のクロック数 [MHz] に換算
                    259:        speed = (double)(m_count * num_of_inst) * m_inst_cycle / t;
                    260: 
                    261:        // 表示用にベンチマーク ROM のリビジョンを取得
                    262:        int rev;
                    263: rev = 0;
                    264: #if 0
                    265:        IPLROM1 *iplrom1 = (IPLROM1 *)vm->SearchDevice(DEVICE_IPLROM1);
                    266:        ASSERT(iplrom1);
                    267:        if (!iplrom1->GetBenchmarkROM(m_test_num, NULL, &rev)) {
                    268:                rev = 0;
                    269:        }
                    270: #endif
                    271: 
                    272:        // XXX NetBSD ホストでは有効桁2桁と思われる
                    273:        putlog(0, "ベンチマーク#%d.%d (%s 実行速度) 68030/%3.0fMHz, %d MIPS",
                    274:                m_test_num, rev, m_test_name, speed, (m_count * num_of_inst) / t);
                    275: 
                    276:        // 電源オフ
                    277:        // XXX とりあえずね
                    278:        exit(1);
                    279: }
                    280: 
                    281: //
                    282: void
                    283: PlutoDevice::write_8_benchmark(uint32 addr, uint32 data)
                    284: {
                    285:        switch (data) {
                    286:         case 0:        // ベンチマーク終了
                    287:                benchmark_end();
                    288:                break;
                    289:         case 2:        // ベンチマーク開始
                    290:         case 3:
                    291:         case 4:
                    292:         case 5:
                    293:                benchmark_start(data);
                    294:                break;
                    295:         default:
                    296:                PANIC("not impl");
                    297:        }
                    298: }

unix.superglobalmegacorp.com

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