cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

setup.c (8604B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * arch/sh/kernel/setup.c
      4 *
      5 * This file handles the architecture-dependent parts of initialization
      6 *
      7 *  Copyright (C) 1999  Niibe Yutaka
      8 *  Copyright (C) 2002 - 2010 Paul Mundt
      9 */
     10#include <linux/screen_info.h>
     11#include <linux/ioport.h>
     12#include <linux/init.h>
     13#include <linux/initrd.h>
     14#include <linux/console.h>
     15#include <linux/root_dev.h>
     16#include <linux/utsname.h>
     17#include <linux/nodemask.h>
     18#include <linux/cpu.h>
     19#include <linux/pfn.h>
     20#include <linux/fs.h>
     21#include <linux/mm.h>
     22#include <linux/kexec.h>
     23#include <linux/module.h>
     24#include <linux/smp.h>
     25#include <linux/err.h>
     26#include <linux/crash_dump.h>
     27#include <linux/mmzone.h>
     28#include <linux/clk.h>
     29#include <linux/delay.h>
     30#include <linux/platform_device.h>
     31#include <linux/memblock.h>
     32#include <linux/of.h>
     33#include <linux/of_fdt.h>
     34#include <linux/uaccess.h>
     35#include <uapi/linux/mount.h>
     36#include <asm/io.h>
     37#include <asm/page.h>
     38#include <asm/elf.h>
     39#include <asm/sections.h>
     40#include <asm/irq.h>
     41#include <asm/setup.h>
     42#include <asm/clock.h>
     43#include <asm/smp.h>
     44#include <asm/mmu_context.h>
     45#include <asm/mmzone.h>
     46#include <asm/sparsemem.h>
     47#include <asm/platform_early.h>
     48
     49/*
     50 * Initialize loops_per_jiffy as 10000000 (1000MIPS).
     51 * This value will be used at the very early stage of serial setup.
     52 * The bigger value means no problem.
     53 */
     54struct sh_cpuinfo cpu_data[NR_CPUS] __read_mostly = {
     55	[0] = {
     56		.type			= CPU_SH_NONE,
     57		.family			= CPU_FAMILY_UNKNOWN,
     58		.loops_per_jiffy	= 10000000,
     59		.phys_bits		= MAX_PHYSMEM_BITS,
     60	},
     61};
     62EXPORT_SYMBOL(cpu_data);
     63
     64/*
     65 * The machine vector. First entry in .machvec.init, or clobbered by
     66 * sh_mv= on the command line, prior to .machvec.init teardown.
     67 */
     68struct sh_machine_vector sh_mv = { .mv_name = "generic", };
     69EXPORT_SYMBOL(sh_mv);
     70
     71#ifdef CONFIG_VT
     72struct screen_info screen_info;
     73#endif
     74
     75extern int root_mountflags;
     76
     77#define RAMDISK_IMAGE_START_MASK	0x07FF
     78#define RAMDISK_PROMPT_FLAG		0x8000
     79#define RAMDISK_LOAD_FLAG		0x4000
     80
     81static char __initdata command_line[COMMAND_LINE_SIZE] = { 0, };
     82
     83static struct resource code_resource = {
     84	.name = "Kernel code",
     85	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
     86};
     87
     88static struct resource data_resource = {
     89	.name = "Kernel data",
     90	.flags = IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
     91};
     92
     93static struct resource bss_resource = {
     94	.name	= "Kernel bss",
     95	.flags	= IORESOURCE_BUSY | IORESOURCE_SYSTEM_RAM,
     96};
     97
     98unsigned long memory_start;
     99EXPORT_SYMBOL(memory_start);
    100unsigned long memory_end = 0;
    101EXPORT_SYMBOL(memory_end);
    102unsigned long memory_limit = 0;
    103
    104static struct resource mem_resources[MAX_NUMNODES];
    105
    106int l1i_cache_shape, l1d_cache_shape, l2_cache_shape;
    107
    108static int __init early_parse_mem(char *p)
    109{
    110	if (!p)
    111		return 1;
    112
    113	memory_limit = PAGE_ALIGN(memparse(p, &p));
    114
    115	pr_notice("Memory limited to %ldMB\n", memory_limit >> 20);
    116
    117	return 0;
    118}
    119early_param("mem", early_parse_mem);
    120
    121void __init check_for_initrd(void)
    122{
    123#ifdef CONFIG_BLK_DEV_INITRD
    124	unsigned long start, end;
    125
    126	/*
    127	 * Check for the rare cases where boot loaders adhere to the boot
    128	 * ABI.
    129	 */
    130	if (!LOADER_TYPE || !INITRD_START || !INITRD_SIZE)
    131		goto disable;
    132
    133	start = INITRD_START + __MEMORY_START;
    134	end = start + INITRD_SIZE;
    135
    136	if (unlikely(end <= start))
    137		goto disable;
    138	if (unlikely(start & ~PAGE_MASK)) {
    139		pr_err("initrd must be page aligned\n");
    140		goto disable;
    141	}
    142
    143	if (unlikely(start < __MEMORY_START)) {
    144		pr_err("initrd start (%08lx) < __MEMORY_START(%x)\n",
    145			start, __MEMORY_START);
    146		goto disable;
    147	}
    148
    149	if (unlikely(end > memblock_end_of_DRAM())) {
    150		pr_err("initrd extends beyond end of memory "
    151		       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
    152		       end, (unsigned long)memblock_end_of_DRAM());
    153		goto disable;
    154	}
    155
    156	/*
    157	 * If we got this far in spite of the boot loader's best efforts
    158	 * to the contrary, assume we actually have a valid initrd and
    159	 * fix up the root dev.
    160	 */
    161	ROOT_DEV = Root_RAM0;
    162
    163	/*
    164	 * Address sanitization
    165	 */
    166	initrd_start = (unsigned long)__va(start);
    167	initrd_end = initrd_start + INITRD_SIZE;
    168
    169	memblock_reserve(__pa(initrd_start), INITRD_SIZE);
    170
    171	return;
    172
    173disable:
    174	pr_info("initrd disabled\n");
    175	initrd_start = initrd_end = 0;
    176#endif
    177}
    178
    179#ifndef CONFIG_GENERIC_CALIBRATE_DELAY
    180void calibrate_delay(void)
    181{
    182	struct clk *clk = clk_get(NULL, "cpu_clk");
    183
    184	if (IS_ERR(clk))
    185		panic("Need a sane CPU clock definition!");
    186
    187	loops_per_jiffy = (clk_get_rate(clk) >> 1) / HZ;
    188
    189	printk(KERN_INFO "Calibrating delay loop (skipped)... "
    190			 "%lu.%02lu BogoMIPS PRESET (lpj=%lu)\n",
    191			 loops_per_jiffy/(500000/HZ),
    192			 (loops_per_jiffy/(5000/HZ)) % 100,
    193			 loops_per_jiffy);
    194}
    195#endif
    196
    197void __init __add_active_range(unsigned int nid, unsigned long start_pfn,
    198						unsigned long end_pfn)
    199{
    200	struct resource *res = &mem_resources[nid];
    201	unsigned long start, end;
    202
    203	WARN_ON(res->name); /* max one active range per node for now */
    204
    205	start = start_pfn << PAGE_SHIFT;
    206	end = end_pfn << PAGE_SHIFT;
    207
    208	res->name = "System RAM";
    209	res->start = start;
    210	res->end = end - 1;
    211	res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
    212
    213	if (request_resource(&iomem_resource, res)) {
    214		pr_err("unable to request memory_resource 0x%lx 0x%lx\n",
    215		       start_pfn, end_pfn);
    216		return;
    217	}
    218
    219	/*
    220	 * We don't know which RAM region contains kernel data or
    221	 * the reserved crashkernel region, so try it repeatedly
    222	 * and let the resource manager test it.
    223	 */
    224	request_resource(res, &code_resource);
    225	request_resource(res, &data_resource);
    226	request_resource(res, &bss_resource);
    227#ifdef CONFIG_KEXEC
    228	request_resource(res, &crashk_res);
    229#endif
    230
    231	/*
    232	 * Also make sure that there is a PMB mapping that covers this
    233	 * range before we attempt to activate it, to avoid reset by MMU.
    234	 * We can hit this path with NUMA or memory hot-add.
    235	 */
    236	pmb_bolt_mapping((unsigned long)__va(start), start, end - start,
    237			 PAGE_KERNEL);
    238
    239	memblock_set_node(PFN_PHYS(start_pfn), PFN_PHYS(end_pfn - start_pfn),
    240			  &memblock.memory, nid);
    241}
    242
    243void __init __weak plat_early_device_setup(void)
    244{
    245}
    246
    247#ifdef CONFIG_OF_FLATTREE
    248void __ref sh_fdt_init(phys_addr_t dt_phys)
    249{
    250	static int done = 0;
    251	void *dt_virt;
    252
    253	/* Avoid calling an __init function on secondary cpus. */
    254	if (done) return;
    255
    256#ifdef CONFIG_USE_BUILTIN_DTB
    257	dt_virt = __dtb_start;
    258#else
    259	dt_virt = phys_to_virt(dt_phys);
    260#endif
    261
    262	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
    263		pr_crit("Error: invalid device tree blob"
    264			" at physical address %p\n", (void *)dt_phys);
    265
    266		while (true)
    267			cpu_relax();
    268	}
    269
    270	done = 1;
    271}
    272#endif
    273
    274void __init setup_arch(char **cmdline_p)
    275{
    276	enable_mmu();
    277
    278	ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
    279
    280	printk(KERN_NOTICE "Boot params:\n"
    281			   "... MOUNT_ROOT_RDONLY - %08lx\n"
    282			   "... RAMDISK_FLAGS     - %08lx\n"
    283			   "... ORIG_ROOT_DEV     - %08lx\n"
    284			   "... LOADER_TYPE       - %08lx\n"
    285			   "... INITRD_START      - %08lx\n"
    286			   "... INITRD_SIZE       - %08lx\n",
    287			   MOUNT_ROOT_RDONLY, RAMDISK_FLAGS,
    288			   ORIG_ROOT_DEV, LOADER_TYPE,
    289			   INITRD_START, INITRD_SIZE);
    290
    291#ifdef CONFIG_BLK_DEV_RAM
    292	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
    293#endif
    294
    295	if (!MOUNT_ROOT_RDONLY)
    296		root_mountflags &= ~MS_RDONLY;
    297	setup_initial_init_mm(_text, _etext, _edata, _end);
    298
    299	code_resource.start = virt_to_phys(_text);
    300	code_resource.end = virt_to_phys(_etext)-1;
    301	data_resource.start = virt_to_phys(_etext);
    302	data_resource.end = virt_to_phys(_edata)-1;
    303	bss_resource.start = virt_to_phys(__bss_start);
    304	bss_resource.end = virt_to_phys(__bss_stop)-1;
    305
    306#ifdef CONFIG_CMDLINE_OVERWRITE
    307	strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line));
    308#else
    309	strlcpy(command_line, COMMAND_LINE, sizeof(command_line));
    310#ifdef CONFIG_CMDLINE_EXTEND
    311	strlcat(command_line, " ", sizeof(command_line));
    312	strlcat(command_line, CONFIG_CMDLINE, sizeof(command_line));
    313#endif
    314#endif
    315
    316	/* Save unparsed command line copy for /proc/cmdline */
    317	memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE);
    318	*cmdline_p = command_line;
    319
    320	parse_early_param();
    321
    322	plat_early_device_setup();
    323
    324	sh_mv_setup();
    325
    326	/* Let earlyprintk output early console messages */
    327	sh_early_platform_driver_probe("earlyprintk", 1, 1);
    328
    329#ifdef CONFIG_OF_FLATTREE
    330#ifdef CONFIG_USE_BUILTIN_DTB
    331	unflatten_and_copy_device_tree();
    332#else
    333	unflatten_device_tree();
    334#endif
    335#endif
    336
    337	paging_init();
    338
    339	/* Perform the machine specific initialisation */
    340	if (likely(sh_mv.mv_setup))
    341		sh_mv.mv_setup(cmdline_p);
    342
    343	plat_smp_setup();
    344}
    345
    346/* processor boot mode configuration */
    347int generic_mode_pins(void)
    348{
    349	pr_warn("generic_mode_pins(): missing mode pin configuration\n");
    350	return 0;
    351}
    352
    353int test_mode_pin(int pin)
    354{
    355	return sh_mv.mv_mode_pins() & pin;
    356}