mirror of
				https://gitlab.com/qemu-project/ipxe.git
				synced 2025-11-03 07:59:06 +08:00 
			
		
		
		
	Compare commits
	
		
			100 Commits
		
	
	
		
			vgafix
			...
			interprete
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dcb50f550d | |||
| e51e7bbad7 | |||
| 523788ccda | |||
| 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 | |||
| 66a2ff442d | |||
| 3bcd0d3271 | |||
| 4bb521a8c4 | |||
| b9be454010 | |||
| e3d543437e | |||
| 137ca5d877 | |||
| 900379594a | |||
| 91944c6341 | |||
| dac41fc4ec | |||
| 5220bdc524 | |||
| 38f54fb413 | |||
| 5bf8b11527 | |||
| 2d180ce233 | |||
| 4bffe0f0d9 | |||
| c5426cdaa9 | |||
| e72670ad7b | |||
| 68734b9a4d | |||
| 2fef0c541e | |||
| 1cd0a248cc | |||
| 204d39222a | |||
| fcfb70bfb2 | |||
| c5e1f007ac | |||
| 9de6c45dd3 | |||
| 8f59911b20 | |||
| 2061d658b3 | |||
| 2ef5f5e05e | |||
| 475c0dfa8e | |||
| a99e435c8e | |||
| 6b977d1250 | |||
| 08740220ba | |||
| 2dcef4b7a1 | |||
| f07630c74f | |||
| 5a2fa6040e | |||
| c4c03e5be8 | |||
| 47af48012e | |||
| ab19546386 | |||
| 7147532c3f | |||
| 60b5532cfc | |||
| b9571ca12e | |||
| 099e4d39b3 | |||
| 0f3ace92c6 | |||
| d879c8e4d9 | |||
| 5e62b4bc6c | |||
| b0ded89e91 | |||
| 54c4c1d403 | |||
| 563bff4722 | |||
| 2ae5355321 | |||
| ca2be7e094 | |||
| 688646fe6d | |||
| f5c829b6f8 | |||
| 4acded7e57 | |||
| 63fdd9b581 | |||
| 63577207ab | |||
| 7256a6eb24 | |||
| 51ecc05490 | |||
| 54d83e92f0 | |||
| 186306d619 | |||
| 634a86093a | |||
| c453b4c284 | |||
| b6eef14858 | |||
| 6a360ebfde | |||
| 30243ad739 | |||
| d1bc872a2e | |||
| f8565a655e | |||
| 7b60a48752 | 
							
								
								
									
										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 }} \
 | 
			
		||||
 | 
			
		||||
@ -369,7 +369,6 @@ endif
 | 
			
		||||
# Include architecture-specific include path
 | 
			
		||||
ifdef ARCH
 | 
			
		||||
INCDIRS		+= arch/$(ARCH)/include
 | 
			
		||||
INCDIRS		+= arch/$(ARCH)/include/$(PLATFORM)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
###############################################################################
 | 
			
		||||
@ -462,7 +461,9 @@ ifeq ($(CCTYPE),gcc)
 | 
			
		||||
CFLAGS		+= -ffreestanding
 | 
			
		||||
CFLAGS		+= -fcommon
 | 
			
		||||
CFLAGS		+= -Wall -W -Wformat-nonliteral
 | 
			
		||||
CFLAGS		+= -Wno-array-bounds -Wno-dangling-pointer
 | 
			
		||||
HOST_CFLAGS	+= -Wall -W -Wformat-nonliteral
 | 
			
		||||
HOST_CFLAGS	+= -Wno-array-bounds -Wno-dangling-pointer
 | 
			
		||||
endif
 | 
			
		||||
CFLAGS		+= $(WORKAROUND_CFLAGS) $(EXTRA_CFLAGS)
 | 
			
		||||
ASFLAGS		+= $(WORKAROUND_ASFLAGS) $(EXTRA_ASFLAGS)
 | 
			
		||||
@ -510,6 +511,10 @@ CFLAGS		+= -include include/compiler.h
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -DASM_TCHAR='$(ASM_TCHAR)' -DASM_TCHAR_OPS='$(ASM_TCHAR_OPS)'
 | 
			
		||||
 | 
			
		||||
# Inhibit the default -Dlinux
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -Ulinux
 | 
			
		||||
 | 
			
		||||
# CFLAGS for specific object types
 | 
			
		||||
#
 | 
			
		||||
CFLAGS_c	+=
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,10 @@ SYMBOL_PREFIX	= _ipxe__
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -UNVALGRIND
 | 
			
		||||
 | 
			
		||||
# The Linux linker script
 | 
			
		||||
#
 | 
			
		||||
LDSCRIPT	= scripts/linux.lds
 | 
			
		||||
 | 
			
		||||
# Use a two-stage link
 | 
			
		||||
#
 | 
			
		||||
LDFLAGS		+= -r -d
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										6
									
								
								src/arch/arm/Makefile.linux
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								src/arch/arm/Makefile.linux
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,6 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# Include generic Linux Makefile
 | 
			
		||||
#
 | 
			
		||||
MAKEDEPS	+= Makefile.linux
 | 
			
		||||
include Makefile.linux
 | 
			
		||||
@ -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
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@ SRCDIRS		+= arch/arm32/libgcc
 | 
			
		||||
 | 
			
		||||
