mirror of
				https://git.suyu.dev/suyu/suyu
				synced 2025-11-04 00:49:02 -06:00 
			
		
		
		
	got rid of 'src' folders in each sub-project
This commit is contained in:
		
							
								
								
									
										68
									
								
								src/core/arm/arm_interface.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/core/arm/arm_interface.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,68 @@
 | 
			
		||||
// Copyright 2014 Citra Emulator Project
 | 
			
		||||
// Licensed under GPLv2
 | 
			
		||||
// Refer to the license.txt file included.  
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "common_types.h"
 | 
			
		||||
 | 
			
		||||
/// Generic ARM11 CPU interface
 | 
			
		||||
class ARM_Interface {
 | 
			
		||||
public:
 | 
			
		||||
    ARM_Interface() {
 | 
			
		||||
        num_instructions_ = 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~ARM_Interface() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Step CPU by one instruction
 | 
			
		||||
    void Step() {
 | 
			
		||||
        ExecuteInstruction();
 | 
			
		||||
        num_instructions_++;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
    /**
 | 
			
		||||
     * Set the Program Counter to an address
 | 
			
		||||
     * @param addr Address to set PC to
 | 
			
		||||
     */
 | 
			
		||||
    virtual void SetPC(u32 addr) = 0;
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * Get the current Program Counter
 | 
			
		||||
     * @return Returns current PC
 | 
			
		||||
     */
 | 
			
		||||
    virtual u32 PC() = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get an ARM register
 | 
			
		||||
     * @param index Register index (0-15)
 | 
			
		||||
     * @return Returns the value in the register
 | 
			
		||||
     */
 | 
			
		||||
    virtual u32 Reg(int index) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get the current CPSR register
 | 
			
		||||
     * @return Returns the value of the CPSR register
 | 
			
		||||
     */
 | 
			
		||||
    virtual u32 CPSR() = 0;  
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the number of clock ticks since the last rese
 | 
			
		||||
     * @return Returns number of clock ticks
 | 
			
		||||
     */
 | 
			
		||||
    virtual u64 GetTicks() = 0;
 | 
			
		||||
 | 
			
		||||
    /// Getter for num_instructions_
 | 
			
		||||
    u64 num_instructions() { return num_instructions_; }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    
 | 
			
		||||
    /// Execture next instruction
 | 
			
		||||
    virtual void ExecuteInstruction() = 0;
 | 
			
		||||
 | 
			
		||||
    u64 num_instructions_;  ///< Number of instructions executed
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(ARM_Interface);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										1003
									
								
								src/core/arm/disassembler/arm_disasm.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1003
									
								
								src/core/arm/disassembler/arm_disasm.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										146
									
								
								src/core/arm/disassembler/arm_disasm.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								src/core/arm/disassembler/arm_disasm.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,146 @@
 | 
			
		||||
// Copyright 2006 The Android Open Source Project
 | 
			
		||||
 | 
			
		||||
#ifndef ARMDIS_H
 | 
			
		||||
#define ARMDIS_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
// Note: this list of opcodes must match the list used to initialize
 | 
			
		||||
// the opflags[] array in opcode.cpp.
 | 
			
		||||
enum Opcode {
 | 
			
		||||
    OP_INVALID,
 | 
			
		||||
    OP_UNDEFINED,
 | 
			
		||||
    OP_ADC,
 | 
			
		||||
    OP_ADD,
 | 
			
		||||
    OP_AND,
 | 
			
		||||
    OP_B,
 | 
			
		||||
    OP_BL,
 | 
			
		||||
    OP_BIC,
 | 
			
		||||
    OP_BKPT,
 | 
			
		||||
    OP_BLX,
 | 
			
		||||
    OP_BX,
 | 
			
		||||
    OP_CDP,
 | 
			
		||||
    OP_CLZ,
 | 
			
		||||
    OP_CMN,
 | 
			
		||||
    OP_CMP,
 | 
			
		||||
    OP_EOR,
 | 
			
		||||
    OP_LDC,
 | 
			
		||||
    OP_LDM,
 | 
			
		||||
    OP_LDR,
 | 
			
		||||
    OP_LDRB,
 | 
			
		||||
    OP_LDRBT,
 | 
			
		||||
    OP_LDRH,
 | 
			
		||||
    OP_LDRSB,
 | 
			
		||||
    OP_LDRSH,
 | 
			
		||||
    OP_LDRT,
 | 
			
		||||
    OP_MCR,
 | 
			
		||||
    OP_MLA,
 | 
			
		||||
    OP_MOV,
 | 
			
		||||
    OP_MRC,
 | 
			
		||||
    OP_MRS,
 | 
			
		||||
    OP_MSR,
 | 
			
		||||
    OP_MUL,
 | 
			
		||||
    OP_MVN,
 | 
			
		||||
    OP_ORR,
 | 
			
		||||
    OP_PLD,
 | 
			
		||||
    OP_RSB,
 | 
			
		||||
    OP_RSC,
 | 
			
		||||
    OP_SBC,
 | 
			
		||||
    OP_SMLAL,
 | 
			
		||||
    OP_SMULL,
 | 
			
		||||
    OP_STC,
 | 
			
		||||
    OP_STM,
 | 
			
		||||
    OP_STR,
 | 
			
		||||
    OP_STRB,
 | 
			
		||||
    OP_STRBT,
 | 
			
		||||
    OP_STRH,
 | 
			
		||||
    OP_STRT,
 | 
			
		||||
    OP_SUB,
 | 
			
		||||
    OP_SWI,
 | 
			
		||||
    OP_SWP,
 | 
			
		||||
    OP_SWPB,
 | 
			
		||||
    OP_TEQ,
 | 
			
		||||
    OP_TST,
 | 
			
		||||
    OP_UMLAL,
 | 
			
		||||
    OP_UMULL,
 | 
			
		||||
 | 
			
		||||
    // Define thumb opcodes
 | 
			
		||||
    OP_THUMB_UNDEFINED,
 | 
			
		||||
    OP_THUMB_ADC,
 | 
			
		||||
    OP_THUMB_ADD,
 | 
			
		||||
    OP_THUMB_AND,
 | 
			
		||||
    OP_THUMB_ASR,
 | 
			
		||||
    OP_THUMB_B,
 | 
			
		||||
    OP_THUMB_BIC,
 | 
			
		||||
    OP_THUMB_BKPT,
 | 
			
		||||
    OP_THUMB_BL,
 | 
			
		||||
    OP_THUMB_BLX,
 | 
			
		||||
    OP_THUMB_BX,
 | 
			
		||||
    OP_THUMB_CMN,
 | 
			
		||||
    OP_THUMB_CMP,
 | 
			
		||||
    OP_THUMB_EOR,
 | 
			
		||||
    OP_THUMB_LDMIA,
 | 
			
		||||
    OP_THUMB_LDR,
 | 
			
		||||
    OP_THUMB_LDRB,
 | 
			
		||||
    OP_THUMB_LDRH,
 | 
			
		||||
    OP_THUMB_LDRSB,
 | 
			
		||||
    OP_THUMB_LDRSH,
 | 
			
		||||
    OP_THUMB_LSL,
 | 
			
		||||
    OP_THUMB_LSR,
 | 
			
		||||
    OP_THUMB_MOV,
 | 
			
		||||
    OP_THUMB_MUL,
 | 
			
		||||
    OP_THUMB_MVN,
 | 
			
		||||
    OP_THUMB_NEG,
 | 
			
		||||
    OP_THUMB_ORR,
 | 
			
		||||
    OP_THUMB_POP,
 | 
			
		||||
    OP_THUMB_PUSH,
 | 
			
		||||
    OP_THUMB_ROR,
 | 
			
		||||
    OP_THUMB_SBC,
 | 
			
		||||
    OP_THUMB_STMIA,
 | 
			
		||||
    OP_THUMB_STR,
 | 
			
		||||
    OP_THUMB_STRB,
 | 
			
		||||
    OP_THUMB_STRH,
 | 
			
		||||
    OP_THUMB_SUB,
 | 
			
		||||
    OP_THUMB_SWI,
 | 
			
		||||
    OP_THUMB_TST,
 | 
			
		||||
 | 
			
		||||
    OP_END                // must be last
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class ARM_Disasm {
 | 
			
		||||
 public:
 | 
			
		||||
  static char *disasm(uint32_t addr, uint32_t insn, char *buffer);
 | 
			
		||||
  static Opcode decode(uint32_t insn);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  static Opcode decode00(uint32_t insn);
 | 
			
		||||
  static Opcode decode01(uint32_t insn);
 | 
			
		||||
  static Opcode decode10(uint32_t insn);
 | 
			
		||||
  static Opcode decode11(uint32_t insn);
 | 
			
		||||
  static Opcode decode_mul(uint32_t insn);
 | 
			
		||||
  static Opcode decode_ldrh(uint32_t insn);
 | 
			
		||||
  static Opcode decode_alu(uint32_t insn);
 | 
			
		||||
 | 
			
		||||
  static char *disasm_alu(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_branch(uint32_t addr, Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_bx(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_bkpt(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_clz(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_memblock(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_mem(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_memhalf(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_mcr(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_mla(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_umlal(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_mul(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_mrs(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_msr(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_pld(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_swi(uint32_t insn, char *ptr);
 | 
			
		||||
  static char *disasm_swp(Opcode opcode, uint32_t insn, char *ptr);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
extern char *disasm_insn_thumb(uint32_t pc, uint32_t insn1, uint32_t insn2, char *result);
 | 
			
		||||
extern Opcode decode_insn_thumb(uint32_t given);
 | 
			
		||||
 | 
			
		||||
#endif /* ARMDIS_H */
 | 
			
		||||
							
								
								
									
										86
									
								
								src/core/arm/interpreter/arm_interpreter.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								src/core/arm/interpreter/arm_interpreter.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Copyright (C) 2013 Citrus Emulator
 | 
			
		||||
 *
 | 
			
		||||
 * @file    arm_interpreter.h
 | 
			
		||||
 * @author  bunnei
 | 
			
		||||
 * @date    2014-04-04
 | 
			
		||||
 * @brief   ARM interface instance for SkyEye interprerer
 | 
			
		||||
 *
 | 
			
		||||
 * @section LICENSE
 | 
			
		||||
 * 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 at
 | 
			
		||||
 * http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
 *
 | 
			
		||||
 * Official project repository can be found at:
 | 
			
		||||
 * http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include "arm_interpreter.h"
 | 
			
		||||
 | 
			
		||||
const static cpu_config_t s_arm11_cpu_info = {
 | 
			
		||||
    "armv6", "arm11", 0x0007b000, 0x0007f000, NONCACHE
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
ARM_Interpreter::ARM_Interpreter()  {
 | 
			
		||||
 | 
			
		||||
    state = new ARMul_State;
 | 
			
		||||
 | 
			
		||||
    ARMul_EmulateInit();
 | 
			
		||||
    ARMul_NewState(state);
 | 
			
		||||
 | 
			
		||||
    state->abort_model = 0;
 | 
			
		||||
    state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
 | 
			
		||||
    state->bigendSig = LOW;
 | 
			
		||||
 | 
			
		||||
    ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
 | 
			
		||||
    state->lateabtSig = LOW;
 | 
			
		||||
    mmu_init(state);
 | 
			
		||||
 | 
			
		||||
    // Reset the core to initial state
 | 
			
		||||
    ARMul_Reset(state);
 | 
			
		||||
    state->NextInstr = 0;
 | 
			
		||||
    state->Emulate = 3;
 | 
			
		||||
 | 
			
		||||
    state->pc = state->Reg[15] = 0x00000000;
 | 
			
		||||
    state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ARM_Interpreter::SetPC(u32 pc) {
 | 
			
		||||
    state->pc = state->Reg[15] = pc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 ARM_Interpreter::PC() {
 | 
			
		||||
    return state->pc;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 ARM_Interpreter::Reg(int index){
 | 
			
		||||
    return state->Reg[index];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32 ARM_Interpreter::CPSR() {
 | 
			
		||||
    return state->Cpsr;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ARM_Interpreter::~ARM_Interpreter() {
 | 
			
		||||
    delete state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ARM_Interpreter::ExecuteInstruction() {
 | 
			
		||||
    state->step++;
 | 
			
		||||
    state->cycle++;
 | 
			
		||||
    state->EndCondition = 0;
 | 
			
		||||
    state->stop_simulator = 0;
 | 
			
		||||
    state->NextInstr = RESUME;
 | 
			
		||||
    state->last_pc = state->Reg[15];
 | 
			
		||||
    state->Reg[15] = ARMul_DoInstr(state);
 | 
			
		||||
    state->Cpsr = ((state->Cpsr & 0x0fffffdf) | (state->NFlag << 31) | (state->ZFlag << 30) | 
 | 
			
		||||
                   (state->CFlag << 29) | (state->VFlag << 28) | (state->TFlag << 5));
 | 
			
		||||
    FLUSHPIPE;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										57
									
								
								src/core/arm/interpreter/arm_interpreter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/core/arm/interpreter/arm_interpreter.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
			
		||||
/**
 | 
			
		||||
* Copyright (C) 2013 Citrus Emulator
 | 
			
		||||
*
 | 
			
		||||
* @file    arm_interpreter.h
 | 
			
		||||
* @author  bunnei
 | 
			
		||||
* @date    2014-04-04
 | 
			
		||||
* @brief   ARM interface instance for SkyEye interprerer
 | 
			
		||||
*
 | 
			
		||||
* @section LICENSE
 | 
			
		||||
* 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 at
 | 
			
		||||
* http://www.gnu.org/copyleft/gpl.html
 | 
			
		||||
*
 | 
			
		||||
* Official project repository can be found at:
 | 
			
		||||
* http://code.google.com/p/gekko-gc-emu/
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "common_types.h"
 | 
			
		||||
#include "arm/arm_interface.h"
 | 
			
		||||
 | 
			
		||||
#include "arm/interpreter/armdefs.h"
 | 
			
		||||
#include "arm/interpreter/armemu.h"
 | 
			
		||||
 | 
			
		||||
class ARM_Interpreter : virtual public ARM_Interface {
 | 
			
		||||
public:
 | 
			
		||||
    ARM_Interpreter();
 | 
			
		||||
    ~ARM_Interpreter();
 | 
			
		||||
 | 
			
		||||
    void ExecuteInstruction();
 | 
			
		||||
 | 
			
		||||
    void SetPC(u32 pc);
 | 
			
		||||
 | 
			
		||||
    u32 PC();
 | 
			
		||||
 | 
			
		||||
    u32 Reg(int index);
 | 
			
		||||
 | 
			
		||||
    u32 CPSR();
 | 
			
		||||
 | 
			
		||||
    u64 GetTicks() {
 | 
			
		||||
        return ARMul_Time(state);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    ARMul_State* state;
 | 
			
		||||
 | 
			
		||||
    DISALLOW_COPY_AND_ASSIGN(ARM_Interpreter);
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										103
									
								
								src/core/arm/interpreter/arm_regformat.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								src/core/arm/interpreter/arm_regformat.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
			
		||||
#ifndef __ARM_REGFORMAT_H__
 | 
			
		||||
#define __ARM_REGFORMAT_H__
 | 
			
		||||
 | 
			
		||||
enum arm_regno{
 | 
			
		||||
    R0 = 0,
 | 
			
		||||
    R1,
 | 
			
		||||
    R2,
 | 
			
		||||
    R3,
 | 
			
		||||
    R4,
 | 
			
		||||
    R5,
 | 
			
		||||
    R6,
 | 
			
		||||
    R7,
 | 
			
		||||
    R8,
 | 
			
		||||
    R9,
 | 
			
		||||
    R10,
 | 
			
		||||
    R11,
 | 
			
		||||
    R12,
 | 
			
		||||
    R13,
 | 
			
		||||
    LR,
 | 
			
		||||
    R15, //PC,
 | 
			
		||||
    CPSR_REG,
 | 
			
		||||
    SPSR_REG,
 | 
			
		||||
#if 1
 | 
			
		||||
    PHYS_PC,
 | 
			
		||||
    R13_USR,
 | 
			
		||||
    R14_USR,
 | 
			
		||||
    R13_SVC,
 | 
			
		||||
    R14_SVC,
 | 
			
		||||
    R13_ABORT,
 | 
			
		||||
    R14_ABORT,
 | 
			
		||||
    R13_UNDEF,
 | 
			
		||||
    R14_UNDEF,
 | 
			
		||||
    R13_IRQ,
 | 
			
		||||
    R14_IRQ,
 | 
			
		||||
    R8_FIRQ,
 | 
			
		||||
    R9_FIRQ,
 | 
			
		||||
    R10_FIRQ,
 | 
			
		||||
    R11_FIRQ,
 | 
			
		||||
    R12_FIRQ,
 | 
			
		||||
    R13_FIRQ,
 | 
			
		||||
    R14_FIRQ,
 | 
			
		||||
    SPSR_INVALID1,
 | 
			
		||||
    SPSR_INVALID2,
 | 
			
		||||
    SPSR_SVC,
 | 
			
		||||
    SPSR_ABORT,
 | 
			
		||||
    SPSR_UNDEF,
 | 
			
		||||
    SPSR_IRQ,
 | 
			
		||||
    SPSR_FIRQ,
 | 
			
		||||
    MODE_REG, /* That is the cpsr[4 : 0], just for calculation easily */
 | 
			
		||||
    BANK_REG,
 | 
			
		||||
    EXCLUSIVE_TAG,
 | 
			
		||||
    EXCLUSIVE_STATE,
 | 
			
		||||
    EXCLUSIVE_RESULT,
 | 
			
		||||
    CP15_BASE,
 | 
			
		||||
    CP15_C0 = CP15_BASE,
 | 
			
		||||
    CP15_C0_C0 = CP15_C0,
 | 
			
		||||
    CP15_MAIN_ID = CP15_C0_C0,
 | 
			
		||||
    CP15_CACHE_TYPE,
 | 
			
		||||
    CP15_TCM_STATUS,
 | 
			
		||||
    CP15_TLB_TYPE,
 | 
			
		||||
    CP15_C0_C1,
 | 
			
		||||
    CP15_PROCESSOR_FEATURE_0 = CP15_C0_C1,
 | 
			
		||||
    CP15_PROCESSOR_FEATURE_1,
 | 
			
		||||
    CP15_DEBUG_FEATURE_0,
 | 
			
		||||
    CP15_AUXILIARY_FEATURE_0,
 | 
			
		||||
    CP15_C1_C0,
 | 
			
		||||
    CP15_CONTROL = CP15_C1_C0,
 | 
			
		||||
    CP15_AUXILIARY_CONTROL,
 | 
			
		||||
    CP15_COPROCESSOR_ACCESS_CONTROL,
 | 
			
		||||
    CP15_C2,
 | 
			
		||||
    CP15_C2_C0 = CP15_C2,
 | 
			
		||||
    CP15_TRANSLATION_BASE = CP15_C2_C0,
 | 
			
		||||
    CP15_TRANSLATION_BASE_TABLE_0 = CP15_TRANSLATION_BASE,
 | 
			
		||||
    CP15_TRANSLATION_BASE_TABLE_1,
 | 
			
		||||
    CP15_TRANSLATION_BASE_CONTROL,
 | 
			
		||||
    CP15_DOMAIN_ACCESS_CONTROL,
 | 
			
		||||
    CP15_RESERVED,
 | 
			
		||||
    /* Fault status */
 | 
			
		||||
    CP15_FAULT_STATUS,
 | 
			
		||||
    CP15_INSTR_FAULT_STATUS,
 | 
			
		||||
    CP15_COMBINED_DATA_FSR = CP15_FAULT_STATUS,
 | 
			
		||||
    CP15_INST_FSR,
 | 
			
		||||
    /* Fault Address register */
 | 
			
		||||
    CP15_FAULT_ADDRESS,
 | 
			
		||||
    CP15_COMBINED_DATA_FAR = CP15_FAULT_ADDRESS,
 | 
			
		||||
    CP15_WFAR,
 | 
			
		||||
    CP15_IFAR,
 | 
			
		||||
    CP15_PID,
 | 
			
		||||
    CP15_CONTEXT_ID,
 | 
			
		||||
    CP15_THREAD_URO,
 | 
			
		||||
    CP15_TLB_FAULT_ADDR, /* defined by SkyEye */
 | 
			
		||||
    CP15_TLB_FAULT_STATUS, /* defined by SkyEye */
 | 
			
		||||
    /* VFP registers */
 | 
			
		||||
    VFP_BASE,
 | 
			
		||||
    VFP_FPSID = VFP_BASE,
 | 
			
		||||
    VFP_FPSCR,
 | 
			
		||||
    VFP_FPEXC,
 | 
			
		||||
#endif    
 | 
			
		||||
    MAX_REG_NUM,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define VFP_OFFSET(x) (x - VFP_BASE)
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										83
									
								
								src/core/arm/interpreter/armcpu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								src/core/arm/interpreter/armcpu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,83 @@
 | 
			
		||||
/*
 | 
			
		||||
 *    arm
 | 
			
		||||
 *    armcpu.h
 | 
			
		||||
 *
 | 
			
		||||
 *    Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net)
 | 
			
		||||
 *
 | 
			
		||||
 *    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 *    it under the terms of the GNU General Public License version 2 as
 | 
			
		||||
 *    published by the Free Software Foundation.
 | 
			
		||||
 *
 | 
			
		||||
 *    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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef __ARM_CPU_H__
 | 
			
		||||
#define __ARM_CPU_H__
 | 
			
		||||
//#include <skyeye_thread.h>
 | 
			
		||||
//#include <skyeye_obj.h>
 | 
			
		||||
//#include <skyeye_mach.h>
 | 
			
		||||
//#include <skyeye_exec.h>
 | 
			
		||||
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "thread.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct ARM_CPU_State_s {
 | 
			
		||||
    ARMul_State * core;
 | 
			
		||||
    uint32_t core_num;
 | 
			
		||||
    /* The core id that boot from
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t boot_core_id;
 | 
			
		||||
}ARM_CPU_State;
 | 
			
		||||
 | 
			
		||||
//static ARM_CPU_State* get_current_cpu(){
 | 
			
		||||
//    machine_config_t* mach = get_current_mach();
 | 
			
		||||
//    /* Casting a conf_obj_t to ARM_CPU_State type */
 | 
			
		||||
//    ARM_CPU_State* cpu = (ARM_CPU_State*)mach->cpu_data->obj;
 | 
			
		||||
//
 | 
			
		||||
//    return cpu;
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
* @brief Get the core instance boot from
 | 
			
		||||
*
 | 
			
		||||
* @return
 | 
			
		||||
*/
 | 
			
		||||
//static ARMul_State* get_boot_core(){
 | 
			
		||||
//    ARM_CPU_State* cpu = get_current_cpu();
 | 
			
		||||
//    return &cpu->core[cpu->boot_core_id];
 | 
			
		||||
//}
 | 
			
		||||
/**
 | 
			
		||||
* @brief Get the instance of running core
 | 
			
		||||
*
 | 
			
		||||
* @return the core instance
 | 
			
		||||
*/
 | 
			
		||||
//static ARMul_State* get_current_core(){
 | 
			
		||||
//    /* Casting a conf_obj_t to ARM_CPU_State type */
 | 
			
		||||
//    int id = Common::CurrentThreadId();
 | 
			
		||||
//    /* If thread is not in running mode, we should give the boot core */
 | 
			
		||||
//    if(get_thread_state(id) != Running_state){
 | 
			
		||||
//        return get_boot_core();
 | 
			
		||||
//    }
 | 
			
		||||
//    /* Judge if we are running in paralell or sequenial */
 | 
			
		||||
//    if(thread_exist(id)){
 | 
			
		||||
//        conf_object_t* conf_obj = get_current_exec_priv(id);
 | 
			
		||||
//        return (ARMul_State*)get_cast_conf_obj(conf_obj, "arm_core_t");
 | 
			
		||||
//    }
 | 
			
		||||
//
 | 
			
		||||
//    return NULL;
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
#define CURRENT_CORE get_current_core()
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										934
									
								
								src/core/arm/interpreter/armdefs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										934
									
								
								src/core/arm/interpreter/armdefs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,934 @@
 | 
			
		||||
/*  armdefs.h -- ARMulator common definitions:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
#ifndef _ARMDEFS_H_
 | 
			
		||||
#define _ARMDEFS_H_
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_WINDOWS
 | 
			
		||||
#include <windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//teawater add for arm2x86 2005.02.14-------------------------------------------
 | 
			
		||||
// koodailar remove it for mingw 2005.12.18----------------
 | 
			
		||||
//anthonylee modify it for portable 2007.01.30
 | 
			
		||||
//#include "portable/mman.h"
 | 
			
		||||
 | 
			
		||||
#include "arm_regformat.h"
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#include "skyeye_defs.h"
 | 
			
		||||
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//teawater add for arm2x86 2005.07.03-------------------------------------------
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_LINUX
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
 | 
			
		||||
//#include <memory_space.h>
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
#if 0
 | 
			
		||||
#if 0
 | 
			
		||||
#define DIFF_STATE 1
 | 
			
		||||
#define __FOLLOW_MODE__ 0
 | 
			
		||||
#else
 | 
			
		||||
#define DIFF_STATE 0
 | 
			
		||||
#define __FOLLOW_MODE__ 1
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifndef FALSE
 | 
			
		||||
#define FALSE 0
 | 
			
		||||
#define TRUE 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LOW 0
 | 
			
		||||
#define HIGH 1
 | 
			
		||||
#define LOWHIGH 1
 | 
			
		||||
#define HIGHLOW 2
 | 
			
		||||
 | 
			
		||||
#ifndef u8
 | 
			
		||||
#define u8      unsigned char
 | 
			
		||||
#define u16     unsigned short
 | 
			
		||||
#define u32     unsigned int
 | 
			
		||||
#define u64     unsigned long long
 | 
			
		||||
#endif /*u8 */
 | 
			
		||||
 | 
			
		||||
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_LINUX
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//#define DBCT_TEST_SPEED
 | 
			
		||||
#define DBCT_TEST_SPEED_SEC    10
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
 | 
			
		||||
//#define DBCT_GDBRSP
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//#include <skyeye_defs.h>
 | 
			
		||||
//#include <skyeye_types.h>
 | 
			
		||||
 | 
			
		||||
#define ARM_BYTE_TYPE         0
 | 
			
		||||
#define ARM_HALFWORD_TYPE     1
 | 
			
		||||
#define ARM_WORD_TYPE         2
 | 
			
		||||
 | 
			
		||||
//the define of cachetype
 | 
			
		||||
#define NONCACHE  0
 | 
			
		||||
#define DATACACHE  1
 | 
			
		||||
#define INSTCACHE  2
 | 
			
		||||
 | 
			
		||||
#ifndef __STDC__
 | 
			
		||||
typedef char *VoidStar;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
typedef unsigned long long ARMdword;    /* must be 64 bits wide */
 | 
			
		||||
typedef unsigned int ARMword;    /* must be 32 bits wide */
 | 
			
		||||
typedef unsigned char ARMbyte;    /* must be 8 bits wide */
 | 
			
		||||
typedef unsigned short ARMhword;    /* must be 16 bits wide */
 | 
			
		||||
typedef struct ARMul_State ARMul_State;
 | 
			
		||||
typedef struct ARMul_io ARMul_io;
 | 
			
		||||
typedef struct ARMul_Energy ARMul_Energy;
 | 
			
		||||
 | 
			
		||||
//teawater add for arm2x86 2005.06.24-------------------------------------------
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
//chy 2005-05-11
 | 
			
		||||
#ifndef __CYGWIN__
 | 
			
		||||
//teawater add for arm2x86 2005.02.14-------------------------------------------
 | 
			
		||||
typedef unsigned char           uint8_t;
 | 
			
		||||
typedef unsigned short          uint16_t;
 | 
			
		||||
typedef unsigned int            u32;
 | 
			
		||||
#if defined (__x86_64__)
 | 
			
		||||
typedef unsigned long           uint64_t;
 | 
			
		||||
#else
 | 
			
		||||
typedef unsigned long long      uint64_t;
 | 
			
		||||
#endif
 | 
			
		||||
////AJ2D--------------------------------------------------------------------------
 | 
			
		||||
#endif
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include "armmmu.h"
 | 
			
		||||
//#include "lcd/skyeye_lcd.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//#include "skyeye.h"
 | 
			
		||||
//#include "skyeye_device.h"
 | 
			
		||||
//#include "net/skyeye_net.h"
 | 
			
		||||
//#include "skyeye_config.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef unsigned ARMul_CPInits (ARMul_State * state);
 | 
			
		||||
typedef unsigned ARMul_CPExits (ARMul_State * state);
 | 
			
		||||
typedef unsigned ARMul_LDCs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword value);
 | 
			
		||||
typedef unsigned ARMul_STCs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword * value);
 | 
			
		||||
typedef unsigned ARMul_MRCs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword * value);
 | 
			
		||||
typedef unsigned ARMul_MCRs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword value);
 | 
			
		||||
typedef unsigned ARMul_MRRCs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword * value1, ARMword * value2);
 | 
			
		||||
typedef unsigned ARMul_MCRRs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr, ARMword value1, ARMword value2);
 | 
			
		||||
typedef unsigned ARMul_CDPs (ARMul_State * state, unsigned type,
 | 
			
		||||
                 ARMword instr);
 | 
			
		||||
typedef unsigned ARMul_CPReads (ARMul_State * state, unsigned reg,
 | 
			
		||||
                ARMword * value);
 | 
			
		||||
typedef unsigned ARMul_CPWrites (ARMul_State * state, unsigned reg,
 | 
			
		||||
                 ARMword value);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//added by ksh,2004-3-5
 | 
			
		||||
struct ARMul_io
 | 
			
		||||
{
 | 
			
		||||
    ARMword *instr;        //to display the current interrupt state
 | 
			
		||||
    ARMword *net_flag;    //to judge if network is enabled
 | 
			
		||||
    ARMword *net_int;    //netcard interrupt
 | 
			
		||||
 | 
			
		||||
    //ywc,2004-04-01
 | 
			
		||||
    ARMword *ts_int;
 | 
			
		||||
    ARMword *ts_is_enable;
 | 
			
		||||
    ARMword *ts_addr_begin;
 | 
			
		||||
    ARMword *ts_addr_end;
 | 
			
		||||
    ARMword *ts_buffer;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* added by ksh,2004-11-26,some energy profiling */
 | 
			
		||||
struct ARMul_Energy
 | 
			
		||||
{
 | 
			
		||||
    int energy_prof;    /* <tktan>  BUG200103282109 : for energy profiling */
 | 
			
		||||
    int enable_func_energy;    /* <tktan> BUG200105181702 */
 | 
			
		||||
    char *func_energy;
 | 
			
		||||
    int func_display;    /* <tktan> BUG200103311509 : for function call display */
 | 
			
		||||
    int func_disp_start;    /* <tktan> BUG200104191428 : to start func profiling */
 | 
			
		||||
    char *start_func;    /* <tktan> BUG200104191428 */
 | 
			
		||||
 | 
			
		||||
    FILE *outfile;        /* <tktan> BUG200105201531 : direct console to file */
 | 
			
		||||
    long long tcycle, pcycle;
 | 
			
		||||
    float t_energy;
 | 
			
		||||
    void *cur_task;        /* <tktan> BUG200103291737 */
 | 
			
		||||
    long long t_mem_cycle, t_idle_cycle, t_uart_cycle;
 | 
			
		||||
    long long p_mem_cycle, p_idle_cycle, p_uart_cycle;
 | 
			
		||||
    long long p_io_update_tcycle;
 | 
			
		||||
    /*record CCCR,to get current core frequency */
 | 
			
		||||
    ARMword cccr;
 | 
			
		||||
};
 | 
			
		||||
#if 0
 | 
			
		||||
#define MAX_BANK 8
 | 
			
		||||
#define MAX_STR  1024
 | 
			
		||||
 | 
			
		||||
typedef struct mem_bank
 | 
			
		||||
{
 | 
			
		||||
    ARMword (*read_byte) (ARMul_State * state, ARMword addr);
 | 
			
		||||
    void (*write_byte) (ARMul_State * state, ARMword addr, ARMword data);
 | 
			
		||||
      ARMword (*read_halfword) (ARMul_State * state, ARMword addr);
 | 
			
		||||
    void (*write_halfword) (ARMul_State * state, ARMword addr,
 | 
			
		||||
                ARMword data);
 | 
			
		||||
      ARMword (*read_word) (ARMul_State * state, ARMword addr);
 | 
			
		||||
    void (*write_word) (ARMul_State * state, ARMword addr, ARMword data);
 | 
			
		||||
    unsigned int addr, len;
 | 
			
		||||
    char filename[MAX_STR];
 | 
			
		||||
    unsigned type;        //chy 2003-09-21: maybe io,ram,rom
 | 
			
		||||
} mem_bank_t;
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
    int bank_num;
 | 
			
		||||
    int current_num;    /*current num of bank */
 | 
			
		||||
    mem_bank_t mem_banks[MAX_BANK];
 | 
			
		||||
} mem_config_t;
 | 
			
		||||
#endif
 | 
			
		||||
#define VFP_REG_NUM 64
 | 
			
		||||
struct ARMul_State
 | 
			
		||||
{
 | 
			
		||||
    ARMword Emulate;    /* to start and stop emulation */
 | 
			
		||||
    unsigned EndCondition;    /* reason for stopping */
 | 
			
		||||
    unsigned ErrorCode;    /* type of illegal instruction */
 | 
			
		||||
 | 
			
		||||
    /* Order of the following register should not be modified */
 | 
			
		||||
    ARMword Reg[16];    /* the current register file */
 | 
			
		||||
    ARMword Cpsr;        /* the current psr */
 | 
			
		||||
    ARMword Spsr_copy;
 | 
			
		||||
    ARMword phys_pc;
 | 
			
		||||
    ARMword Reg_usr[2];
 | 
			
		||||
    ARMword Reg_svc[2]; /* R13_SVC R14_SVC */
 | 
			
		||||
    ARMword Reg_abort[2]; /* R13_ABORT R14_ABORT */
 | 
			
		||||
    ARMword Reg_undef[2]; /* R13 UNDEF R14 UNDEF */
 | 
			
		||||
    ARMword Reg_irq[2];   /* R13_IRQ R14_IRQ */
 | 
			
		||||
    ARMword Reg_firq[7];  /* R8---R14 FIRQ */
 | 
			
		||||
    ARMword Spsr[7];    /* the exception psr's */
 | 
			
		||||
    ARMword Mode;        /* the current mode */
 | 
			
		||||
    ARMword Bank;        /* the current register bank */
 | 
			
		||||
    ARMword exclusive_tag;
 | 
			
		||||
    ARMword exclusive_state;
 | 
			
		||||
    ARMword exclusive_result;
 | 
			
		||||
    ARMword CP15[VFP_BASE - CP15_BASE];
 | 
			
		||||
    ARMword VFP[3]; /* FPSID, FPSCR, and FPEXC */
 | 
			
		||||
    /* VFPv2 and VFPv3-D16 has 16 doubleword registers (D0-D16 or S0-S31).
 | 
			
		||||
       VFPv3-D32/ASIMD may have up to 32 doubleword registers (D0-D31),
 | 
			
		||||
        and only 32 singleword registers are accessible (S0-S31). */
 | 
			
		||||
    ARMword ExtReg[VFP_REG_NUM];
 | 
			
		||||
    /* ---- End of the ordered registers ---- */
 | 
			
		||||
    
 | 
			
		||||
    ARMword RegBank[7][16];    /* all the registers */
 | 
			
		||||
    //chy:2003-08-19, used in arm xscale
 | 
			
		||||
    /* 40 bit accumulator.  We always keep this 64 bits wide,
 | 
			
		||||
       and move only 40 bits out of it in an MRA insn.  */
 | 
			
		||||
    ARMdword Accumulator;
 | 
			
		||||
 | 
			
		||||
    ARMword NFlag, ZFlag, CFlag, VFlag, IFFlags;    /* dummy flags for speed */
 | 
			
		||||
        unsigned long long int icounter, debug_icounter, kernel_icounter;
 | 
			
		||||
        unsigned int shifter_carry_out;
 | 
			
		||||
        //ARMword translate_pc;
 | 
			
		||||
 | 
			
		||||
    /* add armv6 flags dyf:2010-08-09 */
 | 
			
		||||
    ARMword GEFlag, EFlag, AFlag, QFlags;
 | 
			
		||||
    //chy:2003-08-19, used in arm v5e|xscale
 | 
			
		||||
    ARMword SFlag;
 | 
			
		||||
#ifdef MODET
 | 
			
		||||
    ARMword TFlag;        /* Thumb state */
 | 
			
		||||
#endif
 | 
			
		||||
    ARMword instr, pc, temp;    /* saved register state */
 | 
			
		||||
    ARMword loaded, decoded;    /* saved pipeline state */
 | 
			
		||||
    //chy 2006-04-12 for ICE breakpoint
 | 
			
		||||
    ARMword loaded_addr, decoded_addr;    /* saved pipeline state addr*/
 | 
			
		||||
    unsigned int NumScycles, NumNcycles, NumIcycles, NumCcycles, NumFcycles;    /* emulated cycles used */
 | 
			
		||||
    unsigned long long NumInstrs;    /* the number of instructions executed */
 | 
			
		||||
    unsigned NextInstr;
 | 
			
		||||
    unsigned VectorCatch;    /* caught exception mask */
 | 
			
		||||
    unsigned CallDebug;    /* set to call the debugger */
 | 
			
		||||
    unsigned CanWatch;    /* set by memory interface if its willing to suffer the
 | 
			
		||||
                   overhead of checking for watchpoints on each memory
 | 
			
		||||
                   access */
 | 
			
		||||
    unsigned int StopHandle;
 | 
			
		||||
 | 
			
		||||
    char *CommandLine;    /* Command Line from ARMsd */
 | 
			
		||||
 | 
			
		||||
    ARMul_CPInits *CPInit[16];    /* coprocessor initialisers */
 | 
			
		||||
    ARMul_CPExits *CPExit[16];    /* coprocessor finalisers */
 | 
			
		||||
    ARMul_LDCs *LDC[16];    /* LDC instruction */
 | 
			
		||||
    ARMul_STCs *STC[16];    /* STC instruction */
 | 
			
		||||
    ARMul_MRCs *MRC[16];    /* MRC instruction */
 | 
			
		||||
    ARMul_MCRs *MCR[16];    /* MCR instruction */
 | 
			
		||||
    ARMul_MRRCs *MRRC[16];    /* MRRC instruction */
 | 
			
		||||
    ARMul_MCRRs *MCRR[16];    /* MCRR instruction */
 | 
			
		||||
    ARMul_CDPs *CDP[16];    /* CDP instruction */
 | 
			
		||||
    ARMul_CPReads *CPRead[16];    /* Read CP register */
 | 
			
		||||
    ARMul_CPWrites *CPWrite[16];    /* Write CP register */
 | 
			
		||||
    unsigned char *CPData[16];    /* Coprocessor data */
 | 
			
		||||
    unsigned char const *CPRegWords[16];    /* map of coprocessor register sizes */
 | 
			
		||||
 | 
			
		||||
    unsigned EventSet;    /* the number of events in the queue */
 | 
			
		||||
    unsigned int Now;    /* time to the nearest cycle */
 | 
			
		||||
    struct EventNode **EventPtr;    /* the event list */
 | 
			
		||||
 | 
			
		||||
    unsigned Debug;        /* show instructions as they are executed */
 | 
			
		||||
    unsigned NresetSig;    /* reset the processor */
 | 
			
		||||
    unsigned NfiqSig;
 | 
			
		||||
    unsigned NirqSig;
 | 
			
		||||
 | 
			
		||||
    unsigned abortSig;
 | 
			
		||||
    unsigned NtransSig;
 | 
			
		||||
    unsigned bigendSig;
 | 
			
		||||
    unsigned prog32Sig;
 | 
			
		||||
    unsigned data32Sig;
 | 
			
		||||
    unsigned syscallSig;
 | 
			
		||||
 | 
			
		||||
/* 2004-05-09 chy
 | 
			
		||||
----------------------------------------------------------
 | 
			
		||||
read ARM Architecture Reference Manual
 | 
			
		||||
2.6.5 Data Abort
 | 
			
		||||
There are three Abort Model in ARM arch.
 | 
			
		||||
 | 
			
		||||
Early Abort Model: used in some ARMv3 and earlier implementations. In this
 | 
			
		||||
model, base register wirteback occurred for LDC,LDM,STC,STM instructions, and
 | 
			
		||||
the base register was unchanged for all other instructions. (oldest)
 | 
			
		||||
 | 
			
		||||
Base Restored Abort Model: If a Data Abort occurs in an instruction which
 | 
			
		||||
specifies base register writeback, the value in the base register is
 | 
			
		||||
unchanged. (strongarm, xscale)
 | 
			
		||||
 | 
			
		||||
Base Updated Abort Model: If a Data Abort occurs in an instruction which
 | 
			
		||||
specifies base register writeback, the base register writeback still occurs.
 | 
			
		||||
(arm720T)
 | 
			
		||||
 | 
			
		||||
read PART B
 | 
			
		||||
chap2 The System Control Coprocessor  CP15
 | 
			
		||||
2.4 Register1:control register
 | 
			
		||||
L(bit 6): in some ARMv3 and earlier implementations, the abort model of the
 | 
			
		||||
processor could be configured:
 | 
			
		||||
0=early Abort Model Selected(now obsolete)
 | 
			
		||||
1=Late Abort Model selceted(same as Base Updated Abort Model)
 | 
			
		||||
 | 
			
		||||
on later processors, this bit reads as 1 and ignores writes.
 | 
			
		||||
-------------------------------------------------------------
 | 
			
		||||
So, if lateabtSig=1, then it means Late Abort Model(Base Updated Abort Model)
 | 
			
		||||
    if lateabtSig=0, then it means Base Restored Abort Model
 | 
			
		||||
*/
 | 
			
		||||
    unsigned lateabtSig;
 | 
			
		||||
 | 
			
		||||
    ARMword Vector;        /* synthesize aborts in cycle modes */
 | 
			
		||||
    ARMword Aborted;    /* sticky flag for aborts */
 | 
			
		||||
    ARMword Reseted;    /* sticky flag for Reset */
 | 
			
		||||
    ARMword Inted, LastInted;    /* sticky flags for interrupts */
 | 
			
		||||
    ARMword Base;        /* extra hand for base writeback */
 | 
			
		||||
    ARMword AbortAddr;    /* to keep track of Prefetch aborts */
 | 
			
		||||
 | 
			
		||||
    const struct Dbg_HostosInterface *hostif;
 | 
			
		||||
 | 
			
		||||
    int verbose;        /* non-zero means print various messages like the banner */
 | 
			
		||||
 | 
			
		||||
    mmu_state_t mmu;
 | 
			
		||||
    int mmu_inited;
 | 
			
		||||
    //mem_state_t mem;
 | 
			
		||||
    /*remove io_state to skyeye_mach_*.c files */
 | 
			
		||||
    //io_state_t io;
 | 
			
		||||
    /* point to a interrupt pending register. now for skyeye-ne2k.c
 | 
			
		||||
     * later should move somewhere. e.g machine_config_t*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //chy: 2003-08-11, for different arm core type
 | 
			
		||||
    unsigned is_v4;        /* Are we emulating a v4 architecture (or higher) ?  */
 | 
			
		||||
    unsigned is_v5;        /* Are we emulating a v5 architecture ?  */
 | 
			
		||||
    unsigned is_v5e;    /* Are we emulating a v5e architecture ?  */
 | 
			
		||||
    unsigned is_v6;        /* Are we emulating a v6 architecture ?  */
 | 
			
		||||
    unsigned is_v7;        /* Are we emulating a v7 architecture ?  */
 | 
			
		||||
    unsigned is_XScale;    /* Are we emulating an XScale architecture ?  */
 | 
			
		||||
    unsigned is_iWMMXt;    /* Are we emulating an iWMMXt co-processor ?  */
 | 
			
		||||
    unsigned is_ep9312;    /* Are we emulating a Cirrus Maverick co-processor ?  */
 | 
			
		||||
    //chy 2005-09-19
 | 
			
		||||
    unsigned is_pxa27x;    /* Are we emulating a Intel PXA27x co-processor ?  */
 | 
			
		||||
    //chy: seems only used in xscale's CP14
 | 
			
		||||
    unsigned int LastTime;    /* Value of last call to ARMul_Time() */
 | 
			
		||||
    ARMword CP14R0_CCD;    /* used to count 64 clock cycles with CP14 R0 bit 3 set */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//added by ksh:for handle different machs io 2004-3-5
 | 
			
		||||
    ARMul_io mach_io;
 | 
			
		||||
 | 
			
		||||
/*added by ksh,2004-11-26,some energy profiling*/
 | 
			
		||||
    ARMul_Energy energy;
 | 
			
		||||
 | 
			
		||||
//teawater add for next_dis 2004.10.27-----------------------
 | 
			
		||||
    int disassemble;
 | 
			
		||||
//AJ2D------------------------------------------
 | 
			
		||||
 | 
			
		||||
//teawater add for arm2x86 2005.02.15-------------------------------------------
 | 
			
		||||
    u32 trap;
 | 
			
		||||
    u32 tea_break_addr;
 | 
			
		||||
    u32 tea_break_ok;
 | 
			
		||||
    int tea_pc;
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
//teawater add for arm2x86 2005.07.03-------------------------------------------
 | 
			
		||||
 | 
			
		||||
    /*
 | 
			
		||||
     * 2007-01-24 removed the term-io functions by Anthony Lee,
 | 
			
		||||
     * moved to "device/uart/skyeye_uart_stdio.c".
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
//teawater add for arm2x86 2005.07.05-------------------------------------------
 | 
			
		||||
    //arm_arm A2-18
 | 
			
		||||
    int abort_model;    //0 Base Restored Abort Model, 1 the Early Abort Model, 2 Base Updated Abort Model 
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
//teawater change for return if running tb dirty 2005.07.09---------------------
 | 
			
		||||
    void *tb_now;
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//teawater add for record reg value to ./reg.txt 2005.07.10---------------------
 | 
			
		||||
    FILE *tea_reg_fd;
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/*added by ksh in 2005-10-1*/
 | 
			
		||||
    cpu_config_t *cpu;
 | 
			
		||||
    //mem_config_t *mem_bank;
 | 
			
		||||
 | 
			
		||||
/* added LPC remap function */
 | 
			
		||||
    int vector_remap_flag;
 | 
			
		||||
    u32 vector_remap_addr;
 | 
			
		||||
    u32 vector_remap_size;
 | 
			
		||||
 | 
			
		||||
    u32 step;
 | 
			
		||||
    u32 cycle;
 | 
			
		||||
    int stop_simulator;
 | 
			
		||||
    conf_object_t *dyncom_cpu;
 | 
			
		||||
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
 | 
			
		||||
#ifdef DBCT_TEST_SPEED
 | 
			
		||||
    uint64_t    instr_count;
 | 
			
		||||
#endif    //DBCT_TEST_SPEED
 | 
			
		||||
//    FILE * state_log;
 | 
			
		||||
//diff log
 | 
			
		||||
//#if DIFF_STATE
 | 
			
		||||
    FILE * state_log;
 | 
			
		||||
//#endif
 | 
			
		||||
    /* monitored memory for exclusice access */
 | 
			
		||||
    ARMword exclusive_tag_array[128];
 | 
			
		||||
    /* 1 means exclusive access and 0 means open access */
 | 
			
		||||
    ARMword exclusive_access_state;
 | 
			
		||||
 | 
			
		||||
    memory_space_intf space;    
 | 
			
		||||
    u32 CurrInstr;
 | 
			
		||||
    u32 last_pc; /* the last pc executed */
 | 
			
		||||
    u32 last_instr; /* the last inst executed */
 | 
			
		||||
    u32 WriteAddr[17];
 | 
			
		||||
    u32 WriteData[17];
 | 
			
		||||
    u32 WritePc[17];
 | 
			
		||||
    u32 CurrWrite;
 | 
			
		||||
};
 | 
			
		||||
#define DIFF_WRITE 0
 | 
			
		||||
 | 
			
		||||
typedef ARMul_State arm_core_t;
 | 
			
		||||
#define ResetPin NresetSig
 | 
			
		||||
#define FIQPin NfiqSig
 | 
			
		||||
#define IRQPin NirqSig
 | 
			
		||||
#define AbortPin abortSig
 | 
			
		||||
#define TransPin NtransSig
 | 
			
		||||
#define BigEndPin bigendSig
 | 
			
		||||
#define Prog32Pin prog32Sig
 | 
			
		||||
#define Data32Pin data32Sig
 | 
			
		||||
#define LateAbortPin lateabtSig
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                        Types of ARM we know about                         *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* The bitflags */
 | 
			
		||||
#define ARM_Fix26_Prop   0x01
 | 
			
		||||
#define ARM_Nexec_Prop   0x02
 | 
			
		||||
#define ARM_Debug_Prop   0x10
 | 
			
		||||
#define ARM_Isync_Prop   ARM_Debug_Prop
 | 
			
		||||
#define ARM_Lock_Prop    0x20
 | 
			
		||||
//chy 2003-08-11 
 | 
			
		||||
#define ARM_v4_Prop      0x40
 | 
			
		||||
#define ARM_v5_Prop      0x80
 | 
			
		||||
/*jeff.du 2010-08-05 */
 | 
			
		||||
#define ARM_v6_Prop      0xc0
 | 
			
		||||
 | 
			
		||||
#define ARM_v5e_Prop     0x100
 | 
			
		||||
#define ARM_XScale_Prop  0x200
 | 
			
		||||
#define ARM_ep9312_Prop  0x400
 | 
			
		||||
#define ARM_iWMMXt_Prop  0x800
 | 
			
		||||
//chy 2005-09-19
 | 
			
		||||
#define ARM_PXA27X_Prop  0x1000
 | 
			
		||||
#define ARM_v7_Prop      0x2000
 | 
			
		||||
 | 
			
		||||
/* ARM2 family */
 | 
			
		||||
#define ARM2    (ARM_Fix26_Prop)
 | 
			
		||||
#define ARM2as  ARM2
 | 
			
		||||
#define ARM61   ARM2
 | 
			
		||||
#define ARM3    ARM2
 | 
			
		||||
 | 
			
		||||
#ifdef ARM60            /* previous definition in armopts.h */
 | 
			
		||||
#undef ARM60
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ARM6 family */
 | 
			
		||||
#define ARM6    (ARM_Lock_Prop)
 | 
			
		||||
#define ARM60   ARM6
 | 
			
		||||
#define ARM600  ARM6
 | 
			
		||||
#define ARM610  ARM6
 | 
			
		||||
#define ARM620  ARM6
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                   Macros to extract instruction fields                    *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define BIT(n) ( (ARMword)(instr>>(n))&1)    /* bit n of instruction */
 | 
			
		||||
#define BITS(m,n) ( (ARMword)(instr<<(31-(n))) >> ((31-(n))+(m)) )    /* bits m to n of instr */
 | 
			
		||||
#define TOPBITS(n) (instr >> (n))    /* bits 31 to n of instr */
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                      The hardware vector addresses                        *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define ARMResetV 0L
 | 
			
		||||
#define ARMUndefinedInstrV 4L
 | 
			
		||||
#define ARMSWIV 8L
 | 
			
		||||
#define ARMPrefetchAbortV 12L
 | 
			
		||||
#define ARMDataAbortV 16L
 | 
			
		||||
#define ARMAddrExceptnV 20L
 | 
			
		||||
#define ARMIRQV 24L
 | 
			
		||||
#define ARMFIQV 28L
 | 
			
		||||
#define ARMErrorV 32L        /* This is an offset, not an address ! */
 | 
			
		||||
 | 
			
		||||
#define ARMul_ResetV ARMResetV
 | 
			
		||||
#define ARMul_UndefinedInstrV ARMUndefinedInstrV
 | 
			
		||||
#define ARMul_SWIV ARMSWIV
 | 
			
		||||
#define ARMul_PrefetchAbortV ARMPrefetchAbortV
 | 
			
		||||
#define ARMul_DataAbortV ARMDataAbortV
 | 
			
		||||
#define ARMul_AddrExceptnV ARMAddrExceptnV
 | 
			
		||||
#define ARMul_IRQV ARMIRQV
 | 
			
		||||
#define ARMul_FIQV ARMFIQV
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                          Mode and Bank Constants                          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define USER26MODE 0L
 | 
			
		||||
#define FIQ26MODE 1L
 | 
			
		||||
#define IRQ26MODE 2L
 | 
			
		||||
#define SVC26MODE 3L
 | 
			
		||||
#define USER32MODE 16L
 | 
			
		||||
#define FIQ32MODE 17L
 | 
			
		||||
#define IRQ32MODE 18L
 | 
			
		||||
#define SVC32MODE 19L
 | 
			
		||||
#define ABORT32MODE 23L
 | 
			
		||||
#define UNDEF32MODE 27L
 | 
			
		||||
//chy 2006-02-15 add system32 mode
 | 
			
		||||
#define SYSTEM32MODE 31L
 | 
			
		||||
 | 
			
		||||
#define ARM32BITMODE (state->Mode > 3)
 | 
			
		||||
#define ARM26BITMODE (state->Mode <= 3)
 | 
			
		||||
#define ARMMODE (state->Mode)
 | 
			
		||||
#define ARMul_MODEBITS 0x1fL
 | 
			
		||||
#define ARMul_MODE32BIT ARM32BITMODE
 | 
			
		||||
#define ARMul_MODE26BIT ARM26BITMODE
 | 
			
		||||
 | 
			
		||||
#define USERBANK 0
 | 
			
		||||
#define FIQBANK 1
 | 
			
		||||
#define IRQBANK 2
 | 
			
		||||
#define SVCBANK 3
 | 
			
		||||
#define ABORTBANK 4
 | 
			
		||||
#define UNDEFBANK 5
 | 
			
		||||
#define DUMMYBANK 6
 | 
			
		||||
#define SYSTEMBANK USERBANK
 | 
			
		||||
#define BANK_CAN_ACCESS_SPSR(bank)  \
 | 
			
		||||
  ((bank) != USERBANK && (bank) != SYSTEMBANK && (bank) != DUMMYBANK)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                  Definitons of things in the emulator                     *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
extern void ARMul_EmulateInit (void);
 | 
			
		||||
extern void ARMul_Reset (ARMul_State * state);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
extern ARMul_State *ARMul_NewState (ARMul_State * state);
 | 
			
		||||
extern ARMword ARMul_DoProg (ARMul_State * state);
 | 
			
		||||
extern ARMword ARMul_DoInstr (ARMul_State * state);
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                Definitons of things for event handling                    *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
extern void ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
 | 
			
		||||
                 unsigned (*func) ());
 | 
			
		||||
extern void ARMul_EnvokeEvent (ARMul_State * state);
 | 
			
		||||
extern unsigned int ARMul_Time (ARMul_State * state);
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                          Useful support routines                          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_GetReg (ARMul_State * state, unsigned mode,
 | 
			
		||||
                 unsigned reg);
 | 
			
		||||
extern void ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg,
 | 
			
		||||
              ARMword value);
 | 
			
		||||
extern ARMword ARMul_GetPC (ARMul_State * state);
 | 
			
		||||
extern ARMword ARMul_GetNextPC (ARMul_State * state);
 | 
			
		||||
extern void ARMul_SetPC (ARMul_State * state, ARMword value);
 | 
			
		||||
extern ARMword ARMul_GetR15 (ARMul_State * state);
 | 
			
		||||
extern void ARMul_SetR15 (ARMul_State * state, ARMword value);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_GetCPSR (ARMul_State * state);
 | 
			
		||||
extern void ARMul_SetCPSR (ARMul_State * state, ARMword value);
 | 
			
		||||
extern ARMword ARMul_GetSPSR (ARMul_State * state, ARMword mode);
 | 
			
		||||
extern void ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value);
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                  Definitons of things to handle aborts                    *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
extern void ARMul_Abort (ARMul_State * state, ARMword address);
 | 
			
		||||
#ifdef MODET
 | 
			
		||||
#define ARMul_ABORTWORD (state->TFlag ? 0xefffdfff : 0xefffffff)    /* SWI -1 */
 | 
			
		||||
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
 | 
			
		||||
                                        state->AbortAddr = (address & (state->TFlag ? ~1L : ~3L))
 | 
			
		||||
#else
 | 
			
		||||
#define ARMul_ABORTWORD 0xefffffff    /* SWI -1 */
 | 
			
		||||
#define ARMul_PREFETCHABORT(address) if (state->AbortAddr == 1) \
 | 
			
		||||
                                        state->AbortAddr = (address & ~3L)
 | 
			
		||||
#endif
 | 
			
		||||
#define ARMul_DATAABORT(address) state->abortSig = HIGH ; \
 | 
			
		||||
                                 state->Aborted = ARMul_DataAbortV ;
 | 
			
		||||
#define ARMul_CLEARABORT state->abortSig = LOW
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*              Definitons of things in the memory interface                 *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
extern unsigned ARMul_MemoryInit (ARMul_State * state,
 | 
			
		||||
                  unsigned int initmemsize);
 | 
			
		||||
extern void ARMul_MemoryExit (ARMul_State * state);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_LoadInstrS (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword isize);
 | 
			
		||||
extern ARMword ARMul_LoadInstrN (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword isize);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
extern ARMword ARMul_ReLoadInstr (ARMul_State * state, ARMword address,
 | 
			
		||||
                  ARMword isize);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
extern ARMword ARMul_LoadWordS (ARMul_State * state, ARMword address);
 | 
			
		||||
extern ARMword ARMul_LoadWordN (ARMul_State * state, ARMword address);
 | 
			
		||||
extern ARMword ARMul_LoadHalfWord (ARMul_State * state, ARMword address);
 | 
			
		||||
extern ARMword ARMul_LoadByte (ARMul_State * state, ARMword address);
 | 
			
		||||
 | 
			
		||||
extern void ARMul_StoreWordS (ARMul_State * state, ARMword address,
 | 
			
		||||
                  ARMword data);
 | 
			
		||||
extern void ARMul_StoreWordN (ARMul_State * state, ARMword address,
 | 
			
		||||
                  ARMword data);
 | 
			
		||||
extern void ARMul_StoreHalfWord (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword data);
 | 
			
		||||
extern void ARMul_StoreByte (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword data);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_SwapWord (ARMul_State * state, ARMword address,
 | 
			
		||||
                   ARMword data);
 | 
			
		||||
extern ARMword ARMul_SwapByte (ARMul_State * state, ARMword address,
 | 
			
		||||
                   ARMword data);
 | 
			
		||||
 | 
			
		||||
extern void ARMul_Icycles (ARMul_State * state, unsigned number,
 | 
			
		||||
               ARMword address);
 | 
			
		||||
extern void ARMul_Ccycles (ARMul_State * state, unsigned number,
 | 
			
		||||
               ARMword address);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_ReadWord (ARMul_State * state, ARMword address);
 | 
			
		||||
extern ARMword ARMul_ReadByte (ARMul_State * state, ARMword address);
 | 
			
		||||
extern void ARMul_WriteWord (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword data);
 | 
			
		||||
extern void ARMul_WriteByte (ARMul_State * state, ARMword address,
 | 
			
		||||
                 ARMword data);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_MemAccess (ARMul_State * state, ARMword, ARMword,
 | 
			
		||||
                ARMword, ARMword, ARMword, ARMword, ARMword,
 | 
			
		||||
                ARMword, ARMword, ARMword);
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*            Definitons of things in the co-processor interface             *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define ARMul_FIRST 0
 | 
			
		||||
#define ARMul_TRANSFER 1
 | 
			
		||||
#define ARMul_BUSY 2
 | 
			
		||||
#define ARMul_DATA 3
 | 
			
		||||
#define ARMul_INTERRUPT 4
 | 
			
		||||
#define ARMul_DONE 0
 | 
			
		||||
#define ARMul_CANT 1
 | 
			
		||||
#define ARMul_INC 3
 | 
			
		||||
 | 
			
		||||
#define ARMul_CP13_R0_FIQ       0x1
 | 
			
		||||
#define ARMul_CP13_R0_IRQ       0x2
 | 
			
		||||
#define ARMul_CP13_R8_PMUS      0x1
 | 
			
		||||
 | 
			
		||||
#define ARMul_CP14_R0_ENABLE    0x0001
 | 
			
		||||
#define ARMul_CP14_R0_CLKRST    0x0004
 | 
			
		||||
#define ARMul_CP14_R0_CCD       0x0008
 | 
			
		||||
#define ARMul_CP14_R0_INTEN0    0x0010
 | 
			
		||||
#define ARMul_CP14_R0_INTEN1    0x0020
 | 
			
		||||
#define ARMul_CP14_R0_INTEN2    0x0040
 | 
			
		||||
#define ARMul_CP14_R0_FLAG0     0x0100
 | 
			
		||||
#define ARMul_CP14_R0_FLAG1     0x0200
 | 
			
		||||
#define ARMul_CP14_R0_FLAG2     0x0400
 | 
			
		||||
#define ARMul_CP14_R10_MOE_IB   0x0004
 | 
			
		||||
#define ARMul_CP14_R10_MOE_DB   0x0008
 | 
			
		||||
#define ARMul_CP14_R10_MOE_BT   0x000c
 | 
			
		||||
#define ARMul_CP15_R1_ENDIAN    0x0080
 | 
			
		||||
#define ARMul_CP15_R1_ALIGN     0x0002
 | 
			
		||||
#define ARMul_CP15_R5_X         0x0400
 | 
			
		||||
#define ARMul_CP15_R5_ST_ALIGN  0x0001
 | 
			
		||||
#define ARMul_CP15_R5_IMPRE     0x0406
 | 
			
		||||
#define ARMul_CP15_R5_MMU_EXCPT 0x0400
 | 
			
		||||
#define ARMul_CP15_DBCON_M      0x0100
 | 
			
		||||
#define ARMul_CP15_DBCON_E1     0x000c
 | 
			
		||||
#define ARMul_CP15_DBCON_E0     0x0003
 | 
			
		||||
 | 
			
		||||
extern unsigned ARMul_CoProInit (ARMul_State * state);
 | 
			
		||||
extern void ARMul_CoProExit (ARMul_State * state);
 | 
			
		||||
extern void ARMul_CoProAttach (ARMul_State * state, unsigned number,
 | 
			
		||||
                   ARMul_CPInits * init, ARMul_CPExits * exit,
 | 
			
		||||
                   ARMul_LDCs * ldc, ARMul_STCs * stc,
 | 
			
		||||
                   ARMul_MRCs * mrc, ARMul_MCRs * mcr,
 | 
			
		||||
                   ARMul_MRRCs * mrrc, ARMul_MCRRs * mcrr,
 | 
			
		||||
                   ARMul_CDPs * cdp,
 | 
			
		||||
                   ARMul_CPReads * read, ARMul_CPWrites * write);
 | 
			
		||||
extern void ARMul_CoProDetach (ARMul_State * state, unsigned number);
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*               Definitons of things in the host environment                *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
extern unsigned ARMul_OSInit (ARMul_State * state);
 | 
			
		||||
extern void ARMul_OSExit (ARMul_State * state);
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_OSLastErrorP (ARMul_State * state);
 | 
			
		||||
 | 
			
		||||
extern ARMword ARMul_Debug (ARMul_State * state, ARMword pc, ARMword instr);
 | 
			
		||||
extern unsigned ARMul_OSException (ARMul_State * state, ARMword vector,
 | 
			
		||||
                   ARMword pc);
 | 
			
		||||
extern int rdi_log;
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                            Host-dependent stuff                           *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#ifdef macintosh
 | 
			
		||||
pascal void SpinCursor (short increment);    /* copied from CursorCtl.h */
 | 
			
		||||
# define HOURGLASS           SpinCursor( 1 )
 | 
			
		||||
# define HOURGLASS_RATE      1023    /* 2^n - 1 */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//teawater add for arm2x86 2005.02.14-------------------------------------------
 | 
			
		||||
/*ywc 2005-03-31*/
 | 
			
		||||
/*
 | 
			
		||||
#include "arm2x86.h"
 | 
			
		||||
#include "arm2x86_dp.h"
 | 
			
		||||
#include "arm2x86_movl.h"
 | 
			
		||||
#include "arm2x86_psr.h"
 | 
			
		||||
#include "arm2x86_shift.h"
 | 
			
		||||
#include "arm2x86_mem.h"
 | 
			
		||||
#include "arm2x86_mul.h"
 | 
			
		||||
#include "arm2x86_test.h"
 | 
			
		||||
#include "arm2x86_other.h"
 | 
			
		||||
#include "list.h"
 | 
			
		||||
#include "tb.h"
 | 
			
		||||
*/
 | 
			
		||||
#define EQ 0
 | 
			
		||||
#define NE 1
 | 
			
		||||
#define CS 2
 | 
			
		||||
#define CC 3
 | 
			
		||||
#define MI 4
 | 
			
		||||
#define PL 5
 | 
			
		||||
#define VS 6
 | 
			
		||||
#define VC 7
 | 
			
		||||
#define HI 8
 | 
			
		||||
#define LS 9
 | 
			
		||||
#define GE 10
 | 
			
		||||
#define LT 11
 | 
			
		||||
#define GT 12
 | 
			
		||||
#define LE 13
 | 
			
		||||
#define AL 14
 | 
			
		||||
#define NV 15
 | 
			
		||||
 | 
			
		||||
#ifndef NFLAG
 | 
			
		||||
#define NFLAG    state->NFlag
 | 
			
		||||
#endif //NFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef ZFLAG
 | 
			
		||||
#define ZFLAG    state->ZFlag
 | 
			
		||||
#endif //ZFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef CFLAG
 | 
			
		||||
#define CFLAG    state->CFlag
 | 
			
		||||
#endif //CFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef VFLAG
 | 
			
		||||
#define VFLAG    state->VFlag
 | 
			
		||||
#endif //VFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef IFLAG
 | 
			
		||||
#define IFLAG    (state->IFFlags >> 1)
 | 
			
		||||
#endif //IFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef FFLAG
 | 
			
		||||
#define FFLAG    (state->IFFlags & 1)
 | 
			
		||||
#endif //FFLAG
 | 
			
		||||
 | 
			
		||||
#ifndef IFFLAGS
 | 
			
		||||
#define IFFLAGS    state->IFFlags
 | 
			
		||||
#endif //VFLAG
 | 
			
		||||
 | 
			
		||||
#define FLAG_MASK    0xf0000000
 | 
			
		||||
#define NBIT_SHIFT    31
 | 
			
		||||
#define ZBIT_SHIFT    30
 | 
			
		||||
#define CBIT_SHIFT    29
 | 
			
		||||
#define VBIT_SHIFT    28
 | 
			
		||||
#ifdef DBCT
 | 
			
		||||
//teawater change for local tb branch directly jump 2005.10.18------------------
 | 
			
		||||
#include "dbct/list.h"
 | 
			
		||||
#include "dbct/arm2x86.h"
 | 
			
		||||
#include "dbct/arm2x86_dp.h"
 | 
			
		||||
#include "dbct/arm2x86_movl.h"
 | 
			
		||||
#include "dbct/arm2x86_psr.h"
 | 
			
		||||
#include "dbct/arm2x86_shift.h"
 | 
			
		||||
#include "dbct/arm2x86_mem.h"
 | 
			
		||||
#include "dbct/arm2x86_mul.h"
 | 
			
		||||
#include "dbct/arm2x86_test.h"
 | 
			
		||||
#include "dbct/arm2x86_other.h"
 | 
			
		||||
#include "dbct/arm2x86_coproc.h"
 | 
			
		||||
#include "dbct/tb.h"
 | 
			
		||||
#endif
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
#define SKYEYE_OUTREGS(fd) { fprintf ((fd), "R %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,C %x,S %x,%x,%x,%x,%x,%x,%x,M %x,B %x,E %x,I %x,P %x,T %x,L %x,D %x,",\
 | 
			
		||||
                         state->Reg[0],state->Reg[1],state->Reg[2],state->Reg[3], \
 | 
			
		||||
                         state->Reg[4],state->Reg[5],state->Reg[6],state->Reg[7], \
 | 
			
		||||
                         state->Reg[8],state->Reg[9],state->Reg[10],state->Reg[11], \
 | 
			
		||||
                         state->Reg[12],state->Reg[13],state->Reg[14],state->Reg[15], \
 | 
			
		||||
             state->Cpsr,   state->Spsr[0], state->Spsr[1], state->Spsr[2],\
 | 
			
		||||
                         state->Spsr[3],state->Spsr[4], state->Spsr[5], state->Spsr[6],\
 | 
			
		||||
             state->Mode,state->Bank,state->ErrorCode,state->instr,state->pc,\
 | 
			
		||||
             state->temp,state->loaded,state->decoded);}
 | 
			
		||||
 | 
			
		||||
#define SKYEYE_OUTMOREREGS(fd) { fprintf ((fd),"\
 | 
			
		||||
RUs %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
 | 
			
		||||
RF  %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
 | 
			
		||||
RI  %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
 | 
			
		||||
RS  %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
 | 
			
		||||
RA  %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,\
 | 
			
		||||
RUn %x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x,%x\n",\
 | 
			
		||||
                         state->RegBank[0][0],state->RegBank[0][1],state->RegBank[0][2],state->RegBank[0][3], \
 | 
			
		||||
                         state->RegBank[0][4],state->RegBank[0][5],state->RegBank[0][6],state->RegBank[0][7], \
 | 
			
		||||
                         state->RegBank[0][8],state->RegBank[0][9],state->RegBank[0][10],state->RegBank[0][11], \
 | 
			
		||||
                         state->RegBank[0][12],state->RegBank[0][13],state->RegBank[0][14],state->RegBank[0][15], \
 | 
			
		||||
                         state->RegBank[1][0],state->RegBank[1][1],state->RegBank[1][2],state->RegBank[1][3], \
 | 
			
		||||
                         state->RegBank[1][4],state->RegBank[1][5],state->RegBank[1][6],state->RegBank[1][7], \
 | 
			
		||||
                         state->RegBank[1][8],state->RegBank[1][9],state->RegBank[1][10],state->RegBank[1][11], \
 | 
			
		||||
                         state->RegBank[1][12],state->RegBank[1][13],state->RegBank[1][14],state->RegBank[1][15], \
 | 
			
		||||
                         state->RegBank[2][0],state->RegBank[2][1],state->RegBank[2][2],state->RegBank[2][3], \
 | 
			
		||||
                         state->RegBank[2][4],state->RegBank[2][5],state->RegBank[2][6],state->RegBank[2][7], \
 | 
			
		||||
                         state->RegBank[2][8],state->RegBank[2][9],state->RegBank[2][10],state->RegBank[2][11], \
 | 
			
		||||
                         state->RegBank[2][12],state->RegBank[2][13],state->RegBank[2][14],state->RegBank[2][15], \
 | 
			
		||||
                         state->RegBank[3][0],state->RegBank[3][1],state->RegBank[3][2],state->RegBank[3][3], \
 | 
			
		||||
                         state->RegBank[3][4],state->RegBank[3][5],state->RegBank[3][6],state->RegBank[3][7], \
 | 
			
		||||
                         state->RegBank[3][8],state->RegBank[3][9],state->RegBank[3][10],state->RegBank[3][11], \
 | 
			
		||||
                         state->RegBank[3][12],state->RegBank[3][13],state->RegBank[3][14],state->RegBank[3][15], \
 | 
			
		||||
                         state->RegBank[4][0],state->RegBank[4][1],state->RegBank[4][2],state->RegBank[4][3], \
 | 
			
		||||
                         state->RegBank[4][4],state->RegBank[4][5],state->RegBank[4][6],state->RegBank[4][7], \
 | 
			
		||||
                         state->RegBank[4][8],state->RegBank[4][9],state->RegBank[4][10],state->RegBank[4][11], \
 | 
			
		||||
                         state->RegBank[4][12],state->RegBank[4][13],state->RegBank[4][14],state->RegBank[4][15], \
 | 
			
		||||
                         state->RegBank[5][0],state->RegBank[5][1],state->RegBank[5][2],state->RegBank[5][3], \
 | 
			
		||||
                         state->RegBank[5][4],state->RegBank[5][5],state->RegBank[5][6],state->RegBank[5][7], \
 | 
			
		||||
                         state->RegBank[5][8],state->RegBank[5][9],state->RegBank[5][10],state->RegBank[5][11], \
 | 
			
		||||
                         state->RegBank[5][12],state->RegBank[5][13],state->RegBank[5][14],state->RegBank[5][15] \
 | 
			
		||||
        );}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define SA1110        0x6901b110
 | 
			
		||||
#define SA1100        0x4401a100
 | 
			
		||||
#define PXA250          0x69052100
 | 
			
		||||
#define PXA270           0x69054110
 | 
			
		||||
//#define PXA250              0x69052903
 | 
			
		||||
// 0x69052903;  //PXA250 B1 from intel 278522-001.pdf
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern void ARMul_UndefInstr (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_FixCPSR (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_FixSPSR (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_ConsolePrint (ARMul_State *, const char *, ...);
 | 
			
		||||
extern void ARMul_SelectProcessor (ARMul_State *, unsigned);
 | 
			
		||||
 | 
			
		||||
#define DIFF_LOG 0
 | 
			
		||||
#define SAVE_LOG 0
 | 
			
		||||
 | 
			
		||||
#endif /* _ARMDEFS_H_ */
 | 
			
		||||
							
								
								
									
										6631
									
								
								src/core/arm/interpreter/armemu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6631
									
								
								src/core/arm/interpreter/armemu.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										659
									
								
								src/core/arm/interpreter/armemu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										659
									
								
								src/core/arm/interpreter/armemu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,659 @@
 | 
			
		||||
/*  armemu.h -- ARMulator emulation macros:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
#ifndef __ARMEMU_H__
 | 
			
		||||
#define __ARMEMU_H__
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
//#include "skyeye.h"
 | 
			
		||||
 | 
			
		||||
extern ARMword isize;
 | 
			
		||||
 | 
			
		||||
/* Condition code values.  */
 | 
			
		||||
#define EQ 0
 | 
			
		||||
#define NE 1
 | 
			
		||||
#define CS 2
 | 
			
		||||
#define CC 3
 | 
			
		||||
#define MI 4
 | 
			
		||||
#define PL 5
 | 
			
		||||
#define VS 6
 | 
			
		||||
#define VC 7
 | 
			
		||||
#define HI 8
 | 
			
		||||
#define LS 9
 | 
			
		||||
#define GE 10
 | 
			
		||||
#define LT 11
 | 
			
		||||
#define GT 12
 | 
			
		||||
#define LE 13
 | 
			
		||||
#define AL 14
 | 
			
		||||
#define NV 15
 | 
			
		||||
 | 
			
		||||
/* Shift Opcodes.  */
 | 
			
		||||
#define LSL 0
 | 
			
		||||
#define LSR 1
 | 
			
		||||
#define ASR 2
 | 
			
		||||
#define ROR 3
 | 
			
		||||
 | 
			
		||||
/* Macros to twiddle the status flags and mode.  */
 | 
			
		||||
#define NBIT ((unsigned)1L << 31)
 | 
			
		||||
#define ZBIT (1L << 30)
 | 
			
		||||
#define CBIT (1L << 29)
 | 
			
		||||
#define VBIT (1L << 28)
 | 
			
		||||
#define SBIT (1L << 27)
 | 
			
		||||
#define IBIT (1L << 7)
 | 
			
		||||
#define FBIT (1L << 6)
 | 
			
		||||
#define IFBITS (3L << 6)
 | 
			
		||||
#define R15IBIT (1L << 27)
 | 
			
		||||
#define R15FBIT (1L << 26)
 | 
			
		||||
#define R15IFBITS (3L << 26)
 | 
			
		||||
 | 
			
		||||
#define POS(i) ( (~(i)) >> 31 )
 | 
			
		||||
#define NEG(i) ( (i) >> 31 )
 | 
			
		||||
 | 
			
		||||
#ifdef MODET			/* Thumb support.  */
 | 
			
		||||
/* ??? This bit is actually in the low order bit of the PC in the hardware.
 | 
			
		||||
   It isn't clear if the simulator needs to model that or not.  */
 | 
			
		||||
#define TBIT (1L << 5)
 | 
			
		||||
#define TFLAG state->TFlag
 | 
			
		||||
#define SETT state->TFlag = 1
 | 
			
		||||
#define CLEART state->TFlag = 0
 | 
			
		||||
#define ASSIGNT(res) state->TFlag = res
 | 
			
		||||
#define INSN_SIZE (TFLAG ? 2 : 4)
 | 
			
		||||
#else
 | 
			
		||||
#define TBIT (1L << 5)
 | 
			
		||||
#define INSN_SIZE 4
 | 
			
		||||
#define TFLAG 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*add armv6 CPSR  feature*/
 | 
			
		||||
#define EFLAG state->EFlag
 | 
			
		||||
#define SETE state->EFlag = 1
 | 
			
		||||
#define CLEARE state->EFlag = 0
 | 
			
		||||
#define ASSIGNE(res) state->NFlag = res
 | 
			
		||||
 | 
			
		||||
#define AFLAG state->AFlag
 | 
			
		||||
#define SETA  state->AFlag = 1
 | 
			
		||||
#define CLEARA state->AFlag = 0
 | 
			
		||||
#define ASSIGNA(res) state->NFlag = res
 | 
			
		||||
 | 
			
		||||
#define QFLAG state->QFlag
 | 
			
		||||
#define SETQ state->QFlag = 1
 | 
			
		||||
#define CLEARQ state->AFlag = 0
 | 
			
		||||
#define ASSIGNQ(res) state->QFlag = res
 | 
			
		||||
 | 
			
		||||
/* add end */
 | 
			
		||||
 | 
			
		||||
#define NFLAG state->NFlag
 | 
			
		||||
#define SETN state->NFlag = 1
 | 
			
		||||
#define CLEARN state->NFlag = 0
 | 
			
		||||
#define ASSIGNN(res) state->NFlag = res
 | 
			
		||||
 | 
			
		||||
#define ZFLAG state->ZFlag
 | 
			
		||||
#define SETZ state->ZFlag = 1
 | 
			
		||||
#define CLEARZ state->ZFlag = 0
 | 
			
		||||
#define ASSIGNZ(res) state->ZFlag = res
 | 
			
		||||
 | 
			
		||||
#define CFLAG state->CFlag
 | 
			
		||||
#define SETC state->CFlag = 1
 | 
			
		||||
#define CLEARC state->CFlag = 0
 | 
			
		||||
#define ASSIGNC(res) state->CFlag = res
 | 
			
		||||
 | 
			
		||||
#define VFLAG state->VFlag
 | 
			
		||||
#define SETV state->VFlag = 1
 | 
			
		||||
#define CLEARV state->VFlag = 0
 | 
			
		||||
#define ASSIGNV(res) state->VFlag = res
 | 
			
		||||
 | 
			
		||||
#define SFLAG state->SFlag
 | 
			
		||||
#define SETS state->SFlag = 1
 | 
			
		||||
#define CLEARS state->SFlag = 0
 | 
			
		||||
#define ASSIGNS(res) state->SFlag = res
 | 
			
		||||
 | 
			
		||||
#define IFLAG (state->IFFlags >> 1)
 | 
			
		||||
#define FFLAG (state->IFFlags & 1)
 | 
			
		||||
#define IFFLAGS state->IFFlags
 | 
			
		||||
#define ASSIGNINT(res) state->IFFlags = (((res) >> 6) & 3)
 | 
			
		||||
#define ASSIGNR15INT(res) state->IFFlags = (((res) >> 26) & 3) ;
 | 
			
		||||
 | 
			
		||||
#define PSR_FBITS (0xff000000L)
 | 
			
		||||
#define PSR_SBITS (0x00ff0000L)
 | 
			
		||||
#define PSR_XBITS (0x0000ff00L)
 | 
			
		||||
#define PSR_CBITS (0x000000ffL)
 | 
			
		||||
 | 
			
		||||
#if defined MODE32 || defined MODET
 | 
			
		||||
#define CCBITS (0xf8000000L)
 | 
			
		||||
#else
 | 
			
		||||
#define CCBITS (0xf0000000L)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define INTBITS (0xc0L)
 | 
			
		||||
 | 
			
		||||
#if defined MODET && defined MODE32
 | 
			
		||||
#define PCBITS (0xffffffffL)
 | 
			
		||||
#else
 | 
			
		||||
#define PCBITS (0xfffffffcL)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MODEBITS (0x1fL)
 | 
			
		||||
#define R15INTBITS (3L << 26)
 | 
			
		||||
 | 
			
		||||
#if defined MODET && defined MODE32
 | 
			
		||||
#define R15PCBITS (0x03ffffffL)
 | 
			
		||||
#else
 | 
			
		||||
#define R15PCBITS (0x03fffffcL)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define R15PCMODEBITS (0x03ffffffL)
 | 
			
		||||
#define R15MODEBITS (0x3L)
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#define PCMASK PCBITS
 | 
			
		||||
#define PCWRAP(pc) (pc)
 | 
			
		||||
#else
 | 
			
		||||
#define PCMASK R15PCBITS
 | 
			
		||||
#define PCWRAP(pc) ((pc) & R15PCBITS)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define R15CCINTMODE (state->Reg[15] & (CCBITS | R15INTBITS | R15MODEBITS))
 | 
			
		||||
#define R15INT (state->Reg[15] & R15INTBITS)
 | 
			
		||||
#define R15INTPC (state->Reg[15] & (R15INTBITS | R15PCBITS))
 | 
			
		||||
#define R15INTPCMODE (state->Reg[15] & (R15INTBITS | R15PCBITS | R15MODEBITS))
 | 
			
		||||
#define R15INTMODE (state->Reg[15] & (R15INTBITS | R15MODEBITS))
 | 
			
		||||
#define R15PC (state->Reg[15] & R15PCBITS)
 | 
			
		||||
#define R15PCMODE (state->Reg[15] & (R15PCBITS | R15MODEBITS))
 | 
			
		||||
#define R15MODE (state->Reg[15] & R15MODEBITS)
 | 
			
		||||
 | 
			
		||||
#define ECC ((NFLAG << 31) | (ZFLAG << 30) | (CFLAG << 29) | (VFLAG << 28) | (SFLAG << 27))
 | 
			
		||||
#define EINT (IFFLAGS << 6)
 | 
			
		||||
#define ER15INT (IFFLAGS << 26)
 | 
			
		||||
#define EMODE (state->Mode)
 | 
			
		||||
 | 
			
		||||
//#ifdef MODET
 | 
			
		||||
//#define CPSR (ECC | EINT | EMODE | (TFLAG << 5))
 | 
			
		||||
//#else
 | 
			
		||||
//#define CPSR (ECC | EINT | EMODE)
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#define PATCHR15
 | 
			
		||||
#else
 | 
			
		||||
#define PATCHR15 state->Reg[15] = ECC | ER15INT | EMODE | R15PC
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define GETSPSR(bank) (ARMul_GetSPSR (state, EMODE))
 | 
			
		||||
#define SETPSR_F(d,s) d = ((d) & ~PSR_FBITS) | ((s) & PSR_FBITS)
 | 
			
		||||
#define SETPSR_S(d,s) d = ((d) & ~PSR_SBITS) | ((s) & PSR_SBITS)
 | 
			
		||||
#define SETPSR_X(d,s) d = ((d) & ~PSR_XBITS) | ((s) & PSR_XBITS)
 | 
			
		||||
#define SETPSR_C(d,s) d = ((d) & ~PSR_CBITS) | ((s) & PSR_CBITS)
 | 
			
		||||
 | 
			
		||||
#define SETR15PSR(s) 								\
 | 
			
		||||
  do										\
 | 
			
		||||
    {										\
 | 
			
		||||
      if (state->Mode == USER26MODE)						\
 | 
			
		||||
        {									\
 | 
			
		||||
          state->Reg[15] = ((s) & CCBITS) | R15PC | ER15INT | EMODE;		\
 | 
			
		||||
          ASSIGNN ((state->Reg[15] & NBIT) != 0);				\
 | 
			
		||||
          ASSIGNZ ((state->Reg[15] & ZBIT) != 0);				\
 | 
			
		||||
          ASSIGNC ((state->Reg[15] & CBIT) != 0);				\
 | 
			
		||||
          ASSIGNV ((state->Reg[15] & VBIT) != 0);				\
 | 
			
		||||
        }									\
 | 
			
		||||
      else									\
 | 
			
		||||
        {									\
 | 
			
		||||
          state->Reg[15] = R15PC | ((s) & (CCBITS | R15INTBITS | R15MODEBITS));	\
 | 
			
		||||
          ARMul_R15Altered (state);						\
 | 
			
		||||
       }									\
 | 
			
		||||
    }										\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define SETABORT(i, m, d)						\
 | 
			
		||||
  do									\
 | 
			
		||||
    { 									\
 | 
			
		||||
      int SETABORT_mode = (m);						\
 | 
			
		||||
									\
 | 
			
		||||
      ARMul_SetSPSR (state, SETABORT_mode, ARMul_GetCPSR (state));	\
 | 
			
		||||
      ARMul_SetCPSR (state, ((ARMul_GetCPSR (state) & ~(EMODE | TBIT))	\
 | 
			
		||||
			     | (i) | SETABORT_mode));			\
 | 
			
		||||
      state->Reg[14] = temp - (d);					\
 | 
			
		||||
    }									\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
//#ifndef MODE32
 | 
			
		||||
#define VECTORS 0x20
 | 
			
		||||
#define LEGALADDR 0x03ffffff
 | 
			
		||||
#define VECTORACCESS(address) (address < VECTORS && ARMul_MODE26BIT && state->prog32Sig)
 | 
			
		||||
#define ADDREXCEPT(address)   (address > LEGALADDR && !state->data32Sig)
 | 
			
		||||
//#endif
 | 
			
		||||
 | 
			
		||||
#define INTERNALABORT(address)			\
 | 
			
		||||
  do						\
 | 
			
		||||
    {						\
 | 
			
		||||
      if (address < VECTORS)			\
 | 
			
		||||
	state->Aborted = ARMul_DataAbortV;	\
 | 
			
		||||
      else					\
 | 
			
		||||
	state->Aborted = ARMul_AddrExceptnV;	\
 | 
			
		||||
    }						\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#define TAKEABORT ARMul_Abort (state, ARMul_DataAbortV)
 | 
			
		||||
#else
 | 
			
		||||
#define TAKEABORT 					\
 | 
			
		||||
  do							\
 | 
			
		||||
    {							\
 | 
			
		||||
      if (state->Aborted == ARMul_AddrExceptnV) 	\
 | 
			
		||||
	ARMul_Abort (state, ARMul_AddrExceptnV); 	\
 | 
			
		||||
      else 						\
 | 
			
		||||
	ARMul_Abort (state, ARMul_DataAbortV);		\
 | 
			
		||||
    }							\
 | 
			
		||||
  while (0)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define CPTAKEABORT					\
 | 
			
		||||
  do							\
 | 
			
		||||
    {							\
 | 
			
		||||
      if (!state->Aborted)				\
 | 
			
		||||
	ARMul_Abort (state, ARMul_UndefinedInstrV); 	\
 | 
			
		||||
      else if (state->Aborted == ARMul_AddrExceptnV) 	\
 | 
			
		||||
	ARMul_Abort (state, ARMul_AddrExceptnV); 	\
 | 
			
		||||
      else 						\
 | 
			
		||||
	ARMul_Abort (state, ARMul_DataAbortV);		\
 | 
			
		||||
    }							\
 | 
			
		||||
  while (0);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Different ways to start the next instruction.  */
 | 
			
		||||
#define SEQ           0
 | 
			
		||||
#define NONSEQ        1
 | 
			
		||||
#define PCINCEDSEQ    2
 | 
			
		||||
#define PCINCEDNONSEQ 3
 | 
			
		||||
#define PRIMEPIPE     4
 | 
			
		||||
#define RESUME        8
 | 
			
		||||
 | 
			
		||||
/************************************/
 | 
			
		||||
/* shenoubang 2012-3-11 */
 | 
			
		||||
/* for armv7 DBG DMB DSB instr*/
 | 
			
		||||
/************************************/
 | 
			
		||||
#define MBReqTypes_Writes	0
 | 
			
		||||
#define MBReqTypes_All		1
 | 
			
		||||
 | 
			
		||||
#define NORMALCYCLE state->NextInstr = 0
 | 
			
		||||
#define BUSUSEDN    state->NextInstr |= 1	/* The next fetch will be an N cycle.  */
 | 
			
		||||
#define BUSUSEDINCPCS						\
 | 
			
		||||
  do								\
 | 
			
		||||
    {								\
 | 
			
		||||
      if (! state->is_v4)					\
 | 
			
		||||
        {							\
 | 
			
		||||
	  /* A standard PC inc and an S cycle.  */		\
 | 
			
		||||
	  state->Reg[15] += isize;				\
 | 
			
		||||
	  state->NextInstr = (state->NextInstr & 0xff) | 2;	\
 | 
			
		||||
	}							\
 | 
			
		||||
    }								\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define BUSUSEDINCPCN					\
 | 
			
		||||
  do							\
 | 
			
		||||
    {							\
 | 
			
		||||
      if (state->is_v4)					\
 | 
			
		||||
	BUSUSEDN;					\
 | 
			
		||||
      else						\
 | 
			
		||||
	{						\
 | 
			
		||||
	  /* A standard PC inc and an N cycle.  */	\
 | 
			
		||||
	  state->Reg[15] += isize;			\
 | 
			
		||||
	  state->NextInstr |= 3;			\
 | 
			
		||||
	}						\
 | 
			
		||||
    }							\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define INCPC 			\
 | 
			
		||||
  do				\
 | 
			
		||||
    {				\
 | 
			
		||||
      /* A standard PC inc.  */	\
 | 
			
		||||
      state->Reg[15] += isize;	\
 | 
			
		||||
      state->NextInstr |= 2;	\
 | 
			
		||||
    }				\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define FLUSHPIPE state->NextInstr |= PRIMEPIPE
 | 
			
		||||
 | 
			
		||||
/* Cycle based emulation.  */
 | 
			
		||||
 | 
			
		||||
#define OUTPUTCP(i,a,b)
 | 
			
		||||
#define NCYCLE
 | 
			
		||||
#define SCYCLE
 | 
			
		||||
#define ICYCLE
 | 
			
		||||
#define CCYCLE
 | 
			
		||||
#define NEXTCYCLE(c)
 | 
			
		||||
 | 
			
		||||
/* Macros to extract parts of instructions.  */
 | 
			
		||||
#define DESTReg (BITS (12, 15))
 | 
			
		||||
#define LHSReg  (BITS (16, 19))
 | 
			
		||||
#define RHSReg  (BITS ( 0,  3))
 | 
			
		||||
 | 
			
		||||
#define DEST (state->Reg[DESTReg])
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#ifdef MODET
 | 
			
		||||
#define LHS ((LHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[LHSReg]))
 | 
			
		||||
#define RHS ((RHSReg == 15) ? (state->Reg[15] & 0xFFFFFFFC) : (state->Reg[RHSReg]))
 | 
			
		||||
#else
 | 
			
		||||
#define LHS (state->Reg[LHSReg])
 | 
			
		||||
#define RHS (state->Reg[RHSReg])
 | 
			
		||||
#endif
 | 
			
		||||
#else
 | 
			
		||||
#define LHS ((LHSReg == 15) ? R15PC : (state->Reg[LHSReg]))
 | 
			
		||||
#define RHS ((RHSReg == 15) ? R15PC : (state->Reg[RHSReg]))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define MULDESTReg (BITS (16, 19))
 | 
			
		||||
#define MULLHSReg  (BITS ( 0,  3))
 | 
			
		||||
#define MULRHSReg  (BITS ( 8, 11))
 | 
			
		||||
#define MULACCReg  (BITS (12, 15))
 | 
			
		||||
 | 
			
		||||
#define DPImmRHS (ARMul_ImmedTable[BITS(0, 11)])
 | 
			
		||||
#define DPSImmRHS temp = BITS(0,11) ; \
 | 
			
		||||
                  rhs = ARMul_ImmedTable[temp] ; \
 | 
			
		||||
                  if (temp > 255) /* There was a shift.  */ \
 | 
			
		||||
                     ASSIGNC (rhs >> 31) ;
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#define DPRegRHS  ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
 | 
			
		||||
                                      : GetDPRegRHS (state, instr))
 | 
			
		||||
#define DPSRegRHS ((BITS (4,11) == 0) ? state->Reg[RHSReg] \
 | 
			
		||||
                                      : GetDPSRegRHS (state, instr))
 | 
			
		||||
#else
 | 
			
		||||
#define DPRegRHS  ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
 | 
			
		||||
                                       : GetDPRegRHS (state, instr))
 | 
			
		||||
#define DPSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
 | 
			
		||||
                                       : GetDPSRegRHS (state, instr))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSBase state->Reg[LHSReg]
 | 
			
		||||
#define LSImmRHS (BITS(0,11))
 | 
			
		||||
 | 
			
		||||
#ifdef MODE32
 | 
			
		||||
#define LSRegRHS ((BITS (4, 11) == 0) ? state->Reg[RHSReg] \
 | 
			
		||||
                                      : GetLSRegRHS (state, instr))
 | 
			
		||||
#else
 | 
			
		||||
#define LSRegRHS ((BITS (0, 11) < 15) ? state->Reg[RHSReg] \
 | 
			
		||||
                                      : GetLSRegRHS (state, instr))
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define LSMNumRegs ((ARMword) ARMul_BitList[BITS (0, 7)] + \
 | 
			
		||||
                    (ARMword) ARMul_BitList[BITS (8, 15)] )
 | 
			
		||||
#define LSMBaseFirst ((LHSReg == 0 && BIT (0)) || \
 | 
			
		||||
                      (BIT (LHSReg) && BITS (0, LHSReg - 1) == 0))
 | 
			
		||||
 | 
			
		||||
#define SWAPSRC (state->Reg[RHSReg])
 | 
			
		||||
 | 
			
		||||
#define LSCOff (BITS (0, 7) << 2)
 | 
			
		||||
#define CPNum   BITS (8, 11)
 | 
			
		||||
 | 
			
		||||
/* Determine if access to coprocessor CP is permitted.
 | 
			
		||||
   The XScale has a register in CP15 which controls access to CP0 - CP13.  */
 | 
			
		||||
//chy 2003-09-03, new CP_ACCESS_ALLOWED
 | 
			
		||||
/*
 | 
			
		||||
#define CP_ACCESS_ALLOWED(STATE, CP)			\
 | 
			
		||||
    (   ((CP) >= 14)					\
 | 
			
		||||
     || (! (STATE)->is_XScale)				\
 | 
			
		||||
     || (read_cp15_reg (15, 0, 1) & (1 << (CP))))
 | 
			
		||||
*/
 | 
			
		||||
//#define CP_ACCESS_ALLOWED(STATE, CP)			\
 | 
			
		||||
//	(((CP) >= 14)					\
 | 
			
		||||
//	|| (!(STATE)->is_XScale)				\
 | 
			
		||||
//	|| (xscale_cp15_cp_access_allowed(STATE, 15, CP)))
 | 
			
		||||
 | 
			
		||||
#define CP_ACCESS_ALLOWED(STATE, CP) false // Disabled coprocessor shit /bunnei
 | 
			
		||||
 | 
			
		||||
/* Macro to rotate n right by b bits.  */
 | 
			
		||||
#define ROTATER(n, b) (((n) >> (b)) | ((n) << (32 - (b))))
 | 
			
		||||
 | 
			
		||||
/* Macros to store results of instructions.  */
 | 
			
		||||
#define WRITEDEST(d)				\
 | 
			
		||||
  do						\
 | 
			
		||||
    {						\
 | 
			
		||||
      if (DESTReg == 15) 			\
 | 
			
		||||
	WriteR15 (state, d); 			\
 | 
			
		||||
      else 					\
 | 
			
		||||
	DEST = d;				\
 | 
			
		||||
    }						\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define WRITESDEST(d)				\
 | 
			
		||||
  do						\
 | 
			
		||||
    {						\
 | 
			
		||||
      if (DESTReg == 15)			\
 | 
			
		||||
	WriteSR15 (state, d);			\
 | 
			
		||||
      else					\
 | 
			
		||||
	{					\
 | 
			
		||||
	  DEST = d;				\
 | 
			
		||||
	  ARMul_NegZero (state, d);		\
 | 
			
		||||
	}					\
 | 
			
		||||
    }						\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define WRITEDESTB(d)				\
 | 
			
		||||
  do						\
 | 
			
		||||
    {						\
 | 
			
		||||
      if (DESTReg == 15){			\
 | 
			
		||||
	WriteR15Branch (state, d);		\
 | 
			
		||||
      }						\
 | 
			
		||||
      else{					\
 | 
			
		||||
	DEST = d;				\
 | 
			
		||||
      }						\
 | 
			
		||||
    }						\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define BYTETOBUS(data) ((data & 0xff) | \
 | 
			
		||||
                        ((data & 0xff) << 8) | \
 | 
			
		||||
                        ((data & 0xff) << 16) | \
 | 
			
		||||
                        ((data & 0xff) << 24))
 | 
			
		||||
 | 
			
		||||
#define BUSTOBYTE(address, data)				\
 | 
			
		||||
  do								\
 | 
			
		||||
    {								\
 | 
			
		||||
      if (state->bigendSig) 					\
 | 
			
		||||
	temp = (data >> (((address ^ 3) & 3) << 3)) & 0xff;	\
 | 
			
		||||
      else							\
 | 
			
		||||
	temp = (data >> ((address & 3) << 3)) & 0xff;		\
 | 
			
		||||
    }								\
 | 
			
		||||
  while (0)
 | 
			
		||||
 | 
			
		||||
#define LOADMULT(instr,   address, wb)  LoadMult   (state, instr, address, wb)
 | 
			
		||||
#define LOADSMULT(instr,  address, wb)  LoadSMult  (state, instr, address, wb)
 | 
			
		||||
#define STOREMULT(instr,  address, wb)  StoreMult  (state, instr, address, wb)
 | 
			
		||||
#define STORESMULT(instr, address, wb)  StoreSMult (state, instr, address, wb)
 | 
			
		||||
 | 
			
		||||
#define POSBRANCH ((instr & 0x7fffff) << 2)
 | 
			
		||||
#define NEGBRANCH ((0xff000000 |(instr & 0xffffff)) << 2)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Values for Emulate.  */
 | 
			
		||||
#define STOP            0	/* stop */
 | 
			
		||||
#define CHANGEMODE      1	/* change mode */
 | 
			
		||||
#define ONCE            2	/* execute just one interation */
 | 
			
		||||
#define RUN             3	/* continuous execution */
 | 
			
		||||
 | 
			
		||||
/* Stuff that is shared across modes.  */
 | 
			
		||||
extern unsigned ARMul_MultTable[];	/* Number of I cycles for a mult.  */
 | 
			
		||||
extern ARMword ARMul_ImmedTable[];	/* Immediate DP LHS values.  */
 | 
			
		||||
extern char ARMul_BitList[];	/* Number of bits in a byte table.  */
 | 
			
		||||
 | 
			
		||||
#define EVENTLISTSIZE 1024L
 | 
			
		||||
 | 
			
		||||
/* Thumb support.  */
 | 
			
		||||
typedef enum
 | 
			
		||||
{
 | 
			
		||||
	t_undefined,		/* Undefined Thumb instruction.  */
 | 
			
		||||
	t_decoded,		/* Instruction decoded to ARM equivalent.  */
 | 
			
		||||
	t_branch		/* Thumb branch (already processed).  */
 | 
			
		||||
}
 | 
			
		||||
tdstate;
 | 
			
		||||
 | 
			
		||||
/*********************************************************************************
 | 
			
		||||
 * Check all the possible undef or unpredict behavior, Some of them probably is
 | 
			
		||||
 * out-of-updated with the newer ISA.
 | 
			
		||||
 * -- Michael.Kang
 | 
			
		||||
 ********************************************************************************/
 | 
			
		||||
#define UNDEF_WARNING ERROR_LOG(ARM11, "undefined or unpredicted behavior for arm instruction.\n");
 | 
			
		||||
 | 
			
		||||
/* Macros to scrutinize instructions.  */
 | 
			
		||||
#define UNDEF_Test UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_Test
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_Shift UNDEF_WARNING
 | 
			
		||||
#define UNDEF_Shift
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_MSRPC UNDEF_WARNING
 | 
			
		||||
#define UNDEF_MSRPC
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_MRSPC UNDEF_WARNING
 | 
			
		||||
#define UNDEF_MRSPC
 | 
			
		||||
 | 
			
		||||
#define UNDEF_MULPCDest UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_MULPCDest
 | 
			
		||||
 | 
			
		||||
#define UNDEF_MULDestEQOp1 UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_MULDestEQOp1
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSRBPC UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSRBPC
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSRBaseEQOffWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSRBaseEQOffWb
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSRBaseEQDestWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSRBaseEQDestWb
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSRPCBaseWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSRPCBaseWb
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSRPCOffWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSRPCOffWb
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSMNoRegs UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSMNoRegs
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSMPCBase UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSMPCBase
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSMUserBankWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSMUserBankWb
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSMBaseInListWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSMBaseInListWb
 | 
			
		||||
 | 
			
		||||
#define UNDEF_SWPPC UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_SWPPC
 | 
			
		||||
 | 
			
		||||
#define UNDEF_CoProHS UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_CoProHS
 | 
			
		||||
 | 
			
		||||
#define UNDEF_MCRPC UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_MCRPC
 | 
			
		||||
 | 
			
		||||
//#define UNDEF_LSCPCBaseWb UNDEF_WARNING
 | 
			
		||||
#define UNDEF_LSCPCBaseWb
 | 
			
		||||
 | 
			
		||||
#define UNDEF_UndefNotBounced UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_UndefNotBounced
 | 
			
		||||
 | 
			
		||||
#define UNDEF_ShortInt UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_ShortInt
 | 
			
		||||
 | 
			
		||||
#define UNDEF_IllegalMode UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_IllegalMode
 | 
			
		||||
 | 
			
		||||
#define UNDEF_Prog32SigChange UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_Prog32SigChange
 | 
			
		||||
 | 
			
		||||
#define UNDEF_Data32SigChange UNDEF_WARNING
 | 
			
		||||
//#define UNDEF_Data32SigChange
 | 
			
		||||
 | 
			
		||||
/* Prototypes for exported functions.  */
 | 
			
		||||
extern unsigned ARMul_NthReg (ARMword, unsigned);
 | 
			
		||||
extern int AddOverflow (ARMword, ARMword, ARMword);
 | 
			
		||||
extern int SubOverflow (ARMword, ARMword, ARMword);
 | 
			
		||||
/* Prototypes for exported functions.  */
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
extern ARMword ARMul_Emulate26 (ARMul_State *);
 | 
			
		||||
extern ARMword ARMul_Emulate32 (ARMul_State *);
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 }
 | 
			
		||||
#endif
 | 
			
		||||
extern unsigned IntPending (ARMul_State *);
 | 
			
		||||
extern void ARMul_CPSRAltered (ARMul_State *);
 | 
			
		||||
extern void ARMul_R15Altered (ARMul_State *);
 | 
			
		||||
extern ARMword ARMul_GetPC (ARMul_State *);
 | 
			
		||||
extern ARMword ARMul_GetNextPC (ARMul_State *);
 | 
			
		||||
extern ARMword ARMul_GetR15 (ARMul_State *);
 | 
			
		||||
extern ARMword ARMul_GetCPSR (ARMul_State *);
 | 
			
		||||
extern void ARMul_EnvokeEvent (ARMul_State *);
 | 
			
		||||
extern unsigned int ARMul_Time (ARMul_State *);
 | 
			
		||||
extern void ARMul_NegZero (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_SetPC (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_SetR15 (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_SetCPSR (ARMul_State *, ARMword);
 | 
			
		||||
extern ARMword ARMul_GetSPSR (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_Abort26 (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_Abort32 (ARMul_State *, ARMword);
 | 
			
		||||
extern ARMword ARMul_MRC (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_MRRC (ARMul_State *, ARMword, ARMword *, ARMword *);
 | 
			
		||||
extern void ARMul_CDP (ARMul_State *, ARMword);
 | 
			
		||||
extern void ARMul_LDC (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_STC (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_MCR (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_MCRR (ARMul_State *, ARMword, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_SetSPSR (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern ARMword ARMul_Align (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern ARMword ARMul_SwitchMode (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_MSRCpsr (ARMul_State *, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_SubOverflow (ARMul_State *, ARMword, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_AddOverflow (ARMul_State *, ARMword, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_SubCarry (ARMul_State *, ARMword, ARMword, ARMword);
 | 
			
		||||
extern void ARMul_AddCarry (ARMul_State *, ARMword, ARMword, ARMword);
 | 
			
		||||
extern tdstate ARMul_ThumbDecode (ARMul_State *, ARMword, ARMword, ARMword *);
 | 
			
		||||
extern ARMword ARMul_GetReg (ARMul_State *, unsigned, unsigned);
 | 
			
		||||
extern void ARMul_SetReg (ARMul_State *, unsigned, unsigned, ARMword);
 | 
			
		||||
extern void ARMul_ScheduleEvent (ARMul_State *, unsigned int,
 | 
			
		||||
				 unsigned (*)(ARMul_State *));
 | 
			
		||||
/* Coprocessor support functions.  */
 | 
			
		||||
extern unsigned ARMul_CoProInit (ARMul_State *);
 | 
			
		||||
extern void ARMul_CoProExit (ARMul_State *);
 | 
			
		||||
extern void ARMul_CoProAttach (ARMul_State *, unsigned, ARMul_CPInits *,
 | 
			
		||||
			       ARMul_CPExits *, ARMul_LDCs *, ARMul_STCs *,
 | 
			
		||||
			       ARMul_MRCs *, ARMul_MCRs *, ARMul_MRRCs *, ARMul_MCRRs *, 
 | 
			
		||||
			       ARMul_CDPs *, ARMul_CPReads *, ARMul_CPWrites *);
 | 
			
		||||
extern void ARMul_CoProDetach (ARMul_State *, unsigned);
 | 
			
		||||
extern ARMword read_cp15_reg (unsigned, unsigned, unsigned);
 | 
			
		||||
 | 
			
		||||
extern unsigned DSPLDC4 (ARMul_State *, unsigned, ARMword, ARMword);
 | 
			
		||||
extern unsigned DSPMCR4 (ARMul_State *, unsigned, ARMword, ARMword);
 | 
			
		||||
extern unsigned DSPMRC4 (ARMul_State *, unsigned, ARMword, ARMword *);
 | 
			
		||||
extern unsigned DSPSTC4 (ARMul_State *, unsigned, ARMword, ARMword *);
 | 
			
		||||
extern unsigned DSPCDP4 (ARMul_State *, unsigned, ARMword);
 | 
			
		||||
extern unsigned DSPMCR5 (ARMul_State *, unsigned, ARMword, ARMword);
 | 
			
		||||
extern unsigned DSPMRC5 (ARMul_State *, unsigned, ARMword, ARMword *);
 | 
			
		||||
extern unsigned DSPLDC5 (ARMul_State *, unsigned, ARMword, ARMword);
 | 
			
		||||
extern unsigned DSPSTC5 (ARMul_State *, unsigned, ARMword, ARMword *);
 | 
			
		||||
extern unsigned DSPCDP5 (ARMul_State *, unsigned, ARMword);
 | 
			
		||||
extern unsigned DSPMCR6 (ARMul_State *, unsigned, ARMword, ARMword);
 | 
			
		||||
extern unsigned DSPMRC6 (ARMul_State *, unsigned, ARMword, ARMword *);
 | 
			
		||||
extern unsigned DSPCDP6 (ARMul_State *, unsigned, ARMword);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										579
									
								
								src/core/arm/interpreter/arminit.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										579
									
								
								src/core/arm/interpreter/arminit.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,579 @@
 | 
			
		||||
/*  arminit.c -- ARMulator initialization:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "platform.h"
 | 
			
		||||
#if EMU_PLATFORM == PLATFORM_LINUX
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include <math.h>
 | 
			
		||||
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
#include "armemu.h"
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                 Definitions for the emulator architecture                 *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void ARMul_EmulateInit (void);
 | 
			
		||||
ARMul_State *ARMul_NewState (ARMul_State * state);
 | 
			
		||||
void ARMul_Reset (ARMul_State * state);
 | 
			
		||||
ARMword ARMul_DoCycle (ARMul_State * state);
 | 
			
		||||
unsigned ARMul_DoCoPro (ARMul_State * state);
 | 
			
		||||
ARMword ARMul_DoProg (ARMul_State * state);
 | 
			
		||||
ARMword ARMul_DoInstr (ARMul_State * state);
 | 
			
		||||
void ARMul_Abort (ARMul_State * state, ARMword address);
 | 
			
		||||
 | 
			
		||||
unsigned ARMul_MultTable[32] =
 | 
			
		||||
	{ 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
 | 
			
		||||
	10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16
 | 
			
		||||
};
 | 
			
		||||
ARMword ARMul_ImmedTable[4096];	/* immediate DP LHS values */
 | 
			
		||||
char ARMul_BitList[256];	/* number of bits in a byte table */
 | 
			
		||||
 | 
			
		||||
//chy 2006-02-22 add test debugmode
 | 
			
		||||
extern int debugmode;
 | 
			
		||||
extern int remote_interrupt( void );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void arm_dyncom_Abort(ARMul_State * state, ARMword vector)
 | 
			
		||||
{
 | 
			
		||||
	ARMul_Abort(state, vector);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ahe-ykl : the following code to initialize user mode 
 | 
			
		||||
   code is architecture dependent and probably model dependant. */
 | 
			
		||||
 | 
			
		||||
//#include "skyeye_arch.h"
 | 
			
		||||
//#include "skyeye_pref.h"
 | 
			
		||||
//#include "skyeye_exec_info.h"
 | 
			
		||||
//#include "bank_defs.h"
 | 
			
		||||
#include "armcpu.h"
 | 
			
		||||
//#include "skyeye_callback.h"
 | 
			
		||||
 | 
			
		||||
//void arm_user_mode_init(generic_arch_t * arch_instance)
 | 
			
		||||
//{
 | 
			
		||||
//	sky_pref_t *pref = get_skyeye_pref();
 | 
			
		||||
//	
 | 
			
		||||
//	if (pref->user_mode_sim)
 | 
			
		||||
//	{
 | 
			
		||||
//		sky_exec_info_t *info = get_skyeye_exec_info();
 | 
			
		||||
//		info->arch_page_size = 0x1000;
 | 
			
		||||
//		info->arch_stack_top = 0x1ffffff0;// + 0x401fe7 - 0xff0; /* arbitrary value */
 | 
			
		||||
//		/* stack initial address specific to architecture may be placed here */
 | 
			
		||||
//		
 | 
			
		||||
//		/* we need to mmap the stack space, if we are using skyeye space */
 | 
			
		||||
//		if (info->mmap_access)
 | 
			
		||||
//		{
 | 
			
		||||
//			/* get system stack size */
 | 
			
		||||
//			size_t stacksize = 0;
 | 
			
		||||
//			pthread_attr_t attr;
 | 
			
		||||
//			pthread_attr_init(&attr);
 | 
			
		||||
//			pthread_attr_getstacksize(&attr, &stacksize);
 | 
			
		||||
//			if (stacksize > info->arch_stack_top)
 | 
			
		||||
//			{
 | 
			
		||||
//				printf("arch_stack_top is too low\n");
 | 
			
		||||
//				stacksize = info->arch_stack_top;
 | 
			
		||||
//			}
 | 
			
		||||
//			
 | 
			
		||||
//			/* Note: Skyeye is occupating 0x400000 to 0x600000 */
 | 
			
		||||
//			/* We do a mmap */
 | 
			
		||||
//			void* ret = mmap( (info->arch_stack_top) - stacksize, 
 | 
			
		||||
//				    stacksize + 0x1000 , PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
 | 
			
		||||
//			if (ret == MAP_FAILED){
 | 
			
		||||
//				/* ideally, we should find an empty space until it works */
 | 
			
		||||
//				printf("mmap error, stack couldn't be mapped: errno %d\n", errno);
 | 
			
		||||
//				exit(-1);
 | 
			
		||||
//			} else {
 | 
			
		||||
//				memset(ret, '\0', stacksize);
 | 
			
		||||
//				//printf("stack top has been defined at %x size %x\n", (uint32_t) ret + stacksize, stacksize);
 | 
			
		||||
//				//info->arch_stack_top = (uint32_t) ret + stacksize;
 | 
			
		||||
//			}
 | 
			
		||||
//		}
 | 
			
		||||
//
 | 
			
		||||
//		exec_stack_init();
 | 
			
		||||
//		
 | 
			
		||||
//		ARM_CPU_State* cpu = get_current_cpu();
 | 
			
		||||
//		arm_core_t* core = &cpu->core[0];
 | 
			
		||||
//
 | 
			
		||||
//		uint32_t sp = info->initial_sp;
 | 
			
		||||
//
 | 
			
		||||
//		core->Cpsr = 0x10; /* User mode */
 | 
			
		||||
//		/* FIXME: may need to add thumb */
 | 
			
		||||
//		core->Reg[13] = sp;
 | 
			
		||||
//		core->Reg[10] = info->start_data;
 | 
			
		||||
//		core->Reg[0] = 0;
 | 
			
		||||
//		bus_read(32, sp + 4, &(core->Reg[1]));
 | 
			
		||||
//		bus_read(32, sp + 8, &(core->Reg[2]));
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*         Call this routine once to set up the emulator's tables.           *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_EmulateInit (void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int i, j;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 4096; i++) {	/* the values of 12 bit dp rhs's */
 | 
			
		||||
		ARMul_ImmedTable[i] = ROTATER (i & 0xffL, (i >> 7L) & 0x1eL);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 256; ARMul_BitList[i++] = 0);	/* how many bits in LSM */
 | 
			
		||||
	for (j = 1; j < 256; j <<= 1)
 | 
			
		||||
		for (i = 0; i < 256; i++)
 | 
			
		||||
			if ((i & j) > 0)
 | 
			
		||||
				ARMul_BitList[i]++;
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < 256; i++)
 | 
			
		||||
		ARMul_BitList[i] *= 4;	/* you always need 4 times these values */
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*            Returns a new instantiation of the ARMulator's state           *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMul_State *
 | 
			
		||||
ARMul_NewState (ARMul_State *state)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i, j;
 | 
			
		||||
 | 
			
		||||
	memset (state, 0, sizeof (ARMul_State));
 | 
			
		||||
 | 
			
		||||
	state->Emulate = RUN;
 | 
			
		||||
	for (i = 0; i < 16; i++) {
 | 
			
		||||
		state->Reg[i] = 0;
 | 
			
		||||
		for (j = 0; j < 7; j++)
 | 
			
		||||
			state->RegBank[j][i] = 0;
 | 
			
		||||
	}
 | 
			
		||||
	for (i = 0; i < 7; i++)
 | 
			
		||||
		state->Spsr[i] = 0;
 | 
			
		||||
	state->Mode = 0;
 | 
			
		||||
 | 
			
		||||
	state->CallDebug = FALSE;
 | 
			
		||||
	state->Debug = FALSE;
 | 
			
		||||
	state->VectorCatch = 0;
 | 
			
		||||
	state->Aborted = FALSE;
 | 
			
		||||
	state->Reseted = FALSE;
 | 
			
		||||
	state->Inted = 3;
 | 
			
		||||
	state->LastInted = 3;
 | 
			
		||||
 | 
			
		||||
	state->CommandLine = NULL;
 | 
			
		||||
 | 
			
		||||
	state->EventSet = 0;
 | 
			
		||||
	state->Now = 0;
 | 
			
		||||
	state->EventPtr =
 | 
			
		||||
		(struct EventNode **) malloc ((unsigned) EVENTLISTSIZE *
 | 
			
		||||
					      sizeof (struct EventNode *));
 | 
			
		||||
#if DIFF_STATE
 | 
			
		||||
	state->state_log = fopen("/data/state.log", "w");
 | 
			
		||||
	printf("create pc log file.\n");
 | 
			
		||||
#endif
 | 
			
		||||
	if (state->EventPtr == NULL) {
 | 
			
		||||
		printf ("SKYEYE: ARMul_NewState malloc state->EventPtr error\n");
 | 
			
		||||
		exit(-1);
 | 
			
		||||
	}
 | 
			
		||||
	for (i = 0; i < EVENTLISTSIZE; i++)
 | 
			
		||||
		*(state->EventPtr + i) = NULL;
 | 
			
		||||
#if SAVE_LOG
 | 
			
		||||
	state->state_log = fopen("/tmp/state.log", "w");
 | 
			
		||||
	printf("create pc log file.\n");
 | 
			
		||||
#else
 | 
			
		||||
#if DIFF_LOG
 | 
			
		||||
	state->state_log = fopen("/tmp/state.log", "r");
 | 
			
		||||
	printf("loaded pc log file.\n");
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef ARM61
 | 
			
		||||
	state->prog32Sig = LOW;
 | 
			
		||||
	state->data32Sig = LOW;
 | 
			
		||||
#else
 | 
			
		||||
	state->prog32Sig = HIGH;
 | 
			
		||||
	state->data32Sig = HIGH;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	state->lateabtSig = HIGH;
 | 
			
		||||
	state->bigendSig = LOW;
 | 
			
		||||
 | 
			
		||||
	//chy:2003-08-19 
 | 
			
		||||
	state->LastTime = 0;
 | 
			
		||||
	state->CP14R0_CCD = -1;
 | 
			
		||||
	
 | 
			
		||||
	/* ahe-ykl: common function for interpret and dyncom */
 | 
			
		||||
	//sky_pref_t *pref = get_skyeye_pref();
 | 
			
		||||
	//if (pref->user_mode_sim)
 | 
			
		||||
	//	register_callback(arm_user_mode_init, Bootmach_callback);
 | 
			
		||||
 | 
			
		||||
	memset(&state->exclusive_tag_array[0], 0xFF, sizeof(state->exclusive_tag_array[0]) * 128);
 | 
			
		||||
	state->exclusive_access_state = 0;
 | 
			
		||||
	//state->cpu = (cpu_config_t *) malloc (sizeof (cpu_config_t));
 | 
			
		||||
	//state->mem_bank = (mem_config_t *) malloc (sizeof (mem_config_t));
 | 
			
		||||
	return (state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*       Call this routine to set ARMulator to model a certain processor     *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SelectProcessor (ARMul_State * state, unsigned properties)
 | 
			
		||||
{
 | 
			
		||||
	if (properties & ARM_Fix26_Prop) {
 | 
			
		||||
		state->prog32Sig = LOW;
 | 
			
		||||
		state->data32Sig = LOW;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		state->prog32Sig = HIGH;
 | 
			
		||||
		state->data32Sig = HIGH;
 | 
			
		||||
	}
 | 
			
		||||
/* 2004-05-09 chy
 | 
			
		||||
below line sould be in skyeye_mach_XXX.c 's XXX_mach_init function
 | 
			
		||||
*/
 | 
			
		||||
	// state->lateabtSig = HIGH;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	state->is_v4 =
 | 
			
		||||
		(properties & (ARM_v4_Prop | ARM_v5_Prop)) ? HIGH : LOW;
 | 
			
		||||
	state->is_v5 = (properties & ARM_v5_Prop) ? HIGH : LOW;
 | 
			
		||||
	state->is_v5e = (properties & ARM_v5e_Prop) ? HIGH : LOW;
 | 
			
		||||
	state->is_XScale = (properties & ARM_XScale_Prop) ? HIGH : LOW;
 | 
			
		||||
	state->is_iWMMXt = (properties & ARM_iWMMXt_Prop) ? HIGH : LOW;
 | 
			
		||||
	/* state->is_v6 = LOW */;
 | 
			
		||||
	/* jeff.du 2010-08-05 */
 | 
			
		||||
	state->is_v6 = (properties & ARM_v6_Prop) ? HIGH : LOW;
 | 
			
		||||
	state->is_ep9312 = (properties & ARM_ep9312_Prop) ? HIGH : LOW;
 | 
			
		||||
	//chy 2005-09-19
 | 
			
		||||
	state->is_pxa27x = (properties & ARM_PXA27X_Prop) ? HIGH : LOW;
 | 
			
		||||
 | 
			
		||||
	/* shenoubang 2012-3-11 */
 | 
			
		||||
	state->is_v7 = (properties & ARM_v7_Prop) ? HIGH : LOW;
 | 
			
		||||
 | 
			
		||||
	/* Only initialse the coprocessor support once we
 | 
			
		||||
	   know what kind of chip we are dealing with.  */
 | 
			
		||||
	//ARMul_CoProInit (state); Commented out /bunnei
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
* Call this routine to set up the initial machine state (or perform a RESET *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_Reset (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	//fprintf(stderr,"armul_reset 0: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
	state->NextInstr = 0;
 | 
			
		||||
	if (state->prog32Sig) {
 | 
			
		||||
		state->Reg[15] = 0;
 | 
			
		||||
		state->Cpsr = INTBITS | SVC32MODE;
 | 
			
		||||
		state->Mode = SVC32MODE;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		state->Reg[15] = R15INTBITS | SVC26MODE;
 | 
			
		||||
		state->Cpsr = INTBITS | SVC26MODE;
 | 
			
		||||
		state->Mode = SVC26MODE;
 | 
			
		||||
	}
 | 
			
		||||
	//fprintf(stderr,"armul_reset 1: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
	ARMul_CPSRAltered (state);
 | 
			
		||||
	state->Bank = SVCBANK;
 | 
			
		||||
	FLUSHPIPE;
 | 
			
		||||
 | 
			
		||||
	state->EndCondition = 0;
 | 
			
		||||
	state->ErrorCode = 0;
 | 
			
		||||
 | 
			
		||||
	//fprintf(stderr,"armul_reset 2: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
	state->NresetSig = HIGH;
 | 
			
		||||
	state->NfiqSig = HIGH;
 | 
			
		||||
	state->NirqSig = HIGH;
 | 
			
		||||
	state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
 | 
			
		||||
	state->abortSig = LOW;
 | 
			
		||||
	state->AbortAddr = 1;
 | 
			
		||||
 | 
			
		||||
	state->NumInstrs = 0;
 | 
			
		||||
	state->NumNcycles = 0;
 | 
			
		||||
	state->NumScycles = 0;
 | 
			
		||||
	state->NumIcycles = 0;
 | 
			
		||||
	state->NumCcycles = 0;
 | 
			
		||||
	state->NumFcycles = 0;
 | 
			
		||||
 | 
			
		||||
	//fprintf(stderr,"armul_reset 3: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
	//mmu_reset (state); Commented out /bunnei
 | 
			
		||||
	//fprintf(stderr,"armul_reset 4: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
 | 
			
		||||
	//mem_reset (state); /* move to memory/ram.c */
 | 
			
		||||
 | 
			
		||||
	//fprintf(stderr,"armul_reset 5: state->  Cpsr 0x%x, Mode %d\n",state->Cpsr,state->Mode);  
 | 
			
		||||
	/*remove later. walimis 03.7.17 */
 | 
			
		||||
	//io_reset(state);
 | 
			
		||||
	//lcd_disable(state);
 | 
			
		||||
 | 
			
		||||
	/*ywc 2005-04-07 move from ARMul_NewState , because skyeye_config.no_dbct will
 | 
			
		||||
	 *be configured in skyeye_option_init and it is called after ARMul_NewState*/
 | 
			
		||||
	state->tea_break_ok = 0;
 | 
			
		||||
	state->tea_break_addr = 0;
 | 
			
		||||
	state->tea_pc = 0;
 | 
			
		||||
#ifdef DBCT
 | 
			
		||||
	if (!skyeye_config.no_dbct) {
 | 
			
		||||
		//teawater add for arm2x86 2005.02.14-------------------------------------------
 | 
			
		||||
		if (arm2x86_init (state)) {
 | 
			
		||||
			printf ("SKYEYE: arm2x86_init error\n");
 | 
			
		||||
			skyeye_exit (-1);
 | 
			
		||||
		}
 | 
			
		||||
		//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
* Emulate the execution of an entire program.  Start the correct emulator   *
 | 
			
		||||
* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the   *
 | 
			
		||||
* address of the last instruction that is executed.                         *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
 | 
			
		||||
#ifdef DBCT_TEST_SPEED
 | 
			
		||||
static ARMul_State	*dbct_test_speed_state = NULL;
 | 
			
		||||
static void
 | 
			
		||||
dbct_test_speed_sig(int signo)
 | 
			
		||||
{
 | 
			
		||||
	printf("\n0x%llx %llu\n", dbct_test_speed_state->instr_count, dbct_test_speed_state->instr_count);
 | 
			
		||||
	skyeye_exit(0);
 | 
			
		||||
}
 | 
			
		||||
#endif	//DBCT_TEST_SPEED
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_DoProg (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	ARMword pc = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 2007-01-24 removed the term-io functions by Anthony Lee,
 | 
			
		||||
	 * moved to "device/uart/skyeye_uart_stdio.c".
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
//teawater add DBCT_TEST_SPEED 2005.10.04---------------------------------------
 | 
			
		||||
#ifdef DBCT_TEST_SPEED
 | 
			
		||||
	{
 | 
			
		||||
		if (!dbct_test_speed_state) {
 | 
			
		||||
			//init timer
 | 
			
		||||
			struct itimerval	value;
 | 
			
		||||
			struct sigaction	act;
 | 
			
		||||
 | 
			
		||||
			dbct_test_speed_state = state;
 | 
			
		||||
			state->instr_count = 0;
 | 
			
		||||
			act.sa_handler = dbct_test_speed_sig;
 | 
			
		||||
			act.sa_flags = SA_RESTART;
 | 
			
		||||
			//cygwin don't support ITIMER_VIRTUAL or ITIMER_PROF
 | 
			
		||||
#ifndef __CYGWIN__
 | 
			
		||||
			if (sigaction(SIGVTALRM, &act, NULL) == -1) {
 | 
			
		||||
#else
 | 
			
		||||
			if (sigaction(SIGALRM, &act, NULL) == -1) {
 | 
			
		||||
#endif	//__CYGWIN__
 | 
			
		||||
				fprintf(stderr, "init timer error.\n");
 | 
			
		||||
				skyeye_exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
			if (skyeye_config.dbct_test_speed_sec) {
 | 
			
		||||
				value.it_value.tv_sec = skyeye_config.dbct_test_speed_sec;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				value.it_value.tv_sec = DBCT_TEST_SPEED_SEC;
 | 
			
		||||
			}
 | 
			
		||||
			printf("dbct_test_speed_sec = %ld\n", value.it_value.tv_sec);
 | 
			
		||||
			value.it_value.tv_usec = 0;
 | 
			
		||||
			value.it_interval.tv_sec = 0; 
 | 
			
		||||
			value.it_interval.tv_usec = 0;
 | 
			
		||||
#ifndef __CYGWIN__
 | 
			
		||||
			if (setitimer(ITIMER_VIRTUAL, &value, NULL) == -1) {
 | 
			
		||||
#else
 | 
			
		||||
			if (setitimer(ITIMER_REAL, &value, NULL) == -1) {
 | 
			
		||||
#endif	//__CYGWIN__
 | 
			
		||||
				fprintf(stderr, "init timer error.\n");
 | 
			
		||||
				skyeye_exit(-1);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
#endif	//DBCT_TEST_SPEED
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
	state->Emulate = RUN;
 | 
			
		||||
	while (state->Emulate != STOP) {
 | 
			
		||||
		state->Emulate = RUN;
 | 
			
		||||
 | 
			
		||||
		/*ywc 2005-03-31 */
 | 
			
		||||
		if (state->prog32Sig && ARMul_MODE32BIT) {
 | 
			
		||||
#ifdef DBCT
 | 
			
		||||
			if (skyeye_config.no_dbct) {
 | 
			
		||||
				pc = ARMul_Emulate32 (state);
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				pc = ARMul_Emulate32_dbct (state);
 | 
			
		||||
			}
 | 
			
		||||
#else
 | 
			
		||||
			pc = ARMul_Emulate32 (state);
 | 
			
		||||
#endif
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		else {
 | 
			
		||||
			_dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!");
 | 
			
		||||
		}
 | 
			
		||||
		//chy 2006-02-22, should test debugmode first
 | 
			
		||||
		//chy 2006-04-14, put below codes in ARMul_Emulate
 | 
			
		||||
#if 0
 | 
			
		||||
		if(debugmode)
 | 
			
		||||
		  if(remote_interrupt())
 | 
			
		||||
			state->Emulate = STOP;
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * 2007-01-24 removed the term-io functions by Anthony Lee,
 | 
			
		||||
	 * moved to "device/uart/skyeye_uart_stdio.c".
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	return (pc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
* Emulate the execution of one instruction.  Start the correct emulator     *
 | 
			
		||||
* (Emulate26 for a 26 bit ARM and Emulate32 for a 32 bit ARM), return the   *
 | 
			
		||||
* address of the instruction that is executed.                              *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_DoInstr (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	ARMword pc = 0;
 | 
			
		||||
 | 
			
		||||
	state->Emulate = ONCE;
 | 
			
		||||
 | 
			
		||||
	/*ywc 2005-03-31 */
 | 
			
		||||
	if (state->prog32Sig && ARMul_MODE32BIT) {
 | 
			
		||||
#ifdef DBCT
 | 
			
		||||
		if (skyeye_config.no_dbct) {
 | 
			
		||||
			pc = ARMul_Emulate32 (state);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
//teawater add compile switch for DBCT GDB RSP function 2005.10.21--------------
 | 
			
		||||
#ifndef DBCT_GDBRSP
 | 
			
		||||
			printf("DBCT GDBRSP function switch is off.\n");
 | 
			
		||||
			printf("To use this function, open \"#define DBCT_GDBRSP\" in arch/arm/common/armdefs.h & recompile skyeye.\n");
 | 
			
		||||
			skyeye_exit(-1);
 | 
			
		||||
#endif	//DBCT_GDBRSP
 | 
			
		||||
//AJ2D--------------------------------------------------------------------------
 | 
			
		||||
			pc = ARMul_Emulate32_dbct (state);
 | 
			
		||||
		}
 | 
			
		||||
#else
 | 
			
		||||
		pc = ARMul_Emulate32 (state);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	else {
 | 
			
		||||
		_dbg_assert_msg_(ARM11, false, "Unsupported ARM 26-bit Mode!");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (pc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
* This routine causes an Abort to occur, including selecting the correct    *
 | 
			
		||||
* mode, register bank, and the saving of registers.  Call with the          *
 | 
			
		||||
* appropriate vector's memory address (0,4,8 ....)                          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_Abort (ARMul_State * state, ARMword vector)
 | 
			
		||||
{
 | 
			
		||||
	ARMword temp;
 | 
			
		||||
	int isize = INSN_SIZE;
 | 
			
		||||
	int esize = (TFLAG ? 0 : 4);
 | 
			
		||||
	int e2size = (TFLAG ? -4 : 0);
 | 
			
		||||
 | 
			
		||||
	state->Aborted = FALSE;
 | 
			
		||||
 | 
			
		||||
	if (state->prog32Sig)
 | 
			
		||||
		if (ARMul_MODE26BIT)
 | 
			
		||||
			temp = R15PC;
 | 
			
		||||
		else
 | 
			
		||||
			temp = state->Reg[15];
 | 
			
		||||
	else
 | 
			
		||||
		temp = R15PC | ECC | ER15INT | EMODE;
 | 
			
		||||
 | 
			
		||||
	switch (vector) {
 | 
			
		||||
	case ARMul_ResetV:	/* RESET */
 | 
			
		||||
		SETABORT (INTBITS, state->prog32Sig ? SVC32MODE : SVC26MODE,
 | 
			
		||||
			  0);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_UndefinedInstrV:	/* Undefined Instruction */
 | 
			
		||||
		SETABORT (IBIT, state->prog32Sig ? UNDEF32MODE : SVC26MODE,
 | 
			
		||||
			  isize);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_SWIV:	/* Software Interrupt */
 | 
			
		||||
		SETABORT (IBIT, state->prog32Sig ? SVC32MODE : SVC26MODE,
 | 
			
		||||
			  isize);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_PrefetchAbortV:	/* Prefetch Abort */
 | 
			
		||||
		state->AbortAddr = 1;
 | 
			
		||||
		SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
 | 
			
		||||
			  esize);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_DataAbortV:	/* Data Abort */
 | 
			
		||||
		SETABORT (IBIT, state->prog32Sig ? ABORT32MODE : SVC26MODE,
 | 
			
		||||
			  e2size);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_AddrExceptnV:	/* Address Exception */
 | 
			
		||||
		SETABORT (IBIT, SVC26MODE, isize);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_IRQV:	/* IRQ */
 | 
			
		||||
		//chy 2003-09-02 the if sentence seems no use
 | 
			
		||||
#if 0
 | 
			
		||||
		if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
 | 
			
		||||
		    || (temp & ARMul_CP13_R0_IRQ))
 | 
			
		||||
#endif
 | 
			
		||||
			SETABORT (IBIT,
 | 
			
		||||
				  state->prog32Sig ? IRQ32MODE : IRQ26MODE,
 | 
			
		||||
				  esize);
 | 
			
		||||
		break;
 | 
			
		||||
	case ARMul_FIQV:	/* FIQ */
 | 
			
		||||
		//chy 2003-09-02 the if sentence seems no use
 | 
			
		||||
#if 0
 | 
			
		||||
		if (!state->is_XScale || !state->CPRead[13] (state, 0, &temp)
 | 
			
		||||
		    || (temp & ARMul_CP13_R0_FIQ))
 | 
			
		||||
#endif
 | 
			
		||||
			SETABORT (INTBITS,
 | 
			
		||||
				  state->prog32Sig ? FIQ32MODE : FIQ26MODE,
 | 
			
		||||
				  esize);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ARMul_MODE32BIT) {
 | 
			
		||||
		if (state->mmu.control & CONTROL_VECTOR)
 | 
			
		||||
			vector += 0xffff0000;	//for v4 high exception  address
 | 
			
		||||
		if (state->vector_remap_flag)
 | 
			
		||||
			vector += state->vector_remap_addr; /* support some remap function in LPC processor */
 | 
			
		||||
		ARMul_SetR15 (state, vector);
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
		ARMul_SetR15 (state, R15CCINTMODE | vector);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										238
									
								
								src/core/arm/interpreter/armmmu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										238
									
								
								src/core/arm/interpreter/armmmu.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,238 @@
 | 
			
		||||
/*
 | 
			
		||||
    armmmu.c - Memory Management Unit emulation.
 | 
			
		||||
    ARMulator extensions for the ARM7100 family.
 | 
			
		||||
    Copyright (C) 1999  Ben Williamson
 | 
			
		||||
 | 
			
		||||
    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
/* two header for arm disassemble */
 | 
			
		||||
//#include "skyeye_arch.h"
 | 
			
		||||
#include "armcpu.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
extern mmu_ops_t xscale_mmu_ops;
 | 
			
		||||
exception_t arm_mmu_write(short size, u32 addr, uint32_t *value);
 | 
			
		||||
exception_t arm_mmu_read(short size, u32 addr, uint32_t *value);
 | 
			
		||||
#define MMU_OPS (state->mmu.ops)
 | 
			
		||||
ARMword skyeye_cachetype = -1;
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
mmu_init (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	state->mmu.control = 0x70;
 | 
			
		||||
	state->mmu.translation_table_base = 0xDEADC0DE;
 | 
			
		||||
	state->mmu.domain_access_control = 0xDEADC0DE;
 | 
			
		||||
	state->mmu.fault_status = 0;
 | 
			
		||||
	state->mmu.fault_address = 0;
 | 
			
		||||
	state->mmu.process_id = 0;
 | 
			
		||||
 | 
			
		||||
	switch (state->cpu->cpu_val & state->cpu->cpu_mask) {
 | 
			
		||||
	//case SA1100:
 | 
			
		||||
	//case SA1110:
 | 
			
		||||
	//	NOTICE_LOG(ARM11, "SKYEYE: use sa11xx mmu ops\n");
 | 
			
		||||
	//	state->mmu.ops = sa_mmu_ops;
 | 
			
		||||
	//	break;
 | 
			
		||||
	//case PXA250:
 | 
			
		||||
	//case PXA270:		//xscale
 | 
			
		||||
	//	NOTICE_LOG(ARM11, "SKYEYE: use xscale mmu ops\n");
 | 
			
		||||
	//	state->mmu.ops = xscale_mmu_ops;
 | 
			
		||||
	//	break;
 | 
			
		||||
	//case 0x41807200:	//arm720t
 | 
			
		||||
	//case 0x41007700:	//arm7tdmi
 | 
			
		||||
	//case 0x41007100:	//arm7100
 | 
			
		||||
	//	NOTICE_LOG(ARM11,  "SKYEYE: use arm7100 mmu ops\n");
 | 
			
		||||
	//	state->mmu.ops = arm7100_mmu_ops;
 | 
			
		||||
	//	break;
 | 
			
		||||
	//case 0x41009200:
 | 
			
		||||
	//	NOTICE_LOG(ARM11, "SKYEYE: use arm920t mmu ops\n");
 | 
			
		||||
	//	state->mmu.ops = arm920t_mmu_ops;
 | 
			
		||||
	//	break;
 | 
			
		||||
	//case 0x41069260:
 | 
			
		||||
	//	NOTICE_LOG(ARM11, "SKYEYE: use arm926ejs mmu ops\n");
 | 
			
		||||
	//	state->mmu.ops = arm926ejs_mmu_ops;
 | 
			
		||||
	//	break;
 | 
			
		||||
	/* case 0x560f5810: */
 | 
			
		||||
	case 0x0007b000:
 | 
			
		||||
		NOTICE_LOG(ARM11, "SKYEYE: use arm11jzf-s mmu ops\n");
 | 
			
		||||
		state->mmu.ops = arm1176jzf_s_mmu_ops;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		ERROR_LOG (ARM11,
 | 
			
		||||
			 "SKYEYE: armmmu.c : mmu_init: unknown cpu_val&cpu_mask 0x%x\n",
 | 
			
		||||
			 state->cpu->cpu_val & state->cpu->cpu_mask);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	};
 | 
			
		||||
	ret = state->mmu.ops.init (state);
 | 
			
		||||
	state->mmu_inited = (ret == 0);
 | 
			
		||||
	/* initialize mmu_read and mmu_write for disassemble */
 | 
			
		||||
	//skyeye_config_t *config  = get_current_config();
 | 
			
		||||
	//generic_arch_t *arch_instance = get_arch_instance(config->arch->arch_name);
 | 
			
		||||
	//arch_instance->mmu_read = arm_mmu_read;
 | 
			
		||||
	//arch_instance->mmu_write = arm_mmu_write;
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
mmu_reset (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	if (state->mmu_inited)
 | 
			
		||||
		mmu_exit (state);
 | 
			
		||||
	return mmu_init (state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mmu_exit (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	MMU_OPS.exit (state);
 | 
			
		||||
	state->mmu_inited = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	return MMU_OPS.read_byte (state, virt_addr, data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	return MMU_OPS.read_halfword (state, virt_addr, data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	return MMU_OPS.read_word (state, virt_addr, data);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	//static int count = 0;
 | 
			
		||||
	//count ++;
 | 
			
		||||
	fault = MMU_OPS.write_byte (state, virt_addr, data);
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	//static int count = 0;
 | 
			
		||||
	//count ++;
 | 
			
		||||
	fault = MMU_OPS.write_halfword (state, virt_addr, data);
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	fault = MMU_OPS.write_word (state, virt_addr, data);
 | 
			
		||||
 | 
			
		||||
	/*used for debug for MMU*
 | 
			
		||||
 | 
			
		||||
	   if (!fault){
 | 
			
		||||
	   ARMword tmp;
 | 
			
		||||
 | 
			
		||||
	   if (mmu_read_word(state, virt_addr, &tmp)){
 | 
			
		||||
	   err_msg("load back\n");
 | 
			
		||||
	   exit(-1);
 | 
			
		||||
	   }else{
 | 
			
		||||
	   if (tmp != data){
 | 
			
		||||
	   err_msg("load back not equal %d %x\n", count, virt_addr);
 | 
			
		||||
	   }
 | 
			
		||||
	   }
 | 
			
		||||
	   }
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	return fault;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_load_instr (ARMul_State * state, ARMword virt_addr, ARMword * instr)
 | 
			
		||||
{
 | 
			
		||||
	return MMU_OPS.load_instr (state, virt_addr, instr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value)
 | 
			
		||||
{
 | 
			
		||||
	return MMU_OPS.mrc (state, instr, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mmu_mcr (ARMul_State * state, ARMword instr, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	MMU_OPS.mcr (state, instr, value);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*ywc 20050416*/
 | 
			
		||||
int
 | 
			
		||||
mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr, ARMword * phys_addr)
 | 
			
		||||
{
 | 
			
		||||
	return (MMU_OPS.v2p_dbct (state, virt_addr, phys_addr));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
//
 | 
			
		||||
///* dis_mmu_read for disassemble */
 | 
			
		||||
//exception_t arm_mmu_read(short size, uint32_t addr, uint32_t * value)
 | 
			
		||||
//{
 | 
			
		||||
//	ARMul_State *state;
 | 
			
		||||
//	ARM_CPU_State *cpu = get_current_cpu();
 | 
			
		||||
//	state = &cpu->core[0];
 | 
			
		||||
//	switch(size){
 | 
			
		||||
//	case 8:
 | 
			
		||||
//		MMU_OPS.read_byte (state, addr, value);
 | 
			
		||||
//		break;
 | 
			
		||||
//	case 16:
 | 
			
		||||
//	case 32:
 | 
			
		||||
//		break;
 | 
			
		||||
//	default:
 | 
			
		||||
//		ERROR_LOG(ARM11, "Error size %d", size);
 | 
			
		||||
//		break;
 | 
			
		||||
//	}
 | 
			
		||||
//	return No_exp;
 | 
			
		||||
//}
 | 
			
		||||
///* dis_mmu_write for disassemble */
 | 
			
		||||
//exception_t arm_mmu_write(short size, uint32_t addr, uint32_t *value)
 | 
			
		||||
//{
 | 
			
		||||
//	ARMul_State *state;
 | 
			
		||||
//	ARM_CPU_State *cpu = get_current_cpu();
 | 
			
		||||
//		state = &cpu->core[0];
 | 
			
		||||
//	switch(size){
 | 
			
		||||
//	case 8:
 | 
			
		||||
//		MMU_OPS.write_byte (state, addr, value);
 | 
			
		||||
//		break;
 | 
			
		||||
//	case 16:
 | 
			
		||||
//	case 32:
 | 
			
		||||
//		break;
 | 
			
		||||
//	default:
 | 
			
		||||
//		printf("In %s error size %d Line %d\n", __func__, size, __LINE__);
 | 
			
		||||
//		break;
 | 
			
		||||
//	}
 | 
			
		||||
//	return No_exp;
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										254
									
								
								src/core/arm/interpreter/armmmu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								src/core/arm/interpreter/armmmu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,254 @@
 | 
			
		||||
/*
 | 
			
		||||
    armmmu.c - Memory Management Unit emulation.
 | 
			
		||||
    ARMulator extensions for the ARM7100 family.
 | 
			
		||||
    Copyright (C) 1999  Ben Williamson
 | 
			
		||||
 | 
			
		||||
    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _ARMMMU_H_
 | 
			
		||||
#define _ARMMMU_H_
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define WORD_SHT			2
 | 
			
		||||
#define WORD_SIZE			(1<<WORD_SHT)
 | 
			
		||||
/* The MMU is accessible with MCR and MRC operations to copro 15: */
 | 
			
		||||
 | 
			
		||||
#define MMU_COPRO			(15)
 | 
			
		||||
 | 
			
		||||
/* Register numbers in the MMU: */
 | 
			
		||||
 | 
			
		||||
typedef enum mmu_regnum_t
 | 
			
		||||
{
 | 
			
		||||
	MMU_ID = 0,
 | 
			
		||||
	MMU_CONTROL = 1,
 | 
			
		||||
	MMU_TRANSLATION_TABLE_BASE = 2,
 | 
			
		||||
	MMU_DOMAIN_ACCESS_CONTROL = 3,
 | 
			
		||||
	MMU_FAULT_STATUS = 5,
 | 
			
		||||
	MMU_FAULT_ADDRESS = 6,
 | 
			
		||||
	MMU_CACHE_OPS = 7,
 | 
			
		||||
	MMU_TLB_OPS = 8,
 | 
			
		||||
	MMU_CACHE_LOCKDOWN = 9,
 | 
			
		||||
	MMU_TLB_LOCKDOWN = 10,
 | 
			
		||||
	MMU_PID = 13,
 | 
			
		||||
 | 
			
		||||
	/*MMU_V4 */
 | 
			
		||||
	MMU_V4_CACHE_OPS = 7,
 | 
			
		||||
	MMU_V4_TLB_OPS = 8,
 | 
			
		||||
 | 
			
		||||
	/*MMU_V3 */
 | 
			
		||||
	MMU_V3_FLUSH_TLB = 5,
 | 
			
		||||
	MMU_V3_FLUSH_TLB_ENTRY = 6,
 | 
			
		||||
	MMU_V3_FLUSH_CACHE = 7,
 | 
			
		||||
 | 
			
		||||
	/*MMU Intel SA-1100 */
 | 
			
		||||
	MMU_SA_RB_OPS = 9,
 | 
			
		||||
	MMU_SA_DEBUG = 14,
 | 
			
		||||
	MMU_SA_CP15_R15 = 15,
 | 
			
		||||
	//chy 2003-08-24
 | 
			
		||||
	/*Intel xscale CP15 */
 | 
			
		||||
	XSCALE_CP15_CACHE_TYPE = 0,
 | 
			
		||||
	XSCALE_CP15_AUX_CONTROL = 1,
 | 
			
		||||
	XSCALE_CP15_COPRO_ACCESS = 15,
 | 
			
		||||
 | 
			
		||||
} mmu_regnum_t;
 | 
			
		||||
 | 
			
		||||
/* Bits in the control register */
 | 
			
		||||
 | 
			
		||||
#define CONTROL_MMU			(1<<0)
 | 
			
		||||
#define CONTROL_ALIGN_FAULT		(1<<1)
 | 
			
		||||
#define CONTROL_CACHE			(1<<2)
 | 
			
		||||
#define CONTROL_DATA_CACHE		(1<<2)
 | 
			
		||||
#define CONTROL_WRITE_BUFFER		(1<<3)
 | 
			
		||||
#define CONTROL_BIG_ENDIAN		(1<<7)
 | 
			
		||||
#define CONTROL_SYSTEM			(1<<8)
 | 
			
		||||
#define CONTROL_ROM			(1<<9)
 | 
			
		||||
#define CONTROL_UNDEFINED               (1<<10)
 | 
			
		||||
#define CONTROL_BRANCH_PREDICT          (1<<11)
 | 
			
		||||
#define CONTROL_INSTRUCTION_CACHE       (1<<12)
 | 
			
		||||
#define CONTROL_VECTOR                  (1<<13)
 | 
			
		||||
#define CONTROL_RR                      (1<<14)
 | 
			
		||||
#define CONTROL_L4                      (1<<15)
 | 
			
		||||
#define CONTROL_XP                      (1<<23)
 | 
			
		||||
#define CONTROL_EE                      (1<<25)
 | 
			
		||||
 | 
			
		||||
/*Macro defines for MMU state*/
 | 
			
		||||
#define MMU_CTL (state->mmu.control)
 | 
			
		||||
#define MMU_Enabled (state->mmu.control & CONTROL_MMU)
 | 
			
		||||
#define MMU_Disabled (!(MMU_Enabled))
 | 
			
		||||
#define MMU_Aligned (state->mmu.control & CONTROL_ALIGN_FAULT)
 | 
			
		||||
 | 
			
		||||
#define MMU_ICacheEnabled (MMU_CTL & CONTROL_INSTRUCTION_CACHE)
 | 
			
		||||
#define MMU_ICacheDisabled (!(MMU_ICacheDisabled))
 | 
			
		||||
 | 
			
		||||
#define MMU_DCacheEnabled (MMU_CTL & CONTROL_DATA_CACHE)
 | 
			
		||||
#define MMU_DCacheDisabled (!(MMU_DCacheEnabled))
 | 
			
		||||
 | 
			
		||||
#define MMU_CacheEnabled (MMU_CTL & CONTROL_CACHE)
 | 
			
		||||
#define MMU_CacheDisabled (!(MMU_CacheEnabled))
 | 
			
		||||
 | 
			
		||||
#define MMU_WBEnabled (MMU_CTL & CONTROL_WRITE_BUFFER)
 | 
			
		||||
#define MMU_WBDisabled (!(MMU_WBEnabled))
 | 
			
		||||
 | 
			
		||||
/*virt_addr exchange according to CP15.R13(process id virtul mapping)*/
 | 
			
		||||
#define PID_VA_MAP_MASK	0xfe000000
 | 
			
		||||
//#define mmu_pid_va_map(va) ({\
 | 
			
		||||
//	ARMword ret; \
 | 
			
		||||
//	if ((va) & PID_VA_MAP_MASK)\
 | 
			
		||||
//		ret = (va); \
 | 
			
		||||
//	else \
 | 
			
		||||
//		ret = ((va) | (state->mmu.process_id & PID_VA_MAP_MASK));\
 | 
			
		||||
//	ret;\
 | 
			
		||||
//})
 | 
			
		||||
#define mmu_pid_va_map(va) ((va) & PID_VA_MAP_MASK) ? (va) : ((va) | (state->mmu.process_id & PID_VA_MAP_MASK))
 | 
			
		||||
 | 
			
		||||
/* FS[3:0] in the fault status register: */
 | 
			
		||||
 | 
			
		||||
typedef enum fault_t
 | 
			
		||||
{
 | 
			
		||||
	NO_FAULT = 0x0,
 | 
			
		||||
	ALIGNMENT_FAULT = 0x1,
 | 
			
		||||
 | 
			
		||||
	SECTION_TRANSLATION_FAULT = 0x5,
 | 
			
		||||
	PAGE_TRANSLATION_FAULT = 0x7,
 | 
			
		||||
	SECTION_DOMAIN_FAULT = 0x9,
 | 
			
		||||
	PAGE_DOMAIN_FAULT = 0xB,
 | 
			
		||||
	SECTION_PERMISSION_FAULT = 0xD,
 | 
			
		||||
	SUBPAGE_PERMISSION_FAULT = 0xF,
 | 
			
		||||
 | 
			
		||||
	/* defined by skyeye */
 | 
			
		||||
	TLB_READ_MISS = 0x30,
 | 
			
		||||
	TLB_WRITE_MISS = 0x40,
 | 
			
		||||
 | 
			
		||||
} fault_t;
 | 
			
		||||
 | 
			
		||||
typedef struct mmu_ops_s
 | 
			
		||||
{
 | 
			
		||||
	/*initilization */
 | 
			
		||||
	int (*init) (ARMul_State * state);
 | 
			
		||||
	/*free on exit */
 | 
			
		||||
	void (*exit) (ARMul_State * state);
 | 
			
		||||
	/*read byte data */
 | 
			
		||||
	  fault_t (*read_byte) (ARMul_State * state, ARMword va,
 | 
			
		||||
				ARMword * data);
 | 
			
		||||
	/*write byte data */
 | 
			
		||||
	  fault_t (*write_byte) (ARMul_State * state, ARMword va,
 | 
			
		||||
				 ARMword data);
 | 
			
		||||
	/*read halfword data */
 | 
			
		||||
	  fault_t (*read_halfword) (ARMul_State * state, ARMword va,
 | 
			
		||||
				    ARMword * data);
 | 
			
		||||
	/*write halfword data */
 | 
			
		||||
	  fault_t (*write_halfword) (ARMul_State * state, ARMword va,
 | 
			
		||||
				     ARMword data);
 | 
			
		||||
	/*read word data */
 | 
			
		||||
	  fault_t (*read_word) (ARMul_State * state, ARMword va,
 | 
			
		||||
				ARMword * data);
 | 
			
		||||
	/*write word data */
 | 
			
		||||
	  fault_t (*write_word) (ARMul_State * state, ARMword va,
 | 
			
		||||
				 ARMword data);
 | 
			
		||||
	/*load instr */
 | 
			
		||||
	  fault_t (*load_instr) (ARMul_State * state, ARMword va,
 | 
			
		||||
				 ARMword * instr);
 | 
			
		||||
	/*mcr */
 | 
			
		||||
	  ARMword (*mcr) (ARMul_State * state, ARMword instr, ARMword val);
 | 
			
		||||
	/*mrc */
 | 
			
		||||
	  ARMword (*mrc) (ARMul_State * state, ARMword instr, ARMword * val);
 | 
			
		||||
 | 
			
		||||
	/*ywc 2005-04-16 convert virtual address to physics address */
 | 
			
		||||
	int (*v2p_dbct) (ARMul_State * state, ARMword virt_addr,
 | 
			
		||||
			 ARMword * phys_addr);
 | 
			
		||||
} mmu_ops_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "arm/mmu/tlb.h"
 | 
			
		||||
#include "arm/mmu/rb.h"
 | 
			
		||||
#include "arm/mmu/wb.h"
 | 
			
		||||
#include "arm/mmu/cache.h"
 | 
			
		||||
 | 
			
		||||
/*special process mmu.h*/
 | 
			
		||||
//#include "arm/mmu/sa_mmu.h"
 | 
			
		||||
//#include "arm/mmu/arm7100_mmu.h"
 | 
			
		||||
//#include "arm/mmu/arm920t_mmu.h"
 | 
			
		||||
//#include "arm/mmu/arm926ejs_mmu.h"
 | 
			
		||||
#include "arm/mmu/arm1176jzf_s_mmu.h"
 | 
			
		||||
//#include "arm/mmu/cortex_a9_mmu.h"
 | 
			
		||||
 | 
			
		||||
typedef struct mmu_state_t
 | 
			
		||||
{
 | 
			
		||||
	ARMword control;
 | 
			
		||||
	ARMword translation_table_base;
 | 
			
		||||
/* dyf 201-08-11 for arm1176 */
 | 
			
		||||
	ARMword auxiliary_control;
 | 
			
		||||
	ARMword coprocessor_access_control;
 | 
			
		||||
	ARMword translation_table_base0;
 | 
			
		||||
	ARMword translation_table_base1;
 | 
			
		||||
	ARMword translation_table_ctrl;
 | 
			
		||||
/* arm1176 end */
 | 
			
		||||
 | 
			
		||||
	ARMword domain_access_control;
 | 
			
		||||
	ARMword fault_status;
 | 
			
		||||
	ARMword fault_statusi;  /* prefetch fault status */
 | 
			
		||||
	ARMword fault_address;
 | 
			
		||||
	ARMword last_domain;
 | 
			
		||||
	ARMword process_id;
 | 
			
		||||
	ARMword context_id;
 | 
			
		||||
	ARMword thread_uro_id;
 | 
			
		||||
	ARMword cache_locked_down;
 | 
			
		||||
	ARMword tlb_locked_down;
 | 
			
		||||
//chy 2003-08-24 for xscale
 | 
			
		||||
	ARMword cache_type;	// 0
 | 
			
		||||
	ARMword aux_control;	// 1
 | 
			
		||||
	ARMword copro_access;	// 15
 | 
			
		||||
 | 
			
		||||
	mmu_ops_t ops;
 | 
			
		||||
	//union
 | 
			
		||||
	//{
 | 
			
		||||
		//sa_mmu_t sa_mmu;
 | 
			
		||||
		//arm7100_mmu_t arm7100_mmu;
 | 
			
		||||
		//arm920t_mmu_t arm920t_mmu;
 | 
			
		||||
		//arm926ejs_mmu_t arm926ejs_mmu;
 | 
			
		||||
	//} u;
 | 
			
		||||
} mmu_state_t;
 | 
			
		||||
 | 
			
		||||
int mmu_init (ARMul_State * state);
 | 
			
		||||
int mmu_reset (ARMul_State * state);
 | 
			
		||||
void mmu_exit (ARMul_State * state);
 | 
			
		||||
 | 
			
		||||
fault_t mmu_read_word (ARMul_State * state, ARMword virt_addr,
 | 
			
		||||
		       ARMword * data);
 | 
			
		||||
fault_t mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
 | 
			
		||||
fault_t mmu_load_instr (ARMul_State * state, ARMword virt_addr,
 | 
			
		||||
			ARMword * instr);
 | 
			
		||||
 | 
			
		||||
ARMword mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value);
 | 
			
		||||
void mmu_mcr (ARMul_State * state, ARMword instr, ARMword value);
 | 
			
		||||
 | 
			
		||||
/*ywc 20050416*/
 | 
			
		||||
int mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
 | 
			
		||||
		  ARMword * phys_addr);
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_byte (ARMul_State * state, ARMword virt_addr, ARMword * data);
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_halfword (ARMul_State * state, ARMword virt_addr, ARMword * data);
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_read_word (ARMul_State * state, ARMword virt_addr, ARMword * data);
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_byte (ARMul_State * state, ARMword virt_addr, ARMword data);
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_halfword (ARMul_State * state, ARMword virt_addr, ARMword data);
 | 
			
		||||
fault_t
 | 
			
		||||
mmu_write_word (ARMul_State * state, ARMword virt_addr, ARMword data);
 | 
			
		||||
#endif /* _ARMMMU_H_ */
 | 
			
		||||
							
								
								
									
										742
									
								
								src/core/arm/interpreter/armos.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										742
									
								
								src/core/arm/interpreter/armos.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,742 @@
 | 
			
		||||
/*  armos.c -- ARMulator OS interface:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
/* This file contains a model of Demon, ARM Ltd's Debug Monitor,
 | 
			
		||||
including all the SWI's required to support the C library. The code in
 | 
			
		||||
it is not really for the faint-hearted (especially the abort handling
 | 
			
		||||
code), but it is a complete example. Defining NOOS will disable all the
 | 
			
		||||
fun, and definign VAILDATE will define SWI 1 to enter SVC mode, and SWI
 | 
			
		||||
0x11 to halt the emulator. */
 | 
			
		||||
 | 
			
		||||
//chy 2005-09-12 disable below line
 | 
			
		||||
//#include "config.h"
 | 
			
		||||
 | 
			
		||||
#include <time.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include "skyeye_defs.h"
 | 
			
		||||
#ifndef __USE_LARGEFILE64
 | 
			
		||||
#define __USE_LARGEFILE64               /* When use 64 bit large file need define it! for stat64*/
 | 
			
		||||
#endif
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <sys/stat.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef O_RDONLY
 | 
			
		||||
#define O_RDONLY 0
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef O_WRONLY
 | 
			
		||||
#define O_WRONLY 1
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef O_RDWR
 | 
			
		||||
#define O_RDWR   2
 | 
			
		||||
#endif
 | 
			
		||||
#ifndef O_BINARY
 | 
			
		||||
#define O_BINARY 0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __STDC__
 | 
			
		||||
#define unlink(s) remove(s)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef HAVE_UNISTD_H
 | 
			
		||||
#include <unistd.h>		/* For SEEK_SET etc */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef __riscos
 | 
			
		||||
extern int _fisatty (FILE *);
 | 
			
		||||
#define isatty_(f) _fisatty(f)
 | 
			
		||||
#else
 | 
			
		||||
#ifdef __ZTC__
 | 
			
		||||
#include <io.h>
 | 
			
		||||
#define isatty_(f) isatty((f)->_file)
 | 
			
		||||
#else
 | 
			
		||||
#ifdef macintosh
 | 
			
		||||
#include <ioctl.h>
 | 
			
		||||
#define isatty_(f) (~ioctl ((f)->_file, FIOINTERACTIVE, NULL))
 | 
			
		||||
#else
 | 
			
		||||
#define isatty_(f) isatty (fileno (f))
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
#include "armos.h"
 | 
			
		||||
#include "armemu.h"
 | 
			
		||||
 | 
			
		||||
#ifndef NOOS
 | 
			
		||||
#ifndef VALIDATE
 | 
			
		||||
/* #ifndef ASIM */
 | 
			
		||||
//chy 2005-09-12 disable below line
 | 
			
		||||
//#include "armfpe.h"
 | 
			
		||||
/* #endif */
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define DUMP_SYSCALL 0
 | 
			
		||||
#define dump(...) do { if (DUMP_SYSCALL) printf(__VA_ARGS__); } while(0)
 | 
			
		||||
//#define debug(...)			printf(__VA_ARGS__);
 | 
			
		||||
#define debug(...)			;
 | 
			
		||||
 | 
			
		||||
extern unsigned ARMul_OSHandleSWI (ARMul_State * state, ARMword number);
 | 
			
		||||
 | 
			
		||||
#ifndef FOPEN_MAX
 | 
			
		||||
#define FOPEN_MAX 64
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                          OS private Information                           *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
unsigned arm_dyncom_SWI(ARMul_State * state, ARMword number)
 | 
			
		||||
{
 | 
			
		||||
	return ARMul_OSHandleSWI(state, number);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//mmap_area_t *mmap_global = NULL;
 | 
			
		||||
 | 
			
		||||
static int translate_open_mode[] = {
 | 
			
		||||
	O_RDONLY,		/* "r"   */
 | 
			
		||||
	O_RDONLY + O_BINARY,	/* "rb"  */
 | 
			
		||||
	O_RDWR,			/* "r+"  */
 | 
			
		||||
	O_RDWR + O_BINARY,	/* "r+b" */
 | 
			
		||||
	O_WRONLY + O_CREAT + O_TRUNC,	/* "w"   */
 | 
			
		||||
	O_WRONLY + O_BINARY + O_CREAT + O_TRUNC,	/* "wb"  */
 | 
			
		||||
	O_RDWR + O_CREAT + O_TRUNC,	/* "w+"  */
 | 
			
		||||
	O_RDWR + O_BINARY + O_CREAT + O_TRUNC,	/* "w+b" */
 | 
			
		||||
	O_WRONLY + O_APPEND + O_CREAT,	/* "a"   */
 | 
			
		||||
	O_WRONLY + O_BINARY + O_APPEND + O_CREAT,	/* "ab"  */
 | 
			
		||||
	O_RDWR + O_APPEND + O_CREAT,	/* "a+"  */
 | 
			
		||||
	O_RDWR + O_BINARY + O_APPEND + O_CREAT	/* "a+b" */
 | 
			
		||||
};
 | 
			
		||||
//
 | 
			
		||||
//static void
 | 
			
		||||
//SWIWrite0 (ARMul_State * state, ARMword addr)
 | 
			
		||||
//{
 | 
			
		||||
//	ARMword temp;
 | 
			
		||||
//
 | 
			
		||||
//	//while ((temp = ARMul_ReadByte (state, addr++)) != 0)
 | 
			
		||||
//	while(1){
 | 
			
		||||
//		mem_read(8, addr++, &temp);
 | 
			
		||||
//		if(temp != 0)
 | 
			
		||||
//			(void) fputc ((char) temp, stdout);
 | 
			
		||||
//		else
 | 
			
		||||
//			break;
 | 
			
		||||
//	}
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//static void
 | 
			
		||||
//WriteCommandLineTo (ARMul_State * state, ARMword addr)
 | 
			
		||||
//{
 | 
			
		||||
//	ARMword temp;
 | 
			
		||||
//	char *cptr = state->CommandLine;
 | 
			
		||||
//	if (cptr == NULL)
 | 
			
		||||
//		cptr = "\0";
 | 
			
		||||
//	do {
 | 
			
		||||
//		temp = (ARMword) * cptr++;
 | 
			
		||||
//		//ARMul_WriteByte (state, addr++, temp);
 | 
			
		||||
//		mem_write(8, addr++, temp);
 | 
			
		||||
//	}
 | 
			
		||||
//	while (temp != 0);
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//static void
 | 
			
		||||
//SWIopen (ARMul_State * state, ARMword name, ARMword SWIflags)
 | 
			
		||||
//{
 | 
			
		||||
//	char dummy[2000];
 | 
			
		||||
//	int flags;
 | 
			
		||||
//	int i;
 | 
			
		||||
//
 | 
			
		||||
//	for (i = 0; (dummy[i] = ARMul_ReadByte (state, name + i)); i++);
 | 
			
		||||
//	assert(SWIflags< (sizeof(translate_open_mode)/ sizeof(translate_open_mode[0])));
 | 
			
		||||
//	/* Now we need to decode the Demon open mode */
 | 
			
		||||
//	flags = translate_open_mode[SWIflags];
 | 
			
		||||
//	flags = SWIflags;
 | 
			
		||||
//
 | 
			
		||||
//	/* Filename ":tt" is special: it denotes stdin/out */
 | 
			
		||||
//	if (strcmp (dummy, ":tt") == 0) {
 | 
			
		||||
//		if (flags == O_RDONLY)	/* opening tty "r" */
 | 
			
		||||
//			state->Reg[0] = 0;	/* stdin */
 | 
			
		||||
//		else
 | 
			
		||||
//			state->Reg[0] = 1;	/* stdout */
 | 
			
		||||
//	}
 | 
			
		||||
//	else {
 | 
			
		||||
//		state->Reg[0] = (int) open (dummy, flags, 0666);
 | 
			
		||||
//	}
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//static void
 | 
			
		||||
//SWIread (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
 | 
			
		||||
//{
 | 
			
		||||
//	int res;
 | 
			
		||||
//	int i;
 | 
			
		||||
//	char *local = (char*) malloc (len);
 | 
			
		||||
//
 | 
			
		||||
//	if (local == NULL) {
 | 
			
		||||
//		fprintf (stderr,
 | 
			
		||||
//			 "sim: Unable to read 0x%ulx bytes - out of memory\n",
 | 
			
		||||
//			 len);
 | 
			
		||||
//		return;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	res = read (f, local, len);
 | 
			
		||||
//	if (res > 0)
 | 
			
		||||
//		for (i = 0; i < res; i++)
 | 
			
		||||
//			//ARMul_WriteByte (state, ptr + i, local[i]);
 | 
			
		||||
//			mem_write(8, ptr + i, local[i]);
 | 
			
		||||
//	free (local);
 | 
			
		||||
//	//state->Reg[0] = res == -1 ? -1 : len - res;
 | 
			
		||||
//	state->Reg[0] = res;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//static void
 | 
			
		||||
//SWIwrite (ARMul_State * state, ARMword f, ARMword ptr, ARMword len)
 | 
			
		||||
//{
 | 
			
		||||
//	int res;
 | 
			
		||||
//	ARMword i;
 | 
			
		||||
//	char *local = malloc (len);
 | 
			
		||||
//
 | 
			
		||||
//	if (local == NULL) {
 | 
			
		||||
//		fprintf (stderr,
 | 
			
		||||
//			 "sim: Unable to write 0x%lx bytes - out of memory\n",
 | 
			
		||||
//			 (long unsigned int) len);
 | 
			
		||||
//		return;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	for (i = 0; i < len; i++){
 | 
			
		||||
//		//local[i] = ARMul_ReadByte (state, ptr + i);
 | 
			
		||||
//		ARMword data;
 | 
			
		||||
//		mem_read(8, ptr + i, &data);
 | 
			
		||||
//		local[i] = data & 0xFF;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	res = write (f, local, len);
 | 
			
		||||
//	//state->Reg[0] = res == -1 ? -1 : len - res;
 | 
			
		||||
//	state->Reg[0] = res;
 | 
			
		||||
//	free (local);
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
//static void
 | 
			
		||||
//SWIflen (ARMul_State * state, ARMword fh)
 | 
			
		||||
//{
 | 
			
		||||
//	ARMword addr;
 | 
			
		||||
//
 | 
			
		||||
//	if (fh == 0 || fh > FOPEN_MAX) {
 | 
			
		||||
//		state->Reg[0] = -1L;
 | 
			
		||||
//		return;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	addr = lseek (fh, 0, SEEK_CUR);
 | 
			
		||||
//
 | 
			
		||||
//	state->Reg[0] = lseek (fh, 0L, SEEK_END);
 | 
			
		||||
//	(void) lseek (fh, addr, SEEK_SET);
 | 
			
		||||
//
 | 
			
		||||
//}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
* The emulator calls this routine when a SWI instruction is encuntered. The *
 | 
			
		||||
* parameter passed is the SWI number (lower 24 bits of the instruction).    *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
/* ahe-ykl information is retrieved from elf header and the starting value of
 | 
			
		||||
   brk_static is in sky_info_t */
 | 
			
		||||
 | 
			
		||||
/* brk static hold the value of brk */
 | 
			
		||||
static uint32_t brk_static = -1;
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
ARMul_OSHandleSWI (ARMul_State * state, ARMword number)
 | 
			
		||||
{
 | 
			
		||||
	number &= 0xfffff;
 | 
			
		||||
	ARMword addr, temp;
 | 
			
		||||
 | 
			
		||||
	switch (number) {
 | 
			
		||||
//	case SWI_Syscall:
 | 
			
		||||
//		if (state->Reg[7] != 0) 
 | 
			
		||||
//			return ARMul_OSHandleSWI(state, state->Reg[7]);
 | 
			
		||||
//		else
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//	case SWI_Read:
 | 
			
		||||
//		SWIread (state, state->Reg[0], state->Reg[1], state->Reg[2]);
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_GetUID32:
 | 
			
		||||
//		state->Reg[0] = getuid();
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_GetGID32:
 | 
			
		||||
//		state->Reg[0] = getgid();
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_GetEUID32:
 | 
			
		||||
//		state->Reg[0] = geteuid();
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_GetEGID32:
 | 
			
		||||
//		state->Reg[0] = getegid();
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Write:
 | 
			
		||||
//		SWIwrite (state, state->Reg[0], state->Reg[1], state->Reg[2]);
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Open:
 | 
			
		||||
//		SWIopen (state, state->Reg[0], state->Reg[1]);
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Close:
 | 
			
		||||
//		state->Reg[0] = close (state->Reg[0]);
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Seek:{
 | 
			
		||||
//			/* We must return non-zero for failure */
 | 
			
		||||
//			state->Reg[0] =
 | 
			
		||||
//				lseek (state->Reg[0], state->Reg[1],
 | 
			
		||||
//					     SEEK_SET);
 | 
			
		||||
//			return TRUE;
 | 
			
		||||
//		}
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_ExitGroup:
 | 
			
		||||
//	case SWI_Exit:
 | 
			
		||||
//		{
 | 
			
		||||
//		struct timeval tv;
 | 
			
		||||
//		//gettimeofday(&tv,NULL);
 | 
			
		||||
//		//printf("In %s, %d  sec, %d usec\n", __FUNCTION__, tv.tv_sec, tv.tv_usec);
 | 
			
		||||
//		printf("passed %d sec, %lld usec\n", get_clock_sec(), get_clock_us());
 | 
			
		||||
//
 | 
			
		||||
//		/* quit here */
 | 
			
		||||
//		run_command("quit");
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//		}
 | 
			
		||||
//	case SWI_Times:{
 | 
			
		||||
//		uint32_t dest = state->Reg[0];
 | 
			
		||||
//		struct tms now;
 | 
			
		||||
//		struct target_tms32 nowret;
 | 
			
		||||
//
 | 
			
		||||
//		uint32_t ret = times(&now);
 | 
			
		||||
//
 | 
			
		||||
//		if (ret == -1){
 | 
			
		||||
//			debug("syscall %s error %d\n", "SWI_Times", ret);
 | 
			
		||||
//			state->Reg[0] = ret;
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//		}
 | 
			
		||||
//		
 | 
			
		||||
//		nowret.tms_cstime = now.tms_cstime;
 | 
			
		||||
//		nowret.tms_cutime = now.tms_cutime;
 | 
			
		||||
//		nowret.tms_stime = now.tms_stime;
 | 
			
		||||
//		nowret.tms_utime = now.tms_utime;
 | 
			
		||||
//
 | 
			
		||||
//		uint32_t offset;
 | 
			
		||||
//		for (offset = 0; offset < sizeof(nowret); offset++) {
 | 
			
		||||
//			bus_write(8, dest + offset, *((uint8_t *) &nowret + offset));
 | 
			
		||||
//		}
 | 
			
		||||
//
 | 
			
		||||
//		state->Reg[0] = ret;
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//		}
 | 
			
		||||
//	
 | 
			
		||||
//	case SWI_Gettimeofday: {
 | 
			
		||||
//		uint32_t dest1 = state->Reg[0];
 | 
			
		||||
//		uint32_t dest2 = state->Reg[1]; // Unsure of this
 | 
			
		||||
//		struct timeval val;
 | 
			
		||||
//		struct timezone zone;
 | 
			
		||||
//		struct target_timeval32 valret;
 | 
			
		||||
//		struct target_timezone32 zoneret;
 | 
			
		||||
//	
 | 
			
		||||
//		uint32_t ret = gettimeofday(&val, &zone);
 | 
			
		||||
//		valret.tv_sec = val.tv_sec;
 | 
			
		||||
//		valret.tv_usec = val.tv_usec;
 | 
			
		||||
//		zoneret.tz_dsttime = zoneret.tz_dsttime;
 | 
			
		||||
//		zoneret.tz_minuteswest = zoneret.tz_minuteswest;
 | 
			
		||||
//
 | 
			
		||||
//		if (ret == -1){
 | 
			
		||||
//			debug("syscall %s error %d\n", "SWI_Gettimeofday", ret);
 | 
			
		||||
//			state->Reg[0] = ret;
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//		}
 | 
			
		||||
//		
 | 
			
		||||
//		uint32_t offset;
 | 
			
		||||
//		if (dest1) {
 | 
			
		||||
//			for (offset = 0; offset < sizeof(valret); offset++) {
 | 
			
		||||
//				bus_write(8, dest1 + offset, *((uint8_t *) &valret + offset));
 | 
			
		||||
//			}
 | 
			
		||||
//			state->Reg[0] = ret;
 | 
			
		||||
//		}
 | 
			
		||||
//		if (dest2) {
 | 
			
		||||
//			for (offset = 0; offset < sizeof(zoneret); offset++) {
 | 
			
		||||
//				bus_write(8, dest2 + offset, *((uint8_t *) &zoneret + offset));
 | 
			
		||||
//			}
 | 
			
		||||
//			state->Reg[0] = ret;
 | 
			
		||||
//		}
 | 
			
		||||
//
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//	}
 | 
			
		||||
//	case SWI_Brk:
 | 
			
		||||
//		/* initialize brk value */
 | 
			
		||||
//		/* suppose that brk_static doesn't reach 0xffffffff... */
 | 
			
		||||
//		if (brk_static == -1) {
 | 
			
		||||
//			brk_static = (get_skyeye_pref()->info).brk;
 | 
			
		||||
//		}
 | 
			
		||||
//
 | 
			
		||||
//		/* FIXME there might be a need to do a mmap */
 | 
			
		||||
//		
 | 
			
		||||
//		if(state->Reg[0]){
 | 
			
		||||
//			if (get_skyeye_exec_info()->mmap_access) {
 | 
			
		||||
//				/* if new brk is greater than current brk, allocate memory */
 | 
			
		||||
//				if (state->Reg[0] > brk_static) {
 | 
			
		||||
//					uint32_t ret = mmap( (void *) brk_static, state->Reg[0] - brk_static,
 | 
			
		||||
//							   PROT_WRITE, MAP_PRIVATE | MAP_FIXED | MAP_ANONYMOUS, -1, 0 );
 | 
			
		||||
//					if (ret != MAP_FAILED)
 | 
			
		||||
//						brk_static = ret;
 | 
			
		||||
//				}
 | 
			
		||||
//			}
 | 
			
		||||
//			brk_static = state->Reg[0];
 | 
			
		||||
//			//state->Reg[0] = 0; /* FIXME return value of brk set to be the address on success */
 | 
			
		||||
//		} else {
 | 
			
		||||
//			state->Reg[0] = brk_static;
 | 
			
		||||
//		}
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Break:
 | 
			
		||||
//		state->Emulate = FALSE;
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Mmap:{
 | 
			
		||||
//		int addr = state->Reg[0];
 | 
			
		||||
//		int len = state->Reg[1];
 | 
			
		||||
//		int prot = state->Reg[2];
 | 
			
		||||
//		int flag = state->Reg[3];
 | 
			
		||||
//		int fd = state->Reg[4];
 | 
			
		||||
//		int offset = state->Reg[5];
 | 
			
		||||
//		mmap_area_t *area = new_mmap_area(addr, len);
 | 
			
		||||
//		state->Reg[0] = area->bank.addr;
 | 
			
		||||
//		//printf("syscall %d mmap(0x%x,%x,0x%x,0x%x,%d,0x%x) = 0x%x\n",\
 | 
			
		||||
//				SWI_Mmap, addr, len, prot, flag, fd, offset, state->Reg[0]);
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Munmap:
 | 
			
		||||
//		state->Reg[0] = 0;
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//		
 | 
			
		||||
//	case SWI_Mmap2:{
 | 
			
		||||
//		int addr = state->Reg[0];
 | 
			
		||||
//		int len = state->Reg[1];
 | 
			
		||||
//		int prot = state->Reg[2];
 | 
			
		||||
//		int flag = state->Reg[3];
 | 
			
		||||
//		int fd = state->Reg[4];
 | 
			
		||||
//		int offset = state->Reg[5] * 4096; /* page offset */
 | 
			
		||||
//		mmap_area_t *area = new_mmap_area(addr, len);
 | 
			
		||||
//		state->Reg[0] = area->bank.addr;
 | 
			
		||||
//		
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//	}
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Breakpoint:
 | 
			
		||||
//		//chy 2005-09-12 change below line
 | 
			
		||||
//		//state->EndCondition = RDIError_BreakpointReached;
 | 
			
		||||
//		//printf ("SKYEYE: in armos.c : should not come here!!!!\n");
 | 
			
		||||
//		state->EndCondition = 0;
 | 
			
		||||
//		/*modified by ksh to support breakpoiont*/
 | 
			
		||||
//		state->Emulate = STOP;
 | 
			
		||||
//		return (TRUE);
 | 
			
		||||
//	case SWI_Uname:
 | 
			
		||||
//		{
 | 
			
		||||
//		struct utsname *uts = (uintptr_t) state->Reg[0]; /* uname should write data in this address */
 | 
			
		||||
//		struct utsname utsbuf;
 | 
			
		||||
//		//printf("Uname size is %x\n", sizeof(utsbuf));
 | 
			
		||||
//		char *buf;
 | 
			
		||||
//		uintptr_t sp ; /* used as a temporary address */
 | 
			
		||||
//
 | 
			
		||||
//#define COPY_UTS_STRING(addr) 					\
 | 
			
		||||
//			buf = addr;				\
 | 
			
		||||
//			while(*buf != NULL) { 			\
 | 
			
		||||
//				bus_write(8, sp, *buf); 	\
 | 
			
		||||
//				sp++; 				\
 | 
			
		||||
//				buf++;	 			\
 | 
			
		||||
//			}
 | 
			
		||||
//#define COPY_UTS(field)	/*printf("%s: %s at %p\n", #field, utsbuf.field, uts->field);*/	\
 | 
			
		||||
//			sp = (uintptr_t) uts->field;						\
 | 
			
		||||
//			COPY_UTS_STRING((&utsbuf)->field);
 | 
			
		||||
//
 | 
			
		||||
//		if (uname(&utsbuf) < 0) {
 | 
			
		||||
//			printf("syscall uname: utsname error\n");
 | 
			
		||||
//			state->Reg[0] = -1;
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//		}
 | 
			
		||||
//		
 | 
			
		||||
//		/* FIXME for now, this is just the host system call
 | 
			
		||||
//		   Some data should be missing, as it depends on
 | 
			
		||||
//		   the version of utsname */
 | 
			
		||||
//		COPY_UTS(sysname);
 | 
			
		||||
//		COPY_UTS(nodename);
 | 
			
		||||
//		COPY_UTS(release);
 | 
			
		||||
//		COPY_UTS(version);
 | 
			
		||||
//		COPY_UTS(machine);
 | 
			
		||||
//		
 | 
			
		||||
//		state->Reg[0] = 0;
 | 
			
		||||
//		return TRUE;
 | 
			
		||||
//		}
 | 
			
		||||
//	case SWI_Fcntl:
 | 
			
		||||
//		{
 | 
			
		||||
//			uint32_t fd = state->Reg[0];
 | 
			
		||||
//			uint32_t cmd = state->Reg[1];
 | 
			
		||||
//			uint32_t arg = state->Reg[2];
 | 
			
		||||
//			uint32_t ret;
 | 
			
		||||
//
 | 
			
		||||
//			switch(cmd){
 | 
			
		||||
//			case (F_GETFD):
 | 
			
		||||
//			{
 | 
			
		||||
//				ret = fcntl(fd, cmd, arg);
 | 
			
		||||
//				//printf("syscall fcntl for getfd not implemented, ret %d\n", ret);
 | 
			
		||||
//				state->Reg[0] = ret;
 | 
			
		||||
//				return FALSE;
 | 
			
		||||
//			}
 | 
			
		||||
//			default:
 | 
			
		||||
//				break;
 | 
			
		||||
//			}
 | 
			
		||||
//
 | 
			
		||||
//			printf("syscall fcntl unimplemented fd %x cmd %x\n", fd, cmd);
 | 
			
		||||
//			state->Reg[0] = -1;
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//
 | 
			
		||||
//		}
 | 
			
		||||
//	case SWI_Fstat64:
 | 
			
		||||
//		{
 | 
			
		||||
//			uint32_t dest = state->Reg[1];
 | 
			
		||||
//			uint32_t fd = state->Reg[0];
 | 
			
		||||
//			struct stat64 statbuf;
 | 
			
		||||
//			struct target_stat64 statret;
 | 
			
		||||
//			memset(&statret, 0, sizeof(struct target_stat64));
 | 
			
		||||
//			uint32_t ret = fstat64(fd, &statbuf);
 | 
			
		||||
//
 | 
			
		||||
//			if (ret == -1){
 | 
			
		||||
//				printf("syscall %s returned error\n", "SWI_Fstat");
 | 
			
		||||
//				state->Reg[0] = ret;
 | 
			
		||||
//				return FALSE;
 | 
			
		||||
//			}
 | 
			
		||||
//			
 | 
			
		||||
//			/* copy statbuf to the process memory space
 | 
			
		||||
//			   FIXME can't say if endian has an effect here */
 | 
			
		||||
//			uint32_t offset;
 | 
			
		||||
//			//printf("Fstat system is size %x\n", sizeof(statbuf));
 | 
			
		||||
//			//printf("Fstat target is size %x\n", sizeof(statret));
 | 
			
		||||
//			
 | 
			
		||||
//			/* we copy system structure data stat64 into arm fixed size structure target_stat64 */
 | 
			
		||||
//			statret.st_dev = 	statbuf.st_dev;
 | 
			
		||||
//			statret.st_ino = 	statbuf.st_ino;
 | 
			
		||||
//			statret.st_mode = 	statbuf.st_mode;
 | 
			
		||||
//			statret.st_nlink = 	statbuf.st_nlink;
 | 
			
		||||
//			statret.st_uid = 	statbuf.st_uid;
 | 
			
		||||
//			statret.st_gid = 	statbuf.st_gid;
 | 
			
		||||
//			statret.st_rdev = 	statbuf.st_rdev;
 | 
			
		||||
//			statret.st_size = 	statbuf.st_size;
 | 
			
		||||
//			statret.st_blksize = 	statbuf.st_blksize;
 | 
			
		||||
//			statret.st_blocks = 	statbuf.st_blocks;
 | 
			
		||||
//			statret.st32_atime = 	statbuf.st_atime;
 | 
			
		||||
//			statret.st32_mtime = 	statbuf.st_mtime;
 | 
			
		||||
//			statret.st32_ctime = 	statbuf.st_ctime;
 | 
			
		||||
//			
 | 
			
		||||
//			for (offset = 0; offset < sizeof(statret); offset++) {
 | 
			
		||||
//				bus_write(8, dest + offset, *((uint8_t *) &statret + offset));
 | 
			
		||||
//			}
 | 
			
		||||
//
 | 
			
		||||
//			state->Reg[0] = ret;
 | 
			
		||||
//			return TRUE;
 | 
			
		||||
//		}
 | 
			
		||||
//	case SWI_Set_tls:
 | 
			
		||||
//		{
 | 
			
		||||
//			//printf("syscall set_tls unimplemented\n");
 | 
			
		||||
//			state->mmu.thread_uro_id = state->Reg[0];
 | 
			
		||||
//			state->CP15[CP15_THREAD_URO - CP15_BASE] = state->Reg[0];
 | 
			
		||||
//			state->Reg[0] = 0;
 | 
			
		||||
//			return FALSE;
 | 
			
		||||
//		}
 | 
			
		||||
//#if 0
 | 
			
		||||
//	case SWI_Clock:
 | 
			
		||||
//		/* return number of centi-seconds... */
 | 
			
		||||
//		state->Reg[0] =
 | 
			
		||||
//#ifdef CLOCKS_PER_SEC
 | 
			
		||||
//			(CLOCKS_PER_SEC >= 100)
 | 
			
		||||
//			? (ARMword) (clock () / (CLOCKS_PER_SEC / 100))
 | 
			
		||||
//			: (ARMword) ((clock () * 100) / CLOCKS_PER_SEC);
 | 
			
		||||
//#else
 | 
			
		||||
//			/* presume unix... clock() returns microseconds */
 | 
			
		||||
//			(ARMword) (clock () / 10000);
 | 
			
		||||
//#endif
 | 
			
		||||
//		return (TRUE);
 | 
			
		||||
//
 | 
			
		||||
//	case SWI_Time:
 | 
			
		||||
//		state->Reg[0] = (ARMword) time (NULL);
 | 
			
		||||
//		return (TRUE);
 | 
			
		||||
//	case SWI_Flen:
 | 
			
		||||
//		SWIflen (state, state->Reg[0]);
 | 
			
		||||
//		return (TRUE);
 | 
			
		||||
//
 | 
			
		||||
//#endif
 | 
			
		||||
	default:
 | 
			
		||||
 | 
			
		||||
		_dbg_assert_msg_(ARM11, false, "ImplementMe: ARMul_OSHandleSWI!");
 | 
			
		||||
 | 
			
		||||
		return (FALSE);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * @brief For mmap syscall.A mmap_area is a memory bank. Get from ppc.
 | 
			
		||||
// */
 | 
			
		||||
//static mmap_area_t* new_mmap_area(int sim_addr, int len){
 | 
			
		||||
//	mmap_area_t *area = (mmap_area_t *)malloc(sizeof(mmap_area_t));
 | 
			
		||||
//	if(area == NULL){
 | 
			
		||||
//		printf("error, failed %s\n",__FUNCTION__);
 | 
			
		||||
//		exit(0);
 | 
			
		||||
//	}
 | 
			
		||||
//#if FAST_MEMORY   
 | 
			
		||||
//	if (mmap_next_base == -1)
 | 
			
		||||
//	{
 | 
			
		||||
//		mmap_next_base = get_skyeye_exec_info()->brk;
 | 
			
		||||
//	}
 | 
			
		||||
//#endif
 | 
			
		||||
//
 | 
			
		||||
//	memset(area, 0x0, sizeof(mmap_area_t));
 | 
			
		||||
//	area->bank.addr = mmap_next_base;
 | 
			
		||||
//	area->bank.len = len;
 | 
			
		||||
//	area->bank.bank_write = mmap_mem_write;
 | 
			
		||||
//	area->bank.bank_read = mmap_mem_read;
 | 
			
		||||
//	area->bank.type = MEMTYPE_RAM;
 | 
			
		||||
//	area->bank.objname = "mmap";
 | 
			
		||||
//	addr_mapping(&area->bank);
 | 
			
		||||
//
 | 
			
		||||
//#if FAST_MEMORY
 | 
			
		||||
//	if (get_skyeye_exec_info()->mmap_access)
 | 
			
		||||
//	{
 | 
			
		||||
//		/* FIXME check proper flags */
 | 
			
		||||
//		/* FIXME we may delete the need of banks up there */
 | 
			
		||||
//		uint32_t ret = mmap(mmap_next_base, len, PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 | 
			
		||||
//		mmap_next_base = ret;
 | 
			
		||||
//	}
 | 
			
		||||
//	area->mmap_addr = (uint8_t*)get_dma_addr(mmap_next_base);
 | 
			
		||||
//#else	
 | 
			
		||||
//	area->mmap_addr = malloc(len);
 | 
			
		||||
//	if(area->mmap_addr == NULL){
 | 
			
		||||
//		printf("error mmap malloc\n");
 | 
			
		||||
//		exit(0);
 | 
			
		||||
//	}
 | 
			
		||||
//	memset(area->mmap_addr, 0x0, len);
 | 
			
		||||
//#endif
 | 
			
		||||
//	
 | 
			
		||||
//	area->next = NULL;
 | 
			
		||||
//	if(mmap_global){
 | 
			
		||||
//		area->next = mmap_global->next;
 | 
			
		||||
//		mmap_global->next = area;
 | 
			
		||||
//	}else{
 | 
			
		||||
//		mmap_global = area;
 | 
			
		||||
//	}
 | 
			
		||||
//	mmap_next_base = mmap_next_base + len;
 | 
			
		||||
//	return area;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
//static mmap_area_t *get_mmap_area(int addr){
 | 
			
		||||
//	mmap_area_t *tmp = mmap_global;
 | 
			
		||||
//	while(tmp){
 | 
			
		||||
//		if ((tmp->bank.addr <= addr) && (tmp->bank.addr + tmp->bank.len > addr)){
 | 
			
		||||
//			return tmp;
 | 
			
		||||
//		}
 | 
			
		||||
//		tmp = tmp->next;
 | 
			
		||||
//	}
 | 
			
		||||
//	printf("cannot get mmap area:addr=0x%x\n", addr);
 | 
			
		||||
//	return NULL;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * @brief the mmap_area bank write function. Get from ppc.
 | 
			
		||||
// *
 | 
			
		||||
// * @param size size to write, 8/16/32
 | 
			
		||||
// * @param addr address to write
 | 
			
		||||
// * @param value value to write
 | 
			
		||||
// *
 | 
			
		||||
// * @return sucess return 1,otherwise 0.
 | 
			
		||||
// */
 | 
			
		||||
//static char mmap_mem_write(short size, int addr, uint32_t value){
 | 
			
		||||
//	mmap_area_t *area_tmp = get_mmap_area(addr);
 | 
			
		||||
//	mem_bank_t *bank_tmp = &area_tmp->bank;
 | 
			
		||||
//	int offset = addr - bank_tmp->addr;
 | 
			
		||||
//	switch(size){
 | 
			
		||||
//		case 8:{
 | 
			
		||||
//			//uint8_t value_endian = value;
 | 
			
		||||
//			uint8_t value_endian = (uint8_t)value;
 | 
			
		||||
//			*(uint8_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
 | 
			
		||||
//			break;
 | 
			
		||||
//		}
 | 
			
		||||
//		case 16:{
 | 
			
		||||
//			//uint16_t value_endian = half_to_BE((uint16_t)value);
 | 
			
		||||
//			uint16_t value_endian = ((uint16_t)value);
 | 
			
		||||
//			*(uint16_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
 | 
			
		||||
//			break;
 | 
			
		||||
//		}
 | 
			
		||||
//		case 32:{
 | 
			
		||||
//			//uint32_t value_endian = word_to_BE((uint32_t)value);
 | 
			
		||||
//			uint32_t value_endian = ((uint32_t)value);
 | 
			
		||||
//			*(uint32_t *)&(((char *)area_tmp->mmap_addr)[offset]) = value_endian;
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,value_endian);
 | 
			
		||||
//			break;
 | 
			
		||||
//		}
 | 
			
		||||
//		default:
 | 
			
		||||
//			printf("invalid size %d\n",size);
 | 
			
		||||
//			return 0;
 | 
			
		||||
//	}
 | 
			
		||||
//	return 1;
 | 
			
		||||
//}
 | 
			
		||||
//
 | 
			
		||||
///**
 | 
			
		||||
// * @brief the mmap_area bank read function. Get from ppc.
 | 
			
		||||
// *
 | 
			
		||||
// * @param size size to read, 8/16/32
 | 
			
		||||
// * @param addr address to read
 | 
			
		||||
// * @param value value to read
 | 
			
		||||
// *
 | 
			
		||||
// * @return sucess return 1,otherwise 0.
 | 
			
		||||
// */
 | 
			
		||||
//static char mmap_mem_read(short size, int addr, uint32_t * value){
 | 
			
		||||
//	mmap_area_t *area_tmp = get_mmap_area(addr);
 | 
			
		||||
//	mem_bank_t *bank_tmp = &area_tmp->bank;
 | 
			
		||||
//	int offset = addr - bank_tmp->addr;
 | 
			
		||||
//	switch(size){
 | 
			
		||||
//		case 8:{
 | 
			
		||||
//			//*(uint8_t *)value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
 | 
			
		||||
//			*value = *(uint8_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]);
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
 | 
			
		||||
//			break;
 | 
			
		||||
//		}
 | 
			
		||||
//		case 16:{
 | 
			
		||||
//			//*(uint16_t *)value = half_from_BE(*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
 | 
			
		||||
//			*value = (*(uint16_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint16_t*)value);
 | 
			
		||||
//			break;
 | 
			
		||||
//		}
 | 
			
		||||
//		case 32:
 | 
			
		||||
//			//*value = (uint32_t)word_from_BE(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
 | 
			
		||||
//			*value = (uint32_t)(*(uint32_t *)&(((uint8_t *)area_tmp->mmap_addr)[offset]));
 | 
			
		||||
//			debug("in %s,size=%d,addr=0x%x,value=0x%x\n",__FUNCTION__,size,addr,*(uint32_t*)value);
 | 
			
		||||
//			break;
 | 
			
		||||
//		default:
 | 
			
		||||
//			printf("invalid size %d\n",size);
 | 
			
		||||
//			return 0;
 | 
			
		||||
//	}
 | 
			
		||||
//	return 1;
 | 
			
		||||
//}
 | 
			
		||||
							
								
								
									
										138
									
								
								src/core/arm/interpreter/armos.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										138
									
								
								src/core/arm/interpreter/armos.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,138 @@
 | 
			
		||||
/*  armos.h -- ARMulator OS definitions:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
//#include "bank_defs.h"
 | 
			
		||||
//#include "dyncom/defines.h"
 | 
			
		||||
 | 
			
		||||
//typedef struct mmap_area{
 | 
			
		||||
//	mem_bank_t bank;
 | 
			
		||||
//	void *mmap_addr;
 | 
			
		||||
//	struct mmap_area *next;
 | 
			
		||||
//}mmap_area_t;
 | 
			
		||||
 | 
			
		||||
#if FAST_MEMORY
 | 
			
		||||
/* in user mode, mmap_base will be on initial brk,
 | 
			
		||||
   set at the first mmap request */
 | 
			
		||||
#define mmap_base -1
 | 
			
		||||
#else
 | 
			
		||||
#define mmap_base 0x50000000
 | 
			
		||||
#endif
 | 
			
		||||
static long mmap_next_base = mmap_base;
 | 
			
		||||
 | 
			
		||||
//static mmap_area_t* new_mmap_area(int sim_addr, int len);
 | 
			
		||||
static char mmap_mem_write(short size, int addr, uint32_t value);
 | 
			
		||||
static char mmap_mem_read(short size, int addr, uint32_t * value);
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                               SWI numbers                                 *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
#define SWI_Syscall                0x0
 | 
			
		||||
#define SWI_Exit                   0x1
 | 
			
		||||
#define SWI_Read                   0x3
 | 
			
		||||
#define SWI_Write                  0x4
 | 
			
		||||
#define SWI_Open                   0x5
 | 
			
		||||
#define SWI_Close                  0x6
 | 
			
		||||
#define SWI_Seek                   0x13
 | 
			
		||||
#define SWI_Rename                 0x26
 | 
			
		||||
#define SWI_Break                  0x11
 | 
			
		||||
 | 
			
		||||
#define SWI_Times		   0x2b
 | 
			
		||||
#define SWI_Brk			   0x2d
 | 
			
		||||
 | 
			
		||||
#define SWI_Mmap                   0x5a
 | 
			
		||||
#define SWI_Munmap                 0x5b
 | 
			
		||||
#define SWI_Mmap2                  0xc0
 | 
			
		||||
 | 
			
		||||
#define SWI_GetUID32               0xc7
 | 
			
		||||
#define SWI_GetGID32               0xc8
 | 
			
		||||
#define SWI_GetEUID32              0xc9
 | 
			
		||||
#define SWI_GetEGID32              0xca
 | 
			
		||||
 | 
			
		||||
#define SWI_ExitGroup		   0xf8
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
#define SWI_Time                   0xd
 | 
			
		||||
#define SWI_Clock                  0x61
 | 
			
		||||
#define SWI_Time                   0x63
 | 
			
		||||
#define SWI_Remove                 0x64
 | 
			
		||||
#define SWI_Rename                 0x65
 | 
			
		||||
#define SWI_Flen                   0x6c
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define SWI_Uname		   0x7a
 | 
			
		||||
#define SWI_Fcntl                  0xdd 
 | 
			
		||||
#define SWI_Fstat64  		   0xc5
 | 
			
		||||
#define SWI_Gettimeofday           0x4e
 | 
			
		||||
#define SWI_Set_tls                0xf0005
 | 
			
		||||
 | 
			
		||||
#define SWI_Breakpoint             0x180000	/* see gdb's tm-arm.h */
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                             SWI structures                                *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
/* Arm binaries (for now) only support 32 bit, and expect to receive
 | 
			
		||||
   32-bit compliant structure in return of a systen call. Because
 | 
			
		||||
   we use host system calls to emulate system calls, the returned
 | 
			
		||||
   structure can be 32-bit compliant or 64-bit compliant, depending
 | 
			
		||||
   on the OS running skyeye. Therefore, we need a fixed size structure
 | 
			
		||||
   adapted to arm.*/
 | 
			
		||||
 | 
			
		||||
/* Borrowed from qemu */
 | 
			
		||||
struct target_stat64 {
 | 
			
		||||
	unsigned short	st_dev;
 | 
			
		||||
	unsigned char	__pad0[10];
 | 
			
		||||
	uint32_t	__st_ino;
 | 
			
		||||
	unsigned int	st_mode;
 | 
			
		||||
	unsigned int	st_nlink;
 | 
			
		||||
	uint32_t	st_uid;
 | 
			
		||||
	uint32_t	st_gid;
 | 
			
		||||
	unsigned short	st_rdev;
 | 
			
		||||
	unsigned char	__pad3[10];
 | 
			
		||||
	unsigned char	__pad31[4];
 | 
			
		||||
	long long	st_size;
 | 
			
		||||
	uint32_t	st_blksize;
 | 
			
		||||
	unsigned char	__pad32[4];
 | 
			
		||||
	uint32_t	st_blocks;
 | 
			
		||||
	uint32_t	__pad4;
 | 
			
		||||
	uint32_t	st32_atime;
 | 
			
		||||
	uint32_t	__pad5;
 | 
			
		||||
	uint32_t	st32_mtime;
 | 
			
		||||
	uint32_t	__pad6;
 | 
			
		||||
	uint32_t	st32_ctime;
 | 
			
		||||
	uint32_t	__pad7;
 | 
			
		||||
	unsigned long long	st_ino;
 | 
			
		||||
};// __attribute__((packed));
 | 
			
		||||
 | 
			
		||||
struct target_tms32 {
 | 
			
		||||
    uint32_t tms_utime;
 | 
			
		||||
    uint32_t tms_stime;
 | 
			
		||||
    uint32_t tms_cutime;
 | 
			
		||||
    uint32_t tms_cstime;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct target_timeval32 {
 | 
			
		||||
	uint32_t tv_sec;     /* seconds */
 | 
			
		||||
	uint32_t tv_usec;    /* microseconds */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct target_timezone32 {
 | 
			
		||||
	int32_t tz_minuteswest;     /* minutes west of Greenwich */
 | 
			
		||||
	int32_t tz_dsttime;         /* type of DST correction */
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										954
									
								
								src/core/arm/interpreter/armsupp.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										954
									
								
								src/core/arm/interpreter/armsupp.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,954 @@
 | 
			
		||||
/*  armsupp.c -- ARMulator support code:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
#include "armemu.h"
 | 
			
		||||
//#include "ansidecl.h"
 | 
			
		||||
#include "skyeye_defs.h"
 | 
			
		||||
unsigned xscale_cp15_cp_access_allowed (ARMul_State * state, unsigned reg,
 | 
			
		||||
                                        unsigned cpnum);
 | 
			
		||||
//extern int skyeye_instr_debug;
 | 
			
		||||
/* Definitions for the support routines.  */
 | 
			
		||||
 | 
			
		||||
static ARMword ModeToBank (ARMword);
 | 
			
		||||
static void EnvokeList (ARMul_State *, unsigned int, unsigned int);
 | 
			
		||||
 | 
			
		||||
struct EventNode
 | 
			
		||||
{				/* An event list node.  */
 | 
			
		||||
	unsigned (*func) (ARMul_State *);	/* The function to call.  */
 | 
			
		||||
	struct EventNode *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* This routine returns the value of a register from a mode.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetReg (ARMul_State * state, unsigned mode, unsigned reg)
 | 
			
		||||
{
 | 
			
		||||
	mode &= MODEBITS;
 | 
			
		||||
	if (mode != state->Mode)
 | 
			
		||||
		return (state->RegBank[ModeToBank ((ARMword) mode)][reg]);
 | 
			
		||||
	else
 | 
			
		||||
		return (state->Reg[reg]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine sets the value of a register for a mode.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SetReg (ARMul_State * state, unsigned mode, unsigned reg, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	mode &= MODEBITS;
 | 
			
		||||
	if (mode != state->Mode)
 | 
			
		||||
		state->RegBank[ModeToBank ((ARMword) mode)][reg] = value;
 | 
			
		||||
	else
 | 
			
		||||
		state->Reg[reg] = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine returns the value of the PC, mode independently.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetPC (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	if (state->Mode > SVC26MODE)
 | 
			
		||||
		return state->Reg[15];
 | 
			
		||||
	else
 | 
			
		||||
		return R15PC;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine returns the value of the PC, mode independently.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetNextPC (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	if (state->Mode > SVC26MODE)
 | 
			
		||||
		return state->Reg[15] + isize;
 | 
			
		||||
	else
 | 
			
		||||
		return (state->Reg[15] + isize) & R15PCBITS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine sets the value of the PC.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SetPC (ARMul_State * state, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	if (ARMul_MODE32BIT)
 | 
			
		||||
		state->Reg[15] = value & PCBITS;
 | 
			
		||||
	else
 | 
			
		||||
		state->Reg[15] = R15CCINTMODE | (value & R15PCBITS);
 | 
			
		||||
	FLUSHPIPE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine returns the value of register 15, mode independently.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetR15 (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	if (state->Mode > SVC26MODE)
 | 
			
		||||
		return (state->Reg[15]);
 | 
			
		||||
	else
 | 
			
		||||
		return (R15PC | ECC | ER15INT | EMODE);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine sets the value of Register 15.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SetR15 (ARMul_State * state, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	if (ARMul_MODE32BIT)
 | 
			
		||||
		state->Reg[15] = value & PCBITS;
 | 
			
		||||
	else {
 | 
			
		||||
		state->Reg[15] = value;
 | 
			
		||||
		ARMul_R15Altered (state);
 | 
			
		||||
	}
 | 
			
		||||
	FLUSHPIPE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine returns the value of the CPSR.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetCPSR (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	//chy 2003-08-20: below is from gdb20030716, maybe isn't suitable for system simulator
 | 
			
		||||
	//return (CPSR | state->Cpsr); for gdb20030716
 | 
			
		||||
    // NOTE(bunnei): Changed this from [now] commented out macro "CPSR"
 | 
			
		||||
    return ((ECC | EINT | EMODE | (TFLAG << 5)));	//had be tested in old skyeye with gdb5.0-5.3
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine sets the value of the CPSR.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SetCPSR (ARMul_State * state, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	state->Cpsr = value;
 | 
			
		||||
	ARMul_CPSRAltered (state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine does all the nasty bits involved in a write to the CPSR,
 | 
			
		||||
   including updating the register bank, given a MSR instruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_FixCPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 | 
			
		||||
{  
 | 
			
		||||
	state->Cpsr = ARMul_GetCPSR (state);
 | 
			
		||||
	//chy 2006-02-16 , should not consider system mode, don't conside 26bit mode
 | 
			
		||||
	if (state->Mode != USER26MODE && state->Mode != USER32MODE ) {
 | 
			
		||||
		/* In user mode, only write flags.  */
 | 
			
		||||
		if (BIT (16))
 | 
			
		||||
			SETPSR_C (state->Cpsr, rhs);
 | 
			
		||||
		if (BIT (17))
 | 
			
		||||
			SETPSR_X (state->Cpsr, rhs);
 | 
			
		||||
		if (BIT (18))
 | 
			
		||||
			SETPSR_S (state->Cpsr, rhs);
 | 
			
		||||
	}
 | 
			
		||||
	if (BIT (19))
 | 
			
		||||
		SETPSR_F (state->Cpsr, rhs);
 | 
			
		||||
	ARMul_CPSRAltered (state);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Get an SPSR from the specified mode.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_GetSPSR (ARMul_State * state, ARMword mode)
 | 
			
		||||
{
 | 
			
		||||
	ARMword bank = ModeToBank (mode & MODEBITS);
 | 
			
		||||
 | 
			
		||||
	if (!BANK_CAN_ACCESS_SPSR (bank))
 | 
			
		||||
		return ARMul_GetCPSR (state);
 | 
			
		||||
 | 
			
		||||
	return state->Spsr[bank];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine does a write to an SPSR.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SetSPSR (ARMul_State * state, ARMword mode, ARMword value)
 | 
			
		||||
{
 | 
			
		||||
	ARMword bank = ModeToBank (mode & MODEBITS);
 | 
			
		||||
 | 
			
		||||
	if (BANK_CAN_ACCESS_SPSR (bank))
 | 
			
		||||
		state->Spsr[bank] = value;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine does a write to the current SPSR, given an MSR instruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_FixSPSR (ARMul_State * state, ARMword instr, ARMword rhs)
 | 
			
		||||
{
 | 
			
		||||
	if (BANK_CAN_ACCESS_SPSR (state->Bank)) {
 | 
			
		||||
		if (BIT (16))
 | 
			
		||||
			SETPSR_C (state->Spsr[state->Bank], rhs);
 | 
			
		||||
		if (BIT (17))
 | 
			
		||||
			SETPSR_X (state->Spsr[state->Bank], rhs);
 | 
			
		||||
		if (BIT (18))
 | 
			
		||||
			SETPSR_S (state->Spsr[state->Bank], rhs);
 | 
			
		||||
		if (BIT (19))
 | 
			
		||||
			SETPSR_F (state->Spsr[state->Bank], rhs);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine updates the state of the emulator after the Cpsr has been
 | 
			
		||||
   changed.  Both the processor flags and register bank are updated.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_CPSRAltered (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	ARMword oldmode;
 | 
			
		||||
 | 
			
		||||
	if (state->prog32Sig == LOW)
 | 
			
		||||
		state->Cpsr &= (CCBITS | INTBITS | R15MODEBITS);
 | 
			
		||||
 | 
			
		||||
	oldmode = state->Mode;
 | 
			
		||||
 | 
			
		||||
	if (state->Mode != (state->Cpsr & MODEBITS)) {
 | 
			
		||||
		state->Mode =
 | 
			
		||||
			ARMul_SwitchMode (state, state->Mode,
 | 
			
		||||
					  state->Cpsr & MODEBITS);
 | 
			
		||||
 | 
			
		||||
		state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
 | 
			
		||||
	}
 | 
			
		||||
	//state->Cpsr &= ~MODEBITS;
 | 
			
		||||
 | 
			
		||||
	ASSIGNINT (state->Cpsr & INTBITS);
 | 
			
		||||
	//state->Cpsr &= ~INTBITS;
 | 
			
		||||
	ASSIGNN ((state->Cpsr & NBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~NBIT;
 | 
			
		||||
	ASSIGNZ ((state->Cpsr & ZBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~ZBIT;
 | 
			
		||||
	ASSIGNC ((state->Cpsr & CBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~CBIT;
 | 
			
		||||
	ASSIGNV ((state->Cpsr & VBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~VBIT;
 | 
			
		||||
	ASSIGNS ((state->Cpsr & SBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~SBIT;
 | 
			
		||||
#ifdef MODET
 | 
			
		||||
	ASSIGNT ((state->Cpsr & TBIT) != 0);
 | 
			
		||||
	//state->Cpsr &= ~TBIT;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	if (oldmode > SVC26MODE) {
 | 
			
		||||
		if (state->Mode <= SVC26MODE) {
 | 
			
		||||
			state->Emulate = CHANGEMODE;
 | 
			
		||||
			state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		if (state->Mode > SVC26MODE) {
 | 
			
		||||
			state->Emulate = CHANGEMODE;
 | 
			
		||||
			state->Reg[15] = R15PC;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			state->Reg[15] = ECC | ER15INT | EMODE | R15PC;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine updates the state of the emulator after register 15 has
 | 
			
		||||
   been changed.  Both the processor flags and register bank are updated.
 | 
			
		||||
   This routine should only be called from a 26 bit mode.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_R15Altered (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	if (state->Mode != R15MODE) {
 | 
			
		||||
		state->Mode = ARMul_SwitchMode (state, state->Mode, R15MODE);
 | 
			
		||||
		state->NtransSig = (state->Mode & 3) ? HIGH : LOW;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (state->Mode > SVC26MODE)
 | 
			
		||||
		state->Emulate = CHANGEMODE;
 | 
			
		||||
 | 
			
		||||
	ASSIGNR15INT (R15INT);
 | 
			
		||||
 | 
			
		||||
	ASSIGNN ((state->Reg[15] & NBIT) != 0);
 | 
			
		||||
	ASSIGNZ ((state->Reg[15] & ZBIT) != 0);
 | 
			
		||||
	ASSIGNC ((state->Reg[15] & CBIT) != 0);
 | 
			
		||||
	ASSIGNV ((state->Reg[15] & VBIT) != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine controls the saving and restoring of registers across mode
 | 
			
		||||
   changes.  The regbank matrix is largely unused, only rows 13 and 14 are
 | 
			
		||||
   used across all modes, 8 to 14 are used for FIQ, all others use the USER
 | 
			
		||||
   column.  It's easier this way.  old and new parameter are modes numbers.
 | 
			
		||||
   Notice the side effect of changing the Bank variable.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_SwitchMode (ARMul_State * state, ARMword oldmode, ARMword newmode)
 | 
			
		||||
{
 | 
			
		||||
	unsigned i;
 | 
			
		||||
	ARMword oldbank;
 | 
			
		||||
	ARMword newbank;
 | 
			
		||||
	static int revision_value = 53;
 | 
			
		||||
 | 
			
		||||
	oldbank = ModeToBank (oldmode);
 | 
			
		||||
	newbank = state->Bank = ModeToBank (newmode);
 | 
			
		||||
 | 
			
		||||
	/* Do we really need to do it?  */
 | 
			
		||||
	if (oldbank != newbank) {
 | 
			
		||||
		if (oldbank == 3 && newbank == 2) {
 | 
			
		||||
			//printf("icounter is %d PC is %x MODE CHANGED : %d --> %d\n", state->NumInstrs, state->pc, oldbank, newbank);
 | 
			
		||||
			if (state->NumInstrs >= 5832487) {
 | 
			
		||||
//				printf("%d, ", state->NumInstrs + revision_value);
 | 
			
		||||
//				printf("revision_value : %d\n", revision_value);
 | 
			
		||||
				revision_value ++;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/* Save away the old registers.  */
 | 
			
		||||
		switch (oldbank) {
 | 
			
		||||
		case USERBANK:
 | 
			
		||||
		case IRQBANK:
 | 
			
		||||
		case SVCBANK:
 | 
			
		||||
		case ABORTBANK:
 | 
			
		||||
		case UNDEFBANK:
 | 
			
		||||
			if (newbank == FIQBANK)
 | 
			
		||||
				for (i = 8; i < 13; i++)
 | 
			
		||||
					state->RegBank[USERBANK][i] =
 | 
			
		||||
						state->Reg[i];
 | 
			
		||||
			state->RegBank[oldbank][13] = state->Reg[13];
 | 
			
		||||
			state->RegBank[oldbank][14] = state->Reg[14];
 | 
			
		||||
			break;
 | 
			
		||||
		case FIQBANK:
 | 
			
		||||
			for (i = 8; i < 15; i++)
 | 
			
		||||
				state->RegBank[FIQBANK][i] = state->Reg[i];
 | 
			
		||||
			break;
 | 
			
		||||
		case DUMMYBANK:
 | 
			
		||||
			for (i = 8; i < 15; i++)
 | 
			
		||||
				state->RegBank[DUMMYBANK][i] = 0;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			abort ();
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Restore the new registers.  */
 | 
			
		||||
		switch (newbank) {
 | 
			
		||||
		case USERBANK:
 | 
			
		||||
		case IRQBANK:
 | 
			
		||||
		case SVCBANK:
 | 
			
		||||
		case ABORTBANK:
 | 
			
		||||
		case UNDEFBANK:
 | 
			
		||||
			if (oldbank == FIQBANK)
 | 
			
		||||
				for (i = 8; i < 13; i++)
 | 
			
		||||
					state->Reg[i] =
 | 
			
		||||
						state->RegBank[USERBANK][i];
 | 
			
		||||
			state->Reg[13] = state->RegBank[newbank][13];
 | 
			
		||||
			state->Reg[14] = state->RegBank[newbank][14];
 | 
			
		||||
			break;
 | 
			
		||||
		case FIQBANK:
 | 
			
		||||
			for (i = 8; i < 15; i++)
 | 
			
		||||
				state->Reg[i] = state->RegBank[FIQBANK][i];
 | 
			
		||||
			break;
 | 
			
		||||
		case DUMMYBANK:
 | 
			
		||||
			for (i = 8; i < 15; i++)
 | 
			
		||||
				state->Reg[i] = 0;
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			abort ();
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return newmode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Given a processor mode, this routine returns the
 | 
			
		||||
   register bank that will be accessed in that mode.  */
 | 
			
		||||
 | 
			
		||||
static ARMword
 | 
			
		||||
ModeToBank (ARMword mode)
 | 
			
		||||
{
 | 
			
		||||
	static ARMword bankofmode[] = {
 | 
			
		||||
		USERBANK, FIQBANK, IRQBANK, SVCBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, DUMMYBANK,
 | 
			
		||||
		USERBANK, FIQBANK, IRQBANK, SVCBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, ABORTBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, UNDEFBANK,
 | 
			
		||||
		DUMMYBANK, DUMMYBANK, DUMMYBANK, SYSTEMBANK
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	if (mode >= (sizeof (bankofmode) / sizeof (bankofmode[0])))
 | 
			
		||||
		return DUMMYBANK;
 | 
			
		||||
 | 
			
		||||
	return bankofmode[mode];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Returns the register number of the nth register in a reg list.  */
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
ARMul_NthReg (ARMword instr, unsigned number)
 | 
			
		||||
{
 | 
			
		||||
	unsigned bit, upto;
 | 
			
		||||
 | 
			
		||||
	for (bit = 0, upto = 0; upto <= number; bit++)
 | 
			
		||||
		if (BIT (bit))
 | 
			
		||||
			upto++;
 | 
			
		||||
 | 
			
		||||
	return (bit - 1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assigns the N and Z flags depending on the value of result.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_NegZero (ARMul_State * state, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	if (NEG (result)) {
 | 
			
		||||
		SETN;
 | 
			
		||||
		CLEARZ;
 | 
			
		||||
	}
 | 
			
		||||
	else if (result == 0) {
 | 
			
		||||
		CLEARN;
 | 
			
		||||
		SETZ;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		CLEARN;
 | 
			
		||||
		CLEARZ;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Compute whether an addition of A and B, giving RESULT, overflowed.  */
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
AddOverflow (ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	return ((NEG (a) && NEG (b) && POS (result))
 | 
			
		||||
		|| (POS (a) && POS (b) && NEG (result)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Compute whether a subtraction of A and B, giving RESULT, overflowed.  */
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
SubOverflow (ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	return ((NEG (a) && POS (b) && POS (result))
 | 
			
		||||
		|| (POS (a) && NEG (b) && NEG (result)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assigns the C flag after an addition of a and b to give result.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_AddCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	ASSIGNC ((NEG (a) && NEG (b)) ||
 | 
			
		||||
		 (NEG (a) && POS (result)) || (NEG (b) && POS (result)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assigns the V flag after an addition of a and b to give result.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_AddOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	ASSIGNV (AddOverflow (a, b, result));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assigns the C flag after an subtraction of a and b to give result.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SubCarry (ARMul_State * state, ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	ASSIGNC ((NEG (a) && POS (b)) ||
 | 
			
		||||
		 (NEG (a) && POS (result)) || (POS (b) && POS (result)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Assigns the V flag after an subtraction of a and b to give result.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_SubOverflow (ARMul_State * state, ARMword a, ARMword b, ARMword result)
 | 
			
		||||
{
 | 
			
		||||
	ASSIGNV (SubOverflow (a, b, result));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the work of generating the addresses used in an
 | 
			
		||||
   LDC instruction.  The code here is always post-indexed, it's up to the
 | 
			
		||||
   caller to get the input address correct and to handle base register
 | 
			
		||||
   modification. It also handles the Busy-Waiting.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_LDC (ARMul_State * state, ARMword instr, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
	ARMword data;
 | 
			
		||||
 | 
			
		||||
	UNDEF_LSCPCBaseWb;
 | 
			
		||||
	//printf("SKYEYE ARMul_LDC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
 | 
			
		||||
/*chy 2004-05-23 should update this function in the future,should concern dataabort*/
 | 
			
		||||
// chy 2004-05-25 , fix it now,so needn't printf 
 | 
			
		||||
//  printf("SKYEYE ARMul_LDC, should update this function!!!!!\n");
 | 
			
		||||
	//exit(-1);
 | 
			
		||||
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		/* 
 | 
			
		||||
		   printf
 | 
			
		||||
		   ("SKYEYE ARMul_LDC,NOT ALLOW, underinstr, CPnum is %x, instr %x, addr %x\n",
 | 
			
		||||
		   CPNum, instr, address);
 | 
			
		||||
		 */
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ADDREXCEPT (address))
 | 
			
		||||
		INTERNALABORT (address);
 | 
			
		||||
 | 
			
		||||
	cpab = (state->LDC[CPNum]) (state, ARMul_FIRST, instr, 0);
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->LDC[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->LDC[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    0);
 | 
			
		||||
	}
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		/* 
 | 
			
		||||
		   printf
 | 
			
		||||
		   ("SKYEYE ARMul_LDC,NOT CAN, underinstr, CPnum is %x, instr %x, addr %x\n",
 | 
			
		||||
		   CPNum, instr, address);
 | 
			
		||||
		 */
 | 
			
		||||
		CPTAKEABORT;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpab = (state->LDC[CPNum]) (state, ARMul_TRANSFER, instr, 0);
 | 
			
		||||
	data = ARMul_LoadWordN (state, address);
 | 
			
		||||
	//chy 2004-05-25      
 | 
			
		||||
	if (state->abortSig || state->Aborted)
 | 
			
		||||
		goto L_ldc_takeabort;
 | 
			
		||||
 | 
			
		||||
	BUSUSEDINCPCN;
 | 
			
		||||
//chy 2004-05-25
 | 
			
		||||
/*
 | 
			
		||||
  if (BIT (21))
 | 
			
		||||
    LSBase = state->Base;
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
	cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
 | 
			
		||||
 | 
			
		||||
	while (cpab == ARMul_INC) {
 | 
			
		||||
		address += 4;
 | 
			
		||||
		data = ARMul_LoadWordN (state, address);
 | 
			
		||||
		//chy 2004-05-25  
 | 
			
		||||
		if (state->abortSig || state->Aborted)
 | 
			
		||||
			goto L_ldc_takeabort;
 | 
			
		||||
 | 
			
		||||
		cpab = (state->LDC[CPNum]) (state, ARMul_DATA, instr, data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
//chy 2004-05-25
 | 
			
		||||
      L_ldc_takeabort:
 | 
			
		||||
	if (BIT (21)) {
 | 
			
		||||
		if (!
 | 
			
		||||
		    ((state->abortSig || state->Aborted)
 | 
			
		||||
		     && state->lateabtSig == LOW))
 | 
			
		||||
			LSBase = state->Base;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (state->abortSig || state->Aborted)
 | 
			
		||||
		TAKEABORT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the work of generating the addresses used in an
 | 
			
		||||
   STC instruction.  The code here is always post-indexed, it's up to the
 | 
			
		||||
   caller to get the input address correct and to handle base register
 | 
			
		||||
   modification. It also handles the Busy-Waiting.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_STC (ARMul_State * state, ARMword instr, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
	ARMword data;
 | 
			
		||||
 | 
			
		||||
	UNDEF_LSCPCBaseWb;
 | 
			
		||||
 | 
			
		||||
	//printf("SKYEYE ARMul_STC, CPnum is %x, instr %x, addr %x\n",CPNum, instr, address);
 | 
			
		||||
	/*chy 2004-05-23 should update this function in the future,should concern dataabort */
 | 
			
		||||
//  skyeye_instr_debug=0;printf("SKYEYE  debug end!!!!\n");
 | 
			
		||||
// chy 2004-05-25 , fix it now,so needn't printf 
 | 
			
		||||
//  printf("SKYEYE ARMul_STC, should update this function!!!!!\n");
 | 
			
		||||
 | 
			
		||||
	//exit(-1);
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		/* 
 | 
			
		||||
		   printf
 | 
			
		||||
		   ("SKYEYE ARMul_STC,NOT ALLOW, undefinstr,  CPnum is %x, instr %x, addr %x\n",
 | 
			
		||||
		   CPNum, instr, address);
 | 
			
		||||
		 */
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (ADDREXCEPT (address) || VECTORACCESS (address))
 | 
			
		||||
		INTERNALABORT (address);
 | 
			
		||||
 | 
			
		||||
	cpab = (state->STC[CPNum]) (state, ARMul_FIRST, instr, &data);
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->STC[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->STC[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    &data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		/* 
 | 
			
		||||
		   printf
 | 
			
		||||
		   ("SKYEYE ARMul_STC,CANT, undefinstr,  CPnum is %x, instr %x, addr %x\n",
 | 
			
		||||
		   CPNum, instr, address);
 | 
			
		||||
		 */
 | 
			
		||||
		CPTAKEABORT;
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#ifndef MODE32
 | 
			
		||||
	if (ADDREXCEPT (address) || VECTORACCESS (address))
 | 
			
		||||
		INTERNALABORT (address);
 | 
			
		||||
#endif
 | 
			
		||||
	BUSUSEDINCPCN;
 | 
			
		||||
//chy 2004-05-25
 | 
			
		||||
/*
 | 
			
		||||
  if (BIT (21))
 | 
			
		||||
    LSBase = state->Base;
 | 
			
		||||
*/
 | 
			
		||||
	cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
 | 
			
		||||
	ARMul_StoreWordN (state, address, data);
 | 
			
		||||
	//chy 2004-05-25      
 | 
			
		||||
	if (state->abortSig || state->Aborted)
 | 
			
		||||
		goto L_stc_takeabort;
 | 
			
		||||
 | 
			
		||||
	while (cpab == ARMul_INC) {
 | 
			
		||||
		address += 4;
 | 
			
		||||
		cpab = (state->STC[CPNum]) (state, ARMul_DATA, instr, &data);
 | 
			
		||||
		ARMul_StoreWordN (state, address, data);
 | 
			
		||||
		//chy 2004-05-25  
 | 
			
		||||
		if (state->abortSig || state->Aborted)
 | 
			
		||||
			goto L_stc_takeabort;
 | 
			
		||||
	}
 | 
			
		||||
//chy 2004-05-25
 | 
			
		||||
      L_stc_takeabort:
 | 
			
		||||
	if (BIT (21)) {
 | 
			
		||||
		if (!
 | 
			
		||||
		    ((state->abortSig || state->Aborted)
 | 
			
		||||
		     && state->lateabtSig == LOW))
 | 
			
		||||
			LSBase = state->Base;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (state->abortSig || state->Aborted)
 | 
			
		||||
		TAKEABORT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the Busy-Waiting for an MCR instruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_MCR (ARMul_State * state, ARMword instr, ARMword source)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
 | 
			
		||||
	//printf("SKYEYE ARMul_MCR, CPnum is %x, source %x\n",CPNum, source);
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		//chy 2004-07-19 should fix in the future ????!!!!
 | 
			
		||||
		//printf("SKYEYE ARMul_MCR, ACCESS_not ALLOWed, UndefinedInstr  CPnum is %x, source %x\n",CPNum, source);
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpab = (state->MCR[CPNum]) (state, ARMul_FIRST, instr, source);
 | 
			
		||||
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->MCR[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->MCR[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    source);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		printf ("SKYEYE ARMul_MCR, CANT, UndefinedInstr %x CPnum is %x, source %x\n", instr, CPNum, source);
 | 
			
		||||
		ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		BUSUSEDINCPCN;
 | 
			
		||||
		ARMul_Ccycles (state, 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the Busy-Waiting for an MCRR instruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_MCRR (ARMul_State * state, ARMword instr, ARMword source1, ARMword source2)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpab = (state->MCRR[CPNum]) (state, ARMul_FIRST, instr, source1, source2);
 | 
			
		||||
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->MCRR[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0, 0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->MCRR[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    source1, source2);
 | 
			
		||||
	}
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x, source %x %x\n", __FUNCTION__, CPNum, instr, source1, source2);
 | 
			
		||||
		ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		BUSUSEDINCPCN;
 | 
			
		||||
		ARMul_Ccycles (state, 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the Busy-Waiting for an MRC instruction.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_MRC (ARMul_State * state, ARMword instr)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
	ARMword result = 0;
 | 
			
		||||
 | 
			
		||||
	//printf("SKYEYE ARMul_MRC, CPnum is %x, instr %x\n",CPNum, instr);
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		//chy 2004-07-19 should fix in the future????!!!!
 | 
			
		||||
		//printf("SKYEYE ARMul_MRC,NOT ALLOWed UndefInstr  CPnum is %x, instr %x\n",CPNum, instr);
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return -1;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpab = (state->MRC[CPNum]) (state, ARMul_FIRST, instr, &result);
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->MRC[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0);
 | 
			
		||||
			return (0);
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->MRC[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    &result);
 | 
			
		||||
	}
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		printf ("SKYEYE ARMul_MRC,CANT UndefInstr  CPnum is %x, instr %x\n", CPNum, instr);
 | 
			
		||||
		ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
		/* Parent will destroy the flags otherwise.  */
 | 
			
		||||
		result = ECC;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		BUSUSEDINCPCN;
 | 
			
		||||
		ARMul_Ccycles (state, 1, 0);
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the Busy-Waiting for an MRRC instruction. (to verify) */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_MRRC (ARMul_State * state, ARMword instr, ARMword * dest1, ARMword * dest2)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
	ARMword result1 = 0;
 | 
			
		||||
	ARMword result2 = 0;
 | 
			
		||||
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cpab = (state->MRRC[CPNum]) (state, ARMul_FIRST, instr, &result1, &result2);
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->MRRC[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr, 0, 0);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->MRRC[CPNum]) (state, ARMul_BUSY, instr,
 | 
			
		||||
						    &result1, &result2);
 | 
			
		||||
	}
 | 
			
		||||
	if (cpab == ARMul_CANT) {
 | 
			
		||||
		printf ("In %s, CoProcesscor returned CANT, CPnum is %x, instr %x\n", __FUNCTION__, CPNum, instr);
 | 
			
		||||
		ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		BUSUSEDINCPCN;
 | 
			
		||||
		ARMul_Ccycles (state, 1, 0);
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	*dest1 = result1;
 | 
			
		||||
	*dest2 = result2;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function does the Busy-Waiting for an CDP instruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_CDP (ARMul_State * state, ARMword instr)
 | 
			
		||||
{
 | 
			
		||||
	unsigned cpab;
 | 
			
		||||
 | 
			
		||||
	if (!CP_ACCESS_ALLOWED (state, CPNum)) {
 | 
			
		||||
		ARMul_UndefInstr (state, instr);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	cpab = (state->CDP[CPNum]) (state, ARMul_FIRST, instr);
 | 
			
		||||
	while (cpab == ARMul_BUSY) {
 | 
			
		||||
		ARMul_Icycles (state, 1, 0);
 | 
			
		||||
		if (IntPending (state)) {
 | 
			
		||||
			cpab = (state->CDP[CPNum]) (state, ARMul_INTERRUPT,
 | 
			
		||||
						    instr);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
			cpab = (state->CDP[CPNum]) (state, ARMul_BUSY, instr);
 | 
			
		||||
	}
 | 
			
		||||
	if (cpab == ARMul_CANT)
 | 
			
		||||
		ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
	else
 | 
			
		||||
		BUSUSEDN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This function handles Undefined instructions, as CP isntruction.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_UndefInstr (ARMul_State * state, ARMword instr)
 | 
			
		||||
{
 | 
			
		||||
	ERROR_LOG(ARM11, "Undefined instruction!! Instr: 0x%x", instr);
 | 
			
		||||
	ARMul_Abort (state, ARMul_UndefinedInstrV);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Return TRUE if an interrupt is pending, FALSE otherwise.  */
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
IntPending (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	/* Any exceptions.  */
 | 
			
		||||
	if (state->NresetSig == LOW) {
 | 
			
		||||
		ARMul_Abort (state, ARMul_ResetV);
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else if (!state->NfiqSig && !FFLAG) {
 | 
			
		||||
		ARMul_Abort (state, ARMul_FIQV);
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
	else if (!state->NirqSig && !IFLAG) {
 | 
			
		||||
		ARMul_Abort (state, ARMul_IRQV);
 | 
			
		||||
		return TRUE;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return FALSE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Align a word access to a non word boundary.  */
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_Align (ARMul_State *state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	/* This code assumes the address is really unaligned,
 | 
			
		||||
	   as a shift by 32 is undefined in C.  */
 | 
			
		||||
 | 
			
		||||
	address = (address & 3) << 3;	/* Get the word address.  */
 | 
			
		||||
	return ((data >> address) | (data << (32 - address)));	/* rot right */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine is used to call another routine after a certain number of
 | 
			
		||||
   cycles have been executed. The first parameter is the number of cycles
 | 
			
		||||
   delay before the function is called, the second argument is a pointer
 | 
			
		||||
   to the function. A delay of zero doesn't work, just call the function.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_ScheduleEvent (ARMul_State * state, unsigned int delay,
 | 
			
		||||
		     unsigned (*what) (ARMul_State *))
 | 
			
		||||
{
 | 
			
		||||
	unsigned int when;
 | 
			
		||||
	struct EventNode *event;
 | 
			
		||||
 | 
			
		||||
	if (state->EventSet++ == 0)
 | 
			
		||||
		state->Now = ARMul_Time (state);
 | 
			
		||||
	when = (state->Now + delay) % EVENTLISTSIZE;
 | 
			
		||||
	event = (struct EventNode *) malloc (sizeof (struct EventNode));
 | 
			
		||||
 | 
			
		||||
	_dbg_assert_msg_(ARM11, event, "SKYEYE:ARMul_ScheduleEvent: malloc event error\n");
 | 
			
		||||
 | 
			
		||||
	event->func = what;
 | 
			
		||||
	event->next = *(state->EventPtr + when);
 | 
			
		||||
	*(state->EventPtr + when) = event;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine is called at the beginning of
 | 
			
		||||
   every cycle, to envoke scheduled events.  */
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_EnvokeEvent (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	static unsigned int then;
 | 
			
		||||
 | 
			
		||||
	then = state->Now;
 | 
			
		||||
	state->Now = ARMul_Time (state) % EVENTLISTSIZE;
 | 
			
		||||
	if (then < state->Now)
 | 
			
		||||
		/* Schedule events.  */
 | 
			
		||||
		EnvokeList (state, then, state->Now);
 | 
			
		||||
	else if (then > state->Now) {
 | 
			
		||||
		/* Need to wrap around the list.  */
 | 
			
		||||
		EnvokeList (state, then, EVENTLISTSIZE - 1L);
 | 
			
		||||
		EnvokeList (state, 0L, state->Now);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Envokes all the entries in a range.  */
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
EnvokeList (ARMul_State * state, unsigned int from, unsigned int to)
 | 
			
		||||
{
 | 
			
		||||
	for (; from <= to; from++) {
 | 
			
		||||
		struct EventNode *anevent;
 | 
			
		||||
 | 
			
		||||
		anevent = *(state->EventPtr + from);
 | 
			
		||||
		while (anevent) {
 | 
			
		||||
			(anevent->func) (state);
 | 
			
		||||
			state->EventSet--;
 | 
			
		||||
			anevent = anevent->next;
 | 
			
		||||
		}
 | 
			
		||||
		*(state->EventPtr + from) = NULL;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* This routine is returns the number of clock ticks since the last reset.  */
 | 
			
		||||
 | 
			
		||||
unsigned int
 | 
			
		||||
ARMul_Time (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
	return (state->NumScycles + state->NumNcycles +
 | 
			
		||||
		state->NumIcycles + state->NumCcycles + state->NumFcycles);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										680
									
								
								src/core/arm/interpreter/armvirt.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										680
									
								
								src/core/arm/interpreter/armvirt.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,680 @@
 | 
			
		||||
/*  armvirt.c -- ARMulator virtual memory interace:  ARM6 Instruction Emulator.
 | 
			
		||||
    Copyright (C) 1994 Advanced RISC Machines Ltd.
 | 
			
		||||
 
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
/* This file contains a complete ARMulator memory model, modelling a
 | 
			
		||||
"virtual memory" system. A much simpler model can be found in armfast.c,
 | 
			
		||||
and that model goes faster too, but has a fixed amount of memory. This
 | 
			
		||||
model's memory has 64K pages, allocated on demand from a 64K entry page
 | 
			
		||||
table. The routines PutWord and GetWord implement this. Pages are never
 | 
			
		||||
freed as they might be needed again. A single area of memory may be
 | 
			
		||||
defined to generate aborts. */
 | 
			
		||||
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
#include "skyeye_defs.h"
 | 
			
		||||
//#include "code_cov.h"
 | 
			
		||||
 | 
			
		||||
#ifdef VALIDATE			/* for running the validate suite */
 | 
			
		||||
#define TUBE 48 * 1024 * 1024	/* write a char on the screen */
 | 
			
		||||
#define ABORTS 1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* #define ABORTS */
 | 
			
		||||
 | 
			
		||||
#ifdef ABORTS			/* the memory system will abort */
 | 
			
		||||
/* For the old test suite Abort between 32 Kbytes and 32 Mbytes
 | 
			
		||||
   For the new test suite Abort between 8 Mbytes and 26 Mbytes */
 | 
			
		||||
/* #define LOWABORT 32 * 1024
 | 
			
		||||
#define HIGHABORT 32 * 1024 * 1024 */
 | 
			
		||||
#define LOWABORT 8 * 1024 * 1024
 | 
			
		||||
#define HIGHABORT 26 * 1024 * 1024
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define NUMPAGES 64 * 1024
 | 
			
		||||
#define PAGESIZE 64 * 1024
 | 
			
		||||
#define PAGEBITS 16
 | 
			
		||||
#define OFFSETBITS 0xffff
 | 
			
		||||
//chy 2003-08-19: seems no use ????
 | 
			
		||||
int SWI_vector_installed = FALSE;
 | 
			
		||||
extern ARMword skyeye_cachetype;
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Get a byte into Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
static fault_t
 | 
			
		||||
GetByte (ARMul_State * state, ARMword address, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_read_byte (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
//              printf("SKYEYE: GetByte fault %d \n", fault);
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Get a halfword into Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
static fault_t
 | 
			
		||||
GetHalfWord (ARMul_State * state, ARMword address, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_read_halfword (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
//              printf("SKYEYE: GetHalfWord fault %d \n", fault);
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Get a Word from Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
static fault_t
 | 
			
		||||
GetWord (ARMul_State * state, ARMword address, ARMword * data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_read_word (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
#if 0
 | 
			
		||||
/* XXX */ extern int hack;
 | 
			
		||||
		hack = 1;
 | 
			
		||||
#endif
 | 
			
		||||
#if 0
 | 
			
		||||
		printf ("mmu_read_word at 0x%08x: ", address);
 | 
			
		||||
		switch (fault) {
 | 
			
		||||
		case ALIGNMENT_FAULT:
 | 
			
		||||
			printf ("ALIGNMENT_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_TRANSLATION_FAULT:
 | 
			
		||||
			printf ("SECTION_TRANSLATION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case PAGE_TRANSLATION_FAULT:
 | 
			
		||||
			printf ("PAGE_TRANSLATION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_DOMAIN_FAULT:
 | 
			
		||||
			printf ("SECTION_DOMAIN_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_PERMISSION_FAULT:
 | 
			
		||||
			printf ("SECTION_PERMISSION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SUBPAGE_PERMISSION_FAULT:
 | 
			
		||||
			printf ("SUBPAGE_PERMISSION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			printf ("Unrecognized fault number!");
 | 
			
		||||
		}
 | 
			
		||||
		printf ("\tpc = 0x%08x\n", state->Reg[15]);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//2003-07-10 chy: lyh change
 | 
			
		||||
/****************************************************************************\
 | 
			
		||||
 * 			Load a Instrion Word into Virtual Memory						*
 | 
			
		||||
\****************************************************************************/
 | 
			
		||||
static fault_t
 | 
			
		||||
LoadInstr (ARMul_State * state, ARMword address, ARMword * instr)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	fault = mmu_load_instr (state, address, instr);
 | 
			
		||||
	return fault;
 | 
			
		||||
	//if (fault)
 | 
			
		||||
	//      log_msg("load_instr fault = %d, address = %x\n", fault, address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Put a byte into Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
static fault_t
 | 
			
		||||
PutByte (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_write_byte (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
//              printf("SKYEYE: PutByte fault %d \n", fault);
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Put a halfword into Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
static fault_t
 | 
			
		||||
PutHalfWord (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_write_halfword (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
//              printf("SKYEYE: PutHalfWord fault %d \n", fault);
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*        Put a Word into Virtual Memory, maybe allocating the page          *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
static fault_t
 | 
			
		||||
PutWord (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = mmu_write_word (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
//chy 2003-07-11: sometime has fault, but linux can continue running  !!!!????
 | 
			
		||||
#if 0
 | 
			
		||||
/* XXX */ extern int hack;
 | 
			
		||||
		hack = 1;
 | 
			
		||||
#endif
 | 
			
		||||
#if 0
 | 
			
		||||
		printf ("mmu_write_word at 0x%08x: ", address);
 | 
			
		||||
		switch (fault) {
 | 
			
		||||
		case ALIGNMENT_FAULT:
 | 
			
		||||
			printf ("ALIGNMENT_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_TRANSLATION_FAULT:
 | 
			
		||||
			printf ("SECTION_TRANSLATION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case PAGE_TRANSLATION_FAULT:
 | 
			
		||||
			printf ("PAGE_TRANSLATION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_DOMAIN_FAULT:
 | 
			
		||||
			printf ("SECTION_DOMAIN_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SECTION_PERMISSION_FAULT:
 | 
			
		||||
			printf ("SECTION_PERMISSION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		case SUBPAGE_PERMISSION_FAULT:
 | 
			
		||||
			printf ("SUBPAGE_PERMISSION_FAULT");
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			printf ("Unrecognized fault number!");
 | 
			
		||||
		}
 | 
			
		||||
		printf ("\tpc = 0x%08x\n", state->Reg[15]);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
	return fault;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                      Initialise the memory interface                      *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
unsigned
 | 
			
		||||
ARMul_MemoryInit (ARMul_State * state, unsigned int initmemsize)
 | 
			
		||||
{
 | 
			
		||||
	return TRUE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                         Remove the memory interface                       *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_MemoryExit (ARMul_State * state)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                   ReLoad Instruction                                     *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_ReLoadInstr (ARMul_State * state, ARMword address, ARMword isize)
 | 
			
		||||
{
 | 
			
		||||
	ARMword data;
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
#ifdef ABORTS
 | 
			
		||||
	if (address >= LOWABORT && address < HIGHABORT) {
 | 
			
		||||
		ARMul_PREFETCHABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
#if 0
 | 
			
		||||
	/* do profiling for code coverage */
 | 
			
		||||
	if (skyeye_config.code_cov.prof_on)
 | 
			
		||||
			cov_prof(EXEC_FLAG, address);
 | 
			
		||||
#endif
 | 
			
		||||
#if 1
 | 
			
		||||
	if ((isize == 2) && (address & 0x2)) {
 | 
			
		||||
		ARMword lo, hi;
 | 
			
		||||
		if (!(skyeye_cachetype == INSTCACHE))
 | 
			
		||||
			fault = GetHalfWord (state, address, &lo);
 | 
			
		||||
		else
 | 
			
		||||
			fault = LoadInstr (state, address, &lo);
 | 
			
		||||
#if 0
 | 
			
		||||
		if (!fault) {
 | 
			
		||||
			if (!(skyeye_cachetype == INSTCACHE))
 | 
			
		||||
				fault = GetHalfWord (state, address + isize, &hi);
 | 
			
		||||
			else
 | 
			
		||||
				fault = LoadInstr (state, address + isize, &hi);
 | 
			
		||||
 | 
			
		||||
		}
 | 
			
		||||
#endif
 | 
			
		||||
		if (fault) {
 | 
			
		||||
			ARMul_PREFETCHABORT (address);
 | 
			
		||||
			return ARMul_ABORTWORD;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			ARMul_CLEARABORT;
 | 
			
		||||
		}
 | 
			
		||||
		return lo;
 | 
			
		||||
#if 0
 | 
			
		||||
		if (state->bigendSig == HIGH)
 | 
			
		||||
			return (lo << 16) | (hi >> 16);
 | 
			
		||||
		else
 | 
			
		||||
			return ((hi & 0xFFFF) << 16) | (lo >> 16);
 | 
			
		||||
#endif
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
	if (!(skyeye_cachetype == INSTCACHE))
 | 
			
		||||
		fault = GetWord (state, address, &data);
 | 
			
		||||
	else
 | 
			
		||||
		fault = LoadInstr (state, address, &data);
 | 
			
		||||
 | 
			
		||||
	if (fault) {
 | 
			
		||||
 | 
			
		||||
		/* dyf add for s3c6410 no instcache temporary 2010.9.17 */
 | 
			
		||||
		if (!(skyeye_cachetype == INSTCACHE)) {
 | 
			
		||||
			/* set translation fault  on prefetch abort */
 | 
			
		||||
			state->mmu.fault_statusi = fault  & 0xFF;
 | 
			
		||||
			state->mmu.fault_address = address;
 | 
			
		||||
		}
 | 
			
		||||
		/* add end */
 | 
			
		||||
 | 
			
		||||
		ARMul_PREFETCHABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                   Load Instruction, Sequential Cycle                      *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadInstrS (ARMul_State * state, ARMword address, ARMword isize)
 | 
			
		||||
{
 | 
			
		||||
	state->NumScycles++;
 | 
			
		||||
 | 
			
		||||
#ifdef HOURGLASS
 | 
			
		||||
	if ((state->NumScycles & HOURGLASS_RATE) == 0) {
 | 
			
		||||
		HOURGLASS;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	return ARMul_ReLoadInstr (state, address, isize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                 Load Instruction, Non Sequential Cycle                    *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadInstrN (ARMul_State * state, ARMword address, ARMword isize)
 | 
			
		||||
{
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	return ARMul_ReLoadInstr (state, address, isize);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                      Read Word (but don't tell anyone!)                   *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_ReadWord (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	ARMword data;
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
#ifdef ABORTS
 | 
			
		||||
	if (address >= LOWABORT && address < HIGHABORT) {
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	fault = GetWord (state, address, &data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
	return data;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                        Load Word, Sequential Cycle                        *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadWordS (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	state->NumScycles++;
 | 
			
		||||
 | 
			
		||||
	return ARMul_ReadWord (state, address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                      Load Word, Non Sequential Cycle                      *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadWordN (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	return ARMul_ReadWord (state, address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                     Load Halfword, (Non Sequential Cycle)                 *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadHalfWord (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	ARMword data;
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
	fault = GetHalfWord (state, address, &data);
 | 
			
		||||
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                      Read Byte (but don't tell anyone!)                   *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
int ARMul_ICE_ReadByte(ARMul_State * state, ARMword address, ARMword *presult)
 | 
			
		||||
{
 | 
			
		||||
 ARMword data;
 | 
			
		||||
 fault_t fault;
 | 
			
		||||
 fault = GetByte (state, address, &data);
 | 
			
		||||
 if (fault) {
 | 
			
		||||
	 *presult=-1; fault=ALIGNMENT_FAULT; return fault;
 | 
			
		||||
 }else{
 | 
			
		||||
	 *(char *)presult=(unsigned char)(data & 0xff); fault=NO_FAULT; return fault;
 | 
			
		||||
 }
 | 
			
		||||
}
 | 
			
		||||
	 
 | 
			
		||||
 
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_ReadByte (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	ARMword data;
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
	fault = GetByte (state, address, &data);
 | 
			
		||||
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return ARMul_ABORTWORD;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return data;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                     Load Byte, (Non Sequential Cycle)                     *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_LoadByte (ARMul_State * state, ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	return ARMul_ReadByte (state, address);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                     Write Word (but don't tell anyone!)                   *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_WriteWord (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
 | 
			
		||||
#ifdef ABORTS
 | 
			
		||||
	if (address >= LOWABORT && address < HIGHABORT) {
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	fault = PutWord (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                       Store Word, Sequential Cycle                        *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_StoreWordS (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	state->NumScycles++;
 | 
			
		||||
 | 
			
		||||
	ARMul_WriteWord (state, address, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                       Store Word, Non Sequential Cycle                        *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_StoreWordN (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	ARMul_WriteWord (state, address, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                    Store HalfWord, (Non Sequential Cycle)                 *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_StoreHalfWord (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
	fault = PutHalfWord (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//chy 2006-04-15 
 | 
			
		||||
int ARMul_ICE_WriteByte (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	fault = PutByte (state, address, data);
 | 
			
		||||
	if (fault) 
 | 
			
		||||
		return 1; 
 | 
			
		||||
	else 
 | 
			
		||||
		return 0;
 | 
			
		||||
}
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                     Write Byte (but don't tell anyone!)                   *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
//chy 2003-07-10, add real write byte fun
 | 
			
		||||
void
 | 
			
		||||
ARMul_WriteByte (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	fault_t fault;
 | 
			
		||||
	fault = PutByte (state, address, data);
 | 
			
		||||
	if (fault) {
 | 
			
		||||
		state->mmu.fault_status =
 | 
			
		||||
			(fault | (state->mmu.last_domain << 4)) & 0xFF;
 | 
			
		||||
		state->mmu.fault_address = address;
 | 
			
		||||
		ARMul_DATAABORT (address);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		ARMul_CLEARABORT;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                    Store Byte, (Non Sequential Cycle)                     *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_StoreByte (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
#ifdef VALIDATE
 | 
			
		||||
	if (address == TUBE) {
 | 
			
		||||
		if (data == 4)
 | 
			
		||||
			state->Emulate = FALSE;
 | 
			
		||||
		else
 | 
			
		||||
			(void) putc ((char) data, stderr);	/* Write Char */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	ARMul_WriteByte (state, address, data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                   Swap Word, (Two Non Sequential Cycles)                  *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_SwapWord (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	ARMword temp;
 | 
			
		||||
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	temp = ARMul_ReadWord (state, address);
 | 
			
		||||
 | 
			
		||||
	state->NumNcycles++;
 | 
			
		||||
 | 
			
		||||
	PutWord (state, address, data);
 | 
			
		||||
 | 
			
		||||
	return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                   Swap Byte, (Two Non Sequential Cycles)                  *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
ARMul_SwapByte (ARMul_State * state, ARMword address, ARMword data)
 | 
			
		||||
{
 | 
			
		||||
	ARMword temp;
 | 
			
		||||
 | 
			
		||||
	temp = ARMul_LoadByte (state, address);
 | 
			
		||||
	ARMul_StoreByte (state, address, data);
 | 
			
		||||
 | 
			
		||||
	return temp;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                             Count I Cycles                                *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_Icycles (ARMul_State * state, unsigned number,
 | 
			
		||||
	       ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	state->NumIcycles += number;
 | 
			
		||||
	ARMul_CLEARABORT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/***************************************************************************\
 | 
			
		||||
*                             Count C Cycles                                *
 | 
			
		||||
\***************************************************************************/
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
ARMul_Ccycles (ARMul_State * state, unsigned number,
 | 
			
		||||
	       ARMword address)
 | 
			
		||||
{
 | 
			
		||||
	state->NumCcycles += number;
 | 
			
		||||
	ARMul_CLEARABORT;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										111
									
								
								src/core/arm/interpreter/skyeye_defs.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								src/core/arm/interpreter/skyeye_defs.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,111 @@
 | 
			
		||||
#ifndef CORE_ARM_SKYEYE_DEFS_H_
 | 
			
		||||
#define CORE_ARM_SKYEYE_DEFS_H_
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#define MODE32
 | 
			
		||||
#define MODET
 | 
			
		||||
 | 
			
		||||
typedef struct
 | 
			
		||||
{
 | 
			
		||||
	const char *cpu_arch_name;	/*cpu architecture version name.e.g. armv4t */
 | 
			
		||||
	const char *cpu_name;	/*cpu name. e.g. arm7tdmi or arm720t */
 | 
			
		||||
	u32 cpu_val;	/*CPU value; also call MMU ID or processor id;see
 | 
			
		||||
				   ARM Architecture Reference Manual B2-6 */
 | 
			
		||||
	u32 cpu_mask;	/*cpu_val's mask. */
 | 
			
		||||
	u32 cachetype;	/*this cpu has what kind of cache */
 | 
			
		||||
} cpu_config_t;
 | 
			
		||||
 | 
			
		||||
typedef struct conf_object_s{
 | 
			
		||||
	char* objname;
 | 
			
		||||
	void* obj;
 | 
			
		||||
	char* class_name;
 | 
			
		||||
}conf_object_t;
 | 
			
		||||
 | 
			
		||||
typedef enum{
 | 
			
		||||
	/* No exception */
 | 
			
		||||
	No_exp = 0,
 | 
			
		||||
	/* Memory allocation exception */
 | 
			
		||||
	Malloc_exp,
 | 
			
		||||
	/* File open exception */
 | 
			
		||||
	File_open_exp,
 | 
			
		||||
	/* DLL open exception */
 | 
			
		||||
	Dll_open_exp,
 | 
			
		||||
	/* Invalid argument exception */
 | 
			
		||||
	Invarg_exp,
 | 
			
		||||
	/* Invalid module exception */
 | 
			
		||||
	Invmod_exp,
 | 
			
		||||
	/* wrong format exception for config file parsing */
 | 
			
		||||
	Conf_format_exp,
 | 
			
		||||
	/* some reference excess the predefiend range. Such as the index out of array range */
 | 
			
		||||
	Excess_range_exp,
 | 
			
		||||
	/* Can not find the desirable result */
 | 
			
		||||
	Not_found_exp,
 | 
			
		||||
 | 
			
		||||
	/* Unknown exception */
 | 
			
		||||
	Unknown_exp
 | 
			
		||||
}exception_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	Align = 0,
 | 
			
		||||
	UnAlign	
 | 
			
		||||
}align_t;
 | 
			
		||||
 | 
			
		||||
typedef enum {
 | 
			
		||||
	Little_endian = 0,
 | 
			
		||||
	Big_endian
 | 
			
		||||
}endian_t;
 | 
			
		||||
//typedef int exception_t;
 | 
			
		||||
 | 
			
		||||
typedef enum{
 | 
			
		||||
	Phys_addr = 0,
 | 
			
		||||
	Virt_addr
 | 
			
		||||
}addr_type_t;
 | 
			
		||||
 | 
			
		||||
typedef exception_t(*read_byte_t)(conf_object_t* target, u32 addr, void *buf, size_t count);
 | 
			
		||||
typedef exception_t(*write_byte_t)(conf_object_t* target, u32 addr, const void *buf, size_t count);
 | 
			
		||||
 | 
			
		||||
typedef struct memory_space{
 | 
			
		||||
	conf_object_t* conf_obj;
 | 
			
		||||
	read_byte_t read;
 | 
			
		||||
	write_byte_t write;
 | 
			
		||||
}memory_space_intf;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * a running instance for a specific archteciture.
 | 
			
		||||
 */
 | 
			
		||||
typedef struct generic_arch_s
 | 
			
		||||
{
 | 
			
		||||
	char* arch_name;
 | 
			
		||||
	void (*init) (void);
 | 
			
		||||
	void (*reset) (void);
 | 
			
		||||
	void (*step_once) (void);
 | 
			
		||||
	void (*set_pc)(u32 addr);
 | 
			
		||||
	u32 (*get_pc)(void);
 | 
			
		||||
	u32 (*get_step)(void);
 | 
			
		||||
	//chy 2004-04-15 
 | 
			
		||||
	//int (*ICE_write_byte) (u32 addr, uint8_t v);
 | 
			
		||||
	//int (*ICE_read_byte)(u32 addr, uint8_t *pv);
 | 
			
		||||
	u32 (*get_regval_by_id)(int id);
 | 
			
		||||
	u32 (*get_regnum)(void);
 | 
			
		||||
	char* (*get_regname_by_id)(int id);
 | 
			
		||||
	exception_t (*set_regval_by_id)(int id, u32 value);
 | 
			
		||||
	/*
 | 
			
		||||
	 * read a data by virtual address.
 | 
			
		||||
	 */
 | 
			
		||||
	exception_t (*mmu_read)(short size, u32 addr, u32 * value);
 | 
			
		||||
	/*
 | 
			
		||||
	 * write a data by a virtual address.
 | 
			
		||||
	 */
 | 
			
		||||
	exception_t (*mmu_write)(short size, u32 addr, u32 value);
 | 
			
		||||
	/**
 | 
			
		||||
	 * get a signal from external
 | 
			
		||||
	 */
 | 
			
		||||
	//exception_t (*signal)(interrupt_signal_t* signal);
 | 
			
		||||
 | 
			
		||||
	endian_t endianess;
 | 
			
		||||
	align_t alignment;
 | 
			
		||||
} generic_arch_t;
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										513
									
								
								src/core/arm/interpreter/thumbemu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										513
									
								
								src/core/arm/interpreter/thumbemu.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,513 @@
 | 
			
		||||
/*  thumbemu.c -- Thumb instruction emulation.
 | 
			
		||||
    Copyright (C) 1996, Cygnus Software Technologies Ltd.
 | 
			
		||||
 | 
			
		||||
    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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
 | 
			
		||||
 | 
			
		||||
/* We can provide simple Thumb simulation by decoding the Thumb
 | 
			
		||||
instruction into its corresponding ARM instruction, and using the
 | 
			
		||||
existing ARM simulator.  */
 | 
			
		||||
 | 
			
		||||
#include "skyeye_defs.h"
 | 
			
		||||
 | 
			
		||||
#ifndef MODET			/* required for the Thumb instruction support */
 | 
			
		||||
#if 1
 | 
			
		||||
#error "MODET needs to be defined for the Thumb world to work"
 | 
			
		||||
#else
 | 
			
		||||
#define MODET (1)
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "armdefs.h"
 | 
			
		||||
#include "armemu.h"
 | 
			
		||||
#include "armos.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Decode a 16bit Thumb instruction.  The instruction is in the low
 | 
			
		||||
   16-bits of the tinstr field, with the following Thumb instruction
 | 
			
		||||
   held in the high 16-bits.  Passing in two Thumb instructions allows
 | 
			
		||||
   easier simulation of the special dual BL instruction.  */
 | 
			
		||||
 | 
			
		||||
tdstate
 | 
			
		||||
ARMul_ThumbDecode (
 | 
			
		||||
     ARMul_State *state,
 | 
			
		||||
     ARMword pc,
 | 
			
		||||
     ARMword tinstr,
 | 
			
		||||
     ARMword *ainstr)
 | 
			
		||||
{
 | 
			
		||||
	tdstate valid = t_decoded;	/* default assumes a valid instruction */
 | 
			
		||||
	ARMword next_instr;
 | 
			
		||||
 | 
			
		||||
	if (state->bigendSig) {
 | 
			
		||||
		next_instr = tinstr & 0xFFFF;
 | 
			
		||||
		tinstr >>= 16;
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
		next_instr = tinstr >> 16;
 | 
			
		||||
		tinstr &= 0xFFFF;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
#if 1				/* debugging to catch non updates */
 | 
			
		||||
	*ainstr = 0xDEADC0DE;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	switch ((tinstr & 0xF800) >> 11) {
 | 
			
		||||
	case 0:		/* LSL */
 | 
			
		||||
	case 1:		/* LSR */
 | 
			
		||||
	case 2:		/* ASR */
 | 
			
		||||
		/* Format 1 */
 | 
			
		||||
		*ainstr = 0xE1B00000	/* base opcode */
 | 
			
		||||
			| ((tinstr & 0x1800) >> (11 - 5))	/* shift type */
 | 
			
		||||
			|((tinstr & 0x07C0) << (7 - 6))	/* imm5 */
 | 
			
		||||
			|((tinstr & 0x0038) >> 3)	/* Rs */
 | 
			
		||||
			|((tinstr & 0x0007) << 12);	/* Rd */
 | 
			
		||||
		break;
 | 
			
		||||
	case 3:		/* ADD/SUB */
 | 
			
		||||
		/* Format 2 */
 | 
			
		||||
		{
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE0900000,	/* ADDS Rd,Rs,Rn    */
 | 
			
		||||
				0xE0500000,	/* SUBS Rd,Rs,Rn    */
 | 
			
		||||
				0xE2900000,	/* ADDS Rd,Rs,#imm3 */
 | 
			
		||||
				0xE2500000	/* SUBS Rd,Rs,#imm3 */
 | 
			
		||||
			};
 | 
			
		||||
			/* It is quicker indexing into a table, than performing switch
 | 
			
		||||
			   or conditionals: */
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x0600) >> 9]	/* base opcode */
 | 
			
		||||
				|((tinstr & 0x01C0) >> 6)	/* Rn or imm3 */
 | 
			
		||||
				|((tinstr & 0x0038) << (16 - 3))	/* Rs */
 | 
			
		||||
				|((tinstr & 0x0007) << (12 - 0));	/* Rd */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 4:		/* MOV */
 | 
			
		||||
	case 5:		/* CMP */
 | 
			
		||||
	case 6:		/* ADD */
 | 
			
		||||
	case 7:		/* SUB */
 | 
			
		||||
		/* Format 3 */
 | 
			
		||||
		{
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE3B00000,	/* MOVS Rd,#imm8    */
 | 
			
		||||
				0xE3500000,	/* CMP  Rd,#imm8    */
 | 
			
		||||
				0xE2900000,	/* ADDS Rd,Rd,#imm8 */
 | 
			
		||||
				0xE2500000,	/* SUBS Rd,Rd,#imm8 */
 | 
			
		||||
			};
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x1800) >> 11]	/* base opcode */
 | 
			
		||||
				|((tinstr & 0x00FF) >> 0)	/* imm8 */
 | 
			
		||||
				|((tinstr & 0x0700) << (16 - 8))	/* Rn */
 | 
			
		||||
				|((tinstr & 0x0700) << (12 - 8));	/* Rd */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 8:		/* Arithmetic and high register transfers */
 | 
			
		||||
		/* TODO: Since the subsets for both Format 4 and Format 5
 | 
			
		||||
		   instructions are made up of different ARM encodings, we could
 | 
			
		||||
		   save the following conditional, and just have one large
 | 
			
		||||
		   subset. */
 | 
			
		||||
		if ((tinstr & (1 << 10)) == 0) {
 | 
			
		||||
			/* Format 4 */
 | 
			
		||||
            enum OpcodeType { t_norm, t_shift, t_neg, t_mul };
 | 
			
		||||
			struct ThumbOpcode {
 | 
			
		||||
				ARMword opcode;
 | 
			
		||||
                OpcodeType otype;
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            ThumbOpcode subset[16] = {
 | 
			
		||||
				{
 | 
			
		||||
				0xE0100000, t_norm},	/* ANDS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE0300000, t_norm},	/* EORS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1B00010, t_shift},	/* MOVS Rd,Rd,LSL Rs */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1B00030, t_shift},	/* MOVS Rd,Rd,LSR Rs */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1B00050, t_shift},	/* MOVS Rd,Rd,ASR Rs */
 | 
			
		||||
				{
 | 
			
		||||
				0xE0B00000, t_norm},	/* ADCS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE0D00000, t_norm},	/* SBCS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1B00070, t_shift},	/* MOVS Rd,Rd,ROR Rs */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1100000, t_norm},	/* TST  Rd,Rs        */
 | 
			
		||||
				{
 | 
			
		||||
				0xE2700000, t_neg},	/* RSBS Rd,Rs,#0     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1500000, t_norm},	/* CMP  Rd,Rs        */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1700000, t_norm},	/* CMN  Rd,Rs        */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1900000, t_norm},	/* ORRS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE0100090, t_mul},	/* MULS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1D00000, t_norm},	/* BICS Rd,Rd,Rs     */
 | 
			
		||||
				{
 | 
			
		||||
				0xE1F00000, t_norm}	/* MVNS Rd,Rs        */
 | 
			
		||||
			};
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x03C0) >> 6].opcode;	/* base */
 | 
			
		||||
			switch (subset[(tinstr & 0x03C0) >> 6].otype) {
 | 
			
		||||
			case t_norm:
 | 
			
		||||
				*ainstr |= ((tinstr & 0x0007) << 16)	/* Rn */
 | 
			
		||||
					|((tinstr & 0x0007) << 12)	/* Rd */
 | 
			
		||||
					|((tinstr & 0x0038) >> 3);	/* Rs */
 | 
			
		||||
				break;
 | 
			
		||||
			case t_shift:
 | 
			
		||||
				*ainstr |= ((tinstr & 0x0007) << 12)	/* Rd */
 | 
			
		||||
					|((tinstr & 0x0007) >> 0)	/* Rm */
 | 
			
		||||
					|((tinstr & 0x0038) << (8 - 3));	/* Rs */
 | 
			
		||||
				break;
 | 
			
		||||
			case t_neg:
 | 
			
		||||
				*ainstr |= ((tinstr & 0x0007) << 12)	/* Rd */
 | 
			
		||||
					|((tinstr & 0x0038) << (16 - 3));	/* Rn */
 | 
			
		||||
				break;
 | 
			
		||||
			case t_mul:
 | 
			
		||||
				*ainstr |= ((tinstr & 0x0007) << 16)	/* Rd */
 | 
			
		||||
					|((tinstr & 0x0007) << 8)	/* Rs */
 | 
			
		||||
					|((tinstr & 0x0038) >> 3);	/* Rm */
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			/* Format 5 */
 | 
			
		||||
			ARMword Rd = ((tinstr & 0x0007) >> 0);
 | 
			
		||||
			ARMword Rs = ((tinstr & 0x0038) >> 3);
 | 
			
		||||
			if (tinstr & (1 << 7))
 | 
			
		||||
				Rd += 8;
 | 
			
		||||
			if (tinstr & (1 << 6))
 | 
			
		||||
				Rs += 8;
 | 
			
		||||
			switch ((tinstr & 0x03C0) >> 6) {
 | 
			
		||||
			case 0x1:	/* ADD Rd,Rd,Hs */
 | 
			
		||||
			case 0x2:	/* ADD Hd,Hd,Rs */
 | 
			
		||||
			case 0x3:	/* ADD Hd,Hd,Hs */
 | 
			
		||||
				*ainstr = 0xE0800000	/* base */
 | 
			
		||||
					| (Rd << 16)	/* Rn */
 | 
			
		||||
					|(Rd << 12)	/* Rd */
 | 
			
		||||
					|(Rs << 0);	/* Rm */
 | 
			
		||||
				break;
 | 
			
		||||
			case 0x5:	/* CMP Rd,Hs */
 | 
			
		||||
			case 0x6:	/* CMP Hd,Rs */
 | 
			
		||||
			case 0x7:	/* CMP Hd,Hs */
 | 
			
		||||
				*ainstr = 0xE1500000	/* base */
 | 
			
		||||
					| (Rd << 16)	/* Rn */
 | 
			
		||||
					|(Rd << 12)	/* Rd */
 | 
			
		||||
					|(Rs << 0);	/* Rm */
 | 
			
		||||
				break;
 | 
			
		||||
			case 0x9:	/* MOV Rd,Hs */
 | 
			
		||||
			case 0xA:	/* MOV Hd,Rs */
 | 
			
		||||
			case 0xB:	/* MOV Hd,Hs */
 | 
			
		||||
				*ainstr = 0xE1A00000	/* base */
 | 
			
		||||
					| (Rd << 16)	/* Rn */
 | 
			
		||||
					|(Rd << 12)	/* Rd */
 | 
			
		||||
					|(Rs << 0);	/* Rm */
 | 
			
		||||
				break;
 | 
			
		||||
			case 0xC:	/* BX Rs */
 | 
			
		||||
			case 0xD:	/* BX Hs */
 | 
			
		||||
				*ainstr = 0xE12FFF10	/* base */
 | 
			
		||||
					| ((tinstr & 0x0078) >> 3);	/* Rd */
 | 
			
		||||
				break;
 | 
			
		||||
			case 0x0:	/* UNDEFINED */
 | 
			
		||||
			case 0x4:	/* UNDEFINED */
 | 
			
		||||
			case 0x8:	/* UNDEFINED */
 | 
			
		||||
				valid = t_undefined;
 | 
			
		||||
				break;
 | 
			
		||||
			case 0xE:	/* BLX */
 | 
			
		||||
			case 0xF:	/* BLX */
 | 
			
		||||
				if (state->is_v5) {
 | 
			
		||||
					*ainstr = 0xE1200030	/* base */
 | 
			
		||||
						|(Rs << 0);	/* Rm */
 | 
			
		||||
				} else {
 | 
			
		||||
					valid = t_undefined;
 | 
			
		||||
				}
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 9:		/* LDR Rd,[PC,#imm8] */
 | 
			
		||||
		/* Format 6 */
 | 
			
		||||
		*ainstr = 0xE59F0000	/* base */
 | 
			
		||||
			| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
 | 
			
		||||
			|((tinstr & 0x00FF) << (2 - 0));	/* off8 */
 | 
			
		||||
		break;
 | 
			
		||||
	case 10:
 | 
			
		||||
	case 11:
 | 
			
		||||
		/* TODO: Format 7 and Format 8 perform the same ARM encoding, so
 | 
			
		||||
		   the following could be merged into a single subset, saving on
 | 
			
		||||
		   the following boolean: */
 | 
			
		||||
		if ((tinstr & (1 << 9)) == 0) {
 | 
			
		||||
			/* Format 7 */
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE7800000,	/* STR  Rd,[Rb,Ro] */
 | 
			
		||||
				0xE7C00000,	/* STRB Rd,[Rb,Ro] */
 | 
			
		||||
				0xE7900000,	/* LDR  Rd,[Rb,Ro] */
 | 
			
		||||
				0xE7D00000	/* LDRB Rd,[Rb,Ro] */
 | 
			
		||||
			};
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x0C00) >> 10]	/* base */
 | 
			
		||||
				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
 | 
			
		||||
				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
 | 
			
		||||
				|((tinstr & 0x01C0) >> 6);	/* Ro */
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			/* Format 8 */
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE18000B0,	/* STRH  Rd,[Rb,Ro] */
 | 
			
		||||
				0xE19000D0,	/* LDRSB Rd,[Rb,Ro] */
 | 
			
		||||
				0xE19000B0,	/* LDRH  Rd,[Rb,Ro] */
 | 
			
		||||
				0xE19000F0	/* LDRSH Rd,[Rb,Ro] */
 | 
			
		||||
			};
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x0C00) >> 10]	/* base */
 | 
			
		||||
				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
 | 
			
		||||
				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
 | 
			
		||||
				|((tinstr & 0x01C0) >> 6);	/* Ro */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 12:		/* STR Rd,[Rb,#imm5] */
 | 
			
		||||
	case 13:		/* LDR Rd,[Rb,#imm5] */
 | 
			
		||||
	case 14:		/* STRB Rd,[Rb,#imm5] */
 | 
			
		||||
	case 15:		/* LDRB Rd,[Rb,#imm5] */
 | 
			
		||||
		/* Format 9 */
 | 
			
		||||
		{
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE5800000,	/* STR  Rd,[Rb,#imm5] */
 | 
			
		||||
				0xE5900000,	/* LDR  Rd,[Rb,#imm5] */
 | 
			
		||||
				0xE5C00000,	/* STRB Rd,[Rb,#imm5] */
 | 
			
		||||
				0xE5D00000	/* LDRB Rd,[Rb,#imm5] */
 | 
			
		||||
			};
 | 
			
		||||
			/* The offset range defends on whether we are transferring a
 | 
			
		||||
			   byte or word value: */
 | 
			
		||||
			*ainstr = subset[(tinstr & 0x1800) >> 11]	/* base */
 | 
			
		||||
				|((tinstr & 0x0007) << (12 - 0))	/* Rd */
 | 
			
		||||
				|((tinstr & 0x0038) << (16 - 3))	/* Rb */
 | 
			
		||||
				|((tinstr & 0x07C0) >> (6 - ((tinstr & (1 << 12)) ? 0 : 2)));	/* off5 */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 16:		/* STRH Rd,[Rb,#imm5] */
 | 
			
		||||
	case 17:		/* LDRH Rd,[Rb,#imm5] */
 | 
			
		||||
		/* Format 10 */
 | 
			
		||||
		*ainstr = ((tinstr & (1 << 11))	/* base */
 | 
			
		||||
			   ? 0xE1D000B0	/* LDRH */
 | 
			
		||||
			   : 0xE1C000B0)	/* STRH */
 | 
			
		||||
			|((tinstr & 0x0007) << (12 - 0))	/* Rd */
 | 
			
		||||
			|((tinstr & 0x0038) << (16 - 3))	/* Rb */
 | 
			
		||||
			|((tinstr & 0x01C0) >> (6 - 1))	/* off5, low nibble */
 | 
			
		||||
			|((tinstr & 0x0600) >> (9 - 8));	/* off5, high nibble */
 | 
			
		||||
		break;
 | 
			
		||||
	case 18:		/* STR Rd,[SP,#imm8] */
 | 
			
		||||
	case 19:		/* LDR Rd,[SP,#imm8] */
 | 
			
		||||
		/* Format 11 */
 | 
			
		||||
		*ainstr = ((tinstr & (1 << 11))	/* base */
 | 
			
		||||
			   ? 0xE59D0000	/* LDR */
 | 
			
		||||
			   : 0xE58D0000)	/* STR */
 | 
			
		||||
			|((tinstr & 0x0700) << (12 - 8))	/* Rd */
 | 
			
		||||
			|((tinstr & 0x00FF) << 2);	/* off8 */
 | 
			
		||||
		break;
 | 
			
		||||
	case 20:		/* ADD Rd,PC,#imm8 */
 | 
			
		||||
	case 21:		/* ADD Rd,SP,#imm8 */
 | 
			
		||||
		/* Format 12 */
 | 
			
		||||
		if ((tinstr & (1 << 11)) == 0) {
 | 
			
		||||
			/* NOTE: The PC value used here should by word aligned */
 | 
			
		||||
			/* We encode shift-left-by-2 in the rotate immediate field,
 | 
			
		||||
			   so no shift of off8 is needed.  */
 | 
			
		||||
			*ainstr = 0xE28F0F00	/* base */
 | 
			
		||||
				| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
 | 
			
		||||
				|(tinstr & 0x00FF);	/* off8 */
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			/* We encode shift-left-by-2 in the rotate immediate field,
 | 
			
		||||
			   so no shift of off8 is needed.  */
 | 
			
		||||
			*ainstr = 0xE28D0F00	/* base */
 | 
			
		||||
				| ((tinstr & 0x0700) << (12 - 8))	/* Rd */
 | 
			
		||||
				|(tinstr & 0x00FF);	/* off8 */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 22:
 | 
			
		||||
	case 23:
 | 
			
		||||
		if ((tinstr & 0x0F00) == 0x0000) {
 | 
			
		||||
			/* Format 13 */
 | 
			
		||||
			/* NOTE: The instruction contains a shift left of 2
 | 
			
		||||
			   equivalent (implemented as ROR #30): */
 | 
			
		||||
			*ainstr = ((tinstr & (1 << 7))	/* base */
 | 
			
		||||
				   ? 0xE24DDF00	/* SUB */
 | 
			
		||||
				   : 0xE28DDF00)	/* ADD */
 | 
			
		||||
				|(tinstr & 0x007F);	/* off7 */
 | 
			
		||||
		}
 | 
			
		||||
		else if ((tinstr & 0x0F00) == 0x0e00)
 | 
			
		||||
			*ainstr = 0xEF000000 | SWI_Breakpoint;
 | 
			
		||||
		else {
 | 
			
		||||
			/* Format 14 */
 | 
			
		||||
			ARMword subset[4] = {
 | 
			
		||||
				0xE92D0000,	/* STMDB sp!,{rlist}    */
 | 
			
		||||
				0xE92D4000,	/* STMDB sp!,{rlist,lr} */
 | 
			
		||||
				0xE8BD0000,	/* LDMIA sp!,{rlist}    */
 | 
			
		||||
				0xE8BD8000	/* LDMIA sp!,{rlist,pc} */
 | 
			
		||||
			};
 | 
			
		||||
			*ainstr = subset[((tinstr & (1 << 11)) >> 10) | ((tinstr & (1 << 8)) >> 8)]	/* base */
 | 
			
		||||
				|(tinstr & 0x00FF);	/* mask8 */
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 24:		/* STMIA */
 | 
			
		||||
	case 25:		/* LDMIA */
 | 
			
		||||
		/* Format 15 */
 | 
			
		||||
		*ainstr = ((tinstr & (1 << 11))	/* base */
 | 
			
		||||
			   ? 0xE8B00000	/* LDMIA */
 | 
			
		||||
			   : 0xE8A00000)	/* STMIA */
 | 
			
		||||
			|((tinstr & 0x0700) << (16 - 8))	/* Rb */
 | 
			
		||||
			|(tinstr & 0x00FF);	/* mask8 */
 | 
			
		||||
		break;
 | 
			
		||||
	case 26:		/* Bcc */
 | 
			
		||||
	case 27:		/* Bcc/SWI */
 | 
			
		||||
		if ((tinstr & 0x0F00) == 0x0F00) {
 | 
			
		||||
			if (tinstr == (ARMul_ABORTWORD & 0xffff) &&
 | 
			
		||||
					state->AbortAddr == pc) {
 | 
			
		||||
				*ainstr = ARMul_ABORTWORD;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			/* Format 17 : SWI */
 | 
			
		||||
			*ainstr = 0xEF000000;
 | 
			
		||||
			/* Breakpoint must be handled specially.  */
 | 
			
		||||
			if ((tinstr & 0x00FF) == 0x18)
 | 
			
		||||
				*ainstr |= ((tinstr & 0x00FF) << 16);
 | 
			
		||||
			/* New breakpoint value.  See gdb/arm-tdep.c  */
 | 
			
		||||
			else if ((tinstr & 0x00FF) == 0xFE)
 | 
			
		||||
				*ainstr |= SWI_Breakpoint;
 | 
			
		||||
			else
 | 
			
		||||
				*ainstr |= (tinstr & 0x00FF);
 | 
			
		||||
		}
 | 
			
		||||
		else if ((tinstr & 0x0F00) != 0x0E00) {
 | 
			
		||||
			/* Format 16 */
 | 
			
		||||
			int doit = FALSE;
 | 
			
		||||
			/* TODO: Since we are doing a switch here, we could just add
 | 
			
		||||
			   the SWI and undefined instruction checks into this
 | 
			
		||||
			   switch to same on a couple of conditionals: */
 | 
			
		||||
			switch ((tinstr & 0x0F00) >> 8) {
 | 
			
		||||
			case EQ:
 | 
			
		||||
				doit = ZFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case NE:
 | 
			
		||||
				doit = !ZFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case VS:
 | 
			
		||||
				doit = VFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case VC:
 | 
			
		||||
				doit = !VFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case MI:
 | 
			
		||||
				doit = NFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case PL:
 | 
			
		||||
				doit = !NFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case CS:
 | 
			
		||||
				doit = CFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case CC:
 | 
			
		||||
				doit = !CFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			case HI:
 | 
			
		||||
				doit = (CFLAG && !ZFLAG);
 | 
			
		||||
				break;
 | 
			
		||||
			case LS:
 | 
			
		||||
				doit = (!CFLAG || ZFLAG);
 | 
			
		||||
				break;
 | 
			
		||||
			case GE:
 | 
			
		||||
				doit = ((!NFLAG && !VFLAG)
 | 
			
		||||
					|| (NFLAG && VFLAG));
 | 
			
		||||
				break;
 | 
			
		||||
			case LT:
 | 
			
		||||
				doit = ((NFLAG && !VFLAG)
 | 
			
		||||
					|| (!NFLAG && VFLAG));
 | 
			
		||||
				break;
 | 
			
		||||
			case GT:
 | 
			
		||||
				doit = ((!NFLAG && !VFLAG && !ZFLAG)
 | 
			
		||||
					|| (NFLAG && VFLAG && !ZFLAG));
 | 
			
		||||
				break;
 | 
			
		||||
			case LE:
 | 
			
		||||
				doit = ((NFLAG && !VFLAG)
 | 
			
		||||
					|| (!NFLAG && VFLAG)) || ZFLAG;
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (doit) {
 | 
			
		||||
				state->Reg[15] = (pc + 4
 | 
			
		||||
						  + (((tinstr & 0x7F) << 1)
 | 
			
		||||
						     | ((tinstr & (1 << 7)) ?
 | 
			
		||||
							0xFFFFFF00 : 0)));
 | 
			
		||||
				FLUSHPIPE;
 | 
			
		||||
			}
 | 
			
		||||
			valid = t_branch;
 | 
			
		||||
		}
 | 
			
		||||
		else		/* UNDEFINED : cc=1110(AL) uses different format */
 | 
			
		||||
			valid = t_undefined;
 | 
			
		||||
		break;
 | 
			
		||||
	case 28:		/* B */
 | 
			
		||||
		/* Format 18 */
 | 
			
		||||
		state->Reg[15] = (pc + 4 + (((tinstr & 0x3FF) << 1)
 | 
			
		||||
					    | ((tinstr & (1 << 10)) ?
 | 
			
		||||
					       0xFFFFF800 : 0)));
 | 
			
		||||
		FLUSHPIPE;
 | 
			
		||||
		valid = t_branch;
 | 
			
		||||
		break;
 | 
			
		||||
	case 29:
 | 
			
		||||
		if(tinstr & 0x1)
 | 
			
		||||
			valid = t_undefined;
 | 
			
		||||
		else{
 | 
			
		||||
			/* BLX 1 for armv5t and above */
 | 
			
		||||
			ARMword tmp = (pc + 2);
 | 
			
		||||
			state->Reg[15] =
 | 
			
		||||
				(state->Reg[14] + ((tinstr & 0x07FF) << 1)) & 0xFFFFFFFC;
 | 
			
		||||
			state->Reg[14] = (tmp | 1);
 | 
			
		||||
			CLEART;
 | 
			
		||||
			DEBUG_LOG(ARM11, "In %s, After  BLX(1),LR=0x%x,PC=0x%x, offset=0x%x\n", __FUNCTION__, state->Reg[14], state->Reg[15], (tinstr &0x7FF) << 1);
 | 
			
		||||
			valid = t_branch;
 | 
			
		||||
			FLUSHPIPE;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case 30:		/* BL instruction 1 */
 | 
			
		||||
		/* Format 19 */
 | 
			
		||||
		/* There is no single ARM instruction equivalent for this Thumb
 | 
			
		||||
		   instruction. To keep the simulation simple (from the user
 | 
			
		||||
		   perspective) we check if the following instruction is the
 | 
			
		||||
		   second half of this BL, and if it is we simulate it
 | 
			
		||||
		   immediately.  */
 | 
			
		||||
		state->Reg[14] = state->Reg[15]
 | 
			
		||||
			+ (((tinstr & 0x07FF) << 12)
 | 
			
		||||
			   | ((tinstr & (1 << 10)) ? 0xFF800000 : 0));
 | 
			
		||||
		valid = t_branch;	/* in-case we don't have the 2nd half */
 | 
			
		||||
		//tinstr = next_instr;	/* move the instruction down */
 | 
			
		||||
		//if (((tinstr & 0xF800) >> 11) != 31)
 | 
			
		||||
		//	break;	/* exit, since not correct instruction */
 | 
			
		||||
		/* else we fall through to process the second half of the BL */
 | 
			
		||||
		//pc += 2;	/* point the pc at the 2nd half */
 | 
			
		||||
		state->Reg[15] = pc + 2;
 | 
			
		||||
		FLUSHPIPE;
 | 
			
		||||
		break;
 | 
			
		||||
	case 31:		/* BL instruction 2 */
 | 
			
		||||
		/* Format 19 */
 | 
			
		||||
		/* There is no single ARM instruction equivalent for this
 | 
			
		||||
		   instruction. Also, it should only ever be matched with the
 | 
			
		||||
		   fmt19 "BL instruction 1" instruction. However, we do allow
 | 
			
		||||
		   the simulation of it on its own, with undefined results if
 | 
			
		||||
		   r14 is not suitably initialised.  */
 | 
			
		||||
		{
 | 
			
		||||
			ARMword tmp = (pc + 2);
 | 
			
		||||
			state->Reg[15] =
 | 
			
		||||
				(state->Reg[14] + ((tinstr & 0x07FF) << 1));
 | 
			
		||||
			state->Reg[14] = (tmp | 1);
 | 
			
		||||
			valid = t_branch;
 | 
			
		||||
			FLUSHPIPE;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return valid;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1132
									
								
								src/core/arm/mmu/arm1176jzf_s_mmu.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1132
									
								
								src/core/arm/mmu/arm1176jzf_s_mmu.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										37
									
								
								src/core/arm/mmu/arm1176jzf_s_mmu.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/core/arm/mmu/arm1176jzf_s_mmu.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
/*
 | 
			
		||||
    arm1176JZF-S_mmu.h - ARM1176JZF-S Memory Management Unit emulation.
 | 
			
		||||
 | 
			
		||||
    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#ifndef _ARM1176JZF_S_MMU_H_
 | 
			
		||||
#define _ARM1176JZF_S_MMU_H_
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
typedef struct arm1176jzf-s_mmu_s
 | 
			
		||||
{
 | 
			
		||||
    tlb_t i_tlb;
 | 
			
		||||
    cache_t i_cache;
 | 
			
		||||
 | 
			
		||||
    tlb_t d_tlb;
 | 
			
		||||
    cache_t d_cache;
 | 
			
		||||
    wb_t wb_t;
 | 
			
		||||
} arm1176jzf-s_mmu_t;
 | 
			
		||||
#endif
 | 
			
		||||
extern mmu_ops_t arm1176jzf_s_mmu_ops;
 | 
			
		||||
 | 
			
		||||
ARMword
 | 
			
		||||
arm1176jzf_s_mmu_mrc (ARMul_State *state, ARMword instr, ARMword *value);
 | 
			
		||||
#endif /*_ARM1176JZF_S_MMU_H_*/
 | 
			
		||||
							
								
								
									
										168
									
								
								src/core/arm/mmu/cache.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								src/core/arm/mmu/cache.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,168 @@
 | 
			
		||||
#ifndef _MMU_CACHE_H_
 | 
			
		||||
#define _MMU_CACHE_H_
 | 
			
		||||
 | 
			
		||||
typedef struct cache_line_t
 | 
			
		||||
{
 | 
			
		||||
    ARMword tag;        /*      cache line align address |
 | 
			
		||||
                   bit2: last half dirty
 | 
			
		||||
                   bit1: first half dirty
 | 
			
		||||
                   bit0: cache valid flag
 | 
			
		||||
                 */
 | 
			
		||||
    ARMword pa;        /*physical address */
 | 
			
		||||
    ARMword *data;        /*array of cached data */
 | 
			
		||||
} cache_line_t;
 | 
			
		||||
#define TAG_VALID_FLAG 0x00000001
 | 
			
		||||
#define TAG_FIRST_HALF_DIRTY 0x00000002
 | 
			
		||||
#define TAG_LAST_HALF_DIRTY    0x00000004
 | 
			
		||||
 | 
			
		||||
/*cache set association*/
 | 
			
		||||
typedef struct cache_set_s
 | 
			
		||||
{
 | 
			
		||||
    cache_line_t *lines;
 | 
			
		||||
    int cycle;
 | 
			
		||||
} cache_set_t;
 | 
			
		||||
 | 
			
		||||
enum
 | 
			
		||||
{
 | 
			
		||||
    CACHE_WRITE_BACK,
 | 
			
		||||
    CACHE_WRITE_THROUGH,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct cache_s
 | 
			
		||||
{
 | 
			
		||||
    int width;        /*bytes in a line */
 | 
			
		||||
    int way;        /*way of set asscociate */
 | 
			
		||||
    int set;        /*num of set */
 | 
			
		||||
    int w_mode;        /*write back or write through */
 | 
			
		||||
    //int a_mode;   /*alloc mode: random or round-bin*/
 | 
			
		||||
    cache_set_t *sets;
 | 
			
		||||
  /**/} cache_s;
 | 
			
		||||
 | 
			
		||||
typedef struct cache_desc_s
 | 
			
		||||
{
 | 
			
		||||
    int width;
 | 
			
		||||
    int way;
 | 
			
		||||
    int set;
 | 
			
		||||
    int w_mode;
 | 
			
		||||
//      int a_mode;
 | 
			
		||||
} cache_desc_t;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*virtual address to cache set index*/
 | 
			
		||||
#define va_cache_set(va, cache_t) \
 | 
			
		||||
    (((va) / (cache_t)->width) & ((cache_t)->set - 1))
 | 
			
		||||
/*virtual address to cahce line aligned*/
 | 
			
		||||
#define va_cache_align(va, cache_t) \
 | 
			
		||||
        ((va) & ~((cache_t)->width - 1))
 | 
			
		||||
/*virtaul address to cache line word index*/
 | 
			
		||||
#define va_cache_index(va, cache_t) \
 | 
			
		||||
        (((va) & ((cache_t)->width - 1)) >> WORD_SHT)
 | 
			
		||||
 | 
			
		||||
/*see Page 558 in arm manual*/
 | 
			
		||||
/*set/index format value to cache set value*/
 | 
			
		||||
#define index_cache_set(index, cache_t) \
 | 
			
		||||
    (((index) / (cache_t)->width) & ((cache_t)->set - 1))
 | 
			
		||||
 | 
			
		||||
/*************************cache********************/
 | 
			
		||||
/* mmu cache init
 | 
			
		||||
 *
 | 
			
		||||
 * @cache_t :cache_t to init
 | 
			
		||||
 * @width    :cache line width in byte
 | 
			
		||||
 * @way        :way of each cache set
 | 
			
		||||
 * @set        :cache set num
 | 
			
		||||
 * @w_mode    :cache w_mode
 | 
			
		||||
 *
 | 
			
		||||
 * $ -1: error
 | 
			
		||||
 *      0: sucess
 | 
			
		||||
 */
 | 
			
		||||
int
 | 
			
		||||
mmu_cache_init (cache_s * cache_t, int width, int way, int set, int w_mode);
 | 
			
		||||
 | 
			
		||||
/* free a cache_t's inner data, the ptr self is not freed,
 | 
			
		||||
 * when needed do like below:
 | 
			
		||||
 *         mmu_cache_exit(cache);
 | 
			
		||||
 *         free(cache_t);
 | 
			
		||||
 *
 | 
			
		||||
 * @cache_t : the cache_t to free
 | 
			
		||||
 */
 | 
			
		||||
void mmu_cache_exit (cache_s * cache_t);
 | 
			
		||||
 | 
			
		||||
/* mmu cache search
 | 
			
		||||
 *
 | 
			
		||||
 * @state    :ARMul_State
 | 
			
		||||
 * @cache_t    :cache_t to search
 | 
			
		||||
 * @va        :virtual address
 | 
			
		||||
 *
 | 
			
		||||
 * $    NULL:    no cache match
 | 
			
		||||
 *         cache    :cache matched
 | 
			
		||||
 * */
 | 
			
		||||
cache_line_t *mmu_cache_search (ARMul_State * state, cache_s * cache_t,
 | 
			
		||||
                ARMword va);
 | 
			
		||||
 | 
			
		||||
/*  mmu cache search by set/index 
 | 
			
		||||
 *
 | 
			
		||||
 * @state    :ARMul_State
 | 
			
		||||
 * @cache_t    :cache_t to search
 | 
			
		||||
 * @index       :set/index value. 
 | 
			
		||||
 *
 | 
			
		||||
 * $    NULL:    no cache match
 | 
			
		||||
 *         cache    :cache matched
 | 
			
		||||
 * */
 | 
			
		||||
 | 
			
		||||
cache_line_t *mmu_cache_search_by_index (ARMul_State * state,
 | 
			
		||||
                     cache_s * cache_t, ARMword index);
 | 
			
		||||
 | 
			
		||||
/* mmu cache alloc
 | 
			
		||||
 *
 | 
			
		||||
 * @state :ARMul_State
 | 
			
		||||
 * @cache_t    :cache_t to alloc from
 | 
			
		||||
 * @va        :virtual address that require cache alloc, need not cache aligned
 | 
			
		||||
 * @pa        :physical address of va
 | 
			
		||||
 *
 | 
			
		||||
 * $    cache_alloced, always alloc OK
 | 
			
		||||
 */
 | 
			
		||||
cache_line_t *mmu_cache_alloc (ARMul_State * state, cache_s * cache_t,
 | 
			
		||||
                   ARMword va, ARMword pa);
 | 
			
		||||
 | 
			
		||||
/* mmu_cache_write_back write cache data to memory
 | 
			
		||||
 *
 | 
			
		||||
 * @state:
 | 
			
		||||
 * @cache_t :cache_t of the cache line
 | 
			
		||||
 * @cache : cache line
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
mmu_cache_write_back (ARMul_State * state, cache_s * cache_t,
 | 
			
		||||
              cache_line_t * cache);
 | 
			
		||||
 | 
			
		||||
/* mmu_cache_clean: clean a cache of va in cache_t
 | 
			
		||||
 *
 | 
			
		||||
 * @state    :ARMul_State
 | 
			
		||||
 * @cache_t    :cache_t to clean
 | 
			
		||||
 * @va        :virtaul address
 | 
			
		||||
 */
 | 
			
		||||
void mmu_cache_clean (ARMul_State * state, cache_s * cache_t, ARMword va);
 | 
			
		||||
void
 | 
			
		||||
mmu_cache_clean_by_index (ARMul_State * state, cache_s * cache_t,
 | 
			
		||||
              ARMword index);
 | 
			
		||||
 | 
			
		||||
/* mmu_cache_invalidate : invalidate a cache of va
 | 
			
		||||
 *
 | 
			
		||||
 * @state    :ARMul_State
 | 
			
		||||
 * @cache_t    :cache_t to invalid
 | 
			
		||||
 * @va        :virt_addr to invalid
 | 
			
		||||
 */
 | 
			
		||||
void
 | 
			
		||||
mmu_cache_invalidate (ARMul_State * state, cache_s * cache_t, ARMword va);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mmu_cache_invalidate_by_index (ARMul_State * state, cache_s * cache_t,
 | 
			
		||||
                   ARMword index);
 | 
			
		||||
 | 
			
		||||
void mmu_cache_invalidate_all (ARMul_State * state, cache_s * cache_t);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mmu_cache_soft_flush (ARMul_State * state, cache_s * cache_t, ARMword pa);
 | 
			
		||||
 | 
			
		||||
cache_line_t* mmu_cache_dirty_cache(ARMul_State * state, cache_s * cache_t);
 | 
			
		||||
 | 
			
		||||
#endif /*_MMU_CACHE_H_*/
 | 
			
		||||
							
								
								
									
										55
									
								
								src/core/arm/mmu/rb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/core/arm/mmu/rb.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
#ifndef _MMU_RB_H
 | 
			
		||||
#define _MMU_RB_H
 | 
			
		||||
 | 
			
		||||
enum rb_type_t
 | 
			
		||||
{
 | 
			
		||||
    RB_INVALID = 0,        //invalid
 | 
			
		||||
    RB_1,            //1     word
 | 
			
		||||
    RB_4,            //4 word
 | 
			
		||||
    RB_8,            //8 word
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*bytes of each rb_type*/
 | 
			
		||||
extern ARMword rb_masks[];
 | 
			
		||||
 | 
			
		||||
#define RB_WORD_NUM 8
 | 
			
		||||
typedef struct rb_entry_s
 | 
			
		||||
{
 | 
			
		||||
    ARMword data[RB_WORD_NUM];    //array to store data
 | 
			
		||||
    ARMword va;        //first word va
 | 
			
		||||
    int type;        //rb type
 | 
			
		||||
    fault_t fault;        //fault set by rb alloc
 | 
			
		||||
} rb_entry_t;
 | 
			
		||||
 | 
			
		||||
typedef struct rb_s
 | 
			
		||||
{
 | 
			
		||||
    int num;
 | 
			
		||||
    rb_entry_t *entrys;
 | 
			
		||||
} rb_s;
 | 
			
		||||
 | 
			
		||||
/*mmu_rb_init
 | 
			
		||||
 * @rb_t    :rb_t to init
 | 
			
		||||
 * @num        :number of entry
 | 
			
		||||
 * */
 | 
			
		||||
int mmu_rb_init (rb_s * rb_t, int num);
 | 
			
		||||
 | 
			
		||||
/*mmu_rb_exit*/
 | 
			
		||||
void mmu_rb_exit (rb_s * rb_t);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*mmu_rb_search
 | 
			
		||||
 * @rb_t    :rb_t to serach
 | 
			
		||||
 * @va        :va address to math
 | 
			
		||||
 *
 | 
			
		||||
 * $    NULL :not match
 | 
			
		||||
 *         NO-NULL:
 | 
			
		||||
 * */
 | 
			
		||||
rb_entry_t *mmu_rb_search (rb_s * rb_t, ARMword va);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void mmu_rb_invalidate_entry (rb_s * rb_t, int i);
 | 
			
		||||
void mmu_rb_invalidate_all (rb_s * rb_t);
 | 
			
		||||
void mmu_rb_load (ARMul_State * state, rb_s * rb_t, int i_rb,
 | 
			
		||||
          int type, ARMword va);
 | 
			
		||||
 | 
			
		||||
#endif /*_MMU_RB_H_*/
 | 
			
		||||
							
								
								
									
										94
									
								
								src/core/arm/mmu/tlb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/core/arm/mmu/tlb.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
#ifndef _MMU_TLB_H_
 | 
			
		||||
#define _MMU_TLB_H_
 | 
			
		||||
 | 
			
		||||
typedef enum tlb_mapping_t
 | 
			
		||||
{
 | 
			
		||||
    TLB_INVALID = 0,
 | 
			
		||||
    TLB_SMALLPAGE = 1,
 | 
			
		||||
    TLB_LARGEPAGE = 2,
 | 
			
		||||
    TLB_SECTION = 3,
 | 
			
		||||
    TLB_ESMALLPAGE = 4,
 | 
			
		||||
    TLB_TINYPAGE = 5
 | 
			
		||||
} tlb_mapping_t;
 | 
			
		||||
 | 
			
		||||
extern ARMword tlb_masks[];
 | 
			
		||||
 | 
			
		||||
/* Permissions bits in a TLB entry:
 | 
			
		||||
 *
 | 
			
		||||
 *         31         12 11 10  9  8  7  6  5  4  3   2   1   0
 | 
			
		||||
 *        +-------------+-----+-----+-----+-----+---+---+-------+
 | 
			
		||||
 * Page:|             | ap3 | ap2 | ap1 | ap0 | C | B |       |
 | 
			
		||||
 *        +-------------+-----+-----+-----+-----+---+---+-------+
 | 
			
		||||
 *
 | 
			
		||||
 *         31         12 11 10  9              4  3   2   1   0
 | 
			
		||||
 *            +-------------+-----+-----------------+---+---+-------+
 | 
			
		||||
 * Section:    |             |  AP |                 | C | B |       |
 | 
			
		||||
 *            +-------------+-----+-----------------+---+---+-------+
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
section:
 | 
			
		||||
    section base address    [31:20]
 | 
			
		||||
    AP            - table 8-2, page 8-8
 | 
			
		||||
    domain
 | 
			
		||||
    C,B
 | 
			
		||||
 | 
			
		||||
page:
 | 
			
		||||
    page base address    [31:16] or [31:12]
 | 
			
		||||
    ap[3:0]
 | 
			
		||||
    domain (from L1)
 | 
			
		||||
    C,B
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct tlb_entry_t
 | 
			
		||||
{
 | 
			
		||||
    ARMword virt_addr;
 | 
			
		||||
    ARMword phys_addr;
 | 
			
		||||
    ARMword perms;
 | 
			
		||||
    ARMword domain;
 | 
			
		||||
    tlb_mapping_t mapping;
 | 
			
		||||
} tlb_entry_t;
 | 
			
		||||
 | 
			
		||||
typedef struct tlb_s
 | 
			
		||||
{
 | 
			
		||||
    int num;        /*num of tlb entry */
 | 
			
		||||
    int cycle;        /*current tlb cycle */
 | 
			
		||||
    tlb_entry_t *entrys;
 | 
			
		||||
} tlb_s;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define tlb_c_flag(tlb) \
 | 
			
		||||
    ((tlb)->perms & 0x8)
 | 
			
		||||
#define tlb_b_flag(tlb) \
 | 
			
		||||
    ((tlb)->perms & 0x4)
 | 
			
		||||
 | 
			
		||||
#define  tlb_va_to_pa(tlb, va) \
 | 
			
		||||
(\
 | 
			
		||||
 {\
 | 
			
		||||
    ARMword mask = tlb_masks[tlb->mapping];      \
 | 
			
		||||
    (tlb->phys_addr & mask) | (va & ~mask);\
 | 
			
		||||
 }\
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
check_access (ARMul_State * state, ARMword virt_addr, tlb_entry_t * tlb,
 | 
			
		||||
          int read);
 | 
			
		||||
 | 
			
		||||
fault_t
 | 
			
		||||
translate (ARMul_State * state, ARMword virt_addr, tlb_s * tlb_t,
 | 
			
		||||
       tlb_entry_t ** tlb);
 | 
			
		||||
 | 
			
		||||
int mmu_tlb_init (tlb_s * tlb_t, int num);
 | 
			
		||||
 | 
			
		||||
void mmu_tlb_exit (tlb_s * tlb_t);
 | 
			
		||||
 | 
			
		||||
void mmu_tlb_invalidate_all (ARMul_State * state, tlb_s * tlb_t);
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
mmu_tlb_invalidate_entry (ARMul_State * state, tlb_s * tlb_t, ARMword addr);
 | 
			
		||||
 | 
			
		||||
tlb_entry_t *mmu_tlb_search (ARMul_State * state, tlb_s * tlb_t,
 | 
			
		||||
                 ARMword virt_addr);
 | 
			
		||||
 | 
			
		||||
#endif        /*_MMU_TLB_H_*/
 | 
			
		||||
							
								
								
									
										63
									
								
								src/core/arm/mmu/wb.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/core/arm/mmu/wb.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
			
		||||
#ifndef _MMU_WB_H_
 | 
			
		||||
#define _MMU_WB_H_
 | 
			
		||||
 | 
			
		||||
typedef struct wb_entry_s
 | 
			
		||||
{
 | 
			
		||||
    ARMword pa;        //phy_addr
 | 
			
		||||
    ARMbyte *data;        //data
 | 
			
		||||
    int nb;            //number byte to write
 | 
			
		||||
} wb_entry_t;
 | 
			
		||||
 | 
			
		||||
typedef struct wb_s
 | 
			
		||||
{
 | 
			
		||||
    int num;        //number of wb_entry
 | 
			
		||||
    int nb;            //number of byte of each entry
 | 
			
		||||
    int first;        //
 | 
			
		||||
    int last;        //
 | 
			
		||||
    int used;        //
 | 
			
		||||
    wb_entry_t *entrys;
 | 
			
		||||
} wb_s;
 | 
			
		||||
 | 
			
		||||
typedef struct wb_desc_s
 | 
			
		||||
{
 | 
			
		||||
    int num;
 | 
			
		||||
    int nb;
 | 
			
		||||
} wb_desc_t;
 | 
			
		||||
 | 
			
		||||
/* wb_init
 | 
			
		||||
 * @wb_t    :wb_t to init
 | 
			
		||||
 * @num        :num of entrys
 | 
			
		||||
 * @nw        :num of word of each entry
 | 
			
		||||
 *
 | 
			
		||||
 * $    -1:error
 | 
			
		||||
 *          0:ok
 | 
			
		||||
 * */
 | 
			
		||||
int mmu_wb_init (wb_s * wb_t, int num, int nb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* wb_exit
 | 
			
		||||
 * @wb_t :wb_t to exit
 | 
			
		||||
 * */
 | 
			
		||||
void mmu_wb_exit (wb_s * wb);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* wb_write_bytes :put bytess in Write Buffer
 | 
			
		||||
 * @state:    ARMul_State
 | 
			
		||||
 * @wb_t:    write buffer
 | 
			
		||||
 * @pa:        physical address
 | 
			
		||||
 * @data:    data ptr
 | 
			
		||||
 * @n        number of byte to write
 | 
			
		||||
 *
 | 
			
		||||
 * Note: write buffer merge is not implemented, can be done late
 | 
			
		||||
 * */
 | 
			
		||||
void
 | 
			
		||||
mmu_wb_write_bytess (ARMul_State * state, wb_s * wb_t, ARMword pa,
 | 
			
		||||
             ARMbyte * data, int n);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* wb_drain_all
 | 
			
		||||
 * @wb_t wb_t to drain
 | 
			
		||||
 * */
 | 
			
		||||
void mmu_wb_drain_all (ARMul_State * state, wb_s * wb_t);
 | 
			
		||||
 | 
			
		||||
#endif /*_MMU_WB_H_*/
 | 
			
		||||
		Reference in New Issue
	
	Block a user