setup.c
来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,121 行 · 第 1/2 页
C
1,121 行
/* * Fill the naca & systemcfg structures with informations * retreived from the device-tree. Need to be called before * finish_device_tree() since the later requires some of the * informations filled up here to properly parse the interrupt * tree. * It also sets up the cache line sizes which allows to call * routines like flush_icache_range (used by the hash init * later on). */ initialize_naca();#ifdef CONFIG_PPC_PSERIES /* * Initialize RTAS if available */ rtas_initialize();#endif /* CONFIG_PPC_PSERIES */ /* * Check if we have an initrd provided via the device-tree */ check_for_initrd(); /* * Do some platform specific early initializations, that includes * setting up the hash table pointers. It also sets up some interrupt-mapping * related options that will be used by finish_device_tree() */ ppc_md.init_early(); /* * "Finish" the device-tree, that is do the actual parsing of * some of the properties like the interrupt map */ finish_device_tree(); /* * Initialize xmon */#ifdef CONFIG_XMON_DEFAULT xmon_init();#endif /* * Register early console */ early_console_initialized = 1; register_console(&udbg_console);#endif /* !CONFIG_PPC_ISERIES */ /* Save unparsed command line copy for /proc/cmdline */ strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); parse_early_param();#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) /* * iSeries has already initialized the cpu maps at this point. */ setup_cpu_maps();#endif /* defined(CONFIG_SMP) && !defined(CONFIG_PPC_ISERIES) */ printk("Starting Linux PPC64 %s\n", UTS_RELEASE); printk("-----------------------------------------------------\n"); printk("naca = 0x%p\n", naca); printk("naca->pftSize = 0x%lx\n", naca->pftSize); printk("naca->debug_switch = 0x%lx\n", naca->debug_switch); printk("naca->interrupt_controller = 0x%ld\n", naca->interrupt_controller); printk("systemcfg = 0x%p\n", systemcfg); printk("systemcfg->processorCount = 0x%lx\n", systemcfg->processorCount); printk("systemcfg->physicalMemorySize = 0x%lx\n", systemcfg->physicalMemorySize); printk("systemcfg->dCacheL1LineSize = 0x%x\n", systemcfg->dCacheL1LineSize); printk("systemcfg->iCacheL1LineSize = 0x%x\n", systemcfg->iCacheL1LineSize); printk("htab_data.htab = 0x%p\n", htab_data.htab); printk("htab_data.num_ptegs = 0x%lx\n", htab_data.htab_num_ptegs); printk("-----------------------------------------------------\n"); mm_init_ppc64(); DBG(" <- setup_system()\n");}void machine_restart(char *cmd){ if (ppc_md.nvram_sync) ppc_md.nvram_sync(); ppc_md.restart(cmd);}EXPORT_SYMBOL(machine_restart); void machine_power_off(void){ if (ppc_md.nvram_sync) ppc_md.nvram_sync(); ppc_md.power_off();}EXPORT_SYMBOL(machine_power_off); void machine_halt(void){ if (ppc_md.nvram_sync) ppc_md.nvram_sync(); ppc_md.halt();}EXPORT_SYMBOL(machine_halt);unsigned long ppc_proc_freq;unsigned long ppc_tb_freq;static int ppc64_panic_event(struct notifier_block *this, unsigned long event, void *ptr){ ppc_md.panic((char *)ptr); /* May not return */ return NOTIFY_DONE;}#ifdef CONFIG_SMPDEFINE_PER_CPU(unsigned int, pvr);#endifstatic int show_cpuinfo(struct seq_file *m, void *v){ unsigned long cpu_id = (unsigned long)v - 1; unsigned int pvr; unsigned short maj; unsigned short min; if (cpu_id == NR_CPUS) { seq_printf(m, "timebase\t: %lu\n", ppc_tb_freq); if (ppc_md.get_cpuinfo != NULL) ppc_md.get_cpuinfo(m); return 0; } /* We only show online cpus: disable preempt (overzealous, I * knew) to prevent cpu going down. */ preempt_disable(); if (!cpu_online(cpu_id)) { preempt_enable(); return 0; }#ifdef CONFIG_SMP pvr = per_cpu(pvr, cpu_id);#else pvr = mfspr(SPRN_PVR);#endif maj = (pvr >> 8) & 0xFF; min = pvr & 0xFF; seq_printf(m, "processor\t: %lu\n", cpu_id); seq_printf(m, "cpu\t\t: "); if (cur_cpu_spec->pvr_mask) seq_printf(m, "%s", cur_cpu_spec->cpu_name); else seq_printf(m, "unknown (%08x)", pvr);#ifdef CONFIG_ALTIVEC if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) seq_printf(m, ", altivec supported");#endif /* CONFIG_ALTIVEC */ seq_printf(m, "\n"); /* * Assume here that all clock rates are the same in a * smp system. -- Cort */ seq_printf(m, "clock\t\t: %lu.%06luMHz\n", ppc_proc_freq / 1000000, ppc_proc_freq % 1000000); seq_printf(m, "revision\t: %hd.%hd\n\n", maj, min); preempt_enable(); return 0;}static void *c_start(struct seq_file *m, loff_t *pos){ return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;}static void *c_next(struct seq_file *m, void *v, loff_t *pos){ ++*pos; return c_start(m, pos);}static void c_stop(struct seq_file *m, void *v){}struct seq_operations cpuinfo_op = { .start =c_start, .next = c_next, .stop = c_stop, .show = show_cpuinfo,};#if 0 /* XXX not currently used */unsigned long memory_limit;static int __init early_parsemem(char *p){ if (!p) return 0; memory_limit = memparse(p, &p); return 0;}early_param("mem", early_parsemem);#endif#ifdef CONFIG_PPC_MULTIPLATFORMstatic int __init set_preferred_console(void){ struct device_node *prom_stdout; char *name; int offset = 0;#if 0 phandle *stdout_ph;#endif DBG(" -> set_preferred_console()\n"); /* The user has requested a console so this is already set up. */ if (strstr(saved_command_line, "console=")) { DBG(" console was specified !\n"); return -EBUSY; } if (!of_chosen) { DBG(" of_chosen is NULL !\n"); return -ENODEV; } /* We are getting a weird phandle from OF ... */#if 0 stdout_ph = (phandle *)get_property(of_chosen, "linux,stdout-package", NULL); if (stdout_ph == NULL) { DBG(" no linux,stdout-package !\n"); return -ENODEV; } prom_stdout = of_find_node_by_phandle(*stdout_ph); if (!prom_stdout) { DBG(" can't find stdout package for phandle 0x%x !\n", *stdout_ph); return -ENODEV; }#endif /* ... So use the full path instead */#if 1 name = (char *)get_property(of_chosen, "linux,stdout-path", NULL); if (name == NULL) { DBG(" no linux,stdout-path !\n"); return -ENODEV; } prom_stdout = of_find_node_by_path(name); if (!prom_stdout) { DBG(" can't find stdout package %s !\n", name); return -ENODEV; } #endif DBG("stdout is %s\n", prom_stdout->full_name); name = (char *)get_property(prom_stdout, "name", NULL); if (!name) { DBG(" stdout package has no name !\n"); goto not_found; } if (strcmp(name, "serial") == 0) { int i; u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); if (i > 8) { switch (reg[1]) { case 0x3f8: offset = 0; break; case 0x2f8: offset = 1; break; case 0x898: offset = 2; break; case 0x890: offset = 3; break; default: /* We dont recognise the serial port */ goto not_found; } } }#ifdef CONFIG_PPC_PSERIES else if (strcmp(name, "vty") == 0) { u32 *reg = (u32 *)get_property(prom_stdout, "reg", NULL); char *compat = (char *)get_property(prom_stdout, "compatible", NULL); if (reg && compat && (strcmp(compat, "hvterm-protocol") == 0)) { /* Host Virtual Serial Interface */ int offset; switch (reg[0]) { case 0x30000000: offset = 0; break; case 0x30000001: offset = 1; break; default: goto not_found; } of_node_put(prom_stdout); DBG("Found hvsi console at offset %d\n", offset); return add_preferred_console("hvsi", offset, NULL); } else { /* pSeries LPAR virtual console */ of_node_put(prom_stdout); DBG("Found hvc console\n"); return add_preferred_console("hvc", 0, NULL); } }#endif /* CONFIG_PPC_PSERIES */ else if (strcmp(name, "ch-a") == 0) offset = 0; else if (strcmp(name, "ch-b") == 0) offset = 1; else goto not_found; of_node_put(prom_stdout); DBG("Found serial console at ttyS%d\n", offset); return add_preferred_console("ttyS", offset, NULL); not_found: DBG("No preferred console found !\n"); of_node_put(prom_stdout); return -ENODEV;}console_initcall(set_preferred_console);#endif /* CONFIG_PPC_MULTIPLATFORM */#ifdef CONFIG_IRQSTACKSstatic void __init irqstack_early_init(void){ unsigned int i; /* * interrupt stacks must be under 256MB, we cannot afford to take * SLB misses on them. */ for_each_cpu(i) { softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, 0x10000000)); hardirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, 0x10000000)); }}#else#define irqstack_early_init()#endif/* * Stack space used when we detect a bad kernel stack pointer, and * early in SMP boots before relocation is enabled. */static void __init emergency_stack_init(void){ unsigned long limit; unsigned int i; /* * Emergency stacks must be under 256MB, we cannot afford to take * SLB misses on them. The ABI also requires them to be 128-byte * aligned. * * Since we use these as temporary stacks during secondary CPU * bringup, we need to get at them in real mode. This means they * must also be within the RMO region. */ limit = min(0x10000000UL, lmb.rmo_size); for_each_cpu(i) paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128, limit)) + PAGE_SIZE;}/* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until * mem_init is called. */void __init setup_arch(char **cmdline_p){ extern int panic_timeout; extern void do_init_bootmem(void); ppc64_boot_msg(0x12, "Setup Arch"); *cmdline_p = cmd_line; /* * Set cache line size based on type of cpu as a default. * Systems with OF can look in the properties on the cpu node(s) * for a possibly more accurate value. */ dcache_bsize = systemcfg->dCacheL1LineSize; icache_bsize = systemcfg->iCacheL1LineSize; /* reboot on panic */ panic_timeout = 180; if (ppc_md.panic) notifier_chain_register(&panic_notifier_list, &ppc64_panic_block); init_mm.start_code = PAGE_OFFSET; init_mm.end_code = (unsigned long) _etext; init_mm.end_data = (unsigned long) _edata; init_mm.brk = klimit; irqstack_early_init(); emergency_stack_init(); /* set up the bootmem stuff with available memory */ do_init_bootmem(); /* Select the correct idle loop for the platform. */ idle_setup(); ppc_md.setup_arch(); paging_init(); ppc64_boot_msg(0x15, "Setup Done");}/* ToDo: do something useful if ppc_md is not yet setup. */#define PPC64_LINUX_FUNCTION 0x0f000000#define PPC64_IPL_MESSAGE 0xc0000000#define PPC64_TERM_MESSAGE 0xb0000000#define PPC64_ATTN_MESSAGE 0xa0000000#define PPC64_DUMP_MESSAGE 0xd0000000static void ppc64_do_msg(unsigned int src, const char *msg){ if (ppc_md.progress) { char buf[32]; sprintf(buf, "%08x \n", src); ppc_md.progress(buf, 0); sprintf(buf, "%-16s", msg); ppc_md.progress(buf, 0); }}/* Print a boot progress message. */void ppc64_boot_msg(unsigned int src, const char *msg){ ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg); printk("[boot]%04x %s\n", src, msg);}/* Print a termination message (print only -- does not stop the kernel) */void ppc64_terminate_msg(unsigned int src, const char *msg){ ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg); printk("[terminate]%04x %s\n", src, msg);}/* Print something that needs attention (device error, etc) */void ppc64_attention_msg(unsigned int src, const char *msg){ ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg); printk("[attention]%04x %s\n", src, msg);}/* Print a dump progress message. */void ppc64_dump_msg(unsigned int src, const char *msg){ ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg); printk("[dump]%04x %s\n", src, msg);}int set_spread_lpevents( char * str ){ /* The parameter is the number of processors to share in processing lp events */ unsigned long i; unsigned long val = simple_strtoul( str, NULL, 0 ); if ( ( val > 0 ) && ( val <= NR_CPUS ) ) { for ( i=1; i<val; ++i ) paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; printk("lpevent processing spread over %ld processors\n", val); } else printk("invalid spreaqd_lpevents %ld\n", val); return 1;} /* This should only be called on processor 0 during calibrate decr */void setup_default_decr(void){ struct paca_struct *lpaca = get_paca(); if ( decr_overclock_set && !decr_overclock_proc0_set ) decr_overclock_proc0 = decr_overclock; lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0; lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;}int set_decr_overclock_proc0( char * str ){ unsigned long val = simple_strtoul( str, NULL, 0 ); if ( ( val >= 1 ) && ( val <= 48 ) ) { decr_overclock_proc0_set = 1; decr_overclock_proc0 = val; printk("proc 0 decrementer overclock factor of %ld\n", val); } else printk("invalid proc 0 decrementer overclock factor of %ld\n", val); return 1;}int set_decr_overclock( char * str ){ unsigned long val = simple_strtoul( str, NULL, 0 ); if ( ( val >= 1 ) && ( val <= 48 ) ) { decr_overclock_set = 1; decr_overclock = val; printk("decrementer overclock factor of %ld\n", val); } else printk("invalid decrementer overclock factor of %ld\n", val); return 1;}__setup("spread_lpevents=", set_spread_lpevents );__setup("decr_overclock_proc0=", set_decr_overclock_proc0 );__setup("decr_overclock=", set_decr_overclock );#ifdef CONFIG_XMONstatic int __init early_xmon(char *p){ /* ensure xmon is enabled */ xmon_init(); debugger(0); return 0;}early_param("xmon", early_xmon);#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?