diff options
| author | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2026-01-28 12:53:53 +0100 |
| commit | 8e82785c584dc13e20f9229decb95bd17bbe9cd1 (patch) | |
| tree | a8b359e59196be5b2e3862bed189107f4bc9975f /src/arch/x86/interface | |
| parent | Merge branch 'master' into openslx (diff) | |
| parent | [prefix] Make unlzma.S compatible with 386 class CPUs (diff) | |
| download | ipxe-openslx.tar.gz ipxe-openslx.tar.xz ipxe-openslx.zip | |
Merge branch 'master' into openslxopenslx
Diffstat (limited to 'src/arch/x86/interface')
29 files changed, 366 insertions, 834 deletions
diff --git a/src/arch/x86/interface/efi/efix86_nap.c b/src/arch/x86/interface/efi/efix86_nap.c deleted file mode 100644 index 296876b85..000000000 --- a/src/arch/x86/interface/efi/efix86_nap.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008 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 <ipxe/nap.h> -#include <ipxe/efi/efi.h> - -/** @file - * - * iPXE CPU sleeping API for EFI - * - */ - -/** - * Sleep until next interrupt - * - */ -static void efix86_cpu_nap ( void ) { - /* - * I can't find any EFI API that allows us to put the CPU to - * sleep. The CpuSleep() function is defined in CpuLib.h, but - * isn't part of any exposed protocol so we have no way to - * call it. - * - * The EFI shell doesn't seem to bother sleeping the CPU; it - * just sits there idly burning power. - * - * If a shutdown is in progess, there may be nothing to - * generate an interrupt since the timer is disabled in the - * first step of ExitBootServices(). - */ - if ( ! efi_shutdown_in_progress ) - __asm__ __volatile__ ( "hlt" ); -} - -PROVIDE_NAP ( efix86, cpu_nap, efix86_cpu_nap ); diff --git a/src/arch/x86/interface/pcbios/acpi_timer.c b/src/arch/x86/interface/pcbios/acpi_timer.c index 2e4047e38..e1523578b 100644 --- a/src/arch/x86/interface/pcbios/acpi_timer.c +++ b/src/arch/x86/interface/pcbios/acpi_timer.c @@ -102,20 +102,19 @@ static void acpi_udelay ( unsigned long usecs ) { * @ret rc Return status code */ static int acpi_timer_probe ( void ) { - struct acpi_fadt fadtab; - userptr_t fadt; + const struct acpi_fadt *fadt; unsigned int pm_tmr_blk; /* Locate FADT */ - fadt = acpi_table ( FADT_SIGNATURE, 0 ); + fadt = container_of ( acpi_table ( FADT_SIGNATURE, 0 ), + struct acpi_fadt, acpi ); if ( ! fadt ) { DBGC ( &acpi_timer, "ACPI could not find FADT\n" ); return -ENOENT; } /* Read FADT */ - copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) ); - pm_tmr_blk = le32_to_cpu ( fadtab.pm_tmr_blk ); + pm_tmr_blk = le32_to_cpu ( fadt->pm_tmr_blk ); if ( ! pm_tmr_blk ) { DBGC ( &acpi_timer, "ACPI has no timer\n" ); return -ENOENT; diff --git a/src/arch/x86/interface/pcbios/acpipwr.c b/src/arch/x86/interface/pcbios/acpipwr.c index f08b4af25..cb82ef1b4 100644 --- a/src/arch/x86/interface/pcbios/acpipwr.c +++ b/src/arch/x86/interface/pcbios/acpipwr.c @@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include <string.h> #include <unistd.h> #include <errno.h> #include <byteswap.h> @@ -62,8 +63,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * uglier hacks I have ever implemented, but it's still prettier than * the ACPI specification itself. */ -static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset, - void *data ) { +static int acpi_extract_sx ( const struct acpi_header *zsdt, size_t len, + size_t offset, void *data ) { unsigned int *sx = data; uint8_t bytes[4]; uint8_t *byte; @@ -77,7 +78,8 @@ static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset, } /* Read first four bytes of value */ - copy_from_user ( bytes, zsdt, offset, sizeof ( bytes ) ); + memcpy ( bytes, ( ( ( const void * ) zsdt ) + offset ), + sizeof ( bytes ) ); DBGC ( colour, "ACPI found \\_Sx containing %02x:%02x:%02x:%02x\n", bytes[0], bytes[1], bytes[2], bytes[3] ); @@ -111,8 +113,7 @@ static int acpi_extract_sx ( userptr_t zsdt, size_t len, size_t offset, * @ret rc Return status code */ int acpi_poweroff ( void ) { - struct acpi_fadt fadtab; - userptr_t fadt; + const struct acpi_fadt *fadt; unsigned int pm1a_cnt_blk; unsigned int pm1b_cnt_blk; unsigned int pm1a_cnt; @@ -123,16 +124,16 @@ int acpi_poweroff ( void ) { int rc; /* Locate FADT */ - fadt = acpi_table ( FADT_SIGNATURE, 0 ); + fadt = container_of ( acpi_table ( FADT_SIGNATURE, 0 ), + struct acpi_fadt, acpi ); if ( ! fadt ) { DBGC ( colour, "ACPI could not find FADT\n" ); return -ENOENT; } /* Read FADT */ - copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) ); - pm1a_cnt_blk = le32_to_cpu ( fadtab.pm1a_cnt_blk ); - pm1b_cnt_blk = le32_to_cpu ( fadtab.pm1b_cnt_blk ); + pm1a_cnt_blk = le32_to_cpu ( fadt->pm1a_cnt_blk ); + pm1b_cnt_blk = le32_to_cpu ( fadt->pm1b_cnt_blk ); pm1a_cnt = ( pm1a_cnt_blk + ACPI_PM1_CNT ); pm1b_cnt = ( pm1b_cnt_blk + ACPI_PM1_CNT ); diff --git a/src/arch/x86/interface/pcbios/basemem.c b/src/arch/x86/interface/pcbios/basemem.c index 6a46081aa..8f3a30e92 100644 --- a/src/arch/x86/interface/pcbios/basemem.c +++ b/src/arch/x86/interface/pcbios/basemem.c @@ -27,7 +27,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <realmode.h> #include <bios.h> #include <basemem.h> -#include <ipxe/hidemem.h> +#include <ipxe/memmap.h> /** @file * diff --git a/src/arch/x86/interface/pcbios/bios_cachedhcp.c b/src/arch/x86/interface/pcbios/bios_cachedhcp.c index bea803d6e..60191c9c5 100644 --- a/src/arch/x86/interface/pcbios/bios_cachedhcp.c +++ b/src/arch/x86/interface/pcbios/bios_cachedhcp.c @@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> +#include <string.h> #include <ipxe/init.h> #include <ipxe/cachedhcp.h> #include <realmode.h> @@ -60,7 +61,7 @@ static void cachedhcp_init ( void ) { /* Record cached DHCPACK */ if ( ( rc = cachedhcp_record ( &cached_dhcpack, 0, - phys_to_user ( cached_dhcpack_phys ), + phys_to_virt ( cached_dhcpack_phys ), sizeof ( BOOTPLAYER_t ) ) ) != 0 ) { DBGC ( colour, "CACHEDHCP could not record DHCPACK: %s\n", strerror ( rc ) ); @@ -73,5 +74,6 @@ static void cachedhcp_init ( void ) { /** Cached DHCPACK initialisation function */ struct init_fn cachedhcp_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "cachedhcp", .initialise = cachedhcp_init, }; diff --git a/src/arch/x86/interface/pcbios/bios_mp.c b/src/arch/x86/interface/pcbios/bios_mp.c index 9e1179ccd..4525a60cf 100644 --- a/src/arch/x86/interface/pcbios/bios_mp.c +++ b/src/arch/x86/interface/pcbios/bios_mp.c @@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ #include <registers.h> +#include <librm.h> #include <ipxe/uaccess.h> #include <ipxe/timer.h> #include <ipxe/msr.h> @@ -92,9 +93,9 @@ static void bios_mp_exec_boot ( mp_func_t func, void *opaque ) { "pushl %k1\n\t" "call *%k0\n\t" "addl $8, %%esp\n\t" ) - : : "r" ( mp_address ( mp_call ) ), - "r" ( mp_address ( func ) ), - "r" ( mp_address ( opaque ) ) ); + : : "R" ( mp_address ( mp_call ) ), + "R" ( mp_address ( func ) ), + "R" ( mp_address ( opaque ) ) ); } /** diff --git a/src/arch/x86/interface/pcbios/bios_reboot.c b/src/arch/x86/interface/pcbios/bios_reboot.c index 071173f19..c7f25405f 100644 --- a/src/arch/x86/interface/pcbios/bios_reboot.c +++ b/src/arch/x86/interface/pcbios/bios_reboot.c @@ -29,6 +29,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ +#include <string.h> #include <ipxe/reboot.h> #include <realmode.h> #include <bios.h> @@ -38,14 +39,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** * Reboot system * - * @v warm Perform a warm reboot + * @v flags Reboot flags */ -static void bios_reboot ( int warm ) { - uint16_t flag; +static void bios_reboot ( int flags ) { + uint16_t type; /* Configure BIOS for cold/warm reboot */ - flag = ( warm ? BDA_REBOOT_WARM : 0 ); - put_real ( flag, BDA_SEG, BDA_REBOOT ); + type = ( ( flags & REBOOT_WARM ) ? BDA_REBOOT_WARM : 0 ); + put_real ( type, BDA_SEG, BDA_REBOOT ); /* Jump to system reset vector */ __asm__ __volatile__ ( REAL_CODE ( "ljmp $0xf000, $0xfff0" ) : ); diff --git a/src/arch/x86/interface/pcbios/bios_smbios.c b/src/arch/x86/interface/pcbios/bios_smbios.c index 366679d36..aaec1eea1 100644 --- a/src/arch/x86/interface/pcbios/bios_smbios.c +++ b/src/arch/x86/interface/pcbios/bios_smbios.c @@ -45,19 +45,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @ret rc Return status code */ static int bios_find_smbios2 ( struct smbios *smbios ) { - struct smbios_entry entry; - int rc; + const struct smbios_entry *entry; /* Scan through BIOS segment to find SMBIOS 32-bit entry point */ - if ( ( rc = find_smbios_entry ( real_to_user ( BIOS_SEG, 0 ), 0x10000, - &entry ) ) != 0 ) - return rc; + entry = find_smbios_entry ( real_to_virt ( BIOS_SEG, 0 ), 0x10000 ); + if ( ! entry ) + return -ENOENT; /* Fill in entry point descriptor structure */ - smbios->address = phys_to_user ( entry.smbios_address ); - smbios->len = entry.smbios_len; - smbios->count = entry.smbios_count; - smbios->version = SMBIOS_VERSION ( entry.major, entry.minor ); + smbios->address = phys_to_virt ( entry->smbios_address ); + smbios->len = entry->smbios_len; + smbios->count = entry->smbios_count; + smbios->version = SMBIOS_VERSION ( entry->major, entry->minor ); return 0; } @@ -69,26 +68,25 @@ static int bios_find_smbios2 ( struct smbios *smbios ) { * @ret rc Return status code */ static int bios_find_smbios3 ( struct smbios *smbios ) { - struct smbios3_entry entry; - int rc; + const struct smbios3_entry *entry; /* Scan through BIOS segment to find SMBIOS 64-bit entry point */ - if ( ( rc = find_smbios3_entry ( real_to_user ( BIOS_SEG, 0 ), 0x10000, - &entry ) ) != 0 ) - return rc; + entry = find_smbios3_entry ( real_to_virt ( BIOS_SEG, 0 ), 0x10000 ); + if ( ! entry ) + return -ENOENT; /* Check that address is accessible */ - if ( entry.smbios_address > ~( ( physaddr_t ) 0 ) ) { + if ( entry->smbios_address > ~( ( physaddr_t ) 0 ) ) { DBG ( "SMBIOS3 at %08llx is inaccessible\n", - ( ( unsigned long long ) entry.smbios_address ) ); + ( ( unsigned long long ) entry->smbios_address ) ); return -ENOTSUP; } /* Fill in entry point descriptor structure */ - smbios->address = phys_to_user ( entry.smbios_address ); - smbios->len = entry.smbios_len; + smbios->address = phys_to_virt ( entry->smbios_address ); + smbios->len = entry->smbios_len; smbios->count = 0; - smbios->version = SMBIOS_VERSION ( entry.major, entry.minor ); + smbios->version = SMBIOS_VERSION ( entry->major, entry->minor ); return 0; } diff --git a/src/arch/x86/interface/pcbios/biosint.c b/src/arch/x86/interface/pcbios/biosint.c index 667e9ed81..f5e54ede8 100644 --- a/src/arch/x86/interface/pcbios/biosint.c +++ b/src/arch/x86/interface/pcbios/biosint.c @@ -1,3 +1,4 @@ +#include <string.h> #include <errno.h> #include <realmode.h> #include <biosint.h> diff --git a/src/arch/x86/interface/pcbios/e820mangler.S b/src/arch/x86/interface/pcbios/e820mangler.S index ef5dc2754..b9e891dff 100644 --- a/src/arch/x86/interface/pcbios/e820mangler.S +++ b/src/arch/x86/interface/pcbios/e820mangler.S @@ -564,6 +564,8 @@ int15_88: int15: /* See if we want to intercept this call */ pushfw + cmpb $0, %cs:int15_intercept_flag + je 3f cmpw $0xe820, %ax jne 1f cmpl $SMAP, %edx @@ -587,3 +589,9 @@ int15: int15_vector: .long 0 .size int15_vector, . - int15_vector + + .section ".text16.data", "aw", @progbits + .globl int15_intercept_flag +int15_intercept_flag: + .byte 1 + .size int15_intercept_flag, . - int15_intercept_flag diff --git a/src/arch/x86/interface/pcbios/hidemem.c b/src/arch/x86/interface/pcbios/hidemem.c index 1a3022c5d..2b85459b6 100644 --- a/src/arch/x86/interface/pcbios/hidemem.c +++ b/src/arch/x86/interface/pcbios/hidemem.c @@ -22,6 +22,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +#include <string.h> #include <assert.h> #include <realmode.h> #include <biosint.h> @@ -29,7 +30,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <fakee820.h> #include <ipxe/init.h> #include <ipxe/io.h> -#include <ipxe/hidemem.h> +#include <ipxe/uheap.h> +#include <ipxe/memmap.h> /** Set to true if you want to test a fake E820 map */ #define FAKE_E820 0 @@ -72,13 +74,17 @@ extern void int15(); extern struct segoff __text16 ( int15_vector ); #define int15_vector __use_text16 ( int15_vector ) +/** INT 15 interception flag */ +extern uint8_t __text16 ( int15_intercept_flag ); +#define int15_intercept_flag __use_text16 ( int15_intercept_flag ) + /* The linker defines these symbols for us */ extern char _textdata[]; extern char _etextdata[]; -extern char _text16_memsz[]; -#define _text16_memsz ( ( size_t ) _text16_memsz ) -extern char _data16_memsz[]; -#define _data16_memsz ( ( size_t ) _data16_memsz ) +extern size_t ABS_SYMBOL ( _text16_memsz ); +#define _text16_memsz ABS_VALUE ( _text16_memsz ) +extern size_t ABS_SYMBOL ( _data16_memsz ); +#define _data16_memsz ABS_VALUE ( _data16_memsz ) /** * Hide region of memory from system memory map @@ -113,21 +119,43 @@ void hide_basemem ( void ) { } /** - * Hide umalloc() region + * Hide .text and .data + * + */ +void hide_textdata ( void ) { + hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), + virt_to_phys ( _etextdata ) ); +} + +/** + * Synchronise in-use regions with the externally visible system memory map * */ -void hide_umalloc ( physaddr_t start, physaddr_t end ) { - assert ( end <= virt_to_phys ( _textdata ) ); +static void int15_sync ( void ) { + physaddr_t start; + physaddr_t end; + + /* Besides our fixed base memory and textdata regions, we + * support hiding only a single in-use memory region (the + * umalloc region), which must be placed before the hidden + * textdata region (even if zero-length). + */ + start = uheap_start; + end = uheap_end; + if ( start == end ) + start = end = virt_to_phys ( _textdata ); hide_region ( &hidemem_umalloc, start, end ); } /** - * Hide .text and .data + * Set INT 15 interception flag * + * @v intercept Intercept INT 15 calls to modify memory map */ -void hide_textdata ( void ) { - hide_region ( &hidemem_textdata, virt_to_phys ( _textdata ), - virt_to_phys ( _etextdata ) ); +void int15_intercept ( int intercept ) { + + /* Set flag for INT 15 handler */ + int15_intercept_flag = intercept; } /** @@ -137,26 +165,25 @@ void hide_textdata ( void ) { * returned by the BIOS. */ static void hide_etherboot ( void ) { - struct memory_map memmap; unsigned int rm_ds_top; unsigned int rm_cs_top; unsigned int fbms; /* Dump memory map before mangling */ DBG ( "Hiding iPXE from system memory map\n" ); - get_memmap ( &memmap ); + memmap_dump_all ( 1 ); /* Hook in fake E820 map, if we're testing one */ if ( FAKE_E820 ) { DBG ( "Hooking in fake E820 map\n" ); fake_e820(); - get_memmap ( &memmap ); + memmap_dump_all ( 1 ); } /* Initialise the hidden regions */ hide_basemem(); - hide_umalloc ( virt_to_phys ( _textdata ), virt_to_phys ( _textdata ) ); hide_textdata(); + int15_sync(); /* Some really moronic BIOSes bring up the PXE stack via the * UNDI loader entry point and then don't bother to unload it @@ -183,7 +210,7 @@ static void hide_etherboot ( void ) { /* Dump memory map after mangling */ DBG ( "Hidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); + memmap_dump_all ( 1 ); } /** @@ -193,7 +220,6 @@ static void hide_etherboot ( void ) { * possible. */ static void unhide_etherboot ( int flags __unused ) { - struct memory_map memmap; int rc; /* If we have more than one hooked interrupt at this point, it @@ -224,7 +250,7 @@ static void unhide_etherboot ( int flags __unused ) { /* Dump memory map after unhiding */ DBG ( "Unhidden iPXE from system memory map\n" ); - get_memmap ( &memmap ); + memmap_dump_all ( 1 ); } /** Hide Etherboot startup function */ @@ -233,3 +259,5 @@ struct startup_fn hide_etherboot_startup_fn __startup_fn ( STARTUP_EARLY ) = { .startup = hide_etherboot, .shutdown = unhide_etherboot, }; + +PROVIDE_MEMMAP ( int15, memmap_sync, int15_sync ); diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c index 372d40ba3..3fb25d261 100644 --- a/src/arch/x86/interface/pcbios/int13.c +++ b/src/arch/x86/interface/pcbios/int13.c @@ -25,17 +25,18 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <stdlib.h> +#include <string.h> #include <limits.h> #include <byteswap.h> #include <errno.h> #include <assert.h> #include <ipxe/blockdev.h> -#include <ipxe/io.h> #include <ipxe/acpi.h> #include <ipxe/sanboot.h> #include <ipxe/device.h> #include <ipxe/pci.h> #include <ipxe/eltorito.h> +#include <ipxe/memmap.h> #include <realmode.h> #include <bios.h> #include <biosint.h> @@ -181,8 +182,7 @@ static int int13_parse_eltorito ( struct san_device *sandev, void *scratch ) { int rc; /* Read boot record volume descriptor */ - if ( ( rc = sandev_read ( sandev, ELTORITO_LBA, 1, - virt_to_user ( boot ) ) ) != 0 ) { + if ( ( rc = sandev_read ( sandev, ELTORITO_LBA, 1, boot ) ) != 0 ) { DBGC ( sandev->drive, "INT13 drive %02x could not read El " "Torito boot record volume descriptor: %s\n", sandev->drive, strerror ( rc ) ); @@ -228,7 +228,7 @@ static int int13_guess_geometry_hdd ( struct san_device *sandev, void *scratch, int rc; /* Read partition table */ - if ( ( rc = sandev_read ( sandev, 0, 1, virt_to_user ( mbr ) ) ) != 0 ) { + if ( ( rc = sandev_read ( sandev, 0, 1, mbr ) ) != 0 ) { DBGC ( sandev->drive, "INT13 drive %02x could not read " "partition table to guess geometry: %s\n", sandev->drive, strerror ( rc ) ); @@ -517,12 +517,12 @@ static int int13_rw_sectors ( struct san_device *sandev, int ( * sandev_rw ) ( struct san_device *sandev, uint64_t lba, unsigned int count, - userptr_t buffer ) ) { + void *buffer ) ) { struct int13_data *int13 = sandev->priv; unsigned int cylinder, head, sector; unsigned long lba; unsigned int count; - userptr_t buffer; + void *buffer; int rc; /* Validate blocksize */ @@ -549,7 +549,7 @@ static int int13_rw_sectors ( struct san_device *sandev, lba = ( ( ( ( cylinder * int13->heads ) + head ) * int13->sectors_per_track ) + sector - 1 ); count = ix86->regs.al; - buffer = real_to_user ( ix86->segs.es, ix86->regs.bx ); + buffer = real_to_virt ( ix86->segs.es, ix86->regs.bx ); DBGC2 ( sandev->drive, "C/H/S %d/%d/%d = LBA %08lx <-> %04x:%04x " "(count %d)\n", cylinder, head, sector, lba, ix86->segs.es, @@ -710,12 +710,12 @@ static int int13_extended_rw ( struct san_device *sandev, int ( * sandev_rw ) ( struct san_device *sandev, uint64_t lba, unsigned int count, - userptr_t buffer ) ) { + void *buffer ) ) { struct int13_disk_address addr; uint8_t bufsize; uint64_t lba; unsigned long count; - userptr_t buffer; + void *buffer; int rc; /* Extended reads are not allowed on floppy drives. @@ -743,11 +743,11 @@ static int int13_extended_rw ( struct san_device *sandev, if ( ( addr.count == 0xff ) || ( ( addr.buffer.segment == 0xffff ) && ( addr.buffer.offset == 0xffff ) ) ) { - buffer = phys_to_user ( addr.buffer_phys ); + buffer = phys_to_virt ( addr.buffer_phys ); DBGC2 ( sandev->drive, "%08llx", ( ( unsigned long long ) addr.buffer_phys ) ); } else { - buffer = real_to_user ( addr.buffer.segment, + buffer = real_to_virt ( addr.buffer.segment, addr.buffer.offset ); DBGC2 ( sandev->drive, "%04x:%04x", addr.buffer.segment, addr.buffer.offset ); @@ -1058,7 +1058,7 @@ static int int13_cdrom_read_boot_catalog ( struct san_device *sandev, /* Read from boot catalog */ if ( ( rc = sandev_read ( sandev, start, command.count, - phys_to_user ( command.buffer ) ) ) != 0 ) { + phys_to_virt ( command.buffer ) ) ) != 0 ) { DBGC ( sandev->drive, "INT13 drive %02x could not read boot " "catalog: %s\n", sandev->drive, strerror ( rc ) ); return -INT13_STATUS_READ_ERROR; @@ -1455,8 +1455,8 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) { "catalog (status %04x)\n", drive, status ); return -EIO; } - copy_from_user ( &catalog, phys_to_user ( eltorito_cmd.buffer ), 0, - sizeof ( catalog ) ); + memcpy ( &catalog, phys_to_virt ( eltorito_cmd.buffer ), + sizeof ( catalog ) ); /* Sanity checks */ if ( catalog.valid.platform_id != ELTORITO_PLATFORM_X86 ) { @@ -1523,7 +1523,6 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) { */ static int int13_boot ( unsigned int drive, struct san_boot_config *config __unused ) { - struct memory_map memmap; struct segoff address; int rc; @@ -1537,7 +1536,7 @@ static int int13_boot ( unsigned int drive, * many problems that turn out to be memory-map related that * it's worth doing. */ - get_memmap ( &memmap ); + memmap_dump_all ( 1 ); /* Jump to boot sector */ if ( ( rc = call_bootsector ( address.segment, address.offset, diff --git a/src/arch/x86/interface/pcbios/int13con.c b/src/arch/x86/interface/pcbios/int13con.c index 8106cd153..925228874 100644 --- a/src/arch/x86/interface/pcbios/int13con.c +++ b/src/arch/x86/interface/pcbios/int13con.c @@ -288,6 +288,7 @@ static void int13con_init ( void ) { * INT13 console initialisation function */ struct init_fn int13con_init_fn __init_fn ( INIT_CONSOLE ) = { + .name = "int13con", .initialise = int13con_init, }; diff --git a/src/arch/x86/interface/pcbios/memmap.c b/src/arch/x86/interface/pcbios/int15.c index daae382b8..73bdbbe4a 100644 --- a/src/arch/x86/interface/pcbios/memmap.c +++ b/src/arch/x86/interface/pcbios/int15.c @@ -24,11 +24,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> +#include <string.h> #include <errno.h> +#include <assert.h> #include <realmode.h> #include <bios.h> #include <memsizes.h> #include <ipxe/io.h> +#include <ipxe/memmap.h> /** * @file @@ -151,7 +154,7 @@ static unsigned int extmemsize_88 ( void ) { * @ret extmem Extended memory size, in kB * * Note that this is only an approximation; for an accurate picture, - * use the E820 memory map obtained via get_memmap(); + * use the E820 memory map obtained via memmap_describe(); */ unsigned int extmemsize ( void ) { unsigned int extmem_e801; @@ -166,12 +169,13 @@ unsigned int extmemsize ( void ) { /** * Get e820 memory map * - * @v memmap Memory map to fill in + * @v region Memory region of interest to be updated * @ret rc Return status code */ -static int meme820 ( struct memory_map *memmap ) { - struct memory_region *region = memmap->regions; - struct memory_region *prev_region = NULL; +static int meme820 ( struct memmap_region *region ) { + unsigned int count = 0; + uint64_t start = 0; + uint64_t len = 0; uint32_t next = 0; uint32_t smap; uint32_t size; @@ -225,13 +229,6 @@ static int meme820 ( struct memory_map *memmap ) { break; } - /* If first region is not RAM, assume map is invalid */ - if ( ( memmap->count == 0 ) && - ( e820buf.type != E820_TYPE_RAM ) ) { - DBG ( "INT 15,e820 failed, first entry not RAM\n" ); - return -EINVAL; - } - DBG ( "INT 15,e820 region [%llx,%llx) type %d", e820buf.start, ( e820buf.start + e820buf.len ), ( int ) e820buf.type ); @@ -258,27 +255,36 @@ static int meme820 ( struct memory_map *memmap ) { continue; } - region->start = e820buf.start; - region->end = e820buf.start + e820buf.len; - /* Check for adjacent regions and merge them */ - if ( prev_region && ( region->start == prev_region->end ) ) { - prev_region->end = region->end; + if ( e820buf.start == ( start + len ) ) { + len += e820buf.len; } else { - prev_region = region; - region++; - memmap->count++; + start = e820buf.start; + len = e820buf.len; } - if ( memmap->count >= ( sizeof ( memmap->regions ) / - sizeof ( memmap->regions[0] ) ) ) { - DBG ( "INT 15,e820 too many regions returned\n" ); - /* Not a fatal error; what we've got so far at - * least represents valid regions of memory, - * even if we couldn't get them all. - */ - break; + /* Sanity check: first region (base memory) should + * start at address zero. + */ + if ( ( count == 0 ) && ( start != 0 ) ) { + DBG ( "INT 15,e820 region 0 starts at %llx (expected " + "0); assuming insane\n", start ); + return -EINVAL; + } + + /* Sanity check: second region (extended memory) + * should start at address 0x100000. + */ + if ( ( count == 1 ) && ( start != 0x100000 ) ) { + DBG ( "INT 15,e820 region 1 starts at %llx (expected " + "100000); assuming insane\n", start ); + return -EINVAL; } + + /* Update region of interest */ + memmap_update ( region, start, len, MEMMAP_FL_MEMORY, "e820" ); + count++; + } while ( next != 0 ); /* Sanity checks. Some BIOSes report complete garbage via INT @@ -287,19 +293,9 @@ static int meme820 ( struct memory_map *memmap ) { * region (starting at 0) and at least one high memory region * (starting at 0x100000). */ - if ( memmap->count < 2 ) { + if ( count < 2 ) { DBG ( "INT 15,e820 returned only %d regions; assuming " - "insane\n", memmap->count ); - return -EINVAL; - } - if ( memmap->regions[0].start != 0 ) { - DBG ( "INT 15,e820 region 0 starts at %llx (expected 0); " - "assuming insane\n", memmap->regions[0].start ); - return -EINVAL; - } - if ( memmap->regions[1].start != 0x100000 ) { - DBG ( "INT 15,e820 region 1 starts at %llx (expected 100000); " - "assuming insane\n", memmap->regions[0].start ); + "insane\n", count ); return -EINVAL; } @@ -307,37 +303,52 @@ static int meme820 ( struct memory_map *memmap ) { } /** - * Get memory map + * Describe memory region from system memory map * - * @v memmap Memory map to fill in + * @v min Minimum address + * @v hide Hide in-use regions from the memory map + * @v region Region descriptor to fill in */ -void x86_get_memmap ( struct memory_map *memmap ) { - unsigned int basemem, extmem; +static void int15_describe ( uint64_t min, int hide, + struct memmap_region *region ) { + unsigned int basemem; + unsigned int extmem; + uint64_t inaccessible; int rc; - DBG ( "Fetching system memory map\n" ); + /* Initialise region */ + memmap_init ( min, region ); - /* Clear memory map */ - memset ( memmap, 0, sizeof ( *memmap ) ); + /* Mark addresses above 4GB as inaccessible: we have no way to + * access them either in a 32-bit build or in a 64-bit build + * (since the 64-bit build identity-maps only the 32-bit + * address space). + */ + inaccessible = ( 1ULL << 32 ); + memmap_update ( region, inaccessible, -inaccessible, + MEMMAP_FL_INACCESSIBLE, NULL ); - /* Get base and extended memory sizes */ - basemem = basememsize(); - DBG ( "FBMS base memory size %d kB [0,%x)\n", - basemem, ( basemem * 1024 ) ); - extmem = extmemsize(); - - /* Try INT 15,e820 first */ - if ( ( rc = meme820 ( memmap ) ) == 0 ) { + /* Enable/disable INT 15 interception as applicable */ + int15_intercept ( hide ); + + /* Try INT 15,e820 first, falling back to constructing a map + * from basemem and extmem sizes + */ + if ( ( rc = meme820 ( region ) ) == 0 ) { DBG ( "Obtained system memory map via INT 15,e820\n" ); - return; + } else { + basemem = basememsize(); + DBG ( "FBMS base memory size %d kB [0,%x)\n", + basemem, ( basemem * 1024 ) ); + extmem = extmemsize(); + memmap_update ( region, 0, ( basemem * 1024 ), + MEMMAP_FL_MEMORY, "basemem" ); + memmap_update ( region, 0x100000, ( extmem * 1024 ), + MEMMAP_FL_MEMORY, "extmem" ); } - /* Fall back to constructing a map from basemem and extmem sizes */ - DBG ( "INT 15,e820 failed; constructing map\n" ); - memmap->regions[0].end = ( basemem * 1024 ); - memmap->regions[1].start = 0x100000; - memmap->regions[1].end = 0x100000 + ( extmem * 1024 ); - memmap->count = 2; + /* Restore INT 15 interception */ + int15_intercept ( 1 ); } -PROVIDE_IOAPI ( x86, get_memmap, x86_get_memmap ); +PROVIDE_MEMMAP ( int15, memmap_describe, int15_describe ); diff --git a/src/arch/x86/interface/pcbios/memtop_umalloc.c b/src/arch/x86/interface/pcbios/memtop_umalloc.c deleted file mode 100644 index 1d3f40a1c..000000000 --- a/src/arch/x86/interface/pcbios/memtop_umalloc.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2007 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -/** - * @file - * - * External memory allocation - * - */ - -#include <limits.h> -#include <errno.h> -#include <ipxe/uaccess.h> -#include <ipxe/hidemem.h> -#include <ipxe/io.h> -#include <ipxe/memblock.h> -#include <ipxe/umalloc.h> - -/** Maximum usable address for external allocated memory */ -#define EM_MAX_ADDRESS 0xffffffffUL - -/** Alignment of external allocated memory */ -#define EM_ALIGN ( 4 * 1024 ) - -/** Equivalent of NOWHERE for user pointers */ -#define UNOWHERE ( ~UNULL ) - -/** An external memory block */ -struct external_memory { - /** Size of this memory block (excluding this header) */ - size_t size; - /** Block is currently in use */ - int used; -}; - -/** Top of heap */ -static userptr_t top = UNULL; - -/** Bottom of heap (current lowest allocated block) */ -static userptr_t bottom = UNULL; - -/** Remaining space on heap */ -static size_t heap_size; - -/** - * Find largest usable memory region - * - * @ret start Start of region - * @ret len Length of region - */ -size_t largest_memblock ( userptr_t *start ) { - struct memory_map memmap; - struct memory_region *region; - physaddr_t max = EM_MAX_ADDRESS; - physaddr_t region_start; - physaddr_t region_end; - size_t region_len; - unsigned int i; - size_t len = 0; - - /* Avoid returning uninitialised data on error */ - *start = UNULL; - - /* Scan through all memory regions */ - get_memmap ( &memmap ); - for ( i = 0 ; i < memmap.count ; i++ ) { - region = &memmap.regions[i]; - DBG ( "Considering [%llx,%llx)\n", region->start, region->end ); - - /* Truncate block to maximum physical address */ - if ( region->start > max ) { - DBG ( "...starts after maximum address %lx\n", max ); - continue; - } - region_start = region->start; - if ( region->end > max ) { - DBG ( "...end truncated to maximum address %lx\n", max); - region_end = 0; /* =max, given the wraparound */ - } else { - region_end = region->end; - } - region_len = ( region_end - region_start ); - - /* Use largest block */ - if ( region_len > len ) { - DBG ( "...new best block found\n" ); - *start = phys_to_user ( region_start ); - len = region_len; - } - } - - return len; -} - -/** - * Initialise external heap - * - */ -static void init_eheap ( void ) { - userptr_t base; - - heap_size = largest_memblock ( &base ); - bottom = top = userptr_add ( base, heap_size ); - DBG ( "External heap grows downwards from %lx (size %zx)\n", - user_to_phys ( top, 0 ), heap_size ); -} - -/** - * Collect free blocks - * - */ -static void ecollect_free ( void ) { - struct external_memory extmem; - size_t len; - - /* Walk the free list and collect empty blocks */ - while ( bottom != top ) { - copy_from_user ( &extmem, bottom, -sizeof ( extmem ), - sizeof ( extmem ) ); - if ( extmem.used ) - break; - DBG ( "EXTMEM freeing [%lx,%lx)\n", user_to_phys ( bottom, 0 ), - user_to_phys ( bottom, extmem.size ) ); - len = ( extmem.size + sizeof ( extmem ) ); - bottom = userptr_add ( bottom, len ); - heap_size += len; - } -} - -/** - * Reallocate external memory - * - * @v old_ptr Memory previously allocated by umalloc(), or UNULL - * @v new_size Requested size - * @ret new_ptr Allocated memory, or UNULL - * - * Calling realloc() with a new size of zero is a valid way to free a - * memory block. - */ -static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { - struct external_memory extmem; - userptr_t new = ptr; - size_t align; - - /* (Re)initialise external memory allocator if necessary */ - if ( bottom == top ) - init_eheap(); - - /* Get block properties into extmem */ - if ( ptr && ( ptr != UNOWHERE ) ) { - /* Determine old size */ - copy_from_user ( &extmem, ptr, -sizeof ( extmem ), - sizeof ( extmem ) ); - } else { - /* Create a zero-length block */ - if ( heap_size < sizeof ( extmem ) ) { - DBG ( "EXTMEM out of space\n" ); - return UNULL; - } - ptr = bottom = userptr_add ( bottom, -sizeof ( extmem ) ); - heap_size -= sizeof ( extmem ); - DBG ( "EXTMEM allocating [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), user_to_phys ( ptr, 0 ) ); - extmem.size = 0; - } - extmem.used = ( new_size > 0 ); - - /* Expand/shrink block if possible */ - if ( ptr == bottom ) { - /* Update block */ - new = userptr_add ( ptr, - ( new_size - extmem.size ) ); - align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) ); - new_size += align; - new = userptr_add ( new, -align ); - if ( new_size > ( heap_size + extmem.size ) ) { - DBG ( "EXTMEM out of space\n" ); - return UNULL; - } - DBG ( "EXTMEM expanding [%lx,%lx) to [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), - user_to_phys ( ptr, extmem.size ), - user_to_phys ( new, 0 ), - user_to_phys ( new, new_size )); - memmove_user ( new, 0, ptr, 0, ( ( extmem.size < new_size ) ? - extmem.size : new_size ) ); - bottom = new; - heap_size -= ( new_size - extmem.size ); - extmem.size = new_size; - } else { - /* Cannot expand; can only pretend to shrink */ - if ( new_size > extmem.size ) { - /* Refuse to expand */ - DBG ( "EXTMEM cannot expand [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), - user_to_phys ( ptr, extmem.size ) ); - return UNULL; - } - } - - /* Write back block properties */ - copy_to_user ( new, -sizeof ( extmem ), &extmem, - sizeof ( extmem ) ); - - /* Collect any free blocks and update hidden memory region */ - ecollect_free(); - hide_umalloc ( user_to_phys ( bottom, ( ( bottom == top ) ? - 0 : -sizeof ( extmem ) ) ), - user_to_phys ( top, 0 ) ); - - return ( new_size ? new : UNOWHERE ); -} - -PROVIDE_UMALLOC ( memtop, urealloc, memtop_urealloc ); diff --git a/src/arch/x86/interface/pcbios/pcibios.c b/src/arch/x86/interface/pcbios/pcibios.c index 7b7a769e3..6b88ee907 100644 --- a/src/arch/x86/interface/pcbios/pcibios.c +++ b/src/arch/x86/interface/pcbios/pcibios.c @@ -120,6 +120,7 @@ int pcibios_write ( struct pci_device *pci, uint32_t command, uint32_t value ){ return ( status >> 8 ); } +PROVIDE_PCIAPI_INLINE ( pcbios, pci_can_probe ); PROVIDE_PCIAPI ( pcbios, pci_discover, pcibios_discover ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_byte ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_read_config_word ); @@ -128,5 +129,4 @@ PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_byte ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_word ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_write_config_dword ); PROVIDE_PCIAPI_INLINE ( pcbios, pci_ioremap ); - -struct pci_api pcibios_api = PCIAPI_RUNTIME ( pcbios ); +PROVIDE_PCIAPI_RUNTIME ( pcbios, PCIAPI_PRIORITY_PCBIOS ); diff --git a/src/arch/x86/interface/pcbios/pcicloud.c b/src/arch/x86/interface/pcbios/pcicloud.c deleted file mode 100644 index 98ba38b31..000000000 --- a/src/arch/x86/interface/pcbios/pcicloud.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - * - * You can also choose to distribute this program under the terms of - * the Unmodified Binary Distribution Licence (as given in the file - * COPYING.UBDL), provided that you have satisfied its requirements. - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include <stdint.h> -#include <ipxe/init.h> -#include <ipxe/pci.h> -#include <ipxe/ecam.h> -#include <ipxe/pcibios.h> -#include <ipxe/pcidirect.h> -#include <ipxe/pcicloud.h> - -/** @file - * - * Cloud VM PCI configuration space access - * - */ - -/** Selected PCI configuration space access API */ -static struct pci_api *pcicloud = &ecam_api; - -/** - * Find next PCI bus:dev.fn address range in system - * - * @v busdevfn Starting PCI bus:dev.fn address - * @v range PCI bus:dev.fn address range to fill in - */ -static void pcicloud_discover ( uint32_t busdevfn, struct pci_range *range ) { - - pcicloud->pci_discover ( busdevfn, range ); -} - -/** - * Read byte from PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value read - * @ret rc Return status code - */ -static int pcicloud_read_config_byte ( struct pci_device *pci, - unsigned int where, uint8_t *value ) { - - return pcicloud->pci_read_config_byte ( pci, where, value ); -} - -/** - * Read 16-bit word from PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value read - * @ret rc Return status code - */ -static int pcicloud_read_config_word ( struct pci_device *pci, - unsigned int where, uint16_t *value ) { - - return pcicloud->pci_read_config_word ( pci, where, value ); -} - -/** - * Read 32-bit dword from PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value read - * @ret rc Return status code - */ -static int pcicloud_read_config_dword ( struct pci_device *pci, - unsigned int where, uint32_t *value ) { - - return pcicloud->pci_read_config_dword ( pci, where, value ); -} - -/** - * Write byte to PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value to be written - * @ret rc Return status code - */ -static int pcicloud_write_config_byte ( struct pci_device *pci, - unsigned int where, uint8_t value ) { - - return pcicloud->pci_write_config_byte ( pci, where, value ); -} - -/** - * Write 16-bit word to PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value to be written - * @ret rc Return status code - */ -static int pcicloud_write_config_word ( struct pci_device *pci, - unsigned int where, uint16_t value ) { - - return pcicloud->pci_write_config_word ( pci, where, value ); -} - -/** - * Write 32-bit dword to PCI configuration space - * - * @v pci PCI device - * @v where Location within PCI configuration space - * @v value Value to be written - * @ret rc Return status code - */ -static int pcicloud_write_config_dword ( struct pci_device *pci, - unsigned int where, uint32_t value ) { - - return pcicloud->pci_write_config_dword ( pci, where, value ); -} - -/** - * Map PCI bus address as an I/O address - * - * @v bus_addr PCI bus address - * @v len Length of region - * @ret io_addr I/O address, or NULL on error - */ -static void * pcicloud_ioremap ( struct pci_device *pci, - unsigned long bus_addr, size_t len ) { - - return pcicloud->pci_ioremap ( pci, bus_addr, len ); -} - -PROVIDE_PCIAPI ( cloud, pci_discover, pcicloud_discover ); -PROVIDE_PCIAPI ( cloud, pci_read_config_byte, pcicloud_read_config_byte ); -PROVIDE_PCIAPI ( cloud, pci_read_config_word, pcicloud_read_config_word ); -PROVIDE_PCIAPI ( cloud, pci_read_config_dword, pcicloud_read_config_dword ); -PROVIDE_PCIAPI ( cloud, pci_write_config_byte, pcicloud_write_config_byte ); -PROVIDE_PCIAPI ( cloud, pci_write_config_word, pcicloud_write_config_word ); -PROVIDE_PCIAPI ( cloud, pci_write_config_dword, pcicloud_write_config_dword ); -PROVIDE_PCIAPI ( cloud, pci_ioremap, pcicloud_ioremap ); - -/** - * Initialise cloud VM PCI configuration space access - * - */ -static void pcicloud_init ( void ) { - static struct pci_api *apis[] = { - &ecam_api, &pcibios_api, &pcidirect_api - }; - struct pci_device pci; - uint32_t busdevfn; - unsigned int i; - int rc; - - /* Select first API that successfully discovers a PCI device */ - for ( i = 0 ; i < ( sizeof ( apis ) / sizeof ( apis[0] ) ) ; i++ ) { - pcicloud = apis[i]; - busdevfn = 0; - if ( ( rc = pci_find_next ( &pci, &busdevfn ) ) == 0 ) { - DBGC ( pcicloud, "PCICLOUD selected %s API (found " - PCI_FMT ")\n", pcicloud->name, - PCI_ARGS ( &pci ) ); - return; - } - } - - /* Fall back to using final attempted API if no devices found */ - pcicloud = apis[ i - 1 ]; - DBGC ( pcicloud, "PCICLOUD selected %s API (nothing detected)\n", - pcicloud->name ); -} - -/** Cloud VM PCI configuration space access initialisation function */ -struct init_fn pcicloud_init_fn __init_fn ( INIT_EARLY ) = { - .initialise = pcicloud_init, -}; diff --git a/src/arch/x86/interface/pcbios/rsdp.c b/src/arch/x86/interface/pcbios/rsdp.c index 3c67b7525..6913be552 100644 --- a/src/arch/x86/interface/pcbios/rsdp.c +++ b/src/arch/x86/interface/pcbios/rsdp.c @@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ #include <stdint.h> +#include <string.h> #include <realmode.h> #include <bios.h> #include <ipxe/acpi.h> @@ -53,50 +54,51 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * * @v start Start address to search * @v len Length to search - * @ret rsdt ACPI root system description table, or UNULL + * @ret rsdt ACPI root system description table, or NULL */ -static userptr_t rsdp_find_rsdt_range ( userptr_t start, size_t len ) { +static const struct acpi_rsdt * rsdp_find_rsdt_range ( const void *start, + size_t len ) { static const char signature[8] = RSDP_SIGNATURE; - struct acpi_rsdp rsdp; - userptr_t rsdt; + const struct acpi_rsdp *rsdp; + const struct acpi_rsdt *rsdt; size_t offset; uint8_t sum; unsigned int i; /* Search for RSDP */ - for ( offset = 0 ; ( ( offset + sizeof ( rsdp ) ) < len ) ; + for ( offset = 0 ; ( ( offset + sizeof ( *rsdp ) ) < len ) ; offset += RSDP_STRIDE ) { /* Check signature and checksum */ - copy_from_user ( &rsdp, start, offset, sizeof ( rsdp ) ); - if ( memcmp ( rsdp.signature, signature, + rsdp = ( start + offset ); + if ( memcmp ( rsdp->signature, signature, sizeof ( signature ) ) != 0 ) continue; - for ( sum = 0, i = 0 ; i < sizeof ( rsdp ) ; i++ ) - sum += *( ( ( uint8_t * ) &rsdp ) + i ); + for ( sum = 0, i = 0 ; i < sizeof ( *rsdp ) ; i++ ) + sum += *( ( ( uint8_t * ) rsdp ) + i ); if ( sum != 0 ) continue; /* Extract RSDT */ - rsdt = phys_to_user ( le32_to_cpu ( rsdp.rsdt ) ); + rsdt = phys_to_virt ( le32_to_cpu ( rsdp->rsdt ) ); DBGC ( rsdt, "RSDT %#08lx found via RSDP %#08lx\n", - user_to_phys ( rsdt, 0 ), - user_to_phys ( start, offset ) ); + virt_to_phys ( rsdt ), + ( virt_to_phys ( start ) + offset ) ); return rsdt; } - return UNULL; + return NULL; } /** * Locate ACPI root system description table * - * @ret rsdt ACPI root system description table, or UNULL + * @ret rsdt ACPI root system description table, or NULL */ -static userptr_t rsdp_find_rsdt ( void ) { - static userptr_t rsdt; +static const struct acpi_rsdt * rsdp_find_rsdt ( void ) { + static const struct acpi_rsdt *rsdt; + const void *ebda; uint16_t ebda_seg; - userptr_t ebda; size_t ebda_len; /* Return existing RSDT if already found */ @@ -106,7 +108,7 @@ static userptr_t rsdp_find_rsdt ( void ) { /* Search EBDA */ get_real ( ebda_seg, BDA_SEG, BDA_EBDA ); if ( ebda_seg < RSDP_EBDA_END_SEG ) { - ebda = real_to_user ( ebda_seg, 0 ); + ebda = real_to_virt ( ebda_seg, 0 ); ebda_len = ( ( RSDP_EBDA_END_SEG - ebda_seg ) * 16 ); rsdt = rsdp_find_rsdt_range ( ebda, ebda_len ); if ( rsdt ) @@ -114,12 +116,12 @@ static userptr_t rsdp_find_rsdt ( void ) { } /* Search fixed BIOS area */ - rsdt = rsdp_find_rsdt_range ( phys_to_user ( RSDP_BIOS_START ), + rsdt = rsdp_find_rsdt_range ( phys_to_virt ( RSDP_BIOS_START ), RSDP_BIOS_LEN ); if ( rsdt ) return rsdt; - return UNULL; + return NULL; } PROVIDE_ACPI ( rsdp, acpi_find_rsdt, rsdp_find_rsdt ); diff --git a/src/arch/x86/interface/pcbios/rtc_entropy.c b/src/arch/x86/interface/pcbios/rtc_entropy.c index 8f47ff6b8..7c98019b6 100644 --- a/src/arch/x86/interface/pcbios/rtc_entropy.c +++ b/src/arch/x86/interface/pcbios/rtc_entropy.c @@ -53,6 +53,12 @@ extern void rtc_isr ( void ); /** Previous RTC interrupt handler */ static struct segoff rtc_old_handler; +/** Previous RTC interrupt enabled state */ +static uint8_t rtc_irq_enabled; + +/** Previous RTC periodic interrupt enabled state */ +static uint8_t rtc_int_enabled; + /** Flag set by RTC interrupt handler */ extern volatile uint8_t __text16 ( rtc_flag ); #define rtc_flag __use_text16 ( rtc_flag ) @@ -107,8 +113,9 @@ static void rtc_unhook_isr ( void ) { /** * Enable RTC interrupts * + * @ret enabled Periodic interrupt was previously enabled */ -static void rtc_enable_int ( void ) { +static int rtc_enable_int ( void ) { uint8_t status_b; /* Clear any stale pending interrupts via status register C */ @@ -124,6 +131,9 @@ static void rtc_enable_int ( void ) { /* Re-enable NMI and reset to default address */ outb ( CMOS_DEFAULT_ADDRESS, CMOS_ADDRESS ); inb ( CMOS_DATA ); /* Discard; may be needed on some platforms */ + + /* Return previous state */ + return ( status_b & RTC_STATUS_B_PIE ); } /** @@ -198,8 +208,11 @@ static int rtc_entropy_enable ( void ) { /* Hook ISR and enable RTC interrupts */ rtc_hook_isr(); - enable_irq ( RTC_IRQ ); - rtc_enable_int(); + rtc_irq_enabled = enable_irq ( RTC_IRQ ); + rtc_int_enabled = rtc_enable_int(); + DBGC ( &rtc_flag, "RTC had IRQ%d %sabled, interrupt %sabled\n", + RTC_IRQ, ( rtc_irq_enabled ? "en" : "dis" ), + ( rtc_int_enabled ? "en" : "dis" ) ); /* Check that RTC interrupts are working */ if ( ( rc = rtc_entropy_check() ) != 0 ) @@ -223,8 +236,10 @@ static int rtc_entropy_enable ( void ) { return 0; err_check: - rtc_disable_int(); - disable_irq ( RTC_IRQ ); + if ( ! rtc_int_enabled ) + rtc_disable_int(); + if ( ! rtc_irq_enabled ) + disable_irq ( RTC_IRQ ); rtc_unhook_isr(); err_no_tsc: return rc; @@ -236,9 +251,11 @@ static int rtc_entropy_enable ( void ) { */ static void rtc_entropy_disable ( void ) { - /* Disable RTC interrupts and unhook ISR */ - rtc_disable_int(); - disable_irq ( RTC_IRQ ); + /* Restore RTC interrupt state and unhook ISR */ + if ( ! rtc_int_enabled ) + rtc_disable_int(); + if ( ! rtc_irq_enabled ) + disable_irq ( RTC_IRQ ); rtc_unhook_isr(); } diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c index 3ca15271a..48394bdd9 100644 --- a/src/arch/x86/interface/pcbios/vesafb.c +++ b/src/arch/x86/interface/pcbios/vesafb.c @@ -103,7 +103,7 @@ struct vesafb { /** Font definition */ struct fbcon_font font; /** Character glyphs */ - struct segoff glyphs; + const uint8_t *glyphs; /** Saved VGA mode */ uint8_t saved_mode; }; @@ -140,11 +140,10 @@ static int vesafb_rc ( unsigned int status ) { * Get character glyph * * @v character Unicode character - * @v glyph Character glyph to fill in + * @ret glyph Character glyph */ -static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) { +static const uint8_t * vesafb_glyph ( unsigned int character ) { unsigned int index; - size_t offset; /* Identify glyph */ if ( character < VESAFB_ASCII ) { @@ -287,10 +286,8 @@ static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) { } } - /* Copy glyph from BIOS font table */ - offset = ( index * VESAFB_CHAR_HEIGHT ); - copy_from_real ( glyph, vesafb.glyphs.segment, - ( vesafb.glyphs.offset + offset ), VESAFB_CHAR_HEIGHT); + /* Return glyph in BIOS font table */ + return &vesafb.glyphs[ index * VESAFB_CHAR_HEIGHT ]; } /** @@ -298,6 +295,7 @@ static void vesafb_glyph ( unsigned int character, uint8_t *glyph ) { * */ static void vesafb_font ( void ) { + struct segoff glyphs; /* Get font information * @@ -318,12 +316,13 @@ static void vesafb_font ( void ) { "movw %%es, %%cx\n\t" "movw %%bp, %%dx\n\t" "popw %%bp\n\t" /* gcc bug */ ) - : "=c" ( vesafb.glyphs.segment ), - "=d" ( vesafb.glyphs.offset ) + : "=c" ( glyphs.segment ), + "=d" ( glyphs.offset ) : "a" ( VBE_GET_FONT ), "b" ( VESAFB_FONT ) ); DBGC ( &vbe_buf, "VESAFB has font %04x at %04x:%04x\n", - VESAFB_FONT, vesafb.glyphs.segment, vesafb.glyphs.offset ); + VESAFB_FONT, glyphs.segment, glyphs.offset ); + vesafb.glyphs = real_to_virt ( glyphs.segment, glyphs.offset ); vesafb.font.height = VESAFB_CHAR_HEIGHT; vesafb.font.glyph = vesafb_glyph; } @@ -338,8 +337,8 @@ static void vesafb_font ( void ) { */ static int vesafb_mode_list ( uint16_t **mode_numbers ) { struct vbe_controller_info *controller = &vbe_buf.controller; - userptr_t video_mode_ptr; - uint16_t mode_number; + const uint16_t *video_mode_ptr; + const uint16_t *mode_number; uint16_t status; size_t len; int rc; @@ -375,20 +374,18 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) { controller->video_mode_ptr.offset ); /* Calculate length of mode list */ - video_mode_ptr = real_to_user ( controller->video_mode_ptr.segment, + video_mode_ptr = real_to_virt ( controller->video_mode_ptr.segment, controller->video_mode_ptr.offset ); - len = 0; - do { - copy_from_user ( &mode_number, video_mode_ptr, len, - sizeof ( mode_number ) ); - len += sizeof ( mode_number ); - } while ( mode_number != VBE_MODE_END ); + mode_number = video_mode_ptr; + while ( *(mode_number++) != VBE_MODE_END ) {} + len = ( ( ( const void * ) mode_number ) - + ( ( const void * ) video_mode_ptr ) ); /* Allocate and fill mode list */ *mode_numbers = malloc ( len ); if ( ! *mode_numbers ) return -ENOMEM; - copy_from_user ( *mode_numbers, video_mode_ptr, 0, len ); + memcpy ( *mode_numbers, video_mode_ptr, len ); return 0; } @@ -607,7 +604,7 @@ static int vesafb_init ( struct console_configuration *config ) { } /* Initialise frame buffer console */ - if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_user ( vesafb.start ), + if ( ( rc = fbcon_init ( &vesafb.fbcon, phys_to_virt ( vesafb.start ), &vesafb.pixel, &vesafb.map, &vesafb.font, config ) ) != 0 ) goto err_fbcon_init; diff --git a/src/arch/x86/interface/pxe/pxe_call.c b/src/arch/x86/interface/pxe/pxe_call.c index 0e8d5c5a8..9a6a20dd3 100644 --- a/src/arch/x86/interface/pxe/pxe_call.c +++ b/src/arch/x86/interface/pxe/pxe_call.c @@ -55,12 +55,12 @@ extern void pxe_int_1a ( void ); static int int_1a_hooked = 0; /** Real-mode code segment size */ -extern char _text16_memsz[]; -#define _text16_memsz ( ( size_t ) _text16_memsz ) +extern size_t ABS_SYMBOL ( _text16_memsz ); +#define _text16_memsz ABS_VALUE ( _text16_memsz ) /** Real-mode data segment size */ -extern char _data16_memsz[]; -#define _data16_memsz ( ( size_t ) _data16_memsz ) +extern size_t ABS_SYMBOL (_data16_memsz ); +#define _data16_memsz ABS_VALUE ( _data16_memsz ) /** PXENV_UNDI_TRANSMIT API call profiler */ static struct profiler pxe_api_tx_profiler __profiler = @@ -144,10 +144,10 @@ static struct profiler * pxe_api_profiler ( unsigned int opcode ) { */ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { uint16_t opcode = ix86->regs.bx; - userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di ); struct profiler *profiler = pxe_api_profiler ( opcode ); + union u_PXENV_ANY *params = + real_to_virt ( ix86->segs.es, ix86->regs.di ); struct pxe_api_call *call; - union u_PXENV_ANY params; PXENV_EXIT_t ret; /* Start profiling */ @@ -160,17 +160,13 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { call = &pxenv_unknown_api; } - /* Copy parameter block from caller */ - copy_from_user ( ¶ms, uparams, 0, call->params_len ); - /* Set default status in case child routine fails to do so */ - params.Status = PXENV_STATUS_FAILURE; + params->Status = PXENV_STATUS_FAILURE; /* Hand off to relevant API routine */ - ret = call->entry ( ¶ms ); + ret = call->entry ( params ); - /* Copy modified parameter block back to caller and return */ - copy_to_user ( uparams, 0, ¶ms, call->params_len ); + /* Return exit code in %ax */ ix86->regs.ax = ret; /* Stop profiling, if applicable */ @@ -195,24 +191,20 @@ int pxe_api_call_weak ( struct i386_all_regs *ix86 ) { * @ret ax PXE exit code */ __asmcall void pxe_loader_call ( struct i386_all_regs *ix86 ) { - userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di ); - struct s_UNDI_LOADER params; + struct s_UNDI_LOADER *params = + real_to_virt ( ix86->segs.es, ix86->regs.di ); PXENV_EXIT_t ret; - /* Copy parameter block from caller */ - copy_from_user ( ¶ms, uparams, 0, sizeof ( params ) ); - /* Fill in ROM segment address */ ppxe.UNDIROMID.segment = ix86->segs.ds; /* Set default status in case child routine fails to do so */ - params.Status = PXENV_STATUS_FAILURE; + params->Status = PXENV_STATUS_FAILURE; /* Call UNDI loader */ - ret = undi_loader ( ¶ms ); + ret = undi_loader ( params ); - /* Copy modified parameter block back to caller and return */ - copy_to_user ( uparams, 0, ¶ms, sizeof ( params ) ); + /* Return exit code in %ax */ ix86->regs.ax = ret; } @@ -265,6 +257,7 @@ static void pxe_init_structures ( void ) { /** PXE structure initialiser */ struct init_fn pxe_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "pxe", .initialise = pxe_init_structures, }; diff --git a/src/arch/x86/interface/pxe/pxe_file.c b/src/arch/x86/interface/pxe/pxe_file.c index 456ffb5fd..997667ccf 100644 --- a/src/arch/x86/interface/pxe/pxe_file.c +++ b/src/arch/x86/interface/pxe/pxe_file.c @@ -8,7 +8,6 @@ #include <stdio.h> #include <errno.h> #include <byteswap.h> -#include <ipxe/uaccess.h> #include <ipxe/posix_io.h> #include <ipxe/features.h> #include <pxe.h> @@ -53,30 +52,20 @@ FEATURE ( FEATURE_MISC, "PXEXT", DHCP_EB_FEATURE_PXE_EXT, 2 ); * */ static PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) { - userptr_t filename; - size_t filename_len; + const char *filename; int fd; DBG ( "PXENV_FILE_OPEN" ); - /* Copy name from external program, and open it */ - filename = real_to_user ( file_open->FileName.segment, - file_open->FileName.offset ); - filename_len = strlen_user ( filename, 0 ); - { - char uri_string[ filename_len + 1 ]; - - copy_from_user ( uri_string, filename, 0, - sizeof ( uri_string ) ); - DBG ( " %s", uri_string ); - fd = open ( uri_string ); - } - + /* Open specified filename */ + filename = real_to_virt ( file_open->FileName.segment, + file_open->FileName.offset ); + DBG ( " %s", filename ); + fd = open ( filename ); if ( fd < 0 ) { file_open->Status = PXENV_STATUS ( fd ); return PXENV_EXIT_FAILURE; } - DBG ( " as file %d", fd ); file_open->FileHandle = fd; @@ -148,17 +137,17 @@ pxenv_file_select ( struct s_PXENV_FILE_SELECT *file_select ) { * */ static PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) { - userptr_t buffer; + void *buffer; ssize_t len; DBG ( "PXENV_FILE_READ %d to %04x:%04x+%04x", file_read->FileHandle, file_read->Buffer.segment, file_read->Buffer.offset, file_read->BufferSize ); - buffer = real_to_user ( file_read->Buffer.segment, + buffer = real_to_virt ( file_read->Buffer.segment, file_read->Buffer.offset ); - if ( ( len = read_user ( file_read->FileHandle, buffer, 0, - file_read->BufferSize ) ) < 0 ) { + if ( ( len = read ( file_read->FileHandle, buffer, + file_read->BufferSize ) ) < 0 ) { file_read->Status = PXENV_STATUS ( len ); return PXENV_EXIT_FAILURE; } @@ -210,27 +199,18 @@ pxenv_get_file_size ( struct s_PXENV_GET_FILE_SIZE *get_file_size ) { * */ static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { - userptr_t command; - size_t command_len; + const char *command; int rc; DBG ( "PXENV_FILE_EXEC" ); - /* Copy name from external program, and exec it */ - command = real_to_user ( file_exec->Command.segment, + /* Execute specified command */ + command = real_to_virt ( file_exec->Command.segment, file_exec->Command.offset ); - command_len = strlen_user ( command, 0 ); - { - char command_string[ command_len + 1 ]; - - copy_from_user ( command_string, command, 0, - sizeof ( command_string ) ); - DBG ( " %s", command_string ); - - if ( ( rc = system ( command_string ) ) != 0 ) { - file_exec->Status = PXENV_STATUS ( rc ); - return PXENV_EXIT_FAILURE; - } + DBG ( " %s", command ); + if ( ( rc = system ( command ) ) != 0 ) { + file_exec->Status = PXENV_STATUS ( rc ); + return PXENV_EXIT_FAILURE; } file_exec->Status = PXENV_STATUS_SUCCESS; @@ -251,23 +231,22 @@ static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { */ static PXENV_EXIT_t pxenv_file_cmdline ( struct s_PXENV_FILE_CMDLINE *file_cmdline ) { - userptr_t buffer; - size_t max_len; + char *buffer; size_t len; DBG ( "PXENV_FILE_CMDLINE to %04x:%04x+%04x \"%s\"\n", file_cmdline->Buffer.segment, file_cmdline->Buffer.offset, file_cmdline->BufferSize, pxe_cmdline ); - buffer = real_to_user ( file_cmdline->Buffer.segment, + buffer = real_to_virt ( file_cmdline->Buffer.segment, file_cmdline->Buffer.offset ); len = file_cmdline->BufferSize; - max_len = ( pxe_cmdline ? - ( strlen ( pxe_cmdline ) + 1 /* NUL */ ) : 0 ); - if ( len > max_len ) - len = max_len; - copy_to_user ( buffer, 0, pxe_cmdline, len ); - file_cmdline->BufferSize = max_len; + if ( pxe_cmdline ) { + len = snprintf ( buffer, len, "%s", pxe_cmdline ); + file_cmdline->BufferSize = ( len + 1 /* NUL */ ); + } else { + file_cmdline->BufferSize = 0; + } file_cmdline->Status = PXENV_STATUS_SUCCESS; return PXENV_EXIT_SUCCESS; diff --git a/src/arch/x86/interface/pxe/pxe_preboot.c b/src/arch/x86/interface/pxe/pxe_preboot.c index 09e721b34..863aaae9a 100644 --- a/src/arch/x86/interface/pxe/pxe_preboot.c +++ b/src/arch/x86/interface/pxe/pxe_preboot.c @@ -33,7 +33,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdint.h> #include <string.h> #include <stdlib.h> -#include <ipxe/uaccess.h> #include <ipxe/dhcp.h> #include <ipxe/fakedhcp.h> #include <ipxe/device.h> @@ -48,7 +47,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include "pxe_call.h" /* Avoid dragging in isapnp.o unnecessarily */ -uint16_t isapnp_read_port; +uint16_t isapnp_read_port __attribute__ (( weak )); /** Zero-based versions of PXENV_GET_CACHED_INFO::PacketType */ enum pxe_cached_info_indices { @@ -184,7 +183,7 @@ pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) { union pxe_cached_info *info; unsigned int idx; size_t len; - userptr_t buffer; + void *buffer; DBGC ( &pxe_netdev, "PXENV_GET_CACHED_INFO %s to %04x:%04x+%x", pxenv_get_cached_info_name ( get_cached_info->PacketType ), @@ -243,9 +242,9 @@ pxenv_get_cached_info ( struct s_PXENV_GET_CACHED_INFO *get_cached_info ) { len = sizeof ( *info ); if ( len < sizeof ( *info ) ) DBGC ( &pxe_netdev, " buffer may be too short" ); - buffer = real_to_user ( get_cached_info->Buffer.segment, + buffer = real_to_virt ( get_cached_info->Buffer.segment, get_cached_info->Buffer.offset ); - copy_to_user ( buffer, 0, info, len ); + memcpy ( buffer, info, len ); get_cached_info->BufferSize = len; } diff --git a/src/arch/x86/interface/pxe/pxe_tftp.c b/src/arch/x86/interface/pxe/pxe_tftp.c index 3b4c6d847..aa675fd13 100644 --- a/src/arch/x86/interface/pxe/pxe_tftp.c +++ b/src/arch/x86/interface/pxe/pxe_tftp.c @@ -33,7 +33,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include <stdio.h> #include <errno.h> #include <byteswap.h> -#include <ipxe/uaccess.h> #include <ipxe/in.h> #include <ipxe/tftp.h> #include <ipxe/iobuf.h> @@ -49,7 +48,7 @@ struct pxe_tftp_connection { /** Data transfer interface */ struct interface xfer; /** Data buffer */ - userptr_t buffer; + void *buffer; /** Size of data buffer */ size_t size; /** Starting offset of data buffer */ @@ -121,9 +120,8 @@ static int pxe_tftp_xfer_deliver ( struct pxe_tftp_connection *pxe_tftp, ( pxe_tftp->start + pxe_tftp->size ) ); rc = -ENOBUFS; } else { - copy_to_user ( pxe_tftp->buffer, - ( pxe_tftp->offset - pxe_tftp->start ), - iobuf->data, len ); + memcpy ( ( pxe_tftp->buffer + pxe_tftp->offset - + pxe_tftp->start ), iobuf->data, len ); } /* Calculate new buffer position */ @@ -378,14 +376,14 @@ static PXENV_EXIT_t pxenv_tftp_read ( struct s_PXENV_TFTP_READ *tftp_read ) { tftp_read->Buffer.segment, tftp_read->Buffer.offset ); /* Read single block into buffer */ - pxe_tftp.buffer = real_to_user ( tftp_read->Buffer.segment, + pxe_tftp.buffer = real_to_virt ( tftp_read->Buffer.segment, tftp_read->Buffer.offset ); pxe_tftp.size = pxe_tftp.blksize; pxe_tftp.start = pxe_tftp.offset; while ( ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) && ( pxe_tftp.offset == pxe_tftp.start ) ) step(); - pxe_tftp.buffer = UNULL; + pxe_tftp.buffer = NULL; tftp_read->BufferSize = ( pxe_tftp.offset - pxe_tftp.start ); tftp_read->PacketNumber = ++pxe_tftp.blkidx; @@ -492,11 +490,11 @@ PXENV_EXIT_t pxenv_tftp_read_file ( struct s_PXENV_TFTP_READ_FILE } /* Read entire file */ - pxe_tftp.buffer = phys_to_user ( tftp_read_file->Buffer ); + pxe_tftp.buffer = phys_to_virt ( tftp_read_file->Buffer ); pxe_tftp.size = tftp_read_file->BufferSize; while ( ( rc = pxe_tftp.rc ) == -EINPROGRESS ) step(); - pxe_tftp.buffer = UNULL; + pxe_tftp.buffer = NULL; tftp_read_file->BufferSize = pxe_tftp.max_offset; /* Close TFTP file */ diff --git a/src/arch/x86/interface/pxe/pxe_udp.c b/src/arch/x86/interface/pxe/pxe_udp.c index a5d5eb77b..61c858dde 100644 --- a/src/arch/x86/interface/pxe/pxe_udp.c +++ b/src/arch/x86/interface/pxe/pxe_udp.c @@ -9,7 +9,6 @@ #include <ipxe/iobuf.h> #include <ipxe/xfer.h> #include <ipxe/udp.h> -#include <ipxe/uaccess.h> #include <ipxe/process.h> #include <ipxe/netdevice.h> #include <ipxe/malloc.h> @@ -296,7 +295,7 @@ pxenv_udp_write ( struct s_PXENV_UDP_WRITE *pxenv_udp_write ) { }; size_t len; struct io_buffer *iobuf; - userptr_t buffer; + const void *buffer; int rc; DBG ( "PXENV_UDP_WRITE" ); @@ -328,9 +327,9 @@ pxenv_udp_write ( struct s_PXENV_UDP_WRITE *pxenv_udp_write ) { pxenv_udp_write->Status = PXENV_STATUS_OUT_OF_RESOURCES; return PXENV_EXIT_FAILURE; } - buffer = real_to_user ( pxenv_udp_write->buffer.segment, + buffer = real_to_virt ( pxenv_udp_write->buffer.segment, pxenv_udp_write->buffer.offset ); - copy_from_user ( iob_put ( iobuf, len ), buffer, 0, len ); + memcpy ( iob_put ( iobuf, len ), buffer, len ); DBG ( " %04x:%04x+%x %d->%s:%d\n", pxenv_udp_write->buffer.segment, pxenv_udp_write->buffer.offset, pxenv_udp_write->buffer_size, @@ -400,7 +399,7 @@ static PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *pxenv_udp_read ) { struct pxe_udp_pseudo_header *pshdr; uint16_t d_port_wanted = pxenv_udp_read->d_port; uint16_t d_port; - userptr_t buffer; + void *buffer; size_t len; /* Try receiving a packet, if the queue is empty */ @@ -438,12 +437,12 @@ static PXENV_EXIT_t pxenv_udp_read ( struct s_PXENV_UDP_READ *pxenv_udp_read ) { } /* Copy packet to buffer and record length */ - buffer = real_to_user ( pxenv_udp_read->buffer.segment, + buffer = real_to_virt ( pxenv_udp_read->buffer.segment, pxenv_udp_read->buffer.offset ); len = iob_len ( iobuf ); if ( len > pxenv_udp_read->buffer_size ) len = pxenv_udp_read->buffer_size; - copy_to_user ( buffer, 0, iobuf->data, len ); + memcpy ( buffer, iobuf->data, len ); pxenv_udp_read->buffer_size = len; /* Fill in source/dest information */ diff --git a/src/arch/x86/interface/syslinux/com32_call.c b/src/arch/x86/interface/syslinux/com32_call.c index 19fdbaff9..a23f46436 100644 --- a/src/arch/x86/interface/syslinux/com32_call.c +++ b/src/arch/x86/interface/syslinux/com32_call.c @@ -49,9 +49,8 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad DBGC ( &com32_regs, "COM32 INT%x in %#08lx out %#08lx\n", interrupt, inregs_phys, outregs_phys ); - memcpy_user ( virt_to_user( &com32_regs ), 0, - phys_to_user ( inregs_phys ), 0, - sizeof(com32sys_t) ); + memcpy ( &com32_regs, phys_to_virt ( inregs_phys ), + sizeof ( com32sys_t ) ); com32_int_vector = interrupt; @@ -108,9 +107,8 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad : : ); if ( outregs_phys ) { - memcpy_user ( phys_to_user ( outregs_phys ), 0, - virt_to_user( &com32_regs ), 0, - sizeof(com32sys_t) ); + memcpy ( phys_to_virt ( outregs_phys ), + &com32_regs, sizeof ( com32sys_t ) ); } } @@ -122,9 +120,8 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t DBGC ( &com32_regs, "COM32 farcall %04x:%04x in %#08lx out %#08lx\n", ( proc >> 16 ), ( proc & 0xffff ), inregs_phys, outregs_phys ); - memcpy_user ( virt_to_user( &com32_regs ), 0, - phys_to_user ( inregs_phys ), 0, - sizeof(com32sys_t) ); + memcpy ( &com32_regs, phys_to_virt ( inregs_phys ), + sizeof ( com32sys_t ) ); com32_farcall_proc = proc; @@ -170,9 +167,8 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t : : ); if ( outregs_phys ) { - memcpy_user ( phys_to_user ( outregs_phys ), 0, - virt_to_user( &com32_regs ), 0, - sizeof(com32sys_t) ); + memcpy ( phys_to_virt ( outregs_phys ), + &com32_regs, sizeof ( com32sys_t ) ); } } @@ -185,7 +181,7 @@ int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) DBGC ( &com32_regs, "COM32 cfarcall %04x:%04x params %#08lx+%#zx\n", ( proc >> 16 ), ( proc & 0xffff ), stack, stacksz ); - copy_user_to_rm_stack ( phys_to_user ( stack ), stacksz ); + copy_to_rm_stack ( phys_to_virt ( stack ), stacksz ); com32_farcall_proc = proc; __asm__ __volatile__ ( @@ -194,7 +190,7 @@ int __asmcall com32_cfarcall ( uint32_t proc, physaddr_t stack, size_t stacksz ) : : "ecx", "edx" ); - remove_user_from_rm_stack ( 0, stacksz ); + remove_from_rm_stack ( NULL, stacksz ); return eax; } diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index b75e8ef7c..c3e921075 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -37,6 +37,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include <ipxe/posix_io.h> #include <ipxe/process.h> #include <ipxe/serial.h> +#include <ipxe/ns16550.h> #include <ipxe/init.h> #include <ipxe/image.h> #include <ipxe/version.h> @@ -88,14 +89,9 @@ static uint16_t comboot_graphics_mode = 0; * Print a string with a particular terminator */ static void print_user_string ( unsigned int segment, unsigned int offset, char terminator ) { - int i = 0; - char c; - userptr_t str = real_to_user ( segment, offset ); - for ( ; ; ) { - copy_from_user ( &c, str, i, 1 ); - if ( c == terminator ) break; - putchar ( c ); - i++; + char *c; + for ( c = real_to_virt ( segment, offset ) ; *c != terminator ; c++ ) { + putchar ( *c ); } } @@ -109,26 +105,26 @@ static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsig unsigned int i; /* Copy shuffle descriptor list so it doesn't get overwritten */ - copy_from_user ( shuf, real_to_user ( list_segment, list_offset ), 0, - count * sizeof( comboot_shuffle_descriptor ) ); + memcpy ( shuf, real_to_virt ( list_segment, list_offset ), + count * sizeof( comboot_shuffle_descriptor ) ); /* Do the copies */ for ( i = 0; i < count; i++ ) { - userptr_t src_u = phys_to_user ( shuf[ i ].src ); - userptr_t dest_u = phys_to_user ( shuf[ i ].dest ); + const void *src = phys_to_virt ( shuf[ i ].src ); + void *dest = phys_to_virt ( shuf[ i ].dest ); if ( shuf[ i ].src == 0xFFFFFFFF ) { /* Fill with 0 instead of copying */ - memset_user ( dest_u, 0, 0, shuf[ i ].len ); + memset ( dest, 0, shuf[ i ].len ); } else if ( shuf[ i ].dest == 0xFFFFFFFF ) { /* Copy new list of descriptors */ count = shuf[ i ].len / sizeof( comboot_shuffle_descriptor ); assert ( count <= COMBOOT_MAX_SHUFFLE_DESCRIPTORS ); - copy_from_user ( shuf, src_u, 0, shuf[ i ].len ); + memcpy ( shuf, src, shuf[ i ].len ); i = -1; } else { /* Regular copy */ - memmove_user ( dest_u, 0, src_u, 0, shuf[ i ].len ); + memmove ( dest, src, shuf[ i ].len ); } } } @@ -164,7 +160,7 @@ void comboot_force_text_mode ( void ) { /** * Fetch kernel and optional initrd */ -static int comboot_fetch_kernel ( char *kernel_file, char *cmdline ) { +static int comboot_fetch_kernel ( const char *kernel_file, char *cmdline ) { struct image *kernel; struct image *initrd; char *initrd_file; @@ -258,8 +254,8 @@ static __asmcall __used void int21 ( struct i386_all_regs *ix86 ) { break; case 0x04: /* Write Character to Serial Port */ - if ( serial_console.base ) { - uart_transmit ( &serial_console, ix86->regs.dl ); + if ( serial_console ) { + uart_transmit ( serial_console, ix86->regs.dl ); ix86->flags &= ~CF; } break; @@ -346,10 +342,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0003: /* Run command */ { - userptr_t cmd_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int len = strlen_user ( cmd_u, 0 ); - char cmd[len + 1]; - copy_from_user ( cmd, cmd_u, 0, len + 1 ); + const char *cmd = real_to_virt ( ix86->segs.es, + ix86->regs.bx ); DBG ( "COMBOOT: executing command '%s'\n", cmd ); system ( cmd ); DBG ( "COMBOOT: exiting after executing command...\n" ); @@ -370,11 +364,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0006: /* Open file */ { int fd; - userptr_t file_u = real_to_user ( ix86->segs.es, ix86->regs.si ); - int len = strlen_user ( file_u, 0 ); - char file[len + 1]; - - copy_from_user ( file, file_u, 0, len + 1 ); + const char *file = real_to_virt ( ix86->segs.es, + ix86->regs.si ); if ( file[0] == '\0' ) { DBG ( "COMBOOT: attempted open with empty file name\n" ); @@ -410,7 +401,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { int len = ix86->regs.cx * COMBOOT_FILE_BLOCKSZ; int rc; fd_set fds; - userptr_t buf = real_to_user ( ix86->segs.es, ix86->regs.bx ); + void *buf = real_to_virt ( ix86->segs.es, + ix86->regs.bx ); /* Wait for data ready to read */ FD_ZERO ( &fds ); @@ -418,7 +410,7 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { select ( &fds, 1 ); - rc = read_user ( fd, buf, 0, len ); + rc = read ( fd, buf, len ); if ( rc < 0 ) { DBG ( "COMBOOT: read failed\n" ); ix86->regs.si = 0; @@ -454,9 +446,11 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { break; case 0x000B: /* Get Serial Console Configuration */ - if ( serial_console.base ) { - ix86->regs.dx = ( ( intptr_t ) serial_console.base ); - ix86->regs.cx = serial_console.divisor; + if ( serial_console ) { + struct ns16550_uart *comport = serial_console->priv; + + ix86->regs.dx = ( ( intptr_t ) comport->base ); + ix86->regs.cx = comport->divisor; ix86->regs.bx = 0; ix86->flags &= ~CF; } @@ -483,13 +477,10 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0010: /* Resolve hostname */ { - userptr_t hostname_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int len = strlen_user ( hostname_u, 0 ); - char hostname[len]; + const char *hostname = real_to_virt ( ix86->segs.es, + ix86->regs.bx ); struct in_addr addr; - copy_from_user ( hostname, hostname_u, 0, len + 1 ); - /* TODO: * "If the hostname does not contain a dot (.), the * local domain name is automatically appended." @@ -526,8 +517,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { "lret\n\t" ) : - : "r" ( ix86->segs.ds ), - "r" ( ix86->regs.ebp ), + : "R" ( ix86->segs.ds ), + "R" ( ix86->regs.ebp ), "d" ( ix86->regs.ebx ), "S" ( ix86->regs.esi ) ); @@ -549,15 +540,10 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0016: /* Run kernel image */ { - userptr_t file_u = real_to_user ( ix86->segs.ds, ix86->regs.si ); - userptr_t cmd_u = real_to_user ( ix86->segs.es, ix86->regs.bx ); - int file_len = strlen_user ( file_u, 0 ); - int cmd_len = strlen_user ( cmd_u, 0 ); - char file[file_len + 1]; - char cmd[cmd_len + 1]; - - copy_from_user ( file, file_u, 0, file_len + 1 ); - copy_from_user ( cmd, cmd_u, 0, cmd_len + 1 ); + const char *file = real_to_virt ( ix86->segs.ds, + ix86->regs.si ); + char *cmd = real_to_virt ( ix86->segs.es, + ix86->regs.bx ); DBG ( "COMBOOT: run kernel %s %s\n", file, cmd ); comboot_fetch_kernel ( file, cmd ); @@ -595,9 +581,9 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { shuffle ( ix86->segs.es, ix86->regs.di, ix86->regs.cx ); /* Copy initial register values to .text16 */ - memcpy_user ( real_to_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), 0, - real_to_user ( ix86->segs.ds, ix86->regs.si ), 0, - sizeof(syslinux_rm_regs) ); + memcpy ( real_to_virt ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), + real_to_virt ( ix86->segs.ds, ix86->regs.si ), + sizeof(syslinux_rm_regs) ); /* Load initial register values */ __asm__ __volatile__ ( @@ -702,4 +688,4 @@ void unhook_comboot_interrupts ( ) { } /* Avoid dragging in serial console support unconditionally */ -struct uart serial_console __attribute__ (( weak )); +struct uart *serial_console __attribute__ (( weak )); diff --git a/src/arch/x86/interface/vmware/guestinfo.c b/src/arch/x86/interface/vmware/guestinfo.c index 4134515c1..c181d96e9 100644 --- a/src/arch/x86/interface/vmware/guestinfo.c +++ b/src/arch/x86/interface/vmware/guestinfo.c @@ -200,6 +200,7 @@ static void guestinfo_init ( void ) { /** GuestInfo settings initialiser */ struct init_fn guestinfo_init_fn __init_fn ( INIT_NORMAL ) = { + .name = "guestinfo", .initialise = guestinfo_init, }; diff --git a/src/arch/x86/interface/vmware/vmconsole.c b/src/arch/x86/interface/vmware/vmconsole.c index f7df4f75b..3b892c837 100644 --- a/src/arch/x86/interface/vmware/vmconsole.c +++ b/src/arch/x86/interface/vmware/vmconsole.c @@ -134,5 +134,6 @@ static void vmconsole_init ( void ) { * VMware logfile console initialisation function */ struct init_fn vmconsole_init_fn __init_fn ( INIT_CONSOLE ) = { + .name = "vmconsole", .initialise = vmconsole_init, }; |
