Annotation of nono/m680x0/m68030cache.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2023 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: // キャッシュ
        !             8: 
        !             9: #include "mpu680x0.h"
        !            10: #include "m68030cache.h"
        !            11: 
        !            12: // 命令キャッシュから指定のアドレスをワードフェッチ。
        !            13: // ここでは PC を進めたりはしない。
        !            14: // バスエラーが起きると例外 M68K::EXCEP_BUSERR をスローする。
        !            15: uint32
        !            16: MPU680x0Device::fetch_16_cache(uint32 addr)
        !            17: {
        !            18:        putlog(2, "%s addr=%08x", __func__, addr);
        !            19:        // addr を含むロングワードを読み込んでから、上位か下位だけ返す。
        !            20:        uint32 data = fetch_32_cache_aligned(addr & ~3);
        !            21:        if ((addr & 2) == 0) {
        !            22:                return data >> 16;
        !            23:        } else {
        !            24:                return data & 0xffff;
        !            25:        }
        !            26: }
        !            27: 
        !            28: // 命令キャッシュから指定のアドレス (ミスアライン可) をロングワードフェッチ。
        !            29: // ここでは PC を進めたりはしない。
        !            30: // バスエラーが起きると例外 M68K::EXCEP_BUSERR をスローする。
        !            31: uint32
        !            32: MPU680x0Device::fetch_32_cache(uint32 addr)
        !            33: {
        !            34:        putlog(2, "%s addr=%08x", __func__, addr);
        !            35:        if ((addr & 2) == 0) {
        !            36:                return fetch_32_cache_aligned(addr);
        !            37:        } else {
        !            38:                uint32 data;
        !            39:                data  = fetch_16_cache(addr) << 16;
        !            40:                data |= fetch_16_cache(addr + 2);
        !            41:                return data;
        !            42:        }
        !            43: }
        !            44: 
        !            45: // 命令キャッシュから指定のアドレスをロングワードフェッチ。
        !            46: // addr の下位2ビットは無視される。
        !            47: // ここでは PC を進めたりはしない。
        !            48: uint32
        !            49: MPU680x0Device::fetch_32_cache_aligned(uint32 addr)
        !            50: {
        !            51:        putlog(2, "%s addr=%08x", __func__, addr);
        !            52:        uint32 tag = (addr & 0xffffff00) | (IsSuper() ? 1 : 0);
        !            53:        uint32 idx = (addr & 0x000000f0) >> 4;
        !            54: 
        !            55:        auto& l = icache->line[idx];
        !            56:        if (l.tag != tag) {
        !            57:                // タグが一致しなければ、1ライン充填。
        !            58:                // XXX 可能ならバースト転送?
        !            59:                putlog(2, "%s line[%d] invalidate", __func__, idx);
        !            60: 
        !            61:                l.tag = tag;
        !            62:                l.valid_all = 0;
        !            63:                // XXX 未実装
        !            64:                // FALLTHROUGH
        !            65:        }
        !            66: 
        !            67:        // タグが一致した
        !            68:        uint32 sel = (addr & 0x0000000c) >> 2;
        !            69:        if (l.valid[sel] == 0) {
        !            70:                // シングル充填。
        !            71:                uint32 data = fetch_32_bus((addr & 0xfffffff0) + (sel << 2));
        !            72:                if (__predict_true(bus.ci == false)) {
        !            73:                        l.data[sel] = data;
        !            74:                        l.valid[sel] = 1;
        !            75:                        putlog(2, "%s line[%d][%d] <- %08x", __func__, idx, sel, data);
        !            76:                } else {
        !            77:                        putlog(2, "%s line[%d][%d] = %08x (CI)", __func__, idx, sel, data);
        !            78:                }
        !            79:                return data;
        !            80:        }
        !            81: 
        !            82:        // エントリが有効
        !            83:        putlog(2, "%s line[%d][%d] -> %08x", __func__, idx, sel, l.data[sel]);
        !            84:        return l.data[sel];
        !            85: }
        !            86: 
        !            87: #if 0
        !            88: uint32
        !            89: MPU680x0Device::read_8_cache(busaddr addr)
        !            90: {
        !            91:        printf("%s not implemented\n", __func__);
        !            92:        return -1;
        !            93: }
        !            94: 
        !            95: uint32
        !            96: MPU680x0Device::read_16_cache(busaddr addr)
        !            97: {
        !            98:        printf("%s not implemented\n", __func__);
        !            99:        return -1;
        !           100: }
        !           101: 
        !           102: uint32
        !           103: MPU680x0Device::read_32_cache(busaddr addr)
        !           104: {
        !           105:        printf("%s not implemented\n", __func__);
        !           106:        return -1;
        !           107: }
        !           108: 
        !           109: void
        !           110: MPU680x0Device::write_8_cache(busaddr addr, uint32 data)
        !           111: {
        !           112:        printf("%s not implemented\n", __func__);
        !           113: }
        !           114: 
        !           115: void
        !           116: MPU680x0Device::write_16_cache(busaddr addr, uint32 data)
        !           117: {
        !           118:        printf("%s not implemented\n", __func__);
        !           119: }
        !           120: 
        !           121: void
        !           122: MPU680x0Device::write_32_cache(busaddr addr, uint32 data)
        !           123: {
        !           124:        printf("%s not implemented\n", __func__);
        !           125: }
        !           126: #endif
        !           127: 
        !           128: // CACR レジスタ書き込み
        !           129: void
        !           130: MPU680x0Device::SetCACR(uint32 newval)
        !           131: {
        !           132:        newval &= M68K::CACR_MASK;
        !           133:        uint32 oldval = reg.cacr;
        !           134:        uint32 chgval = oldval ^ newval;
        !           135: 
        !           136:        // EI
        !           137:        if ((chgval & M68K::CACR_EI) != 0) {
        !           138:                if ((newval & M68K::CACR_EI) != 0) {
        !           139:                        // 命令キャッシュ有効
        !           140:                        icache_enable = true;
        !           141:                        putlog(1, "I-Cache enabled");
        !           142:                } else {
        !           143:                        // 命令キャッシュ無効
        !           144:                        icache_enable = false;
        !           145:                        putlog(1, "I-Cache disabled");
        !           146:                }
        !           147:        }
        !           148: 
        !           149:        // FI
        !           150:        if ((chgval & M68K::CACR_FI) != 0) {
        !           151:                icache_freeze = (newval & M68K::CACR_FI);
        !           152:        }
        !           153: 
        !           154:        // CEI
        !           155:        if ((chgval & M68K::CACR_CEI) != 0) {
        !           156:                // CAAR の b7-2 で示されるロングワードを無効にする。
        !           157:                uint32 idx = (reg.cacr & 0x000000f0) >> 4;
        !           158:                uint32 num = (reg.cacr & 0x0000000c) >> 2;
        !           159:                auto& l = icache->line[idx];
        !           160:                l.valid[num] = 0;
        !           161: 
        !           162:                newval &= ~M68K::CACR_CEI;
        !           163:        }
        !           164: 
        !           165:        // CI
        !           166:        if ((chgval & M68K::CACR_CI) != 0) {
        !           167:                // 命令キャッシュの全エントリをクリア。
        !           168:                for (auto& l : icache->line) {
        !           169:                        l.valid_all = 0;
        !           170:                }
        !           171: 
        !           172:                newval &= ~M68K::CACR_CI;
        !           173:        }
        !           174: 
        !           175:        // データキャッシュは未実装。
        !           176:        newval &= ~(M68K::CACR_CD | M68K::CACR_CED);
        !           177: 
        !           178:        // とりあえずレジスタイメージも保存。
        !           179:        reg.cacr = newval;
        !           180: }

unix.superglobalmegacorp.com

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