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;
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
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}
u8 coreId
Definition IntelACPI.h:1
Result
Enumeration of generic kernel API result codes.
Definition API.h:69
@ Success
Definition API.h:70
@ Read
Definition API.h:98
@ Write
Definition API.h:99
static T * create()
Abstract function to create an instance of T.
Result
Result codes.
Definition CoreManager.h:46
Represents a single Core in a Central Processing Unit (CPU).
Definition CoreServer.h:51
virtual Result initialize()
Initialize the server.
CoreManager * m_cores
Definition CoreServer.h:240
Implements a CoreServer for ARM/Allwinner (sunxi) based System-on-Chips.
virtual Core::Result sendIPI(uint coreId)
Send Inter-Processor-Interrupt.
virtual void waitIPI() const
Wait for Inter-Processor-Interrupt.
SunxiCoreServer()
Class constructor function.
virtual Core::Result discoverCores()
Discover processor cores.
virtual Core::Result bootCore(uint coreId, CoreInfo *info)
Boot a processor core.
virtual Result initialize()
Initialize the server.
static const Address SecondaryCoreInfoOffset
Offset of the CoreInfo struct relative to the kernel's physical base address.
static const Size SoftwareInterruptNumber
Software Generated Interrupt number for sending/receiving between cores.
SunxiCpuConfig m_cpuConfig
CPU Configuration Module instance.
static const Address SecondaryCoreInfoAddress
Physical memory address for CoreInfo passed to secondary cores during bootup.
virtual Result discover()
Discover processors.
virtual Result initialize()
Perform initialization.
virtual Result boot(CoreInfo *info)
Boot a processor.
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
#define SELF
Definition ProcessID.h:35
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
@ WatchIRQ
Definition ProcessCtl.h:43
@ EnterSleep
Definition ProcessCtl.h:51
@ SendIRQ
Definition ProcessCtl.h:46
@ EnableIRQ
Definition ProcessCtl.h:44
unsigned long Address
A memory address.
Definition Types.h:131
#define ERROR(msg)
Output an error message.
Definition Log.h:61
unsigned int uint
Unsigned integer number.
Definition Types.h:44
Result
Result code for Actions.
Definition Core.h:48
@ IOError
Definition Core.h:55
@ Success
Definition Core.h:49
@ BootError
Definition Core.h:52
Per-Core information structure.
Definition CoreInfo.h:61
Memory::Range memory
Defines the physical memory available to the core.
Definition CoreInfo.h:69
uint booted
Set to non-zero by early boot code when this core is running.
Definition CoreInfo.h:63
Address phys
Physical address.
Definition Memory.h:58
System information structure.
Definition SystemInfo.h:80
uint coreId
Core Identifier.
Definition SystemInfo.h:105