Back to home page

LXR

 
 

    


0001 /*
0002  *  linux/arch/m68k/kernel/setup.c
0003  *
0004  *  Copyright (C) 1995  Hamish Macdonald
0005  */
0006 
0007 /*
0008  * This file handles the architecture-dependent parts of system setup
0009  */
0010 
0011 #include <linux/kernel.h>
0012 #include <linux/mm.h>
0013 #include <linux/sched.h>
0014 #include <linux/delay.h>
0015 #include <linux/interrupt.h>
0016 #include <linux/fs.h>
0017 #include <linux/console.h>
0018 #include <linux/genhd.h>
0019 #include <linux/errno.h>
0020 #include <linux/string.h>
0021 #include <linux/init.h>
0022 #include <linux/bootmem.h>
0023 #include <linux/proc_fs.h>
0024 #include <linux/seq_file.h>
0025 #include <linux/module.h>
0026 #include <linux/initrd.h>
0027 
0028 #include <asm/bootinfo.h>
0029 #include <asm/byteorder.h>
0030 #include <asm/sections.h>
0031 #include <asm/setup.h>
0032 #include <asm/fpu.h>
0033 #include <asm/irq.h>
0034 #include <asm/io.h>
0035 #include <asm/machdep.h>
0036 #ifdef CONFIG_AMIGA
0037 #include <asm/amigahw.h>
0038 #endif
0039 #ifdef CONFIG_ATARI
0040 #include <asm/atarihw.h>
0041 #include <asm/atari_stram.h>
0042 #endif
0043 #ifdef CONFIG_SUN3X
0044 #include <asm/dvma.h>
0045 #endif
0046 #include <asm/natfeat.h>
0047 
0048 #if !FPSTATESIZE || !NR_IRQS
0049 #warning No CPU/platform type selected, your kernel will not work!
0050 #warning Are you building an allnoconfig kernel?
0051 #endif
0052 
0053 unsigned long m68k_machtype;
0054 EXPORT_SYMBOL(m68k_machtype);
0055 unsigned long m68k_cputype;
0056 EXPORT_SYMBOL(m68k_cputype);
0057 unsigned long m68k_fputype;
0058 unsigned long m68k_mmutype;
0059 EXPORT_SYMBOL(m68k_mmutype);
0060 #ifdef CONFIG_VME
0061 unsigned long vme_brdtype;
0062 EXPORT_SYMBOL(vme_brdtype);
0063 #endif
0064 
0065 int m68k_is040or060;
0066 EXPORT_SYMBOL(m68k_is040or060);
0067 
0068 extern unsigned long availmem;
0069 
0070 int m68k_num_memory;
0071 EXPORT_SYMBOL(m68k_num_memory);
0072 int m68k_realnum_memory;
0073 EXPORT_SYMBOL(m68k_realnum_memory);
0074 unsigned long m68k_memoffset;
0075 struct m68k_mem_info m68k_memory[NUM_MEMINFO];
0076 EXPORT_SYMBOL(m68k_memory);
0077 
0078 static struct m68k_mem_info m68k_ramdisk __initdata;
0079 
0080 static char m68k_command_line[CL_SIZE] __initdata;
0081 
0082 void (*mach_sched_init) (irq_handler_t handler) __initdata = NULL;
0083 /* machine dependent irq functions */
0084 void (*mach_init_IRQ) (void) __initdata = NULL;
0085 void (*mach_get_model) (char *model);
0086 void (*mach_get_hardware_list) (struct seq_file *m);
0087 /* machine dependent timer functions */
0088 int (*mach_hwclk) (int, struct rtc_time*);
0089 EXPORT_SYMBOL(mach_hwclk);
0090 int (*mach_set_clock_mmss) (unsigned long);
0091 unsigned int (*mach_get_ss)(void);
0092 int (*mach_get_rtc_pll)(struct rtc_pll_info *);
0093 int (*mach_set_rtc_pll)(struct rtc_pll_info *);
0094 EXPORT_SYMBOL(mach_get_ss);
0095 EXPORT_SYMBOL(mach_get_rtc_pll);
0096 EXPORT_SYMBOL(mach_set_rtc_pll);
0097 void (*mach_reset)( void );
0098 void (*mach_halt)( void );
0099 void (*mach_power_off)( void );
0100 long mach_max_dma_address = 0x00ffffff; /* default set to the lower 16MB */
0101 #ifdef CONFIG_HEARTBEAT
0102 void (*mach_heartbeat) (int);
0103 EXPORT_SYMBOL(mach_heartbeat);
0104 #endif
0105 #ifdef CONFIG_M68K_L2_CACHE
0106 void (*mach_l2_flush) (int);
0107 #endif
0108 #if IS_ENABLED(CONFIG_INPUT_M68K_BEEP)
0109 void (*mach_beep)(unsigned int, unsigned int);
0110 EXPORT_SYMBOL(mach_beep);
0111 #endif
0112 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
0113 int isa_type;
0114 int isa_sex;
0115 EXPORT_SYMBOL(isa_type);
0116 EXPORT_SYMBOL(isa_sex);
0117 #endif
0118 
0119 extern int amiga_parse_bootinfo(const struct bi_record *);
0120 extern int atari_parse_bootinfo(const struct bi_record *);
0121 extern int mac_parse_bootinfo(const struct bi_record *);
0122 extern int q40_parse_bootinfo(const struct bi_record *);
0123 extern int bvme6000_parse_bootinfo(const struct bi_record *);
0124 extern int mvme16x_parse_bootinfo(const struct bi_record *);
0125 extern int mvme147_parse_bootinfo(const struct bi_record *);
0126 extern int hp300_parse_bootinfo(const struct bi_record *);
0127 extern int apollo_parse_bootinfo(const struct bi_record *);
0128 
0129 extern void config_amiga(void);
0130 extern void config_atari(void);
0131 extern void config_mac(void);
0132 extern void config_sun3(void);
0133 extern void config_apollo(void);
0134 extern void config_mvme147(void);
0135 extern void config_mvme16x(void);
0136 extern void config_bvme6000(void);
0137 extern void config_hp300(void);
0138 extern void config_q40(void);
0139 extern void config_sun3x(void);
0140 
0141 #define MASK_256K 0xfffc0000
0142 
0143 extern void paging_init(void);
0144 
0145 static void __init m68k_parse_bootinfo(const struct bi_record *record)
0146 {
0147     uint16_t tag;
0148 
0149     save_bootinfo(record);
0150 
0151     while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
0152         int unknown = 0;
0153         const void *data = record->data;
0154         uint16_t size = be16_to_cpu(record->size);
0155 
0156         switch (tag) {
0157         case BI_MACHTYPE:
0158         case BI_CPUTYPE:
0159         case BI_FPUTYPE:
0160         case BI_MMUTYPE:
0161             /* Already set up by head.S */
0162             break;
0163 
0164         case BI_MEMCHUNK:
0165             if (m68k_num_memory < NUM_MEMINFO) {
0166                 const struct mem_info *m = data;
0167                 m68k_memory[m68k_num_memory].addr =
0168                     be32_to_cpu(m->addr);
0169                 m68k_memory[m68k_num_memory].size =
0170                     be32_to_cpu(m->size);
0171                 m68k_num_memory++;
0172             } else
0173                 pr_warn("%s: too many memory chunks\n",
0174                     __func__);
0175             break;
0176 
0177         case BI_RAMDISK:
0178             {
0179                 const struct mem_info *m = data;
0180                 m68k_ramdisk.addr = be32_to_cpu(m->addr);
0181                 m68k_ramdisk.size = be32_to_cpu(m->size);
0182             }
0183             break;
0184 
0185         case BI_COMMAND_LINE:
0186             strlcpy(m68k_command_line, data,
0187                 sizeof(m68k_command_line));
0188             break;
0189 
0190         default:
0191             if (MACH_IS_AMIGA)
0192                 unknown = amiga_parse_bootinfo(record);
0193             else if (MACH_IS_ATARI)
0194                 unknown = atari_parse_bootinfo(record);
0195             else if (MACH_IS_MAC)
0196                 unknown = mac_parse_bootinfo(record);
0197             else if (MACH_IS_Q40)
0198                 unknown = q40_parse_bootinfo(record);
0199             else if (MACH_IS_BVME6000)
0200                 unknown = bvme6000_parse_bootinfo(record);
0201             else if (MACH_IS_MVME16x)
0202                 unknown = mvme16x_parse_bootinfo(record);
0203             else if (MACH_IS_MVME147)
0204                 unknown = mvme147_parse_bootinfo(record);
0205             else if (MACH_IS_HP300)
0206                 unknown = hp300_parse_bootinfo(record);
0207             else if (MACH_IS_APOLLO)
0208                 unknown = apollo_parse_bootinfo(record);
0209             else
0210                 unknown = 1;
0211         }
0212         if (unknown)
0213             pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
0214                 tag);
0215         record = (struct bi_record *)((unsigned long)record + size);
0216     }
0217 
0218     m68k_realnum_memory = m68k_num_memory;
0219 #ifdef CONFIG_SINGLE_MEMORY_CHUNK
0220     if (m68k_num_memory > 1) {
0221         pr_warn("%s: ignoring last %i chunks of physical memory\n",
0222             __func__, (m68k_num_memory - 1));
0223         m68k_num_memory = 1;
0224     }
0225 #endif
0226 }
0227 
0228 void __init setup_arch(char **cmdline_p)
0229 {
0230 #ifndef CONFIG_SUN3
0231     int i;
0232 #endif
0233 
0234     /* The bootinfo is located right after the kernel */
0235     if (!CPU_IS_COLDFIRE)
0236         m68k_parse_bootinfo((const struct bi_record *)_end);
0237 
0238     if (CPU_IS_040)
0239         m68k_is040or060 = 4;
0240     else if (CPU_IS_060)
0241         m68k_is040or060 = 6;
0242 
0243     /* FIXME: m68k_fputype is passed in by Penguin booter, which can
0244      * be confused by software FPU emulation. BEWARE.
0245      * We should really do our own FPU check at startup.
0246      * [what do we do with buggy 68LC040s? if we have problems
0247      *  with them, we should add a test to check_bugs() below] */
0248 #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY)
0249     /* clear the fpu if we have one */
0250     if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
0251         volatile int zero = 0;
0252         asm volatile ("frestore %0" : : "m" (zero));
0253     }
0254 #endif
0255 
0256     if (CPU_IS_060) {
0257         u32 pcr;
0258 
0259         asm (".chip 68060; movec %%pcr,%0; .chip 68k"
0260              : "=d" (pcr));
0261         if (((pcr >> 8) & 0xff) <= 5) {
0262             pr_warn("Enabling workaround for errata I14\n");
0263             asm (".chip 68060; movec %0,%%pcr; .chip 68k"
0264                  : : "d" (pcr | 0x20));
0265         }
0266     }
0267 
0268     init_mm.start_code = PAGE_OFFSET;
0269     init_mm.end_code = (unsigned long)_etext;
0270     init_mm.end_data = (unsigned long)_edata;
0271     init_mm.brk = (unsigned long)_end;
0272 
0273 #if defined(CONFIG_BOOTPARAM)
0274     strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
0275     m68k_command_line[CL_SIZE - 1] = 0;
0276 #endif /* CONFIG_BOOTPARAM */
0277     process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
0278     *cmdline_p = m68k_command_line;
0279     memcpy(boot_command_line, *cmdline_p, CL_SIZE);
0280 
0281     parse_early_param();
0282 
0283 #ifdef CONFIG_DUMMY_CONSOLE
0284     conswitchp = &dummy_con;
0285 #endif
0286 
0287     switch (m68k_machtype) {
0288 #ifdef CONFIG_AMIGA
0289     case MACH_AMIGA:
0290         config_amiga();
0291         break;
0292 #endif
0293 #ifdef CONFIG_ATARI
0294     case MACH_ATARI:
0295         config_atari();
0296         break;
0297 #endif
0298 #ifdef CONFIG_MAC
0299     case MACH_MAC:
0300         config_mac();
0301         break;
0302 #endif
0303 #ifdef CONFIG_SUN3
0304     case MACH_SUN3:
0305         config_sun3();
0306         break;
0307 #endif
0308 #ifdef CONFIG_APOLLO
0309     case MACH_APOLLO:
0310         config_apollo();
0311         break;
0312 #endif
0313 #ifdef CONFIG_MVME147
0314     case MACH_MVME147:
0315         config_mvme147();
0316         break;
0317 #endif
0318 #ifdef CONFIG_MVME16x
0319     case MACH_MVME16x:
0320         config_mvme16x();
0321         break;
0322 #endif
0323 #ifdef CONFIG_BVME6000
0324     case MACH_BVME6000:
0325         config_bvme6000();
0326         break;
0327 #endif
0328 #ifdef CONFIG_HP300
0329     case MACH_HP300:
0330         config_hp300();
0331         break;
0332 #endif
0333 #ifdef CONFIG_Q40
0334     case MACH_Q40:
0335         config_q40();
0336         break;
0337 #endif
0338 #ifdef CONFIG_SUN3X
0339     case MACH_SUN3X:
0340         config_sun3x();
0341         break;
0342 #endif
0343 #ifdef CONFIG_COLDFIRE
0344     case MACH_M54XX:
0345     case MACH_M5441X:
0346         config_BSP(NULL, 0);
0347         break;
0348 #endif
0349     default:
0350         panic("No configuration setup");
0351     }
0352 
0353     paging_init();
0354 
0355 #ifdef CONFIG_NATFEAT
0356     nf_init();
0357 #endif
0358 
0359 #ifndef CONFIG_SUN3
0360     for (i = 1; i < m68k_num_memory; i++)
0361         free_bootmem_node(NODE_DATA(i), m68k_memory[i].addr,
0362                   m68k_memory[i].size);
0363 #ifdef CONFIG_BLK_DEV_INITRD
0364     if (m68k_ramdisk.size) {
0365         reserve_bootmem_node(__virt_to_node(phys_to_virt(m68k_ramdisk.addr)),
0366                      m68k_ramdisk.addr, m68k_ramdisk.size,
0367                      BOOTMEM_DEFAULT);
0368         initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
0369         initrd_end = initrd_start + m68k_ramdisk.size;
0370         pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
0371     }
0372 #endif
0373 
0374 #ifdef CONFIG_ATARI
0375     if (MACH_IS_ATARI)
0376         atari_stram_reserve_pages((void *)availmem);
0377 #endif
0378 #ifdef CONFIG_SUN3X
0379     if (MACH_IS_SUN3X) {
0380         dvma_init();
0381     }
0382 #endif
0383 
0384 #endif /* !CONFIG_SUN3 */
0385 
0386 /* set ISA defs early as possible */
0387 #if defined(CONFIG_ISA) && defined(MULTI_ISA)
0388     if (MACH_IS_Q40) {
0389         isa_type = ISA_TYPE_Q40;
0390         isa_sex = 0;
0391     }
0392 #ifdef CONFIG_AMIGA_PCMCIA
0393     if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
0394         isa_type = ISA_TYPE_AG;
0395         isa_sex = 1;
0396     }
0397 #endif
0398 #ifdef CONFIG_ATARI_ROM_ISA
0399     if (MACH_IS_ATARI) {
0400         isa_type = ISA_TYPE_ENEC;
0401         isa_sex = 0;
0402     }
0403 #endif
0404 #endif
0405 }
0406 
0407 static int show_cpuinfo(struct seq_file *m, void *v)
0408 {
0409     const char *cpu, *mmu, *fpu;
0410     unsigned long clockfreq, clockfactor;
0411 
0412 #define LOOP_CYCLES_68020   (8)
0413 #define LOOP_CYCLES_68030   (8)
0414 #define LOOP_CYCLES_68040   (3)
0415 #define LOOP_CYCLES_68060   (1)
0416 #define LOOP_CYCLES_COLDFIRE    (2)
0417 
0418     if (CPU_IS_020) {
0419         cpu = "68020";
0420         clockfactor = LOOP_CYCLES_68020;
0421     } else if (CPU_IS_030) {
0422         cpu = "68030";
0423         clockfactor = LOOP_CYCLES_68030;
0424     } else if (CPU_IS_040) {
0425         cpu = "68040";
0426         clockfactor = LOOP_CYCLES_68040;
0427     } else if (CPU_IS_060) {
0428         cpu = "68060";
0429         clockfactor = LOOP_CYCLES_68060;
0430     } else if (CPU_IS_COLDFIRE) {
0431         cpu = "ColdFire";
0432         clockfactor = LOOP_CYCLES_COLDFIRE;
0433     } else {
0434         cpu = "680x0";
0435         clockfactor = 0;
0436     }
0437 
0438 #ifdef CONFIG_M68KFPU_EMU_ONLY
0439     fpu = "none(soft float)";
0440 #else
0441     if (m68k_fputype & FPU_68881)
0442         fpu = "68881";
0443     else if (m68k_fputype & FPU_68882)
0444         fpu = "68882";
0445     else if (m68k_fputype & FPU_68040)
0446         fpu = "68040";
0447     else if (m68k_fputype & FPU_68060)
0448         fpu = "68060";
0449     else if (m68k_fputype & FPU_SUNFPA)
0450         fpu = "Sun FPA";
0451     else if (m68k_fputype & FPU_COLDFIRE)
0452         fpu = "ColdFire";
0453     else
0454         fpu = "none";
0455 #endif
0456 
0457     if (m68k_mmutype & MMU_68851)
0458         mmu = "68851";
0459     else if (m68k_mmutype & MMU_68030)
0460         mmu = "68030";
0461     else if (m68k_mmutype & MMU_68040)
0462         mmu = "68040";
0463     else if (m68k_mmutype & MMU_68060)
0464         mmu = "68060";
0465     else if (m68k_mmutype & MMU_SUN3)
0466         mmu = "Sun-3";
0467     else if (m68k_mmutype & MMU_APOLLO)
0468         mmu = "Apollo";
0469     else if (m68k_mmutype & MMU_COLDFIRE)
0470         mmu = "ColdFire";
0471     else
0472         mmu = "unknown";
0473 
0474     clockfreq = loops_per_jiffy * HZ * clockfactor;
0475 
0476     seq_printf(m, "CPU:\t\t%s\n"
0477            "MMU:\t\t%s\n"
0478            "FPU:\t\t%s\n"
0479            "Clocking:\t%lu.%1luMHz\n"
0480            "BogoMips:\t%lu.%02lu\n"
0481            "Calibration:\t%lu loops\n",
0482            cpu, mmu, fpu,
0483            clockfreq/1000000,(clockfreq/100000)%10,
0484            loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
0485            loops_per_jiffy);
0486     return 0;
0487 }
0488 
0489 static void *c_start(struct seq_file *m, loff_t *pos)
0490 {
0491     return *pos < 1 ? (void *)1 : NULL;
0492 }
0493 static void *c_next(struct seq_file *m, void *v, loff_t *pos)
0494 {
0495     ++*pos;
0496     return NULL;
0497 }
0498 static void c_stop(struct seq_file *m, void *v)
0499 {
0500 }
0501 const struct seq_operations cpuinfo_op = {
0502     .start  = c_start,
0503     .next   = c_next,
0504     .stop   = c_stop,
0505     .show   = show_cpuinfo,
0506 };
0507 
0508 #ifdef CONFIG_PROC_HARDWARE
0509 static int hardware_proc_show(struct seq_file *m, void *v)
0510 {
0511     char model[80];
0512     unsigned long mem;
0513     int i;
0514 
0515     if (mach_get_model)
0516         mach_get_model(model);
0517     else
0518         strcpy(model, "Unknown m68k");
0519 
0520     seq_printf(m, "Model:\t\t%s\n", model);
0521     for (mem = 0, i = 0; i < m68k_num_memory; i++)
0522         mem += m68k_memory[i].size;
0523     seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
0524 
0525     if (mach_get_hardware_list)
0526         mach_get_hardware_list(m);
0527 
0528     return 0;
0529 }
0530 
0531 static int hardware_proc_open(struct inode *inode, struct file *file)
0532 {
0533     return single_open(file, hardware_proc_show, NULL);
0534 }
0535 
0536 static const struct file_operations hardware_proc_fops = {
0537     .open       = hardware_proc_open,
0538     .read       = seq_read,
0539     .llseek     = seq_lseek,
0540     .release    = single_release,
0541 };
0542 
0543 static int __init proc_hardware_init(void)
0544 {
0545     proc_create("hardware", 0, NULL, &hardware_proc_fops);
0546     return 0;
0547 }
0548 module_init(proc_hardware_init);
0549 #endif
0550 
0551 void check_bugs(void)
0552 {
0553 #if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
0554     if (m68k_fputype == 0) {
0555         pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
0556             "WHICH IS REQUIRED BY LINUX/M68K ***\n");
0557         pr_emerg("Upgrade your hardware or join the FPU "
0558             "emulation project\n");
0559         panic("no FPU");
0560     }
0561 #endif /* !CONFIG_M68KFPU_EMU */
0562 }
0563 
0564 #ifdef CONFIG_ADB
0565 static int __init adb_probe_sync_enable (char *str) {
0566     extern int __adb_probe_sync;
0567     __adb_probe_sync = 1;
0568     return 1;
0569 }
0570 
0571 __setup("adb_sync", adb_probe_sync_enable);
0572 #endif /* CONFIG_ADB */