FreeNOS
SunxiCoreServer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 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/User.h>
19 #include <FreeNOS/API.h>
20 #include <Log.h>
21 #include <Factory.h>
22 #include "SunxiCoreServer.h"
23 
25 {
26  return new SunxiCoreServer();
27 }
28 
30  : CoreServer()
31  , m_cpuConfig()
32 {
34 }
35 
37 {
38  SunxiCpuConfig::Result cpuResult;
39  SystemInformation info;
40 
42  if (r != API::Success)
43  {
44  ERROR("failed to register SGI vector: "
45  "ProcessCtl(WatchIRQ) returned: " << (uint)r);
46  return IOError;
47  }
48 
49  cpuResult = m_cpuConfig.initialize();
50  if (cpuResult != SunxiCpuConfig::Success)
51  {
52  ERROR("failed to initialize CPU configuration module: " <<
53  (uint) cpuResult);
54  return IOError;
55  }
56 
57  // When running as a secondary core, flag ourselves as booted
58  if (info.coreId != 0)
59  {
60  CoreInfo tmpInfo;
61  VMCopy(SELF, API::Read, (Address) &tmpInfo, SecondaryCoreInfoAddress, sizeof(tmpInfo));
62  tmpInfo.booted = 1;
63  VMCopy(SELF, API::Write, (Address) &tmpInfo, SecondaryCoreInfoAddress, sizeof(tmpInfo));
64  }
65 
66  return CoreServer::initialize();
67 }
68 
70 {
71  // Calculate the memory location of the CoreInfo structure passed to the
72  // secondary core. Note that the location is relative to the info->memory.phys address
73  const Address secondaryCoreInfoRelAddr = info->memory.phys + SecondaryCoreInfoOffset;
74 
75  // Copy the CoreInfo structure as input for the secondary core.
76  // The first copy is used when setting up the early-MMU and the
77  // second copy is passed as input to the kernel.
78  VMCopy(SELF, API::Write, (Address) info, SecondaryCoreInfoAddress, sizeof(*info));
79  VMCopy(SELF, API::Write, (Address) info, secondaryCoreInfoRelAddr, sizeof(*info));
80 
81  // Reset the secondary core
83  {
84  ERROR("failed to boot coreId" << coreId);
85  return Core::BootError;
86  }
87 
88  // Wait until the core raises the 'booted' flag in CoreInfo
89  while (1)
90  {
91  CoreInfo check;
92 
93  VMCopy(SELF, API::Read, (Address) &check, secondaryCoreInfoRelAddr, sizeof(check));
94 
95  if (check.booted)
96  break;
97  }
98 
99  return Core::Success;
100 }
101 
103 {
105  {
106  ERROR("failed to discover cores");
107  return Core::IOError;
108  }
109 
110  return Core::Success;
111 }
112 
114 {
115  // Wait for IPI which will wake us
117  ProcessCtl(SELF, EnterSleep, 0, 0);
118 }
119 
121 {
123  if (r != API::Success)
124  {
125  ERROR("failed to send IPI to core" << coreId << ": " << (uint)r);
126  return Core::IOError;
127  }
128 
129  return Core::Success;
130 }
API::Result
Result
Enumeration of generic kernel API result codes.
Definition: API.h:68
Core::IOError
@ IOError
Definition: Core.h:55
EnableIRQ
@ EnableIRQ
Definition: ProcessCtl.h:44
Core::BootError
@ BootError
Definition: Core.h:52
WatchIRQ
@ WatchIRQ
Definition: ProcessCtl.h:43
SendIRQ
@ SendIRQ
Definition: ProcessCtl.h:46
CoreServer::initialize
virtual Result initialize()
Initialize the server.
Definition: CoreServer.cpp:260
API::Write
@ Write
Definition: API.h:99
SunxiCoreServer::waitIPI
virtual void waitIPI() const
Wait for Inter-Processor-Interrupt.
Definition: SunxiCoreServer.cpp:113
Address
unsigned long Address
A memory address.
Definition: Types.h:131
CoreInfo::memory
Memory::Range memory
Defines the physical memory available to the core.
Definition: CoreInfo.h:69
SunxiCoreServer.h
SunxiCpuConfig::initialize
virtual Result initialize()
Perform initialization.
Definition: SunxiCpuConfig.cpp:21
SunxiCpuConfig::boot
virtual Result boot(CoreInfo *info)
Boot a processor.
Definition: SunxiCpuConfig.cpp:52
SystemInformation::coreId
uint coreId
Core Identifier.
Definition: SystemInfo.h:105
ProcessCtl
API::Result ProcessCtl(const ProcessID proc, const ProcessOperation op, const Address addr=0, const Address output=0)
Prototype for user applications.
Definition: ProcessCtl.h:93
SunxiCoreServer
Implements a CoreServer for ARM/Allwinner (sunxi) based System-on-Chips.
Definition: SunxiCoreServer.h:35
SunxiCoreServer::initialize
virtual Result initialize()
Initialize the server.
Definition: SunxiCoreServer.cpp:36
Log.h
uint
unsigned int uint
Unsigned integer number.
Definition: Types.h:44
API::Read
@ Read
Definition: API.h:98
SELF
#define SELF
Definition: ProcessID.h:35
CoreServer
Represents a single Core in a Central Processing Unit (CPU).
Definition: CoreServer.h:49
SunxiCoreServer::SunxiCoreServer
SunxiCoreServer()
Class constructor function.
Definition: SunxiCoreServer.cpp:29
ChannelServer< CoreServer, CoreMessage >::Result
Result
Result codes.
Definition: ChannelServer.h:99
Memory::Range::phys
Address phys
Physical address.
Definition: Memory.h:58
ChannelServer< CoreServer, CoreMessage >::IOError
@ IOError
Definition: ChannelServer.h:104
SunxiCoreServer::SecondaryCoreInfoAddress
static const Address SecondaryCoreInfoAddress
Physical memory address for CoreInfo passed to secondary cores during bootup.
Definition: SunxiCoreServer.h:43
SunxiCoreServer::SecondaryCoreInfoOffset
static const Address SecondaryCoreInfoOffset
Offset of the CoreInfo struct relative to the kernel's physical base address.
Definition: SunxiCoreServer.h:40
CoreServer::m_cores
CoreManager * m_cores
Definition: CoreServer.h:240
AbstractFactory::create
static T * create()
Abstract function to create an instance of T.
EnterSleep
@ EnterSleep
Definition: ProcessCtl.h:51
SunxiCoreServer::discoverCores
virtual Core::Result discoverCores()
Discover processor cores.
Definition: SunxiCoreServer.cpp:102
CoreInfo
Per-Core information structure.
Definition: CoreInfo.h:60
Core::Result
Result
Result code for Actions.
Definition: Core.h:47
SunxiCoreServer::m_cpuConfig
SunxiCpuConfig m_cpuConfig
CPU Configuration Module instance.
Definition: SunxiCoreServer.h:98
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
SystemInformation
System information structure.
Definition: SystemInfo.h:79
CoreManager::Success
@ Success
Definition: CoreManager.h:47
API::Success
@ Success
Definition: API.h:70
SunxiCoreServer::SoftwareInterruptNumber
static const Size SoftwareInterruptNumber
Software Generated Interrupt number for sending/receiving between cores.
Definition: SunxiCoreServer.h:48
Core::Success
@ Success
Definition: Core.h:49
SunxiCoreServer::bootCore
virtual Core::Result bootCore(uint coreId, CoreInfo *info)
Boot a processor core.
Definition: SunxiCoreServer.cpp:69
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
SunxiCpuConfig::discover
virtual Result discover()
Discover processors.
Definition: SunxiCpuConfig.cpp:44
Factory.h
coreId
u8 coreId
Definition: IntelACPI.h:64
CoreManager::Result
Result
Result codes.
Definition: CoreManager.h:45
SunxiCoreServer::sendIPI
virtual Core::Result sendIPI(uint coreId)
Send Inter-Processor-Interrupt.
Definition: SunxiCoreServer.cpp:120