#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <linux/screen_info.h>
-#include <linux/of_iommu.h>
#include <linux/of_platform.h>
#include <linux/init.h>
#include <linux/kexec.h>
#ifdef MULTI_CPU
-struct processor processor __read_mostly;
+struct processor processor __ro_after_init;
#endif
#ifdef MULTI_TLB
-struct cpu_tlb_fns cpu_tlb __read_mostly;
+struct cpu_tlb_fns cpu_tlb __ro_after_init;
#endif
#ifdef MULTI_USER
-struct cpu_user_fns cpu_user __read_mostly;
+struct cpu_user_fns cpu_user __ro_after_init;
#endif
#ifdef MULTI_CACHE
-struct cpu_cache_fns cpu_cache __read_mostly;
+struct cpu_cache_fns cpu_cache __ro_after_init;
#endif
#ifdef CONFIG_OUTER_CACHE
-struct outer_cache_fns outer_cache __read_mostly;
+struct outer_cache_fns outer_cache __ro_after_init;
EXPORT_SYMBOL(outer_cache);
#endif
/* arch specifies the register format */
switch (arch) {
case CPU_ARCH_ARMv7:
- asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR"
- : /* No output operands */
- : "r" (1));
+ set_csselr(CSSELR_ICACHE | CSSELR_L1);
isb();
- asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR"
- : "=r" (id_reg));
+ id_reg = read_ccsidr();
line_size = 4 << ((id_reg & 0x7) + 2);
num_sets = ((id_reg >> 13) & 0x7fff) + 1;
aliasing_icache = (line_size * num_sets) > PAGE_SIZE;
{
unsigned int arch = cpu_architecture();
- if (arch == CPU_ARCH_ARMv7M) {
- cacheid = 0;
- } else if (arch >= CPU_ARCH_ARMv6) {
+ if (arch >= CPU_ARCH_ARMv6) {
unsigned int cachetype = read_cpuid_cachetype();
- if ((cachetype & (7 << 29)) == 4 << 29) {
+
+ if ((arch == CPU_ARCH_ARMv7M) && !cachetype) {
+ cacheid = 0;
+ } else if ((cachetype & (7 << 29)) == 4 << 29) {
/* ARMv7 register format */
arch = CPU_ARCH_ARMv7;
cacheid = CACHEID_VIPT_NONALIASING;
kernel_data.end = virt_to_phys(_end - 1);
for_each_memblock(memory, region) {
+ phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+ phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+ unsigned long boot_alias_start;
+
+ /*
+ * Some systems have a special memory alias which is only
+ * used for booting. We need to advertise this region to
+ * kexec-tools so they know where bootable RAM is located.
+ */
+ boot_alias_start = phys_to_idmap(start);
+ if (arm_has_idmap_alias() && boot_alias_start != IDMAP_INVALID_ADDR) {
+ res = memblock_virt_alloc(sizeof(*res), 0);
+ res->name = "System RAM (boot alias)";
+ res->start = boot_alias_start;
+ res->end = phys_to_idmap(end);
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ request_resource(&iomem_resource, res);
+ }
+
res = memblock_virt_alloc(sizeof(*res), 0);
res->name = "System RAM";
- res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
- res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+ res->start = start;
+ res->end = end;
res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
request_resource(&iomem_resource, res);
* machine from the device tree, if no callback is provided,
* otherwise we would always need an init_machine callback.
*/
- of_iommu_init();
if (machine_desc->init_machine)
machine_desc->init_machine();
-#ifdef CONFIG_OF
- else
- of_platform_populate(NULL, of_default_bus_match_table,
- NULL, NULL);
-#endif
+
return 0;
}
arch_initcall(customize_machine);
(unsigned long)(crash_base >> 20),
(unsigned long)(total_mem >> 20));
+ /* The crashk resource must always be located in normal mem */
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
insert_resource(&iomem_resource, &crashk_res);
+
+ if (arm_has_idmap_alias()) {
+ /*
+ * If we have a special RAM alias for use at boot, we
+ * need to advertise to kexec tools where the alias is.
+ */
+ static struct resource crashk_boot_res = {
+ .name = "Crash kernel (boot alias)",
+ .flags = IORESOURCE_BUSY | IORESOURCE_MEM,
+ };
+
+ crashk_boot_res.start = phys_to_idmap(crash_base);
+ crashk_boot_res.end = crashk_boot_res.start + crash_size - 1;
+ insert_resource(&iomem_resource, &crashk_boot_res);
+ }
}
#else
static inline void reserve_crashkernel(void) {}