1*a0d261ccSBagas Sanjaya/* SPDX-License-Identifier: GPL-2.0-only */ 24c076fb4SDavid Daney/* 349d148b4SSteven J. Hill * Copyright (C) 2007-2017 Cavium, Inc. 44c076fb4SDavid Daney */ 54c076fb4SDavid Daney#include <asm/asm.h> 64c076fb4SDavid Daney#include <asm/regdef.h> 74c076fb4SDavid Daney 849d148b4SSteven J. Hill#define CVMSEG_BASE -32768 949d148b4SSteven J. Hill#define CVMSEG_SIZE 6912 1049d148b4SSteven J. Hill#define SAVE_REG(r) sd $r, CVMSEG_BASE + CVMSEG_SIZE - ((32 - r) * 8)($0) 114c076fb4SDavid Daney 124c076fb4SDavid Daney NESTED(octeon_wdt_nmi_stage2, 0, sp) 134c076fb4SDavid Daney .set push 144c076fb4SDavid Daney .set noreorder 154c076fb4SDavid Daney .set noat 1649d148b4SSteven J. Hill /* Clear Dcache so cvmseg works right. */ 1749d148b4SSteven J. Hill cache 1,0($0) 1849d148b4SSteven J. Hill /* Use K0 to do a read/modify/write of CVMMEMCTL */ 1949d148b4SSteven J. Hill dmfc0 k0, $11, 7 2049d148b4SSteven J. Hill /* Clear out the size of CVMSEG */ 2149d148b4SSteven J. Hill dins k0, $0, 0, 6 2249d148b4SSteven J. Hill /* Set CVMSEG to its largest value */ 2349d148b4SSteven J. Hill ori k0, k0, 0x1c0 | 54 2449d148b4SSteven J. Hill /* Store the CVMMEMCTL value */ 2549d148b4SSteven J. Hill dmtc0 k0, $11, 7 2649d148b4SSteven J. Hill /* 2749d148b4SSteven J. Hill * Restore K0 from the debug scratch register, it was saved in 2849d148b4SSteven J. Hill * the boot-vector code. 2949d148b4SSteven J. Hill */ 3049d148b4SSteven J. Hill dmfc0 k0, $31 3149d148b4SSteven J. Hill 3249d148b4SSteven J. Hill /* 3349d148b4SSteven J. Hill * Save all registers to the top CVMSEG. This shouldn't 344c076fb4SDavid Daney * corrupt any state used by the kernel. Also all registers 3549d148b4SSteven J. Hill * should have the value right before the NMI. 3649d148b4SSteven J. Hill */ 374c076fb4SDavid Daney SAVE_REG(0) 384c076fb4SDavid Daney SAVE_REG(1) 394c076fb4SDavid Daney SAVE_REG(2) 404c076fb4SDavid Daney SAVE_REG(3) 414c076fb4SDavid Daney SAVE_REG(4) 424c076fb4SDavid Daney SAVE_REG(5) 434c076fb4SDavid Daney SAVE_REG(6) 444c076fb4SDavid Daney SAVE_REG(7) 454c076fb4SDavid Daney SAVE_REG(8) 464c076fb4SDavid Daney SAVE_REG(9) 474c076fb4SDavid Daney SAVE_REG(10) 484c076fb4SDavid Daney SAVE_REG(11) 494c076fb4SDavid Daney SAVE_REG(12) 504c076fb4SDavid Daney SAVE_REG(13) 514c076fb4SDavid Daney SAVE_REG(14) 524c076fb4SDavid Daney SAVE_REG(15) 534c076fb4SDavid Daney SAVE_REG(16) 544c076fb4SDavid Daney SAVE_REG(17) 554c076fb4SDavid Daney SAVE_REG(18) 564c076fb4SDavid Daney SAVE_REG(19) 574c076fb4SDavid Daney SAVE_REG(20) 584c076fb4SDavid Daney SAVE_REG(21) 594c076fb4SDavid Daney SAVE_REG(22) 604c076fb4SDavid Daney SAVE_REG(23) 614c076fb4SDavid Daney SAVE_REG(24) 624c076fb4SDavid Daney SAVE_REG(25) 634c076fb4SDavid Daney SAVE_REG(26) 644c076fb4SDavid Daney SAVE_REG(27) 654c076fb4SDavid Daney SAVE_REG(28) 664c076fb4SDavid Daney SAVE_REG(29) 674c076fb4SDavid Daney SAVE_REG(30) 684c076fb4SDavid Daney SAVE_REG(31) 6949d148b4SSteven J. Hill /* Write zero to all CVMSEG locations per Core-15169 */ 7049d148b4SSteven J. Hill dli a0, CVMSEG_SIZE - (33 * 8) 7149d148b4SSteven J. Hill1: sd zero, CVMSEG_BASE(a0) 7249d148b4SSteven J. Hill daddiu a0, a0, -8 7349d148b4SSteven J. Hill bgez a0, 1b 7449d148b4SSteven J. Hill nop 754c076fb4SDavid Daney /* Set the stack to begin right below the registers */ 7649d148b4SSteven J. Hill dli sp, CVMSEG_BASE + CVMSEG_SIZE - (32 * 8) 774c076fb4SDavid Daney /* Load the address of the third stage handler */ 7849d148b4SSteven J. Hill dla $25, octeon_wdt_nmi_stage3 794c076fb4SDavid Daney /* Call the third stage handler */ 8049d148b4SSteven J. Hill jal $25 814c076fb4SDavid Daney /* a0 is the address of the saved registers */ 824c076fb4SDavid Daney move a0, sp 834c076fb4SDavid Daney /* Loop forvever if we get here. */ 8449d148b4SSteven J. Hill2: b 2b 854c076fb4SDavid Daney nop 864c076fb4SDavid Daney .set pop 874c076fb4SDavid Daney END(octeon_wdt_nmi_stage2) 88