feat(tlib): 新增MIPS32架构支持
为Renode添加龙芯1E300的MIPS32最小架构实现 **主要内容:** - 创建完整的MIPS32 CPU状态结构 - 实现CP0系统控制寄存器 - 添加MMU和中断处理框架 - 集成TCG翻译和softmmu支持 - 提供C#接口层 **构建结果:** - 成功编译translate-mips-le.so(791KB) - 所有符号正确链接 **后续工作:** 指令执行逻辑将在后续提交中实现 Authored: liuwb <liuwb@microsat.com>
This commit is contained in:
@@ -94,7 +94,9 @@ set (TARGET_WORD_SIZE "32" CACHE STRING "Target word size")
|
||||
message(VERBOSE "Target is: ${TARGET_WORD_SIZE}-bit ${TARGET_ARCH}")
|
||||
|
||||
set_property (CACHE HOST_ARCH PROPERTY STRINGS i386 arm aarch64)
|
||||
set_property (CACHE TARGET_ARCH PROPERTY STRINGS i386 x86_64 arm arm-m arm64 sparc ppc ppc64 riscv riscv64 xtensa)
|
||||
# [MIPS架构支持] 在目标架构列表中添加 mips 和 mips64,用于支持龙芯1E300等MIPS处理器
|
||||
set_property (CACHE TARGET_ARCH PROPERTY STRINGS i386 x86_64 arm arm-m arm64 sparc ppc ppc64 riscv riscv64 xtensa mips mips64)
|
||||
# set_property (CACHE TARGET_ARCH PROPERTY STRINGS i386 x86_64 arm arm-m arm64 sparc ppc ppc64 riscv riscv64 xtensa)
|
||||
|
||||
if(NOT HOST_ARCH)
|
||||
message (FATAL_ERROR "Host architecture not set")
|
||||
@@ -133,7 +135,9 @@ if(NOT ${CMAKE_PROJECT_NAME} STREQUAL tlib)
|
||||
endif()
|
||||
|
||||
set(TARGET_INSN_START_EXTRA_WORDS 0)
|
||||
if("${TARGET_ACTUAL_ARCH}" MATCHES "^(arm|i386|sparc)$")
|
||||
# [MIPS架构支持] 为MIPS架构设置指令起始额外字段数为1,与ARM、i386、SPARC保持一致
|
||||
# 这个参数用于TCG中间代码生成时的指令跟踪,MIPS32需要额外的1个字段来存储延迟槽信息
|
||||
if("${TARGET_ACTUAL_ARCH}" MATCHES "^(arm|i386|sparc|mips)$")
|
||||
set(TARGET_INSN_START_EXTRA_WORDS 1)
|
||||
elseif("${TARGET_ACTUAL_ARCH}" STREQUAL "arm64")
|
||||
set(TARGET_INSN_START_EXTRA_WORDS 2)
|
||||
@@ -143,6 +147,15 @@ if("${TARGET_ACTUAL_ARCH}" STREQUAL "arm64" AND NOT "${TARGET_WORD_SIZE}" STREQU
|
||||
message (FATAL_ERROR "ERROR: arm64 target has to be built with TARGET_WORD_SIZE=64")
|
||||
endif()
|
||||
|
||||
# [MIPS架构支持] 为MIPS架构设置特定的编译配置
|
||||
# 1. TARGET_LONG_BITS=32: 设置目标long类型为32位(MIPS32标准)
|
||||
# 2. TARGET_MIPS宏: 启用MIPS特定的代码路径和功能
|
||||
# 3. 这些定义会影响cpu.h中的类型定义和指令翻译行为
|
||||
if("${TARGET_ACTUAL_ARCH}" STREQUAL "mips")
|
||||
set(TARGET_LONG_BITS 32)
|
||||
add_definitions(-DTARGET_MIPS)
|
||||
endif()
|
||||
|
||||
string (TOUPPER "${HOST_ARCH}" HOST_ARCH_U)
|
||||
string (TOUPPER "${TARGET_ACTUAL_ARCH}" TARGET_ACTUAL_ARCH_U)
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* MIPS callbacks.
|
||||
*
|
||||
* Copyright (c) Antmicro
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "callbacks.h"
|
||||
#include "arch_callbacks.h"
|
||||
|
||||
// 默认中断处理 - 返回-1表示没有挂起的中断
|
||||
DEFAULT_INT_HANDLER1(int32_t tlib_find_best_interrupt, void)
|
||||
|
||||
// 默认中断确认处理 - 空实现
|
||||
DEFAULT_VOID_HANDLER1(void tlib_acknowledge_interrupt, int32_t number)
|
||||
|
||||
// 默认CPU停机处理 - 空实现
|
||||
DEFAULT_VOID_HANDLER1(void tlib_on_cpu_halted, void)
|
||||
|
||||
// 默认CPU断电处理 - 空实现
|
||||
DEFAULT_VOID_HANDLER1(void tlib_on_cpu_power_down, void)
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* MIPS callbacks.
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// MIPS架构回调函数声明
|
||||
// 这些函数由tlib调用,在C#层实现
|
||||
|
||||
// 查找最高优先级的中断
|
||||
int32_t tlib_find_best_interrupt(void);
|
||||
|
||||
// 确认中断(清除中断源)
|
||||
void tlib_acknowledge_interrupt(int32_t number);
|
||||
|
||||
// CPU停机回调
|
||||
void tlib_on_cpu_halted(void);
|
||||
|
||||
// CPU断电回调
|
||||
void tlib_on_cpu_power_down(void);
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* MIPS interface functions.
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
#include "unwind.h"
|
||||
|
||||
// 设置程序入口点
|
||||
void tlib_set_entry_point(uint32_t entry_point)
|
||||
{
|
||||
cpu->pc = entry_point;
|
||||
}
|
||||
|
||||
EXC_VOID_1(tlib_set_entry_point, uint32_t, entry_point)
|
||||
|
||||
// 设置CPU ID(用于多核)
|
||||
void tlib_set_cpu_id(uint32_t cpu_id)
|
||||
{
|
||||
// 可以存储在CP0_EBase或其他位置
|
||||
cpu->CP0_EBase = (cpu->CP0_EBase & 0x3FF) | (cpu_id << 10);
|
||||
}
|
||||
|
||||
EXC_VOID_1(tlib_set_cpu_id, uint32_t, cpu_id)
|
||||
|
||||
// 设置龙芯处理器ID
|
||||
void tlib_set_loongson_cpu_id(uint32_t cpu_id)
|
||||
{
|
||||
// 设置CP0_PRId寄存器
|
||||
cpu->CP0_PRId = cpu_id;
|
||||
}
|
||||
|
||||
EXC_VOID_1(tlib_set_loongson_cpu_id, uint32_t, cpu_id)
|
||||
|
||||
// 清除WFI状态
|
||||
void tlib_clear_wfi()
|
||||
{
|
||||
cpu->wfi = 0;
|
||||
}
|
||||
|
||||
EXC_VOID_0(tlib_clear_wfi)
|
||||
|
||||
// 设置WFI状态
|
||||
void tlib_set_wfi()
|
||||
{
|
||||
cpu->wfi = 1;
|
||||
}
|
||||
|
||||
EXC_VOID_0(tlib_set_wfi)
|
||||
@@ -0,0 +1,24 @@
|
||||
*
|
||||
* MIPS interface functions.
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// MIPS架构特定的导出函数声明
|
||||
// 这些函数会被C#层调用
|
||||
|
||||
// 设置CPU入口点(PC)
|
||||
void tlib_set_entry_point(uint32_t entry_point);
|
||||
|
||||
// 设置CPU ID(用于多核系统)
|
||||
void tlib_set_cpu_id(uint32_t cpu_id);
|
||||
|
||||
// 龙芯1E300特定:设置处理器ID
|
||||
void tlib_set_loongson_cpu_id(uint32_t cpu_id);
|
||||
|
||||
// WFI (Wait For Interrupt) 控制
|
||||
void tlib_clear_wfi(void);
|
||||
void tlib_set_wfi(void);
|
||||
222
src/Infrastructure/src/Emulator/Cores/tlib/arch/mips/cpu.h
Normal file
222
src/Infrastructure/src/Emulator/Cores/tlib/arch/mips/cpu.h
Normal file
@@ -0,0 +1,222 @@
|
||||
/*
|
||||
* MIPS
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// MIPS32架构支持 - 最小框架实现
|
||||
// 基于SPARC架构改编,用于龙芯1E300等MIPS32处理器
|
||||
|
||||
#if (TARGET_LONG_BITS == 32)
|
||||
#ifdef TARGET_PHYS_ADDR_BITS
|
||||
#undef TARGET_PHYS_ADDR_BITS
|
||||
#endif
|
||||
#define TARGET_PHYS_ADDR_BITS 32
|
||||
#else
|
||||
#error "Only 32-bit MIPS target is currently supported."
|
||||
#endif
|
||||
|
||||
#define TARGET_FPREGS 32
|
||||
#define TARGET_PAGE_BITS 12 /* 4k */
|
||||
#define TARGET_PHYS_ADDR_SPACE_BITS 32
|
||||
|
||||
#include "cpu_registers.h"
|
||||
#include "cpu-defs.h"
|
||||
#include "softfloat-2.h"
|
||||
|
||||
#define SUPPORTS_GUEST_PROFILING
|
||||
|
||||
// MIPS异常代码
|
||||
#define EXCP_NONE -1
|
||||
#define EXCP_RESET 0
|
||||
#define EXCP_TLBMOD 1 // TLB modification exception
|
||||
#define EXCP_TLBL 2 // TLB exception (load or instruction fetch)
|
||||
#define EXCP_TLBS 3 // TLB exception (store)
|
||||
#define EXCP_AdEL 4 // Address error exception (load or instruction fetch)
|
||||
#define EXCP_AdES 5 // Address error exception (store)
|
||||
#define EXCP_IBE 6 // Bus error exception (instruction fetch)
|
||||
#define EXCP_DBE 7 // Bus error exception (data reference: load or store)
|
||||
#define EXCP_SYSCALL 8 // Syscall exception
|
||||
#define EXCP_BREAK 9 // Breakpoint exception
|
||||
#define EXCP_RI 10 // Reserved instruction exception
|
||||
#define EXCP_CpU 11 // Coprocessor Unusable exception
|
||||
#define EXCP_OVERFLOW 12 // Arithmetic overflow exception
|
||||
#define EXCP_TRAP 13 // Trap exception
|
||||
#define EXCP_FPE 15 // Floating point exception
|
||||
#define EXCP_C2E 18 // Coprocessor 2 exception
|
||||
#define EXCP_DWATCH 23 // Data watchpoint
|
||||
#define EXCP_CACHE 30 // Cache error
|
||||
|
||||
// CP0 Status寄存器位定义
|
||||
#define CP0_STATUS_IE (1 << 0) // Interrupt Enable
|
||||
#define CP0_STATUS_EXL (1 << 1) // Exception Level
|
||||
#define CP0_STATUS_ERL (1 << 2) // Error Level
|
||||
#define CP0_STATUS_KSU (3 << 3) // Operating mode (Kernel/Supervisor/User)
|
||||
#define CP0_STATUS_IM (0xFF << 8) // Interrupt Mask
|
||||
#define CP0_STATUS_BEV (1 << 22) // Bootstrap Exception Vector
|
||||
#define CP0_STATUS_CU0 (1 << 28) // Coprocessor 0 Usable
|
||||
#define CP0_STATUS_CU1 (1 << 29) // Coprocessor 1 (FPU) Usable
|
||||
|
||||
// CP0 Cause寄存器位定义
|
||||
#define CP0_CAUSE_EXCCODE_SHIFT 2
|
||||
#define CP0_CAUSE_EXCCODE_MASK (0x1F << CP0_CAUSE_EXCCODE_SHIFT)
|
||||
#define CP0_CAUSE_IP (0xFF << 8) // Interrupt Pending
|
||||
#define CP0_CAUSE_BD (1 << 31) // Branch Delay
|
||||
|
||||
// MMU模式数量(用户态和内核态)
|
||||
#define NB_MMU_MODES 2
|
||||
|
||||
// MIPS CPU状态结构体
|
||||
// 注意:必须使用CPUState作为结构体名(Renode框架要求)
|
||||
typedef struct CPUState {
|
||||
// 通用寄存器 (GPR 0-31)
|
||||
// 注意: $0 (zero) 总是硬连线为0
|
||||
target_ulong gpr[32];
|
||||
|
||||
// 程序计数器(注意:必须使用小写pc,cpu-common.h中的CPU_PC宏依赖此命名)
|
||||
target_ulong pc;
|
||||
|
||||
// HI/LO寄存器(用于乘法和除法)
|
||||
target_ulong HI;
|
||||
target_ulong LO;
|
||||
|
||||
// CP0 - 协处理器0(系统控制寄存器)
|
||||
target_ulong CP0_Index; // TLB Index
|
||||
target_ulong CP0_Random; // TLB Random
|
||||
target_ulong CP0_EntryLo0; // TLB EntryLo0
|
||||
target_ulong CP0_EntryLo1; // TLB EntryLo1
|
||||
target_ulong CP0_Context; // TLB Context
|
||||
target_ulong CP0_PageMask; // TLB PageMask
|
||||
target_ulong CP0_Wired; // TLB Wired
|
||||
target_ulong CP0_BadVAddr; // Bad Virtual Address
|
||||
target_ulong CP0_Count; // Timer Count
|
||||
target_ulong CP0_EntryHi; // TLB EntryHi
|
||||
target_ulong CP0_Compare; // Timer Compare
|
||||
target_ulong CP0_Status; // Status Register
|
||||
target_ulong CP0_Cause; // Cause Register
|
||||
target_ulong CP0_EPC; // Exception Program Counter
|
||||
target_ulong CP0_PRId; // Processor Revision Identifier
|
||||
target_ulong CP0_Config0; // Config0
|
||||
target_ulong CP0_Config1; // Config1
|
||||
target_ulong CP0_EBase; // Exception Base
|
||||
|
||||
// 龙芯1E300特定寄存器(预留空间)
|
||||
target_ulong loongson_custom[8];
|
||||
|
||||
// FPU状态(CP1 - 浮点协处理器)
|
||||
float_status fp_status;
|
||||
float64 fpr[32]; // FPU寄存器(可以是32个32位或16个64位)
|
||||
uint32_t fcr0; // FPU Implementation/Revision register
|
||||
uint32_t fcr31; // FPU Control/Status register
|
||||
|
||||
// 内部状态和标志
|
||||
uint32_t hflags; // 内部CPU标志
|
||||
int error_code;
|
||||
uint32_t btarget; // 分支目标地址(用于延迟槽处理)
|
||||
|
||||
// 通用CPU字段(由Renode框架定义)
|
||||
CPU_COMMON
|
||||
} CPUState;
|
||||
|
||||
// CPU特性定义(简化版本)
|
||||
typedef struct mips_def_t {
|
||||
const char *name;
|
||||
uint32_t CP0_PRId;
|
||||
uint32_t CP0_Config0;
|
||||
uint32_t CP0_Config1;
|
||||
uint32_t features;
|
||||
} mips_def_t;
|
||||
|
||||
// CPU特性标志
|
||||
#define MIPS_FEATURE_FPU (1 << 0)
|
||||
#define MIPS_FEATURE_MIPS32 (1 << 1)
|
||||
#define MIPS_FEATURE_MIPS64 (1 << 2)
|
||||
|
||||
// hflags标志位定义
|
||||
#define MIPS_HFLAG_MODE 0x00007 // 执行模式掩码
|
||||
#define MIPS_HFLAG_KM 0 // Kernel mode
|
||||
#define MIPS_HFLAG_SM 1 // Supervisor mode
|
||||
#define MIPS_HFLAG_UM 2 // User mode
|
||||
|
||||
// 分支延迟槽处理
|
||||
#define MIPS_HFLAG_BMASK 0x00078 // 分支掩码
|
||||
#define MIPS_HFLAG_B 0x00008 // 无条件分支
|
||||
#define MIPS_HFLAG_BC 0x00010 // 条件分支
|
||||
#define MIPS_HFLAG_BL 0x00020 // Likely分支
|
||||
// 分支延迟槽处理
|
||||
#define MIPS_HFLAG_BMASK 0x00078 // 分支掩码
|
||||
#define MIPS_HFLAG_B 0x00008 // 无条件分支
|
||||
#define MIPS_HFLAG_BC 0x00010 // 条件分支
|
||||
#define MIPS_HFLAG_BL 0x00020 // Likely分支
|
||||
#define MIPS_HFLAG_BR 0x00040 // 分支到寄存器
|
||||
|
||||
// DisasContext完整定义(必须在include之前)
|
||||
typedef struct DisasContext {
|
||||
DisasContextBase base;
|
||||
uint32_t opcode;
|
||||
int mem_idx;
|
||||
} DisasContext;
|
||||
|
||||
// 设置寄存器$0总是为0
|
||||
static inline void sync_zero_reg(CPUState *env)
|
||||
{
|
||||
env->gpr[0] = 0;
|
||||
}
|
||||
|
||||
// 辅助函数声明 - 必须放在CPUState定义之后,include之前
|
||||
static inline int cpu_mmu_index(CPUState *env)
|
||||
{
|
||||
// 简化版本:只区分内核态和用户态
|
||||
return (env->CP0_Status & CP0_STATUS_EXL) ? 0 : 1;
|
||||
}
|
||||
|
||||
// 获取当前执行模式
|
||||
static inline int mips_cpu_mode(CPUState *env)
|
||||
{
|
||||
if (env->CP0_Status & CP0_STATUS_EXL) {
|
||||
return MIPS_HFLAG_KM; // Exception level = kernel mode
|
||||
}
|
||||
if (env->CP0_Status & CP0_STATUS_ERL) {
|
||||
return MIPS_HFLAG_KM; // Error level = kernel mode
|
||||
}
|
||||
return (env->hflags & MIPS_HFLAG_MODE);
|
||||
}
|
||||
|
||||
// 检查中断使能
|
||||
static inline int mips_interrupts_enabled(CPUState *env)
|
||||
{
|
||||
return (env->CP0_Status & CP0_STATUS_IE) &&
|
||||
!(env->CP0_Status & CP0_STATUS_EXL) &&
|
||||
!(env->CP0_Status & CP0_STATUS_ERL);
|
||||
}
|
||||
|
||||
// 函数声明(在helper.c中实现)
|
||||
int cpu_handle_mmu_fault(CPUState *env, target_ulong address, int access_type,
|
||||
int mmu_idx, int is_softmmu, int no_page_fault, target_phys_addr_t *paddr);
|
||||
|
||||
#include "cpu-all.h"
|
||||
#include "exec-all.h"
|
||||
|
||||
// TB状态获取函数(必需)
|
||||
static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
|
||||
target_ulong *cs_base, int *flags)
|
||||
{
|
||||
*pc = env->pc;
|
||||
*cs_base = 0;
|
||||
*flags = env->hflags;
|
||||
}
|
||||
|
||||
// 必需的CPU接口函数
|
||||
static inline int cpu_has_work(CPUState *env)
|
||||
{
|
||||
return (env->interrupt_request & CPU_INTERRUPT_HARD);
|
||||
}
|
||||
|
||||
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
|
||||
{
|
||||
env->pc = tb->pc;
|
||||
}
|
||||
|
||||
// MIPS寄存器别名(用于TCG)
|
||||
#define RA 31 // 返回地址寄存器
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* MIPS寄存器接口
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "cpu_registers.h"
|
||||
|
||||
// 获取寄存器指针(32位版本)
|
||||
uint32_t *get_reg_pointer_32(int reg)
|
||||
{
|
||||
switch(reg) {
|
||||
case MIPS_REG_ZERO ... MIPS_REG_RA: // GPR 0-31
|
||||
return (uint32_t *)&(cpu->gpr[reg]);
|
||||
case MIPS_REG_PC:
|
||||
return (uint32_t *)&(cpu->pc);
|
||||
case MIPS_REG_HI:
|
||||
return (uint32_t *)&(cpu->HI);
|
||||
case MIPS_REG_LO:
|
||||
return (uint32_t *)&(cpu->LO);
|
||||
case MIPS_CP0_STATUS:
|
||||
return (uint32_t *)&(cpu->CP0_Status);
|
||||
case MIPS_CP0_CAUSE:
|
||||
return (uint32_t *)&(cpu->CP0_Cause);
|
||||
case MIPS_CP0_EPC:
|
||||
return (uint32_t *)&(cpu->CP0_EPC);
|
||||
case MIPS_CP0_BADVADDR:
|
||||
return (uint32_t *)&(cpu->CP0_BadVAddr);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// 生成寄存器访问函数(tlib_get_register_value_32 和 tlib_set_register_value_32)
|
||||
CPU_REGISTER_ACCESSOR(32)
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* MIPS寄存器接口
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// MIPS32寄存器枚举定义
|
||||
// 用于C#和C代码之间的寄存器访问
|
||||
|
||||
// MIPS寄存器枚举
|
||||
// 这些值将被导出到C#层用于寄存器访问
|
||||
typedef enum {
|
||||
// 通用寄存器 GPR 0-31
|
||||
MIPS_REG_ZERO = 0, // $0 - 常量0
|
||||
MIPS_REG_AT, // $1 - 汇编器临时寄存器
|
||||
MIPS_REG_V0, // $2 - 函数返回值
|
||||
MIPS_REG_V1, // $3 - 函数返回值
|
||||
MIPS_REG_A0, // $4 - 函数参数
|
||||
MIPS_REG_A1, // $5 - 函数参数
|
||||
MIPS_REG_A2, // $6 - 函数参数
|
||||
MIPS_REG_A3, // $7 - 函数参数
|
||||
MIPS_REG_T0, // $8 - 临时寄存器
|
||||
MIPS_REG_T1, // $9
|
||||
MIPS_REG_T2, // $10
|
||||
MIPS_REG_T3, // $11
|
||||
MIPS_REG_T4, // $12
|
||||
MIPS_REG_T5, // $13
|
||||
MIPS_REG_T6, // $14
|
||||
MIPS_REG_T7, // $15
|
||||
MIPS_REG_S0, // $16 - 保存寄存器
|
||||
MIPS_REG_S1, // $17
|
||||
MIPS_REG_S2, // $18
|
||||
MIPS_REG_S3, // $19
|
||||
MIPS_REG_S4, // $20
|
||||
MIPS_REG_S5, // $21
|
||||
MIPS_REG_S6, // $22
|
||||
MIPS_REG_S7, // $23
|
||||
MIPS_REG_T8, // $24 - 临时寄存器
|
||||
MIPS_REG_T9, // $25
|
||||
MIPS_REG_K0, // $26 - 内核保留寄存器
|
||||
MIPS_REG_K1, // $27
|
||||
MIPS_REG_GP, // $28 - 全局指针
|
||||
MIPS_REG_SP, // $29 - 栈指针
|
||||
MIPS_REG_FP, // $30 - 帧指针 (或 S8)
|
||||
MIPS_REG_RA, // $31 - 返回地址
|
||||
|
||||
// 特殊寄存器 (从32开始)
|
||||
MIPS_REG_PC = 32, // 程序计数器
|
||||
MIPS_REG_HI, // HI寄存器 (乘除法高位)
|
||||
MIPS_REG_LO, // LO寄存器 (乘除法低位)
|
||||
|
||||
// CP0寄存器 (从40开始,为了对齐)
|
||||
MIPS_CP0_INDEX = 40, // CP0 Register 0
|
||||
MIPS_CP0_RANDOM, // CP0 Register 1
|
||||
MIPS_CP0_ENTRYLO0, // CP0 Register 2
|
||||
MIPS_CP0_ENTRYLO1, // CP0 Register 3
|
||||
MIPS_CP0_CONTEXT, // CP0 Register 4
|
||||
MIPS_CP0_PAGEMASK, // CP0 Register 5
|
||||
MIPS_CP0_WIRED, // CP0 Register 6
|
||||
// Register 7 reserved
|
||||
MIPS_CP0_BADVADDR = 48, // CP0 Register 8
|
||||
MIPS_CP0_COUNT, // CP0 Register 9
|
||||
MIPS_CP0_ENTRYHI, // CP0 Register 10
|
||||
MIPS_CP0_COMPARE, // CP0 Register 11
|
||||
MIPS_CP0_STATUS, // CP0 Register 12
|
||||
MIPS_CP0_CAUSE, // CP0 Register 13
|
||||
MIPS_CP0_EPC, // CP0 Register 14
|
||||
MIPS_CP0_PRID, // CP0 Register 15
|
||||
MIPS_CP0_CONFIG0, // CP0 Register 16, Select 0
|
||||
MIPS_CP0_CONFIG1, // CP0 Register 16, Select 1
|
||||
// ... 更多CONFIG寄存器
|
||||
MIPS_CP0_EBASE = 63, // CP0 Register 15, Select 1
|
||||
|
||||
// FPU控制寄存器 (从64开始)
|
||||
MIPS_FCR0 = 64, // FPU Implementation/Revision
|
||||
MIPS_FCR31 = 95, // FPU Control/Status
|
||||
|
||||
// FPU通用寄存器 (从96开始)
|
||||
MIPS_FPR0 = 96,
|
||||
MIPS_FPR1,
|
||||
MIPS_FPR2,
|
||||
MIPS_FPR3,
|
||||
MIPS_FPR4,
|
||||
MIPS_FPR5,
|
||||
MIPS_FPR6,
|
||||
MIPS_FPR7,
|
||||
MIPS_FPR8,
|
||||
MIPS_FPR9,
|
||||
MIPS_FPR10,
|
||||
MIPS_FPR11,
|
||||
MIPS_FPR12,
|
||||
MIPS_FPR13,
|
||||
MIPS_FPR14,
|
||||
MIPS_FPR15,
|
||||
MIPS_FPR16,
|
||||
MIPS_FPR17,
|
||||
MIPS_FPR18,
|
||||
MIPS_FPR19,
|
||||
MIPS_FPR20,
|
||||
MIPS_FPR21,
|
||||
MIPS_FPR22,
|
||||
MIPS_FPR23,
|
||||
MIPS_FPR24,
|
||||
MIPS_FPR25,
|
||||
MIPS_FPR26,
|
||||
MIPS_FPR27,
|
||||
MIPS_FPR28,
|
||||
MIPS_FPR29,
|
||||
MIPS_FPR30,
|
||||
MIPS_FPR31,
|
||||
|
||||
// 寄存器总数
|
||||
MIPS_REGISTERS_COUNT
|
||||
} MIPSRegister;
|
||||
|
||||
// 辅助宏:检查寄存器是否为GPR
|
||||
#define IS_GPR(reg) ((reg) >= MIPS_REG_ZERO && (reg) <= MIPS_REG_RA)
|
||||
|
||||
// 辅助宏:检查寄存器是否为CP0
|
||||
#define IS_CP0(reg) ((reg) >= MIPS_CP0_INDEX && (reg) <= MIPS_CP0_EBASE)
|
||||
|
||||
// 辅助宏:检查寄存器是否为FPR
|
||||
#define IS_FPR(reg) ((reg) >= MIPS_FPR0 && (reg) <= MIPS_FPR31)
|
||||
132
src/Infrastructure/src/Emulator/Cores/tlib/arch/mips/helper.c
Normal file
132
src/Infrastructure/src/Emulator/Cores/tlib/arch/mips/helper.c
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* MIPS
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#include "cpu.h"
|
||||
|
||||
// MIPS Helper函数实现
|
||||
|
||||
// CPU初始化
|
||||
void cpu_reset(CPUState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
// 清零所有通用寄存器
|
||||
for (i = 0; i < 32; i++) {
|
||||
env->gpr[i] = 0;
|
||||
}
|
||||
|
||||
// 初始化PC到复位向量
|
||||
env->pc = 0xBFC00000; // MIPS复位向量地址
|
||||
|
||||
// 初始化HI/LO
|
||||
env->HI = 0;
|
||||
env->LO = 0;
|
||||
|
||||
// 初始化CP0寄存器
|
||||
env->CP0_Status = CP0_STATUS_BEV | CP0_STATUS_ERL; // Bootstrap向量启用,Error Level
|
||||
env->CP0_Cause = 0;
|
||||
env->CP0_EPC = 0;
|
||||
env->CP0_PRId = 0x00006302; // 示例处理器ID(需要根据龙芯1E300实际值修改)
|
||||
env->CP0_Config0 = 0x80000000; // 基本配置
|
||||
env->CP0_Config1 = 0;
|
||||
env->CP0_Random = 0x0000001f;
|
||||
env->CP0_Wired = 0;
|
||||
env->CP0_Count = 0;
|
||||
env->CP0_Compare = 0;
|
||||
|
||||
// 初始化内部状态
|
||||
env->hflags = MIPS_HFLAG_KM; // Kernel mode
|
||||
env->error_code = 0;
|
||||
|
||||
// 清除中断
|
||||
env->interrupt_request = 0;
|
||||
}
|
||||
|
||||
// 计算MMU索引
|
||||
int cpu_mips_mmu_index(CPUState *env)
|
||||
{
|
||||
return cpu_mmu_index(env);
|
||||
}
|
||||
|
||||
// CPU初始化函数(必需)
|
||||
int cpu_init(const char *cpu_model)
|
||||
{
|
||||
cpu_reset(cpu);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 架构清理函数(必需)
|
||||
void tlib_arch_dispose()
|
||||
{
|
||||
// 最小实现:无需特殊清理
|
||||
}
|
||||
|
||||
// 内存事务状态获取(必需)
|
||||
uint64_t cpu_get_state_for_memory_transaction(CPUState *env, target_ulong addr, int access_type)
|
||||
{
|
||||
return 0; // 最小实现
|
||||
}
|
||||
|
||||
// MMU故障处理(简化版)
|
||||
int cpu_handle_mmu_fault(CPUState *env, target_ulong address, int access_type,
|
||||
int mmu_idx, int is_softmmu, int no_page_fault, target_phys_addr_t *paddr)
|
||||
{
|
||||
// 最小实现:直接映射物理地址
|
||||
*paddr = address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 获取物理页面用于调试(必需)
|
||||
target_phys_addr_t cpu_get_phys_page_debug(CPUState *env, target_ulong addr)
|
||||
{
|
||||
// 最小实现:直接映射
|
||||
return addr;
|
||||
}
|
||||
|
||||
// 中断处理(必需)
|
||||
void do_interrupt(CPUState *env)
|
||||
{
|
||||
// 最小实现:基本异常处理
|
||||
int cause = env->exception_index;
|
||||
|
||||
// 保存PC到EPC
|
||||
env->CP0_EPC = env->pc;
|
||||
|
||||
// 设置Cause寄存器
|
||||
env->CP0_Cause = (env->CP0_Cause & ~CP0_CAUSE_EXCCODE_MASK) |
|
||||
(cause << CP0_CAUSE_EXCCODE_SHIFT);
|
||||
|
||||
// 进入异常级别
|
||||
env->CP0_Status |= CP0_STATUS_EXL;
|
||||
|
||||
// 跳转到异常向量
|
||||
if (env->CP0_Status & CP0_STATUS_BEV) {
|
||||
env->pc = 0xBFC00380; // Bootstrap exception vector
|
||||
} else {
|
||||
env->pc = 0x80000180; // Normal exception vector
|
||||
}
|
||||
}
|
||||
|
||||
// 中断处理前检查(必需)
|
||||
int process_interrupt(int interrupt_request, CPUState *env)
|
||||
{
|
||||
if ((interrupt_request & CPU_INTERRUPT_HARD) && mips_interrupts_enabled(env)) {
|
||||
env->exception_index = EXCP_SYSCALL; // 简化版本
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// CPU执行前序(必需)
|
||||
void cpu_exec_prologue(CPUState *env)
|
||||
{
|
||||
// 最小实现
|
||||
}
|
||||
|
||||
// CPU执行后序(必需)
|
||||
void cpu_exec_epilogue(CPUState *env)
|
||||
{
|
||||
// 最小实现
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
/*
|
||||
* MIPS
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
|
||||
#include "def-helper.h"
|
||||
|
||||
/* Exceptions */
|
||||
DEF_HELPER_2(raise_exception, void, env, i32)
|
||||
|
||||
#include "def-helper.h"
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* MIPS
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
#include "cpu.h"
|
||||
#include "helper.h"
|
||||
|
||||
// MIPS操作辅助函数实现
|
||||
|
||||
// 触发异常
|
||||
void HELPER(raise_exception)(CPUState *env, uint32_t exception)
|
||||
{
|
||||
env->exception_index = exception;
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
// TLB填充函数(必需)
|
||||
int arch_tlb_fill(CPUState *env, target_ulong addr, int access_type, int mmu_idx, void *retaddr, int no_page_fault,
|
||||
int access_width, target_phys_addr_t *paddr)
|
||||
{
|
||||
return cpu_handle_mmu_fault(env, addr, access_type, mmu_idx, 1, no_page_fault, paddr);
|
||||
}
|
||||
|
||||
// MMU故障异常触发(必需)
|
||||
void arch_raise_mmu_fault_exception(CPUState *env, int errcode, int access_type, target_ulong address, void *retaddr)
|
||||
{
|
||||
cpu_restore_state(env, retaddr);
|
||||
cpu_loop_exit(env);
|
||||
}
|
||||
|
||||
// 生成softmmu访问函数(__ldb_mmu, __ldl_mmu, __stb_mmu等)
|
||||
#define MMUSUFFIX _mmu
|
||||
|
||||
#define SHIFT 0
|
||||
#include "softmmu_template.h"
|
||||
|
||||
#define SHIFT 1
|
||||
#include "softmmu_template.h"
|
||||
|
||||
#define SHIFT 2
|
||||
#include "softmmu_template.h"
|
||||
|
||||
#define SHIFT 3
|
||||
#include "softmmu_template.h"
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* MIPS
|
||||
* Author:liuwb
|
||||
* Date:2026_0209
|
||||
*/
|
||||
|
||||
/* MIPS translation - Minimal implementation */
|
||||
/*
|
||||
modify history:
|
||||
2026_0210 wangsx:add translate
|
||||
1.整数(ALU) (I/R型)
|
||||
addiu(加立即数(不触发溢出异常))/addi(加立即数(有溢出异常))
|
||||
addu寄存器加(不触发溢出异常)/add寄存器加(有溢出异常)
|
||||
subu寄存器减(不触发溢出异常)/sub寄存器减(有溢出异常)
|
||||
and/andi 按位与
|
||||
or/ori 按位或 (立即数零扩展)
|
||||
xor/xori 按位异或 (立即数零扩展)
|
||||
nor 按位或非
|
||||
slt(小于则置 1(有符号比较))/sltu 小于则置 1(无符号比较)
|
||||
slti/sltiu 与立即数比较,小于则置 1 (slti 按有符号,sltiu 按无符号。)
|
||||
2.移位
|
||||
sll (逻辑左移)
|
||||
srl (逻辑右移)
|
||||
sra (算术右移)
|
||||
sllv (变量逻辑左移)
|
||||
srlv (变量逻辑右移)
|
||||
srav (变量算术右移)
|
||||
3.Load/Store(先做对齐访问,后补不对齐)
|
||||
**32 位字(word)**
|
||||
lw _加载字_(Load Word)
|
||||
sw _存储字_(Store Word)
|
||||
**8 位字节(byte)**
|
||||
lb _加载字节(符号扩展)_ 读 1 字节,扩展到 32 位时 **保留符号**(0x80 会扩展成负数)。
|
||||
lbu _加载字节(零扩展)_ 读 1 字节,扩展到 32 位时 **高位补 0**。
|
||||
sb _存储字节_ 读 1 字节,扩展到 32 位时 **高位补 0**。
|
||||
**16 位半字(halfword)**
|
||||
lh _加载半字(符号扩展)_
|
||||
lhu _加载半字(零扩展)_
|
||||
sh _存储半字_
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "exec-all.h"
|
||||
#include "tcg-op.h"
|
||||
|
||||
void translate_init(void)
|
||||
{
|
||||
// 最小实现
|
||||
}
|
||||
|
||||
int gen_intermediate_code(CPUState *env, DisasContextBase *dcbase)
|
||||
{
|
||||
// 最小实现:只生成一个退出指令
|
||||
dcbase->tb->size = 4;
|
||||
dcbase->tb->icount = 1;
|
||||
tcg_gen_exit_tb(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t gen_intermediate_code_epilogue(CPUState *env, DisasContextBase *dcbase)
|
||||
{
|
||||
return dcbase->tb->size;
|
||||
}
|
||||
|
||||
void restore_state_to_opc(CPUState *env, TranslationBlock *tb, target_ulong *data)
|
||||
{
|
||||
env->pc = data[0];
|
||||
}
|
||||
|
||||
// 设置反汇编上下文(必需)
|
||||
void setup_disas_context(DisasContextBase *dcbase, CPUState *env)
|
||||
{
|
||||
DisasContext *ctx = (DisasContext *)dcbase;
|
||||
ctx->mem_idx = cpu_mmu_index(env);
|
||||
}
|
||||
|
||||
// 生成断点指令(必需)
|
||||
int gen_breakpoint(DisasContextBase *dcbase, CPUBreakpoint *bp)
|
||||
{
|
||||
tcg_gen_exit_tb(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 同步PC(必需)
|
||||
void gen_sync_pc(DisasContext *dc)
|
||||
{
|
||||
// 最小实现
|
||||
}
|
||||
Reference in New Issue
Block a user