FreeNOS
IntelMP.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FreeNOS/System.h>
19 #include <Log.h>
20 #include "IntelConstant.h"
21 #include "IntelMP.h"
22 #include "IntelBoot.h"
23 
25  : CoreManager()
26  , m_apic(apic)
27 {
28 }
29 
31 {
32  SystemInformation info;
33 
37 
38  return Success;
39 }
40 
42 {
43  MPFloat *mpf;
44 
45  // Look for the Multiprocessor configuration
46  for (uint i = 0; i < MPAreaSize - sizeof(Address); i += sizeof(Address))
47  {
48  mpf = (MPFloat *)(addr + i);
49 
50  if (mpf->signature == MPFloatSignature)
51  return (MPConfig *) (mpf->configAddr - MPAreaAddr + addr);
52  }
53  return ZERO;
54 }
55 
57 {
58  MPConfig *mpc = 0;
59  MPEntry *entry;
60 
61  // Clear previous discoveries
62  m_cores.clear();
63 
64  // Try to find MPTable in the BIOS memory.
65  mpc = scanMemory(m_bios.getBase());
66 
67  // Retry in the last 1MB of physical memory if not found.
68  if (!mpc)
69  {
71  if (!mpc)
72  {
73  ERROR("MP header not found");
74  return NotFound;
75  }
76  }
77 
78  // Found config
79  DEBUG("MP header found at " << (void *) mpc);
80  DEBUG("Local APIC at " << (void *) mpc->apicAddr);
81  entry = (MPEntry *)(mpc + 1);
82 
83  // Search for multiprocessor entries
84  for (uint i = 0; i < mpc->count; i++)
86 
87  return Success;
88 }
89 
91 {
92  DEBUG("booting core" << info->coreId << " at " <<
93  (void *) info->memory.phys << " with kernel: " << info->kernelCommand);
94 
95  // Copy 16-bit realmode startup code
97 
98  // Copy the CoreInfo structure
99  VMCopy(SELF, API::Write, (Address) info, MPInfoAddr, sizeof(*info));
100 
101  // Send inter-processor-interrupt to wakeup the processor
103  {
104  ERROR("failed to send startup IPI via APIC");
105  return IOError;
106  }
107 
108  // Wait until the core raises the 'booted' flag in CoreInfo
109  while (1)
110  {
111  CoreInfo check;
112 
113  VMCopy(SELF, API::Read, (Address) &check, MPInfoAddr, sizeof(check));
114 
115  if (check.booted)
116  break;
117  }
118  return Success;
119 }
120 
122 {
123  if (entry->type == MPEntryProc)
124  {
125  m_cores.append(entry->apicId);
126  return entry + 1;
127  }
128  else
129  return (MPEntry *) (((Address)(entry)) + 8);
130 }
IntelMP::IntelMP
IntelMP(IntelAPIC &apic)
Constructor.
Definition: IntelMP.cpp:24
CoreManager::NotFound
@ NotFound
Definition: CoreManager.h:49
CoreManager::m_cores
List< uint > m_cores
List of core ids found.
Definition: CoreManager.h:91
List::clear
virtual void clear()
Clears the entire List.
Definition: List.h:232
IntelMP::MPEntryAddr
static const Address MPEntryAddr
Physical memory address at which cores start (bootEntry16).
Definition: IntelMP.h:81
IntelMP::MPAreaSize
static const Size MPAreaSize
BIOS memory area size to search for MP tables.
Definition: IntelMP.h:90
IntelMP::discover
virtual Result discover()
Discover processors.
Definition: IntelMP.cpp:56
IO::map
Result map(Address phys, Size size=4096, Memory::Access access=Memory::Readable|Memory::Writable|Memory::User)
Map I/O address space.
Definition: IO.cpp:38
IntelMP::m_apic
IntelAPIC & m_apic
APIC instance.
Definition: IntelMP.h:196
PAGESIZE
#define PAGESIZE
ARM uses 4K pages.
Definition: ARMConstant.h:97
API::Write
@ Write
Definition: API.h:99
CoreManager
Generic Core Manager.
Definition: CoreManager.h:36
IntelConstant.h
IntelMP::MPFloat
Multiprocessor Floating Structure.
Definition: IntelMP.h:95
IntController::Success
@ Success
Definition: IntController.h:44
Address
unsigned long Address
A memory address.
Definition: Types.h:131
IntelMP::boot
virtual Result boot(CoreInfo *info)
Boot a processor.
Definition: IntelMP.cpp:90
CoreInfo::memory
Memory::Range memory
Defines the physical memory available to the core.
Definition: CoreInfo.h:69
IntelAPIC::IOBase
static const uint IOBase
APIC memory mapped I/O register base offset (physical address).
Definition: IntelAPIC.h:52
Log.h
uint
unsigned int uint
Unsigned integer number.
Definition: Types.h:44
IntelMP::MPFloat::configAddr
unsigned long configAddr
Definition: IntelMP.h:98
API::Read
@ Read
Definition: API.h:98
IntelMP::MPEntryProc
static const uint MPEntryProc
Multiprocessor Configuration Type ID for processors.
Definition: IntelMP.h:78
CoreInfo::coreId
uint coreId
Core identifier.
Definition: CoreInfo.h:66
MegaByte
#define MegaByte(v)
Convert megabytes to bytes.
Definition: Macros.h:57
SELF
#define SELF
Definition: ProcessID.h:35
IntelMP::MPFloatSignature
static const uint MPFloatSignature
Multiprocessor Floating Structure Signature.
Definition: IntelMP.h:75
IntelMP::MPFloat::signature
unsigned long signature
Definition: IntelMP.h:97
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
CoreInfo::kernelCommand
char kernelCommand[KERNEL_PATHLEN]
Kernel command.
Definition: CoreInfo.h:78
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
IntelMP::scanMemory
MPConfig * scanMemory(Address addr)
Scan memory for a Multiprocessor Config structure.
Definition: IntelMP.cpp:41
List::append
void append(T t)
Insert an item at the end of the list.
Definition: List.h:139
IntelMP::initialize
virtual Result initialize()
Perform initialization.
Definition: IntelMP.cpp:30
IntelMP::MPEntry
Multiprocessor Configuration Entry.
Definition: IntelMP.h:129
CoreInfo
Per-Core information structure.
Definition: CoreInfo.h:60
IntelMP.h
IntelBoot.h
IntelMP::MPInfoAddr
static const Address MPInfoAddr
Physical memory address for the CoreInfo structure.
Definition: IntelMP.h:84
CoreManager::IOError
@ IOError
Definition: CoreManager.h:48
bootEntry16
C void bootEntry16()
Entry point in 16-bit real mode.
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
entry
u32 entry[]
Definition: IntelACPI.h:64
SystemInformation
System information structure.
Definition: SystemInfo.h:79
CoreManager::Success
@ Success
Definition: CoreManager.h:47
SystemInformation::memorySize
Size memorySize
Total and available memory in bytes.
Definition: SystemInfo.h:102
IO::getBase
Address getBase() const
Get memory I/O base offset.
Definition: IO.cpp:28
IntelAPIC
Intel Advanced Programmable Interrupt Controller (APIC)
Definition: IntelAPIC.h:45
IntelMP::MPAreaAddr
static const Address MPAreaAddr
BIOS memory area to search for MP tables.
Definition: IntelMP.h:87
VMCopy
API::Result VMCopy(const ProcessID proc, const API::Operation how, const Address ours, const Address theirs, const Size sz)
Prototype for user applications.
Definition: VMCopy.h:42
IntelMP::m_bios
IntelIO m_bios
I/O instance for BIOS memory.
Definition: IntelMP.h:190
IntelAPIC::sendStartupIPI
IntController::Result sendStartupIPI(uint cpuId, Address addr)
Send startup Intercore-Processor-Interrupt.
Definition: IntelAPIC.cpp:195
ZERO
#define ZERO
Zero value.
Definition: Macros.h:43
IntelMP::MPConfig
Multiprocessor Configuration Structure.
Definition: IntelMP.h:110
IntelMP::parseEntry
MPEntry * parseEntry(MPEntry *entry)
Parse Multiprocessor Config entry.
Definition: IntelMP.cpp:121
IntelMP::m_lastMemory
IntelIO m_lastMemory
I/O instance for the last 1MB of physical memory.
Definition: IntelMP.h:193
CoreManager::Result
Result
Result codes.
Definition: CoreManager.h:45
IntelAPIC::getIO
IntelIO & getIO()
Get I/O object.
Definition: IntelAPIC.cpp:45