# ARM32-specific flags
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -mthumb -mcpu=cortex-a15 -mabi=aapcs -mfloat-abi=soft
 | 
			
		||||
CFLAGS		+= -mthumb -mcpu=cortex-a15 -mabi=aapcs
 | 
			
		||||
CFLAGS		+= -mword-relocations
 | 
			
		||||
ASFLAGS		+= -mthumb -mcpu=cortex-a15
 | 
			
		||||
 | 
			
		||||
@ -13,6 +13,11 @@ ASFLAGS		+= -mthumb -mcpu=cortex-a15
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -fshort-wchar
 | 
			
		||||
 | 
			
		||||
# EFI requires that enums are always 32 bits, and nothing else
 | 
			
		||||
# currently cares
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -fno-short-enums
 | 
			
		||||
 | 
			
		||||
# Include common ARM Makefile
 | 
			
		||||
MAKEDEPS	+= arch/arm/Makefile
 | 
			
		||||
include arch/arm/Makefile
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# UEFI requires that enums are always 32 bits
 | 
			
		||||
# EFI uses the soft float ABI
 | 
			
		||||
#
 | 
			
		||||
CFLAGS		+= -fno-short-enums
 | 
			
		||||
CFLAGS		+= -mfloat-abi=soft
 | 
			
		||||
 | 
			
		||||
# Specify EFI image builder
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 | 
			
		||||
 | 
			
		||||
	.section ".note.GNU-stack", "", %progbits
 | 
			
		||||
	.text
 | 
			
		||||
	.arm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM32
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								src/arch/arm32/include/ipxe/efi/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/arch/arm32/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_ARM32
 | 
			
		||||
 | 
			
		||||
/** DHCP client network device interface */
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_EFI_DHCPARCH_H */
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 | 
			
		||||
 | 
			
		||||
	.section ".note.GNU-stack", "", %progbits
 | 
			
		||||
	.text
 | 
			
		||||
	.thumb
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
 | 
			
		||||
 | 
			
		||||
	.section ".note.GNU-stack", "", %progbits
 | 
			
		||||
	.text
 | 
			
		||||
	.arm
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										10
									
								
								src/arch/arm64/Makefile.linux
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								src/arch/arm64/Makefile.linux
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,10 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# Starting virtual address
 | 
			
		||||
#
 | 
			
		||||
LDFLAGS += -Ttext=0x400000
 | 
			
		||||
 | 
			
		||||
# Include generic Linux Makefile
 | 
			
		||||
#
 | 
			
		||||
MAKEDEPS += arch/arm/Makefile.linux
 | 
			
		||||
include arch/arm/Makefile.linux
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2015 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_ARM64
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								src/arch/arm64/include/ipxe/efi/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/arch/arm64/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_ARM64
 | 
			
		||||
 | 
			
		||||
/** DHCP client network device interface */
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_EFI_DHCPARCH_H */
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# Linker script
 | 
			
		||||
# Starting virtual address
 | 
			
		||||
#
 | 
			
		||||
LDSCRIPT = arch/i386/scripts/linux.lds
 | 
			
		||||
LDFLAGS += -Ttext=0x08048000
 | 
			
		||||
 | 
			
		||||
# Compiler flags for building host API wrapper
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
@ -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) ))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 VMware, Inc.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_IA32
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								src/arch/i386/include/ipxe/efi/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/arch/i386/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_IA32
 | 
			
		||||
 | 
			
		||||
/** DHCP client network device interface */
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_EFI_DHCPARCH_H */
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
@ -22,9 +22,6 @@ SRCDIRS		+= arch/x86/drivers/xen
 | 
			
		||||
SRCDIRS		+= arch/x86/drivers/hyperv
 | 
			
		||||
SRCDIRS		+= arch/x86/transitions
 | 
			
		||||
 | 
			
		||||
# breaks building some of the linux-related objects
 | 
			
		||||
CFLAGS		+= -Ulinux
 | 
			
		||||
 | 
			
		||||
# disable valgrind
 | 
			
		||||
CFLAGS		+= -DNVALGRIND
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,9 +1,5 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# Include x86 Linux headers
 | 
			
		||||
#
 | 
			
		||||
INCDIRS += arch/x86/include/linux
 | 
			
		||||
 | 
			
		||||
# Include generic Linux Makefile
 | 
			
		||||
#
 | 
			
		||||
