1 INTERFACE [arm && exynos]:
5 #include "mem_layout.h"
6 #include "mmio_register_block.h"
8 EXTENSION class Platform_control
12 class Pmu : public Mmio_register_block
15 explicit Pmu(Address virt) : Mmio_register_block(virt) {}
23 ARM_COMMON_OPTION = 0x2408,
26 static Mword core_pwr_reg(Cpu_phys_id cpu, unsigned func)
27 { return 0x2000 + Core_offset * cxx::int_value<Cpu_phys_id>(cpu) + func; }
29 Mword read(unsigned reg) const
30 { return Mmio_register_block::read<Mword>(reg); }
32 void write(Mword val, unsigned reg) const
33 { Mmio_register_block::write(val, reg); }
35 Mword core_read(Cpu_phys_id cpu, unsigned reg) const
36 { return Mmio_register_block::read<Mword>(core_pwr_reg(cpu, reg)); }
38 void core_write(Mword val, Cpu_phys_id cpu, unsigned reg) const
39 { Mmio_register_block::write(val, core_pwr_reg(cpu, reg)); }
44 Aftr, Lpa, Dstop, Sleep,
51 Pmu_core_local_power_enable = 3,
54 static Static_object<Pmu> pmu;
58 //--------------------------------------------------------------------------
59 IMPLEMENTATION [arm && exynos && !mp]:
63 Platform_control::power_up_core(Cpu_phys_id)
65 return -L4_err::ENodev;
68 //--------------------------------------------------------------------------
69 IMPLEMENTATION [arm && exynos]:
71 Static_object<Platform_control::Pmu> Platform_control::pmu;
75 Platform_control::init(Cpu_number cpu)
77 if (cpu == Cpu_number::boot_cpu())
79 assert (!pmu->get_mmio_base());
80 pmu.construct(Kmem::mmio_remap(Mem_layout::Pmu_phys_base));
82 for (Cpu_phys_id i = Cpu_phys_id(0);
85 pmu->core_write((pmu->core_read(i, Pmu::Option) & ~(1 << 0)) | (1 << 1), i, Pmu::Option);
87 pmu->write(2, Pmu::ARM_COMMON_OPTION);
91 //--------------------------------------------------------------------------
92 IMPLEMENTATION [arm && exynos && mp]:
95 #include "outer_cache.h"
97 #include "poll_timeout_kclock.h"
102 Platform_control::power_up_core(Cpu_phys_id cpu)
104 // CPU already powered up?
105 if ((pmu->core_read(cpu, Pmu::Status) & Pmu_core_local_power_enable) != 0)
108 pmu->core_write(Pmu_core_local_power_enable, cpu, Pmu::Config);
110 Lock_guard<Cpu_lock, Lock_guard_inverse_policy> cpu_lock_guard(&cpu_lock);
112 Poll_timeout_kclock pt(10000);
113 while (pt.test((pmu->core_read(cpu, Pmu::Status)
114 & Pmu_core_local_power_enable)
115 != Pmu_core_local_power_enable))
118 return pt.timed_out() ? -L4_err::ENodev : 0;
123 Platform_control::set_one_vector(Mword addr_p, Mword vector)
125 Mword addr_v = Kmem::mmio_remap(addr_p);
126 Io::write<Mword>(vector, addr_v);
127 Mem_unit::flush_dcache((void *)addr_v, (void *)(addr_v + sizeof(void *)));
128 Outer_cache::flush(addr_p);
133 Platform_control::setup_cpu_start_vector(Cpu_phys_id cpu, Mword phys_reset_vector)
135 unsigned long b = Mem_layout::Sysram_phys_base;
137 if (Platform::running_ns())
138 b += Platform::is_4210() ? 0x1f01c : 0x2f01c;
139 else if (Platform::is_4210() && Platform::subrev() == 0x11)
140 b = Mem_layout::Pmu_phys_base + 0x814;
141 else if (Platform::is_4210() && Platform::subrev() == 0)
144 if (Platform::is_4412())
145 b += cxx::int_value<Cpu_phys_id>(cpu) * 4;
147 set_one_vector(b, phys_reset_vector);
153 Platform_control::boot_ap_cpus(Address phys_reset_vector)
155 assert(current_cpu() == Cpu_number::boot_cpu());
157 if (Platform::is_4412())
159 for (Cpu_phys_id i = Cpu_phys_id(1);
160 i < Cpu_phys_id(4) && i < Cpu_phys_id(Config::Max_num_cpus);
163 setup_cpu_start_vector(i, phys_reset_vector);
165 if (Platform::running_ns())
166 Exynos_smc::cpuboot(phys_reset_vector,
167 cxx::int_value<Cpu_phys_id>(i));
168 Ipi::send(Ipi::Global_request, Cpu_number::boot_cpu(), i);
174 Mem_unit::flush_dcache();
176 Cpu_phys_id const second = Cpu_phys_id(1);
177 setup_cpu_start_vector(second, phys_reset_vector);
178 power_up_core(second);
180 if (Platform::is_5250() && Platform::running_ns())
181 Exynos_smc::cpuboot(phys_reset_vector, 1);
183 Ipi::send(Ipi::Global_request, Cpu_number::boot_cpu(), second);