2018-06-05 14:34:03 -04:00
/*
* x86_64 - efi / bootboot . c
*
2021-01-15 15:07:25 -05:00
* Copyright ( C ) 2017 - 2021 bzt ( bztsrc @ gitlab )
2018-06-05 14:34:03 -04:00
*
* Permission is hereby granted , free of charge , to any person
* obtaining a copy of this software and associated documentation
* files ( the " Software " ) , to deal in the Software without
* restriction , including without limitation the rights to use , copy ,
* modify , merge , publish , distribute , sublicense , and / or sell copies
* of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND ,
* EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY ,
* WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE .
*
* This file is part of the BOOTBOOT Protocol package .
* @ brief Booting code for EFI
*
*/
# define BBDEBUG 1
//#define GOP_DEBUG BBDEBUG
2020-09-17 16:36:06 -04:00
# define USE_MP_SERVICES 0 /* without fallback to ACPI parser and APIC INIT + SIPI */
2018-06-05 14:34:03 -04:00
# if BBDEBUG
# define DBG(fmt, ...) do{Print(fmt,__VA_ARGS__); }while(0);
# else
# define DBG(fmt, ...)
# endif
// get UEFI functions and environment
# include <efi.h>
# include <efilib.h>
2018-11-09 05:59:14 -05:00
# include <eficon.h>
2018-06-05 14:34:03 -04:00
# include <efiprot.h>
# include <efigpt.h>
# include "tinf.h"
2020-06-24 10:33:08 -04:00
// get BOOTBOOT specific stuff
# include "../dist/bootboot.h"
2018-06-05 14:34:03 -04:00
/*** ELF64 defines and structs ***/
# define ELFMAG "\177ELF"
# define SELFMAG 4
# define EI_CLASS 4 /* File class byte index */
# define ELFCLASS64 2 /* 64-bit objects */
# define EI_DATA 5 /* Data encoding byte index */
# define ELFDATA2LSB 1 /* 2's complement, little endian */
# define PT_LOAD 1 /* Loadable program segment */
# define EM_X86_64 62 /* AMD x86-64 architecture */
typedef struct
{
unsigned char e_ident [ 16 ] ; /* Magic number and other info */
UINT16 e_type ; /* Object file type */
UINT16 e_machine ; /* Architecture */
UINT32 e_version ; /* Object file version */
UINT64 e_entry ; /* Entry point virtual address */
UINT64 e_phoff ; /* Program header table file offset */
UINT64 e_shoff ; /* Section header table file offset */
UINT32 e_flags ; /* Processor-specific flags */
UINT16 e_ehsize ; /* ELF header size in bytes */
UINT16 e_phentsize ; /* Program header table entry size */
UINT16 e_phnum ; /* Program header table entry count */
UINT16 e_shentsize ; /* Section header table entry size */
UINT16 e_shnum ; /* Section header table entry count */
UINT16 e_shstrndx ; /* Section header string table index */
} Elf64_Ehdr ;
typedef struct
{
UINT32 p_type ; /* Segment type */
UINT32 p_flags ; /* Segment flags */
UINT64 p_offset ; /* Segment file offset */
UINT64 p_vaddr ; /* Segment virtual address */
UINT64 p_paddr ; /* Segment physical address */
UINT64 p_filesz ; /* Segment size in file */
UINT64 p_memsz ; /* Segment size in memory */
UINT64 p_align ; /* Segment alignment */
} Elf64_Phdr ;
2020-06-15 11:11:59 -04:00
typedef struct
{
UINT32 sh_name ; /* Section name (string tbl index) */
UINT32 sh_type ; /* Section type */
UINT64 sh_flags ; /* Section flags */
UINT64 sh_addr ; /* Section virtual addr at execution */
UINT64 sh_offset ; /* Section file offset */
UINT64 sh_size ; /* Section size in bytes */
UINT32 sh_link ; /* Link to another section */
UINT32 sh_info ; /* Additional section information */
UINT64 sh_addralign ; /* Section alignment */
UINT64 sh_entsize ; /* Entry size if section holds table */
} Elf64_Shdr ;
typedef struct
{
UINT32 st_name ; /* Symbol name (string tbl index) */
UINT8 st_info ; /* Symbol type and binding */
UINT8 st_other ; /* Symbol visibility */
UINT16 st_shndx ; /* Section index */
UINT64 st_value ; /* Symbol value */
UINT64 st_size ; /* Symbol size */
} Elf64_Sym ;
2018-06-05 14:34:03 -04:00
/*** PE32+ defines and structs ***/
# define MZ_MAGIC 0x5a4d /* "MZ" */
# define PE_MAGIC 0x00004550 /* "PE\0\0" */
# define IMAGE_FILE_MACHINE_AMD64 0x8664 /* AMD x86_64 architecture */
# define PE_OPT_MAGIC_PE32PLUS 0x020b /* PE32+ format */
typedef struct
{
UINT16 magic ; /* MZ magic */
UINT16 reserved [ 29 ] ; /* reserved */
UINT32 peaddr ; /* address of pe header */
} mz_hdr ;
typedef struct {
UINT32 magic ; /* PE magic */
UINT16 machine ; /* machine type */
UINT16 sections ; /* number of sections */
UINT32 timestamp ; /* time_t */
UINT32 sym_table ; /* symbol table offset */
2020-06-15 11:11:59 -04:00
INT32 numsym ; /* number of symbols */
2018-06-05 14:34:03 -04:00
UINT16 opt_hdr_size ; /* size of optional header */
UINT16 flags ; /* flags */
UINT16 file_type ; /* file type, PE32PLUS magic */
UINT8 ld_major ; /* linker major version */
UINT8 ld_minor ; /* linker minor version */
UINT32 text_size ; /* size of text section(s) */
UINT32 data_size ; /* size of data section(s) */
UINT32 bss_size ; /* size of bss section(s) */
2020-06-15 11:11:59 -04:00
INT32 entry_point ; /* file offset of entry point */
INT32 code_base ; /* relative code addr in ram */
2018-06-05 14:34:03 -04:00
} pe_hdr ;
2020-06-15 11:11:59 -04:00
typedef struct {
UINT32 iszero ; /* if this is not zero, then iszero+nameoffs gives UTF-8 string */
UINT32 nameoffs ;
INT32 value ; /* value of the symbol */
UINT16 section ; /* section it belongs to */
UINT16 type ; /* symbol type */
UINT8 storclass ; /* storage class */
UINT8 auxsyms ; /* number of pe_sym records following */
} pe_sym ;
2018-06-05 14:34:03 -04:00
/*** EFI defines and structs ***/
struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL ;
struct EFI_FILE_PROTOCOL ;
2020-09-17 16:36:06 -04:00
# if USE_MP_SERVICES
2019-02-07 18:41:34 -05:00
# ifndef EFI_MP_SERVICES_PROTOCOL_GUID
# define EFI_MP_SERVICES_PROTOCOL_GUID \
{ 0x3fdda605 , 0xa76e , 0x4f46 , { 0xad , 0x29 , 0x12 , 0xf4 , 0x53 , 0x1b , 0x3d , 0x08 } }
typedef struct _EFI_MP_SERVICES_PROTOCOL EFI_MP_SERVICES_PROTOCOL ;
# define PROCESSOR_AS_BSP_BIT 0x00000001
typedef struct {
UINT64 ProcessorId ;
UINT32 StatusFlag ;
} EFI_PROCESSOR_INFORMATION ;
typedef
EFI_STATUS
( EFIAPI * EFI_MP_SERVICES_DUMMY ) (
IN EFI_MP_SERVICES_PROTOCOL * This
) ;
typedef
VOID
( EFIAPI * EFI_AP_PROCEDURE ) (
IN OUT VOID * Buffer
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS ) (
IN EFI_MP_SERVICES_PROTOCOL * This ,
OUT UINTN * NumberOfProcessors ,
OUT UINTN * NumberOfEnabledProcessors
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_MP_SERVICES_GET_PROCESSOR_INFO ) (
IN EFI_MP_SERVICES_PROTOCOL * This ,
IN UINTN ProcessorNumber ,
OUT EFI_PROCESSOR_INFORMATION * ProcessorInfoBuffer
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_MP_SERVICES_STARTUP_THIS_AP ) (
IN EFI_MP_SERVICES_PROTOCOL * This ,
IN EFI_AP_PROCEDURE Procedure ,
IN UINTN ProcessorNumber ,
IN EFI_EVENT WaitEvent OPTIONAL ,
IN UINTN TimeoutInMicroseconds ,
IN VOID * ProcedureArgument OPTIONAL ,
OUT BOOLEAN * Finished OPTIONAL
) ;
struct _EFI_MP_SERVICES_PROTOCOL {
EFI_MP_SERVICES_GET_NUMBER_OF_PROCESSORS GetNumberOfProcessors ;
EFI_MP_SERVICES_GET_PROCESSOR_INFO GetProcessorInfo ;
EFI_MP_SERVICES_DUMMY StartupAllAPs ;
EFI_MP_SERVICES_STARTUP_THIS_AP StartupThisAP ;
EFI_MP_SERVICES_DUMMY SwitchBSP ;
EFI_MP_SERVICES_DUMMY EnableDisableAP ;
EFI_MP_SERVICES_DUMMY WhoAmI ;
} ;
# endif
2020-09-17 16:36:06 -04:00
# else
extern void ap_trampoline ( ) ;
UINT16 lapic_ids [ 1024 ] ;
2021-01-22 21:20:04 -05:00
UINT64 lapic_addr = 0 ;
2020-09-17 16:36:06 -04:00
# endif
2019-02-07 18:41:34 -05:00
2018-06-05 14:34:03 -04:00
typedef
EFI_STATUS
( EFIAPI * EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME ) (
IN struct EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * This ,
OUT struct EFI_FILE_PROTOCOL * * Root
) ;
/* Intel EFI headers has simple file protocol, but not GNU EFI */
# ifndef EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION
typedef struct _EFI_SIMPLE_FILE_SYSTEM_PROTOCOL {
UINT64 Revision ;
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume ;
} EFI_SIMPLE_FILE_SYSTEM_PROTOCOL ;
typedef struct _EFI_FILE_PROTOCOL {
UINT64 Revision ;
EFI_FILE_OPEN Open ;
EFI_FILE_CLOSE Close ;
EFI_FILE_DELETE Delete ;
EFI_FILE_READ Read ;
EFI_FILE_WRITE Write ;
EFI_FILE_GET_POSITION GetPosition ;
EFI_FILE_SET_POSITION SetPosition ;
EFI_FILE_GET_INFO GetInfo ;
EFI_FILE_SET_INFO SetInfo ;
EFI_FILE_FLUSH Flush ;
} EFI_FILE_PROTOCOL ;
# endif
# ifndef EFI_PCI_OPTION_ROM_TABLE_GUID
# define EFI_PCI_OPTION_ROM_TABLE_GUID \
{ 0x7462660f , 0x1cbd , 0x48da , { 0xad , 0x11 , 0x91 , 0x71 , 0x79 , 0x13 , 0x83 , 0x1c } }
typedef struct {
2018-06-28 07:10:26 -04:00
EFI_PHYSICAL_ADDRESS RomAddress ;
2018-06-05 14:34:03 -04:00
EFI_MEMORY_TYPE MemoryType ;
2018-06-28 07:10:26 -04:00
UINT32 RomLength ;
UINT32 Seg ;
UINT8 Bus ;
UINT8 Dev ;
UINT8 Func ;
BOOLEAN ExecutedLegacyBiosImage ;
2018-06-05 14:34:03 -04:00
BOOLEAN DontLoadEfiRom ;
} EFI_PCI_OPTION_ROM_DESCRIPTOR ;
typedef struct {
UINT64 PciOptionRomCount ;
EFI_PCI_OPTION_ROM_DESCRIPTOR * PciOptionRomDescriptors ;
} EFI_PCI_OPTION_ROM_TABLE ;
# endif
2020-09-19 19:43:33 -04:00
# ifndef EFI_SERIAL_IO_PROTOCOL_GUID
# define EFI_SERIAL_IO_PROTOCOL_GUID \
{ 0xBB25CF6F , 0xF1D4 , 0x11D2 , { 0x9A , 0x0C , 0x00 , 0x90 , 0x27 , 0x3F , 0xC1 , 0xFD } }
typedef enum {
DefaultParity ,
NoParity ,
EvenParity ,
OddParity ,
MarkParity ,
SpaceParity
} EFI_PARITY_TYPE ;
typedef enum {
DefaultStopBits ,
OneStopBit , // 1 stop bit
OneFiveStopBits , // 1.5 stop bits
TwoStopBits // 2 stop bits
} EFI_STOP_BITS_TYPE ;
typedef
EFI_STATUS
( EFIAPI * EFI_SERIAL_DUMMY ) (
IN EFI_SERIAL_IO_PROTOCOL * This
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_SERIAL_SET_ATTRIBUTES ) (
IN struct _EFI_SERIAL_IO_PROTOCOL * This ,
IN UINT64 BaudRate ,
IN UINT32 ReceiveFifoDepth ,
IN UINT32 Timeout ,
IN EFI_PARITY_TYPE Parity ,
IN UINT8 DataBits ,
IN EFI_STOP_BITS_TYPE StopBits
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_SERIAL_WRITE ) (
IN struct _EFI_SERIAL_IO_PROTOCOL * This ,
IN OUT UINTN * BufferSize ,
IN VOID * Buffer
) ;
typedef
EFI_STATUS
( EFIAPI * EFI_SERIAL_READ ) (
IN struct _EFI_SERIAL_IO_PROTOCOL * This ,
IN OUT UINTN * BufferSize ,
OUT VOID * Buffer
) ;
typedef struct _EFI_SERIAL_IO_PROTOCOL {
UINT32 Revision ;
EFI_SERIAL_DUMMY Reset ;
EFI_SERIAL_SET_ATTRIBUTES SetAttributes ;
EFI_SERIAL_DUMMY SetControl ;
EFI_SERIAL_DUMMY GetControl ;
EFI_SERIAL_WRITE Write ;
EFI_SERIAL_READ Read ;
} EFI_SERIAL_IO_PROTOCOL ;
# endif
2018-06-05 14:34:03 -04:00
/*** other defines and structs ***/
typedef struct {
UINT8 magic [ 8 ] ;
UINT8 chksum ;
CHAR8 oemid [ 6 ] ;
UINT8 revision ;
UINT32 rsdt ;
UINT32 length ;
UINT64 xsdt ;
UINT32 echksum ;
} __attribute__ ( ( packed ) ) ACPI_RSDPTR ;
# define PAGESIZE 4096
2018-11-09 05:59:14 -05:00
/**
* return type for fs drivers
*/
typedef struct {
UINT8 * ptr ;
UINTN size ;
} file_t ;
2018-06-05 14:34:03 -04:00
/*** common variables ***/
file_t env ; // environment file descriptor
file_t initrd ; // initrd file descriptor
file_t core ; // kernel file descriptor
BOOTBOOT * bootboot ; // the BOOTBOOT structure
UINT64 * paging ; // paging table for MMU
UINT64 entrypoint ; // kernel entry point
2020-06-15 21:35:19 -04:00
UINT64 fb_addr = BOOTBOOT_FB ; // virtual addresses
UINT64 bb_addr = BOOTBOOT_INFO ;
UINT64 env_addr = BOOTBOOT_ENV ;
UINT64 core_addr = BOOTBOOT_CORE ;
2021-01-20 23:54:39 -05:00
UINT64 initstack = 1024 ;
2020-11-09 08:10:55 -05:00
2018-06-05 14:34:03 -04:00
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL * Volume ;
EFI_FILE_HANDLE RootDir ;
EFI_FILE_PROTOCOL * Root ;
2018-11-09 05:59:14 -05:00
SIMPLE_INPUT_INTERFACE * CI ;
2021-01-21 15:37:00 -05:00
unsigned char * kne , nosmp = 0 ;
2021-01-24 00:14:50 -05:00
volatile char bsp_done = 0 , ap_done = 0 ;
2018-06-05 14:34:03 -04:00
// default environment variables. M$ states that 1024x768 must be supported
int reqwidth = 1024 , reqheight = 768 ;
char * kernelname = " sys/core " ;
// alternative environment name
char * cfgname = " sys/config " ;
2018-11-09 05:59:14 -05:00
/**
* SHA - 256
*/
typedef struct {
UINT8 d [ 64 ] ;
UINT32 l ;
UINT32 b [ 2 ] ;
UINT32 s [ 8 ] ;
} SHA256_CTX ;
# define SHA_ADD(a,b,c) if(a>0xffffffff-(c))b++;a+=c;
# define SHA_ROTL(a,b) (((a)<<(b))|((a)>>(32-(b))))
# define SHA_ROTR(a,b) (((a)>>(b))|((a)<<(32-(b))))
# define SHA_CH(x,y,z) (((x)&(y))^(~(x)&(z)))
# define SHA_MAJ(x,y,z) (((x)&(y))^((x)&(z))^((y)&(z)))
# define SHA_EP0(x) (SHA_ROTR(x,2)^SHA_ROTR(x,13)^SHA_ROTR(x,22))
# define SHA_EP1(x) (SHA_ROTR(x,6)^SHA_ROTR(x,11)^SHA_ROTR(x,25))
# define SHA_SIG0(x) (SHA_ROTR(x,7)^SHA_ROTR(x,18)^((x)>>3))
# define SHA_SIG1(x) (SHA_ROTR(x,17)^SHA_ROTR(x,19)^((x)>>10))
static UINT32 sha256_k [ 64 ] = {
0x428a2f98 , 0x71374491 , 0xb5c0fbcf , 0xe9b5dba5 , 0x3956c25b , 0x59f111f1 , 0x923f82a4 , 0xab1c5ed5 ,
0xd807aa98 , 0x12835b01 , 0x243185be , 0x550c7dc3 , 0x72be5d74 , 0x80deb1fe , 0x9bdc06a7 , 0xc19bf174 ,
0xe49b69c1 , 0xefbe4786 , 0x0fc19dc6 , 0x240ca1cc , 0x2de92c6f , 0x4a7484aa , 0x5cb0a9dc , 0x76f988da ,
0x983e5152 , 0xa831c66d , 0xb00327c8 , 0xbf597fc7 , 0xc6e00bf3 , 0xd5a79147 , 0x06ca6351 , 0x14292967 ,
0x27b70a85 , 0x2e1b2138 , 0x4d2c6dfc , 0x53380d13 , 0x650a7354 , 0x766a0abb , 0x81c2c92e , 0x92722c85 ,
0xa2bfe8a1 , 0xa81a664b , 0xc24b8b70 , 0xc76c51a3 , 0xd192e819 , 0xd6990624 , 0xf40e3585 , 0x106aa070 ,
0x19a4c116 , 0x1e376c08 , 0x2748774c , 0x34b0bcb5 , 0x391c0cb3 , 0x4ed8aa4a , 0x5b9cca4f , 0x682e6ff3 ,
0x748f82ee , 0x78a5636f , 0x84c87814 , 0x8cc70208 , 0x90befffa , 0xa4506ceb , 0xbef9a3f7 , 0xc67178f2
} ;
void sha256_t ( SHA256_CTX * ctx )
{
UINT32 a , b , c , d , e , f , g , h , i , j , t1 , t2 , m [ 64 ] ;
for ( i = 0 , j = 0 ; i < 16 ; i + + , j + = 4 ) m [ i ] = ( ctx - > d [ j ] < < 24 ) | ( ctx - > d [ j + 1 ] < < 16 ) | ( ctx - > d [ j + 2 ] < < 8 ) | ( ctx - > d [ j + 3 ] ) ;
for ( ; i < 64 ; i + + ) m [ i ] = SHA_SIG1 ( m [ i - 2 ] ) + m [ i - 7 ] + SHA_SIG0 ( m [ i - 15 ] ) + m [ i - 16 ] ;
a = ctx - > s [ 0 ] ; b = ctx - > s [ 1 ] ; c = ctx - > s [ 2 ] ; d = ctx - > s [ 3 ] ;
e = ctx - > s [ 4 ] ; f = ctx - > s [ 5 ] ; g = ctx - > s [ 6 ] ; h = ctx - > s [ 7 ] ;
for ( i = 0 ; i < 64 ; i + + ) {
t1 = h + SHA_EP1 ( e ) + SHA_CH ( e , f , g ) + sha256_k [ i ] + m [ i ] ;
t2 = SHA_EP0 ( a ) + SHA_MAJ ( a , b , c ) ; h = g ; g = f ; f = e ; e = d + t1 ; d = c ; c = b ; b = a ; a = t1 + t2 ;
}
ctx - > s [ 0 ] + = a ; ctx - > s [ 1 ] + = b ; ctx - > s [ 2 ] + = c ; ctx - > s [ 3 ] + = d ;
ctx - > s [ 4 ] + = e ; ctx - > s [ 5 ] + = f ; ctx - > s [ 6 ] + = g ; ctx - > s [ 7 ] + = h ;
}
void SHA256_Init ( SHA256_CTX * ctx )
{
ctx - > l = 0 ; ctx - > b [ 0 ] = ctx - > b [ 1 ] = 0 ;
ctx - > s [ 0 ] = 0x6a09e667 ; ctx - > s [ 1 ] = 0xbb67ae85 ; ctx - > s [ 2 ] = 0x3c6ef372 ; ctx - > s [ 3 ] = 0xa54ff53a ;
ctx - > s [ 4 ] = 0x510e527f ; ctx - > s [ 5 ] = 0x9b05688c ; ctx - > s [ 6 ] = 0x1f83d9ab ; ctx - > s [ 7 ] = 0x5be0cd19 ;
}
void SHA256_Update ( SHA256_CTX * ctx , const void * data , int len )
{
UINT8 * d = ( UINT8 * ) data ;
for ( ; len - - ; d + + ) {
ctx - > d [ ctx - > l + + ] = * d ;
if ( ctx - > l = = 64 ) { sha256_t ( ctx ) ; SHA_ADD ( ctx - > b [ 0 ] , ctx - > b [ 1 ] , 512 ) ; ctx - > l = 0 ; }
}
}
void SHA256_Final ( unsigned char * h , SHA256_CTX * ctx )
{
UINT32 i = ctx - > l ;
ctx - > d [ i + + ] = 0x80 ;
if ( ctx - > l < 56 ) { while ( i < 56 ) ctx - > d [ i + + ] = 0x00 ; }
else { while ( i < 64 ) ctx - > d [ i + + ] = 0x00 ; sha256_t ( ctx ) ; ZeroMem ( ctx - > d , 56 ) ; }
SHA_ADD ( ctx - > b [ 0 ] , ctx - > b [ 1 ] , ctx - > l * 8 ) ;
ctx - > d [ 63 ] = ctx - > b [ 0 ] ; ctx - > d [ 62 ] = ctx - > b [ 0 ] > > 8 ; ctx - > d [ 61 ] = ctx - > b [ 0 ] > > 16 ; ctx - > d [ 60 ] = ctx - > b [ 0 ] > > 24 ;
ctx - > d [ 59 ] = ctx - > b [ 1 ] ; ctx - > d [ 58 ] = ctx - > b [ 1 ] > > 8 ; ctx - > d [ 57 ] = ctx - > b [ 1 ] > > 16 ; ctx - > d [ 56 ] = ctx - > b [ 1 ] > > 24 ;
sha256_t ( ctx ) ;
for ( i = 0 ; i < 4 ; i + + ) {
h [ i ] = ( ctx - > s [ 0 ] > > ( 24 - i * 8 ) ) ; h [ i + 4 ] = ( ctx - > s [ 1 ] > > ( 24 - i * 8 ) ) ;
h [ i + 8 ] = ( ctx - > s [ 2 ] > > ( 24 - i * 8 ) ) ; h [ i + 12 ] = ( ctx - > s [ 3 ] > > ( 24 - i * 8 ) ) ;
h [ i + 16 ] = ( ctx - > s [ 4 ] > > ( 24 - i * 8 ) ) ; h [ i + 20 ] = ( ctx - > s [ 5 ] > > ( 24 - i * 8 ) ) ;
h [ i + 24 ] = ( ctx - > s [ 6 ] > > ( 24 - i * 8 ) ) ; h [ i + 28 ] = ( ctx - > s [ 7 ] > > ( 24 - i * 8 ) ) ;
}
}
/**
* precalculated CRC32c lookup table for polynomial 0x1EDC6F41 ( castagnoli - crc )
*/
UINT32 crc32c_lookup [ 256 ] = {
0x00000000L , 0xF26B8303L , 0xE13B70F7L , 0x1350F3F4L , 0xC79A971FL , 0x35F1141CL , 0x26A1E7E8L , 0xD4CA64EBL ,
0x8AD958CFL , 0x78B2DBCCL , 0x6BE22838L , 0x9989AB3BL , 0x4D43CFD0L , 0xBF284CD3L , 0xAC78BF27L , 0x5E133C24L ,
0x105EC76FL , 0xE235446CL , 0xF165B798L , 0x030E349BL , 0xD7C45070L , 0x25AFD373L , 0x36FF2087L , 0xC494A384L ,
0x9A879FA0L , 0x68EC1CA3L , 0x7BBCEF57L , 0x89D76C54L , 0x5D1D08BFL , 0xAF768BBCL , 0xBC267848L , 0x4E4DFB4BL ,
0x20BD8EDEL , 0xD2D60DDDL , 0xC186FE29L , 0x33ED7D2AL , 0xE72719C1L , 0x154C9AC2L , 0x061C6936L , 0xF477EA35L ,
0xAA64D611L , 0x580F5512L , 0x4B5FA6E6L , 0xB93425E5L , 0x6DFE410EL , 0x9F95C20DL , 0x8CC531F9L , 0x7EAEB2FAL ,
0x30E349B1L , 0xC288CAB2L , 0xD1D83946L , 0x23B3BA45L , 0xF779DEAEL , 0x05125DADL , 0x1642AE59L , 0xE4292D5AL ,
0xBA3A117EL , 0x4851927DL , 0x5B016189L , 0xA96AE28AL , 0x7DA08661L , 0x8FCB0562L , 0x9C9BF696L , 0x6EF07595L ,
0x417B1DBCL , 0xB3109EBFL , 0xA0406D4BL , 0x522BEE48L , 0x86E18AA3L , 0x748A09A0L , 0x67DAFA54L , 0x95B17957L ,
0xCBA24573L , 0x39C9C670L , 0x2A993584L , 0xD8F2B687L , 0x0C38D26CL , 0xFE53516FL , 0xED03A29BL , 0x1F682198L ,
0x5125DAD3L , 0xA34E59D0L , 0xB01EAA24L , 0x42752927L , 0x96BF4DCCL , 0x64D4CECFL , 0x77843D3BL , 0x85EFBE38L ,
0xDBFC821CL , 0x2997011FL , 0x3AC7F2EBL , 0xC8AC71E8L , 0x1C661503L , 0xEE0D9600L , 0xFD5D65F4L , 0x0F36E6F7L ,
0x61C69362L , 0x93AD1061L , 0x80FDE395L , 0x72966096L , 0xA65C047DL , 0x5437877EL , 0x4767748AL , 0xB50CF789L ,
0xEB1FCBADL , 0x197448AEL , 0x0A24BB5AL , 0xF84F3859L , 0x2C855CB2L , 0xDEEEDFB1L , 0xCDBE2C45L , 0x3FD5AF46L ,
0x7198540DL , 0x83F3D70EL , 0x90A324FAL , 0x62C8A7F9L , 0xB602C312L , 0x44694011L , 0x5739B3E5L , 0xA55230E6L ,
0xFB410CC2L , 0x092A8FC1L , 0x1A7A7C35L , 0xE811FF36L , 0x3CDB9BDDL , 0xCEB018DEL , 0xDDE0EB2AL , 0x2F8B6829L ,
0x82F63B78L , 0x709DB87BL , 0x63CD4B8FL , 0x91A6C88CL , 0x456CAC67L , 0xB7072F64L , 0xA457DC90L , 0x563C5F93L ,
0x082F63B7L , 0xFA44E0B4L , 0xE9141340L , 0x1B7F9043L , 0xCFB5F4A8L , 0x3DDE77ABL , 0x2E8E845FL , 0xDCE5075CL ,
0x92A8FC17L , 0x60C37F14L , 0x73938CE0L , 0x81F80FE3L , 0x55326B08L , 0xA759E80BL , 0xB4091BFFL , 0x466298FCL ,
0x1871A4D8L , 0xEA1A27DBL , 0xF94AD42FL , 0x0B21572CL , 0xDFEB33C7L , 0x2D80B0C4L , 0x3ED04330L , 0xCCBBC033L ,
0xA24BB5A6L , 0x502036A5L , 0x4370C551L , 0xB11B4652L , 0x65D122B9L , 0x97BAA1BAL , 0x84EA524EL , 0x7681D14DL ,
0x2892ED69L , 0xDAF96E6AL , 0xC9A99D9EL , 0x3BC21E9DL , 0xEF087A76L , 0x1D63F975L , 0x0E330A81L , 0xFC588982L ,
0xB21572C9L , 0x407EF1CAL , 0x532E023EL , 0xA145813DL , 0x758FE5D6L , 0x87E466D5L , 0x94B49521L , 0x66DF1622L ,
0x38CC2A06L , 0xCAA7A905L , 0xD9F75AF1L , 0x2B9CD9F2L , 0xFF56BD19L , 0x0D3D3E1AL , 0x1E6DCDEEL , 0xEC064EEDL ,
0xC38D26C4L , 0x31E6A5C7L , 0x22B65633L , 0xD0DDD530L , 0x0417B1DBL , 0xF67C32D8L , 0xE52CC12CL , 0x1747422FL ,
0x49547E0BL , 0xBB3FFD08L , 0xA86F0EFCL , 0x5A048DFFL , 0x8ECEE914L , 0x7CA56A17L , 0x6FF599E3L , 0x9D9E1AE0L ,
0xD3D3E1ABL , 0x21B862A8L , 0x32E8915CL , 0xC083125FL , 0x144976B4L , 0xE622F5B7L , 0xF5720643L , 0x07198540L ,
0x590AB964L , 0xAB613A67L , 0xB831C993L , 0x4A5A4A90L , 0x9E902E7BL , 0x6CFBAD78L , 0x7FAB5E8CL , 0x8DC0DD8FL ,
0xE330A81AL , 0x115B2B19L , 0x020BD8EDL , 0xF0605BEEL , 0x24AA3F05L , 0xD6C1BC06L , 0xC5914FF2L , 0x37FACCF1L ,
0x69E9F0D5L , 0x9B8273D6L , 0x88D28022L , 0x7AB90321L , 0xAE7367CAL , 0x5C18E4C9L , 0x4F48173DL , 0xBD23943EL ,
0xF36E6F75L , 0x0105EC76L , 0x12551F82L , 0xE03E9C81L , 0x34F4F86AL , 0xC69F7B69L , 0xD5CF889DL , 0x27A40B9EL ,
0x79B737BAL , 0x8BDCB4B9L , 0x988C474DL , 0x6AE7C44EL , 0xBE2DA0A5L , 0x4C4623A6L , 0x5F16D052L , 0xAD7D5351L
} ;
UINT32 crc32_calc ( char * start , int length )
{
UINT32 crc32_val = 0 ;
while ( length - - ) crc32_val = ( crc32_val > > 8 ) ^ crc32c_lookup [ ( crc32_val & 0xff ) ^ ( unsigned char ) * start + + ] ;
return crc32_val ;
}
2018-11-09 06:43:03 -05:00
/**
* AES - 256 - CBC
*/
# define GETU32(pt) (((UINT32)(pt)[0]<<24)^((UINT32)(pt)[1]<<16)^((UINT32)(pt)[2]<<8)^((UINT32)(pt)[3]))
# define PUTU32(ct,st) {(ct)[0]=(UINT8)((st)>>24);(ct)[1]=(UINT8)((st)>>16);(ct)[2]=(UINT8)((st)>>8);(ct)[3]=(UINT8)(st);}
static const UINT32 Te0 [ 256 ] = {
0xc66363a5U , 0xf87c7c84U , 0xee777799U , 0xf67b7b8dU , 0xfff2f20dU , 0xd66b6bbdU , 0xde6f6fb1U , 0x91c5c554U ,
0x60303050U , 0x02010103U , 0xce6767a9U , 0x562b2b7dU , 0xe7fefe19U , 0xb5d7d762U , 0x4dababe6U , 0xec76769aU ,
0x8fcaca45U , 0x1f82829dU , 0x89c9c940U , 0xfa7d7d87U , 0xeffafa15U , 0xb25959ebU , 0x8e4747c9U , 0xfbf0f00bU ,
0x41adadecU , 0xb3d4d467U , 0x5fa2a2fdU , 0x45afafeaU , 0x239c9cbfU , 0x53a4a4f7U , 0xe4727296U , 0x9bc0c05bU ,
0x75b7b7c2U , 0xe1fdfd1cU , 0x3d9393aeU , 0x4c26266aU , 0x6c36365aU , 0x7e3f3f41U , 0xf5f7f702U , 0x83cccc4fU ,
0x6834345cU , 0x51a5a5f4U , 0xd1e5e534U , 0xf9f1f108U , 0xe2717193U , 0xabd8d873U , 0x62313153U , 0x2a15153fU ,
0x0804040cU , 0x95c7c752U , 0x46232365U , 0x9dc3c35eU , 0x30181828U , 0x379696a1U , 0x0a05050fU , 0x2f9a9ab5U ,
0x0e070709U , 0x24121236U , 0x1b80809bU , 0xdfe2e23dU , 0xcdebeb26U , 0x4e272769U , 0x7fb2b2cdU , 0xea75759fU ,
0x1209091bU , 0x1d83839eU , 0x582c2c74U , 0x341a1a2eU , 0x361b1b2dU , 0xdc6e6eb2U , 0xb45a5aeeU , 0x5ba0a0fbU ,
0xa45252f6U , 0x763b3b4dU , 0xb7d6d661U , 0x7db3b3ceU , 0x5229297bU , 0xdde3e33eU , 0x5e2f2f71U , 0x13848497U ,
0xa65353f5U , 0xb9d1d168U , 0x00000000U , 0xc1eded2cU , 0x40202060U , 0xe3fcfc1fU , 0x79b1b1c8U , 0xb65b5bedU ,
0xd46a6abeU , 0x8dcbcb46U , 0x67bebed9U , 0x7239394bU , 0x944a4adeU , 0x984c4cd4U , 0xb05858e8U , 0x85cfcf4aU ,
0xbbd0d06bU , 0xc5efef2aU , 0x4faaaae5U , 0xedfbfb16U , 0x864343c5U , 0x9a4d4dd7U , 0x66333355U , 0x11858594U ,
0x8a4545cfU , 0xe9f9f910U , 0x04020206U , 0xfe7f7f81U , 0xa05050f0U , 0x783c3c44U , 0x259f9fbaU , 0x4ba8a8e3U ,
0xa25151f3U , 0x5da3a3feU , 0x804040c0U , 0x058f8f8aU , 0x3f9292adU , 0x219d9dbcU , 0x70383848U , 0xf1f5f504U ,
0x63bcbcdfU , 0x77b6b6c1U , 0xafdada75U , 0x42212163U , 0x20101030U , 0xe5ffff1aU , 0xfdf3f30eU , 0xbfd2d26dU ,
0x81cdcd4cU , 0x180c0c14U , 0x26131335U , 0xc3ecec2fU , 0xbe5f5fe1U , 0x359797a2U , 0x884444ccU , 0x2e171739U ,
0x93c4c457U , 0x55a7a7f2U , 0xfc7e7e82U , 0x7a3d3d47U , 0xc86464acU , 0xba5d5de7U , 0x3219192bU , 0xe6737395U ,
0xc06060a0U , 0x19818198U , 0x9e4f4fd1U , 0xa3dcdc7fU , 0x44222266U , 0x542a2a7eU , 0x3b9090abU , 0x0b888883U ,
0x8c4646caU , 0xc7eeee29U , 0x6bb8b8d3U , 0x2814143cU , 0xa7dede79U , 0xbc5e5ee2U , 0x160b0b1dU , 0xaddbdb76U ,
0xdbe0e03bU , 0x64323256U , 0x743a3a4eU , 0x140a0a1eU , 0x924949dbU , 0x0c06060aU , 0x4824246cU , 0xb85c5ce4U ,
0x9fc2c25dU , 0xbdd3d36eU , 0x43acacefU , 0xc46262a6U , 0x399191a8U , 0x319595a4U , 0xd3e4e437U , 0xf279798bU ,
0xd5e7e732U , 0x8bc8c843U , 0x6e373759U , 0xda6d6db7U , 0x018d8d8cU , 0xb1d5d564U , 0x9c4e4ed2U , 0x49a9a9e0U ,
0xd86c6cb4U , 0xac5656faU , 0xf3f4f407U , 0xcfeaea25U , 0xca6565afU , 0xf47a7a8eU , 0x47aeaee9U , 0x10080818U ,
0x6fbabad5U , 0xf0787888U , 0x4a25256fU , 0x5c2e2e72U , 0x381c1c24U , 0x57a6a6f1U , 0x73b4b4c7U , 0x97c6c651U ,
0xcbe8e823U , 0xa1dddd7cU , 0xe874749cU , 0x3e1f1f21U , 0x964b4bddU , 0x61bdbddcU , 0x0d8b8b86U , 0x0f8a8a85U ,
0xe0707090U , 0x7c3e3e42U , 0x71b5b5c4U , 0xcc6666aaU , 0x904848d8U , 0x06030305U , 0xf7f6f601U , 0x1c0e0e12U ,
0xc26161a3U , 0x6a35355fU , 0xae5757f9U , 0x69b9b9d0U , 0x17868691U , 0x99c1c158U , 0x3a1d1d27U , 0x279e9eb9U ,
0xd9e1e138U , 0xebf8f813U , 0x2b9898b3U , 0x22111133U , 0xd26969bbU , 0xa9d9d970U , 0x078e8e89U , 0x339494a7U ,
0x2d9b9bb6U , 0x3c1e1e22U , 0x15878792U , 0xc9e9e920U , 0x87cece49U , 0xaa5555ffU , 0x50282878U , 0xa5dfdf7aU ,
0x038c8c8fU , 0x59a1a1f8U , 0x09898980U , 0x1a0d0d17U , 0x65bfbfdaU , 0xd7e6e631U , 0x844242c6U , 0xd06868b8U ,
0x824141c3U , 0x299999b0U , 0x5a2d2d77U , 0x1e0f0f11U , 0x7bb0b0cbU , 0xa85454fcU , 0x6dbbbbd6U , 0x2c16163aU ,
} ;
static const UINT32 Te1 [ 256 ] = {
0xa5c66363U , 0x84f87c7cU , 0x99ee7777U , 0x8df67b7bU , 0x0dfff2f2U , 0xbdd66b6bU , 0xb1de6f6fU , 0x5491c5c5U ,
0x50603030U , 0x03020101U , 0xa9ce6767U , 0x7d562b2bU , 0x19e7fefeU , 0x62b5d7d7U , 0xe64dababU , 0x9aec7676U ,
0x458fcacaU , 0x9d1f8282U , 0x4089c9c9U , 0x87fa7d7dU , 0x15effafaU , 0xebb25959U , 0xc98e4747U , 0x0bfbf0f0U ,
0xec41adadU , 0x67b3d4d4U , 0xfd5fa2a2U , 0xea45afafU , 0xbf239c9cU , 0xf753a4a4U , 0x96e47272U , 0x5b9bc0c0U ,
0xc275b7b7U , 0x1ce1fdfdU , 0xae3d9393U , 0x6a4c2626U , 0x5a6c3636U , 0x417e3f3fU , 0x02f5f7f7U , 0x4f83ccccU ,
0x5c683434U , 0xf451a5a5U , 0x34d1e5e5U , 0x08f9f1f1U , 0x93e27171U , 0x73abd8d8U , 0x53623131U , 0x3f2a1515U ,
0x0c080404U , 0x5295c7c7U , 0x65462323U , 0x5e9dc3c3U , 0x28301818U , 0xa1379696U , 0x0f0a0505U , 0xb52f9a9aU ,
0x090e0707U , 0x36241212U , 0x9b1b8080U , 0x3ddfe2e2U , 0x26cdebebU , 0x694e2727U , 0xcd7fb2b2U , 0x9fea7575U ,
0x1b120909U , 0x9e1d8383U , 0x74582c2cU , 0x2e341a1aU , 0x2d361b1bU , 0xb2dc6e6eU , 0xeeb45a5aU , 0xfb5ba0a0U ,
0xf6a45252U , 0x4d763b3bU , 0x61b7d6d6U , 0xce7db3b3U , 0x7b522929U , 0x3edde3e3U , 0x715e2f2fU , 0x97138484U ,
0xf5a65353U , 0x68b9d1d1U , 0x00000000U , 0x2cc1ededU , 0x60402020U , 0x1fe3fcfcU , 0xc879b1b1U , 0xedb65b5bU ,
0xbed46a6aU , 0x468dcbcbU , 0xd967bebeU , 0x4b723939U , 0xde944a4aU , 0xd4984c4cU , 0xe8b05858U , 0x4a85cfcfU ,
0x6bbbd0d0U , 0x2ac5efefU , 0xe54faaaaU , 0x16edfbfbU , 0xc5864343U , 0xd79a4d4dU , 0x55663333U , 0x94118585U ,
0xcf8a4545U , 0x10e9f9f9U , 0x06040202U , 0x81fe7f7fU , 0xf0a05050U , 0x44783c3cU , 0xba259f9fU , 0xe34ba8a8U ,
0xf3a25151U , 0xfe5da3a3U , 0xc0804040U , 0x8a058f8fU , 0xad3f9292U , 0xbc219d9dU , 0x48703838U , 0x04f1f5f5U ,
0xdf63bcbcU , 0xc177b6b6U , 0x75afdadaU , 0x63422121U , 0x30201010U , 0x1ae5ffffU , 0x0efdf3f3U , 0x6dbfd2d2U ,
0x4c81cdcdU , 0x14180c0cU , 0x35261313U , 0x2fc3ececU , 0xe1be5f5fU , 0xa2359797U , 0xcc884444U , 0x392e1717U ,
0x5793c4c4U , 0xf255a7a7U , 0x82fc7e7eU , 0x477a3d3dU , 0xacc86464U , 0xe7ba5d5dU , 0x2b321919U , 0x95e67373U ,
0xa0c06060U , 0x98198181U , 0xd19e4f4fU , 0x7fa3dcdcU , 0x66442222U , 0x7e542a2aU , 0xab3b9090U , 0x830b8888U ,
0xca8c4646U , 0x29c7eeeeU , 0xd36bb8b8U , 0x3c281414U , 0x79a7dedeU , 0xe2bc5e5eU , 0x1d160b0bU , 0x76addbdbU ,
0x3bdbe0e0U , 0x56643232U , 0x4e743a3aU , 0x1e140a0aU , 0xdb924949U , 0x0a0c0606U , 0x6c482424U , 0xe4b85c5cU ,
0x5d9fc2c2U , 0x6ebdd3d3U , 0xef43acacU , 0xa6c46262U , 0xa8399191U , 0xa4319595U , 0x37d3e4e4U , 0x8bf27979U ,
0x32d5e7e7U , 0x438bc8c8U , 0x596e3737U , 0xb7da6d6dU , 0x8c018d8dU , 0x64b1d5d5U , 0xd29c4e4eU , 0xe049a9a9U ,
0xb4d86c6cU , 0xfaac5656U , 0x07f3f4f4U , 0x25cfeaeaU , 0xafca6565U , 0x8ef47a7aU , 0xe947aeaeU , 0x18100808U ,
0xd56fbabaU , 0x88f07878U , 0x6f4a2525U , 0x725c2e2eU , 0x24381c1cU , 0xf157a6a6U , 0xc773b4b4U , 0x5197c6c6U ,
0x23cbe8e8U , 0x7ca1ddddU , 0x9ce87474U , 0x213e1f1fU , 0xdd964b4bU , 0xdc61bdbdU , 0x860d8b8bU , 0x850f8a8aU ,
0x90e07070U , 0x427c3e3eU , 0xc471b5b5U , 0xaacc6666U , 0xd8904848U , 0x05060303U , 0x01f7f6f6U , 0x121c0e0eU ,
0xa3c26161U , 0x5f6a3535U , 0xf9ae5757U , 0xd069b9b9U , 0x91178686U , 0x5899c1c1U , 0x273a1d1dU , 0xb9279e9eU ,
0x38d9e1e1U , 0x13ebf8f8U , 0xb32b9898U , 0x33221111U , 0xbbd26969U , 0x70a9d9d9U , 0x89078e8eU , 0xa7339494U ,
0xb62d9b9bU , 0x223c1e1eU , 0x92158787U , 0x20c9e9e9U , 0x4987ceceU , 0xffaa5555U , 0x78502828U , 0x7aa5dfdfU ,
0x8f038c8cU , 0xf859a1a1U , 0x80098989U , 0x171a0d0dU , 0xda65bfbfU , 0x31d7e6e6U , 0xc6844242U , 0xb8d06868U ,
0xc3824141U , 0xb0299999U , 0x775a2d2dU , 0x111e0f0fU , 0xcb7bb0b0U , 0xfca85454U , 0xd66dbbbbU , 0x3a2c1616U ,
} ;
static const UINT32 Te2 [ 256 ] = {
0x63a5c663U , 0x7c84f87cU , 0x7799ee77U , 0x7b8df67bU , 0xf20dfff2U , 0x6bbdd66bU , 0x6fb1de6fU , 0xc55491c5U ,
0x30506030U , 0x01030201U , 0x67a9ce67U , 0x2b7d562bU , 0xfe19e7feU , 0xd762b5d7U , 0xabe64dabU , 0x769aec76U ,
0xca458fcaU , 0x829d1f82U , 0xc94089c9U , 0x7d87fa7dU , 0xfa15effaU , 0x59ebb259U , 0x47c98e47U , 0xf00bfbf0U ,
0xadec41adU , 0xd467b3d4U , 0xa2fd5fa2U , 0xafea45afU , 0x9cbf239cU , 0xa4f753a4U , 0x7296e472U , 0xc05b9bc0U ,
0xb7c275b7U , 0xfd1ce1fdU , 0x93ae3d93U , 0x266a4c26U , 0x365a6c36U , 0x3f417e3fU , 0xf702f5f7U , 0xcc4f83ccU ,
0x345c6834U , 0xa5f451a5U , 0xe534d1e5U , 0xf108f9f1U , 0x7193e271U , 0xd873abd8U , 0x31536231U , 0x153f2a15U ,
0x040c0804U , 0xc75295c7U , 0x23654623U , 0xc35e9dc3U , 0x18283018U , 0x96a13796U , 0x050f0a05U , 0x9ab52f9aU ,
0x07090e07U , 0x12362412U , 0x809b1b80U , 0xe23ddfe2U , 0xeb26cdebU , 0x27694e27U , 0xb2cd7fb2U , 0x759fea75U ,
0x091b1209U , 0x839e1d83U , 0x2c74582cU , 0x1a2e341aU , 0x1b2d361bU , 0x6eb2dc6eU , 0x5aeeb45aU , 0xa0fb5ba0U ,
0x52f6a452U , 0x3b4d763bU , 0xd661b7d6U , 0xb3ce7db3U , 0x297b5229U , 0xe33edde3U , 0x2f715e2fU , 0x84971384U ,
0x53f5a653U , 0xd168b9d1U , 0x00000000U , 0xed2cc1edU , 0x20604020U , 0xfc1fe3fcU , 0xb1c879b1U , 0x5bedb65bU ,
0x6abed46aU , 0xcb468dcbU , 0xbed967beU , 0x394b7239U , 0x4ade944aU , 0x4cd4984cU , 0x58e8b058U , 0xcf4a85cfU ,
0xd06bbbd0U , 0xef2ac5efU , 0xaae54faaU , 0xfb16edfbU , 0x43c58643U , 0x4dd79a4dU , 0x33556633U , 0x85941185U ,
0x45cf8a45U , 0xf910e9f9U , 0x02060402U , 0x7f81fe7fU , 0x50f0a050U , 0x3c44783cU , 0x9fba259fU , 0xa8e34ba8U ,
0x51f3a251U , 0xa3fe5da3U , 0x40c08040U , 0x8f8a058fU , 0x92ad3f92U , 0x9dbc219dU , 0x38487038U , 0xf504f1f5U ,
0xbcdf63bcU , 0xb6c177b6U , 0xda75afdaU , 0x21634221U , 0x10302010U , 0xff1ae5ffU , 0xf30efdf3U , 0xd26dbfd2U ,
0xcd4c81cdU , 0x0c14180cU , 0x13352613U , 0xec2fc3ecU , 0x5fe1be5fU , 0x97a23597U , 0x44cc8844U , 0x17392e17U ,
0xc45793c4U , 0xa7f255a7U , 0x7e82fc7eU , 0x3d477a3dU , 0x64acc864U , 0x5de7ba5dU , 0x192b3219U , 0x7395e673U ,
0x60a0c060U , 0x81981981U , 0x4fd19e4fU , 0xdc7fa3dcU , 0x22664422U , 0x2a7e542aU , 0x90ab3b90U , 0x88830b88U ,
0x46ca8c46U , 0xee29c7eeU , 0xb8d36bb8U , 0x143c2814U , 0xde79a7deU , 0x5ee2bc5eU , 0x0b1d160bU , 0xdb76addbU ,
0xe03bdbe0U , 0x32566432U , 0x3a4e743aU , 0x0a1e140aU , 0x49db9249U , 0x060a0c06U , 0x246c4824U , 0x5ce4b85cU ,
0xc25d9fc2U , 0xd36ebdd3U , 0xacef43acU , 0x62a6c462U , 0x91a83991U , 0x95a43195U , 0xe437d3e4U , 0x798bf279U ,
0xe732d5e7U , 0xc8438bc8U , 0x37596e37U , 0x6db7da6dU , 0x8d8c018dU , 0xd564b1d5U , 0x4ed29c4eU , 0xa9e049a9U ,
0x6cb4d86cU , 0x56faac56U , 0xf407f3f4U , 0xea25cfeaU , 0x65afca65U , 0x7a8ef47aU , 0xaee947aeU , 0x08181008U ,
0xbad56fbaU , 0x7888f078U , 0x256f4a25U , 0x2e725c2eU , 0x1c24381cU , 0xa6f157a6U , 0xb4c773b4U , 0xc65197c6U ,
0xe823cbe8U , 0xdd7ca1ddU , 0x749ce874U , 0x1f213e1fU , 0x4bdd964bU , 0xbddc61bdU , 0x8b860d8bU , 0x8a850f8aU ,
0x7090e070U , 0x3e427c3eU , 0xb5c471b5U , 0x66aacc66U , 0x48d89048U , 0x03050603U , 0xf601f7f6U , 0x0e121c0eU ,
0x61a3c261U , 0x355f6a35U , 0x57f9ae57U , 0xb9d069b9U , 0x86911786U , 0xc15899c1U , 0x1d273a1dU , 0x9eb9279eU ,
0xe138d9e1U , 0xf813ebf8U , 0x98b32b98U , 0x11332211U , 0x69bbd269U , 0xd970a9d9U , 0x8e89078eU , 0x94a73394U ,
0x9bb62d9bU , 0x1e223c1eU , 0x87921587U , 0xe920c9e9U , 0xce4987ceU , 0x55ffaa55U , 0x28785028U , 0xdf7aa5dfU ,
0x8c8f038cU , 0xa1f859a1U , 0x89800989U , 0x0d171a0dU , 0xbfda65bfU , 0xe631d7e6U , 0x42c68442U , 0x68b8d068U ,
0x41c38241U , 0x99b02999U , 0x2d775a2dU , 0x0f111e0fU , 0xb0cb7bb0U , 0x54fca854U , 0xbbd66dbbU , 0x163a2c16U ,
} ;
static const UINT32 Te3 [ 256 ] = {
0x6363a5c6U , 0x7c7c84f8U , 0x777799eeU , 0x7b7b8df6U , 0xf2f20dffU , 0x6b6bbdd6U , 0x6f6fb1deU , 0xc5c55491U ,
0x30305060U , 0x01010302U , 0x6767a9ceU , 0x2b2b7d56U , 0xfefe19e7U , 0xd7d762b5U , 0xababe64dU , 0x76769aecU ,
0xcaca458fU , 0x82829d1fU , 0xc9c94089U , 0x7d7d87faU , 0xfafa15efU , 0x5959ebb2U , 0x4747c98eU , 0xf0f00bfbU ,
0xadadec41U , 0xd4d467b3U , 0xa2a2fd5fU , 0xafafea45U , 0x9c9cbf23U , 0xa4a4f753U , 0x727296e4U , 0xc0c05b9bU ,
0xb7b7c275U , 0xfdfd1ce1U , 0x9393ae3dU , 0x26266a4cU , 0x36365a6cU , 0x3f3f417eU , 0xf7f702f5U , 0xcccc4f83U ,
0x34345c68U , 0xa5a5f451U , 0xe5e534d1U , 0xf1f108f9U , 0x717193e2U , 0xd8d873abU , 0x31315362U , 0x15153f2aU ,
0x04040c08U , 0xc7c75295U , 0x23236546U , 0xc3c35e9dU , 0x18182830U , 0x9696a137U , 0x05050f0aU , 0x9a9ab52fU ,
0x0707090eU , 0x12123624U , 0x80809b1bU , 0xe2e23ddfU , 0xebeb26cdU , 0x2727694eU , 0xb2b2cd7fU , 0x75759feaU ,
0x09091b12U , 0x83839e1dU , 0x2c2c7458U , 0x1a1a2e34U , 0x1b1b2d36U , 0x6e6eb2dcU , 0x5a5aeeb4U , 0xa0a0fb5bU ,
0x5252f6a4U , 0x3b3b4d76U , 0xd6d661b7U , 0xb3b3ce7dU , 0x29297b52U , 0xe3e33eddU , 0x2f2f715eU , 0x84849713U ,
0x5353f5a6U , 0xd1d168b9U , 0x00000000U , 0xeded2cc1U , 0x20206040U , 0xfcfc1fe3U , 0xb1b1c879U , 0x5b5bedb6U ,
0x6a6abed4U , 0xcbcb468dU , 0xbebed967U , 0x39394b72U , 0x4a4ade94U , 0x4c4cd498U , 0x5858e8b0U , 0xcfcf4a85U ,
0xd0d06bbbU , 0xefef2ac5U , 0xaaaae54fU , 0xfbfb16edU , 0x4343c586U , 0x4d4dd79aU , 0x33335566U , 0x85859411U ,
0x4545cf8aU , 0xf9f910e9U , 0x02020604U , 0x7f7f81feU , 0x5050f0a0U , 0x3c3c4478U , 0x9f9fba25U , 0xa8a8e34bU ,
0x5151f3a2U , 0xa3a3fe5dU , 0x4040c080U , 0x8f8f8a05U , 0x9292ad3fU , 0x9d9dbc21U , 0x38384870U , 0xf5f504f1U ,
0xbcbcdf63U , 0xb6b6c177U , 0xdada75afU , 0x21216342U , 0x10103020U , 0xffff1ae5U , 0xf3f30efdU , 0xd2d26dbfU ,
0xcdcd4c81U , 0x0c0c1418U , 0x13133526U , 0xecec2fc3U , 0x5f5fe1beU , 0x9797a235U , 0x4444cc88U , 0x1717392eU ,
0xc4c45793U , 0xa7a7f255U , 0x7e7e82fcU , 0x3d3d477aU , 0x6464acc8U , 0x5d5de7baU , 0x19192b32U , 0x737395e6U ,
0x6060a0c0U , 0x81819819U , 0x4f4fd19eU , 0xdcdc7fa3U , 0x22226644U , 0x2a2a7e54U , 0x9090ab3bU , 0x8888830bU ,
0x4646ca8cU , 0xeeee29c7U , 0xb8b8d36bU , 0x14143c28U , 0xdede79a7U , 0x5e5ee2bcU , 0x0b0b1d16U , 0xdbdb76adU ,
0xe0e03bdbU , 0x32325664U , 0x3a3a4e74U , 0x0a0a1e14U , 0x4949db92U , 0x06060a0cU , 0x24246c48U , 0x5c5ce4b8U ,
0xc2c25d9fU , 0xd3d36ebdU , 0xacacef43U , 0x6262a6c4U , 0x9191a839U , 0x9595a431U , 0xe4e437d3U , 0x79798bf2U ,
0xe7e732d5U , 0xc8c8438bU , 0x3737596eU , 0x6d6db7daU , 0x8d8d8c01U , 0xd5d564b1U , 0x4e4ed29cU , 0xa9a9e049U ,
0x6c6cb4d8U , 0x5656faacU , 0xf4f407f3U , 0xeaea25cfU , 0x6565afcaU , 0x7a7a8ef4U , 0xaeaee947U , 0x08081810U ,
0xbabad56fU , 0x787888f0U , 0x25256f4aU , 0x2e2e725cU , 0x1c1c2438U , 0xa6a6f157U , 0xb4b4c773U , 0xc6c65197U ,
0xe8e823cbU , 0xdddd7ca1U , 0x74749ce8U , 0x1f1f213eU , 0x4b4bdd96U , 0xbdbddc61U , 0x8b8b860dU , 0x8a8a850fU ,
0x707090e0U , 0x3e3e427cU , 0xb5b5c471U , 0x6666aaccU , 0x4848d890U , 0x03030506U , 0xf6f601f7U , 0x0e0e121cU ,
0x6161a3c2U , 0x35355f6aU , 0x5757f9aeU , 0xb9b9d069U , 0x86869117U , 0xc1c15899U , 0x1d1d273aU , 0x9e9eb927U ,
0xe1e138d9U , 0xf8f813ebU , 0x9898b32bU , 0x11113322U , 0x6969bbd2U , 0xd9d970a9U , 0x8e8e8907U , 0x9494a733U ,
0x9b9bb62dU , 0x1e1e223cU , 0x87879215U , 0xe9e920c9U , 0xcece4987U , 0x5555ffaaU , 0x28287850U , 0xdfdf7aa5U ,
0x8c8c8f03U , 0xa1a1f859U , 0x89898009U , 0x0d0d171aU , 0xbfbfda65U , 0xe6e631d7U , 0x4242c684U , 0x6868b8d0U ,
0x4141c382U , 0x9999b029U , 0x2d2d775aU , 0x0f0f111eU , 0xb0b0cb7bU , 0x5454fca8U , 0xbbbbd66dU , 0x16163a2cU ,
} ;
static const UINT32 Td0 [ 256 ] = {
0x51f4a750U , 0x7e416553U , 0x1a17a4c3U , 0x3a275e96U , 0x3bab6bcbU , 0x1f9d45f1U , 0xacfa58abU , 0x4be30393U ,
0x2030fa55U , 0xad766df6U , 0x88cc7691U , 0xf5024c25U , 0x4fe5d7fcU , 0xc52acbd7U , 0x26354480U , 0xb562a38fU ,
0xdeb15a49U , 0x25ba1b67U , 0x45ea0e98U , 0x5dfec0e1U , 0xc32f7502U , 0x814cf012U , 0x8d4697a3U , 0x6bd3f9c6U ,
0x038f5fe7U , 0x15929c95U , 0xbf6d7aebU , 0x955259daU , 0xd4be832dU , 0x587421d3U , 0x49e06929U , 0x8ec9c844U ,
0x75c2896aU , 0xf48e7978U , 0x99583e6bU , 0x27b971ddU , 0xbee14fb6U , 0xf088ad17U , 0xc920ac66U , 0x7dce3ab4U ,
0x63df4a18U , 0xe51a3182U , 0x97513360U , 0x62537f45U , 0xb16477e0U , 0xbb6bae84U , 0xfe81a01cU , 0xf9082b94U ,
0x70486858U , 0x8f45fd19U , 0x94de6c87U , 0x527bf8b7U , 0xab73d323U , 0x724b02e2U , 0xe31f8f57U , 0x6655ab2aU ,
0xb2eb2807U , 0x2fb5c203U , 0x86c57b9aU , 0xd33708a5U , 0x302887f2U , 0x23bfa5b2U , 0x02036abaU , 0xed16825cU ,
0x8acf1c2bU , 0xa779b492U , 0xf307f2f0U , 0x4e69e2a1U , 0x65daf4cdU , 0x0605bed5U , 0xd134621fU , 0xc4a6fe8aU ,
0x342e539dU , 0xa2f355a0U , 0x058ae132U , 0xa4f6eb75U , 0x0b83ec39U , 0x4060efaaU , 0x5e719f06U , 0xbd6e1051U ,
0x3e218af9U , 0x96dd063dU , 0xdd3e05aeU , 0x4de6bd46U , 0x91548db5U , 0x71c45d05U , 0x0406d46fU , 0x605015ffU ,
0x1998fb24U , 0xd6bde997U , 0x894043ccU , 0x67d99e77U , 0xb0e842bdU , 0x07898b88U , 0xe7195b38U , 0x79c8eedbU ,
0xa17c0a47U , 0x7c420fe9U , 0xf8841ec9U , 0x00000000U , 0x09808683U , 0x322bed48U , 0x1e1170acU , 0x6c5a724eU ,
0xfd0efffbU , 0x0f853856U , 0x3daed51eU , 0x362d3927U , 0x0a0fd964U , 0x685ca621U , 0x9b5b54d1U , 0x24362e3aU ,
0x0c0a67b1U , 0x9357e70fU , 0xb4ee96d2U , 0x1b9b919eU , 0x80c0c54fU , 0x61dc20a2U , 0x5a774b69U , 0x1c121a16U ,
0xe293ba0aU , 0xc0a02ae5U , 0x3c22e043U , 0x121b171dU , 0x0e090d0bU , 0xf28bc7adU , 0x2db6a8b9U , 0x141ea9c8U ,
0x57f11985U , 0xaf75074cU , 0xee99ddbbU , 0xa37f60fdU , 0xf701269fU , 0x5c72f5bcU , 0x44663bc5U , 0x5bfb7e34U ,
0x8b432976U , 0xcb23c6dcU , 0xb6edfc68U , 0xb8e4f163U , 0xd731dccaU , 0x42638510U , 0x13972240U , 0x84c61120U ,
0x854a247dU , 0xd2bb3df8U , 0xaef93211U , 0xc729a16dU , 0x1d9e2f4bU , 0xdcb230f3U , 0x0d8652ecU , 0x77c1e3d0U ,
0x2bb3166cU , 0xa970b999U , 0x119448faU , 0x47e96422U , 0xa8fc8cc4U , 0xa0f03f1aU , 0x567d2cd8U , 0x223390efU ,
0x87494ec7U , 0xd938d1c1U , 0x8ccaa2feU , 0x98d40b36U , 0xa6f581cfU , 0xa57ade28U , 0xdab78e26U , 0x3fadbfa4U ,
0x2c3a9de4U , 0x5078920dU , 0x6a5fcc9bU , 0x547e4662U , 0xf68d13c2U , 0x90d8b8e8U , 0x2e39f75eU , 0x82c3aff5U ,
0x9f5d80beU , 0x69d0937cU , 0x6fd52da9U , 0xcf2512b3U , 0xc8ac993bU , 0x10187da7U , 0xe89c636eU , 0xdb3bbb7bU ,
0xcd267809U , 0x6e5918f4U , 0xec9ab701U , 0x834f9aa8U , 0xe6956e65U , 0xaaffe67eU , 0x21bccf08U , 0xef15e8e6U ,
0xbae79bd9U , 0x4a6f36ceU , 0xea9f09d4U , 0x29b07cd6U , 0x31a4b2afU , 0x2a3f2331U , 0xc6a59430U , 0x35a266c0U ,
0x744ebc37U , 0xfc82caa6U , 0xe090d0b0U , 0x33a7d815U , 0xf104984aU , 0x41ecdaf7U , 0x7fcd500eU , 0x1791f62fU ,
0x764dd68dU , 0x43efb04dU , 0xccaa4d54U , 0xe49604dfU , 0x9ed1b5e3U , 0x4c6a881bU , 0xc12c1fb8U , 0x4665517fU ,
0x9d5eea04U , 0x018c355dU , 0xfa877473U , 0xfb0b412eU , 0xb3671d5aU , 0x92dbd252U , 0xe9105633U , 0x6dd64713U ,
0x9ad7618cU , 0x37a10c7aU , 0x59f8148eU , 0xeb133c89U , 0xcea927eeU , 0xb761c935U , 0xe11ce5edU , 0x7a47b13cU ,
0x9cd2df59U , 0x55f2733fU , 0x1814ce79U , 0x73c737bfU , 0x53f7cdeaU , 0x5ffdaa5bU , 0xdf3d6f14U , 0x7844db86U ,
0xcaaff381U , 0xb968c43eU , 0x3824342cU , 0xc2a3405fU , 0x161dc372U , 0xbce2250cU , 0x283c498bU , 0xff0d9541U ,
0x39a80171U , 0x080cb3deU , 0xd8b4e49cU , 0x6456c190U , 0x7bcb8461U , 0xd532b670U , 0x486c5c74U , 0xd0b85742U ,
} ;
static const UINT32 Td1 [ 256 ] = {
0x5051f4a7U , 0x537e4165U , 0xc31a17a4U , 0x963a275eU , 0xcb3bab6bU , 0xf11f9d45U , 0xabacfa58U , 0x934be303U ,
0x552030faU , 0xf6ad766dU , 0x9188cc76U , 0x25f5024cU , 0xfc4fe5d7U , 0xd7c52acbU , 0x80263544U , 0x8fb562a3U ,
0x49deb15aU , 0x6725ba1bU , 0x9845ea0eU , 0xe15dfec0U , 0x02c32f75U , 0x12814cf0U , 0xa38d4697U , 0xc66bd3f9U ,
0xe7038f5fU , 0x9515929cU , 0xebbf6d7aU , 0xda955259U , 0x2dd4be83U , 0xd3587421U , 0x2949e069U , 0x448ec9c8U ,
0x6a75c289U , 0x78f48e79U , 0x6b99583eU , 0xdd27b971U , 0xb6bee14fU , 0x17f088adU , 0x66c920acU , 0xb47dce3aU ,
0x1863df4aU , 0x82e51a31U , 0x60975133U , 0x4562537fU , 0xe0b16477U , 0x84bb6baeU , 0x1cfe81a0U , 0x94f9082bU ,
0x58704868U , 0x198f45fdU , 0x8794de6cU , 0xb7527bf8U , 0x23ab73d3U , 0xe2724b02U , 0x57e31f8fU , 0x2a6655abU ,
0x07b2eb28U , 0x032fb5c2U , 0x9a86c57bU , 0xa5d33708U , 0xf2302887U , 0xb223bfa5U , 0xba02036aU , 0x5ced1682U ,
0x2b8acf1cU , 0x92a779b4U , 0xf0f307f2U , 0xa14e69e2U , 0xcd65daf4U , 0xd50605beU , 0x1fd13462U , 0x8ac4a6feU ,
0x9d342e53U , 0xa0a2f355U , 0x32058ae1U , 0x75a4f6ebU , 0x390b83ecU , 0xaa4060efU , 0x065e719fU , 0x51bd6e10U ,
0xf93e218aU , 0x3d96dd06U , 0xaedd3e05U , 0x464de6bdU , 0xb591548dU , 0x0571c45dU , 0x6f0406d4U , 0xff605015U ,
0x241998fbU , 0x97d6bde9U , 0xcc894043U , 0x7767d99eU , 0xbdb0e842U , 0x8807898bU , 0x38e7195bU , 0xdb79c8eeU ,
0x47a17c0aU , 0xe97c420fU , 0xc9f8841eU , 0x00000000U , 0x83098086U , 0x48322bedU , 0xac1e1170U , 0x4e6c5a72U ,
0xfbfd0effU , 0x560f8538U , 0x1e3daed5U , 0x27362d39U , 0x640a0fd9U , 0x21685ca6U , 0xd19b5b54U , 0x3a24362eU ,
0xb10c0a67U , 0x0f9357e7U , 0xd2b4ee96U , 0x9e1b9b91U , 0x4f80c0c5U , 0xa261dc20U , 0x695a774bU , 0x161c121aU ,
0x0ae293baU , 0xe5c0a02aU , 0x433c22e0U , 0x1d121b17U , 0x0b0e090dU , 0xadf28bc7U , 0xb92db6a8U , 0xc8141ea9U ,
0x8557f119U , 0x4caf7507U , 0xbbee99ddU , 0xfda37f60U , 0x9ff70126U , 0xbc5c72f5U , 0xc544663bU , 0x345bfb7eU ,
0x768b4329U , 0xdccb23c6U , 0x68b6edfcU , 0x63b8e4f1U , 0xcad731dcU , 0x10426385U , 0x40139722U , 0x2084c611U ,
0x7d854a24U , 0xf8d2bb3dU , 0x11aef932U , 0x6dc729a1U , 0x4b1d9e2fU , 0xf3dcb230U , 0xec0d8652U , 0xd077c1e3U ,
0x6c2bb316U , 0x99a970b9U , 0xfa119448U , 0x2247e964U , 0xc4a8fc8cU , 0x1aa0f03fU , 0xd8567d2cU , 0xef223390U ,
0xc787494eU , 0xc1d938d1U , 0xfe8ccaa2U , 0x3698d40bU , 0xcfa6f581U , 0x28a57adeU , 0x26dab78eU , 0xa43fadbfU ,
0xe42c3a9dU , 0x0d507892U , 0x9b6a5fccU , 0x62547e46U , 0xc2f68d13U , 0xe890d8b8U , 0x5e2e39f7U , 0xf582c3afU ,
0xbe9f5d80U , 0x7c69d093U , 0xa96fd52dU , 0xb3cf2512U , 0x3bc8ac99U , 0xa710187dU , 0x6ee89c63U , 0x7bdb3bbbU ,
0x09cd2678U , 0xf46e5918U , 0x01ec9ab7U , 0xa8834f9aU , 0x65e6956eU , 0x7eaaffe6U , 0x0821bccfU , 0xe6ef15e8U ,
0xd9bae79bU , 0xce4a6f36U , 0xd4ea9f09U , 0xd629b07cU , 0xaf31a4b2U , 0x312a3f23U , 0x30c6a594U , 0xc035a266U ,
0x37744ebcU , 0xa6fc82caU , 0xb0e090d0U , 0x1533a7d8U , 0x4af10498U , 0xf741ecdaU , 0x0e7fcd50U , 0x2f1791f6U ,
0x8d764dd6U , 0x4d43efb0U , 0x54ccaa4dU , 0xdfe49604U , 0xe39ed1b5U , 0x1b4c6a88U , 0xb8c12c1fU , 0x7f466551U ,
0x049d5eeaU , 0x5d018c35U , 0x73fa8774U , 0x2efb0b41U , 0x5ab3671dU , 0x5292dbd2U , 0x33e91056U , 0x136dd647U ,
0x8c9ad761U , 0x7a37a10cU , 0x8e59f814U , 0x89eb133cU , 0xeecea927U , 0x35b761c9U , 0xede11ce5U , 0x3c7a47b1U ,
0x599cd2dfU , 0x3f55f273U , 0x791814ceU , 0xbf73c737U , 0xea53f7cdU , 0x5b5ffdaaU , 0x14df3d6fU , 0x867844dbU ,
0x81caaff3U , 0x3eb968c4U , 0x2c382434U , 0x5fc2a340U , 0x72161dc3U , 0x0cbce225U , 0x8b283c49U , 0x41ff0d95U ,
0x7139a801U , 0xde080cb3U , 0x9cd8b4e4U , 0x906456c1U , 0x617bcb84U , 0x70d532b6U , 0x74486c5cU , 0x42d0b857U ,
} ;
static const UINT32 Td2 [ 256 ] = {
0xa75051f4U , 0x65537e41U , 0xa4c31a17U , 0x5e963a27U , 0x6bcb3babU , 0x45f11f9dU , 0x58abacfaU , 0x03934be3U ,
0xfa552030U , 0x6df6ad76U , 0x769188ccU , 0x4c25f502U , 0xd7fc4fe5U , 0xcbd7c52aU , 0x44802635U , 0xa38fb562U ,
0x5a49deb1U , 0x1b6725baU , 0x0e9845eaU , 0xc0e15dfeU , 0x7502c32fU , 0xf012814cU , 0x97a38d46U , 0xf9c66bd3U ,
0x5fe7038fU , 0x9c951592U , 0x7aebbf6dU , 0x59da9552U , 0x832dd4beU , 0x21d35874U , 0x692949e0U , 0xc8448ec9U ,
0x896a75c2U , 0x7978f48eU , 0x3e6b9958U , 0x71dd27b9U , 0x4fb6bee1U , 0xad17f088U , 0xac66c920U , 0x3ab47dceU ,
0x4a1863dfU , 0x3182e51aU , 0x33609751U , 0x7f456253U , 0x77e0b164U , 0xae84bb6bU , 0xa01cfe81U , 0x2b94f908U ,
0x68587048U , 0xfd198f45U , 0x6c8794deU , 0xf8b7527bU , 0xd323ab73U , 0x02e2724bU , 0x8f57e31fU , 0xab2a6655U ,
0x2807b2ebU , 0xc2032fb5U , 0x7b9a86c5U , 0x08a5d337U , 0x87f23028U , 0xa5b223bfU , 0x6aba0203U , 0x825ced16U ,
0x1c2b8acfU , 0xb492a779U , 0xf2f0f307U , 0xe2a14e69U , 0xf4cd65daU , 0xbed50605U , 0x621fd134U , 0xfe8ac4a6U ,
0x539d342eU , 0x55a0a2f3U , 0xe132058aU , 0xeb75a4f6U , 0xec390b83U , 0xefaa4060U , 0x9f065e71U , 0x1051bd6eU ,
0x8af93e21U , 0x063d96ddU , 0x05aedd3eU , 0xbd464de6U , 0x8db59154U , 0x5d0571c4U , 0xd46f0406U , 0x15ff6050U ,
0xfb241998U , 0xe997d6bdU , 0x43cc8940U , 0x9e7767d9U , 0x42bdb0e8U , 0x8b880789U , 0x5b38e719U , 0xeedb79c8U ,
0x0a47a17cU , 0x0fe97c42U , 0x1ec9f884U , 0x00000000U , 0x86830980U , 0xed48322bU , 0x70ac1e11U , 0x724e6c5aU ,
0xfffbfd0eU , 0x38560f85U , 0xd51e3daeU , 0x3927362dU , 0xd9640a0fU , 0xa621685cU , 0x54d19b5bU , 0x2e3a2436U ,
0x67b10c0aU , 0xe70f9357U , 0x96d2b4eeU , 0x919e1b9bU , 0xc54f80c0U , 0x20a261dcU , 0x4b695a77U , 0x1a161c12U ,
0xba0ae293U , 0x2ae5c0a0U , 0xe0433c22U , 0x171d121bU , 0x0d0b0e09U , 0xc7adf28bU , 0xa8b92db6U , 0xa9c8141eU ,
0x198557f1U , 0x074caf75U , 0xddbbee99U , 0x60fda37fU , 0x269ff701U , 0xf5bc5c72U , 0x3bc54466U , 0x7e345bfbU ,
0x29768b43U , 0xc6dccb23U , 0xfc68b6edU , 0xf163b8e4U , 0xdccad731U , 0x85104263U , 0x22401397U , 0x112084c6U ,
0x247d854aU , 0x3df8d2bbU , 0x3211aef9U , 0xa16dc729U , 0x2f4b1d9eU , 0x30f3dcb2U , 0x52ec0d86U , 0xe3d077c1U ,
0x166c2bb3U , 0xb999a970U , 0x48fa1194U , 0x642247e9U , 0x8cc4a8fcU , 0x3f1aa0f0U , 0x2cd8567dU , 0x90ef2233U ,
0x4ec78749U , 0xd1c1d938U , 0xa2fe8ccaU , 0x0b3698d4U , 0x81cfa6f5U , 0xde28a57aU , 0x8e26dab7U , 0xbfa43fadU ,
0x9de42c3aU , 0x920d5078U , 0xcc9b6a5fU , 0x4662547eU , 0x13c2f68dU , 0xb8e890d8U , 0xf75e2e39U , 0xaff582c3U ,
0x80be9f5dU , 0x937c69d0U , 0x2da96fd5U , 0x12b3cf25U , 0x993bc8acU , 0x7da71018U , 0x636ee89cU , 0xbb7bdb3bU ,
0x7809cd26U , 0x18f46e59U , 0xb701ec9aU , 0x9aa8834fU , 0x6e65e695U , 0xe67eaaffU , 0xcf0821bcU , 0xe8e6ef15U ,
0x9bd9bae7U , 0x36ce4a6fU , 0x09d4ea9fU , 0x7cd629b0U , 0xb2af31a4U , 0x23312a3fU , 0x9430c6a5U , 0x66c035a2U ,
0xbc37744eU , 0xcaa6fc82U , 0xd0b0e090U , 0xd81533a7U , 0x984af104U , 0xdaf741ecU , 0x500e7fcdU , 0xf62f1791U ,
0xd68d764dU , 0xb04d43efU , 0x4d54ccaaU , 0x04dfe496U , 0xb5e39ed1U , 0x881b4c6aU , 0x1fb8c12cU , 0x517f4665U ,
0xea049d5eU , 0x355d018cU , 0x7473fa87U , 0x412efb0bU , 0x1d5ab367U , 0xd25292dbU , 0x5633e910U , 0x47136dd6U ,
0x618c9ad7U , 0x0c7a37a1U , 0x148e59f8U , 0x3c89eb13U , 0x27eecea9U , 0xc935b761U , 0xe5ede11cU , 0xb13c7a47U ,
0xdf599cd2U , 0x733f55f2U , 0xce791814U , 0x37bf73c7U , 0xcdea53f7U , 0xaa5b5ffdU , 0x6f14df3dU , 0xdb867844U ,
0xf381caafU , 0xc43eb968U , 0x342c3824U , 0x405fc2a3U , 0xc372161dU , 0x250cbce2U , 0x498b283cU , 0x9541ff0dU ,
0x017139a8U , 0xb3de080cU , 0xe49cd8b4U , 0xc1906456U , 0x84617bcbU , 0xb670d532U , 0x5c74486cU , 0x5742d0b8U ,
} ;
static const UINT32 Td3 [ 256 ] = {
0xf4a75051U , 0x4165537eU , 0x17a4c31aU , 0x275e963aU , 0xab6bcb3bU , 0x9d45f11fU , 0xfa58abacU , 0xe303934bU ,
0x30fa5520U , 0x766df6adU , 0xcc769188U , 0x024c25f5U , 0xe5d7fc4fU , 0x2acbd7c5U , 0x35448026U , 0x62a38fb5U ,
0xb15a49deU , 0xba1b6725U , 0xea0e9845U , 0xfec0e15dU , 0x2f7502c3U , 0x4cf01281U , 0x4697a38dU , 0xd3f9c66bU ,
0x8f5fe703U , 0x929c9515U , 0x6d7aebbfU , 0x5259da95U , 0xbe832dd4U , 0x7421d358U , 0xe0692949U , 0xc9c8448eU ,
0xc2896a75U , 0x8e7978f4U , 0x583e6b99U , 0xb971dd27U , 0xe14fb6beU , 0x88ad17f0U , 0x20ac66c9U , 0xce3ab47dU ,
0xdf4a1863U , 0x1a3182e5U , 0x51336097U , 0x537f4562U , 0x6477e0b1U , 0x6bae84bbU , 0x81a01cfeU , 0x082b94f9U ,
0x48685870U , 0x45fd198fU , 0xde6c8794U , 0x7bf8b752U , 0x73d323abU , 0x4b02e272U , 0x1f8f57e3U , 0x55ab2a66U ,
0xeb2807b2U , 0xb5c2032fU , 0xc57b9a86U , 0x3708a5d3U , 0x2887f230U , 0xbfa5b223U , 0x036aba02U , 0x16825cedU ,
0xcf1c2b8aU , 0x79b492a7U , 0x07f2f0f3U , 0x69e2a14eU , 0xdaf4cd65U , 0x05bed506U , 0x34621fd1U , 0xa6fe8ac4U ,
0x2e539d34U , 0xf355a0a2U , 0x8ae13205U , 0xf6eb75a4U , 0x83ec390bU , 0x60efaa40U , 0x719f065eU , 0x6e1051bdU ,
0x218af93eU , 0xdd063d96U , 0x3e05aeddU , 0xe6bd464dU , 0x548db591U , 0xc45d0571U , 0x06d46f04U , 0x5015ff60U ,
0x98fb2419U , 0xbde997d6U , 0x4043cc89U , 0xd99e7767U , 0xe842bdb0U , 0x898b8807U , 0x195b38e7U , 0xc8eedb79U ,
0x7c0a47a1U , 0x420fe97cU , 0x841ec9f8U , 0x00000000U , 0x80868309U , 0x2bed4832U , 0x1170ac1eU , 0x5a724e6cU ,
0x0efffbfdU , 0x8538560fU , 0xaed51e3dU , 0x2d392736U , 0x0fd9640aU , 0x5ca62168U , 0x5b54d19bU , 0x362e3a24U ,
0x0a67b10cU , 0x57e70f93U , 0xee96d2b4U , 0x9b919e1bU , 0xc0c54f80U , 0xdc20a261U , 0x774b695aU , 0x121a161cU ,
0x93ba0ae2U , 0xa02ae5c0U , 0x22e0433cU , 0x1b171d12U , 0x090d0b0eU , 0x8bc7adf2U , 0xb6a8b92dU , 0x1ea9c814U ,
0xf1198557U , 0x75074cafU , 0x99ddbbeeU , 0x7f60fda3U , 0x01269ff7U , 0x72f5bc5cU , 0x663bc544U , 0xfb7e345bU ,
0x4329768bU , 0x23c6dccbU , 0xedfc68b6U , 0xe4f163b8U , 0x31dccad7U , 0x63851042U , 0x97224013U , 0xc6112084U ,
0x4a247d85U , 0xbb3df8d2U , 0xf93211aeU , 0x29a16dc7U , 0x9e2f4b1dU , 0xb230f3dcU , 0x8652ec0dU , 0xc1e3d077U ,
0xb3166c2bU , 0x70b999a9U , 0x9448fa11U , 0xe9642247U , 0xfc8cc4a8U , 0xf03f1aa0U , 0x7d2cd856U , 0x3390ef22U ,
0x494ec787U , 0x38d1c1d9U , 0xcaa2fe8cU , 0xd40b3698U , 0xf581cfa6U , 0x7ade28a5U , 0xb78e26daU , 0xadbfa43fU ,
0x3a9de42cU , 0x78920d50U , 0x5fcc9b6aU , 0x7e466254U , 0x8d13c2f6U , 0xd8b8e890U , 0x39f75e2eU , 0xc3aff582U ,
0x5d80be9fU , 0xd0937c69U , 0xd52da96fU , 0x2512b3cfU , 0xac993bc8U , 0x187da710U , 0x9c636ee8U , 0x3bbb7bdbU ,
0x267809cdU , 0x5918f46eU , 0x9ab701ecU , 0x4f9aa883U , 0x956e65e6U , 0xffe67eaaU , 0xbccf0821U , 0x15e8e6efU ,
0xe79bd9baU , 0x6f36ce4aU , 0x9f09d4eaU , 0xb07cd629U , 0xa4b2af31U , 0x3f23312aU , 0xa59430c6U , 0xa266c035U ,
0x4ebc3774U , 0x82caa6fcU , 0x90d0b0e0U , 0xa7d81533U , 0x04984af1U , 0xecdaf741U , 0xcd500e7fU , 0x91f62f17U ,
0x4dd68d76U , 0xefb04d43U , 0xaa4d54ccU , 0x9604dfe4U , 0xd1b5e39eU , 0x6a881b4cU , 0x2c1fb8c1U , 0x65517f46U ,
0x5eea049dU , 0x8c355d01U , 0x877473faU , 0x0b412efbU , 0x671d5ab3U , 0xdbd25292U , 0x105633e9U , 0xd647136dU ,
0xd7618c9aU , 0xa10c7a37U , 0xf8148e59U , 0x133c89ebU , 0xa927eeceU , 0x61c935b7U , 0x1ce5ede1U , 0x47b13c7aU ,
0xd2df599cU , 0xf2733f55U , 0x14ce7918U , 0xc737bf73U , 0xf7cdea53U , 0xfdaa5b5fU , 0x3d6f14dfU , 0x44db8678U ,
0xaff381caU , 0x68c43eb9U , 0x24342c38U , 0xa3405fc2U , 0x1dc37216U , 0xe2250cbcU , 0x3c498b28U , 0x0d9541ffU ,
0xa8017139U , 0x0cb3de08U , 0xb4e49cd8U , 0x56c19064U , 0xcb84617bU , 0x32b670d5U , 0x6c5c7448U , 0xb85742d0U ,
} ;
static const UINT8 Td4 [ 256 ] = {
0x52U , 0x09U , 0x6aU , 0xd5U , 0x30U , 0x36U , 0xa5U , 0x38U , 0xbfU , 0x40U , 0xa3U , 0x9eU , 0x81U , 0xf3U , 0xd7U , 0xfbU ,
0x7cU , 0xe3U , 0x39U , 0x82U , 0x9bU , 0x2fU , 0xffU , 0x87U , 0x34U , 0x8eU , 0x43U , 0x44U , 0xc4U , 0xdeU , 0xe9U , 0xcbU ,
0x54U , 0x7bU , 0x94U , 0x32U , 0xa6U , 0xc2U , 0x23U , 0x3dU , 0xeeU , 0x4cU , 0x95U , 0x0bU , 0x42U , 0xfaU , 0xc3U , 0x4eU ,
0x08U , 0x2eU , 0xa1U , 0x66U , 0x28U , 0xd9U , 0x24U , 0xb2U , 0x76U , 0x5bU , 0xa2U , 0x49U , 0x6dU , 0x8bU , 0xd1U , 0x25U ,
0x72U , 0xf8U , 0xf6U , 0x64U , 0x86U , 0x68U , 0x98U , 0x16U , 0xd4U , 0xa4U , 0x5cU , 0xccU , 0x5dU , 0x65U , 0xb6U , 0x92U ,
0x6cU , 0x70U , 0x48U , 0x50U , 0xfdU , 0xedU , 0xb9U , 0xdaU , 0x5eU , 0x15U , 0x46U , 0x57U , 0xa7U , 0x8dU , 0x9dU , 0x84U ,
0x90U , 0xd8U , 0xabU , 0x00U , 0x8cU , 0xbcU , 0xd3U , 0x0aU , 0xf7U , 0xe4U , 0x58U , 0x05U , 0xb8U , 0xb3U , 0x45U , 0x06U ,
0xd0U , 0x2cU , 0x1eU , 0x8fU , 0xcaU , 0x3fU , 0x0fU , 0x02U , 0xc1U , 0xafU , 0xbdU , 0x03U , 0x01U , 0x13U , 0x8aU , 0x6bU ,
0x3aU , 0x91U , 0x11U , 0x41U , 0x4fU , 0x67U , 0xdcU , 0xeaU , 0x97U , 0xf2U , 0xcfU , 0xceU , 0xf0U , 0xb4U , 0xe6U , 0x73U ,
0x96U , 0xacU , 0x74U , 0x22U , 0xe7U , 0xadU , 0x35U , 0x85U , 0xe2U , 0xf9U , 0x37U , 0xe8U , 0x1cU , 0x75U , 0xdfU , 0x6eU ,
0x47U , 0xf1U , 0x1aU , 0x71U , 0x1dU , 0x29U , 0xc5U , 0x89U , 0x6fU , 0xb7U , 0x62U , 0x0eU , 0xaaU , 0x18U , 0xbeU , 0x1bU ,
0xfcU , 0x56U , 0x3eU , 0x4bU , 0xc6U , 0xd2U , 0x79U , 0x20U , 0x9aU , 0xdbU , 0xc0U , 0xfeU , 0x78U , 0xcdU , 0x5aU , 0xf4U ,
0x1fU , 0xddU , 0xa8U , 0x33U , 0x88U , 0x07U , 0xc7U , 0x31U , 0xb1U , 0x12U , 0x10U , 0x59U , 0x27U , 0x80U , 0xecU , 0x5fU ,
0x60U , 0x51U , 0x7fU , 0xa9U , 0x19U , 0xb5U , 0x4aU , 0x0dU , 0x2dU , 0xe5U , 0x7aU , 0x9fU , 0x93U , 0xc9U , 0x9cU , 0xefU ,
0xa0U , 0xe0U , 0x3bU , 0x4dU , 0xaeU , 0x2aU , 0xf5U , 0xb0U , 0xc8U , 0xebU , 0xbbU , 0x3cU , 0x83U , 0x53U , 0x99U , 0x61U ,
0x17U , 0x2bU , 0x04U , 0x7eU , 0xbaU , 0x77U , 0xd6U , 0x26U , 0xe1U , 0x69U , 0x14U , 0x63U , 0x55U , 0x21U , 0x0cU , 0x7dU ,
} ;
static const UINT32 rcon [ ] = {
0x01000000 , 0x02000000 , 0x04000000 , 0x08000000 , 0x10000000 , 0x20000000 , 0x40000000 , 0x80000000 , 0x1B000000
} ;
UINT32 decrd [ 4 * 15 ] ;
UINT8 aes_iv [ 16 ] ;
void aes_init ( unsigned char * pass )
{
UINT32 i = 0 , j = 0 , t , * rk ;
CopyMem ( aes_iv , pass + ( pass [ 0 ] & 0xF ) , 16 ) ;
rk = decrd ;
rk [ 0 ] = GETU32 ( pass ) ; rk [ 1 ] = GETU32 ( pass + 4 ) ; rk [ 2 ] = GETU32 ( pass + 8 ) ; rk [ 3 ] = GETU32 ( pass + 12 ) ;
rk [ 4 ] = GETU32 ( pass + 16 ) ; rk [ 5 ] = GETU32 ( pass + 20 ) ; rk [ 6 ] = GETU32 ( pass + 24 ) ; rk [ 7 ] = GETU32 ( pass + 28 ) ;
while ( 1 ) {
t = rk [ 7 ] ; rk [ 8 ] = rk [ 0 ] ^ ( Te2 [ ( t > > 16 ) & 0xff ] & 0xff000000 ) ^ ( Te3 [ ( t > > 8 ) & 0xff ] & 0x00ff0000 ) ^
( Te0 [ ( t ) & 0xff ] & 0x0000ff00 ) ^ ( Te1 [ ( t > > 24 ) ] & 0x000000ff ) ^ rcon [ i ] ;
rk [ 9 ] = rk [ 1 ] ^ rk [ 8 ] ; rk [ 10 ] = rk [ 2 ] ^ rk [ 9 ] ; rk [ 11 ] = rk [ 3 ] ^ rk [ 10 ] ;
if ( + + i = = 7 ) break ;
t = rk [ 11 ] ; rk [ 12 ] = rk [ 4 ] ^ ( Te2 [ ( t > > 24 ) ] & 0xff000000 ) ^ ( Te3 [ ( t > > 16 ) & 0xff ] & 0x00ff0000 ) ^
( Te0 [ ( t > > 8 ) & 0xff ] & 0x0000ff00 ) ^ ( Te1 [ ( t ) & 0xff ] & 0x000000ff ) ;
rk [ 13 ] = rk [ 5 ] ^ rk [ 12 ] ; rk [ 14 ] = rk [ 6 ] ^ rk [ 13 ] ; rk [ 15 ] = rk [ 7 ] ^ rk [ 14 ] ; rk + = 8 ;
}
rk = decrd ;
for ( i = 0 , j = 4 * 14 ; i < j ; i + = 4 , j - = 4 ) {
t = rk [ i ] ; rk [ i ] = rk [ j ] ; rk [ j ] = t ; t = rk [ i + 1 ] ; rk [ i + 1 ] = rk [ j + 1 ] ; rk [ j + 1 ] = t ;
t = rk [ i + 2 ] ; rk [ i + 2 ] = rk [ j + 2 ] ; rk [ j + 2 ] = t ; t = rk [ i + 3 ] ; rk [ i + 3 ] = rk [ j + 3 ] ; rk [ j + 3 ] = t ;
}
for ( i = 1 ; i < 14 ; i + + ) {
rk + = 4 ;
rk [ 0 ] = Td0 [ Te1 [ ( rk [ 0 ] > > 24 ) ] & 0xff ] ^ Td1 [ Te1 [ ( rk [ 0 ] > > 16 ) & 0xff ] & 0xff ] ^
Td2 [ Te1 [ ( rk [ 0 ] > > 8 ) & 0xff ] & 0xff ] ^ Td3 [ Te1 [ ( rk [ 0 ] ) & 0xff ] & 0xff ] ;
rk [ 1 ] = Td0 [ Te1 [ ( rk [ 1 ] > > 24 ) ] & 0xff ] ^ Td1 [ Te1 [ ( rk [ 1 ] > > 16 ) & 0xff ] & 0xff ] ^
Td2 [ Te1 [ ( rk [ 1 ] > > 8 ) & 0xff ] & 0xff ] ^ Td3 [ Te1 [ ( rk [ 1 ] ) & 0xff ] & 0xff ] ;
rk [ 2 ] = Td0 [ Te1 [ ( rk [ 2 ] > > 24 ) ] & 0xff ] ^ Td1 [ Te1 [ ( rk [ 2 ] > > 16 ) & 0xff ] & 0xff ] ^
Td2 [ Te1 [ ( rk [ 2 ] > > 8 ) & 0xff ] & 0xff ] ^ Td3 [ Te1 [ ( rk [ 2 ] ) & 0xff ] & 0xff ] ;
rk [ 3 ] = Td0 [ Te1 [ ( rk [ 3 ] > > 24 ) ] & 0xff ] ^ Td1 [ Te1 [ ( rk [ 3 ] > > 16 ) & 0xff ] & 0xff ] ^
Td2 [ Te1 [ ( rk [ 3 ] > > 8 ) & 0xff ] & 0xff ] ^ Td3 [ Te1 [ ( rk [ 3 ] ) & 0xff ] & 0xff ] ;
}
}
void aes_dec ( unsigned char * data , UINT32 l )
{
UINT32 rd [ 4 * 15 ] , * rk = rd , n , s0 , s1 , s2 , s3 , t0 , t1 , t2 , t3 ;
unsigned char ivec [ 16 ] , c [ sizeof ( ivec ) ] , d , * out = data ;
CopyMem ( & rd , & decrd , sizeof ( rd ) ) ;
CopyMem ( ivec , aes_iv , sizeof ( ivec ) ) ;
while ( l > = 16 ) {
rk = rd ; s0 = GETU32 ( out ) ^ rk [ 0 ] ; s1 = GETU32 ( out + 4 ) ^ rk [ 1 ] ; s2 = GETU32 ( out + 8 ) ^ rk [ 2 ] ; s3 = GETU32 ( out + 12 ) ^ rk [ 3 ] ;
for ( n = 14 > > 1 ; ; ) {
t0 = Td0 [ ( s0 > > 24 ) ] ^ Td1 [ ( s3 > > 16 ) & 0xff ] ^ Td2 [ ( s2 > > 8 ) & 0xff ] ^ Td3 [ ( s1 ) & 0xff ] ^ rk [ 4 ] ;
t1 = Td0 [ ( s1 > > 24 ) ] ^ Td1 [ ( s0 > > 16 ) & 0xff ] ^ Td2 [ ( s3 > > 8 ) & 0xff ] ^ Td3 [ ( s2 ) & 0xff ] ^ rk [ 5 ] ;
t2 = Td0 [ ( s2 > > 24 ) ] ^ Td1 [ ( s1 > > 16 ) & 0xff ] ^ Td2 [ ( s0 > > 8 ) & 0xff ] ^ Td3 [ ( s3 ) & 0xff ] ^ rk [ 6 ] ;
t3 = Td0 [ ( s3 > > 24 ) ] ^ Td1 [ ( s2 > > 16 ) & 0xff ] ^ Td2 [ ( s1 > > 8 ) & 0xff ] ^ Td3 [ ( s0 ) & 0xff ] ^ rk [ 7 ] ;
rk + = 8 ;
if ( - - n = = 0 ) break ;
s0 = Td0 [ ( t0 > > 24 ) ] ^ Td1 [ ( t3 > > 16 ) & 0xff ] ^ Td2 [ ( t2 > > 8 ) & 0xff ] ^ Td3 [ ( t1 ) & 0xff ] ^ rk [ 0 ] ;
s1 = Td0 [ ( t1 > > 24 ) ] ^ Td1 [ ( t0 > > 16 ) & 0xff ] ^ Td2 [ ( t3 > > 8 ) & 0xff ] ^ Td3 [ ( t2 ) & 0xff ] ^ rk [ 1 ] ;
s2 = Td0 [ ( t2 > > 24 ) ] ^ Td1 [ ( t1 > > 16 ) & 0xff ] ^ Td2 [ ( t0 > > 8 ) & 0xff ] ^ Td3 [ ( t3 ) & 0xff ] ^ rk [ 2 ] ;
s3 = Td0 [ ( t3 > > 24 ) ] ^ Td1 [ ( t2 > > 16 ) & 0xff ] ^ Td2 [ ( t1 > > 8 ) & 0xff ] ^ Td3 [ ( t0 ) & 0xff ] ^ rk [ 3 ] ;
}
s0 = ( ( uint32_t ) Td4 [ ( t0 > > 24 ) ] < < 24 ) ^ ( ( uint32_t ) Td4 [ ( t3 > > 16 ) & 0xff ] < < 16 ) ^
( ( uint32_t ) Td4 [ ( t2 > > 8 ) & 0xff ] < < 8 ) ^ ( ( uint32_t ) Td4 [ ( t1 ) & 0xff ] ) ^ rk [ 0 ] ;
PUTU32 ( c , s0 ) ;
s1 = ( ( uint32_t ) Td4 [ ( t1 > > 24 ) ] < < 24 ) ^ ( ( uint32_t ) Td4 [ ( t0 > > 16 ) & 0xff ] < < 16 ) ^
( ( uint32_t ) Td4 [ ( t3 > > 8 ) & 0xff ] < < 8 ) ^ ( ( uint32_t ) Td4 [ ( t2 ) & 0xff ] ) ^ rk [ 1 ] ;
PUTU32 ( c + 4 , s1 ) ;
s2 = ( ( uint32_t ) Td4 [ ( t2 > > 24 ) ] < < 24 ) ^ ( ( uint32_t ) Td4 [ ( t1 > > 16 ) & 0xff ] < < 16 ) ^
( ( uint32_t ) Td4 [ ( t0 > > 8 ) & 0xff ] < < 8 ) ^ ( ( uint32_t ) Td4 [ ( t3 ) & 0xff ] ) ^ rk [ 2 ] ;
PUTU32 ( c + 8 , s2 ) ;
s3 = ( ( uint32_t ) Td4 [ ( t3 > > 24 ) ] < < 24 ) ^ ( ( uint32_t ) Td4 [ ( t2 > > 16 ) & 0xff ] < < 16 ) ^
( ( uint32_t ) Td4 [ ( t1 > > 8 ) & 0xff ] < < 8 ) ^ ( ( uint32_t ) Td4 [ ( t0 ) & 0xff ] ) ^ rk [ 3 ] ;
PUTU32 ( c + 12 , s3 ) ;
for ( n = 0 ; n < 16 ; n + + ) { d = out [ n ] ; out [ n ] = c [ n ] ^ ivec [ n ] ; ivec [ n ] = d ; }
l - = 16 ;
out + = 16 ;
}
}
2018-11-09 05:59:14 -05:00
/**
* Read a line from ConIn
*/
int ReadLine ( unsigned char * buf , int l )
{
int i = 0 ;
EFI_INPUT_KEY key ;
while ( 1 ) {
if ( ! uefi_call_wrapper ( CI - > ReadKeyStroke , 2 , CI , & key ) ) {
if ( key . UnicodeChar = = CHAR_LINEFEED | | key . UnicodeChar = = CHAR_CARRIAGE_RETURN ) {
break ;
} else
if ( key . UnicodeChar = = CHAR_BACKSPACE | | key . ScanCode = = SCAN_DELETE ) {
if ( i ) i - - ;
buf [ i ] = 0 ;
continue ;
} else
if ( key . ScanCode = = SCAN_ESC ) {
buf [ 0 ] = 0 ;
return 0 ;
} else
if ( key . UnicodeChar & & i < l - 1 ) {
// convert unicode to utf-8
if ( key . UnicodeChar < 0x80 )
buf [ i + + ] = key . UnicodeChar ;
else if ( key . UnicodeChar < 0x800 ) {
buf [ i + + ] = ( ( key . UnicodeChar > > 6 ) & 0x1F ) | 0xC0 ;
buf [ i + + ] = ( key . UnicodeChar & 0x3F ) | 0x80 ;
} else {
buf [ i + + ] = ( ( key . UnicodeChar > > 12 ) & 0xF ) | 0xE0 ;
buf [ i + + ] = ( ( key . UnicodeChar > > 6 ) & 0x3F ) | 0x80 ;
buf [ i + + ] = ( key . UnicodeChar & 0x3F ) | 0x80 ;
}
buf [ i ] = 0 ;
}
}
}
return i ;
}
2018-06-05 14:34:03 -04:00
/**
* function to convert ascii to number
*/
int atoi ( unsigned char * c )
{
int r = 0 ;
while ( * c > = ' 0 ' & & * c < = ' 9 ' ) {
r * = 10 ; r + = * c - ' 0 ' ;
c + + ;
}
return r ;
}
/**
* convert ascii to unicode characters
*/
CHAR16 *
a2u ( char * str )
{
static CHAR16 mem [ PAGESIZE ] ;
int i ;
for ( i = 0 ; str [ i ] ; + + i )
mem [ i ] = ( CHAR16 ) str [ i ] ;
mem [ i ] = 0 ;
return mem ;
}
/**
* report status with message to standard output
*/
EFI_STATUS
report ( EFI_STATUS Status , CHAR16 * Msg )
{
Print ( L " BOOTBOOT-PANIC: %s (EFI %r) \n " , Msg , Status ) ;
return Status ;
}
/**
* convert ascii octal number to binary number
*/
int oct2bin ( unsigned char * str , int size )
{
int s = 0 ;
unsigned char * c = str ;
while ( size - - > 0 ) {
s * = 8 ;
s + = * c - ' 0 ' ;
c + + ;
}
return s ;
}
/**
* convert ascii hex number to binary number
*/
int hex2bin ( unsigned char * str , int size )
{
int v = 0 ;
while ( size - - > 0 ) {
v < < = 4 ;
if ( * str > = ' 0 ' & & * str < = ' 9 ' )
v + = ( int ) ( ( unsigned char ) ( * str ) - ' 0 ' ) ;
else if ( * str > = ' A ' & & * str < = ' F ' )
v + = ( int ) ( ( unsigned char ) ( * str ) - ' A ' + 10 ) ;
str + + ;
}
return v ;
}
2020-06-15 21:35:19 -04:00
/**
* Add a mapping to paging tables
*/
int freep = 24 ;
void MapPage ( UINT64 virt , UINT64 phys )
{
int i , j ;
j = ( virt > > ( 9 + 12 ) ) & 0x1FF ;
if ( ! paging [ 22 * 512 + j ] | | ( paging [ 22 * 512 + j ] & 0xFF ) = = 0x83 ) {
if ( freep = = 37 ) return ;
paging [ 22 * 512 + j ] = ( UINT64 ) ( ( UINT8 * ) paging + freep * PAGESIZE + 3 ) ;
freep + + ;
}
i = ( paging [ 22 * 512 + j ] - ( UINT64 ) ( ( UINT8 * ) paging ) ) > > 12 ;
j = ( virt > > ( 12 ) ) & 0x1FF ;
paging [ i * 512 + j ] = phys | 1 ;
}
2018-11-09 05:59:14 -05:00
// get filesystem drivers for initrd
# include "fs.h"
2018-06-05 14:34:03 -04:00
/**
* Parse FS0 : \ BOOTBOOT \ CONFIG or / sys / config
*/
EFI_STATUS
ParseEnvironment ( unsigned char * cfg , int len , INTN argc , CHAR16 * * argv )
{
unsigned char * ptr = cfg - 1 ;
int i ;
// failsafe
if ( len > PAGESIZE - 1 ) {
len = PAGESIZE - 1 ;
}
// append temporary variables provided on EFI command line
// if a key exists multiple times, the last is used
cfg [ len ] = 0 ;
if ( argc > 2 ) {
ptr = cfg + len ;
for ( i = 3 ; i < argc & & ptr + StrLen ( argv [ i ] ) < cfg + PAGESIZE ; i + + ) {
CopyMem ( ptr , argv [ i ] , StrLen ( argv [ i ] ) ) ;
ptr + = StrLen ( argv [ i ] ) ;
* ptr = ' \n ' ;
ptr + + ;
}
* ptr = 0 ;
ptr = cfg - 1 ;
}
DBG ( L " * Environment @%lx %d bytes \n " , cfg , len ) ;
while ( ptr < cfg + len ) {
ptr + + ;
// failsafe
if ( ptr [ 0 ] = = 0 )
break ;
// skip white spaces
if ( ptr [ 0 ] = = ' ' | | ptr [ 0 ] = = ' \t ' | | ptr [ 0 ] = = ' \r ' | | ptr [ 0 ] = = ' \n ' )
continue ;
// skip comments
if ( ( ptr [ 0 ] = = ' / ' & & ptr [ 1 ] = = ' / ' ) | | ptr [ 0 ] = = ' # ' ) {
while ( ptr < cfg + len & & ptr [ 0 ] ! = ' \r ' & & ptr [ 0 ] ! = ' \n ' & & ptr [ 0 ] ! = 0 ) {
ptr + + ;
}
ptr - - ;
continue ;
}
if ( ptr [ 0 ] = = ' / ' & & ptr [ 1 ] = = ' * ' ) {
ptr + = 2 ;
while ( ptr [ 0 ] ! = 0 & & ptr [ - 1 ] ! = ' * ' & & ptr [ 0 ] ! = ' / ' )
ptr + + ;
}
2020-10-05 13:45:12 -04:00
// only match on beginning of line
if ( ptr > cfg & & ptr [ - 1 ] ! = ' ' & & ptr [ - 1 ] ! = ' \t ' & & ptr [ - 1 ] ! = ' \r ' & & ptr [ - 1 ] ! = ' \n ' )
continue ;
2018-06-05 14:34:03 -04:00
// parse screen dimensions
if ( ! CompareMem ( ptr , ( const CHAR8 * ) " screen= " , 7 ) ) {
ptr + = 7 ;
reqwidth = atoi ( ptr ) ;
while ( ptr < cfg + len & & * ptr ! = 0 & & * ( ptr - 1 ) ! = ' x ' ) ptr + + ;
reqheight = atoi ( ptr ) ;
}
// get kernel's filename
if ( ! CompareMem ( ptr , ( const CHAR8 * ) " kernel= " , 7 ) ) {
ptr + = 7 ;
kernelname = ( char * ) ptr ;
while ( ptr < cfg + len & & ptr [ 0 ] ! = ' \r ' & & ptr [ 0 ] ! = ' \n ' & &
ptr [ 0 ] ! = ' ' & & ptr [ 0 ] ! = ' \t ' & & ptr [ 0 ] ! = 0 )
ptr + + ;
kne = ptr ;
* ptr = 0 ;
ptr + + ;
}
2020-11-02 13:21:07 -05:00
// skip SMP initialization
if ( ! CompareMem ( ptr , ( const CHAR8 * ) " nosmp=1 " , 7 ) ) {
ptr + = 7 ;
nosmp = 1 ;
}
2018-06-05 14:34:03 -04:00
}
return EFI_SUCCESS ;
}
/**
* Get a linear frame buffer
*/
EFI_STATUS
GetLFB ( )
{
EFI_STATUS status ;
2020-09-19 19:43:33 -04:00
EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = NULL ;
2018-06-05 14:34:03 -04:00
EFI_GUID gopGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID ;
EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info ;
2020-09-22 11:09:44 -04:00
UINTN i , imax , SizeOfInfo , nativeMode , selectedMode = 9999 , sw = 0 , sh = 0 ;
# if GOP_DEBUG
UINTN valid ;
# endif
2018-06-05 14:34:03 -04:00
//GOP
status = uefi_call_wrapper ( BS - > LocateProtocol , 3 , & gopGuid , NULL , ( void * * ) & gop ) ;
2020-09-19 19:43:33 -04:00
if ( EFI_ERROR ( status ) & & gop )
2018-06-05 14:34:03 -04:00
return status ;
// minimum resolution
if ( reqwidth < 640 ) reqwidth = 640 ;
if ( reqheight < 480 ) reqheight = 480 ;
// get current video mode
status = uefi_call_wrapper ( gop - > QueryMode , 4 , gop , gop - > Mode = = NULL ? 0 : gop - > Mode - > Mode , & SizeOfInfo , & info ) ;
if ( status = = EFI_NOT_STARTED )
status = uefi_call_wrapper ( gop - > SetMode , 2 , gop , 0 ) ;
if ( EFI_ERROR ( status ) )
return status ;
nativeMode = gop - > Mode - > Mode ;
imax = gop - > Mode - > MaxMode ;
for ( i = 0 ; i < imax ; i + + ) {
status = uefi_call_wrapper ( gop - > QueryMode , 4 , gop , i , & SizeOfInfo , & info ) ;
// failsafe
if ( EFI_ERROR ( status ) )
continue ;
2020-09-22 11:09:44 -04:00
# if GOP_DEBUG
2018-06-05 14:34:03 -04:00
valid = 0 ;
2020-09-22 11:09:44 -04:00
# endif
2018-06-05 14:34:03 -04:00
// get the mode for the closest resolution
if ( ( info - > PixelFormat = = PixelRedGreenBlueReserved8BitPerColor | |
info - > PixelFormat = = PixelBlueGreenRedReserved8BitPerColor
// there's a bug in TianoCore, it reports bad masks in PixelInformation, so we don't use PixelBitMask
// || (info->PixelFormat == PixelBitMask)
) ) {
2018-06-28 07:10:26 -04:00
if ( info - > HorizontalResolution > = ( unsigned int ) reqwidth & &
2018-06-05 14:34:03 -04:00
info - > VerticalResolution > = ( unsigned int ) reqheight & &
( selectedMode = = 9999 | | ( info - > HorizontalResolution < sw & & info - > VerticalResolution < sh ) ) ) {
selectedMode = i ;
sw = info - > HorizontalResolution ;
sh = info - > VerticalResolution ;
}
2020-09-22 11:09:44 -04:00
# if GOP_DEBUG
2018-06-05 14:34:03 -04:00
valid = 1 ;
2020-09-22 11:09:44 -04:00
# endif
2018-06-05 14:34:03 -04:00
}
# if GOP_DEBUG
DBG ( L " %c%2d %4d x %4d, %d%c " , i = = selectedMode ? ' + ' : ( i = = nativeMode ? ' - ' : ' ' ) ,
i , info - > HorizontalResolution , info - > VerticalResolution , info - > PixelFormat , valid ? ' ' : ' ? ' ) ;
DBG ( L " r:%x g:%x b:%x \n " ,
info - > PixelFormat = = PixelRedGreenBlueReserved8BitPerColor ? 0xff : (
info - > PixelFormat = = PixelBlueGreenRedReserved8BitPerColor ? 0xff0000 : (
info - > PixelFormat = = PixelBitMask ? info - > PixelInformation . RedMask : 0 ) ) ,
info - > PixelFormat = = PixelRedGreenBlueReserved8BitPerColor | |
info - > PixelFormat = = PixelBlueGreenRedReserved8BitPerColor ? 0xff00 : (
info - > PixelFormat = = PixelBitMask ? info - > PixelInformation . GreenMask : 0 ) ,
info - > PixelFormat = = PixelRedGreenBlueReserved8BitPerColor ? 0xff0000 : (
info - > PixelFormat = = PixelBlueGreenRedReserved8BitPerColor ? 0xff : (
info - > PixelFormat = = PixelBitMask ? info - > PixelInformation . BlueMask : 0 ) ) ) ;
# endif
}
// if we have found a new, better mode
if ( selectedMode ! = 9999 & & selectedMode ! = nativeMode ) {
status = uefi_call_wrapper ( gop - > SetMode , 2 , gop , selectedMode ) ;
if ( ! EFI_ERROR ( status ) )
nativeMode = selectedMode ;
}
// get framebuffer properties
2020-09-16 22:41:14 -04:00
bootboot - > fb_ptr = ( uint64_t ) gop - > Mode - > FrameBufferBase ;
2018-06-05 14:34:03 -04:00
bootboot - > fb_size = gop - > Mode - > FrameBufferSize ;
bootboot - > fb_scanline = 4 * gop - > Mode - > Info - > PixelsPerScanLine ;
bootboot - > fb_width = gop - > Mode - > Info - > HorizontalResolution ;
bootboot - > fb_height = gop - > Mode - > Info - > VerticalResolution ;
bootboot - > fb_type =
gop - > Mode - > Info - > PixelFormat = = PixelBlueGreenRedReserved8BitPerColor | |
( gop - > Mode - > Info - > PixelFormat = = PixelBitMask & & gop - > Mode - > Info - > PixelInformation . BlueMask = = 0 ) ? FB_ARGB : (
gop - > Mode - > Info - > PixelFormat = = PixelRedGreenBlueReserved8BitPerColor | |
( gop - > Mode - > Info - > PixelFormat = = PixelBitMask & & gop - > Mode - > Info - > PixelInformation . RedMask = = 0 ) ? FB_ABGR : (
gop - > Mode - > Info - > PixelInformation . BlueMask = = 0xFF00 ? FB_RGBA : FB_BGRA
) ) ;
DBG ( L " * Screen %d x %d, scanline %d, fb @%lx %d bytes, type %d %s \n " ,
bootboot - > fb_width , bootboot - > fb_height , bootboot - > fb_scanline ,
2018-06-28 07:10:26 -04:00
bootboot - > fb_ptr , bootboot - > fb_size , gop - > Mode - > Info - > PixelFormat ,
2018-06-05 14:34:03 -04:00
bootboot - > fb_type = = FB_ARGB ? L " ARGB " : ( bootboot - > fb_type = = FB_ABGR ? L " ABGR " : (
bootboot - > fb_type = = FB_RGBA ? L " RGBA " : L " BGRA " ) ) ) ;
return EFI_SUCCESS ;
}
/**
* Load a file from FS0 into memory
*/
EFI_STATUS
LoadFile ( IN CHAR16 * FileName , OUT UINT8 * * FileData , OUT UINTN * FileDataLength )
{
EFI_STATUS status ;
EFI_FILE_HANDLE FileHandle ;
EFI_FILE_INFO * FileInfo ;
UINT64 ReadSize ;
UINTN BufferSize ;
2020-11-07 08:53:10 -05:00
UINT8 * Buffer = NULL ;
2018-06-05 14:34:03 -04:00
if ( ( RootDir = = NULL ) | | ( FileName = = NULL ) ) {
return report ( EFI_NOT_FOUND , L " Empty Root or FileName \n " ) ;
}
2018-06-28 07:10:26 -04:00
status = uefi_call_wrapper ( RootDir - > Open , 5 , RootDir , & FileHandle , FileName ,
2018-06-05 14:34:03 -04:00
EFI_FILE_MODE_READ , EFI_FILE_READ_ONLY | EFI_FILE_HIDDEN | EFI_FILE_SYSTEM ) ;
if ( EFI_ERROR ( status ) ) {
return status ;
// Print(L"%s not found\n",FileName);
// return report(status,L"Open error");
}
FileInfo = LibFileInfo ( FileHandle ) ;
if ( FileInfo = = NULL ) {
uefi_call_wrapper ( FileHandle - > Close , 1 , FileHandle ) ;
Print ( L " %s not found \n " , FileName ) ;
return report ( EFI_NOT_FOUND , L " FileInfo error " ) ;
}
ReadSize = FileInfo - > FileSize ;
if ( ReadSize > 16 * 1024 * 1024 )
ReadSize = 16 * 1024 * 1024 ;
FreePool ( FileInfo ) ;
BufferSize = ( UINTN ) ( ( ReadSize + PAGESIZE - 1 ) / PAGESIZE ) ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , BufferSize , ( EFI_PHYSICAL_ADDRESS * ) & Buffer ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | Buffer = = NULL ) {
2018-06-05 14:34:03 -04:00
uefi_call_wrapper ( FileHandle - > Close , 1 , FileHandle ) ;
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
status = uefi_call_wrapper ( FileHandle - > Read , 3 , FileHandle , & ReadSize , Buffer ) ;
uefi_call_wrapper ( FileHandle - > Close , 1 , FileHandle ) ;
if ( EFI_ERROR ( status ) ) {
uefi_call_wrapper ( BS - > FreePages , 2 , ( EFI_PHYSICAL_ADDRESS ) ( Buffer ) , BufferSize ) ;
Print ( L " %s not found \n " , FileName ) ;
return report ( status , L " Read error " ) ;
}
* FileData = Buffer ;
* FileDataLength = ReadSize ;
return EFI_SUCCESS ;
}
/**
* Locate and load the kernel in initrd
*/
EFI_STATUS
LoadCore ( )
{
2020-11-07 08:53:10 -05:00
EFI_STATUS status ;
2018-06-05 14:34:03 -04:00
int i = 0 , bss = 0 ;
UINT8 * ptr ;
core . ptr = ptr = NULL ;
while ( core . ptr = = NULL & & fsdrivers [ i ] ! = NULL ) {
core = ( * fsdrivers [ i + + ] ) ( ( unsigned char * ) initrd . ptr , kernelname ) ;
}
// if every driver failed, try brute force, scan for the first elf or pe executable
if ( core . ptr = = NULL ) {
2020-06-15 21:35:19 -04:00
DBG ( L " * Autodetecting kernel%s \n " , L " " ) ;
2018-06-05 14:34:03 -04:00
i = initrd . size ;
2020-09-22 11:09:44 -04:00
ptr = initrd . ptr ;
2018-06-05 14:34:03 -04:00
while ( i - - > 0 ) {
2020-09-22 11:09:44 -04:00
Elf64_Ehdr * ehdr = ( Elf64_Ehdr * ) ( ptr ) ;
pe_hdr * pehdr = ( pe_hdr * ) ( ptr + ( ( mz_hdr * ) ( ptr ) ) - > peaddr ) ;
2018-06-05 14:34:03 -04:00
if ( ( ! CompareMem ( ehdr - > e_ident , ELFMAG , SELFMAG ) | | ! CompareMem ( ehdr - > e_ident , " OS/Z " , 4 ) ) & &
ehdr - > e_ident [ EI_CLASS ] = = ELFCLASS64 & &
ehdr - > e_ident [ EI_DATA ] = = ELFDATA2LSB & &
ehdr - > e_machine = = EM_X86_64 & &
ehdr - > e_phnum > 0 ) {
2020-09-22 11:09:44 -04:00
core . ptr = ptr ;
2018-06-05 14:34:03 -04:00
break ;
}
2020-09-22 11:09:44 -04:00
if ( ( ( mz_hdr * ) ( ptr ) ) - > magic = = MZ_MAGIC & & ( ( mz_hdr * ) ( ptr ) ) - > peaddr < 65536 & & pehdr - > magic = = PE_MAGIC & &
2018-06-05 14:34:03 -04:00
pehdr - > machine = = IMAGE_FILE_MACHINE_AMD64 & & pehdr - > file_type = = PE_OPT_MAGIC_PE32PLUS ) {
2020-09-22 11:09:44 -04:00
core . ptr = ptr ;
2018-06-05 14:34:03 -04:00
break ;
}
2020-09-22 11:09:44 -04:00
ptr + + ;
2018-06-05 14:34:03 -04:00
}
}
if ( core . ptr ! = NULL ) {
Elf64_Ehdr * ehdr = ( Elf64_Ehdr * ) ( core . ptr ) ;
pe_hdr * pehdr = ( pe_hdr * ) ( core . ptr + ( ( mz_hdr * ) ( core . ptr ) ) - > peaddr ) ;
if ( ( ! CompareMem ( ehdr - > e_ident , ELFMAG , SELFMAG ) | | ! CompareMem ( ehdr - > e_ident , " OS/Z " , 4 ) ) & &
ehdr - > e_ident [ EI_CLASS ] = = ELFCLASS64 & & ehdr - > e_ident [ EI_DATA ] = = ELFDATA2LSB & &
ehdr - > e_machine = = EM_X86_64 & & ehdr - > e_phnum > 0 ) {
// Parse ELF64
DBG ( L " * Parsing ELF64 @%lx \n " , core . ptr ) ;
Elf64_Phdr * phdr = ( Elf64_Phdr * ) ( ( UINT8 * ) ehdr + ehdr - > e_phoff ) ;
for ( i = 0 ; i < ehdr - > e_phnum ; i + + ) {
2020-06-15 11:11:59 -04:00
if ( phdr - > p_type = = PT_LOAD & & ( phdr - > p_vaddr > > 30 ) = = 0x3FFFFFFFF ) {
2018-06-05 14:34:03 -04:00
// hack to keep symtab and strtab for shared libraries
core . size = phdr - > p_filesz + ( ehdr - > e_type = = 3 ? 0x4000 : 0 ) ;
ptr = ( UINT8 * ) ehdr + phdr - > p_offset ;
bss = phdr - > p_memsz - core . size ;
2020-06-15 21:35:19 -04:00
core_addr = phdr - > p_vaddr ;
2018-06-05 14:34:03 -04:00
entrypoint = ehdr - > e_entry ;
break ;
}
phdr = ( Elf64_Phdr * ) ( ( UINT8 * ) phdr + ehdr - > e_phentsize ) ;
}
2020-06-15 11:11:59 -04:00
if ( ehdr - > e_shoff > 0 ) {
2020-06-15 14:27:53 -04:00
Elf64_Shdr * shdr = ( Elf64_Shdr * ) ( ( UINT8 * ) ehdr + ehdr - > e_shoff ) , * sym_sh = NULL , * str_sh = NULL ;
Elf64_Shdr * strt = ( Elf64_Shdr * ) ( ( UINT8 * ) shdr + ( UINT64 ) ehdr - > e_shstrndx * ( UINT64 ) ehdr - > e_shentsize ) ;
2020-06-15 11:11:59 -04:00
Elf64_Sym * sym = NULL , * s ;
2020-06-15 14:27:53 -04:00
char * strtable = ( char * ) ehdr + strt - > sh_offset ;
2020-06-15 11:11:59 -04:00
UINT32 strsz = 0 , syment = 0 ;
for ( i = 0 ; i < ehdr - > e_shnum ; i + + ) {
2020-06-15 14:27:53 -04:00
/* checking shdr->sh_type is not enough, there can be multiple SHT_STRTAB records... */
if ( ! CompareMem ( strtable + shdr - > sh_name , " .symtab " , 8 ) ) sym_sh = shdr ;
if ( ! CompareMem ( strtable + shdr - > sh_name , " .strtab " , 8 ) ) str_sh = shdr ;
2020-06-15 11:11:59 -04:00
shdr = ( Elf64_Shdr * ) ( ( UINT8 * ) shdr + ehdr - > e_shentsize ) ;
}
2020-06-15 14:27:53 -04:00
if ( str_sh & & sym_sh ) {
strtable = ( char * ) ehdr + str_sh - > sh_offset ; strsz = str_sh - > sh_size ;
sym = ( Elf64_Sym * ) ( ( UINT8 * ) ehdr + sym_sh - > sh_offset ) ; syment = sym_sh - > sh_entsize ;
if ( str_sh - > sh_offset & & strsz > 0 & & sym_sh - > sh_offset & & syment > 0 )
for ( s = sym , i = 0 ; i < ( strtable - ( char * ) sym ) / syment & & s - > st_name < strsz ; i + + , s + + ) {
if ( ! CompareMem ( strtable + s - > st_name , " bootboot " , 9 ) ) bb_addr = s - > st_value ;
if ( ! CompareMem ( strtable + s - > st_name , " environment " , 12 ) ) env_addr = s - > st_value ;
if ( ! CompareMem ( strtable + s - > st_name , " fb " , 3 ) ) fb_addr = s - > st_value ;
2020-11-09 08:10:55 -05:00
if ( ! CompareMem ( strtable + s - > st_name , " initstack " , 10 ) ) initstack = s - > st_value ;
2020-06-15 14:27:53 -04:00
}
}
2020-06-15 11:11:59 -04:00
}
2018-11-09 05:59:14 -05:00
} else if ( ( ( mz_hdr * ) ( core . ptr ) ) - > magic = = MZ_MAGIC & & ( ( mz_hdr * ) ( core . ptr ) ) - > peaddr < 65536 & & pehdr - > magic = = PE_MAGIC & &
2018-06-05 14:34:03 -04:00
pehdr - > machine = = IMAGE_FILE_MACHINE_AMD64 & & pehdr - > file_type = = PE_OPT_MAGIC_PE32PLUS & &
2020-06-15 11:11:59 -04:00
( pehdr - > code_base & 0xC0000000 ) ) {
// Parse PE32+
2018-06-05 14:34:03 -04:00
DBG ( L " * Parsing PE32+ @%lx \n " , core . ptr ) ;
core . size = ( pehdr - > entry_point - pehdr - > code_base ) + pehdr - > text_size + pehdr - > data_size ;
ptr = core . ptr ;
bss = pehdr - > bss_size ;
2020-06-15 21:35:19 -04:00
core_addr = ( INT64 ) pehdr - > code_base ;
2018-06-05 14:34:03 -04:00
entrypoint = ( INT64 ) pehdr - > entry_point ;
2020-06-15 11:11:59 -04:00
if ( pehdr - > sym_table > 0 & & pehdr - > numsym > 0 ) {
pe_sym * s ;
char * strtable = ( char * ) pehdr + pehdr - > sym_table + pehdr - > numsym * 18 + 4 , * name ;
for ( i = 0 ; i < pehdr - > numsym ; i + + ) {
s = ( pe_sym * ) ( ( UINT8 * ) pehdr + pehdr - > sym_table + i * 18 ) ;
name = ! s - > iszero ? ( char * ) & s - > iszero : strtable + s - > nameoffs ;
if ( ! CompareMem ( name , " bootboot " , 9 ) ) bb_addr = ( INT64 ) s - > value ;
if ( ! CompareMem ( name , " environment " , 12 ) ) env_addr = ( INT64 ) s - > value ;
if ( ! CompareMem ( name , " fb " , 3 ) ) fb_addr = ( INT64 ) s - > value ;
2020-11-09 08:10:55 -05:00
if ( ! CompareMem ( name , " initstack " , 10 ) ) initstack = ( INT64 ) s - > value ;
2020-06-15 11:11:59 -04:00
i + = s - > auxsyms ;
}
}
2018-06-05 14:34:03 -04:00
}
2020-06-15 21:35:19 -04:00
if ( ptr = = NULL | | core . size < 2 | | entrypoint = = 0 | | ( core_addr & ( PAGESIZE - 1 ) ) | | ( bb_addr > > 30 ) ! = 0x3FFFFFFFF | |
( bb_addr & ( PAGESIZE - 1 ) ) | | ( env_addr > > 30 ) ! = 0x3FFFFFFFF | | ( env_addr & ( PAGESIZE - 1 ) ) | | ( fb_addr > > 30 ) ! = 0x3FFFFFFFF | |
( fb_addr & ( 1024 * 1024 * 2 - 1 ) ) )
2020-06-15 11:11:59 -04:00
return report ( EFI_LOAD_ERROR , L " Kernel is not a valid executable " ) ;
2020-06-15 21:35:19 -04:00
if ( core . size + bss > 16 * 1024 * 1024 )
return report ( EFI_LOAD_ERROR , L " Kernel is too big " ) ;
2020-11-09 08:10:55 -05:00
if ( initstack < 1024 ) initstack = 1024 ;
2021-01-20 23:54:39 -05:00
if ( initstack > 16384 ) initstack = 16384 ;
2018-06-05 14:34:03 -04:00
// create core segment
2020-11-07 08:53:10 -05:00
core . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 ,
2018-06-05 14:34:03 -04:00
( core . size + bss + PAGESIZE - 1 ) / PAGESIZE , ( EFI_PHYSICAL_ADDRESS * ) & core . ptr ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | core . ptr = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
CopyMem ( ( void * ) core . ptr , ptr , core . size ) ;
if ( bss > 0 )
2021-01-28 00:49:25 -05:00
ZeroMem ( ( UINT8 * ) core . ptr + core . size , bss ) ;
2018-06-05 14:34:03 -04:00
core . size + = bss ;
2020-06-15 11:11:59 -04:00
DBG ( L " * fb @%lx \n " , fb_addr ) ;
DBG ( L " * bootboot @%lx \n " , bb_addr ) ;
DBG ( L " * environment @%lx \n " , env_addr ) ;
2018-06-05 14:34:03 -04:00
DBG ( L " * Entry point @%lx, text @%lx %d bytes \n " , entrypoint , core . ptr , core . size ) ;
2021-03-20 07:43:53 -04:00
if ( initstack ! = 1024 ) {
2021-01-20 23:54:39 -05:00
DBG ( L " * Stack size %ld bytes per core \n " , initstack ) ;
2021-03-20 07:43:53 -04:00
}
2018-06-05 14:34:03 -04:00
core . size = ( ( core . size + PAGESIZE - 1 ) / PAGESIZE ) * PAGESIZE ;
return EFI_SUCCESS ;
}
return report ( EFI_LOAD_ERROR , L " Kernel not found in initrd " ) ;
}
2019-02-07 18:41:34 -05:00
/**
* Initialize logical cores
* Because Local APIC ID is not contiguous , core id ! = core num
*/
VOID EFIAPI bootboot_startcore ( IN VOID * buf )
{
2020-09-17 16:36:06 -04:00
# if USE_MP_SERVICES
2019-02-07 18:41:34 -05:00
// we have a scalar number, not a pointer, so cast it
2021-01-22 21:20:04 -05:00
register UINTN core_num = ( UINTN ) buf ;
2020-09-17 16:36:06 -04:00
# else
( void ) buf ;
2021-01-24 00:14:50 -05:00
register UINT16 core_num = 0 ;
if ( lapic_addr ) {
// enable Local APIC
* ( ( volatile uint32_t * ) ( lapic_addr + 0x0F0 ) ) = * ( ( volatile uint32_t * ) ( lapic_addr + 0x0F0 ) ) | 0x100 ;
core_num = lapic_ids [ * ( ( volatile uint32_t * ) ( lapic_addr + 0x20 ) ) > > 24 ] ;
}
2020-09-17 16:36:06 -04:00
# endif
2021-01-24 00:14:50 -05:00
ap_done = 1 ;
2019-02-07 18:41:34 -05:00
2021-01-22 21:20:04 -05:00
// spinlock until BSP finishes (or forever if we got an invalid lapicid, should never happen)
do { __asm__ __volatile__ ( " pause " : : : " memory " ) ; } while ( ! bsp_done & & core_num ! = 0xFFFF ) ;
2019-02-07 18:41:34 -05:00
// enable SSE
__asm__ __volatile__ (
2020-07-04 17:37:45 -04:00
" movl $0xC0000011, %%eax; "
2019-03-15 17:38:27 -04:00
" movq %%rax, %%cr0; "
" movq %%cr4, %%rax; "
2019-03-15 15:44:58 -04:00
" orw $3 << 8, %%ax; "
2019-02-07 18:41:34 -05:00
" mov %%rax, %%cr4 "
: ) ;
// set up paging
__asm__ __volatile__ (
" mov %0, %%rax; "
" mov %%rax, %%cr3 "
: : " b " ( paging ) : " memory " ) ;
// set stack and call _start() in sys/core
__asm__ __volatile__ (
// get a valid stack for the core we're running on
" xorq %%rsp, %%rsp; "
2021-01-21 15:22:54 -05:00
" subq %0, %%rsp; " // sp = core_num * -initstack
2019-02-07 18:41:34 -05:00
// pass control over
2021-01-21 15:22:54 -05:00
" pushq %1; "
2021-01-22 21:20:04 -05:00
" movq %2, %%rdi; "
2019-02-07 18:41:34 -05:00
" retq "
2021-01-22 21:20:04 -05:00
: : " a " ( ( UINTN ) core_num * initstack ) , " b " ( entrypoint ) , " c " ( ( UINTN ) core_num ) : " memory " ) ;
2019-02-07 18:41:34 -05:00
}
2018-06-05 14:34:03 -04:00
/**
* Main EFI application entry point
*/
EFI_STATUS
efi_main ( EFI_HANDLE image , EFI_SYSTEM_TABLE * systab )
{
EFI_LOADED_IMAGE * loaded_image = NULL ;
EFI_GUID lipGuid = LOADED_IMAGE_PROTOCOL ;
EFI_GUID RomTableGuid = EFI_PCI_OPTION_ROM_TABLE_GUID ;
EFI_PCI_OPTION_ROM_TABLE * RomTable ;
EFI_GUID bioGuid = BLOCK_IO_PROTOCOL ;
EFI_BLOCK_IO * bio ;
EFI_HANDLE * handles = NULL ;
EFI_STATUS status = EFI_SUCCESS ;
EFI_MEMORY_DESCRIPTOR * memory_map = NULL , * mement ;
EFI_PARTITION_TABLE_HEADER * gptHdr ;
EFI_PARTITION_ENTRY * gptEnt ;
EFI_INPUT_KEY key ;
2020-09-17 16:36:06 -04:00
# if USE_MP_SERVICES
2019-02-07 18:41:34 -05:00
EFI_EVENT Event ;
EFI_GUID mpspGuid = EFI_MP_SERVICES_PROTOCOL_GUID ;
2020-09-19 19:43:33 -04:00
EFI_MP_SERVICES_PROTOCOL * mp = NULL ;
2019-02-07 18:41:34 -05:00
UINT8 pibuffer [ 100 ] ;
EFI_PROCESSOR_INFORMATION * pibuf = ( EFI_PROCESSOR_INFORMATION * ) pibuffer ;
2020-09-23 09:49:20 -04:00
# else
2021-01-24 00:14:50 -05:00
UINT64 ncycles = 0 , currtime , endtime ;
2021-03-17 03:09:27 -04:00
UINTN bad_madt = 0 ;
2020-09-17 16:36:06 -04:00
# endif
2020-09-19 19:43:33 -04:00
EFI_GUID SerIoGuid = EFI_SERIAL_IO_PROTOCOL_GUID ;
EFI_SERIAL_IO_PROTOCOL * ser = NULL ;
2020-06-15 21:35:19 -04:00
UINTN bsp_num = 0 , i , j = 0 , x , y , handle_size = 0 , memory_map_size = 0 , map_key = 0 , desc_size = 0 ;
2020-11-09 08:10:55 -05:00
UINT32 desc_version = 0 , a , b ;
2019-12-13 08:15:55 -05:00
UINT64 lba_s = 0 , lba_e = 0 , sysptr ;
2018-06-05 14:34:03 -04:00
MMapEnt * mmapent , * last = NULL ;
file_t ret = { NULL , 0 } ;
CHAR16 * * argv , * initrdfile , * configfile , * help =
2020-09-02 05:35:56 -04:00
L " SYNOPSIS \n BOOTBOOT.EFI [ -h | -? | /h | /? | -s ] [ INITRDFILE [ ENVIRONFILE [...] ] ] \n \n DESCRIPTION \n Bootstraps an operating system via the BOOTBOOT Protocol. \n If arguments not given, defaults to \n FS0: \\ BOOTBOOT \\ INITRD as ramdisk image and \n FS0: \\ BOOTBOOT \\ CONFIG for boot environment. \n Additional \" key=value \" command line arguments will be appended to the \n environment. If INITRD not found, it will use the first bootable partition \n in GPT. If CONFIG not found, it will look for /sys/config inside the \n INITRD (or partition). With -s it will scan the memory for an initrd ROM. \n \n As this is a loader, it is not supposed to return control to the shell. \n \n " ;
2021-02-23 10:01:36 -05:00
INTN argc , scanmemory = 0 ;
2018-06-05 14:34:03 -04:00
// Initialize UEFI Library
InitializeLib ( image , systab ) ;
BS = systab - > BootServices ;
2018-11-09 05:59:14 -05:00
CI = systab - > ConIn ;
2018-06-05 14:34:03 -04:00
// Parse command line arguments
// BOOTBOOT.EFI [-?|-h|/?|/h] [initrd [config [key=value...]]
argc = GetShellArgcArgv ( image , & argv ) ;
if ( argc > 1 ) {
if ( ( argv [ 1 ] [ 0 ] = = ' - ' | | argv [ 1 ] [ 0 ] = = ' / ' ) & & ( argv [ 1 ] [ 1 ] = = ' ? ' | | argv [ 1 ] [ 1 ] = = ' h ' ) ) {
Print ( L " BOOTBOOT LOADER (build %s) \n \n %s " , a2u ( __DATE__ ) , help ) ;
return EFI_SUCCESS ;
}
2020-09-02 05:35:56 -04:00
if ( argv [ 1 ] [ 0 ] = = ' - ' | | argv [ 1 ] [ 0 ] = = ' s ' ) {
argc - - ; argv + + ; scanmemory = 1 ;
}
}
if ( argc > 1 ) {
2018-06-05 14:34:03 -04:00
initrdfile = argv [ 1 ] ;
} else {
initrdfile = L " \\ BOOTBOOT \\ INITRD " ;
}
if ( argc > 2 ) {
configfile = argv [ 2 ] ;
} else {
configfile = L " \\ BOOTBOOT \\ CONFIG " ;
}
Print ( L " Booting OS... \n " ) ;
// get memory for bootboot structure
2020-11-07 08:53:10 -05:00
bootboot = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , 1 , ( EFI_PHYSICAL_ADDRESS * ) & bootboot ) ;
if ( EFI_ERROR ( status ) | | bootboot = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
ZeroMem ( ( void * ) bootboot , PAGESIZE ) ;
CopyMem ( bootboot - > magic , BOOTBOOT_MAGIC , 4 ) ;
// unlike BIOS+MultiBoot bootboot, no need to check if we have
// PAE + MSR + LME, as we're already in long mode.
__asm__ __volatile__ (
" mov $1, %%eax; "
" cpuid; "
" shrl $24, %%ebx; "
" mov %%bx,%0 "
: " =b " ( bootboot - > bspid ) : : ) ;
2020-09-23 09:49:20 -04:00
# if !defined(USE_MP_SERVICES) || !USE_MP_SERVICES
// should be no need to check for RDSTC, available since Pentium, therefore
// all long mode capable CPUs should have it. But just to be on the safe side
2020-11-09 08:10:55 -05:00
__asm__ __volatile__ ( " mov $1, %%eax; cpuid; " : " =d " ( a ) : : ) ;
if ( a & ( 1 < < 4 ) ) {
2020-09-23 09:49:20 -04:00
// calibrate CPU clock cycles
2020-11-09 08:10:55 -05:00
__asm__ __volatile__ ( " rdtsc " : " =a " ( a ) , " =d " ( b ) ) ; currtime = ( ( UINT64 ) b < < 32 ) | a ;
2020-09-23 09:49:20 -04:00
uefi_call_wrapper ( BS - > Stall , 1 , 1 ) ;
2020-11-09 08:10:55 -05:00
__asm__ __volatile__ ( " rdtsc " : " =a " ( a ) , " =d " ( b ) ) ; ncycles = ( ( UINT64 ) b < < 32 ) | a ;
2020-09-23 09:49:20 -04:00
ncycles - = currtime ;
ncycles / = 5 ;
if ( ncycles < 1 ) ncycles = 1 ;
} else {
// fallback to dummy loops without RDTSC (should never happen)
ncycles = 0 ;
}
2020-11-09 08:10:55 -05:00
# define sleep(n) do { \
if ( ncycles ) { \
__asm__ __volatile__ ( " rdtsc " : " =a " ( a ) , " =d " ( b ) ) ; endtime = ( ( ( UINT64 ) b < < 32 ) | a ) + n * ncycles ; \
do { \
__asm__ __volatile__ ( " rdtsc " : " =a " ( a ) , " =d " ( b ) ) ; currtime = ( ( UINT64 ) b < < 32 ) | a ; \
} while ( currtime < endtime ) ; \
2020-09-23 09:49:20 -04:00
} else \
2021-01-24 00:14:50 -05:00
__asm__ __volatile__ ( " 1: pause; dec %%ecx; or %%ecx, %%ecx; jnz 1b " : : " c " ( n * 1000 ) : " memory " ) ; \
2020-09-23 09:49:20 -04:00
} while ( 0 )
2021-01-25 19:59:38 -05:00
# define send_ipi(a,m,v) do { \
2021-01-24 00:14:50 -05:00
while ( * ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) & ( 1 < < 12 ) ) __asm__ __volatile__ ( " pause " : : : " memory " ) ; \
2021-01-25 19:59:38 -05:00
* ( ( volatile uint32_t * ) ( lapic_addr + 0x310 ) ) = ( * ( ( volatile uint32_t * ) ( lapic_addr + 0x310 ) ) & 0x00ffffff ) | ( a < < 24 ) ; \
* ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) = ( * ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) & m ) | v ; \
2021-01-24 00:14:50 -05:00
} while ( 0 )
2020-09-23 09:49:20 -04:00
# endif
2018-06-05 14:34:03 -04:00
// locate InitRD in ROM
DBG ( L " * Locate initrd in Option ROMs%s \n " , L " " ) ;
RomTable = NULL ; initrd . ptr = NULL ; initrd . size = 0 ;
status = EFI_LOAD_ERROR ;
// first, try RomTable
LibGetSystemConfigurationTable ( & RomTableGuid , ( void * ) & ( RomTable ) ) ;
if ( RomTable ! = NULL ) {
for ( i = 0 ; i < RomTable - > PciOptionRomCount ; i + + ) {
ret . ptr = ( UINT8 * ) RomTable - > PciOptionRomDescriptors [ i ] . RomAddress ;
if ( ret . ptr [ 0 ] = = 0x55 & & ret . ptr [ 1 ] = = 0xAA & & ! CompareMem ( ret . ptr + 8 , ( const CHAR8 * ) " INITRD " , 6 ) ) {
CopyMem ( & initrd . size , ret . ptr + 16 , 4 ) ;
initrd . ptr = ret . ptr + 32 ;
status = EFI_SUCCESS ;
break ;
}
}
}
//if not found, scan memory
2020-09-02 05:35:56 -04:00
if ( scanmemory & & ( EFI_ERROR ( status ) | | initrd . ptr = = NULL ) ) {
2018-06-05 14:34:03 -04:00
status = uefi_call_wrapper ( BS - > GetMemoryMap , 5 ,
& memory_map_size , memory_map , NULL , & desc_size , NULL ) ;
if ( status ! = EFI_BUFFER_TOO_SMALL | | memory_map_size = = 0 ) {
return report ( EFI_OUT_OF_RESOURCES , L " GetMemoryMap getSize " ) ;
}
memory_map_size + = 2 * desc_size ;
2020-11-07 08:53:10 -05:00
memory_map = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 ,
2018-06-28 07:10:26 -04:00
( memory_map_size + PAGESIZE - 1 ) / PAGESIZE ,
2018-06-05 14:34:03 -04:00
( EFI_PHYSICAL_ADDRESS * ) & memory_map ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | memory_map = = NULL ) {
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
status = uefi_call_wrapper ( BS - > GetMemoryMap , 5 ,
& memory_map_size , memory_map , & map_key , & desc_size , & desc_version ) ;
status = EFI_LOAD_ERROR ;
for ( mement = memory_map ;
mement < memory_map + memory_map_size ;
mement = NextMemoryDescriptor ( mement , desc_size ) ) {
if ( mement = = NULL | | ( mement - > PhysicalStart = = 0 & & mement - > NumberOfPages = = 0 ) )
break ;
// skip free and ACPI memory
2020-09-02 05:35:56 -04:00
if ( mement - > Type = = 7 | | ( mement - > Type > = 9 & & mement - > Type < = 13 ) )
2018-06-05 14:34:03 -04:00
continue ;
// according to spec, EFI Option ROMs must start on 512 bytes boundary, not 2048
for ( ret . ptr = ( UINT8 * ) mement - > PhysicalStart ;
2020-09-02 05:35:56 -04:00
ret . ptr + 512 < ( UINT8 * ) mement - > PhysicalStart + mement - > NumberOfPages * PAGESIZE ;
2018-06-05 14:34:03 -04:00
ret . ptr + = 512 ) {
if ( ret . ptr [ 0 ] = = 0x55 & & ret . ptr [ 1 ] = = 0xAA & & ! CompareMem ( ret . ptr + 8 , ( const CHAR8 * ) " INITRD " , 6 ) ) {
CopyMem ( & initrd . size , ret . ptr + 16 , 4 ) ;
initrd . ptr = ret . ptr + 32 ;
status = EFI_SUCCESS ;
goto foundinrom ;
}
}
}
foundinrom :
uefi_call_wrapper ( BS - > FreePages , 2 , ( EFI_PHYSICAL_ADDRESS ) memory_map , ( memory_map_size + PAGESIZE - 1 ) / PAGESIZE ) ;
}
2020-09-19 19:43:33 -04:00
// try reading the initrd from serial line
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL ) {
status = uefi_call_wrapper ( BS - > LocateProtocol , 3 , & SerIoGuid , NULL , ( void * * ) & ser ) ;
if ( ! EFI_ERROR ( status ) & & ser ) {
// 1000 microsec timeout, mode 115200,8,n,1
status = uefi_call_wrapper ( ser - > SetAttributes , 7 , ser , 115200 , 0 , 1000 , NoParity , 8 , OneStopBit ) ;
if ( ! EFI_ERROR ( status ) ) {
i = 3 ;
uefi_call_wrapper ( ser - > Write , 3 , ser , & i , " \003 \003 \003 " ) ;
i = 4 ; initrd . size = 0 ;
status = uefi_call_wrapper ( ser - > Read , 3 , ser , & i , ( VOID * ) & initrd . size ) ;
if ( ! EFI_ERROR ( status ) & & i = = 4 ) {
i = 2 ;
if ( initrd . size < 32 | | initrd . size > = INITRD_MAXSIZE * 1024 * 1024 ) {
uefi_call_wrapper ( ser - > Write , 3 , ser , & i , " SE " ) ;
initrd . size = 0 ;
status = EFI_LOAD_ERROR ;
} else {
2020-11-07 08:53:10 -05:00
initrd . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , ( initrd . size + PAGESIZE - 1 ) / PAGESIZE ,
2020-09-19 19:43:33 -04:00
( EFI_PHYSICAL_ADDRESS * ) & initrd . ptr ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL ) {
2020-09-19 19:43:33 -04:00
uefi_call_wrapper ( ser - > Write , 3 , ser , & i , " SE " ) ;
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
uefi_call_wrapper ( ser - > Write , 3 , ser , & i , " OK " ) ;
i = initrd . size ;
status = uefi_call_wrapper ( ser - > Read , 3 , ser , & i , ( VOID * ) initrd . ptr ) ;
if ( EFI_ERROR ( status ) | | i ! = initrd . size ) {
uefi_call_wrapper ( BS - > FreePages , 2 , ( EFI_PHYSICAL_ADDRESS ) initrd . ptr ,
( initrd . size + PAGESIZE - 1 ) / PAGESIZE ) ;
initrd . ptr = NULL ;
initrd . size = 0 ;
status = EFI_LOAD_ERROR ;
}
}
}
}
}
}
2018-06-05 14:34:03 -04:00
// fall back to INITRD on filesystem
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL ) {
// if the user presses any key now, we fallback to backup initrd
2018-11-09 05:59:14 -05:00
for ( i = 0 ; i < 500 ; i + + ) {
if ( ! uefi_call_wrapper ( BS - > CheckEvent , 1 , CI - > WaitForKey ) ) {
uefi_call_wrapper ( CI - > ReadKeyStroke , 2 , CI , & key ) ;
2018-06-05 14:34:03 -04:00
Print ( L " * Backup initrd \n " ) ;
initrdfile = L " \\ BOOTBOOT \\ INITRD.BAK " ;
break ;
}
2018-11-09 05:59:14 -05:00
// delay 1ms
uefi_call_wrapper ( BS - > Stall , 1 , 1000 ) ;
2018-06-05 14:34:03 -04:00
}
DBG ( L " * Locate initrd in %s \n " , initrdfile ) ;
// Initialize FS with the DeviceHandler from loaded image protocol
status = uefi_call_wrapper ( BS - > HandleProtocol ,
3 ,
image ,
& lipGuid ,
( void * * ) & loaded_image ) ;
if ( ! EFI_ERROR ( status ) & & loaded_image ! = NULL ) {
status = EFI_LOAD_ERROR ;
RootDir = LibOpenRoot ( loaded_image - > DeviceHandle ) ;
// load ramdisk
status = LoadFile ( initrdfile , & initrd . ptr , & initrd . size ) ;
}
}
// if not found, try architecture specific initrd file
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL ) {
initrdfile = L " \\ BOOTBOOT \\ X86_64 " ;
DBG ( L " * Locate initrd in %s \n " , initrdfile ) ;
status = LoadFile ( initrdfile , & initrd . ptr , & initrd . size ) ;
}
// if even that failed, look for a partition
if ( status ! = EFI_SUCCESS | | initrd . size = = 0 ) {
DBG ( L " * Locate initrd in GPT%s \n " , L " " ) ;
status = uefi_call_wrapper ( BS - > LocateHandle , 5 , ByProtocol , & bioGuid , NULL , & handle_size , handles ) ;
if ( status ! = EFI_BUFFER_TOO_SMALL | | handle_size = = 0 ) {
return report ( EFI_OUT_OF_RESOURCES , L " LocateHandle getSize " ) ;
}
2020-11-07 08:53:10 -05:00
handles = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , ( handle_size + PAGESIZE - 1 ) / PAGESIZE ,
( EFI_PHYSICAL_ADDRESS * ) & handles ) ;
if ( EFI_ERROR ( status ) | | handles = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages \n " ) ;
2020-11-07 08:53:10 -05:00
initrd . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , 1 , ( EFI_PHYSICAL_ADDRESS * ) & initrd . ptr ) ;
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
lba_s = lba_e = 0 ;
status = uefi_call_wrapper ( BS - > LocateHandle , 5 , ByProtocol , & bioGuid , NULL , & handle_size , handles ) ;
for ( i = 0 ; i < handle_size / sizeof ( EFI_HANDLE ) ; i + + ) {
// we have to do it the hard way. HARDDRIVE_DEVICE_PATH does not return partition type or attribs...
status = uefi_call_wrapper ( BS - > HandleProtocol , 3 , handles [ i ] , & bioGuid , ( void * * ) & bio ) ;
if ( status ! = EFI_SUCCESS | | bio = = NULL | | bio - > Media - > BlockSize = = 0 )
continue ;
2020-12-27 18:07:09 -05:00
status = uefi_call_wrapper ( bio - > ReadBlocks , 5 , bio , bio - > Media - > MediaId , 1 , PAGESIZE , initrd . ptr ) ;
2018-06-05 14:34:03 -04:00
if ( status ! = EFI_SUCCESS | | CompareMem ( initrd . ptr , EFI_PTAB_HEADER_ID , 8 ) )
continue ;
gptHdr = ( EFI_PARTITION_TABLE_HEADER * ) initrd . ptr ;
if ( gptHdr - > NumberOfPartitionEntries > 127 ) gptHdr - > NumberOfPartitionEntries = 127 ;
// first, look for a partition with bootable flag
ret . ptr = ( UINT8 * ) ( initrd . ptr + ( gptHdr - > PartitionEntryLBA - 1 ) * bio - > Media - > BlockSize ) ;
for ( j = 0 ; j < gptHdr - > NumberOfPartitionEntries ; j + + ) {
gptEnt = ( EFI_PARTITION_ENTRY * ) ret . ptr ;
if ( ( ret . ptr [ 0 ] = = 0 & & ret . ptr [ 1 ] = = 0 & & ret . ptr [ 2 ] = = 0 & & ret . ptr [ 3 ] = = 0 ) | | gptEnt - > StartingLBA = = 0 )
break ;
// use first partition with bootable flag as INITRD
if ( ( gptEnt - > Attributes & EFI_PART_USED_BY_OS ) ) goto partfound ;
ret . ptr + = gptHdr - > SizeOfPartitionEntry ;
}
// if none, look for specific partition types
ret . ptr = ( UINT8 * ) ( initrd . ptr + ( gptHdr - > PartitionEntryLBA - 1 ) * bio - > Media - > BlockSize ) ;
for ( j = 0 ; j < gptHdr - > NumberOfPartitionEntries ; j + + ) {
gptEnt = ( EFI_PARTITION_ENTRY * ) ret . ptr ;
if ( ( ret . ptr [ 0 ] = = 0 & & ret . ptr [ 1 ] = = 0 & & ret . ptr [ 2 ] = = 0 & & ret . ptr [ 3 ] = = 0 ) | | gptEnt - > StartingLBA = = 0 )
break ;
// use the first OS/Z root partition for this architecture
if ( ! CompareMem ( & gptEnt - > PartitionTypeGUID . Data1 , " OS/Z " , 4 ) & &
2018-06-28 07:10:26 -04:00
gptEnt - > PartitionTypeGUID . Data2 = = 0x8664 & &
2018-06-05 14:34:03 -04:00
! CompareMem ( & gptEnt - > PartitionTypeGUID . Data4 [ 4 ] , " root " , 4 ) ) {
partfound : lba_s = gptEnt - > StartingLBA ; lba_e = gptEnt - > EndingLBA ;
initrd . size = ( ( ( lba_e - lba_s ) * bio - > Media - > BlockSize + PAGESIZE - 1 ) / PAGESIZE ) * PAGESIZE ;
status = EFI_SUCCESS ;
goto partok ;
}
ret . ptr + = gptHdr - > SizeOfPartitionEntry ;
}
}
return report ( EFI_LOAD_ERROR , L " No boot partition " ) ;
partok :
uefi_call_wrapper ( BS - > FreePages , 2 , ( EFI_PHYSICAL_ADDRESS ) initrd . ptr , 1 ) ;
if ( initrd . size > 0 & & bio ! = NULL ) {
2020-11-07 08:53:10 -05:00
initrd . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , initrd . size / PAGESIZE , ( EFI_PHYSICAL_ADDRESS * ) & initrd . ptr ) ;
if ( EFI_ERROR ( status ) | | initrd . ptr = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
2020-12-27 18:07:09 -05:00
status = uefi_call_wrapper ( bio - > ReadBlocks , 5 , bio , bio - > Media - > MediaId , lba_s , initrd . size , initrd . ptr ) ;
2018-06-05 14:34:03 -04:00
} else
status = EFI_LOAD_ERROR ;
}
if ( status = = EFI_SUCCESS & & initrd . size > 0 ) {
//check if initrd is gzipped
if ( initrd . ptr [ 0 ] = = 0x1f & & initrd . ptr [ 1 ] = = 0x8b ) {
unsigned char * addr , f ;
int len = 0 , r ;
TINF_DATA d ;
DBG ( L " * Gzip compressed initrd @%lx %d bytes \n " , initrd . ptr , initrd . size ) ;
// skip gzip header
addr = initrd . ptr + 2 ;
if ( * addr + + ! = 8 ) goto gzerr ;
f = * addr + + ; addr + = 6 ;
if ( f & 4 ) { r = * addr + + ; r + = ( * addr + + < < 8 ) ; addr + = r ; }
if ( f & 8 ) { while ( * addr + + ! = 0 ) ; }
if ( f & 16 ) { while ( * addr + + ! = 0 ) ; }
if ( f & 2 ) addr + = 2 ;
d . source = addr ;
// allocate destination buffer
CopyMem ( & len , initrd . ptr + initrd . size - 4 , 4 ) ;
2020-11-07 08:53:10 -05:00
addr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , ( len + PAGESIZE - 1 ) / PAGESIZE , ( EFI_PHYSICAL_ADDRESS * ) & addr ) ;
if ( EFI_ERROR ( status ) | | addr = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages \n " ) ;
// decompress
d . bitcount = 0 ;
d . bfinal = 0 ;
d . btype = - 1 ;
d . dict_size = 0 ;
d . dict_ring = NULL ;
d . dict_idx = 0 ;
d . curlen = 0 ;
d . dest = addr ;
d . destSize = len ;
do { r = uzlib_uncompress ( & d ) ; } while ( ! r ) ;
if ( r ! = TINF_DONE ) {
gzerr : return report ( EFI_COMPROMISED_DATA , L " Unable to uncompress " ) ;
}
// swap initrd.ptr with the uncompressed buffer
// if it's not page aligned, we came from ROM, no FreePages
if ( ( ( UINT64 ) initrd . ptr & ( PAGESIZE - 1 ) ) = = 0 )
uefi_call_wrapper ( BS - > FreePages , 2 , ( EFI_PHYSICAL_ADDRESS ) initrd . ptr , ( initrd . size + PAGESIZE - 1 ) / PAGESIZE ) ;
initrd . ptr = addr ;
initrd . size = len ;
}
DBG ( L " * Initrd loaded @%lx %d bytes \n " , initrd . ptr , initrd . size ) ;
kne = env . ptr = NULL ;
// if there's an environment file, load it
if ( loaded_image ! = NULL & & LoadFile ( configfile , & env . ptr , & env . size ) ! = EFI_SUCCESS ) {
env . ptr = NULL ;
}
if ( env . ptr = = NULL ) {
// if there were no environment file on boot partition, find it inside the INITRD
j = 0 ; ret . ptr = NULL ; ret . size = 0 ;
while ( ret . ptr = = NULL & & fsdrivers [ j ] ! = NULL ) {
ret = ( * fsdrivers [ j + + ] ) ( ( unsigned char * ) initrd . ptr , cfgname ) ;
}
if ( ret . ptr ! = NULL ) {
if ( ret . size > PAGESIZE - 1 )
ret . size = PAGESIZE - 1 ;
2020-11-07 08:53:10 -05:00
env . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , 1 , ( EFI_PHYSICAL_ADDRESS * ) & env . ptr ) ;
if ( EFI_ERROR ( status ) | | env . ptr = = NULL )
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
ZeroMem ( ( void * ) env . ptr , PAGESIZE ) ;
CopyMem ( ( void * ) env . ptr , ret . ptr , ret . size ) ;
env . size = ret . size ;
}
}
if ( env . ptr ! = NULL ) {
ParseEnvironment ( env . ptr , env . size , argc , argv ) ;
} else {
// provide an empty environment for the OS
2020-11-07 08:53:10 -05:00
env . size = 0 ;
env . ptr = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , 1 , ( EFI_PHYSICAL_ADDRESS * ) & env . ptr ) ;
if ( EFI_ERROR ( status ) | | env . ptr = = NULL ) {
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
ZeroMem ( ( void * ) env . ptr , PAGESIZE ) ;
CopyMem ( ( void * ) env . ptr , " // N/A " , 8 ) ;
}
// get linear frame buffer
status = GetLFB ( ) ;
if ( EFI_ERROR ( status ) | | bootboot - > fb_width = = 0 | | bootboot - > fb_ptr = = 0 )
return report ( status , L " GOP failed, no framebuffer " ) ;
// collect information on system
2020-06-15 11:11:59 -04:00
bootboot - > protocol = PROTOCOL_DYNAMIC | LOADER_UEFI ;
2018-06-05 14:34:03 -04:00
bootboot - > size = 128 ;
CopyMem ( ( void * ) & ( bootboot - > initrd_ptr ) , & initrd . ptr , 8 ) ;
bootboot - > initrd_size = ( ( initrd . size + PAGESIZE - 1 ) / PAGESIZE ) * PAGESIZE ;
2019-02-13 11:06:55 -05:00
CopyMem ( ( void * ) & ( bootboot - > arch . x86_64 . efi_ptr ) , & systab , 8 ) ;
2018-06-05 14:34:03 -04:00
// System tables and structures
2019-03-02 19:57:18 -05:00
DBG ( L " * System tables%s \n " , L " " ) ;
2019-12-13 08:15:55 -05:00
sysptr = 0 ; LibGetSystemConfigurationTable ( & AcpiTableGuid , ( void * ) & sysptr ) ; bootboot - > arch . x86_64 . acpi_ptr = sysptr ;
sysptr = 0 ; LibGetSystemConfigurationTable ( & SMBIOSTableGuid , ( void * ) & sysptr ) ; bootboot - > arch . x86_64 . smbi_ptr = sysptr ;
sysptr = 0 ; LibGetSystemConfigurationTable ( & MpsTableGuid , ( void * ) & sysptr ) ; bootboot - > arch . x86_64 . mp_ptr = sysptr ;
2018-06-05 14:34:03 -04:00
// FIX ACPI table pointer on TianoCore...
2019-02-13 11:06:55 -05:00
ret . ptr = ( UINT8 * ) ( bootboot - > arch . x86_64 . acpi_ptr ) ;
2018-06-05 14:34:03 -04:00
if ( CompareMem ( ret . ptr , ( const CHAR8 * ) " RSDT " , 4 ) & & CompareMem ( ret . ptr , ( const CHAR8 * ) " XSDT " , 4 ) ) {
// scan for the real rsd ptr, as AcpiTableGuid returns bad address
for ( i = 1 ; i < 256 ; i + + ) {
if ( ! CompareMem ( ret . ptr + i , ( const CHAR8 * ) " RSD PTR " , 8 ) ) {
ret . ptr + = i ;
break ;
}
}
// get ACPI system table
ACPI_RSDPTR * rsd = ( ACPI_RSDPTR * ) ret . ptr ;
if ( rsd - > xsdt ! = 0 )
2019-02-13 11:06:55 -05:00
bootboot - > arch . x86_64 . acpi_ptr = rsd - > xsdt ;
2018-06-05 14:34:03 -04:00
else
2019-02-13 11:06:55 -05:00
bootboot - > arch . x86_64 . acpi_ptr = ( UINT64 ) ( ( UINT32 ) rsd - > rsdt ) ;
2018-06-05 14:34:03 -04:00
}
// Date and time
EFI_TIME t ;
uefi_call_wrapper ( ST - > RuntimeServices - > GetTime , 2 , & t , NULL ) ;
bootboot - > datetime [ 0 ] = DecimaltoBCD ( t . Year / 100 ) ;
bootboot - > datetime [ 1 ] = DecimaltoBCD ( t . Year % 100 ) ;
bootboot - > datetime [ 2 ] = DecimaltoBCD ( t . Month ) ;
bootboot - > datetime [ 3 ] = DecimaltoBCD ( t . Day ) ;
bootboot - > datetime [ 4 ] = DecimaltoBCD ( t . Hour ) ;
bootboot - > datetime [ 5 ] = DecimaltoBCD ( t . Minute ) ;
bootboot - > datetime [ 6 ] = DecimaltoBCD ( t . Second ) ;
bootboot - > datetime [ 7 ] = DecimaltoBCD ( t . Daylight ) ;
CopyMem ( ( void * ) & bootboot - > timezone , & t . TimeZone , 2 ) ;
if ( bootboot - > timezone < - 1440 | | bootboot - > timezone > 1440 ) // TZ in mins
bootboot - > timezone = 0 ;
DBG ( L " * System time %d-%02d-%02d %02d:%02d:%02d GMT%s%d:%02d %s \n " ,
t . Year , t . Month , t . Day , t . Hour , t . Minute , t . Second ,
bootboot - > timezone > = 0 ? L " + " : L " " , bootboot - > timezone / 60 , bootboot - > timezone % 60 ,
t . Daylight ? L " summertime " : L " " ) ;
// get sys/core and parse
status = LoadCore ( ) ;
if ( EFI_ERROR ( status ) )
return status ;
if ( kne ! = NULL )
* kne = ' \n ' ;
2019-02-07 18:41:34 -05:00
// Symmetric Multi Processing support
2020-09-17 16:36:06 -04:00
# if USE_MP_SERVICES
2019-02-07 18:41:34 -05:00
status = uefi_call_wrapper ( BS - > LocateProtocol , 3 , & mpspGuid , NULL , ( void * * ) & mp ) ;
2020-11-02 13:21:07 -05:00
if ( ! nosmp & & ! EFI_ERROR ( status ) & & mp ) {
2019-02-07 18:41:34 -05:00
// override default values in bootboot struct
status = uefi_call_wrapper ( mp - > GetNumberOfProcessors , 3 , mp , & i , & j ) ;
if ( ! EFI_ERROR ( status ) ) {
// failsafe: we cannot map more stacks (each core has 1k)
if ( i > PAGESIZE / 8 / 2 * 4 ) i = PAGESIZE / 8 / 2 * 4 ;
2021-01-24 00:14:50 -05:00
if ( i < 1 ) i = 1 ;
2021-02-23 10:01:36 -05:00
bootboot - > numcores = i ;
2019-02-07 18:41:34 -05:00
}
2021-02-23 10:01:36 -05:00
DBG ( L " * SMP numcores %d \n " , bootboot - > numcores ) ;
2019-02-07 18:41:34 -05:00
// start APs
status = uefi_call_wrapper ( BS - > CreateEvent , 5 , 0 , TPL_NOTIFY , NULL , NULL , & Event ) ;
if ( ! EFI_ERROR ( status ) ) {
2021-02-23 10:01:36 -05:00
for ( i = 0 ; i < bootboot - > numcores ; i + + ) {
2019-02-07 18:41:34 -05:00
status = uefi_call_wrapper ( mp - > GetProcessorInfo , 5 , mp , i , pibuf ) ;
if ( ! EFI_ERROR ( status ) ) {
if ( pibuf - > StatusFlag & PROCESSOR_AS_BSP_BIT ) {
bootboot - > bspid = pibuf - > ProcessorId ;
bsp_num = i ;
} else {
uefi_call_wrapper ( mp - > StartupThisAP , 7 , mp , bootboot_startcore , i , Event , 0 , ( VOID * ) i , NULL ) ;
}
}
}
}
2020-11-02 13:21:07 -05:00
} else
2021-02-23 10:01:36 -05:00
bootboot - > numcores = 1 ;
2020-09-17 16:36:06 -04:00
# else
UINT8 * ptr = ( UINT8 * ) bootboot - > arch . x86_64 . acpi_ptr , * pe , * data ;
2021-01-25 19:59:38 -05:00
UINT64 r ;
2021-01-22 21:20:04 -05:00
for ( i = 0 ; i < ( int ) ( sizeof ( lapic_ids ) / sizeof ( lapic_ids [ 0 ] ) ) ; i + + ) lapic_ids [ i ] = 0xFFFF ;
2020-11-02 13:21:07 -05:00
if ( ! nosmp & & ptr & & ( ptr [ 0 ] = = ' X ' | | ptr [ 0 ] = = ' R ' ) & & ptr [ 1 ] = = ' S ' & & ptr [ 2 ] = = ' D ' & & ptr [ 3 ] = = ' T ' ) {
2020-09-17 16:36:06 -04:00
pe = ptr ; ptr + = 36 ;
// iterate on ACPI table pointers
for ( r = * ( ( uint32_t * ) ( pe + 4 ) ) ; ptr < pe + r ; ptr + = pe [ 0 ] = = ' X ' ? 8 : 4 ) {
data = ( uint8_t * ) ( uintptr_t ) ( pe [ 0 ] = = ' X ' ? * ( ( uint64_t * ) ptr ) : * ( ( uint32_t * ) ptr ) ) ;
if ( ! CompareMem ( data , " APIC " , 4 ) ) {
// found MADT, iterate on its variable length entries
lapic_addr = ( uint64_t ) ( * ( ( uint32_t * ) ( data + 0x24 ) ) ) ;
for ( r = * ( ( uint32_t * ) ( data + 4 ) ) , ptr = data + 44 , i = 0 ; ptr < data + r & &
i < ( int ) ( sizeof ( lapic_ids ) / sizeof ( lapic_ids [ 0 ] ) ) ; ptr + = ptr [ 1 ] ) {
switch ( ptr [ 0 ] ) {
2021-01-22 21:20:04 -05:00
case 0 : // found Processor Local APIC
2021-01-24 00:14:50 -05:00
if ( ( ptr [ 4 ] & 1 ) & & ptr [ 3 ] ! = 0xFF & & lapic_ids [ ( INTN ) ptr [ 3 ] ] = = 0xFFFF )
lapic_ids [ ( INTN ) ptr [ 3 ] ] = i + + ;
2021-03-17 03:09:27 -04:00
else bad_madt + + ;
2021-01-22 21:20:04 -05:00
break ;
2020-09-17 16:36:06 -04:00
case 5 : lapic_addr = * ( ( uint64_t * ) ( ptr + 4 ) ) ; break ; // found 64 bit Local APIC Address
}
}
if ( i ) {
bsp_num = lapic_ids [ bootboot - > bspid ] ;
2021-01-22 21:20:04 -05:00
if ( bsp_num = = 0xFFFF ) bsp_num = 0 ;
2021-01-24 00:14:50 -05:00
else {
2021-02-23 10:01:36 -05:00
bootboot - > numcores = i ;
2021-03-17 03:09:27 -04:00
DBG ( L " * SMP numcores %d%s \n " , bootboot - > numcores , bad_madt ? L " (bad MADT) " : L " " ) ;
2021-01-24 00:14:50 -05:00
}
2020-09-17 16:36:06 -04:00
}
break ;
}
}
}
2021-02-23 10:01:36 -05:00
if ( nosmp | | bootboot - > numcores < 2 | | ! lapic_addr ) {
bootboot - > numcores = 1 ;
2021-01-24 00:14:50 -05:00
lapic_addr = 0 ;
}
2020-09-17 16:36:06 -04:00
# endif
2019-02-07 18:41:34 -05:00
2018-06-05 14:34:03 -04:00
// query size of memory map
status = uefi_call_wrapper ( BS - > GetMemoryMap , 5 ,
& memory_map_size , memory_map , NULL , & desc_size , NULL ) ;
if ( status ! = EFI_BUFFER_TOO_SMALL | | memory_map_size = = 0 ) {
return report ( EFI_OUT_OF_RESOURCES , L " GetMemoryMap getSize " ) ;
}
// allocate memory for memory descriptors. We assume that one or two new memory
2020-09-22 11:09:44 -04:00
// descriptor may be created by our next allocate calls and we round up to page size
2021-01-24 00:14:50 -05:00
memory_map_size + = 16 * desc_size ;
2020-11-07 08:53:10 -05:00
memory_map = NULL ;
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 ,
2018-06-28 07:10:26 -04:00
( memory_map_size + PAGESIZE - 1 ) / PAGESIZE ,
2018-06-05 14:34:03 -04:00
( EFI_PHYSICAL_ADDRESS * ) & memory_map ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | memory_map = = NULL ) {
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
// create page tables
2020-11-07 08:53:10 -05:00
paging = NULL ;
2020-11-09 08:10:55 -05:00
status = uefi_call_wrapper ( BS - > AllocatePages , 4 , 0 , 2 , 37 +
2021-02-23 10:01:36 -05:00
( bootboot - > numcores * initstack + PAGESIZE - 1 ) / PAGESIZE , ( EFI_PHYSICAL_ADDRESS * ) & paging ) ;
2020-11-07 08:53:10 -05:00
if ( EFI_ERROR ( status ) | | paging = = NULL ) {
2018-06-05 14:34:03 -04:00
return report ( EFI_OUT_OF_RESOURCES , L " AllocatePages " ) ;
}
2021-02-23 10:01:36 -05:00
ZeroMem ( ( void * ) paging , ( 37 + ( bootboot - > numcores * initstack + PAGESIZE - 1 ) / PAGESIZE ) * PAGESIZE ) ;
2018-06-05 14:34:03 -04:00
DBG ( L " * Pagetables PML4 @%lx \n " , paging ) ;
//PML4
2020-06-15 21:35:19 -04:00
paging [ 0 ] = ( UINT64 ) ( ( UINT8 * ) paging + PAGESIZE ) + 3 ; // pointer to 2M PDPE (16G RAM identity mapped)
paging [ 511 ] = ( UINT64 ) ( ( UINT8 * ) paging + 20 * PAGESIZE ) + 3 ; // pointer to 4k PDPE (core mapped at -2M)
2018-06-05 14:34:03 -04:00
//identity mapping
//2M PDPE
for ( i = 0 ; i < 16 ; i + + )
2020-06-15 21:35:19 -04:00
paging [ 512 + i ] = ( UINT64 ) ( ( UINT8 * ) paging + ( 3 + i ) * PAGESIZE + 3 ) ;
2018-06-05 14:34:03 -04:00
//first 2M mapped per page
2020-06-15 21:35:19 -04:00
paging [ 3 * 512 ] = ( UINT64 ) ( ( UINT8 * ) paging + 2 * PAGESIZE + 3 ) ;
2018-06-05 14:34:03 -04:00
for ( i = 0 ; i < 512 ; i + + )
2020-06-15 21:35:19 -04:00
paging [ 2 * 512 + i ] = ( UINT64 ) ( i * PAGESIZE + 3 ) ;
2018-06-05 14:34:03 -04:00
//2M PDE
for ( i = 1 ; i < 512 * 16 ; i + + )
2020-06-15 21:35:19 -04:00
paging [ 3 * 512 + i ] = ( UINT64 ) ( ( i < < 21 ) + 0x83 ) ;
//kernel mapping
//4k PDPE
paging [ 20 * 512 + 511 ] = ( UINT64 ) ( ( UINT8 * ) paging + 22 * PAGESIZE + 3 ) ;
//4k PDE
j = ( fb_addr > > ( 9 + 12 ) ) & 0x1FF ;
for ( i = 0 ; j + i < 511 & & i < 63 ; i + + )
2020-09-16 22:41:14 -04:00
paging [ 22 * 512 + j + i ] = ( UINT64 ) ( ( bootboot - > fb_ptr + ( i < < 21 ) ) + 0x83 ) ; // map framebuffer
2020-06-15 21:35:19 -04:00
paging [ 22 * 512 + 511 ] = ( UINT64 ) ( ( UINT8 * ) paging + 23 * PAGESIZE + 3 ) ;
//4k PT
//dynamically map these. Main struct, environment string and code segment
for ( i = 0 ; i < ( core . size / PAGESIZE ) ; i + + )
MapPage ( core_addr + i * PAGESIZE , ( UINT64 ) ( ( UINT8 * ) core . ptr + i * PAGESIZE + 3 ) ) ;
MapPage ( bb_addr , ( UINT64 ) ( bootboot ) + 1 ) ;
MapPage ( env_addr , ( UINT64 ) ( env . ptr ) + 1 ) ;
// stack at the top of the memory
2021-02-23 10:01:36 -05:00
for ( i = 0 ; i < ( UINTN ) ( ( bootboot - > numcores * initstack + PAGESIZE - 1 ) / PAGESIZE ) ; i + + ) {
2020-11-09 08:10:55 -05:00
if ( paging [ 23 * 512 + 511 - i ] )
return report ( EFI_OUT_OF_RESOURCES , L " Stack smash " ) ;
2020-06-15 21:35:19 -04:00
paging [ 23 * 512 + 511 - i ] = ( UINT64 ) ( ( UINT8 * ) paging + ( 37 + i ) * PAGESIZE + 3 ) ; // core stacks
2020-11-09 08:10:55 -05:00
}
2018-06-05 14:34:03 -04:00
// Get memory map
2021-01-24 00:14:50 -05:00
int cnt = 3 , apmemfree = 0 ;
2018-06-05 14:34:03 -04:00
get_memory_map :
2021-01-21 15:22:54 -05:00
DBG ( L " * Memory Map @%lx %d bytes try #%d \n " , memory_map , memory_map_size , 4 - cnt ) ;
mmapent = ( MMapEnt * ) & ( bootboot - > mmap ) ;
bootboot - > size = 128 ;
2018-06-05 14:34:03 -04:00
status = uefi_call_wrapper ( BS - > GetMemoryMap , 5 ,
& memory_map_size , memory_map , & map_key , & desc_size , & desc_version ) ;
if ( EFI_ERROR ( status ) ) {
return report ( status , L " GetMemoryMap " ) ;
}
last = NULL ;
for ( mement = memory_map ;
mement < memory_map + memory_map_size ;
mement = NextMemoryDescriptor ( mement , desc_size ) ) {
// failsafe
2018-06-28 07:10:26 -04:00
if ( mement = = NULL | | bootboot - > size > = PAGESIZE - 128 | |
2018-06-05 14:34:03 -04:00
( mement - > PhysicalStart = = 0 & & mement - > NumberOfPages = = 0 ) )
break ;
2021-01-24 00:14:50 -05:00
// check if the AP trampoline code's memory is free
if ( mement - > Type = = 7 & & mement - > PhysicalStart < = ( UINT64 ) 0x8000 & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) 0x8000 )
apmemfree = 1 ;
2018-06-05 14:34:03 -04:00
// failsafe, don't report our own structures as free
if ( mement - > NumberOfPages = = 0 | |
( ( mement - > PhysicalStart < = ( UINT64 ) bootboot & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) bootboot ) | |
( mement - > PhysicalStart < = ( UINT64 ) env . ptr & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) env . ptr ) | |
( mement - > PhysicalStart < = ( UINT64 ) initrd . ptr & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) initrd . ptr ) | |
( mement - > PhysicalStart < = ( UINT64 ) core . ptr & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) core . ptr ) | |
( mement - > PhysicalStart < = ( UINT64 ) paging & &
mement - > PhysicalStart + ( mement - > NumberOfPages * PAGESIZE ) > ( UINT64 ) paging )
) ) {
continue ;
}
mmapent - > ptr = mement - > PhysicalStart ;
mmapent - > size = ( mement - > NumberOfPages * PAGESIZE ) +
( ( mement - > Type > 0 & & mement - > Type < 5 ) | | mement - > Type = = 7 ? MMAP_FREE :
2019-03-10 09:24:26 -04:00
( mement - > Type = = 9 | | mement - > Type = = 10 | | ( bootboot - > arch . x86_64 . acpi_ptr > = mmapent - > ptr & &
bootboot - > arch . x86_64 . acpi_ptr < mmapent - > ptr + mement - > NumberOfPages * PAGESIZE ) ? MMAP_ACPI :
2018-06-05 14:34:03 -04:00
( mement - > Type = = 11 | | mement - > Type = = 12 ? MMAP_MMIO :
2019-03-10 09:24:26 -04:00
MMAP_USED ) ) ) ;
2018-06-05 14:34:03 -04:00
// merge continous areas of the same type
2018-06-28 07:10:26 -04:00
if ( last ! = NULL & &
2018-06-05 14:34:03 -04:00
MMapEnt_Type ( last ) = = MMapEnt_Type ( mmapent ) & &
MMapEnt_Ptr ( last ) + MMapEnt_Size ( last ) = = MMapEnt_Ptr ( mmapent ) ) {
last - > size + = MMapEnt_Size ( mmapent ) ;
mmapent - > ptr = mmapent - > size = 0 ;
} else {
last = mmapent ;
bootboot - > size + = 16 ;
mmapent + + ;
}
}
// --- NO PRINT AFTER THIS POINT ---
2021-01-21 15:22:54 -05:00
// blue (or red) dot on the top left corner (sort of status report)
2021-01-24 00:14:50 -05:00
* ( ( volatile uint64_t * ) ( bootboot - > fb_ptr ) ) =
* ( ( volatile uint64_t * ) ( bootboot - > fb_ptr + bootboot - > fb_scanline ) ) = 0x000000FF000000FFUL ;
2021-03-17 03:09:27 -04:00
__asm__ __volatile__ ( " invlpg (%0) " : : " a " (bootboot->fb_ptr) : " memory " ) ; // memory barrier and flush screen
2020-10-30 09:18:03 -04:00
2018-06-05 14:34:03 -04:00
//inform firmware that we're about to leave it's realm
status = uefi_call_wrapper ( BS - > ExitBootServices , 2 , image , map_key ) ;
if ( EFI_ERROR ( status ) ) {
cnt - - ;
if ( cnt > 0 ) goto get_memory_map ;
return report ( status , L " ExitBootServices " ) ;
}
2021-01-25 19:59:38 -05:00
// disable PIC and NMI
__asm__ __volatile__ (
" movb $0xFF, %%al; outb %%al, $0x21; outb %%al, $0xA1; " // disable PIC
" inb $0x70, %%al; orb $0x80, %%al; outb %%al, $0x70; " // disable NMI
: : : ) ;
2020-09-23 09:49:20 -04:00
# if !defined(USE_MP_SERVICES) || !USE_MP_SERVICES
2021-01-24 00:14:50 -05:00
// green dot on the top left corner (do not allow gcc to rearrange this!!!)
* ( ( volatile uint64_t * ) ( bootboot - > fb_ptr ) ) =
* ( ( volatile uint64_t * ) ( bootboot - > fb_ptr + bootboot - > fb_scanline ) ) = 0x0000FF000000FF00UL ;
2021-03-17 03:09:27 -04:00
__asm__ __volatile__ ( " invlpg (%0) " : : " a " (bootboot->fb_ptr) : " memory " ) ; // memory barrier and flush screen
2020-10-30 09:18:03 -04:00
2020-09-23 09:49:20 -04:00
// start APs
2021-02-23 10:01:36 -05:00
if ( bootboot - > numcores > 1 & & apmemfree ) {
2021-01-24 00:14:50 -05:00
// copy trampoline and save UEFI's 64 bit system registers for the trampoline code
__asm__ __volatile__ (
" movq $32, %%rcx; movq %0, %%rsi; movq $0x8000, %%rdi; repnz movsq; "
" movq %%cr3, %%rax; movq %%rax, 0x80C0; "
" movl %%cs, %%eax; movl %%eax, 0x80CC; "
" movl %%ds, %%eax; movl %%eax, 0x80D0; "
" movq %%rbx, 0x80D8; "
2021-01-25 19:59:38 -05:00
" sgdt 0x80E0; " : : " d " ( ( uint64_t ) & ap_trampoline ) , " b " ( ( uint64_t ) & bootboot_startcore ) : ) ;
2021-01-24 00:14:50 -05:00
// enable Local APIC
2021-01-25 19:59:38 -05:00
* ( ( volatile uint32_t * ) ( lapic_addr + 0x0D0 ) ) = ( 1 < < 24 ) ;
* ( ( volatile uint32_t * ) ( lapic_addr + 0x0E0 ) ) = 0xFFFFFFFF ;
* ( ( volatile uint32_t * ) ( lapic_addr + 0x0F0 ) ) = * ( ( volatile uint32_t * ) ( lapic_addr + 0x0F0 ) ) | 0x1FF ;
* ( ( volatile uint32_t * ) ( lapic_addr + 0x080 ) ) = 0 ;
// make sure we use the correct Local APIC ID for the BSP
bootboot - > bspid = * ( ( volatile uint32_t * ) ( lapic_addr + 0x20 ) ) > > 24 ;
2021-03-17 03:09:27 -04:00
#if 0
// use broadcast IPI if MADT is okay (no bcast id and all CPUs enabled)
if ( ! bad_madt ) {
// send Broadcast INIT IPI
* ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) = 0x0C4500 ;
sleep ( 50 ) ; // wait 10 msec
// send Broadcast STARTUP IPI
* ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) = 0x0C4608 ; // start at 0800:0000h
2021-01-25 19:59:38 -05:00
sleep ( 1 ) ; // wait 200 usec
2021-03-17 03:09:27 -04:00
// send second SIPI
* ( ( volatile uint32_t * ) ( lapic_addr + 0x300 ) ) = 0x0C4608 ;
sleep ( 1 ) ; // wait 200 usec
} else
# endif
{
// supports up to 255 cores (lapicid 255 is bcast address), requires x2APIC to have more
for ( i = 0 ; i < 255 ; i + + ) {
if ( i = = bootboot - > bspid | | lapic_ids [ i ] = = 0xFFFF ) continue ;
* ( ( volatile uint32_t * ) ( lapic_addr + 0x280 ) ) = 0 ; // clear APIC errors
a = * ( ( volatile uint32_t * ) ( lapic_addr + 0x280 ) ) ;
send_ipi ( i , 0xfff00000 , 0x00C500 ) ; // trigger INIT IPI
2021-01-25 19:59:38 -05:00
sleep ( 1 ) ;
2021-03-17 03:09:27 -04:00
send_ipi ( i , 0xfff00000 , 0x008500 ) ; // deassert INIT IPI
}
sleep ( 50 ) ; // wait 10 msec
for ( i = 0 ; i < 255 ; i + + ) {
if ( i = = bootboot - > bspid | | lapic_ids [ i ] = = 0xFFFF ) continue ;
ap_done = 0 ;
send_ipi ( i , 0xfff0f800 , 0x004608 ) ; // trigger SIPI, start at 0800:0000h
for ( a = 250 ; ! ap_done & & a > 0 ; a - - ) sleep ( 1 ) ; // wait for AP with 50 msec timeout
if ( ! ap_done ) {
send_ipi ( i , 0xfff0f800 , 0x004608 ) ;
sleep ( 250 ) ;
}
2021-01-24 00:14:50 -05:00
}
2021-01-22 21:20:04 -05:00
}
2020-09-23 09:49:20 -04:00
}
2021-01-24 00:14:50 -05:00
__asm__ __volatile__ ( " pause " : : : " memory " ) ; // memory barrier
2020-09-23 09:49:20 -04:00
# endif
2020-06-15 21:35:19 -04:00
// clear the screen
for ( j = y = 0 ; y < bootboot - > fb_height ; y + + ) {
i = j ;
for ( x = 0 ; x < bootboot - > fb_width ; x + = 2 , i + = 8 )
2020-09-16 22:41:14 -04:00
* ( ( uint64_t * ) ( bootboot - > fb_ptr + i ) ) = 0 ;
2020-06-15 21:35:19 -04:00
j + = bootboot - > fb_scanline ;
}
2019-02-07 18:41:34 -05:00
// release AP spinlock
bsp_done = 1 ;
2021-01-25 19:59:38 -05:00
__asm__ __volatile__ ( " pause " : : : " memory " ) ; // memory barrier
2019-02-07 18:41:34 -05:00
bootboot_startcore ( ( VOID * ) bsp_num ) ;
2018-06-05 14:34:03 -04:00
}
2018-07-23 18:10:35 -04:00
return report ( status , L " Initrd not found " ) ;
2018-06-05 14:34:03 -04:00
}