summaryrefslogtreecommitdiff
path: root/Kernel/Arch/x86
diff options
context:
space:
mode:
authorHendiadyoin1 <leon2002.la@gmail.com>2021-07-01 14:51:41 +0200
committerAndreas Kling <kling@serenityos.org>2021-07-01 17:32:34 +0200
commit5f6c51361045f26812eba26d8531a8e079d63807 (patch)
tree8188e83c709fda56f21b3348d558ffc52e273d29 /Kernel/Arch/x86
parent6b9cf8376e17d46207637b16decc499ca75b83de (diff)
downloadserenity-5f6c51361045f26812eba26d8531a8e079d63807.zip
Kernel: Add support for 64-bit unaligned Mem-ops
Also let the compiler enforce the size and type restrictions
Diffstat (limited to 'Kernel/Arch/x86')
-rw-r--r--Kernel/Arch/x86/CPU.h45
1 files changed, 29 insertions, 16 deletions
diff --git a/Kernel/Arch/x86/CPU.h b/Kernel/Arch/x86/CPU.h
index 298ed8d12a..6753fc89b1 100644
--- a/Kernel/Arch/x86/CPU.h
+++ b/Kernel/Arch/x86/CPU.h
@@ -7,6 +7,7 @@
#pragma once
#include <AK/Atomic.h>
+#include <AK/Concepts.h>
#include <AK/Vector.h>
#include <Kernel/Arch/x86/DescriptorTable.h>
@@ -29,45 +30,57 @@ inline u32 get_iopl_from_eflags(u32 eflags)
return (eflags & iopl_mask) >> 12;
}
-template<typename T>
-void read_possibly_unaligned_data(u8* where, T& data)
+template<Integral T>
+void read_possibly_unaligned_data(u8* where, T& data) requires(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2)
{
- // FIXME: Implement 64 bit unaligned data access
- VERIFY(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2);
- if (((FlatPtr)where % sizeof(T)) == 0) {
+ if (((FlatPtr)where % alignof(T)) == 0) {
data = *(T*)where;
return;
}
- if (sizeof(T) == 2) {
- data = *(u8*)where | ((u16)(*(where + 1)) << 8);
+ if constexpr (sizeof(T) == 2) {
+ data = *where | ((u16)(*(where + 1)) << 8);
return;
}
- if (sizeof(T) == 4) {
- data = *(u8*)where | (((u32) * (where + 1)) << 8) | (((u32) * (where + 2)) << 16) | (((u32) * (u8*)(where + 3)) << 24);
+ if constexpr (sizeof(T) == 4) {
+ data = *where | (((u32) * (where + 1)) << 8) | (((u32) * (where + 2)) << 16) | (((u32) * (where + 3)) << 24);
+ return;
+ }
+ if constexpr (sizeof(T) == 8) {
+ data = *where | (((u32) * (where + 1)) << 8) | (((u64) * (where + 2)) << 16) | (((u64) * (where + 3)) << 24)
+ | (((u64) * (where + 4)) << 32) | (((u64) * (where + 5)) << 40) | (((u64) * (where + 6)) << 48) | (((u64) * (where + 7)) << 56);
return;
}
VERIFY_NOT_REACHED();
}
-template<typename T>
-void write_possibly_unaligned_data(u8* where, T data)
+template<Integral T>
+void write_possibly_unaligned_data(u8* where, T data) requires(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2)
{
- // FIXME: Implement 64 bit unaligned data access
- VERIFY(sizeof(T) == 8 || sizeof(T) == 4 || sizeof(T) == 2);
- if (((FlatPtr)where % sizeof(T)) == 0) {
+ if (((FlatPtr)where % alignof(T)) == 0) {
*(T*)where = data;
return;
}
- if (sizeof(T) == 2) {
+ if constexpr (sizeof(T) == 2) {
+ where[0] = (u8)(data & 0xFF);
+ where[1] = (u8)((data >> 8) & 0xFF);
+ return;
+ }
+ if constexpr (sizeof(T) == 4) {
where[0] = (u8)(data & 0xFF);
where[1] = (u8)((data >> 8) & 0xFF);
+ where[2] = (u8)((data >> 16) & 0xFF);
+ where[3] = (u8)((data >> 24) & 0xFF);
return;
}
- if (sizeof(T) == 4) {
+ if constexpr (sizeof(T) == 8) {
where[0] = (u8)(data & 0xFF);
where[1] = (u8)((data >> 8) & 0xFF);
where[2] = (u8)((data >> 16) & 0xFF);
where[3] = (u8)((data >> 24) & 0xFF);
+ where[5] = (u8)(data >> 32 & 0xFF);
+ where[5] = (u8)((data >> 40) & 0xFF);
+ where[6] = (u8)((data >> 48) & 0xFF);
+ where[7] = (u8)((data >> 52) & 0xFF);
return;
}
VERIFY_NOT_REACHED();