mirror of
				https://gitlab.com/qemu-project/ipxe.git
				synced 2025-11-03 07:59:06 +08:00 
			
		
		
		
	Compare commits
	
		
			160 Commits
		
	
	
		
			dns_primar
			...
			efiinitrd
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 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 | |||
| f48b01cb01 | |||
| 8fce26730c | |||
| da81214cec | |||
| 0c383bf00a | |||
| 8e478e648f | |||
| 52f72d298a | |||
| 2c78242732 | |||
| 6b2c94d3a7 | |||
| ea33ea33c0 | |||
| 80c45c5c71 | |||
| 028aac99a3 | |||
| 1a7317e7d4 | |||
| 18b861024a | |||
| 007d3cb800 | |||
| 88419b608d | |||
| 081b3eefc4 | |||
| 3aa6b79c8d | |||
| 649176cd60 | |||
| 9448ac5445 | |||
| be667ba948 | |||
| ff228f745c | |||
| 56b30364c5 | |||
| 8fc3c26eae | |||
| 6459e3b7b1 | |||
| 8f5fc16143 | |||
| bc19aeca5f | |||
| 131daf1aae | |||
| a80124456e | |||
| 3b81a4e256 | |||
| 9f81e97af5 | |||
| 6d2cead461 | |||
| 856ffe000e | |||
| c5af41a6f5 | |||
| 04879352c4 | |||
| 491c075f7f | |||
| b52ea20841 | |||
| cad1cc6b44 | |||
| 6871a7de70 | |||
| 727b034f11 | |||
| 06467ee70f | |||
| d6e36a2d73 | |||
| 99242bbe2e | |||
| faf26bf8b8 | |||
| f0ea19b238 | |||
| fb69d14002 | |||
| c220b93f31 | |||
| 67f8878e10 | |||
| 9e46ffa924 | |||
| ef70667557 | |||
| 9f5b9e3abb | |||
| b4216fa506 | |||
| 1b61c2118c | |||
| a202de385d | |||
| 0965cec53c | |||
| 9dfcdc04c8 | |||
| d8014b1801 | |||
| 319caeaa7b | |||
| 814aef68c5 | |||
| 725f0370fa | |||
| 5d3fad5c10 | |||
| d3c8944d5c | |||
| d72c8fdc90 | |||
| 87f1796f15 | |||
| 70995397e5 | |||
| f58b5109f4 | |||
| 614c3f43a1 | |||
| 1e1b9593e6 | |||
| 27825e5557 | |||
| dd35475438 | |||
| ba93c9134c | |||
| 2ff3385e00 | |||
| 7e9631b60f | |||
| 3cd3a73261 | 
							
								
								
									
										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 }} \
 | 
			
		||||
 | 
			
		||||
@ -16,7 +16,7 @@ BLOCKSIZE = 512 * 1024
 | 
			
		||||
def detect_architecture(image):
 | 
			
		||||
    """Detect CPU architecture"""
 | 
			
		||||
    mdir = subprocess.run(['mdir', '-b', '-i', image, '::/EFI/BOOT'],
 | 
			
		||||
                          capture_output=True)
 | 
			
		||||
                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 | 
			
		||||
    if any(b'BOOTAA64.EFI' in x for x in mdir.stdout.splitlines()):
 | 
			
		||||
        return 'arm64'
 | 
			
		||||
    return 'x86_64'
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
@ -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
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
							
								
								
									
										12
									
								
								src/arch/loong64/include/bits/entropy.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/arch/loong64/include/bits/entropy.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,12 @@
 | 
			
		||||
#ifndef _BITS_ENTROPY_H
 | 
			
		||||
#define _BITS_ENTROPY_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * LoongArch64-specific entropy API implementations
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#endif /* _BITS_ENTROPY_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
 | 
			
		||||
 | 
			
		||||
@ -45,7 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) {
 | 
			
		||||
	       PCIDIRECT_CONFIG_ADDRESS );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_num_bus );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_discover );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_dword );
 | 
			
		||||
@ -53,3 +53,5 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap );
 | 
			
		||||
 | 
			
		||||
struct pci_api pcidirect_api = PCIAPI_RUNTIME ( direct );
 | 
			
		||||
 | 
			
		||||
