summaryrefslogtreecommitdiff
path: root/libcpu/mips/common
diff options
context:
space:
mode:
authorWBI\nxf44444 <[email protected]>2020-10-26 14:58:46 +0800
committerWBI\nxf44444 <[email protected]>2020-10-26 14:58:46 +0800
commit102976e89f2d5f004dbad25ad42a0dc659294ed2 (patch)
tree0d9da35d5b46a075a5ddc36d732a66e8a080b5ce /libcpu/mips/common
parent6bc3301e0880703b7889d69f262f7e633c951737 (diff)
parent877921f10bd2904c8e683f0df7a4d2596e3e64ba (diff)
note
Diffstat (limited to 'libcpu/mips/common')
-rw-r--r--libcpu/mips/common/asm.h89
-rw-r--r--libcpu/mips/common/context_gcc.S45
-rw-r--r--libcpu/mips/common/entry_gcc.S29
-rw-r--r--libcpu/mips/common/exception.c88
-rw-r--r--libcpu/mips/common/exception_gcc.S21
-rw-r--r--libcpu/mips/common/mips_addrspace.h23
-rw-r--r--libcpu/mips/common/mips_fpu.h4
-rw-r--r--libcpu/mips/common/mips_regs.h52
-rw-r--r--libcpu/mips/common/ptrace.h27
-rw-r--r--libcpu/mips/common/stack.c21
-rw-r--r--libcpu/mips/common/stackframe.h20
11 files changed, 329 insertions, 90 deletions
diff --git a/libcpu/mips/common/asm.h b/libcpu/mips/common/asm.h
index ec451650d2..1b39eea05a 100644
--- a/libcpu/mips/common/asm.h
+++ b/libcpu/mips/common/asm.h
@@ -14,6 +14,7 @@
#ifndef __ASM_H__
#define __ASM_H__
+#include <rtconfig.h>
/*
* LEAF - declare leaf routine
*/
@@ -117,7 +118,94 @@ symbol = value
/*
* Macros to handle different pointer/register sizes for 32/64-bit code
*/
+#if defined ARCH_MIPS64
+/*
+ * Size of a register
+ */
+#define SZREG 8
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#define REG_S sd
+#define REG_L ld
+#define REG_SUBU dsubu
+#define REG_ADDU daddu
+
+/*
+ * How to add/sub/load/store/shift C int variables.
+ */
+#define INT_ADD dadd
+#define INT_ADDU daddu
+#define INT_ADDI daddi
+#define INT_ADDIU daddiu
+#define INT_SUB dsub
+#define INT_SUBU dsubu
+#define INT_L ld
+#define INT_S sd
+#define INT_SLL dsll
+#define INT_SLLV dsllv
+#define INT_SRL dsrl
+#define INT_SRLV dsrlv
+#define INT_SRA dsra
+#define INT_SRAV dsrav
+
+/*
+ * Use the following macros in assemblercode to load/store registers,
+ * pointers etc.
+ */
+#define LONG_ADD dadd
+#define LONG_ADDU daddu
+#define LONG_ADDI daddi
+#define LONG_ADDIU daddiu
+#define LONG_SUB dsub
+#define LONG_SUBU dsubu
+#define LONG_L ld
+#define LONG_S sd
+#define LONG_SP sdp
+#define LONG_SLL dsll
+#define LONG_SLLV dsllv
+#define LONG_SRL dsrl
+#define LONG_SRLV dsrlv
+#define LONG_SRA dsra
+#define LONG_SRAV dsrav
+
+#define LONG .dword
+#define LONGSIZE 8
+#define LONGMASK 7
+#define LONGLOG 3
+
+/*
+ * How to add/sub/load/store/shift pointers.
+ */
+#define PTR_ADD dadd
+#define PTR_ADDU daddu
+#define PTR_ADDI daddi
+#define PTR_ADDIU daddiu
+#define PTR_SUB dsub
+#define PTR_SUBU dsubu
+#define PTR_L ld
+#define PTR_S sd
+#define PTR_LA dla
+#define PTR_LI dli
+#define PTR_SLL dsll
+#define PTR_SLLV dsllv
+#define PTR_SRL dsrl
+#define PTR_SRLV dsrlv
+#define PTR_SRA dsra
+#define PTR_SRAV dsrav
+
+#define PTR_SCALESHIFT 3
+
+#define PTR .dword
+#define PTRSIZE 8
+#define PTRLOG 3
+
+#define MFC0 dmfc0
+#define MTC0 dmtc0
+#else
/*
* Size of a register
*/
@@ -211,6 +299,7 @@ symbol = value
#define MFC0 mfc0
#define MTC0 mtc0
+#endif
#define SSNOP sll zero, zero, 1
diff --git a/libcpu/mips/common/context_gcc.S b/libcpu/mips/common/context_gcc.S
index 251fc81c3c..3fdbe374c9 100644
--- a/libcpu/mips/common/context_gcc.S
+++ b/libcpu/mips/common/context_gcc.S
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
+ * 2020-07-26 lizhirui Fixed some problems
*/
#ifndef __ASSEMBLY__
@@ -25,11 +26,11 @@
*/
.globl rt_hw_context_switch
rt_hw_context_switch:
- mtc0 ra, CP0_EPC
+ MTC0 ra, CP0_EPC
SAVE_ALL
- sw sp, 0(a0) /* store sp in preempted tasks TCB */
- lw sp, 0(a1) /* get new task stack pointer */
+ REG_S sp, 0(a0) /* store sp in preempted tasks TCB */
+ REG_L sp, 0(a1) /* get new task stack pointer */
RESTORE_ALL_AND_RET
@@ -39,7 +40,7 @@ rt_hw_context_switch:
*/
.globl rt_hw_context_switch_to
rt_hw_context_switch_to:
- lw sp, 0(a0) /* get new task stack pointer */
+ REG_L sp, 0(a0) /* get new task stack pointer */
RESTORE_ALL_AND_RET
/*
@@ -50,18 +51,18 @@ rt_hw_context_switch_to:
.globl rt_interrupt_to_thread
.globl rt_hw_context_switch_interrupt
rt_hw_context_switch_interrupt:
- la t0, rt_thread_switch_interrupt_flag
- lw t1, 0(t0)
+ PTR_LA t0, rt_thread_switch_interrupt_flag
+ REG_L t1, 0(t0)
nop
bnez t1, _reswitch
nop
li t1, 0x01 /* set rt_thread_switch_interrupt_flag to 1 */
- sw t1, 0(t0)
- la t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
- sw a0, 0(t0)
+ LONG_S t1, 0(t0)
+ PTR_LA t0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
+ LONG_S a0, 0(t0)
_reswitch:
- la t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
- sw a1, 0(t0)
+ PTR_LA t0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
+ LONG_S a1, 0(t0)
jr ra
nop
@@ -78,7 +79,7 @@ mips_irq_handle:
/* let k0 keep the current context sp */
move k0, sp
/* switch to kernel stack */
- la sp, _system_stack
+ PTR_LA sp, _system_stack
jal rt_interrupt_enter
nop
@@ -96,25 +97,25 @@ mips_irq_handle:
* if rt_thread_switch_interrupt_flag set, jump to
* rt_hw_context_switch_interrupt_do and do not return
*/
- la k0, rt_thread_switch_interrupt_flag
- lw k1, 0(k0)
+ PTR_LA k0, rt_thread_switch_interrupt_flag
+ LONG_L k1, 0(k0)
beqz k1, spurious_interrupt
nop
- sw zero, 0(k0) /* clear flag */
+ LONG_S zero, 0(k0) /* clear flag */
nop
/*
* switch to the new thread
*/
- la k0, rt_interrupt_from_thread
- lw k1, 0(k0)
+ PTR_LA k0, rt_interrupt_from_thread
+ LONG_L k1, 0(k0)
nop
- sw sp, 0(k1) /* store sp in preempted task TCB */
+ LONG_S sp, 0(k1) /* store sp in preempted task TCB */
- la k0, rt_interrupt_to_thread
- lw k1, 0(k0)
+ PTR_LA k0, rt_interrupt_to_thread
+ LONG_L k1, 0(k0)
nop
- lw sp, 0(k1) /* get new task stack pointer */
+ LONG_L sp, 0(k1) /* get new task stack pointer */
j spurious_interrupt
nop
diff --git a/libcpu/mips/common/entry_gcc.S b/libcpu/mips/common/entry_gcc.S
index b6f758e273..d1a0704809 100644
--- a/libcpu/mips/common/entry_gcc.S
+++ b/libcpu/mips/common/entry_gcc.S
@@ -15,6 +15,9 @@
#include <mips.h>
#include <rtconfig.h>
+#include "asm.h"
+#include <rtconfig.h>
+
.section ".start", "ax"
.set noreorder
@@ -25,27 +28,33 @@ _rtthread_entry:
.globl _start
_start:
#endif
- la ra, _rtthread_entry
+ PTR_LA ra, _rtthread_entry
/* disable interrupt */
- mtc0 zero, CP0_CAUSE
- mtc0 zero, CP0_STATUS # Set CPU to disable interrupt.
+ MTC0 zero, CP0_CAUSE
+ MTC0 zero, CP0_STATUS # Set CPU to disable interrupt.
ehb
+
+#ifdef ARCH_MIPS64
+ dli t0, ST0_KX
+ MTC0 t0, CP0_STATUS
+#endif
+
/* setup stack pointer */
- la sp, _system_stack
- la gp, _gp
+ PTR_LA sp, _system_stack
+ PTR_LA gp, _gp
bal rt_cpu_early_init
nop
/* clear bss */
- la t0, __bss_start
- la t1, __bss_end
+ PTR_LA t0, __bss_start
+ PTR_LA t1, __bss_end
+
_clr_bss_loop:
sw zero, 0(t0)
- bne t0, t1, _clr_bss_loop
- addiu t0, t0, 4
-
+ bne t1, t0, _clr_bss_loop
+ addu t0, 4
/* jump to RT-Thread RTOS */
jal rtthread_startup
nop
diff --git a/libcpu/mips/common/exception.c b/libcpu/mips/common/exception.c
index de67e98199..3da8ecead6 100644
--- a/libcpu/mips/common/exception.c
+++ b/libcpu/mips/common/exception.c
@@ -19,10 +19,45 @@
/*@{*/
-extern rt_uint32_t __ebase_entry;
-rt_uint32_t rt_interrupt_from_thread;
-rt_uint32_t rt_interrupt_to_thread;
-rt_uint32_t rt_thread_switch_interrupt_flag;
+extern rt_ubase_t __ebase_entry;
+rt_ubase_t rt_interrupt_from_thread;
+rt_ubase_t rt_interrupt_to_thread;
+rt_ubase_t rt_thread_switch_interrupt_flag;
+
+const char *exception_name[] = {
+ "Interrupt",
+ "(X)TLB Modify Exception",
+ "(X)TLB Read/Fetch Exception",
+ "(X)TLB Write Exception",
+ "Address Read/Fetch Exception",
+ "Address Write Exception",
+ "",
+ "",
+ "Syscall",
+ "Breakpoint",
+ "Reversed Instruction Exception",
+ "Coprocessor Unit Invalid",
+ "Overflow",
+ "Trap",
+ "FPU Exception in Vector Instruction",
+ "FPU Exception",
+ "Loongson Custom Exception",
+ "",
+ "",
+ "(X)TLB Read Denied Exception",
+ "(X)TLB Execute Denied Exception",
+ "Vector Module Disabled Exception",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Cache Error Exception",
+ ""
+ };
rt_base_t rt_hw_interrupt_disable(void)
{
@@ -39,7 +74,7 @@ void rt_hw_interrupt_enable(rt_base_t level)
/**
* exception handle table
*/
-#define RT_EXCEPTION_MAX 31
+#define RT_EXCEPTION_MAX 32
exception_func_t sys_exception_handlers[RT_EXCEPTION_MAX];
/**
@@ -59,10 +94,13 @@ exception_func_t rt_set_except_vector(int n, exception_func_t func)
return old_handler;
}
-void mips_dump_regs(struct pt_regs *regs) {
+void mips_dump_regs(struct pt_regs *regs)
+{
int i, j;
- for(i = 0; i < 32 / 4; i++) {
- for(j = 0; j < 4; j++) {
+ for (i = 0; i < 32 / 4; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
int reg = 4 * i + j;
rt_kprintf("%d: 0x%08x, ", reg, regs->regs[reg]);
}
@@ -84,9 +122,15 @@ void cache_error_handler(void)
static void unhandled_exception_handle(struct pt_regs *regs)
{
- rt_kprintf("Unknown Exception, EPC: 0x%08x, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause());
+ rt_kprintf("Unknown Exception, EPC: 0x%p, CAUSE: 0x%08x\n", read_c0_epc(), read_c0_cause());
+ rt_kprintf("Exception Name:%s\n",exception_name[(read_c0_cause() >> 2) & 0x1f]);
+#ifdef SOC_LS2K1000
+ rt_kprintf("ExeCode = 0x%08x,BadAddr = 0x%p\n",(read_c0_cause() >> 2) & 0x1f,mmu_tlb_get_bad_vaddr());
+#else
+ rt_kprintf("ExeCode = 0x%08x\n",(read_c0_cause() >> 2) & 0x1f);
+#endif
rt_kprintf("ST0: 0x%08x ",regs->cp0_status);
- rt_kprintf("ErrorPC: 0x%08x\n",read_c0_errorepc());
+ rt_kprintf("ErrorPC: 0x%p\n",read_c0_errorepc());
mips_dump_regs(regs);
rt_hw_cpu_shutdown();
}
@@ -95,13 +139,17 @@ static void install_default_exception_handler(void)
{
rt_int32_t i;
- for (i=0; i<RT_EXCEPTION_MAX; i++)
- sys_exception_handlers[i] = (exception_func_t)unhandled_exception_handle;
+ for (i = 0; i < RT_EXCEPTION_MAX; i++)
+ sys_exception_handlers[i] =
+ (exception_func_t)unhandled_exception_handle;
}
int rt_hw_exception_init(void)
{
- rt_uint32_t ebase = (rt_uint32_t)&__ebase_entry;
+ rt_ubase_t ebase = (rt_ubase_t)&__ebase_entry;
+#ifdef ARCH_MIPS64
+ ebase |= 0xffffffff00000000;
+#endif
write_c0_ebase(ebase);
clear_c0_status(ST0_BEV | ST0_ERL | ST0_EXL);
clear_c0_status(ST0_IM | ST0_IE);
@@ -114,12 +162,14 @@ int rt_hw_exception_init(void)
void rt_general_exc_dispatch(struct pt_regs *regs)
{
- rt_uint32_t cause, exccode;
+ rt_ubase_t cause, exccode;
+ cause = read_c0_cause();
+ exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
- exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE;
+ if (exccode == 0)
+ {
+ rt_ubase_t status, pending;
- if (exccode == 0) {
- rt_uint32_t status, pending;
status = read_c0_status();
pending = (cause & CAUSEF_IP) & (status & ST0_IM);
if (pending & CAUSEF_IP0)
@@ -138,7 +188,9 @@ void rt_general_exc_dispatch(struct pt_regs *regs)
rt_do_mips_cpu_irq(6);
if (pending & CAUSEF_IP7)
rt_do_mips_cpu_irq(7);
- } else {
+ }
+ else
+ {
if (sys_exception_handlers[exccode])
sys_exception_handlers[exccode](regs);
}
diff --git a/libcpu/mips/common/exception_gcc.S b/libcpu/mips/common/exception_gcc.S
index 176b60e594..c685928a84 100644
--- a/libcpu/mips/common/exception_gcc.S
+++ b/libcpu/mips/common/exception_gcc.S
@@ -1,12 +1,18 @@
/*
- * Copyright (c) 2006-2019, RT-Thread Development Team
+ * Copyright (c) 2006-2020, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-12-04 Jiaxun Yang Initial version
+ * 2020-07-26 lizhirui Add xtlb exception entry
*/
+#ifndef __ASSEMBLY__
+#define __ASSEMBLY__
+#endif
+
+#include <mips.h>
.section ".exc_vectors", "ax"
.extern tlb_refill_handler
@@ -21,6 +27,11 @@ tlb_refill_exception:
b _general_exception_handler
nop
+ /* 0x080 - XTLB refill handler */
+ .org ebase_start + 0x080
+ b _general_exception_handler
+ nop
+
/* 0x100 - Cache error handler */
.org ebase_start + 0x100
j cache_error_handler
@@ -45,15 +56,15 @@ irq_exception:
/* general exception handler */
_general_exception_handler:
.set noreorder
- la $k0, mips_irq_handle
- jr $k0
+ PTR_LA k0, mips_irq_handle
+ jr k0
nop
.set reorder
/* interrupt handler */
_irq_handler:
.set noreorder
- la $k0, mips_irq_handle
- jr $k0
+ PTR_LA k0, mips_irq_handle
+ jr k0
nop
.set reorder
diff --git a/libcpu/mips/common/mips_addrspace.h b/libcpu/mips/common/mips_addrspace.h
index 10fc2d6593..f3bb60662e 100644
--- a/libcpu/mips/common/mips_addrspace.h
+++ b/libcpu/mips/common/mips_addrspace.h
@@ -24,7 +24,7 @@
#define _ATYPE_ __PTRDIFF_TYPE__
#define _ATYPE32_ int
#define _ATYPE64_ __s64
-#ifdef CONFIG_64BIT
+#ifdef ARCH_MIPS64
#define _CONST64_(x) x ## L
#else
#define _CONST64_(x) x ## LL
@@ -54,7 +54,7 @@
#define XPHYSADDR(a) ((_ACAST64_(a)) & \
_CONST64_(0x000000ffffffffff))
-#ifdef CONFIG_64BIT
+#ifdef ARCH_MIPS64
/*
* Memory segments (64bit kernel mode addresses)
@@ -75,6 +75,12 @@
#define CKSEG2ADDR(a) (CPHYSADDR(a) | CKSEG2)
#define CKSEG3ADDR(a) (CPHYSADDR(a) | CKSEG3)
+#define KUSEGBASE 0xffffffff00000000
+#define KSEG0BASE 0xffffffff80000000
+#define KSEG1BASE 0xffffffffa0000000
+#define KSEG2BASE 0xffffffffc0000000
+#define KSEG3BASE 0xffffffffe0000000
+
#else
#define CKSEG0ADDR(a) (CPHYSADDR(a) | KSEG0BASE)
@@ -90,6 +96,12 @@
#define KSEG2ADDR(a) (CPHYSADDR(a) | KSEG2BASE)
#define KSEG3ADDR(a) (CPHYSADDR(a) | KSEG3BASE)
+#define CKUSEG 0x00000000
+#define CKSEG0 0x80000000
+#define CKSEG1 0xa0000000
+#define CKSEG2 0xc0000000
+#define CKSEG3 0xe0000000
+
/*
* Memory segments (32bit kernel mode addresses)
* These are the traditional names used in the 32-bit universe.
@@ -100,14 +112,9 @@
#define KSEG2BASE 0xc0000000
#define KSEG3BASE 0xe0000000
-#define CKUSEG 0x00000000
-#define CKSEG0 0x80000000
-#define CKSEG1 0xa0000000
-#define CKSEG2 0xc0000000
-#define CKSEG3 0xe0000000
-
#endif
+
/*
* Cache modes for XKPHYS address conversion macros
*/
diff --git a/libcpu/mips/common/mips_fpu.h b/libcpu/mips/common/mips_fpu.h
index d6351f7655..50df3746a5 100644
--- a/libcpu/mips/common/mips_fpu.h
+++ b/libcpu/mips/common/mips_fpu.h
@@ -18,7 +18,7 @@
* init hardware FPU
*/
#ifdef RT_USING_FPU
-inline void rt_hw_fpu_init(void)
+rt_inline void rt_hw_fpu_init(void)
{
rt_uint32_t c0_status = 0;
rt_uint32_t c1_status = 0;
@@ -38,7 +38,7 @@ inline void rt_hw_fpu_init(void)
return ;
}
#else
- inline void rt_hw_fpu_init(void){} /* Do nothing */
+ rt_inline void rt_hw_fpu_init(void){} /* Do nothing */
#endif
#endif
diff --git a/libcpu/mips/common/mips_regs.h b/libcpu/mips/common/mips_regs.h
index 7e1359fa33..a13e24b539 100644
--- a/libcpu/mips/common/mips_regs.h
+++ b/libcpu/mips/common/mips_regs.h
@@ -10,13 +10,14 @@
#ifndef _MIPS_REGS_H_
#define _MIPS_REGS_H_
-
+#include <rtconfig.h>
#define REG_A0 4
#define REG_SP 29
#define REG_GP 28
#define REG_FP 30
#define REG_RA 31
+#ifndef ARCH_MIPS64
#define zero $0 /* wired zero */
#define AT $1 /* assembler temp - uppercase because of ".set at" */
#define v0 $2 /* return value */
@@ -56,6 +57,49 @@
#define s8 $30 /* same like fp! */
#define ra $31 /* return address */
+#else
+
+#define zero $0 /* wired zero */
+#define AT $at /* assembler temp - uppercase because of ".set at" */
+#define v0 $2 /* return value - caller saved */
+#define v1 $3
+#define a0 $4 /* argument registers */
+#define a1 $5
+#define a2 $6
+#define a3 $7
+#define a4 $8 /* arg reg 64 bit; caller saved in 32 bit */
+#define ta0 $8
+#define a5 $9
+#define ta1 $9
+#define a6 $10
+#define ta2 $10
+#define a7 $11
+#define ta3 $11
+#define t0 $12 /* caller saved */
+#define t1 $13
+#define t2 $14
+#define t3 $15
+#define s0 $16 /* callee saved */
+#define s1 $17
+#define s2 $18
+#define s3 $19
+#define s4 $20
+#define s5 $21
+#define s6 $22
+#define s7 $23
+#define t8 $24 /* caller saved */
+#define t9 $25 /* callee address for PIC/temp */
+#define jp $25 /* PIC jump register */
+#define k0 $26 /* kernel temporary */
+#define k1 $27
+#define gp $28 /* global pointer - caller saved for PIC */
+#define sp $29 /* stack pointer */
+#define fp $30 /* frame pointer */
+#define s8 $30 /* callee saved */
+#define ra $31 /* return address */
+
+#endif
+
#define fv0 $f0 /* return value */
#define fv0f $f1
#define fv1 $f2
@@ -955,7 +999,7 @@ do { \
#define write_32bit_cp0_set1_register(register,value) \
__asm__ __volatile__( \
- "ctc0\t%0,"STR(register)"\n\t" \
+ "ctc0\t%0,$"STR(register)"\n\t" \
"nop" \
: : "r" (value));
@@ -993,14 +1037,14 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
- "cfc1\t%0,"STR(source)"\n\t" \
+ "cfc1\t%0,$"STR(source)"\n\t" \
".set\tpop" \
: "=r" (__res)); \
__res;})
#define write_32bit_cp1_register(register,value) \
__asm__ __volatile__( \
- "ctc1\t%0,"STR(register)"\n\t" \
+ "ctc1\t%0,$"STR(register)"\n\t" \
"nop" \
: : "r" (value));
diff --git a/libcpu/mips/common/ptrace.h b/libcpu/mips/common/ptrace.h
index cae57cbf4c..00ce58a085 100644
--- a/libcpu/mips/common/ptrace.h
+++ b/libcpu/mips/common/ptrace.h
@@ -14,6 +14,8 @@
#include "asm.h"
#include "mips_regs.h"
+#define HI_LO_SIZE 4
+
#define FP_REG_SIZE 8
#define NUM_FPU_REGS 16
@@ -27,6 +29,7 @@ struct mips_fpu_struct {
};
struct pt_regs {
+#ifndef ARCH_MIPS64
/* Only O32 Need This! */
/* Pad bytes for argument save space on the stack. */
rt_uint32_t pad0[8];
@@ -41,6 +44,18 @@ struct pt_regs {
rt_uint32_t cp0_badvaddr;
rt_uint32_t cp0_cause;
rt_uint32_t cp0_epc;
+#else
+ /* Saved main processor registers. */
+ unsigned long regs[32];
+
+ /* Saved special registers. */
+ rt_uint32_t cp0_status;
+ rt_uint32_t hi;
+ rt_uint32_t lo;
+ unsigned long cp0_badvaddr;
+ rt_uint32_t cp0_cause;
+ unsigned long cp0_epc;
+#endif
#ifdef RT_USING_FPU
/* FPU Registers */
@@ -52,7 +67,11 @@ struct pt_regs {
#endif
/* Note: For call stack o32 ABI has 0x8 shadowsoace Here */
+#ifdef ARCH_MIPS64
+#define PT_R0 (0x0 * LONGSIZE) /* 0 */
+#else
#define PT_R0 (0x8 * LONGSIZE) /* 0 */
+#endif
#define PT_R1 ((PT_R0) + LONGSIZE) /* 1 */
#define PT_R2 ((PT_R1) + LONGSIZE) /* 2 */
#define PT_R3 ((PT_R2) + LONGSIZE) /* 3 */
@@ -89,8 +108,8 @@ struct pt_regs {
* Saved special registers
*/
#define PT_STATUS ((PT_R31) + LONGSIZE) /* 32 */
-#define PT_HI ((PT_STATUS) + LONGSIZE) /* 33 */
-#define PT_LO ((PT_HI) + LONGSIZE) /* 34 */
+#define PT_HI ((PT_STATUS) + HI_LO_SIZE) /* 33 */
+#define PT_LO ((PT_HI) + HI_LO_SIZE) /* 34 */
#define PT_BADVADDR ((PT_LO) + LONGSIZE) /* 35 */
#define PT_CAUSE ((PT_BADVADDR) + LONGSIZE) /* 36 */
#define PT_EPC ((PT_CAUSE) + LONGSIZE) /* 37 */
@@ -115,9 +134,9 @@ struct pt_regs {
#define PT_FPU_R28 ((PT_FPU_R26) + FP_REG_SIZE)
#define PT_FPU_R30 ((PT_FPU_R28) + FP_REG_SIZE)
#define PT_FPU_FCSR31 ((PT_FPU_R30) + FP_REG_SIZE)
-#define PT_FPU_PAD0 ((PT_FPU_FCSR31) + LONGSIZE)
+#define PT_FPU_PAD0 ((PT_FPU_FCSR31) + 4)
-#define PT_FPU_END ((PT_FPU_PAD0) + LONGSIZE)
+#define PT_FPU_END ((PT_FPU_PAD0) + 4)
#define PT_SIZE PT_FPU_END
#else
#define PT_SIZE PT_REG_END
diff --git a/libcpu/mips/common/stack.c b/libcpu/mips/common/stack.c
index b0e613c7a7..b933b184e7 100644
--- a/libcpu/mips/common/stack.c
+++ b/libcpu/mips/common/stack.c
@@ -16,8 +16,8 @@ register rt_uint32_t $GP __asm__ ("$28");
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit)
{
- static rt_uint32_t wSR=0;
- static rt_uint32_t wGP;
+ static rt_ubase_t wSR=0;
+ static rt_ubase_t wGP;
rt_uint8_t *stk;
struct pt_regs *pt;
@@ -25,26 +25,27 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
rt_uint32_t i;
/* Get stack aligned */
- stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_uint32_t)stack_addr, 8);
+ stk = (rt_uint8_t *)RT_ALIGN_DOWN((rt_ubase_t)stack_addr, 8);
stk -= sizeof(struct pt_regs);
pt = (struct pt_regs*)stk;
+#ifndef ARCH_MIPS64
for (i = 0; i < 8; ++i)
{
pt->pad0[i] = 0xdeadbeef;
}
-
+#endif
/* Fill Stack register numbers */
for (i = 0; i < 32; ++i)
{
pt->regs[i] = 0xdeadbeef;
}
- pt->regs[REG_SP] = (rt_uint32_t)stk;
- pt->regs[REG_A0] = (rt_uint32_t)parameter;
- pt->regs[REG_GP] = (rt_uint32_t)$GP;
- pt->regs[REG_FP] = (rt_uint32_t)0x0;
- pt->regs[REG_RA] = (rt_uint32_t)texit;
+ pt->regs[REG_SP] = (rt_ubase_t)stk;
+ pt->regs[REG_A0] = (rt_ubase_t)parameter;
+ pt->regs[REG_GP] = (rt_ubase_t)$GP;
+ pt->regs[REG_FP] = (rt_ubase_t)0x0;
+ pt->regs[REG_RA] = (rt_ubase_t)texit;
pt->hi = 0x0;
pt->lo = 0x0;
@@ -53,7 +54,7 @@ rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_ad
pt->cp0_status |= (ST0_CU1 | ST0_FR);
#endif
pt->cp0_cause = read_c0_cause();
- pt->cp0_epc = (rt_uint32_t)tentry;
+ pt->cp0_epc = (rt_ubase_t)tentry;
pt->cp0_badvaddr = 0x0;
return stk;
diff --git a/libcpu/mips/common/stackframe.h b/libcpu/mips/common/stackframe.h
index 77d55f6934..bb92a18c9c 100644
--- a/libcpu/mips/common/stackframe.h
+++ b/libcpu/mips/common/stackframe.h
@@ -22,7 +22,9 @@
#ifdef RT_USING_FPU
/* Ensure CU1 (FPU) is enabled */
MFC0 v1, CP0_STATUS
- ori v1, ST0_CU1
+ lui t1, %hi(ST0_CU1)
+ addiu t1, t1, %lo(ST0_CU1)
+ or v1, v1, t1
MTC0 v1, CP0_STATUS
SSNOP
cfc1 v1, fcr31
@@ -60,11 +62,11 @@
mfhi v1
LONG_S $8, PT_R8(sp)
LONG_S $9, PT_R9(sp)
- LONG_S v1, PT_HI(sp)
+ sw v1, PT_HI(sp)
mflo v1
LONG_S $10, PT_R10(sp)
LONG_S $11, PT_R11(sp)
- LONG_S v1, PT_LO(sp)
+ sw v1, PT_LO(sp)
LONG_S $12, PT_R12(sp)
LONG_S $13, PT_R13(sp)
LONG_S $14, PT_R14(sp)
@@ -125,11 +127,13 @@
#ifdef RT_USING_FPU
/* Ensure CU1 (FPU) is enabled */
MFC0 v1, CP0_STATUS
- ori v1, ST0_CU1
+ lui t1, %hi(ST0_CU1)
+ addiu t1, t1, %lo(ST0_CU1)
+ or v1, v1, t1
MTC0 v1, CP0_STATUS
SSNOP
LONG_L v1, PT_FPU_FCSR31(sp)
- ctc1 v1, fcsr31
+ ctc1 v1, fcr31
l.d $f0, PT_FPU_R0(sp)
l.d $f2, PT_FPU_R2(sp)
l.d $f4, PT_FPU_R4(sp)
@@ -159,11 +163,11 @@
.endm
.macro RESTORE_TEMP
- LONG_L $24, PT_LO(sp)
+ lw $24, PT_LO(sp)
LONG_L $8, PT_R8(sp)
LONG_L $9, PT_R9(sp)
mtlo $24
- LONG_L $24, PT_HI(sp)
+ lw $24, PT_HI(sp)
LONG_L $10, PT_R10(sp)
LONG_L $11, PT_R11(sp)
mthi $24
@@ -202,6 +206,8 @@
li v1, ~(ST0_CU1 | ST0_FR | ST0_IM)
and v0, v1
or v0, a0
+ li v1, (ST0_KX | ST0_SX | ST0_UX)
+ or v0, v1
mtc0 v0, CP0_STATUS
LONG_L v1, PT_EPC(sp)
MTC0 v1, CP0_EPC