1 /* 2 * Permission is hereby granted, free of charge, to any person obtaining a copy 3 * of this software and associated documentation files (the "Software"), to 4 * deal in the Software without restriction, including without limitation the 5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 6 * sell copies of the Software, and to permit persons to whom the Software is 7 * furnished to do so, subject to the following conditions: 8 * 9 * The above copyright notice and this permission notice shall be included in 10 * all copies or substantial portions of the Software. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 18 * DEALINGS IN THE SOFTWARE. 19 * 20 * Copyright (c) 2016, Citrix Systems, Inc. 21 */ 22 23 /* 24 * automatically generated by rust-bindgen using: 25 * 26 * # bindgen start_info.h -- -include stdint.h > start_info.rs 27 * 28 * From the canonical version in upstream Xen repository 29 * xen/include/public/arch-x86/hvm/start_info.h 30 * at commit: 31 * b4642c32c4d079916d5607ddda0232aae5e1690e 32 * 33 * The generated file has been edited to eliminate unnecessary 34 * definitions, add comments, and relocate definitions and tests for clarity. 35 * Added Default to the list of traits that are automatically derived. 36 * 37 * The definitions in this file are intended to be exported and used by a particular 38 * VMM implementation in order to boot a Linux guest using the PVH entry point as 39 * specified in the x86/HVM direct boot ABI. 40 * These structures contain all the required information (cmdline address, ACPI RSDP, 41 * memory maps, etc) that must be written to guest memory before starting guest 42 * execution by jumping to the PVH entry point address. 43 * A comparable set of definitions to hvm_start_info and hvm_memmap_table_entry in this 44 * file would be the boot_params and boot_e820_entry definitions used by the Linux 45 * 64-bit boot protocol. 46 * 47 * Start of day structure passed to PVH guests and to HVM guests in %ebx. 48 * 49 * NOTE: nothing will be loaded at physical address 0, so a 0 value in any 50 * of the address fields should be treated as not present. 51 * 52 * 0 +----------------+ 53 * | magic | Contains the magic value XEN_HVM_START_MAGIC_VALUE 54 * | | ("xEn3" with the 0x80 bit of the "E" set). 55 * 4 +----------------+ 56 * | version | Version of this structure. Current version is 1. New 57 * | | versions are guaranteed to be backwards-compatible. 58 * 8 +----------------+ 59 * | flags | SIF_xxx flags. 60 * 12 +----------------+ 61 * | nr_modules | Number of modules passed to the kernel. 62 * 16 +----------------+ 63 * | modlist_paddr | Physical address of an array of modules 64 * | | (layout of the structure below). 65 * 24 +----------------+ 66 * | cmdline_paddr | Physical address of the command line, 67 * | | a zero-terminated ASCII string. 68 * 32 +----------------+ 69 * | rsdp_paddr | Physical address of the RSDP ACPI data structure. 70 * 40 +----------------+ 71 * | memmap_paddr | Physical address of the (optional) memory map. Only 72 * | | present in version 1 and newer of the structure. 73 * 48 +----------------+ 74 * | memmap_entries | Number of entries in the memory map table. Zero 75 * | | if there is no memory map being provided. Only 76 * | | present in version 1 and newer of the structure. 77 * 52 +----------------+ 78 * | reserved | Version 1 and newer only. 79 * 56 +----------------+ 80 * 81 * The layout of each entry in the module structure is the following: 82 * 83 * 0 +----------------+ 84 * | paddr | Physical address of the module. 85 * 8 +----------------+ 86 * | size | Size of the module in bytes. 87 * 16 +----------------+ 88 * | cmdline_paddr | Physical address of the command line, 89 * | | a zero-terminated ASCII string. 90 * 24 +----------------+ 91 * | reserved | 92 * 32 +----------------+ 93 * 94 * The layout of each entry in the memory map table is as follows: 95 * 96 * 0 +----------------+ 97 * | addr | Base address 98 * 8 +----------------+ 99 * | size | Size of mapping in bytes 100 * 16 +----------------+ 101 * | type | Type of mapping as defined between the hypervisor 102 * | | and guest. See XEN_HVM_MEMMAP_TYPE_* values below. 103 * 20 +----------------| 104 * | reserved | 105 * 24 +----------------+ 106 * 107 * The address and sizes are always a 64bit little endian unsigned integer. 108 * 109 * NB: Xen on x86 will always try to place all the data below the 4GiB 110 * boundary. 111 * 112 * Version numbers of the hvm_start_info structure have evolved like this: 113 * 114 * Version 0: Initial implementation. 115 * 116 * Version 1: Added the memmap_paddr/memmap_entries fields (plus 4 bytes of 117 * padding) to the end of the hvm_start_info struct. These new 118 * fields can be used to pass a memory map to the guest. The 119 * memory map is optional and so guests that understand version 1 120 * of the structure must check that memmap_entries is non-zero 121 * before trying to read the memory map. 122 */ 123 124 #[repr(C)] 125 #[derive(Debug, Copy, Clone, Default)] 126 pub struct HvmStartInfo { 127 pub magic: u32, 128 pub version: u32, 129 pub flags: u32, 130 pub nr_modules: u32, 131 pub modlist_paddr: u64, 132 pub cmdline_paddr: u64, 133 pub rsdp_paddr: u64, 134 pub memmap_paddr: u64, 135 pub memmap_entries: u32, 136 pub reserved: u32, 137 } 138 139 impl HvmStartInfo { 140 pub const XEN_HVM_START_MAGIC_VALUE: u32 = 0x336ec578; 141 } 142 143 #[repr(C)] 144 #[derive(Debug, Copy, Clone, Default)] 145 pub struct HvmModlistEntry { 146 pub paddr: u64, 147 pub size: u64, 148 pub cmdline_paddr: u64, 149 pub reserved: u64, 150 } 151 152 #[repr(C)] 153 #[derive(Debug, Copy, Clone, Default)] 154 pub struct HvmMemmapTableEntry { 155 pub addr: u64, 156 pub size: u64, 157 pub type_: u32, 158 pub reserved: u32, 159 } 160 161 /// The E820 types known to the kernel. 162 #[derive(Copy, Clone, Debug)] 163 #[repr(u32)] 164 pub enum E820Type { 165 Ram = 1, 166 Reserved = 2, 167 Acpi = 3, 168 Nvs = 4, 169 Unusable = 5, 170 Pmem = 7, 171 Pram = 12, 172 SoftReserved = 0xefffffff, 173 ReservedKern = 128, 174 } 175 176 impl From<u32> for E820Type { from(val: u32) -> Self177 fn from(val: u32) -> Self { 178 match val { 179 1 => E820Type::Ram, 180 2 => E820Type::Reserved, 181 3 => E820Type::Acpi, 182 4 => E820Type::Nvs, 183 5 => E820Type::Unusable, 184 7 => E820Type::Pmem, 185 12 => E820Type::Pram, 186 0xefffffff => E820Type::SoftReserved, 187 128 => E820Type::ReservedKern, 188 _ => E820Type::Reserved, 189 } 190 } 191 } 192 193 #[cfg(test)] 194 mod tests { 195 use super::*; 196 197 #[test] bindgen_test_layout_hvm_start_info()198 fn bindgen_test_layout_hvm_start_info() { 199 const UNINIT: ::std::mem::MaybeUninit<HvmStartInfo> = ::std::mem::MaybeUninit::uninit(); 200 let ptr = UNINIT.as_ptr(); 201 assert_eq!( 202 ::std::mem::size_of::<HvmStartInfo>(), 203 56usize, 204 concat!("Size of: ", stringify!(hvm_start_info)) 205 ); 206 assert_eq!( 207 ::std::mem::align_of::<HvmStartInfo>(), 208 8usize, 209 concat!("Alignment of ", stringify!(hvm_start_info)) 210 ); 211 assert_eq!( 212 unsafe { ::std::ptr::addr_of!((*ptr).magic) as usize - ptr as usize }, 213 0usize, 214 concat!( 215 "Offset of field: ", 216 stringify!(hvm_start_info), 217 "::", 218 stringify!(magic) 219 ) 220 ); 221 assert_eq!( 222 unsafe { ::std::ptr::addr_of!((*ptr).version) as usize - ptr as usize }, 223 4usize, 224 concat!( 225 "Offset of field: ", 226 stringify!(hvm_start_info), 227 "::", 228 stringify!(version) 229 ) 230 ); 231 assert_eq!( 232 unsafe { ::std::ptr::addr_of!((*ptr).flags) as usize - ptr as usize }, 233 8usize, 234 concat!( 235 "Offset of field: ", 236 stringify!(hvm_start_info), 237 "::", 238 stringify!(flags) 239 ) 240 ); 241 assert_eq!( 242 unsafe { ::std::ptr::addr_of!((*ptr).nr_modules) as usize - ptr as usize }, 243 12usize, 244 concat!( 245 "Offset of field: ", 246 stringify!(hvm_start_info), 247 "::", 248 stringify!(nr_modules) 249 ) 250 ); 251 assert_eq!( 252 unsafe { ::std::ptr::addr_of!((*ptr).modlist_paddr) as usize - ptr as usize }, 253 16usize, 254 concat!( 255 "Offset of field: ", 256 stringify!(hvm_start_info), 257 "::", 258 stringify!(modlist_paddr) 259 ) 260 ); 261 assert_eq!( 262 unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize }, 263 24usize, 264 concat!( 265 "Offset of field: ", 266 stringify!(hvm_start_info), 267 "::", 268 stringify!(cmdline_paddr) 269 ) 270 ); 271 assert_eq!( 272 unsafe { ::std::ptr::addr_of!((*ptr).rsdp_paddr) as usize - ptr as usize }, 273 32usize, 274 concat!( 275 "Offset of field: ", 276 stringify!(hvm_start_info), 277 "::", 278 stringify!(rsdp_paddr) 279 ) 280 ); 281 assert_eq!( 282 unsafe { ::std::ptr::addr_of!((*ptr).memmap_paddr) as usize - ptr as usize }, 283 40usize, 284 concat!( 285 "Offset of field: ", 286 stringify!(hvm_start_info), 287 "::", 288 stringify!(memmap_paddr) 289 ) 290 ); 291 assert_eq!( 292 unsafe { ::std::ptr::addr_of!((*ptr).memmap_entries) as usize - ptr as usize }, 293 48usize, 294 concat!( 295 "Offset of field: ", 296 stringify!(hvm_start_info), 297 "::", 298 stringify!(memmap_entries) 299 ) 300 ); 301 assert_eq!( 302 unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize }, 303 52usize, 304 concat!( 305 "Offset of field: ", 306 stringify!(hvm_start_info), 307 "::", 308 stringify!(reserved) 309 ) 310 ); 311 } 312 313 #[test] bindgen_test_layout_hvm_modlist_entry()314 fn bindgen_test_layout_hvm_modlist_entry() { 315 const UNINIT: ::std::mem::MaybeUninit<HvmModlistEntry> = ::std::mem::MaybeUninit::uninit(); 316 let ptr = UNINIT.as_ptr(); 317 assert_eq!( 318 ::std::mem::size_of::<HvmModlistEntry>(), 319 32usize, 320 concat!("Size of: ", stringify!(hvm_modlist_entry)) 321 ); 322 assert_eq!( 323 ::std::mem::align_of::<HvmModlistEntry>(), 324 8usize, 325 concat!("Alignment of ", stringify!(hvm_modlist_entry)) 326 ); 327 assert_eq!( 328 unsafe { ::std::ptr::addr_of!((*ptr).paddr) as usize - ptr as usize }, 329 0usize, 330 concat!( 331 "Offset of field: ", 332 stringify!(hvm_modlist_entry), 333 "::", 334 stringify!(paddr) 335 ) 336 ); 337 assert_eq!( 338 unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize }, 339 8usize, 340 concat!( 341 "Offset of field: ", 342 stringify!(hvm_modlist_entry), 343 "::", 344 stringify!(size) 345 ) 346 ); 347 assert_eq!( 348 unsafe { ::std::ptr::addr_of!((*ptr).cmdline_paddr) as usize - ptr as usize }, 349 16usize, 350 concat!( 351 "Offset of field: ", 352 stringify!(hvm_modlist_entry), 353 "::", 354 stringify!(cmdline_paddr) 355 ) 356 ); 357 assert_eq!( 358 unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize }, 359 24usize, 360 concat!( 361 "Offset of field: ", 362 stringify!(hvm_modlist_entry), 363 "::", 364 stringify!(reserved) 365 ) 366 ); 367 } 368 369 #[test] bindgen_test_layout_hvm_memmap_table_entry()370 fn bindgen_test_layout_hvm_memmap_table_entry() { 371 const UNINIT: ::std::mem::MaybeUninit<HvmMemmapTableEntry> = 372 ::std::mem::MaybeUninit::uninit(); 373 let ptr = UNINIT.as_ptr(); 374 assert_eq!( 375 ::std::mem::size_of::<HvmMemmapTableEntry>(), 376 24usize, 377 concat!("Size of: ", stringify!(hvm_memmap_table_entry)) 378 ); 379 assert_eq!( 380 ::std::mem::align_of::<HvmMemmapTableEntry>(), 381 8usize, 382 concat!("Alignment of ", stringify!(hvm_memmap_table_entry)) 383 ); 384 assert_eq!( 385 unsafe { ::std::ptr::addr_of!((*ptr).addr) as usize - ptr as usize }, 386 0usize, 387 concat!( 388 "Offset of field: ", 389 stringify!(hvm_memmap_table_entry), 390 "::", 391 stringify!(addr) 392 ) 393 ); 394 assert_eq!( 395 unsafe { ::std::ptr::addr_of!((*ptr).size) as usize - ptr as usize }, 396 8usize, 397 concat!( 398 "Offset of field: ", 399 stringify!(hvm_memmap_table_entry), 400 "::", 401 stringify!(size) 402 ) 403 ); 404 assert_eq!( 405 unsafe { ::std::ptr::addr_of!((*ptr).type_) as usize - ptr as usize }, 406 16usize, 407 concat!( 408 "Offset of field: ", 409 stringify!(hvm_memmap_table_entry), 410 "::", 411 stringify!(type_) 412 ) 413 ); 414 assert_eq!( 415 unsafe { ::std::ptr::addr_of!((*ptr).reserved) as usize - ptr as usize }, 416 20usize, 417 concat!( 418 "Offset of field: ", 419 stringify!(hvm_memmap_table_entry), 420 "::", 421 stringify!(reserved) 422 ) 423 ); 424 } 425 } 426