Annotation of nono/m680x0/m68030cache.cpp, revision 1.1.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.