1588cb88cSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
276d2a049SPalmer Dabbelt /*
376d2a049SPalmer Dabbelt * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
476d2a049SPalmer Dabbelt * Chen Liqin <liqin.chen@sunplusct.com>
576d2a049SPalmer Dabbelt * Lennox Wu <lennox.wu@sunplusct.com>
676d2a049SPalmer Dabbelt * Copyright (C) 2012 Regents of the University of California
700ab027aSNick Kossifidis * Copyright (C) 2020 FORTH-ICS/CARV
800ab027aSNick Kossifidis * Nick Kossifidis <mick@ics.forth.gr>
976d2a049SPalmer Dabbelt */
1076d2a049SPalmer Dabbelt
11724f4c0dSSunil V L #include <linux/acpi.h>
12a0418108SRob Herring #include <linux/cpu.h>
1376d2a049SPalmer Dabbelt #include <linux/init.h>
1476d2a049SPalmer Dabbelt #include <linux/mm.h>
1576d2a049SPalmer Dabbelt #include <linux/memblock.h>
1676d2a049SPalmer Dabbelt #include <linux/sched.h>
1776d2a049SPalmer Dabbelt #include <linux/console.h>
1876d2a049SPalmer Dabbelt #include <linux/screen_info.h>
1976d2a049SPalmer Dabbelt #include <linux/of_fdt.h>
2076d2a049SPalmer Dabbelt #include <linux/sched/task.h>
21f1e58583SAtish Patra #include <linux/smp.h>
22b91540d5SAtish Patra #include <linux/efi.h>
23e53d2818SNick Kossifidis #include <linux/crash_dump.h>
2454a519e6SAlexandre Ghiti #include <linux/panic_notifier.h>
2576d2a049SPalmer Dabbelt
26f9956119SSunil V L #include <asm/acpi.h>
27ffb0b0afSHeiko Stuebner #include <asm/alternative.h>
281631ba12SHeiko Stuebner #include <asm/cacheflush.h>
291b0a08a4SAndrew Jones #include <asm/cpufeature.h>
30f1e58583SAtish Patra #include <asm/cpu_ops.h>
316262f661SAtish Patra #include <asm/early_ioremap.h>
3244c92257SVitaly Wool #include <asm/pgtable.h>
3376d2a049SPalmer Dabbelt #include <asm/setup.h>
3419a00869SAtish Patra #include <asm/set_memory.h>
3576d2a049SPalmer Dabbelt #include <asm/sections.h>
36b9dcd9e4SAtish Patra #include <asm/sbi.h>
3776d2a049SPalmer Dabbelt #include <asm/tlbflush.h>
3876d2a049SPalmer Dabbelt #include <asm/thread_info.h>
398ad8b727SNick Hu #include <asm/kasan.h>
40b91540d5SAtish Patra #include <asm/efi.h>
4176d2a049SPalmer Dabbelt
42ffaee272SPaul Walmsley #include "head.h"
43ffaee272SPaul Walmsley
44d9a5d5c4SArnd Bergmann #if defined(CONFIG_EFI)
45d9a5d5c4SArnd Bergmann struct screen_info screen_info __section(".data");
4676d2a049SPalmer Dabbelt #endif
4776d2a049SPalmer Dabbelt
48aff77833SZong Li /*
49aff77833SZong Li * The lucky hart to first increment this variable will boot the other cores.
50aff77833SZong Li * This is used before the kernel initializes the BSS so it can't be in the
51aff77833SZong Li * BSS.
52aff77833SZong Li */
5344c92257SVitaly Wool atomic_t hart_lottery __section(".sdata")
5444c92257SVitaly Wool #ifdef CONFIG_XIP_KERNEL
5544c92257SVitaly Wool = ATOMIC_INIT(0xC001BEEF)
5644c92257SVitaly Wool #endif
5744c92257SVitaly Wool ;
58f99fb607SAtish Patra unsigned long boot_cpu_hartid;
59f1e58583SAtish Patra static DEFINE_PER_CPU(struct cpu, cpu_devices);
6076d2a049SPalmer Dabbelt
6100ab027aSNick Kossifidis /*
6200ab027aSNick Kossifidis * Place kernel memory regions on the resource tree so that
6300ab027aSNick Kossifidis * kexec-tools can retrieve them from /proc/iomem. While there
6400ab027aSNick Kossifidis * also add "System RAM" regions for compatibility with other
6500ab027aSNick Kossifidis * archs, and the rest of the known regions for completeness.
6600ab027aSNick Kossifidis */
67ffe0e526SNick Kossifidis static struct resource kimage_res = { .name = "Kernel image", };
6800ab027aSNick Kossifidis static struct resource code_res = { .name = "Kernel code", };
6900ab027aSNick Kossifidis static struct resource data_res = { .name = "Kernel data", };
7000ab027aSNick Kossifidis static struct resource rodata_res = { .name = "Kernel rodata", };
7100ab027aSNick Kossifidis static struct resource bss_res = { .name = "Kernel bss", };
7256409750SNick Kossifidis #ifdef CONFIG_CRASH_DUMP
7356409750SNick Kossifidis static struct resource elfcorehdr_res = { .name = "ELF Core hdr", };
7456409750SNick Kossifidis #endif
7500ab027aSNick Kossifidis
add_resource(struct resource * parent,struct resource * res)7600ab027aSNick Kossifidis static int __init add_resource(struct resource *parent,
7700ab027aSNick Kossifidis struct resource *res)
7800ab027aSNick Kossifidis {
7900ab027aSNick Kossifidis int ret = 0;
8000ab027aSNick Kossifidis
8100ab027aSNick Kossifidis ret = insert_resource(parent, res);
8200ab027aSNick Kossifidis if (ret < 0) {
8300ab027aSNick Kossifidis pr_err("Failed to add a %s resource at %llx\n",
8400ab027aSNick Kossifidis res->name, (unsigned long long) res->start);
8500ab027aSNick Kossifidis return ret;
8600ab027aSNick Kossifidis }
8700ab027aSNick Kossifidis
8800ab027aSNick Kossifidis return 1;
8900ab027aSNick Kossifidis }
9000ab027aSNick Kossifidis
add_kernel_resources(void)91ffe0e526SNick Kossifidis static int __init add_kernel_resources(void)
9200ab027aSNick Kossifidis {
9300ab027aSNick Kossifidis int ret = 0;
9400ab027aSNick Kossifidis
9500ab027aSNick Kossifidis /*
9600ab027aSNick Kossifidis * The memory region of the kernel image is continuous and
97ffe0e526SNick Kossifidis * was reserved on setup_bootmem, register it here as a
98ffe0e526SNick Kossifidis * resource, with the various segments of the image as
99ffe0e526SNick Kossifidis * child nodes.
10000ab027aSNick Kossifidis */
10100ab027aSNick Kossifidis
10200ab027aSNick Kossifidis code_res.start = __pa_symbol(_text);
10300ab027aSNick Kossifidis code_res.end = __pa_symbol(_etext) - 1;
10400ab027aSNick Kossifidis code_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
10500ab027aSNick Kossifidis
10600ab027aSNick Kossifidis rodata_res.start = __pa_symbol(__start_rodata);
10700ab027aSNick Kossifidis rodata_res.end = __pa_symbol(__end_rodata) - 1;
10800ab027aSNick Kossifidis rodata_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
10900ab027aSNick Kossifidis
11000ab027aSNick Kossifidis data_res.start = __pa_symbol(_data);
11100ab027aSNick Kossifidis data_res.end = __pa_symbol(_edata) - 1;
11200ab027aSNick Kossifidis data_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
11300ab027aSNick Kossifidis
11400ab027aSNick Kossifidis bss_res.start = __pa_symbol(__bss_start);
11500ab027aSNick Kossifidis bss_res.end = __pa_symbol(__bss_stop) - 1;
11600ab027aSNick Kossifidis bss_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
11700ab027aSNick Kossifidis
118ffe0e526SNick Kossifidis kimage_res.start = code_res.start;
119ffe0e526SNick Kossifidis kimage_res.end = bss_res.end;
120ffe0e526SNick Kossifidis kimage_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
121ffe0e526SNick Kossifidis
122ffe0e526SNick Kossifidis ret = add_resource(&iomem_resource, &kimage_res);
123ffe0e526SNick Kossifidis if (ret < 0)
124ffe0e526SNick Kossifidis return ret;
125ffe0e526SNick Kossifidis
126ffe0e526SNick Kossifidis ret = add_resource(&kimage_res, &code_res);
127ffe0e526SNick Kossifidis if (ret < 0)
128ffe0e526SNick Kossifidis return ret;
129ffe0e526SNick Kossifidis
130ffe0e526SNick Kossifidis ret = add_resource(&kimage_res, &rodata_res);
131ffe0e526SNick Kossifidis if (ret < 0)
132ffe0e526SNick Kossifidis return ret;
133ffe0e526SNick Kossifidis
134ffe0e526SNick Kossifidis ret = add_resource(&kimage_res, &data_res);
135ffe0e526SNick Kossifidis if (ret < 0)
136ffe0e526SNick Kossifidis return ret;
137ffe0e526SNick Kossifidis
138ffe0e526SNick Kossifidis ret = add_resource(&kimage_res, &bss_res);
139ffe0e526SNick Kossifidis
140ffe0e526SNick Kossifidis return ret;
141ffe0e526SNick Kossifidis }
142ffe0e526SNick Kossifidis
init_resources(void)143ffe0e526SNick Kossifidis static void __init init_resources(void)
144ffe0e526SNick Kossifidis {
145ffe0e526SNick Kossifidis struct memblock_region *region = NULL;
146ffe0e526SNick Kossifidis struct resource *res = NULL;
147ffe0e526SNick Kossifidis struct resource *mem_res = NULL;
148ffe0e526SNick Kossifidis size_t mem_res_sz = 0;
149ffe0e526SNick Kossifidis int num_resources = 0, res_idx = 0;
150ffe0e526SNick Kossifidis int ret = 0;
151ffe0e526SNick Kossifidis
152ffe0e526SNick Kossifidis /* + 1 as memblock_alloc() might increase memblock.reserved.cnt */
153ffe0e526SNick Kossifidis num_resources = memblock.memory.cnt + memblock.reserved.cnt + 1;
154ffe0e526SNick Kossifidis res_idx = num_resources - 1;
155ffe0e526SNick Kossifidis
156ffe0e526SNick Kossifidis mem_res_sz = num_resources * sizeof(*mem_res);
157797f0375SAtish Patra mem_res = memblock_alloc(mem_res_sz, SMP_CACHE_BYTES);
158797f0375SAtish Patra if (!mem_res)
159797f0375SAtish Patra panic("%s: Failed to allocate %zu bytes\n", __func__, mem_res_sz);
160ffe0e526SNick Kossifidis
16100ab027aSNick Kossifidis /*
16200ab027aSNick Kossifidis * Start by adding the reserved regions, if they overlap
16300ab027aSNick Kossifidis * with /memory regions, insert_resource later on will take
16400ab027aSNick Kossifidis * care of it.
16500ab027aSNick Kossifidis */
166ffe0e526SNick Kossifidis ret = add_kernel_resources();
167ffe0e526SNick Kossifidis if (ret < 0)
168ffe0e526SNick Kossifidis goto error;
169ffe0e526SNick Kossifidis
170bbc8486eSMingzheng Xing #ifdef CONFIG_KEXEC_CORE
171bbc8486eSMingzheng Xing if (crashk_res.start != crashk_res.end) {
172bbc8486eSMingzheng Xing ret = add_resource(&iomem_resource, &crashk_res);
173bbc8486eSMingzheng Xing if (ret < 0)
174bbc8486eSMingzheng Xing goto error;
175bbc8486eSMingzheng Xing }
176bbc8486eSMingzheng Xing if (crashk_low_res.start != crashk_low_res.end) {
177bbc8486eSMingzheng Xing ret = add_resource(&iomem_resource, &crashk_low_res);
178bbc8486eSMingzheng Xing if (ret < 0)
179bbc8486eSMingzheng Xing goto error;
180bbc8486eSMingzheng Xing }
181bbc8486eSMingzheng Xing #endif
182bbc8486eSMingzheng Xing
18356409750SNick Kossifidis #ifdef CONFIG_CRASH_DUMP
18456409750SNick Kossifidis if (elfcorehdr_size > 0) {
18556409750SNick Kossifidis elfcorehdr_res.start = elfcorehdr_addr;
18656409750SNick Kossifidis elfcorehdr_res.end = elfcorehdr_addr + elfcorehdr_size - 1;
18756409750SNick Kossifidis elfcorehdr_res.flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
18856409750SNick Kossifidis add_resource(&iomem_resource, &elfcorehdr_res);
18956409750SNick Kossifidis }
19056409750SNick Kossifidis #endif
19156409750SNick Kossifidis
19200ab027aSNick Kossifidis for_each_reserved_mem_region(region) {
193ffe0e526SNick Kossifidis res = &mem_res[res_idx--];
19400ab027aSNick Kossifidis
19500ab027aSNick Kossifidis res->name = "Reserved";
196e61bf5c0SXianting Tian res->flags = IORESOURCE_MEM | IORESOURCE_EXCLUSIVE;
19700ab027aSNick Kossifidis res->start = __pfn_to_phys(memblock_region_reserved_base_pfn(region));
19800ab027aSNick Kossifidis res->end = __pfn_to_phys(memblock_region_reserved_end_pfn(region)) - 1;
19900ab027aSNick Kossifidis
20000ab027aSNick Kossifidis /*
20100ab027aSNick Kossifidis * Ignore any other reserved regions within
20200ab027aSNick Kossifidis * system memory.
20300ab027aSNick Kossifidis */
204797f0375SAtish Patra if (memblock_is_memory(res->start)) {
205ffe0e526SNick Kossifidis /* Re-use this pre-allocated resource */
206ffe0e526SNick Kossifidis res_idx++;
20700ab027aSNick Kossifidis continue;
208797f0375SAtish Patra }
20900ab027aSNick Kossifidis
21000ab027aSNick Kossifidis ret = add_resource(&iomem_resource, res);
21100ab027aSNick Kossifidis if (ret < 0)
21200ab027aSNick Kossifidis goto error;
21300ab027aSNick Kossifidis }
21400ab027aSNick Kossifidis
21500ab027aSNick Kossifidis /* Add /memory regions to the resource tree */
21600ab027aSNick Kossifidis for_each_mem_region(region) {
217ffe0e526SNick Kossifidis res = &mem_res[res_idx--];
21800ab027aSNick Kossifidis
21900ab027aSNick Kossifidis if (unlikely(memblock_is_nomap(region))) {
22000ab027aSNick Kossifidis res->name = "Reserved";
221e61bf5c0SXianting Tian res->flags = IORESOURCE_MEM | IORESOURCE_EXCLUSIVE;
22200ab027aSNick Kossifidis } else {
22300ab027aSNick Kossifidis res->name = "System RAM";
22400ab027aSNick Kossifidis res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
22500ab027aSNick Kossifidis }
22600ab027aSNick Kossifidis
22700ab027aSNick Kossifidis res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
22800ab027aSNick Kossifidis res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
22900ab027aSNick Kossifidis
23000ab027aSNick Kossifidis ret = add_resource(&iomem_resource, res);
23100ab027aSNick Kossifidis if (ret < 0)
23200ab027aSNick Kossifidis goto error;
23300ab027aSNick Kossifidis }
23400ab027aSNick Kossifidis
235ffe0e526SNick Kossifidis /* Clean-up any unused pre-allocated resources */
236aa3e1ba3SPetr Pavlu if (res_idx >= 0)
2374421cca0SMike Rapoport memblock_free(mem_res, (res_idx + 1) * sizeof(*mem_res));
23800ab027aSNick Kossifidis return;
23900ab027aSNick Kossifidis
24000ab027aSNick Kossifidis error:
24100ab027aSNick Kossifidis /* Better an empty resource tree than an inconsistent one */
24200ab027aSNick Kossifidis release_child_resources(&iomem_resource);
2434421cca0SMike Rapoport memblock_free(mem_res, mem_res_sz);
24400ab027aSNick Kossifidis }
24500ab027aSNick Kossifidis
24600ab027aSNick Kossifidis
parse_dtb(void)2478f3a2b4aSAnup Patel static void __init parse_dtb(void)
24876d2a049SPalmer Dabbelt {
2498f3a2b4aSAnup Patel /* Early scan of device tree from init memory */
250aa9b1d0dSAlexandre Ghiti if (early_init_dt_scan(dtb_early_va, dtb_early_pa)) {
25146ad48e8SKefeng Wang const char *name = of_flat_dt_get_machine_name();
25246ad48e8SKefeng Wang
25346ad48e8SKefeng Wang if (name) {
25446ad48e8SKefeng Wang pr_info("Machine model: %s\n", name);
25546ad48e8SKefeng Wang dump_stack_set_arch_desc("%s (DT)", name);
25646ad48e8SKefeng Wang }
25710f6913cSWenting Zhang } else {
25810f6913cSWenting Zhang pr_err("No DTB passed to the kernel\n");
25946ad48e8SKefeng Wang }
2608fd6e05cSPaul Walmsley
2618fd6e05cSPaul Walmsley #ifdef CONFIG_CMDLINE_FORCE
262803930eeSJason Wang strscpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
2638fd6e05cSPaul Walmsley pr_info("Forcing kernel command line to: %s\n", boot_command_line);
2648fd6e05cSPaul Walmsley #endif
26576d2a049SPalmer Dabbelt }
26676d2a049SPalmer Dabbelt
2678ee0b418SGreentime Hu extern void __init init_rt_signal_env(void);
2688ee0b418SGreentime Hu
setup_arch(char ** cmdline_p)26976d2a049SPalmer Dabbelt void __init setup_arch(char **cmdline_p)
27076d2a049SPalmer Dabbelt {
2718f3a2b4aSAnup Patel parse_dtb();
272723a42f4SKefeng Wang setup_initial_init_mm(_stext, _etext, _edata, _end);
27376d2a049SPalmer Dabbelt
274680f9b8eSAnup Patel *cmdline_p = boot_command_line;
275680f9b8eSAnup Patel
2766262f661SAtish Patra early_ioremap_setup();
27724fc1808SJisheng Zhang sbi_init();
2786134b110SAnup Patel jump_label_init();
279680f9b8eSAnup Patel parse_early_param();
280680f9b8eSAnup Patel
281b91540d5SAtish Patra efi_init();
28276d2a049SPalmer Dabbelt paging_init();
283724f4c0dSSunil V L
284724f4c0dSSunil V L /* Parse the ACPI tables for possible boot-time configuration */
285724f4c0dSSunil V L acpi_boot_table_init();
286724f4c0dSSunil V L
2872d268251SPalmer Dabbelt #if IS_ENABLED(CONFIG_BUILTIN_DTB)
2882d268251SPalmer Dabbelt unflatten_and_copy_device_tree();
2892d268251SPalmer Dabbelt #else
29076d2a049SPalmer Dabbelt unflatten_device_tree();
2912d268251SPalmer Dabbelt #endif
292cbd34f4bSAtish Patra misc_mem_init();
29351858aafSZong Li
294e53d2818SNick Kossifidis init_resources();
29562149f35SAtish Patra
2968ad8b727SNick Hu #ifdef CONFIG_KASAN
2978ad8b727SNick Hu kasan_init();
2988ad8b727SNick Hu #endif
2998ad8b727SNick Hu
30076d2a049SPalmer Dabbelt #ifdef CONFIG_SMP
30176d2a049SPalmer Dabbelt setup_smp();
30276d2a049SPalmer Dabbelt #endif
30376d2a049SPalmer Dabbelt
304f9956119SSunil V L if (!acpi_disabled)
305f9956119SSunil V L acpi_init_rintc_map();
306f9956119SSunil V L
3077ea5a736SAndrew Jones riscv_init_cbo_blocksizes();
3088f7e001eSPalmer Dabbelt riscv_fill_hwcap();
309ffb0b0afSHeiko Stuebner apply_boot_alternatives();
310*dd8aad26SYong-Xuan Wang init_rt_signal_env();
3111b0a08a4SAndrew Jones
312abcc445aSJisheng Zhang if (IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM) &&
313abcc445aSJisheng Zhang riscv_isa_extension_available(NULL, ZICBOM))
314abcc445aSJisheng Zhang riscv_noncoherent_supported();
31529267151SJisheng Zhang riscv_set_dma_cache_alignment();
3161b0a08a4SAndrew Jones
3171b0a08a4SAndrew Jones riscv_user_isa_enable();
31876d2a049SPalmer Dabbelt }
319f1e58583SAtish Patra
topology_init(void)320f1e58583SAtish Patra static int __init topology_init(void)
321f1e58583SAtish Patra {
3224f0e8eefSAtish Patra int i, ret;
3234f0e8eefSAtish Patra
324f1e58583SAtish Patra for_each_possible_cpu(i) {
325f1e58583SAtish Patra struct cpu *cpu = &per_cpu(cpu_devices, i);
326f1e58583SAtish Patra
327f1e58583SAtish Patra cpu->hotpluggable = cpu_has_hotplug(i);
3284f0e8eefSAtish Patra ret = register_cpu(cpu, i);
3294f0e8eefSAtish Patra if (unlikely(ret))
3304f0e8eefSAtish Patra pr_warn("Warning: %s: register_cpu %d failed (%d)\n",
3314f0e8eefSAtish Patra __func__, i, ret);
332f1e58583SAtish Patra }
333f1e58583SAtish Patra
334f1e58583SAtish Patra return 0;
335f1e58583SAtish Patra }
336f1e58583SAtish Patra subsys_initcall(topology_init);
33719a00869SAtish Patra
free_initmem(void)33819a00869SAtish Patra void free_initmem(void)
33919a00869SAtish Patra {
3406fdd5d2fSBjörn Töpel if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
3416fdd5d2fSBjörn Töpel set_kernel_memory(lm_alias(__init_begin), lm_alias(__init_end), set_memory_rw_nx);
3426fdd5d2fSBjörn Töpel if (IS_ENABLED(CONFIG_64BIT))
3436fdd5d2fSBjörn Töpel set_kernel_memory(__init_begin, __init_end, set_memory_nx);
3446fdd5d2fSBjörn Töpel }
345f105ea98SAtish Patra
34619a00869SAtish Patra free_initmem_default(POISON_FREE_INITMEM);
34719a00869SAtish Patra }
34854a519e6SAlexandre Ghiti
dump_kernel_offset(struct notifier_block * self,unsigned long v,void * p)34954a519e6SAlexandre Ghiti static int dump_kernel_offset(struct notifier_block *self,
35054a519e6SAlexandre Ghiti unsigned long v, void *p)
35154a519e6SAlexandre Ghiti {
35254a519e6SAlexandre Ghiti pr_emerg("Kernel Offset: 0x%lx from 0x%lx\n",
35354a519e6SAlexandre Ghiti kernel_map.virt_offset,
35454a519e6SAlexandre Ghiti KERNEL_LINK_ADDR);
35554a519e6SAlexandre Ghiti
35654a519e6SAlexandre Ghiti return 0;
35754a519e6SAlexandre Ghiti }
35854a519e6SAlexandre Ghiti
35954a519e6SAlexandre Ghiti static struct notifier_block kernel_offset_notifier = {
36054a519e6SAlexandre Ghiti .notifier_call = dump_kernel_offset
36154a519e6SAlexandre Ghiti };
36254a519e6SAlexandre Ghiti
register_kernel_offset_dumper(void)36354a519e6SAlexandre Ghiti static int __init register_kernel_offset_dumper(void)
36454a519e6SAlexandre Ghiti {
36554a519e6SAlexandre Ghiti if (IS_ENABLED(CONFIG_RANDOMIZE_BASE))
36654a519e6SAlexandre Ghiti atomic_notifier_chain_register(&panic_notifier_list,
36754a519e6SAlexandre Ghiti &kernel_offset_notifier);
36854a519e6SAlexandre Ghiti
36954a519e6SAlexandre Ghiti return 0;
37054a519e6SAlexandre Ghiti }
37154a519e6SAlexandre Ghiti device_initcall(register_kernel_offset_dumper);
372