You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
| #include "core.h"
 | |
| 
 | |
| #include "apic.h"
 | |
| #include "lapic.h"
 | |
| 
 | |
| /*! \brief Initial size of CPU core stacks
 | |
|  *
 | |
|  * Used during startup in `boot/startup.asm`
 | |
|  */
 | |
| extern "C" const unsigned long CPU_CORE_STACK_SIZE = 4096;
 | |
| 
 | |
| /*! \brief Reserved memory for CPU core stacks
 | |
|  */
 | |
| alignas(
 | |
|     16) static unsigned char cpu_core_stack[Core::MAX * CPU_CORE_STACK_SIZE];
 | |
| 
 | |
| /*! \brief Pointer to stack memory
 | |
|  *
 | |
|  * Incremented during startup of each core (bootstrap and application
 | |
|  * processors) in `boot/startup.asm`
 | |
|  */
 | |
| unsigned char* cpu_core_stack_pointer = cpu_core_stack;
 | |
| 
 | |
| namespace Core {
 | |
| 
 | |
| static unsigned cores = 0;  ///< Number of available CPU cores
 | |
| static volatile unsigned
 | |
|     core_id[255];  ///< Lookup table for CPU core IDs with LAPIC ID as index
 | |
| 
 | |
| static unsigned online_cores = 0;    ///< Number of currently online CPU cores
 | |
| static bool online_core[Core::MAX];  ///< Lookup table for online CPU cores with
 | |
|                                      ///< CPU core ID as index
 | |
| 
 | |
| void init() {
 | |
|   // Increment number of online CPU cores
 | |
|   if (__atomic_fetch_add(&online_cores, 1, __ATOMIC_RELAXED) == 0) {
 | |
|     // Fill Lookup table
 | |
|     for (unsigned i = 0; i < Core::MAX; i++) {
 | |
|       uint8_t lapic_id = APIC::getLAPICID(i);
 | |
|       if (lapic_id < APIC::INVALID_ID) {  // ignore invalid LAPICs
 | |
|         core_id[lapic_id] = i;
 | |
|         cores++;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Get CPU ID
 | |
|   uint8_t cpu = getID();
 | |
| 
 | |
|   // initialize local APIC with logical APIC ID
 | |
|   LAPIC::init(APIC::getLogicalAPICID(cpu));
 | |
| 
 | |
|   // set current CPU online
 | |
|   online_core[cpu] = true;
 | |
| }
 | |
| 
 | |
| void exit() {
 | |
|   // CPU core offline
 | |
|   online_core[getID()] = false;
 | |
|   __atomic_fetch_sub(&online_cores, 1, __ATOMIC_RELAXED);
 | |
| }
 | |
| 
 | |
| unsigned getID() { return core_id[LAPIC::getID()]; }
 | |
| 
 | |
| unsigned count() { return cores; }
 | |
| 
 | |
| unsigned countOnline() { return online_cores; }
 | |
| 
 | |
| bool isOnline(uint8_t core_id) {
 | |
|   return core_id > Core::MAX ? false : online_core[core_id];
 | |
| }
 | |
| 
 | |
| }  // namespace Core
 |