mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 587ef78ad0 | |||
| 96bb6ba441 | |||
| 33cb56cf1b | |||
| 60531ff6e2 | |||
| 04e60a278a | |||
| 471599dc77 | |||
| 7d71cf318a | |||
| 6625e49cea | |||
| 9f17d1116d | |||
| 2733c4763a | |||
| cff857461b | |||
| 6a004be0cc | |||
| cf9ad00afc | |||
| 76a286530a | |||
| 3c83843e11 | |||
| be8ecaf805 | |||
| 62a1d5c0f5 | |||
| 84cb774390 | |||
| bfa5262f0e | |||
| ef0a6f4792 | |||
| c6901792f0 | |||
| a2bed43939 | |||
| 7cc305f7b4 | |||
| dc16de3204 | |||
| 6c0335adf6 | |||
| 8450fa4a7b | |||
| 4e456d9928 | |||
| d405a0bd84 | |||
| 49c13e81bc | |||
| 8b645eea16 | |||
| 6f250be279 | |||
| b6304f2984 | |||
| aa85c2918a |
61
.github/workflows/build.yml
vendored
61
.github/workflows/build.yml
vendored
@ -4,14 +4,45 @@ on: push
|
||||
|
||||
jobs:
|
||||
|
||||
cache:
|
||||
name: Cache
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
restore-keys: |
|
||||
apt-cache-
|
||||
- name: Download packages
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install -y -d -o Acquire::Retries=50 \
|
||||
mtools syslinux isolinux \
|
||||
libc6-dev-i386 valgrind \
|
||||
gcc-arm-none-eabi gcc-aarch64-linux-gnu
|
||||
|
||||
x86:
|
||||
name: x86
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo dpkg --add-architecture i386
|
||||
@ -32,12 +63,21 @@ jobs:
|
||||
|
||||
arm32:
|
||||
name: ARM32
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
@ -52,12 +92,21 @@ jobs:
|
||||
|
||||
arm64:
|
||||
name: ARM64
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
needs: cache
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Cache permissions
|
||||
run: |
|
||||
sudo chown $(id -un) /var/cache/apt/archives
|
||||
- name: Cache packages
|
||||
uses: actions/cache/restore@v3
|
||||
with:
|
||||
path: /var/cache/apt/archives/*.deb
|
||||
key: apt-cache-${{ github.run_id }}-${{ github.run_attempt }}
|
||||
- name: Install packages
|
||||
run: |
|
||||
sudo apt update
|
||||
|
||||
4
.github/workflows/coverity.yml
vendored
4
.github/workflows/coverity.yml
vendored
@ -8,10 +8,10 @@ on:
|
||||
jobs:
|
||||
submit:
|
||||
name: Submit
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
- name: Download Coverity Scan
|
||||
run: |
|
||||
curl --form token=${{ secrets.COVERITY_SCAN_TOKEN }} \
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
#ifndef _BITS_ENTROPY_H
|
||||
#define _BITS_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* ARM-specific entropy API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_ENTROPY_H */
|
||||
@ -9,6 +9,9 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#include <ipxe/arm_io.h>
|
||||
|
||||
#endif /* _BITS_IO_H */
|
||||
|
||||
@ -20,9 +20,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
/*
|
||||
* Physical<->Bus address mappings
|
||||
*
|
||||
|
||||
@ -8,6 +8,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
|
||||
@ -8,6 +8,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
|
||||
@ -8,6 +8,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
/** Declare a function with standard calling conventions */
|
||||
#define __asmcall __attribute__ (( cdecl, regparm(0) ))
|
||||
|
||||
|
||||
26
src/arch/loong64/Makefile
Normal file
26
src/arch/loong64/Makefile
Normal file
@ -0,0 +1,26 @@
|
||||
# Assembler section type character
|
||||
#
|
||||
ASM_TCHAR := @
|
||||
ASM_TCHAR_OPS := @
|
||||
|
||||
# LoongArch64-specific flags
|
||||
#
|
||||
CFLAGS += -fstrength-reduce -fomit-frame-pointer
|
||||
CFLAGS += -falign-jumps=1 -falign-loops=1 -falign-functions=1
|
||||
|
||||
# Check if -mno-explicit-relocs is valid
|
||||
ifeq ($(CCTYPE),gcc)
|
||||
MNER_TEST = $(CC) -mno-explicit-relocs -x c -c /dev/null -o /dev/null >/dev/null 2>&1
|
||||
MNER_FLAGS := $(shell $(MNER_TEST) && $(ECHO) '-mno-explicit-relocs')
|
||||
WORKAROUND_CFLAGS += $(MNER_FLAGS)
|
||||
endif
|
||||
|
||||
# EFI requires -fshort-wchar, and nothing else currently uses wchar_t
|
||||
CFLAGS += -fshort-wchar
|
||||
|
||||
# LoongArch64-specific directories containing source files
|
||||
SRCDIRS += arch/loong64/core
|
||||
|
||||
# Include platform-specific Makefile
|
||||
MAKEDEPS += arch/loong64/Makefile.$(PLATFORM)
|
||||
include arch/loong64/Makefile.$(PLATFORM)
|
||||
10
src/arch/loong64/Makefile.linux
Normal file
10
src/arch/loong64/Makefile.linux
Normal file
@ -0,0 +1,10 @@
|
||||
# -*- makefile -*- : Force emacs to use Makefile mode
|
||||
|
||||
# Starting virtual address
|
||||
#
|
||||
LDFLAGS += -Ttext=0x120000000
|
||||
|
||||
# Include generic Linux Makefile
|
||||
#
|
||||
MAKEDEPS += Makefile.linux
|
||||
include Makefile.linux
|
||||
120
src/arch/loong64/core/loong64_bigint.c
Normal file
120
src/arch/loong64/core/loong64_bigint.c
Normal file
@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <ipxe/bigint.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Big integer support
|
||||
*/
|
||||
|
||||
/**
|
||||
* Multiply big integers
|
||||
*
|
||||
* @v multiplicand0 Element 0 of big integer to be multiplied
|
||||
* @v multiplier0 Element 0 of big integer to be multiplied
|
||||
* @v result0 Element 0 of big integer to hold result
|
||||
* @v size Number of elements
|
||||
*/
|
||||
void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
const uint64_t *multiplier0,
|
||||
uint64_t *result0, unsigned int size ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
|
||||
( ( const void * ) multiplicand0 );
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
|
||||
( ( const void * ) multiplier0 );
|
||||
bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
|
||||
( ( void * ) result0 );
|
||||
unsigned int i;
|
||||
unsigned int j;
|
||||
uint64_t multiplicand_element;
|
||||
uint64_t multiplier_element;
|
||||
uint64_t *result_elements;
|
||||
uint64_t discard_low;
|
||||
uint64_t discard_high;
|
||||
uint64_t discard_temp_low;
|
||||
uint64_t discard_temp_high;
|
||||
|
||||
/* Zero result */
|
||||
memset ( result, 0, sizeof ( *result ) );
|
||||
|
||||
/* Multiply integers one element at a time */
|
||||
for ( i = 0 ; i < size ; i++ ) {
|
||||
multiplicand_element = multiplicand->element[i];
|
||||
for ( j = 0 ; j < size ; j++ ) {
|
||||
multiplier_element = multiplier->element[j];
|
||||
result_elements = &result->element[ i + j ];
|
||||
/* Perform a single multiply, and add the
|
||||
* resulting double-element into the result,
|
||||
* carrying as necessary. The carry can
|
||||
* never overflow beyond the end of the
|
||||
* result, since:
|
||||
*
|
||||
* a < 2^{n}, b < 2^{n} => ab < 2^{2n}
|
||||
*/
|
||||
__asm__ __volatile__ ( "mul.d %1, %6, %7\n\t"
|
||||
"mulh.du %2, %6, %7\n\t"
|
||||
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %0, 8\n\t"
|
||||
|
||||
"add.d %3, %3, %1\n\t"
|
||||
"sltu $t0, %3, %1\n\t"
|
||||
|
||||
"add.d %4, %4, %2\n\t"
|
||||
"sltu $t1, %4, %2\n\t"
|
||||
|
||||
"add.d %4, %4, $t0\n\t"
|
||||
"sltu $t0, %4, $t0\n\t"
|
||||
"or $t0, $t0, $t1\n\t"
|
||||
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"beqz $t0, 2f\n"
|
||||
"1:\n\t"
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"add.d %3, %3, $t0\n\t"
|
||||
"sltu $t0, %3, $t0\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"bnez $t0, 1b\n"
|
||||
"2:"
|
||||
: "+r" ( result_elements ),
|
||||
"=&r" ( discard_low ),
|
||||
"=&r" ( discard_high ),
|
||||
"=r" ( discard_temp_low ),
|
||||
"=r" ( discard_temp_high ),
|
||||
"+m" ( *result )
|
||||
: "r" ( multiplicand_element ),
|
||||
"r" ( multiplier_element )
|
||||
: "t0", "t1" );
|
||||
}
|
||||
}
|
||||
}
|
||||
266
src/arch/loong64/core/loong64_string.c
Normal file
266
src/arch/loong64/core/loong64_string.c
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
* Copyright (c) 2023, Xiaotian Wu <wuxiaotian@loongson.cn>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Optimised string operations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Copy memory area
|
||||
*
|
||||
* @v dest Destination address
|
||||
* @v src Source address
|
||||
* @v len Length
|
||||
* @ret dest Destination address
|
||||
*/
|
||||
void loong64_memcpy ( void *dest, const void *src, size_t len ) {
|
||||
void *discard_dest;
|
||||
void *discard_end;
|
||||
const void *discard_src;
|
||||
size_t discard_offset;
|
||||
unsigned long discard_data;
|
||||
unsigned long discard_low;
|
||||
unsigned long discard_high;
|
||||
|
||||
/* If length is too short, then just copy individual bytes.
|
||||
*/
|
||||
if ( len < 16 ) {
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"ldx.b %1, %3, %0\n\t"
|
||||
"stx.b %1, %2, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest ), "r" ( src ), "0" ( len )
|
||||
: "memory", "t0" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Copy 16 bytes at a time: one initial
|
||||
* potentially unaligned access, multiple destination-aligned
|
||||
* accesses, one final potentially unaligned access.
|
||||
*/
|
||||
__asm__ __volatile__ ( "ld.d %3, %1, 0\n\t"
|
||||
"ld.d %4, %1, 8\n\t"
|
||||
"addi.d %1, %1, 16\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"andi %3, %0, 15\n\t"
|
||||
"sub.d %0, %0, %3\n\t"
|
||||
"sub.d %1, %1, %3\n\t"
|
||||
"addi.d $t0, $zero, 0xf\n\t"
|
||||
"andn %2, %5, $t0\n\t"
|
||||
"b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"ld.d %3, %1, 0\n\t"
|
||||
"ld.d %4, %1, 8\n\t"
|
||||
"addi.d %1, %1, 16\n\t"
|
||||
"st.d %3, %0, 0\n\t"
|
||||
"st.d %4, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %2, 1b\n\t"
|
||||
"ld.d %3, %6, -16\n\t"
|
||||
"ld.d %4, %6, -8\n\t"
|
||||
"st.d %3, %5, -16\n\t"
|
||||
"st.d %4, %5, -8\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_src ),
|
||||
"=&r" ( discard_end ),
|
||||
"=&r" ( discard_low ),
|
||||
"=&r" ( discard_high )
|
||||
: "r" ( dest + len ), "r" ( src + len ),
|
||||
"0" ( dest ), "1" ( src )
|
||||
: "memory", "t0" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Zero memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_bzero ( void *dest, size_t len ) {
|
||||
size_t discard_offset;
|
||||
void *discard_dest;
|
||||
void *discard_end;
|
||||
|
||||
/* If length is too short, then just zero individual bytes.
|
||||
*/
|
||||
if ( len < 16 ) {
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"stx.b $zero, %1, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset )
|
||||
: "r" ( dest ), "0" ( len )
|
||||
: "memory" );
|
||||
return;
|
||||
}
|
||||
|
||||
/* To zero 16 bytes at a time: one initial
|
||||
* potentially unaligned access, multiple aligned accesses,
|
||||
* one final potentially unaligned access.
|
||||
*/
|
||||
|
||||
__asm__ __volatile__ ( "st.d $zero, %0, 0\n\t"
|
||||
"st.d $zero, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"addi.w $t0, $zero, 15\n\t"
|
||||
"andn %0, %0, $t0\n\t"
|
||||
"addi.w $t0, $zero, 15\n\t"
|
||||
"andn %1, %2, $t0\n\t"
|
||||
"b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"st.d $zero, %0, 0\n\t"
|
||||
"st.d $zero, %0, 8\n\t"
|
||||
"addi.d %0, %0, 16\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %1, 1b\n\t"
|
||||
"st.d $zero, %2, -16\n\t"
|
||||
"st.d $zero, %2, -8\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_end )
|
||||
: "r" ( dest + len ), "0" ( dest )
|
||||
: "memory", "t0" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v len Length
|
||||
* @v character Fill character
|
||||
*
|
||||
* The unusual parameter order is to allow for more efficient
|
||||
* tail-calling to loong64_memset() when zeroing a region.
|
||||
*/
|
||||
void loong64_memset ( void *dest, size_t len, int character ) {
|
||||
size_t discard_offset;
|
||||
|
||||
/* Use optimised zeroing code if applicable */
|
||||
if ( character == 0 ) {
|
||||
loong64_bzero ( dest, len );
|
||||
return;
|
||||
}
|
||||
|
||||
/* Fill one byte at a time. Calling memset() with a non-zero
|
||||
* value is relatively rare and unlikely to be
|
||||
* performance-critical.
|
||||
*/
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"stx.b %2, %1, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset )
|
||||
: "r" ( dest ), "r" ( character ), "0" ( len )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region forwards
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove_forwards ( void *dest, const void *src, size_t len ) {
|
||||
void *discard_dest;
|
||||
const void *discard_src;
|
||||
unsigned long discard_data;
|
||||
|
||||
/* Assume memmove() is not performance-critical, and perform a
|
||||
* bytewise copy for simplicity.
|
||||
*/
|
||||
__asm__ __volatile__ ( "b 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"ld.b %2, %1, 0\n\t"
|
||||
"addi.d %1, %1, 1\n\t"
|
||||
"st.b %2, %0, 0\n\t"
|
||||
"addi.d %0, %0, 1\n\t"
|
||||
"\n2:\n\t"
|
||||
"bne %0, %3, 1b\n\t"
|
||||
: "=&r" ( discard_dest ),
|
||||
"=&r" ( discard_src ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest + len ), "0" ( dest ), "1" ( src )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region backwards
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove_backwards ( void *dest, const void *src, size_t len ) {
|
||||
size_t discard_offset;
|
||||
unsigned long discard_data;
|
||||
|
||||
/* Assume memmove() is not performance-critical, and perform a
|
||||
* bytewise copy for simplicity.
|
||||
*/
|
||||
__asm__ __volatile__ ( "beqz %0, 2f\n\t"
|
||||
"\n1:\n\t"
|
||||
"addi.d %0, %0, -1\n\t"
|
||||
"ldx.b %1, %3, %0\n\t"
|
||||
"stx.b %1, %2, %0\n\t"
|
||||
"bnez %0, 1b\n\t"
|
||||
"\n2:\n\t"
|
||||
: "=&r" ( discard_offset ),
|
||||
"=&r" ( discard_data )
|
||||
: "r" ( dest ), "r" ( src ), "0" ( len )
|
||||
: "memory" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
*/
|
||||
void loong64_memmove ( void *dest, const void *src, size_t len ) {
|
||||
|
||||
if ( dest <= src ) {
|
||||
loong64_memmove_forwards ( dest, src, len );
|
||||
} else {
|
||||
loong64_memmove_backwards ( dest, src, len );
|
||||
}
|
||||
}
|
||||
53
src/arch/loong64/core/setjmp.S
Normal file
53
src/arch/loong64/core/setjmp.S
Normal file
@ -0,0 +1,53 @@
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
|
||||
|
||||
.section ".note.GNU-stack", "", %progbits
|
||||
.text
|
||||
/*
|
||||
int setjmp(jmp_buf env);
|
||||
*/
|
||||
.globl setjmp
|
||||
.type setjmp, %function
|
||||
setjmp:
|
||||
/* Store registers */
|
||||
st.d $s0, $a0, 0x0
|
||||
st.d $s1, $a0, 0x8
|
||||
st.d $s2, $a0, 0x10
|
||||
st.d $s3, $a0, 0x18
|
||||
st.d $s4, $a0, 0x20
|
||||
st.d $s5, $a0, 0x28
|
||||
st.d $s6, $a0, 0x30
|
||||
st.d $s7, $a0, 0x38
|
||||
st.d $s8, $a0, 0x40
|
||||
st.d $fp, $a0, 0x48
|
||||
st.d $sp, $a0, 0x50
|
||||
st.d $ra, $a0, 0x58
|
||||
|
||||
move $a0, $zero
|
||||
jirl $zero, $ra, 0
|
||||
.size setjmp, . - setjmp
|
||||
|
||||
/*
|
||||
void longjmp(jmp_buf env, int val);
|
||||
*/
|
||||
.globl longjmp
|
||||
.type longjmp, %function
|
||||
longjmp:
|
||||
/* Restore registers */
|
||||
ld.d $s0, $a0, 0x0
|
||||
ld.d $s1, $a0, 0x8
|
||||
ld.d $s2, $a0, 0x10
|
||||
ld.d $s3, $a0, 0x18
|
||||
ld.d $s4, $a0, 0x20
|
||||
ld.d $s5, $a0, 0x28
|
||||
ld.d $s6, $a0, 0x30
|
||||
ld.d $s7, $a0, 0x38
|
||||
ld.d $s8, $a0, 0x40
|
||||
ld.d $fp, $a0, 0x48
|
||||
ld.d $sp, $a0, 0x50
|
||||
ld.d $ra, $a0, 0x58
|
||||
addi.d $a0, $zero, 1 # a0 = 1
|
||||
beqz $a1, .exit # if (a1 == 0); goto L0
|
||||
move $a0, $a1 # a0 = a1
|
||||
.exit:
|
||||
jirl $zero, $ra, 0
|
||||
.size longjmp, . - longjmp
|
||||
12
src/arch/loong64/include/bits/acpi.h
Normal file
12
src/arch/loong64/include/bits/acpi.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_ACPI_H
|
||||
#define _BITS_ACPI_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific ACPI API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_ACPI_H */
|
||||
336
src/arch/loong64/include/bits/bigint.h
Normal file
336
src/arch/loong64/include/bits/bigint.h
Normal file
@ -0,0 +1,336 @@
|
||||
#ifndef _BITS_BIGINT_H
|
||||
#define _BITS_BIGINT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Big integer support
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
/** Element of a big integer */
|
||||
typedef uint64_t bigint_element_t;
|
||||
|
||||
/**
|
||||
* Initialise big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer to initialise
|
||||
* @v size Number of elements
|
||||
* @v data Raw data
|
||||
* @v len Length of raw data
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_init_raw ( uint64_t *value0, unsigned int size,
|
||||
const void *data, size_t len ) {
|
||||
size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len );
|
||||
uint8_t *value_byte = ( ( void * ) value0 );
|
||||
const uint8_t *data_byte = ( data + len );
|
||||
|
||||
/* Copy raw data in reverse order, padding with zeros */
|
||||
while ( len-- )
|
||||
*(value_byte++) = *(--data_byte);
|
||||
while ( pad_len-- )
|
||||
*(value_byte++) = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add big integers
|
||||
*
|
||||
* @v addend0 Element 0 of big integer to add
|
||||
* @v value0 Element 0 of big integer to be added to
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_add_raw ( const uint64_t *addend0, uint64_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_addend;
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_addend_i;
|
||||
uint64_t discard_value_i;
|
||||
unsigned int discard_size;
|
||||
__asm__ __volatile__ ( "move $t0, $zero\n"
|
||||
"1:\n\t"
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
|
||||
"add.d %4, %4, $t0\n\t"
|
||||
"sltu $t0, %4, $t0\n\t"
|
||||
|
||||
"add.d %4, %4, %3\n\t"
|
||||
"sltu $t1, %4, %3\n\t"
|
||||
|
||||
"or $t0, $t0, $t1\n\t"
|
||||
"st.d %4, %1, 0\n\t"
|
||||
"addi.d %1, %1, 8\n\t"
|
||||
"addi.w %2, %2, -1\n\t"
|
||||
"bnez %2, 1b"
|
||||
: "=r" ( discard_addend ),
|
||||
"=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_addend_i ),
|
||||
"=r" ( discard_value_i ),
|
||||
"+m" ( *value )
|
||||
: "0" ( addend0 ),
|
||||
"1" ( value0 ),
|
||||
"2" ( size )
|
||||
: "t0", "t1" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract big integers
|
||||
*
|
||||
* @v subtrahend0 Element 0 of big integer to subtract
|
||||
* @v value0 Element 0 of big integer to be subtracted from
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
||||
unsigned int size ) {
|
||||
uint64_t *discard_subtrahend;
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_subtrahend_i;
|
||||
uint64_t discard_value_i;
|
||||
unsigned int discard_size;
|
||||
unsigned int flag = 0;
|
||||
|
||||
discard_subtrahend = (uint64_t*) subtrahend0;
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
|
||||
do {
|
||||
discard_subtrahend_i = *discard_subtrahend;
|
||||
discard_subtrahend++;
|
||||
discard_value_i = *discard_value;
|
||||
|
||||
discard_value_i = discard_value_i - discard_subtrahend_i - flag;
|
||||
|
||||
if ( *discard_value < (discard_subtrahend_i + flag)) {
|
||||
flag = 1;
|
||||
} else {
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
*discard_value = discard_value_i;
|
||||
|
||||
discard_value++;
|
||||
discard_size -= 1;
|
||||
} while (discard_size != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate big integer left
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_rol_raw ( uint64_t *value0, unsigned int size ) {
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
unsigned int discard_size;
|
||||
uint64_t current_value_i;
|
||||
unsigned int flag = 0;
|
||||
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
do {
|
||||
discard_value_i = *discard_value;
|
||||
current_value_i = discard_value_i;
|
||||
|
||||
discard_value_i += discard_value_i + flag;
|
||||
|
||||
if (discard_value_i < current_value_i) {
|
||||
flag = 1;
|
||||
} else {
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
*discard_value = discard_value_i;
|
||||
discard_value++;
|
||||
discard_size -= 1;
|
||||
} while ( discard_size != 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate big integer right
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_ror_raw ( uint64_t *value0, unsigned int size ) {
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_value_j;
|
||||
unsigned int discard_size;
|
||||
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
|
||||
discard_value_j = 0;
|
||||
|
||||
do {
|
||||
discard_size -= 1;
|
||||
|
||||
discard_value_i = *(discard_value + discard_size);
|
||||
|
||||
discard_value_j = (discard_value_j << 63) | (discard_value_i >> 1);
|
||||
|
||||
*(discard_value + discard_size) = discard_value_j;
|
||||
|
||||
discard_value_j = discard_value_i;
|
||||
} while ( discard_size > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if big integer is equal to zero
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret is_zero Big integer is equal to zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline, pure )) int
|
||||
bigint_is_zero_raw ( const uint64_t *value0, unsigned int size ) {
|
||||
const uint64_t *value = value0;
|
||||
uint64_t value_i;
|
||||
|
||||
do {
|
||||
value_i = *(value++);
|
||||
if ( value_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return ( value_i == 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare big integers
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v reference0 Element 0 of reference big integer
|
||||
* @v size Number of elements
|
||||
* @ret geq Big integer is greater than or equal to the reference
|
||||
*/
|
||||
static inline __attribute__ (( always_inline, pure )) int
|
||||
bigint_is_geq_raw ( const uint64_t *value0, const uint64_t *reference0,
|
||||
unsigned int size ) {
|
||||
const uint64_t *value = ( value0 + size );
|
||||
const uint64_t *reference = ( reference0 + size );
|
||||
uint64_t value_i;
|
||||
uint64_t reference_i;
|
||||
|
||||
do {
|
||||
value_i = *(--value);
|
||||
reference_i = *(--reference);
|
||||
if ( value_i != reference_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return ( value_i >= reference_i );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if bit is set in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @v bit Bit to test
|
||||
* @ret is_set Bit is set
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_bit_is_set_raw ( const uint64_t *value0, unsigned int size,
|
||||
unsigned int bit ) {
|
||||
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( const void * ) value0 );
|
||||
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
|
||||
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
|
||||
|
||||
return ( !! ( value->element[index] & ( 1UL << subindex ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find highest bit set in big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer
|
||||
* @v size Number of elements
|
||||
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
bigint_max_set_bit_raw ( const uint64_t *value0, unsigned int size ) {
|
||||
const uint64_t *value = ( value0 + size );
|
||||
int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) );
|
||||
uint64_t value_i;
|
||||
|
||||
do {
|
||||
value_i = *(--value);
|
||||
max_bit -= ( 64 - fls ( value_i ) );
|
||||
if ( value_i )
|
||||
break;
|
||||
} while ( --size );
|
||||
|
||||
return max_bit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grow big integer
|
||||
*
|
||||
* @v source0 Element 0 of source big integer
|
||||
* @v source_size Number of elements in source big integer
|
||||
* @v dest0 Element 0 of destination big integer
|
||||
* @v dest_size Number of elements in destination big integer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_grow_raw ( const uint64_t *source0, unsigned int source_size,
|
||||
uint64_t *dest0, unsigned int dest_size ) {
|
||||
unsigned int pad_size = ( dest_size - source_size );
|
||||
|
||||
memcpy ( dest0, source0, sizeof ( bigint_t ( source_size ) ) );
|
||||
memset ( ( dest0 + source_size ), 0, sizeof ( bigint_t ( pad_size ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Shrink big integer
|
||||
*
|
||||
* @v source0 Element 0 of source big integer
|
||||
* @v source_size Number of elements in source big integer
|
||||
* @v dest0 Element 0 of destination big integer
|
||||
* @v dest_size Number of elements in destination big integer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused,
|
||||
uint64_t *dest0, unsigned int dest_size ) {
|
||||
|
||||
memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalise big integer
|
||||
*
|
||||
* @v value0 Element 0 of big integer to finalise
|
||||
* @v size Number of elements
|
||||
* @v out Output buffer
|
||||
* @v len Length of output buffer
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_done_raw ( const uint64_t *value0, unsigned int size __unused,
|
||||
void *out, size_t len ) {
|
||||
const uint8_t *value_byte = ( ( const void * ) value0 );
|
||||
uint8_t *out_byte = ( out + len );
|
||||
|
||||
/* Copy raw data in reverse order */
|
||||
while ( len-- )
|
||||
*(--out_byte) = *(value_byte++);
|
||||
}
|
||||
|
||||
extern void bigint_multiply_raw ( const uint64_t *multiplicand0,
|
||||
const uint64_t *multiplier0,
|
||||
uint64_t *value0, unsigned int size );
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
102
src/arch/loong64/include/bits/bitops.h
Normal file
102
src/arch/loong64/include/bits/bitops.h
Normal file
@ -0,0 +1,102 @@
|
||||
#ifndef _BITS_BITOPS_H
|
||||
#define _BITS_BITOPS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* loongArch bit operations
|
||||
*
|
||||
* We perform atomic bit set and bit clear operations using "ll"
|
||||
* and "sc". We use the output constraint to inform the
|
||||
* compiler that any memory from the start of the bit field up to and
|
||||
* including the byte containing the bit may be modified. (This is
|
||||
* overkill but shouldn't matter in practice since we're unlikely to
|
||||
* subsequently read other bits from the same bit field.)
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Test and set bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
* @ret old Old value of bit (zero or non-zero)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
test_and_set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
unsigned int index = ( bit / 64 );
|
||||
unsigned int offset = ( bit % 64 );
|
||||
volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
|
||||
uint64_t mask = ( 1UL << offset );
|
||||
uint64_t old;
|
||||
uint64_t new;
|
||||
|
||||
__asm__ __volatile__ ( "1: \n\t"
|
||||
"ll.d %[old], %[qword] \n\t"
|
||||
"or %[new], %[old], %[mask] \n\t"
|
||||
"sc.d %[new], %[qword] \n\t"
|
||||
"beqz %[new], 1b \n\t"
|
||||
: [old] "=&r" ( old ),
|
||||
[new] "=&r" ( new ),
|
||||
[qword] "+m" ( *qword )
|
||||
: [mask] "r" ( mask )
|
||||
: "cc", "memory");
|
||||
return ( !! ( old & mask ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test and clear bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
* @ret old Old value of bit (zero or non-zero)
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
test_and_clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
unsigned int index = ( bit / 64 );
|
||||
unsigned int offset = ( bit % 64 );
|
||||
volatile uint64_t *qword = ( ( ( volatile uint64_t * ) bits ) + index );
|
||||
uint64_t mask = ( 1UL << offset );
|
||||
uint64_t old;
|
||||
uint64_t new;
|
||||
|
||||
__asm__ __volatile__ ( "1: \n\t"
|
||||
"ll.d %[old], %[qword] \n\t"
|
||||
"andn %[new], %[old], %[mask] \n\t"
|
||||
"sc.d %[new], %[qword] \n\t"
|
||||
"beqz %[new], 1b \n\t"
|
||||
: [old] "=&r" ( old ),
|
||||
[new] "=&r" ( new ),
|
||||
[qword] "+m" ( *qword )
|
||||
: [mask] "r" ( mask )
|
||||
: "cc", "memory");
|
||||
return ( !! ( old & mask ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
set_bit ( unsigned int bit, volatile void *bits ) {
|
||||
|
||||
test_and_set_bit ( bit, bits );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear bit atomically
|
||||
*
|
||||
* @v bit Bit to set
|
||||
* @v bits Bit field
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
clear_bit ( unsigned int bit, volatile void *bits ) {
|
||||
|
||||
test_and_clear_bit ( bit, bits );
|
||||
}
|
||||
|
||||
#endif /* _BITS_BITOPS_H */
|
||||
47
src/arch/loong64/include/bits/byteswap.h
Normal file
47
src/arch/loong64/include/bits/byteswap.h
Normal file
@ -0,0 +1,47 @@
|
||||
#ifndef _BITS_BYTESWAP_H
|
||||
#define _BITS_BYTESWAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Byte-order swapping functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint16_t
|
||||
__bswap_variable_16 ( uint16_t x ) {
|
||||
__asm__ ( "revb.2h %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_16s ( uint16_t *x ) {
|
||||
*x = __bswap_variable_16 ( *x );
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint32_t
|
||||
__bswap_variable_32 ( uint32_t x ) {
|
||||
__asm__ ( "revb.2w %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_32s ( uint32_t *x ) {
|
||||
*x = __bswap_variable_32 ( *x );
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline, const )) uint64_t
|
||||
__bswap_variable_64 ( uint64_t x ) {
|
||||
__asm__ ( "revb.d %0, %1" : "=r" ( x ) : "r" ( x ) );
|
||||
return x;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
__bswap_64s ( uint64_t *x ) {
|
||||
*x = __bswap_variable_64 ( *x );
|
||||
}
|
||||
|
||||
#endif
|
||||
19
src/arch/loong64/include/bits/compiler.h
Normal file
19
src/arch/loong64/include/bits/compiler.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _BITS_COMPILER_H
|
||||
#define _BITS_COMPILER_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Dummy relocation type */
|
||||
#define RELOC_TYPE_NONE R_LARCH_NONE
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "a"
|
||||
|
||||
#define __asmcall
|
||||
#define __libgcc
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
||||
#endif /*_BITS_COMPILER_H */
|
||||
8
src/arch/loong64/include/bits/endian.h
Normal file
8
src/arch/loong64/include/bits/endian.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef _BITS_ENDIAN_H
|
||||
#define _BITS_ENDIAN_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
|
||||
#endif /* _BITS_ENDIAN_H */
|
||||
19
src/arch/loong64/include/bits/errfile.h
Normal file
19
src/arch/loong64/include/bits/errfile.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _BITS_ERRFILE_H
|
||||
#define _BITS_ERRFILE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific error file identifiers
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* @addtogroup errfile Error file identifiers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif /* _BITS_ERRFILE_H */
|
||||
12
src/arch/loong64/include/bits/hyperv.h
Normal file
12
src/arch/loong64/include/bits/hyperv.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_HYPERV_H
|
||||
#define _BITS_HYPERV_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Hyper-V interface
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_HYPERV_H */
|
||||
15
src/arch/loong64/include/bits/io.h
Normal file
15
src/arch/loong64/include/bits/io.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef _BITS_IO_H
|
||||
#define _BITS_IO_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific I/O API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#endif /* _BITS_IO_H */
|
||||
12
src/arch/loong64/include/bits/iomap.h
Normal file
12
src/arch/loong64/include/bits/iomap.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_IOMAP_H
|
||||
#define _BITS_IOMAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific I/O mapping API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_IOMAP_H */
|
||||
12
src/arch/loong64/include/bits/nap.h
Normal file
12
src/arch/loong64/include/bits/nap.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_NAP_H
|
||||
#define _BITS_NAP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific CPU sleeping API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_MAP_H */
|
||||
12
src/arch/loong64/include/bits/pci_io.h
Normal file
12
src/arch/loong64/include/bits/pci_io.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_PCI_IO_H
|
||||
#define _BITS_PCI_IO_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific PCI I/O API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_PCI_IO_H */
|
||||
28
src/arch/loong64/include/bits/profile.h
Normal file
28
src/arch/loong64/include/bits/profile.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef _BITS_PROFILE_H
|
||||
#define _BITS_PROFILE_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Profiling
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Get profiling timestamp
|
||||
*
|
||||
* @ret timestamp Timestamp
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) uint64_t
|
||||
profile_timestamp ( void ) {
|
||||
uint64_t cycles;
|
||||
|
||||
/* Read cycle counter */
|
||||
__asm__ __volatile__ ( "rdtime.d %0, $zero\n\t" : "=r" ( cycles ) );
|
||||
return cycles;
|
||||
}
|
||||
|
||||
#endif /* _BITS_PROFILE_H */
|
||||
12
src/arch/loong64/include/bits/reboot.h
Normal file
12
src/arch/loong64/include/bits/reboot.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_REBOOT_H
|
||||
#define _BITS_REBOOT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific reboot API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_REBOOT_H */
|
||||
12
src/arch/loong64/include/bits/sanboot.h
Normal file
12
src/arch/loong64/include/bits/sanboot.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_SANBOOT_H
|
||||
#define _BITS_SANBOOT_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific sanboot API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_SANBOOT_H */
|
||||
12
src/arch/loong64/include/bits/smbios.h
Normal file
12
src/arch/loong64/include/bits/smbios.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_SMBIOS_H
|
||||
#define _BITS_SMBIOS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific SMBIOS API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_SMBIOS_H */
|
||||
23
src/arch/loong64/include/bits/stdint.h
Normal file
23
src/arch/loong64/include/bits/stdint.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef _BITS_STDINT_H
|
||||
#define _BITS_STDINT_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
typedef signed long ssize_t;
|
||||
typedef signed long off_t;
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
typedef signed char int8_t;
|
||||
typedef signed short int16_t;
|
||||
typedef signed int int32_t;
|
||||
typedef signed long long int64_t;
|
||||
|
||||
typedef unsigned long physaddr_t;
|
||||
typedef unsigned long intptr_t;
|
||||
|
||||
#endif /* _BITS_STDINT_H */
|
||||
61
src/arch/loong64/include/bits/string.h
Normal file
61
src/arch/loong64/include/bits/string.h
Normal file
@ -0,0 +1,61 @@
|
||||
#ifndef _BITS_STRING_H
|
||||
#define _BITS_STRING_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* String functions
|
||||
*
|
||||
*/
|
||||
|
||||
extern void loong64_bzero ( void *dest, size_t len );
|
||||
extern void loong64_memset ( void *dest, size_t len, int character );
|
||||
extern void loong64_memcpy ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove_forwards ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove_backwards ( void *dest, const void *src, size_t len );
|
||||
extern void loong64_memmove ( void *dest, const void *src, size_t len );
|
||||
|
||||
/**
|
||||
* Fill memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v character Fill character
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memset ( void *dest, int character, size_t len ) {
|
||||
loong64_memset ( dest, len, character );
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memcpy ( void *dest, const void *src, size_t len ) {
|
||||
loong64_memcpy ( dest, src, len );
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy (possibly overlapping) memory region
|
||||
*
|
||||
* @v dest Destination region
|
||||
* @v src Source region
|
||||
* @v len Length
|
||||
* @ret dest Destination region
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void *
|
||||
memmove ( void *dest, const void *src, size_t len ) {
|
||||
loong64_memmove ( dest, src, len );
|
||||
return dest;
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRING_H */
|
||||
69
src/arch/loong64/include/bits/strings.h
Normal file
69
src/arch/loong64/include/bits/strings.h
Normal file
@ -0,0 +1,69 @@
|
||||
#ifndef _BITS_STRINGS_H
|
||||
#define _BITS_STRINGS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* String functions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsll ( long long value ){
|
||||
unsigned long long bits = value;
|
||||
unsigned long long lsb;
|
||||
unsigned int lz;
|
||||
|
||||
/* Extract least significant set bit */
|
||||
lsb = ( bits & -bits );
|
||||
|
||||
/* Count number of leading zeroes before LSB */
|
||||
__asm__ ( "clz.d %0, %1" : "=r" ( lz ) : "r" ( lsb ) );
|
||||
|
||||
return ( 64 - lz );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find first (i.e. least significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret lsb Least significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __ffsl ( long value ) {
|
||||
|
||||
return __ffsll ( value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsll ( long long value ){
|
||||
unsigned int lz;
|
||||
|
||||
/* Count number of leading zeroes */
|
||||
__asm__ ( "clz.d %0, %1" : "=r" ( lz ) : "r" ( value ) );
|
||||
|
||||
return ( 64 - lz );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find last (i.e. most significant) set bit
|
||||
*
|
||||
* @v value Value
|
||||
* @ret msb Most significant bit set in value (LSB=1), or zero
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int __flsl ( long value ) {
|
||||
|
||||
return __flsll ( value );
|
||||
}
|
||||
|
||||
#endif /* _BITS_STRINGS_H */
|
||||
19
src/arch/loong64/include/bits/tcpip.h
Normal file
19
src/arch/loong64/include/bits/tcpip.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _BITS_TCPIP_H
|
||||
#define _BITS_TCPIP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Transport-network layer interface
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
static inline __attribute__ (( always_inline )) uint16_t
|
||||
tcpip_continue_chksum ( uint16_t partial, const void *data, size_t len ) {
|
||||
|
||||
/* Not yet optimised */
|
||||
return generic_tcpip_continue_chksum ( partial, data, len );
|
||||
}
|
||||
|
||||
#endif /* _BITS_TCPIP_H */
|
||||
12
src/arch/loong64/include/bits/time.h
Normal file
12
src/arch/loong64/include/bits/time.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_TIME_H
|
||||
#define _BITS_TIME_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific time API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_TIME_H */
|
||||
12
src/arch/loong64/include/bits/uaccess.h
Normal file
12
src/arch/loong64/include/bits/uaccess.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_UACCESS_H
|
||||
#define _BITS_UACCESS_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific user access API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UACCESS_H */
|
||||
12
src/arch/loong64/include/bits/uart.h
Normal file
12
src/arch/loong64/include/bits/uart.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_UART_H
|
||||
#define _BITS_UART_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* 16550-compatible UART
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UART_H */
|
||||
12
src/arch/loong64/include/bits/umalloc.h
Normal file
12
src/arch/loong64/include/bits/umalloc.h
Normal file
@ -0,0 +1,12 @@
|
||||
#ifndef _BITS_UMALLOC_H
|
||||
#define _BITS_UMALLOC_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* LoongArch64-specific user memory allocation API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#endif /* _BITS_UMALLOC_H */
|
||||
13
src/arch/loong64/include/bits/xen.h
Normal file
13
src/arch/loong64/include/bits/xen.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef _BITS_XEN_H
|
||||
#define _BITS_XEN_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Xen interface
|
||||
*
|
||||
*/
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/nonxen.h>
|
||||
|
||||
#endif /* _BITS_XEN_H */
|
||||
45
src/arch/loong64/include/gdbmach.h
Normal file
45
src/arch/loong64/include/gdbmach.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef GDBMACH_H
|
||||
#define GDBMACH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* GDB architecture specifics
|
||||
*
|
||||
* This file declares functions for manipulating the machine state and
|
||||
* debugging context.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef unsigned long gdbreg_t;
|
||||
|
||||
/* Register snapshot */
|
||||
enum {
|
||||
/* Not yet implemented */
|
||||
GDBMACH_NREGS,
|
||||
};
|
||||
|
||||
#define GDBMACH_SIZEOF_REGS ( GDBMACH_NREGS * sizeof ( gdbreg_t ) )
|
||||
|
||||
static inline void gdbmach_set_pc ( gdbreg_t *regs, gdbreg_t pc ) {
|
||||
/* Not yet implemented */
|
||||
( void ) regs;
|
||||
( void ) pc;
|
||||
}
|
||||
|
||||
static inline void gdbmach_set_single_step ( gdbreg_t *regs, int step ) {
|
||||
/* Not yet implemented */
|
||||
( void ) regs;
|
||||
( void ) step;
|
||||
}
|
||||
|
||||
static inline void gdbmach_breakpoint ( void ) {
|
||||
/* Not yet implemented */
|
||||
}
|
||||
|
||||
extern int gdbmach_set_breakpoint ( int type, unsigned long addr, size_t len,
|
||||
int enable );
|
||||
extern void gdbmach_init ( void );
|
||||
|
||||
#endif /* GDBMACH_H */
|
||||
20
src/arch/loong64/include/ipxe/efi/dhcparch.h
Normal file
20
src/arch/loong64/include/ipxe/efi/dhcparch.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef _IPXE_EFI_DHCPARCH_H
|
||||
#define _IPXE_EFI_DHCPARCH_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DHCP client architecture definitions
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/dhcp.h>
|
||||
|
||||
/** DHCP client architecture */
|
||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_LOONG64
|
||||
|
||||
/** DHCP client network device interface */
|
||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
|
||||
|
||||
#endif /* _IPXE_EFI_DHCPARCH_H */
|
||||
53
src/arch/loong64/include/limits.h
Normal file
53
src/arch/loong64/include/limits.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef LIMITS_H
|
||||
#define LIMITS_H 1
|
||||
|
||||
/* Number of bits in a `char' */
|
||||
#define CHAR_BIT 8
|
||||
|
||||
/* Minimum and maximum values a `signed char' can hold */
|
||||
#define SCHAR_MIN (-128)
|
||||
#define SCHAR_MAX 127
|
||||
|
||||
/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */
|
||||
#define UCHAR_MAX 255
|
||||
|
||||
/* Minimum and maximum values a `char' can hold */
|
||||
#define CHAR_MIN SCHAR_MIN
|
||||
#define CHAR_MAX SCHAR_MAX
|
||||
|
||||
/* Minimum and maximum values a `signed short int' can hold */
|
||||
#define SHRT_MIN (-32768)
|
||||
#define SHRT_MAX 32767
|
||||
|
||||
/* Maximum value an `unsigned short' can hold. (Minimum is 0.) */
|
||||
#define USHRT_MAX 65535
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#define INT_MAX 2147483647
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
/* Minimum and maximum values a `signed int' can hold */
|
||||
#define INT_MAX 2147483647
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
|
||||
/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */
|
||||
#define UINT_MAX 4294967295U
|
||||
|
||||
/* Minimum and maximum values a `signed long' can hold */
|
||||
#define LONG_MAX 9223372036854775807L
|
||||
#define LONG_MIN (-LONG_MAX - 1L)
|
||||
|
||||
/* Maximum value an `unsigned long' can hold. (Minimum is 0.) */
|
||||
#define ULONG_MAX 18446744073709551615UL
|
||||
|
||||
/* Minimum and maximum values a `signed long long' can hold */
|
||||
#define LLONG_MAX 9223372036854775807LL
|
||||
#define LLONG_MIN (-LONG_MAX - 1LL)
|
||||
|
||||
/* Maximum value an `unsigned long long' can hold. (Minimum is 0.) */
|
||||
#define ULLONG_MAX 18446744073709551615ULL
|
||||
|
||||
#endif /* LIMITS_H */
|
||||
31
src/arch/loong64/include/setjmp.h
Normal file
31
src/arch/loong64/include/setjmp.h
Normal file
@ -0,0 +1,31 @@
|
||||
#ifndef _SETJMP_H
|
||||
#define _SETJMP_H
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** jump buffer env*/
|
||||
typedef struct {
|
||||
uint64_t s0;
|
||||
uint64_t s1;
|
||||
uint64_t s2;
|
||||
uint64_t s3;
|
||||
uint64_t s4;
|
||||
uint64_t s5;
|
||||
uint64_t s6;
|
||||
uint64_t s7;
|
||||
uint64_t s8;
|
||||
|
||||
uint64_t fp;
|
||||
uint64_t sp;
|
||||
uint64_t ra;
|
||||
} jmp_buf[1];
|
||||
|
||||
extern int __asmcall __attribute__ (( returns_twice ))
|
||||
setjmp ( jmp_buf env );
|
||||
|
||||
extern void __asmcall __attribute__ (( noreturn ))
|
||||
longjmp ( jmp_buf env, int val );
|
||||
|
||||
#endif /* _SETJMP_H */
|
||||
103
src/arch/x86/core/rdrand.c
Normal file
103
src/arch/x86/core/rdrand.c
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Hardware random number generator
|
||||
*
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/entropy.h>
|
||||
#include <ipxe/drbg.h>
|
||||
|
||||
struct entropy_source rdrand_entropy __entropy_source ( ENTROPY_PREFERRED );
|
||||
|
||||
/** Number of times to retry RDRAND instruction */
|
||||
#define RDRAND_RETRY_COUNT 16
|
||||
|
||||
/** Colour for debug messages */
|
||||
#define colour &rdrand_entropy
|
||||
|
||||
/**
|
||||
* Enable entropy gathering
|
||||
*
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rdrand_entropy_enable ( void ) {
|
||||
struct x86_features features;
|
||||
|
||||
/* Check that RDRAND is supported */
|
||||
x86_features ( &features );
|
||||
if ( ! ( features.intel.ecx & CPUID_FEATURES_INTEL_ECX_RDRAND ) ) {
|
||||
DBGC ( colour, "RDRAND not supported\n" );
|
||||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
/* Data returned by RDRAND is theoretically full entropy, up
|
||||
* to a security strength of 128 bits, so assume that each
|
||||
* sample contains exactly 8 bits of entropy.
|
||||
*/
|
||||
if ( DRBG_SECURITY_STRENGTH > 128 )
|
||||
return -ENOTSUP;
|
||||
entropy_init ( &rdrand_entropy, MIN_ENTROPY ( 8.0 ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rdrand_get_noise ( noise_sample_t *noise ) {
|
||||
unsigned int result;
|
||||
unsigned int discard_c;
|
||||
unsigned int ok;
|
||||
|
||||
/* Issue RDRAND, retrying until CF is set */
|
||||
__asm__ ( "\n1:\n\t"
|
||||
"rdrand %0\n\t"
|
||||
"sbb %1, %1\n\t"
|
||||
"loopz 1b\n\t"
|
||||
: "=r" ( result ), "=r" ( ok ), "=c" ( discard_c )
|
||||
: "2" ( RDRAND_RETRY_COUNT ) );
|
||||
if ( ! ok ) {
|
||||
DBGC ( colour, "RDRAND failed to become ready\n" );
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
*noise = result;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Hardware random number generator entropy source */
|
||||
struct entropy_source rdrand_entropy __entropy_source ( ENTROPY_PREFERRED ) = {
|
||||
.name = "rdrand",
|
||||
.enable = rdrand_entropy_enable,
|
||||
.get_noise = rdrand_get_noise,
|
||||
};
|
||||
@ -247,19 +247,17 @@ static void bzimage_update_header ( struct image *image,
|
||||
*
|
||||
* @v image bzImage file
|
||||
* @v bzimg bzImage context
|
||||
* @v cmdline Kernel command line
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int bzimage_parse_cmdline ( struct image *image,
|
||||
struct bzimage_context *bzimg,
|
||||
char *cmdline ) {
|
||||
struct bzimage_context *bzimg ) {
|
||||
const char *vga;
|
||||
const char *mem;
|
||||
char *sep;
|
||||
char *vga;
|
||||
char *mem;
|
||||
char *end;
|
||||
|
||||
/* Look for "vga=" */
|
||||
if ( ( vga = strstr ( cmdline, "vga=" ) ) ) {
|
||||
vga += 4;
|
||||
if ( ( vga = image_argument ( image, "vga=" ) ) ) {
|
||||
sep = strchr ( vga, ' ' );
|
||||
if ( sep )
|
||||
*sep = '\0';
|
||||
@ -270,10 +268,10 @@ static int bzimage_parse_cmdline ( struct image *image,
|
||||
} else if ( strcmp ( vga, "ask" ) == 0 ) {
|
||||
bzimg->vid_mode = BZI_VID_MODE_ASK;
|
||||
} else {
|
||||
bzimg->vid_mode = strtoul ( vga, &vga, 0 );
|
||||
if ( *vga ) {
|
||||
bzimg->vid_mode = strtoul ( vga, &end, 0 );
|
||||
if ( *end ) {
|
||||
DBGC ( image, "bzImage %p strange \"vga=\" "
|
||||
"terminator '%c'\n", image, *vga );
|
||||
"terminator '%c'\n", image, *end );
|
||||
}
|
||||
}
|
||||
if ( sep )
|
||||
@ -281,10 +279,9 @@ static int bzimage_parse_cmdline ( struct image *image,
|
||||
}
|
||||
|
||||
/* Look for "mem=" */
|
||||
if ( ( mem = strstr ( cmdline, "mem=" ) ) ) {
|
||||
mem += 4;
|
||||
bzimg->mem_limit = strtoul ( mem, &mem, 0 );
|
||||
switch ( *mem ) {
|
||||
if ( ( mem = image_argument ( image, "mem=" ) ) ) {
|
||||
bzimg->mem_limit = strtoul ( mem, &end, 0 );
|
||||
switch ( *end ) {
|
||||
case 'G':
|
||||
case 'g':
|
||||
bzimg->mem_limit <<= 10;
|
||||
@ -302,7 +299,7 @@ static int bzimage_parse_cmdline ( struct image *image,
|
||||
break;
|
||||
default:
|
||||
DBGC ( image, "bzImage %p strange \"mem=\" "
|
||||
"terminator '%c'\n", image, *mem );
|
||||
"terminator '%c'\n", image, *end );
|
||||
break;
|
||||
}
|
||||
bzimg->mem_limit -= 1;
|
||||
@ -316,11 +313,10 @@ static int bzimage_parse_cmdline ( struct image *image,
|
||||
*
|
||||
* @v image bzImage image
|
||||
* @v bzimg bzImage context
|
||||
* @v cmdline Kernel command line
|
||||
*/
|
||||
static void bzimage_set_cmdline ( struct image *image,
|
||||
struct bzimage_context *bzimg,
|
||||
const char *cmdline ) {
|
||||
struct bzimage_context *bzimg ) {
|
||||
const char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
||||
size_t cmdline_len;
|
||||
|
||||
/* Copy command line down to real-mode portion */
|
||||
@ -528,7 +524,6 @@ static void bzimage_load_initrds ( struct image *image,
|
||||
*/
|
||||
static int bzimage_exec ( struct image *image ) {
|
||||
struct bzimage_context bzimg;
|
||||
char *cmdline = ( image->cmdline ? image->cmdline : "" );
|
||||
int rc;
|
||||
|
||||
/* Read and parse header from image */
|
||||
@ -551,7 +546,7 @@ static int bzimage_exec ( struct image *image ) {
|
||||
}
|
||||
|
||||
/* Parse command line for bootloader parameters */
|
||||
if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0)
|
||||
if ( ( rc = bzimage_parse_cmdline ( image, &bzimg ) ) != 0)
|
||||
return rc;
|
||||
|
||||
/* Check that initrds can be loaded */
|
||||
@ -568,7 +563,7 @@ static int bzimage_exec ( struct image *image ) {
|
||||
bzimg.rm_filesz, bzimg.pm_sz );
|
||||
|
||||
/* Store command line */
|
||||
bzimage_set_cmdline ( image, &bzimg, cmdline );
|
||||
bzimage_set_cmdline ( image, &bzimg );
|
||||
|
||||
/* Prepare for exiting. Must do this before loading initrds,
|
||||
* since loading the initrds will corrupt the external heap.
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
#ifndef _BITS_ENTROPY_H
|
||||
#define _BITS_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* x86-specific entropy API implementations
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/rtc_entropy.h>
|
||||
|
||||
#endif /* _BITS_ENTROPY_H */
|
||||
@ -28,6 +28,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_cpuid ( ERRFILE_ARCH | ERRFILE_CORE | 0x00110000 )
|
||||
#define ERRFILE_rdtsc_timer ( ERRFILE_ARCH | ERRFILE_CORE | 0x00120000 )
|
||||
#define ERRFILE_acpi_timer ( ERRFILE_ARCH | ERRFILE_CORE | 0x00130000 )
|
||||
#define ERRFILE_rdrand ( ERRFILE_ARCH | ERRFILE_CORE | 0x00140000 )
|
||||
|
||||
#define ERRFILE_bootsector ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00000000 )
|
||||
#define ERRFILE_bzimage ( ERRFILE_ARCH | ERRFILE_IMAGE | 0x00010000 )
|
||||
|
||||
@ -9,6 +9,9 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
#include <ipxe/x86_io.h>
|
||||
|
||||
#endif /* _BITS_IO_H */
|
||||
|
||||
@ -39,6 +39,9 @@ struct x86_features {
|
||||
/** Get standard features */
|
||||
#define CPUID_FEATURES 0x00000001UL
|
||||
|
||||
/** RDRAND instruction is supported */
|
||||
#define CPUID_FEATURES_INTEL_ECX_RDRAND 0x40000000UL
|
||||
|
||||
/** Hypervisor is present */
|
||||
#define CPUID_FEATURES_INTEL_ECX_HYPERVISOR 0x80000000UL
|
||||
|
||||
|
||||
@ -1,62 +0,0 @@
|
||||
#ifndef _IPXE_RTC_ENTROPY_H
|
||||
#define _IPXE_RTC_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* RTC-based entropy source
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ENTROPY_RTC
|
||||
#define ENTROPY_PREFIX_rtc
|
||||
#else
|
||||
#define ENTROPY_PREFIX_rtc __rtc_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* min-entropy per sample
|
||||
*
|
||||
* @ret min_entropy min-entropy of each sample
|
||||
*/
|
||||
static inline __always_inline min_entropy_t
|
||||
ENTROPY_INLINE ( rtc, min_entropy_per_sample ) ( void ) {
|
||||
|
||||
/* The min-entropy has been measured on several platforms
|
||||
* using the entropy_sample test code. Modelling the samples
|
||||
* as independent, and using a confidence level of 99.99%, the
|
||||
* measurements were as follows:
|
||||
*
|
||||
* qemu-kvm : 7.38 bits
|
||||
* VMware : 7.46 bits
|
||||
* Physical hardware : 2.67 bits
|
||||
*
|
||||
* We choose the lowest of these (2.67 bits) and apply a 50%
|
||||
* safety margin to allow for some potential non-independence
|
||||
* of samples.
|
||||
*/
|
||||
return MIN_ENTROPY ( 1.3 );
|
||||
}
|
||||
|
||||
extern uint8_t rtc_sample ( void );
|
||||
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static inline __always_inline int
|
||||
ENTROPY_INLINE ( rtc, get_noise ) ( noise_sample_t *noise ) {
|
||||
|
||||
/* Get sample */
|
||||
*noise = rtc_sample();
|
||||
|
||||
/* Always successful */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _IPXE_RTC_ENTROPY_H */
|
||||
@ -28,9 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
|
||||
/** Page shift */
|
||||
#define PAGE_SHIFT 12
|
||||
|
||||
/*
|
||||
* Physical<->Bus address mappings
|
||||
*
|
||||
|
||||
@ -39,9 +39,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/cpuid.h>
|
||||
#include <ipxe/entropy.h>
|
||||
|
||||
struct entropy_source rtc_entropy __entropy_source ( ENTROPY_NORMAL );
|
||||
|
||||
/** Maximum time to wait for an RTC interrupt, in milliseconds */
|
||||
#define RTC_MAX_WAIT_MS 100
|
||||
|
||||
/** Number of RTC interrupts to check for */
|
||||
#define RTC_CHECK_COUNT 3
|
||||
|
||||
/** RTC interrupt handler */
|
||||
extern void rtc_isr ( void );
|
||||
|
||||
@ -145,6 +150,7 @@ static void rtc_disable_int ( void ) {
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int rtc_entropy_check ( void ) {
|
||||
unsigned int count = 0;
|
||||
unsigned int i;
|
||||
|
||||
/* Check that RTC interrupts are working */
|
||||
@ -158,14 +164,18 @@ static int rtc_entropy_check ( void ) {
|
||||
"cli\n\t" );
|
||||
|
||||
/* Check for RTC interrupt flag */
|
||||
if ( rtc_flag )
|
||||
return 0;
|
||||
if ( rtc_flag ) {
|
||||
rtc_flag = 0;
|
||||
if ( ++count >= RTC_CHECK_COUNT )
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Delay */
|
||||
mdelay ( 1 );
|
||||
}
|
||||
|
||||
DBGC ( &rtc_flag, "RTC timed out waiting for interrupt\n" );
|
||||
DBGC ( &rtc_flag, "RTC timed out waiting for interrupt %d/%d\n",
|
||||
( count + 1 ), RTC_CHECK_COUNT );
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -195,6 +205,21 @@ static int rtc_entropy_enable ( void ) {
|
||||
if ( ( rc = rtc_entropy_check() ) != 0 )
|
||||
goto err_check;
|
||||
|
||||
/* The min-entropy has been measured on several platforms
|
||||
* using the entropy_sample test code. Modelling the samples
|
||||
* as independent, and using a confidence level of 99.99%, the
|
||||
* measurements were as follows:
|
||||
*
|
||||
* qemu-kvm : 7.38 bits
|
||||
* VMware : 7.46 bits
|
||||
* Physical hardware : 2.67 bits
|
||||
*
|
||||
* We choose the lowest of these (2.67 bits) and apply a 50%
|
||||
* safety margin to allow for some potential non-independence
|
||||
* of samples.
|
||||
*/
|
||||
entropy_init ( &rtc_entropy, MIN_ENTROPY ( 1.3 ) );
|
||||
|
||||
return 0;
|
||||
|
||||
err_check:
|
||||
@ -218,11 +243,12 @@ static void rtc_entropy_disable ( void ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Measure a single RTC tick
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret delta Length of RTC tick (in TSC units)
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
uint8_t rtc_sample ( void ) {
|
||||
static int rtc_get_noise ( noise_sample_t *noise ) {
|
||||
uint32_t before;
|
||||
uint32_t after;
|
||||
uint32_t temp;
|
||||
@ -257,10 +283,14 @@ uint8_t rtc_sample ( void ) {
|
||||
: "=a" ( after ), "=d" ( before ), "=Q" ( temp )
|
||||
: "2" ( 0 ) );
|
||||
|
||||
return ( after - before );
|
||||
*noise = ( after - before );
|
||||
return 0;
|
||||
}
|
||||
|
||||
PROVIDE_ENTROPY_INLINE ( rtc, min_entropy_per_sample );
|
||||
PROVIDE_ENTROPY ( rtc, entropy_enable, rtc_entropy_enable );
|
||||
PROVIDE_ENTROPY ( rtc, entropy_disable, rtc_entropy_disable );
|
||||
PROVIDE_ENTROPY_INLINE ( rtc, get_noise );
|
||||
/** RTC entropy source */
|
||||
struct entropy_source rtc_entropy __entropy_source ( ENTROPY_NORMAL ) = {
|
||||
.name = "rtc",
|
||||
.enable = rtc_entropy_enable,
|
||||
.disable = rtc_entropy_disable,
|
||||
.get_noise = rtc_get_noise,
|
||||
};
|
||||
|
||||
@ -8,6 +8,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
/** Unprefixed constant operand modifier */
|
||||
#define ASM_NO_PREFIX "c"
|
||||
|
||||
/** Declare a function with standard calling conventions */
|
||||
#define __asmcall __attribute__ (( regparm(0) ))
|
||||
|
||||
|
||||
@ -352,6 +352,9 @@ REQUIRE_OBJECT ( vram_settings );
|
||||
#ifdef ACPI_SETTINGS
|
||||
REQUIRE_OBJECT ( acpi_settings );
|
||||
#endif
|
||||
#ifdef EFI_SETTINGS
|
||||
REQUIRE_OBJECT ( efi_settings );
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Drag in selected keyboard map
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -23,18 +21,31 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/entropy.h>
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Nonexistent entropy source
|
||||
* Entropy configuration options
|
||||
*
|
||||
*
|
||||
* This source provides no entropy and must NOT be used in a
|
||||
* security-sensitive environment.
|
||||
*/
|
||||
|
||||
#include <ipxe/entropy.h>
|
||||
PROVIDE_REQUIRING_SYMBOL();
|
||||
|
||||
PROVIDE_ENTROPY_INLINE ( null, min_entropy_per_sample );
|
||||
PROVIDE_ENTROPY_INLINE ( null, entropy_enable );
|
||||
PROVIDE_ENTROPY_INLINE ( null, entropy_disable );
|
||||
PROVIDE_ENTROPY_INLINE ( null, get_noise );
|
||||
/*
|
||||
* Drag in entropy sources
|
||||
*/
|
||||
#ifdef ENTROPY_RTC
|
||||
REQUIRE_OBJECT ( rtc_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_EFITICK
|
||||
REQUIRE_OBJECT ( efi_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_EFIRNG
|
||||
REQUIRE_OBJECT ( efi_rng );
|
||||
#endif
|
||||
#ifdef ENTROPY_LINUX
|
||||
REQUIRE_OBJECT ( linux_entropy );
|
||||
#endif
|
||||
#ifdef ENTROPY_RDRAND
|
||||
REQUIRE_OBJECT ( rdrand );
|
||||
#endif
|
||||
@ -49,3 +49,6 @@ REQUIRE_OBJECT ( eth_slow );
|
||||
#ifdef NET_PROTO_EAPOL
|
||||
REQUIRE_OBJECT ( eapol );
|
||||
#endif
|
||||
#ifdef NET_PROTO_LLDP
|
||||
REQUIRE_OBJECT ( lldp );
|
||||
#endif
|
||||
|
||||
@ -19,13 +19,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define SMBIOS_EFI
|
||||
#define SANBOOT_EFI
|
||||
#define BOFM_EFI
|
||||
#define ENTROPY_EFI
|
||||
#define ENTROPY_EFITICK
|
||||
#define ENTROPY_EFIRNG
|
||||
#define TIME_EFI
|
||||
#define REBOOT_EFI
|
||||
#define ACPI_EFI
|
||||
#define FDT_EFI
|
||||
|
||||
#define NET_PROTO_IPV6 /* IPv6 protocol */
|
||||
#define NET_PROTO_LLDP /* Link Layer Discovery protocol */
|
||||
|
||||
#define DOWNLOAD_PROTO_FILE /* Local filesystem access */
|
||||
|
||||
@ -46,9 +48,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#define REBOOT_CMD /* Reboot command */
|
||||
|
||||
#define EFI_SETTINGS /* EFI variable settings */
|
||||
|
||||
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
||||
#define IOAPI_X86
|
||||
#define NAP_EFIX86
|
||||
#define ENTROPY_RDRAND
|
||||
#define CPUID_CMD /* x86 CPU feature detection command */
|
||||
#define UNSAFE_STD /* Avoid setting direction flag */
|
||||
#endif
|
||||
|
||||
@ -33,4 +33,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define SANBOOT_PROTO_FCP
|
||||
#define SANBOOT_PROTO_HTTP
|
||||
|
||||
#if defined ( __i386__ ) || defined ( __x86_64__ )
|
||||
#define ENTROPY_RDRAND
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DEFAULTS_LINUX_H */
|
||||
|
||||
@ -20,6 +20,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define SMBIOS_PCBIOS
|
||||
#define SANBOOT_PCBIOS
|
||||
#define ENTROPY_RTC
|
||||
#define ENTROPY_RDRAND
|
||||
#define TIME_RTC
|
||||
#define REBOOT_PCBIOS
|
||||
#define ACPI_RSDP
|
||||
|
||||
@ -40,6 +40,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define NET_PROTO_STP /* Spanning Tree protocol */
|
||||
#define NET_PROTO_LACP /* Link Aggregation control protocol */
|
||||
#define NET_PROTO_EAPOL /* EAP over LAN protocol */
|
||||
//#define NET_PROTO_LLDP /* Link Layer Discovery protocol */
|
||||
|
||||
/*
|
||||
* PXE support
|
||||
@ -149,7 +150,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
//#define POWEROFF_CMD /* Power off command */
|
||||
//#define IMAGE_TRUST_CMD /* Image trust management commands */
|
||||
//#define PCI_CMD /* PCI commands */
|
||||
//#define PARAM_CMD /* Form parameter commands */
|
||||
//#define PARAM_CMD /* Request parameter commands */
|
||||
//#define NEIGHBOUR_CMD /* Neighbour management commands */
|
||||
//#define PING_CMD /* Ping command */
|
||||
//#define CONSOLE_CMD /* Console command */
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <config/defaults.h>
|
||||
|
||||
#define PCI_SETTINGS /* PCI device settings */
|
||||
//#define CPUID_SETTINGS /* CPUID settings */
|
||||
//#define MEMMAP_SETTINGS /* Memory map settings */
|
||||
|
||||
@ -77,17 +77,12 @@ size_t cpio_name_len ( struct image *image ) {
|
||||
*/
|
||||
static void cpio_parse_cmdline ( struct image *image,
|
||||
struct cpio_header *cpio ) {
|
||||
const char *cmdline;
|
||||
char *arg;
|
||||
const char *arg;
|
||||
char *end;
|
||||
unsigned int mode;
|
||||
|
||||
/* Skip image filename */
|
||||
cmdline = ( cpio_name ( image ) + cpio_name_len ( image ) );
|
||||
|
||||
/* Look for "mode=" */
|
||||
if ( ( arg = strstr ( cmdline, "mode=" ) ) ) {
|
||||
arg += 5;
|
||||
if ( ( arg = image_argument ( image, "mode=" ) ) ) {
|
||||
mode = strtoul ( arg, &end, 8 /* Octal for file mode */ );
|
||||
if ( *end && ( *end != ' ' ) ) {
|
||||
DBGC ( image, "CPIO %p strange \"mode=\" "
|
||||
|
||||
@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <libgen.h>
|
||||
@ -569,3 +570,33 @@ struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
|
||||
err_alloc_image:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find argument within image command line
|
||||
*
|
||||
* @v image Image
|
||||
* @v key Argument search key (including trailing delimiter)
|
||||
* @ret value Argument value, or NULL if not found
|
||||
*/
|
||||
const char * image_argument ( struct image *image, const char *key ) {
|
||||
const char *cmdline = image->cmdline;
|
||||
const char *search;
|
||||
const char *match;
|
||||
const char *next;
|
||||
|
||||
/* Find argument */
|
||||
for ( search = cmdline ; search ; search = next ) {
|
||||
|
||||
/* Find next occurrence, if any */
|
||||
match = strstr ( search, key );
|
||||
if ( ! match )
|
||||
break;
|
||||
next = ( match + strlen ( key ) );
|
||||
|
||||
/* Check preceding delimiter, if any */
|
||||
if ( ( match == cmdline ) || isspace ( match[-1] ) )
|
||||
return next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Form parameters
|
||||
* Request parameters
|
||||
*
|
||||
*/
|
||||
|
||||
@ -37,7 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
static LIST_HEAD ( parameters );
|
||||
|
||||
/**
|
||||
* Free form parameter list
|
||||
* Free request parameter list
|
||||
*
|
||||
* @v refcnt Reference count
|
||||
*/
|
||||
@ -60,7 +60,7 @@ static void free_parameters ( struct refcnt *refcnt ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Find form parameter list by name
|
||||
* Find request parameter list by name
|
||||
*
|
||||
* @v name Parameter list name (may be NULL)
|
||||
* @ret params Parameter list, or NULL if not found
|
||||
@ -78,7 +78,7 @@ struct parameters * find_parameters ( const char *name ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create form parameter list
|
||||
* Create request parameter list
|
||||
*
|
||||
* @v name Parameter list name (may be NULL)
|
||||
* @ret params Parameter list, or NULL on failure
|
||||
@ -118,15 +118,17 @@ struct parameters * create_parameters ( const char *name ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add form parameter
|
||||
* Add request parameter
|
||||
*
|
||||
* @v params Parameter list
|
||||
* @v key Parameter key
|
||||
* @v value Parameter value
|
||||
* @v flags Parameter flags
|
||||
* @ret param Parameter, or NULL on failure
|
||||
*/
|
||||
struct parameter * add_parameter ( struct parameters *params,
|
||||
const char *key, const char *value ) {
|
||||
const char *key, const char *value,
|
||||
unsigned int flags ) {
|
||||
struct parameter *param;
|
||||
size_t key_len;
|
||||
size_t value_len;
|
||||
@ -147,11 +149,14 @@ struct parameter * add_parameter ( struct parameters *params,
|
||||
param->key = key_copy;
|
||||
strcpy ( value_copy, value );
|
||||
param->value = value_copy;
|
||||
param->flags = flags;
|
||||
|
||||
/* Add to list of parameters */
|
||||
list_add_tail ( ¶m->list, ¶ms->entries );
|
||||
|
||||
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"\n",
|
||||
params->name, param->key, param->value );
|
||||
DBGC ( params, "PARAMS \"%s\" added \"%s\"=\"%s\"%s%s\n",
|
||||
params->name, param->key, param->value,
|
||||
( ( param->flags & PARAMETER_FORM ) ? " (form)" : "" ),
|
||||
( ( param->flags & PARAMETER_HEADER ) ? " (header)" : "" ) );
|
||||
return param;
|
||||
}
|
||||
|
||||
@ -302,7 +302,7 @@ int parse_autovivified_setting ( char *text, struct named_setting *setting ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse form parameter list name
|
||||
* Parse request parameter list name
|
||||
*
|
||||
* @v text Text
|
||||
* @ret params Parameter list
|
||||
|
||||
@ -51,59 +51,33 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
__einfo_uniqify ( EINFO_EPIPE, 0x02, "Adaptive proportion test failed" )
|
||||
|
||||
/**
|
||||
* Calculate cutoff value for the repetition count test
|
||||
* Initialise repetition count test
|
||||
*
|
||||
* @ret cutoff Cutoff value
|
||||
*
|
||||
* This is the cutoff value for the Repetition Count Test defined in
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
|
||||
* @v source Entropy source
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
repetition_count_cutoff ( void ) {
|
||||
double max_repetitions;
|
||||
unsigned int cutoff;
|
||||
static void repetition_count_test_init ( struct entropy_source *source ) {
|
||||
struct entropy_repetition_count_test *test =
|
||||
&source->repetition_count_test;
|
||||
|
||||
/* The cutoff formula for the repetition test is:
|
||||
*
|
||||
* C = ( 1 + ( -log2(W) / H_min ) )
|
||||
*
|
||||
* where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
|
||||
* 2011 Draft) Section 8.5.2.1.3.1).
|
||||
*/
|
||||
max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
|
||||
min_entropy_per_sample() ) );
|
||||
|
||||
/* Round up to a whole number of repetitions. We don't have
|
||||
* the ceil() function available, so do the rounding by hand.
|
||||
*/
|
||||
cutoff = max_repetitions;
|
||||
if ( cutoff < max_repetitions )
|
||||
cutoff++;
|
||||
linker_assert ( ( cutoff >= max_repetitions ), rounding_error );
|
||||
|
||||
/* Floating-point operations are not allowed in iPXE since we
|
||||
* never set up a suitable environment. Abort the build
|
||||
* unless the calculated number of repetitions is a
|
||||
* compile-time constant.
|
||||
*/
|
||||
linker_assert ( __builtin_constant_p ( cutoff ),
|
||||
repetition_count_cutoff_not_constant );
|
||||
|
||||
return cutoff;
|
||||
/* Sanity checks */
|
||||
assert ( test->repetition_count == 0 );
|
||||
assert ( test->cutoff > 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform repetition count test
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @v sample Noise sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the Repetition Count Test defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 8.5.2.1.2.
|
||||
*/
|
||||
static int repetition_count_test ( noise_sample_t sample ) {
|
||||
static noise_sample_t most_recent_sample;
|
||||
static unsigned int repetition_count = 0;
|
||||
static int repetition_count_test ( struct entropy_source *source,
|
||||
noise_sample_t sample ) {
|
||||
struct entropy_repetition_count_test *test =
|
||||
&source->repetition_count_test;
|
||||
|
||||
/* A = the most recently seen sample value
|
||||
* B = the number of times that value A has been seen in a row
|
||||
@ -116,158 +90,71 @@ static int repetition_count_test ( noise_sample_t sample ) {
|
||||
* the initial value of most_recent_sample is treated as being
|
||||
* undefined.)
|
||||
*/
|
||||
if ( ( sample == most_recent_sample ) && ( repetition_count > 0 ) ) {
|
||||
if ( ( sample == test->most_recent_sample ) &&
|
||||
( test->repetition_count > 0 ) ) {
|
||||
|
||||
/* a) If the new sample = A, then B is incremented by one. */
|
||||
repetition_count++;
|
||||
test->repetition_count++;
|
||||
|
||||
/* i. If B >= C, then an error condition is raised
|
||||
* due to a failure of the test
|
||||
*/
|
||||
if ( repetition_count >= repetition_count_cutoff() )
|
||||
if ( test->repetition_count >= test->cutoff ) {
|
||||
DBGC ( source, "ENTROPY %s excessively repeated "
|
||||
"value %d (%d/%d)\n", source->name, sample,
|
||||
test->repetition_count, test->cutoff );
|
||||
return -EPIPE_REPETITION_COUNT_TEST;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* b) Else:
|
||||
* i. A = new sample
|
||||
*/
|
||||
most_recent_sample = sample;
|
||||
test->most_recent_sample = sample;
|
||||
|
||||
/* ii. B = 1 */
|
||||
repetition_count = 1;
|
||||
test->repetition_count = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Window size for the adaptive proportion test
|
||||
* Initialise adaptive proportion test
|
||||
*
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
|
||||
* five possible window sizes: 16, 64, 256, 4096 and 65536.
|
||||
*
|
||||
* We expect to generate relatively few (<256) entropy samples during
|
||||
* a typical iPXE run; the use of a large window size would mean that
|
||||
* the test would never complete a single cycle. We use a window size
|
||||
* of 64, which is the smallest window size that permits values of
|
||||
* H_min down to one bit per sample.
|
||||
* @v source Entropy source
|
||||
*/
|
||||
#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
|
||||
static void adaptive_proportion_test_init ( struct entropy_source *source ) {
|
||||
struct entropy_adaptive_proportion_test *test =
|
||||
&source->adaptive_proportion_test;
|
||||
|
||||
/**
|
||||
* Combine adaptive proportion test window size and min-entropy
|
||||
*
|
||||
* @v n N (window size)
|
||||
* @v h H (min-entropy)
|
||||
* @ret n_h (N,H) combined value
|
||||
*/
|
||||
#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
|
||||
/* Sanity checks */
|
||||
assert ( test->sample_count == 0 );
|
||||
assert ( test->repetition_count == 0 );
|
||||
assert ( test->cutoff > 0 );
|
||||
|
||||
/**
|
||||
* Define a row of the adaptive proportion cutoff table
|
||||
*
|
||||
* @v h H (min-entropy)
|
||||
* @v c16 Cutoff for N=16
|
||||
* @v c64 Cutoff for N=64
|
||||
* @v c256 Cutoff for N=256
|
||||
* @v c4096 Cutoff for N=4096
|
||||
* @v c65536 Cutoff for N=65536
|
||||
*/
|
||||
#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
|
||||
case APC_N_H ( 16, h ) : return c16; \
|
||||
case APC_N_H ( 64, h ) : return c64; \
|
||||
case APC_N_H ( 256, h ) : return c256; \
|
||||
case APC_N_H ( 4096, h ) : return c4096; \
|
||||
case APC_N_H ( 65536, h ) : return c65536;
|
||||
|
||||
/** Value used to represent "N/A" in adaptive proportion cutoff table */
|
||||
#define APC_NA 0
|
||||
|
||||
/**
|
||||
* Look up value in adaptive proportion test cutoff table
|
||||
*
|
||||
* @v n N (window size)
|
||||
* @v h H (min-entropy)
|
||||
* @ret cutoff Cutoff
|
||||
*
|
||||
* This is the table of cutoff values defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 8.5.2.1.3.1.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
|
||||
switch ( APC_N_H ( n, h ) ) {
|
||||
APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
|
||||
APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
|
||||
APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
|
||||
APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
|
||||
APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
|
||||
APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
|
||||
APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
|
||||
APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
|
||||
APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
|
||||
APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
|
||||
APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
|
||||
APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
|
||||
APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
|
||||
APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
|
||||
APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
|
||||
APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
|
||||
APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
|
||||
APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
|
||||
APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
|
||||
APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
|
||||
default:
|
||||
return APC_NA;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cutoff value for the adaptive proportion test
|
||||
*
|
||||
* @ret cutoff Cutoff value
|
||||
*
|
||||
* This is the cutoff value for the Adaptive Proportion Test defined
|
||||
* in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
adaptive_proportion_cutoff ( void ) {
|
||||
unsigned int h;
|
||||
unsigned int n;
|
||||
unsigned int cutoff;
|
||||
|
||||
/* Look up cutoff value in cutoff table */
|
||||
n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
|
||||
h = ( min_entropy_per_sample() / MIN_ENTROPY_SCALE );
|
||||
cutoff = adaptive_proportion_cutoff_lookup ( n, h );
|
||||
|
||||
/* Fail unless cutoff value is a build-time constant */
|
||||
linker_assert ( __builtin_constant_p ( cutoff ),
|
||||
adaptive_proportion_cutoff_not_constant );
|
||||
|
||||
/* Fail if cutoff value is N/A */
|
||||
linker_assert ( ( cutoff != APC_NA ),
|
||||
adaptive_proportion_cutoff_not_applicable );
|
||||
|
||||
return cutoff;
|
||||
/* Ensure that a new test run starts immediately */
|
||||
test->sample_count = ADAPTIVE_PROPORTION_WINDOW_SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform adaptive proportion test
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @v sample Noise sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the Adaptive Proportion Test for the Most Common Value
|
||||
* defined in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.
|
||||
*/
|
||||
static int adaptive_proportion_test ( noise_sample_t sample ) {
|
||||
static noise_sample_t current_counted_sample;
|
||||
static unsigned int sample_count = ADAPTIVE_PROPORTION_WINDOW_SIZE;
|
||||
static unsigned int repetition_count;
|
||||
static int adaptive_proportion_test ( struct entropy_source *source,
|
||||
noise_sample_t sample ) {
|
||||
struct entropy_adaptive_proportion_test *test =
|
||||
&source->adaptive_proportion_test;
|
||||
|
||||
/* A = the sample value currently being counted
|
||||
* B = the number of samples examined in this run of the test so far
|
||||
* S = the number of samples examined in this run of the test so far
|
||||
* N = the total number of samples that must be observed in
|
||||
* one run of the test, also known as the "window size" of
|
||||
* the test
|
||||
@ -284,37 +171,41 @@ static int adaptive_proportion_test ( noise_sample_t sample ) {
|
||||
*/
|
||||
|
||||
/* 2. If S = N, then a new run of the test begins: */
|
||||
if ( sample_count == ADAPTIVE_PROPORTION_WINDOW_SIZE ) {
|
||||
if ( test->sample_count == ADAPTIVE_PROPORTION_WINDOW_SIZE ) {
|
||||
|
||||
/* a. A = the current sample */
|
||||
current_counted_sample = sample;
|
||||
test->current_counted_sample = sample;
|
||||
|
||||
/* b. S = 0 */
|
||||
sample_count = 0;
|
||||
test->sample_count = 0;
|
||||
|
||||
/* c. B = 0 */
|
||||
repetition_count = 0;
|
||||
test->repetition_count = 0;
|
||||
|
||||
} else {
|
||||
|
||||
/* Else: (the test is already running)
|
||||
* a. S = S + 1
|
||||
*/
|
||||
sample_count++;
|
||||
test->sample_count++;
|
||||
|
||||
/* b. If A = the current sample, then: */
|
||||
if ( sample == current_counted_sample ) {
|
||||
if ( sample == test->current_counted_sample ) {
|
||||
|
||||
/* i. B = B + 1 */
|
||||
repetition_count++;
|
||||
test->repetition_count++;
|
||||
|
||||
/* ii. If S (sic) > C then raise an error
|
||||
* condition, because the test has
|
||||
* detected a failure
|
||||
*/
|
||||
if ( repetition_count > adaptive_proportion_cutoff() )
|
||||
if ( test->repetition_count > test->cutoff ) {
|
||||
DBGC ( source, "ENTROPY %s excessively "
|
||||
"repeated value %d (%d/%d)\n",
|
||||
source->name, sample,
|
||||
test->repetition_count, test->cutoff );
|
||||
return -EPIPE_ADAPTIVE_PROPORTION_TEST;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -324,62 +215,180 @@ static int adaptive_proportion_test ( noise_sample_t sample ) {
|
||||
/**
|
||||
* Get entropy sample
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @ret entropy Entropy sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the GetEntropy function defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 6.5.1.
|
||||
*/
|
||||
static int get_entropy ( entropy_sample_t *entropy ) {
|
||||
static int rc = 0;
|
||||
static int get_entropy ( struct entropy_source *source,
|
||||
entropy_sample_t *entropy ) {
|
||||
noise_sample_t noise;
|
||||
int rc;
|
||||
|
||||
/* Any failure is permanent */
|
||||
if ( rc != 0 )
|
||||
return rc;
|
||||
if ( ( rc = source->rc ) != 0 )
|
||||
goto err_broken;
|
||||
|
||||
/* Get noise sample */
|
||||
if ( ( rc = get_noise ( &noise ) ) != 0 )
|
||||
return rc;
|
||||
if ( ( rc = get_noise ( source, &noise ) ) != 0 )
|
||||
goto err_get_noise;
|
||||
|
||||
/* Perform Repetition Count Test and Adaptive Proportion Test
|
||||
* as mandated by ANS X9.82 Part 2 (October 2011 Draft)
|
||||
* Section 8.5.2.1.1.
|
||||
*/
|
||||
if ( ( rc = repetition_count_test ( noise ) ) != 0 )
|
||||
return rc;
|
||||
if ( ( rc = adaptive_proportion_test ( noise ) ) != 0 )
|
||||
return rc;
|
||||
if ( ( rc = repetition_count_test ( source, noise ) ) != 0 )
|
||||
goto err_repetition_count_test;
|
||||
if ( ( rc = adaptive_proportion_test ( source, noise ) ) != 0 )
|
||||
goto err_adaptive_proportion_test;
|
||||
|
||||
/* We do not use any optional conditioning component */
|
||||
*entropy = noise;
|
||||
|
||||
return 0;
|
||||
|
||||
err_adaptive_proportion_test:
|
||||
err_repetition_count_test:
|
||||
err_get_noise:
|
||||
source->rc = rc;
|
||||
err_broken:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate number of samples required for startup tests
|
||||
* Initialise startup test
|
||||
*
|
||||
* @ret num_samples Number of samples required
|
||||
*
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
|
||||
* that at least one full cycle of the continuous tests must be
|
||||
* performed at start-up.
|
||||
* @v source Entropy source
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
startup_test_count ( void ) {
|
||||
unsigned int num_samples;
|
||||
static void startup_test_init ( struct entropy_source *source ) {
|
||||
struct entropy_startup_test *test = &source->startup_test;
|
||||
|
||||
/* At least max(N,C) samples shall be generated by the noise
|
||||
* source for start-up testing.
|
||||
*/
|
||||
num_samples = repetition_count_cutoff();
|
||||
if ( num_samples < adaptive_proportion_cutoff() )
|
||||
num_samples = adaptive_proportion_cutoff();
|
||||
linker_assert ( __builtin_constant_p ( num_samples ),
|
||||
startup_test_count_not_constant );
|
||||
/* Sanity check */
|
||||
assert ( test->tested == 0 );
|
||||
assert ( test->count > 0 );
|
||||
}
|
||||
|
||||
return num_samples;
|
||||
/**
|
||||
* Perform startup test
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int startup_test ( struct entropy_source *source ) {
|
||||
struct entropy_startup_test *test = &source->startup_test;
|
||||
entropy_sample_t sample;
|
||||
int rc;
|
||||
|
||||
/* Perform mandatory number of startup tests */
|
||||
for ( ; test->tested < test->count ; test->tested++ ) {
|
||||
if ( ( rc = get_entropy ( source, &sample ) ) != 0 ) {
|
||||
DBGC ( source, "ENTROPY %s failed: %s\n",
|
||||
source->name, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable entropy gathering
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int entropy_enable ( struct entropy_source *source ) {
|
||||
int rc;
|
||||
|
||||
/* Refuse to enable a previously failed source */
|
||||
if ( ( rc = source->rc ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Enable entropy source */
|
||||
if ( ( rc = source->enable() ) != 0 ) {
|
||||
DBGC ( source, "ENTROPY %s could not enable: %s\n",
|
||||
source->name, strerror ( rc ) );
|
||||
source->rc = rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
assert ( source->min_entropy_per_sample > 0 );
|
||||
|
||||
/* Initialise test state if this source has not previously been used */
|
||||
if ( source->startup_test.tested == 0 ) {
|
||||
repetition_count_test_init ( source );
|
||||
adaptive_proportion_test_init ( source );
|
||||
startup_test_init ( source );
|
||||
}
|
||||
|
||||
DBGC ( source, "ENTROPY %s enabled\n", source->name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable and test entropy source
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int entropy_enable_and_test ( struct entropy_source *source ) {
|
||||
int rc;
|
||||
|
||||
/* Enable source */
|
||||
if ( ( rc = entropy_enable ( source ) ) != 0 )
|
||||
goto err_enable;
|
||||
|
||||
/* Test source */
|
||||
if ( ( rc = startup_test ( source ) ) != 0 )
|
||||
goto err_test;
|
||||
|
||||
DBGC ( source, "ENTROPY %s passed %d startup tests\n",
|
||||
source->name, source->startup_test.count );
|
||||
return 0;
|
||||
|
||||
err_test:
|
||||
entropy_disable ( source );
|
||||
err_enable:
|
||||
assert ( source->rc == rc );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable first working entropy source
|
||||
*
|
||||
* @v source Entropy source to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int entropy_enable_working ( struct entropy_source **source ) {
|
||||
int rc;
|
||||
|
||||
/* Find the first working source */
|
||||
rc = -ENOENT;
|
||||
for_each_table_entry ( *source, ENTROPY_SOURCES ) {
|
||||
if ( ( rc = entropy_enable_and_test ( *source ) ) == 0 )
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBGC ( *source, "ENTROPY has no working sources: %s\n",
|
||||
strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable entropy gathering
|
||||
*
|
||||
* @v source Entropy source
|
||||
*/
|
||||
void entropy_disable ( struct entropy_source *source ) {
|
||||
|
||||
/* Disable entropy gathering, if applicable */
|
||||
if ( source->disable )
|
||||
source->disable();
|
||||
|
||||
DBGC ( source, "ENTROPY %s disabled\n", source->name );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,7 +411,7 @@ static uint32_t make_next_nonce ( void ) {
|
||||
/**
|
||||
* Obtain entropy input temporary buffer
|
||||
*
|
||||
* @v num_samples Number of entropy samples
|
||||
* @v min_entropy Min-entropy required
|
||||
* @v tmp Temporary buffer
|
||||
* @v tmp_len Length of temporary buffer
|
||||
* @ret rc Return status code
|
||||
@ -412,47 +421,41 @@ static uint32_t make_next_nonce ( void ) {
|
||||
* and condensing each entropy source output after each GetEntropy
|
||||
* call) as defined in ANS X9.82 Part 4 (April 2011 Draft) Section
|
||||
* 13.3.4.2.
|
||||
*
|
||||
* To minimise code size, the number of samples required is calculated
|
||||
* at compilation time.
|
||||
*/
|
||||
int get_entropy_input_tmp ( unsigned int num_samples, uint8_t *tmp,
|
||||
int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
|
||||
size_t tmp_len ) {
|
||||
static unsigned int startup_tested = 0;
|
||||
struct entropy_source *source;
|
||||
struct {
|
||||
uint32_t nonce;
|
||||
entropy_sample_t sample;
|
||||
} __attribute__ (( packed )) data;;
|
||||
uint8_t df_buf[tmp_len];
|
||||
min_entropy_t entropy_total;
|
||||
unsigned int num_samples;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
/* Enable entropy gathering */
|
||||
if ( ( rc = entropy_enable() ) != 0 )
|
||||
return rc;
|
||||
if ( ( rc = entropy_enable_working ( &source ) ) != 0 )
|
||||
goto err_enable_working;
|
||||
|
||||
/* Perform mandatory startup tests, if not yet performed */
|
||||
for ( ; startup_tested < startup_test_count() ; startup_tested++ ) {
|
||||
if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
|
||||
goto err_get_entropy;
|
||||
}
|
||||
/* Sanity checks */
|
||||
assert ( source->startup_test.count > 0 );
|
||||
assert ( source->startup_test.tested >= source->startup_test.count );
|
||||
|
||||
/* 3. entropy_total = 0
|
||||
*
|
||||
* (Nothing to do; the number of entropy samples required has
|
||||
* already been precalculated.)
|
||||
*/
|
||||
/* 3. entropy_total = 0 */
|
||||
entropy_total = MIN_ENTROPY ( 0 );
|
||||
|
||||
/* 4. tmp = a fixed n-bit value, such as 0^n */
|
||||
memset ( tmp, 0, tmp_len );
|
||||
|
||||
/* 5. While ( entropy_total < min_entropy ) */
|
||||
while ( num_samples-- ) {
|
||||
for ( num_samples = 0 ; entropy_total < min_entropy ; num_samples++ ) {
|
||||
/* 5.1. ( status, entropy_bitstring, assessed_entropy )
|
||||
* = GetEntropy()
|
||||
* 5.2. If status indicates an error, return ( status, Null )
|
||||
*/
|
||||
if ( ( rc = get_entropy ( &data.sample ) ) != 0 )
|
||||
if ( ( rc = get_entropy ( source, &data.sample ) ) != 0 )
|
||||
goto err_get_entropy;
|
||||
|
||||
/* 5.3. nonce = MakeNextNonce() */
|
||||
@ -466,19 +469,26 @@ int get_entropy_input_tmp ( unsigned int num_samples, uint8_t *tmp,
|
||||
for ( i = 0 ; i < tmp_len ; i++ )
|
||||
tmp[i] ^= df_buf[i];
|
||||
|
||||
/* 5.5. entropy_total = entropy_total + assessed_entropy
|
||||
*
|
||||
* (Nothing to do; the number of entropy samples
|
||||
* required has already been precalculated.)
|
||||
*/
|
||||
/* 5.5. entropy_total = entropy_total + assessed_entropy */
|
||||
entropy_total += source->min_entropy_per_sample;
|
||||
}
|
||||
|
||||
/* Disable entropy gathering */
|
||||
entropy_disable();
|
||||
entropy_disable ( source );
|
||||
|
||||
DBGC ( source, "ENTROPY %s gathered %d bits in %d samples\n",
|
||||
source->name, ( min_entropy / MIN_ENTROPY_SCALE ), num_samples );
|
||||
return 0;
|
||||
|
||||
err_get_entropy:
|
||||
entropy_disable();
|
||||
entropy_disable ( source );
|
||||
assert ( source->rc == rc );
|
||||
err_enable_working:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Drag in objects via entropy_enable */
|
||||
REQUIRING_SYMBOL ( entropy_enable );
|
||||
|
||||
/* Drag in entropy configuration */
|
||||
REQUIRE_OBJECT ( config_entropy );
|
||||
|
||||
@ -609,6 +609,7 @@ static void scsicmd_read_capacity_cmd ( struct scsi_command *scsicmd,
|
||||
*/
|
||||
static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
|
||||
int rc ) {
|
||||
struct scsi_device *scsidev = scsicmd->scsidev;
|
||||
struct scsi_read_capacity_private *priv = scsicmd_priv ( scsicmd );
|
||||
struct scsi_capacity_16 *capacity16 = &priv->capacity.capacity16;
|
||||
struct scsi_capacity_10 *capacity10 = &priv->capacity.capacity10;
|
||||
@ -645,6 +646,9 @@ static void scsicmd_read_capacity_done ( struct scsi_command *scsicmd,
|
||||
}
|
||||
capacity.max_count = -1U;
|
||||
|
||||
/* Allow transport layer to update capacity */
|
||||
block_capacity ( &scsidev->scsi, &capacity );
|
||||
|
||||
/* Return capacity to caller */
|
||||
block_capacity ( &scsicmd->block, &capacity );
|
||||
|
||||
|
||||
@ -98,8 +98,16 @@ static void eisa_remove ( struct eisa_device *eisa ) {
|
||||
static int eisabus_probe ( struct root_device *rootdev ) {
|
||||
struct eisa_device *eisa = NULL;
|
||||
unsigned int slot;
|
||||
uint8_t system;
|
||||
int rc;
|
||||
|
||||
/* Check for EISA system board */
|
||||
system = inb ( EISA_VENDOR_ID );
|
||||
if ( system & 0x80 ) {
|
||||
DBG ( "No EISA system board (read %02x)\n", system );
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for ( slot = EISA_MIN_SLOT ; slot <= EISA_MAX_SLOT ; slot++ ) {
|
||||
/* Allocate struct eisa_device */
|
||||
if ( ! eisa )
|
||||
|
||||
@ -205,6 +205,7 @@ int pci_read_config ( struct pci_device *pci ) {
|
||||
pci_read_config_dword ( pci, PCI_REVISION, &tmp );
|
||||
pci->class = ( tmp >> 8 );
|
||||
pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
|
||||
pci_read_config_byte ( pci, PCI_HEADER_TYPE, &pci->hdrtype );
|
||||
pci_read_bases ( pci );
|
||||
|
||||
/* Initialise generic device component */
|
||||
|
||||
@ -1067,11 +1067,15 @@ static void realtek_detect ( struct realtek_nic *rtl ) {
|
||||
* Note that enabling DAC seems to cause bizarre behaviour
|
||||
* (lockups, garbage data on the wire) on some systems, even
|
||||
* if only 32-bit addresses are used.
|
||||
*
|
||||
* Disable VLAN offload, since some cards seem to have it
|
||||
* enabled by default.
|
||||
*/
|
||||
cpcr = readw ( rtl->regs + RTL_CPCR );
|
||||
cpcr |= ( RTL_CPCR_MULRW | RTL_CPCR_CPRX | RTL_CPCR_CPTX );
|
||||
if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) )
|
||||
cpcr |= RTL_CPCR_DAC;
|
||||
cpcr &= ~RTL_CPCR_VLAN;
|
||||
writew ( cpcr, rtl->regs + RTL_CPCR );
|
||||
check_cpcr = readw ( rtl->regs + RTL_CPCR );
|
||||
|
||||
|
||||
@ -228,8 +228,9 @@ enum realtek_legacy_status {
|
||||
|
||||
/** C+ Command Register (word) */
|
||||
#define RTL_CPCR 0xe0
|
||||
#define RTL_CPCR_DAC 0x0010 /**< PCI Dual Address Cycle Enable */
|
||||
#define RTL_CPCR_MULRW 0x0008 /**< PCI Multiple Read/Write Enable */
|
||||
#define RTL_CPCR_VLAN 0x0040 /**< VLAN tag stripping enable */
|
||||
#define RTL_CPCR_DAC 0x0010 /**< PCI Dual Address Cycle enable */
|
||||
#define RTL_CPCR_MULRW 0x0008 /**< PCI Multiple Read/Write enable */
|
||||
#define RTL_CPCR_CPRX 0x0002 /**< C+ receive enable */
|
||||
#define RTL_CPCR_CPTX 0x0001 /**< C+ transmit enable */
|
||||
|
||||
|
||||
@ -25,7 +25,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Form parameter commands
|
||||
* Request parameter commands
|
||||
*
|
||||
*/
|
||||
|
||||
@ -90,12 +90,16 @@ static int params_exec ( int argc, char **argv ) {
|
||||
struct param_options {
|
||||
/** Parameter list name */
|
||||
char *params;
|
||||
/** Parameter is a header */
|
||||
int header;
|
||||
};
|
||||
|
||||
/** "param" option list */
|
||||
static struct option_descriptor param_opts[] = {
|
||||
OPTION_DESC ( "params", 'p', required_argument,
|
||||
struct param_options, params, parse_string ),
|
||||
OPTION_DESC ( "header", 'H', no_argument,
|
||||
struct param_options, header, parse_flag ),
|
||||
};
|
||||
|
||||
/** "param" command descriptor */
|
||||
@ -114,6 +118,7 @@ static int param_exec ( int argc, char **argv ) {
|
||||
struct param_options opts;
|
||||
char *key;
|
||||
char *value;
|
||||
unsigned int flags;
|
||||
struct parameters *params;
|
||||
struct parameter *param;
|
||||
int rc;
|
||||
@ -132,12 +137,15 @@ static int param_exec ( int argc, char **argv ) {
|
||||
goto err_parse_value;
|
||||
}
|
||||
|
||||
/* Construct flags */
|
||||
flags = ( opts.header ? PARAMETER_HEADER : PARAMETER_FORM );
|
||||
|
||||
/* Identify parameter list */
|
||||
if ( ( rc = parse_parameters ( opts.params, ¶ms ) ) != 0 )
|
||||
goto err_parse_parameters;
|
||||
|
||||
/* Add parameter */
|
||||
param = add_parameter ( params, key, value );
|
||||
param = add_parameter ( params, key, value, flags );
|
||||
if ( ! param ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_add_parameter;
|
||||
@ -154,7 +162,7 @@ static int param_exec ( int argc, char **argv ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/** Form parameter commands */
|
||||
/** Request parameter commands */
|
||||
struct command param_commands[] __command = {
|
||||
{
|
||||
.name = "params",
|
||||
|
||||
@ -262,10 +262,10 @@ static inline void eplatform_discard ( int dummy __unused, ... ) {}
|
||||
".balign 8\n\t" \
|
||||
"\n1:\n\t" \
|
||||
".long ( 4f - 1b )\n\t" \
|
||||
".long %c0\n\t" \
|
||||
".long %" ASM_NO_PREFIX "0\n\t" \
|
||||
".long ( 2f - 1b )\n\t" \
|
||||
".long ( 3f - 1b )\n\t" \
|
||||
".long %c1\n\t" \
|
||||
".long %" ASM_NO_PREFIX "1\n\t" \
|
||||
"\n2:\t.asciz \"" __einfo_desc ( einfo ) "\"\n\t" \
|
||||
"\n3:\t.asciz \"" __FILE__ "\"\n\t" \
|
||||
".balign 8\n\t" \
|
||||
|
||||
188
src/include/ipxe/efi/Guid/GlobalVariable.h
Normal file
188
src/include/ipxe/efi/Guid/GlobalVariable.h
Normal file
@ -0,0 +1,188 @@
|
||||
/** @file
|
||||
GUID for EFI (NVRAM) Variables.
|
||||
|
||||
Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Revision Reference:
|
||||
GUID defined in UEFI 2.1
|
||||
**/
|
||||
|
||||
#ifndef __GLOBAL_VARIABLE_GUID_H__
|
||||
#define __GLOBAL_VARIABLE_GUID_H__
|
||||
|
||||
FILE_LICENCE ( BSD2_PATENT );
|
||||
|
||||
#define EFI_GLOBAL_VARIABLE \
|
||||
{ \
|
||||
0x8BE4DF61, 0x93CA, 0x11d2, {0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C } \
|
||||
}
|
||||
|
||||
extern EFI_GUID gEfiGlobalVariableGuid;
|
||||
|
||||
//
|
||||
// Follow UEFI 2.4 spec:
|
||||
// To prevent name collisions with possible future globally defined variables,
|
||||
// other internal firmware data variables that are not defined here must be
|
||||
// saved with a unique VendorGuid other than EFI_GLOBAL_VARIABLE or
|
||||
// any other GUID defined by the UEFI Specification. Implementations must
|
||||
// only permit the creation of variables with a UEFI Specification-defined
|
||||
// VendorGuid when these variables are documented in the UEFI Specification.
|
||||
//
|
||||
// Note: except the globally defined variables defined below, the spec also defines
|
||||
// L"Boot####" - A boot load option.
|
||||
// L"Driver####" - A driver load option.
|
||||
// L"SysPrep####" - A System Prep application load option.
|
||||
// L"Key####" - Describes hot key relationship with a Boot#### load option.
|
||||
// The attribute for them is NV+BS+RT, #### is a printed hex value, and no 0x or h
|
||||
// is included in the hex value. They can not be expressed as a #define like other globally
|
||||
// defined variables, it is because we can not list the Boot0000, Boot0001, etc one by one.
|
||||
//
|
||||
|
||||
///
|
||||
/// The language codes that the firmware supports. This value is deprecated.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_LANG_CODES_VARIABLE_NAME L"LangCodes"
|
||||
///
|
||||
/// The language code that the system is configured for. This value is deprecated.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_LANG_VARIABLE_NAME L"Lang"
|
||||
///
|
||||
/// The firmware's boot managers timeout, in seconds, before initiating the default boot selection.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_TIME_OUT_VARIABLE_NAME L"Timeout"
|
||||
///
|
||||
/// The language codes that the firmware supports.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_PLATFORM_LANG_CODES_VARIABLE_NAME L"PlatformLangCodes"
|
||||
///
|
||||
/// The language code that the system is configured for.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_PLATFORM_LANG_VARIABLE_NAME L"PlatformLang"
|
||||
///
|
||||
/// The device path of the default input/output/error output console.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_CON_IN_VARIABLE_NAME L"ConIn"
|
||||
#define EFI_CON_OUT_VARIABLE_NAME L"ConOut"
|
||||
#define EFI_ERR_OUT_VARIABLE_NAME L"ErrOut"
|
||||
///
|
||||
/// The device path of all possible input/output/error output devices.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_CON_IN_DEV_VARIABLE_NAME L"ConInDev"
|
||||
#define EFI_CON_OUT_DEV_VARIABLE_NAME L"ConOutDev"
|
||||
#define EFI_ERR_OUT_DEV_VARIABLE_NAME L"ErrOutDev"
|
||||
///
|
||||
/// The ordered boot option load list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_ORDER_VARIABLE_NAME L"BootOrder"
|
||||
///
|
||||
/// The boot option for the next boot only.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_NEXT_VARIABLE_NAME L"BootNext"
|
||||
///
|
||||
/// The boot option that was selected for the current boot.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_CURRENT_VARIABLE_NAME L"BootCurrent"
|
||||
///
|
||||
/// The types of boot options supported by the boot manager. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_BOOT_OPTION_SUPPORT_VARIABLE_NAME L"BootOptionSupport"
|
||||
///
|
||||
/// The ordered driver load option list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_DRIVER_ORDER_VARIABLE_NAME L"DriverOrder"
|
||||
///
|
||||
/// The ordered System Prep Application load option list.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_SYS_PREP_ORDER_VARIABLE_NAME L"SysPrepOrder"
|
||||
///
|
||||
/// Identifies the level of hardware error record persistence
|
||||
/// support implemented by the platform. This variable is
|
||||
/// only modified by firmware and is read-only to the OS.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_HW_ERR_REC_SUPPORT_VARIABLE_NAME L"HwErrRecSupport"
|
||||
///
|
||||
/// Whether the system is operating in setup mode (1) or not (0).
|
||||
/// All other values are reserved. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SETUP_MODE_NAME L"SetupMode"
|
||||
///
|
||||
/// The Key Exchange Key Signature Database.
|
||||
/// Its attribute is NV+BS+RT+AT.
|
||||
///
|
||||
#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
|
||||
///
|
||||
/// The public Platform Key.
|
||||
/// Its attribute is NV+BS+RT+AT.
|
||||
///
|
||||
#define EFI_PLATFORM_KEY_NAME L"PK"
|
||||
///
|
||||
/// Array of GUIDs representing the type of signatures supported
|
||||
/// by the platform firmware. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SIGNATURE_SUPPORT_NAME L"SignatureSupport"
|
||||
///
|
||||
/// Whether the platform firmware is operating in Secure boot mode (1) or not (0).
|
||||
/// All other values are reserved. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_SECURE_BOOT_MODE_NAME L"SecureBoot"
|
||||
///
|
||||
/// The OEM's default Key Exchange Key Signature Database. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_KEK_DEFAULT_VARIABLE_NAME L"KEKDefault"
|
||||
///
|
||||
/// The OEM's default public Platform Key. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_PK_DEFAULT_VARIABLE_NAME L"PKDefault"
|
||||
///
|
||||
/// The OEM's default secure boot signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DB_DEFAULT_VARIABLE_NAME L"dbDefault"
|
||||
///
|
||||
/// The OEM's default secure boot blacklist signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DBX_DEFAULT_VARIABLE_NAME L"dbxDefault"
|
||||
///
|
||||
/// The OEM's default secure boot timestamp signature store. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_DBT_DEFAULT_VARIABLE_NAME L"dbtDefault"
|
||||
///
|
||||
/// Allows the firmware to indicate supported features and actions to the OS.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_OS_INDICATIONS_SUPPORT_VARIABLE_NAME L"OsIndicationsSupported"
|
||||
///
|
||||
/// Allows the OS to request the firmware to enable certain features and to take certain actions.
|
||||
/// Its attribute is NV+BS+RT.
|
||||
///
|
||||
#define EFI_OS_INDICATIONS_VARIABLE_NAME L"OsIndications"
|
||||
///
|
||||
/// Whether the system is configured to use only vendor provided
|
||||
/// keys or not. Should be treated as read-only.
|
||||
/// Its attribute is BS+RT.
|
||||
///
|
||||
#define EFI_VENDOR_KEYS_VARIABLE_NAME L"VendorKeys"
|
||||
|
||||
#endif
|
||||
@ -30,17 +30,17 @@ FILE_LICENCE ( BSD2_PATENT );
|
||||
// Assume standard LoongArch 64-bit alignment.
|
||||
// Need to check portability of long long
|
||||
//
|
||||
typedef unsigned long UINT64;
|
||||
typedef long INT64;
|
||||
typedef unsigned int UINT32;
|
||||
typedef int INT32;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned short CHAR16;
|
||||
typedef short INT16;
|
||||
typedef unsigned char BOOLEAN;
|
||||
typedef unsigned char UINT8;
|
||||
typedef char CHAR8;
|
||||
typedef char INT8;
|
||||
typedef unsigned long long UINT64;
|
||||
typedef long long INT64;
|
||||
typedef unsigned int UINT32;
|
||||
typedef int INT32;
|
||||
typedef unsigned short UINT16;
|
||||
typedef unsigned short CHAR16;
|
||||
typedef short INT16;
|
||||
typedef unsigned char BOOLEAN;
|
||||
typedef unsigned char UINT8;
|
||||
typedef char CHAR8;
|
||||
typedef char INT8;
|
||||
|
||||
//
|
||||
// Unsigned value of native width. (4 bytes on supported 32-bit processor instructions,
|
||||
|
||||
@ -66,7 +66,7 @@ typedef enum {
|
||||
// /// EfiGcdMemoryTypeUnaccepted is defined in PrePiDxeCis.h because it has not been
|
||||
// /// defined in PI spec.
|
||||
// EfiGcdMemoryTypeUnaccepted,
|
||||
EfiGcdMemoryTypeMaximum = 8
|
||||
EfiGcdMemoryTypeMaximum = 7
|
||||
} EFI_GCD_MEMORY_TYPE;
|
||||
|
||||
///
|
||||
|
||||
@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
||||
extern int efi_autoexec_load ( EFI_HANDLE device );
|
||||
extern int efi_autoexec_load ( EFI_HANDLE device,
|
||||
EFI_DEVICE_PATH_PROTOCOL *path );
|
||||
|
||||
#endif /* _IPXE_EFI_AUTOEXEC_H */
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
#ifndef _IPXE_EFI_ENTROPY_H
|
||||
#define _IPXE_EFI_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* EFI entropy source
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ENTROPY_EFI
|
||||
#define ENTROPY_PREFIX_efi
|
||||
#else
|
||||
#define ENTROPY_PREFIX_efi __efi_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* min-entropy per sample
|
||||
*
|
||||
* @ret min_entropy min-entropy of each sample
|
||||
*/
|
||||
static inline __always_inline min_entropy_t
|
||||
ENTROPY_INLINE ( efi, min_entropy_per_sample ) ( void ) {
|
||||
|
||||
/* We use essentially the same mechanism as for the BIOS
|
||||
* RTC-based entropy source, and so assume the same
|
||||
* min-entropy per sample.
|
||||
*/
|
||||
return MIN_ENTROPY ( 1.3 );
|
||||
}
|
||||
|
||||
#endif /* _IPXE_EFI_ENTROPY_H */
|
||||
@ -12,40 +12,11 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <ipxe/api.h>
|
||||
#include <ipxe/hash_df.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tables.h>
|
||||
#include <config/entropy.h>
|
||||
|
||||
/**
|
||||
* Calculate static inline entropy API function name
|
||||
*
|
||||
* @v _prefix Subsystem prefix
|
||||
* @v _api_func API function
|
||||
* @ret _subsys_func Subsystem API function
|
||||
*/
|
||||
#define ENTROPY_INLINE( _subsys, _api_func ) \
|
||||
SINGLE_API_INLINE ( ENTROPY_PREFIX_ ## _subsys, _api_func )
|
||||
|
||||
/**
|
||||
* Provide a entropy API implementation
|
||||
*
|
||||
* @v _prefix Subsystem prefix
|
||||
* @v _api_func API function
|
||||
* @v _func Implementing function
|
||||
*/
|
||||
#define PROVIDE_ENTROPY( _subsys, _api_func, _func ) \
|
||||
PROVIDE_SINGLE_API ( ENTROPY_PREFIX_ ## _subsys, _api_func, _func )
|
||||
|
||||
/**
|
||||
* Provide a static inline entropy API implementation
|
||||
*
|
||||
* @v _prefix Subsystem prefix
|
||||
* @v _api_func API function
|
||||
*/
|
||||
#define PROVIDE_ENTROPY_INLINE( _subsys, _api_func ) \
|
||||
PROVIDE_SINGLE_API_INLINE ( ENTROPY_PREFIX_ ## _subsys, _api_func )
|
||||
|
||||
/** A noise sample */
|
||||
typedef uint8_t noise_sample_t;
|
||||
|
||||
@ -71,56 +42,148 @@ typedef unsigned int min_entropy_t;
|
||||
#define MIN_ENTROPY( bits ) \
|
||||
( ( min_entropy_t ) ( (bits) * MIN_ENTROPY_SCALE ) )
|
||||
|
||||
/* Include all architecture-independent entropy API headers */
|
||||
#include <ipxe/null_entropy.h>
|
||||
#include <ipxe/efi/efi_entropy.h>
|
||||
#include <ipxe/linux/linux_entropy.h>
|
||||
|
||||
/* Include all architecture-dependent entropy API headers */
|
||||
#include <bits/entropy.h>
|
||||
/**
|
||||
* Repetition count test state
|
||||
*
|
||||
* This is the state for the repetition Count Test defined in ANS
|
||||
* X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
|
||||
*/
|
||||
struct entropy_repetition_count_test {
|
||||
/**
|
||||
* A = the most recently seen sample value
|
||||
*/
|
||||
noise_sample_t most_recent_sample;
|
||||
/**
|
||||
* B = the number of times that value A has been seen in a row
|
||||
*/
|
||||
unsigned int repetition_count;
|
||||
/**
|
||||
* C = the cutoff value above which the repetition test should fail
|
||||
*
|
||||
* Filled in by entropy_init().
|
||||
*/
|
||||
unsigned int cutoff;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enable entropy gathering
|
||||
* Adaptive proportion test state
|
||||
*
|
||||
* @ret rc Return status code
|
||||
* This is the state for the Adaptive Proportion Test for the Most
|
||||
* Common Value defined in ANS X9.82 Part 2 (October 2011 Draft)
|
||||
* Section 8.5.2.1.3.
|
||||
*/
|
||||
int entropy_enable ( void );
|
||||
struct entropy_adaptive_proportion_test {
|
||||
/**
|
||||
* A = the sample value currently being counted
|
||||
*/
|
||||
noise_sample_t current_counted_sample;
|
||||
/**
|
||||
* S = the number of samples examined in this run of the test so far
|
||||
*/
|
||||
unsigned int sample_count;
|
||||
/**
|
||||
* B = the current number of times that S (sic) has been seen
|
||||
* in the W (sic) samples examined so far
|
||||
*/
|
||||
unsigned int repetition_count;
|
||||
/**
|
||||
* C = the cutoff value above which the repetition test should fail
|
||||
*
|
||||
* Filled in by entropy_init().
|
||||
*/
|
||||
unsigned int cutoff;
|
||||
};
|
||||
|
||||
/**
|
||||
* Disable entropy gathering
|
||||
* Startup test state
|
||||
*
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
|
||||
* that at least one full cycle of the continuous tests must be
|
||||
* performed at start-up.
|
||||
*/
|
||||
void entropy_disable ( void );
|
||||
struct entropy_startup_test {
|
||||
/** Number of startup tests performed */
|
||||
unsigned int tested;
|
||||
/**
|
||||
* Number of startup tests required for one full cycle
|
||||
*
|
||||
* Filled in by entropy_init().
|
||||
*/
|
||||
unsigned int count;
|
||||
};
|
||||
|
||||
/**
|
||||
* min-entropy per sample
|
||||
/** An entropy source */
|
||||
struct entropy_source {
|
||||
/** Name */
|
||||
const char *name;
|
||||
/**
|
||||
* min-entropy per sample
|
||||
*
|
||||
* min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
|
||||
* NIST SP 800-90 Appendix C.3 as
|
||||
*
|
||||
* H_min = -log2 ( p_max )
|
||||
*
|
||||
* where p_max is the probability of the most likely sample value.
|
||||
*
|
||||
* Filled in by entropy_init().
|
||||
*/
|
||||
min_entropy_t min_entropy_per_sample;
|
||||
/** Repetition count test state */
|
||||
struct entropy_repetition_count_test repetition_count_test;
|
||||
/** Adaptive proportion test state */
|
||||
struct entropy_adaptive_proportion_test adaptive_proportion_test;
|
||||
/** Startup test state */
|
||||
struct entropy_startup_test startup_test;
|
||||
/**
|
||||
* Failure status (if any)
|
||||
*
|
||||
* Any failure of an entropy source is regarded as permanent.
|
||||
*/
|
||||
int rc;
|
||||
|
||||
/**
|
||||
* Enable entropy gathering
|
||||
*
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * enable ) ( void );
|
||||
/**
|
||||
* Disable entropy gathering
|
||||
*
|
||||
*/
|
||||
void ( * disable ) ( void );
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the GetNoise function defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 6.5.2.
|
||||
*/
|
||||
int ( * get_noise ) ( noise_sample_t *noise );
|
||||
};
|
||||
|
||||
/** Entropy source table */
|
||||
#define ENTROPY_SOURCES __table ( struct entropy_source, "entropy_sources" )
|
||||
|
||||
/** Declare an entropy source */
|
||||
#define __entropy_source( order ) __table_entry ( ENTROPY_SOURCES, order )
|
||||
|
||||
/** @defgroup entropy_source_order Entropy source order
|
||||
*
|
||||
* @ret min_entropy min-entropy of each sample
|
||||
*
|
||||
* min-entropy is defined in ANS X9.82 Part 1-2006 Section 8.3 and in
|
||||
* NIST SP 800-90 Appendix C.3 as
|
||||
*
|
||||
* H_min = -log2 ( p_max )
|
||||
*
|
||||
* where p_max is the probability of the most likely sample value.
|
||||
*
|
||||
* This must be a compile-time constant.
|
||||
* @{
|
||||
*/
|
||||
min_entropy_t min_entropy_per_sample ( void );
|
||||
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the GetNoise function defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 6.5.2.
|
||||
*/
|
||||
int get_noise ( noise_sample_t *noise );
|
||||
#define ENTROPY_PREFERRED 01 /**< Preferred entropy source */
|
||||
#define ENTROPY_NORMAL 02 /**< Normal entropy source */
|
||||
#define ENTROPY_FALLBACK 03 /**< Fallback entropy source */
|
||||
|
||||
extern int get_entropy_input_tmp ( unsigned int num_samples,
|
||||
uint8_t *tmp, size_t tmp_len );
|
||||
/** @} */
|
||||
|
||||
extern int get_entropy_input_tmp ( min_entropy_t min_entropy, uint8_t *tmp,
|
||||
size_t tmp_len );
|
||||
|
||||
/** Use SHA-256 as the underlying hash algorithm for Hash_df
|
||||
*
|
||||
@ -131,6 +194,22 @@ extern int get_entropy_input_tmp ( unsigned int num_samples,
|
||||
/** Underlying hash algorithm output length (in bytes) */
|
||||
#define ENTROPY_HASH_DF_OUTLEN_BYTES SHA256_DIGEST_SIZE
|
||||
|
||||
/**
|
||||
* Get noise sample
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @ret noise Noise sample
|
||||
* @ret rc Return status code
|
||||
*
|
||||
* This is the GetNoise function defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 6.5.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
get_noise ( struct entropy_source *source, noise_sample_t *noise ) {
|
||||
|
||||
return source->get_noise ( noise );
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtain entropy input
|
||||
*
|
||||
@ -145,8 +224,8 @@ extern int get_entropy_input_tmp ( unsigned int num_samples,
|
||||
* each entropy source output after each GetEntropy call) as defined
|
||||
* in ANS X9.82 Part 4 (April 2011 Draft) Section 13.3.4.2.
|
||||
*
|
||||
* To minimise code size, the number of samples required is calculated
|
||||
* at compilation time.
|
||||
* This function is inlined since the entropy amount and length inputs
|
||||
* are always compile-time constants.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) int
|
||||
get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
|
||||
@ -154,41 +233,16 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
|
||||
size_t tmp_len = ( ( ( min_entropy_bits * 2 ) + 7 ) / 8 );
|
||||
uint8_t tmp_buf[ tmp_len ];
|
||||
uint8_t *tmp = ( ( tmp_len > max_len ) ? tmp_buf : data );
|
||||
double min_samples;
|
||||
unsigned int num_samples;
|
||||
unsigned int n;
|
||||
int rc;
|
||||
|
||||
/* Sanity checks */
|
||||
linker_assert ( ( min_entropy_per_sample() <=
|
||||
MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
|
||||
min_entropy_per_sample_is_impossibly_high );
|
||||
/* Sanity check */
|
||||
linker_assert ( ( min_entropy_bits <= ( 8 * max_len ) ),
|
||||
entropy_buffer_too_small );
|
||||
|
||||
/* Round up minimum entropy to an integral number of bytes */
|
||||
min_entropy_bits = ( ( min_entropy_bits + 7 ) & ~7 );
|
||||
|
||||
/* Calculate number of samples required to contain sufficient entropy */
|
||||
min_samples = ( MIN_ENTROPY ( min_entropy_bits ) /
|
||||
min_entropy_per_sample() );
|
||||
|
||||
/* Round up to a whole number of samples. We don't have the
|
||||
* ceil() function available, so do the rounding by hand.
|
||||
*/
|
||||
num_samples = min_samples;
|
||||
if ( num_samples < min_samples )
|
||||
num_samples++;
|
||||
linker_assert ( ( num_samples >= min_samples ), rounding_error );
|
||||
|
||||
/* Floating-point operations are not allowed in iPXE since we
|
||||
* never set up a suitable environment. Abort the build
|
||||
* unless the calculated number of samples is a compile-time
|
||||
* constant.
|
||||
*/
|
||||
linker_assert ( __builtin_constant_p ( num_samples ),
|
||||
num_samples_not_constant );
|
||||
|
||||
/* (Unnumbered). The output length of the hash function shall
|
||||
* meet or exceed the security strength indicated by the
|
||||
* min_entropy parameter.
|
||||
@ -218,8 +272,10 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
|
||||
linker_assert ( __builtin_constant_p ( tmp_len ),
|
||||
tmp_len_not_constant );
|
||||
linker_assert ( ( n == ( 8 * tmp_len ) ), tmp_len_mismatch );
|
||||
if ( ( rc = get_entropy_input_tmp ( num_samples, tmp, tmp_len ) ) != 0 )
|
||||
if ( ( rc = get_entropy_input_tmp ( MIN_ENTROPY ( min_entropy_bits ),
|
||||
tmp, tmp_len ) ) != 0 ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* 6. If ( n < min_length ), then tmp = tmp || 0^(min_length-n)
|
||||
* 7. If ( n > max_length ), then tmp = df ( tmp, max_length )
|
||||
@ -242,4 +298,231 @@ get_entropy_input ( unsigned int min_entropy_bits, void *data, size_t min_len,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cutoff value for the repetition count test
|
||||
*
|
||||
* @v min_entropy_per_sample Min-entropy per sample
|
||||
* @ret cutoff Cutoff value
|
||||
*
|
||||
* This is the cutoff value for the Repetition Count Test defined in
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
entropy_repetition_count_cutoff ( min_entropy_t min_entropy_per_sample ) {
|
||||
double max_repetitions;
|
||||
unsigned int cutoff;
|
||||
|
||||
/* The cutoff formula for the repetition test is:
|
||||
*
|
||||
* C = ( 1 + ( -log2(W) / H_min ) )
|
||||
*
|
||||
* where W is set at 2^(-30) (in ANS X9.82 Part 2 (October
|
||||
* 2011 Draft) Section 8.5.2.1.3.1).
|
||||
*/
|
||||
max_repetitions = ( 1 + ( MIN_ENTROPY ( 30 ) /
|
||||
min_entropy_per_sample ) );
|
||||
|
||||
/* Round up to a whole number of repetitions. We don't have
|
||||
* the ceil() function available, so do the rounding by hand.
|
||||
*/
|
||||
cutoff = max_repetitions;
|
||||
if ( cutoff < max_repetitions )
|
||||
cutoff++;
|
||||
linker_assert ( ( cutoff >= max_repetitions ), rounding_error );
|
||||
|
||||
/* Floating-point operations are not allowed in iPXE since we
|
||||
* never set up a suitable environment. Abort the build
|
||||
* unless the calculated number of repetitions is a
|
||||
* compile-time constant.
|
||||
*/
|
||||
linker_assert ( __builtin_constant_p ( cutoff ),
|
||||
repetition_count_cutoff_not_constant );
|
||||
|
||||
return cutoff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Window size for the adaptive proportion test
|
||||
*
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.1 allows
|
||||
* five possible window sizes: 16, 64, 256, 4096 and 65536.
|
||||
*
|
||||
* We expect to generate relatively few (<256) entropy samples during
|
||||
* a typical iPXE run; the use of a large window size would mean that
|
||||
* the test would never complete a single cycle. We use a window size
|
||||
* of 64, which is the smallest window size that permits values of
|
||||
* H_min down to one bit per sample.
|
||||
*/
|
||||
#define ADAPTIVE_PROPORTION_WINDOW_SIZE 64
|
||||
|
||||
/**
|
||||
* Combine adaptive proportion test window size and min-entropy
|
||||
*
|
||||
* @v n N (window size)
|
||||
* @v h H (min-entropy)
|
||||
* @ret n_h (N,H) combined value
|
||||
*/
|
||||
#define APC_N_H( n, h ) ( ( (n) << 8 ) | (h) )
|
||||
|
||||
/**
|
||||
* Define a row of the adaptive proportion cutoff table
|
||||
*
|
||||
* @v h H (min-entropy)
|
||||
* @v c16 Cutoff for N=16
|
||||
* @v c64 Cutoff for N=64
|
||||
* @v c256 Cutoff for N=256
|
||||
* @v c4096 Cutoff for N=4096
|
||||
* @v c65536 Cutoff for N=65536
|
||||
*/
|
||||
#define APC_TABLE_ROW( h, c16, c64, c256, c4096, c65536) \
|
||||
case APC_N_H ( 16, h ) : return c16; \
|
||||
case APC_N_H ( 64, h ) : return c64; \
|
||||
case APC_N_H ( 256, h ) : return c256; \
|
||||
case APC_N_H ( 4096, h ) : return c4096; \
|
||||
case APC_N_H ( 65536, h ) : return c65536;
|
||||
|
||||
/** Value used to represent "N/A" in adaptive proportion cutoff table */
|
||||
#define APC_NA 0
|
||||
|
||||
/**
|
||||
* Look up value in adaptive proportion test cutoff table
|
||||
*
|
||||
* @v n N (window size)
|
||||
* @v h H (min-entropy)
|
||||
* @ret cutoff Cutoff
|
||||
*
|
||||
* This is the table of cutoff values defined in ANS X9.82 Part 2
|
||||
* (October 2011 Draft) Section 8.5.2.1.3.1.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
entropy_adaptive_proportion_cutoff_lookup ( unsigned int n, unsigned int h ) {
|
||||
switch ( APC_N_H ( n, h ) ) {
|
||||
APC_TABLE_ROW ( 1, APC_NA, 51, 168, 2240, 33537 );
|
||||
APC_TABLE_ROW ( 2, APC_NA, 35, 100, 1193, 17053 );
|
||||
APC_TABLE_ROW ( 3, 10, 24, 61, 643, 8705 );
|
||||
APC_TABLE_ROW ( 4, 8, 16, 38, 354, 4473 );
|
||||
APC_TABLE_ROW ( 5, 6, 12, 25, 200, 2321 );
|
||||
APC_TABLE_ROW ( 6, 5, 9, 17, 117, 1220 );
|
||||
APC_TABLE_ROW ( 7, 4, 7, 15, 71, 653 );
|
||||
APC_TABLE_ROW ( 8, 4, 5, 9, 45, 358 );
|
||||
APC_TABLE_ROW ( 9, 3, 4, 7, 30, 202 );
|
||||
APC_TABLE_ROW ( 10, 3, 4, 5, 21, 118 );
|
||||
APC_TABLE_ROW ( 11, 2, 3, 4, 15, 71 );
|
||||
APC_TABLE_ROW ( 12, 2, 3, 4, 11, 45 );
|
||||
APC_TABLE_ROW ( 13, 2, 2, 3, 9, 30 );
|
||||
APC_TABLE_ROW ( 14, 2, 2, 3, 7, 21 );
|
||||
APC_TABLE_ROW ( 15, 1, 2, 2, 6, 15 );
|
||||
APC_TABLE_ROW ( 16, 1, 2, 2, 5, 11 );
|
||||
APC_TABLE_ROW ( 17, 1, 1, 2, 4, 9 );
|
||||
APC_TABLE_ROW ( 18, 1, 1, 2, 4, 7 );
|
||||
APC_TABLE_ROW ( 19, 1, 1, 1, 3, 6 );
|
||||
APC_TABLE_ROW ( 20, 1, 1, 1, 3, 5 );
|
||||
default:
|
||||
return APC_NA;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate cutoff value for the adaptive proportion test
|
||||
*
|
||||
* @v min_entropy_per_sample Min-entropy per sample
|
||||
* @ret cutoff Cutoff value
|
||||
*
|
||||
* This is the cutoff value for the Adaptive Proportion Test defined
|
||||
* in ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.3.1.2.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
entropy_adaptive_proportion_cutoff ( min_entropy_t min_entropy_per_sample ) {
|
||||
unsigned int h;
|
||||
unsigned int n;
|
||||
unsigned int cutoff;
|
||||
|
||||
/* Look up cutoff value in cutoff table */
|
||||
n = ADAPTIVE_PROPORTION_WINDOW_SIZE;
|
||||
h = ( min_entropy_per_sample / MIN_ENTROPY_SCALE );
|
||||
cutoff = entropy_adaptive_proportion_cutoff_lookup ( n, h );
|
||||
|
||||
/* Fail unless cutoff value is a compile-time constant */
|
||||
linker_assert ( __builtin_constant_p ( cutoff ),
|
||||
adaptive_proportion_cutoff_not_constant );
|
||||
|
||||
/* Fail if cutoff value is N/A */
|
||||
linker_assert ( ( cutoff != APC_NA ),
|
||||
adaptive_proportion_cutoff_not_applicable );
|
||||
|
||||
return cutoff;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate number of samples required for startup tests
|
||||
*
|
||||
* @v repetition_count_cutoff Repetition count test cutoff value
|
||||
* @v adaptive_proportion_cutoff Adaptive proportion test cutoff value
|
||||
* @ret num_samples Number of samples required
|
||||
*
|
||||
* ANS X9.82 Part 2 (October 2011 Draft) Section 8.5.2.1.5 requires
|
||||
* that at least one full cycle of the continuous tests must be
|
||||
* performed at start-up.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) unsigned int
|
||||
entropy_startup_test_count ( unsigned int repetition_count_cutoff,
|
||||
unsigned int adaptive_proportion_cutoff ) {
|
||||
unsigned int num_samples;
|
||||
|
||||
/* At least max(N,C) samples shall be generated by the noise
|
||||
* source for start-up testing.
|
||||
*/
|
||||
num_samples = repetition_count_cutoff;
|
||||
if ( num_samples < adaptive_proportion_cutoff )
|
||||
num_samples = adaptive_proportion_cutoff;
|
||||
linker_assert ( __builtin_constant_p ( num_samples ),
|
||||
startup_test_count_not_constant );
|
||||
|
||||
return num_samples;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise entropy source
|
||||
*
|
||||
* @v source Entropy source
|
||||
* @v min_entropy_per_sample Min-entropy per sample
|
||||
*
|
||||
* The cutoff value calculations for the repetition count test and the
|
||||
* adaptive proportion test are provided as static inline functions
|
||||
* since the results will always be compile-time constants.
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
entropy_init ( struct entropy_source *source,
|
||||
min_entropy_t min_entropy_per_sample ) {
|
||||
unsigned int repetition_count_cutoff;
|
||||
unsigned int adaptive_proportion_cutoff;
|
||||
unsigned int startup_test_count;
|
||||
|
||||
/* Sanity check */
|
||||
linker_assert ( min_entropy_per_sample > MIN_ENTROPY ( 0 ),
|
||||
min_entropy_per_sample_is_zero );
|
||||
linker_assert ( ( min_entropy_per_sample <=
|
||||
MIN_ENTROPY ( 8 * sizeof ( noise_sample_t ) ) ),
|
||||
min_entropy_per_sample_is_impossibly_high );
|
||||
|
||||
/* Calculate test cutoff values */
|
||||
repetition_count_cutoff =
|
||||
entropy_repetition_count_cutoff ( min_entropy_per_sample );
|
||||
adaptive_proportion_cutoff =
|
||||
entropy_adaptive_proportion_cutoff ( min_entropy_per_sample );
|
||||
startup_test_count =
|
||||
entropy_startup_test_count ( repetition_count_cutoff,
|
||||
adaptive_proportion_cutoff );
|
||||
|
||||
/* Record min-entropy per sample and test cutoff values */
|
||||
source->min_entropy_per_sample = min_entropy_per_sample;
|
||||
source->repetition_count_test.cutoff = repetition_count_cutoff;
|
||||
source->adaptive_proportion_test.cutoff = adaptive_proportion_cutoff;
|
||||
source->startup_test.count = startup_test_count;
|
||||
}
|
||||
|
||||
extern int entropy_enable ( struct entropy_source *source );
|
||||
extern void entropy_disable ( struct entropy_source *source );
|
||||
extern int get_noise ( struct entropy_source *source, noise_sample_t *noise );
|
||||
|
||||
#endif /* _IPXE_ENTROPY_H */
|
||||
|
||||
@ -295,6 +295,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_ntp ( ERRFILE_NET | 0x00490000 )
|
||||
#define ERRFILE_httpntlm ( ERRFILE_NET | 0x004a0000 )
|
||||
#define ERRFILE_eap ( ERRFILE_NET | 0x004b0000 )
|
||||
#define ERRFILE_lldp ( ERRFILE_NET | 0x004c0000 )
|
||||
|
||||
#define ERRFILE_image ( ERRFILE_IMAGE | 0x00000000 )
|
||||
#define ERRFILE_elf ( ERRFILE_IMAGE | 0x00010000 )
|
||||
@ -402,6 +403,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_pci_cmd ( ERRFILE_OTHER | 0x00590000 )
|
||||
#define ERRFILE_dhe ( ERRFILE_OTHER | 0x005a0000 )
|
||||
#define ERRFILE_efi_cmdline ( ERRFILE_OTHER | 0x005b0000 )
|
||||
#define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 )
|
||||
#define ERRFILE_efi_settings ( ERRFILE_OTHER | 0x005d0000 )
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ETH_P_SLOW 0x8809 /* Ethernet slow protocols */
|
||||
#define ETH_P_EAPOL 0x888E /* 802.1X EAP over LANs */
|
||||
#define ETH_P_AOE 0x88A2 /* ATA over Ethernet */
|
||||
#define ETH_P_LLDP 0x88CC /* Link Layer Discovery Protocol */
|
||||
#define ETH_P_FCOE 0x8906 /* Fibre Channel over Ethernet */
|
||||
#define ETH_P_FIP 0x8914 /* FCoE Initialization Protocol */
|
||||
|
||||
|
||||
@ -195,6 +195,7 @@ extern struct image * image_find_selected ( void );
|
||||
extern int image_set_trust ( int require_trusted, int permanent );
|
||||
extern struct image * image_memory ( const char *name, userptr_t data,
|
||||
size_t len );
|
||||
extern const char * image_argument ( struct image *image, const char *key );
|
||||
extern int image_pixbuf ( struct image *image, struct pixel_buffer **pixbuf );
|
||||
extern int image_asn1 ( struct image *image, size_t offset,
|
||||
struct asn1_cursor **cursor );
|
||||
|
||||
@ -22,6 +22,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
/** Default iSCSI port */
|
||||
#define ISCSI_PORT 3260
|
||||
|
||||
/** Default iSCSI first burst length */
|
||||
#define ISCSI_FIRST_BURST_LEN 65536
|
||||
|
||||
/** Default iSCSI maximum burst length */
|
||||
#define ISCSI_MAX_BURST_LEN 262144
|
||||
|
||||
/** Default iSCSI maximum receive data segment length */
|
||||
#define ISCSI_MAX_RECV_DATA_SEG_LEN 8192
|
||||
|
||||
/**
|
||||
* iSCSI segment lengths
|
||||
*
|
||||
@ -577,6 +586,9 @@ struct iscsi_session {
|
||||
/** CHAP response (used for both initiator and target auth) */
|
||||
struct chap_response chap;
|
||||
|
||||
/** Maximum burst length */
|
||||
size_t max_burst_len;
|
||||
|
||||
/** Initiator session ID (IANA format) qualifier
|
||||
*
|
||||
* This is part of the ISID. It is generated randomly
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
#ifndef _IPXE_LINUX_ENTROPY_H
|
||||
#define _IPXE_LINUX_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* /dev/random-based entropy source
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#ifdef ENTROPY_LINUX
|
||||
#define ENTROPY_PREFIX_linux
|
||||
#else
|
||||
#define ENTROPY_PREFIX_linux __linux_
|
||||
#endif
|
||||
|
||||
/**
|
||||
* min-entropy per sample
|
||||
*
|
||||
* @ret min_entropy min-entropy of each sample
|
||||
*/
|
||||
static inline __always_inline min_entropy_t
|
||||
ENTROPY_INLINE ( linux, min_entropy_per_sample ) ( void ) {
|
||||
|
||||
/* linux_get_noise() reads a single byte from /dev/random,
|
||||
* which is supposed to block until a sufficient amount of
|
||||
* entropy is available. We therefore assume that each sample
|
||||
* contains exactly 8 bits of entropy.
|
||||
*/
|
||||
return MIN_ENTROPY ( 8.0 );
|
||||
}
|
||||
|
||||
#endif /* _IPXE_LINUX_ENTROPY_H */
|
||||
97
src/include/ipxe/lldp.h
Normal file
97
src/include/ipxe/lldp.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef _IPXE_LLDP_H
|
||||
#define _IPXE_LLDP_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Link Layer Discovery Protocol
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/** An LLDP TLV header */
|
||||
struct lldp_tlv {
|
||||
/** Type and length */
|
||||
uint16_t type_len;
|
||||
/** Data */
|
||||
uint8_t data[0];
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
/**
|
||||
* Extract LLDP TLV type
|
||||
*
|
||||
* @v type_len Type and length
|
||||
* @ret type Type
|
||||
*/
|
||||
#define LLDP_TLV_TYPE( type_len ) ( (type_len) >> 9 )
|
||||
|
||||
/**
|
||||
* Extract LLDP TLV length
|
||||
*
|
||||
* @v type_len Type and length
|
||||
* @ret len Length
|
||||
*/
|
||||
#define LLDP_TLV_LEN( type_len ) ( (type_len) & 0x01ff )
|
||||
|
||||
/** End of LLDP data unit */
|
||||
#define LLDP_TYPE_END 0x00
|
||||
|
||||
/** LLDP settings block name */
|
||||
#define LLDP_SETTINGS_NAME "lldp"
|
||||
|
||||
/**
|
||||
* Construct LLDP setting tag
|
||||
*
|
||||
* LLDP settings are encoded as
|
||||
*
|
||||
* ${netX.lldp/<prefix>.<type>.<index>.<offset>.<length>}
|
||||
*
|
||||
* where
|
||||
*
|
||||
* <type> is the TLV type
|
||||
*
|
||||
* <offset> is the starting offset within the TLV value
|
||||
*
|
||||
* <length> is the length (or zero to read the from <offset> to the end)
|
||||
*
|
||||
* <prefix>, if it has a non-zero value, is the subtype byte string
|
||||
* of length <offset> to match at the start of the TLV value, up to
|
||||
* a maximum matched length of 4 bytes
|
||||
*
|
||||
* <index> is the index of the entry matching <type> and <prefix> to
|
||||
* be accessed, with zero indicating the first matching entry
|
||||
*
|
||||
* The <prefix> is designed to accommodate both matching of the OUI
|
||||
* within an organization-specific TLV (e.g. 0x0080c2 for IEEE 802.1
|
||||
* TLVs) and of a subtype byte as found within many TLVs.
|
||||
*
|
||||
* This encoding allows most LLDP values to be extracted easily. For
|
||||
* example
|
||||
*
|
||||
* System name: ${netX.lldp/5.0.0.0:string}
|
||||
*
|
||||
* System description: ${netX.lldp/6.0.0.0:string}
|
||||
*
|
||||
* Port description: ${netX.lldp/4.0.0.0:string}
|
||||
*
|
||||
* Port interface name: ${netX.lldp/5.2.0.1.0:string}
|
||||
*
|
||||
* Chassis MAC address: ${netX.lldp/4.1.0.1.0:hex}
|
||||
*
|
||||
* Management IPv4 address: ${netX.lldp/5.1.8.0.2.4:ipv4}
|
||||
*
|
||||
* Port VLAN ID: ${netX.lldp/0x0080c2.1.127.0.4.2:int16}
|
||||
*
|
||||
* Port VLAN name: ${netX.lldp/0x0080c2.3.127.0.7.0:string}
|
||||
*
|
||||
* Maximum frame size: ${netX.lldp/0x00120f.4.127.0.4.2:uint16}
|
||||
*
|
||||
*/
|
||||
#define LLDP_TAG( prefix, type, index, offset, length ) \
|
||||
( ( ( ( uint64_t ) (prefix) ) << 32 ) | \
|
||||
( (type) << 24 ) | ( (index) << 16 ) | \
|
||||
( (offset) << 8 ) | ( (length) << 0 ) )
|
||||
|
||||
#endif /* _IPXE_LLDP_H */
|
||||
76
src/include/ipxe/nonxen.h
Normal file
76
src/include/ipxe/nonxen.h
Normal file
@ -0,0 +1,76 @@
|
||||
#ifndef _IPXE_NONXEN_H
|
||||
#define _IPXE_NONXEN_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Stub Xen definitions for platforms with no Xen support
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#define __XEN_GUEST_HANDLE(name) __guest_handle_ ## name
|
||||
|
||||
#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
|
||||
|
||||
#define ___DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
typedef type * __XEN_GUEST_HANDLE(name)
|
||||
|
||||
#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
___DEFINE_XEN_GUEST_HANDLE(name, type); \
|
||||
___DEFINE_XEN_GUEST_HANDLE(const_##name, const type)
|
||||
|
||||
#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
|
||||
|
||||
typedef unsigned long xen_pfn_t;
|
||||
|
||||
typedef unsigned long xen_ulong_t;
|
||||
|
||||
struct arch_vcpu_info {};
|
||||
|
||||
struct arch_shared_info {};
|
||||
|
||||
#define XEN_LEGACY_MAX_VCPUS 0
|
||||
|
||||
struct xen_hypervisor;
|
||||
|
||||
static inline __attribute__ (( always_inline )) unsigned long
|
||||
xen_hypercall_1 ( struct xen_hypervisor *xen __unused,
|
||||
unsigned int hypercall __unused,
|
||||
unsigned long arg1 __unused ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) unsigned long
|
||||
xen_hypercall_2 ( struct xen_hypervisor *xen __unused,
|
||||
unsigned int hypercall __unused,
|
||||
unsigned long arg1 __unused, unsigned long arg2 __unused ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) unsigned long
|
||||
xen_hypercall_3 ( struct xen_hypervisor *xen __unused,
|
||||
unsigned int hypercall __unused,
|
||||
unsigned long arg1 __unused, unsigned long arg2 __unused,
|
||||
unsigned long arg3 __unused ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) unsigned long
|
||||
xen_hypercall_4 ( struct xen_hypervisor *xen __unused,
|
||||
unsigned int hypercall __unused,
|
||||
unsigned long arg1 __unused, unsigned long arg2 __unused,
|
||||
unsigned long arg3 __unused, unsigned long arg4 __unused ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline __attribute__ (( always_inline )) unsigned long
|
||||
xen_hypercall_5 ( struct xen_hypervisor *xen __unused,
|
||||
unsigned int hypercall __unused,
|
||||
unsigned long arg1 __unused, unsigned long arg2 __unused,
|
||||
unsigned long arg3 __unused, unsigned long arg4 __unused,
|
||||
unsigned long arg5 __unused ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* _IPXE_NONXEN_H */
|
||||
@ -1,52 +0,0 @@
|
||||
#ifndef _IPXE_NULL_ENTROPY_H
|
||||
#define _IPXE_NULL_ENTROPY_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Nonexistent entropy source
|
||||
*
|
||||
* This source provides no entropy and must NOT be used in a
|
||||
* security-sensitive environment.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef ENTROPY_NULL
|
||||
#define ENTROPY_PREFIX_null
|
||||
#else
|
||||
#define ENTROPY_PREFIX_null __null_
|
||||
#endif
|
||||
|
||||
static inline __always_inline int
|
||||
ENTROPY_INLINE ( null, entropy_enable ) ( void ) {
|
||||
/* Do nothing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline __always_inline void
|
||||
ENTROPY_INLINE ( null, entropy_disable ) ( void ) {
|
||||
/* Do nothing */
|
||||
}
|
||||
|
||||
static inline __always_inline min_entropy_t
|
||||
ENTROPY_INLINE ( null, min_entropy_per_sample ) ( void ) {
|
||||
/* Actual amount of min-entropy is zero. To avoid
|
||||
* division-by-zero errors and to allow compilation of
|
||||
* entropy-consuming code, pretend to have 1 bit of entropy in
|
||||
* each sample.
|
||||
*/
|
||||
return MIN_ENTROPY ( 1.0 );
|
||||
}
|
||||
|
||||
static inline __always_inline int
|
||||
ENTROPY_INLINE ( null, get_noise ) ( noise_sample_t *noise ) {
|
||||
|
||||
/* All sample values are constant */
|
||||
*noise = 0x01;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* _IPXE_NULL_ENTROPY_H */
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
/** @file
|
||||
*
|
||||
* Form parameters
|
||||
* Request parameters
|
||||
*
|
||||
*/
|
||||
|
||||
@ -12,7 +12,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/list.h>
|
||||
#include <ipxe/refcnt.h>
|
||||
|
||||
/** A form parameter list */
|
||||
/** A request parameter list */
|
||||
struct parameters {
|
||||
/** Reference count */
|
||||
struct refcnt refcnt;
|
||||
@ -24,18 +24,26 @@ struct parameters {
|
||||
struct list_head entries;
|
||||
};
|
||||
|
||||
/** A form parameter */
|
||||
/** A request parameter */
|
||||
struct parameter {
|
||||
/** List of form parameters */
|
||||
/** List of request parameters */
|
||||
struct list_head list;
|
||||
/** Key */
|
||||
const char *key;
|
||||
/** Value */
|
||||
const char *value;
|
||||
/** Flags */
|
||||
unsigned int flags;
|
||||
};
|
||||
|
||||
/** Request parameter is a form parameter */
|
||||
#define PARAMETER_FORM 0x0001
|
||||
|
||||
/** Request parameter is a header parameter */
|
||||
#define PARAMETER_HEADER 0x0002
|
||||
|
||||
/**
|
||||
* Increment form parameter list reference count
|
||||
* Increment request parameter list reference count
|
||||
*
|
||||
* @v params Parameter list, or NULL
|
||||
* @ret params Parameter list as passed in
|
||||
@ -47,7 +55,7 @@ params_get ( struct parameters *params ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement form parameter list reference count
|
||||
* Decrement request parameter list reference count
|
||||
*
|
||||
* @v params Parameter list, or NULL
|
||||
*/
|
||||
@ -57,7 +65,7 @@ params_put ( struct parameters *params ) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Claim ownership of form parameter list
|
||||
* Claim ownership of request parameter list
|
||||
*
|
||||
* @v params Parameter list
|
||||
* @ret params Parameter list
|
||||
@ -71,13 +79,14 @@ claim_parameters ( struct parameters *params ) {
|
||||
return params;
|
||||
}
|
||||
|
||||
/** Iterate over all form parameters in a list */
|
||||
/** Iterate over all request parameters in a list */
|
||||
#define for_each_param( param, params ) \
|
||||
list_for_each_entry ( (param), &(params)->entries, list )
|
||||
|
||||
extern struct parameters * find_parameters ( const char *name );
|
||||
extern struct parameters * create_parameters ( const char *name );
|
||||
extern struct parameter * add_parameter ( struct parameters *params,
|
||||
const char *key, const char *value );
|
||||
const char *key, const char *value,
|
||||
unsigned int flags );
|
||||
|
||||
#endif /* _IPXE_PARAMS_H */
|
||||
|
||||
@ -227,6 +227,8 @@ struct pci_device {
|
||||
uint32_t class;
|
||||
/** Interrupt number */
|
||||
uint8_t irq;
|
||||
/** Header type */
|
||||
uint8_t hdrtype;
|
||||
/** Segment, bus, device, and function (bus:dev.fn) number */
|
||||
uint32_t busdevfn;
|
||||
/** Driver for this device */
|
||||
|
||||
@ -383,9 +383,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
#define for_each_table_entry( pointer, table ) \
|
||||
for ( pointer = table_start ( table ) ; \
|
||||
pointer < table_end ( table ) ; \
|
||||
pointer++ )
|
||||
for ( (pointer) = table_start ( table ) ; \
|
||||
(pointer) < table_end ( table ) ; \
|
||||
(pointer)++ )
|
||||
|
||||
/**
|
||||
* Iterate through all remaining entries within a linker table
|
||||
@ -412,9 +412,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
#define for_each_table_entry_continue( pointer, table ) \
|
||||
for ( pointer++ ; \
|
||||
pointer < table_end ( table ) ; \
|
||||
pointer++ )
|
||||
for ( (pointer)++ ; \
|
||||
(pointer) < table_end ( table ) ; \
|
||||
(pointer)++ )
|
||||
|
||||
/**
|
||||
* Iterate through all entries within a linker table in reverse order
|
||||
@ -438,9 +438,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
#define for_each_table_entry_reverse( pointer, table ) \
|
||||
for ( pointer = ( table_end ( table ) - 1 ) ; \
|
||||
pointer >= table_start ( table ) ; \
|
||||
pointer-- )
|
||||
for ( (pointer) = ( table_end ( table ) - 1 ) ; \
|
||||
(pointer) >= table_start ( table ) ; \
|
||||
(pointer)-- )
|
||||
|
||||
/**
|
||||
* Iterate through all remaining entries within a linker table in reverse order
|
||||
@ -467,8 +467,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
*/
|
||||
#define for_each_table_entry_continue_reverse( pointer, table ) \
|
||||
for ( pointer-- ; \
|
||||
pointer >= table_start ( table ) ; \
|
||||
pointer-- )
|
||||
for ( (pointer)-- ; \
|
||||
(pointer) >= table_start ( table ) ; \
|
||||
(pointer)-- )
|
||||
|
||||
#endif /* _IPXE_TABLES_H */
|
||||
|
||||
@ -84,7 +84,7 @@ struct uri {
|
||||
const char *equery;
|
||||
/** Fragment (with original URI encoding) */
|
||||
const char *efragment;
|
||||
/** Form parameters */
|
||||
/** Request parameters */
|
||||
struct parameters *params;
|
||||
} __attribute__ (( packed ));
|
||||
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* arch-arm.h
|
||||
*
|
||||
* Guest OS interface to ARM Xen.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright 2011 (C) Citrix Systems
|
||||
*/
|
||||
|
||||
@ -63,15 +46,15 @@ FILE_LICENCE ( MIT );
|
||||
*
|
||||
* All memory which is shared with other entities in the system
|
||||
* (including the hypervisor and other guests) must reside in memory
|
||||
* which is mapped as Normal Inner-cacheable. This applies to:
|
||||
* which is mapped as Normal Inner Write-Back Outer Write-Back Inner-Shareable.
|
||||
* This applies to:
|
||||
* - hypercall arguments passed via a pointer to guest memory.
|
||||
* - memory shared via the grant table mechanism (including PV I/O
|
||||
* rings etc).
|
||||
* - memory shared with the hypervisor (struct shared_info, struct
|
||||
* vcpu_info, the grant table, etc).
|
||||
*
|
||||
* Any Inner cache allocation strategy (Write-Back, Write-Through etc)
|
||||
* is acceptable. There is no restriction on the Outer-cacheability.
|
||||
* Any cache allocation hints are acceptable.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -89,15 +72,10 @@ FILE_LICENCE ( MIT );
|
||||
* unavailable/unsupported.
|
||||
*
|
||||
* HYPERVISOR_memory_op
|
||||
* All generic sub-operations.
|
||||
*
|
||||
* In addition the following arch specific sub-ops:
|
||||
* * XENMEM_add_to_physmap
|
||||
* * XENMEM_add_to_physmap_batch
|
||||
* All generic sub-operations
|
||||
*
|
||||
* HYPERVISOR_domctl
|
||||
* All generic sub-operations, with the exception of:
|
||||
* * XEN_DOMCTL_iomem_permission (not yet implemented)
|
||||
* * XEN_DOMCTL_irq_permission (not yet implemented)
|
||||
*
|
||||
* HYPERVISOR_sched_op
|
||||
@ -114,7 +92,9 @@ FILE_LICENCE ( MIT );
|
||||
* All generic sub-operations
|
||||
*
|
||||
* HYPERVISOR_physdev_op
|
||||
* No sub-operations are currenty supported
|
||||
* Exactly these sub-operations are supported:
|
||||
* PHYSDEVOP_pci_device_add
|
||||
* PHYSDEVOP_pci_device_remove
|
||||
*
|
||||
* HYPERVISOR_sysctl
|
||||
* All generic sub-operations, with the exception of:
|
||||
@ -135,6 +115,8 @@ FILE_LICENCE ( MIT );
|
||||
* * VCPUOP_register_vcpu_info
|
||||
* * VCPUOP_register_runstate_memory_area
|
||||
*
|
||||
* HYPERVISOR_argo_op
|
||||
* All generic sub-operations
|
||||
*
|
||||
* Other notes on the ARM ABI:
|
||||
*
|
||||
@ -172,6 +154,7 @@ FILE_LICENCE ( MIT );
|
||||
|
||||
#define XEN_HYPERCALL_TAG 0XEA1
|
||||
|
||||
#define int64_aligned_t int64_t __attribute__((aligned(8)))
|
||||
#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
@ -179,14 +162,14 @@ FILE_LICENCE ( MIT );
|
||||
typedef union { type *p; unsigned long q; } \
|
||||
__guest_handle_ ## name; \
|
||||
typedef union { type *p; uint64_aligned_t q; } \
|
||||
__guest_handle_64_ ## name;
|
||||
__guest_handle_64_ ## name
|
||||
|
||||
/*
|
||||
* XEN_GUEST_HANDLE represents a guest pointer, when passed as a field
|
||||
* in a struct in memory. On ARM is always 8 bytes sizes and 8 bytes
|
||||
* aligned.
|
||||
* XEN_GUEST_HANDLE_PARAM represent a guest pointer, when passed as an
|
||||
* hypercall argument. It is 4 bytes on aarch and 8 bytes on aarch64.
|
||||
* XEN_GUEST_HANDLE_PARAM represents a guest pointer, when passed as an
|
||||
* hypercall argument. It is 4 bytes on aarch32 and 8 bytes on aarch64.
|
||||
*/
|
||||
#define __DEFINE_XEN_GUEST_HANDLE(name, type) \
|
||||
___DEFINE_XEN_GUEST_HANDLE(name, type); \
|
||||
@ -194,19 +177,29 @@ FILE_LICENCE ( MIT );
|
||||
#define DEFINE_XEN_GUEST_HANDLE(name) __DEFINE_XEN_GUEST_HANDLE(name, name)
|
||||
#define __XEN_GUEST_HANDLE(name) __guest_handle_64_ ## name
|
||||
#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
|
||||
/* this is going to be changed on 64 bit */
|
||||
#define XEN_GUEST_HANDLE_PARAM(name) __guest_handle_ ## name
|
||||
#define set_xen_guest_handle_raw(hnd, val) \
|
||||
do { \
|
||||
typeof(&(hnd)) _sxghr_tmp = &(hnd); \
|
||||
__typeof__(&(hnd)) _sxghr_tmp = &(hnd); \
|
||||
_sxghr_tmp->q = 0; \
|
||||
_sxghr_tmp->p = val; \
|
||||
} while ( 0 )
|
||||
#ifdef __XEN_TOOLS__
|
||||
#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
|
||||
#endif
|
||||
#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
|
||||
|
||||
typedef uint64_t xen_pfn_t;
|
||||
#define PRI_xen_pfn PRIx64
|
||||
#define PRIu_xen_pfn PRIu64
|
||||
|
||||
/*
|
||||
* Maximum number of virtual CPUs in legacy multi-processor guests.
|
||||
* Only one. All other VCPUS must use VCPUOP_register_vcpu_info.
|
||||
*/
|
||||
#define XEN_LEGACY_MAX_VCPUS 1
|
||||
|
||||
typedef uint64_t xen_ulong_t;
|
||||
#define PRI_xen_ulong PRIx64
|
||||
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
|
||||
# define __DECL_REG(n64, n32) union { \
|
||||
@ -263,10 +256,10 @@ struct vcpu_guest_core_regs
|
||||
|
||||
/* Return address and mode */
|
||||
__DECL_REG(pc64, pc32); /* ELR_EL2 */
|
||||
uint32_t cpsr; /* SPSR_EL2 */
|
||||
uint64_t cpsr; /* SPSR_EL2 */
|
||||
|
||||
union {
|
||||
uint32_t spsr_el1; /* AArch64 */
|
||||
uint64_t spsr_el1; /* AArch64 */
|
||||
uint32_t spsr_svc; /* AArch32 */
|
||||
};
|
||||
|
||||
@ -282,17 +275,6 @@ DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
|
||||
|
||||
#undef __DECL_REG
|
||||
|
||||
typedef uint64_t xen_pfn_t;
|
||||
#define PRI_xen_pfn PRIx64
|
||||
|
||||
/* Maximum number of virtual CPUs in legacy multi-processor guests. */
|
||||
/* Only one. All other VCPUS must use VCPUOP_register_vcpu_info */
|
||||
#define XEN_LEGACY_MAX_VCPUS 1
|
||||
|
||||
typedef uint64_t xen_ulong_t;
|
||||
#define PRI_xen_ulong PRIx64
|
||||
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
struct vcpu_guest_context {
|
||||
#define _VGCF_online 0
|
||||
#define VGCF_online (1<<_VGCF_online)
|
||||
@ -300,12 +282,46 @@ struct vcpu_guest_context {
|
||||
|
||||
struct vcpu_guest_core_regs user_regs; /* Core CPU registers */
|
||||
|
||||
uint32_t sctlr;
|
||||
uint64_t sctlr;
|
||||
uint64_t ttbcr, ttbr0, ttbr1;
|
||||
};
|
||||
typedef struct vcpu_guest_context vcpu_guest_context_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* struct xen_arch_domainconfig's ABI is covered by
|
||||
* XEN_DOMCTL_INTERFACE_VERSION.
|
||||
*/
|
||||
#define XEN_DOMCTL_CONFIG_GIC_NATIVE 0
|
||||
#define XEN_DOMCTL_CONFIG_GIC_V2 1
|
||||
#define XEN_DOMCTL_CONFIG_GIC_V3 2
|
||||
|
||||
#define XEN_DOMCTL_CONFIG_TEE_NONE 0
|
||||
#define XEN_DOMCTL_CONFIG_TEE_OPTEE 1
|
||||
|
||||
struct xen_arch_domainconfig {
|
||||
/* IN/OUT */
|
||||
uint8_t gic_version;
|
||||
/* IN */
|
||||
uint16_t tee_type;
|
||||
/* IN */
|
||||
uint32_t nr_spis;
|
||||
/*
|
||||
* OUT
|
||||
* Based on the property clock-frequency in the DT timer node.
|
||||
* The property may be present when the bootloader/firmware doesn't
|
||||
* set correctly CNTFRQ which hold the timer frequency.
|
||||
*
|
||||
* As it's not possible to trap this register, we have to replicate
|
||||
* the value in the guest DT.
|
||||
*
|
||||
* = 0 => property not present
|
||||
* > 0 => Value of the property
|
||||
*
|
||||
*/
|
||||
uint32_t clock_frequency;
|
||||
};
|
||||
#endif /* __XEN__ || __XEN_TOOLS__ */
|
||||
|
||||
struct arch_vcpu_info {
|
||||
};
|
||||
@ -320,7 +336,7 @@ typedef uint64_t xen_callback_t;
|
||||
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
|
||||
/* PSR bits (CPSR, SPSR)*/
|
||||
/* PSR bits (CPSR, SPSR) */
|
||||
|
||||
#define PSR_THUMB (1<<5) /* Thumb Mode enable */
|
||||
#define PSR_FIQ_MASK (1<<6) /* Fast Interrupt mask */
|
||||
@ -330,6 +346,7 @@ typedef uint64_t xen_callback_t;
|
||||
#define PSR_DBG_MASK (1<<9) /* arm64: Debug Exception mask */
|
||||
#define PSR_IT_MASK (0x0600fc00) /* Thumb If-Then Mask */
|
||||
#define PSR_JAZELLE (1<<24) /* Jazelle Mode */
|
||||
#define PSR_Z (1<<30) /* Zero condition flag */
|
||||
|
||||
/* 32 bit modes */
|
||||
#define PSR_MODE_USR 0x10
|
||||
@ -352,10 +369,18 @@ typedef uint64_t xen_callback_t;
|
||||
#define PSR_MODE_EL1t 0x04
|
||||
#define PSR_MODE_EL0t 0x00
|
||||
|
||||
#define PSR_GUEST32_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
|
||||
/*
|
||||
* We set PSR_Z to be able to boot Linux kernel versions with an invalid
|
||||
* encoding of the first 8 NOP instructions. See commit a92882a4d270 in
|
||||
* Linux.
|
||||
*
|
||||
* Note that PSR_Z is also set by U-Boot and QEMU -kernel when loading
|
||||
* zImage kernels on aarch32.
|
||||
*/
|
||||
#define PSR_GUEST32_INIT (PSR_Z|PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_SVC)
|
||||
#define PSR_GUEST64_INIT (PSR_ABT_MASK|PSR_FIQ_MASK|PSR_IRQ_MASK|PSR_MODE_EL1h)
|
||||
|
||||
#define SCTLR_GUEST_INIT 0x00c50078
|
||||
#define SCTLR_GUEST_INIT xen_mk_ullong(0x00c50078)
|
||||
|
||||
/*
|
||||
* Virtual machine platform (memory layout, interrupts)
|
||||
@ -366,27 +391,78 @@ typedef uint64_t xen_callback_t;
|
||||
*/
|
||||
|
||||
/* Physical Address Space */
|
||||
#define GUEST_GICD_BASE 0x03001000ULL
|
||||
#define GUEST_GICD_SIZE 0x00001000ULL
|
||||
#define GUEST_GICC_BASE 0x03002000ULL
|
||||
#define GUEST_GICC_SIZE 0x00000100ULL
|
||||
|
||||
/* 16MB == 4096 pages reserved for guest to use as a region to map its
|
||||
/* Virtio MMIO mappings */
|
||||
#define GUEST_VIRTIO_MMIO_BASE xen_mk_ullong(0x02000000)
|
||||
#define GUEST_VIRTIO_MMIO_SIZE xen_mk_ullong(0x00100000)
|
||||
|
||||
/*
|
||||
* vGIC mappings: Only one set of mapping is used by the guest.
|
||||
* Therefore they can overlap.
|
||||
*/
|
||||
|
||||
/* vGIC v2 mappings */
|
||||
#define GUEST_GICD_BASE xen_mk_ullong(0x03001000)
|
||||
#define GUEST_GICD_SIZE xen_mk_ullong(0x00001000)
|
||||
#define GUEST_GICC_BASE xen_mk_ullong(0x03002000)
|
||||
#define GUEST_GICC_SIZE xen_mk_ullong(0x00002000)
|
||||
|
||||
/* vGIC v3 mappings */
|
||||
#define GUEST_GICV3_GICD_BASE xen_mk_ullong(0x03001000)
|
||||
#define GUEST_GICV3_GICD_SIZE xen_mk_ullong(0x00010000)
|
||||
|
||||
#define GUEST_GICV3_RDIST_REGIONS 1
|
||||
|
||||
#define GUEST_GICV3_GICR0_BASE xen_mk_ullong(0x03020000) /* vCPU0..127 */
|
||||
#define GUEST_GICV3_GICR0_SIZE xen_mk_ullong(0x01000000)
|
||||
|
||||
/*
|
||||
* 256 MB is reserved for VPCI configuration space based on calculation
|
||||
* 256 buses x 32 devices x 8 functions x 4 KB = 256 MB
|
||||
*/
|
||||
#define GUEST_VPCI_ECAM_BASE xen_mk_ullong(0x10000000)
|
||||
#define GUEST_VPCI_ECAM_SIZE xen_mk_ullong(0x10000000)
|
||||
|
||||
/* ACPI tables physical address */
|
||||
#define GUEST_ACPI_BASE xen_mk_ullong(0x20000000)
|
||||
#define GUEST_ACPI_SIZE xen_mk_ullong(0x02000000)
|
||||
|
||||
/* PL011 mappings */
|
||||
#define GUEST_PL011_BASE xen_mk_ullong(0x22000000)
|
||||
#define GUEST_PL011_SIZE xen_mk_ullong(0x00001000)
|
||||
|
||||
/* Guest PCI-PCIe memory space where config space and BAR will be available.*/
|
||||
#define GUEST_VPCI_ADDR_TYPE_MEM xen_mk_ullong(0x02000000)
|
||||
#define GUEST_VPCI_MEM_ADDR xen_mk_ullong(0x23000000)
|
||||
#define GUEST_VPCI_MEM_SIZE xen_mk_ullong(0x10000000)
|
||||
|
||||
/*
|
||||
* 16MB == 4096 pages reserved for guest to use as a region to map its
|
||||
* grant table in.
|
||||
*/
|
||||
#define GUEST_GNTTAB_BASE 0x38000000ULL
|
||||
#define GUEST_GNTTAB_SIZE 0x01000000ULL
|
||||
#define GUEST_GNTTAB_BASE xen_mk_ullong(0x38000000)
|
||||
#define GUEST_GNTTAB_SIZE xen_mk_ullong(0x01000000)
|
||||
|
||||
#define GUEST_MAGIC_BASE 0x39000000ULL
|
||||
#define GUEST_MAGIC_SIZE 0x01000000ULL
|
||||
#define GUEST_MAGIC_BASE xen_mk_ullong(0x39000000)
|
||||
#define GUEST_MAGIC_SIZE xen_mk_ullong(0x01000000)
|
||||
|
||||
#define GUEST_RAM_BANKS 2
|
||||
|
||||
#define GUEST_RAM0_BASE 0x40000000ULL /* 3GB of low RAM @ 1GB */
|
||||
#define GUEST_RAM0_SIZE 0xc0000000ULL
|
||||
/*
|
||||
* The way to find the extended regions (to be exposed to the guest as unused
|
||||
* address space) relies on the fact that the regions reserved for the RAM
|
||||
* below are big enough to also accommodate such regions.
|
||||
*/
|
||||
#define GUEST_RAM0_BASE xen_mk_ullong(0x40000000) /* 3GB of low RAM @ 1GB */
|
||||
#define GUEST_RAM0_SIZE xen_mk_ullong(0xc0000000)
|
||||
|
||||
#define GUEST_RAM1_BASE 0x0200000000ULL /* 1016GB of RAM @ 8GB */
|
||||
#define GUEST_RAM1_SIZE 0xfe00000000ULL
|
||||
/* 4GB @ 4GB Prefetch Memory for VPCI */
|
||||
#define GUEST_VPCI_ADDR_TYPE_PREFETCH_MEM xen_mk_ullong(0x42000000)
|
||||
#define GUEST_VPCI_PREFETCH_MEM_ADDR xen_mk_ullong(0x100000000)
|
||||
#define GUEST_VPCI_PREFETCH_MEM_SIZE xen_mk_ullong(0x100000000)
|
||||
|
||||
#define GUEST_RAM1_BASE xen_mk_ullong(0x0200000000) /* 1016GB of RAM @ 8GB */
|
||||
#define GUEST_RAM1_SIZE xen_mk_ullong(0xfe00000000)
|
||||
|
||||
#define GUEST_RAM_BASE GUEST_RAM0_BASE /* Lowest RAM address */
|
||||
/* Largest amount of actual RAM, not including holes */
|
||||
@ -395,12 +471,20 @@ typedef uint64_t xen_callback_t;
|
||||
#define GUEST_RAM_BANK_BASES { GUEST_RAM0_BASE, GUEST_RAM1_BASE }
|
||||
#define GUEST_RAM_BANK_SIZES { GUEST_RAM0_SIZE, GUEST_RAM1_SIZE }
|
||||
|
||||
/* Current supported guest VCPUs */
|
||||
#define GUEST_MAX_VCPUS 128
|
||||
|
||||
/* Interrupts */
|
||||
#define GUEST_TIMER_VIRT_PPI 27
|
||||
#define GUEST_TIMER_PHYS_S_PPI 29
|
||||
#define GUEST_TIMER_PHYS_NS_PPI 30
|
||||
#define GUEST_EVTCHN_PPI 31
|
||||
|
||||
#define GUEST_VPL011_SPI 32
|
||||
|
||||
#define GUEST_VIRTIO_MMIO_SPI_FIRST 33
|
||||
#define GUEST_VIRTIO_MMIO_SPI_LAST 43
|
||||
|
||||
/* PSCI functions */
|
||||
#define PSCI_cpu_suspend 0
|
||||
#define PSCI_cpu_off 1
|
||||
@ -409,6 +493,11 @@ typedef uint64_t xen_callback_t;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
/* Stub definition of PMU structure */
|
||||
typedef struct xen_pmu_arch { uint8_t dummy; } xen_pmu_arch_t;
|
||||
#endif
|
||||
|
||||
#endif /* __XEN_PUBLIC_ARCH_ARM_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* xen-x86_32.h
|
||||
*
|
||||
* Guest OS interface to x86 32-bit Xen.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2004-2007, K A Fraser
|
||||
*/
|
||||
|
||||
@ -60,34 +43,31 @@ FILE_LICENCE ( MIT );
|
||||
#define __HYPERVISOR_VIRT_START_PAE 0xF5800000
|
||||
#define __MACH2PHYS_VIRT_START_PAE 0xF5800000
|
||||
#define __MACH2PHYS_VIRT_END_PAE 0xF6800000
|
||||
#define HYPERVISOR_VIRT_START_PAE \
|
||||
mk_unsigned_long(__HYPERVISOR_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_START_PAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_END_PAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_END_PAE)
|
||||
#define HYPERVISOR_VIRT_START_PAE xen_mk_ulong(__HYPERVISOR_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_START_PAE xen_mk_ulong(__MACH2PHYS_VIRT_START_PAE)
|
||||
#define MACH2PHYS_VIRT_END_PAE xen_mk_ulong(__MACH2PHYS_VIRT_END_PAE)
|
||||
|
||||
/* Non-PAE bounds are obsolete. */
|
||||
#define __HYPERVISOR_VIRT_START_NONPAE 0xFC000000
|
||||
#define __MACH2PHYS_VIRT_START_NONPAE 0xFC000000
|
||||
#define __MACH2PHYS_VIRT_END_NONPAE 0xFC400000
|
||||
#define HYPERVISOR_VIRT_START_NONPAE \
|
||||
mk_unsigned_long(__HYPERVISOR_VIRT_START_NONPAE)
|
||||
xen_mk_ulong(__HYPERVISOR_VIRT_START_NONPAE)
|
||||
#define MACH2PHYS_VIRT_START_NONPAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_START_NONPAE)
|
||||
xen_mk_ulong(__MACH2PHYS_VIRT_START_NONPAE)
|
||||
#define MACH2PHYS_VIRT_END_NONPAE \
|
||||
mk_unsigned_long(__MACH2PHYS_VIRT_END_NONPAE)
|
||||
xen_mk_ulong(__MACH2PHYS_VIRT_END_NONPAE)
|
||||
|
||||
#define __HYPERVISOR_VIRT_START __HYPERVISOR_VIRT_START_PAE
|
||||
#define __MACH2PHYS_VIRT_START __MACH2PHYS_VIRT_START_PAE
|
||||
#define __MACH2PHYS_VIRT_END __MACH2PHYS_VIRT_END_PAE
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START)
|
||||
#endif
|
||||
|
||||
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>2)
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)MACH2PHYS_VIRT_START)
|
||||
@ -106,6 +86,7 @@ FILE_LICENCE ( MIT );
|
||||
do { if ( sizeof(hnd) == 8 ) *(uint64_t *)&(hnd) = 0; \
|
||||
(hnd).p = val; \
|
||||
} while ( 0 )
|
||||
#define int64_aligned_t int64_t __attribute__((aligned(8)))
|
||||
#define uint64_aligned_t uint64_t __attribute__((aligned(8)))
|
||||
#define __XEN_GUEST_HANDLE_64(name) __guest_handle_64_ ## name
|
||||
#define XEN_GUEST_HANDLE_64(name) __XEN_GUEST_HANDLE_64(name)
|
||||
@ -113,22 +94,44 @@ FILE_LICENCE ( MIT );
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#if defined(XEN_GENERATING_COMPAT_HEADERS)
|
||||
/* nothing */
|
||||
#elif defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax). */
|
||||
#define __DECL_REG_LO8(which) union { \
|
||||
uint32_t e ## which ## x; \
|
||||
uint16_t which ## x; \
|
||||
struct { \
|
||||
uint8_t which ## l; \
|
||||
uint8_t which ## h; \
|
||||
}; \
|
||||
}
|
||||
#define __DECL_REG_LO16(name) union { \
|
||||
uint32_t e ## name, _e ## name; \
|
||||
uint16_t name; \
|
||||
}
|
||||
#else
|
||||
/* Other sources must always use the proper 32-bit name (e.g., eax). */
|
||||
#define __DECL_REG_LO8(which) uint32_t e ## which ## x
|
||||
#define __DECL_REG_LO16(name) uint32_t e ## name
|
||||
#endif
|
||||
|
||||
struct cpu_user_regs {
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
uint32_t esi;
|
||||
uint32_t edi;
|
||||
uint32_t ebp;
|
||||
uint32_t eax;
|
||||
__DECL_REG_LO8(b);
|
||||
__DECL_REG_LO8(c);
|
||||
__DECL_REG_LO8(d);
|
||||
__DECL_REG_LO16(si);
|
||||
__DECL_REG_LO16(di);
|
||||
__DECL_REG_LO16(bp);
|
||||
__DECL_REG_LO8(a);
|
||||
uint16_t error_code; /* private */
|
||||
uint16_t entry_vector; /* private */
|
||||
uint32_t eip;
|
||||
__DECL_REG_LO16(ip);
|
||||
uint16_t cs;
|
||||
uint8_t saved_upcall_mask;
|
||||
uint8_t _pad0;
|
||||
uint32_t eflags; /* eflags.IF == !saved_upcall_mask */
|
||||
uint32_t esp;
|
||||
__DECL_REG_LO16(flags); /* eflags.IF == !saved_upcall_mask */
|
||||
__DECL_REG_LO16(sp);
|
||||
uint16_t ss, _pad1;
|
||||
uint16_t es, _pad2;
|
||||
uint16_t ds, _pad3;
|
||||
@ -138,6 +141,9 @@ struct cpu_user_regs {
|
||||
typedef struct cpu_user_regs cpu_user_regs_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
|
||||
|
||||
#undef __DECL_REG_LO8
|
||||
#undef __DECL_REG_LO16
|
||||
|
||||
/*
|
||||
* Page-directory addresses above 4GB do not fit into architectural %cr3.
|
||||
* When accessing %cr3, or equivalent field in vcpu_guest_context, guests
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* xen-x86_64.h
|
||||
*
|
||||
* Guest OS interface to x86 64-bit Xen.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2004-2006, K A Fraser
|
||||
*/
|
||||
|
||||
@ -46,11 +29,11 @@ FILE_LICENCE ( MIT );
|
||||
*/
|
||||
|
||||
#define FLAT_RING3_CS32 0xe023 /* GDT index 260 */
|
||||
#define FLAT_RING3_CS64 0xe033 /* GDT index 261 */
|
||||
#define FLAT_RING3_DS32 0xe02b /* GDT index 262 */
|
||||
#define FLAT_RING3_CS64 0xe033 /* GDT index 262 */
|
||||
#define FLAT_RING3_DS32 0xe02b /* GDT index 261 */
|
||||
#define FLAT_RING3_DS64 0x0000 /* NULL selector */
|
||||
#define FLAT_RING3_SS32 0xe02b /* GDT index 262 */
|
||||
#define FLAT_RING3_SS64 0xe02b /* GDT index 262 */
|
||||
#define FLAT_RING3_SS32 0xe02b /* GDT index 261 */
|
||||
#define FLAT_RING3_SS64 0xe02b /* GDT index 261 */
|
||||
|
||||
#define FLAT_KERNEL_DS64 FLAT_RING3_DS64
|
||||
#define FLAT_KERNEL_DS32 FLAT_RING3_DS32
|
||||
@ -78,12 +61,12 @@ FILE_LICENCE ( MIT );
|
||||
#define __MACH2PHYS_VIRT_END 0xFFFF804000000000
|
||||
|
||||
#ifndef HYPERVISOR_VIRT_START
|
||||
#define HYPERVISOR_VIRT_START mk_unsigned_long(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_END mk_unsigned_long(__HYPERVISOR_VIRT_END)
|
||||
#define HYPERVISOR_VIRT_START xen_mk_ulong(__HYPERVISOR_VIRT_START)
|
||||
#define HYPERVISOR_VIRT_END xen_mk_ulong(__HYPERVISOR_VIRT_END)
|
||||
#endif
|
||||
|
||||
#define MACH2PHYS_VIRT_START mk_unsigned_long(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END mk_unsigned_long(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_VIRT_START xen_mk_ulong(__MACH2PHYS_VIRT_START)
|
||||
#define MACH2PHYS_VIRT_END xen_mk_ulong(__MACH2PHYS_VIRT_END)
|
||||
#define MACH2PHYS_NR_ENTRIES ((MACH2PHYS_VIRT_END-MACH2PHYS_VIRT_START)>>3)
|
||||
#ifndef machine_to_phys_mapping
|
||||
#define machine_to_phys_mapping ((unsigned long *)HYPERVISOR_VIRT_START)
|
||||
@ -132,7 +115,35 @@ struct iret_context {
|
||||
/* Bottom of iret stack frame. */
|
||||
};
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
/* Anonymous unions include all permissible names (e.g., al/ah/ax/eax/rax). */
|
||||
#define __DECL_REG_LOHI(which) union { \
|
||||
uint64_t r ## which ## x; \
|
||||
uint32_t e ## which ## x; \
|
||||
uint16_t which ## x; \
|
||||
struct { \
|
||||
uint8_t which ## l; \
|
||||
uint8_t which ## h; \
|
||||
}; \
|
||||
}
|
||||
#define __DECL_REG_LO8(name) union { \
|
||||
uint64_t r ## name; \
|
||||
uint32_t e ## name; \
|
||||
uint16_t name; \
|
||||
uint8_t name ## l; \
|
||||
}
|
||||
#define __DECL_REG_LO16(name) union { \
|
||||
uint64_t r ## name; \
|
||||
uint32_t e ## name; \
|
||||
uint16_t name; \
|
||||
}
|
||||
#define __DECL_REG_HI(num) union { \
|
||||
uint64_t r ## num; \
|
||||
uint32_t r ## num ## d; \
|
||||
uint16_t r ## num ## w; \
|
||||
uint8_t r ## num ## b; \
|
||||
}
|
||||
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */
|
||||
#define __DECL_REG(name) union { \
|
||||
uint64_t r ## name, e ## name; \
|
||||
@ -143,40 +154,51 @@ struct iret_context {
|
||||
#define __DECL_REG(name) uint64_t r ## name
|
||||
#endif
|
||||
|
||||
#ifndef __DECL_REG_LOHI
|
||||
#define __DECL_REG_LOHI(name) __DECL_REG(name ## x)
|
||||
#define __DECL_REG_LO8 __DECL_REG
|
||||
#define __DECL_REG_LO16 __DECL_REG
|
||||
#define __DECL_REG_HI(num) uint64_t r ## num
|
||||
#endif
|
||||
|
||||
struct cpu_user_regs {
|
||||
uint64_t r15;
|
||||
uint64_t r14;
|
||||
uint64_t r13;
|
||||
uint64_t r12;
|
||||
__DECL_REG(bp);
|
||||
__DECL_REG(bx);
|
||||
uint64_t r11;
|
||||
uint64_t r10;
|
||||
uint64_t r9;
|
||||
uint64_t r8;
|
||||
__DECL_REG(ax);
|
||||
__DECL_REG(cx);
|
||||
__DECL_REG(dx);
|
||||
__DECL_REG(si);
|
||||
__DECL_REG(di);
|
||||
__DECL_REG_HI(15);
|
||||
__DECL_REG_HI(14);
|
||||
__DECL_REG_HI(13);
|
||||
__DECL_REG_HI(12);
|
||||
__DECL_REG_LO8(bp);
|
||||
__DECL_REG_LOHI(b);
|
||||
__DECL_REG_HI(11);
|
||||
__DECL_REG_HI(10);
|
||||
__DECL_REG_HI(9);
|
||||
__DECL_REG_HI(8);
|
||||
__DECL_REG_LOHI(a);
|
||||
__DECL_REG_LOHI(c);
|
||||
__DECL_REG_LOHI(d);
|
||||
__DECL_REG_LO8(si);
|
||||
__DECL_REG_LO8(di);
|
||||
uint32_t error_code; /* private */
|
||||
uint32_t entry_vector; /* private */
|
||||
__DECL_REG(ip);
|
||||
__DECL_REG_LO16(ip);
|
||||
uint16_t cs, _pad0[1];
|
||||
uint8_t saved_upcall_mask;
|
||||
uint8_t _pad1[3];
|
||||
__DECL_REG(flags); /* rflags.IF == !saved_upcall_mask */
|
||||
__DECL_REG(sp);
|
||||
__DECL_REG_LO16(flags); /* rflags.IF == !saved_upcall_mask */
|
||||
__DECL_REG_LO8(sp);
|
||||
uint16_t ss, _pad2[3];
|
||||
uint16_t es, _pad3[3];
|
||||
uint16_t ds, _pad4[3];
|
||||
uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */
|
||||
uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */
|
||||
uint16_t fs, _pad5[3];
|
||||
uint16_t gs, _pad6[3];
|
||||
};
|
||||
typedef struct cpu_user_regs cpu_user_regs_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
|
||||
|
||||
#undef __DECL_REG
|
||||
#undef __DECL_REG_LOHI
|
||||
#undef __DECL_REG_LO8
|
||||
#undef __DECL_REG_LO16
|
||||
#undef __DECL_REG_HI
|
||||
|
||||
#define xen_pfn_to_cr3(pfn) ((unsigned long)(pfn) << 12)
|
||||
#define xen_cr3_to_pfn(cr3) ((unsigned long)(cr3) >> 12)
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* arch-x86/xen.h
|
||||
*
|
||||
* Guest OS interface to x86 Xen.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2004-2006, K A Fraser
|
||||
*/
|
||||
|
||||
@ -56,13 +39,20 @@ FILE_LICENCE ( MIT );
|
||||
#define XEN_GUEST_HANDLE(name) __XEN_GUEST_HANDLE(name)
|
||||
#define XEN_GUEST_HANDLE_PARAM(name) XEN_GUEST_HANDLE(name)
|
||||
#define set_xen_guest_handle_raw(hnd, val) do { (hnd).p = val; } while (0)
|
||||
#ifdef __XEN_TOOLS__
|
||||
#define get_xen_guest_handle(val, hnd) do { val = (hnd).p; } while (0)
|
||||
#endif
|
||||
#define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
|
||||
|
||||
#if defined(__i386__)
|
||||
# ifdef __XEN__
|
||||
__DeFiNe__ __DECL_REG_LO8(which) uint32_t e ## which ## x
|
||||
__DeFiNe__ __DECL_REG_LO16(name) union { uint32_t e ## name; }
|
||||
# endif
|
||||
#include "xen-x86_32.h"
|
||||
# ifdef __XEN__
|
||||
__UnDeF__ __DECL_REG_LO8
|
||||
__UnDeF__ __DECL_REG_LO16
|
||||
__DeFiNe__ __DECL_REG_LO8(which) e ## which ## x
|
||||
__DeFiNe__ __DECL_REG_LO16(name) e ## name
|
||||
# endif
|
||||
#elif defined(__x86_64__)
|
||||
#include "xen-x86_64.h"
|
||||
#endif
|
||||
@ -70,6 +60,7 @@ FILE_LICENCE ( MIT );
|
||||
#ifndef __ASSEMBLY__
|
||||
typedef unsigned long xen_pfn_t;
|
||||
#define PRI_xen_pfn "lx"
|
||||
#define PRIu_xen_pfn "lu"
|
||||
#endif
|
||||
|
||||
#define XEN_HAVE_PV_GUEST_ENTRY 1
|
||||
@ -137,6 +128,12 @@ typedef unsigned long xen_ulong_t;
|
||||
* Level == 1: Kernel may enter
|
||||
* Level == 2: Kernel may enter
|
||||
* Level == 3: Everyone may enter
|
||||
*
|
||||
* Note: For compatibility with kernels not setting up exception handlers
|
||||
* early enough, Xen will avoid trying to inject #GP (and hence crash
|
||||
* the domain) when an RDMSR would require this, but no handler was
|
||||
* set yet. The precise conditions are implementation specific, and
|
||||
* new code may not rely on such behavior anyway.
|
||||
*/
|
||||
#define TI_GET_DPL(_ti) ((_ti)->flags & 3)
|
||||
#define TI_GET_IF(_ti) ((_ti)->flags & 4)
|
||||
@ -157,14 +154,12 @@ typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */
|
||||
* The following is all CPU context. Note that the fpu_ctxt block is filled
|
||||
* in by FXSAVE if the CPU has feature FXSR; otherwise FSAVE is used.
|
||||
*
|
||||
* Also note that when calling DOMCTL_setvcpucontext and VCPU_initialise
|
||||
* for HVM and PVH guests, not all information in this structure is updated:
|
||||
* Also note that when calling DOMCTL_setvcpucontext for HVM guests, not all
|
||||
* information in this structure is updated, the fields read include: fpu_ctxt
|
||||
* (if VGCT_I387_VALID is set), flags, user_regs and debugreg[*].
|
||||
*
|
||||
* - For HVM guests, the structures read include: fpu_ctxt (if
|
||||
* VGCT_I387_VALID is set), flags, user_regs, debugreg[*]
|
||||
*
|
||||
* - PVH guests are the same as HVM guests, but additionally use ctrlreg[3] to
|
||||
* set cr3. All other fields not used should be set to 0.
|
||||
* Note: VCPUOP_initialise for HVM guests is non-symetric with
|
||||
* DOMCTL_setvcpucontext, and uses struct vcpu_hvm_context from hvm/hvm_vcpu.h
|
||||
*/
|
||||
struct vcpu_guest_context {
|
||||
/* FPU registers come first so they can be aligned for FXSAVE/FXRSTOR. */
|
||||
@ -222,14 +217,117 @@ typedef struct vcpu_guest_context vcpu_guest_context_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
|
||||
|
||||
struct arch_shared_info {
|
||||
unsigned long max_pfn; /* max pfn that appears in table */
|
||||
/* Frame containing list of mfns containing list of mfns containing p2m. */
|
||||
/*
|
||||
* Number of valid entries in the p2m table(s) anchored at
|
||||
* pfn_to_mfn_frame_list_list and/or p2m_vaddr.
|
||||
*/
|
||||
unsigned long max_pfn;
|
||||
/*
|
||||
* Frame containing list of mfns containing list of mfns containing p2m.
|
||||
* A value of 0 indicates it has not yet been set up, ~0 indicates it has
|
||||
* been set to invalid e.g. due to the p2m being too large for the 3-level
|
||||
* p2m tree. In this case the linear mapper p2m list anchored at p2m_vaddr
|
||||
* is to be used.
|
||||
*/
|
||||
xen_pfn_t pfn_to_mfn_frame_list_list;
|
||||
unsigned long nmi_reason;
|
||||
uint64_t pad[32];
|
||||
/*
|
||||
* Following three fields are valid if p2m_cr3 contains a value different
|
||||
* from 0.
|
||||
* p2m_cr3 is the root of the address space where p2m_vaddr is valid.
|
||||
* p2m_cr3 is in the same format as a cr3 value in the vcpu register state
|
||||
* and holds the folded machine frame number (via xen_pfn_to_cr3) of a
|
||||
* L3 or L4 page table.
|
||||
* p2m_vaddr holds the virtual address of the linear p2m list. All entries
|
||||
* in the range [0...max_pfn[ are accessible via this pointer.
|
||||
* p2m_generation will be incremented by the guest before and after each
|
||||
* change of the mappings of the p2m list. p2m_generation starts at 0 and
|
||||
* a value with the least significant bit set indicates that a mapping
|
||||
* update is in progress. This allows guest external software (e.g. in Dom0)
|
||||
* to verify that read mappings are consistent and whether they have changed
|
||||
* since the last check.
|
||||
* Modifying a p2m element in the linear p2m list is allowed via an atomic
|
||||
* write only.
|
||||
*/
|
||||
unsigned long p2m_cr3; /* cr3 value of the p2m address space */
|
||||
unsigned long p2m_vaddr; /* virtual address of the p2m list */
|
||||
unsigned long p2m_generation; /* generation count of p2m mapping */
|
||||
#ifdef __i386__
|
||||
/* There's no room for this field in the generic structure. */
|
||||
uint32_t wc_sec_hi;
|
||||
#endif
|
||||
};
|
||||
typedef struct arch_shared_info arch_shared_info_t;
|
||||
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
/*
|
||||
* struct xen_arch_domainconfig's ABI is covered by
|
||||
* XEN_DOMCTL_INTERFACE_VERSION.
|
||||
*/
|
||||
struct xen_arch_domainconfig {
|
||||
#define _XEN_X86_EMU_LAPIC 0
|
||||
#define XEN_X86_EMU_LAPIC (1U<<_XEN_X86_EMU_LAPIC)
|
||||
#define _XEN_X86_EMU_HPET 1
|
||||
#define XEN_X86_EMU_HPET (1U<<_XEN_X86_EMU_HPET)
|
||||
#define _XEN_X86_EMU_PM 2
|
||||
#define XEN_X86_EMU_PM (1U<<_XEN_X86_EMU_PM)
|
||||
#define _XEN_X86_EMU_RTC 3
|
||||
#define XEN_X86_EMU_RTC (1U<<_XEN_X86_EMU_RTC)
|
||||
#define _XEN_X86_EMU_IOAPIC 4
|
||||
#define XEN_X86_EMU_IOAPIC (1U<<_XEN_X86_EMU_IOAPIC)
|
||||
#define _XEN_X86_EMU_PIC 5
|
||||
#define XEN_X86_EMU_PIC (1U<<_XEN_X86_EMU_PIC)
|
||||
#define _XEN_X86_EMU_VGA 6
|
||||
#define XEN_X86_EMU_VGA (1U<<_XEN_X86_EMU_VGA)
|
||||
#define _XEN_X86_EMU_IOMMU 7
|
||||
#define XEN_X86_EMU_IOMMU (1U<<_XEN_X86_EMU_IOMMU)
|
||||
#define _XEN_X86_EMU_PIT 8
|
||||
#define XEN_X86_EMU_PIT (1U<<_XEN_X86_EMU_PIT)
|
||||
#define _XEN_X86_EMU_USE_PIRQ 9
|
||||
#define XEN_X86_EMU_USE_PIRQ (1U<<_XEN_X86_EMU_USE_PIRQ)
|
||||
#define _XEN_X86_EMU_VPCI 10
|
||||
#define XEN_X86_EMU_VPCI (1U<<_XEN_X86_EMU_VPCI)
|
||||
|
||||
#define XEN_X86_EMU_ALL (XEN_X86_EMU_LAPIC | XEN_X86_EMU_HPET | \
|
||||
XEN_X86_EMU_PM | XEN_X86_EMU_RTC | \
|
||||
XEN_X86_EMU_IOAPIC | XEN_X86_EMU_PIC | \
|
||||
XEN_X86_EMU_VGA | XEN_X86_EMU_IOMMU | \
|
||||
XEN_X86_EMU_PIT | XEN_X86_EMU_USE_PIRQ |\
|
||||
XEN_X86_EMU_VPCI)
|
||||
uint32_t emulation_flags;
|
||||
|
||||
/*
|
||||
* Select whether to use a relaxed behavior for accesses to MSRs not explicitly
|
||||
* handled by Xen instead of injecting a #GP to the guest. Note this option
|
||||
* doesn't allow the guest to read or write to the underlying MSR.
|
||||
*/
|
||||
#define XEN_X86_MSR_RELAXED (1u << 0)
|
||||
uint32_t misc_flags;
|
||||
};
|
||||
|
||||
/* Max XEN_X86_* constant. Used for ABI checking. */
|
||||
#define XEN_X86_MISC_FLAGS_MAX XEN_X86_MSR_RELAXED
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Representations of architectural CPUID and MSR information. Used as the
|
||||
* serialised version of Xen's internal representation.
|
||||
*/
|
||||
typedef struct xen_cpuid_leaf {
|
||||
#define XEN_CPUID_NO_SUBLEAF 0xffffffffu
|
||||
uint32_t leaf, subleaf;
|
||||
uint32_t a, b, c, d;
|
||||
} xen_cpuid_leaf_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_cpuid_leaf_t);
|
||||
|
||||
typedef struct xen_msr_entry {
|
||||
uint32_t idx;
|
||||
uint32_t flags; /* Reserved MBZ. */
|
||||
uint64_t val;
|
||||
} xen_msr_entry_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_msr_entry_t);
|
||||
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
/*
|
||||
@ -262,6 +360,13 @@ typedef struct arch_shared_info arch_shared_info_t;
|
||||
#define XEN_CPUID XEN_EMULATE_PREFIX "cpuid"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Debug console IO port, also called "port E9 hack". Each character written
|
||||
* to this IO port will be printed on the hypervisor console, subject to log
|
||||
* level restrictions.
|
||||
*/
|
||||
#define XEN_HVM_DEBUGCONS_IOPORT 0xe9
|
||||
|
||||
#endif /* __XEN_PUBLIC_ARCH_X86_XEN_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* event_channel.h
|
||||
*
|
||||
* Event channels between domains.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2003-2004, K A Fraser.
|
||||
*/
|
||||
|
||||
@ -76,6 +59,9 @@ FILE_LICENCE ( MIT );
|
||||
#define EVTCHNOP_init_control 11
|
||||
#define EVTCHNOP_expand_array 12
|
||||
#define EVTCHNOP_set_priority 13
|
||||
#ifdef __XEN__
|
||||
#define EVTCHNOP_reset_cont 14
|
||||
#endif
|
||||
/* ` } */
|
||||
|
||||
typedef uint32_t evtchn_port_t;
|
||||
@ -87,7 +73,7 @@ DEFINE_XEN_GUEST_HANDLE(evtchn_port_t);
|
||||
* is allocated in <dom> and returned as <port>.
|
||||
* NOTES:
|
||||
* 1. If the caller is unprivileged then <dom> must be DOMID_SELF.
|
||||
* 2. <rdom> may be DOMID_SELF, allowing loopback connections.
|
||||
* 2. <remote_dom> may be DOMID_SELF, allowing loopback connections.
|
||||
*/
|
||||
struct evtchn_alloc_unbound {
|
||||
/* IN parameters */
|
||||
@ -266,6 +252,10 @@ typedef struct evtchn_unmask evtchn_unmask_t;
|
||||
* NOTES:
|
||||
* 1. <dom> may be specified as DOMID_SELF.
|
||||
* 2. Only a sufficiently-privileged domain may specify other than DOMID_SELF.
|
||||
* 3. Destroys all control blocks and event array, resets event channel
|
||||
* operations to 2-level ABI if called with <dom> == DOMID_SELF and FIFO
|
||||
* ABI was used. Guests should not bind events during EVTCHNOP_reset call
|
||||
* as these events are likely to be lost.
|
||||
*/
|
||||
struct evtchn_reset {
|
||||
/* IN parameters. */
|
||||
@ -305,7 +295,7 @@ typedef struct evtchn_expand_array evtchn_expand_array_t;
|
||||
*/
|
||||
struct evtchn_set_priority {
|
||||
/* IN parameters. */
|
||||
uint32_t port;
|
||||
evtchn_port_t port;
|
||||
uint32_t priority;
|
||||
};
|
||||
typedef struct evtchn_set_priority evtchn_set_priority_t;
|
||||
@ -319,16 +309,16 @@ typedef struct evtchn_set_priority evtchn_set_priority_t;
|
||||
struct evtchn_op {
|
||||
uint32_t cmd; /* enum event_channel_op */
|
||||
union {
|
||||
struct evtchn_alloc_unbound alloc_unbound;
|
||||
struct evtchn_bind_interdomain bind_interdomain;
|
||||
struct evtchn_bind_virq bind_virq;
|
||||
struct evtchn_bind_pirq bind_pirq;
|
||||
struct evtchn_bind_ipi bind_ipi;
|
||||
struct evtchn_close close;
|
||||
struct evtchn_send send;
|
||||
struct evtchn_status status;
|
||||
struct evtchn_bind_vcpu bind_vcpu;
|
||||
struct evtchn_unmask unmask;
|
||||
evtchn_alloc_unbound_t alloc_unbound;
|
||||
evtchn_bind_interdomain_t bind_interdomain;
|
||||
evtchn_bind_virq_t bind_virq;
|
||||
evtchn_bind_pirq_t bind_pirq;
|
||||
evtchn_bind_ipi_t bind_ipi;
|
||||
evtchn_close_t close;
|
||||
evtchn_send_t send;
|
||||
evtchn_status_t status;
|
||||
evtchn_bind_vcpu_t bind_vcpu;
|
||||
evtchn_unmask_t unmask;
|
||||
} u;
|
||||
};
|
||||
typedef struct evtchn_op evtchn_op_t;
|
||||
|
||||
@ -1,26 +1,9 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* features.h
|
||||
*
|
||||
* Feature flags, reported by XENVER_get_features.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2006, Keir Fraser <keir@xensource.com>
|
||||
*/
|
||||
|
||||
@ -96,6 +79,40 @@ FILE_LICENCE ( MIT );
|
||||
/* operation as Dom0 is supported */
|
||||
#define XENFEAT_dom0 11
|
||||
|
||||
/* Xen also maps grant references at pfn = mfn.
|
||||
* This feature flag is deprecated and should not be used.
|
||||
#define XENFEAT_grant_map_identity 12
|
||||
*/
|
||||
|
||||
/* Guest can use XENMEMF_vnode to specify virtual node for memory op. */
|
||||
#define XENFEAT_memory_op_vnode_supported 13
|
||||
|
||||
/* arm: Hypervisor supports ARM SMC calling convention. */
|
||||
#define XENFEAT_ARM_SMCCC_supported 14
|
||||
|
||||
/*
|
||||
* x86/PVH: If set, ACPI RSDP can be placed at any address. Otherwise RSDP
|
||||
* must be located in lower 1MB, as required by ACPI Specification for IA-PC
|
||||
* systems.
|
||||
* This feature flag is only consulted if XEN_ELFNOTE_GUEST_OS contains
|
||||
* the "linux" string.
|
||||
*/
|
||||
#define XENFEAT_linux_rsdp_unrestricted 15
|
||||
|
||||
/*
|
||||
* A direct-mapped (or 1:1 mapped) domain is a domain for which its
|
||||
* local pages have gfn == mfn. If a domain is direct-mapped,
|
||||
* XENFEAT_direct_mapped is set; otherwise XENFEAT_not_direct_mapped
|
||||
* is set.
|
||||
*
|
||||
* If neither flag is set (e.g. older Xen releases) the assumptions are:
|
||||
* - not auto_translated domains (x86 only) are always direct-mapped
|
||||
* - on x86, auto_translated domains are not direct-mapped
|
||||
* - on ARM, Dom0 is direct-mapped, DomUs are not
|
||||
*/
|
||||
#define XENFEAT_not_direct_mapped 16
|
||||
#define XENFEAT_direct_mapped 17
|
||||
|
||||
#define XENFEAT_NR_SUBMAPS 1
|
||||
|
||||
#endif /* __XEN_PUBLIC_FEATURES_H__ */
|
||||
|
||||
@ -1,27 +1,10 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/******************************************************************************
|
||||
* grant_table.h
|
||||
*
|
||||
* Interface for granting foreign access to page frames, and receiving
|
||||
* page-ownership transfers.
|
||||
*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
*
|
||||
* Copyright (c) 2004, K A Fraser
|
||||
*/
|
||||
|
||||
@ -45,7 +28,7 @@ FILE_LICENCE ( MIT );
|
||||
* table are identified by grant references. A grant reference is an
|
||||
* integer, which indexes into the grant table. It acts as a
|
||||
* capability which the grantee can use to perform operations on the
|
||||
* granter’s memory.
|
||||
* granter's memory.
|
||||
*
|
||||
* This capability-based system allows shared-memory communications
|
||||
* between unprivileged domains. A grant reference also encapsulates
|
||||
@ -123,8 +106,9 @@ typedef uint32_t grant_ref_t;
|
||||
*/
|
||||
|
||||
/*
|
||||
* Version 1 of the grant table entry structure is maintained purely
|
||||
* for backwards compatibility. New guests should use version 2.
|
||||
* Version 1 of the grant table entry structure is maintained largely for
|
||||
* backwards compatibility. New guests are recommended to support using
|
||||
* version 2 to overcome version 1 limitations, but to default to version 1.
|
||||
*/
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x0003020a
|
||||
#define grant_entry_v1 grant_entry
|
||||
@ -136,8 +120,10 @@ struct grant_entry_v1 {
|
||||
/* The domain being granted foreign privileges. [GST] */
|
||||
domid_t domid;
|
||||
/*
|
||||
* GTF_permit_access: Frame that @domid is allowed to map and access. [GST]
|
||||
* GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN]
|
||||
* GTF_permit_access: GFN that @domid is allowed to map and access. [GST]
|
||||
* GTF_accept_transfer: GFN that @domid is allowed to transfer into. [GST]
|
||||
* GTF_transfer_completed: MFN whose ownership transferred by @domid
|
||||
* (non-translated guests only). [XEN]
|
||||
*/
|
||||
uint32_t frame;
|
||||
};
|
||||
@ -166,11 +152,13 @@ typedef struct grant_entry_v1 grant_entry_v1_t;
|
||||
#define GTF_type_mask (3U<<0)
|
||||
|
||||
/*
|
||||
* Subflags for GTF_permit_access.
|
||||
* Subflags for GTF_permit_access and GTF_transitive.
|
||||
* GTF_readonly: Restrict @domid to read-only mappings and accesses. [GST]
|
||||
* GTF_reading: Grant entry is currently mapped for reading by @domid. [XEN]
|
||||
* GTF_writing: Grant entry is currently mapped for writing by @domid. [XEN]
|
||||
* GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags for the grant [GST]
|
||||
* Further subflags for GTF_permit_access only.
|
||||
* GTF_PAT, GTF_PWT, GTF_PCD: (x86) cache attribute flags to be used for
|
||||
* mappings of the grant [GST]
|
||||
* GTF_sub_page: Grant access to only a subrange of the page. @domid
|
||||
* will only be allowed to copy from the grant, and not
|
||||
* map it. [GST]
|
||||
@ -311,6 +299,7 @@ typedef uint16_t grant_status_t;
|
||||
#define GNTTABOP_get_status_frames 9
|
||||
#define GNTTABOP_get_version 10
|
||||
#define GNTTABOP_swap_grant_ref 11
|
||||
#define GNTTABOP_cache_flush 12
|
||||
#endif /* __XEN_INTERFACE_VERSION__ */
|
||||
/* ` } */
|
||||
|
||||
@ -322,7 +311,7 @@ typedef uint32_t grant_handle_t;
|
||||
/*
|
||||
* GNTTABOP_map_grant_ref: Map the grant entry (<dom>,<ref>) for access
|
||||
* by devices and/or host CPUs. If successful, <handle> is a tracking number
|
||||
* that must be presented later to destroy the mapping(s). On error, <handle>
|
||||
* that must be presented later to destroy the mapping(s). On error, <status>
|
||||
* is a negative status code.
|
||||
* NOTES:
|
||||
* 1. If GNTMAP_device_map is specified then <dev_bus_addr> is the address
|
||||
@ -410,12 +399,13 @@ typedef struct gnttab_dump_table gnttab_dump_table_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(gnttab_dump_table_t);
|
||||
|
||||
/*
|
||||
* GNTTABOP_transfer_grant_ref: Transfer <frame> to a foreign domain. The
|
||||
* foreign domain has previously registered its interest in the transfer via
|
||||
* <domid, ref>.
|
||||
* GNTTABOP_transfer: Transfer <frame> to a foreign domain. The foreign domain
|
||||
* has previously registered its interest in the transfer via <domid, ref>.
|
||||
*
|
||||
* Note that, even if the transfer fails, the specified page no longer belongs
|
||||
* to the calling domain *unless* the error is GNTST_bad_page.
|
||||
*
|
||||
* Note further that only PV guests can use this operation.
|
||||
*/
|
||||
struct gnttab_transfer {
|
||||
/* IN parameters. */
|
||||
@ -454,7 +444,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_t);
|
||||
|
||||
struct gnttab_copy {
|
||||
/* IN parameters. */
|
||||
struct {
|
||||
struct gnttab_copy_ptr {
|
||||
union {
|
||||
grant_ref_t ref;
|
||||
xen_pfn_t gmfn;
|
||||
@ -513,10 +503,9 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t);
|
||||
#if __XEN_INTERFACE_VERSION__ >= 0x0003020a
|
||||
/*
|
||||
* GNTTABOP_set_version: Request a particular version of the grant
|
||||
* table shared table structure. This operation can only be performed
|
||||
* once in any given domain. It must be performed before any grants
|
||||
* are activated; otherwise, the domain will be stuck with version 1.
|
||||
* The only defined versions are 1 and 2.
|
||||
* table shared table structure. This operation may be used to toggle
|
||||
* between different versions, but must be performed while no grants
|
||||
* are active. The only defined versions are 1 and 2.
|
||||
*/
|
||||
struct gnttab_set_version {
|
||||
/* IN/OUT parameters */
|
||||
@ -576,6 +565,25 @@ struct gnttab_swap_grant_ref {
|
||||
typedef struct gnttab_swap_grant_ref gnttab_swap_grant_ref_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t);
|
||||
|
||||
/*
|
||||
* Issue one or more cache maintenance operations on a portion of a
|
||||
* page granted to the calling domain by a foreign domain.
|
||||
*/
|
||||
struct gnttab_cache_flush {
|
||||
union {
|
||||
uint64_t dev_bus_addr;
|
||||
grant_ref_t ref;
|
||||
} a;
|
||||
uint16_t offset; /* offset from start of grant */
|
||||
uint16_t length; /* size within the grant */
|
||||
#define GNTTAB_CACHE_CLEAN (1u<<0)
|
||||
#define GNTTAB_CACHE_INVAL (1u<<1)
|
||||
#define GNTTAB_CACHE_SOURCE_GREF (1u<<31)
|
||||
uint32_t op;
|
||||
};
|
||||
typedef struct gnttab_cache_flush gnttab_cache_flush_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(gnttab_cache_flush_t);
|
||||
|
||||
#endif /* __XEN_INTERFACE_VERSION__ */
|
||||
|
||||
/*
|
||||
@ -606,9 +614,6 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t);
|
||||
#define _GNTMAP_contains_pte (4)
|
||||
#define GNTMAP_contains_pte (1<<_GNTMAP_contains_pte)
|
||||
|
||||
#define _GNTMAP_can_fail (5)
|
||||
#define GNTMAP_can_fail (1<<_GNTMAP_can_fail)
|
||||
|
||||
/*
|
||||
* Bits to be placed in guest kernel available PTE bits (architecture
|
||||
* dependent; only supported when XENFEAT_gnttab_map_avail_bits is set).
|
||||
@ -633,6 +638,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t);
|
||||
#define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary. */
|
||||
#define GNTST_address_too_big (-11) /* transfer page address too large. */
|
||||
#define GNTST_eagain (-12) /* Operation not done; try again. */
|
||||
#define GNTST_no_space (-13) /* Out of space (handles etc). */
|
||||
/* ` } */
|
||||
|
||||
#define GNTTABOP_error_msgs { \
|
||||
@ -648,7 +654,8 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_swap_grant_ref_t);
|
||||
"bad page", \
|
||||
"copy arguments cross page boundary", \
|
||||
"page address size too large", \
|
||||
"operation not done; try again" \
|
||||
"operation not done; try again", \
|
||||
"out of space", \
|
||||
}
|
||||
|
||||
#endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
|
||||
|
||||
@ -1,21 +1,6 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
* Copyright (c) 2007, Keir Fraser
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_HVM_HVM_OP_H__
|
||||
@ -32,12 +17,33 @@ FILE_LICENCE ( MIT );
|
||||
#define HVMOP_get_param 1
|
||||
struct xen_hvm_param {
|
||||
domid_t domid; /* IN */
|
||||
uint16_t pad;
|
||||
uint32_t index; /* IN */
|
||||
uint64_t value; /* IN/OUT */
|
||||
};
|
||||
typedef struct xen_hvm_param xen_hvm_param_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_param_t);
|
||||
|
||||
struct xen_hvm_altp2m_suppress_ve {
|
||||
uint16_t view;
|
||||
uint8_t suppress_ve; /* Boolean type. */
|
||||
uint8_t pad1;
|
||||
uint32_t pad2;
|
||||
uint64_t gfn;
|
||||
};
|
||||
|
||||
struct xen_hvm_altp2m_suppress_ve_multi {
|
||||
uint16_t view;
|
||||
uint8_t suppress_ve; /* Boolean type. */
|
||||
uint8_t pad1;
|
||||
int32_t first_error; /* Should be set to 0. */
|
||||
uint64_t first_gfn; /* Value may be updated. */
|
||||
uint64_t last_gfn;
|
||||
uint64_t first_error_gfn; /* Gfn of the first error. */
|
||||
};
|
||||
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00040900
|
||||
|
||||
/* Set the logical level of one of a domain's PCI INTx wires. */
|
||||
#define HVMOP_set_pci_intx_level 2
|
||||
struct xen_hvm_set_pci_intx_level {
|
||||
@ -76,63 +82,38 @@ struct xen_hvm_set_pci_link_route {
|
||||
typedef struct xen_hvm_set_pci_link_route xen_hvm_set_pci_link_route_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_pci_link_route_t);
|
||||
|
||||
#endif /* __XEN_INTERFACE_VERSION__ < 0x00040900 */
|
||||
|
||||
/* Flushes all VCPU TLBs: @arg must be NULL. */
|
||||
#define HVMOP_flush_tlbs 5
|
||||
|
||||
/*
|
||||
* hvmmem_type_t should not be defined when generating the corresponding
|
||||
* compat header. This will ensure that the improperly named HVMMEM_(*)
|
||||
* values are defined only once.
|
||||
*/
|
||||
#ifndef XEN_GENERATING_COMPAT_HEADERS
|
||||
|
||||
typedef enum {
|
||||
HVMMEM_ram_rw, /* Normal read/write guest RAM */
|
||||
HVMMEM_ram_ro, /* Read-only; writes are discarded */
|
||||
HVMMEM_mmio_dm, /* Reads and write go to the device model */
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00040700
|
||||
HVMMEM_mmio_write_dm, /* Read-only; writes go to the device model */
|
||||
#else
|
||||
HVMMEM_unused, /* Placeholder; setting memory to this type
|
||||
will fail for code after 4.7.0 */
|
||||
#endif
|
||||
HVMMEM_ioreq_server /* Memory type claimed by an ioreq server; type
|
||||
changes to this value are only allowed after
|
||||
an ioreq server has claimed its ownership.
|
||||
Only pages with HVMMEM_ram_rw are allowed to
|
||||
change to this type; conversely, pages with
|
||||
this type are only allowed to be changed back
|
||||
to HVMMEM_ram_rw. */
|
||||
} hvmmem_type_t;
|
||||
|
||||
/* Following tools-only interfaces may change in future. */
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
|
||||
/* Track dirty VRAM. */
|
||||
#define HVMOP_track_dirty_vram 6
|
||||
struct xen_hvm_track_dirty_vram {
|
||||
/* Domain to be tracked. */
|
||||
domid_t domid;
|
||||
/* Number of pages to track. */
|
||||
uint32_t nr;
|
||||
/* First pfn to track. */
|
||||
uint64_aligned_t first_pfn;
|
||||
/* OUT variable. */
|
||||
/* Dirty bitmap buffer. */
|
||||
XEN_GUEST_HANDLE_64(uint8) dirty_bitmap;
|
||||
};
|
||||
typedef struct xen_hvm_track_dirty_vram xen_hvm_track_dirty_vram_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_track_dirty_vram_t);
|
||||
|
||||
/* Notify that some pages got modified by the Device Model. */
|
||||
#define HVMOP_modified_memory 7
|
||||
struct xen_hvm_modified_memory {
|
||||
/* Domain to be updated. */
|
||||
domid_t domid;
|
||||
/* Number of pages. */
|
||||
uint32_t nr;
|
||||
/* First pfn. */
|
||||
uint64_aligned_t first_pfn;
|
||||
};
|
||||
typedef struct xen_hvm_modified_memory xen_hvm_modified_memory_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_modified_memory_t);
|
||||
|
||||
#define HVMOP_set_mem_type 8
|
||||
/* Notify that a region of memory is to be treated in a specific way. */
|
||||
struct xen_hvm_set_mem_type {
|
||||
/* Domain to be updated. */
|
||||
domid_t domid;
|
||||
/* Memory type */
|
||||
uint16_t hvmmem_type;
|
||||
/* Number of pages. */
|
||||
uint32_t nr;
|
||||
/* First pfn. */
|
||||
uint64_aligned_t first_pfn;
|
||||
};
|
||||
typedef struct xen_hvm_set_mem_type xen_hvm_set_mem_type_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_mem_type_t);
|
||||
|
||||
#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
|
||||
#endif /* XEN_GENERATING_COMPAT_HEADERS */
|
||||
|
||||
/* Hint from PV drivers for pagetable destruction. */
|
||||
#define HVMOP_pagetable_dying 9
|
||||
@ -171,38 +152,6 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_xentrace_t);
|
||||
/* Deprecated by XENMEM_access_op_get_access */
|
||||
#define HVMOP_get_mem_access 13
|
||||
|
||||
#define HVMOP_inject_trap 14
|
||||
/* Inject a trap into a VCPU, which will get taken up on the next
|
||||
* scheduling of it. Note that the caller should know enough of the
|
||||
* state of the CPU before injecting, to know what the effect of
|
||||
* injecting the trap will be.
|
||||
*/
|
||||
struct xen_hvm_inject_trap {
|
||||
/* Domain to be queried. */
|
||||
domid_t domid;
|
||||
/* VCPU */
|
||||
uint32_t vcpuid;
|
||||
/* Vector number */
|
||||
uint32_t vector;
|
||||
/* Trap type (HVMOP_TRAP_*) */
|
||||
uint32_t type;
|
||||
/* NB. This enumeration precisely matches hvm.h:X86_EVENTTYPE_* */
|
||||
# define HVMOP_TRAP_ext_int 0 /* external interrupt */
|
||||
# define HVMOP_TRAP_nmi 2 /* nmi */
|
||||
# define HVMOP_TRAP_hw_exc 3 /* hardware exception */
|
||||
# define HVMOP_TRAP_sw_int 4 /* software interrupt (CD nn) */
|
||||
# define HVMOP_TRAP_pri_sw_exc 5 /* ICEBP (F1) */
|
||||
# define HVMOP_TRAP_sw_exc 6 /* INT3 (CC), INTO (CE) */
|
||||
/* Error code, or ~0u to skip */
|
||||
uint32_t error_code;
|
||||
/* Intruction length */
|
||||
uint32_t insn_len;
|
||||
/* CR2 for page faults */
|
||||
uint64_aligned_t cr2;
|
||||
};
|
||||
typedef struct xen_hvm_inject_trap xen_hvm_inject_trap_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_trap_t);
|
||||
|
||||
#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
|
||||
|
||||
#define HVMOP_get_mem_type 15
|
||||
@ -222,155 +171,202 @@ DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_mem_type_t);
|
||||
/* Following tools-only interfaces may change in future. */
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
|
||||
/* MSI injection for emulated devices */
|
||||
#define HVMOP_inject_msi 16
|
||||
struct xen_hvm_inject_msi {
|
||||
/* Domain to be injected */
|
||||
domid_t domid;
|
||||
/* Data -- lower 32 bits */
|
||||
uint32_t data;
|
||||
/* Address (0xfeexxxxx) */
|
||||
uint64_t addr;
|
||||
};
|
||||
typedef struct xen_hvm_inject_msi xen_hvm_inject_msi_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_inject_msi_t);
|
||||
|
||||
/*
|
||||
* IOREQ Servers
|
||||
*
|
||||
* The interface between an I/O emulator an Xen is called an IOREQ Server.
|
||||
* A domain supports a single 'legacy' IOREQ Server which is instantiated if
|
||||
* parameter...
|
||||
*
|
||||
* HVM_PARAM_IOREQ_PFN is read (to get the gmfn containing the synchronous
|
||||
* ioreq structures), or...
|
||||
* HVM_PARAM_BUFIOREQ_PFN is read (to get the gmfn containing the buffered
|
||||
* ioreq ring), or...
|
||||
* HVM_PARAM_BUFIOREQ_EVTCHN is read (to get the event channel that Xen uses
|
||||
* to request buffered I/O emulation).
|
||||
*
|
||||
* The following hypercalls facilitate the creation of IOREQ Servers for
|
||||
* 'secondary' emulators which are invoked to implement port I/O, memory, or
|
||||
* PCI config space ranges which they explicitly register.
|
||||
* Definitions relating to DMOP_create_ioreq_server. (Defined here for
|
||||
* backwards compatibility).
|
||||
*/
|
||||
|
||||
typedef uint16_t ioservid_t;
|
||||
|
||||
#define HVM_IOREQSRV_BUFIOREQ_OFF 0
|
||||
#define HVM_IOREQSRV_BUFIOREQ_LEGACY 1
|
||||
/*
|
||||
* HVMOP_create_ioreq_server: Instantiate a new IOREQ Server for a secondary
|
||||
* emulator servicing domain <domid>.
|
||||
*
|
||||
* The <id> handed back is unique for <domid>. If <handle_bufioreq> is zero
|
||||
* the buffered ioreq ring will not be allocated and hence all emulation
|
||||
* requestes to this server will be synchronous.
|
||||
* Use this when read_pointer gets updated atomically and
|
||||
* the pointer pair gets read atomically:
|
||||
*/
|
||||
#define HVMOP_create_ioreq_server 17
|
||||
struct xen_hvm_create_ioreq_server {
|
||||
domid_t domid; /* IN - domain to be serviced */
|
||||
uint8_t handle_bufioreq; /* IN - should server handle buffered ioreqs */
|
||||
ioservid_t id; /* OUT - server id */
|
||||
};
|
||||
typedef struct xen_hvm_create_ioreq_server xen_hvm_create_ioreq_server_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_create_ioreq_server_t);
|
||||
|
||||
/*
|
||||
* HVMOP_get_ioreq_server_info: Get all the information necessary to access
|
||||
* IOREQ Server <id>.
|
||||
*
|
||||
* The emulator needs to map the synchronous ioreq structures and buffered
|
||||
* ioreq ring (if it exists) that Xen uses to request emulation. These are
|
||||
* hosted in domain <domid>'s gmfns <ioreq_pfn> and <bufioreq_pfn>
|
||||
* respectively. In addition, if the IOREQ Server is handling buffered
|
||||
* emulation requests, the emulator needs to bind to event channel
|
||||
* <bufioreq_port> to listen for them. (The event channels used for
|
||||
* synchronous emulation requests are specified in the per-CPU ioreq
|
||||
* structures in <ioreq_pfn>).
|
||||
* If the IOREQ Server is not handling buffered emulation requests then the
|
||||
* values handed back in <bufioreq_pfn> and <bufioreq_port> will both be 0.
|
||||
*/
|
||||
#define HVMOP_get_ioreq_server_info 18
|
||||
struct xen_hvm_get_ioreq_server_info {
|
||||
domid_t domid; /* IN - domain to be serviced */
|
||||
ioservid_t id; /* IN - server id */
|
||||
evtchn_port_t bufioreq_port; /* OUT - buffered ioreq port */
|
||||
uint64_aligned_t ioreq_pfn; /* OUT - sync ioreq pfn */
|
||||
uint64_aligned_t bufioreq_pfn; /* OUT - buffered ioreq pfn */
|
||||
};
|
||||
typedef struct xen_hvm_get_ioreq_server_info xen_hvm_get_ioreq_server_info_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_get_ioreq_server_info_t);
|
||||
|
||||
/*
|
||||
* HVM_map_io_range_to_ioreq_server: Register an I/O range of domain <domid>
|
||||
* for emulation by the client of IOREQ
|
||||
* Server <id>
|
||||
* HVM_unmap_io_range_from_ioreq_server: Deregister an I/O range of <domid>
|
||||
* for emulation by the client of IOREQ
|
||||
* Server <id>
|
||||
*
|
||||
* There are three types of I/O that can be emulated: port I/O, memory accesses
|
||||
* and PCI config space accesses. The <type> field denotes which type of range
|
||||
* the <start> and <end> (inclusive) fields are specifying.
|
||||
* PCI config space ranges are specified by segment/bus/device/function values
|
||||
* which should be encoded using the HVMOP_PCI_SBDF helper macro below.
|
||||
*
|
||||
* NOTE: unless an emulation request falls entirely within a range mapped
|
||||
* by a secondary emulator, it will not be passed to that emulator.
|
||||
*/
|
||||
#define HVMOP_map_io_range_to_ioreq_server 19
|
||||
#define HVMOP_unmap_io_range_from_ioreq_server 20
|
||||
struct xen_hvm_io_range {
|
||||
domid_t domid; /* IN - domain to be serviced */
|
||||
ioservid_t id; /* IN - server id */
|
||||
uint32_t type; /* IN - type of range */
|
||||
# define HVMOP_IO_RANGE_PORT 0 /* I/O port range */
|
||||
# define HVMOP_IO_RANGE_MEMORY 1 /* MMIO range */
|
||||
# define HVMOP_IO_RANGE_PCI 2 /* PCI segment/bus/dev/func range */
|
||||
uint64_aligned_t start, end; /* IN - inclusive start and end of range */
|
||||
};
|
||||
typedef struct xen_hvm_io_range xen_hvm_io_range_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_io_range_t);
|
||||
|
||||
#define HVMOP_PCI_SBDF(s,b,d,f) \
|
||||
((((s) & 0xffff) << 16) | \
|
||||
(((b) & 0xff) << 8) | \
|
||||
(((d) & 0x1f) << 3) | \
|
||||
((f) & 0x07))
|
||||
|
||||
/*
|
||||
* HVMOP_destroy_ioreq_server: Destroy the IOREQ Server <id> servicing domain
|
||||
* <domid>.
|
||||
*
|
||||
* Any registered I/O ranges will be automatically deregistered.
|
||||
*/
|
||||
#define HVMOP_destroy_ioreq_server 21
|
||||
struct xen_hvm_destroy_ioreq_server {
|
||||
domid_t domid; /* IN - domain to be serviced */
|
||||
ioservid_t id; /* IN - server id */
|
||||
};
|
||||
typedef struct xen_hvm_destroy_ioreq_server xen_hvm_destroy_ioreq_server_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_destroy_ioreq_server_t);
|
||||
|
||||
/*
|
||||
* HVMOP_set_ioreq_server_state: Enable or disable the IOREQ Server <id> servicing
|
||||
* domain <domid>.
|
||||
*
|
||||
* The IOREQ Server will not be passed any emulation requests until it is in the
|
||||
* enabled state.
|
||||
* Note that the contents of the ioreq_pfn and bufioreq_fn (see
|
||||
* HVMOP_get_ioreq_server_info) are not meaningful until the IOREQ Server is in
|
||||
* the enabled state.
|
||||
*/
|
||||
#define HVMOP_set_ioreq_server_state 22
|
||||
struct xen_hvm_set_ioreq_server_state {
|
||||
domid_t domid; /* IN - domain to be serviced */
|
||||
ioservid_t id; /* IN - server id */
|
||||
uint8_t enabled; /* IN - enabled? */
|
||||
};
|
||||
typedef struct xen_hvm_set_ioreq_server_state xen_hvm_set_ioreq_server_state_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_set_ioreq_server_state_t);
|
||||
#define HVM_IOREQSRV_BUFIOREQ_ATOMIC 2
|
||||
|
||||
#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
/*
|
||||
* HVMOP_set_evtchn_upcall_vector: Set a <vector> that should be used for event
|
||||
* channel upcalls on the specified <vcpu>. If set,
|
||||
* this vector will be used in preference to the
|
||||
* domain global callback via (see
|
||||
* HVM_PARAM_CALLBACK_IRQ).
|
||||
*/
|
||||
#define HVMOP_set_evtchn_upcall_vector 23
|
||||
struct xen_hvm_evtchn_upcall_vector {
|
||||
uint32_t vcpu;
|
||||
uint8_t vector;
|
||||
};
|
||||
typedef struct xen_hvm_evtchn_upcall_vector xen_hvm_evtchn_upcall_vector_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_evtchn_upcall_vector_t);
|
||||
|
||||
#endif /* defined(__i386__) || defined(__x86_64__) */
|
||||
|
||||
#define HVMOP_guest_request_vm_event 24
|
||||
|
||||
/* HVMOP_altp2m: perform altp2m state operations */
|
||||
#define HVMOP_altp2m 25
|
||||
|
||||
#define HVMOP_ALTP2M_INTERFACE_VERSION 0x00000001
|
||||
|
||||
struct xen_hvm_altp2m_domain_state {
|
||||
/* IN or OUT variable on/off */
|
||||
uint8_t state;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_domain_state xen_hvm_altp2m_domain_state_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_domain_state_t);
|
||||
|
||||
struct xen_hvm_altp2m_vcpu_enable_notify {
|
||||
uint32_t vcpu_id;
|
||||
uint32_t pad;
|
||||
/* #VE info area gfn */
|
||||
uint64_t gfn;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t);
|
||||
|
||||
struct xen_hvm_altp2m_vcpu_disable_notify {
|
||||
uint32_t vcpu_id;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_vcpu_disable_notify xen_hvm_altp2m_vcpu_disable_notify_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_disable_notify_t);
|
||||
|
||||
struct xen_hvm_altp2m_view {
|
||||
/* IN/OUT variable */
|
||||
uint16_t view;
|
||||
uint16_t hvmmem_default_access; /* xenmem_access_t */
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_view xen_hvm_altp2m_view_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_view_t);
|
||||
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00040a00
|
||||
struct xen_hvm_altp2m_set_mem_access {
|
||||
/* view */
|
||||
uint16_t view;
|
||||
/* Memory type */
|
||||
uint16_t access; /* xenmem_access_t */
|
||||
uint32_t pad;
|
||||
/* gfn */
|
||||
uint64_t gfn;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t);
|
||||
#endif /* __XEN_INTERFACE_VERSION__ < 0x00040a00 */
|
||||
|
||||
struct xen_hvm_altp2m_mem_access {
|
||||
/* view */
|
||||
uint16_t view;
|
||||
/* Memory type */
|
||||
uint16_t access; /* xenmem_access_t */
|
||||
uint32_t pad;
|
||||
/* gfn */
|
||||
uint64_t gfn;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_mem_access xen_hvm_altp2m_mem_access_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_mem_access_t);
|
||||
|
||||
struct xen_hvm_altp2m_set_mem_access_multi {
|
||||
/* view */
|
||||
uint16_t view;
|
||||
uint16_t pad;
|
||||
/* Number of pages */
|
||||
uint32_t nr;
|
||||
/*
|
||||
* Used for continuation purposes.
|
||||
* Must be set to zero upon initial invocation.
|
||||
*/
|
||||
uint64_t opaque;
|
||||
/* List of pfns to set access for */
|
||||
XEN_GUEST_HANDLE(const_uint64) pfn_list;
|
||||
/* Corresponding list of access settings for pfn_list */
|
||||
XEN_GUEST_HANDLE(const_uint8) access_list;
|
||||
};
|
||||
|
||||
struct xen_hvm_altp2m_change_gfn {
|
||||
/* view */
|
||||
uint16_t view;
|
||||
uint16_t pad1;
|
||||
uint32_t pad2;
|
||||
/* old gfn */
|
||||
uint64_t old_gfn;
|
||||
/* new gfn, INVALID_GFN (~0UL) means revert */
|
||||
uint64_t new_gfn;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_change_gfn xen_hvm_altp2m_change_gfn_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_change_gfn_t);
|
||||
|
||||
struct xen_hvm_altp2m_get_vcpu_p2m_idx {
|
||||
uint32_t vcpu_id;
|
||||
uint16_t altp2m_idx;
|
||||
};
|
||||
|
||||
struct xen_hvm_altp2m_set_visibility {
|
||||
uint16_t altp2m_idx;
|
||||
uint8_t visible;
|
||||
uint8_t pad;
|
||||
};
|
||||
|
||||
struct xen_hvm_altp2m_op {
|
||||
uint32_t version; /* HVMOP_ALTP2M_INTERFACE_VERSION */
|
||||
uint32_t cmd;
|
||||
/* Get/set the altp2m state for a domain */
|
||||
#define HVMOP_altp2m_get_domain_state 1
|
||||
#define HVMOP_altp2m_set_domain_state 2
|
||||
/* Set a given VCPU to receive altp2m event notifications */
|
||||
#define HVMOP_altp2m_vcpu_enable_notify 3
|
||||
/* Create a new view */
|
||||
#define HVMOP_altp2m_create_p2m 4
|
||||
/* Destroy a view */
|
||||
#define HVMOP_altp2m_destroy_p2m 5
|
||||
/* Switch view for an entire domain */
|
||||
#define HVMOP_altp2m_switch_p2m 6
|
||||
/* Notify that a page of memory is to have specific access types */
|
||||
#define HVMOP_altp2m_set_mem_access 7
|
||||
/* Change a p2m entry to have a different gfn->mfn mapping */
|
||||
#define HVMOP_altp2m_change_gfn 8
|
||||
/* Set access for an array of pages */
|
||||
#define HVMOP_altp2m_set_mem_access_multi 9
|
||||
/* Set the "Suppress #VE" bit on a page */
|
||||
#define HVMOP_altp2m_set_suppress_ve 10
|
||||
/* Get the "Suppress #VE" bit of a page */
|
||||
#define HVMOP_altp2m_get_suppress_ve 11
|
||||
/* Get the access of a page of memory from a certain view */
|
||||
#define HVMOP_altp2m_get_mem_access 12
|
||||
/* Disable altp2m event notifications for a given VCPU */
|
||||
#define HVMOP_altp2m_vcpu_disable_notify 13
|
||||
/* Get the active vcpu p2m index */
|
||||
#define HVMOP_altp2m_get_p2m_idx 14
|
||||
/* Set the "Supress #VE" bit for a range of pages */
|
||||
#define HVMOP_altp2m_set_suppress_ve_multi 15
|
||||
/* Set visibility for a given altp2m view */
|
||||
#define HVMOP_altp2m_set_visibility 16
|
||||
domid_t domain;
|
||||
uint16_t pad1;
|
||||
uint32_t pad2;
|
||||
union {
|
||||
struct xen_hvm_altp2m_domain_state domain_state;
|
||||
struct xen_hvm_altp2m_vcpu_enable_notify enable_notify;
|
||||
struct xen_hvm_altp2m_view view;
|
||||
#if __XEN_INTERFACE_VERSION__ < 0x00040a00
|
||||
struct xen_hvm_altp2m_set_mem_access set_mem_access;
|
||||
#endif /* __XEN_INTERFACE_VERSION__ < 0x00040a00 */
|
||||
struct xen_hvm_altp2m_mem_access mem_access;
|
||||
struct xen_hvm_altp2m_change_gfn change_gfn;
|
||||
struct xen_hvm_altp2m_set_mem_access_multi set_mem_access_multi;
|
||||
struct xen_hvm_altp2m_suppress_ve suppress_ve;
|
||||
struct xen_hvm_altp2m_suppress_ve_multi suppress_ve_multi;
|
||||
struct xen_hvm_altp2m_vcpu_disable_notify disable_notify;
|
||||
struct xen_hvm_altp2m_get_vcpu_p2m_idx get_vcpu_p2m_idx;
|
||||
struct xen_hvm_altp2m_set_visibility set_visibility;
|
||||
uint8_t pad[64];
|
||||
} u;
|
||||
};
|
||||
typedef struct xen_hvm_altp2m_op xen_hvm_altp2m_op_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_op_t);
|
||||
|
||||
#endif /* __XEN_PUBLIC_HVM_HVM_OP_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@ -1,21 +1,6 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
/*
|
||||
* 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 THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS 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.
|
||||
* Copyright (c) 2007, Keir Fraser
|
||||
*/
|
||||
|
||||
#ifndef __XEN_PUBLIC_HVM_PARAMS_H__
|
||||
@ -25,22 +10,67 @@ FILE_LICENCE ( MIT );
|
||||
|
||||
#include "hvm_op.h"
|
||||
|
||||
/* These parameters are deprecated and their meaning is undefined. */
|
||||
#if defined(__XEN__) || defined(__XEN_TOOLS__)
|
||||
|
||||
#define HVM_PARAM_PAE_ENABLED 4
|
||||
#define HVM_PARAM_DM_DOMAIN 13
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR0 20
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR3 21
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR4 22
|
||||
#define HVM_PARAM_MEMORY_EVENT_INT3 23
|
||||
#define HVM_PARAM_NESTEDHVM 24
|
||||
#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25
|
||||
#define HVM_PARAM_BUFIOREQ_EVTCHN 26
|
||||
#define HVM_PARAM_MEMORY_EVENT_MSR 30
|
||||
|
||||
#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
|
||||
|
||||
/*
|
||||
* Parameter space for HVMOP_{set,get}_param.
|
||||
*/
|
||||
|
||||
#define HVM_PARAM_CALLBACK_IRQ 0
|
||||
#define HVM_PARAM_CALLBACK_IRQ_TYPE_MASK xen_mk_ullong(0xFF00000000000000)
|
||||
/*
|
||||
* How should CPU0 event-channel notifications be delivered?
|
||||
* val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt).
|
||||
* val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows:
|
||||
* Domain = val[47:32], Bus = val[31:16],
|
||||
* DevFn = val[15: 8], IntX = val[ 1: 0]
|
||||
* val[63:56] == 2: val[7:0] is a vector number, check for
|
||||
* XENFEAT_hvm_callback_vector to know if this delivery
|
||||
* method is available.
|
||||
*
|
||||
* If val == 0 then CPU0 event-channel notifications are not delivered.
|
||||
* If val != 0, val[63:56] encodes the type, as follows:
|
||||
*/
|
||||
#define HVM_PARAM_CALLBACK_IRQ 0
|
||||
|
||||
#define HVM_PARAM_CALLBACK_TYPE_GSI 0
|
||||
/*
|
||||
* val[55:0] is a delivery GSI. GSI 0 cannot be used, as it aliases val == 0,
|
||||
* and disables all notifications.
|
||||
*/
|
||||
|
||||
#define HVM_PARAM_CALLBACK_TYPE_PCI_INTX 1
|
||||
/*
|
||||
* val[55:0] is a delivery PCI INTx line:
|
||||
* Domain = val[47:32], Bus = val[31:16] DevFn = val[15:8], IntX = val[1:0]
|
||||
*/
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define HVM_PARAM_CALLBACK_TYPE_VECTOR 2
|
||||
/*
|
||||
* val[7:0] is a vector number. Check for XENFEAT_hvm_callback_vector to know
|
||||
* if this delivery method is available.
|
||||
*/
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
#define HVM_PARAM_CALLBACK_TYPE_PPI 2
|
||||
/*
|
||||
* val[55:16] needs to be zero.
|
||||
* val[15:8] is interrupt flag of the PPI used by event-channel:
|
||||
* bit 8: the PPI is edge(1) or level(0) triggered
|
||||
* bit 9: the PPI is active low(1) or high(0)
|
||||
* val[7:0] is a PPI number used by event-channel.
|
||||
* This is only used by ARM/ARM64 and masking/eoi the interrupt associated to
|
||||
* the notification is handled by the interrupt controller.
|
||||
*/
|
||||
#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_MASK 0xFF00
|
||||
#define HVM_PARAM_CALLBACK_TYPE_PPI_FLAG_LOW_LEVEL 2
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These are not used by Xen. They are here for convenience of HVM-guest
|
||||
@ -49,18 +79,103 @@ FILE_LICENCE ( MIT );
|
||||
#define HVM_PARAM_STORE_PFN 1
|
||||
#define HVM_PARAM_STORE_EVTCHN 2
|
||||
|
||||
#define HVM_PARAM_PAE_ENABLED 4
|
||||
|
||||
#define HVM_PARAM_IOREQ_PFN 5
|
||||
|
||||
#define HVM_PARAM_BUFIOREQ_PFN 6
|
||||
#define HVM_PARAM_BUFIOREQ_EVTCHN 26
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
|
||||
/* Expose Viridian interfaces to this HVM guest? */
|
||||
/*
|
||||
* Viridian enlightenments
|
||||
*
|
||||
* (See http://download.microsoft.com/download/A/B/4/AB43A34E-BDD0-4FA6-BDEF-79EEF16E880B/Hypervisor%20Top%20Level%20Functional%20Specification%20v4.0.docx)
|
||||
*
|
||||
* To expose viridian enlightenments to the guest set this parameter
|
||||
* to the desired feature mask. The base feature set must be present
|
||||
* in any valid feature mask.
|
||||
*/
|
||||
#define HVM_PARAM_VIRIDIAN 9
|
||||
|
||||
/* Base+Freq viridian feature sets:
|
||||
*
|
||||
* - Hypercall MSRs (HV_X64_MSR_GUEST_OS_ID and HV_X64_MSR_HYPERCALL)
|
||||
* - APIC access MSRs (HV_X64_MSR_EOI, HV_X64_MSR_ICR and HV_X64_MSR_TPR)
|
||||
* - Virtual Processor index MSR (HV_X64_MSR_VP_INDEX)
|
||||
* - Timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
|
||||
* HV_X64_MSR_APIC_FREQUENCY)
|
||||
*/
|
||||
#define _HVMPV_base_freq 0
|
||||
#define HVMPV_base_freq (1 << _HVMPV_base_freq)
|
||||
|
||||
/* Feature set modifications */
|
||||
|
||||
/* Disable timer frequency MSRs (HV_X64_MSR_TSC_FREQUENCY and
|
||||
* HV_X64_MSR_APIC_FREQUENCY).
|
||||
* This modification restores the viridian feature set to the
|
||||
* original 'base' set exposed in releases prior to Xen 4.4.
|
||||
*/
|
||||
#define _HVMPV_no_freq 1
|
||||
#define HVMPV_no_freq (1 << _HVMPV_no_freq)
|
||||
|
||||
/* Enable Partition Time Reference Counter (HV_X64_MSR_TIME_REF_COUNT) */
|
||||
#define _HVMPV_time_ref_count 2
|
||||
#define HVMPV_time_ref_count (1 << _HVMPV_time_ref_count)
|
||||
|
||||
/* Enable Reference TSC Page (HV_X64_MSR_REFERENCE_TSC) */
|
||||
#define _HVMPV_reference_tsc 3
|
||||
#define HVMPV_reference_tsc (1 << _HVMPV_reference_tsc)
|
||||
|
||||
/* Use Hypercall for remote TLB flush */
|
||||
#define _HVMPV_hcall_remote_tlb_flush 4
|
||||
#define HVMPV_hcall_remote_tlb_flush (1 << _HVMPV_hcall_remote_tlb_flush)
|
||||
|
||||
/* Use APIC assist */
|
||||
#define _HVMPV_apic_assist 5
|
||||
#define HVMPV_apic_assist (1 << _HVMPV_apic_assist)
|
||||
|
||||
/* Enable crash MSRs */
|
||||
#define _HVMPV_crash_ctl 6
|
||||
#define HVMPV_crash_ctl (1 << _HVMPV_crash_ctl)
|
||||
|
||||
/* Enable SYNIC MSRs */
|
||||
#define _HVMPV_synic 7
|
||||
#define HVMPV_synic (1 << _HVMPV_synic)
|
||||
|
||||
/* Enable STIMER MSRs */
|
||||
#define _HVMPV_stimer 8
|
||||
#define HVMPV_stimer (1 << _HVMPV_stimer)
|
||||
|
||||
/* Use Synthetic Cluster IPI Hypercall */
|
||||
#define _HVMPV_hcall_ipi 9
|
||||
#define HVMPV_hcall_ipi (1 << _HVMPV_hcall_ipi)
|
||||
|
||||
/* Enable ExProcessorMasks */
|
||||
#define _HVMPV_ex_processor_masks 10
|
||||
#define HVMPV_ex_processor_masks (1 << _HVMPV_ex_processor_masks)
|
||||
|
||||
/* Allow more than 64 VPs */
|
||||
#define _HVMPV_no_vp_limit 11
|
||||
#define HVMPV_no_vp_limit (1 << _HVMPV_no_vp_limit)
|
||||
|
||||
/* Enable vCPU hotplug */
|
||||
#define _HVMPV_cpu_hotplug 12
|
||||
#define HVMPV_cpu_hotplug (1 << _HVMPV_cpu_hotplug)
|
||||
|
||||
#define HVMPV_feature_mask \
|
||||
(HVMPV_base_freq | \
|
||||
HVMPV_no_freq | \
|
||||
HVMPV_time_ref_count | \
|
||||
HVMPV_reference_tsc | \
|
||||
HVMPV_hcall_remote_tlb_flush | \
|
||||
HVMPV_apic_assist | \
|
||||
HVMPV_crash_ctl | \
|
||||
HVMPV_synic | \
|
||||
HVMPV_stimer | \
|
||||
HVMPV_hcall_ipi | \
|
||||
HVMPV_ex_processor_masks | \
|
||||
HVMPV_no_vp_limit | \
|
||||
HVMPV_cpu_hotplug)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -94,9 +209,6 @@ FILE_LICENCE ( MIT );
|
||||
/* Identity-map page directory used by Intel EPT when CR0.PG=0. */
|
||||
#define HVM_PARAM_IDENT_PT 12
|
||||
|
||||
/* Device Model domain, defaults to 0. */
|
||||
#define HVM_PARAM_DM_DOMAIN 13
|
||||
|
||||
/* ACPI S state: currently support S0 and S3 on x86. */
|
||||
#define HVM_PARAM_ACPI_S_STATE 14
|
||||
|
||||
@ -121,27 +233,9 @@ FILE_LICENCE ( MIT );
|
||||
*/
|
||||
#define HVM_PARAM_ACPI_IOPORTS_LOCATION 19
|
||||
|
||||
/* Enable blocking memory events, async or sync (pause vcpu until response)
|
||||
* onchangeonly indicates messages only on a change of value */
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR0 20
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR3 21
|
||||
#define HVM_PARAM_MEMORY_EVENT_CR4 22
|
||||
#define HVM_PARAM_MEMORY_EVENT_INT3 23
|
||||
#define HVM_PARAM_MEMORY_EVENT_SINGLE_STEP 25
|
||||
#define HVM_PARAM_MEMORY_EVENT_MSR 30
|
||||
|
||||
#define HVMPME_MODE_MASK (3 << 0)
|
||||
#define HVMPME_mode_disabled 0
|
||||
#define HVMPME_mode_async 1
|
||||
#define HVMPME_mode_sync 2
|
||||
#define HVMPME_onchangeonly (1 << 2)
|
||||
|
||||
/* Boolean: Enable nestedhvm (hvm only) */
|
||||
#define HVM_PARAM_NESTEDHVM 24
|
||||
|
||||
/* Params for the mem event rings */
|
||||
#define HVM_PARAM_PAGING_RING_PFN 27
|
||||
#define HVM_PARAM_ACCESS_RING_PFN 28
|
||||
#define HVM_PARAM_MONITOR_RING_PFN 28
|
||||
#define HVM_PARAM_SHARING_RING_PFN 29
|
||||
|
||||
/* SHUTDOWN_* action in case of a triple fault */
|
||||
@ -153,6 +247,57 @@ FILE_LICENCE ( MIT );
|
||||
/* Location of the VM Generation ID in guest physical address space. */
|
||||
#define HVM_PARAM_VM_GENERATION_ID_ADDR 34
|
||||
|
||||
#define HVM_NR_PARAMS 35
|
||||
/*
|
||||
* Set mode for altp2m:
|
||||
* disabled: don't activate altp2m (default)
|
||||
* mixed: allow access to all altp2m ops for both in-guest and external tools
|
||||
* external: allow access to external privileged tools only
|
||||
* limited: guest only has limited access (ie. control VMFUNC and #VE)
|
||||
*
|
||||
* Note that 'mixed' mode has not been evaluated for safety from a
|
||||
* security perspective. Before using this mode in a
|
||||
* security-critical environment, each subop should be evaluated for
|
||||
* safety, with unsafe subops blacklisted in XSM.
|
||||
*/
|
||||
#define HVM_PARAM_ALTP2M 35
|
||||
#define XEN_ALTP2M_disabled 0
|
||||
#define XEN_ALTP2M_mixed 1
|
||||
#define XEN_ALTP2M_external 2
|
||||
#define XEN_ALTP2M_limited 3
|
||||
|
||||
/*
|
||||
* Size of the x87 FPU FIP/FDP registers that the hypervisor needs to
|
||||
* save/restore. This is a workaround for a hardware limitation that
|
||||
* does not allow the full FIP/FDP and FCS/FDS to be restored.
|
||||
*
|
||||
* Valid values are:
|
||||
*
|
||||
* 8: save/restore 64-bit FIP/FDP and clear FCS/FDS (default if CPU
|
||||
* has FPCSDS feature).
|
||||
*
|
||||
* 4: save/restore 32-bit FIP/FDP, FCS/FDS, and clear upper 32-bits of
|
||||
* FIP/FDP.
|
||||
*
|
||||
* 0: allow hypervisor to choose based on the value of FIP/FDP
|
||||
* (default if CPU does not have FPCSDS).
|
||||
*
|
||||
* If FPCSDS (bit 13 in CPUID leaf 0x7, subleaf 0x0) is set, the CPU
|
||||
* never saves FCS/FDS and this parameter should be left at the
|
||||
* default of 8.
|
||||
*/
|
||||
#define HVM_PARAM_X87_FIP_WIDTH 36
|
||||
|
||||
/*
|
||||
* TSS (and its size) used on Intel when CR0.PE=0. The address occupies
|
||||
* the low 32 bits, while the size is in the high 32 ones.
|
||||
*/
|
||||
#define HVM_PARAM_VM86_TSS_SIZED 37
|
||||
|
||||
/* Enable MCA capabilities. */
|
||||
#define HVM_PARAM_MCA_CAP 38
|
||||
#define XEN_HVM_MCA_CAP_LMCE (xen_mk_ullong(1) << 0)
|
||||
#define XEN_HVM_MCA_CAP_MASK XEN_HVM_MCA_CAP_LMCE
|
||||
|
||||
#define HVM_NR_PARAMS 39
|
||||
|
||||
#endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */
|
||||
|
||||
@ -59,6 +59,10 @@ sub try_import_file {
|
||||
if ( /^\#include\s+[<\"](\S+)[>\"]/ ) {
|
||||
push @dependencies, catfile ( $subdir, $1 );
|
||||
}
|
||||
# Patch "Unsupported architecture" line
|
||||
if ( /^\#error\s+"Unsupported\sarchitecture"/ ) {
|
||||
$_ = "#include <bits/xen.h>"
|
||||
}
|
||||
# Write out line
|
||||
print $outfh "$_\n";
|
||||
# Apply FILE_LICENCE() immediately after include guard
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user