blob: 1dab6adc241b572a9c07686a154c9ef687947f85 [file] [log] [blame]
/*
* Save/restore CPU state macros
*
* Copyright (C) 2016 Mark Cave-Ayland (mark.cave-ayland@ilande.co.uk>)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2
*
*/
#include "autoconf.h"
#define STACKFRAME_SZ 0x60
/* These are just handy. */
#define _SV save %sp, -STACKFRAME_SZ, %sp
#define _RS restore
#define FLUSH_ALL_KERNEL_WINDOWS \
_SV; _SV; _SV; _SV; _SV; _SV; _SV; \
_RS; _RS; _RS; _RS; _RS; _RS; _RS;
#define SAVE_CPU_GENERAL_STATE(type) \
/* Save general state into context at %g1 */ \
rd %psr, %g4; \
st %g4, [%g1]; \
rd %wim, %g4; \
st %g4, [%g1 + 0x4];
#define SAVE_CPU_WINDOW_STATE(type) \
/* Save window state into context at %g1 */ \
st %o0, [%g1 + 0x30]; \
st %o1, [%g1 + 0x34]; \
st %o2, [%g1 + 0x38]; \
st %o3, [%g1 + 0x3c]; \
st %o4, [%g1 + 0x40]; \
st %o5, [%g1 + 0x44]; \
st %o6, [%g1 + 0x48]; \
st %o7, [%g1 + 0x4c]; \
\
set nwindows, %g6; \
ld [%g6], %g6; /* nwindows */ \
mov %g6, %g5; \
sub %g5, 1, %g5; /* mask */ \
\
rd %psr, %g4; \
and %g4, %g5, %g4; /* window */ \
\
rd %psr, %g3; \
srl %g3, 5, %g3; \
sll %g3, 5, %g3; /* psr hi */ \
\
mov %g1, %g2; \
add %g2, 0x50, %g2; \
\
save_cpu_window_##type: \
mov %g3, %g7; \
or %g7, %g4, %g7; \
wr %g7, %psr; \
\
st %l0, [%g2]; \
st %l1, [%g2 + 0x4]; \
st %l2, [%g2 + 0x8]; \
st %l3, [%g2 + 0xc]; \
st %l4, [%g2 + 0x10]; \
st %l5, [%g2 + 0x14]; \
st %l6, [%g2 + 0x18]; \
st %l7, [%g2 + 0x1c]; \
st %i0, [%g2 + 0x20]; \
st %i1, [%g2 + 0x24]; \
st %i2, [%g2 + 0x28]; \
st %i3, [%g2 + 0x2c]; \
st %i4, [%g2 + 0x30]; \
st %i5, [%g2 + 0x34]; \
st %i6, [%g2 + 0x38]; \
st %i7, [%g2 + 0x3c]; \
dec %g4; \
and %g4, %g5, %g4; \
subcc %g6, 1, %g6; \
bne save_cpu_window_##type; \
add %g2, 0x40, %g2; \
\
/* Get back to the correct window */ \
ld [%g1], %g2; \
wr %g2, %psr;
#define SAVE_CPU_STATE(type) \
SAVE_CPU_GENERAL_STATE(type); \
SAVE_CPU_WINDOW_STATE(type);
#define RESTORE_CPU_GENERAL_STATE(type) \
/* Restore window state from context at %g1 */ \
ld [%g1], %g2; \
wr %g2, %psr; \
ld [%g1 + 0x4], %g2; \
wr %g2, %wim;
#define RESTORE_CPU_WINDOW_STATE(type) \
/* Restore window state from context at %g1 */ \
set nwindows, %g6; \
ld [%g6], %g6; /* nwindows */ \
mov %g6, %g5; \
sub %g5, 1, %g5; /* mask */ \
\
rd %psr, %g4; \
and %g4, %g5, %g4; /* window */ \
\
rd %psr, %g3; \
srl %g3, 5, %g3; \
sll %g3, 5, %g3; /* psr hi */ \
\
mov %g1, %g2; \
add %g2, 0x50, %g2; \
\
restore_cpu_window_##type: \
mov %g3, %g7; \
or %g7, %g4, %g7; \
wr %g7, %psr; \
\
ld [%g2], %l0; \
ld [%g2 + 0x4], %l1; \
ld [%g2 + 0x8], %l2; \
ld [%g2 + 0xc], %l3; \
ld [%g2 + 0x10], %l4; \
ld [%g2 + 0x14], %l5; \
ld [%g2 + 0x18], %l6; \
ld [%g2 + 0x1c], %l7; \
ld [%g2 + 0x20], %i0; \
ld [%g2 + 0x24], %i1; \
ld [%g2 + 0x28], %i2; \
ld [%g2 + 0x2c], %i3; \
ld [%g2 + 0x30], %i4; \
ld [%g2 + 0x34], %i5; \
ld [%g2 + 0x38], %i6; \
ld [%g2 + 0x3c], %i7; \
dec %g4; \
and %g4, %g5, %g4; \
subcc %g6, 1, %g6; \
bne restore_cpu_window_##type; \
add %g2, 0x40, %g2; \
\
/* Get back to the correct window */ \
ld [%g1], %g2; \
wr %g2, %psr; \
\
ld [%g1 + 0x30], %o0; \
ld [%g1 + 0x34], %o1; \
ld [%g1 + 0x38], %o2; \
ld [%g1 + 0x3c], %o3; \
ld [%g1 + 0x40], %o4; \
ld [%g1 + 0x44], %o5; \
ld [%g1 + 0x48], %o6; \
ld [%g1 + 0x4c], %o7;
#define RESTORE_CPU_STATE(type) \
RESTORE_CPU_GENERAL_STATE(type); \
RESTORE_CPU_WINDOW_STATE(type);