/*
 *  i386 breakpoint helpers
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "cpu.h"
#include "exec/helper-proto.h"


void hw_breakpoint_insert(CPUX86State *env, int index)
{
    CPUState *cs = CPU(x86_env_get_cpu(env));
    int type = 0, err = 0;

    switch (hw_breakpoint_type(env->dr[7], index)) {
    case DR7_TYPE_BP_INST:
        if (hw_breakpoint_enabled(env->dr[7], index)) {
            err = cpu_breakpoint_insert(cs, env->dr[index], BP_CPU,
                                        &env->cpu_breakpoint[index]);
        }
        break;
    case DR7_TYPE_DATA_WR:
        type = BP_CPU | BP_MEM_WRITE;
        break;
    case DR7_TYPE_IO_RW:
        /* No support for I/O watchpoints yet */
        break;
    case DR7_TYPE_DATA_RW:
        type = BP_CPU | BP_MEM_ACCESS;
        break;
    }

    if (type != 0) {
        err = cpu_watchpoint_insert(cs, env->dr[index],
                                    hw_breakpoint_len(env->dr[7], index),
                                    type, &env->cpu_watchpoint[index]);
    }

    if (err) {
        env->cpu_breakpoint[index] = NULL;
    }
}

void hw_breakpoint_remove(CPUX86State *env, int index)
{
    CPUState *cs;

    if (!env->cpu_breakpoint[index]) {
        return;
    }
    cs = CPU(x86_env_get_cpu(env));
    switch (hw_breakpoint_type(env->dr[7], index)) {
    case DR7_TYPE_BP_INST:
        if (hw_breakpoint_enabled(env->dr[7], index)) {
            cpu_breakpoint_remove_by_ref(cs, env->cpu_breakpoint[index]);
        }
        break;
    case DR7_TYPE_DATA_WR:
    case DR7_TYPE_DATA_RW:
        cpu_watchpoint_remove_by_ref(cs, env->cpu_watchpoint[index]);
        break;
    case DR7_TYPE_IO_RW:
        /* No support for I/O watchpoints yet */
        break;
    }
}

static bool check_hw_breakpoints(CPUX86State *env, bool force_dr6_update)
{
    target_ulong dr6;
    int reg;
    bool hit_enabled = false;

    dr6 = env->dr[6] & ~0xf;
    for (reg = 0; reg < DR7_MAX_BP; reg++) {
        bool bp_match = false;
        bool wp_match = false;

        switch (hw_breakpoint_type(env->dr[7], reg)) {
        case DR7_TYPE_BP_INST:
            if (env->dr[reg] == env->eip) {
                bp_match = true;
            }
            break;
        case DR7_TYPE_DATA_WR:
        case DR7_TYPE_DATA_RW:
            if (env->cpu_watchpoint[reg] &&
                env->cpu_watchpoint[reg]->flags & BP_WATCHPOINT_HIT) {
                wp_match = true;
            }
            break;
        case DR7_TYPE_IO_RW:
            break;
        }
        if (bp_match || wp_match) {
            dr6 |= 1 << reg;
            if (hw_breakpoint_enabled(env->dr[7], reg)) {
                hit_enabled = true;
            }
        }
    }

    if (hit_enabled || force_dr6_update) {
        env->dr[6] = dr6;
    }

    return hit_enabled;
}

void breakpoint_handler(CPUState *cs)
{
    X86CPU *cpu = X86_CPU(cs);
    CPUX86State *env = &cpu->env;
    CPUBreakpoint *bp;

    if (cs->watchpoint_hit) {
        if (cs->watchpoint_hit->flags & BP_CPU) {
            cs->watchpoint_hit = NULL;
            if (check_hw_breakpoints(env, false)) {
                raise_exception(env, EXCP01_DB);
            } else {
                cpu_resume_from_signal(cs, NULL);
            }
        }
    } else {
        QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
            if (bp->pc == env->eip) {
                if (bp->flags & BP_CPU) {
                    check_hw_breakpoints(env, true);
                    raise_exception(env, EXCP01_DB);
                }
                break;
            }
        }
    }
}

void helper_single_step(CPUX86State *env)
{
#ifndef CONFIG_USER_ONLY
    check_hw_breakpoints(env, true);
    env->dr[6] |= DR6_BS;
#endif
    raise_exception(env, EXCP01_DB);
}

void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)
{
#ifndef CONFIG_USER_ONLY
    int i;

    if (reg < 4) {
        hw_breakpoint_remove(env, reg);
        env->dr[reg] = t0;
        hw_breakpoint_insert(env, reg);
    } else if (reg == 7) {
        for (i = 0; i < DR7_MAX_BP; i++) {
            hw_breakpoint_remove(env, i);
        }
        env->dr[7] = t0;
        for (i = 0; i < DR7_MAX_BP; i++) {
            hw_breakpoint_insert(env, i);
        }
    } else {
        env->dr[reg] = t0;
    }
#endif
}
