The Pedigree Project  0.1
ppc32/Processor.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/processor/Processor.h"
21 #include "../ppc_common/PhysicalMemoryManager.h"
22 #include "HashedPageTable.h"
23 #include "InterruptManager.h"
24 #include "Translation.h"
25 #include "VirtualAddressSpace.h"
26 #include "pedigree/kernel/Log.h"
27 #include "pedigree/kernel/machine/openfirmware/Device.h"
28 #include "pedigree/kernel/machine/openfirmware/OpenFirmware.h"
29 #include "pedigree/kernel/panic.h"
30 #include "pedigree/kernel/process/initialiseMultitasking.h"
31 #include "pedigree/kernel/processor/PhysicalMemoryManager.h"
32 
33 static uint32_t detectMemory()
34 {
35  // Grab the memory node.
36  OFDevice memory(OpenFirmware::instance().findDevice("/memory"));
37 
38  // Ask it about its registers.
39  uint32_t registersLength = memory.getPropertyLength("reg");
40  if (registersLength == static_cast<uint32_t>(-1))
41  {
42  ERROR("getproplen failed for /memory:reg.");
43  return 0;
44  }
45  uint32_t registers[32];
46  if (memory.getProperty(
47  "reg", reinterpret_cast<OFParam>(registers),
48  32 * sizeof(uint32_t)) == -1)
49  {
50  ERROR("getprop failed for /memory:reg.");
51  return 0;
52  }
53 
54  // The current upper limit of RAM.
55  uint32_t currentMax = 0;
56 
57  // Registers are address:size pairs - how many did we get?
58  for (uint32_t i = 0; i < registersLength / (2 * sizeof(uint32_t)); i++)
59  {
60  uint32_t address = registers[i * 2];
61  uint32_t size = registers[i * 2 + 1];
62  if (address != currentMax && size > 0)
63  // This means we have a memory hole. We don't handle holes atm, so
64  // we have to signal it.
65  panic("Memory hole detected, and not handled");
66  currentMax += size;
67  }
68 
69  NOTICE(
70  "Detected " << Dec << (currentMax / 0x100000)
71  << "MB of installed RAM.");
72  return currentMax;
73 }
74 
76 {
77  // Initialise openfirmware.
78 
80  reinterpret_cast<OpenFirmware::OFInterface>(Info.prom));
81 
82  Translations translations;
83  uint32_t ramMax = detectMemory();
84 
85  // Remove some of the chaff we don't care about - that is
86  // anything mapped below KERNEL_SPACE_START that is not in the
87  // bottom 0x3000.
88  // translations.removeRange(0x3000, KERNEL_SPACE_START);
89  translations.removeRange(0xD0000000, 0xDE000000);
90 
93 
94  v.initialise(translations);
95 
96  HashedPageTable::instance().initialise(translations, ramMax);
97 
98  // Initialise this processor's interrupt handling
102 
103  // Initialise the virtual address space.
104  v.initialRoster(translations);
105 
106  // And the physical memory manager.
108  static_cast<PpcCommonPhysicalMemoryManager &>(
110  p.initialise(translations, ramMax);
111 
112  // m_Initialised = 1;
113 }
114 
116 {
117  // Floating point is available.
118  uint32_t msr;
119  asm volatile("mfmsr %0" : "=r"(msr));
120  msr |= MSR_FP;
121  asm volatile("mtmsr %0" ::"r"(msr));
122 
123  initialiseMultitasking();
124 
125  m_Initialised = 2;
126 }
127 
129 {
130 }
131 
133 {
135  reinterpret_cast<PPC32VirtualAddressSpace &>(AddressSpace);
136 
137  uint32_t vsid = static_cast<uint32_t>(s.m_Vsid) * 8;
138 
139  asm volatile("mtsr 0, %0" ::"r"(vsid + 0));
140  asm volatile("mtsr 1, %0" ::"r"(vsid + 1));
141  asm volatile("mtsr 2, %0" ::"r"(vsid + 2));
142  asm volatile("mtsr 3, %0" ::"r"(vsid + 3));
143  asm volatile("mtsr 4, %0" ::"r"(vsid + 4));
144  asm volatile("mtsr 5, %0" ::"r"(vsid + 5));
145  asm volatile("mtsr 6, %0" ::"r"(vsid + 6));
146  asm volatile("mtsr 7, %0" ::"r"(vsid + 7));
147  asm volatile("sync; isync");
148 
149  Processor::information().setVirtualAddressSpace(AddressSpace);
150 }
Bootstrap structure passed to the kernel entry point.
static HashedPageTable & instance()
void removeRange(uintptr_t start, uintptr_t end)
Definition: Translation.cc:122
static OpenFirmware & instance()
Definition: OpenFirmware.h:45
static void initialise2(const BootstrapStruct_t &Info) INITIALISATION_ONLY
second/last stage in the initialisation of the processor-specific interface
static EXPORTED_PUBLIC VirtualAddressSpace & getKernelAddressSpace()
static ProcessorInformation & information()
Definition: Processor.cc:45
static void switchAddressSpace(VirtualAddressSpace &AddressSpace)
static size_t m_Initialised
Definition: Processor.h:371
static void initialise1(const BootstrapStruct_t &Info) INITIALISATION_ONLY
first stage in the initialisation of the processor-specific interface
#define NOTICE(text)
Definition: Log.h:74
bool initialise(Translations &translations)
void initialise(OFInterface interface)
Definition: OpenFirmware.cc:35
Implementation of the PhysicalMemoryManager for common ppc.
static void identify(HugeStaticString &str)
#define ERROR(text)
Definition: Log.h:82
Definition: Log.h:138
void EXPORTED_PUBLIC panic(const char *msg) NORETURN
Definition: panic.cc:121
void initialise(Translations &translations, uint32_t ramMax)
void initialRoster(Translations &translations)