160 lines
4.8 KiB
C
160 lines
4.8 KiB
C
/*
|
|
* 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);
|