📄 xensetup.c
字号:
/****************************************************************************** * xensetup.c * Copyright (c) 2004-2005 Hewlett-Packard Co * Dan Magenheimer <dan.magenheimer@hp.com> */#include <xen/config.h>#include <xen/lib.h>#include <xen/errno.h>#include <xen/multiboot.h>#include <xen/sched.h>#include <xen/mm.h>#include <public/version.h>#include <xen/gdbstub.h>#include <xen/version.h>#include <xen/console.h>#include <xen/domain.h>#include <xen/serial.h>#include <xen/trace.h>#include <xen/keyhandler.h>#include <xen/vga.h>#include <asm/meminit.h>#include <asm/page.h>#include <asm/setup.h>#include <asm/vhpt.h>#include <xen/string.h>#include <asm/vmx.h>#include <linux/efi.h>#include <asm/iosapic.h>#include <xen/softirq.h>#include <xen/rcupdate.h>#include <xsm/acm/acm_hooks.h>#include <asm/sn/simulator.h>#include <asm/sal.h>unsigned long xenheap_phys_end, total_pages;char saved_command_line[COMMAND_LINE_SIZE];char __initdata dom0_command_line[COMMAND_LINE_SIZE];cpumask_t cpu_present_map;extern unsigned long domain0_ready;int find_max_pfn (unsigned long, unsigned long, void *);/* FIXME: which header these declarations should be there ? */extern void early_setup_arch(char **);extern void late_setup_arch(char **);extern void hpsim_serial_init(void);extern void setup_per_cpu_areas(void);extern void mem_init(void);extern void init_IRQ(void);extern void trap_init(void);extern void xen_patch_kernel(void);/* nosmp: ignore secondary processors */static int __initdata opt_nosmp;boolean_param("nosmp", opt_nosmp);/* maxcpus: maximum number of CPUs to activate */static unsigned int __initdata max_cpus = NR_CPUS;integer_param("maxcpus", max_cpus); /* xencons: toggle xenconsole input (and irq). Note: you have to disable 8250 serials in domains (to avoid use of the same resource). */static int __initdata opt_xencons = 1;integer_param("xencons", opt_xencons);/* xencons_poll: toggle non-legacy xencons UARTs to run in polling mode */static int __initdata opt_xencons_poll;boolean_param("xencons_poll", opt_xencons_poll);unsigned long xenheap_size = XENHEAP_DEFAULT_SIZE;unsigned long xen_pstart;void *xen_pickle_offset __read_mostly;static void __init parse_xenheap_megabytes(char *s){ unsigned long megabytes = simple_strtoll(s, NULL, 0);#define XENHEAP_MEGABYTES_MIN 16UL if (megabytes < XENHEAP_MEGABYTES_MIN) megabytes = XENHEAP_MEGABYTES_MIN;#define XENHEAP_MEGABYTES_MAX 4096UL /* need more? If so, __pickle()/__unpickle() must be revised. */ if (megabytes > XENHEAP_MEGABYTES_MAX) megabytes = XENHEAP_MEGABYTES_MAX; xenheap_size = megabytes * 1024 * 1024;}custom_param("xenheap_megabytes", parse_xenheap_megabytes);static int __initxen_count_pages(u64 start, u64 end, void *arg){ unsigned long *count = arg; /* FIXME: do we need consider difference between DMA-usable memory and * normal memory? Seems that HV has no requirement to operate DMA which * is owned by Dom0? */ *count += (end - start) >> PAGE_SHIFT; return 0;}static void __init do_initcalls(void){ initcall_t *call; for ( call = &__initcall_start; call < &__initcall_end; call++ ) (*call)();}/* * IPF loader only supports one command line currently, for * both xen and guest kernel. This function provides pre-parse * to mixed command line, to split it into two parts. * * User should split the parameters by "--", with strings after * spliter for guest kernel. Missing "--" means whole line belongs * to guest. Example: * "com2=57600,8n1 console=com2 -- console=ttyS1 console=tty * root=/dev/sda3 ro" */static char null[4] = { 0 };void __init early_cmdline_parse(char **cmdline_p){ char *guest_cmd; static const char * const split = "--"; if (*cmdline_p == NULL) { *cmdline_p = &null[0]; saved_command_line[0] = '\0'; dom0_command_line[0] = '\0'; return; } guest_cmd = strstr(*cmdline_p, split); /* If no spliter, whole line is for guest */ if (guest_cmd == NULL) { guest_cmd = *cmdline_p; *cmdline_p = &null[0]; } else { *guest_cmd = '\0'; /* Split boot parameters for xen and guest */ guest_cmd += strlen(split); while (*guest_cmd == ' ') guest_cmd++; } strlcpy(saved_command_line, *cmdline_p, COMMAND_LINE_SIZE); strlcpy(dom0_command_line, guest_cmd, COMMAND_LINE_SIZE); return;}struct ns16550_defaults ns16550_com1 = { .data_bits = 8, .parity = 'n', .stop_bits = 1};unsigned int ns16550_com1_gsi;unsigned int ns16550_com1_polarity;unsigned int ns16550_com1_trigger;struct ns16550_defaults ns16550_com2 = { .data_bits = 8, .parity = 'n', .stop_bits = 1};/* efi_print: print efi table at boot */static int __initdata opt_efi_print;boolean_param("efi_print", opt_efi_print);/* print EFI memory map: */static void __initefi_print(void){ void *efi_map_start, *efi_map_end; u64 efi_desc_size; efi_memory_desc_t *md; void *p; int i; if (!opt_efi_print) return; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; efi_desc_size = ia64_boot_param->efi_memdesc_size; for (i = 0, p = efi_map_start; p < efi_map_end; ++i, p += efi_desc_size) { md = p; printk("mem%02u: type=%2u, attr=0x%016lx, range=[0x%016lx-0x%016lx) " "(%luMB)\n", i, md->type, md->attribute, md->phys_addr, md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), md->num_pages >> (20 - EFI_PAGE_SHIFT)); }}/* * These functions are utility functions for getting and * testing memory descriptors for allocating the xenheap area. */static efi_memory_desc_t * __initefi_get_md (unsigned long phys_addr){ void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; u64 efi_desc_size; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; efi_desc_size = ia64_boot_param->efi_memdesc_size; for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; if (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT)) return md; } return 0;}static int __initis_xenheap_usable_memory(efi_memory_desc_t *md){ if (!(md->attribute & EFI_MEMORY_WB)) return 0; switch (md->type) { case EFI_LOADER_CODE: case EFI_LOADER_DATA: case EFI_BOOT_SERVICES_CODE: case EFI_BOOT_SERVICES_DATA: case EFI_CONVENTIONAL_MEMORY: return 1; } return 0;}static inline int __initmd_overlaps(const efi_memory_desc_t *md, unsigned long phys_addr){ return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));}static inline int __initmd_overlap_with_boot_param(const efi_memory_desc_t *md){ return md_overlaps(md, __pa(ia64_boot_param)) || md_overlaps(md, ia64_boot_param->efi_memmap) || md_overlaps(md, ia64_boot_param->command_line);}#define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)#define MD_END(md) ((md)->phys_addr + MD_SIZE(md))static unsigned long __initefi_get_max_addr (void){ void *efi_map_start, *efi_map_end, *p; efi_memory_desc_t *md; u64 efi_desc_size; unsigned long max_addr = 0; efi_map_start = __va(ia64_boot_param->efi_memmap); efi_map_end = efi_map_start + ia64_boot_param->efi_memmap_size; efi_desc_size = ia64_boot_param->efi_memdesc_size; for (p = efi_map_start; p < efi_map_end; p += efi_desc_size) { md = p; if (is_xenheap_usable_memory(md) && MD_END(md) > max_addr) max_addr = MD_END(md); } return max_addr;}extern char __init_begin[], __init_end[];static void noinline init_done(void){ memset(__init_begin, 0, __init_end - __init_begin); flush_icache_range((unsigned long)__init_begin, (unsigned long)__init_end); init_xenheap_pages(__pa(__init_begin), __pa(__init_end)); printk("Freed %ldkB init memory.\n", (long)(__init_end-__init_begin)>>10); startup_cpu_idle_loop();}struct xen_heap_desc { void* xen_heap_start; unsigned long xenheap_phys_end; efi_memory_desc_t* kern_md;};static int __initinit_xenheap_mds(unsigned long start, unsigned long end, void *arg){ struct xen_heap_desc *desc = (struct xen_heap_desc*)arg; unsigned long md_end = __pa(desc->xen_heap_start); efi_memory_desc_t* md; start = __pa(start); end = __pa(end); for (md = efi_get_md(md_end); md != NULL && md->phys_addr < desc->xenheap_phys_end; md = efi_get_md(md_end)) { md_end = MD_END(md); if (md == desc->kern_md || (md->type == EFI_LOADER_DATA && !md_overlap_with_boot_param(md)) || ((md->attribute & EFI_MEMORY_WB) && is_xenheap_usable_memory(md))) { unsigned long s = max(start, max(__pa(desc->xen_heap_start), md->phys_addr)); unsigned long e = min(end, min(md_end, desc->xenheap_phys_end)); init_xenheap_pages(s, e); } } return 0;}int running_on_sim;static int __initis_platform_hp_ski(void){ int i; long cpuid[6]; for (i = 0; i < 5; ++i) cpuid[i] = ia64_get_cpuid(i); if ((cpuid[0] & 0xff) != 'H') return 0; if ((cpuid[3] & 0xff) != 0x4) return 0; if (((cpuid[3] >> 8) & 0xff) != 0x0) return 0; if (((cpuid[3] >> 16) & 0xff) != 0x0) return 0; if (((cpuid[3] >> 24) & 0x7) != 0x7) return 0; return 1;}#ifdef CONFIG_XEN_IA64_PERVCPU_VHPTstatic int __initdata dom0_vhpt_size_log2;integer_param("dom0_vhpt_size_log2", dom0_vhpt_size_log2);#endifvoid __init start_kernel(void){ char *cmdline; unsigned long nr_pages; unsigned long dom0_memory_start, dom0_memory_size; unsigned long dom0_initrd_start, dom0_initrd_size; unsigned long md_end, relo_start, relo_end, relo_size = 0; struct domain *idle_domain; struct vcpu *dom0_vcpu0; efi_memory_desc_t *kern_md, *last_md, *md; void *xen_heap_start; struct xen_heap_desc heap_desc;#ifdef CONFIG_SMP int i;#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -