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