^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Nios2-specific parts of system setup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2010 Tobias Klauser <tklauser@distanz.ch>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 Microtronix Datacom Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2001 Vic Phillips <vic@microtronix.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file is subject to the terms and conditions of the GNU General Public
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * License. See the file "COPYING" in the main directory of this archive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched/task.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/initrd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/of_fdt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/screen_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/mmu_context.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/sections.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/cpuinfo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned long memory_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) EXPORT_SYMBOL(memory_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) unsigned long memory_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) EXPORT_SYMBOL(memory_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static struct pt_regs fake_regs = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) 0, 0, 0, 0, 0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) 0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #ifdef CONFIG_VT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct screen_info screen_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* Copy a short hook instruction sequence to the exception address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static inline void copy_exception_handler(unsigned int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) unsigned int start = (unsigned int) exception_handler_hook;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) volatile unsigned int tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (start == addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /* The CPU exception address already points to the handler. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) "ldw %2,0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) "stw %2,0(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) "ldw %2,4(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) "stw %2,4(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) "ldw %2,8(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) "stw %2,8(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) "flushd 0(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "flushd 4(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) "flushd 8(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) "flushi %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) "addi %1,%1,4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) "flushi %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) "addi %1,%1,4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) "flushi %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) "flushp\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) : /* no output registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) : "r" (start), "r" (addr), "r" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) : "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Copy the fast TLB miss handler */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static inline void copy_fast_tlb_miss_handler(unsigned int addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) unsigned int start = (unsigned int) fast_handler;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) unsigned int end = (unsigned int) fast_handler_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) volatile unsigned int tmp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) __asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "1:\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) " ldw %3,0(%0)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) " stw %3,0(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) " flushd 0(%1)\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) " flushi %1\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) " flushp\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) " addi %0,%0,4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) " addi %1,%1,4\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) " bne %0,%2,1b\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) : /* no output registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) : "r" (start), "r" (addr), "r" (end), "r" (tmp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) : "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * save args passed from u-boot, called from head.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @r4: NIOS magic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * @r5: initrd start
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * @r6: initrd end or fdt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @r7: kernel command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) asmlinkage void __init nios2_boot_init(unsigned r4, unsigned r5, unsigned r6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) unsigned r7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) unsigned dtb_passed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) char cmdline_passed[COMMAND_LINE_SIZE] __maybe_unused = { 0, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #if defined(CONFIG_NIOS2_PASS_CMDLINE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (r4 == 0x534f494e) { /* r4 is magic NIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #if defined(CONFIG_BLK_DEV_INITRD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (r5) { /* initramfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) initrd_start = r5;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) initrd_end = r6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #endif /* CONFIG_BLK_DEV_INITRD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) dtb_passed = r6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (r7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) strlcpy(cmdline_passed, (char *)r7, COMMAND_LINE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) early_init_devtree((void *)dtb_passed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #ifndef CONFIG_CMDLINE_FORCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (cmdline_passed[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) strlcpy(boot_command_line, cmdline_passed, COMMAND_LINE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #ifdef CONFIG_NIOS2_CMDLINE_IGNORE_DTB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) strlcpy(boot_command_line, CONFIG_CMDLINE, COMMAND_LINE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) parse_early_param();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) void __init setup_arch(char **cmdline_p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) int dram_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) console_verbose();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dram_start = memblock_start_of_DRAM();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) memory_size = memblock_phys_mem_size();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) memory_start = PAGE_ALIGN((unsigned long)__pa(_end));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) memory_end = (unsigned long) CONFIG_NIOS2_MEM_BASE + memory_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) init_mm.start_code = (unsigned long) _stext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) init_mm.end_code = (unsigned long) _etext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) init_mm.end_data = (unsigned long) _edata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) init_mm.brk = (unsigned long) _end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) init_task.thread.kregs = &fake_regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* Keep a copy of command line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) *cmdline_p = boot_command_line;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) min_low_pfn = PFN_UP(memory_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) max_low_pfn = PFN_DOWN(memory_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) max_mapnr = max_low_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) memblock_reserve(dram_start, memory_start - dram_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #ifdef CONFIG_BLK_DEV_INITRD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (initrd_start) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) memblock_reserve(virt_to_phys((void *)initrd_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) initrd_end - initrd_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #endif /* CONFIG_BLK_DEV_INITRD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) early_init_fdt_reserve_self();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) early_init_fdt_scan_reserved_mem();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) unflatten_and_copy_device_tree();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) setup_cpuinfo();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) copy_exception_handler(cpuinfo.exception_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mmu_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) copy_fast_tlb_miss_handler(cpuinfo.fast_tlb_miss_exc_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Initialize MMU context handling here because data from cpuinfo is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * needed for this.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mmu_context_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * get kmalloc into gear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) paging_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }