xref: /linux/arch/m68k/kernel/setup_mm.c (revision 0ea5c948cb64bab5bc7a5516774eb8536f05aa0d)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
266d857b0SGreg Ungerer /*
366d857b0SGreg Ungerer  *  linux/arch/m68k/kernel/setup.c
466d857b0SGreg Ungerer  *
566d857b0SGreg Ungerer  *  Copyright (C) 1995  Hamish Macdonald
666d857b0SGreg Ungerer  */
766d857b0SGreg Ungerer 
866d857b0SGreg Ungerer /*
966d857b0SGreg Ungerer  * This file handles the architecture-dependent parts of system setup
1066d857b0SGreg Ungerer  */
1166d857b0SGreg Ungerer 
1266d857b0SGreg Ungerer #include <linux/kernel.h>
13*9ceecc25SThomas Gleixner #include <linux/cpu.h>
1466d857b0SGreg Ungerer #include <linux/mm.h>
1566d857b0SGreg Ungerer #include <linux/sched.h>
1666d857b0SGreg Ungerer #include <linux/delay.h>
1766d857b0SGreg Ungerer #include <linux/interrupt.h>
1866d857b0SGreg Ungerer #include <linux/fs.h>
1966d857b0SGreg Ungerer #include <linux/console.h>
2066d857b0SGreg Ungerer #include <linux/errno.h>
2166d857b0SGreg Ungerer #include <linux/string.h>
2266d857b0SGreg Ungerer #include <linux/init.h>
231008a115SMike Rapoport #include <linux/memblock.h>
2466d857b0SGreg Ungerer #include <linux/proc_fs.h>
2566d857b0SGreg Ungerer #include <linux/seq_file.h>
2666d857b0SGreg Ungerer #include <linux/module.h>
27d3b41b6bSFinn Thain #include <linux/nvram.h>
2866d857b0SGreg Ungerer #include <linux/initrd.h>
29dc63a086SJason A. Donenfeld #include <linux/random.h>
3066d857b0SGreg Ungerer 
3166d857b0SGreg Ungerer #include <asm/bootinfo.h>
32abe48101SGeert Uytterhoeven #include <asm/byteorder.h>
3366d857b0SGreg Ungerer #include <asm/sections.h>
3466d857b0SGreg Ungerer #include <asm/setup.h>
3566d857b0SGreg Ungerer #include <asm/fpu.h>
3666d857b0SGreg Ungerer #include <asm/irq.h>
3766d857b0SGreg Ungerer #include <asm/io.h>
3866d857b0SGreg Ungerer #include <asm/machdep.h>
3966d857b0SGreg Ungerer #ifdef CONFIG_AMIGA
4066d857b0SGreg Ungerer #include <asm/amigahw.h>
4166d857b0SGreg Ungerer #endif
4266d857b0SGreg Ungerer #include <asm/atarihw.h>
43d3b41b6bSFinn Thain #ifdef CONFIG_ATARI
4466d857b0SGreg Ungerer #include <asm/atari_stram.h>
4566d857b0SGreg Ungerer #endif
4666d857b0SGreg Ungerer #ifdef CONFIG_SUN3X
4766d857b0SGreg Ungerer #include <asm/dvma.h>
4866d857b0SGreg Ungerer #endif
49d3b41b6bSFinn Thain #include <asm/macintosh.h>
5066d857b0SGreg Ungerer #include <asm/natfeat.h>
5191d7b75aSLaurent Vivier #include <asm/config.h>
5266d857b0SGreg Ungerer 
5366d857b0SGreg Ungerer #if !FPSTATESIZE || !NR_IRQS
5466d857b0SGreg Ungerer #warning No CPU/platform type selected, your kernel will not work!
5566d857b0SGreg Ungerer #warning Are you building an allnoconfig kernel?
5666d857b0SGreg Ungerer #endif
5766d857b0SGreg Ungerer 
5866d857b0SGreg Ungerer unsigned long m68k_machtype;
5966d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_machtype);
6066d857b0SGreg Ungerer unsigned long m68k_cputype;
6166d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_cputype);
6266d857b0SGreg Ungerer unsigned long m68k_fputype;
6366d857b0SGreg Ungerer unsigned long m68k_mmutype;
6466d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_mmutype);
6566d857b0SGreg Ungerer #ifdef CONFIG_VME
6666d857b0SGreg Ungerer unsigned long vme_brdtype;
6766d857b0SGreg Ungerer EXPORT_SYMBOL(vme_brdtype);
6866d857b0SGreg Ungerer #endif
6966d857b0SGreg Ungerer 
7066d857b0SGreg Ungerer int m68k_is040or060;
7166d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_is040or060);
7266d857b0SGreg Ungerer 
7366d857b0SGreg Ungerer extern unsigned long availmem;
7466d857b0SGreg Ungerer 
7566d857b0SGreg Ungerer int m68k_num_memory;
7666d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_num_memory);
7766d857b0SGreg Ungerer int m68k_realnum_memory;
7866d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_realnum_memory);
7966d857b0SGreg Ungerer unsigned long m68k_memoffset;
8079930084SGeert Uytterhoeven struct m68k_mem_info m68k_memory[NUM_MEMINFO];
8166d857b0SGreg Ungerer EXPORT_SYMBOL(m68k_memory);
8266d857b0SGreg Ungerer 
8379930084SGeert Uytterhoeven static struct m68k_mem_info m68k_ramdisk __initdata;
8466d857b0SGreg Ungerer 
85a4df02a2SGeert Uytterhoeven static char m68k_command_line[CL_SIZE] __initdata;
8666d857b0SGreg Ungerer 
87f9a01539SArnd Bergmann void (*mach_sched_init) (void) __initdata = NULL;
8866d857b0SGreg Ungerer /* machine dependent irq functions */
8966d857b0SGreg Ungerer void (*mach_init_IRQ) (void) __initdata = NULL;
9066d857b0SGreg Ungerer void (*mach_get_model) (char *model);
9166d857b0SGreg Ungerer void (*mach_get_hardware_list) (struct seq_file *m);
9266d857b0SGreg Ungerer void (*mach_reset)( void );
9366d857b0SGreg Ungerer void (*mach_halt)( void );
9466d857b0SGreg Ungerer #ifdef CONFIG_HEARTBEAT
9566d857b0SGreg Ungerer void (*mach_heartbeat) (int);
9666d857b0SGreg Ungerer EXPORT_SYMBOL(mach_heartbeat);
9766d857b0SGreg Ungerer #endif
9866d857b0SGreg Ungerer #ifdef CONFIG_M68K_L2_CACHE
9966d857b0SGreg Ungerer void (*mach_l2_flush) (int);
10066d857b0SGreg Ungerer #endif
10166d857b0SGreg Ungerer #if defined(CONFIG_ISA) && defined(MULTI_ISA)
10266d857b0SGreg Ungerer int isa_type;
10366d857b0SGreg Ungerer int isa_sex;
10466d857b0SGreg Ungerer EXPORT_SYMBOL(isa_type);
10566d857b0SGreg Ungerer EXPORT_SYMBOL(isa_sex);
10666d857b0SGreg Ungerer #endif
10766d857b0SGreg Ungerer 
10866d857b0SGreg Ungerer #define MASK_256K 0xfffc0000
10966d857b0SGreg Ungerer 
m68k_parse_bootinfo(const struct bi_record * record)11066d857b0SGreg Ungerer static void __init m68k_parse_bootinfo(const struct bi_record *record)
11166d857b0SGreg Ungerer {
1127c236d93SJason A. Donenfeld 	const struct bi_record *first_record = record;
113abe48101SGeert Uytterhoeven 	uint16_t tag;
11466d857b0SGreg Ungerer 
115abe48101SGeert Uytterhoeven 	while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
116abe48101SGeert Uytterhoeven 		int unknown = 0;
117abe48101SGeert Uytterhoeven 		const void *data = record->data;
118abe48101SGeert Uytterhoeven 		uint16_t size = be16_to_cpu(record->size);
119abe48101SGeert Uytterhoeven 
120abe48101SGeert Uytterhoeven 		switch (tag) {
12166d857b0SGreg Ungerer 		case BI_MACHTYPE:
12266d857b0SGreg Ungerer 		case BI_CPUTYPE:
12366d857b0SGreg Ungerer 		case BI_FPUTYPE:
12466d857b0SGreg Ungerer 		case BI_MMUTYPE:
12566d857b0SGreg Ungerer 			/* Already set up by head.S */
12666d857b0SGreg Ungerer 			break;
12766d857b0SGreg Ungerer 
12866d857b0SGreg Ungerer 		case BI_MEMCHUNK:
12966d857b0SGreg Ungerer 			if (m68k_num_memory < NUM_MEMINFO) {
130abe48101SGeert Uytterhoeven 				const struct mem_info *m = data;
131abe48101SGeert Uytterhoeven 				m68k_memory[m68k_num_memory].addr =
132abe48101SGeert Uytterhoeven 					be32_to_cpu(m->addr);
133abe48101SGeert Uytterhoeven 				m68k_memory[m68k_num_memory].size =
134abe48101SGeert Uytterhoeven 					be32_to_cpu(m->size);
13566d857b0SGreg Ungerer 				m68k_num_memory++;
13666d857b0SGreg Ungerer 			} else
1376074a139SGeert Uytterhoeven 				pr_warn("%s: too many memory chunks\n",
1386074a139SGeert Uytterhoeven 					__func__);
13966d857b0SGreg Ungerer 			break;
14066d857b0SGreg Ungerer 
14166d857b0SGreg Ungerer 		case BI_RAMDISK:
142abe48101SGeert Uytterhoeven 			{
143abe48101SGeert Uytterhoeven 				const struct mem_info *m = data;
144abe48101SGeert Uytterhoeven 				m68k_ramdisk.addr = be32_to_cpu(m->addr);
145abe48101SGeert Uytterhoeven 				m68k_ramdisk.size = be32_to_cpu(m->size);
146abe48101SGeert Uytterhoeven 			}
14766d857b0SGreg Ungerer 			break;
14866d857b0SGreg Ungerer 
14966d857b0SGreg Ungerer 		case BI_COMMAND_LINE:
150c01b5a33SWolfram Sang 			strscpy(m68k_command_line, data,
15166d857b0SGreg Ungerer 				sizeof(m68k_command_line));
15266d857b0SGreg Ungerer 			break;
15366d857b0SGreg Ungerer 
154dc63a086SJason A. Donenfeld 		case BI_RNG_SEED: {
155dc63a086SJason A. Donenfeld 			u16 len = be16_to_cpup(data);
156dc63a086SJason A. Donenfeld 			add_bootloader_randomness(data + 2, len);
157dc63a086SJason A. Donenfeld 			/*
158dc63a086SJason A. Donenfeld 			 * Zero the data to preserve forward secrecy, and zero the
159dc63a086SJason A. Donenfeld 			 * length to prevent kexec from using it.
160dc63a086SJason A. Donenfeld 			 */
161dc63a086SJason A. Donenfeld 			memzero_explicit((void *)data, len + 2);
162dc63a086SJason A. Donenfeld 			break;
163dc63a086SJason A. Donenfeld 		}
164dc63a086SJason A. Donenfeld 
16566d857b0SGreg Ungerer 		default:
16666d857b0SGreg Ungerer 			if (MACH_IS_AMIGA)
16766d857b0SGreg Ungerer 				unknown = amiga_parse_bootinfo(record);
16866d857b0SGreg Ungerer 			else if (MACH_IS_ATARI)
16966d857b0SGreg Ungerer 				unknown = atari_parse_bootinfo(record);
17066d857b0SGreg Ungerer 			else if (MACH_IS_MAC)
17166d857b0SGreg Ungerer 				unknown = mac_parse_bootinfo(record);
17266d857b0SGreg Ungerer 			else if (MACH_IS_Q40)
17366d857b0SGreg Ungerer 				unknown = q40_parse_bootinfo(record);
17466d857b0SGreg Ungerer 			else if (MACH_IS_BVME6000)
17566d857b0SGreg Ungerer 				unknown = bvme6000_parse_bootinfo(record);
17666d857b0SGreg Ungerer 			else if (MACH_IS_MVME16x)
17766d857b0SGreg Ungerer 				unknown = mvme16x_parse_bootinfo(record);
17866d857b0SGreg Ungerer 			else if (MACH_IS_MVME147)
17966d857b0SGreg Ungerer 				unknown = mvme147_parse_bootinfo(record);
18066d857b0SGreg Ungerer 			else if (MACH_IS_HP300)
18166d857b0SGreg Ungerer 				unknown = hp300_parse_bootinfo(record);
18266d857b0SGreg Ungerer 			else if (MACH_IS_APOLLO)
18366d857b0SGreg Ungerer 				unknown = apollo_parse_bootinfo(record);
18405d51e42SLaurent Vivier 			else if (MACH_IS_VIRT)
18505d51e42SLaurent Vivier 				unknown = virt_parse_bootinfo(record);
18666d857b0SGreg Ungerer 			else
18766d857b0SGreg Ungerer 				unknown = 1;
18866d857b0SGreg Ungerer 		}
18966d857b0SGreg Ungerer 		if (unknown)
1906074a139SGeert Uytterhoeven 			pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
191abe48101SGeert Uytterhoeven 				tag);
192abe48101SGeert Uytterhoeven 		record = (struct bi_record *)((unsigned long)record + size);
19366d857b0SGreg Ungerer 	}
19466d857b0SGreg Ungerer 
1957c236d93SJason A. Donenfeld 	save_bootinfo(first_record);
1967c236d93SJason A. Donenfeld 
19766d857b0SGreg Ungerer 	m68k_realnum_memory = m68k_num_memory;
19866d857b0SGreg Ungerer #ifdef CONFIG_SINGLE_MEMORY_CHUNK
19966d857b0SGreg Ungerer 	if (m68k_num_memory > 1) {
2006074a139SGeert Uytterhoeven 		pr_warn("%s: ignoring last %i chunks of physical memory\n",
2016074a139SGeert Uytterhoeven 			__func__, (m68k_num_memory - 1));
20266d857b0SGreg Ungerer 		m68k_num_memory = 1;
20366d857b0SGreg Ungerer 	}
20466d857b0SGreg Ungerer #endif
20566d857b0SGreg Ungerer }
20666d857b0SGreg Ungerer 
setup_arch(char ** cmdline_p)20766d857b0SGreg Ungerer void __init setup_arch(char **cmdline_p)
20866d857b0SGreg Ungerer {
20929a20203SGeert Uytterhoeven 	/* The bootinfo is located right after the kernel */
21037314540SGreg Ungerer 	if (!CPU_IS_COLDFIRE)
21166d857b0SGreg Ungerer 		m68k_parse_bootinfo((const struct bi_record *)_end);
21266d857b0SGreg Ungerer 
21366d857b0SGreg Ungerer 	if (CPU_IS_040)
21466d857b0SGreg Ungerer 		m68k_is040or060 = 4;
21566d857b0SGreg Ungerer 	else if (CPU_IS_060)
21666d857b0SGreg Ungerer 		m68k_is040or060 = 6;
21766d857b0SGreg Ungerer 
21866d857b0SGreg Ungerer 	/* FIXME: m68k_fputype is passed in by Penguin booter, which can
21966d857b0SGreg Ungerer 	 * be confused by software FPU emulation. BEWARE.
22066d857b0SGreg Ungerer 	 * We should really do our own FPU check at startup.
22166d857b0SGreg Ungerer 	 * [what do we do with buggy 68LC040s? if we have problems
22266d857b0SGreg Ungerer 	 *  with them, we should add a test to check_bugs() below] */
2236d3ec805SGreg Ungerer #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY)
22466d857b0SGreg Ungerer 	/* clear the fpu if we have one */
2250a2796daSGreg Ungerer 	if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
22666d857b0SGreg Ungerer 		volatile int zero = 0;
22766d857b0SGreg Ungerer 		asm volatile ("frestore %0" : : "m" (zero));
22866d857b0SGreg Ungerer 	}
22966d857b0SGreg Ungerer #endif
23066d857b0SGreg Ungerer 
23166d857b0SGreg Ungerer 	if (CPU_IS_060) {
23266d857b0SGreg Ungerer 		u32 pcr;
23366d857b0SGreg Ungerer 
23466d857b0SGreg Ungerer 		asm (".chip 68060; movec %%pcr,%0; .chip 68k"
23566d857b0SGreg Ungerer 		     : "=d" (pcr));
23666d857b0SGreg Ungerer 		if (((pcr >> 8) & 0xff) <= 5) {
2376074a139SGeert Uytterhoeven 			pr_warn("Enabling workaround for errata I14\n");
23866d857b0SGreg Ungerer 			asm (".chip 68060; movec %0,%%pcr; .chip 68k"
23966d857b0SGreg Ungerer 			     : : "d" (pcr | 0x20));
24066d857b0SGreg Ungerer 		}
24166d857b0SGreg Ungerer 	}
24266d857b0SGreg Ungerer 
243ed408db1SKefeng Wang 	setup_initial_init_mm((void *)PAGE_OFFSET, _etext, _edata, _end);
24466d857b0SGreg Ungerer 
245d1db9120SGreg Ungerer #if defined(CONFIG_BOOTPARAM)
246d1db9120SGreg Ungerer 	strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
247d1db9120SGreg Ungerer 	m68k_command_line[CL_SIZE - 1] = 0;
248d1db9120SGreg Ungerer #endif /* CONFIG_BOOTPARAM */
249aa5ac789SGreg Ungerer 	process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
25066d857b0SGreg Ungerer 	*cmdline_p = m68k_command_line;
25166d857b0SGreg Ungerer 	memcpy(boot_command_line, *cmdline_p, CL_SIZE);
25266d857b0SGreg Ungerer 
25366d857b0SGreg Ungerer 	parse_early_param();
25466d857b0SGreg Ungerer 
25566d857b0SGreg Ungerer 	switch (m68k_machtype) {
25666d857b0SGreg Ungerer #ifdef CONFIG_AMIGA
25766d857b0SGreg Ungerer 	case MACH_AMIGA:
25866d857b0SGreg Ungerer 		config_amiga();
25966d857b0SGreg Ungerer 		break;
26066d857b0SGreg Ungerer #endif
26166d857b0SGreg Ungerer #ifdef CONFIG_ATARI
26266d857b0SGreg Ungerer 	case MACH_ATARI:
26366d857b0SGreg Ungerer 		config_atari();
26466d857b0SGreg Ungerer 		break;
26566d857b0SGreg Ungerer #endif
26666d857b0SGreg Ungerer #ifdef CONFIG_MAC
26766d857b0SGreg Ungerer 	case MACH_MAC:
26866d857b0SGreg Ungerer 		config_mac();
26966d857b0SGreg Ungerer 		break;
27066d857b0SGreg Ungerer #endif
27166d857b0SGreg Ungerer #ifdef CONFIG_SUN3
27266d857b0SGreg Ungerer 	case MACH_SUN3:
27366d857b0SGreg Ungerer 		config_sun3();
27466d857b0SGreg Ungerer 		break;
27566d857b0SGreg Ungerer #endif
27666d857b0SGreg Ungerer #ifdef CONFIG_APOLLO
27766d857b0SGreg Ungerer 	case MACH_APOLLO:
27866d857b0SGreg Ungerer 		config_apollo();
27966d857b0SGreg Ungerer 		break;
28066d857b0SGreg Ungerer #endif
28166d857b0SGreg Ungerer #ifdef CONFIG_MVME147
28266d857b0SGreg Ungerer 	case MACH_MVME147:
28366d857b0SGreg Ungerer 		config_mvme147();
28466d857b0SGreg Ungerer 		break;
28566d857b0SGreg Ungerer #endif
28666d857b0SGreg Ungerer #ifdef CONFIG_MVME16x
28766d857b0SGreg Ungerer 	case MACH_MVME16x:
28866d857b0SGreg Ungerer 		config_mvme16x();
28966d857b0SGreg Ungerer 		break;
29066d857b0SGreg Ungerer #endif
29166d857b0SGreg Ungerer #ifdef CONFIG_BVME6000
29266d857b0SGreg Ungerer 	case MACH_BVME6000:
29366d857b0SGreg Ungerer 		config_bvme6000();
29466d857b0SGreg Ungerer 		break;
29566d857b0SGreg Ungerer #endif
29666d857b0SGreg Ungerer #ifdef CONFIG_HP300
29766d857b0SGreg Ungerer 	case MACH_HP300:
29866d857b0SGreg Ungerer 		config_hp300();
29966d857b0SGreg Ungerer 		break;
30066d857b0SGreg Ungerer #endif
30166d857b0SGreg Ungerer #ifdef CONFIG_Q40
30266d857b0SGreg Ungerer 	case MACH_Q40:
30366d857b0SGreg Ungerer 		config_q40();
30466d857b0SGreg Ungerer 		break;
30566d857b0SGreg Ungerer #endif
30666d857b0SGreg Ungerer #ifdef CONFIG_SUN3X
30766d857b0SGreg Ungerer 	case MACH_SUN3X:
30866d857b0SGreg Ungerer 		config_sun3x();
30966d857b0SGreg Ungerer 		break;
31066d857b0SGreg Ungerer #endif
31137314540SGreg Ungerer #ifdef CONFIG_COLDFIRE
31237314540SGreg Ungerer 	case MACH_M54XX:
31381d33350SGreg Ungerer 	case MACH_M5441X:
31434fa9b21SGreg Ungerer 		cf_bootmem_alloc();
31534fa9b21SGreg Ungerer 		cf_mmu_context_init();
31637314540SGreg Ungerer 		config_BSP(NULL, 0);
31737314540SGreg Ungerer 		break;
31837314540SGreg Ungerer #endif
31905d51e42SLaurent Vivier #ifdef CONFIG_VIRT
32005d51e42SLaurent Vivier 	case MACH_VIRT:
32105d51e42SLaurent Vivier 		config_virt();
32205d51e42SLaurent Vivier 		break;
32305d51e42SLaurent Vivier #endif
32466d857b0SGreg Ungerer 	default:
32566d857b0SGreg Ungerer 		panic("No configuration setup");
32666d857b0SGreg Ungerer 	}
32766d857b0SGreg Ungerer 
328d4b97925SGeert Uytterhoeven 	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size)
3291008a115SMike Rapoport 		memblock_reserve(m68k_ramdisk.addr, m68k_ramdisk.size);
330d4b97925SGeert Uytterhoeven 
331d4b97925SGeert Uytterhoeven 	paging_init();
332d4b97925SGeert Uytterhoeven 
333d4b97925SGeert Uytterhoeven 	if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && m68k_ramdisk.size) {
33466d857b0SGreg Ungerer 		initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
33566d857b0SGreg Ungerer 		initrd_end = initrd_start + m68k_ramdisk.size;
3366074a139SGeert Uytterhoeven 		pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
33766d857b0SGreg Ungerer 	}
338376e3fdeSFinn Thain 
339376e3fdeSFinn Thain #ifdef CONFIG_NATFEAT
340376e3fdeSFinn Thain 	nf_init();
341376e3fdeSFinn Thain #endif
342376e3fdeSFinn Thain 
34366d857b0SGreg Ungerer #ifdef CONFIG_ATARI
34466d857b0SGreg Ungerer 	if (MACH_IS_ATARI)
34566d857b0SGreg Ungerer 		atari_stram_reserve_pages((void *)availmem);
34666d857b0SGreg Ungerer #endif
34766d857b0SGreg Ungerer #ifdef CONFIG_SUN3X
34866d857b0SGreg Ungerer 	if (MACH_IS_SUN3X) {
34966d857b0SGreg Ungerer 		dvma_init();
35066d857b0SGreg Ungerer 	}
35166d857b0SGreg Ungerer #endif
35266d857b0SGreg Ungerer 
35366d857b0SGreg Ungerer /* set ISA defs early as possible */
35466d857b0SGreg Ungerer #if defined(CONFIG_ISA) && defined(MULTI_ISA)
35566d857b0SGreg Ungerer 	if (MACH_IS_Q40) {
35666d857b0SGreg Ungerer 		isa_type = ISA_TYPE_Q40;
35766d857b0SGreg Ungerer 		isa_sex = 0;
35866d857b0SGreg Ungerer 	}
35966d857b0SGreg Ungerer #ifdef CONFIG_AMIGA_PCMCIA
36066d857b0SGreg Ungerer 	if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
36166d857b0SGreg Ungerer 		isa_type = ISA_TYPE_AG;
36266d857b0SGreg Ungerer 		isa_sex = 1;
36366d857b0SGreg Ungerer 	}
36466d857b0SGreg Ungerer #endif
36584b16b7bSMichael Schmitz #ifdef CONFIG_ATARI_ROM_ISA
36684b16b7bSMichael Schmitz 	if (MACH_IS_ATARI) {
36784b16b7bSMichael Schmitz 		isa_type = ISA_TYPE_ENEC;
36884b16b7bSMichael Schmitz 		isa_sex = 0;
36984b16b7bSMichael Schmitz 	}
37084b16b7bSMichael Schmitz #endif
37166d857b0SGreg Ungerer #endif
37266d857b0SGreg Ungerer }
37366d857b0SGreg Ungerer 
show_cpuinfo(struct seq_file * m,void * v)37466d857b0SGreg Ungerer static int show_cpuinfo(struct seq_file *m, void *v)
37566d857b0SGreg Ungerer {
37666d857b0SGreg Ungerer 	const char *cpu, *mmu, *fpu;
37766d857b0SGreg Ungerer 	unsigned long clockfreq, clockfactor;
37866d857b0SGreg Ungerer 
37966d857b0SGreg Ungerer #define LOOP_CYCLES_68020	(8)
38066d857b0SGreg Ungerer #define LOOP_CYCLES_68030	(8)
38166d857b0SGreg Ungerer #define LOOP_CYCLES_68040	(3)
38266d857b0SGreg Ungerer #define LOOP_CYCLES_68060	(1)
383060632adSGreg Ungerer #define LOOP_CYCLES_COLDFIRE	(2)
38466d857b0SGreg Ungerer 
38566d857b0SGreg Ungerer 	if (CPU_IS_020) {
38666d857b0SGreg Ungerer 		cpu = "68020";
38766d857b0SGreg Ungerer 		clockfactor = LOOP_CYCLES_68020;
38866d857b0SGreg Ungerer 	} else if (CPU_IS_030) {
38966d857b0SGreg Ungerer 		cpu = "68030";
39066d857b0SGreg Ungerer 		clockfactor = LOOP_CYCLES_68030;
39166d857b0SGreg Ungerer 	} else if (CPU_IS_040) {
39266d857b0SGreg Ungerer 		cpu = "68040";
39366d857b0SGreg Ungerer 		clockfactor = LOOP_CYCLES_68040;
39466d857b0SGreg Ungerer 	} else if (CPU_IS_060) {
39566d857b0SGreg Ungerer 		cpu = "68060";
39666d857b0SGreg Ungerer 		clockfactor = LOOP_CYCLES_68060;
397060632adSGreg Ungerer 	} else if (CPU_IS_COLDFIRE) {
398060632adSGreg Ungerer 		cpu = "ColdFire";
399060632adSGreg Ungerer 		clockfactor = LOOP_CYCLES_COLDFIRE;
40066d857b0SGreg Ungerer 	} else {
40166d857b0SGreg Ungerer 		cpu = "680x0";
40266d857b0SGreg Ungerer 		clockfactor = 0;
40366d857b0SGreg Ungerer 	}
40466d857b0SGreg Ungerer 
40566d857b0SGreg Ungerer #ifdef CONFIG_M68KFPU_EMU_ONLY
40666d857b0SGreg Ungerer 	fpu = "none(soft float)";
40766d857b0SGreg Ungerer #else
40866d857b0SGreg Ungerer 	if (m68k_fputype & FPU_68881)
40966d857b0SGreg Ungerer 		fpu = "68881";
41066d857b0SGreg Ungerer 	else if (m68k_fputype & FPU_68882)
41166d857b0SGreg Ungerer 		fpu = "68882";
41266d857b0SGreg Ungerer 	else if (m68k_fputype & FPU_68040)
41366d857b0SGreg Ungerer 		fpu = "68040";
41466d857b0SGreg Ungerer 	else if (m68k_fputype & FPU_68060)
41566d857b0SGreg Ungerer 		fpu = "68060";
41666d857b0SGreg Ungerer 	else if (m68k_fputype & FPU_SUNFPA)
41766d857b0SGreg Ungerer 		fpu = "Sun FPA";
418060632adSGreg Ungerer 	else if (m68k_fputype & FPU_COLDFIRE)
419060632adSGreg Ungerer 		fpu = "ColdFire";
42066d857b0SGreg Ungerer 	else
42166d857b0SGreg Ungerer 		fpu = "none";
42266d857b0SGreg Ungerer #endif
42366d857b0SGreg Ungerer 
42466d857b0SGreg Ungerer 	if (m68k_mmutype & MMU_68851)
42566d857b0SGreg Ungerer 		mmu = "68851";
42666d857b0SGreg Ungerer 	else if (m68k_mmutype & MMU_68030)
42766d857b0SGreg Ungerer 		mmu = "68030";
42866d857b0SGreg Ungerer 	else if (m68k_mmutype & MMU_68040)
42966d857b0SGreg Ungerer 		mmu = "68040";
43066d857b0SGreg Ungerer 	else if (m68k_mmutype & MMU_68060)
43166d857b0SGreg Ungerer 		mmu = "68060";
43266d857b0SGreg Ungerer 	else if (m68k_mmutype & MMU_SUN3)
43366d857b0SGreg Ungerer 		mmu = "Sun-3";
43466d857b0SGreg Ungerer 	else if (m68k_mmutype & MMU_APOLLO)
43566d857b0SGreg Ungerer 		mmu = "Apollo";
436060632adSGreg Ungerer 	else if (m68k_mmutype & MMU_COLDFIRE)
437060632adSGreg Ungerer 		mmu = "ColdFire";
43866d857b0SGreg Ungerer 	else
43966d857b0SGreg Ungerer 		mmu = "unknown";
44066d857b0SGreg Ungerer 
44166d857b0SGreg Ungerer 	clockfreq = loops_per_jiffy * HZ * clockfactor;
44266d857b0SGreg Ungerer 
44366d857b0SGreg Ungerer 	seq_printf(m, "CPU:\t\t%s\n"
44466d857b0SGreg Ungerer 		   "MMU:\t\t%s\n"
44566d857b0SGreg Ungerer 		   "FPU:\t\t%s\n"
44666d857b0SGreg Ungerer 		   "Clocking:\t%lu.%1luMHz\n"
44766d857b0SGreg Ungerer 		   "BogoMips:\t%lu.%02lu\n"
44866d857b0SGreg Ungerer 		   "Calibration:\t%lu loops\n",
44966d857b0SGreg Ungerer 		   cpu, mmu, fpu,
45066d857b0SGreg Ungerer 		   clockfreq/1000000,(clockfreq/100000)%10,
45166d857b0SGreg Ungerer 		   loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
45266d857b0SGreg Ungerer 		   loops_per_jiffy);
45366d857b0SGreg Ungerer 	return 0;
45466d857b0SGreg Ungerer }
45566d857b0SGreg Ungerer 
c_start(struct seq_file * m,loff_t * pos)45666d857b0SGreg Ungerer static void *c_start(struct seq_file *m, loff_t *pos)
45766d857b0SGreg Ungerer {
45866d857b0SGreg Ungerer 	return *pos < 1 ? (void *)1 : NULL;
45966d857b0SGreg Ungerer }
c_next(struct seq_file * m,void * v,loff_t * pos)46066d857b0SGreg Ungerer static void *c_next(struct seq_file *m, void *v, loff_t *pos)
46166d857b0SGreg Ungerer {
46266d857b0SGreg Ungerer 	++*pos;
46366d857b0SGreg Ungerer 	return NULL;
46466d857b0SGreg Ungerer }
c_stop(struct seq_file * m,void * v)46566d857b0SGreg Ungerer static void c_stop(struct seq_file *m, void *v)
46666d857b0SGreg Ungerer {
46766d857b0SGreg Ungerer }
46866d857b0SGreg Ungerer const struct seq_operations cpuinfo_op = {
46966d857b0SGreg Ungerer 	.start	= c_start,
47066d857b0SGreg Ungerer 	.next	= c_next,
47166d857b0SGreg Ungerer 	.stop	= c_stop,
47266d857b0SGreg Ungerer 	.show	= show_cpuinfo,
47366d857b0SGreg Ungerer };
47466d857b0SGreg Ungerer 
47566d857b0SGreg Ungerer #ifdef CONFIG_PROC_HARDWARE
hardware_proc_show(struct seq_file * m,void * v)47666d857b0SGreg Ungerer static int hardware_proc_show(struct seq_file *m, void *v)
47766d857b0SGreg Ungerer {
47866d857b0SGreg Ungerer 	char model[80];
47966d857b0SGreg Ungerer 	unsigned long mem;
48066d857b0SGreg Ungerer 	int i;
48166d857b0SGreg Ungerer 
48266d857b0SGreg Ungerer 	if (mach_get_model)
48366d857b0SGreg Ungerer 		mach_get_model(model);
48466d857b0SGreg Ungerer 	else
48566d857b0SGreg Ungerer 		strcpy(model, "Unknown m68k");
48666d857b0SGreg Ungerer 
48766d857b0SGreg Ungerer 	seq_printf(m, "Model:\t\t%s\n", model);
48866d857b0SGreg Ungerer 	for (mem = 0, i = 0; i < m68k_num_memory; i++)
48966d857b0SGreg Ungerer 		mem += m68k_memory[i].size;
49066d857b0SGreg Ungerer 	seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
49166d857b0SGreg Ungerer 
49266d857b0SGreg Ungerer 	if (mach_get_hardware_list)
49366d857b0SGreg Ungerer 		mach_get_hardware_list(m);
49466d857b0SGreg Ungerer 
49566d857b0SGreg Ungerer 	return 0;
49666d857b0SGreg Ungerer }
49766d857b0SGreg Ungerer 
proc_hardware_init(void)49866d857b0SGreg Ungerer static int __init proc_hardware_init(void)
49966d857b0SGreg Ungerer {
5003f3942acSChristoph Hellwig 	proc_create_single("hardware", 0, NULL, hardware_proc_show);
50166d857b0SGreg Ungerer 	return 0;
50266d857b0SGreg Ungerer }
50366d857b0SGreg Ungerer module_init(proc_hardware_init);
50466d857b0SGreg Ungerer #endif
50566d857b0SGreg Ungerer 
arch_cpu_finalize_init(void)506*9ceecc25SThomas Gleixner void __init arch_cpu_finalize_init(void)
50766d857b0SGreg Ungerer {
5082a744007SGreg Ungerer #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
50966d857b0SGreg Ungerer 	if (m68k_fputype == 0) {
5106074a139SGeert Uytterhoeven 		pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
51166d857b0SGreg Ungerer 			"WHICH IS REQUIRED BY LINUX/M68K ***\n");
5126074a139SGeert Uytterhoeven 		pr_emerg("Upgrade your hardware or join the FPU "
51366d857b0SGreg Ungerer 			"emulation project\n");
51466d857b0SGreg Ungerer 		panic("no FPU");
51566d857b0SGreg Ungerer 	}
51666d857b0SGreg Ungerer #endif /* !CONFIG_M68KFPU_EMU */
51766d857b0SGreg Ungerer }
51866d857b0SGreg Ungerer 
51966d857b0SGreg Ungerer #ifdef CONFIG_ADB
adb_probe_sync_enable(char * str)52066d857b0SGreg Ungerer static int __init adb_probe_sync_enable (char *str) {
52166d857b0SGreg Ungerer 	extern int __adb_probe_sync;
52266d857b0SGreg Ungerer 	__adb_probe_sync = 1;
52366d857b0SGreg Ungerer 	return 1;
52466d857b0SGreg Ungerer }
52566d857b0SGreg Ungerer 
52666d857b0SGreg Ungerer __setup("adb_sync", adb_probe_sync_enable);
52766d857b0SGreg Ungerer #endif /* CONFIG_ADB */
528d3b41b6bSFinn Thain 
529d3b41b6bSFinn Thain #if IS_ENABLED(CONFIG_NVRAM)
530d3b41b6bSFinn Thain #ifdef CONFIG_MAC
m68k_nvram_read_byte(int addr)531d3b41b6bSFinn Thain static unsigned char m68k_nvram_read_byte(int addr)
532d3b41b6bSFinn Thain {
533d3b41b6bSFinn Thain 	if (MACH_IS_MAC)
534d3b41b6bSFinn Thain 		return mac_pram_read_byte(addr);
535d3b41b6bSFinn Thain 	return 0xff;
536d3b41b6bSFinn Thain }
537d3b41b6bSFinn Thain 
m68k_nvram_write_byte(unsigned char val,int addr)538d3b41b6bSFinn Thain static void m68k_nvram_write_byte(unsigned char val, int addr)
539d3b41b6bSFinn Thain {
540d3b41b6bSFinn Thain 	if (MACH_IS_MAC)
541d3b41b6bSFinn Thain 		mac_pram_write_byte(val, addr);
542d3b41b6bSFinn Thain }
543d3b41b6bSFinn Thain #endif /* CONFIG_MAC */
544d3b41b6bSFinn Thain 
545d3b41b6bSFinn Thain #ifdef CONFIG_ATARI
m68k_nvram_read(char * buf,size_t count,loff_t * ppos)546d3b41b6bSFinn Thain static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
547d3b41b6bSFinn Thain {
548d3b41b6bSFinn Thain 	if (MACH_IS_ATARI)
549d3b41b6bSFinn Thain 		return atari_nvram_read(buf, count, ppos);
550d3b41b6bSFinn Thain 	else if (MACH_IS_MAC)
551d3b41b6bSFinn Thain 		return nvram_read_bytes(buf, count, ppos);
552d3b41b6bSFinn Thain 	return -EINVAL;
553d3b41b6bSFinn Thain }
554d3b41b6bSFinn Thain 
m68k_nvram_write(char * buf,size_t count,loff_t * ppos)555d3b41b6bSFinn Thain static ssize_t m68k_nvram_write(char *buf, size_t count, loff_t *ppos)
556d3b41b6bSFinn Thain {
557d3b41b6bSFinn Thain 	if (MACH_IS_ATARI)
558d3b41b6bSFinn Thain 		return atari_nvram_write(buf, count, ppos);
559d3b41b6bSFinn Thain 	else if (MACH_IS_MAC)
560d3b41b6bSFinn Thain 		return nvram_write_bytes(buf, count, ppos);
561d3b41b6bSFinn Thain 	return -EINVAL;
562d3b41b6bSFinn Thain }
563d3b41b6bSFinn Thain 
m68k_nvram_set_checksum(void)564d3b41b6bSFinn Thain static long m68k_nvram_set_checksum(void)
565d3b41b6bSFinn Thain {
566d3b41b6bSFinn Thain 	if (MACH_IS_ATARI)
567d3b41b6bSFinn Thain 		return atari_nvram_set_checksum();
568d3b41b6bSFinn Thain 	return -EINVAL;
569d3b41b6bSFinn Thain }
570d3b41b6bSFinn Thain 
m68k_nvram_initialize(void)571d3b41b6bSFinn Thain static long m68k_nvram_initialize(void)
572d3b41b6bSFinn Thain {
573d3b41b6bSFinn Thain 	if (MACH_IS_ATARI)
574d3b41b6bSFinn Thain 		return atari_nvram_initialize();
575d3b41b6bSFinn Thain 	return -EINVAL;
576d3b41b6bSFinn Thain }
577d3b41b6bSFinn Thain #endif /* CONFIG_ATARI */
578d3b41b6bSFinn Thain 
m68k_nvram_get_size(void)579d3b41b6bSFinn Thain static ssize_t m68k_nvram_get_size(void)
580d3b41b6bSFinn Thain {
581d3b41b6bSFinn Thain 	if (MACH_IS_ATARI)
582d3b41b6bSFinn Thain 		return atari_nvram_get_size();
583d3b41b6bSFinn Thain 	else if (MACH_IS_MAC)
584d3b41b6bSFinn Thain 		return mac_pram_get_size();
585d3b41b6bSFinn Thain 	return -ENODEV;
586d3b41b6bSFinn Thain }
587d3b41b6bSFinn Thain 
588d3b41b6bSFinn Thain /* Atari device drivers call .read (to get checksum validation) whereas
589d3b41b6bSFinn Thain  * Mac and PowerMac device drivers just use .read_byte.
590d3b41b6bSFinn Thain  */
591d3b41b6bSFinn Thain const struct nvram_ops arch_nvram_ops = {
592d3b41b6bSFinn Thain #ifdef CONFIG_MAC
593d3b41b6bSFinn Thain 	.read_byte      = m68k_nvram_read_byte,
594d3b41b6bSFinn Thain 	.write_byte     = m68k_nvram_write_byte,
595d3b41b6bSFinn Thain #endif
596d3b41b6bSFinn Thain #ifdef CONFIG_ATARI
597d3b41b6bSFinn Thain 	.read           = m68k_nvram_read,
598d3b41b6bSFinn Thain 	.write          = m68k_nvram_write,
599d3b41b6bSFinn Thain 	.set_checksum   = m68k_nvram_set_checksum,
600d3b41b6bSFinn Thain 	.initialize     = m68k_nvram_initialize,
601d3b41b6bSFinn Thain #endif
602d3b41b6bSFinn Thain 	.get_size       = m68k_nvram_get_size,
603d3b41b6bSFinn Thain };
604d3b41b6bSFinn Thain EXPORT_SYMBOL(arch_nvram_ops);
605d3b41b6bSFinn Thain #endif /* CONFIG_NVRAM */
606