@ -247,18 +247,20 @@ 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,
 | 
			
		||||
				   const char *cmdline ) {
 | 
			
		||||
	char *vga;
 | 
			
		||||
	char *mem;
 | 
			
		||||
				   struct bzimage_context *bzimg ) {
 | 
			
		||||
	const char *vga;
 | 
			
		||||
	const char *mem;
 | 
			
		||||
	char *sep;
 | 
			
		||||
	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';
 | 
			
		||||
		if ( strcmp ( vga, "normal" ) == 0 ) {
 | 
			
		||||
			bzimg->vid_mode = BZI_VID_MODE_NORMAL;
 | 
			
		||||
		} else if ( strcmp ( vga, "ext" ) == 0 ) {
 | 
			
		||||
@ -266,19 +268,20 @@ 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 && ( *vga != ' ' ) ) {
 | 
			
		||||
				DBGC ( image, "bzImage %p strange \"vga=\""
 | 
			
		||||
				       "terminator '%c'\n", image, *vga );
 | 
			
		||||
			bzimg->vid_mode = strtoul ( vga, &end, 0 );
 | 
			
		||||
			if ( *end ) {
 | 
			
		||||
				DBGC ( image, "bzImage %p strange \"vga=\" "
 | 
			
		||||
				       "terminator '%c'\n", image, *end );
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		if ( sep )
 | 
			
		||||
			*sep = ' ';
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* 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;
 | 
			
		||||
@ -296,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;
 | 
			
		||||
@ -310,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 */
 | 
			
		||||
@ -522,7 +524,6 @@ static void bzimage_load_initrds ( struct image *image,
 | 
			
		||||
 */
 | 
			
		||||
static int bzimage_exec ( struct image *image ) {
 | 
			
		||||
	struct bzimage_context bzimg;
 | 
			
		||||
	const char *cmdline = ( image->cmdline ? image->cmdline : "" );
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Read and parse header from image */
 | 
			
		||||
@ -545,7 +546,7 @@ static int bzimage_exec ( struct image *image ) {
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Parse command line for bootloader parameters */
 | 
			
		||||
	if ( ( rc = bzimage_parse_cmdline ( image, &bzimg, cmdline ) ) != 0)
 | 
			
		||||
	if ( ( rc = bzimage_parse_cmdline ( image, &bzimg ) ) != 0)
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	/* Check that initrds can be loaded */
 | 
			
		||||
@ -562,7 +563,7 @@ static int bzimage_exec ( struct image *image ) {
 | 
			
		||||
		      bzimg.rm_filesz, bzimg.pm_sz );
 | 
			
		||||
 | 
			
		||||
	/* Store command line */
 | 
			
		||||
	bzimage_set_cmdline ( image, &bzimg, cmdline );
 | 
			
		||||
	bzimage_set_cmdline ( image, &bzimg );
 | 
			
		||||
 | 
			
		||||
	/* Prepare for exiting.  Must do this before loading initrds,
 | 
			
		||||
	 * since loading the initrds will corrupt the external heap.
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
 | 
			
		||||
@ -11,5 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <ipxe/pcibios.h>
 | 
			
		||||
#include <ipxe/pcidirect.h>
 | 
			
		||||
#include <ipxe/pcicloud.h>
 | 
			
		||||
 | 
			
		||||
#endif /* _BITS_PCI_IO_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										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 */
 | 
			
		||||
@ -145,4 +145,6 @@ PCIAPI_INLINE ( pcbios, pci_ioremap ) ( struct pci_device *pci __unused,
 | 
			
		||||
	return ioremap ( bus_addr, len );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern struct pci_api pcibios_api;
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_PCIBIOS_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										18
									
								
								src/arch/x86/include/ipxe/pcicloud.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								src/arch/x86/include/ipxe/pcicloud.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,18 @@
 | 
			
		||||
#ifndef _IPXE_PCICLOUD_H
 | 
			
		||||
#define _IPXE_PCICLOUD_H
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Cloud VM PCI configuration space access
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#ifdef PCIAPI_CLOUD
 | 
			
		||||
#define PCIAPI_PREFIX_cloud
 | 
			
		||||
#else
 | 
			
		||||
#define PCIAPI_PREFIX_cloud __cloud_
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* _IPXE_PCICLOUD_H */
 | 
			
		||||
@ -26,14 +26,18 @@ struct pci_device;
 | 
			
		||||
extern void pcidirect_prepare ( struct pci_device *pci, int where );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determine number of PCI buses within system
 | 
			
		||||
 * Find next PCI bus:dev.fn address range in system
 | 
			
		||||
 *
 | 
			
		||||
 * @ret num_bus		Number of buses
 | 
			
		||||
 * @v busdevfn		Starting PCI bus:dev.fn address
 | 
			
		||||
 * @v range		PCI bus:dev.fn address range to fill in
 | 
			
		||||
 */
 | 
			
		||||
static inline __always_inline int
 | 
			
		||||
PCIAPI_INLINE ( direct, pci_num_bus ) ( void ) {
 | 
			
		||||
static inline __always_inline void
 | 
			
		||||
PCIAPI_INLINE ( direct, pci_discover ) ( uint32_t busdevfn __unused,
 | 
			
		||||
					 struct pci_range *range ) {
 | 
			
		||||
 | 
			
		||||
	/* Scan first bus and rely on bridge detection to find higher buses */
 | 
			
		||||
	return 1;
 | 
			
		||||
	range->start = PCI_BUSDEVFN ( 0, 0, 0, 0 );
 | 
			
		||||
	range->count = PCI_BUSDEVFN ( 0, 1, 0, 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -151,4 +155,6 @@ PCIAPI_INLINE ( direct, pci_ioremap ) ( struct pci_device *pci __unused,
 | 
			
		||||
	return ioremap ( bus_addr, len );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern struct pci_api pcidirect_api;
 | 
			
		||||
 | 
			
		||||
#endif /* _PCIDIRECT_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
 | 
			
		||||
@ -107,7 +107,7 @@ static int acpi_timer_probe ( void ) {
 | 
			
		||||
	unsigned int pm_tmr_blk;
 | 
			
		||||
 | 
			
		||||
	/* Locate FADT */
 | 
			
		||||
	fadt = acpi_find ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	fadt = acpi_table ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	if ( ! fadt ) {
 | 
			
		||||
		DBGC ( &acpi_timer, "ACPI could not find FADT\n" );
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
 | 
			
		||||
@ -123,7 +123,7 @@ int acpi_poweroff ( void ) {
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Locate FADT */
 | 
			
		||||
	fadt = acpi_find ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	fadt = acpi_table ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	if ( ! fadt ) {
 | 
			
		||||
		DBGC ( colour, "ACPI could not find FADT\n" );
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
 | 
			
		||||
@ -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",
 | 
			
		||||
 | 
			
		||||
@ -34,13 +34,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Determine number of PCI buses within system
 | 
			
		||||
 * Find next PCI bus:dev.fn address range in system
 | 
			
		||||
 *
 | 
			
		||||
 * @ret num_bus		Number of buses
 | 
			
		||||
 * @v busdevfn		Starting PCI bus:dev.fn address
 | 
			
		||||
 * @v range		PCI bus:dev.fn address range to fill in
 | 
			
		||||
 */
 | 
			
		||||
static int pcibios_num_bus ( void ) {
 | 
			
		||||
static void pcibios_discover ( uint32_t busdevfn __unused,
 | 
			
		||||
			       struct pci_range *range ) {
 | 
			
		||||
	int discard_a, discard_D;
 | 
			
		||||
	uint8_t max_bus;
 | 
			
		||||
	uint16_t num_bus;
 | 
			
		||||
 | 
			
		||||
	/* We issue this call using flat real mode, to work around a
 | 
			
		||||
	 * bug in some HP BIOSes.
 | 
			
		||||
@ -48,16 +50,20 @@ static int pcibios_num_bus ( void ) {
 | 
			
		||||
	__asm__ __volatile__ ( REAL_CODE ( "call flatten_real_mode\n\t"
 | 
			
		||||
					   "stc\n\t"
 | 
			
		||||
					   "int $0x1a\n\t"
 | 
			
		||||
					   "movzbw %%cl, %%cx\n\t"
 | 
			
		||||
					   "incw %%cx\n\t"
 | 
			
		||||
					   "jnc 1f\n\t"
 | 
			
		||||
					   "xorw %%cx, %%cx\n\t"
 | 
			
		||||
					   "\n1:\n\t" )
 | 
			
		||||
			       : "=c" ( max_bus ), "=a" ( discard_a ),
 | 
			
		||||
			       : "=c" ( num_bus ), "=a" ( discard_a ),
 | 
			
		||||
				 "=D" ( discard_D )
 | 
			
		||||
			       : "a" ( PCIBIOS_INSTALLATION_CHECK >> 16 ),
 | 
			
		||||
				 "D" ( 0 )
 | 
			
		||||
			       : "ebx", "edx" );
 | 
			
		||||
 | 
			
		||||
	return ( max_bus + 1 );
 | 
			
		||||
	/* Populate range */
 | 
			
		||||
	range->start = PCI_BUSDEVFN ( 0, 0, 0, 0 );
 | 
			
		||||
	range->count = PCI_BUSDEVFN ( 0, num_bus, 0, 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -114,7 +120,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){
 | 
			
		||||
	return ( status >> 8 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PROVIDE_PCIAPI ( pcbios, pci_num_bus, pcibios_num_bus );
 | 
			
		||||
PROVIDE_PCIAPI ( pcbios, pci_discover, pcibios_discover );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_dword );
 | 
			
		||||
@ -122,3 +128,5 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword );
 | 
			
		||||
PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap );
 | 
			
		||||
 | 
			
		||||
struct pci_api pcibios_api = PCIAPI_RUNTIME ( pcbios );
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										191
									
								
								src/arch/x86/interface/pcbios/pcicloud.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										191
									
								
								src/arch/x86/interface/pcbios/pcicloud.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,191 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2022 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <ipxe/init.h>
 | 
			
		||||
#include <ipxe/pci.h>
 | 
			
		||||
#include <ipxe/ecam.h>
 | 
			
		||||
#include <ipxe/pcibios.h>
 | 
			
		||||
#include <ipxe/pcidirect.h>
 | 
			
		||||
#include <ipxe/pcicloud.h>
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * Cloud VM PCI configuration space access
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/** Selected PCI configuration space access API */
 | 
			
		||||
static struct pci_api *pcicloud = &ecam_api;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Find next PCI bus:dev.fn address range in system
 | 
			
		||||
 *
 | 
			
		||||
 * @v busdevfn		Starting PCI bus:dev.fn address
 | 
			
		||||
 * @v range		PCI bus:dev.fn address range to fill in
 | 
			
		||||
 */
 | 
			
		||||
static void pcicloud_discover ( uint32_t busdevfn, struct pci_range *range ) {
 | 
			
		||||
 | 
			
		||||
	pcicloud->pci_discover ( busdevfn, range );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read byte from PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value read
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_read_config_byte ( struct pci_device *pci,
 | 
			
		||||
				       unsigned int where, uint8_t *value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_read_config_byte ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read 16-bit word from PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value read
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_read_config_word ( struct pci_device *pci,
 | 
			
		||||
				       unsigned int where, uint16_t *value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_read_config_word ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Read 32-bit dword from PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value read
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_read_config_dword ( struct pci_device *pci,
 | 
			
		||||
					unsigned int where, uint32_t *value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_read_config_dword ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write byte to PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value to be written
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_write_config_byte ( struct pci_device *pci,
 | 
			
		||||
					unsigned int where, uint8_t value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_write_config_byte ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write 16-bit word to PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value to be written
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_write_config_word ( struct pci_device *pci,
 | 
			
		||||
					unsigned int where, uint16_t value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_write_config_word ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Write 32-bit dword to PCI configuration space
 | 
			
		||||
 *
 | 
			
		||||
 * @v pci		PCI device
 | 
			
		||||
 * @v where		Location within PCI configuration space
 | 
			
		||||
 * @v value		Value to be written
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int pcicloud_write_config_dword ( struct pci_device *pci,
 | 
			
		||||
					 unsigned int where, uint32_t value ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_write_config_dword ( pci, where, value );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Map PCI bus address as an I/O address
 | 
			
		||||
 *
 | 
			
		||||
 * @v bus_addr		PCI bus address
 | 
			
		||||
 * @v len		Length of region
 | 
			
		||||
 * @ret io_addr		I/O address, or NULL on error
 | 
			
		||||
 */
 | 
			
		||||
static void * pcicloud_ioremap ( struct pci_device *pci,
 | 
			
		||||
				 unsigned long bus_addr, size_t len ) {
 | 
			
		||||
 | 
			
		||||
	return pcicloud->pci_ioremap ( pci, bus_addr, len );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_discover, pcicloud_discover );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_read_config_byte, pcicloud_read_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_read_config_word, pcicloud_read_config_word );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_read_config_dword, pcicloud_read_config_dword );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_write_config_byte, pcicloud_write_config_byte );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_write_config_word, pcicloud_write_config_word );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_write_config_dword, pcicloud_write_config_dword );
 | 
			
		||||
PROVIDE_PCIAPI ( cloud, pci_ioremap, pcicloud_ioremap );
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Initialise cloud VM PCI configuration space access
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
static void pcicloud_init ( void ) {
 | 
			
		||||
	static struct pci_api *apis[] = {
 | 
			
		||||
		&ecam_api, &pcibios_api, &pcidirect_api
 | 
			
		||||
	};
 | 
			
		||||
	struct pci_range range;
 | 
			
		||||
	unsigned int i;
 | 
			
		||||
 | 
			
		||||
	/* Select first API that successfully discovers an address range */
 | 
			
		||||
	for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) {
 | 
			
		||||
		pcicloud = apis[i];
 | 
			
		||||
		pcicloud_discover ( 0, &range );
 | 
			
		||||
		if ( range.count != 0 ) {
 | 
			
		||||
			DBGC ( pcicloud, "PCICLOUD selected %s API\n",
 | 
			
		||||
			       pcicloud->name );
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* The PCI direct API can never fail discovery since the range
 | 
			
		||||
	 * is hardcoded.
 | 
			
		||||
	 */
 | 
			
		||||
	assert ( range.count != 0 );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Cloud VM PCI configuration space access initialisation function */
 | 
			
		||||
struct init_fn pcicloud_init_fn __init_fn ( INIT_EARLY ) = {
 | 
			
		||||
	.initialise = pcicloud_init,
 | 
			
		||||
};
 | 
			
		||||
@ -42,6 +42,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
/** 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 +148,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 +162,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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -78,6 +78,15 @@ struct console_driver bios_console __attribute__ (( weak ));
 | 
			
		||||
/** Font corresponding to selected character width and height */
 | 
			
		||||
#define VESAFB_FONT VBE_FONT_8x16
 | 
			
		||||
 | 
			
		||||
/** Number of ASCII glyphs within the font */
 | 
			
		||||
#define VESAFB_ASCII 128
 | 
			
		||||
 | 
			
		||||
/** Glyph to render for non-ASCII characters
 | 
			
		||||
 *
 | 
			
		||||
 * We choose to use one of the box-drawing glyphs.
 | 
			
		||||
 */
 | 
			
		||||
#define VESAFB_UNKNOWN 0xfe
 | 
			
		||||
 | 
			
		||||
/* Forward declaration */
 | 
			
		||||
struct console_driver vesafb_console __console_driver;
 | 
			
		||||
 | 
			
		||||
@ -130,12 +139,24 @@ static int vesafb_rc ( unsigned int status ) {
 | 
			
		||||
/**
 | 
			
		||||
 * Get character glyph
 | 
			
		||||
 *
 | 
			
		||||
 * @v character		Character
 | 
			
		||||
 * @v character		Unicode character
 | 
			
		||||
 * @v glyph		Character glyph to fill in
 | 
			
		||||
 */
 | 
			
		||||
static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) {
 | 
			
		||||
	size_t offset = ( character * VESAFB_CHAR_HEIGHT );
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	size_t offset;
 | 
			
		||||
 | 
			
		||||
	/* Identify glyph */
 | 
			
		||||
	if ( character < VESAFB_ASCII ) {
 | 
			
		||||
		/* ASCII character: use corresponding glyph */
 | 
			
		||||
		index = character;
 | 
			
		||||
	} else {
 | 
			
		||||
		/* Non-ASCII character: use "unknown" glyph */
 | 
			
		||||
		index = VESAFB_UNKNOWN;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Copy glyph from BIOS font table */
 | 
			
		||||
	offset = ( index * VESAFB_CHAR_HEIGHT );
 | 
			
		||||
	copy_from_real ( glyph, vesafb.glyphs.segment,
 | 
			
		||||
			 ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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.*)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -3,5 +3,5 @@
 | 
			
		||||
 */
 | 
			
		||||
#ifdef PLATFORM_pcbios
 | 
			
		||||
#undef PCIAPI_PCBIOS
 | 
			
		||||
#define PCIAPI_DIRECT
 | 
			
		||||
#define PCIAPI_CLOUD
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,6 +26,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#define FDT_EFI
 | 
			
		||||
 | 
			
		||||
#define	NET_PROTO_IPV6		/* IPv6 protocol */
 | 
			
		||||
#define	NET_PROTO_LLDP		/* Link Layer Discovery protocol */
 | 
			
		||||
 | 
			
		||||
#define DOWNLOAD_PROTO_FILE	/* Local filesystem access */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -38,6 +38,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
/** Colour for debug messages */
 | 
			
		||||
#define colour FADT_SIGNATURE
 | 
			
		||||
 | 
			
		||||
/** ACPI table finder
 | 
			
		||||
 *
 | 
			
		||||
 * May be overridden at link time to inject tables for testing.
 | 
			
		||||
 */
 | 
			
		||||
typeof ( acpi_find ) *acpi_finder __attribute__ (( weak )) = acpi_find;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************
 | 
			
		||||
 *
 | 
			
		||||
 * Utility functions
 | 
			
		||||
@ -82,6 +88,18 @@ void acpi_fix_checksum ( struct acpi_header *acpi ) {
 | 
			
		||||
	acpi->checksum -= acpi_checksum ( virt_to_user ( acpi ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Locate ACPI table
 | 
			
		||||
 *
 | 
			
		||||
 * @v signature		Requested table signature
 | 
			
		||||
 * @v index		Requested index of table with this signature
 | 
			
		||||
 * @ret table		Table, or UNULL if not found
 | 
			
		||||
 */
 | 
			
		||||
userptr_t acpi_table ( uint32_t signature, unsigned int index ) {
 | 
			
		||||
 | 
			
		||||
	return ( *acpi_finder ) ( signature, index );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Locate ACPI table via RSDT
 | 
			
		||||
 *
 | 
			
		||||
@ -230,7 +248,7 @@ int acpi_extract ( uint32_t signature, void *data,
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Try DSDT first */
 | 
			
		||||
	fadt = acpi_find ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	fadt = acpi_table ( FADT_SIGNATURE, 0 );
 | 
			
		||||
	if ( fadt ) {
 | 
			
		||||
		copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) );
 | 
			
		||||
		dsdt = phys_to_user ( fadtab.dsdt );
 | 
			
		||||
@ -241,7 +259,7 @@ int acpi_extract ( uint32_t signature, void *data,
 | 
			
		||||
 | 
			
		||||
	/* Try all SSDTs */
 | 
			
		||||
	for ( i = 0 ; ; i++ ) {
 | 
			
		||||
		ssdt = acpi_find ( SSDT_SIGNATURE, i );
 | 
			
		||||
		ssdt = acpi_table ( SSDT_SIGNATURE, i );
 | 
			
		||||
		if ( ! ssdt )
 | 
			
		||||
			break;
 | 
			
		||||
		if ( ( rc = acpi_zsdt ( ssdt, signature, data,
 | 
			
		||||
 | 
			
		||||
@ -88,7 +88,7 @@ static int acpi_settings_fetch ( struct settings *settings,
 | 
			
		||||
	       acpi_name ( tag_signature ), tag_index, tag_offset, tag_len );
 | 
			
		||||
 | 
			
		||||
	/* Locate ACPI table */
 | 
			
		||||
	table = acpi_find ( tag_signature, tag_index );
 | 
			
		||||
	table = acpi_table ( tag_signature, tag_index );
 | 
			
		||||
	if ( ! table )
 | 
			
		||||
		return -ENOENT;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <ipxe/base16.h>
 | 
			
		||||
#include <ipxe/ethernet.h>
 | 
			
		||||
#include <ipxe/if_ether.h>
 | 
			
		||||
#include <ipxe/settings.h>
 | 
			
		||||
#include <ipxe/acpimac.h>
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
@ -46,11 +47,79 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
/** MACA signature */
 | 
			
		||||
#define MACA_SIGNATURE ACPI_SIGNATURE ( 'M', 'A', 'C', 'A' )
 | 
			
		||||
 | 
			
		||||
/** Maximum number of bytes to skip after AMAC/MACA signature
 | 
			
		||||
/** RTMA signature */
 | 
			
		||||
#define RTMA_SIGNATURE ACPI_SIGNATURE ( 'R', 'T', 'M', 'A' )
 | 
			
		||||
 | 
			
		||||
/** Maximum number of bytes to skip after ACPI signature
 | 
			
		||||
 *
 | 
			
		||||
 * This is entirely empirical.
 | 
			
		||||
 */
 | 
			
		||||
#define AUXMAC_MAX_SKIP 8
 | 
			
		||||
#define ACPIMAC_MAX_SKIP 8
 | 
			
		||||
 | 
			
		||||
/** An ACPI MAC extraction mechanism */
 | 
			
		||||
struct acpimac_extractor {
 | 
			
		||||
	/** Prefix string */
 | 
			
		||||
	const char *prefix;
 | 
			
		||||
	/** Encoded MAC length */
 | 
			
		||||
	size_t len;
 | 
			
		||||
	/** Decode MAC
 | 
			
		||||
	 *
 | 
			
		||||
	 * @v mac	Encoded MAC
 | 
			
		||||
	 * @v hw_addr	MAC address to fill in
 | 
			
		||||
	 * @ret rc	Return status code
 | 
			
		||||
	 */
 | 
			
		||||
	int ( * decode ) ( const char *mac, uint8_t *hw_addr );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decode Base16-encoded MAC address
 | 
			
		||||
 *
 | 
			
		||||
 * @v mac		Encoded MAC
 | 
			
		||||
 * @v hw_addr		MAC address to fill in
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int acpimac_decode_base16 ( const char *mac, uint8_t *hw_addr ) {
 | 
			
		||||
	int len;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Attempt to base16-decode MAC address */
 | 
			
		||||
	len = base16_decode ( mac, hw_addr, ETH_ALEN );
 | 
			
		||||
	if ( len < 0 ) {
 | 
			
		||||
		rc = len;
 | 
			
		||||
		DBGC ( colour, "ACPI could not decode base16 MAC \"%s\": %s\n",
 | 
			
		||||
		       mac, strerror ( rc ) );
 | 
			
		||||
		return rc;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Decode raw MAC address
 | 
			
		||||
 *
 | 
			
		||||
 * @v mac		Encoded MAC
 | 
			
		||||
 * @v hw_addr		MAC address to fill in
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int acpimac_decode_raw ( const char *mac, uint8_t *hw_addr ) {
 | 
			
		||||
 | 
			
		||||
	memcpy ( hw_addr, mac, ETH_ALEN );
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** "_AUXMAC_" extraction mechanism */
 | 
			
		||||
static struct acpimac_extractor acpimac_auxmac = {
 | 
			
		||||
	.prefix = "_AUXMAC_#",
 | 
			
		||||
	.len = ( ETH_ALEN * 2 ),
 | 
			
		||||
	.decode = acpimac_decode_base16,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** "_RTXMAC_" extraction mechanism */
 | 
			
		||||
static struct acpimac_extractor acpimac_rtxmac = {
 | 
			
		||||
	.prefix = "_RTXMAC_#",
 | 
			
		||||
	.len = ETH_ALEN,
 | 
			
		||||
	.decode = acpimac_decode_raw,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extract MAC address from DSDT/SSDT
 | 
			
		||||
@ -59,6 +128,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 * @v len		Length of DSDT/SSDT
 | 
			
		||||
 * @v offset		Offset of signature within DSDT/SSDT
 | 
			
		||||
 * @v data		Data buffer
 | 
			
		||||
 * @v extractor		ACPI MAC address extractor
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 *
 | 
			
		||||
 * Some vendors provide a "system MAC address" within the DSDT/SSDT,
 | 
			
		||||
@ -72,51 +142,44 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
 * string that appears shortly after an "AMAC" or "MACA" signature.
 | 
			
		||||
 * This should work for most implementations encountered in practice.
 | 
			
		||||
 */
 | 
			
		||||
static int acpi_extract_mac ( userptr_t zsdt, size_t len, size_t offset,
 | 
			
		||||
			      void *data ) {
 | 
			
		||||
	static const char prefix[9] = "_AUXMAC_#";
 | 
			
		||||
static int acpimac_extract ( userptr_t zsdt, size_t len, size_t offset,
 | 
			
		||||
			     void *data, struct acpimac_extractor *extractor ){
 | 
			
		||||
	size_t prefix_len = strlen ( extractor->prefix );
 | 
			
		||||
	uint8_t *hw_addr = data;
 | 
			
		||||
	size_t skip = 0;
 | 
			
		||||
	char auxmac[ sizeof ( prefix ) /* "_AUXMAC_#" */ +
 | 
			
		||||
		     ( ETH_ALEN * 2 ) /* MAC */ + 1 /* "#" */ + 1 /* NUL */ ];
 | 
			
		||||
	char *mac = &auxmac[ sizeof ( prefix ) ];
 | 
			
		||||
	int decoded_len;
 | 
			
		||||
	char buf[ prefix_len + extractor->len + 1 /* "#" */ + 1 /* NUL */ ];
 | 
			
		||||
	char *mac = &buf[prefix_len];
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Skip signature and at least one tag byte */
 | 
			
		||||
	offset += ( 4 /* signature */ + 1 /* tag byte */ );
 | 
			
		||||
 | 
			
		||||
	/* Scan for "_AUXMAC_#.....#" close to signature */
 | 
			
		||||
	/* Scan for suitable string close to signature */
 | 
			
		||||
	for ( skip = 0 ;
 | 
			
		||||
	      ( ( skip < AUXMAC_MAX_SKIP ) &&
 | 
			
		||||
		( offset + skip + sizeof ( auxmac ) ) < len ) ;
 | 
			
		||||
	      ( ( skip < ACPIMAC_MAX_SKIP ) &&
 | 
			
		||||
		( offset + skip + sizeof ( buf ) ) <= len ) ;
 | 
			
		||||
	      skip++ ) {
 | 
			
		||||
 | 
			
		||||
		/* Read value */
 | 
			
		||||
		copy_from_user ( auxmac, zsdt, ( offset + skip ),
 | 
			
		||||
				 sizeof ( auxmac ) );
 | 
			
		||||
		copy_from_user ( buf, zsdt, ( offset + skip ),
 | 
			
		||||
				 sizeof ( buf ) );
 | 
			
		||||
 | 
			
		||||
		/* Check for expected format */
 | 
			
		||||
		if ( memcmp ( auxmac, prefix, sizeof ( prefix ) ) != 0 )
 | 
			
		||||
		if ( memcmp ( buf, extractor->prefix, prefix_len ) != 0 )
 | 
			
		||||
			continue;
 | 
			
		||||
		if ( auxmac[ sizeof ( auxmac ) - 2 ] != '#' )
 | 
			
		||||
		if ( buf[ sizeof ( buf ) - 2 ] != '#' )
 | 
			
		||||
			continue;
 | 
			
		||||
		if ( auxmac[ sizeof ( auxmac ) - 1 ] != '\0' )
 | 
			
		||||
		if ( buf[ sizeof ( buf ) - 1 ] != '\0' )
 | 
			
		||||
			continue;
 | 
			
		||||
		DBGC ( colour, "ACPI found MAC string \"%s\"\n", auxmac );
 | 
			
		||||
		DBGC ( colour, "ACPI found MAC:\n" );
 | 
			
		||||
		DBGC_HDA ( colour, ( offset + skip ), buf, sizeof ( buf ) );
 | 
			
		||||
 | 
			
		||||
		/* Terminate MAC address string */
 | 
			
		||||
		mac = &auxmac[ sizeof ( prefix ) ];
 | 
			
		||||
		mac[ ETH_ALEN * 2 ] = '\0';
 | 
			
		||||
		mac[extractor->len] = '\0';
 | 
			
		||||
 | 
			
		||||
		/* Decode MAC address */
 | 
			
		||||
		decoded_len = base16_decode ( mac, hw_addr, ETH_ALEN );
 | 
			
		||||
		if ( decoded_len < 0 ) {
 | 
			
		||||
			rc = decoded_len;
 | 
			
		||||
			DBGC ( colour, "ACPI could not decode MAC \"%s\": %s\n",
 | 
			
		||||
			       mac, strerror ( rc ) );
 | 
			
		||||
		if ( ( rc = extractor->decode ( mac, hw_addr ) ) != 0 )
 | 
			
		||||
			return rc;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Check MAC address validity */
 | 
			
		||||
		if ( ! is_valid_ether_addr ( hw_addr ) ) {
 | 
			
		||||
@ -131,6 +194,36 @@ static int acpi_extract_mac ( userptr_t zsdt, size_t len, size_t offset,
 | 
			
		||||
	return -ENOENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extract "_AUXMAC_" MAC address from DSDT/SSDT
 | 
			
		||||
 *
 | 
			
		||||
 * @v zsdt		DSDT or SSDT
 | 
			
		||||
 * @v len		Length of DSDT/SSDT
 | 
			
		||||
 * @v offset		Offset of signature within DSDT/SSDT
 | 
			
		||||
 * @v data		Data buffer
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int acpimac_extract_auxmac ( userptr_t zsdt, size_t len, size_t offset,
 | 
			
		||||
				    void *data ) {
 | 
			
		||||
 | 
			
		||||
	return acpimac_extract ( zsdt, len, offset, data, &acpimac_auxmac );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extract "_RTXMAC_" MAC address from DSDT/SSDT
 | 
			
		||||
 *
 | 
			
		||||
 * @v zsdt		DSDT or SSDT
 | 
			
		||||
 * @v len		Length of DSDT/SSDT
 | 
			
		||||
 * @v offset		Offset of signature within DSDT/SSDT
 | 
			
		||||
 * @v data		Data buffer
 | 
			
		||||
 * @ret rc		Return status code
 | 
			
		||||
 */
 | 
			
		||||
static int acpimac_extract_rtxmac ( userptr_t zsdt, size_t len, size_t offset,
 | 
			
		||||
				    void *data ) {
 | 
			
		||||
 | 
			
		||||
	return acpimac_extract ( zsdt, len, offset, data, &acpimac_rtxmac );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extract MAC address from DSDT/SSDT
 | 
			
		||||
 *
 | 
			
		||||
@ -142,13 +235,54 @@ int acpi_mac ( uint8_t *hw_addr ) {
 | 
			
		||||
 | 
			
		||||
	/* Look for an "AMAC" address */
 | 
			
		||||
	if ( ( rc = acpi_extract ( AMAC_SIGNATURE, hw_addr,
 | 
			
		||||
				   acpi_extract_mac ) ) == 0 )
 | 
			
		||||
				   acpimac_extract_auxmac ) ) == 0 )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Look for a "MACA" address */
 | 
			
		||||
	if ( ( rc = acpi_extract ( MACA_SIGNATURE, hw_addr,
 | 
			
		||||
				   acpi_extract_mac ) ) == 0 )
 | 
			
		||||
				   acpimac_extract_auxmac ) ) == 0 )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	/* Look for a "RTMA" address */
 | 
			
		||||
	if ( ( rc = acpi_extract ( RTMA_SIGNATURE, hw_addr,
 | 
			
		||||
				   acpimac_extract_rtxmac ) ) == 0 )
 | 
			
		||||
		return 0;
 | 
			
		||||
 | 
			
		||||
	return -ENOENT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Fetch system MAC address setting
 | 
			
		||||
 *
 | 
			
		||||
 * @v data		Buffer to fill with setting data
 | 
			
		||||
 * @v len		Length of buffer
 | 
			
		||||
 * @ret len		Length of setting data, or negative error
 | 
			
		||||
 */
 | 
			
		||||
static int sysmac_fetch ( void *data, size_t len ) {
 | 
			
		||||
	uint8_t mac[ETH_ALEN];
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Try fetching ACPI MAC address */
 | 
			
		||||
	if ( ( rc = acpi_mac ( mac ) ) != 0 )
 | 
			
		||||
		return rc;
 | 
			
		||||
 | 
			
		||||
	/* Return MAC address */
 | 
			
		||||
	if ( len > sizeof ( mac ) )
 | 
			
		||||
		len = sizeof ( mac );
 | 
			
		||||
	memcpy ( data, mac, len );
 | 
			
		||||
	return ( sizeof ( mac ) );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** System MAC address setting */
 | 
			
		||||
const struct setting sysmac_setting __setting ( SETTING_MISC, sysmac ) = {
 | 
			
		||||
	.name = "sysmac",
 | 
			
		||||
	.description = "System MAC",
 | 
			
		||||
	.type = &setting_type_hex,
 | 
			
		||||
	.scope = &builtin_scope,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/** System MAC address built-in setting */
 | 
			
		||||
struct builtin_setting sysmac_builtin_setting __builtin_setting = {
 | 
			
		||||
	.setting = &sysmac_setting,
 | 
			
		||||
	.fetch = sysmac_fetch,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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 */
 | 
			
		||||
@ -90,30 +93,74 @@ static void cachedhcp_free ( struct cached_dhcp_packet *cache ) {
 | 
			
		||||
 */
 | 
			
		||||
static int cachedhcp_apply ( struct cached_dhcp_packet *cache,
 | 
			
		||||
			     struct net_device *netdev ) {
 | 
			
		||||
	struct settings *settings;
 | 
			
		||||
	struct settings *settings = NULL;
 | 
			
		||||
	struct ll_protocol *ll_protocol;
 | 
			
		||||
	const uint8_t *chaddr;
 | 
			
		||||
	uint8_t *hw_addr;
 | 
			
		||||
	uint8_t *ll_addr;
 | 
			
		||||
	size_t ll_addr_len;
 | 
			
		||||
	int rc;
 | 
			
		||||
 | 
			
		||||
	/* Do nothing if cache is empty */
 | 
			
		||||
	if ( ! cache->dhcppkt )
 | 
			
		||||
		return 0;
 | 
			
		||||
	chaddr = cache->dhcppkt->dhcphdr->chaddr;
 | 
			
		||||
 | 
			
		||||
	/* Do nothing unless cached packet's MAC address matches this
 | 
			
		||||
	 * network device, if specified.
 | 
			
		||||
	 */
 | 
			
		||||
	/* Handle association with network device, if specified */
 | 
			
		||||
	if ( netdev ) {
 | 
			
		||||
		if ( memcmp ( netdev->ll_addr, cache->dhcppkt->dhcphdr->chaddr,
 | 
			
		||||
			      netdev->ll_protocol->ll_addr_len ) != 0 ) {
 | 
			
		||||
			DBGC ( colour, "CACHEDHCP %s does not match %s\n",
 | 
			
		||||
			       cache->name, netdev->name );
 | 
			
		||||
		hw_addr = netdev->hw_addr;
 | 
			
		||||
		ll_addr = netdev->ll_addr;
 | 
			
		||||
		ll_protocol = netdev->ll_protocol;
 | 
			
		||||
		ll_addr_len = ll_protocol->ll_addr_len;
 | 
			
		||||
 | 
			
		||||
		/* If cached packet's MAC address matches the network
 | 
			
		||||
		 * device's permanent MAC address, then assume that
 | 
			
		||||
		 * the permanent MAC address ought to be the network
 | 
			
		||||
		 * device's current link-layer address.
 | 
			
		||||
		 *
 | 
			
		||||
		 * This situation can arise when the PXE ROM does not
 | 
			
		||||
		 * understand the system-specific mechanism for
 | 
			
		||||
		 * overriding the MAC address, and so uses the
 | 
			
		||||
		 * permanent MAC address instead.  We choose to match
 | 
			
		||||
		 * this behaviour in order to minimise surprise.
 | 
			
		||||
		 */
 | 
			
		||||
		if ( memcmp ( hw_addr, chaddr, ll_addr_len ) == 0 ) {
 | 
			
		||||
			if ( memcmp ( hw_addr, ll_addr, ll_addr_len ) != 0 ) {
 | 
			
		||||
				DBGC ( colour, "CACHEDHCP %s resetting %s MAC "
 | 
			
		||||
				       "%s ", cache->name, netdev->name,
 | 
			
		||||
				       ll_protocol->ntoa ( ll_addr ) );
 | 
			
		||||
				DBGC ( colour, "-> %s\n",
 | 
			
		||||
				       ll_protocol->ntoa ( hw_addr ) );
 | 
			
		||||
			}
 | 
			
		||||
			memcpy ( ll_addr, hw_addr, ll_addr_len );
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Do nothing unless cached packet's MAC address
 | 
			
		||||
		 * matches this network device.
 | 
			
		||||
		 */
 | 
			
		||||
		if ( memcmp ( ll_addr, chaddr, ll_addr_len ) != 0 ) {
 | 
			
		||||
			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;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Use network device's settings block */
 | 
			
		||||
		settings = netdev_settings ( netdev );
 | 
			
		||||
		DBGC ( colour, "CACHEDHCP %s is for %s\n",
 | 
			
		||||
		       cache->name, netdev->name );
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Select appropriate parent settings block */
 | 
			
		||||
	settings = ( netdev ? netdev_settings ( netdev ) : NULL );
 | 
			
		||||
 | 
			
		||||
	/* Register settings */
 | 
			
		||||
	if ( ( rc = register_settings ( &cache->dhcppkt->settings, settings,
 | 
			
		||||
					cache->name ) ) != 0 ) {
 | 
			
		||||
@ -132,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;
 | 
			
		||||
@ -192,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=\" "
 | 
			
		||||
 | 
			
		||||
@ -446,6 +446,11 @@ void fbcon_putchar ( struct fbcon *fbcon, int character ) {
 | 
			
		||||
	if ( character < 0 )
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Accumulate Unicode characters */
 | 
			
		||||
	character = utf8_accumulate ( &fbcon->utf8, character );
 | 
			
		||||
	if ( character == 0 )
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	/* Handle control characters */
 | 
			
		||||
	switch ( character ) {
 | 
			
		||||
	case '\r':
 | 
			
		||||
 | 
			
		||||
@ -27,6 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <ctype.h>
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <libgen.h>
 | 
			
		||||
@ -569,3 +570,33 @@ struct image * image_memory ( const char *name, userptr_t data, size_t len ) {
 | 
			
		||||
 err_alloc_image:
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Find argument within image command line
 | 
			
		||||
 *
 | 
			
		||||
 * @v image		Image
 | 
			
		||||
 * @v key		Argument search key (including trailing delimiter)
 | 
			
		||||
 * @ret value		Argument value, or NULL if not found
 | 
			
		||||
 */
 | 
			
		||||
const char * image_argument ( struct image *image, const char *key ) {
 | 
			
		||||
	const char *cmdline = image->cmdline;
 | 
			
		||||
	const char *search;
 | 
			
		||||
	const char *match;
 | 
			
		||||
	const char *next;
 | 
			
		||||
 | 
			
		||||
	/* Find argument */
 | 
			
		||||
	for ( search = cmdline ; search ; search = next ) {
 | 
			
		||||
 | 
			
		||||
		/* Find next occurrence, if any */
 | 
			
		||||
		match = strstr ( search, key );
 | 
			
		||||
		if ( ! match )
 | 
			
		||||
			break;
 | 
			
		||||
		next = ( match + strlen ( key ) );
 | 
			
		||||
 | 
			
		||||
		/* Check preceding delimiter, if any */
 | 
			
		||||
		if ( ( match == cmdline ) || isspace ( match[-1] ) )
 | 
			
		||||
			return next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										137
									
								
								src/core/utf8.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								src/core/utf8.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,137 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2022 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 );
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <ipxe/utf8.h>
 | 
			
		||||
 | 
			
		||||
/** @file
 | 
			
		||||
 *
 | 
			
		||||
 * UTF-8 Unicode encoding
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Accumulate Unicode character from UTF-8 byte sequence
 | 
			
		||||
 *
 | 
			
		||||
 * @v utf8		UTF-8 accumulator
 | 
			
		||||
 * @v byte		UTF-8 byte
 | 
			
		||||
 * @ret character	Unicode character, or 0 if incomplete
 | 
			
		||||
 */
 | 
			
		||||
unsigned int utf8_accumulate ( struct utf8_accumulator *utf8, uint8_t byte ) {
 | 
			
		||||
	static unsigned int min[] = {
 | 
			
		||||
		UTF8_MIN_TWO,
 | 
			
		||||
		UTF8_MIN_THREE,
 | 
			
		||||
		UTF8_MIN_FOUR,
 | 
			
		||||
	};
 | 
			
		||||
	unsigned int shift;
 | 
			
		||||
	unsigned int len;
 | 
			
		||||
	uint8_t tmp;
 | 
			
		||||
 | 
			
		||||
	/* Handle continuation bytes */
 | 
			
		||||
	if ( UTF8_IS_CONTINUATION ( byte ) ) {
 | 
			
		||||
 | 
			
		||||
		/* Fail if this is an unexpected continuation byte */
 | 
			
		||||
		if ( utf8->remaining == 0 ) {
 | 
			
		||||
			DBGC ( utf8, "UTF8 %p unexpected %02x\n", utf8, byte );
 | 
			
		||||
			return UTF8_INVALID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Apply continuation byte */
 | 
			
		||||
		utf8->character <<= UTF8_CONTINUATION_BITS;
 | 
			
		||||
		utf8->character |= ( byte & UTF8_CONTINUATION_MASK );
 | 
			
		||||
 | 
			
		||||
		/* Return 0 if more continuation bytes are expected */
 | 
			
		||||
		if ( --utf8->remaining != 0 )
 | 
			
		||||
			return 0;
 | 
			
		||||
 | 
			
		||||
		/* Fail if sequence is illegal */
 | 
			
		||||
		if ( utf8->character < utf8->min ) {
 | 
			
		||||
			DBGC ( utf8, "UTF8 %p illegal %02x\n", utf8,
 | 
			
		||||
			       utf8->character );
 | 
			
		||||
			return UTF8_INVALID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Sanity check */
 | 
			
		||||
		assert ( utf8->character != 0 );
 | 
			
		||||
 | 
			
		||||
		/* Return completed character */
 | 
			
		||||
		DBGC2 ( utf8, "UTF8 %p accumulated %02x\n",
 | 
			
		||||
			utf8, utf8->character );
 | 
			
		||||
		return utf8->character;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Reset state and report failure if this is an unexpected
 | 
			
		||||
	 * non-continuation byte.  Do not return UTF8_INVALID since
 | 
			
		||||
	 * doing so could cause us to drop a valid ASCII character.
 | 
			
		||||
	 */
 | 
			
		||||
	if ( utf8->remaining != 0 ) {
 | 
			
		||||
		shift = ( utf8->remaining * UTF8_CONTINUATION_BITS );
 | 
			
		||||
		DBGC ( utf8, "UTF8 %p unexpected %02x (partial %02x/%02x)\n",
 | 
			
		||||
		       utf8, byte, ( utf8->character << shift ),
 | 
			
		||||
		       ( ( 1 << shift ) - 1 ) );
 | 
			
		||||
		utf8->remaining = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Handle initial bytes */
 | 
			
		||||
	if ( ! UTF8_IS_ASCII ( byte ) ) {
 | 
			
		||||
 | 
			
		||||
		/* Sanity check */
 | 
			
		||||
		assert ( utf8->remaining == 0 );
 | 
			
		||||
 | 
			
		||||
		/* Count total number of bytes in sequence */
 | 
			
		||||
		tmp = byte;
 | 
			
		||||
		len = 0;
 | 
			
		||||
		while ( tmp & UTF8_HIGH_BIT ) {
 | 
			
		||||
			tmp <<= 1;
 | 
			
		||||
			len++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Check for illegal length */
 | 
			
		||||
		if ( len > UTF8_MAX_LEN ) {
 | 
			
		||||
			DBGC ( utf8, "UTF8 %p illegal %02x length %d\n",
 | 
			
		||||
			       utf8, byte, len );
 | 
			
		||||
			return UTF8_INVALID;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		/* Store initial bits of character */
 | 
			
		||||
		utf8->character = ( tmp >> len );
 | 
			
		||||
 | 
			
		||||
		/* Store number of bytes remaining */
 | 
			
		||||
		len--;
 | 
			
		||||
		utf8->remaining = len;
 | 
			
		||||
		assert ( utf8->remaining > 0 );
 | 
			
		||||
 | 
			
		||||
		/* Store minimum legal value */
 | 
			
		||||
		utf8->min = min[ len - 1 ];
 | 
			
		||||
		assert ( utf8->min > 0 );
 | 
			
		||||
 | 
			
		||||
		/* Await continuation bytes */
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Handle ASCII bytes */
 | 
			
		||||
	return byte;
 | 
			
		||||
}
 | 
			
		||||
@ -38,6 +38,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
 | 
			
		||||
#include <ipxe/crypto.h>
 | 
			
		||||
#include <ipxe/ecb.h>
 | 
			
		||||
#include <ipxe/cbc.h>
 | 
			
		||||
#include <ipxe/gcm.h>
 | 
			
		||||
#include <ipxe/aes.h>
 | 
			
		||||
 | 
			
		||||
/** AES strides
 | 
			
		||||
@ -778,25 +779,18 @@ static int aes_setkey ( void *ctx, const void *key, size_t keylen ) {
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Set initialisation vector
 | 
			
		||||
 *
 | 
			
		||||
 * @v ctx		Context
 | 
			
		||||
 * @v iv		Initialisation vector
 | 
			
		||||
 */
 | 
			
		||||
static void aes_setiv ( void *ctx __unused, const void *iv __unused ) {
 | 
			
		||||
	/* Nothing to do */
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Basic AES algorithm */
 | 
			
		||||
struct cipher_algorithm aes_algorithm = {
 | 
			
		||||
	.name = "aes",
 | 
			
		||||
	.ctxsize = sizeof ( struct aes_context ),
 | 
			
		||||
	.blocksize = AES_BLOCKSIZE,
 | 
			
		||||
	.alignsize = 0,
 | 
			
		||||
	.authsize = 0,
 | 
			
		||||
	.setkey = aes_setkey,
 | 
			
		||||
	.setiv = aes_setiv,
 | 
			
		||||
	.setiv = cipher_null_setiv,
 | 
			
		||||
	.encrypt = aes_encrypt,
 | 
			
		||||
	.decrypt = aes_decrypt,
 | 
			
		||||
	.auth = cipher_null_auth,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* AES in Electronic Codebook mode */
 | 
			
		||||
@ -806,3 +800,7 @@ ECB_CIPHER ( aes_ecb, aes_ecb_algorithm,
 | 
			
		||||
/* AES in Cipher Block Chaining mode */
 | 
			
		||||
CBC_CIPHER ( aes_cbc, aes_cbc_algorithm,
 | 
			
		||||
	     aes_algorithm, struct aes_context, AES_BLOCKSIZE );
 | 
			
		||||
 | 
			
		||||
/* AES in Galois/Counter mode */
 | 
			
		||||
GCM_CIPHER ( aes_gcm, aes_gcm_algorithm,
 | 
			
		||||
	     aes_algorithm, struct aes_context, AES_BLOCKSIZE );
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user