commit
a2cb31086f
@ -0,0 +1,5 @@ |
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <generated/asm-offsets.h> |
@ -0,0 +1,61 @@ |
||||
/*
|
||||
* offset.c: Calculate pt_regs and task_struct offsets. |
||||
* |
||||
* Copyright (C) 1996 David S. Miller |
||||
* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003 Ralf Baechle |
||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
||||
* |
||||
* Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com |
||||
* Copyright (C) 2000 MIPS Technologies, Inc. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <asm/ptrace.h> |
||||
#include <linux/stddef.h> |
||||
#include <linux/kbuild.h> |
||||
|
||||
void output_ptreg_defines(void) |
||||
{ |
||||
COMMENT("MIPS pt_regs offsets."); |
||||
OFFSET(PT_R0, pt_regs, regs[0]); |
||||
OFFSET(PT_R1, pt_regs, regs[1]); |
||||
OFFSET(PT_R2, pt_regs, regs[2]); |
||||
OFFSET(PT_R3, pt_regs, regs[3]); |
||||
OFFSET(PT_R4, pt_regs, regs[4]); |
||||
OFFSET(PT_R5, pt_regs, regs[5]); |
||||
OFFSET(PT_R6, pt_regs, regs[6]); |
||||
OFFSET(PT_R7, pt_regs, regs[7]); |
||||
OFFSET(PT_R8, pt_regs, regs[8]); |
||||
OFFSET(PT_R9, pt_regs, regs[9]); |
||||
OFFSET(PT_R10, pt_regs, regs[10]); |
||||
OFFSET(PT_R11, pt_regs, regs[11]); |
||||
OFFSET(PT_R12, pt_regs, regs[12]); |
||||
OFFSET(PT_R13, pt_regs, regs[13]); |
||||
OFFSET(PT_R14, pt_regs, regs[14]); |
||||
OFFSET(PT_R15, pt_regs, regs[15]); |
||||
OFFSET(PT_R16, pt_regs, regs[16]); |
||||
OFFSET(PT_R17, pt_regs, regs[17]); |
||||
OFFSET(PT_R18, pt_regs, regs[18]); |
||||
OFFSET(PT_R19, pt_regs, regs[19]); |
||||
OFFSET(PT_R20, pt_regs, regs[20]); |
||||
OFFSET(PT_R21, pt_regs, regs[21]); |
||||
OFFSET(PT_R22, pt_regs, regs[22]); |
||||
OFFSET(PT_R23, pt_regs, regs[23]); |
||||
OFFSET(PT_R24, pt_regs, regs[24]); |
||||
OFFSET(PT_R25, pt_regs, regs[25]); |
||||
OFFSET(PT_R26, pt_regs, regs[26]); |
||||
OFFSET(PT_R27, pt_regs, regs[27]); |
||||
OFFSET(PT_R28, pt_regs, regs[28]); |
||||
OFFSET(PT_R29, pt_regs, regs[29]); |
||||
OFFSET(PT_R30, pt_regs, regs[30]); |
||||
OFFSET(PT_R31, pt_regs, regs[31]); |
||||
OFFSET(PT_LO, pt_regs, lo); |
||||
OFFSET(PT_HI, pt_regs, hi); |
||||
OFFSET(PT_EPC, pt_regs, cp0_epc); |
||||
OFFSET(PT_BVADDR, pt_regs, cp0_badvaddr); |
||||
OFFSET(PT_STATUS, pt_regs, cp0_status); |
||||
OFFSET(PT_CAUSE, pt_regs, cp0_cause); |
||||
DEFINE(PT_SIZE, sizeof(struct pt_regs)); |
||||
BLANK(); |
||||
} |
@ -0,0 +1,224 @@ |
||||
/* |
||||
* Copyright (C) 1994 - 2000, 2001, 2003 Ralf Baechle |
||||
* Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
||||
* Copyright (C) 2002, 2007 Maciej W. Rozycki |
||||
* Copyright (C) 2001, 2012 MIPS Technologies, Inc. All rights reserved. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <asm/asm.h> |
||||
#include <asm/regdef.h> |
||||
#include <asm/mipsregs.h> |
||||
#include <asm/asm-offsets.h> |
||||
|
||||
#define STATMASK 0x1f |
||||
|
||||
.set noreorder
|
||||
|
||||
/* |
||||
* Macros copied and adapted from Linux MIPS |
||||
*/ |
||||
.macro SAVE_AT
|
||||
.set push
|
||||
.set noat
|
||||
LONG_S $1, PT_R1(sp) |
||||
.set pop
|
||||
.endm |
||||
|
||||
.macro SAVE_TEMP
|
||||
#if __mips_isa_rev < 6 |
||||
mfhi v1 |
||||
#endif |
||||
#ifdef CONFIG_32BIT |
||||
LONG_S $8, PT_R8(sp) |
||||
LONG_S $9, PT_R9(sp) |
||||
#endif |
||||
LONG_S $10, PT_R10(sp) |
||||
LONG_S $11, PT_R11(sp) |
||||
LONG_S $12, PT_R12(sp) |
||||
#if __mips_isa_rev < 6 |
||||
LONG_S v1, PT_HI(sp) |
||||
mflo v1 |
||||
#endif |
||||
LONG_S $13, PT_R13(sp) |
||||
LONG_S $14, PT_R14(sp) |
||||
LONG_S $15, PT_R15(sp) |
||||
LONG_S $24, PT_R24(sp) |
||||
#if __mips_isa_rev < 6 |
||||
LONG_S v1, PT_LO(sp) |
||||
#endif |
||||
.endm |
||||
|
||||
.macro SAVE_STATIC
|
||||
LONG_S $16, PT_R16(sp) |
||||
LONG_S $17, PT_R17(sp) |
||||
LONG_S $18, PT_R18(sp) |
||||
LONG_S $19, PT_R19(sp) |
||||
LONG_S $20, PT_R20(sp) |
||||
LONG_S $21, PT_R21(sp) |
||||
LONG_S $22, PT_R22(sp) |
||||
LONG_S $23, PT_R23(sp) |
||||
LONG_S $30, PT_R30(sp) |
||||
.endm |
||||
|
||||
.macro SAVE_SOME
|
||||
.set push
|
||||
.set noat
|
||||
PTR_SUBU k1, sp, PT_SIZE |
||||
LONG_S sp, PT_R29(k1) |
||||
move sp, k1 |
||||
|
||||
LONG_S $3, PT_R3(sp) |
||||
LONG_S $0, PT_R0(sp) |
||||
mfc0 v1, CP0_STATUS |
||||
LONG_S $2, PT_R2(sp) |
||||
LONG_S v1, PT_STATUS(sp) |
||||
LONG_S $4, PT_R4(sp) |
||||
mfc0 v1, CP0_CAUSE |
||||
LONG_S $5, PT_R5(sp) |
||||
LONG_S v1, PT_CAUSE(sp) |
||||
LONG_S $6, PT_R6(sp) |
||||
MFC0 v1, CP0_EPC |
||||
LONG_S $7, PT_R7(sp) |
||||
#ifdef CONFIG_64BIT |
||||
LONG_S $8, PT_R8(sp) |
||||
LONG_S $9, PT_R9(sp) |
||||
#endif |
||||
LONG_S v1, PT_EPC(sp) |
||||
LONG_S $25, PT_R25(sp) |
||||
LONG_S $28, PT_R28(sp) |
||||
LONG_S $31, PT_R31(sp) |
||||
.set pop
|
||||
.endm |
||||
|
||||
.macro RESTORE_AT
|
||||
.set push
|
||||
.set noat
|
||||
LONG_L $1, PT_R1(sp) |
||||
.set pop
|
||||
.endm |
||||
|
||||
.macro RESTORE_TEMP
|
||||
#if __mips_isa_rev < 6 |
||||
LONG_L $24, PT_LO(sp) |
||||
mtlo $24 |
||||
LONG_L $24, PT_HI(sp) |
||||
mthi $24 |
||||
#endif |
||||
#ifdef CONFIG_32BIT |
||||
LONG_L $8, PT_R8(sp) |
||||
LONG_L $9, PT_R9(sp) |
||||
#endif |
||||
LONG_L $10, PT_R10(sp) |
||||
LONG_L $11, PT_R11(sp) |
||||
LONG_L $12, PT_R12(sp) |
||||
LONG_L $13, PT_R13(sp) |
||||
LONG_L $14, PT_R14(sp) |
||||
LONG_L $15, PT_R15(sp) |
||||
LONG_L $24, PT_R24(sp) |
||||
.endm |
||||
|
||||
.macro RESTORE_STATIC
|
||||
LONG_L $16, PT_R16(sp) |
||||
LONG_L $17, PT_R17(sp) |
||||
LONG_L $18, PT_R18(sp) |
||||
LONG_L $19, PT_R19(sp) |
||||
LONG_L $20, PT_R20(sp) |
||||
LONG_L $21, PT_R21(sp) |
||||
LONG_L $22, PT_R22(sp) |
||||
LONG_L $23, PT_R23(sp) |
||||
LONG_L $30, PT_R30(sp) |
||||
.endm |
||||
|
||||
.macro RESTORE_SOME
|
||||
.set push
|
||||
.set reorder
|
||||
.set noat
|
||||
mfc0 a0, CP0_STATUS |
||||
ori a0, STATMASK |
||||
xori a0, STATMASK |
||||
mtc0 a0, CP0_STATUS |
||||
li v1, ST0_CU1 | ST0_FR | ST0_IM |
||||
and a0, v1 |
||||
LONG_L v0, PT_STATUS(sp) |
||||
nor v1, $0, v1 |
||||
and v0, v1 |
||||
or v0, a0 |
||||
mtc0 v0, CP0_STATUS |
||||
LONG_L v1, PT_EPC(sp) |
||||
MTC0 v1, CP0_EPC |
||||
LONG_L $31, PT_R31(sp) |
||||
LONG_L $28, PT_R28(sp) |
||||
LONG_L $25, PT_R25(sp) |
||||
#ifdef CONFIG_64BIT |
||||
LONG_L $8, PT_R8(sp) |
||||
LONG_L $9, PT_R9(sp) |
||||
#endif |
||||
LONG_L $7, PT_R7(sp) |
||||
LONG_L $6, PT_R6(sp) |
||||
LONG_L $5, PT_R5(sp) |
||||
LONG_L $4, PT_R4(sp) |
||||
LONG_L $3, PT_R3(sp) |
||||
LONG_L $2, PT_R2(sp) |
||||
.set pop
|
||||
.endm |
||||
|
||||
.macro RESTORE_SP
|
||||
LONG_L sp, PT_R29(sp) |
||||
.endm |
||||
|
||||
NESTED(except_vec3_generic, 0, sp) |
||||
PTR_LA k1, handle_reserved |
||||
jr k1 |
||||
nop |
||||
END(except_vec3_generic) |
||||
|
||||
NESTED(except_vec_ejtag_debug, 0, sp) |
||||
PTR_LA k1, handle_ejtag_debug |
||||
jr k1 |
||||
nop |
||||
END(except_vec_ejtag_debug) |
||||
|
||||
NESTED(handle_reserved, PT_SIZE, sp) |
||||
SAVE_SOME |
||||
SAVE_AT |
||||
SAVE_TEMP |
||||
SAVE_STATIC |
||||
|
||||
PTR_LA t9, do_reserved |
||||
jr t9 |
||||
move a0, sp |
||||
END(handle_reserved) |
||||
|
||||
NESTED(handle_ejtag_debug, PT_SIZE, sp) |
||||
.set push
|
||||
.set noat
|
||||
MTC0 k1, CP0_DESAVE |
||||
|
||||
/* Check for SDBBP */ |
||||
MFC0 k1, CP0_DEBUG |
||||
sll k1, k1, 30 |
||||
bgez k1, ejtag_return |
||||
nop |
||||
|
||||
SAVE_SOME |
||||
SAVE_AT |
||||
SAVE_TEMP |
||||
SAVE_STATIC |
||||
|
||||
PTR_LA t9, do_ejtag_debug |
||||
jalr t9 |
||||
move a0, sp |
||||
|
||||
RESTORE_TEMP |
||||
RESTORE_STATIC |
||||
RESTORE_AT |
||||
RESTORE_SOME |
||||
RESTORE_SP |
||||
|
||||
ejtag_return: |
||||
MFC0 k1, CP0_DESAVE |
||||
deret |
||||
.set pop
|
||||
END(handle_ejtag_debug) |
@ -0,0 +1,19 @@ |
||||
/*
|
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
int arch_reserve_stacks(void) |
||||
{ |
||||
/* reserve space for exception vector table */ |
||||
gd->start_addr_sp -= 0x500; |
||||
gd->start_addr_sp &= ~0xFFF; |
||||
gd->irq_sp = gd->start_addr_sp; |
||||
debug("Reserving %d Bytes for exception vector at: %08lx\n", |
||||
0x500, gd->start_addr_sp); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,106 @@ |
||||
/*
|
||||
* Copyright (C) 1994 - 1999, 2000, 01, 06 Ralf Baechle |
||||
* Copyright (C) 1995, 1996 Paul M. Antoine |
||||
* Copyright (C) 1998 Ulf Carlsson |
||||
* Copyright (C) 1999 Silicon Graphics, Inc. |
||||
* Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com |
||||
* Copyright (C) 2002, 2003, 2004, 2005, 2007 Maciej W. Rozycki |
||||
* Copyright (C) 2000, 2001, 2012 MIPS Technologies, Inc. All rights reserved. |
||||
* Copyright (C) 2014, Imagination Technologies Ltd. |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
#include <asm/mipsregs.h> |
||||
#include <asm/addrspace.h> |
||||
#include <asm/system.h> |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
static void show_regs(const struct pt_regs *regs) |
||||
{ |
||||
const int field = 2 * sizeof(unsigned long); |
||||
unsigned int cause = regs->cp0_cause; |
||||
unsigned int exccode; |
||||
int i; |
||||
|
||||
/*
|
||||
* Saved main processor registers |
||||
*/ |
||||
for (i = 0; i < 32; ) { |
||||
if ((i % 4) == 0) |
||||
printf("$%2d :", i); |
||||
if (i == 0) |
||||
printf(" %0*lx", field, 0UL); |
||||
else if (i == 26 || i == 27) |
||||
printf(" %*s", field, ""); |
||||
else |
||||
printf(" %0*lx", field, regs->regs[i]); |
||||
|
||||
i++; |
||||
if ((i % 4) == 0) |
||||
puts("\n"); |
||||
} |
||||
|
||||
printf("Hi : %0*lx\n", field, regs->hi); |
||||
printf("Lo : %0*lx\n", field, regs->lo); |
||||
|
||||
/*
|
||||
* Saved cp0 registers |
||||
*/ |
||||
printf("epc : %0*lx (text %0*lx)\n", field, regs->cp0_epc, |
||||
field, regs->cp0_epc - gd->reloc_off); |
||||
printf("ra : %0*lx (text %0*lx)\n", field, regs->regs[31], |
||||
field, regs->regs[31] - gd->reloc_off); |
||||
|
||||
printf("Status: %08x\n", (uint32_t) regs->cp0_status); |
||||
|
||||
exccode = (cause & CAUSEF_EXCCODE) >> CAUSEB_EXCCODE; |
||||
printf("Cause : %08x (ExcCode %02x)\n", cause, exccode); |
||||
|
||||
if (1 <= exccode && exccode <= 5) |
||||
printf("BadVA : %0*lx\n", field, regs->cp0_badvaddr); |
||||
|
||||
printf("PrId : %08x\n", read_c0_prid()); |
||||
} |
||||
|
||||
void do_reserved(const struct pt_regs *regs) |
||||
{ |
||||
puts("\nOoops:\n"); |
||||
show_regs(regs); |
||||
hang(); |
||||
} |
||||
|
||||
void do_ejtag_debug(const struct pt_regs *regs) |
||||
{ |
||||
const int field = 2 * sizeof(unsigned long); |
||||
unsigned long depc; |
||||
unsigned int debug; |
||||
|
||||
depc = read_c0_depc(); |
||||
debug = read_c0_debug(); |
||||
|
||||
printf("SDBBP EJTAG debug exception: c0_depc = %0*lx, DEBUG = %08x\n", |
||||
field, depc, debug); |
||||
} |
||||
|
||||
static void set_handler(unsigned long offset, void *addr, unsigned long size) |
||||
{ |
||||
unsigned long ebase = gd->irq_sp; |
||||
|
||||
memcpy((void *)(ebase + offset), addr, size); |
||||
flush_cache(ebase + offset, size); |
||||
} |
||||
|
||||
void trap_init(ulong reloc_addr) |
||||
{ |
||||
unsigned long ebase = gd->irq_sp; |
||||
|
||||
set_handler(0x180, &except_vec3_generic, 0x80); |
||||
set_handler(0x280, &except_vec_ejtag_debug, 0x80); |
||||
|
||||
write_c0_ebase(ebase); |
||||
clear_c0_status(ST0_BEV); |
||||
execution_hazard_barrier(); |
||||
} |
Loading…
Reference in new issue