diff options
Diffstat (limited to 'arch/m68k/sun3x/prom.c')
-rw-r--r-- | arch/m68k/sun3x/prom.c | 166 |
1 files changed, 166 insertions, 0 deletions
diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c new file mode 100644 index 000000000000..574cf06df9e4 --- /dev/null +++ b/arch/m68k/sun3x/prom.c | |||
@@ -0,0 +1,166 @@ | |||
1 | /* Prom access routines for the sun3x */ | ||
2 | |||
3 | #include <linux/types.h> | ||
4 | #include <linux/kernel.h> | ||
5 | #include <linux/tty.h> | ||
6 | #include <linux/console.h> | ||
7 | #include <linux/init.h> | ||
8 | #include <linux/mm.h> | ||
9 | #include <linux/string.h> | ||
10 | |||
11 | #include <asm/page.h> | ||
12 | #include <asm/pgtable.h> | ||
13 | #include <asm/bootinfo.h> | ||
14 | #include <asm/setup.h> | ||
15 | #include <asm/traps.h> | ||
16 | #include <asm/sun3xprom.h> | ||
17 | #include <asm/idprom.h> | ||
18 | #include <asm/segment.h> | ||
19 | #include <asm/sun3ints.h> | ||
20 | #include <asm/openprom.h> | ||
21 | #include <asm/machines.h> | ||
22 | |||
23 | void (*sun3x_putchar)(int); | ||
24 | int (*sun3x_getchar)(void); | ||
25 | int (*sun3x_mayget)(void); | ||
26 | int (*sun3x_mayput)(int); | ||
27 | void (*sun3x_prom_reboot)(void); | ||
28 | e_vector sun3x_prom_abort; | ||
29 | struct linux_romvec *romvec; | ||
30 | |||
31 | /* prom vector table */ | ||
32 | e_vector *sun3x_prom_vbr; | ||
33 | |||
34 | /* Handle returning to the prom */ | ||
35 | void sun3x_halt(void) | ||
36 | { | ||
37 | unsigned long flags; | ||
38 | |||
39 | /* Disable interrupts while we mess with things */ | ||
40 | local_irq_save(flags); | ||
41 | |||
42 | /* Restore prom vbr */ | ||
43 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); | ||
44 | |||
45 | /* Restore prom NMI clock */ | ||
46 | // sun3x_disable_intreg(5); | ||
47 | sun3_enable_irq(7); | ||
48 | |||
49 | /* Let 'er rip */ | ||
50 | __asm__ volatile ("trap #14" : : ); | ||
51 | |||
52 | /* Restore everything */ | ||
53 | sun3_disable_irq(7); | ||
54 | sun3_enable_irq(5); | ||
55 | |||
56 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)vectors)); | ||
57 | local_irq_restore(flags); | ||
58 | } | ||
59 | |||
60 | void sun3x_reboot(void) | ||
61 | { | ||
62 | /* This never returns, don't bother saving things */ | ||
63 | local_irq_disable(); | ||
64 | |||
65 | /* Restore prom vbr */ | ||
66 | __asm__ volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr)); | ||
67 | |||
68 | /* Restore prom NMI clock */ | ||
69 | sun3_disable_irq(5); | ||
70 | sun3_enable_irq(7); | ||
71 | |||
72 | /* Let 'er rip */ | ||
73 | (*romvec->pv_reboot)("vmlinux"); | ||
74 | } | ||
75 | |||
76 | extern char m68k_debug_device[]; | ||
77 | |||
78 | static void sun3x_prom_write(struct console *co, const char *s, | ||
79 | unsigned int count) | ||
80 | { | ||
81 | while (count--) { | ||
82 | if (*s == '\n') | ||
83 | sun3x_putchar('\r'); | ||
84 | sun3x_putchar(*s++); | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* debug console - write-only */ | ||
89 | |||
90 | static struct console sun3x_debug = { | ||
91 | .name = "debug", | ||
92 | .write = sun3x_prom_write, | ||
93 | .flags = CON_PRINTBUFFER, | ||
94 | .index = -1, | ||
95 | }; | ||
96 | |||
97 | void sun3x_prom_init(void) | ||
98 | { | ||
99 | /* Read the vector table */ | ||
100 | |||
101 | sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR); | ||
102 | sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR); | ||
103 | sun3x_mayget = *(int (**)(void)) (SUN3X_P_MAYGET); | ||
104 | sun3x_mayput = *(int (**)(int)) (SUN3X_P_MAYPUT); | ||
105 | sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT); | ||
106 | sun3x_prom_abort = *(e_vector *) (SUN3X_P_ABORT); | ||
107 | romvec = (struct linux_romvec *)SUN3X_PROM_BASE; | ||
108 | |||
109 | idprom_init(); | ||
110 | |||
111 | if(!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) { | ||
112 | printk("Warning: machine reports strange type %02x\n", | ||
113 | idprom->id_machtype); | ||
114 | printk("Pretending it's a 3/80, but very afraid...\n"); | ||
115 | idprom->id_machtype = SM_SUN3X | SM_3_80; | ||
116 | } | ||
117 | |||
118 | /* point trap #14 at abort. | ||
119 | * XXX this is futile since we restore the vbr first - oops | ||
120 | */ | ||
121 | vectors[VEC_TRAP14] = sun3x_prom_abort; | ||
122 | |||
123 | /* If debug=prom was specified, start the debug console */ | ||
124 | |||
125 | if (!strcmp(m68k_debug_device, "prom")) | ||
126 | register_console(&sun3x_debug); | ||
127 | |||
128 | |||
129 | } | ||
130 | |||
131 | /* some prom functions to export */ | ||
132 | int prom_getintdefault(int node, char *property, int deflt) | ||
133 | { | ||
134 | return deflt; | ||
135 | } | ||
136 | |||
137 | int prom_getbool (int node, char *prop) | ||
138 | { | ||
139 | return 1; | ||
140 | } | ||
141 | |||
142 | void prom_printf(char *fmt, ...) | ||
143 | { | ||
144 | |||
145 | } | ||
146 | |||
147 | void prom_halt (void) | ||
148 | { | ||
149 | sun3x_halt(); | ||
150 | } | ||
151 | |||
152 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | ||
153 | * format type. 'num_bytes' is the number of bytes that your idbuf | ||
154 | * has space for. Returns 0xff on error. | ||
155 | */ | ||
156 | unsigned char | ||
157 | prom_get_idprom(char *idbuf, int num_bytes) | ||
158 | { | ||
159 | int i; | ||
160 | |||
161 | /* make a copy of the idprom structure */ | ||
162 | for(i = 0; i < num_bytes; i++) | ||
163 | idbuf[i] = ((char *)SUN3X_IDPROM)[i]; | ||
164 | |||
165 | return idbuf[0]; | ||
166 | } | ||