MAKEDEPS	+= Makefile.linux
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
@ -359,10 +355,6 @@ static size_t bzimage_load_initrd ( struct image *image,
 | 
			
		||||
	size_t offset;
 | 
			
		||||
	size_t pad_len;
 | 
			
		||||
 | 
			
		||||
	/* Do not include kernel image itself as an initrd */
 | 
			
		||||
	if ( initrd == image )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Create cpio header for non-prebuilt images */
 | 
			
		||||
	offset = cpio_header ( initrd, &cpio );
 | 
			
		||||
 | 
			
		||||
@ -410,10 +402,6 @@ static int bzimage_check_initrds ( struct image *image,
 | 
			
		||||
	/* Calculate total loaded length of initrds */
 | 
			
		||||
	for_each_image ( initrd ) {
 | 
			
		||||
 | 
			
		||||
		/* Skip kernel */
 | 
			
		||||
		if ( initrd == image )
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Calculate length */
 | 
			
		||||
		len += bzimage_load_initrd ( image, initrd, UNULL );
 | 
			
		||||
		len = bzimage_align ( len );
 | 
			
		||||
@ -528,7 +516,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 +538,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 +555,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.
 | 
			
		||||
 | 
			
		||||
@ -204,10 +204,6 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start,
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Do not include kernel image itself as a module */
 | 
			
		||||
		if ( module_image == image )
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		/* Page-align the module */
 | 
			
		||||
		start = ( ( start + 0xfff ) & ~0xfff );
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								src/arch/x86/include/ipxe/pcbios/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/arch/x86/include/ipxe/pcbios/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
#ifndef _IPXE_PCBIOS_DHCPARCH_H
 | 
			
		||||
#define _IPXE_PCBIOS_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_X86
 | 
			
		||||
 | 
			
		||||
/** DHCP client network device interface */
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_PCBIOS_DHCPARCH_H */
 | 
			
		||||
@ -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
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 Piotr Jaroszyński <p.jaroszynski@gmail.com>
 | 
			
		||||
 *
 | 
			
		||||
 * 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _LINUX_DHCP_ARCH_H
 | 
			
		||||
#define _LINUX_DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL);
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
// Emulate one of the supported arch-platforms
 | 
			
		||||
#include <arch/i386/include/pcbios/ipxe/dhcp_arch.h>
 | 
			
		||||
//#include <arch/i386/include/efi/ipxe/dhcp_arch.h>
 | 
			
		||||
//#include <arch/x86_64/include/efi/ipxe/dhcp_arch.h>
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -59,7 +59,7 @@ static void cachedhcp_init ( void ) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Record cached DHCPACK */
 | 
			
		||||
	if ( ( rc = cachedhcp_record ( &cached_dhcpack,
 | 
			
		||||
	if ( ( rc = cachedhcp_record ( &cached_dhcpack, 0,
 | 
			
		||||
				       phys_to_user ( cached_dhcpack_phys ),
 | 
			
		||||
				       sizeof ( BOOTPLAYER_t ) ) ) != 0 ) {
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n",
 | 
			
		||||
 | 
			
		||||
@ -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,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -12,6 +12,7 @@
 | 
			
		||||
#include <ipxe/uaccess.h>
 | 
			
		||||
#include <ipxe/process.h>
 | 
			
		||||
#include <ipxe/netdevice.h>
 | 
			
		||||
#include <ipxe/malloc.h>
 | 
			
		||||
#include <realmode.h>
 | 
			
		||||
#include <pxe.h>
 | 
			
		||||
 | 
			
		||||
@ -482,3 +483,28 @@ struct pxe_api_call pxe_udp_api[] __pxe_api_call = {
 | 
			
		||||
	PXE_API_CALL ( PXENV_UDP_READ, pxenv_udp_read,
 | 
			
		||||
		       struct s_PXENV_UDP_READ ),
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Discard some cached PXE UDP data
 | 
			
		||||
 *
 | 
			
		||||
 * @ret discarded	Number of cached items discarded
 | 
			
		||||
 */
 | 
			
		||||
static unsigned int pxe_udp_discard ( void ) {
 | 
			
		||||
	struct io_buffer *iobuf;
 | 
			
		||||
	unsigned int discarded = 0;
 | 
			
		||||
 | 
			
		||||
	/* Try to discard the oldest received UDP packet */
 | 
			
		||||
	iobuf = list_first_entry ( &pxe_udp.list, struct io_buffer, list );
 | 
			
		||||
	if ( iobuf ) {
 | 
			
		||||
		list_del ( &iobuf->list );
 | 
			
		||||
		free_iob ( iobuf );
 | 
			
		||||
		discarded++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return discarded;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** PXE UDP cache discarder */
 | 
			
		||||
struct cache_discarder pxe_udp_discarder __cache_discarder ( CACHE_NORMAL ) = {
 | 
			
		||||
	.discard = pxe_udp_discard,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,8 @@
 | 
			
		||||
# -*- makefile -*- : Force emacs to use Makefile mode
 | 
			
		||||
 | 
			
		||||
# Linker script
 | 
			
		||||
# Starting virtual address
 | 
			
		||||
#
 | 
			
		||||
LDSCRIPT = arch/x86_64/scripts/linux.lds
 | 
			
		||||
LDFLAGS += -Ttext=0x400000
 | 
			
		||||
 | 
			
		||||
# Include generic Linux Makefile
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
@ -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) ))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 VMware, Inc.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86_64
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										20
									
								
								src/arch/x86_64/include/ipxe/efi/dhcparch.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/arch/x86_64/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_X86_64
 | 
			
		||||
 | 
			
		||||
/** DHCP client network device interface */
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 3, 10 /* v3.10 */
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_EFI_DHCPARCH_H */
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 VMware, Inc.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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 (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
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,106 +0,0 @@
 | 
			
		||||
/* -*- sh -*- */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Linker script for x86_64 Linux images
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
OUTPUT_FORMAT ( "elf64-x86-64", "elf64-x86-64", "elf64-x86-64" )
 | 
			
		||||
OUTPUT_ARCH ( i386:x86-64 )
 | 
			
		||||
 | 
			
		||||
SECTIONS {
 | 
			
		||||
	_max_align = 32;
 | 
			
		||||
 | 
			
		||||
	. = 0x400000;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The text section
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	. = ALIGN ( _max_align );
 | 
			
		||||
	.text : {
 | 
			
		||||
		_text = .;
 | 
			
		||||
		*(.text)
 | 
			
		||||
		*(.text.*)
 | 
			
		||||
		_etext = .;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The rodata section
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	. = ALIGN ( _max_align );
 | 
			
		||||
	.rodata : {
 | 
			
		||||
		_rodata = .;
 | 
			
		||||
		*(.rodata)
 | 
			
		||||
		*(.rodata.*)
 | 
			
		||||
		_erodata = .;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The data section
 | 
			
		||||
	 *
 | 
			
		||||
	 * Adjust the address for the data segment.  We want to adjust up to
 | 
			
		||||
	 * the same address within the page on the next page up.
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	. = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1));
 | 
			
		||||
	. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
 | 
			
		||||
	.data : {
 | 
			
		||||
		_data = .;
 | 
			
		||||
		*(.data)
 | 
			
		||||
		*(.data.*)
 | 
			
		||||
		KEEP(*(SORT(.tbl.*)))
 | 
			
		||||
		KEEP(*(.provided))
 | 
			
		||||
		KEEP(*(.provided.*))
 | 
			
		||||
		_edata = .;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The bss section
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	. = ALIGN ( _max_align );
 | 
			
		||||
	.bss : {
 | 
			
		||||
		_bss = .;
 | 
			
		||||
		*(.bss)
 | 
			
		||||
		*(.bss.*)
 | 
			
		||||
		*(COMMON)
 | 
			
		||||
		_ebss = .;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Weak symbols that need zero values if not otherwise defined
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	.weak 0x0 : {
 | 
			
		||||
		_weak = .;
 | 
			
		||||
		*(.weak)
 | 
			
		||||
		*(.weak.*)
 | 
			
		||||
		_eweak = .;
 | 
			
		||||
	}
 | 
			
		||||
	_assert = ASSERT ( ( _weak == _eweak ), ".weak is non-zero length" );
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Dispose of the comment and note sections to make the link map
 | 
			
		||||
	 * easier to read
 | 
			
		||||
	 *
 | 
			
		||||
	 */
 | 
			
		||||
 | 
			
		||||
	/DISCARD/ : {
 | 
			
		||||
		*(.comment)
 | 
			
		||||
		*(.comment.*)
 | 
			
		||||
		*(.note)
 | 
			
		||||
		*(.note.*)
 | 
			
		||||
		*(.rel)
 | 
			
		||||
		*(.rel.*)
 | 
			
		||||
		*(.discard)
 | 
			
		||||
		*(.discard.*)
 | 
			
		||||
		*(.sbat)
 | 
			
		||||
		*(.sbat.*)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -124,3 +124,15 @@ REQUIRE_OBJECT ( rsa_aes_cbc_sha1 );
 | 
			
		||||
    defined ( CRYPTO_DIGEST_SHA256 )
 | 
			
		||||
REQUIRE_OBJECT ( rsa_aes_cbc_sha256 );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* RSA, AES-GCM, and SHA-256 */
 | 
			
		||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
 | 
			
		||||
    defined ( CRYPTO_DIGEST_SHA256 )
 | 
			
		||||
REQUIRE_OBJECT ( rsa_aes_gcm_sha256 );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* RSA, AES-GCM, and SHA-384 */
 | 
			
		||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
 | 
			
		||||
    defined ( CRYPTO_DIGEST_SHA384 )
 | 
			
		||||
REQUIRE_OBJECT ( rsa_aes_gcm_sha384 );
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,4 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2010 VMware, Inc.  All Rights Reserved.
 | 
			
		||||
 *
 | 
			
		||||
 * 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
 | 
			
		||||
@ -21,20 +19,33 @@
 | 
			
		||||
 * COPYING.UBDL), provided that you have satisfied its requirements.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#ifndef _DHCP_ARCH_H
 | 
			
		||||
#define _DHCP_ARCH_H
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <config/entropy.h>
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Architecture-specific DHCP options
 | 
			
		||||
 * Entropy configuration options
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/dhcp.h>
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_ARCHITECTURE DHCP_CLIENT_ARCHITECTURE_X86
 | 
			
		||||
 | 
			
		||||
#define DHCP_ARCH_CLIENT_NDI 1 /* UNDI */ , 2, 1 /* v2.1 */
 | 
			
		||||
PROVIDE_REQUIRING_SYMBOL();
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * 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
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
/** AES-CBC block cipher */
 | 
			
		||||
#define CRYPTO_CIPHER_AES_CBC
 | 
			
		||||
 | 
			
		||||
/** AES-GCM block cipher */
 | 
			
		||||
#define CRYPTO_CIPHER_AES_GCM
 | 
			
		||||
 | 
			
		||||
/** MD4 digest algorithm */
 | 
			
		||||
//#define CRYPTO_DIGEST_MD4
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -49,6 +51,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#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 */
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <ipxe/dhcppkt.h>
 | 
			
		||||
#include <ipxe/init.h>
 | 
			
		||||
#include <ipxe/netdevice.h>
 | 
			
		||||
#include <ipxe/vlan.h>
 | 
			
		||||
#include <ipxe/cachedhcp.h>
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
@ -43,6 +44,8 @@ struct cached_dhcp_packet {
 | 
			
		||||
	const char *name;
 | 
			
		||||
	/** DHCP packet (if any) */
 | 
			
		||||
	struct dhcp_packet *dhcppkt;
 | 
			
		||||
	/** VLAN tag (if applicable) */
 | 
			
		||||
	unsigned int vlan;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** Cached DHCPACK */
 | 
			
		||||
@ -136,15 +139,26 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
 | 
			
		||||
		 * matches this network device.
 | 
			
		||||
		 */
 | 
			
		||||
		if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
 | 
			
		||||
			DBGC ( colour, "CACHEDHCP %s does not match %s\n",
 | 
			
		||||
			       cache->name, netdev->name );
 | 
			
		||||
			DBGC ( colour, "CACHEDHCP %s %s does not match %s\n",
 | 
			
		||||
			       cache->name, ll_protocol->ntoa ( chaddr ),
 | 
			
		||||
			       netdev->name );
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Do nothing unless cached packet's VLAN tag matches
 | 
			
		||||
		 * this network device.
 | 
			
		||||
		 */
 | 
			
		||||
		if ( vlan_tag ( netdev ) != cache->vlan ) {
 | 
			
		||||
			DBGC ( colour, "CACHEDHCP %s VLAN %d does not match "
 | 
			
		||||
			       "%s\n", cache->name, cache->vlan,
 | 
			
		||||
			       netdev->name );
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP %s is for %s\n",
 | 
			
		||||
		       cache->name, netdev->name );
 | 
			
		||||
 | 
			
		||||
		/* Use network device's settings block */
 | 
			
		||||
		settings = netdev_settings ( netdev );
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP %s is for %s\n",
 | 
			
		||||
		       cache->name, netdev->name );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Register settings */
 | 
			
		||||
@ -165,12 +179,13 @@ static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
 | 
			
		||||
 * Record cached DHCP packet
 | 
			
		||||
 *
 | 
			
		||||
 * @v cache		Cached DHCP packet
 | 
			
		||||
 * @v vlan		VLAN tag, if any
 | 
			
		||||
 * @v data		DHCPACK packet buffer
 | 
			
		||||
 * @v max_len		Maximum possible length
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
 | 
			
		||||
		       size_t max_len ) {
 | 
			
		||||
int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan,
 | 
			
		||||
		       userptr_t data, size_t max_len ) {
 | 
			
		||||
	struct dhcp_packet *dhcppkt;
 | 
			
		||||
	struct dhcp_packet *tmp;
 | 
			
		||||
	struct dhcphdr *dhcphdr;
 | 
			
		||||
@ -225,36 +240,55 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, userptr_t data,
 | 
			
		||||
	DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name,
 | 
			
		||||
	       user_to_phys ( data, 0 ), len, max_len );
 | 
			
		||||
	cache->dhcppkt = dhcppkt;
 | 
			
		||||
	cache->vlan = vlan;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cached DHCPACK startup function
 | 
			
		||||
 * Cached DHCP packet startup function
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static void cachedhcp_startup ( void ) {
 | 
			
		||||
 | 
			
		||||
	/* Apply cached ProxyDHCPOFFER, if any */
 | 
			
		||||
	cachedhcp_apply ( &cached_proxydhcp, NULL );
 | 
			
		||||
	cachedhcp_free ( &cached_proxydhcp );
 | 
			
		||||
 | 
			
		||||
	/* Apply cached PXEBSACK, if any */
 | 
			
		||||
	cachedhcp_apply ( &cached_pxebs, NULL );
 | 
			
		||||
	cachedhcp_free ( &cached_pxebs );
 | 
			
		||||
 | 
			
		||||
	/* Free any remaining cached packets */
 | 
			
		||||
	/* Report unclaimed DHCPACK, if any.  Do not free yet, since
 | 
			
		||||
	 * it may still be claimed by a dynamically created device
 | 
			
		||||
	 * such as a VLAN device.
 | 
			
		||||
	 */
 | 
			
		||||
	if ( cached_dhcpack.dhcppkt ) {
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP %s unclaimed\n",
 | 
			
		||||
		       cached_dhcpack.name );
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Cached DHCP packet shutdown function
 | 
			
		||||
 *
 | 
			
		||||
 * @v booting		System is shutting down for OS boot
 | 
			
		||||
 */
 | 
			
		||||
static void cachedhcp_shutdown ( int booting __unused ) {
 | 
			
		||||
 | 
			
		||||
	/* Free cached DHCPACK, if any */
 | 
			
		||||
	if ( cached_dhcpack.dhcppkt ) {
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP %s never claimed\n",
 | 
			
		||||
		       cached_dhcpack.name );
 | 
			
		||||
	}
 | 
			
		||||
	cachedhcp_free ( &cached_dhcpack );
 | 
			
		||||
	cachedhcp_free ( &cached_proxydhcp );
 | 
			
		||||
	cachedhcp_free ( &cached_pxebs );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Cached DHCPACK startup function */
 | 
			
		||||
struct startup_fn cachedhcp_startup_fn __startup_fn ( STARTUP_LATE ) = {
 | 
			
		||||
	.name = "cachedhcp",
 | 
			
		||||
	.startup = cachedhcp_startup,
 | 
			
		||||
	.shutdown = cachedhcp_shutdown,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
@ -311,7 +312,7 @@ void unregister_image ( struct image *image ) {
 | 
			
		||||
struct image * find_image ( const char *name ) {
 | 
			
		||||
	struct image *image;
 | 
			
		||||
 | 
			
		||||
	list_for_each_entry ( image, &images, list ) {
 | 
			
		||||
	for_each_image ( image ) {
 | 
			
		||||
		if ( strcmp ( image->name, name ) == 0 )
 | 
			
		||||
			return image;
 | 
			
		||||
	}
 | 
			
		||||
@ -348,9 +349,8 @@ int image_exec ( struct image *image ) {
 | 
			
		||||
	/* Preserve record of any currently-running image */
 | 
			
		||||
	saved_current_image = current_image;
 | 
			
		||||
 | 
			
		||||
	/* Take out a temporary reference to the image.  This allows
 | 
			
		||||
	 * the image to unregister itself if necessary, without
 | 
			
		||||
	 * automatically freeing itself.
 | 
			
		||||
	/* Take out a temporary reference to the image, so that it
 | 
			
		||||
	 * does not get freed when temporarily unregistered.
 | 
			
		||||
	 */
 | 
			
		||||
	current_image = image_get ( image );
 | 
			
		||||
 | 
			
		||||
@ -370,6 +370,9 @@ int image_exec ( struct image *image ) {
 | 
			
		||||
	/* Record boot attempt */
 | 
			
		||||
	syslog ( LOG_NOTICE, "Executing \"%s\"\n", image->name );
 | 
			
		||||
 | 
			
		||||
	/* Temporarily unregister the image during its execution */
 | 
			
		||||
	unregister_image ( image );
 | 
			
		||||
 | 
			
		||||
	/* Try executing the image */
 | 
			
		||||
	if ( ( rc = image->type->exec ( image ) ) != 0 ) {
 | 
			
		||||
		DBGC ( image, "IMAGE %s could not execute: %s\n",
 | 
			
		||||
@ -386,6 +389,10 @@ int image_exec ( struct image *image ) {
 | 
			
		||||
			 image->name, strerror ( rc ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Re-register image (unless due to be replaced) */
 | 
			
		||||
	if ( ! image->replacement )
 | 
			
		||||
		register_image ( image );
 | 
			
		||||
 | 
			
		||||
	/* Pick up replacement image before we drop the original
 | 
			
		||||
	 * image's temporary reference.  The replacement image must
 | 
			
		||||
	 * already be registered, so we don't need to hold a temporary
 | 
			
		||||
@ -569,3 +576,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
 | 
			
		||||
 | 
			
		||||
@ -784,6 +784,7 @@ struct cipher_algorithm aes_algorithm = {
 | 
			
		||||
	.name = "aes",
 | 
			
		||||
	.ctxsize = sizeof ( struct aes_context ),
 | 
			
		||||
	.blocksize = AES_BLOCKSIZE,
 | 
			
		||||
	.alignsize = 0,
 | 
			
		||||
	.authsize = 0,
 | 
			
		||||
	.setkey = aes_setkey,
 | 
			
		||||
	.setiv = cipher_null_setiv,
 | 
			
		||||
 | 
			
		||||
@ -119,6 +119,7 @@ struct cipher_algorithm arc4_algorithm = {
 | 
			
		||||
	.name = "ARC4",
 | 
			
		||||
	.ctxsize = ARC4_CTX_SIZE,
 | 
			
		||||
	.blocksize = 1,
 | 
			
		||||
	.alignsize = 1,
 | 
			
		||||
	.authsize = 0,
 | 
			
		||||
	.setkey = arc4_setkey,
 | 
			
		||||
	.setiv = cipher_null_setiv,
 | 
			
		||||
 | 
			
		||||
@ -84,6 +84,7 @@ struct cipher_algorithm cipher_null = {
 | 
			
		||||
	.name = "null",
 | 
			
		||||
	.ctxsize = 0,
 | 
			
		||||
	.blocksize = 1,
 | 
			
		||||
	.alignsize = 1,
 | 
			
		||||
	.authsize = 0,
 | 
			
		||||
	.setkey = cipher_null_setkey,
 | 
			
		||||
	.setiv = cipher_null_setiv,
 | 
			
		||||
 | 
			
		||||
@ -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 );
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,22 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <ipxe/crypto.h>
 | 
			
		||||
#include <ipxe/gcm.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Perform encryption
 | 
			
		||||
 *
 | 
			
		||||
 * This value is chosen to allow for ANDing with a fragment length.
 | 
			
		||||
 */
 | 
			
		||||
#define GCM_FL_ENCRYPT 0x00ff
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Calculate hash over an initialisation vector value
 | 
			
		||||
 *
 | 
			
		||||
 * The hash calculation for a non 96-bit initialisation vector is
 | 
			
		||||
 * identical to the calculation used for additional data, except that
 | 
			
		||||
 * the non-additional data length counter is used.
 | 
			
		||||
 */
 | 
			
		||||
#define GCM_FL_IV 0x0100
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GCM field polynomial
 | 
			
		||||
 *
 | 
			
		||||
@ -292,23 +308,18 @@ static void gcm_multiply_key ( const union gcm_block *key,
 | 
			
		||||
 * Encrypt/decrypt/authenticate data
 | 
			
		||||
 *
 | 
			
		||||
 * @v context		Context
 | 
			
		||||
 * @v src		Input data, or NULL to process additional data
 | 
			
		||||
 * @v src		Input data
 | 
			
		||||
 * @v dst		Output data, or NULL to process additional data
 | 
			
		||||
 * @v hash		Hash input data
 | 
			
		||||
 * @v len		Length of data
 | 
			
		||||
 * @v flags		Operation flags
 | 
			
		||||
 */
 | 
			
		||||
static void gcm_process ( struct gcm_context *context, const void *src,
 | 
			
		||||
			  void *dst, const void *hash, size_t len ) {
 | 
			
		||||
			  void *dst, size_t len, unsigned int flags ) {
 | 
			
		||||
	union gcm_block tmp;
 | 
			
		||||
	uint64_t *total;
 | 
			
		||||
	size_t frag_len;
 | 
			
		||||
	unsigned int block;
 | 
			
		||||
 | 
			
		||||
	/* Sanity checks */
 | 
			
		||||
	assert ( hash != NULL );
 | 
			
		||||
	assert ( ( ( src == NULL ) && ( dst == NULL ) ) ||
 | 
			
		||||
		 ( ( hash == src ) || ( hash == dst ) ) );
 | 
			
		||||
 | 
			
		||||
	/* Calculate block number (for debugging) */
 | 
			
		||||
	block = ( ( ( context->len.len.add + 8 * sizeof ( tmp ) - 1 ) /
 | 
			
		||||
		    ( 8 * sizeof ( tmp ) ) ) +
 | 
			
		||||
@ -316,17 +327,21 @@ static void gcm_process ( struct gcm_context *context, const void *src,
 | 
			
		||||
		    ( 8 * sizeof ( tmp ) ) ) + 1 );
 | 
			
		||||
 | 
			
		||||
	/* Update total length (in bits) */
 | 
			
		||||
	total = ( src ? &context->len.len.data : &context->len.len.add );
 | 
			
		||||
	total = ( ( dst || ( flags & GCM_FL_IV ) ) ?
 | 
			
		||||
		  &context->len.len.data : &context->len.len.add );
 | 
			
		||||
	*total += ( len * 8 );
 | 
			
		||||
 | 
			
		||||
	/* Process data */
 | 
			
		||||
	for ( ; len ; hash += frag_len, len -= frag_len, block++ ) {
 | 
			
		||||
	for ( ; len ; src += frag_len, len -= frag_len, block++ ) {
 | 
			
		||||
 | 
			
		||||
		/* Calculate fragment length */
 | 
			
		||||
		frag_len = len;
 | 
			
		||||
		if ( frag_len > sizeof ( tmp ) )
 | 
			
		||||
			frag_len = sizeof ( tmp );
 | 
			
		||||
 | 
			
		||||
		/* Update hash with input data */
 | 
			
		||||
		gcm_xor ( src, &context->hash, &context->hash, frag_len );
 | 
			
		||||
 | 
			
		||||
		/* Encrypt/decrypt block, if applicable */
 | 
			
		||||
		if ( dst ) {
 | 
			
		||||
 | 
			
		||||
@ -345,12 +360,14 @@ static void gcm_process ( struct gcm_context *context, const void *src,
 | 
			
		||||
 | 
			
		||||
			/* Encrypt/decrypt data */
 | 
			
		||||
			gcm_xor ( src, &tmp, dst, frag_len );
 | 
			
		||||
			src += frag_len;
 | 
			
		||||
			dst += frag_len;
 | 
			
		||||
 | 
			
		||||
			/* Update hash with encrypted data, if applicable */
 | 
			
		||||
			gcm_xor ( &tmp, &context->hash, &context->hash,
 | 
			
		||||
				  ( frag_len & flags ) );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Update hash */
 | 
			
		||||
		gcm_xor ( hash, &context->hash, &context->hash, frag_len );
 | 
			
		||||
		gcm_multiply_key ( &context->key, &context->hash );
 | 
			
		||||
		DBGC2 ( context, "GCM %p X[%d]:\n", context, block );
 | 
			
		||||
		DBGC2_HDA ( context, 0, &context->hash,
 | 
			
		||||
@ -452,9 +469,18 @@ int gcm_setkey ( struct gcm_context *context, const void *key, size_t keylen,
 | 
			
		||||
 * @v ivlen		Initialisation vector length
 | 
			
		||||
 */
 | 
			
		||||
void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
 | 
			
		||||
	union gcm_block *check = ( ( void * ) context );
 | 
			
		||||
 | 
			
		||||
	/* Sanity checks */
 | 
			
		||||
	linker_assert ( &context->hash == check, gcm_bad_layout );
 | 
			
		||||
	linker_assert ( &context->len == check + 1, gcm_bad_layout );
 | 
			
		||||
	linker_assert ( &context->ctr == check + 2, gcm_bad_layout );
 | 
			
		||||
	linker_assert ( &context->key == check + 3, gcm_bad_layout );
 | 
			
		||||
 | 
			
		||||
	/* Reset non-key state */
 | 
			
		||||
	memset ( context, 0, offsetof ( typeof ( *context ), key ) );
 | 
			
		||||
 | 
			
		||||
	/* Reset counter */
 | 
			
		||||
	memset ( context->ctr.ctr.iv, 0, sizeof ( context->ctr.ctr.iv ) );
 | 
			
		||||
	context->ctr.ctr.value = cpu_to_be32 ( 1 );
 | 
			
		||||
 | 
			
		||||
	/* Process initialisation vector */
 | 
			
		||||
@ -466,15 +492,12 @@ void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
 | 
			
		||||
	} else {
 | 
			
		||||
 | 
			
		||||
		/* Calculate hash over initialisation vector */
 | 
			
		||||
		gcm_process ( context, iv, NULL, iv, ivlen );
 | 
			
		||||
		gcm_process ( context, iv, NULL, ivlen, GCM_FL_IV );
 | 
			
		||||
		gcm_hash ( context, &context->ctr );
 | 
			
		||||
 | 
			
		||||
		/* Reset accumulated hash */
 | 
			
		||||
		memset ( &context->hash, 0, sizeof ( context->hash ) );
 | 
			
		||||
 | 
			
		||||
		/* Reset data lengths */
 | 
			
		||||
		assert ( context->len.len.add == 0 );
 | 
			
		||||
		context->len.len.data = 0;
 | 
			
		||||
 | 
			
		||||
		/* Reset non-key, non-counter state */
 | 
			
		||||
		memset ( context, 0, offsetof ( typeof ( *context ), ctr ) );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	DBGC2 ( context, "GCM %p Y[0]:\n", context );
 | 
			
		||||
@ -491,20 +514,9 @@ void gcm_setiv ( struct gcm_context *context, const void *iv, size_t ivlen ) {
 | 
			
		||||
 */
 | 
			
		||||
void gcm_encrypt ( struct gcm_context *context, const void *src, void *dst,
 | 
			
		||||
		   size_t len ) {
 | 
			
		||||
	const void *hash;
 | 
			
		||||
 | 
			
		||||
	/* Determine hash input */
 | 
			
		||||
	if ( dst ) {
 | 
			
		||||
		/* Encrypting: hash the encrypted data */
 | 
			
		||||
		hash = dst;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Authenticating: hash the input data */
 | 
			
		||||
		hash = src;
 | 
			
		||||
		src = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Process data */
 | 
			
		||||
	gcm_process ( context, src, dst, hash, len );
 | 
			
		||||
	gcm_process ( context, src, dst, len, GCM_FL_ENCRYPT );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -517,15 +529,7 @@ void gcm_encrypt ( struct gcm_context *context, const void *src, void *dst,
 | 
			
		||||
 */
 | 
			
		||||
void gcm_decrypt ( struct gcm_context *context, const void *src, void *dst,
 | 
			
		||||
		   size_t len ) {
 | 
			
		||||
	const void *hash;
 | 
			
		||||
 | 
			
		||||
	/* Determine hash input */
 | 
			
		||||
	hash = src;
 | 
			
		||||
	if ( ! dst ) {
 | 
			
		||||
		/* Authenticating: only hash */
 | 
			
		||||
		src = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Process data */
 | 
			
		||||
	gcm_process ( context, src, dst, hash, len );
 | 
			
		||||
	gcm_process ( context, src, dst, len, 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -27,48 +27,65 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <ipxe/rsa.h>
 | 
			
		||||
#include <ipxe/aes.h>
 | 
			
		||||
#include <ipxe/sha1.h>
 | 
			
		||||
#include <ipxe/sha256.h>
 | 
			
		||||
#include <ipxe/tls.h>
 | 
			
		||||
 | 
			
		||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 03 ) = {
 | 
			
		||||
tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = {
 | 
			
		||||
	.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA ),
 | 
			
		||||
	.key_len = ( 128 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA1_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_dhe_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha1_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 04 ) = {
 | 
			
		||||
tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = {
 | 
			
		||||
	.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA ),
 | 
			
		||||
	.key_len = ( 256 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA1_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_dhe_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha1_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 13 ) = {
 | 
			
		||||
tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = {
 | 
			
		||||
	.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
 | 
			
		||||
	.key_len = ( 128 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA1_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_pubkey_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha1_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_RSA_WITH_AES_256_CBC_SHA cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 14 ) = {
 | 
			
		||||
tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 16 ) = {
 | 
			
		||||
	.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
 | 
			
		||||
	.key_len = ( 256 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA1_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_pubkey_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha1_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -31,44 +31,60 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 01 ) = {
 | 
			
		||||
tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = {
 | 
			
		||||
	.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ),
 | 
			
		||||
	.key_len = ( 128 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA256_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_dhe_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha256_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 02 ) = {
 | 
			
		||||
tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 04 ) = {
 | 
			
		||||
	.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ),
 | 
			
		||||
	.key_len = ( 256 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA256_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_dhe_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha256_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 11 ) = {
 | 
			
		||||
tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = {
 | 
			
		||||
	.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
 | 
			
		||||
	.key_len = ( 128 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA256_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_pubkey_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha256_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** TLS_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
 | 
			
		||||
struct tls_cipher_suite
 | 
			
		||||
tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 12 ) = {
 | 
			
		||||
tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 14 ) = {
 | 
			
		||||
	.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
 | 
			
		||||
	.key_len = ( 256 / 8 ),
 | 
			
		||||
	.fixed_iv_len = 0,
 | 
			
		||||
	.record_iv_len = AES_BLOCKSIZE,
 | 
			
		||||
	.mac_len = SHA256_DIGEST_SIZE,
 | 
			
		||||
	.exchange = &tls_pubkey_exchange_algorithm,
 | 
			
		||||
	.pubkey = &rsa_algorithm,
 | 
			
		||||
	.cipher = &aes_cbc_algorithm,
 | 
			
		||||
	.digest = &sha256_algorithm,
 | 
			
		||||
	.handshake = &sha256_algorithm,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user