1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
3 
4 #include <linux/console.h>
5 #include <linux/memblock.h>
6 #include <linux/initrd.h>
7 #include <linux/of.h>
8 #include <linux/of_fdt.h>
9 #include <linux/start_kernel.h>
10 #include <linux/dma-map-ops.h>
11 #include <asm/sections.h>
12 #include <asm/mmu_context.h>
13 #include <asm/pgalloc.h>
14 
15 #ifdef CONFIG_BLK_DEV_INITRD
setup_initrd(void)16 static void __init setup_initrd(void)
17 {
18 	unsigned long size;
19 
20 	if (initrd_start >= initrd_end) {
21 		pr_err("initrd not found or empty");
22 		goto disable;
23 	}
24 
25 	if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) {
26 		pr_err("initrd extends beyond end of memory");
27 		goto disable;
28 	}
29 
30 	size = initrd_end - initrd_start;
31 
32 	if (memblock_is_region_reserved(__pa(initrd_start), size)) {
33 		pr_err("INITRD: 0x%08lx+0x%08lx overlaps in-use memory region",
34 		       __pa(initrd_start), size);
35 		goto disable;
36 	}
37 
38 	memblock_reserve(__pa(initrd_start), size);
39 
40 	pr_info("Initial ramdisk at: 0x%p (%lu bytes)\n",
41 		(void *)(initrd_start), size);
42 
43 	initrd_below_start_ok = 1;
44 
45 	return;
46 
47 disable:
48 	initrd_start = initrd_end = 0;
49 
50 	pr_err(" - disabling initrd\n");
51 }
52 #endif
53 
csky_memblock_init(void)54 static void __init csky_memblock_init(void)
55 {
56 	unsigned long lowmem_size = PFN_DOWN(LOWMEM_LIMIT - PHYS_OFFSET_OFFSET);
57 	unsigned long sseg_size = PFN_DOWN(SSEG_SIZE - PHYS_OFFSET_OFFSET);
58 	unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0 };
59 	signed long size;
60 
61 	memblock_reserve(__pa(_start), _end - _start);
62 
63 	early_init_fdt_reserve_self();
64 	early_init_fdt_scan_reserved_mem();
65 
66 	memblock_dump_all();
67 
68 	min_low_pfn = PFN_UP(memblock_start_of_DRAM());
69 	max_low_pfn = max_pfn = PFN_DOWN(memblock_end_of_DRAM());
70 
71 	size = max_pfn - min_low_pfn;
72 
73 	if (size >= lowmem_size) {
74 		max_low_pfn = min_low_pfn + lowmem_size;
75 #ifdef CONFIG_PAGE_OFFSET_80000000
76 		write_mmu_msa1(read_mmu_msa0() + SSEG_SIZE);
77 #endif
78 	} else if (size > sseg_size) {
79 		max_low_pfn = min_low_pfn + sseg_size;
80 	}
81 
82 #ifdef CONFIG_BLK_DEV_INITRD
83 	setup_initrd();
84 #endif
85 
86 	max_zone_pfn[ZONE_NORMAL] = max_low_pfn;
87 
88 	mmu_init(min_low_pfn, max_low_pfn);
89 
90 #ifdef CONFIG_HIGHMEM
91 	max_zone_pfn[ZONE_HIGHMEM] = max_pfn;
92 
93 	highstart_pfn = max_low_pfn;
94 	highend_pfn   = max_pfn;
95 #endif
96 	memblock_set_current_limit(PFN_PHYS(max_low_pfn));
97 
98 	dma_contiguous_reserve(0);
99 
100 	free_area_init(max_zone_pfn);
101 }
102 
setup_arch(char ** cmdline_p)103 void __init setup_arch(char **cmdline_p)
104 {
105 	*cmdline_p = boot_command_line;
106 
107 	console_verbose();
108 
109 	pr_info("Phys. mem: %ldMB\n",
110 		(unsigned long) memblock_phys_mem_size()/1024/1024);
111 
112 	setup_initial_init_mm(_start, _etext, _edata, _end);
113 
114 	parse_early_param();
115 
116 	csky_memblock_init();
117 
118 	unflatten_and_copy_device_tree();
119 
120 #ifdef CONFIG_SMP
121 	setup_smp();
122 #endif
123 
124 	sparse_init();
125 
126 	fixaddr_init();
127 
128 #ifdef CONFIG_HIGHMEM
129 	kmap_init();
130 #endif
131 }
132 
133 unsigned long va_pa_offset;
134 EXPORT_SYMBOL(va_pa_offset);
135 
read_mmu_msa(void)136 static inline unsigned long read_mmu_msa(void)
137 {
138 #ifdef CONFIG_PAGE_OFFSET_80000000
139 	return read_mmu_msa0();
140 #endif
141 
142 #ifdef CONFIG_PAGE_OFFSET_A0000000
143 	return read_mmu_msa1();
144 #endif
145 }
146 
csky_start(unsigned int unused,void * dtb_start)147 asmlinkage __visible void __init csky_start(unsigned int unused,
148 					    void *dtb_start)
149 {
150 	/* Clean up bss section */
151 	memset(__bss_start, 0, __bss_stop - __bss_start);
152 
153 	va_pa_offset = read_mmu_msa() & ~(SSEG_SIZE - 1);
154 
155 	pre_trap_init();
156 
157 	if (dtb_start == NULL)
158 		early_init_dt_scan(__dtb_start, __pa(dtb_start));
159 	else
160 		early_init_dt_scan(dtb_start, __pa(dtb_start));
161 
162 	start_kernel();
163 
164 	asm volatile("br .\n");
165 }
166