//----------------------------------------------------------------------------// // OS on Kaleid // // // // Desc: Inline assembly functions // // // // // // Copyright © 2018-2020 The OS/K Team // // // // This file is part of OS/K. // // // // OS/K is free software: you can redistribute it and/or modify // // it under the terms of the GNU General Public License as published by // // the Free Software Foundation, either version 3 of the License, or // // any later version. // // // // OS/K is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY//without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU General Public License for more details. // // // // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// #ifndef _LIBC_H #include #endif #ifndef _ASM_H #define _ASM_H //------------------------------------------// // IRQ-related stuff // //------------------------------------------// // // Launch interrupt // #define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") // // Returns whether IRQs are enabled // static inline bool KeCheckIRQStatus(void) { ulong flags; asm volatile ("pushf\n\tpop %0" : "=g"(flags) ); return flags & (1 << 9); } // // Disables IRQs // #define KeDisableIRQs() asm volatile ("cli") // // Enables IRQs // #define KeEnableIRQs() asm volatile ("sti") // // Disables IRQs, but saves its previous state // static inline ulong KePauseIRQs(void) { ulong flags; asm volatile ("pushf\n\tcli\n\tpop %0" : "=r"(flags) : : "memory"); return flags; } extern void KeSendEOItoPIC(uchar isr); extern void KeEnableNMI(void); extern void KeDisableNMI(void); // // Restore IRQ flag to its state before KePauseIRQs // #define KeRestoreIRQs(flags) asm("push %0\n\tpopf" : : "rm"(flags) : "memory","cc") //------------------------------------------// // 101 ways to hang the system // //------------------------------------------// // // Just relaxes the CPU a few cycles // #define KeRelaxCPU() asm volatile("pause\n": : : "memory") // // Pauses CPU until next interuption // #define KePauseCPU() asm volatile ("sti\n\thlt") // // Halts the CPU indefinitely // #define KeHaltCPU() do { asm volatile ("hlt"); } while (1) // // Halts the system, making sure it won't recover // #define KeCrashSystem() do { KeDisableIRQs(); KeHaltCPU(); } while (1) //------------------------------------------// // Ports I/O // //------------------------------------------// static inline void IoWriteByteOnPort(ushort port, uchar val) { asm volatile ("outb %1, %0" : : "dN" (port), "a" (val)); } static inline void IoWriteWordOnPort(ushort port, ushort val) { asm volatile ("outw %1, %0" : : "dN" (port), "a" (val)); } static inline void IoWriteDWordOnPort(ushort port, uint val) { asm volatile ("outl %1, %0" : : "dN" (port), "a" (val)); } static inline uchar IoReadByteFromPort(ushort port) { uchar ret; asm volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } static inline ushort IoReadWordFromPort(ushort port) { ushort ret; asm volatile ("inw %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } static inline ushort IoReadDWordFromPort(ushort port) { uint ret; asm volatile ("inl %1, %0" : "=a"(ret) : "Nd"(port)); return ret; } static inline ulong KeReadStsc(void) { int eax, edx; asm volatile ("rdtsc":"=a"(eax),"=d"(edx)); return ((ulong)edx << 32) + eax; } static inline void KeFlushTlbSingle(ulong addr) { asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); } //------------------------------------------// // Misc. I/O // //------------------------------------------// // // Wait for completion of some I/O operation // Port 0x80 is used for 'checkpoints' during POST // #define IoWaitCompletion() IoWriteByteOnPort(0x80, 0) #endif