aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/dec/prom/init.c
blob: 60f74256e689fe93b56d4d10476f9bca55403810 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * init.c: PROM library initialisation code.
 *
 * Copyright (C) 1998 Harald Koerfgen
 * Copyright (C) 2002, 2004  Maciej W. Rozycki
 */
#include <linux/config.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/string.h>
#include <linux/types.h>

#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/processor.h>

#include <asm/dec/prom.h>


int (*__rex_bootinit)(void);
int (*__rex_bootread)(void);
int (*__rex_getbitmap)(memmap *);
unsigned long *(*__rex_slot_address)(int);
void *(*__rex_gettcinfo)(void);
int (*__rex_getsysid)(void);
void (*__rex_clear_cache)(void);

int (*__prom_getchar)(void);
char *(*__prom_getenv)(char *);
int (*__prom_printf)(char *, ...);

int (*__pmax_open)(char*, int);
int (*__pmax_lseek)(int, long, int);
int (*__pmax_read)(int, void *, int);
int (*__pmax_close)(int);


/*
 * Detect which PROM the DECSTATION has, and set the callback vectors
 * appropriately.
 */
void __init which_prom(s32 magic, s32 *prom_vec)
{
	/*
	 * No sign of the REX PROM's magic number means we assume a non-REX
	 * machine (i.e. we're on a DS2100/3100, DS5100 or DS5000/2xx)
	 */
	if (prom_is_rex(magic)) {
		/*
		 * Set up prom abstraction structure with REX entry points.
		 */
		__rex_bootinit =
			(void *)(long)*(prom_vec + REX_PROM_BOOTINIT);
		__rex_bootread =
			(void *)(long)*(prom_vec + REX_PROM_BOOTREAD);
		__rex_getbitmap =
			(void *)(long)*(prom_vec + REX_PROM_GETBITMAP);
		__prom_getchar =
			(void *)(long)*(prom_vec + REX_PROM_GETCHAR);
		__prom_getenv =
			(void *)(long)*(prom_vec + REX_PROM_GETENV);
		__rex_getsysid =
			(void *)(long)*(prom_vec + REX_PROM_GETSYSID);
		__rex_gettcinfo =
			(void *)(long)*(prom_vec + REX_PROM_GETTCINFO);
		__prom_printf =
			(void *)(long)*(prom_vec + REX_PROM_PRINTF);
		__rex_slot_address =
			(void *)(long)*(prom_vec + REX_PROM_SLOTADDR);
		__rex_clear_cache =
			(void *)(long)*(prom_vec + REX_PROM_CLEARCACHE);
	} else {
		/*
		 * Set up prom abstraction structure with non-REX entry points.
		 */
		__prom_getchar = (void *)PMAX_PROM_GETCHAR;
		__prom_getenv = (void *)PMAX_PROM_GETENV;
		__prom_printf = (void *)PMAX_PROM_PRINTF;
		__pmax_open = (void *)PMAX_PROM_OPEN;
		__pmax_lseek = (void *)PMAX_PROM_LSEEK;
		__pmax_read = (void *)PMAX_PROM_READ;
		__pmax_close = (void *)PMAX_PROM_CLOSE;
	}
}

void __init prom_init(void)
{
	extern void dec_machine_halt(void);
	static char cpu_msg[] __initdata =
		"Sorry, this kernel is compiled for a wrong CPU type!\n";
	static char r3k_msg[] __initdata =
		"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
	static char r4k_msg[] __initdata =
		"Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
	s32 argc = fw_arg0;
	s32 argv = fw_arg1;
	u32 magic = fw_arg2;
	s32 prom_vec = fw_arg3;

	/*
	 * Determine which PROM we have
	 * (and therefore which machine we're on!)
	 */
	which_prom(magic, prom_vec);

	if (prom_is_rex(magic))
		rex_clear_cache();

	/* Register the early console.  */
	register_prom_console();

	/* Were we compiled with the right CPU option? */
#if defined(CONFIG_CPU_R3000)
	if ((current_cpu_data.cputype == CPU_R4000SC) ||
	    (current_cpu_data.cputype == CPU_R4400SC)) {
		printk(cpu_msg);
		printk(r4k_msg);
		dec_machine_halt();
	}
#endif

#if defined(CONFIG_CPU_R4X00)
	if ((current_cpu_data.cputype == CPU_R3000) ||
	    (current_cpu_data.cputype == CPU_R3000A)) {
		printk(cpu_msg);
		printk(r3k_msg);
		dec_machine_halt();
	}
#endif

	prom_meminit(magic);
	prom_identify_arch(magic);
	prom_init_cmdline(argc, argv, magic);
}