<commit_before>package net.katsuster.semu;

/**
 * ARM MMU
 *
 * @author katsuhiro
 */
public class MMU {
    private boolean enable;

    private ARM9 cpu;
    private StdCoProc stdCp;
    private int tableBase;

    public MMU(ARM9 cpu, StdCoProc cp) {
        this.enable = false;

        this.cpu = cpu;
        this.stdCp = cp;
        this.tableBase = 0;
    }

    /**
     * MMU が有効か否かを取得します。
     *
     * @return MMU が有効ならば true、無効ならば false
     */
    public boolean isEnable() {
        return enable;
    }

    /**
     * MMU が有効か否かを設定します。
     *
     * @param e MMU が有効ならば true、無効ならば false
     */
    public void setEnable(boolean e) {
        enable = e;
    }

    /**
     * MMU が接続されている CPU を取得します。
     *
     * @return MMU が接続されている CPU
     */
    public ARM9 getCPU() {
        return cpu;
    }

    /**
     * MMU が接続されている標準コプロセッサを取得します。
     *
     * @return MMU が接続されている標準コプロセッサ
     */
    public StdCoProc getStdCoProc() {
        return stdCp;
    }

    /**
     * MMU の状態を更新します。
     *
     * 下記を変更した際に呼び出す必要があります。
     *
     * - TTBR0: 変換テーブルベース（Cp15 レジスタ 2）
     */
    public void update() {
        tableBase = getStdCoProc().getCReg(StdCoProc.CR02_MMU_TTBR0);
    }

    /**
     * アドレス変換を行います。
     *
     * 変換時にエラーが発生した場合はアボートが発生します。
     * 仮想アドレスが指すデータの種類により、
     * 命令の場合はプリフェッチアボートが発生します。
     * データの場合はデータアボートが発生します。
     *
     * @param va   仮想アドレス（VA）
     * @param inst 仮想アドレスが指すデータの種類、
     *             命令の場合は true、データの場合は false
     * @return 物理アドレス（PA）
     */
    public int translate(int va, boolean inst) {
        int paL1, entryL1, typeL1, pa;

        if (!isEnable()) {
            return va;
        }

        paL1 = getL1Address(va);
        if (!getCPU().tryRead(paL1)) {
            getCPU().raiseException(ARM9.EXCEPT_ABT_DATA,
                    String.format("MMU read L1 [%08x]", paL1));
            return 0;<commit_msg>add types of MMU fault status.<commit_after>package net.katsuster.semu;

/**
 * ARM MMU
 *
 * @author katsuhiro
 */
public class MMU {
    private boolean enable;

    private ARM9 cpu;
    private StdCoProc stdCp;
    private int tableBase;

    public MMU(ARM9 cpu, StdCoProc cp) {
        this.enable = false;

        this.cpu = cpu;
        this.stdCp = cp;
        this.tableBase = 0;
    }

    /**
     * MMU が有効か否かを取得します。
     *
     * @return MMU が有効ならば true、無効ならば false
     */
    public boolean isEnable() {
        return enable;
    }

    /**
     * MMU が有効か否かを設定します。
     *
     * @param e MMU が有効ならば true、無効ならば false
     */
    public void setEnable(boolean e) {
        enable = e;
    }

    /**
     * MMU が接続されている CPU を取得します。
     *
     * @return MMU が接続されている CPU
     */
    public ARM9 getCPU() {
        return cpu;
    }

    /**
     * MMU が接続されている標準コプロセッサを取得します。
     *
     * @return MMU が接続されている標準コプロセッサ
     */
    public StdCoProc getStdCoProc() {
        return stdCp;
    }

    /**
     * MMU の状態を更新します。
     *
     * 下記を変更した際に呼び出す必要があります。
     *
     * - TTBR0: 変換テーブルベース（Cp15 レジスタ 2）
     */
    public void update() {
        tableBase = getStdCoProc().getCReg(StdCoProc.CR02_MMU_TTBR0);
    }

    public static final int FS_TERM = 0x2;
    public static final int FS_VECT = 0x0;
    public static final int FS_ALIGN1 = 0x1;
    public static final int FS_ALIGN2 = 0x3;
    public static final int FS_TRANS_L1 = 0xc;
    public static final int FS_TRANS_L2 = 0xe;
    public static final int FS_TRANS_SEC = 0x5;
    public static final int FS_TRANS_PAGE = 0x7;
    public static final int FS_DOM_SEC = 0x9;
    public static final int FS_DOM_PAGE = 0xb;
    public static final int FS_PERM_SEC = 0xd;
    public static final int FS_PERM_PAGE = 0xf;
    public static final int FS_LINE_SEC = 0x4;
    public static final int FS_LINE_PAGE = 0x6;
    public static final int FS_ABORT_SEC = 0x8;
    public static final int FS_ABORT_PAGE = 0xa;

    /**
     * MMU フォルトを発生させます。
     *
     * CPU に対しては、プリフェッチアボート例外、
     * またはデータアボート例外を発生させます。
     *
     * @param fs   フォルトステータス
     * @param dom  ドメイン、存在しない場合は 0
     * @param va   仮想アドレス（VA）
     * @param inst 命令の場合は true、データの場合は false
     * @param dbgmsg デバッグ用のメッセージ
     */
    public void faultMMU(int fs, int dom, int va, boolean inst, String dbgmsg) {
        int val, num;

        //フォルトステータス
        val = stdCp.getCReg(5);
        BitOp.setField(val, 4, 3, dom);
        BitOp.setField(val, 0, 3, fs);
        stdCp.setCReg(5, val);

        //フォルトアドレス
        stdCp.setCReg(6, va);

        //例外を発生させる
        if (inst) {
            //プリフェッチアボート例外
            num = ARM9.EXCEPT_ABT_INST;
        } else {
            //データアボート例外
            num = ARM9.EXCEPT_ABT_DATA;
        }
        getCPU().raiseException(num, dbgmsg);
    }

    /**
     * アドレス変換を行います。
     *
     * 変換時にエラーが発生した場合はアボートが発生します。
     * 仮想アドレスが指すデータの種類により、
     * 命令の場合はプリフェッチアボートが発生します。
     * データの場合はデータアボートが発生します。
     *
     * @param va   仮想アドレス（VA）
     * @param inst 仮想アドレスが指すデータの種類、
     *             命令の場合は true、データの場合は false
     * @return 物理アドレス（PA）
     */
    public int translate(int va, boolean inst) {
        int paL1, entryL1, typeL1, pa;

        if (!isEnable()) {
            return va;
        }

        paL1 = getL1Address(va);
        if (!getCPU().tryRead(paL1)) {
            faultMMU(FS_TRANS_L1, 0, va, inst,
                    String.format("MMU read L1 [%08x]", paL1));
            return 0;
{'fraction_non_alphanumeric': 0.09985152190051967, 'fraction_numerical': 0.016146993318485525, 'mean_word_length': 1.8244234800838575, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4531007', 'n_tokens_mistral': 2507, 'n_tokens_neox': 2390, 'n_words': 445}