Cpu(unsigned id) { set_id(id); }
+
+ struct Ids {
+ Mword _pfr[2], _dfr0, _afr0, _mmfr[4];
+ };
+ void id_init();
+
+ enum {
+ Copro_dbg_model_not_supported = 0,
+ Copro_dbg_model_v6 = 2,
+ Copro_dbg_model_v6_1 = 3,
+ Copro_dbg_model_v7 = 4,
+ };
+
+ unsigned copro_dbg_model() const { return _cpu_id._dfr0 & 0xf; }
+
private:
static Cpu *_boot_cpu;
unsigned _phys_id;
+ Ids _cpu_id;
};
+// ------------------------------------------------------------------------
INTERFACE [arm && armv5]:
EXTENSION class Cpu
Cp15_c1_cache_bits = Cp15_c1_cache
| Cp15_c1_insn_cache,
-
- Smp_enable = 0x20,
};
};
enum {
Cp15_c1_ee = 1 << 25,
Cp15_c1_nmfi = 1 << 27,
- Cp15_c1_tre = 1 << 28,
- Cp15_c1_afe = 1 << 29,
Cp15_c1_te = 1 << 30,
+ Cp15_c1_rao_sbop = (0xf << 3) | (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23),
Cp15_c1_cache_bits = Cp15_c1_cache
| Cp15_c1_insn_cache,
Cp15_c1_generic = Cp15_c1_mmu
| (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
| Cp15_c1_branch_predict
+ | Cp15_c1_rao_sbop
| Cp15_c1_high_vector,
};
};
Cp15_c1_ha = 1 << 17,
Cp15_c1_ee = 1 << 25,
Cp15_c1_nmfi = 1 << 27,
- Cp15_c1_tre = 1 << 28,
- Cp15_c1_afe = 1 << 29,
Cp15_c1_te = 1 << 30,
+ Cp15_c1_rao_sbop = (0xf << 3) | (1 << 16) | (1 << 18) | (1 << 22) | (1 << 23),
Cp15_c1_cache_bits = Cp15_c1_cache
| Cp15_c1_insn_cache,
| (Config::Cp15_c1_use_alignment_check ? Cp15_c1_alignment_check : 0)
| Cp15_c1_branch_predict
| Cp15_c1_high_vector
+ | Cp15_c1_rao_sbop
| (Config::Cp15_c1_use_a9_swp_enable ? Cp15_c1_sw : 0),
-
- Smp_enable = 0x41,
};
};
};
};
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv6]:
+
+PRIVATE static inline void
+Cpu::enable_smp()
+{
+ asm volatile ("mrc p15, 0, %0, c1, c0, 1 \n"
+ "orr %0, %1 \n"
+ "mcr p15, 0, %0, c1, c0, 1 \n"
+ : : "r" (0), "i" (0x20));
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv7]:
+
+PRIVATE static inline void
+Cpu::enable_smp()
+{
+ Mword midr;
+ asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (midr));
+
+ // ACTRL is implementation defined
+ if ((midr & 0xff0ffff0) != 0x410fc090)
+ return;
+
+ Mword actrl;
+ asm volatile ("mrc p15, 0, %0, c1, c0, 1" : "=r" (actrl));
+ if (!(actrl & 0x40))
+ asm volatile ("mcr p15, 0, %0, c1, c0, 1" : : "r" (actrl | 0x41));
+}
+
//---------------------------------------------------------------------------
IMPLEMENTATION [arm && (mpcore || armca9)]:
-PUBLIC static inline void
+PRIVATE static inline void
Cpu::early_init_platform()
{
- Io::write<Mword>(0xffffffff, Mem_layout::Mp_scu_map_base + 0xc);
- Io::write<Mword>(1, Mem_layout::Mp_scu_map_base + 0);
+ enum {
+ Scu_control = Mem_layout::Mp_scu_map_base + 0x0,
+ Scu_config = Mem_layout::Mp_scu_map_base + 0x4,
+ Scu_power_status = Mem_layout::Mp_scu_map_base + 0x8,
+ Scu_inv = Mem_layout::Mp_scu_map_base + 0xc,
+ };
+
+ Io::write<Mword>(0xffffffff, Scu_inv);
+ Io::write<Mword>(Io::read<Mword>(Scu_control) | 1, Scu_control);
Io::write<Mword>(Io::read<Mword>(Mem_layout::Gic_cpu_map_base + 0) | 1,
Mem_layout::Gic_cpu_map_base + 0);
Mem_unit::clean_dcache();
- Mword tmp = 0;
- __asm__ __volatile__("mrc p15, 0, %0, c1, c0, 1 \n"
- "orr %0, %1 \n"
- "mcr p15, 0, %0, c1, c0, 1 \n"
- : : "r" (tmp), "i" (Smp_enable));
+ enable_smp();
}
//---------------------------------------------------------------------------
IMPLEMENTATION [arm && !(mpcore || armca9)]:
-PUBLIC static inline void Cpu::early_init_platform()
+PRIVATE static inline void Cpu::early_init_platform()
{}
//---------------------------------------------------------------------------
early_init_platform();
Mem_unit::flush_cache();
-
- print_infos();
}
_phys_id = Proc::cpu_id();
init_tz();
+
+ id_init();
+
+ print_infos();
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && !armv6plus]:
+
+IMPLEMENT
+void
+Cpu::id_init()
+{
+}
+
+//---------------------------------------------------------------------------
+IMPLEMENTATION [arm && armv6plus]:
+
+IMPLEMENT
+void
+Cpu::id_init()
+{
+ __asm__("mrc p15, 0, %0, c0, c1, 0": "=r" (_cpu_id._pfr[0]));
+ __asm__("mrc p15, 0, %0, c0, c1, 1": "=r" (_cpu_id._pfr[1]));
+ __asm__("mrc p15, 0, %0, c0, c1, 2": "=r" (_cpu_id._dfr0));
+ __asm__("mrc p15, 0, %0, c0, c1, 3": "=r" (_cpu_id._afr0));
+ __asm__("mrc p15, 0, %0, c0, c1, 4": "=r" (_cpu_id._mmfr[0]));
+ __asm__("mrc p15, 0, %0, c0, c1, 5": "=r" (_cpu_id._mmfr[1]));
+ __asm__("mrc p15, 0, %0, c0, c1, 6": "=r" (_cpu_id._mmfr[2]));
+ __asm__("mrc p15, 0, %0, c0, c1, 7": "=r" (_cpu_id._mmfr[3]));
}
//---------------------------------------------------------------------------
// enable nonsecure access to vfp coprocessor
asm volatile("mov r0, #0xc00;"
- "mcr p15, 0, r0, c1, c1, 2;"
- : : : "r0"
- );
+ "mcr p15, 0, r0, c1, c1, 2;"
+ : : : "r0"
+ );
enable_irq_ovrr();
}
volatile register Mword r0 asm("r0") = (Mword)nonsecure_state;
extern char go_nonsecure;
- asm volatile( "stmdb sp!, {fp} \n"
- "stmdb sp!, {r0} \n"
- "mov r2, sp \n" // copy sp_svc to sp_mon
- "cps #0x16 \n" // switch to monitor mode
- "mov sp, r2 \n"
- "adr r3, 1f \n" // save return eip
- "mrs r4, cpsr \n" // save return psr
- "mov pc, r1 \n" // go nonsecure!
- "1: \n"
- "mov r0, sp \n" // copy sp_mon to sp_svc
- "cps #0x13 \n" // switch to svc mode
- "mov sp, r0 \n"
- "ldmia sp!, {r0} \n"
- "ldmia sp!, {fp} \n"
- : : "r" (r0), "r" (&go_nonsecure)
- : "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r12", "r14", "memory");
+ asm volatile("stmdb sp!, {fp} \n"
+ "stmdb sp!, {r0} \n"
+ "mov r2, sp \n" // copy sp_svc to sp_mon
+ "cps #0x16 \n" // switch to monitor mode
+ "mov sp, r2 \n"
+ "adr r3, 1f \n" // save return eip
+ "mrs r4, cpsr \n" // save return psr
+ "mov pc, r1 \n" // go nonsecure!
+ "1: \n"
+ "mov r0, sp \n" // copy sp_mon to sp_svc
+ "cps #0x13 \n" // switch to svc mode
+ "mov sp, r0 \n"
+ "ldmia sp!, {r0} \n"
+ "ldmia sp!, {fp} \n"
+ : : "r" (r0), "r" (&go_nonsecure)
+ : "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r12", "r14", "memory");
}
PUBLIC static inline
Cpu::enable_irq_ovrr()
{
// set IRQ/FIQ/Abort override bits
- asm volatile("mov r0, #0x1c0; \n"
- "mcr p15, 0, r0, c1, c1, 3; \n"
- : : : "r0");
+ asm volatile("mov r0, #0x1c0 \n"
+ "mcr p15, 0, r0, c1, c1, 3 \n"
+ : : : "r0");
}
IMPLEMENTATION [!tz || !armca9]:
Cpu::print_infos()
{}
+// ------------------------------------------------------------------------
+IMPLEMENTATION [debug && armv6plus]:
+
+PRIVATE
+void
+Cpu::id_print_infos()
+{
+ printf("ID_PFR0: %08lx\n", _cpu_id._pfr[0]);
+ printf("ID_PFR1: %08lx\n", _cpu_id._pfr[1]);
+ printf("ID_DFR0: %08lx\n", _cpu_id._dfr0);
+ printf("ID_AFR0: %08lx\n", _cpu_id._afr0);
+ printf("ID_MMFR0: %08lx\n", _cpu_id._mmfr[0]);
+ printf("ID_MMFR1: %08lx\n", _cpu_id._mmfr[1]);
+ printf("ID_MMFR2: %08lx\n", _cpu_id._mmfr[2]);
+ printf("ID_MMFR3: %08lx\n", _cpu_id._mmfr[3]);
+}
+
+// ------------------------------------------------------------------------
+IMPLEMENTATION [debug && !armv6plus]:
+
+PRIVATE
+void
+Cpu::id_print_infos()
+{
+}
+
// ------------------------------------------------------------------------
IMPLEMENTATION [debug]:
-PRIVATE static
+PRIVATE
void
Cpu::print_infos()
{
printf("Cache config: %s\n", Config::cache_enabled ? "ON" : "OFF");
+ id_print_infos();
}