/*
 *  emu main
 * 
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <elf.h>
#include <endian.h>
#include <errno.h>

#include "gemu.h"

#include "i386/hsw_interp.h"

unsigned long x86_stack_size;
unsigned long stktop;

void gemu_log(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

/* virtual x86 CPU stuff */

extern int invoke_code16(Interp_ENV *, int, int);
extern int invoke_code32(Interp_ENV *, int);
extern char *e_print_cpuemu_regs(ENVPARAMS, int is32);
extern char *e_emu_disasm(ENVPARAMS, unsigned char *org, int is32);
extern void init_npu(void);

Interp_ENV env_global;
Interp_ENV *envp_global;

QWORD EMUtime = 0;

int CEmuStat = 0;

long instr_count;

/* who will initialize this? */
unsigned long io_bitmap[IO_BITMAP_SIZE+1];

/* debug flag, 0=disable 1..9=level */
int d_emu = 0;

unsigned long CRs[5] =
{
	0x00000013,	/* valid bits: 0xe005003f */
	0x00000000,	/* invalid */
	0x00000000,
	0x00000000,
	0x00000000
};

/*
 * DR0-3 = linear address of breakpoint 0-3
 * DR4=5 = reserved
 * DR6	b0-b3 = BP active
 *	b13   = BD
 *	b14   = BS
 *	b15   = BT
 * DR7	b0-b1 = G:L bp#0
 *	b2-b3 = G:L bp#1
 *	b4-b5 = G:L bp#2
 *	b6-b7 = G:L bp#3
 *	b8-b9 = GE:LE
 *	b13   = GD
 *	b16-19= LLRW bp#0	LL=00(1),01(2),11(4)
 *	b20-23= LLRW bp#1	RW=00(x),01(w),11(rw)
 *	b24-27= LLRW bp#2
 *	b28-31= LLRW bp#3
 */
unsigned long DRs[8] =
{
	0x00000000,
	0x00000000,
	0x00000000,
	0x00000000,
	0xffff1ff0,
	0x00000400,
	0xffff1ff0,
	0x00000400
};

unsigned long TRs[2] =
{
	0x00000000,
	0x00000000
};

void FatalAppExit(UINT wAction, LPCSTR lpText)
{
    fprintf(stderr, "Fatal error '%s' in CPU\n", lpText);
    exit(1);
}

int e_debug_check(unsigned char *PC)
{
    register unsigned long d7 = DRs[7];

    if (d7&0x03) {
	if (d7&0x30000) return 0;	/* only execute(00) bkp */
	if ((long)PC==DRs[0]) {
	    e_printf("DBRK: DR0 hit at %p\n",PC);
	    DRs[6] |= 1;
	    return 1;
	}
    }
    if (d7&0x0c) {
	if (d7&0x300000) return 0;
	if ((long)PC==DRs[1]) {
	    e_printf("DBRK: DR1 hit at %p\n",PC);
	    DRs[6] |= 2;
	    return 1;
	}
    }
    if (d7&0x30) {
	if (d7&0x3000000) return 0;
	if ((long)PC==DRs[2]) {
	    e_printf("DBRK: DR2 hit at %p\n",PC);
	    DRs[6] |= 4;
	    return 1;
	}
    }
    if (d7&0xc0) {
	if (d7&0x30000000) return 0;
	if ((long)PC==DRs[3]) {
	    e_printf("DBRK: DR3 hit at %p\n",PC);
	    DRs[6] |= 8;
	    return 1;
	}
    }
    return 0;
}

/* Debug stuff */
void logstr(unsigned long mask, const char *fmt,...) 
{
    va_list ap;

    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
}

/* unconditional message into debug log and stderr */
#undef error
void error(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    vfprintf(stderr, fmt, ap);
    va_end(ap);
    exit(1);
}

int PortIO(DWORD port, DWORD value, UINT size, BOOL is_write)
{
    fprintf(stderr, "IO: %s port=0x%lx value=0x%lx size=%d",
            is_write ? "write" : "read", port, value, size);
    return value;
}

