From patchwork Thu Jan 19 03:52:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Douglas Goldstein X-Patchwork-Id: 9525143 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C474560437 for ; Thu, 19 Jan 2017 03:55:31 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A05222854A for ; Thu, 19 Jan 2017 03:55:31 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 947A628648; Thu, 19 Jan 2017 03:55:31 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-3.6 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RCVD_IN_SORBS_SPAM,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 4D8412854A for ; Thu, 19 Jan 2017 03:55:30 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cU3mZ-000542-Ce; Thu, 19 Jan 2017 03:53:03 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cU3mX-000539-Gd for xen-devel@lists.xen.org; Thu, 19 Jan 2017 03:53:01 +0000 Received: from [85.158.143.35] by server-5.bemta-6.messagelabs.com id 01/D3-11476-C1830885; Thu, 19 Jan 2017 03:53:00 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrIIsWRWlGSWpSXmKPExsVyMfTqEV1pi4Y Ig/c3dS2WfFzM4sDocXT3b6YAxijWzLyk/IoE1oyFL88zFUzYy1gx528nawPjlomMXYxcHEIC Exglrv2awtzFyMnBIrCfWeLQRVeQhITAMlaJjnfXWEESEgIxEk/3bWeEsMskZu1pYwOxhQQUJ H5POMQEMWklk8SHp+vBJrEJaEg8+TUDrEhEQFri2ufLYOuYBa4ySWy8cZMJJCEsYCPR/e4OO8 RqVYnJV1+zgNi8AnESH9suQ22Wl1h4/ghYPadAqkRfax8LxOYUiY07brPjEp/AKLSAkWEVo0Z xalFZapGukZFeUlFmekZJbmJmjq6hgZlebmpxcWJ6ak5iUrFecn7uJkZgQDIAwQ7GNfMDDzFK cjApifKe02+IEOJLyk+pzEgszogvKs1JLT7EKMPBoSTBO9kMKCdYlJqeWpGWmQOMDZi0BAePk ghvN0iat7ggMbc4Mx0idYrRmKOn6/RLJo49uy6/ZBJiycvPS5US5+0EKRUAKc0ozYMbBIvZS4 yyUsK8jECnCfEUpBblZpagyr9iFOdgVBLm5TIHmsKTmVcCt+8V0ClMQKdYKdeDnFKSiJCSamD 0Yz9w9sz9NsOEiY+m/XdSkb+itHbn8/PP05MM/rXXFd+qNQi2NrhyhuUBl6yFaMwxWba+ySl8 DDeTH1xbnXo6c0KJxzzjhHNbA1clbq+7uc5fbjLLuRwV+zR/1aTLMY19u09Oehi13H1WH5ub0 /IKwxs7WpY7zer16qhetUeyqCv+ydGaY7pKLMUZiYZazEXFiQB3p+vt1AIAAA== X-Env-Sender: cardoe@cardoe.com X-Msg-Ref: server-11.tower-21.messagelabs.com!1484797978!53308239!1 X-Originating-IP: [209.85.213.196] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.1.1; banners=-,-,- X-VirusChecked: Checked Received: (qmail 23299 invoked from network); 19 Jan 2017 03:52:59 -0000 Received: from mail-yb0-f196.google.com (HELO mail-yb0-f196.google.com) (209.85.213.196) by server-11.tower-21.messagelabs.com with AES128-GCM-SHA256 encrypted SMTP; 19 Jan 2017 03:52:59 -0000 Received: by mail-yb0-f196.google.com with SMTP id p3so1342087yba.2 for ; Wed, 18 Jan 2017 19:52:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cardoe.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=lXFbs8GDySm3tLsrZPo8wpxHBjynQl2xBnE+sRYBq+M=; b=i+FKHX6vvGnveJDI2S0PLxpCLz2rgaFKiaCCG/nKsZX8sy0k1+LL+Ucz36fR1+b+2y segLhhjNLFxT9XlicsjnMG9HeV26wTvez1BaL0kuuyQ+nH4kZZcPZe41J6QllqctABt6 WXmNSGSuRCJErZVZM8qWMbjkmhrUNLatAHWSw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=lXFbs8GDySm3tLsrZPo8wpxHBjynQl2xBnE+sRYBq+M=; b=WIZ87yvYCOoNjQKWZ32B0/nfM+2XFiVT8P3JucDS2wncV6NzwdghC3SZhehZr5CfpH hMqR6sE0xdA+sXPFpbK7SmsuGETqYgA5ehSzihRrKL4IeVVscMGW/imNVc6SVJJZCF1A VpxusPpq9rFawZqfVU4uU+xsL41byOKQhm/aRKdXjnJQ/OKqH4tlE4+tDzo3OFUGrB9P VO+Ii5r/nuuCI9h/DRY7lXjYED906lSVSNy1vAX9fVuTrpHw9POppW9M2l9aFOo78M09 BY3+RsAQBvPdcDOo+L6H/geSQaYyV9twZl6GvPHxPntJlMHVDAC21H5bLou6PEMx4xFw hi8w== X-Gm-Message-State: AIkVDXJxMDEzvw2jwLeCOnudHu+6J2nohQo+mUXn1rV82ljN1qz/AYOpqRbtSikVWOWp8Q== X-Received: by 10.37.5.134 with SMTP id 128mr4742780ybf.1.1484797977909; Wed, 18 Jan 2017 19:52:57 -0800 (PST) Received: from swanson.attlocal.net (104-179-196-18.lightspeed.brhmal.sbcglobal.net. [104.179.196.18]) by smtp.gmail.com with ESMTPSA id g133sm1203373ywe.19.2017.01.18.19.52.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 18 Jan 2017 19:52:57 -0800 (PST) From: Doug Goldstein To: xen-devel@lists.xen.org Date: Wed, 18 Jan 2017 21:52:41 -0600 Message-Id: <0b46179471cf796fce0a4a58371efb99235e8d0a.1484797961.git-series.cardoe@cardoe.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: References: In-Reply-To: References: Cc: jgross@suse.com, sstabellini@kernel.org, konrad.wilk@oracle.com, Andrew Cooper , daniel.kiper@oracle.com, Doug Goldstein , pgnet.dev@gmail.com, ning.sun@intel.com, julien.grall@arm.com, Jan Beulich , qiaowei.ren@intel.com, gang.wei@intel.com, fu.wei@linaro.org Subject: [Xen-devel] [PATCH v5 1/5] x86: add multiboot2 protocol support X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Daniel Kiper Add multiboot2 protocol support. Alter min memory limit handling as we now may not find it from either multiboot (v1) or multiboot2. This way we are laying the foundation for EFI + GRUB2 + Xen development. Signed-off-by: Daniel Kiper Reviewed-by: Jan Beulich Reviewed-by: Doug Goldstein --- v9 - suggestions/fixes: - use .L label instead of numeric one in multiboot2 data scanning loop; I hope that this change does not invalidate Jan's Reviewed-by (suggested by Jan Beulich). v8 - suggestions/fixes: - use sizeof(/) instead of sizeof() if it is possible (suggested by Jan Beulich). v7 - suggestions/fixes: - rename mbi_mbi/mbi2_mbi to mbi_reloc/mbi2_reloc respectively (suggested by Jan Beulich), - initialize mbi_out->flags using "|=" instead of "=" (suggested by Jan Beulich), - use sizeof(*mmap_dst) instead of sizeof(memory_map_t) if it makes sense (suggested by Jan Beulich). v6 - suggestions/fixes: - properly index multiboot2_tag_mmap_t.entries[] (suggested by Jan Beulich), - do not index mbi_out_mods[] beyond its end (suggested by Andrew Cooper), - reduce number of casts (suggested by Andrew Cooper and Jan Beulich), - add braces to increase code readability (suggested by Andrew Cooper). v5 - suggestions/fixes: - check multiboot2_tag_mmap_t.entry_size before multiboot2_tag_mmap_t.entries[] use (suggested by Jan Beulich), - properly index multiboot2_tag_mmap_t.entries[] (suggested by Jan Beulich), - use "type name[]" instad of "type name[0]" in xen/include/xen/multiboot2.h (suggested by Jan Beulich), - remove unneeded comment (suggested by Jan Beulich). v4 - suggestions/fixes: - avoid assembly usage in xen/arch/x86/boot/reloc.c, - fix boundary check issue and optimize for() loops in mbi2_mbi(), - move to stdcall calling convention, - remove unneeded typeof() from ALIGN_UP() macro (suggested by Jan Beulich), - add and use NULL definition in xen/arch/x86/boot/reloc.c (suggested by Jan Beulich), - do not read data beyond the end of multiboot2 information in xen/arch/x86/boot/head.S (suggested by Jan Beulich), - add :req to some .macro arguments (suggested by Jan Beulich), - use cmovcc if possible, - add .L to multiboot2_header_end label (suggested by Jan Beulich), - add .L to multiboot2_proto label (suggested by Jan Beulich), - improve label names (suggested by Jan Beulich). v3 - suggestions/fixes: - reorder reloc() arguments (suggested by Jan Beulich), - remove .L from multiboot2 header labels (suggested by Andrew Cooper, Jan Beulich and Konrad Rzeszutek Wilk), - take into account alignment when skipping multiboot2 fixed part (suggested by Konrad Rzeszutek Wilk), - create modules data if modules count != 0 (suggested by Jan Beulich), - improve macros (suggested by Jan Beulich), - reduce number of casts (suggested by Jan Beulich), - use const if possible (suggested by Jan Beulich), - drop static and __used__ attribute from reloc() (suggested by Jan Beulich), - remove isolated/stray __packed attribute from multiboot2_memory_map_t type definition (suggested by Jan Beulich), - reformat xen/include/xen/multiboot2.h (suggested by Konrad Rzeszutek Wilk), - improve comments (suggested by Konrad Rzeszutek Wilk), - remove hard tabs (suggested by Jan Beulich and Konrad Rzeszutek Wilk). v2 - suggestions/fixes: - generate multiboot2 header using macros (suggested by Jan Beulich), - improve comments (suggested by Jan Beulich), - simplify assembly in xen/arch/x86/boot/head.S (suggested by Jan Beulich), - do not include include/xen/compiler.h in xen/arch/x86/boot/reloc.c (suggested by Jan Beulich), - do not read data beyond the end of multiboot2 information (suggested by Jan Beulich). v2 - not fixed yet: - dynamic dependency generation for xen/arch/x86/boot/reloc.S; this requires more work; I am not sure that it pays because potential patch requires more changes than addition of just multiboot2.h to Makefile (suggested by Jan Beulich), - isolated/stray __packed attribute usage for multiboot2_memory_map_t (suggested by Jan Beulich). --- --- xen/arch/x86/boot/Makefile | 3 +- xen/arch/x86/boot/head.S | 107 +++++++++++++++++++- xen/arch/x86/boot/reloc.c | 148 ++++++++++++++++++++++++++- xen/arch/x86/x86_64/asm-offsets.c | 9 ++- xen/include/xen/multiboot2.h | 169 +++++++++++++++++++++++++++++++- 5 files changed, 426 insertions(+), 10 deletions(-) create mode 100644 xen/include/xen/multiboot2.h diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index 5fdb5ae..06893d8 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -1,6 +1,7 @@ obj-bin-y += head.o -RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h +RELOC_DEPS = $(BASEDIR)/include/asm-x86/config.h $(BASEDIR)/include/xen/multiboot.h \ + $(BASEDIR)/include/xen/multiboot2.h head.o: reloc.S diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 6f2c668..d423fd8 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -19,6 +20,28 @@ #define BOOT_PSEUDORM_CS 0x0020 #define BOOT_PSEUDORM_DS 0x0028 +#define MB2_HT(name) (MULTIBOOT2_HEADER_TAG_##name) +#define MB2_TT(name) (MULTIBOOT2_TAG_TYPE_##name) + + .macro mb2ht_args arg:req, args:vararg + .long \arg + .ifnb \args + mb2ht_args \args + .endif + .endm + + .macro mb2ht_init type:req, req:req, args:vararg + .align MULTIBOOT2_TAG_ALIGN +.Lmb2ht_init_start\@: + .short \type + .short \req + .long .Lmb2ht_init_end\@ - .Lmb2ht_init_start\@ + .ifnb \args + mb2ht_args \args + .endif +.Lmb2ht_init_end\@: + .endm + ENTRY(start) jmp __start @@ -34,6 +57,42 @@ multiboot1_header_start: /*** MULTIBOOT1 HEADER ****/ .long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) multiboot1_header_end: +/*** MULTIBOOT2 HEADER ****/ +/* Some ideas are taken from grub-2.00/grub-core/tests/boot/kernel-i386.S file. */ + .align MULTIBOOT2_HEADER_ALIGN + +multiboot2_header_start: + /* Magic number indicating a Multiboot2 header. */ + .long MULTIBOOT2_HEADER_MAGIC + /* Architecture: i386. */ + .long MULTIBOOT2_ARCHITECTURE_I386 + /* Multiboot2 header length. */ + .long .Lmultiboot2_header_end - multiboot2_header_start + /* Multiboot2 header checksum. */ + .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT2_ARCHITECTURE_I386 + \ + (.Lmultiboot2_header_end - multiboot2_header_start)) + + /* Multiboot2 information request tag. */ + mb2ht_init MB2_HT(INFORMATION_REQUEST), MB2_HT(REQUIRED), \ + MB2_TT(BASIC_MEMINFO), MB2_TT(MMAP) + + /* Align modules at page boundry. */ + mb2ht_init MB2_HT(MODULE_ALIGN), MB2_HT(REQUIRED) + + /* Console flags tag. */ + mb2ht_init MB2_HT(CONSOLE_FLAGS), MB2_HT(OPTIONAL), \ + MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED + + /* Framebuffer tag. */ + mb2ht_init MB2_HT(FRAMEBUFFER), MB2_HT(OPTIONAL), \ + 0, /* Number of the columns - no preference. */ \ + 0, /* Number of the lines - no preference. */ \ + 0 /* Number of bits per pixel - no preference. */ + + /* Multiboot2 header end tag. */ + mb2ht_init MB2_HT(END), MB2_HT(REQUIRED) +.Lmultiboot2_header_end: + .section .init.rodata, "a", @progbits .align 4 @@ -82,10 +141,52 @@ __start: mov %ecx,%es mov %ecx,%ss - /* Check for Multiboot bootloader */ + /* Bootloaders may set multiboot{1,2}.mem_lower to a nonzero value. */ + xor %edx,%edx + + /* Check for Multiboot2 bootloader. */ + cmp $MULTIBOOT2_BOOTLOADER_MAGIC,%eax + je .Lmultiboot2_proto + + /* Check for Multiboot bootloader. */ cmp $MULTIBOOT_BOOTLOADER_MAGIC,%eax jne not_multiboot + /* Get mem_lower from Multiboot information. */ + testb $MBI_MEMLIMITS,MB_flags(%ebx) + + /* Not available? BDA value will be fine. */ + cmovnz MB_mem_lower(%ebx),%edx + jmp trampoline_setup + +.Lmultiboot2_proto: + /* Skip Multiboot2 information fixed part. */ + lea (MB2_fixed_sizeof+MULTIBOOT2_TAG_ALIGN-1)(%ebx),%ecx + and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx + +.Lmb2_tsize: + /* Check Multiboot2 information total size. */ + mov %ecx,%edi + sub %ebx,%edi + cmp %edi,MB2_fixed_total_size(%ebx) + jbe trampoline_setup + + /* Get mem_lower from Multiboot2 information. */ + cmpl $MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO,MB2_tag_type(%ecx) + cmove MB2_mem_lower(%ecx),%edx + je trampoline_setup + + /* Is it the end of Multiboot2 information? */ + cmpl $MULTIBOOT2_TAG_TYPE_END,MB2_tag_type(%ecx) + je trampoline_setup + + /* Go to next Multiboot2 information tag. */ + add MB2_tag_size(%ecx),%ecx + add $(MULTIBOOT2_TAG_ALIGN-1),%ecx + and $~(MULTIBOOT2_TAG_ALIGN-1),%ecx + jmp .Lmb2_tsize + +trampoline_setup: /* Set up trampoline segment 64k below EBDA */ movzwl 0x40e,%ecx /* EBDA segment */ cmp $0xa000,%ecx /* sanity check (high) */ @@ -100,9 +201,6 @@ __start: * Compare the value in the BDA with the information from the * multiboot structure (if available) and use the smallest. */ - testb $MBI_MEMLIMITS,(%ebx) - jz 2f /* not available? BDA value will be fine */ - mov MB_mem_lower(%ebx),%edx cmp $0x100,%edx /* is the multiboot value too small? */ jb 2f /* if so, do not use it */ shl $10-4,%edx @@ -121,6 +219,7 @@ __start: mov $sym_phys(cpu0_stack)+1024,%esp push %ecx /* Boot trampoline address. */ push %ebx /* Multiboot information address. */ + push %eax /* Multiboot magic. */ call reloc mov %eax,sym_phys(multiboot_ptr) diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c index ea8cb37..b22bf1e 100644 --- a/xen/arch/x86/boot/reloc.c +++ b/xen/arch/x86/boot/reloc.c @@ -5,15 +5,18 @@ * and modules. This is most easily done early with paging disabled. * * Copyright (c) 2009, Citrix Systems, Inc. + * Copyright (c) 2013-2016 Oracle and/or its affiliates. All rights reserved. * * Authors: * Keir Fraser + * Daniel Kiper */ /* * This entry point is entered from xen/arch/x86/boot/head.S with: - * - 0x4(%esp) = MULTIBOOT_INFORMATION_ADDRESS, - * - 0x8(%esp) = BOOT_TRAMPOLINE_ADDRESS. + * - 0x4(%esp) = MULTIBOOT_MAGIC, + * - 0x8(%esp) = MULTIBOOT_INFORMATION_ADDRESS, + * - 0xc(%esp) = BOOT_TRAMPOLINE_ADDRESS. */ asm ( " .text \n" @@ -23,7 +26,12 @@ asm ( ); typedef unsigned int u32; +typedef unsigned long long u64; + #include "../../../include/xen/multiboot.h" +#include "../../../include/xen/multiboot2.h" + +#define NULL ((void *)0) #define __stdcall __attribute__((__stdcall__)) @@ -32,6 +40,9 @@ typedef unsigned int u32; #define _p(val) ((void *)(unsigned long)(val)) +#define get_mb2_data(tag, type, member) (((multiboot2_tag_##type##_t *)(tag))->member) +#define get_mb2_string(tag, type, member) ((u32)get_mb2_data(tag, type, member)) + static u32 alloc; static u32 alloc_mem(u32 bytes) @@ -39,6 +50,12 @@ static u32 alloc_mem(u32 bytes) return alloc -= ALIGN_UP(bytes, 16); } +static void zero_mem(u32 s, u32 bytes) +{ + while ( bytes-- ) + *(char *)s++ = 0; +} + static u32 copy_mem(u32 src, u32 bytes) { u32 dst, dst_ret; @@ -65,13 +82,11 @@ static u32 copy_string(u32 src) return copy_mem(src, p - src + 1); } -multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline) +static multiboot_info_t *mbi_reloc(u32 mbi_in) { int i; multiboot_info_t *mbi_out; - alloc = trampoline; - mbi_out = _p(copy_mem(mbi_in, sizeof(*mbi_out))); if ( mbi_out->flags & MBI_CMDLINE ) @@ -108,3 +123,126 @@ multiboot_info_t __stdcall *reloc(u32 mbi_in, u32 trampoline) return mbi_out; } + +static multiboot_info_t *mbi2_reloc(u32 mbi_in) +{ + const multiboot2_fixed_t *mbi_fix = _p(mbi_in); + const multiboot2_memory_map_t *mmap_src; + const multiboot2_tag_t *tag; + module_t *mbi_out_mods = NULL; + memory_map_t *mmap_dst; + multiboot_info_t *mbi_out; + u32 ptr; + unsigned int i, mod_idx = 0; + + ptr = alloc_mem(sizeof(*mbi_out)); + mbi_out = _p(ptr); + zero_mem(ptr, sizeof(*mbi_out)); + + /* Skip Multiboot2 information fixed part. */ + ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN); + + /* Get the number of modules. */ + for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size; + tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) ) + { + if ( tag->type == MULTIBOOT2_TAG_TYPE_MODULE ) + ++mbi_out->mods_count; + else if ( tag->type == MULTIBOOT2_TAG_TYPE_END ) + break; + } + + if ( mbi_out->mods_count ) + { + mbi_out->flags |= MBI_MODULES; + mbi_out->mods_addr = alloc_mem(mbi_out->mods_count * sizeof(*mbi_out_mods)); + mbi_out_mods = _p(mbi_out->mods_addr); + } + + /* Skip Multiboot2 information fixed part. */ + ptr = ALIGN_UP(mbi_in + sizeof(*mbi_fix), MULTIBOOT2_TAG_ALIGN); + + /* Put all needed data into mbi_out. */ + for ( tag = _p(ptr); (u32)tag - mbi_in < mbi_fix->total_size; + tag = _p(ALIGN_UP((u32)tag + tag->size, MULTIBOOT2_TAG_ALIGN)) ) + switch ( tag->type ) + { + case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME: + mbi_out->flags |= MBI_LOADERNAME; + ptr = get_mb2_string(tag, string, string); + mbi_out->boot_loader_name = copy_string(ptr); + break; + + case MULTIBOOT2_TAG_TYPE_CMDLINE: + mbi_out->flags |= MBI_CMDLINE; + ptr = get_mb2_string(tag, string, string); + mbi_out->cmdline = copy_string(ptr); + break; + + case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO: + mbi_out->flags |= MBI_MEMLIMITS; + mbi_out->mem_lower = get_mb2_data(tag, basic_meminfo, mem_lower); + mbi_out->mem_upper = get_mb2_data(tag, basic_meminfo, mem_upper); + break; + + case MULTIBOOT2_TAG_TYPE_MMAP: + if ( get_mb2_data(tag, mmap, entry_size) < sizeof(*mmap_src) ) + break; + + mbi_out->flags |= MBI_MEMMAP; + mbi_out->mmap_length = get_mb2_data(tag, mmap, size); + mbi_out->mmap_length -= sizeof(multiboot2_tag_mmap_t); + mbi_out->mmap_length /= get_mb2_data(tag, mmap, entry_size); + mbi_out->mmap_length *= sizeof(*mmap_dst); + + mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length); + + mmap_src = get_mb2_data(tag, mmap, entries); + mmap_dst = _p(mbi_out->mmap_addr); + + for ( i = 0; i < mbi_out->mmap_length / sizeof(*mmap_dst); i++ ) + { + /* Init size member properly. */ + mmap_dst[i].size = sizeof(*mmap_dst); + mmap_dst[i].size -= sizeof(mmap_dst[i].size); + /* Now copy a given region data. */ + mmap_dst[i].base_addr_low = (u32)mmap_src->addr; + mmap_dst[i].base_addr_high = (u32)(mmap_src->addr >> 32); + mmap_dst[i].length_low = (u32)mmap_src->len; + mmap_dst[i].length_high = (u32)(mmap_src->len >> 32); + mmap_dst[i].type = mmap_src->type; + mmap_src = _p(mmap_src) + get_mb2_data(tag, mmap, entry_size); + } + break; + + case MULTIBOOT2_TAG_TYPE_MODULE: + if ( mod_idx >= mbi_out->mods_count ) + break; + + mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, module, mod_start); + mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, module, mod_end); + ptr = get_mb2_string(tag, module, cmdline); + mbi_out_mods[mod_idx].string = copy_string(ptr); + mbi_out_mods[mod_idx].reserved = 0; + ++mod_idx; + break; + + case MULTIBOOT2_TAG_TYPE_END: + return mbi_out; + + default: + break; + } + + return mbi_out; +} + +multiboot_info_t __stdcall *reloc(u32 mb_magic, u32 mbi_in, u32 trampoline) +{ + alloc = trampoline; + + if ( mb_magic == MULTIBOOT2_BOOTLOADER_MAGIC ) + return mbi2_reloc(mbi_in); + else + return mbi_reloc(mbi_in); +} diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index 0e1f09d..92f5d81 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -13,6 +13,7 @@ #include #include #include +#include #define DEFINE(_sym, _val) \ asm volatile ("\n.ascii\"==>#define " #_sym " %0 /* " #_val " */<==\"" \ @@ -167,6 +168,14 @@ void __dummy__(void) OFFSET(MB_flags, multiboot_info_t, flags); OFFSET(MB_cmdline, multiboot_info_t, cmdline); OFFSET(MB_mem_lower, multiboot_info_t, mem_lower); + BLANK(); + + DEFINE(MB2_fixed_sizeof, sizeof(multiboot2_fixed_t)); + OFFSET(MB2_fixed_total_size, multiboot2_fixed_t, total_size); + OFFSET(MB2_tag_type, multiboot2_tag_t, type); + OFFSET(MB2_tag_size, multiboot2_tag_t, size); + OFFSET(MB2_mem_lower, multiboot2_tag_basic_meminfo_t, mem_lower); + BLANK(); OFFSET(DOMAIN_vm_assist, struct domain, vm_assist); } diff --git a/xen/include/xen/multiboot2.h b/xen/include/xen/multiboot2.h new file mode 100644 index 0000000..8dd5800 --- /dev/null +++ b/xen/include/xen/multiboot2.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * multiboot2.h - Multiboot 2 header file. + * + * Based on grub-2.00/include/multiboot2.h file. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef __MULTIBOOT2_H__ +#define __MULTIBOOT2_H__ + +/* The magic field should contain this. */ +#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 + +/* This should be in %eax on x86 architecture. */ +#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT2_SEARCH 32768 + +/* Multiboot 2 header alignment. */ +#define MULTIBOOT2_HEADER_ALIGN 8 + +/* Alignment of multiboot 2 modules. */ +#define MULTIBOOT2_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot 2 info structure. */ +#define MULTIBOOT2_INFO_ALIGN 0x00000008 + +/* Multiboot 2 architectures. */ +#define MULTIBOOT2_ARCHITECTURE_I386 0 +#define MULTIBOOT2_ARCHITECTURE_MIPS32 4 + +/* Header tag types. */ +#define MULTIBOOT2_HEADER_TAG_END 0 +#define MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST 1 +#define MULTIBOOT2_HEADER_TAG_ADDRESS 2 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS 3 +#define MULTIBOOT2_HEADER_TAG_CONSOLE_FLAGS 4 +#define MULTIBOOT2_HEADER_TAG_FRAMEBUFFER 5 +#define MULTIBOOT2_HEADER_TAG_MODULE_ALIGN 6 +#define MULTIBOOT2_HEADER_TAG_EFI_BS 7 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 +#define MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 + +/* Header tag flags. */ +#define MULTIBOOT2_HEADER_TAG_REQUIRED 0 +#define MULTIBOOT2_HEADER_TAG_OPTIONAL 1 + +/* Header console tag console_flags. */ +#define MULTIBOOT2_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 +#define MULTIBOOT2_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 + +/* Flags set in the 'flags' member of the multiboot header. */ +#define MULTIBOOT2_TAG_TYPE_END 0 +#define MULTIBOOT2_TAG_TYPE_CMDLINE 1 +#define MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME 2 +#define MULTIBOOT2_TAG_TYPE_MODULE 3 +#define MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO 4 +#define MULTIBOOT2_TAG_TYPE_BOOTDEV 5 +#define MULTIBOOT2_TAG_TYPE_MMAP 6 +#define MULTIBOOT2_TAG_TYPE_VBE 7 +#define MULTIBOOT2_TAG_TYPE_FRAMEBUFFER 8 +#define MULTIBOOT2_TAG_TYPE_ELF_SECTIONS 9 +#define MULTIBOOT2_TAG_TYPE_APM 10 +#define MULTIBOOT2_TAG_TYPE_EFI32 11 +#define MULTIBOOT2_TAG_TYPE_EFI64 12 +#define MULTIBOOT2_TAG_TYPE_SMBIOS 13 +#define MULTIBOOT2_TAG_TYPE_ACPI_OLD 14 +#define MULTIBOOT2_TAG_TYPE_ACPI_NEW 15 +#define MULTIBOOT2_TAG_TYPE_NETWORK 16 +#define MULTIBOOT2_TAG_TYPE_EFI_MMAP 17 +#define MULTIBOOT2_TAG_TYPE_EFI_BS 18 +#define MULTIBOOT2_TAG_TYPE_EFI32_IH 19 +#define MULTIBOOT2_TAG_TYPE_EFI64_IH 20 + +/* Multiboot 2 tag alignment. */ +#define MULTIBOOT2_TAG_ALIGN 8 + +/* Memory types. */ +#define MULTIBOOT2_MEMORY_AVAILABLE 1 +#define MULTIBOOT2_MEMORY_RESERVED 2 +#define MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT2_MEMORY_NVS 4 +#define MULTIBOOT2_MEMORY_BADRAM 5 + +/* Framebuffer types. */ +#define MULTIBOOT2_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT2_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT 2 + +#ifndef __ASSEMBLY__ +typedef struct { + u32 total_size; + u32 reserved; +} multiboot2_fixed_t; + +typedef struct { + u32 type; + u32 size; +} multiboot2_tag_t; + +typedef struct { + u32 type; + u32 size; + char string[]; +} multiboot2_tag_string_t; + +typedef struct { + u32 type; + u32 size; + u32 mem_lower; + u32 mem_upper; +} multiboot2_tag_basic_meminfo_t; + +typedef struct { + u64 addr; + u64 len; + u32 type; + u32 zero; +} multiboot2_memory_map_t; + +typedef struct { + u32 type; + u32 size; + u32 entry_size; + u32 entry_version; + multiboot2_memory_map_t entries[]; +} multiboot2_tag_mmap_t; + +typedef struct { + u32 type; + u32 size; + u64 pointer; +} multiboot2_tag_efi64_t; + +typedef struct { + u32 type; + u32 size; + u64 pointer; +} multiboot2_tag_efi64_ih_t; + +typedef struct { + u32 type; + u32 size; + u32 mod_start; + u32 mod_end; + char cmdline[]; +} multiboot2_tag_module_t; +#endif /* __ASSEMBLY__ */ + +#endif /* __MULTIBOOT2_H__ */