mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 00:32:45 +00:00 
			
		
		
		
	 545ce5b595
			
		
	
	
		545ce5b595
		
	
	
	
	
		
			
			The platform independent Processor.h file includes the shared processor code and includes the specific platform header file. All references to the Arch/x86/Processor.h file have been replaced with a reference to Arch/Processor.h.
		
			
				
	
	
		
			107 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			107 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018-2021, James Mintram <me@jamesrm.com>
 | |
|  * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <AK/Function.h>
 | |
| #include <Kernel/Arch/x86/ASM_wrapper.h>
 | |
| 
 | |
| namespace Kernel {
 | |
| 
 | |
| namespace Memory {
 | |
| class PageDirectory;
 | |
| }
 | |
| 
 | |
| struct ProcessorMessageEntry;
 | |
| struct DeferredCallEntry;
 | |
| 
 | |
| enum class ProcessorSpecificDataID {
 | |
|     MemoryManager,
 | |
|     __Count,
 | |
| };
 | |
| struct ProcessorMessage {
 | |
|     using CallbackFunction = Function<void()>;
 | |
| 
 | |
|     enum Type {
 | |
|         FlushTlb,
 | |
|         Callback,
 | |
|     };
 | |
|     Type type;
 | |
|     Atomic<u32> refs;
 | |
|     union {
 | |
|         ProcessorMessage* next; // only valid while in the pool
 | |
|         alignas(CallbackFunction) u8 callback_storage[sizeof(CallbackFunction)];
 | |
|         struct {
 | |
|             Memory::PageDirectory const* page_directory;
 | |
|             u8* ptr;
 | |
|             size_t page_count;
 | |
|         } flush_tlb;
 | |
|     };
 | |
| 
 | |
|     volatile bool async;
 | |
| 
 | |
|     ProcessorMessageEntry* per_proc_entries;
 | |
| 
 | |
|     CallbackFunction& callback_value()
 | |
|     {
 | |
|         return *bit_cast<CallbackFunction*>(&callback_storage);
 | |
|     }
 | |
| 
 | |
|     void invoke_callback()
 | |
|     {
 | |
|         VERIFY(type == Type::Callback);
 | |
|         callback_value()();
 | |
|     }
 | |
| };
 | |
| 
 | |
| struct ProcessorMessageEntry {
 | |
|     ProcessorMessageEntry* next;
 | |
|     ProcessorMessage* msg;
 | |
| };
 | |
| 
 | |
| struct DeferredCallEntry {
 | |
|     using HandlerFunction = Function<void()>;
 | |
| 
 | |
|     DeferredCallEntry* next;
 | |
|     alignas(HandlerFunction) u8 handler_storage[sizeof(HandlerFunction)];
 | |
|     bool was_allocated;
 | |
| 
 | |
|     HandlerFunction& handler_value()
 | |
|     {
 | |
|         return *bit_cast<HandlerFunction*>(&handler_storage);
 | |
|     }
 | |
| 
 | |
|     void invoke_handler()
 | |
|     {
 | |
|         handler_value()();
 | |
|     }
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| #if ARCH(X86_64) || ARCH(I386)
 | |
| #    include <Kernel/Arch/x86/Processor.h>
 | |
| #elif ARCH(AARCH64)
 | |
| #    include <Kernel/Arch/aarch64/Processor.h>
 | |
| #else
 | |
| #    error "Unknown architecture"
 | |
| #endif
 | |
| 
 | |
| namespace Kernel {
 | |
| template<typename T>
 | |
| class ProcessorSpecific {
 | |
| public:
 | |
|     static void initialize()
 | |
|     {
 | |
|         Processor::current().set_specific(T::processor_specific_data_id(), new T);
 | |
|     }
 | |
|     static T& get()
 | |
|     {
 | |
|         return *Processor::current().get_specific<T>();
 | |
|     }
 | |
| };
 | |
| }
 |