📄 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 <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>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 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(efi_memory_desc_t *md, unsigned long phys_addr){ return (phys_addr - md->phys_addr < (md->num_pages << EFI_PAGE_SHIFT));}#define MD_SIZE(md) (md->num_pages << EFI_PAGE_SHIFT)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();}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;}void __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;#ifdef CONFIG_SMP int i;#endif /* Be sure the struct shared_info size is <= XSI_SIZE. */ BUILD_BUG_ON(sizeof(struct shared_info) > XSI_SIZE); /* Kernel may be relocated by EFI loader */ xen_pstart = ia64_tpa(KERNEL_START); running_on_sim = is_platform_hp_ski(); early_setup_arch(&cmdline); /* We initialise the serial devices very early so we can get debugging. */ if (running_on_sim) hpsim_serial_init(); else { ns16550_init(0, &ns16550_com1); ns16550_init(1, &ns16550_com2); } serial_init_preirq();#ifdef CONFIG_VGA /* Plug in a default VGA mode */ vga_console_info.video_type = XEN_VGATYPE_TEXT_MODE_3; vga_console_info.u.text_mode_3.font_height = 16; /* generic VGA? */ vga_console_info.u.text_mode_3.cursor_x = ia64_boot_param->console_info.orig_x;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -