diff options
Diffstat (limited to 'src/kernel/arch/amd64/regs.c')
-rw-r--r-- | src/kernel/arch/amd64/regs.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/kernel/arch/amd64/regs.c b/src/kernel/arch/amd64/regs.c new file mode 100644 index 0000000..bb4e5aa --- /dev/null +++ b/src/kernel/arch/amd64/regs.c @@ -0,0 +1,26 @@ +#include <kernel/arch/generic.h> +#include <kernel/panic.h> + +void +regs_safecopy(UserRegs *dst, const UserRegs *src) +{ + /* preserved flags: (see intel vol 1 3.4.3.) + * 1<<0 = CF, carry flag + * 1<<2 = PF, parity flag + * 1<<4 = AC, auxilary carry + * 1<<6 = ZF, zero flag + * 1<<7 = SF, sign flag + * 1<<11 = OF, overflow flag + * 1<<10 = DF, direction flag + */ + static_assert( + ((1<<0) | (1<<2) | (1<<4) | (1<<6) | (1<<7) | (1<<10) | (1<<11)) + == 0xCD5 + ); + + uint64_t newflags = (src->flags & 0xCD5) | (dst->flags & ~0xCD5); + /* I "spelled it out" directly instead of using memcpy hoping that gcc + * maybe would notice it can skip copying the last 8 bytes. It didn't :( */ + *dst = *src; + dst->flags = newflags; +} |