diff options
Diffstat (limited to 'arch/m68k/amiga/config.c')
-rw-r--r-- | arch/m68k/amiga/config.c | 1091 |
1 files changed, 545 insertions, 546 deletions
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 3204f412cad8..35748531327d 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c | |||
@@ -22,9 +22,7 @@ | |||
22 | #include <linux/vt_kern.h> | 22 | #include <linux/vt_kern.h> |
23 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
24 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #ifdef CONFIG_ZORRO | ||
26 | #include <linux/zorro.h> | 25 | #include <linux/zorro.h> |
27 | #endif | ||
28 | 26 | ||
29 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
30 | #include <asm/setup.h> | 28 | #include <asm/setup.h> |
@@ -62,55 +60,51 @@ static char s_cdtv[] __initdata = "CDTV"; | |||
62 | static char s_cd32[] __initdata = "CD32"; | 60 | static char s_cd32[] __initdata = "CD32"; |
63 | static char s_draco[] __initdata = "Draco"; | 61 | static char s_draco[] __initdata = "Draco"; |
64 | static char *amiga_models[] __initdata = { | 62 | static char *amiga_models[] __initdata = { |
65 | [AMI_500-AMI_500] = s_a500, | 63 | [AMI_500-AMI_500] = s_a500, |
66 | [AMI_500PLUS-AMI_500] = s_a500p, | 64 | [AMI_500PLUS-AMI_500] = s_a500p, |
67 | [AMI_600-AMI_500] = s_a600, | 65 | [AMI_600-AMI_500] = s_a600, |
68 | [AMI_1000-AMI_500] = s_a1000, | 66 | [AMI_1000-AMI_500] = s_a1000, |
69 | [AMI_1200-AMI_500] = s_a1200, | 67 | [AMI_1200-AMI_500] = s_a1200, |
70 | [AMI_2000-AMI_500] = s_a2000, | 68 | [AMI_2000-AMI_500] = s_a2000, |
71 | [AMI_2500-AMI_500] = s_a2500, | 69 | [AMI_2500-AMI_500] = s_a2500, |
72 | [AMI_3000-AMI_500] = s_a3000, | 70 | [AMI_3000-AMI_500] = s_a3000, |
73 | [AMI_3000T-AMI_500] = s_a3000t, | 71 | [AMI_3000T-AMI_500] = s_a3000t, |
74 | [AMI_3000PLUS-AMI_500] = s_a3000p, | 72 | [AMI_3000PLUS-AMI_500] = s_a3000p, |
75 | [AMI_4000-AMI_500] = s_a4000, | 73 | [AMI_4000-AMI_500] = s_a4000, |
76 | [AMI_4000T-AMI_500] = s_a4000t, | 74 | [AMI_4000T-AMI_500] = s_a4000t, |
77 | [AMI_CDTV-AMI_500] = s_cdtv, | 75 | [AMI_CDTV-AMI_500] = s_cdtv, |
78 | [AMI_CD32-AMI_500] = s_cd32, | 76 | [AMI_CD32-AMI_500] = s_cd32, |
79 | [AMI_DRACO-AMI_500] = s_draco, | 77 | [AMI_DRACO-AMI_500] = s_draco, |
80 | }; | 78 | }; |
81 | 79 | ||
82 | static char amiga_model_name[13] = "Amiga "; | 80 | static char amiga_model_name[13] = "Amiga "; |
83 | 81 | ||
84 | extern char m68k_debug_device[]; | ||
85 | |||
86 | static void amiga_sched_init(irq_handler_t handler); | 82 | static void amiga_sched_init(irq_handler_t handler); |
87 | /* amiga specific irq functions */ | 83 | /* amiga specific irq functions */ |
88 | extern void amiga_init_IRQ (void); | 84 | extern void amiga_init_IRQ(void); |
89 | static void amiga_get_model(char *model); | 85 | static void amiga_get_model(char *model); |
90 | static int amiga_get_hardware_list(char *buffer); | 86 | static int amiga_get_hardware_list(char *buffer); |
91 | /* amiga specific timer functions */ | 87 | /* amiga specific timer functions */ |
92 | static unsigned long amiga_gettimeoffset (void); | 88 | static unsigned long amiga_gettimeoffset(void); |
93 | static int a3000_hwclk (int, struct rtc_time *); | 89 | static int a3000_hwclk(int, struct rtc_time *); |
94 | static int a2000_hwclk (int, struct rtc_time *); | 90 | static int a2000_hwclk(int, struct rtc_time *); |
95 | static int amiga_set_clock_mmss (unsigned long); | 91 | static int amiga_set_clock_mmss(unsigned long); |
96 | static unsigned int amiga_get_ss (void); | 92 | static unsigned int amiga_get_ss(void); |
97 | extern void amiga_mksound( unsigned int count, unsigned int ticks ); | 93 | extern void amiga_mksound(unsigned int count, unsigned int ticks); |
98 | static void amiga_reset (void); | 94 | static void amiga_reset(void); |
99 | extern void amiga_init_sound(void); | 95 | extern void amiga_init_sound(void); |
100 | static void amiga_savekmsg_init(void); | ||
101 | static void amiga_mem_console_write(struct console *co, const char *b, | 96 | static void amiga_mem_console_write(struct console *co, const char *b, |
102 | unsigned int count); | 97 | unsigned int count); |
103 | void amiga_serial_console_write(struct console *co, const char *s, | 98 | void amiga_serial_console_write(struct console *co, const char *s, |
104 | unsigned int count); | 99 | unsigned int count); |
105 | static void amiga_debug_init(void); | ||
106 | #ifdef CONFIG_HEARTBEAT | 100 | #ifdef CONFIG_HEARTBEAT |
107 | static void amiga_heartbeat(int on); | 101 | static void amiga_heartbeat(int on); |
108 | #endif | 102 | #endif |
109 | 103 | ||
110 | static struct console amiga_console_driver = { | 104 | static struct console amiga_console_driver = { |
111 | .name = "debug", | 105 | .name = "debug", |
112 | .flags = CON_PRINTBUFFER, | 106 | .flags = CON_PRINTBUFFER, |
113 | .index = -1, | 107 | .index = -1, |
114 | }; | 108 | }; |
115 | 109 | ||
116 | 110 | ||
@@ -119,24 +113,24 @@ static struct console amiga_console_driver = { | |||
119 | */ | 113 | */ |
120 | 114 | ||
121 | static struct { | 115 | static struct { |
122 | struct resource _ciab, _ciaa, _custom, _kickstart; | 116 | struct resource _ciab, _ciaa, _custom, _kickstart; |
123 | } mb_resources = { | 117 | } mb_resources = { |
124 | ._ciab = { | 118 | ._ciab = { |
125 | .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff | 119 | .name = "CIA B", .start = 0x00bfd000, .end = 0x00bfdfff |
126 | }, | 120 | }, |
127 | ._ciaa = { | 121 | ._ciaa = { |
128 | .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff | 122 | .name = "CIA A", .start = 0x00bfe000, .end = 0x00bfefff |
129 | }, | 123 | }, |
130 | ._custom = { | 124 | ._custom = { |
131 | .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff | 125 | .name = "Custom I/O", .start = 0x00dff000, .end = 0x00dfffff |
132 | }, | 126 | }, |
133 | ._kickstart = { | 127 | ._kickstart = { |
134 | .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff | 128 | .name = "Kickstart ROM", .start = 0x00f80000, .end = 0x00ffffff |
135 | } | 129 | } |
136 | }; | 130 | }; |
137 | 131 | ||
138 | static struct resource rtc_resource = { | 132 | static struct resource rtc_resource = { |
139 | .start = 0x00dc0000, .end = 0x00dcffff | 133 | .start = 0x00dc0000, .end = 0x00dcffff |
140 | }; | 134 | }; |
141 | 135 | ||
142 | static struct resource ram_resource[NUM_MEMINFO]; | 136 | static struct resource ram_resource[NUM_MEMINFO]; |
@@ -148,57 +142,57 @@ static struct resource ram_resource[NUM_MEMINFO]; | |||
148 | 142 | ||
149 | int amiga_parse_bootinfo(const struct bi_record *record) | 143 | int amiga_parse_bootinfo(const struct bi_record *record) |
150 | { | 144 | { |
151 | int unknown = 0; | 145 | int unknown = 0; |
152 | const unsigned long *data = record->data; | 146 | const unsigned long *data = record->data; |
153 | 147 | ||
154 | switch (record->tag) { | 148 | switch (record->tag) { |
155 | case BI_AMIGA_MODEL: | 149 | case BI_AMIGA_MODEL: |
156 | amiga_model = *data; | 150 | amiga_model = *data; |
157 | break; | 151 | break; |
158 | 152 | ||
159 | case BI_AMIGA_ECLOCK: | 153 | case BI_AMIGA_ECLOCK: |
160 | amiga_eclock = *data; | 154 | amiga_eclock = *data; |
161 | break; | 155 | break; |
162 | 156 | ||
163 | case BI_AMIGA_CHIPSET: | 157 | case BI_AMIGA_CHIPSET: |
164 | amiga_chipset = *data; | 158 | amiga_chipset = *data; |
165 | break; | 159 | break; |
166 | 160 | ||
167 | case BI_AMIGA_CHIP_SIZE: | 161 | case BI_AMIGA_CHIP_SIZE: |
168 | amiga_chip_size = *(const int *)data; | 162 | amiga_chip_size = *(const int *)data; |
169 | break; | 163 | break; |
170 | 164 | ||
171 | case BI_AMIGA_VBLANK: | 165 | case BI_AMIGA_VBLANK: |
172 | amiga_vblank = *(const unsigned char *)data; | 166 | amiga_vblank = *(const unsigned char *)data; |
173 | break; | 167 | break; |
174 | 168 | ||
175 | case BI_AMIGA_PSFREQ: | 169 | case BI_AMIGA_PSFREQ: |
176 | amiga_psfreq = *(const unsigned char *)data; | 170 | amiga_psfreq = *(const unsigned char *)data; |
177 | break; | 171 | break; |
178 | 172 | ||
179 | case BI_AMIGA_AUTOCON: | 173 | case BI_AMIGA_AUTOCON: |
180 | #ifdef CONFIG_ZORRO | 174 | #ifdef CONFIG_ZORRO |
181 | if (zorro_num_autocon < ZORRO_NUM_AUTO) { | 175 | if (zorro_num_autocon < ZORRO_NUM_AUTO) { |
182 | const struct ConfigDev *cd = (struct ConfigDev *)data; | 176 | const struct ConfigDev *cd = (struct ConfigDev *)data; |
183 | struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; | 177 | struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; |
184 | dev->rom = cd->cd_Rom; | 178 | dev->rom = cd->cd_Rom; |
185 | dev->slotaddr = cd->cd_SlotAddr; | 179 | dev->slotaddr = cd->cd_SlotAddr; |
186 | dev->slotsize = cd->cd_SlotSize; | 180 | dev->slotsize = cd->cd_SlotSize; |
187 | dev->resource.start = (unsigned long)cd->cd_BoardAddr; | 181 | dev->resource.start = (unsigned long)cd->cd_BoardAddr; |
188 | dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; | 182 | dev->resource.end = dev->resource.start + cd->cd_BoardSize - 1; |
189 | } else | 183 | } else |
190 | printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); | 184 | printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); |
191 | #endif /* CONFIG_ZORRO */ | 185 | #endif /* CONFIG_ZORRO */ |
192 | break; | 186 | break; |
193 | 187 | ||
194 | case BI_AMIGA_SERPER: | 188 | case BI_AMIGA_SERPER: |
195 | /* serial port period: ignored here */ | 189 | /* serial port period: ignored here */ |
196 | break; | 190 | break; |
197 | 191 | ||
198 | default: | 192 | default: |
199 | unknown = 1; | 193 | unknown = 1; |
200 | } | 194 | } |
201 | return(unknown); | 195 | return unknown; |
202 | } | 196 | } |
203 | 197 | ||
204 | /* | 198 | /* |
@@ -207,159 +201,159 @@ int amiga_parse_bootinfo(const struct bi_record *record) | |||
207 | 201 | ||
208 | static void __init amiga_identify(void) | 202 | static void __init amiga_identify(void) |
209 | { | 203 | { |
210 | /* Fill in some default values, if necessary */ | 204 | /* Fill in some default values, if necessary */ |
211 | if (amiga_eclock == 0) | 205 | if (amiga_eclock == 0) |
212 | amiga_eclock = 709379; | 206 | amiga_eclock = 709379; |
213 | |||
214 | memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); | ||
215 | |||
216 | printk("Amiga hardware found: "); | ||
217 | if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { | ||
218 | printk("[%s] ", amiga_models[amiga_model-AMI_500]); | ||
219 | strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); | ||
220 | } | ||
221 | |||
222 | switch(amiga_model) { | ||
223 | case AMI_UNKNOWN: | ||
224 | goto Generic; | ||
225 | |||
226 | case AMI_600: | ||
227 | case AMI_1200: | ||
228 | AMIGAHW_SET(A1200_IDE); | ||
229 | AMIGAHW_SET(PCMCIA); | ||
230 | case AMI_500: | ||
231 | case AMI_500PLUS: | ||
232 | case AMI_1000: | ||
233 | case AMI_2000: | ||
234 | case AMI_2500: | ||
235 | AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ | ||
236 | goto Generic; | ||
237 | |||
238 | case AMI_3000: | ||
239 | case AMI_3000T: | ||
240 | AMIGAHW_SET(AMBER_FF); | ||
241 | AMIGAHW_SET(MAGIC_REKICK); | ||
242 | /* fall through */ | ||
243 | case AMI_3000PLUS: | ||
244 | AMIGAHW_SET(A3000_SCSI); | ||
245 | AMIGAHW_SET(A3000_CLK); | ||
246 | AMIGAHW_SET(ZORRO3); | ||
247 | goto Generic; | ||
248 | |||
249 | case AMI_4000T: | ||
250 | AMIGAHW_SET(A4000_SCSI); | ||
251 | /* fall through */ | ||
252 | case AMI_4000: | ||
253 | AMIGAHW_SET(A4000_IDE); | ||
254 | AMIGAHW_SET(A3000_CLK); | ||
255 | AMIGAHW_SET(ZORRO3); | ||
256 | goto Generic; | ||
257 | |||
258 | case AMI_CDTV: | ||
259 | case AMI_CD32: | ||
260 | AMIGAHW_SET(CD_ROM); | ||
261 | AMIGAHW_SET(A2000_CLK); /* Is this correct? */ | ||
262 | goto Generic; | ||
263 | |||
264 | Generic: | ||
265 | AMIGAHW_SET(AMI_VIDEO); | ||
266 | AMIGAHW_SET(AMI_BLITTER); | ||
267 | AMIGAHW_SET(AMI_AUDIO); | ||
268 | AMIGAHW_SET(AMI_FLOPPY); | ||
269 | AMIGAHW_SET(AMI_KEYBOARD); | ||
270 | AMIGAHW_SET(AMI_MOUSE); | ||
271 | AMIGAHW_SET(AMI_SERIAL); | ||
272 | AMIGAHW_SET(AMI_PARALLEL); | ||
273 | AMIGAHW_SET(CHIP_RAM); | ||
274 | AMIGAHW_SET(PAULA); | ||
275 | |||
276 | switch(amiga_chipset) { | ||
277 | case CS_OCS: | ||
278 | case CS_ECS: | ||
279 | case CS_AGA: | ||
280 | switch (amiga_custom.deniseid & 0xf) { | ||
281 | case 0x0c: | ||
282 | AMIGAHW_SET(DENISE_HR); | ||
283 | break; | ||
284 | case 0x08: | ||
285 | AMIGAHW_SET(LISA); | ||
286 | break; | ||
287 | } | ||
288 | break; | ||
289 | default: | ||
290 | AMIGAHW_SET(DENISE); | ||
291 | break; | ||
292 | } | ||
293 | switch ((amiga_custom.vposr>>8) & 0x7f) { | ||
294 | case 0x00: | ||
295 | AMIGAHW_SET(AGNUS_PAL); | ||
296 | break; | ||
297 | case 0x10: | ||
298 | AMIGAHW_SET(AGNUS_NTSC); | ||
299 | break; | ||
300 | case 0x20: | ||
301 | case 0x21: | ||
302 | AMIGAHW_SET(AGNUS_HR_PAL); | ||
303 | break; | ||
304 | case 0x30: | ||
305 | case 0x31: | ||
306 | AMIGAHW_SET(AGNUS_HR_NTSC); | ||
307 | break; | ||
308 | case 0x22: | ||
309 | case 0x23: | ||
310 | AMIGAHW_SET(ALICE_PAL); | ||
311 | break; | ||
312 | case 0x32: | ||
313 | case 0x33: | ||
314 | AMIGAHW_SET(ALICE_NTSC); | ||
315 | break; | ||
316 | } | ||
317 | AMIGAHW_SET(ZORRO); | ||
318 | break; | ||
319 | |||
320 | case AMI_DRACO: | ||
321 | panic("No support for Draco yet"); | ||
322 | |||
323 | default: | ||
324 | panic("Unknown Amiga Model"); | ||
325 | } | ||
326 | 207 | ||
327 | #define AMIGAHW_ANNOUNCE(name, str) \ | 208 | memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); |
328 | if (AMIGAHW_PRESENT(name)) \ | 209 | |
329 | printk(str) | 210 | printk("Amiga hardware found: "); |
330 | 211 | if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { | |
331 | AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); | 212 | printk("[%s] ", amiga_models[amiga_model-AMI_500]); |
332 | AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); | 213 | strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); |
333 | AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); | 214 | } |
334 | AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); | 215 | |
335 | AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); | 216 | switch (amiga_model) { |
336 | AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); | 217 | case AMI_UNKNOWN: |
337 | AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); | 218 | goto Generic; |
338 | AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); | 219 | |
339 | AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); | 220 | case AMI_600: |
340 | AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); | 221 | case AMI_1200: |
341 | AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); | 222 | AMIGAHW_SET(A1200_IDE); |
342 | AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); | 223 | AMIGAHW_SET(PCMCIA); |
343 | AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); | 224 | case AMI_500: |
344 | AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); | 225 | case AMI_500PLUS: |
345 | AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); | 226 | case AMI_1000: |
346 | AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); | 227 | case AMI_2000: |
347 | AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); | 228 | case AMI_2500: |
348 | AMIGAHW_ANNOUNCE(PAULA, "PAULA "); | 229 | AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ |
349 | AMIGAHW_ANNOUNCE(DENISE, "DENISE "); | 230 | goto Generic; |
350 | AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); | 231 | |
351 | AMIGAHW_ANNOUNCE(LISA, "LISA "); | 232 | case AMI_3000: |
352 | AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); | 233 | case AMI_3000T: |
353 | AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); | 234 | AMIGAHW_SET(AMBER_FF); |
354 | AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); | 235 | AMIGAHW_SET(MAGIC_REKICK); |
355 | AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); | 236 | /* fall through */ |
356 | AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); | 237 | case AMI_3000PLUS: |
357 | AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); | 238 | AMIGAHW_SET(A3000_SCSI); |
358 | AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); | 239 | AMIGAHW_SET(A3000_CLK); |
359 | AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); | 240 | AMIGAHW_SET(ZORRO3); |
360 | if (AMIGAHW_PRESENT(ZORRO)) | 241 | goto Generic; |
361 | printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); | 242 | |
362 | printk("\n"); | 243 | case AMI_4000T: |
244 | AMIGAHW_SET(A4000_SCSI); | ||
245 | /* fall through */ | ||
246 | case AMI_4000: | ||
247 | AMIGAHW_SET(A4000_IDE); | ||
248 | AMIGAHW_SET(A3000_CLK); | ||
249 | AMIGAHW_SET(ZORRO3); | ||
250 | goto Generic; | ||
251 | |||
252 | case AMI_CDTV: | ||
253 | case AMI_CD32: | ||
254 | AMIGAHW_SET(CD_ROM); | ||
255 | AMIGAHW_SET(A2000_CLK); /* Is this correct? */ | ||
256 | goto Generic; | ||
257 | |||
258 | Generic: | ||
259 | AMIGAHW_SET(AMI_VIDEO); | ||
260 | AMIGAHW_SET(AMI_BLITTER); | ||
261 | AMIGAHW_SET(AMI_AUDIO); | ||
262 | AMIGAHW_SET(AMI_FLOPPY); | ||
263 | AMIGAHW_SET(AMI_KEYBOARD); | ||
264 | AMIGAHW_SET(AMI_MOUSE); | ||
265 | AMIGAHW_SET(AMI_SERIAL); | ||
266 | AMIGAHW_SET(AMI_PARALLEL); | ||
267 | AMIGAHW_SET(CHIP_RAM); | ||
268 | AMIGAHW_SET(PAULA); | ||
269 | |||
270 | switch (amiga_chipset) { | ||
271 | case CS_OCS: | ||
272 | case CS_ECS: | ||
273 | case CS_AGA: | ||
274 | switch (amiga_custom.deniseid & 0xf) { | ||
275 | case 0x0c: | ||
276 | AMIGAHW_SET(DENISE_HR); | ||
277 | break; | ||
278 | case 0x08: | ||
279 | AMIGAHW_SET(LISA); | ||
280 | break; | ||
281 | } | ||
282 | break; | ||
283 | default: | ||
284 | AMIGAHW_SET(DENISE); | ||
285 | break; | ||
286 | } | ||
287 | switch ((amiga_custom.vposr>>8) & 0x7f) { | ||
288 | case 0x00: | ||
289 | AMIGAHW_SET(AGNUS_PAL); | ||
290 | break; | ||
291 | case 0x10: | ||
292 | AMIGAHW_SET(AGNUS_NTSC); | ||
293 | break; | ||
294 | case 0x20: | ||
295 | case 0x21: | ||
296 | AMIGAHW_SET(AGNUS_HR_PAL); | ||
297 | break; | ||
298 | case 0x30: | ||
299 | case 0x31: | ||
300 | AMIGAHW_SET(AGNUS_HR_NTSC); | ||
301 | break; | ||
302 | case 0x22: | ||
303 | case 0x23: | ||
304 | AMIGAHW_SET(ALICE_PAL); | ||
305 | break; | ||
306 | case 0x32: | ||
307 | case 0x33: | ||
308 | AMIGAHW_SET(ALICE_NTSC); | ||
309 | break; | ||
310 | } | ||
311 | AMIGAHW_SET(ZORRO); | ||
312 | break; | ||
313 | |||
314 | case AMI_DRACO: | ||
315 | panic("No support for Draco yet"); | ||
316 | |||
317 | default: | ||
318 | panic("Unknown Amiga Model"); | ||
319 | } | ||
320 | |||
321 | #define AMIGAHW_ANNOUNCE(name, str) \ | ||
322 | if (AMIGAHW_PRESENT(name)) \ | ||
323 | printk(str) | ||
324 | |||
325 | AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); | ||
326 | AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); | ||
327 | AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); | ||
328 | AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); | ||
329 | AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); | ||
330 | AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); | ||
331 | AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); | ||
332 | AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); | ||
333 | AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); | ||
334 | AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); | ||
335 | AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); | ||
336 | AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); | ||
337 | AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); | ||
338 | AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); | ||
339 | AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); | ||
340 | AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); | ||
341 | AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); | ||
342 | AMIGAHW_ANNOUNCE(PAULA, "PAULA "); | ||
343 | AMIGAHW_ANNOUNCE(DENISE, "DENISE "); | ||
344 | AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); | ||
345 | AMIGAHW_ANNOUNCE(LISA, "LISA "); | ||
346 | AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); | ||
347 | AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); | ||
348 | AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); | ||
349 | AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); | ||
350 | AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); | ||
351 | AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); | ||
352 | AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); | ||
353 | AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); | ||
354 | if (AMIGAHW_PRESENT(ZORRO)) | ||
355 | printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); | ||
356 | printk("\n"); | ||
363 | 357 | ||
364 | #undef AMIGAHW_ANNOUNCE | 358 | #undef AMIGAHW_ANNOUNCE |
365 | } | 359 | } |
@@ -370,119 +364,105 @@ static void __init amiga_identify(void) | |||
370 | 364 | ||
371 | void __init config_amiga(void) | 365 | void __init config_amiga(void) |
372 | { | 366 | { |
373 | int i; | 367 | int i; |
374 | 368 | ||
375 | amiga_debug_init(); | 369 | amiga_identify(); |
376 | amiga_identify(); | 370 | |
377 | 371 | /* Yuk, we don't have PCI memory */ | |
378 | /* Yuk, we don't have PCI memory */ | 372 | iomem_resource.name = "Memory"; |
379 | iomem_resource.name = "Memory"; | 373 | for (i = 0; i < 4; i++) |
380 | for (i = 0; i < 4; i++) | 374 | request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); |
381 | request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); | 375 | |
382 | 376 | mach_sched_init = amiga_sched_init; | |
383 | mach_sched_init = amiga_sched_init; | 377 | mach_init_IRQ = amiga_init_IRQ; |
384 | mach_init_IRQ = amiga_init_IRQ; | 378 | mach_get_model = amiga_get_model; |
385 | mach_get_model = amiga_get_model; | 379 | mach_get_hardware_list = amiga_get_hardware_list; |
386 | mach_get_hardware_list = amiga_get_hardware_list; | 380 | mach_gettimeoffset = amiga_gettimeoffset; |
387 | mach_gettimeoffset = amiga_gettimeoffset; | 381 | if (AMIGAHW_PRESENT(A3000_CLK)) { |
388 | if (AMIGAHW_PRESENT(A3000_CLK)){ | 382 | mach_hwclk = a3000_hwclk; |
389 | mach_hwclk = a3000_hwclk; | 383 | rtc_resource.name = "A3000 RTC"; |
390 | rtc_resource.name = "A3000 RTC"; | 384 | request_resource(&iomem_resource, &rtc_resource); |
391 | request_resource(&iomem_resource, &rtc_resource); | 385 | } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { |
392 | } | 386 | mach_hwclk = a2000_hwclk; |
393 | else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ | 387 | rtc_resource.name = "A2000 RTC"; |
394 | mach_hwclk = a2000_hwclk; | 388 | request_resource(&iomem_resource, &rtc_resource); |
395 | rtc_resource.name = "A2000 RTC"; | 389 | } |
396 | request_resource(&iomem_resource, &rtc_resource); | 390 | |
397 | } | 391 | /* |
398 | 392 | * default MAX_DMA=0xffffffff on all machines. If we don't do so, the SCSI | |
399 | mach_max_dma_address = 0xffffffff; /* | 393 | * code will not be able to allocate any mem for transfers, unless we are |
400 | * default MAX_DMA=0xffffffff | 394 | * dealing with a Z2 mem only system. /Jes |
401 | * on all machines. If we don't | 395 | */ |
402 | * do so, the SCSI code will not | 396 | mach_max_dma_address = 0xffffffff; |
403 | * be able to allocate any mem | 397 | |
404 | * for transfers, unless we are | 398 | mach_set_clock_mmss = amiga_set_clock_mmss; |
405 | * dealing with a Z2 mem only | 399 | mach_get_ss = amiga_get_ss; |
406 | * system. /Jes | 400 | mach_reset = amiga_reset; |
407 | */ | ||
408 | |||
409 | mach_set_clock_mmss = amiga_set_clock_mmss; | ||
410 | mach_get_ss = amiga_get_ss; | ||
411 | mach_reset = amiga_reset; | ||
412 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) | 401 | #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE) |
413 | mach_beep = amiga_mksound; | 402 | mach_beep = amiga_mksound; |
414 | #endif | 403 | #endif |
415 | 404 | ||
416 | #ifdef CONFIG_HEARTBEAT | 405 | #ifdef CONFIG_HEARTBEAT |
417 | mach_heartbeat = amiga_heartbeat; | 406 | mach_heartbeat = amiga_heartbeat; |
418 | #endif | 407 | #endif |
419 | 408 | ||
420 | /* Fill in the clock values (based on the 700 kHz E-Clock) */ | 409 | /* Fill in the clock values (based on the 700 kHz E-Clock) */ |
421 | amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ | 410 | amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ |
422 | amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ | 411 | amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ |
423 | 412 | ||
424 | /* clear all DMA bits */ | 413 | /* clear all DMA bits */ |
425 | amiga_custom.dmacon = DMAF_ALL; | 414 | amiga_custom.dmacon = DMAF_ALL; |
426 | /* ensure that the DMA master bit is set */ | 415 | /* ensure that the DMA master bit is set */ |
427 | amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; | 416 | amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; |
428 | 417 | ||
429 | /* don't use Z2 RAM as system memory on Z3 capable machines */ | 418 | /* don't use Z2 RAM as system memory on Z3 capable machines */ |
430 | if (AMIGAHW_PRESENT(ZORRO3)) { | 419 | if (AMIGAHW_PRESENT(ZORRO3)) { |
431 | int i, j; | 420 | int i, j; |
432 | u32 disabled_z2mem = 0; | 421 | u32 disabled_z2mem = 0; |
433 | for (i = 0; i < m68k_num_memory; i++) | 422 | |
434 | if (m68k_memory[i].addr < 16*1024*1024) { | 423 | for (i = 0; i < m68k_num_memory; i++) { |
435 | if (i == 0) { | 424 | if (m68k_memory[i].addr < 16*1024*1024) { |
436 | /* don't cut off the branch we're sitting on */ | 425 | if (i == 0) { |
437 | printk("Warning: kernel runs in Zorro II memory\n"); | 426 | /* don't cut off the branch we're sitting on */ |
438 | continue; | 427 | printk("Warning: kernel runs in Zorro II memory\n"); |
428 | continue; | ||
429 | } | ||
430 | disabled_z2mem += m68k_memory[i].size; | ||
431 | m68k_num_memory--; | ||
432 | for (j = i; j < m68k_num_memory; j++) | ||
433 | m68k_memory[j] = m68k_memory[j+1]; | ||
434 | i--; | ||
435 | } | ||
436 | } | ||
437 | if (disabled_z2mem) | ||
438 | printk("%dK of Zorro II memory will not be used as system memory\n", | ||
439 | disabled_z2mem>>10); | ||
439 | } | 440 | } |
440 | disabled_z2mem += m68k_memory[i].size; | 441 | |
441 | m68k_num_memory--; | 442 | /* request all RAM */ |
442 | for (j = i; j < m68k_num_memory; j++) | 443 | for (i = 0; i < m68k_num_memory; i++) { |
443 | m68k_memory[j] = m68k_memory[j+1]; | 444 | ram_resource[i].name = |
444 | i--; | 445 | (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : |
445 | } | 446 | (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : |
446 | if (disabled_z2mem) | 447 | "16-bit Slow RAM"; |
447 | printk("%dK of Zorro II memory will not be used as system memory\n", | 448 | ram_resource[i].start = m68k_memory[i].addr; |
448 | disabled_z2mem>>10); | 449 | ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; |
449 | } | 450 | request_resource(&iomem_resource, &ram_resource[i]); |
450 | 451 | } | |
451 | /* request all RAM */ | 452 | |
452 | for (i = 0; i < m68k_num_memory; i++) { | 453 | /* initialize chipram allocator */ |
453 | ram_resource[i].name = | 454 | amiga_chip_init(); |
454 | (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : | 455 | |
455 | (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : | 456 | /* our beloved beeper */ |
456 | "16-bit Slow RAM"; | 457 | if (AMIGAHW_PRESENT(AMI_AUDIO)) |
457 | ram_resource[i].start = m68k_memory[i].addr; | 458 | amiga_init_sound(); |
458 | ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; | 459 | |
459 | request_resource(&iomem_resource, &ram_resource[i]); | 460 | /* |
460 | } | 461 | * if it is an A3000, set the magic bit that forces |
461 | 462 | * a hard rekick | |
462 | /* initialize chipram allocator */ | 463 | */ |
463 | amiga_chip_init (); | 464 | if (AMIGAHW_PRESENT(MAGIC_REKICK)) |
464 | 465 | *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; | |
465 | /* debugging using chipram */ | ||
466 | if (!strcmp( m68k_debug_device, "mem" )){ | ||
467 | if (!AMIGAHW_PRESENT(CHIP_RAM)) | ||
468 | printk("Warning: no chipram present for debugging\n"); | ||
469 | else { | ||
470 | amiga_savekmsg_init(); | ||
471 | amiga_console_driver.write = amiga_mem_console_write; | ||
472 | register_console(&amiga_console_driver); | ||
473 | } | ||
474 | } | ||
475 | |||
476 | /* our beloved beeper */ | ||
477 | if (AMIGAHW_PRESENT(AMI_AUDIO)) | ||
478 | amiga_init_sound(); | ||
479 | |||
480 | /* | ||
481 | * if it is an A3000, set the magic bit that forces | ||
482 | * a hard rekick | ||
483 | */ | ||
484 | if (AMIGAHW_PRESENT(MAGIC_REKICK)) | ||
485 | *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; | ||
486 | } | 466 | } |
487 | 467 | ||
488 | static unsigned short jiffy_ticks; | 468 | static unsigned short jiffy_ticks; |
@@ -490,12 +470,12 @@ static unsigned short jiffy_ticks; | |||
490 | static void __init amiga_sched_init(irq_handler_t timer_routine) | 470 | static void __init amiga_sched_init(irq_handler_t timer_routine) |
491 | { | 471 | { |
492 | static struct resource sched_res = { | 472 | static struct resource sched_res = { |
493 | .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, | 473 | .name = "timer", .start = 0x00bfd400, .end = 0x00bfd5ff, |
494 | }; | 474 | }; |
495 | jiffy_ticks = (amiga_eclock+HZ/2)/HZ; | 475 | jiffy_ticks = (amiga_eclock+HZ/2)/HZ; |
496 | 476 | ||
497 | if (request_resource(&mb_resources._ciab, &sched_res)) | 477 | if (request_resource(&mb_resources._ciab, &sched_res)) |
498 | printk("Cannot allocate ciab.ta{lo,hi}\n"); | 478 | printk("Cannot allocate ciab.ta{lo,hi}\n"); |
499 | ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ | 479 | ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ |
500 | ciab.talo = jiffy_ticks % 256; | 480 | ciab.talo = jiffy_ticks % 256; |
501 | ciab.tahi = jiffy_ticks / 256; | 481 | ciab.tahi = jiffy_ticks / 256; |
@@ -513,7 +493,7 @@ static void __init amiga_sched_init(irq_handler_t timer_routine) | |||
513 | #define TICK_SIZE 10000 | 493 | #define TICK_SIZE 10000 |
514 | 494 | ||
515 | /* This is always executed with interrupts disabled. */ | 495 | /* This is always executed with interrupts disabled. */ |
516 | static unsigned long amiga_gettimeoffset (void) | 496 | static unsigned long amiga_gettimeoffset(void) |
517 | { | 497 | { |
518 | unsigned short hi, lo, hi2; | 498 | unsigned short hi, lo, hi2; |
519 | unsigned long ticks, offset = 0; | 499 | unsigned long ticks, offset = 0; |
@@ -585,15 +565,15 @@ static int a2000_hwclk(int op, struct rtc_time *t) | |||
585 | 565 | ||
586 | tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; | 566 | tod_2000.cntrl1 = TOD2000_CNTRL1_HOLD; |
587 | 567 | ||
588 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) | 568 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { |
589 | { | 569 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; |
590 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; | 570 | udelay(70); |
591 | udelay(70); | 571 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
592 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | ||
593 | } | 572 | } |
594 | 573 | ||
595 | if (!cnt) | 574 | if (!cnt) |
596 | printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", tod_2000.cntrl1); | 575 | printk(KERN_INFO "hwclk: timed out waiting for RTC (0x%x)\n", |
576 | tod_2000.cntrl1); | ||
597 | 577 | ||
598 | if (!op) { /* read */ | 578 | if (!op) { /* read */ |
599 | t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; | 579 | t->tm_sec = tod_2000.second1 * 10 + tod_2000.second2; |
@@ -606,7 +586,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) | |||
606 | if (t->tm_year <= 69) | 586 | if (t->tm_year <= 69) |
607 | t->tm_year += 100; | 587 | t->tm_year += 100; |
608 | 588 | ||
609 | if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)){ | 589 | if (!(tod_2000.cntrl3 & TOD2000_CNTRL3_24HMODE)) { |
610 | if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) | 590 | if (!(tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour == 12) |
611 | t->tm_hour = 0; | 591 | t->tm_hour = 0; |
612 | else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) | 592 | else if ((tod_2000.hour1 & TOD2000_HOUR1_PM) && t->tm_hour != 12) |
@@ -642,7 +622,7 @@ static int a2000_hwclk(int op, struct rtc_time *t) | |||
642 | return 0; | 622 | return 0; |
643 | } | 623 | } |
644 | 624 | ||
645 | static int amiga_set_clock_mmss (unsigned long nowtime) | 625 | static int amiga_set_clock_mmss(unsigned long nowtime) |
646 | { | 626 | { |
647 | short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; | 627 | short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; |
648 | 628 | ||
@@ -660,8 +640,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime) | |||
660 | 640 | ||
661 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | 641 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
662 | 642 | ||
663 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) | 643 | while ((tod_2000.cntrl1 & TOD2000_CNTRL1_BUSY) && cnt--) { |
664 | { | ||
665 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; | 644 | tod_2000.cntrl1 &= ~TOD2000_CNTRL1_HOLD; |
666 | udelay(70); | 645 | udelay(70); |
667 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; | 646 | tod_2000.cntrl1 |= TOD2000_CNTRL1_HOLD; |
@@ -681,7 +660,7 @@ static int amiga_set_clock_mmss (unsigned long nowtime) | |||
681 | return 0; | 660 | return 0; |
682 | } | 661 | } |
683 | 662 | ||
684 | static unsigned int amiga_get_ss( void ) | 663 | static unsigned int amiga_get_ss(void) |
685 | { | 664 | { |
686 | unsigned int s; | 665 | unsigned int s; |
687 | 666 | ||
@@ -695,71 +674,72 @@ static unsigned int amiga_get_ss( void ) | |||
695 | return s; | 674 | return s; |
696 | } | 675 | } |
697 | 676 | ||
698 | static NORET_TYPE void amiga_reset( void ) | 677 | static NORET_TYPE void amiga_reset(void) |
699 | ATTRIB_NORET; | 678 | ATTRIB_NORET; |
700 | 679 | ||
701 | static void amiga_reset (void) | 680 | static void amiga_reset(void) |
702 | { | 681 | { |
703 | unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); | 682 | unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040); |
704 | unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); | 683 | unsigned long jmp_addr = virt_to_phys(&&jmp_addr_label); |
705 | 684 | ||
706 | local_irq_disable(); | 685 | local_irq_disable(); |
707 | if (CPU_IS_040_OR_060) | 686 | if (CPU_IS_040_OR_060) |
708 | /* Setup transparent translation registers for mapping | 687 | /* Setup transparent translation registers for mapping |
709 | * of 16 MB kernel segment before disabling translation | 688 | * of 16 MB kernel segment before disabling translation |
710 | */ | 689 | */ |
711 | __asm__ __volatile__ | 690 | asm volatile ("\n" |
712 | ("movel %0,%/d0\n\t" | 691 | " move.l %0,%%d0\n" |
713 | "andl #0xff000000,%/d0\n\t" | 692 | " and.l #0xff000000,%%d0\n" |
714 | "orw #0xe020,%/d0\n\t" /* map 16 MB, enable, cacheable */ | 693 | " or.w #0xe020,%%d0\n" /* map 16 MB, enable, cacheable */ |
715 | ".chip 68040\n\t" | 694 | " .chip 68040\n" |
716 | "movec %%d0,%%itt0\n\t" | 695 | " movec %%d0,%%itt0\n" |
717 | "movec %%d0,%%dtt0\n\t" | 696 | " movec %%d0,%%dtt0\n" |
718 | ".chip 68k\n\t" | 697 | " .chip 68k\n" |
719 | "jmp %0@\n\t" | 698 | " jmp %0@\n" |
720 | : /* no outputs */ | 699 | : /* no outputs */ |
721 | : "a" (jmp_addr040)); | 700 | : "a" (jmp_addr040) |
722 | else | 701 | : "d0"); |
723 | /* for 680[23]0, just disable translation and jump to the physical | 702 | else |
724 | * address of the label | 703 | /* for 680[23]0, just disable translation and jump to the physical |
725 | */ | 704 | * address of the label |
726 | __asm__ __volatile__ | 705 | */ |
727 | ("pmove %/tc,%@\n\t" | 706 | asm volatile ("\n" |
728 | "bclr #7,%@\n\t" | 707 | " pmove %%tc,%@\n" |
729 | "pmove %@,%/tc\n\t" | 708 | " bclr #7,%@\n" |
730 | "jmp %0@\n\t" | 709 | " pmove %@,%%tc\n" |
731 | : /* no outputs */ | 710 | " jmp %0@\n" |
732 | : "a" (jmp_addr)); | 711 | : /* no outputs */ |
733 | jmp_addr_label040: | 712 | : "a" (jmp_addr)); |
734 | /* disable translation on '040 now */ | 713 | jmp_addr_label040: |
735 | __asm__ __volatile__ | 714 | /* disable translation on '040 now */ |
736 | ("moveq #0,%/d0\n\t" | 715 | asm volatile ("\n" |
737 | ".chip 68040\n\t" | 716 | " moveq #0,%%d0\n" |
738 | "movec %%d0,%%tc\n\t" /* disable MMU */ | 717 | " .chip 68040\n" |
739 | ".chip 68k\n\t" | 718 | " movec %%d0,%%tc\n" /* disable MMU */ |
740 | : /* no outputs */ | 719 | " .chip 68k\n" |
741 | : /* no inputs */ | 720 | : /* no outputs */ |
742 | : "d0"); | 721 | : /* no inputs */ |
743 | 722 | : "d0"); | |
744 | jmp_addr_label: | 723 | |
745 | /* pickup reset address from AmigaOS ROM, reset devices and jump | 724 | jmp_addr_label: |
746 | * to reset address | 725 | /* pickup reset address from AmigaOS ROM, reset devices and jump |
747 | */ | 726 | * to reset address |
748 | __asm__ __volatile__ | 727 | */ |
749 | ("movew #0x2700,%/sr\n\t" | 728 | asm volatile ("\n" |
750 | "leal 0x01000000,%/a0\n\t" | 729 | " move.w #0x2700,%sr\n" |
751 | "subl %/a0@(-0x14),%/a0\n\t" | 730 | " lea 0x01000000,%a0\n" |
752 | "movel %/a0@(4),%/a0\n\t" | 731 | " sub.l %a0@(-0x14),%a0\n" |
753 | "subql #2,%/a0\n\t" | 732 | " move.l %a0@(4),%a0\n" |
754 | "bra 1f\n\t" | 733 | " subq.l #2,%a0\n" |
755 | /* align on a longword boundary */ | 734 | " jra 1f\n" |
756 | __ALIGN_STR "\n" | 735 | /* align on a longword boundary */ |
757 | "1:\n\t" | 736 | " " __ALIGN_STR "\n" |
758 | "reset\n\t" | 737 | "1:\n" |
759 | "jmp %/a0@" : /* Just that gcc scans it for % escapes */ ); | 738 | " reset\n" |
760 | 739 | " jmp %a0@"); | |
761 | for (;;); | 740 | |
762 | 741 | for (;;) | |
742 | ; | ||
763 | } | 743 | } |
764 | 744 | ||
765 | 745 | ||
@@ -773,11 +753,11 @@ static void amiga_reset (void) | |||
773 | #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ | 753 | #define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ |
774 | 754 | ||
775 | struct savekmsg { | 755 | struct savekmsg { |
776 | unsigned long magic1; /* SAVEKMSG_MAGIC1 */ | 756 | unsigned long magic1; /* SAVEKMSG_MAGIC1 */ |
777 | unsigned long magic2; /* SAVEKMSG_MAGIC2 */ | 757 | unsigned long magic2; /* SAVEKMSG_MAGIC2 */ |
778 | unsigned long magicptr; /* address of magic1 */ | 758 | unsigned long magicptr; /* address of magic1 */ |
779 | unsigned long size; | 759 | unsigned long size; |
780 | char data[0]; | 760 | char data[0]; |
781 | }; | 761 | }; |
782 | 762 | ||
783 | static struct savekmsg *savekmsg; | 763 | static struct savekmsg *savekmsg; |
@@ -785,113 +765,132 @@ static struct savekmsg *savekmsg; | |||
785 | static void amiga_mem_console_write(struct console *co, const char *s, | 765 | static void amiga_mem_console_write(struct console *co, const char *s, |
786 | unsigned int count) | 766 | unsigned int count) |
787 | { | 767 | { |
788 | if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { | 768 | if (savekmsg->size + count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { |
789 | memcpy(savekmsg->data+savekmsg->size, s, count); | 769 | memcpy(savekmsg->data + savekmsg->size, s, count); |
790 | savekmsg->size += count; | 770 | savekmsg->size += count; |
791 | } | 771 | } |
792 | } | 772 | } |
793 | 773 | ||
794 | static void amiga_savekmsg_init(void) | 774 | static int __init amiga_savekmsg_setup(char *arg) |
795 | { | 775 | { |
796 | static struct resource debug_res = { .name = "Debug" }; | 776 | static struct resource debug_res = { .name = "Debug" }; |
777 | |||
778 | if (!MACH_IS_AMIGA || strcmp(arg, "mem")) | ||
779 | goto done; | ||
780 | |||
781 | if (!AMIGAHW_PRESENT(CHIP_RAM)) { | ||
782 | printk("Warning: no chipram present for debugging\n"); | ||
783 | goto done; | ||
784 | } | ||
797 | 785 | ||
798 | savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); | 786 | savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); |
799 | savekmsg->magic1 = SAVEKMSG_MAGIC1; | 787 | savekmsg->magic1 = SAVEKMSG_MAGIC1; |
800 | savekmsg->magic2 = SAVEKMSG_MAGIC2; | 788 | savekmsg->magic2 = SAVEKMSG_MAGIC2; |
801 | savekmsg->magicptr = ZTWO_PADDR(savekmsg); | 789 | savekmsg->magicptr = ZTWO_PADDR(savekmsg); |
802 | savekmsg->size = 0; | 790 | savekmsg->size = 0; |
791 | |||
792 | amiga_console_driver.write = amiga_mem_console_write; | ||
793 | register_console(&amiga_console_driver); | ||
794 | |||
795 | done: | ||
796 | return 0; | ||
803 | } | 797 | } |
804 | 798 | ||
799 | early_param("debug", amiga_savekmsg_setup); | ||
800 | |||
805 | static void amiga_serial_putc(char c) | 801 | static void amiga_serial_putc(char c) |
806 | { | 802 | { |
807 | amiga_custom.serdat = (unsigned char)c | 0x100; | 803 | amiga_custom.serdat = (unsigned char)c | 0x100; |
808 | while (!(amiga_custom.serdatr & 0x2000)) | 804 | while (!(amiga_custom.serdatr & 0x2000)) |
809 | ; | 805 | ; |
810 | } | 806 | } |
811 | 807 | ||
812 | void amiga_serial_console_write(struct console *co, const char *s, | 808 | void amiga_serial_console_write(struct console *co, const char *s, |
813 | unsigned int count) | 809 | unsigned int count) |
814 | { | 810 | { |
815 | while (count--) { | 811 | while (count--) { |
816 | if (*s == '\n') | 812 | if (*s == '\n') |
817 | amiga_serial_putc('\r'); | 813 | amiga_serial_putc('\r'); |
818 | amiga_serial_putc(*s++); | 814 | amiga_serial_putc(*s++); |
819 | } | 815 | } |
820 | } | 816 | } |
821 | 817 | ||
822 | #ifdef CONFIG_SERIAL_CONSOLE | 818 | #ifdef CONFIG_SERIAL_CONSOLE |
823 | void amiga_serial_puts(const char *s) | 819 | void amiga_serial_puts(const char *s) |
824 | { | 820 | { |
825 | amiga_serial_console_write(NULL, s, strlen(s)); | 821 | amiga_serial_console_write(NULL, s, strlen(s)); |
826 | } | 822 | } |
827 | 823 | ||
828 | int amiga_serial_console_wait_key(struct console *co) | 824 | int amiga_serial_console_wait_key(struct console *co) |
829 | { | 825 | { |
830 | int ch; | 826 | int ch; |
831 | 827 | ||
832 | while (!(amiga_custom.intreqr & IF_RBF)) | 828 | while (!(amiga_custom.intreqr & IF_RBF)) |
833 | barrier(); | 829 | barrier(); |
834 | ch = amiga_custom.serdatr & 0xff; | 830 | ch = amiga_custom.serdatr & 0xff; |
835 | /* clear the interrupt, so that another character can be read */ | 831 | /* clear the interrupt, so that another character can be read */ |
836 | amiga_custom.intreq = IF_RBF; | 832 | amiga_custom.intreq = IF_RBF; |
837 | return ch; | 833 | return ch; |
838 | } | 834 | } |
839 | 835 | ||
840 | void amiga_serial_gets(struct console *co, char *s, int len) | 836 | void amiga_serial_gets(struct console *co, char *s, int len) |
841 | { | 837 | { |
842 | int ch, cnt = 0; | 838 | int ch, cnt = 0; |
843 | 839 | ||
844 | while (1) { | 840 | while (1) { |
845 | ch = amiga_serial_console_wait_key(co); | 841 | ch = amiga_serial_console_wait_key(co); |
846 | 842 | ||
847 | /* Check for backspace. */ | 843 | /* Check for backspace. */ |
848 | if (ch == 8 || ch == 127) { | 844 | if (ch == 8 || ch == 127) { |
849 | if (cnt == 0) { | 845 | if (cnt == 0) { |
850 | amiga_serial_putc('\007'); | 846 | amiga_serial_putc('\007'); |
851 | continue; | 847 | continue; |
852 | } | 848 | } |
853 | cnt--; | 849 | cnt--; |
854 | amiga_serial_puts("\010 \010"); | 850 | amiga_serial_puts("\010 \010"); |
855 | continue; | 851 | continue; |
856 | } | 852 | } |
857 | 853 | ||
858 | /* Check for enter. */ | 854 | /* Check for enter. */ |
859 | if (ch == 10 || ch == 13) | 855 | if (ch == 10 || ch == 13) |
860 | break; | 856 | break; |
861 | 857 | ||
862 | /* See if line is too long. */ | 858 | /* See if line is too long. */ |
863 | if (cnt >= len + 1) { | 859 | if (cnt >= len + 1) { |
864 | amiga_serial_putc(7); | 860 | amiga_serial_putc(7); |
865 | cnt--; | 861 | cnt--; |
866 | continue; | 862 | continue; |
867 | } | 863 | } |
868 | 864 | ||
869 | /* Store and echo character. */ | 865 | /* Store and echo character. */ |
870 | s[cnt++] = ch; | 866 | s[cnt++] = ch; |
871 | amiga_serial_putc(ch); | 867 | amiga_serial_putc(ch); |
872 | } | 868 | } |
873 | /* Print enter. */ | 869 | /* Print enter. */ |
874 | amiga_serial_puts("\r\n"); | 870 | amiga_serial_puts("\r\n"); |
875 | s[cnt] = 0; | 871 | s[cnt] = 0; |
876 | } | 872 | } |
877 | #endif | 873 | #endif |
878 | 874 | ||
879 | static void __init amiga_debug_init(void) | 875 | static int __init amiga_debug_setup(char *arg) |
880 | { | 876 | { |
881 | if (!strcmp( m68k_debug_device, "ser" )) { | 877 | if (MACH_IS_AMIGA && !strcmp(arg, "ser")) { |
882 | /* no initialization required (?) */ | 878 | /* no initialization required (?) */ |
883 | amiga_console_driver.write = amiga_serial_console_write; | 879 | amiga_console_driver.write = amiga_serial_console_write; |
884 | register_console(&amiga_console_driver); | 880 | register_console(&amiga_console_driver); |
885 | } | 881 | } |
882 | return 0; | ||
886 | } | 883 | } |
887 | 884 | ||
885 | early_param("debug", amiga_debug_setup); | ||
886 | |||
888 | #ifdef CONFIG_HEARTBEAT | 887 | #ifdef CONFIG_HEARTBEAT |
889 | static void amiga_heartbeat(int on) | 888 | static void amiga_heartbeat(int on) |
890 | { | 889 | { |
891 | if (on) | 890 | if (on) |
892 | ciaa.pra &= ~2; | 891 | ciaa.pra &= ~2; |
893 | else | 892 | else |
894 | ciaa.pra |= 2; | 893 | ciaa.pra |= 2; |
895 | } | 894 | } |
896 | #endif | 895 | #endif |
897 | 896 | ||
@@ -901,81 +900,81 @@ static void amiga_heartbeat(int on) | |||
901 | 900 | ||
902 | static void amiga_get_model(char *model) | 901 | static void amiga_get_model(char *model) |
903 | { | 902 | { |
904 | strcpy(model, amiga_model_name); | 903 | strcpy(model, amiga_model_name); |
905 | } | 904 | } |
906 | 905 | ||
907 | 906 | ||
908 | static int amiga_get_hardware_list(char *buffer) | 907 | static int amiga_get_hardware_list(char *buffer) |
909 | { | 908 | { |
910 | int len = 0; | 909 | int len = 0; |
911 | 910 | ||
912 | if (AMIGAHW_PRESENT(CHIP_RAM)) | 911 | if (AMIGAHW_PRESENT(CHIP_RAM)) |
913 | len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); | 912 | len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); |
914 | len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", | 913 | len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", |
915 | amiga_psfreq, amiga_eclock); | 914 | amiga_psfreq, amiga_eclock); |
916 | if (AMIGAHW_PRESENT(AMI_VIDEO)) { | 915 | if (AMIGAHW_PRESENT(AMI_VIDEO)) { |
917 | char *type; | 916 | char *type; |
918 | switch(amiga_chipset) { | 917 | switch (amiga_chipset) { |
919 | case CS_OCS: | 918 | case CS_OCS: |
920 | type = "OCS"; | 919 | type = "OCS"; |
921 | break; | 920 | break; |
922 | case CS_ECS: | 921 | case CS_ECS: |
923 | type = "ECS"; | 922 | type = "ECS"; |
924 | break; | 923 | break; |
925 | case CS_AGA: | 924 | case CS_AGA: |
926 | type = "AGA"; | 925 | type = "AGA"; |
927 | break; | 926 | break; |
928 | default: | 927 | default: |
929 | type = "Old or Unknown"; | 928 | type = "Old or Unknown"; |
930 | break; | 929 | break; |
930 | } | ||
931 | len += sprintf(buffer+len, "Graphics:\t%s\n", type); | ||
931 | } | 932 | } |
932 | len += sprintf(buffer+len, "Graphics:\t%s\n", type); | ||
933 | } | ||
934 | 933 | ||
935 | #define AMIGAHW_ANNOUNCE(name, str) \ | 934 | #define AMIGAHW_ANNOUNCE(name, str) \ |
936 | if (AMIGAHW_PRESENT(name)) \ | 935 | if (AMIGAHW_PRESENT(name)) \ |
937 | len += sprintf (buffer+len, "\t%s\n", str) | 936 | len += sprintf (buffer+len, "\t%s\n", str) |
938 | 937 | ||
939 | len += sprintf (buffer + len, "Detected hardware:\n"); | 938 | len += sprintf (buffer + len, "Detected hardware:\n"); |
940 | 939 | ||
941 | AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); | 940 | AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); |
942 | AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); | 941 | AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); |
943 | AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); | 942 | AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); |
944 | AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); | 943 | AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); |
945 | AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); | 944 | AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); |
946 | AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); | 945 | AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); |
947 | AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); | 946 | AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); |
948 | AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); | 947 | AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); |
949 | AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); | 948 | AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); |
950 | AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); | 949 | AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); |
951 | AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); | 950 | AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); |
952 | AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); | 951 | AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); |
953 | AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); | 952 | AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); |
954 | AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); | 953 | AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); |
955 | AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); | 954 | AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); |
956 | AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); | 955 | AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); |
957 | AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); | 956 | AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); |
958 | AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); | 957 | AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); |
959 | AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); | 958 | AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); |
960 | AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); | 959 | AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); |
961 | AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); | 960 | AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); |
962 | AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); | 961 | AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); |
963 | AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); | 962 | AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); |
964 | AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); | 963 | AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); |
965 | AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); | 964 | AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); |
966 | AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); | 965 | AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); |
967 | AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); | 966 | AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); |
968 | AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); | 967 | AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); |
969 | AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); | 968 | AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); |
970 | #ifdef CONFIG_ZORRO | 969 | #ifdef CONFIG_ZORRO |
971 | if (AMIGAHW_PRESENT(ZORRO)) | 970 | if (AMIGAHW_PRESENT(ZORRO)) |
972 | len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " | 971 | len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " |
973 | "Device%s\n", | 972 | "Device%s\n", |
974 | AMIGAHW_PRESENT(ZORRO3) ? "I" : "", | 973 | AMIGAHW_PRESENT(ZORRO3) ? "I" : "", |
975 | zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); | 974 | zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); |
976 | #endif /* CONFIG_ZORRO */ | 975 | #endif /* CONFIG_ZORRO */ |
977 | 976 | ||
978 | #undef AMIGAHW_ANNOUNCE | 977 | #undef AMIGAHW_ANNOUNCE |
979 | 978 | ||
980 | return(len); | 979 | return len; |
981 | } | 980 | } |