linux/arch/parisc/kernel/setup.c
<<
>>
Prefs
   1/*
   2 *    Initial setup-routines for HP 9000 based hardware.
   3 *
   4 *    Copyright (C) 1991, 1992, 1995  Linus Torvalds
   5 *    Modifications for PA-RISC (C) 1999 Helge Deller <deller@gmx.de>
   6 *    Modifications copyright 1999 SuSE GmbH (Philipp Rumpf)
   7 *    Modifications copyright 2000 Martin K. Petersen <mkp@mkp.net>
   8 *    Modifications copyright 2000 Philipp Rumpf <prumpf@tux.org>
   9 *    Modifications copyright 2001 Ryan Bradetich <rbradetich@uswest.net>
  10 *
  11 *    Initial PA-RISC Version: 04-23-1999 by Helge Deller
  12 *
  13 *    This program is free software; you can redistribute it and/or modify
  14 *    it under the terms of the GNU General Public License as published by
  15 *    the Free Software Foundation; either version 2, or (at your option)
  16 *    any later version.
  17 *
  18 *    This program is distributed in the hope that it will be useful,
  19 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 *    GNU General Public License for more details.
  22 *
  23 *    You should have received a copy of the GNU General Public License
  24 *    along with this program; if not, write to the Free Software
  25 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26 *
  27 */
  28
  29#include <linux/kernel.h>
  30#include <linux/initrd.h>
  31#include <linux/init.h>
  32#include <linux/console.h>
  33#include <linux/seq_file.h>
  34#define PCI_DEBUG
  35#include <linux/pci.h>
  36#undef PCI_DEBUG
  37#include <linux/proc_fs.h>
  38#include <linux/export.h>
  39#include <linux/sched.h>
  40#include <linux/sched/clock.h>
  41#include <linux/start_kernel.h>
  42
  43#include <asm/processor.h>
  44#include <asm/sections.h>
  45#include <asm/pdc.h>
  46#include <asm/led.h>
  47#include <asm/machdep.h>        /* for pa7300lc_init() proto */
  48#include <asm/pdc_chassis.h>
  49#include <asm/io.h>
  50#include <asm/setup.h>
  51#include <asm/unwind.h>
  52#include <asm/smp.h>
  53
  54static char __initdata command_line[COMMAND_LINE_SIZE];
  55
  56/* Intended for ccio/sba/cpu statistics under /proc/bus/{runway|gsc} */
  57struct proc_dir_entry * proc_runway_root __read_mostly = NULL;
  58struct proc_dir_entry * proc_gsc_root __read_mostly = NULL;
  59struct proc_dir_entry * proc_mckinley_root __read_mostly = NULL;
  60
  61#if !defined(CONFIG_PA20) && (defined(CONFIG_IOMMU_CCIO) || defined(CONFIG_IOMMU_SBA))
  62int parisc_bus_is_phys __read_mostly = 1;       /* Assume no IOMMU is present */
  63EXPORT_SYMBOL(parisc_bus_is_phys);
  64#endif
  65
  66void __init setup_cmdline(char **cmdline_p)
  67{
  68        extern unsigned int boot_args[];
  69
  70        /* Collect stuff passed in from the boot loader */
  71
  72        /* boot_args[0] is free-mem start, boot_args[1] is ptr to command line */
  73        if (boot_args[0] < 64) {
  74                /* called from hpux boot loader */
  75                boot_command_line[0] = '\0';
  76        } else {
  77                strlcpy(boot_command_line, (char *)__va(boot_args[1]),
  78                        COMMAND_LINE_SIZE);
  79
  80#ifdef CONFIG_BLK_DEV_INITRD
  81                if (boot_args[2] != 0) /* did palo pass us a ramdisk? */
  82                {
  83                    initrd_start = (unsigned long)__va(boot_args[2]);
  84                    initrd_end = (unsigned long)__va(boot_args[3]);
  85                }
  86#endif
  87        }
  88
  89        strcpy(command_line, boot_command_line);
  90        *cmdline_p = command_line;
  91}
  92
  93#ifdef CONFIG_PA11
  94void __init dma_ops_init(void)
  95{
  96        switch (boot_cpu_data.cpu_type) {
  97        case pcx:
  98                /*
  99                 * We've got way too many dependencies on 1.1 semantics
 100                 * to support 1.0 boxes at this point.
 101                 */
 102                panic(  "PA-RISC Linux currently only supports machines that conform to\n"
 103                        "the PA-RISC 1.1 or 2.0 architecture specification.\n");
 104
 105        case pcxs:
 106        case pcxt:
 107                hppa_dma_ops = &pcx_dma_ops;
 108                break;
 109        case pcxl2:
 110                pa7300lc_init();
 111        case pcxl: /* falls through */
 112                hppa_dma_ops = &pcxl_dma_ops;
 113                break;
 114        default:
 115                break;
 116        }
 117}
 118#endif
 119
 120extern void collect_boot_cpu_data(void);
 121
 122void __init setup_arch(char **cmdline_p)
 123{
 124#ifdef CONFIG_64BIT
 125        extern int parisc_narrow_firmware;
 126#endif
 127        unwind_init();
 128
 129        init_per_cpu(smp_processor_id());       /* Set Modes & Enable FP */
 130
 131#ifdef CONFIG_64BIT
 132        printk(KERN_INFO "The 64-bit Kernel has started...\n");
 133#else
 134        printk(KERN_INFO "The 32-bit Kernel has started...\n");
 135#endif
 136
 137        printk(KERN_INFO "Kernel default page size is %d KB. Huge pages ",
 138                (int)(PAGE_SIZE / 1024));
 139#ifdef CONFIG_HUGETLB_PAGE
 140        printk(KERN_CONT "enabled with %d MB physical and %d MB virtual size",
 141                 1 << (REAL_HPAGE_SHIFT - 20), 1 << (HPAGE_SHIFT - 20));
 142#else
 143        printk(KERN_CONT "disabled");
 144#endif
 145        printk(KERN_CONT ".\n");
 146
 147        /*
 148         * Check if initial kernel page mappings are sufficient.
 149         * panic early if not, else we may access kernel functions
 150         * and variables which can't be reached.
 151         */
 152        if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
 153                panic("KERNEL_INITIAL_ORDER too small!");
 154
 155        pdc_console_init();
 156
 157#ifdef CONFIG_64BIT
 158        if(parisc_narrow_firmware) {
 159                printk(KERN_INFO "Kernel is using PDC in 32-bit mode.\n");
 160        }
 161#endif
 162        setup_pdc();
 163        setup_cmdline(cmdline_p);
 164        collect_boot_cpu_data();
 165        do_memory_inventory();  /* probe for physical memory */
 166        parisc_cache_init();
 167        paging_init();
 168
 169#ifdef CONFIG_CHASSIS_LCD_LED
 170        /* initialize the LCD/LED after boot_cpu_data is available ! */
 171        led_init();             /* LCD/LED initialization */
 172#endif
 173
 174#ifdef CONFIG_PA11
 175        dma_ops_init();
 176#endif
 177
 178#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
 179        conswitchp = &dummy_con;        /* we use do_take_over_console() later ! */
 180#endif
 181
 182        clear_sched_clock_stable();
 183}
 184
 185/*
 186 * Display CPU info for all CPUs.
 187 * for parisc this is in processor.c
 188 */
 189extern int show_cpuinfo (struct seq_file *m, void *v);
 190
 191static void *
 192c_start (struct seq_file *m, loff_t *pos)
 193{
 194        /* Looks like the caller will call repeatedly until we return
 195         * 0, signaling EOF perhaps.  This could be used to sequence
 196         * through CPUs for example.  Since we print all cpu info in our
 197         * show_cpuinfo() disregarding 'pos' (which I assume is 'v' above)
 198         * we only allow for one "position".  */
 199        return ((long)*pos < 1) ? (void *)1 : NULL;
 200}
 201
 202static void *
 203c_next (struct seq_file *m, void *v, loff_t *pos)
 204{
 205        ++*pos;
 206        return c_start(m, pos);
 207}
 208
 209static void
 210c_stop (struct seq_file *m, void *v)
 211{
 212}
 213
 214const struct seq_operations cpuinfo_op = {
 215        .start  = c_start,
 216        .next   = c_next,
 217        .stop   = c_stop,
 218        .show   = show_cpuinfo
 219};
 220
 221static void __init parisc_proc_mkdir(void)
 222{
 223        /*
 224        ** Can't call proc_mkdir() until after proc_root_init() has been
 225        ** called by start_kernel(). In other words, this code can't
 226        ** live in arch/.../setup.c because start_parisc() calls
 227        ** start_kernel().
 228        */
 229        switch (boot_cpu_data.cpu_type) {
 230        case pcxl:
 231        case pcxl2:
 232                if (NULL == proc_gsc_root)
 233                {
 234                        proc_gsc_root = proc_mkdir("bus/gsc", NULL);
 235                }
 236                break;
 237        case pcxt_:
 238        case pcxu:
 239        case pcxu_:
 240        case pcxw:
 241        case pcxw_:
 242        case pcxw2:
 243                if (NULL == proc_runway_root)
 244                {
 245                        proc_runway_root = proc_mkdir("bus/runway", NULL);
 246                }
 247                break;
 248        case mako:
 249        case mako2:
 250                if (NULL == proc_mckinley_root)
 251                {
 252                        proc_mckinley_root = proc_mkdir("bus/mckinley", NULL);
 253                }
 254                break;
 255        default:
 256                /* FIXME: this was added to prevent the compiler 
 257                 * complaining about missing pcx, pcxs and pcxt
 258                 * I'm assuming they have neither gsc nor runway */
 259                break;
 260        }
 261}
 262
 263static struct resource central_bus = {
 264        .name   = "Central Bus",
 265        .start  = F_EXTEND(0xfff80000),
 266        .end    = F_EXTEND(0xfffaffff),
 267        .flags  = IORESOURCE_MEM,
 268};
 269
 270static struct resource local_broadcast = {
 271        .name   = "Local Broadcast",
 272        .start  = F_EXTEND(0xfffb0000),
 273        .end    = F_EXTEND(0xfffdffff),
 274        .flags  = IORESOURCE_MEM,
 275};
 276
 277static struct resource global_broadcast = {
 278        .name   = "Global Broadcast",
 279        .start  = F_EXTEND(0xfffe0000),
 280        .end    = F_EXTEND(0xffffffff),
 281        .flags  = IORESOURCE_MEM,
 282};
 283
 284static int __init parisc_init_resources(void)
 285{
 286        int result;
 287
 288        result = request_resource(&iomem_resource, &central_bus);
 289        if (result < 0) {
 290                printk(KERN_ERR 
 291                       "%s: failed to claim %s address space!\n", 
 292                       __FILE__, central_bus.name);
 293                return result;
 294        }
 295
 296        result = request_resource(&iomem_resource, &local_broadcast);
 297        if (result < 0) {
 298                printk(KERN_ERR 
 299                       "%s: failed to claim %saddress space!\n", 
 300                       __FILE__, local_broadcast.name);
 301                return result;
 302        }
 303
 304        result = request_resource(&iomem_resource, &global_broadcast);
 305        if (result < 0) {
 306                printk(KERN_ERR 
 307                       "%s: failed to claim %s address space!\n", 
 308                       __FILE__, global_broadcast.name);
 309                return result;
 310        }
 311
 312        return 0;
 313}
 314
 315extern void gsc_init(void);
 316extern void processor_init(void);
 317extern void ccio_init(void);
 318extern void hppb_init(void);
 319extern void dino_init(void);
 320extern void iosapic_init(void);
 321extern void lba_init(void);
 322extern void sba_init(void);
 323extern void eisa_init(void);
 324
 325static int __init parisc_init(void)
 326{
 327        u32 osid = (OS_ID_LINUX << 16);
 328
 329        parisc_proc_mkdir();
 330        parisc_init_resources();
 331        do_device_inventory();                  /* probe for hardware */
 332
 333        parisc_pdc_chassis_init();
 334        
 335        /* set up a new led state on systems shipped LED State panel */
 336        pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART);
 337
 338        /* tell PDC we're Linux. Nevermind failure. */
 339        pdc_stable_write(0x40, &osid, sizeof(osid));
 340        
 341        /* start with known state */
 342        flush_cache_all_local();
 343        flush_tlb_all_local(NULL);
 344
 345        processor_init();
 346#ifdef CONFIG_SMP
 347        pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
 348                num_online_cpus(), num_present_cpus(),
 349#else
 350        pr_info("CPU(s): 1 x %s at %d.%06d MHz\n",
 351#endif
 352                        boot_cpu_data.cpu_name,
 353                        boot_cpu_data.cpu_hz / 1000000,
 354                        boot_cpu_data.cpu_hz % 1000000  );
 355
 356        parisc_setup_cache_timing();
 357
 358        /* These are in a non-obvious order, will fix when we have an iotree */
 359#if defined(CONFIG_IOSAPIC)
 360        iosapic_init();
 361#endif
 362#if defined(CONFIG_IOMMU_SBA)
 363        sba_init();
 364#endif
 365#if defined(CONFIG_PCI_LBA)
 366        lba_init();
 367#endif
 368
 369        /* CCIO before any potential subdevices */
 370#if defined(CONFIG_IOMMU_CCIO)
 371        ccio_init();
 372#endif
 373
 374        /*
 375         * Need to register Asp & Wax before the EISA adapters for the IRQ
 376         * regions.  EISA must come before PCI to be sure it gets IRQ region
 377         * 0.
 378         */
 379#if defined(CONFIG_GSC_LASI) || defined(CONFIG_GSC_WAX)
 380        gsc_init();
 381#endif
 382#ifdef CONFIG_EISA
 383        eisa_init();
 384#endif
 385
 386#if defined(CONFIG_HPPB)
 387        hppb_init();
 388#endif
 389
 390#if defined(CONFIG_GSC_DINO)
 391        dino_init();
 392#endif
 393
 394#ifdef CONFIG_CHASSIS_LCD_LED
 395        register_led_regions(); /* register LED port info in procfs */
 396#endif
 397
 398        return 0;
 399}
 400arch_initcall(parisc_init);
 401
 402void __init start_parisc(void)
 403{
 404        extern void early_trap_init(void);
 405
 406        int ret, cpunum;
 407        struct pdc_coproc_cfg coproc_cfg;
 408
 409        cpunum = smp_processor_id();
 410
 411        init_cpu_topology();
 412
 413        set_firmware_width_unlocked();
 414
 415        ret = pdc_coproc_cfg_unlocked(&coproc_cfg);
 416        if (ret >= 0 && coproc_cfg.ccr_functional) {
 417                mtctl(coproc_cfg.ccr_functional, 10);
 418
 419                per_cpu(cpu_data, cpunum).fp_rev = coproc_cfg.revision;
 420                per_cpu(cpu_data, cpunum).fp_model = coproc_cfg.model;
 421
 422                asm volatile ("fstd     %fr0,8(%sp)");
 423        } else {
 424                panic("must have an fpu to boot linux");
 425        }
 426
 427        early_trap_init(); /* initialize checksum of fault_vector */
 428
 429        start_kernel();
 430        // not reached
 431}
 432