linux/arch/m32r/kernel/setup.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/m32r/kernel/setup.c
   3 *
   4 *  Setup routines for Renesas M32R
   5 *
   6 *  Copyright (c) 2001, 2002  Hiroyuki Kondo, Hirokazu Takata,
   7 *                            Hitoshi Yamamoto
   8 */
   9
  10/* $Id$ */
  11
  12#include <linux/config.h>
  13#include <linux/init.h>
  14#include <linux/stddef.h>
  15#include <linux/fs.h>
  16#include <linux/sched.h>
  17#include <linux/ioport.h>
  18#include <linux/mm.h>
  19#include <linux/bootmem.h>
  20#include <linux/console.h>
  21#include <linux/initrd.h>
  22#include <linux/major.h>
  23#include <linux/root_dev.h>
  24#include <linux/seq_file.h>
  25#include <linux/timex.h>
  26#include <linux/tty.h>
  27#include <asm/processor.h>
  28#include <asm/pgtable.h>
  29#include <asm/io.h>
  30#include <asm/mmu_context.h>
  31#include <asm/m32r.h>
  32#include <asm/setup.h>
  33#include <asm/sections.h>
  34
  35#ifdef CONFIG_MMU
  36extern void init_mmu(void);
  37#endif
  38
  39#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD)   \
  40        || defined(CONFIG_BLK_DEV_IDE_MODULE)                   \
  41        || defined(CONFIG_BLK_DEV_HD_MODULE)
  42struct drive_info_struct { char dummy[32]; } drive_info;
  43#endif
  44
  45extern char _end[];
  46
  47/*
  48 * Machine setup..
  49 */
  50struct cpuinfo_m32r boot_cpu_data;
  51
  52#ifdef CONFIG_BLK_DEV_RAM
  53extern int rd_doload;   /* 1 = load ramdisk, 0 = don't load */
  54extern int rd_prompt;   /* 1 = prompt for ramdisk, 0 = don't prompt */
  55extern int rd_image_start;  /* starting block # of image */
  56#endif
  57
  58#if defined(CONFIG_VGA_CONSOLE)
  59struct screen_info screen_info = {
  60        .orig_video_lines      = 25,
  61        .orig_video_cols       = 80,
  62        .orig_video_mode       = 0,
  63        .orig_video_ega_bx     = 0,
  64        .orig_video_isVGA      = 1,
  65        .orig_video_points     = 8
  66};
  67#endif
  68
  69extern int root_mountflags;
  70
  71static char command_line[COMMAND_LINE_SIZE];
  72
  73static struct resource data_resource = {
  74        .name   = "Kernel data",
  75        .start  = 0,
  76        .end    = 0,
  77        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
  78};
  79
  80static struct resource code_resource = {
  81        .name   = "Kernel code",
  82        .start  = 0,
  83        .end    = 0,
  84        .flags  = IORESOURCE_BUSY | IORESOURCE_MEM
  85};
  86
  87unsigned long memory_start;
  88unsigned long memory_end;
  89
  90void __init setup_arch(char **);
  91int get_cpuinfo(char *);
  92
  93static __inline__ void parse_mem_cmdline(char ** cmdline_p)
  94{
  95        char c = ' ';
  96        char *to = command_line;
  97        char *from = COMMAND_LINE;
  98        int len = 0;
  99        int usermem = 0;
 100
 101        /* Save unparsed command line copy for /proc/cmdline */
 102        memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
 103        saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
 104
 105        memory_start = (unsigned long)CONFIG_MEMORY_START+PAGE_OFFSET;
 106        memory_end = memory_start+(unsigned long)CONFIG_MEMORY_SIZE;
 107
 108        for ( ; ; ) {
 109                if (c == ' ' && !memcmp(from, "mem=", 4)) {
 110                        if (to != command_line)
 111                                to--;
 112
 113                        {
 114                                unsigned long mem_size;
 115
 116                                usermem = 1;
 117                                mem_size = memparse(from+4, &from);
 118                                memory_end = memory_start + mem_size;
 119                        }
 120                }
 121                c = *(from++);
 122                if (!c)
 123                        break;
 124
 125                if (COMMAND_LINE_SIZE <= ++len)
 126                        break;
 127
 128                *(to++) = c;
 129        }
 130        *to = '\0';
 131        *cmdline_p = command_line;
 132        if (usermem)
 133                printk(KERN_INFO "user-defined physical RAM map:\n");
 134}
 135
 136#ifndef CONFIG_DISCONTIGMEM
 137static unsigned long __init setup_memory(void)
 138{
 139        unsigned long start_pfn, max_low_pfn, bootmap_size;
 140
 141        start_pfn = PFN_UP( __pa(_end) );
 142        max_low_pfn = PFN_DOWN( __pa(memory_end) );
 143
 144        /*
 145         * Initialize the boot-time allocator (with low memory only):
 146         */
 147        bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
 148                CONFIG_MEMORY_START>>PAGE_SHIFT, max_low_pfn);
 149
 150        /*
 151         * Register fully available low RAM pages with the bootmem allocator.
 152         */
 153        {
 154                unsigned long curr_pfn;
 155                unsigned long last_pfn;
 156                unsigned long pages;
 157
 158                /*
 159                 * We are rounding up the start address of usable memory:
 160                 */
 161                curr_pfn = PFN_UP(__pa(memory_start));
 162
 163                /*
 164                 * ... and at the end of the usable range downwards:
 165                 */
 166                last_pfn = PFN_DOWN(__pa(memory_end));
 167
 168                if (last_pfn > max_low_pfn)
 169                        last_pfn = max_low_pfn;
 170
 171                pages = last_pfn - curr_pfn;
 172                free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
 173        }
 174
 175        /*
 176         * Reserve the kernel text and
 177         * Reserve the bootmem bitmap. We do this in two steps (first step
 178         * was init_bootmem()), because this catches the (definitely buggy)
 179         * case of us accidentally initializing the bootmem allocator with
 180         * an invalid RAM area.
 181         */
 182        reserve_bootmem(CONFIG_MEMORY_START + PAGE_SIZE,
 183                (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE - 1)
 184                - CONFIG_MEMORY_START);
 185
 186        /*
 187         * reserve physical page 0 - it's a special BIOS page on many boxes,
 188         * enabling clean reboots, SMP operation, laptop functions.
 189         */
 190        reserve_bootmem(CONFIG_MEMORY_START, PAGE_SIZE);
 191
 192        /*
 193         * reserve memory hole
 194         */
 195#ifdef CONFIG_MEMHOLE
 196        reserve_bootmem(CONFIG_MEMHOLE_START, CONFIG_MEMHOLE_SIZE);
 197#endif
 198
 199#ifdef CONFIG_BLK_DEV_INITRD
 200        if (LOADER_TYPE && INITRD_START) {
 201                if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
 202                        reserve_bootmem(INITRD_START, INITRD_SIZE);
 203                        initrd_start = INITRD_START ?
 204                                INITRD_START + PAGE_OFFSET : 0;
 205
 206                        initrd_end = initrd_start + INITRD_SIZE;
 207                        printk("initrd:start[%08lx],size[%08lx]\n",
 208                                initrd_start, INITRD_SIZE);
 209                } else {
 210                        printk("initrd extends beyond end of memory "
 211                                "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
 212                                INITRD_START + INITRD_SIZE,
 213                                max_low_pfn << PAGE_SHIFT);
 214
 215                        initrd_start = 0;
 216                }
 217        }
 218#endif
 219
 220        return max_low_pfn;
 221}
 222#else   /* CONFIG_DISCONTIGMEM */
 223extern unsigned long setup_memory(void);
 224#endif  /* CONFIG_DISCONTIGMEM */
 225
 226#define M32R_PCC_PCATCR 0x00ef7014      /* will move to m32r.h */
 227
 228void __init setup_arch(char **cmdline_p)
 229{
 230        ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
 231
 232        boot_cpu_data.cpu_clock = M32R_CPUCLK;
 233        boot_cpu_data.bus_clock = M32R_BUSCLK;
 234        boot_cpu_data.timer_divide = M32R_TIMER_DIVIDE;
 235
 236#ifdef CONFIG_BLK_DEV_RAM
 237        rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 238        rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
 239        rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 240#endif
 241
 242        if (!MOUNT_ROOT_RDONLY)
 243                root_mountflags &= ~MS_RDONLY;
 244
 245#ifdef CONFIG_VT
 246#if defined(CONFIG_VGA_CONSOLE)
 247        conswitchp = &vga_con;
 248#elif defined(CONFIG_DUMMY_CONSOLE)
 249        conswitchp = &dummy_con;
 250#endif
 251#endif
 252
 253#ifdef CONFIG_DISCONTIGMEM
 254        nodes_clear(node_online_map);
 255        node_set_online(0);
 256        node_set_online(1);
 257#endif  /* CONFIG_DISCONTIGMEM */
 258
 259        init_mm.start_code = (unsigned long) _text;
 260        init_mm.end_code = (unsigned long) _etext;
 261        init_mm.end_data = (unsigned long) _edata;
 262        init_mm.brk = (unsigned long) _end;
 263
 264        code_resource.start = virt_to_phys(_text);
 265        code_resource.end = virt_to_phys(_etext)-1;
 266        data_resource.start = virt_to_phys(_etext);
 267        data_resource.end = virt_to_phys(_edata)-1;
 268
 269        parse_mem_cmdline(cmdline_p);
 270
 271        setup_memory();
 272
 273        paging_init();
 274}
 275
 276#ifdef CONFIG_PROC_FS
 277/*
 278 *      Get CPU information for use by the procfs.
 279 */
 280static int show_cpuinfo(struct seq_file *m, void *v)
 281{
 282        struct cpuinfo_m32r *c = v;
 283        unsigned long cpu = c - cpu_data;
 284
 285#ifdef CONFIG_SMP
 286        if (!cpu_online(cpu))
 287                return 0;
 288#endif  /* CONFIG_SMP */
 289
 290        seq_printf(m, "processor\t: %ld\n", cpu);
 291
 292#ifdef CONFIG_CHIP_VDEC2
 293        seq_printf(m, "cpu family\t: VDEC2\n"
 294                "cache size\t: Unknown\n");
 295#elif  CONFIG_CHIP_M32700
 296        seq_printf(m,"cpu family\t: M32700\n"
 297                "cache size\t: I-8KB/D-8KB\n");
 298#elif  CONFIG_CHIP_M32102
 299        seq_printf(m,"cpu family\t: M32102\n"
 300                "cache size\t: I-8KB\n");
 301#elif  CONFIG_CHIP_OPSP
 302        seq_printf(m,"cpu family\t: OPSP\n"
 303                "cache size\t: I-8KB/D-8KB\n");
 304#elif  CONFIG_CHIP_MP
 305        seq_printf(m, "cpu family\t: M32R-MP\n"
 306                "cache size\t: I-xxKB/D-xxKB\n");
 307#else
 308        seq_printf(m, "cpu family\t: Unknown\n");
 309#endif
 310        seq_printf(m, "bogomips\t: %lu.%02lu\n",
 311                c->loops_per_jiffy/(500000/HZ),
 312                (c->loops_per_jiffy/(5000/HZ)) % 100);
 313#ifdef CONFIG_PLAT_MAPPI
 314        seq_printf(m, "Machine\t\t: Mappi Evaluation board\n");
 315#elif CONFIG_PLAT_MAPPI2
 316        seq_printf(m, "Machine\t\t: Mappi-II Evaluation board\n");
 317#elif  CONFIG_PLAT_M32700UT
 318        seq_printf(m, "Machine\t\t: M32700UT Evaluation board\n");
 319#elif  CONFIG_PLAT_OPSPUT
 320        seq_printf(m, "Machine\t\t: OPSPUT Evaluation board\n");
 321#elif  CONFIG_PLAT_USRV
 322        seq_printf(m, "Machine\t\t: uServer\n");
 323#elif  CONFIG_PLAT_OAKS32R
 324        seq_printf(m, "Machine\t\t: OAKS32R\n");
 325#else
 326        seq_printf(m, "Machine\t\t: Unknown\n");
 327#endif
 328
 329#define PRINT_CLOCK(name, value)                                \
 330        seq_printf(m, name " clock\t: %d.%02dMHz\n",            \
 331                ((value) / 1000000), ((value) % 1000000)/10000)
 332
 333        PRINT_CLOCK("CPU", (int)c->cpu_clock);
 334        PRINT_CLOCK("Bus", (int)c->bus_clock);
 335
 336        seq_printf(m, "\n");
 337
 338        return 0;
 339}
 340
 341static void *c_start(struct seq_file *m, loff_t *pos)
 342{
 343        return *pos < NR_CPUS ? cpu_data + *pos : NULL;
 344}
 345
 346static void *c_next(struct seq_file *m, void *v, loff_t *pos)
 347{
 348        ++*pos;
 349        return c_start(m, pos);
 350}
 351
 352static void c_stop(struct seq_file *m, void *v)
 353{
 354}
 355
 356struct seq_operations cpuinfo_op = {
 357        start:  c_start,
 358        next:   c_next,
 359        stop:   c_stop,
 360        show:   show_cpuinfo,
 361};
 362#endif  /* CONFIG_PROC_FS */
 363
 364unsigned long cpu_initialized __initdata = 0;
 365
 366/*
 367 * cpu_init() initializes state that is per-CPU. Some data is already
 368 * initialized (naturally) in the bootstrap process.
 369 * We reload them nevertheless, this function acts as a
 370 * 'CPU state barrier', nothing should get across.
 371 */
 372#if defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_XNUX2)    \
 373        || defined(CONFIG_CHIP_M32700) || defined(CONFIG_CHIP_M32102) \
 374        || defined(CONFIG_CHIP_OPSP)
 375void __init cpu_init (void)
 376{
 377        int cpu_id = smp_processor_id();
 378
 379        if (test_and_set_bit(cpu_id, &cpu_initialized)) {
 380                printk(KERN_WARNING "CPU#%d already initialized!\n", cpu_id);
 381                for ( ; ; )
 382                        local_irq_enable();
 383        }
 384        printk(KERN_INFO "Initializing CPU#%d\n", cpu_id);
 385
 386        /* Set up and load the per-CPU TSS and LDT */
 387        atomic_inc(&init_mm.mm_count);
 388        current->active_mm = &init_mm;
 389        if (current->mm)
 390                BUG();
 391
 392        /* Force FPU initialization */
 393        current_thread_info()->status = 0;
 394        clear_used_math();
 395
 396#ifdef CONFIG_MMU
 397        /* Set up MMU */
 398        init_mmu();
 399#endif
 400
 401        /* Set up ICUIMASK */
 402        outl(0x00070000, M32R_ICU_IMASK_PORTL);   /* imask=111 */
 403}
 404#endif  /* defined(CONFIG_CHIP_VDEC2) ... */
 405
 406
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.