linux/arch/m68k/kernel/setup_mm.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  linux/arch/m68k/kernel/setup.c
   4 *
   5 *  Copyright (C) 1995  Hamish Macdonald
   6 */
   7
   8/*
   9 * This file handles the architecture-dependent parts of system setup
  10 */
  11
  12#include <linux/kernel.h>
  13#include <linux/mm.h>
  14#include <linux/sched.h>
  15#include <linux/delay.h>
  16#include <linux/interrupt.h>
  17#include <linux/fs.h>
  18#include <linux/console.h>
  19#include <linux/genhd.h>
  20#include <linux/errno.h>
  21#include <linux/string.h>
  22#include <linux/init.h>
  23#include <linux/memblock.h>
  24#include <linux/proc_fs.h>
  25#include <linux/seq_file.h>
  26#include <linux/module.h>
  27#include <linux/nvram.h>
  28#include <linux/initrd.h>
  29
  30#include <asm/bootinfo.h>
  31#include <asm/byteorder.h>
  32#include <asm/sections.h>
  33#include <asm/setup.h>
  34#include <asm/fpu.h>
  35#include <asm/irq.h>
  36#include <asm/io.h>
  37#include <asm/machdep.h>
  38#ifdef CONFIG_AMIGA
  39#include <asm/amigahw.h>
  40#endif
  41#include <asm/atarihw.h>
  42#ifdef CONFIG_ATARI
  43#include <asm/atari_stram.h>
  44#endif
  45#ifdef CONFIG_SUN3X
  46#include <asm/dvma.h>
  47#endif
  48#include <asm/macintosh.h>
  49#include <asm/natfeat.h>
  50
  51#if !FPSTATESIZE || !NR_IRQS
  52#warning No CPU/platform type selected, your kernel will not work!
  53#warning Are you building an allnoconfig kernel?
  54#endif
  55
  56unsigned long m68k_machtype;
  57EXPORT_SYMBOL(m68k_machtype);
  58unsigned long m68k_cputype;
  59EXPORT_SYMBOL(m68k_cputype);
  60unsigned long m68k_fputype;
  61unsigned long m68k_mmutype;
  62EXPORT_SYMBOL(m68k_mmutype);
  63#ifdef CONFIG_VME
  64unsigned long vme_brdtype;
  65EXPORT_SYMBOL(vme_brdtype);
  66#endif
  67
  68int m68k_is040or060;
  69EXPORT_SYMBOL(m68k_is040or060);
  70
  71extern unsigned long availmem;
  72
  73int m68k_num_memory;
  74EXPORT_SYMBOL(m68k_num_memory);
  75int m68k_realnum_memory;
  76EXPORT_SYMBOL(m68k_realnum_memory);
  77unsigned long m68k_memoffset;
  78struct m68k_mem_info m68k_memory[NUM_MEMINFO];
  79EXPORT_SYMBOL(m68k_memory);
  80
  81static struct m68k_mem_info m68k_ramdisk __initdata;
  82
  83static char m68k_command_line[CL_SIZE] __initdata;
  84
  85void (*mach_sched_init) (void) __initdata = NULL;
  86/* machine dependent irq functions */
  87void (*mach_init_IRQ) (void) __initdata = NULL;
  88void (*mach_get_model) (char *model);
  89void (*mach_get_hardware_list) (struct seq_file *m);
  90/* machine dependent timer functions */
  91int (*mach_hwclk) (int, struct rtc_time*);
  92EXPORT_SYMBOL(mach_hwclk);
  93unsigned int (*mach_get_ss)(void);
  94int (*mach_get_rtc_pll)(struct rtc_pll_info *);
  95int (*mach_set_rtc_pll)(struct rtc_pll_info *);
  96EXPORT_SYMBOL(mach_get_ss);
  97EXPORT_SYMBOL(mach_get_rtc_pll);
  98EXPORT_SYMBOL(mach_set_rtc_pll);
  99void (*mach_reset)( void );
 100void (*mach_halt)( void );
 101void (*mach_power_off)( void );
 102#ifdef CONFIG_HEARTBEAT
 103void (*mach_heartbeat) (int);
 104EXPORT_SYMBOL(mach_heartbeat);
 105#endif
 106#ifdef CONFIG_M68K_L2_CACHE
 107void (*mach_l2_flush) (int);
 108#endif
 109#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 110int isa_type;
 111int isa_sex;
 112EXPORT_SYMBOL(isa_type);
 113EXPORT_SYMBOL(isa_sex);
 114#endif
 115
 116extern int amiga_parse_bootinfo(const struct bi_record *);
 117extern int atari_parse_bootinfo(const struct bi_record *);
 118extern int mac_parse_bootinfo(const struct bi_record *);
 119extern int q40_parse_bootinfo(const struct bi_record *);
 120extern int bvme6000_parse_bootinfo(const struct bi_record *);
 121extern int mvme16x_parse_bootinfo(const struct bi_record *);
 122extern int mvme147_parse_bootinfo(const struct bi_record *);
 123extern int hp300_parse_bootinfo(const struct bi_record *);
 124extern int apollo_parse_bootinfo(const struct bi_record *);
 125
 126extern void config_amiga(void);
 127extern void config_atari(void);
 128extern void config_mac(void);
 129extern void config_sun3(void);
 130extern void config_apollo(void);
 131extern void config_mvme147(void);
 132extern void config_mvme16x(void);
 133extern void config_bvme6000(void);
 134extern void config_hp300(void);
 135extern void config_q40(void);
 136extern void config_sun3x(void);
 137
 138#define MASK_256K 0xfffc0000
 139
 140extern void paging_init(void);
 141
 142static void __init m68k_parse_bootinfo(const struct bi_record *record)
 143{
 144        uint16_t tag;
 145
 146        save_bootinfo(record);
 147
 148        while ((tag = be16_to_cpu(record->tag)) != BI_LAST) {
 149                int unknown = 0;
 150                const void *data = record->data;
 151                uint16_t size = be16_to_cpu(record->size);
 152
 153                switch (tag) {
 154                case BI_MACHTYPE:
 155                case BI_CPUTYPE:
 156                case BI_FPUTYPE:
 157                case BI_MMUTYPE:
 158                        /* Already set up by head.S */
 159                        break;
 160
 161                case BI_MEMCHUNK:
 162                        if (m68k_num_memory < NUM_MEMINFO) {
 163                                const struct mem_info *m = data;
 164                                m68k_memory[m68k_num_memory].addr =
 165                                        be32_to_cpu(m->addr);
 166                                m68k_memory[m68k_num_memory].size =
 167                                        be32_to_cpu(m->size);
 168                                m68k_num_memory++;
 169                        } else
 170                                pr_warn("%s: too many memory chunks\n",
 171                                        __func__);
 172                        break;
 173
 174                case BI_RAMDISK:
 175                        {
 176                                const struct mem_info *m = data;
 177                                m68k_ramdisk.addr = be32_to_cpu(m->addr);
 178                                m68k_ramdisk.size = be32_to_cpu(m->size);
 179                        }
 180                        break;
 181
 182                case BI_COMMAND_LINE:
 183                        strlcpy(m68k_command_line, data,
 184                                sizeof(m68k_command_line));
 185                        break;
 186
 187                default:
 188                        if (MACH_IS_AMIGA)
 189                                unknown = amiga_parse_bootinfo(record);
 190                        else if (MACH_IS_ATARI)
 191                                unknown = atari_parse_bootinfo(record);
 192                        else if (MACH_IS_MAC)
 193                                unknown = mac_parse_bootinfo(record);
 194                        else if (MACH_IS_Q40)
 195                                unknown = q40_parse_bootinfo(record);
 196                        else if (MACH_IS_BVME6000)
 197                                unknown = bvme6000_parse_bootinfo(record);
 198                        else if (MACH_IS_MVME16x)
 199                                unknown = mvme16x_parse_bootinfo(record);
 200                        else if (MACH_IS_MVME147)
 201                                unknown = mvme147_parse_bootinfo(record);
 202                        else if (MACH_IS_HP300)
 203                                unknown = hp300_parse_bootinfo(record);
 204                        else if (MACH_IS_APOLLO)
 205                                unknown = apollo_parse_bootinfo(record);
 206                        else
 207                                unknown = 1;
 208                }
 209                if (unknown)
 210                        pr_warn("%s: unknown tag 0x%04x ignored\n", __func__,
 211                                tag);
 212                record = (struct bi_record *)((unsigned long)record + size);
 213        }
 214
 215        m68k_realnum_memory = m68k_num_memory;
 216#ifdef CONFIG_SINGLE_MEMORY_CHUNK
 217        if (m68k_num_memory > 1) {
 218                pr_warn("%s: ignoring last %i chunks of physical memory\n",
 219                        __func__, (m68k_num_memory - 1));
 220                m68k_num_memory = 1;
 221        }
 222#endif
 223}
 224
 225void __init setup_arch(char **cmdline_p)
 226{
 227        /* The bootinfo is located right after the kernel */
 228        if (!CPU_IS_COLDFIRE)
 229                m68k_parse_bootinfo((const struct bi_record *)_end);
 230
 231        if (CPU_IS_040)
 232                m68k_is040or060 = 4;
 233        else if (CPU_IS_060)
 234                m68k_is040or060 = 6;
 235
 236        /* FIXME: m68k_fputype is passed in by Penguin booter, which can
 237         * be confused by software FPU emulation. BEWARE.
 238         * We should really do our own FPU check at startup.
 239         * [what do we do with buggy 68LC040s? if we have problems
 240         *  with them, we should add a test to check_bugs() below] */
 241#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU_ONLY)
 242        /* clear the fpu if we have one */
 243        if (m68k_fputype & (FPU_68881|FPU_68882|FPU_68040|FPU_68060|FPU_COLDFIRE)) {
 244                volatile int zero = 0;
 245                asm volatile ("frestore %0" : : "m" (zero));
 246        }
 247#endif
 248
 249        if (CPU_IS_060) {
 250                u32 pcr;
 251
 252                asm (".chip 68060; movec %%pcr,%0; .chip 68k"
 253                     : "=d" (pcr));
 254                if (((pcr >> 8) & 0xff) <= 5) {
 255                        pr_warn("Enabling workaround for errata I14\n");
 256                        asm (".chip 68060; movec %0,%%pcr; .chip 68k"
 257                             : : "d" (pcr | 0x20));
 258                }
 259        }
 260
 261        setup_initial_init_mm((void *)PAGE_OFFSET, _etext, _edata, _end);
 262
 263#if defined(CONFIG_BOOTPARAM)
 264        strncpy(m68k_command_line, CONFIG_BOOTPARAM_STRING, CL_SIZE);
 265        m68k_command_line[CL_SIZE - 1] = 0;
 266#endif /* CONFIG_BOOTPARAM */
 267        process_uboot_commandline(&m68k_command_line[0], CL_SIZE);
 268        *cmdline_p = m68k_command_line;
 269        memcpy(boot_command_line, *cmdline_p, CL_SIZE);
 270
 271        parse_early_param();
 272
 273        switch (m68k_machtype) {
 274#ifdef CONFIG_AMIGA
 275        case MACH_AMIGA:
 276                config_amiga();
 277                break;
 278#endif
 279#ifdef CONFIG_ATARI
 280        case MACH_ATARI:
 281                config_atari();
 282                break;
 283#endif
 284#ifdef CONFIG_MAC
 285        case MACH_MAC:
 286                config_mac();
 287                break;
 288#endif
 289#ifdef CONFIG_SUN3
 290        case MACH_SUN3:
 291                config_sun3();
 292                break;
 293#endif
 294#ifdef CONFIG_APOLLO
 295        case MACH_APOLLO:
 296                config_apollo();
 297                break;
 298#endif
 299#ifdef CONFIG_MVME147
 300        case MACH_MVME147:
 301                config_mvme147();
 302                break;
 303#endif
 304#ifdef CONFIG_MVME16x
 305        case MACH_MVME16x:
 306                config_mvme16x();
 307                break;
 308#endif
 309#ifdef CONFIG_BVME6000
 310        case MACH_BVME6000:
 311                config_bvme6000();
 312                break;
 313#endif
 314#ifdef CONFIG_HP300
 315        case MACH_HP300:
 316                config_hp300();
 317                break;
 318#endif
 319#ifdef CONFIG_Q40
 320        case MACH_Q40:
 321                config_q40();
 322                break;
 323#endif
 324#ifdef CONFIG_SUN3X
 325        case MACH_SUN3X:
 326                config_sun3x();
 327                break;
 328#endif
 329#ifdef CONFIG_COLDFIRE
 330        case MACH_M54XX:
 331        case MACH_M5441X:
 332                cf_bootmem_alloc();
 333                cf_mmu_context_init();
 334                config_BSP(NULL, 0);
 335                break;
 336#endif
 337        default:
 338                panic("No configuration setup");
 339        }
 340
 341#ifdef CONFIG_BLK_DEV_INITRD
 342        if (m68k_ramdisk.size) {
 343                memblock_reserve(m68k_ramdisk.addr, m68k_ramdisk.size);
 344                initrd_start = (unsigned long)phys_to_virt(m68k_ramdisk.addr);
 345                initrd_end = initrd_start + m68k_ramdisk.size;
 346                pr_info("initrd: %08lx - %08lx\n", initrd_start, initrd_end);
 347        }
 348#endif
 349
 350        paging_init();
 351
 352#ifdef CONFIG_NATFEAT
 353        nf_init();
 354#endif
 355
 356#ifdef CONFIG_ATARI
 357        if (MACH_IS_ATARI)
 358                atari_stram_reserve_pages((void *)availmem);
 359#endif
 360#ifdef CONFIG_SUN3X
 361        if (MACH_IS_SUN3X) {
 362                dvma_init();
 363        }
 364#endif
 365
 366/* set ISA defs early as possible */
 367#if defined(CONFIG_ISA) && defined(MULTI_ISA)
 368        if (MACH_IS_Q40) {
 369                isa_type = ISA_TYPE_Q40;
 370                isa_sex = 0;
 371        }
 372#ifdef CONFIG_AMIGA_PCMCIA
 373        if (MACH_IS_AMIGA && AMIGAHW_PRESENT(PCMCIA)) {
 374                isa_type = ISA_TYPE_AG;
 375                isa_sex = 1;
 376        }
 377#endif
 378#ifdef CONFIG_ATARI_ROM_ISA
 379        if (MACH_IS_ATARI) {
 380                isa_type = ISA_TYPE_ENEC;
 381                isa_sex = 0;
 382        }
 383#endif
 384#endif
 385}
 386
 387static int show_cpuinfo(struct seq_file *m, void *v)
 388{
 389        const char *cpu, *mmu, *fpu;
 390        unsigned long clockfreq, clockfactor;
 391
 392#define LOOP_CYCLES_68020       (8)
 393#define LOOP_CYCLES_68030       (8)
 394#define LOOP_CYCLES_68040       (3)
 395#define LOOP_CYCLES_68060       (1)
 396#define LOOP_CYCLES_COLDFIRE    (2)
 397
 398        if (CPU_IS_020) {
 399                cpu = "68020";
 400                clockfactor = LOOP_CYCLES_68020;
 401        } else if (CPU_IS_030) {
 402                cpu = "68030";
 403                clockfactor = LOOP_CYCLES_68030;
 404        } else if (CPU_IS_040) {
 405                cpu = "68040";
 406                clockfactor = LOOP_CYCLES_68040;
 407        } else if (CPU_IS_060) {
 408                cpu = "68060";
 409                clockfactor = LOOP_CYCLES_68060;
 410        } else if (CPU_IS_COLDFIRE) {
 411                cpu = "ColdFire";
 412                clockfactor = LOOP_CYCLES_COLDFIRE;
 413        } else {
 414                cpu = "680x0";
 415                clockfactor = 0;
 416        }
 417
 418#ifdef CONFIG_M68KFPU_EMU_ONLY
 419        fpu = "none(soft float)";
 420#else
 421        if (m68k_fputype & FPU_68881)
 422                fpu = "68881";
 423        else if (m68k_fputype & FPU_68882)
 424                fpu = "68882";
 425        else if (m68k_fputype & FPU_68040)
 426                fpu = "68040";
 427        else if (m68k_fputype & FPU_68060)
 428                fpu = "68060";
 429        else if (m68k_fputype & FPU_SUNFPA)
 430                fpu = "Sun FPA";
 431        else if (m68k_fputype & FPU_COLDFIRE)
 432                fpu = "ColdFire";
 433        else
 434                fpu = "none";
 435#endif
 436
 437        if (m68k_mmutype & MMU_68851)
 438                mmu = "68851";
 439        else if (m68k_mmutype & MMU_68030)
 440                mmu = "68030";
 441        else if (m68k_mmutype & MMU_68040)
 442                mmu = "68040";
 443        else if (m68k_mmutype & MMU_68060)
 444                mmu = "68060";
 445        else if (m68k_mmutype & MMU_SUN3)
 446                mmu = "Sun-3";
 447        else if (m68k_mmutype & MMU_APOLLO)
 448                mmu = "Apollo";
 449        else if (m68k_mmutype & MMU_COLDFIRE)
 450                mmu = "ColdFire";
 451        else
 452                mmu = "unknown";
 453
 454        clockfreq = loops_per_jiffy * HZ * clockfactor;
 455
 456        seq_printf(m, "CPU:\t\t%s\n"
 457                   "MMU:\t\t%s\n"
 458                   "FPU:\t\t%s\n"
 459                   "Clocking:\t%lu.%1luMHz\n"
 460                   "BogoMips:\t%lu.%02lu\n"
 461                   "Calibration:\t%lu loops\n",
 462                   cpu, mmu, fpu,
 463                   clockfreq/1000000,(clockfreq/100000)%10,
 464                   loops_per_jiffy/(500000/HZ),(loops_per_jiffy/(5000/HZ))%100,
 465                   loops_per_jiffy);
 466        return 0;
 467}
 468
 469static void *c_start(struct seq_file *m, loff_t *pos)
 470{
 471        return *pos < 1 ? (void *)1 : NULL;
 472}
 473static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 474{
 475        ++*pos;
 476        return NULL;
 477}
 478static void c_stop(struct seq_file *m, void *v)
 479{
 480}
 481const struct seq_operations cpuinfo_op = {
 482        .start  = c_start,
 483        .next   = c_next,
 484        .stop   = c_stop,
 485        .show   = show_cpuinfo,
 486};
 487
 488#ifdef CONFIG_PROC_HARDWARE
 489static int hardware_proc_show(struct seq_file *m, void *v)
 490{
 491        char model[80];
 492        unsigned long mem;
 493        int i;
 494
 495        if (mach_get_model)
 496                mach_get_model(model);
 497        else
 498                strcpy(model, "Unknown m68k");
 499
 500        seq_printf(m, "Model:\t\t%s\n", model);
 501        for (mem = 0, i = 0; i < m68k_num_memory; i++)
 502                mem += m68k_memory[i].size;
 503        seq_printf(m, "System Memory:\t%ldK\n", mem >> 10);
 504
 505        if (mach_get_hardware_list)
 506                mach_get_hardware_list(m);
 507
 508        return 0;
 509}
 510
 511static int __init proc_hardware_init(void)
 512{
 513        proc_create_single("hardware", 0, NULL, hardware_proc_show);
 514        return 0;
 515}
 516module_init(proc_hardware_init);
 517#endif
 518
 519void check_bugs(void)
 520{
 521#if defined(CONFIG_FPU) && !defined(CONFIG_M68KFPU_EMU)
 522        if (m68k_fputype == 0) {
 523                pr_emerg("*** YOU DO NOT HAVE A FLOATING POINT UNIT, "
 524                        "WHICH IS REQUIRED BY LINUX/M68K ***\n");
 525                pr_emerg("Upgrade your hardware or join the FPU "
 526                        "emulation project\n");
 527                panic("no FPU");
 528        }
 529#endif /* !CONFIG_M68KFPU_EMU */
 530}
 531
 532#ifdef CONFIG_ADB
 533static int __init adb_probe_sync_enable (char *str) {
 534        extern int __adb_probe_sync;
 535        __adb_probe_sync = 1;
 536        return 1;
 537}
 538
 539__setup("adb_sync", adb_probe_sync_enable);
 540#endif /* CONFIG_ADB */
 541
 542#if IS_ENABLED(CONFIG_NVRAM)
 543#ifdef CONFIG_MAC
 544static unsigned char m68k_nvram_read_byte(int addr)
 545{
 546        if (MACH_IS_MAC)
 547                return mac_pram_read_byte(addr);
 548        return 0xff;
 549}
 550
 551static void m68k_nvram_write_byte(unsigned char val, int addr)
 552{
 553        if (MACH_IS_MAC)
 554                mac_pram_write_byte(val, addr);
 555}
 556#endif /* CONFIG_MAC */
 557
 558#ifdef CONFIG_ATARI
 559static ssize_t m68k_nvram_read(char *buf, size_t count, loff_t *ppos)
 560{
 561        if (MACH_IS_ATARI)
 562                return atari_nvram_read(buf, count, ppos);
 563        else if (MACH_IS_MAC)
 564                return nvram_read_bytes(buf, count, ppos);
 565        return -EINVAL;
 566}
 567
 568static ssize_t m68k_nvram_write(char *buf, size_t count, loff_t *ppos)
 569{
 570        if (MACH_IS_ATARI)
 571                return atari_nvram_write(buf, count, ppos);
 572        else if (MACH_IS_MAC)
 573                return nvram_write_bytes(buf, count, ppos);
 574        return -EINVAL;
 575}
 576
 577static long m68k_nvram_set_checksum(void)
 578{
 579        if (MACH_IS_ATARI)
 580                return atari_nvram_set_checksum();
 581        return -EINVAL;
 582}
 583
 584static long m68k_nvram_initialize(void)
 585{
 586        if (MACH_IS_ATARI)
 587                return atari_nvram_initialize();
 588        return -EINVAL;
 589}
 590#endif /* CONFIG_ATARI */
 591
 592static ssize_t m68k_nvram_get_size(void)
 593{
 594        if (MACH_IS_ATARI)
 595                return atari_nvram_get_size();
 596        else if (MACH_IS_MAC)
 597                return mac_pram_get_size();
 598        return -ENODEV;
 599}
 600
 601/* Atari device drivers call .read (to get checksum validation) whereas
 602 * Mac and PowerMac device drivers just use .read_byte.
 603 */
 604const struct nvram_ops arch_nvram_ops = {
 605#ifdef CONFIG_MAC
 606        .read_byte      = m68k_nvram_read_byte,
 607        .write_byte     = m68k_nvram_write_byte,
 608#endif
 609#ifdef CONFIG_ATARI
 610        .read           = m68k_nvram_read,
 611        .write          = m68k_nvram_write,
 612        .set_checksum   = m68k_nvram_set_checksum,
 613        .initialize     = m68k_nvram_initialize,
 614#endif
 615        .get_size       = m68k_nvram_get_size,
 616};
 617EXPORT_SYMBOL(arch_nvram_ops);
 618#endif /* CONFIG_NVRAM */
 619