diff options
Diffstat (limited to 'src/arch/x86/core')
| -rw-r--r-- | src/arch/x86/core/cpuid.c | 5 | ||||
| -rw-r--r-- | src/arch/x86/core/cpuid_settings.c | 20 | ||||
| -rw-r--r-- | src/arch/x86/core/debugcon.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/gdbmach.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/pci_autoboot.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/pcidirect.c | 4 | ||||
| -rw-r--r-- | src/arch/x86/core/rdrand.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/relocate.c | 96 | ||||
| -rw-r--r-- | src/arch/x86/core/runtime.c | 17 | ||||
| -rw-r--r-- | src/arch/x86/core/video_subr.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/vram_settings.c | 5 | ||||
| -rw-r--r-- | src/arch/x86/core/x86_bigint.c | 100 | ||||
| -rw-r--r-- | src/arch/x86/core/x86_io.c | 69 | ||||
| -rw-r--r-- | src/arch/x86/core/x86_string.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/x86_tcpip.c | 1 | ||||
| -rw-r--r-- | src/arch/x86/core/x86_uart.c | 60 |
16 files changed, 183 insertions, 200 deletions
diff --git a/src/arch/x86/core/cpuid.c b/src/arch/x86/core/cpuid.c index 1a7c93e83..0461b846e 100644 --- a/src/arch/x86/core/cpuid.c +++ b/src/arch/x86/core/cpuid.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <string.h> #include <errno.h> @@ -84,8 +85,8 @@ int cpuid_supported ( uint32_t function ) { return rc; /* Find highest supported function number within this family */ - cpuid ( ( function & CPUID_EXTENDED ), 0, &max_function, &discard_b, - &discard_c, &discard_d ); + cpuid ( ( function & ( CPUID_EXTENDED | CPUID_HYPERVISOR ) ), 0, + &max_function, &discard_b, &discard_c, &discard_d ); /* Fail if maximum function number is meaningless (e.g. if we * are attempting to call an extended function on a CPU which diff --git a/src/arch/x86/core/cpuid_settings.c b/src/arch/x86/core/cpuid_settings.c index 0b67ee91d..ef0164069 100644 --- a/src/arch/x86/core/cpuid_settings.c +++ b/src/arch/x86/core/cpuid_settings.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <string.h> #include <errno.h> @@ -38,7 +39,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * * Bit 31 Extended function * Bits 30-24 (bit 22 = 1) Subfunction number - * (bit 22 = 0) Number of consecutive functions to call, minus one + * Bit 30 (bit 22 = 0) Hypervisor function + * Bits 29-24 (bit 22 = 0) Number of consecutive functions to call, minus one * Bit 23 Return result as little-endian (used for strings) * Bit 22 Interpret bits 30-24 as a subfunction number * Bits 21-18 Unused @@ -98,7 +100,7 @@ enum cpuid_flags { * @v tag Setting tag * @ret function Starting function number */ -#define CPUID_FUNCTION( tag ) ( (tag) & 0x800000ffUL ) +#define CPUID_FUNCTION( tag ) ( (tag) & 0xc00000ffUL ) /** * Extract subfunction number from CPUID setting tag @@ -109,6 +111,14 @@ enum cpuid_flags { #define CPUID_SUBFUNCTION( tag ) ( ( (tag) >> 24 ) & 0x7f ) /** + * Extract number of consecutive functions from CPUID setting tag + * + * @v tag Setting tag + * @ret num_functions Number of consecutive functions + */ +#define CPUID_NUM_FUNCTIONS( tag ) ( ( ( (tag) >> 24 ) & 0x3f ) + 1 ) + +/** * Extract register array from CPUID setting tag * * @v tag Setting tag @@ -165,12 +175,13 @@ static int cpuid_settings_fetch ( struct settings *settings, /* Call each function in turn */ function = CPUID_FUNCTION ( setting->tag ); - subfunction = CPUID_SUBFUNCTION ( setting->tag ); if ( setting->tag & CPUID_USE_SUBFUNCTION ) { + function &= ~CPUID_HYPERVISOR; + subfunction = CPUID_SUBFUNCTION ( setting->tag ); num_functions = 1; } else { - num_functions = ( subfunction + 1 ); subfunction = 0; + num_functions = CPUID_NUM_FUNCTIONS ( setting->tag ); } for ( ; num_functions-- ; function++ ) { @@ -240,6 +251,7 @@ static void cpuid_settings_init ( void ) { /** CPUID settings initialiser */ struct init_fn cpuid_settings_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "cpuid", .initialise = cpuid_settings_init, }; diff --git a/src/arch/x86/core/debugcon.c b/src/arch/x86/core/debugcon.c index 60de61f55..0e3a5dfc7 100644 --- a/src/arch/x86/core/debugcon.c +++ b/src/arch/x86/core/debugcon.c @@ -86,5 +86,6 @@ static void debugcon_init ( void ) { * Debug port console initialisation function */ struct init_fn debugcon_init_fn __init_fn ( INIT_EARLY ) = { + .name = "debugcon", .initialise = debugcon_init, }; diff --git a/src/arch/x86/core/gdbmach.c b/src/arch/x86/core/gdbmach.c index af6abfedd..d4d187e35 100644 --- a/src/arch/x86/core/gdbmach.c +++ b/src/arch/x86/core/gdbmach.c @@ -31,7 +31,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <ipxe/uaccess.h> #include <ipxe/gdbstub.h> #include <librm.h> -#include <gdbmach.h> /** @file * diff --git a/src/arch/x86/core/pci_autoboot.c b/src/arch/x86/core/pci_autoboot.c index 337598091..243e45026 100644 --- a/src/arch/x86/core/pci_autoboot.c +++ b/src/arch/x86/core/pci_autoboot.c @@ -44,5 +44,6 @@ static void pci_autoboot_init ( void ) { /** PCI autoboot device initialisation function */ struct init_fn pci_autoboot_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "autoboot", .initialise = pci_autoboot_init, }; diff --git a/src/arch/x86/core/pcidirect.c b/src/arch/x86/core/pcidirect.c index f4659a1ac..887b78a0b 100644 --- a/src/arch/x86/core/pcidirect.c +++ b/src/arch/x86/core/pcidirect.c @@ -45,6 +45,7 @@ void pcidirect_prepare ( struct pci_device *pci, int where ) { PCIDIRECT_CONFIG_ADDRESS ); } +PROVIDE_PCIAPI_INLINE ( direct, pci_can_probe ); PROVIDE_PCIAPI_INLINE ( direct, pci_discover ); PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( direct, pci_read_config_word ); @@ -53,5 +54,4 @@ PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_byte ); PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_word ); PROVIDE_PCIAPI_INLINE ( direct, pci_write_config_dword ); PROVIDE_PCIAPI_INLINE ( direct, pci_ioremap ); - -struct pci_api pcidirect_api = PCIAPI_RUNTIME ( direct ); +PROVIDE_PCIAPI_RUNTIME ( direct, PCIAPI_PRIORITY_DIRECT ); diff --git a/src/arch/x86/core/rdrand.c b/src/arch/x86/core/rdrand.c index 850ab1f11..05fc3cd23 100644 --- a/src/arch/x86/core/rdrand.c +++ b/src/arch/x86/core/rdrand.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * diff --git a/src/arch/x86/core/relocate.c b/src/arch/x86/core/relocate.c index 765d46560..3cdc53c2e 100644 --- a/src/arch/x86/core/relocate.c +++ b/src/arch/x86/core/relocate.c @@ -1,4 +1,5 @@ -#include <ipxe/io.h> +#include <ipxe/uaccess.h> +#include <ipxe/memmap.h> #include <registers.h> /* @@ -41,82 +42,73 @@ extern char _etextdata[]; * to the prefix in %edi. */ __asmcall void relocate ( struct i386_all_regs *ix86 ) { - struct memory_map memmap; - uint32_t start, end, size, padded_size, max; - uint32_t new_start, new_end; - unsigned i; + struct memmap_region region; + physaddr_t start, end, max; + physaddr_t new_start, new_end; + physaddr_t r_start, r_end; + size_t size, padded_size; - /* Get memory map and current location */ - get_memmap ( &memmap ); + /* Show whole memory map (for debugging) */ + memmap_dump_all ( 0 ); + + /* Get current location */ start = virt_to_phys ( _textdata ); end = virt_to_phys ( _etextdata ); size = ( end - start ); padded_size = ( size + ALIGN - 1 ); - DBG ( "Relocate: currently at [%x,%x)\n" - "...need %x bytes for %d-byte alignment\n", - start, end, padded_size, ALIGN ); + DBGC ( ®ion, "Relocate: currently at [%#08lx,%#08lx)\n" + "...need %#zx bytes for %d-byte alignment\n", + start, end, padded_size, ALIGN ); /* Determine maximum usable address */ max = MAX_ADDR; if ( ix86->regs.ebp < max ) { max = ix86->regs.ebp; - DBG ( "Limiting relocation to [0,%x)\n", max ); + DBGC ( ®ion, "Limiting relocation to [0,%#08lx)\n", max ); } /* Walk through the memory map and find the highest address - * below 4GB that iPXE will fit into. + * above the current iPXE and below 4GB that iPXE will fit + * into. */ new_end = end; - for ( i = 0 ; i < memmap.count ; i++ ) { - struct memory_region *region = &memmap.regions[i]; - uint32_t r_start, r_end; + for_each_memmap_from ( ®ion, end, 0 ) { - DBG ( "Considering [%llx,%llx)\n", region->start, region->end); - /* Truncate block to maximum address. This will be - * less than 4GB, which means that we can get away - * with using just 32-bit arithmetic after this stage. + * strictly less than 4GB, which means that we can get + * away with using just 32-bit arithmetic after this + * stage. */ - if ( region->start > max ) { - DBG ( "...starts after max=%x\n", max ); + DBGC_MEMMAP ( ®ion, ®ion ); + if ( region.min > max ) { + DBGC ( ®ion, "...starts after max=%#08lx\n", max ); + break; + } + r_start = region.min; + if ( ! memmap_is_usable ( ®ion ) ) { + DBGC ( ®ion, "...not usable\n" ); continue; } - r_start = region->start; - if ( region->end > max ) { - DBG ( "...end truncated to max=%x\n", max ); + r_end = ( r_start + memmap_size ( ®ion ) ); + if ( ( r_end == 0 ) || ( r_end > max ) ) { + DBGC ( ®ion, "...end truncated to max=%#08lx\n", + max ); r_end = max; - } else { - r_end = region->end; - } - DBG ( "...usable portion is [%x,%x)\n", r_start, r_end ); - - /* If we have rounded down r_end below r_ start, skip - * this block. - */ - if ( r_end < r_start ) { - DBG ( "...truncated to negative size\n" ); - continue; } + DBGC ( ®ion, "...usable portion is [%#08lx,%#08lx)\n", + r_start, r_end ); /* Check that there is enough space to fit in iPXE */ - if ( ( r_end - r_start ) < size ) { - DBG ( "...too small (need %x bytes)\n", size ); + if ( ( r_end - r_start ) < padded_size ) { + DBGC ( ®ion, "...too small (need %#zx bytes)\n", + padded_size ); continue; } - /* If the start address of the iPXE we would - * place in this block is higher than the end address - * of the current highest block, use this block. - * - * Note that this avoids overlaps with the current - * iPXE, as well as choosing the highest of all viable - * blocks. - */ - if ( ( r_end - size ) > new_end ) { - new_end = r_end; - DBG ( "...new best block found.\n" ); - } + /* Use highest block with enough space */ + new_end = r_end; + DBGC ( ®ion, "...new best block found.\n" ); } /* Calculate new location of iPXE, and align it to the @@ -126,9 +118,9 @@ __asmcall void relocate ( struct i386_all_regs *ix86 ) { new_start += ( ( start - new_start ) & ( ALIGN - 1 ) ); new_end = new_start + size; - DBG ( "Relocating from [%x,%x) to [%x,%x)\n", - start, end, new_start, new_end ); - + DBGC ( ®ion, "Relocating from [%#08lx,%#08lx) to [%#08lx,%#08lx)\n", + start, end, new_start, new_end ); + /* Let prefix know what to copy */ ix86->regs.esi = start; ix86->regs.edi = new_start; diff --git a/src/arch/x86/core/runtime.c b/src/arch/x86/core/runtime.c index 02072b5bf..86083b1f9 100644 --- a/src/arch/x86/core/runtime.c +++ b/src/arch/x86/core/runtime.c @@ -32,6 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stddef.h> #include <stdint.h> #include <stdlib.h> +#include <string.h> #include <ctype.h> #include <errno.h> #include <assert.h> @@ -69,6 +70,7 @@ static void cmdline_image_free ( struct refcnt *refcnt ) { struct image *image = container_of ( refcnt, struct image, refcnt ); DBGC ( image, "RUNTIME freeing command line\n" ); + free_image ( refcnt ); free ( cmdline_copy ); } @@ -76,6 +78,7 @@ static void cmdline_image_free ( struct refcnt *refcnt ) { static struct image cmdline_image = { .refcnt = REF_INIT ( cmdline_image_free ), .name = "<CMDLINE>", + .flags = ( IMAGE_STATIC | IMAGE_STATIC_NAME ), .type = &script_image_type, }; @@ -114,9 +117,7 @@ static void cmdline_strip ( char *cmdline, const char *cruft ) { * @ret rc Return status code */ static int cmdline_init ( void ) { - userptr_t cmdline_user; char *cmdline; - size_t len; int rc; /* Do nothing if no command line was specified */ @@ -124,19 +125,15 @@ static int cmdline_init ( void ) { DBGC ( colour, "RUNTIME found no command line\n" ); return 0; } - cmdline_user = phys_to_user ( cmdline_phys ); - len = ( strlen_user ( cmdline_user, 0 ) + 1 /* NUL */ ); /* Allocate and copy command line */ - cmdline_copy = malloc ( len ); + cmdline_copy = strdup ( phys_to_virt ( cmdline_phys ) ); if ( ! cmdline_copy ) { - DBGC ( colour, "RUNTIME could not allocate %zd bytes for " - "command line\n", len ); + DBGC ( colour, "RUNTIME could not allocate command line\n" ); rc = -ENOMEM; goto err_alloc_cmdline_copy; } cmdline = cmdline_copy; - copy_from_user ( cmdline, cmdline_user, 0, len ); DBGC ( colour, "RUNTIME found command line \"%s\" at %08x\n", cmdline, cmdline_phys ); @@ -151,7 +148,7 @@ static int cmdline_init ( void ) { DBGC ( colour, "RUNTIME using command line \"%s\"\n", cmdline ); /* Prepare and register image */ - cmdline_image.data = virt_to_user ( cmdline ); + cmdline_image.data = cmdline; cmdline_image.len = strlen ( cmdline ); if ( cmdline_image.len ) { if ( ( rc = register_image ( &cmdline_image ) ) != 0 ) { @@ -193,7 +190,7 @@ static int initrd_init ( void ) { initrd_phys, ( initrd_phys + initrd_len ) ); /* Create initrd image */ - image = image_memory ( "<INITRD>", phys_to_user ( initrd_phys ), + image = image_memory ( "<INITRD>", phys_to_virt ( initrd_phys ), initrd_len ); if ( ! image ) { DBGC ( colour, "RUNTIME could not create initrd image\n" ); diff --git a/src/arch/x86/core/video_subr.c b/src/arch/x86/core/video_subr.c index f5cc4cdd4..4e9ef466f 100644 --- a/src/arch/x86/core/video_subr.c +++ b/src/arch/x86/core/video_subr.c @@ -109,5 +109,6 @@ struct console_driver vga_console __console_driver = { }; struct init_fn video_init_fn __init_fn ( INIT_EARLY ) = { + .name = "video", .initialise = video_init, }; diff --git a/src/arch/x86/core/vram_settings.c b/src/arch/x86/core/vram_settings.c index 9c169b40c..a97a463fe 100644 --- a/src/arch/x86/core/vram_settings.c +++ b/src/arch/x86/core/vram_settings.c @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include <string.h> #include <ipxe/uaccess.h> #include <ipxe/settings.h> @@ -47,12 +48,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @ret len Length of setting data, or negative error */ static int vram_fetch ( void *data, size_t len ) { - userptr_t vram = phys_to_user ( VRAM_BASE ); + const void *vram = phys_to_virt ( VRAM_BASE ); /* Copy video RAM */ if ( len > VRAM_LEN ) len = VRAM_LEN; - copy_from_user ( data, vram, 0, len ); + memcpy ( data, vram, len ); return VRAM_LEN; } diff --git a/src/arch/x86/core/x86_bigint.c b/src/arch/x86/core/x86_bigint.c deleted file mode 100644 index 74e5da9a2..000000000 --- a/src/arch/x86/core/x86_bigint.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <string.h> -#include <ipxe/bigint.h> - -/** @file - * - * Big integer support - */ - -/** - * Multiply big integers - * - * @v multiplicand0 Element 0 of big integer to be multiplied - * @v multiplicand_size Number of elements in multiplicand - * @v multiplier0 Element 0 of big integer to be multiplied - * @v multiplier_size Number of elements in multiplier - * @v result0 Element 0 of big integer to hold result - */ -void bigint_multiply_raw ( const uint32_t *multiplicand0, - unsigned int multiplicand_size, - const uint32_t *multiplier0, - unsigned int multiplier_size, - uint32_t *result0 ) { - unsigned int result_size = ( multiplicand_size + multiplier_size ); - const bigint_t ( multiplicand_size ) __attribute__ (( may_alias )) - *multiplicand = ( ( const void * ) multiplicand0 ); - const bigint_t ( multiplier_size ) __attribute__ (( may_alias )) - *multiplier = ( ( const void * ) multiplier0 ); - bigint_t ( result_size ) __attribute__ (( may_alias )) - *result = ( ( void * ) result0 ); - unsigned int i; - unsigned int j; - uint32_t multiplicand_element; - uint32_t multiplier_element; - uint32_t *result_elements; - uint32_t discard_a; - uint32_t discard_d; - long index; - - /* Zero result */ - memset ( result, 0, sizeof ( *result ) ); - - /* Multiply integers one element at a time */ - for ( i = 0 ; i < multiplicand_size ; i++ ) { - multiplicand_element = multiplicand->element[i]; - for ( j = 0 ; j < multiplier_size ; j++ ) { - multiplier_element = multiplier->element[j]; - result_elements = &result->element[ i + j ]; - /* Perform a single multiply, and add the - * resulting double-element into the result, - * carrying as necessary. The carry can - * never overflow beyond the end of the - * result, since: - * - * a < 2^{n}, b < 2^{m} => ab < 2^{n+m} - */ - __asm__ __volatile__ ( "mull %5\n\t" - "addl %%eax, (%6,%2,4)\n\t" - "adcl %%edx, 4(%6,%2,4)\n\t" - "\n1:\n\t" - "adcl $0, 8(%6,%2,4)\n\t" - "inc %2\n\t" - /* Does not affect CF */ - "jc 1b\n\t" - : "=&a" ( discard_a ), - "=&d" ( discard_d ), - "=&r" ( index ), - "+m" ( *result ) - : "0" ( multiplicand_element ), - "g" ( multiplier_element ), - "r" ( result_elements ), - "2" ( 0 ) ); - } - } -} diff --git a/src/arch/x86/core/x86_io.c b/src/arch/x86/core/x86_io.c index 6c6b6e1e7..270ed7bef 100644 --- a/src/arch/x86/core/x86_io.c +++ b/src/arch/x86/core/x86_io.c @@ -32,6 +32,69 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ +/** Threshold for port I/O-mapped addresses + * + * On x86, port I/O instructions (inb/outb/etc) can take only an 8-bit + * or 16-bit address (in %dx). All I/O ports must therefore have a + * value in the first 64kB of the address space. + * + * Virtual addresses below 64kB can never be MMIO addresses: + * + * - In the UEFI memory model and x86_64 BIOS memory model, virtual + * addresses below 64kB are identity-mapped to the corresponding + * physical address. Since the first 64kB of address space is + * always RAM, no MMIO device can exist within this region. + * + * - In the i386 BIOS memory model, virtual addresses below 64kB cover + * the iPXE binary itself (which starts at address zero). Since the + * size of .textdata can never realistically be below 64kB (not + * least since the heap alone is 512kB), and since iPXE is placed + * into RAM as a contiguous block, no MMIO device can exist within + * this region. + * + * We therefore know that any (virtual) address returned by ioremap() + * must be outside the first 64kB of the address space. We can + * therefore use this as a threshold to determine whether a given + * address is a port I/O address or an MMIO address. + */ +#define PIO_THRESHOLD 0x10000 + +/** + * Read from I/O-mapped or memory-mapped device + * + * @v io_addr I/O address + * @ret data Value read + */ +#define X86_IOREADX( _api_func, _suffix, _type ) \ +static _type x86_ ## _api_func ( volatile _type *io_addr ) { \ + if ( ( ( intptr_t ) io_addr ) < PIO_THRESHOLD ) { \ + return in ## _suffix ( io_addr ); \ + } else { \ + return read ## _suffix ( io_addr ); \ + } \ +} +X86_IOREADX ( ioread8, b, uint8_t ); +X86_IOREADX ( ioread16, w, uint16_t ); +X86_IOREADX ( ioread32, l, uint32_t ); + +/** + * Write to I/O-mapped or memory-mapped device + * + * @v data Value to write + * @v io_addr I/O address + */ +#define X86_IOWRITEX( _api_func, _suffix, _type ) \ +static void x86_ ## _api_func ( _type data, volatile _type *io_addr ) { \ + if ( ( ( intptr_t ) io_addr ) < PIO_THRESHOLD ) { \ + out ## _suffix ( data, io_addr ); \ + } else { \ + write ## _suffix ( data, io_addr ); \ + } \ +} +X86_IOWRITEX ( iowrite8, b, uint8_t ); +X86_IOWRITEX ( iowrite16, w, uint16_t ); +X86_IOWRITEX ( iowrite32, l, uint32_t ); + /** * Read 64-bit qword from memory-mapped device * @@ -101,3 +164,9 @@ PROVIDE_IOAPI_INLINE ( x86, writeq ); PROVIDE_IOAPI ( x86, readq, i386_readq ); PROVIDE_IOAPI ( x86, writeq, i386_writeq ); #endif +PROVIDE_IOAPI ( x86, ioread8, x86_ioread8 ); +PROVIDE_IOAPI ( x86, ioread16, x86_ioread16 ); +PROVIDE_IOAPI ( x86, ioread32, x86_ioread32 ); +PROVIDE_IOAPI ( x86, iowrite8, x86_iowrite8 ); +PROVIDE_IOAPI ( x86, iowrite16, x86_iowrite16 ); +PROVIDE_IOAPI ( x86, iowrite32, x86_iowrite32 ); diff --git a/src/arch/x86/core/x86_string.c b/src/arch/x86/core/x86_string.c index 1a1e79dac..923552f66 100644 --- a/src/arch/x86/core/x86_string.c +++ b/src/arch/x86/core/x86_string.c @@ -28,6 +28,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); #include <string.h> #include <config/defaults.h> diff --git a/src/arch/x86/core/x86_tcpip.c b/src/arch/x86/core/x86_tcpip.c index ed323d5d0..b3bfe2546 100644 --- a/src/arch/x86/core/x86_tcpip.c +++ b/src/arch/x86/core/x86_tcpip.c @@ -22,6 +22,7 @@ */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +FILE_SECBOOT ( PERMITTED ); /** @file * diff --git a/src/arch/x86/core/x86_uart.c b/src/arch/x86/core/x86_uart.c index e455775bf..03809ff9b 100644 --- a/src/arch/x86/core/x86_uart.c +++ b/src/arch/x86/core/x86_uart.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>. + * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -29,41 +29,47 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ -#include <errno.h> -#include <ipxe/uart.h> +#include <string.h> +#include <ipxe/serial.h> +#include <ipxe/ns16550.h> -/** UART port bases */ -static uint16_t uart_base[] = { - [COM1] = 0x3f8, - [COM2] = 0x2f8, - [COM3] = 0x3e8, - [COM4] = 0x2e8, -}; +/** Define a fixed ISA UART */ +#define ISA_UART( NAME, BASE ) \ + static struct ns16550_uart ns16550_ ## NAME = { \ + .base = ( ( void * ) (BASE) ), \ + .clock = NS16550_CLK_DEFAULT, \ + }; \ + struct uart NAME = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .op = &ns16550_operations, \ + .priv = &ns16550_ ## NAME, \ + } + +/* Fixed ISA UARTs */ +ISA_UART ( com1, COM1_BASE ); +ISA_UART ( com2, COM2_BASE ); +ISA_UART ( com3, COM3_BASE ); +ISA_UART ( com4, COM4_BASE ); /** - * Select UART port + * Register fixed ISA UARTs * - * @v uart UART - * @v port Port number, or 0 to disable * @ret rc Return status code */ -int uart_select ( struct uart *uart, unsigned int port ) { +int uart_register_fixed ( void ) { + static struct uart *ports[] = { COM1, COM2, COM3, COM4 }; + unsigned int i; int rc; - /* Set new UART base */ - if ( port >= ( sizeof ( uart_base ) / sizeof ( uart_base[0] ) ) ) { - rc = -ENODEV; - goto err; + /* Register all fixed ISA UARTs */ + for ( i = 0 ; i < ( sizeof ( ports ) / sizeof ( ports[0] ) ) ; i++ ) { + if ( ( rc = uart_register ( ports[i] ) ) != 0 ) { + DBGC ( ports[i], "UART could not register %s: %s\n", + ports[i]->name, strerror ( rc ) ); + return rc; + } } - uart->base = ( ( void * ) ( intptr_t ) uart_base[port] ); - - /* Check that UART exists */ - if ( ( rc = uart_exists ( uart ) ) != 0 ) - goto err; return 0; - - err: - uart->base = NULL; - return rc; } |