void LogProcName(WORD wSel, WORD wOff, WORD wAction)
{

}

void INT_handler(int num, void *env)
{
  fprintf(stderr, "EM86: int %d\n", num);
}

/***********************************************************/

/* XXX: currently we use LDT entries */
#define __USER_CS	(0x23|4)
#define __USER_DS	(0x2B|4)

void usage(void)
{
    printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
           "usage: gemu program [arguments...]\n"
           "Linux x86 emulator\n"
           );
    exit(1);
}

int main(int argc, char **argv)
{
    const char *filename;
    struct pt_regs regs1, *regs = &regs1;
    struct image_info info1, *info = &info1;
    Interp_ENV *env;

    if (argc <= 1)
        usage();
    
    filename = argv[1];

    /* Zero out regs */
    memset(regs, 0, sizeof(struct pt_regs));

    /* Zero out image_info */
    memset(info, 0, sizeof(struct image_info));

    if(elf_exec(filename, argv+1, __environ, regs, info) != 0) {
	printf("Error loading %s\n", filename);
	exit(1);
    }
    
#if 0
    printf("start_brk   0x%08lx\n" , info->start_brk);
    printf("end_code    0x%08lx\n" , info->end_code);
    printf("start_code  0x%08lx\n" , info->start_code);
    printf("end_data    0x%08lx\n" , info->end_data);
    printf("start_stack 0x%08lx\n" , info->start_stack);
    printf("brk         0x%08lx\n" , info->brk);
    printf("esp         0x%08lx\n" , regs->esp);
    printf("eip         0x%08lx\n" , regs->eip);
#endif

    target_set_brk((char *)info->brk);
    syscall_init();

    env = &env_global;
    envp_global = env;
    memset(env, 0, sizeof(Interp_ENV));

    env->rax.e   = regs->eax;
    env->rbx.e   = regs->ebx;
    env->rcx.e   = regs->ecx;
    env->rdx.e   = regs->edx;
    env->rsi.esi = regs->esi;
    env->rdi.edi = regs->edi;
    env->rbp.ebp = regs->ebp;
    env->rsp.esp = regs->esp;
    env->cs.cs   = __USER_CS;
    env->ds.ds   = __USER_DS;
    env->es.es   = __USER_DS;
    env->ss.ss   = __USER_DS;
    env->fs.fs   = __USER_DS;
    env->gs.gs   = __USER_DS;
    env->trans_addr = regs->eip;

    LDT[__USER_CS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
    LDT[__USER_CS >> 3].dwSelLimit = 0xfffff;
    LDT[__USER_CS >> 3].lpSelBase = NULL;

    LDT[__USER_DS >> 3].w86Flags = DF_PRESENT | DF_PAGES | DF_32;
    LDT[__USER_DS >> 3].dwSelLimit = 0xfffff;
    LDT[__USER_DS >> 3].lpSelBase = NULL;
    init_npu();

    for(;;) {
        int err;
        uint8_t *pc;

        err = invoke_code32(env, -1);
        env->trans_addr = env->return_addr;
        pc = env->seg_regs[0] + env->trans_addr;
        switch(err) {
        case EXCP0D_GPF:
            if (pc[0] == 0xcd && pc[1] == 0x80) {
                /* syscall */
                env->trans_addr += 2;
                env->rax.e = do_syscall(env->rax.e, 
                                        env->rbx.e,
                                        env->rcx.e,
                                        env->rdx.e,
                                        env->rsi.esi,
                                        env->rdi.edi,
                                        env->rbp.ebp);
            } else {
                goto trap_error;
            }
            break;
        default:
        trap_error:
            fprintf(stderr, "GEMU: Unknown error %d, aborting\n", err);
            d_emu = 9;
            fprintf(stderr, "%s\n%s\n",
                    e_print_cpuemu_regs(env, 1), 
                    e_emu_disasm(env,pc,1));
            abort();
        }
    }
    return 0;
}
