123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #pragma once
- #include <AK/Types.h>
- namespace Kernel {
- ALWAYS_INLINE void cli()
- {
- asm volatile("cli" ::
- : "memory");
- }
- ALWAYS_INLINE void sti()
- {
- asm volatile("sti" ::
- : "memory");
- }
- ALWAYS_INLINE FlatPtr cpu_flags()
- {
- FlatPtr flags;
- asm volatile(
- "pushf\n"
- "pop %0\n"
- : "=rm"(flags)::"memory");
- return flags;
- }
- #if ARCH(I386)
- ALWAYS_INLINE void set_fs(u16 segment)
- {
- asm volatile(
- "mov %%ax, %%fs" ::"a"(segment)
- : "memory");
- }
- ALWAYS_INLINE void set_gs(u16 segment)
- {
- asm volatile(
- "mov %%ax, %%gs" ::"a"(segment)
- : "memory");
- }
- ALWAYS_INLINE u16 get_fs()
- {
- u16 fs;
- asm("mov %%fs, %%eax"
- : "=a"(fs));
- return fs;
- }
- ALWAYS_INLINE u16 get_gs()
- {
- u16 gs;
- asm("mov %%gs, %%eax"
- : "=a"(gs));
- return gs;
- }
- #endif
- template<typename T>
- ALWAYS_INLINE T read_gs_value(FlatPtr offset)
- {
- T val;
- asm volatile(
- "mov %%gs:%a[off], %[val]"
- : [val] "=r"(val)
- : [off] "ir"(offset));
- return val;
- }
- template<typename T>
- ALWAYS_INLINE void write_gs_value(FlatPtr offset, T val)
- {
- asm volatile(
- "mov %[val], %%gs:%a[off]" ::[off] "ir"(offset), [val] "r"(val)
- : "memory");
- }
- ALWAYS_INLINE FlatPtr read_gs_ptr(FlatPtr offset)
- {
- FlatPtr val;
- asm volatile(
- "mov %%gs:%a[off], %[val]"
- : [val] "=r"(val)
- : [off] "ir"(offset));
- return val;
- }
- ALWAYS_INLINE void write_gs_ptr(u32 offset, FlatPtr val)
- {
- asm volatile(
- "mov %[val], %%gs:%a[off]" ::[off] "ir"(offset), [val] "r"(val)
- : "memory");
- }
- ALWAYS_INLINE bool are_interrupts_enabled()
- {
- return cpu_flags() & 0x200;
- }
- FlatPtr read_cr0();
- FlatPtr read_cr2();
- FlatPtr read_cr3();
- FlatPtr read_cr4();
- u64 read_xcr0();
- void write_cr0(FlatPtr);
- void write_cr3(FlatPtr);
- void write_cr4(FlatPtr);
- void write_xcr0(u64);
- void flush_idt();
- ALWAYS_INLINE void load_task_register(u16 selector)
- {
- asm("ltr %0" ::"r"(selector));
- }
- FlatPtr read_dr0();
- void write_dr0(FlatPtr);
- FlatPtr read_dr1();
- void write_dr1(FlatPtr);
- FlatPtr read_dr2();
- void write_dr2(FlatPtr);
- FlatPtr read_dr3();
- void write_dr3(FlatPtr);
- FlatPtr read_dr6();
- void write_dr6(FlatPtr);
- FlatPtr read_dr7();
- void write_dr7(FlatPtr);
- ALWAYS_INLINE static bool is_kernel_mode()
- {
- u16 cs;
- asm volatile(
- "mov %%cs, %[cs] \n"
- : [cs] "=g"(cs));
- return (cs & 3) == 0;
- }
- ALWAYS_INLINE void read_tsc(u32& lsw, u32& msw)
- {
- asm volatile("rdtsc"
- : "=d"(msw), "=a"(lsw));
- }
- ALWAYS_INLINE u64 read_tsc()
- {
- u32 lsw;
- u32 msw;
- read_tsc(lsw, msw);
- return ((u64)msw << 32) | lsw;
- }
- void stac();
- void clac();
- [[noreturn]] ALWAYS_INLINE void halt_this()
- {
- for (;;) {
- asm volatile("cli; hlt");
- }
- }
- }
|