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:
liuwb
2026-02-09 01:19:18 +08:00
parent b3117648be
commit fb988bcd22
14 changed files with 1066 additions and 5 deletions

View File

@@ -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)

View File

@@ -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)

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View 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];
// 程序计数器注意必须使用小写pccpu-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 // 返回地址寄存器

View File

@@ -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)

View File

@@ -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)

View 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)
{
// 最小实现
}

View File

@@ -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"

View File

@@ -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"

View File

@@ -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)
{
// 最小实现
}