From 89fe7886897be76ed902317e311d60ae654057aa Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sun, 20 Apr 2025 18:29:48 +0100 Subject: [uaccess] Remove redundant memcpy_user() and related string functions The memcpy_user(), memmove_user(), memcmp_user(), memset_user(), and strlen_user() functions are now just straightforward wrappers around the corresponding standard library functions. Remove these redundant wrappers. Signed-off-by: Michael Brown --- src/arch/x86/interface/syslinux/com32_call.c | 20 ++++++++------------ src/arch/x86/interface/syslinux/comboot_call.c | 20 ++++++++++---------- 2 files changed, 18 insertions(+), 22 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/interface/syslinux/com32_call.c b/src/arch/x86/interface/syslinux/com32_call.c index 19fdbaff9..da9d6491a 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 ( virt_to_user( &com32_regs ), phys_to_user ( 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_user ( outregs_phys ), + virt_to_user ( &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 ( virt_to_user( &com32_regs ), phys_to_user ( 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_user ( outregs_phys ), + virt_to_user ( &com32_regs ), sizeof ( com32sys_t ) ); } } diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index b75e8ef7c..f26fcad0a 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -119,7 +119,7 @@ static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsig if ( shuf[ i ].src == 0xFFFFFFFF ) { /* Fill with 0 instead of copying */ - memset_user ( dest_u, 0, 0, shuf[ i ].len ); + memset ( dest_u, 0, shuf[ i ].len ); } else if ( shuf[ i ].dest == 0xFFFFFFFF ) { /* Copy new list of descriptors */ count = shuf[ i ].len / sizeof( comboot_shuffle_descriptor ); @@ -128,7 +128,7 @@ static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsig i = -1; } else { /* Regular copy */ - memmove_user ( dest_u, 0, src_u, 0, shuf[ i ].len ); + memmove ( dest_u, src_u, shuf[ i ].len ); } } } @@ -347,7 +347,7 @@ 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 ); + int len = strlen ( cmd_u ); char cmd[len + 1]; copy_from_user ( cmd, cmd_u, 0, len + 1 ); DBG ( "COMBOOT: executing command '%s'\n", cmd ); @@ -371,7 +371,7 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { { int fd; userptr_t file_u = real_to_user ( ix86->segs.es, ix86->regs.si ); - int len = strlen_user ( file_u, 0 ); + int len = strlen ( file_u ); char file[len + 1]; copy_from_user ( file, file_u, 0, len + 1 ); @@ -484,7 +484,7 @@ 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 ); + int len = strlen ( hostname_u ); char hostname[len]; struct in_addr addr; @@ -551,8 +551,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { { 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 ); + int file_len = strlen ( file_u ); + int cmd_len = strlen ( cmd_u ); char file[file_len + 1]; char cmd[cmd_len + 1]; @@ -595,9 +595,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_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), + real_to_user ( ix86->segs.ds, ix86->regs.si ), + sizeof(syslinux_rm_regs) ); /* Load initial register values */ __asm__ __volatile__ ( -- cgit v1.2.3-55-g7522 From 8c31270a21a85cc87bce0e07e19e2041d2510a4c Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 21 Apr 2025 16:16:01 +0100 Subject: [uaccess] Remove user_to_phys() and phys_to_user() Remove the intermediate concept of a user pointer from physical address conversions, leaving virt_to_phys() and phys_to_virt() as the directly implemented functions. Signed-off-by: Michael Brown --- src/arch/x86/core/runtime.c | 4 +-- src/arch/x86/core/vram_settings.c | 2 +- src/arch/x86/image/bzimage.c | 36 ++++++++++---------- src/arch/x86/image/com32.c | 2 +- src/arch/x86/image/initrd.c | 32 +++++++++--------- src/arch/x86/image/multiboot.c | 6 ++-- src/arch/x86/image/nbi.c | 4 +-- src/arch/x86/image/sdi.c | 9 ++--- src/arch/x86/image/ucode.c | 11 +++--- src/arch/x86/include/librm.h | 25 +++++++------- src/arch/x86/include/realmode.h | 2 +- src/arch/x86/interface/pcbios/bios_cachedhcp.c | 2 +- src/arch/x86/interface/pcbios/bios_smbios.c | 4 +-- src/arch/x86/interface/pcbios/int13.c | 6 ++-- src/arch/x86/interface/pcbios/memtop_umalloc.c | 30 ++++++++-------- src/arch/x86/interface/pcbios/rsdp.c | 8 ++--- src/arch/x86/interface/pcbios/vesafb.c | 2 +- src/arch/x86/interface/pxe/pxe_tftp.c | 2 +- src/arch/x86/interface/syslinux/com32_call.c | 10 +++--- src/arch/x86/interface/syslinux/comboot_call.c | 4 +-- src/arch/x86/transitions/librm_mgmt.c | 4 +-- src/core/acpi.c | 24 ++++++------- src/core/blocktrans.c | 2 +- src/core/cachedhcp.c | 2 +- src/core/fbcon.c | 4 +-- src/core/image.c | 4 +-- src/core/uaccess.c | 4 +-- src/drivers/block/srp.c | 4 +-- src/drivers/infiniband/arbel.c | 4 +-- src/drivers/infiniband/golan.c | 4 +-- src/drivers/infiniband/golan.h | 4 +-- src/drivers/infiniband/hermon.c | 4 +-- src/drivers/net/exanic.c | 6 ++-- src/drivers/net/gve.c | 27 +++++++-------- src/drivers/net/thunderx.c | 21 ++++++------ src/drivers/usb/xhci.c | 7 ++-- src/hci/commands/image_mem_cmd.c | 2 +- src/image/elf.c | 2 +- src/image/segment.c | 6 ++-- src/include/ipxe/linux/linux_uaccess.h | 34 +++++++++---------- src/include/ipxe/uaccess.h | 47 +++++++------------------- src/interface/efi/efi_acpi.c | 2 +- src/interface/efi/efi_fbcon.c | 2 +- src/interface/efi/efi_smbios.c | 8 ++--- src/interface/efi/efi_umalloc.c | 4 +-- src/interface/hyperv/vmbus.c | 2 +- src/interface/linux/linux_uaccess.c | 3 +- src/interface/smbios/smbios.c | 8 ++--- 48 files changed, 211 insertions(+), 235 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/core/runtime.c b/src/arch/x86/core/runtime.c index 2b803f772..2d2a10674 100644 --- a/src/arch/x86/core/runtime.c +++ b/src/arch/x86/core/runtime.c @@ -124,7 +124,7 @@ static int cmdline_init ( void ) { DBGC ( colour, "RUNTIME found no command line\n" ); return 0; } - cmdline_user = phys_to_user ( cmdline_phys ); + cmdline_user = phys_to_virt ( cmdline_phys ); len = ( strlen ( cmdline_user ) + 1 /* NUL */ ); /* Allocate and copy command line */ @@ -193,7 +193,7 @@ static int initrd_init ( void ) { initrd_phys, ( initrd_phys + initrd_len ) ); /* Create initrd image */ - image = image_memory ( "", phys_to_user ( initrd_phys ), + image = image_memory ( "", 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/vram_settings.c b/src/arch/x86/core/vram_settings.c index 9c169b40c..ceeada467 100644 --- a/src/arch/x86/core/vram_settings.c +++ b/src/arch/x86/core/vram_settings.c @@ -47,7 +47,7 @@ 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 ); + userptr_t vram = phys_to_virt ( VRAM_BASE ); /* Copy video RAM */ if ( len > VRAM_LEN ) diff --git a/src/arch/x86/image/bzimage.c b/src/arch/x86/image/bzimage.c index 32598525f..0f373c1c8 100644 --- a/src/arch/x86/image/bzimage.c +++ b/src/arch/x86/image/bzimage.c @@ -169,7 +169,7 @@ static int bzimage_parse_header ( struct image *image, bzimg->rm_memsz += BZI_CMDLINE_SIZE; /* Calculate load address of protected-mode portion */ - bzimg->pm_kernel = phys_to_user ( is_bzimage ? BZI_LOAD_HIGH_ADDR + bzimg->pm_kernel = phys_to_virt ( is_bzimage ? BZI_LOAD_HIGH_ADDR : BZI_LOAD_LOW_ADDR ); /* Extract video mode */ @@ -185,8 +185,8 @@ static int bzimage_parse_header ( struct image *image, DBGC ( image, "bzImage %p version %04x RM %#lx+%#zx PM %#lx+%#zx " "cmdlen %zd\n", image, bzimg->version, - user_to_phys ( bzimg->rm_kernel, 0 ), bzimg->rm_filesz, - user_to_phys ( bzimg->pm_kernel, 0 ), bzimg->pm_sz, + virt_to_phys ( bzimg->rm_kernel ), bzimg->rm_filesz, + virt_to_phys ( bzimg->pm_kernel ), bzimg->pm_sz, bzimg->cmdline_size ); return 0; @@ -215,8 +215,8 @@ static void bzimage_update_header ( struct image *image, /* Set command line */ if ( bzimg->version >= 0x0202 ) { - bzimg->bzhdr.cmd_line_ptr = user_to_phys ( bzimg->rm_kernel, - bzimg->rm_cmdline ); + bzimg->bzhdr.cmd_line_ptr = ( virt_to_phys ( bzimg->rm_kernel ) + + bzimg->rm_cmdline ); } else { bzimg->cmdline_magic.magic = BZI_CMDLINE_MAGIC; bzimg->cmdline_magic.offset = bzimg->rm_cmdline; @@ -383,11 +383,11 @@ static size_t bzimage_load_initrd ( struct image *image, } assert ( offset == len ); DBGC ( image, "bzImage %p initrd %p [%#08lx,%#08lx,%#08lx)" - "%s%s\n", image, initrd, user_to_phys ( address, 0 ), - user_to_phys ( address, offset ), - user_to_phys ( address, ( offset + initrd->len ) ), + "%s%s\n", image, initrd, virt_to_phys ( address ), + ( virt_to_phys ( address ) + offset ), + ( virt_to_phys ( address ) + offset + initrd->len ), ( filename ? " " : "" ), ( filename ? filename : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( address, offset ), + DBGC2_MD5A ( image, ( virt_to_phys ( address ) + offset ), ( address + offset ), initrd->len ); } len += initrd->len; @@ -422,11 +422,11 @@ static int bzimage_check_initrds ( struct image *image, len = bzimage_align ( len ); DBGC ( image, "bzImage %p initrd %p from [%#08lx,%#08lx)%s%s\n", - image, initrd, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), + image, initrd, virt_to_phys ( initrd->data ), + ( virt_to_phys ( initrd->data ) + initrd->len ), ( initrd->cmdline ? " " : "" ), ( initrd->cmdline ? initrd->cmdline : "" ) ); - DBGC2_MD5A ( image, user_to_phys ( initrd->data, 0 ), + DBGC2_MD5A ( image, virt_to_phys ( initrd->data ), initrd->data, initrd->len ); } @@ -445,7 +445,7 @@ static int bzimage_check_initrds ( struct image *image, } /* Check that total length fits within kernel's memory limit */ - if ( user_to_phys ( bottom, len ) > bzimg->mem_limit ) { + if ( ( virt_to_phys ( bottom ) + len ) > bzimg->mem_limit ) { DBGC ( image, "bzImage %p not enough space for initrds\n", image ); return -ENOBUFS; @@ -485,12 +485,12 @@ static void bzimage_load_initrds ( struct image *image, /* Find highest usable address */ top = ( highest->data + bzimage_align ( highest->len ) ); - if ( user_to_phys ( top, -1 ) > bzimg->mem_limit ) { - top = phys_to_user ( ( bzimg->mem_limit + 1 ) & + if ( ( virt_to_phys ( top ) - 1UL ) > bzimg->mem_limit ) { + top = phys_to_virt ( ( bzimg->mem_limit + 1 ) & ~( INITRD_ALIGN - 1 ) ); } DBGC ( image, "bzImage %p loading initrds from %#08lx downwards\n", - image, user_to_phys ( top, -1 ) ); + image, ( virt_to_phys ( top ) - 1UL ) ); /* Load initrds in order */ for_each_image ( initrd ) { @@ -512,8 +512,8 @@ static void bzimage_load_initrds ( struct image *image, /* Record initrd location */ if ( ! bzimg->ramdisk_image ) - bzimg->ramdisk_image = user_to_phys ( dest, 0 ); - bzimg->ramdisk_size = ( user_to_phys ( dest, len ) - + bzimg->ramdisk_image = virt_to_phys ( dest ); + bzimg->ramdisk_size = ( virt_to_phys ( dest ) + len - bzimg->ramdisk_image ); } DBGC ( image, "bzImage %p initrds at [%#08lx,%#08lx)\n", diff --git a/src/arch/x86/image/com32.c b/src/arch/x86/image/com32.c index 3e38215cb..a2b60987d 100644 --- a/src/arch/x86/image/com32.c +++ b/src/arch/x86/image/com32.c @@ -211,7 +211,7 @@ static int com32_load_image ( struct image *image ) { filesz = image->len; memsz = filesz; - buffer = phys_to_user ( COM32_START_PHYS ); + buffer = phys_to_virt ( COM32_START_PHYS ); if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { DBGC ( image, "COM32 %p: could not prepare segment: %s\n", image, strerror ( rc ) ); diff --git a/src/arch/x86/image/initrd.c b/src/arch/x86/image/initrd.c index bcf95deef..fff40dd14 100644 --- a/src/arch/x86/image/initrd.c +++ b/src/arch/x86/image/initrd.c @@ -76,10 +76,10 @@ static userptr_t initrd_squash_high ( userptr_t top ) { current -= len; DBGC ( &images, "INITRD squashing %s [%#08lx,%#08lx)->" "[%#08lx,%#08lx)\n", highest->name, - user_to_phys ( highest->data, 0 ), - user_to_phys ( highest->data, highest->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, highest->len ) ); + virt_to_phys ( highest->data ), + ( virt_to_phys ( highest->data ) + highest->len ), + virt_to_phys ( current ), + ( virt_to_phys ( current ) + highest->len ) ); memmove ( current, highest->data, highest->len ); highest->data = current; } @@ -92,10 +92,10 @@ static userptr_t initrd_squash_high ( userptr_t top ) { current -= len; DBGC ( &images, "INITRD copying %s [%#08lx,%#08lx)->" "[%#08lx,%#08lx)\n", initrd->name, - user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ), - user_to_phys ( current, 0 ), - user_to_phys ( current, initrd->len ) ); + virt_to_phys ( initrd->data ), + ( virt_to_phys ( initrd->data ) + initrd->len ), + virt_to_phys ( current ), + ( virt_to_phys ( current ) + initrd->len ) ); memcpy ( current, initrd->data, initrd->len ); initrd->data = current; } @@ -119,10 +119,10 @@ static void initrd_swap ( struct image *low, struct image *high, size_t new_len; DBGC ( &images, "INITRD swapping %s [%#08lx,%#08lx)<->[%#08lx,%#08lx) " - "%s\n", low->name, user_to_phys ( low->data, 0 ), - user_to_phys ( low->data, low->len ), - user_to_phys ( high->data, 0 ), - user_to_phys ( high->data, high->len ), high->name ); + "%s\n", low->name, virt_to_phys ( low->data ), + ( virt_to_phys ( low->data ) + low->len ), + virt_to_phys ( high->data ), + ( virt_to_phys ( high->data ) + high->len ), high->name ); /* Round down length of free space */ free_len &= ~( INITRD_ALIGN - 1 ); @@ -208,9 +208,9 @@ static void initrd_dump ( void ) { /* Dump initrd locations */ for_each_image ( initrd ) { DBGC ( &images, "INITRD %s at [%#08lx,%#08lx)\n", - initrd->name, user_to_phys ( initrd->data, 0 ), - user_to_phys ( initrd->data, initrd->len ) ); - DBGC2_MD5A ( &images, user_to_phys ( initrd->data, 0 ), + initrd->name, virt_to_phys ( initrd->data ), + ( virt_to_phys ( initrd->data ) + initrd->len ) ); + DBGC2_MD5A ( &images, virt_to_phys ( initrd->data ), initrd->data, initrd->len ); } } @@ -239,7 +239,7 @@ void initrd_reshuffle ( userptr_t bottom ) { /* Debug */ DBGC ( &images, "INITRD region [%#08lx,%#08lx)\n", - user_to_phys ( bottom, 0 ), user_to_phys ( top, 0 ) ); + virt_to_phys ( bottom ), virt_to_phys ( top ) ); initrd_dump(); /* Squash initrds as high as possible in memory */ diff --git a/src/arch/x86/image/multiboot.c b/src/arch/x86/image/multiboot.c index fe21f1f1a..24f67e02f 100644 --- a/src/arch/x86/image/multiboot.c +++ b/src/arch/x86/image/multiboot.c @@ -212,7 +212,7 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start, start = ( ( start + 0xfff ) & ~0xfff ); /* Prepare segment */ - if ( ( rc = prep_segment ( phys_to_user ( start ), + if ( ( rc = prep_segment ( phys_to_virt ( start ), module_image->len, module_image->len ) ) != 0 ) { DBGC ( image, "MULTIBOOT %p could not prepare module " @@ -222,7 +222,7 @@ static int multiboot_add_modules ( struct image *image, physaddr_t start, } /* Copy module */ - memcpy ( phys_to_user ( start ), module_image->data, + memcpy ( phys_to_virt ( start ), module_image->data, module_image->len ); /* Add module to list */ @@ -342,7 +342,7 @@ static int multiboot_load_raw ( struct image *image, ( image->len - offset ) ); memsz = ( hdr->mb.bss_end_addr ? ( hdr->mb.bss_end_addr - hdr->mb.load_addr ) : filesz ); - buffer = phys_to_user ( hdr->mb.load_addr ); + buffer = phys_to_virt ( hdr->mb.load_addr ); if ( ( rc = prep_segment ( buffer, filesz, memsz ) ) != 0 ) { DBGC ( image, "MULTIBOOT %p could not prepare segment: %s\n", image, strerror ( rc ) ); diff --git a/src/arch/x86/image/nbi.c b/src/arch/x86/image/nbi.c index 0b02a8985..1f72c1287 100644 --- a/src/arch/x86/image/nbi.c +++ b/src/arch/x86/image/nbi.c @@ -181,7 +181,7 @@ static int nbi_process_segments ( struct image *image, /* Calculate segment load address */ switch ( NBI_LOADADDR_FLAGS ( sh.flags ) ) { case NBI_LOADADDR_ABS: - dest = phys_to_user ( sh.loadaddr ); + dest = phys_to_virt ( sh.loadaddr ); break; case NBI_LOADADDR_AFTER: dest = ( dest + memsz + sh.loadaddr ); @@ -194,7 +194,7 @@ static int nbi_process_segments ( struct image *image, * maintains backwards compatibility with * previous versions of Etherboot. */ - dest = phys_to_user ( ( extmemsize() + 1024 ) * 1024 + dest = phys_to_virt ( ( extmemsize() + 1024 ) * 1024 - sh.loadaddr ); break; default: diff --git a/src/arch/x86/image/sdi.c b/src/arch/x86/image/sdi.c index 5bb5a7569..5e22daeb3 100644 --- a/src/arch/x86/image/sdi.c +++ b/src/arch/x86/image/sdi.c @@ -92,16 +92,17 @@ static int sdi_exec ( struct image *image ) { return -ENOTTY; } DBGC ( image, "SDI %p image at %08lx+%08zx\n", - image, user_to_phys ( image->data, 0 ), image->len ); - DBGC ( image, "SDI %p boot code at %08lx+%llx\n", image, - user_to_phys ( image->data, sdi.boot_offset ), sdi.boot_size ); + image, virt_to_phys ( image->data ), image->len ); + DBGC ( image, "SDI %p boot code at %08llx+%llx\n", image, + ( virt_to_phys ( image->data ) + sdi.boot_offset ), + sdi.boot_size ); /* Copy boot code */ memcpy ( real_to_user ( SDI_BOOT_SEG, SDI_BOOT_OFF ), ( image->data + sdi.boot_offset ), sdi.boot_size ); /* Jump to boot code */ - sdiptr = ( user_to_phys ( image->data, 0 ) | SDI_WTF ); + sdiptr = ( virt_to_phys ( image->data ) | SDI_WTF ); __asm__ __volatile__ ( REAL_CODE ( "ljmp %0, %1\n\t" ) : : "i" ( SDI_BOOT_SEG ), "i" ( SDI_BOOT_OFF ), diff --git a/src/arch/x86/image/ucode.c b/src/arch/x86/image/ucode.c index 9b6b5067a..a9fa8b8c4 100644 --- a/src/arch/x86/image/ucode.c +++ b/src/arch/x86/image/ucode.c @@ -165,7 +165,7 @@ static int ucode_status ( struct ucode_update *update, assert ( id <= control->apic_max ); /* Read status report */ - copy_from_user ( &status, phys_to_user ( control->status ), + copy_from_user ( &status, phys_to_virt ( control->status ), ( id * sizeof ( status ) ), sizeof ( status ) ); /* Ignore empty optional status reports */ @@ -261,7 +261,7 @@ static int ucode_update_all ( struct image *image, /* Construct control structure */ memset ( &control, 0, sizeof ( control ) ); control.desc = virt_to_phys ( update->desc ); - control.status = user_to_phys ( status, 0 ); + control.status = virt_to_phys ( status ); vendor = update->vendor; if ( vendor ) { control.ver_clear = vendor->ver_clear; @@ -446,8 +446,8 @@ static int ucode_parse_intel ( struct image *image, size_t start, /* Populate descriptor */ desc.signature = hdr.signature; desc.version = hdr.version; - desc.address = user_to_phys ( image->data, - ( start + sizeof ( hdr ) ) ); + desc.address = ( virt_to_phys ( image->data ) + + start + sizeof ( hdr ) ); /* Add non-extended descriptor, if applicable */ ucode_describe ( image, start, &ucode_intel, &desc, hdr.platforms, @@ -589,7 +589,8 @@ static int ucode_parse_amd ( struct image *image, size_t start, copy_from_user ( &patch, image->data, ( start + offset ), sizeof ( patch ) ); desc.version = patch.version; - desc.address = user_to_phys ( image->data, ( start + offset ) ); + desc.address = ( virt_to_phys ( image->data ) + + start + offset ); offset += phdr.len; /* Parse equivalence table to find matching signatures */ diff --git a/src/arch/x86/include/librm.h b/src/arch/x86/include/librm.h index 9ed91022e..7755abdcf 100644 --- a/src/arch/x86/include/librm.h +++ b/src/arch/x86/include/librm.h @@ -85,33 +85,32 @@ extern const unsigned long virt_offset; /** * Convert physical address to user pointer * - * @v phys_addr Physical address - * @ret userptr User pointer + * @v phys Physical address + * @ret virt Virtual address */ -static inline __always_inline userptr_t -UACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) { +static inline __always_inline void * +UACCESS_INLINE ( librm, phys_to_virt ) ( unsigned long phys ) { /* In a 64-bit build, any valid physical address is directly * usable as a virtual address, since the low 4GB is * identity-mapped. */ if ( sizeof ( physaddr_t ) > sizeof ( uint32_t ) ) - return ( ( userptr_t ) phys_addr ); + return ( ( void * ) phys ); /* In a 32-bit build, subtract virt_offset */ - return ( ( userptr_t ) ( phys_addr - virt_offset ) ); + return ( ( void * ) ( phys - virt_offset ) ); } /** - * Convert user buffer to physical address + * Convert virtual address to physical address * - * @v userptr User pointer - * @v offset Offset from user pointer - * @ret phys_addr Physical address + * @v virt Virtual address + * @ret phys Physical address */ -static inline __always_inline unsigned long -UACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) { - unsigned long addr = ( ( unsigned long ) ( userptr + offset ) ); +static inline __always_inline physaddr_t +UACCESS_INLINE ( librm, virt_to_phys ) ( volatile const void *virt ) { + physaddr_t addr = ( ( physaddr_t ) virt ); /* In a 64-bit build, any virtual address in the low 4GB is * directly usable as a physical address, since the low 4GB is diff --git a/src/arch/x86/include/realmode.h b/src/arch/x86/include/realmode.h index 4defd3b97..616db5eb9 100644 --- a/src/arch/x86/include/realmode.h +++ b/src/arch/x86/include/realmode.h @@ -73,7 +73,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ static inline __always_inline userptr_t real_to_user ( unsigned int segment, unsigned int offset ) { - return ( phys_to_user ( ( segment << 4 ) + offset ) ); + return ( phys_to_virt ( ( segment << 4 ) + offset ) ); } /** diff --git a/src/arch/x86/interface/pcbios/bios_cachedhcp.c b/src/arch/x86/interface/pcbios/bios_cachedhcp.c index bea803d6e..05d89b3b7 100644 --- a/src/arch/x86/interface/pcbios/bios_cachedhcp.c +++ b/src/arch/x86/interface/pcbios/bios_cachedhcp.c @@ -60,7 +60,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 ) ); diff --git a/src/arch/x86/interface/pcbios/bios_smbios.c b/src/arch/x86/interface/pcbios/bios_smbios.c index 366679d36..ab53d424b 100644 --- a/src/arch/x86/interface/pcbios/bios_smbios.c +++ b/src/arch/x86/interface/pcbios/bios_smbios.c @@ -54,7 +54,7 @@ static int bios_find_smbios2 ( struct smbios *smbios ) { return rc; /* Fill in entry point descriptor structure */ - smbios->address = phys_to_user ( entry.smbios_address ); + 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 ); @@ -85,7 +85,7 @@ static int bios_find_smbios3 ( struct smbios *smbios ) { } /* Fill in entry point descriptor structure */ - smbios->address = phys_to_user ( entry.smbios_address ); + smbios->address = phys_to_virt ( entry.smbios_address ); smbios->len = entry.smbios_len; smbios->count = 0; smbios->version = SMBIOS_VERSION ( entry.major, entry.minor ); diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c index 372d40ba3..d60f7c7cc 100644 --- a/src/arch/x86/interface/pcbios/int13.c +++ b/src/arch/x86/interface/pcbios/int13.c @@ -743,7 +743,7 @@ 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 { @@ -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,7 +1455,7 @@ 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, + copy_from_user ( &catalog, phys_to_virt ( eltorito_cmd.buffer ), 0, sizeof ( catalog ) ); /* Sanity checks */ diff --git a/src/arch/x86/interface/pcbios/memtop_umalloc.c b/src/arch/x86/interface/pcbios/memtop_umalloc.c index 8239b23b8..b87d22516 100644 --- a/src/arch/x86/interface/pcbios/memtop_umalloc.c +++ b/src/arch/x86/interface/pcbios/memtop_umalloc.c @@ -106,7 +106,7 @@ size_t largest_memblock ( userptr_t *start ) { /* Use largest block */ if ( region_len > len ) { DBG ( "...new best block found\n" ); - *start = phys_to_user ( region_start ); + *start = phys_to_virt ( region_start ); len = region_len; } } @@ -124,7 +124,7 @@ static void init_eheap ( void ) { heap_size = largest_memblock ( &base ); bottom = top = ( base + heap_size ); DBG ( "External heap grows downwards from %lx (size %zx)\n", - user_to_phys ( top, 0 ), heap_size ); + virt_to_phys ( top ), heap_size ); } /** @@ -141,8 +141,8 @@ static void ecollect_free ( void ) { sizeof ( extmem ) ); if ( extmem.used ) break; - DBG ( "EXTMEM freeing [%lx,%lx)\n", user_to_phys ( bottom, 0 ), - user_to_phys ( bottom, extmem.size ) ); + DBG ( "EXTMEM freeing [%lx,%lx)\n", virt_to_phys ( bottom ), + ( virt_to_phys ( bottom ) + extmem.size ) ); len = ( extmem.size + sizeof ( extmem ) ); bottom += len; heap_size += len; @@ -182,7 +182,7 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { ptr = bottom = ( bottom - sizeof ( extmem ) ); heap_size -= sizeof ( extmem ); DBG ( "EXTMEM allocating [%lx,%lx)\n", - user_to_phys ( ptr, 0 ), user_to_phys ( ptr, 0 ) ); + virt_to_phys ( ptr ), virt_to_phys ( ptr ) ); extmem.size = 0; } extmem.used = ( new_size > 0 ); @@ -191,7 +191,7 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { if ( ptr == bottom ) { /* Update block */ new = ( ptr - ( new_size - extmem.size ) ); - align = ( user_to_phys ( new, 0 ) & ( EM_ALIGN - 1 ) ); + align = ( virt_to_phys ( new ) & ( EM_ALIGN - 1 ) ); new_size += align; new -= align; if ( new_size > ( heap_size + extmem.size ) ) { @@ -199,10 +199,10 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { 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 )); + virt_to_phys ( ptr ), + ( virt_to_phys ( ptr ) + extmem.size ), + virt_to_phys ( new ), + ( virt_to_phys ( new ) + new_size ) ); memmove ( new, ptr, ( ( extmem.size < new_size ) ? extmem.size : new_size ) ); bottom = new; @@ -213,8 +213,8 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { 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 ) ); + virt_to_phys ( ptr ), + ( virt_to_phys ( ptr ) + extmem.size ) ); return UNULL; } } @@ -225,9 +225,9 @@ static userptr_t memtop_urealloc ( userptr_t ptr, size_t new_size ) { /* 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 ) ); + hide_umalloc ( ( virt_to_phys ( bottom ) - + ( ( bottom == top ) ? 0 : sizeof ( extmem ) ) ), + virt_to_phys ( top ) ); return ( new_size ? new : UNOWHERE ); } diff --git a/src/arch/x86/interface/pcbios/rsdp.c b/src/arch/x86/interface/pcbios/rsdp.c index 3c67b7525..02c58c780 100644 --- a/src/arch/x86/interface/pcbios/rsdp.c +++ b/src/arch/x86/interface/pcbios/rsdp.c @@ -78,10 +78,10 @@ static userptr_t rsdp_find_rsdt_range ( userptr_t start, size_t len ) { 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; } @@ -114,7 +114,7 @@ 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; diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c index 86edbda42..61609fa8c 100644 --- a/src/arch/x86/interface/pcbios/vesafb.c +++ b/src/arch/x86/interface/pcbios/vesafb.c @@ -473,7 +473,7 @@ static int vesafb_init ( struct console_configuration *config ) { vesafb_font(); /* 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_tftp.c b/src/arch/x86/interface/pxe/pxe_tftp.c index 3b4c6d847..2c2eccca4 100644 --- a/src/arch/x86/interface/pxe/pxe_tftp.c +++ b/src/arch/x86/interface/pxe/pxe_tftp.c @@ -492,7 +492,7 @@ 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(); diff --git a/src/arch/x86/interface/syslinux/com32_call.c b/src/arch/x86/interface/syslinux/com32_call.c index da9d6491a..47be69f9f 100644 --- a/src/arch/x86/interface/syslinux/com32_call.c +++ b/src/arch/x86/interface/syslinux/com32_call.c @@ -49,7 +49,7 @@ 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 ( virt_to_user( &com32_regs ), phys_to_user ( inregs_phys ), + memcpy ( virt_to_user( &com32_regs ), phys_to_virt ( inregs_phys ), sizeof ( com32sys_t ) ); com32_int_vector = interrupt; @@ -107,7 +107,7 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad : : ); if ( outregs_phys ) { - memcpy ( phys_to_user ( outregs_phys ), + memcpy ( phys_to_virt ( outregs_phys ), virt_to_user ( &com32_regs ), sizeof ( com32sys_t ) ); } } @@ -120,7 +120,7 @@ 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 ( virt_to_user( &com32_regs ), phys_to_user ( inregs_phys ), + memcpy ( virt_to_user( &com32_regs ), phys_to_virt ( inregs_phys ), sizeof ( com32sys_t ) ); com32_farcall_proc = proc; @@ -167,7 +167,7 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t : : ); if ( outregs_phys ) { - memcpy ( phys_to_user ( outregs_phys ), + memcpy ( phys_to_virt ( outregs_phys ), virt_to_user ( &com32_regs ), sizeof ( com32sys_t ) ); } } @@ -181,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_user_to_rm_stack ( phys_to_virt ( stack ), stacksz ); com32_farcall_proc = proc; __asm__ __volatile__ ( diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index f26fcad0a..d7e923b70 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -114,8 +114,8 @@ static void shuffle ( unsigned int list_segment, unsigned int list_offset, unsig /* 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 ); + userptr_t src_u = phys_to_virt ( shuf[ i ].src ); + userptr_t dest_u = phys_to_virt ( shuf[ i ].dest ); if ( shuf[ i ].src == 0xFFFFFFFF ) { /* Fill with 0 instead of copying */ diff --git a/src/arch/x86/transitions/librm_mgmt.c b/src/arch/x86/transitions/librm_mgmt.c index 82e8eab39..fbc653969 100644 --- a/src/arch/x86/transitions/librm_mgmt.c +++ b/src/arch/x86/transitions/librm_mgmt.c @@ -428,8 +428,8 @@ void setup_sipi ( unsigned int vector, uint32_t handler, copy_to_real ( ( vector << 8 ), 0, sipi, ( ( size_t ) sipi_len ) ); } -PROVIDE_UACCESS_INLINE ( librm, phys_to_user ); -PROVIDE_UACCESS_INLINE ( librm, user_to_phys ); +PROVIDE_UACCESS_INLINE ( librm, phys_to_virt ); +PROVIDE_UACCESS_INLINE ( librm, virt_to_phys ); PROVIDE_UACCESS_INLINE ( librm, virt_to_user ); PROVIDE_UACCESS_INLINE ( librm, memchr_user ); PROVIDE_IOMAP_INLINE ( pages, io_to_bus ); diff --git a/src/core/acpi.c b/src/core/acpi.c index 526bf8555..d7da0ccc1 100644 --- a/src/core/acpi.c +++ b/src/core/acpi.c @@ -128,16 +128,16 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) { copy_from_user ( &acpi, rsdt, 0, sizeof ( acpi ) ); if ( acpi.signature != cpu_to_le32 ( RSDT_SIGNATURE ) ) { DBGC ( colour, "RSDT %#08lx has invalid signature:\n", - user_to_phys ( rsdt, 0 ) ); - DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi, + virt_to_phys ( rsdt ) ); + DBGC_HDA ( colour, virt_to_phys ( rsdt ), &acpi, sizeof ( acpi ) ); return UNULL; } len = le32_to_cpu ( acpi.length ); if ( len < sizeof ( rsdtab->acpi ) ) { DBGC ( colour, "RSDT %#08lx has invalid length:\n", - user_to_phys ( rsdt, 0 ) ); - DBGC_HDA ( colour, user_to_phys ( rsdt, 0 ), &acpi, + virt_to_phys ( rsdt ) ); + DBGC_HDA ( colour, virt_to_phys ( rsdt ), &acpi, sizeof ( acpi ) ); return UNULL; } @@ -154,7 +154,7 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) { sizeof ( entry ) ); /* Read table header */ - table = phys_to_user ( entry ); + table = phys_to_virt ( entry ); copy_from_user ( &acpi.signature, table, 0, sizeof ( acpi.signature ) ); @@ -169,20 +169,20 @@ userptr_t acpi_find_via_rsdt ( uint32_t signature, unsigned int index ) { /* Check table integrity */ if ( acpi_checksum ( table ) != 0 ) { DBGC ( colour, "RSDT %#08lx found %s with bad " - "checksum at %08lx\n", user_to_phys ( rsdt, 0 ), + "checksum at %08lx\n", virt_to_phys ( rsdt ), acpi_name ( signature ), - user_to_phys ( table, 0 ) ); + virt_to_phys ( table ) ); break; } DBGC ( colour, "RSDT %#08lx found %s at %08lx\n", - user_to_phys ( rsdt, 0 ), acpi_name ( signature ), - user_to_phys ( table, 0 ) ); + virt_to_phys ( rsdt ), acpi_name ( signature ), + virt_to_phys ( table ) ); return table; } DBGC ( colour, "RSDT %#08lx could not find %s\n", - user_to_phys ( rsdt, 0 ), acpi_name ( signature ) ); + virt_to_phys ( rsdt ), acpi_name ( signature ) ); return UNULL; } @@ -218,7 +218,7 @@ static int acpi_zsdt ( userptr_t zsdt, uint32_t signature, void *data, if ( buf != cpu_to_le32 ( signature ) ) continue; DBGC ( zsdt, "DSDT/SSDT %#08lx found %s at offset %#zx\n", - user_to_phys ( zsdt, 0 ), acpi_name ( signature ), + virt_to_phys ( zsdt ), acpi_name ( signature ), offset ); /* Attempt to extract data */ @@ -251,7 +251,7 @@ int acpi_extract ( uint32_t signature, void *data, fadt = acpi_table ( FADT_SIGNATURE, 0 ); if ( fadt ) { copy_from_user ( &fadtab, fadt, 0, sizeof ( fadtab ) ); - dsdt = phys_to_user ( fadtab.dsdt ); + dsdt = phys_to_virt ( fadtab.dsdt ); if ( ( rc = acpi_zsdt ( dsdt, signature, data, extract ) ) == 0 ) return 0; diff --git a/src/core/blocktrans.c b/src/core/blocktrans.c index f9dcb95d2..f3be2ba2b 100644 --- a/src/core/blocktrans.c +++ b/src/core/blocktrans.c @@ -248,7 +248,7 @@ int block_translate ( struct interface *block, userptr_t buffer, size_t size ) { DBGC2 ( blktrans, "BLKTRANS %p created", blktrans ); if ( buffer ) { DBGC2 ( blktrans, " for %#lx+%#zx", - user_to_phys ( buffer, 0 ), size ); + virt_to_phys ( buffer ), size ); } DBGC2 ( blktrans, "\n" ); return 0; diff --git a/src/core/cachedhcp.c b/src/core/cachedhcp.c index 04945e646..07589f0b8 100644 --- a/src/core/cachedhcp.c +++ b/src/core/cachedhcp.c @@ -251,7 +251,7 @@ int cachedhcp_record ( struct cached_dhcp_packet *cache, unsigned int vlan, /* Store as cached packet */ DBGC ( colour, "CACHEDHCP %s at %#08lx+%#zx/%#zx\n", cache->name, - user_to_phys ( data, 0 ), len, max_len ); + virt_to_phys ( data ), len, max_len ); cache->dhcppkt = dhcppkt; cache->vlan = vlan; diff --git a/src/core/fbcon.c b/src/core/fbcon.c index 8d05484e2..6d08ac419 100644 --- a/src/core/fbcon.c +++ b/src/core/fbcon.c @@ -613,8 +613,8 @@ int fbcon_init ( struct fbcon *fbcon, userptr_t start, /* Derive overall length */ fbcon->len = ( pixel->height * pixel->stride ); DBGC ( fbcon, "FBCON %p at [%08lx,%08lx)\n", fbcon, - user_to_phys ( fbcon->start, 0 ), - user_to_phys ( fbcon->start, fbcon->len ) ); + virt_to_phys ( fbcon->start ), + ( virt_to_phys ( fbcon->start ) + fbcon->len ) ); /* Calculate margin. If the actual screen size is larger than * the requested screen size, then update the margins so that diff --git a/src/core/image.c b/src/core/image.c index 709d0da9c..e90d82ffb 100644 --- a/src/core/image.c +++ b/src/core/image.c @@ -300,8 +300,8 @@ int register_image ( struct image *image ) { image->flags |= IMAGE_REGISTERED; list_add_tail ( &image->list, &images ); DBGC ( image, "IMAGE %s at [%lx,%lx) registered\n", - image->name, user_to_phys ( image->data, 0 ), - user_to_phys ( image->data, image->len ) ); + image->name, virt_to_phys ( image->data ), + ( virt_to_phys ( image->data ) + image->len ) ); /* Try to detect image type, if applicable. Ignore failures, * since we expect to handle some unrecognised images diff --git a/src/core/uaccess.c b/src/core/uaccess.c index 1c33c10b8..32bd1ac38 100644 --- a/src/core/uaccess.c +++ b/src/core/uaccess.c @@ -32,7 +32,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ /* Flat address space user access API */ -PROVIDE_UACCESS_INLINE ( flat, phys_to_user ); -PROVIDE_UACCESS_INLINE ( flat, user_to_phys ); +PROVIDE_UACCESS_INLINE ( flat, phys_to_virt ); +PROVIDE_UACCESS_INLINE ( flat, virt_to_phys ); PROVIDE_UACCESS_INLINE ( flat, virt_to_user ); PROVIDE_UACCESS_INLINE ( flat, memchr_user ); diff --git a/src/drivers/block/srp.c b/src/drivers/block/srp.c index ab4812519..c12f230f7 100644 --- a/src/drivers/block/srp.c +++ b/src/drivers/block/srp.c @@ -428,7 +428,7 @@ static int srp_cmd ( struct srp_device *srpdev, cmd->data_buffer_formats |= SRP_CMD_DO_FMT_DIRECT; data_out = iob_put ( iobuf, sizeof ( *data_out ) ); data_out->address = - cpu_to_be64 ( user_to_phys ( command->data_out, 0 ) ); + cpu_to_be64 ( virt_to_phys ( command->data_out ) ); data_out->handle = ntohl ( srpdev->memory_handle ); data_out->len = ntohl ( command->data_out_len ); } @@ -438,7 +438,7 @@ static int srp_cmd ( struct srp_device *srpdev, cmd->data_buffer_formats |= SRP_CMD_DI_FMT_DIRECT; data_in = iob_put ( iobuf, sizeof ( *data_in ) ); data_in->address = - cpu_to_be64 ( user_to_phys ( command->data_in, 0 ) ); + cpu_to_be64 ( virt_to_phys ( command->data_in ) ); data_in->handle = ntohl ( srpdev->memory_handle ); data_in->len = ntohl ( command->data_in_len ); } diff --git a/src/drivers/infiniband/arbel.c b/src/drivers/infiniband/arbel.c index 8be06d93d..4cb4167e0 100644 --- a/src/drivers/infiniband/arbel.c +++ b/src/drivers/infiniband/arbel.c @@ -2079,7 +2079,7 @@ static int arbel_start_firmware ( struct arbel *arbel ) { } else { assert ( arbel->firmware_len == fw_len ); } - fw_base = user_to_phys ( arbel->firmware_area, 0 ); + fw_base = virt_to_phys ( arbel->firmware_area ); DBGC ( arbel, "Arbel %p firmware area at [%08lx,%08lx)\n", arbel, fw_base, ( fw_base + fw_len ) ); if ( ( rc = arbel_map_vpm ( arbel, arbel_cmd_map_fa, @@ -2452,7 +2452,7 @@ static int arbel_alloc_icm ( struct arbel *arbel, assert ( arbel->icm_len == icm_len ); assert ( arbel->icm_aux_len == icm_aux_len ); } - icm_phys = user_to_phys ( arbel->icm, 0 ); + icm_phys = virt_to_phys ( arbel->icm ); /* Allocate doorbell UAR */ arbel->db_rec = malloc_phys ( ARBEL_PAGE_SIZE, ARBEL_PAGE_SIZE ); diff --git a/src/drivers/infiniband/golan.c b/src/drivers/infiniband/golan.c index 81fc6c0f0..a33bad9ff 100755 --- a/src/drivers/infiniband/golan.c +++ b/src/drivers/infiniband/golan.c @@ -486,8 +486,8 @@ static inline int golan_provide_pages ( struct golan *golan , uint32_t pages for ( i = 0 , j = MANAGE_PAGES_PSA_OFFSET; i < pas_num; ++i ,++j, next_page_addr += GOLAN_PAGE_SIZE ) { addr = next_page_addr; - if (GOLAN_PAGE_MASK & user_to_phys(addr, 0)) { - DBGC (golan ,"Addr not Page alligned [%lx]\n", user_to_phys(addr, 0)); + if (GOLAN_PAGE_MASK & virt_to_phys(addr)) { + DBGC (golan ,"Addr not Page alligned [%lx]\n", virt_to_phys(addr)); } mailbox->mblock.data[j] = USR_2_BE64_BUS(addr); } diff --git a/src/drivers/infiniband/golan.h b/src/drivers/infiniband/golan.h index 2fd06ecf0..f7da1e960 100755 --- a/src/drivers/infiniband/golan.h +++ b/src/drivers/infiniband/golan.h @@ -69,8 +69,8 @@ FILE_LICENCE ( GPL2_OR_LATER ); #define VIRT_2_BE64_BUS( addr ) cpu_to_be64(((unsigned long long )virt_to_bus(addr))) #define BE64_BUS_2_VIRT( addr ) bus_to_virt(be64_to_cpu(addr)) -#define USR_2_BE64_BUS( addr ) cpu_to_be64(((unsigned long long )user_to_phys(addr, 0))) -#define BE64_BUS_2_USR( addr ) be64_to_cpu(phys_to_user(addr)) +#define USR_2_BE64_BUS( addr ) cpu_to_be64(((unsigned long long )virt_to_phys(addr))) +#define BE64_BUS_2_USR( addr ) be64_to_cpu(phys_to_virt(addr)) #define GET_INBOX(golan, idx) (&(((struct mbox *)(golan->mboxes.inbox))[idx])) #define GET_OUTBOX(golan, idx) (&(((struct mbox *)(golan->mboxes.outbox))[idx])) diff --git a/src/drivers/infiniband/hermon.c b/src/drivers/infiniband/hermon.c index e5c3544fa..3138d8bfb 100644 --- a/src/drivers/infiniband/hermon.c +++ b/src/drivers/infiniband/hermon.c @@ -2382,7 +2382,7 @@ static int hermon_start_firmware ( struct hermon *hermon ) { } else { assert ( hermon->firmware_len == fw_len ); } - fw_base = user_to_phys ( hermon->firmware_area, 0 ); + fw_base = virt_to_phys ( hermon->firmware_area ); DBGC ( hermon, "Hermon %p firmware area at physical [%08lx,%08lx)\n", hermon, fw_base, ( fw_base + fw_len ) ); if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa, @@ -2752,7 +2752,7 @@ static int hermon_map_icm ( struct hermon *hermon, assert ( hermon->icm_len == icm_len ); assert ( hermon->icm_aux_len == icm_aux_len ); } - icm_phys = user_to_phys ( hermon->icm, 0 ); + icm_phys = virt_to_phys ( hermon->icm ); /* Map ICM auxiliary area */ DBGC ( hermon, "Hermon %p mapping ICM AUX => %08lx\n", diff --git a/src/drivers/net/exanic.c b/src/drivers/net/exanic.c index 14a17df47..b3148e090 100644 --- a/src/drivers/net/exanic.c +++ b/src/drivers/net/exanic.c @@ -406,7 +406,7 @@ static int exanic_open ( struct net_device *netdev ) { port->rx_cons = 0; /* Map receive region */ - exanic_write_base ( phys_to_bus ( user_to_phys ( port->rx, 0 ) ), + exanic_write_base ( phys_to_bus ( virt_to_phys ( port->rx ) ), ( port->regs + EXANIC_PORT_RX_BASE ) ); /* Enable promiscuous mode */ @@ -729,8 +729,8 @@ static int exanic_probe_port ( struct exanic *exanic, struct device *dev, DBGC ( port, "EXANIC %s port %d TX [%#05zx,%#05zx) TXF %#02x RX " "[%#lx,%#lx)\n", netdev->name, index, port->tx_offset, ( port->tx_offset + tx_len ), port->txf_slot, - user_to_phys ( port->rx, 0 ), - user_to_phys ( port->rx, EXANIC_RX_LEN ) ); + virt_to_phys ( port->rx ), + ( virt_to_phys ( port->rx ) + EXANIC_RX_LEN ) ); /* Set initial link state */ exanic_check_link ( netdev ); diff --git a/src/drivers/net/gve.c b/src/drivers/net/gve.c index 2cbc401f5..f9ec388a4 100644 --- a/src/drivers/net/gve.c +++ b/src/drivers/net/gve.c @@ -521,14 +521,14 @@ static int gve_deconfigure ( struct gve_nic *gve ) { static int gve_register ( struct gve_nic *gve, struct gve_qpl *qpl ) { struct gve_pages *pages = &gve->scratch.buf->pages; union gve_admin_command *cmd; - physaddr_t addr; + void *addr; unsigned int i; int rc; /* Build page address list */ for ( i = 0 ; i < qpl->count ; i++ ) { - addr = user_to_phys ( qpl->data, ( i * GVE_PAGE_SIZE ) ); - pages->addr[i] = cpu_to_be64 ( dma_phys ( &qpl->map, addr ) ); + addr = ( qpl->data + ( i * GVE_PAGE_SIZE ) ); + pages->addr[i] = cpu_to_be64 ( dma ( &qpl->map, addr ) ); } /* Construct request */ @@ -575,11 +575,10 @@ static void gve_create_tx_param ( struct gve_queue *queue, union gve_admin_command *cmd ) { struct gve_admin_create_tx *create = &cmd->create_tx; const struct gve_queue_type *type = queue->type; - physaddr_t desc = user_to_phys ( queue->desc, 0 ); /* Construct request parameters */ create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) ); - create->desc = cpu_to_be64 ( dma_phys ( &queue->desc_map, desc ) ); + create->desc = cpu_to_be64 ( dma ( &queue->desc_map, queue->desc ) ); create->qpl_id = cpu_to_be32 ( type->qpl ); create->notify_id = cpu_to_be32 ( type->irq ); } @@ -594,14 +593,12 @@ static void gve_create_rx_param ( struct gve_queue *queue, union gve_admin_command *cmd ) { struct gve_admin_create_rx *create = &cmd->create_rx; const struct gve_queue_type *type = queue->type; - physaddr_t desc = user_to_phys ( queue->desc, 0 ); - physaddr_t cmplt = user_to_phys ( queue->cmplt, 0 ); /* Construct request parameters */ create->notify_id = cpu_to_be32 ( type->irq ); create->res = cpu_to_be64 ( dma ( &queue->res_map, queue->res ) ); - create->desc = cpu_to_be64 ( dma_phys ( &queue->desc_map, desc ) ); - create->cmplt = cpu_to_be64 ( dma_phys ( &queue->cmplt_map, cmplt ) ); + create->desc = cpu_to_be64 ( dma ( &queue->desc_map, queue->desc ) ); + create->cmplt = cpu_to_be64 ( dma ( &queue->cmplt_map, queue->cmplt )); create->qpl_id = cpu_to_be32 ( type->qpl ); create->bufsz = cpu_to_be16 ( GVE_BUF_SIZE ); } @@ -760,8 +757,8 @@ static int gve_alloc_qpl ( struct gve_nic *gve, struct gve_qpl *qpl, return -ENOMEM; DBGC ( gve, "GVE %p QPL %#08x at [%08lx,%08lx)\n", - gve, qpl->id, user_to_phys ( qpl->data, 0 ), - user_to_phys ( qpl->data, len ) ); + gve, qpl->id, virt_to_phys ( qpl->data ), + ( virt_to_phys ( qpl->data ) + len ) ); return 0; } @@ -883,8 +880,8 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) { goto err_desc; } DBGC ( gve, "GVE %p %s descriptors at [%08lx,%08lx)\n", - gve, type->name, user_to_phys ( queue->desc, 0 ), - user_to_phys ( queue->desc, desc_len ) ); + gve, type->name, virt_to_phys ( queue->desc ), + ( virt_to_phys ( queue->desc ) + desc_len ) ); /* Allocate completions */ if ( cmplt_len ) { @@ -895,8 +892,8 @@ static int gve_alloc_queue ( struct gve_nic *gve, struct gve_queue *queue ) { goto err_cmplt; } DBGC ( gve, "GVE %p %s completions at [%08lx,%08lx)\n", - gve, type->name, user_to_phys ( queue->cmplt, 0 ), - user_to_phys ( queue->cmplt, cmplt_len ) ); + gve, type->name, virt_to_phys ( queue->cmplt ), + ( virt_to_phys ( queue->cmplt ) + cmplt_len ) ); } /* Allocate queue resources */ diff --git a/src/drivers/net/thunderx.c b/src/drivers/net/thunderx.c index 1865a9b91..3d213b167 100644 --- a/src/drivers/net/thunderx.c +++ b/src/drivers/net/thunderx.c @@ -118,14 +118,14 @@ static int txnic_create_sq ( struct txnic *vnic ) { writeq ( TXNIC_QS_SQ_CFG_RESET, ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) ); /* Configure and enable send queue */ - writeq ( user_to_phys ( vnic->sq.sqe, 0 ), + writeq ( virt_to_phys ( vnic->sq.sqe ), ( vnic->regs + TXNIC_QS_SQ_BASE(0) ) ); writeq ( ( TXNIC_QS_SQ_CFG_ENA | TXNIC_QS_SQ_CFG_QSIZE_1K ), ( vnic->regs + TXNIC_QS_SQ_CFG(0) ) ); DBGC ( vnic, "TXNIC %s SQ at [%08lx,%08lx)\n", - vnic->name, user_to_phys ( vnic->sq.sqe, 0 ), - user_to_phys ( vnic->sq.sqe, TXNIC_SQ_SIZE ) ); + vnic->name, virt_to_phys ( vnic->sq.sqe ), + ( virt_to_phys ( vnic->sq.sqe ) + TXNIC_SQ_SIZE ) ); return 0; } @@ -277,7 +277,7 @@ static int txnic_create_rq ( struct txnic *vnic ) { ( vnic->regs + TXNIC_QS_RBDR_CFG(0) ) ); /* Configure and enable receive buffer descriptor ring */ - writeq ( user_to_phys ( vnic->rq.rqe, 0 ), + writeq ( virt_to_phys ( vnic->rq.rqe ), ( vnic->regs + TXNIC_QS_RBDR_BASE(0) ) ); writeq ( ( TXNIC_QS_RBDR_CFG_ENA | TXNIC_QS_RBDR_CFG_QSIZE_8K | TXNIC_QS_RBDR_CFG_LINES ( TXNIC_RQE_SIZE / @@ -288,8 +288,8 @@ static int txnic_create_rq ( struct txnic *vnic ) { writeq ( TXNIC_QS_RQ_CFG_ENA, ( vnic->regs + TXNIC_QS_RQ_CFG(0) ) ); DBGC ( vnic, "TXNIC %s RQ at [%08lx,%08lx)\n", - vnic->name, user_to_phys ( vnic->rq.rqe, 0 ), - user_to_phys ( vnic->rq.rqe, TXNIC_RQ_SIZE ) ); + vnic->name, virt_to_phys ( vnic->rq.rqe ), + ( virt_to_phys ( vnic->rq.rqe ) + TXNIC_RQ_SIZE ) ); return 0; } @@ -463,14 +463,14 @@ static int txnic_create_cq ( struct txnic *vnic ) { writeq ( TXNIC_QS_CQ_CFG_RESET, ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) ); /* Configure and enable completion queue */ - writeq ( user_to_phys ( vnic->cq.cqe, 0 ), + writeq ( virt_to_phys ( vnic->cq.cqe ), ( vnic->regs + TXNIC_QS_CQ_BASE(0) ) ); writeq ( ( TXNIC_QS_CQ_CFG_ENA | TXNIC_QS_CQ_CFG_QSIZE_256 ), ( vnic->regs + TXNIC_QS_CQ_CFG(0) ) ); DBGC ( vnic, "TXNIC %s CQ at [%08lx,%08lx)\n", - vnic->name, user_to_phys ( vnic->cq.cqe, 0 ), - user_to_phys ( vnic->cq.cqe, TXNIC_CQ_SIZE ) ); + vnic->name, virt_to_phys ( vnic->cq.cqe ), + ( virt_to_phys ( vnic->cq.cqe ) + TXNIC_CQ_SIZE ) ); return 0; } @@ -559,7 +559,8 @@ static void txnic_poll_cq ( struct txnic *vnic ) { default: DBGC ( vnic, "TXNIC %s unknown completion type %d\n", vnic->name, cqe.common.cqe_type ); - DBGC_HDA ( vnic, user_to_phys ( vnic->cq.cqe, offset ), + DBGC_HDA ( vnic, + ( virt_to_phys ( vnic->cq.cqe ) + offset ), &cqe, sizeof ( cqe ) ); break; } diff --git a/src/drivers/usb/xhci.c b/src/drivers/usb/xhci.c index f244086ce..30ee09bbb 100644 --- a/src/drivers/usb/xhci.c +++ b/src/drivers/usb/xhci.c @@ -1014,8 +1014,7 @@ static int xhci_scratchpad_alloc ( struct xhci_device *xhci ) { } /* Populate scratchpad array */ - addr = dma_phys ( &scratch->buffer_map, - user_to_phys ( scratch->buffer, 0 ) ); + addr = dma ( &scratch->buffer_map, scratch->buffer ); for ( i = 0 ; i < scratch->count ; i++ ) { scratch->array[i] = cpu_to_le64 ( addr ); addr += xhci->pagesize; @@ -1027,8 +1026,8 @@ static int xhci_scratchpad_alloc ( struct xhci_device *xhci ) { scratch->array ) ); DBGC2 ( xhci, "XHCI %s scratchpad [%08lx,%08lx) array [%08lx,%08lx)\n", - xhci->name, user_to_phys ( scratch->buffer, 0 ), - user_to_phys ( scratch->buffer, buffer_len ), + xhci->name, virt_to_phys ( scratch->buffer ), + ( virt_to_phys ( scratch->buffer ) + buffer_len ), virt_to_phys ( scratch->array ), ( virt_to_phys ( scratch->array ) + array_len ) ); return 0; diff --git a/src/hci/commands/image_mem_cmd.c b/src/hci/commands/image_mem_cmd.c index c8bfab1ad..5f8363461 100644 --- a/src/hci/commands/image_mem_cmd.c +++ b/src/hci/commands/image_mem_cmd.c @@ -81,7 +81,7 @@ static int imgmem_exec ( int argc, char **argv ) { return rc; /* Create image */ - if ( ( rc = imgmem ( opts.name, phys_to_user ( data ), len ) ) != 0 ) + if ( ( rc = imgmem ( opts.name, phys_to_virt ( data ), len ) ) != 0 ) return rc; return 0; diff --git a/src/image/elf.c b/src/image/elf.c index 46c9fe8eb..fa714b15f 100644 --- a/src/image/elf.c +++ b/src/image/elf.c @@ -50,7 +50,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ static int elf_load_segment ( struct image *image, Elf_Phdr *phdr, physaddr_t dest ) { - userptr_t buffer = phys_to_user ( dest ); + userptr_t buffer = phys_to_virt ( dest ); int rc; DBGC ( image, "ELF %p loading segment [%x,%x) to [%lx,%lx,%lx)\n", diff --git a/src/image/segment.c b/src/image/segment.c index b7f8ef56c..ebc2b703d 100644 --- a/src/image/segment.c +++ b/src/image/segment.c @@ -59,9 +59,9 @@ struct errortab segment_errors[] __errortab = { */ int prep_segment ( userptr_t segment, size_t filesz, size_t memsz ) { struct memory_map memmap; - physaddr_t start = user_to_phys ( segment, 0 ); - physaddr_t mid = user_to_phys ( segment, filesz ); - physaddr_t end = user_to_phys ( segment, memsz ); + physaddr_t start = virt_to_phys ( segment ); + physaddr_t mid = ( start + filesz ); + physaddr_t end = ( start + memsz ); unsigned int i; DBG ( "Preparing segment [%lx,%lx,%lx)\n", start, mid, end ); diff --git a/src/include/ipxe/linux/linux_uaccess.h b/src/include/ipxe/linux/linux_uaccess.h index 4b1257b1e..b4f7e2fc6 100644 --- a/src/include/ipxe/linux/linux_uaccess.h +++ b/src/include/ipxe/linux/linux_uaccess.h @@ -10,10 +10,9 @@ * * We have no concept of the underlying physical addresses, since * these are not exposed to userspace. We provide a stub - * implementation of user_to_phys() since this is required by - * alloc_memblock(). We provide no implementation of phys_to_user(); - * any code attempting to access physical addresses will therefore - * (correctly) fail to link. + * implementation of virt_to_phys() since this is required by + * alloc_memblock(). We provide a matching stub implementation of + * phys_to_virt(). */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); @@ -25,14 +24,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /** - * Convert user pointer to physical address + * Convert virtual address to physical address * - * @v userptr User pointer - * @v offset Offset from user pointer - * @ret phys_addr Physical address + * @v virt Virtual address + * @ret phys Physical address */ -static inline __always_inline unsigned long -UACCESS_INLINE ( linux, user_to_phys ) ( userptr_t userptr, off_t offset ) { +static inline __always_inline physaddr_t +UACCESS_INLINE ( linux, virt_to_phys ) ( volatile const void *virt ) { /* We do not know the real underlying physical address. We * provide this stub implementation only because it is @@ -43,20 +41,20 @@ UACCESS_INLINE ( linux, user_to_phys ) ( userptr_t userptr, off_t offset ) { * virtual address will suffice for the purpose of determining * alignment. */ - return ( ( unsigned long ) ( userptr + offset ) ); + return ( ( physaddr_t ) virt ); } /** - * Convert physical address to user pointer + * Convert physical address to virtual address * - * @v phys_addr Physical address - * @ret userptr User pointer + * @v phys Physical address + * @ret virt Virtual address */ -static inline __always_inline userptr_t -UACCESS_INLINE ( linux, phys_to_user ) ( physaddr_t phys_addr ) { +static inline __always_inline void * +UACCESS_INLINE ( linux, phys_to_virt ) ( physaddr_t phys ) { - /* For symmetry with the stub user_to_phys() */ - return ( ( userptr_t ) phys_addr ); + /* For symmetry with the stub virt_to_phys() */ + return ( ( void * ) phys ); } static inline __always_inline userptr_t diff --git a/src/include/ipxe/uaccess.h b/src/include/ipxe/uaccess.h index 4b3524bab..62030dd8a 100644 --- a/src/include/ipxe/uaccess.h +++ b/src/include/ipxe/uaccess.h @@ -99,14 +99,14 @@ trivial_memchr_user ( userptr_t buffer, off_t offset, int c, size_t len ) { #define PROVIDE_UACCESS_INLINE( _subsys, _api_func ) \ PROVIDE_SINGLE_API_INLINE ( UACCESS_PREFIX_ ## _subsys, _api_func ) -static inline __always_inline userptr_t -UACCESS_INLINE ( flat, phys_to_user ) ( unsigned long phys_addr ) { - return ( ( userptr_t ) phys_addr ); +static inline __always_inline void * +UACCESS_INLINE ( flat, phys_to_virt ) ( physaddr_t phys ) { + return ( ( void * ) phys ); } -static inline __always_inline unsigned long -UACCESS_INLINE ( flat, user_to_phys ) ( userptr_t userptr, off_t offset ) { - return ( ( unsigned long ) ( userptr + offset ) ); +static inline __always_inline physaddr_t +UACCESS_INLINE ( flat, virt_to_phys ) ( volatile const void *virt ) { + return ( ( physaddr_t ) virt ); } static inline __always_inline userptr_t @@ -126,23 +126,6 @@ UACCESS_INLINE ( flat, memchr_user ) ( userptr_t buffer, off_t offset, /* Include all architecture-dependent user access API headers */ #include -/** - * Convert physical address to user pointer - * - * @v phys_addr Physical address - * @ret userptr User pointer - */ -userptr_t phys_to_user ( unsigned long phys_addr ); - -/** - * Convert user pointer to physical address - * - * @v userptr User pointer - * @v offset Offset from user pointer - * @ret phys_addr Physical address - */ -unsigned long user_to_phys ( userptr_t userptr, off_t offset ); - /** * Convert virtual address to user pointer * @@ -154,25 +137,21 @@ userptr_t virt_to_user ( volatile const void *addr ); /** * Convert virtual address to a physical address * - * @v addr Virtual address - * @ret phys_addr Physical address + * @v virt Virtual address + * @ret phys Physical address */ -static inline __always_inline unsigned long -virt_to_phys ( volatile const void *addr ) { - return user_to_phys ( virt_to_user ( addr ), 0 ); -} +physaddr_t __attribute__ (( const )) +virt_to_phys ( volatile const void *virt ); /** * Convert physical address to a virtual address * - * @v addr Virtual address - * @ret phys_addr Physical address + * @v phys Physical address + * @ret virt Virtual address * * This operation is not available under all memory models. */ -static inline __always_inline void * phys_to_virt ( unsigned long phys_addr ) { - return ( phys_to_user ( phys_addr ) ); -} +void * __attribute__ (( const )) phys_to_virt ( physaddr_t phys ); /** * Copy data to user buffer diff --git a/src/interface/efi/efi_acpi.c b/src/interface/efi/efi_acpi.c index 07a225632..c1046c01a 100644 --- a/src/interface/efi/efi_acpi.c +++ b/src/interface/efi/efi_acpi.c @@ -48,7 +48,7 @@ static userptr_t efi_find_rsdt ( void ) { /* Locate RSDT via ACPI configuration table, if available */ if ( rsdp ) - return phys_to_user ( rsdp->RsdtAddress ); + return phys_to_virt ( rsdp->RsdtAddress ); return UNULL; } diff --git a/src/interface/efi/efi_fbcon.c b/src/interface/efi/efi_fbcon.c index 659ebd37e..09cfde4c2 100644 --- a/src/interface/efi/efi_fbcon.c +++ b/src/interface/efi/efi_fbcon.c @@ -583,7 +583,7 @@ static int efifb_init ( struct console_configuration *config ) { mode, efifb.pixel.width, efifb.pixel.height, bpp, efifb.start ); /* Initialise frame buffer console */ - if ( ( rc = fbcon_init ( &efifb.fbcon, phys_to_user ( efifb.start ), + if ( ( rc = fbcon_init ( &efifb.fbcon, phys_to_virt ( efifb.start ), &efifb.pixel, &efifb.map, &efifb.font, config ) ) != 0 ) goto err_fbcon_init; diff --git a/src/interface/efi/efi_smbios.c b/src/interface/efi/efi_smbios.c index d7877b0aa..3c1b77bdc 100644 --- a/src/interface/efi/efi_smbios.c +++ b/src/interface/efi/efi_smbios.c @@ -48,27 +48,27 @@ static int efi_find_smbios ( struct smbios *smbios ) { /* Use 64-bit table if present */ if ( smbios3_entry && ( smbios3_entry->signature == SMBIOS3_SIGNATURE ) ) { - smbios->address = phys_to_user ( smbios3_entry->smbios_address ); + smbios->address = phys_to_virt ( smbios3_entry->smbios_address ); smbios->len = smbios3_entry->smbios_len; smbios->count = 0; smbios->version = SMBIOS_VERSION ( smbios3_entry->major, smbios3_entry->minor ); DBG ( "Found 64-bit SMBIOS v%d.%d entry point at %p (%lx+%zx)\n", smbios3_entry->major, smbios3_entry->minor, smbios3_entry, - user_to_phys ( smbios->address, 0 ), smbios->len ); + virt_to_phys ( smbios->address ), smbios->len ); return 0; } /* Otherwise, use 32-bit table if present */ if ( smbios_entry && ( smbios_entry->signature == SMBIOS_SIGNATURE ) ) { - smbios->address = phys_to_user ( smbios_entry->smbios_address ); + smbios->address = phys_to_virt ( smbios_entry->smbios_address ); smbios->len = smbios_entry->smbios_len; smbios->count = smbios_entry->smbios_count; smbios->version = SMBIOS_VERSION ( smbios_entry->major, smbios_entry->minor ); DBG ( "Found 32-bit SMBIOS v%d.%d entry point at %p (%lx+%zx)\n", smbios_entry->major, smbios_entry->minor, smbios_entry, - user_to_phys ( smbios->address, 0 ), smbios->len ); + virt_to_phys ( smbios->address ), smbios->len ); return 0; } diff --git a/src/interface/efi/efi_umalloc.c b/src/interface/efi/efi_umalloc.c index 488c53f3d..0636cb7fd 100644 --- a/src/interface/efi/efi_umalloc.c +++ b/src/interface/efi/efi_umalloc.c @@ -72,7 +72,7 @@ static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) { return UNULL; } assert ( phys_addr != 0 ); - new_ptr = phys_to_user ( phys_addr + EFI_PAGE_SIZE ); + new_ptr = phys_to_virt ( phys_addr + EFI_PAGE_SIZE ); copy_to_user ( new_ptr, -EFI_PAGE_SIZE, &new_size, sizeof ( new_size ) ); DBG ( "EFI allocated %d pages at %llx\n", @@ -90,7 +90,7 @@ static userptr_t efi_urealloc ( userptr_t old_ptr, size_t new_size ) { memcpy ( new_ptr, old_ptr, ( (old_size < new_size) ? old_size : new_size ) ); old_pages = ( EFI_SIZE_TO_PAGES ( old_size ) + 1 ); - phys_addr = user_to_phys ( old_ptr, -EFI_PAGE_SIZE ); + phys_addr = virt_to_phys ( old_ptr - EFI_PAGE_SIZE ); if ( ( efirc = bs->FreePages ( phys_addr, old_pages ) ) != 0 ){ rc = -EEFI ( efirc ); DBG ( "EFI could not free %d pages at %llx: %s\n", diff --git a/src/interface/hyperv/vmbus.c b/src/interface/hyperv/vmbus.c index 86d2a08d7..49ccf69c8 100644 --- a/src/interface/hyperv/vmbus.c +++ b/src/interface/hyperv/vmbus.c @@ -277,7 +277,7 @@ int vmbus_establish_gpadl ( struct vmbus_device *vmdev, userptr_t data, size_t len ) { struct hv_hypervisor *hv = vmdev->hv; struct vmbus *vmbus = hv->vmbus; - physaddr_t addr = user_to_phys ( data, 0 ); + physaddr_t addr = virt_to_phys ( data ); unsigned int pfn_count = hv_pfn_count ( addr, len ); struct { struct vmbus_gpadl_header gpadlhdr; diff --git a/src/interface/linux/linux_uaccess.c b/src/interface/linux/linux_uaccess.c index e5c394365..4fdd8c03a 100644 --- a/src/interface/linux/linux_uaccess.c +++ b/src/interface/linux/linux_uaccess.c @@ -27,6 +27,7 @@ FILE_LICENCE(GPL2_OR_LATER); * */ -PROVIDE_UACCESS_INLINE(linux, user_to_phys); +PROVIDE_UACCESS_INLINE(linux, phys_to_virt); +PROVIDE_UACCESS_INLINE(linux, virt_to_phys); PROVIDE_UACCESS_INLINE(linux, virt_to_user); PROVIDE_UACCESS_INLINE(linux, memchr_user); diff --git a/src/interface/smbios/smbios.c b/src/interface/smbios/smbios.c index 3e69a0c15..89fa4d7ca 100644 --- a/src/interface/smbios/smbios.c +++ b/src/interface/smbios/smbios.c @@ -86,14 +86,14 @@ int find_smbios_entry ( userptr_t start, size_t len, if ( ( sum = smbios_checksum ( start, offset, entry->len ) ) != 0 ) { DBG ( "SMBIOS at %08lx has bad checksum %02x\n", - user_to_phys ( start, offset ), sum ); + virt_to_phys ( start + offset ), sum ); continue; } /* Fill result structure */ DBG ( "Found SMBIOS v%d.%d entry point at %08lx\n", entry->major, entry->minor, - user_to_phys ( start, offset ) ); + virt_to_phys ( start + offset ) ); return 0; } @@ -126,14 +126,14 @@ int find_smbios3_entry ( userptr_t start, size_t len, if ( ( sum = smbios_checksum ( start, offset, entry->len ) ) != 0 ) { DBG ( "SMBIOS3 at %08lx has bad checksum %02x\n", - user_to_phys ( start, offset ), sum ); + virt_to_phys ( start + offset ), sum ); continue; } /* Fill result structure */ DBG ( "Found SMBIOS3 v%d.%d entry point at %08lx\n", entry->major, entry->minor, - user_to_phys ( start, offset ) ); + virt_to_phys ( start + offset ) ); return 0; } -- cgit v1.2.3-55-g7522 From 050df80bbc455efaf8c44ea00d55fd344d96f808 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 21 Apr 2025 18:28:56 +0100 Subject: [uaccess] Replace real_to_user() with real_to_virt() Remove the intermediate concept of a user pointer from real address conversion, leaving real_to_virt() as the directly implemented function. Signed-off-by: Michael Brown --- src/arch/x86/image/bzimage.c | 2 +- src/arch/x86/image/com32.c | 2 +- src/arch/x86/image/comboot.c | 4 ++-- src/arch/x86/image/nbi.c | 2 +- src/arch/x86/image/pxe_image.c | 2 +- src/arch/x86/image/sdi.c | 2 +- src/arch/x86/include/libkir.h | 4 ++-- src/arch/x86/include/realmode.h | 12 ++++++------ src/arch/x86/interface/pcbios/bios_smbios.c | 4 ++-- src/arch/x86/interface/pcbios/int13.c | 4 ++-- src/arch/x86/interface/pcbios/rsdp.c | 2 +- src/arch/x86/interface/pcbios/vesafb.c | 2 +- src/arch/x86/interface/pxe/pxe_call.c | 4 ++-- src/arch/x86/interface/pxe/pxe_file.c | 8 ++++---- src/arch/x86/interface/pxe/pxe_preboot.c | 2 +- src/arch/x86/interface/pxe/pxe_tftp.c | 2 +- src/arch/x86/interface/pxe/pxe_udp.c | 4 ++-- src/arch/x86/interface/syslinux/comboot_call.c | 20 ++++++++++---------- src/arch/x86/transitions/librm_mgmt.c | 4 ++-- 19 files changed, 43 insertions(+), 43 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/image/bzimage.c b/src/arch/x86/image/bzimage.c index 0f373c1c8..b6a159847 100644 --- a/src/arch/x86/image/bzimage.c +++ b/src/arch/x86/image/bzimage.c @@ -158,7 +158,7 @@ static int bzimage_parse_header ( struct image *image, /* Calculate load address of real-mode portion */ bzimg->rm_kernel_seg = ( is_bzimage ? 0x1000 : 0x9000 ); - bzimg->rm_kernel = real_to_user ( bzimg->rm_kernel_seg, 0 ); + bzimg->rm_kernel = real_to_virt ( bzimg->rm_kernel_seg, 0 ); /* Allow space for the stack and heap */ bzimg->rm_memsz += BZI_STACK_SIZE; diff --git a/src/arch/x86/image/com32.c b/src/arch/x86/image/com32.c index a2b60987d..9a5793b7c 100644 --- a/src/arch/x86/image/com32.c +++ b/src/arch/x86/image/com32.c @@ -236,7 +236,7 @@ static int com32_prepare_bounce_buffer ( struct image * image ) { int rc; seg = COM32_BOUNCE_SEG; - seg_userptr = real_to_user ( seg, 0 ); + seg_userptr = real_to_virt ( seg, 0 ); /* Ensure the entire 64k segment is free */ memsz = 0xFFFF; diff --git a/src/arch/x86/image/comboot.c b/src/arch/x86/image/comboot.c index 8609eb0f7..b171ecb02 100644 --- a/src/arch/x86/image/comboot.c +++ b/src/arch/x86/image/comboot.c @@ -132,7 +132,7 @@ static void comboot_init_psp ( struct image * image, userptr_t seg_userptr ) { * @ret rc Return status code */ static int comboot_exec_loop ( struct image *image ) { - userptr_t seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); + userptr_t seg_userptr = real_to_virt ( COMBOOT_PSP_SEG, 0 ); int state; state = rmsetjmp ( comboot_return ); @@ -251,7 +251,7 @@ static int comboot_prepare_segment ( struct image *image ) int rc; /* Load image in segment */ - seg_userptr = real_to_user ( COMBOOT_PSP_SEG, 0 ); + seg_userptr = real_to_virt ( COMBOOT_PSP_SEG, 0 ); /* Allow etra 0x100 bytes before image for PSP */ filesz = image->len + 0x100; diff --git a/src/arch/x86/image/nbi.c b/src/arch/x86/image/nbi.c index 1f72c1287..41c6e6ffd 100644 --- a/src/arch/x86/image/nbi.c +++ b/src/arch/x86/image/nbi.c @@ -159,7 +159,7 @@ static int nbi_process_segments ( struct image *image, int rc; /* Copy image header to target location */ - dest = real_to_user ( imgheader->location.segment, + dest = real_to_virt ( imgheader->location.segment, imgheader->location.offset ); filesz = memsz = NBI_HEADER_LENGTH; if ( ( rc = process ( image, offset, dest, filesz, memsz ) ) != 0 ) diff --git a/src/arch/x86/image/pxe_image.c b/src/arch/x86/image/pxe_image.c index bdce165ca..5472ea594 100644 --- a/src/arch/x86/image/pxe_image.c +++ b/src/arch/x86/image/pxe_image.c @@ -54,7 +54,7 @@ const char *pxe_cmdline; * @ret rc Return status code */ static int pxe_exec ( struct image *image ) { - userptr_t buffer = real_to_user ( 0, 0x7c00 ); + userptr_t buffer = real_to_virt ( 0, 0x7c00 ); struct net_device *netdev; int rc; diff --git a/src/arch/x86/image/sdi.c b/src/arch/x86/image/sdi.c index 5e22daeb3..40fab2a10 100644 --- a/src/arch/x86/image/sdi.c +++ b/src/arch/x86/image/sdi.c @@ -98,7 +98,7 @@ static int sdi_exec ( struct image *image ) { sdi.boot_size ); /* Copy boot code */ - memcpy ( real_to_user ( SDI_BOOT_SEG, SDI_BOOT_OFF ), + memcpy ( real_to_virt ( SDI_BOOT_SEG, SDI_BOOT_OFF ), ( image->data + sdi.boot_offset ), sdi.boot_size ); /* Jump to boot code */ diff --git a/src/arch/x86/include/libkir.h b/src/arch/x86/include/libkir.h index 1f5b13504..76766b6c2 100644 --- a/src/arch/x86/include/libkir.h +++ b/src/arch/x86/include/libkir.h @@ -194,7 +194,7 @@ copy_from_user ( void *dest, userptr_t buffer, off_t offset, size_t len ) { * @ret buffer User buffer */ static inline __attribute__ (( always_inline )) userptr_t -real_to_user ( unsigned int segment, unsigned int offset ) { +real_to_virt ( unsigned int segment, unsigned int offset ) { return ( ( segment << 16 ) | offset ); } @@ -210,7 +210,7 @@ real_to_user ( unsigned int segment, unsigned int offset ) { */ static inline __attribute__ (( always_inline )) userptr_t virt_to_user ( void * virtual ) { - return real_to_user ( rm_ds, ( intptr_t ) virtual ); + return real_to_virt ( rm_ds, ( intptr_t ) virtual ); } /* TEXT16_CODE: declare a fragment of code that resides in .text16 */ diff --git a/src/arch/x86/include/realmode.h b/src/arch/x86/include/realmode.h index 616db5eb9..0017b42c0 100644 --- a/src/arch/x86/include/realmode.h +++ b/src/arch/x86/include/realmode.h @@ -65,14 +65,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); */ /** - * Convert segment:offset address to user buffer + * Convert segment:offset address to virtual address * * @v segment Real-mode segment * @v offset Real-mode offset - * @ret buffer User buffer + * @ret virt Virtual address */ -static inline __always_inline userptr_t -real_to_user ( unsigned int segment, unsigned int offset ) { +static inline __always_inline void * +real_to_virt ( unsigned int segment, unsigned int offset ) { return ( phys_to_virt ( ( segment << 4 ) + offset ) ); } @@ -87,7 +87,7 @@ real_to_user ( unsigned int segment, unsigned int offset ) { static inline __always_inline void copy_to_real ( unsigned int dest_seg, unsigned int dest_off, void *src, size_t n ) { - copy_to_user ( real_to_user ( dest_seg, dest_off ), 0, src, n ); + copy_to_user ( real_to_virt ( dest_seg, dest_off ), 0, src, n ); } /** @@ -101,7 +101,7 @@ copy_to_real ( unsigned int dest_seg, unsigned int dest_off, static inline __always_inline void copy_from_real ( void *dest, unsigned int src_seg, unsigned int src_off, size_t n ) { - copy_from_user ( dest, real_to_user ( src_seg, src_off ), 0, n ); + copy_from_user ( dest, real_to_virt ( src_seg, src_off ), 0, n ); } /** diff --git a/src/arch/x86/interface/pcbios/bios_smbios.c b/src/arch/x86/interface/pcbios/bios_smbios.c index ab53d424b..e43c74bad 100644 --- a/src/arch/x86/interface/pcbios/bios_smbios.c +++ b/src/arch/x86/interface/pcbios/bios_smbios.c @@ -49,7 +49,7 @@ static int bios_find_smbios2 ( struct smbios *smbios ) { int rc; /* Scan through BIOS segment to find SMBIOS 32-bit entry point */ - if ( ( rc = find_smbios_entry ( real_to_user ( BIOS_SEG, 0 ), 0x10000, + if ( ( rc = find_smbios_entry ( real_to_virt ( BIOS_SEG, 0 ), 0x10000, &entry ) ) != 0 ) return rc; @@ -73,7 +73,7 @@ static int bios_find_smbios3 ( struct smbios *smbios ) { int rc; /* Scan through BIOS segment to find SMBIOS 64-bit entry point */ - if ( ( rc = find_smbios3_entry ( real_to_user ( BIOS_SEG, 0 ), 0x10000, + if ( ( rc = find_smbios3_entry ( real_to_virt ( BIOS_SEG, 0 ), 0x10000, &entry ) ) != 0 ) return rc; diff --git a/src/arch/x86/interface/pcbios/int13.c b/src/arch/x86/interface/pcbios/int13.c index d60f7c7cc..498676b70 100644 --- a/src/arch/x86/interface/pcbios/int13.c +++ b/src/arch/x86/interface/pcbios/int13.c @@ -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, @@ -747,7 +747,7 @@ static int int13_extended_rw ( struct san_device *sandev, 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 ); diff --git a/src/arch/x86/interface/pcbios/rsdp.c b/src/arch/x86/interface/pcbios/rsdp.c index 02c58c780..c2534c7f6 100644 --- a/src/arch/x86/interface/pcbios/rsdp.c +++ b/src/arch/x86/interface/pcbios/rsdp.c @@ -106,7 +106,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 ) diff --git a/src/arch/x86/interface/pcbios/vesafb.c b/src/arch/x86/interface/pcbios/vesafb.c index 61609fa8c..cfa935126 100644 --- a/src/arch/x86/interface/pcbios/vesafb.c +++ b/src/arch/x86/interface/pcbios/vesafb.c @@ -243,7 +243,7 @@ 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 { diff --git a/src/arch/x86/interface/pxe/pxe_call.c b/src/arch/x86/interface/pxe/pxe_call.c index 0e8d5c5a8..f88943fb2 100644 --- a/src/arch/x86/interface/pxe/pxe_call.c +++ b/src/arch/x86/interface/pxe/pxe_call.c @@ -144,7 +144,7 @@ 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 ); + userptr_t uparams = real_to_virt ( ix86->segs.es, ix86->regs.di ); struct profiler *profiler = pxe_api_profiler ( opcode ); struct pxe_api_call *call; union u_PXENV_ANY params; @@ -195,7 +195,7 @@ 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 ); + userptr_t uparams = real_to_virt ( ix86->segs.es, ix86->regs.di ); struct s_UNDI_LOADER params; PXENV_EXIT_t ret; diff --git a/src/arch/x86/interface/pxe/pxe_file.c b/src/arch/x86/interface/pxe/pxe_file.c index 1235520de..64bc335f2 100644 --- a/src/arch/x86/interface/pxe/pxe_file.c +++ b/src/arch/x86/interface/pxe/pxe_file.c @@ -60,7 +60,7 @@ static PXENV_EXIT_t pxenv_file_open ( struct s_PXENV_FILE_OPEN *file_open ) { DBG ( "PXENV_FILE_OPEN" ); /* Copy name from external program, and open it */ - filename = real_to_user ( file_open->FileName.segment, + filename = real_to_virt ( file_open->FileName.segment, file_open->FileName.offset ); filename_len = strlen ( filename ); { @@ -155,7 +155,7 @@ static PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) { 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 ) { @@ -217,7 +217,7 @@ static PXENV_EXIT_t pxenv_file_exec ( struct s_PXENV_FILE_EXEC *file_exec ) { DBG ( "PXENV_FILE_EXEC" ); /* Copy name from external program, and exec it */ - command = real_to_user ( file_exec->Command.segment, + command = real_to_virt ( file_exec->Command.segment, file_exec->Command.offset ); command_len = strlen ( command ); { @@ -259,7 +259,7 @@ pxenv_file_cmdline ( struct s_PXENV_FILE_CMDLINE *file_cmdline ) { 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 ? diff --git a/src/arch/x86/interface/pxe/pxe_preboot.c b/src/arch/x86/interface/pxe/pxe_preboot.c index 09e721b34..727d8e1ea 100644 --- a/src/arch/x86/interface/pxe/pxe_preboot.c +++ b/src/arch/x86/interface/pxe/pxe_preboot.c @@ -243,7 +243,7 @@ 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 ); 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 2c2eccca4..073414dce 100644 --- a/src/arch/x86/interface/pxe/pxe_tftp.c +++ b/src/arch/x86/interface/pxe/pxe_tftp.c @@ -378,7 +378,7 @@ 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; diff --git a/src/arch/x86/interface/pxe/pxe_udp.c b/src/arch/x86/interface/pxe/pxe_udp.c index a5d5eb77b..47abb7df4 100644 --- a/src/arch/x86/interface/pxe/pxe_udp.c +++ b/src/arch/x86/interface/pxe/pxe_udp.c @@ -328,7 +328,7 @@ 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 ); @@ -438,7 +438,7 @@ 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 ) diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index d7e923b70..d8c245757 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -90,7 +90,7 @@ static uint16_t comboot_graphics_mode = 0; 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 ); + userptr_t str = real_to_virt ( segment, offset ); for ( ; ; ) { copy_from_user ( &c, str, i, 1 ); if ( c == terminator ) break; @@ -109,7 +109,7 @@ 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, + copy_from_user ( shuf, real_to_virt ( list_segment, list_offset ), 0, count * sizeof( comboot_shuffle_descriptor ) ); /* Do the copies */ @@ -346,7 +346,7 @@ 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 ); + userptr_t cmd_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); int len = strlen ( cmd_u ); char cmd[len + 1]; copy_from_user ( cmd, cmd_u, 0, len + 1 ); @@ -370,7 +370,7 @@ 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 ); + userptr_t file_u = real_to_virt ( ix86->segs.es, ix86->regs.si ); int len = strlen ( file_u ); char file[len + 1]; @@ -410,7 +410,7 @@ 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 ); + userptr_t buf = real_to_virt ( ix86->segs.es, ix86->regs.bx ); /* Wait for data ready to read */ FD_ZERO ( &fds ); @@ -483,7 +483,7 @@ 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 ); + userptr_t hostname_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); int len = strlen ( hostname_u ); char hostname[len]; struct in_addr addr; @@ -549,8 +549,8 @@ 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 ); + userptr_t file_u = real_to_virt ( ix86->segs.ds, ix86->regs.si ); + userptr_t cmd_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); int file_len = strlen ( file_u ); int cmd_len = strlen ( cmd_u ); char file[file_len + 1]; @@ -595,8 +595,8 @@ 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 ( real_to_user ( rm_cs, (unsigned) __from_text16 ( &comboot_initial_regs ) ), - real_to_user ( ix86->segs.ds, ix86->regs.si ), + 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 */ diff --git a/src/arch/x86/transitions/librm_mgmt.c b/src/arch/x86/transitions/librm_mgmt.c index fbc653969..e0679f0ff 100644 --- a/src/arch/x86/transitions/librm_mgmt.c +++ b/src/arch/x86/transitions/librm_mgmt.c @@ -68,7 +68,7 @@ static struct profiler other_irq_profiler __profiler = { .name = "irq.other" }; uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) { userptr_t rm_stack; rm_sp -= size; - rm_stack = real_to_user ( rm_ss, rm_sp ); + rm_stack = real_to_virt ( rm_ss, rm_sp ); memcpy ( rm_stack, data, size ); return rm_sp; }; @@ -82,7 +82,7 @@ uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) { */ void remove_user_from_rm_stack ( userptr_t data, size_t size ) { if ( data ) { - userptr_t rm_stack = real_to_user ( rm_ss, rm_sp ); + userptr_t rm_stack = real_to_virt ( rm_ss, rm_sp ); memcpy ( rm_stack, data, size ); } rm_sp += size; -- cgit v1.2.3-55-g7522 From 04d0b2fdf9767fed690cdaaf36b4cd60c6bded02 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 21 Apr 2025 18:55:30 +0100 Subject: [uaccess] Remove redundant read_user() Signed-off-by: Michael Brown --- src/arch/x86/interface/pxe/pxe_file.c | 6 +++--- src/arch/x86/interface/syslinux/comboot_call.c | 5 +++-- src/core/posix_io.c | 9 ++++----- src/include/ipxe/posix_io.h | 16 +--------------- 4 files changed, 11 insertions(+), 25 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/interface/pxe/pxe_file.c b/src/arch/x86/interface/pxe/pxe_file.c index 64bc335f2..6bb9f525f 100644 --- a/src/arch/x86/interface/pxe/pxe_file.c +++ b/src/arch/x86/interface/pxe/pxe_file.c @@ -148,7 +148,7 @@ 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, @@ -157,8 +157,8 @@ static PXENV_EXIT_t pxenv_file_read ( struct s_PXENV_FILE_READ *file_read ) { 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; } diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index d8c245757..15539ada5 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -410,7 +410,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_virt ( 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 +419,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; diff --git a/src/core/posix_io.c b/src/core/posix_io.c index 35b52beeb..9112798ec 100644 --- a/src/core/posix_io.c +++ b/src/core/posix_io.c @@ -254,15 +254,14 @@ int select ( fd_set *readfds, int wait ) { /** * Read data from file * - * @v buffer Data buffer - * @v offset Starting offset within data buffer - * @v len Maximum length to read + * @v buf Data buffer + * @v max_len Maximum length to read * @ret len Actual length read, or negative error number * * This call is non-blocking; if no data is available to read then * -EWOULDBLOCK will be returned. */ -ssize_t read_user ( int fd, userptr_t buffer, off_t offset, size_t max_len ) { +ssize_t read ( int fd, void *buf, size_t max_len ) { struct posix_file *file; struct io_buffer *iobuf; size_t len; @@ -281,7 +280,7 @@ ssize_t read_user ( int fd, userptr_t buffer, off_t offset, size_t max_len ) { len = iob_len ( iobuf ); if ( len > max_len ) len = max_len; - copy_to_user ( buffer, offset, iobuf->data, len ); + memcpy ( buf, iobuf->data, len ); iob_pull ( iobuf, len ); if ( ! iob_len ( iobuf ) ) { list_del ( &iobuf->list ); diff --git a/src/include/ipxe/posix_io.h b/src/include/ipxe/posix_io.h index 1a73b5e86..693e0ae34 100644 --- a/src/include/ipxe/posix_io.h +++ b/src/include/ipxe/posix_io.h @@ -10,7 +10,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include -#include /** Minimum file descriptor that will ever be allocated */ #define POSIX_FD_MIN ( 1 ) @@ -22,8 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); typedef uint32_t fd_set; extern int open ( const char *uri_string ); -extern ssize_t read_user ( int fd, userptr_t buffer, - off_t offset, size_t len ); +extern ssize_t read ( int fd, void *buf, size_t len ); extern int select ( fd_set *readfds, int wait ); extern ssize_t fsize ( int fd ); extern int close ( int fd ); @@ -72,16 +70,4 @@ FD_ISSET ( int fd, fd_set *set ) { return ( *set & ( 1 << fd ) ); } -/** - * Read data from file - * - * @v fd File descriptor - * @v buf Data buffer - * @v len Maximum length to read - * @ret len Actual length read, or negative error number - */ -static inline ssize_t read ( int fd, void *buf, size_t len ) { - return read_user ( fd, virt_to_user ( buf ), 0, len ); -} - #endif /* _IPXE_POSIX_IO_H */ -- cgit v1.2.3-55-g7522 From f001e61a687ddb91fc1d29f885c2d3af07267798 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 28 Apr 2025 22:50:23 +0100 Subject: [comboot] Remove userptr_t from COMBOOT API implementation Signed-off-by: Michael Brown --- src/arch/x86/interface/syslinux/comboot_call.c | 60 +++++++++----------------- 1 file changed, 21 insertions(+), 39 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index 15539ada5..714807f7a 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -88,14 +88,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_virt ( 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 +104,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_virt ( 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_virt ( shuf[ i ].src ); - userptr_t dest_u = phys_to_virt ( 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 ( dest_u, 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 ( dest_u, src_u, shuf[ i ].len ); + memmove ( dest, src, shuf[ i ].len ); } } } @@ -164,7 +159,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; @@ -346,10 +341,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0003: /* Run command */ { - userptr_t cmd_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); - int len = strlen ( cmd_u ); - 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 +363,8 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0006: /* Open file */ { int fd; - userptr_t file_u = real_to_virt ( ix86->segs.es, ix86->regs.si ); - int len = strlen ( file_u ); - 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" ); @@ -484,13 +474,10 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0010: /* Resolve hostname */ { - userptr_t hostname_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); - int len = strlen ( hostname_u ); - 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." @@ -550,15 +537,10 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x0016: /* Run kernel image */ { - userptr_t file_u = real_to_virt ( ix86->segs.ds, ix86->regs.si ); - userptr_t cmd_u = real_to_virt ( ix86->segs.es, ix86->regs.bx ); - int file_len = strlen ( file_u ); - int cmd_len = strlen ( cmd_u ); - 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 ); -- cgit v1.2.3-55-g7522 From c9fb94dbaa76c3b21fb3376c1d0b489294576a5e Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 29 Apr 2025 00:24:55 +0100 Subject: [comboot] Remove userptr_t from COM32 API implementation Signed-off-by: Michael Brown --- src/arch/x86/include/librm.h | 4 ++-- src/arch/x86/interface/syslinux/com32_call.c | 12 ++++++------ src/arch/x86/transitions/librm_mgmt.c | 27 ++++++++++++++------------- 3 files changed, 22 insertions(+), 21 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/include/librm.h b/src/arch/x86/include/librm.h index 379b6d849..22b7e3933 100644 --- a/src/arch/x86/include/librm.h +++ b/src/arch/x86/include/librm.h @@ -188,8 +188,8 @@ extern const uint16_t __text16 ( rm_cs ); extern const uint16_t __text16 ( rm_ds ); #define rm_ds __use_text16 ( rm_ds ) -extern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ); -extern void remove_user_from_rm_stack ( userptr_t data, size_t size ); +extern uint16_t copy_to_rm_stack ( const void *data, size_t size ); +extern void remove_from_rm_stack ( void *data, size_t size ); /* CODE_DEFAULT: restore default .code32/.code64 directive */ #ifdef __x86_64__ diff --git a/src/arch/x86/interface/syslinux/com32_call.c b/src/arch/x86/interface/syslinux/com32_call.c index 47be69f9f..a23f46436 100644 --- a/src/arch/x86/interface/syslinux/com32_call.c +++ b/src/arch/x86/interface/syslinux/com32_call.c @@ -49,7 +49,7 @@ 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 ( virt_to_user( &com32_regs ), phys_to_virt ( inregs_phys ), + memcpy ( &com32_regs, phys_to_virt ( inregs_phys ), sizeof ( com32sys_t ) ); com32_int_vector = interrupt; @@ -108,7 +108,7 @@ void __asmcall com32_intcall ( uint8_t interrupt, physaddr_t inregs_phys, physad if ( outregs_phys ) { memcpy ( phys_to_virt ( outregs_phys ), - virt_to_user ( &com32_regs ), sizeof ( com32sys_t ) ); + &com32_regs, sizeof ( com32sys_t ) ); } } @@ -120,7 +120,7 @@ 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 ( virt_to_user( &com32_regs ), phys_to_virt ( inregs_phys ), + memcpy ( &com32_regs, phys_to_virt ( inregs_phys ), sizeof ( com32sys_t ) ); com32_farcall_proc = proc; @@ -168,7 +168,7 @@ void __asmcall com32_farcall ( uint32_t proc, physaddr_t inregs_phys, physaddr_t if ( outregs_phys ) { memcpy ( phys_to_virt ( outregs_phys ), - virt_to_user ( &com32_regs ), sizeof ( com32sys_t ) ); + &com32_regs, sizeof ( com32sys_t ) ); } } @@ -181,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_virt ( stack ), stacksz ); + copy_to_rm_stack ( phys_to_virt ( stack ), stacksz ); com32_farcall_proc = proc; __asm__ __volatile__ ( @@ -190,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/transitions/librm_mgmt.c b/src/arch/x86/transitions/librm_mgmt.c index 5a6942825..da5055cd8 100644 --- a/src/arch/x86/transitions/librm_mgmt.c +++ b/src/arch/x86/transitions/librm_mgmt.c @@ -58,35 +58,36 @@ static struct profiler timer_irq_profiler __profiler = { .name = "irq.timer" }; static struct profiler other_irq_profiler __profiler = { .name = "irq.other" }; /** - * Allocate space on the real-mode stack and copy data there from a - * user buffer + * Allocate space on the real-mode stack and copy data there * - * @v data User buffer + * @v data Stack data * @v size Size of stack data * @ret sp New value of real-mode stack pointer */ -uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ) { - userptr_t rm_stack; +uint16_t copy_to_rm_stack ( const void *data, size_t size ) { + void *rm_stack; + rm_sp -= size; rm_stack = real_to_virt ( rm_ss, rm_sp ); memcpy ( rm_stack, data, size ); return rm_sp; -}; +} /** - * Deallocate space on the real-mode stack, optionally copying back - * data to a user buffer. + * Deallocate space on the real-mode stack, optionally copying back data * - * @v data User buffer + * @v data Stack data buffer, or NULL * @v size Size of stack data */ -void remove_user_from_rm_stack ( userptr_t data, size_t size ) { +void remove_from_rm_stack ( void *data, size_t size ) { + const void *rm_stack; + if ( data ) { - userptr_t rm_stack = real_to_virt ( rm_ss, rm_sp ); - memcpy ( rm_stack, data, size ); + rm_stack = real_to_virt ( rm_ss, rm_sp ); + memcpy ( data, rm_stack, size ); } rm_sp += size; -}; +} /** * Set interrupt vector -- cgit v1.2.3-55-g7522 From e8a6c2657163af1255d1b1ccff3d19c45b0a6182 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Wed, 7 May 2025 22:57:40 +0100 Subject: [build] Constrain PHYS_CODE() and REAL_CODE() to use i386 registers Inline assembly using PHYS_CODE() or REAL_CODE() must use the "R" constraint rather than the "r" constraint to ensure that the compiler chooses registers that will be valid for the 32-bit or 16-bit assembly code fragment. Signed-off-by: Michael Brown --- src/arch/x86/image/com32.c | 12 ++++++------ src/arch/x86/image/comboot.c | 2 +- src/arch/x86/interface/pcbios/bios_mp.c | 6 +++--- src/arch/x86/interface/syslinux/comboot_call.c | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/image/com32.c b/src/arch/x86/image/com32.c index 0c47f95e4..37fb2c3c0 100644 --- a/src/arch/x86/image/com32.c +++ b/src/arch/x86/image/com32.c @@ -114,13 +114,13 @@ static int com32_exec_loop ( struct image *image ) { /* Restore registers */ "popal\n\t" ) : - : "r" ( avail_mem_top ), - "r" ( virt_to_phys ( com32_cfarcall_wrapper ) ), - "r" ( virt_to_phys ( com32_farcall_wrapper ) ), - "r" ( get_fbms() * 1024 - ( COM32_BOUNCE_SEG << 4 ) ), + : "R" ( avail_mem_top ), + "R" ( virt_to_phys ( com32_cfarcall_wrapper ) ), + "R" ( virt_to_phys ( com32_farcall_wrapper ) ), + "R" ( get_fbms() * 1024 - ( COM32_BOUNCE_SEG << 4 ) ), "i" ( COM32_BOUNCE_SEG << 4 ), - "r" ( virt_to_phys ( com32_intcall_wrapper ) ), - "r" ( virt_to_phys ( image->cmdline ? + "R" ( virt_to_phys ( com32_intcall_wrapper ) ), + "R" ( virt_to_phys ( image->cmdline ? image->cmdline : "" ) ), "i" ( COM32_START_PHYS ) : "memory" ); diff --git a/src/arch/x86/image/comboot.c b/src/arch/x86/image/comboot.c index dcf9114b5..f717e1d32 100644 --- a/src/arch/x86/image/comboot.c +++ b/src/arch/x86/image/comboot.c @@ -171,7 +171,7 @@ static int comboot_exec_loop ( struct image *image ) { "xorw %%di, %%di\n\t" "xorw %%bp, %%bp\n\t" "lret\n\t" ) - : : "r" ( COMBOOT_PSP_SEG ) : "eax" ); + : : "R" ( COMBOOT_PSP_SEG ) : "eax" ); DBGC ( image, "COMBOOT %p: returned\n", image ); break; diff --git a/src/arch/x86/interface/pcbios/bios_mp.c b/src/arch/x86/interface/pcbios/bios_mp.c index 9e1179ccd..c903a81fc 100644 --- a/src/arch/x86/interface/pcbios/bios_mp.c +++ b/src/arch/x86/interface/pcbios/bios_mp.c @@ -92,9 +92,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/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index 714807f7a..f7cceb30f 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -514,8 +514,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 ) ); -- cgit v1.2.3-55-g7522 From 6c8fb4b89d49c40339fe61b7ec549d90f1ce9480 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Tue, 17 Jun 2025 14:28:18 +0100 Subject: [uart] Allow for the existence of non-16550 UARTs Remove the assumption that all platforms use a fixed number of 16550 UARTs identifiable by a simple numeric index. Create an abstraction allowing for dynamic instantiation and registration of any number of arbitrary UART models. The common case of the serial console on x86 uses a single fixed UART specified at compile time. Avoid unnecessarily dragging in the dynamic instantiation code in this use case by allowing COMCONSOLE to refer to a single static UART object representing the relevant port. When selecting a UART by command-line argument (as used in the "gdbstub serial " command), allow the UART to be specified as either a numeric index (to retain backwards compatiblity) or a case-insensitive port name such as "COM2". Signed-off-by: Michael Brown --- src/Makefile | 1 + src/arch/x86/core/x86_uart.c | 58 +++---- src/arch/x86/include/bits/ns16550.h | 60 +++++++ src/arch/x86/include/bits/uart.h | 41 ----- src/arch/x86/interface/syslinux/comboot_call.c | 17 +- src/core/gdbserial.c | 42 ++--- src/core/serial.c | 62 ++++--- src/core/uart.c | 176 ++++++++++---------- src/drivers/uart/ns16550.c | 179 +++++++++++++++++++++ src/include/bits/ns16550.h | 15 ++ src/include/bits/uart.h | 15 -- src/include/ipxe/errfile.h | 1 + src/include/ipxe/gdbserial.h | 2 +- src/include/ipxe/ns16550.h | 112 +++++++++++++ src/include/ipxe/serial.h | 2 +- src/include/ipxe/uart.h | 214 +++++++++++++++---------- 16 files changed, 683 insertions(+), 314 deletions(-) create mode 100644 src/arch/x86/include/bits/ns16550.h delete mode 100644 src/arch/x86/include/bits/uart.h create mode 100644 src/drivers/uart/ns16550.c create mode 100644 src/include/bits/ns16550.h delete mode 100644 src/include/bits/uart.h create mode 100644 src/include/ipxe/ns16550.h (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/Makefile b/src/Makefile index 6367b13ea..f3d378e05 100644 --- a/src/Makefile +++ b/src/Makefile @@ -94,6 +94,7 @@ SRCDIRS += drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed SRCDIRS += drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu SRCDIRS += drivers/infiniband/mlx_nodnic/src SRCDIRS += drivers/usb +SRCDIRS += drivers/uart SRCDIRS += interface/pxe interface/efi interface/smbios SRCDIRS += interface/bofm SRCDIRS += interface/xen diff --git a/src/arch/x86/core/x86_uart.c b/src/arch/x86/core/x86_uart.c index e455775bf..2580b931b 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 . + * Copyright (C) 2025 Michael Brown . * * 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,45 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * */ -#include -#include +#include +#include +#include -/** 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 ) \ + struct ns16550_uart NAME = { \ + .uart = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .op = &ns16550_operations, \ + }, \ + .base = ( ( void * ) (BASE) ), \ + } + +/* 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; } diff --git a/src/arch/x86/include/bits/ns16550.h b/src/arch/x86/include/bits/ns16550.h new file mode 100644 index 000000000..9f7d741ae --- /dev/null +++ b/src/arch/x86/include/bits/ns16550.h @@ -0,0 +1,60 @@ +#ifndef _BITS_NS16550_H +#define _BITS_NS16550_H + +/** @file + * + * 16550-compatible UART + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include +#include + +/** + * Write to UART register + * + * @v ns16550 16550 UART + * @v address Register address + * @v data Data + */ +static inline __attribute__ (( always_inline )) void +ns16550_write ( struct ns16550_uart *ns16550, unsigned int address, + uint8_t data ) { + + outb ( data, ( ns16550->base + address ) ); +} + +/** + * Read from UART register + * + * @v ns16550 16550 UART + * @v address Register address + * @ret data Data + */ +static inline __attribute__ (( always_inline )) uint8_t +ns16550_read ( struct ns16550_uart *ns16550, unsigned int address ) { + + return inb ( ns16550->base + address ); +} + +/* Fixed ISA serial port base addresses */ +#define COM1_BASE 0x3f8 +#define COM2_BASE 0x2f8 +#define COM3_BASE 0x3e8 +#define COM4_BASE 0x2e8 + +/* Fixed ISA serial ports */ +extern struct ns16550_uart com1; +extern struct ns16550_uart com2; +extern struct ns16550_uart com3; +extern struct ns16550_uart com4; + +/* Fixed ISA serial port names */ +#define COM1 &com1.uart +#define COM2 &com2.uart +#define COM3 &com3.uart +#define COM4 &com4.uart + +#endif /* _BITS_NS16550_H */ diff --git a/src/arch/x86/include/bits/uart.h b/src/arch/x86/include/bits/uart.h deleted file mode 100644 index e09cd3f4c..000000000 --- a/src/arch/x86/include/bits/uart.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _BITS_UART_H -#define _BITS_UART_H - -/** @file - * - * 16550-compatible UART - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#include -#include - -/** - * Write to UART register - * - * @v uart UART - * @v addr Register address - * @v data Data - */ -static inline __attribute__ (( always_inline )) void -uart_write ( struct uart *uart, unsigned int addr, uint8_t data ) { - outb ( data, ( uart->base + addr ) ); -} - -/** - * Read from UART register - * - * @v uart UART - * @v addr Register address - * @ret data Data - */ -static inline __attribute__ (( always_inline )) uint8_t -uart_read ( struct uart *uart, unsigned int addr ) { - return inb ( uart->base + addr ); -} - -extern int uart_select ( struct uart *uart, unsigned int port ); - -#endif /* _BITS_UART_H */ diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index f7cceb30f..97bdaeae3 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 #include #include +#include #include #include #include @@ -253,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; @@ -445,9 +446,13 @@ 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 = + container_of ( serial_console, + struct ns16550_uart, uart ); + + ix86->regs.dx = ( ( intptr_t ) comport->base ); + ix86->regs.cx = comport->divisor; ix86->regs.bx = 0; ix86->flags &= ~CF; } @@ -685,4 +690,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/core/gdbserial.c b/src/core/gdbserial.c index 1edc28109..0f74e5fe0 100644 --- a/src/core/gdbserial.c +++ b/src/core/gdbserial.c @@ -25,20 +25,12 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include -#include #include #include #include #include #include -/* UART port number */ -#ifdef COMCONSOLE -#define GDBSERIAL_PORT COMCONSOLE -#else -#define GDBSERIAL_PORT 0 -#endif - /* UART baud rate */ #ifdef COMPRESERVE #define GDBSERIAL_BAUD 0 @@ -47,37 +39,30 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #endif /** GDB serial UART */ -static struct uart gdbserial_uart; +static struct uart *gdbserial_uart; struct gdb_transport serial_gdb_transport __gdb_transport; static size_t gdbserial_recv ( char *buf, size_t len ) { assert ( len > 0 ); - while ( ! uart_data_ready ( &gdbserial_uart ) ) {} - buf[0] = uart_receive ( &gdbserial_uart ); + while ( ! uart_data_ready ( gdbserial_uart ) ) {} + buf[0] = uart_receive ( gdbserial_uart ); return 1; } static void gdbserial_send ( const char *buf, size_t len ) { while ( len-- > 0 ) { - uart_transmit ( &gdbserial_uart, *buf++ ); + uart_transmit ( gdbserial_uart, *buf++ ); } } static int gdbserial_init ( int argc, char **argv ) { - unsigned int port; - char *endp; - - if ( argc == 0 ) { - port = GDBSERIAL_PORT; - } else if ( argc == 1 ) { - port = strtoul ( argv[0], &endp, 10 ); - if ( *endp ) { - printf ( "serial: invalid port\n" ); - return 1; - } + const char *port; + + if ( argc == 1 ) { + port = argv[0]; } else { printf ( "serial: syntax \n" ); return 1; @@ -98,14 +83,19 @@ struct gdb_transport serial_gdb_transport __gdb_transport = { .send = gdbserial_send, }; -struct gdb_transport * gdbserial_configure ( unsigned int port, +struct gdb_transport * gdbserial_configure ( const char *name, unsigned int baud ) { int rc; - if ( ( rc = uart_select ( &gdbserial_uart, port ) ) != 0 ) + uart_put ( gdbserial_uart ); + gdbserial_uart = NULL; + + gdbserial_uart = uart_find ( name ); + if ( ! gdbserial_uart ) return NULL; + uart_get ( gdbserial_uart ); - if ( ( rc = uart_init ( &gdbserial_uart, baud ) ) != 0 ) + if ( ( rc = uart_init ( gdbserial_uart, baud ) ) != 0 ) return NULL; return &serial_gdb_transport; diff --git a/src/core/serial.c b/src/core/serial.c index 2866681a8..e718f0d42 100644 --- a/src/core/serial.c +++ b/src/core/serial.c @@ -35,6 +35,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include #include +#include #include #include @@ -44,22 +45,21 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define CONSOLE_SERIAL ( CONSOLE_USAGE_ALL & ~CONSOLE_USAGE_LOG ) #endif -/* UART port number */ -#ifdef COMCONSOLE -#define CONSOLE_PORT COMCONSOLE -#else -#define CONSOLE_PORT 0 +/* Serial console UART */ +#ifndef COMCONSOLE +#define COMCONSOLE NULL #endif -/* UART baud rate */ -#ifdef COMPRESERVE -#define CONSOLE_BAUD 0 -#else -#define CONSOLE_BAUD COMSPEED +/* Serial console baud rate */ +#ifndef COMSPEED +#define COMSPEED 0 #endif -/** Serial console UART */ -struct uart serial_console; +/** Default serial console UART */ +static struct uart * const default_serial_console = COMCONSOLE; + +/** Active serial console UART */ +struct uart *serial_console; /** * Print a character to serial console @@ -69,11 +69,11 @@ struct uart serial_console; static void serial_putchar ( int character ) { /* Do nothing if we have no UART */ - if ( ! serial_console.base ) + if ( ! serial_console ) return; /* Transmit character */ - uart_transmit ( &serial_console, character ); + uart_transmit ( serial_console, character ); } /** @@ -85,14 +85,14 @@ static int serial_getchar ( void ) { uint8_t data; /* Do nothing if we have no UART */ - if ( ! serial_console.base ) + if ( ! serial_console ) return 0; /* Wait for data to be ready */ - while ( ! uart_data_ready ( &serial_console ) ) {} + while ( ! uart_data_ready ( serial_console ) ) {} /* Receive data */ - data = uart_receive ( &serial_console ); + data = uart_receive ( serial_console ); /* Strip any high bit and convert DEL to backspace */ data &= 0x7f; @@ -111,11 +111,11 @@ static int serial_getchar ( void ) { static int serial_iskey ( void ) { /* Do nothing if we have no UART */ - if ( ! serial_console.base ) + if ( ! serial_console ) return 0; /* Check UART */ - return uart_data_ready ( &serial_console ); + return uart_data_ready ( serial_console ); } /** Serial console */ @@ -128,25 +128,23 @@ struct console_driver serial_console_driver __console_driver = { /** Initialise serial console */ static void serial_init ( void ) { + struct uart *uart = default_serial_console; int rc; /* Do nothing if we have no default port */ - if ( ! CONSOLE_PORT ) + if ( ! uart ) return; - /* Select UART */ - if ( ( rc = uart_select ( &serial_console, CONSOLE_PORT ) ) != 0 ) { - DBG ( "Could not select UART %d: %s\n", - CONSOLE_PORT, strerror ( rc ) ); - return; - } - /* Initialise UART */ - if ( ( rc = uart_init ( &serial_console, CONSOLE_BAUD ) ) != 0 ) { - DBG ( "Could not initialise UART %d baud %d: %s\n", - CONSOLE_PORT, CONSOLE_BAUD, strerror ( rc ) ); + if ( ( rc = uart_init ( uart, COMSPEED ) ) != 0 ) { + DBGC ( uart, "SERIAL could not initialise %s baud %d: %s\n", + uart->name, COMSPEED, strerror ( rc ) ); return; } + + /* Record UART as serial console */ + serial_console = uart; + DBGC ( uart, "SERIAL using %s\n", uart->name ); } /** @@ -157,11 +155,11 @@ static void serial_init ( void ) { static void serial_shutdown ( int flags __unused ) { /* Do nothing if we have no UART */ - if ( ! serial_console.base ) + if ( ! serial_console ) return; /* Flush any pending output */ - uart_flush ( &serial_console ); + uart_flush ( serial_console ); /* Leave console enabled; it's still usable */ } diff --git a/src/core/uart.c b/src/core/uart.c index 4dc307fce..a645bd398 100644 --- a/src/core/uart.c +++ b/src/core/uart.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 Michael Brown . + * Copyright (C) 2025 Michael Brown . * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -25,125 +25,139 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** @file * - * 16550-compatible UART + * Generic UARTs * */ -#include +#include +#include #include #include -/** Timeout for transmit holding register to become empty */ -#define UART_THRE_TIMEOUT_MS 100 +/** List of registered UARTs */ +LIST_HEAD ( uarts ); -/** Timeout for transmitter to become empty */ -#define UART_TEMT_TIMEOUT_MS 1000 +static void null_uart_transmit ( struct uart *uart __unused, + uint8_t byte __unused ) { +} + +static int null_uart_data_ready ( struct uart *uart __unused ) { + return 0; +} + +static uint8_t null_uart_receive ( struct uart *uart __unused ) { + return 0; +} + +static int null_uart_init ( struct uart *uart __unused, + unsigned int baud __unused ) { + return 0; +} + +static void null_uart_flush ( struct uart *uart __unused ) { +} + +/** Null UART operations */ +struct uart_operations null_uart_operations = { + .transmit = null_uart_transmit, + .data_ready = null_uart_data_ready, + .receive = null_uart_receive, + .init = null_uart_init, + .flush = null_uart_flush, +}; /** - * Transmit data + * Allocate UART * - * @v uart UART - * @v data Data + * @v priv_len Length of private data + * @ret uart UART, or NULL on error */ -void uart_transmit ( struct uart *uart, uint8_t data ) { - unsigned int i; - uint8_t lsr; - - /* Wait for transmitter holding register to become empty */ - for ( i = 0 ; i < UART_THRE_TIMEOUT_MS ; i++ ) { - lsr = uart_read ( uart, UART_LSR ); - if ( lsr & UART_LSR_THRE ) - break; - mdelay ( 1 ); - } +struct uart * alloc_uart ( size_t priv_len ) { + struct uart *uart; + + /* Allocate and initialise UART */ + uart = zalloc ( sizeof ( *uart ) + priv_len ); + if ( ! uart ) + return NULL; + uart->priv = ( ( ( void * ) uart ) + sizeof ( *uart ) ); - /* Transmit data (even if we timed out) */ - uart_write ( uart, UART_THR, data ); + return uart; } /** - * Flush data + * Register fixed UARTs (when not provided by platform) * - * @v uart UART + * @ret rc Return status code */ -void uart_flush ( struct uart *uart ) { - unsigned int i; - uint8_t lsr; - - /* Wait for transmitter and receiver to become empty */ - for ( i = 0 ; i < UART_TEMT_TIMEOUT_MS ; i++ ) { - uart_read ( uart, UART_RBR ); - lsr = uart_read ( uart, UART_LSR ); - if ( ( lsr & UART_LSR_TEMT ) && ! ( lsr & UART_LSR_DR ) ) - break; - } +__weak int uart_register_fixed ( void ) { + + return 0; } /** - * Check for existence of UART + * Register UART * * @v uart UART * @ret rc Return status code */ -int uart_exists ( struct uart *uart ) { - - /* Fail if no UART port is defined */ - if ( ! uart->base ) - return -ENODEV; +int uart_register ( struct uart *uart ) { - /* Fail if UART scratch register seems not to be present */ - uart_write ( uart, UART_SCR, 0x18 ); - if ( uart_read ( uart, UART_SCR ) != 0x18 ) - return -ENODEV; - uart_write ( uart, UART_SCR, 0xae ); - if ( uart_read ( uart, UART_SCR ) != 0xae ) - return -ENODEV; + /* Add to list of registered UARTs */ + uart_get ( uart ); + list_add_tail ( &uart->list, &uarts ); + DBGC ( uart, "UART %s registered\n", uart->name ); return 0; } /** - * Initialise UART + * Unregister UART * * @v uart UART - * @v baud Baud rate, or zero to leave unchanged - * @ret rc Return status code */ -int uart_init ( struct uart *uart, unsigned int baud ) { - uint8_t dlm; - uint8_t dll; +void uart_unregister ( struct uart *uart ) { + + /* Remove from list of registered UARTs */ + list_del ( &uart->list ); + uart_put ( uart ); +} + +/** + * Find named UART + * + * @v name UART name + * @ret uart UART, or NULL if not found + */ +struct uart * uart_find ( const char *name ) { + struct uart *uart; + unsigned int index; + char *endp; int rc; - /* Check for existence of UART */ - if ( ( rc = uart_exists ( uart ) ) != 0 ) - return rc; - - /* Configure divisor and line control register, if applicable */ - uart_write ( uart, UART_LCR, ( UART_LCR_8N1 | UART_LCR_DLAB ) ); - if ( baud ) { - uart->divisor = ( UART_MAX_BAUD / baud ); - dlm = ( ( uart->divisor >> 8 ) & 0xff ); - dll = ( ( uart->divisor >> 0 ) & 0xff ); - uart_write ( uart, UART_DLM, dlm ); - uart_write ( uart, UART_DLL, dll ); - } else { - dlm = uart_read ( uart, UART_DLM ); - dll = uart_read ( uart, UART_DLL ); - uart->divisor = ( ( dlm << 8 ) | dll ); + /* Register fixed platform UARTs if not already registered */ + if ( list_empty ( &uarts ) ) { + if ( ( rc = uart_register_fixed() ) != 0 ) { + DBGC ( &uarts, "UART could not register fixed UARTs: " + "%s\n", strerror ( rc ) ); + /* Continue anyway */ + } } - uart_write ( uart, UART_LCR, UART_LCR_8N1 ); - /* Disable interrupts */ - uart_write ( uart, UART_IER, 0 ); + /* Try parsing name as a numeric index */ + index = strtoul ( name, &endp, 10 ); - /* Enable FIFOs */ - uart_write ( uart, UART_FCR, UART_FCR_FE ); + /* Find matching UART, if any */ + list_for_each_entry ( uart, &uarts, list ) { - /* Assert DTR and RTS */ - uart_write ( uart, UART_MCR, ( UART_MCR_DTR | UART_MCR_RTS ) ); + /* Check for a matching name */ + if ( strcasecmp ( name, uart->name ) == 0 ) + return uart; - /* Flush any stale data */ - uart_flush ( uart ); + /* Check for a matching numeric index */ + if ( ( *endp == '\0' ) && ( index-- == 0 ) ) + return uart; + } - return 0; + DBGC ( &uarts, "UART %s not found\n", name ); + return NULL; } diff --git a/src/drivers/uart/ns16550.c b/src/drivers/uart/ns16550.c new file mode 100644 index 000000000..58a71261b --- /dev/null +++ b/src/drivers/uart/ns16550.c @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2025 Michael Brown . + * + * 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 + * + * 16550-compatible UART + * + */ + +#include +#include +#include +#include + +/** Timeout for transmit holding register to become empty */ +#define NS16550_THRE_TIMEOUT_MS 100 + +/** Timeout for transmitter to become empty */ +#define NS16550_TEMT_TIMEOUT_MS 1000 + +/** + * Transmit data + * + * @v uart UART + * @v data Data + */ +static void ns16550_transmit ( struct uart *uart, uint8_t data ) { + struct ns16550_uart *ns16550 = + container_of ( uart, struct ns16550_uart, uart ); + unsigned int i; + uint8_t lsr; + + /* Wait for transmitter holding register to become empty */ + for ( i = 0 ; i < NS16550_THRE_TIMEOUT_MS ; i++ ) { + lsr = ns16550_read ( ns16550, NS16550_LSR ); + if ( lsr & NS16550_LSR_THRE ) + break; + mdelay ( 1 ); + } + + /* Transmit data (even if we timed out) */ + ns16550_write ( ns16550, NS16550_THR, data ); +} + +/** + * Check if data is ready + * + * @v uart UART + * @ret ready Data is ready + */ +static int ns16550_data_ready ( struct uart *uart ) { + struct ns16550_uart *ns16550 = + container_of ( uart, struct ns16550_uart, uart ); + uint8_t lsr; + + /* Check for receive data ready */ + lsr = ns16550_read ( ns16550, NS16550_LSR ); + return ( lsr & NS16550_LSR_DR ); +} + +/** + * Receive data + * + * @v uart UART + * @ret data Data + */ +static uint8_t ns16550_receive ( struct uart *uart ) { + struct ns16550_uart *ns16550 = + container_of ( uart, struct ns16550_uart, uart ); + uint8_t rbr; + + /* Receive byte */ + rbr = ns16550_read ( ns16550, NS16550_RBR ); + return rbr; +} + +/** + * Flush transmitted data + * + * @v uart UART + */ +static void ns16550_flush ( struct uart *uart ) { + struct ns16550_uart *ns16550 = + container_of ( uart, struct ns16550_uart, uart ); + unsigned int i; + uint8_t lsr; + + /* Wait for transmitter to become empty */ + for ( i = 0 ; i < NS16550_TEMT_TIMEOUT_MS ; i++ ) { + lsr = ns16550_read ( ns16550, NS16550_LSR ); + if ( lsr & NS16550_LSR_TEMT ) + break; + } +} + +/** + * Initialise UART + * + * @v uart UART + * @v baud Baud rate, or zero to leave unchanged + * @ret rc Return status code + */ +static int ns16550_init ( struct uart *uart, unsigned int baud ) { + struct ns16550_uart *ns16550 = + container_of ( uart, struct ns16550_uart, uart ); + uint8_t dlm; + uint8_t dll; + + /* Fail if UART scratch register seems not to be present */ + ns16550_write ( ns16550, NS16550_SCR, 0x18 ); + if ( ns16550_read ( ns16550, NS16550_SCR ) != 0x18 ) + return -ENODEV; + ns16550_write ( ns16550, NS16550_SCR, 0xae ); + if ( ns16550_read ( ns16550, NS16550_SCR ) != 0xae ) + return -ENODEV; + + /* Configure divisor and line control register, if applicable */ + ns16550_write ( ns16550, NS16550_LCR, + ( NS16550_LCR_8N1 | NS16550_LCR_DLAB ) ); + if ( baud ) { + ns16550->divisor = ( NS16550_MAX_BAUD / baud ); + dlm = ( ( ns16550->divisor >> 8 ) & 0xff ); + dll = ( ( ns16550->divisor >> 0 ) & 0xff ); + ns16550_write ( ns16550, NS16550_DLM, dlm ); + ns16550_write ( ns16550, NS16550_DLL, dll ); + } else { + dlm = ns16550_read ( ns16550, NS16550_DLM ); + dll = ns16550_read ( ns16550, NS16550_DLL ); + ns16550->divisor = ( ( dlm << 8 ) | dll ); + } + ns16550_write ( ns16550, NS16550_LCR, NS16550_LCR_8N1 ); + + /* Disable interrupts */ + ns16550_write ( ns16550, NS16550_IER, 0 ); + + /* Enable FIFOs */ + ns16550_write ( ns16550, NS16550_FCR, NS16550_FCR_FE ); + + /* Assert DTR and RTS */ + ns16550_write ( ns16550, NS16550_MCR, + ( NS16550_MCR_DTR | NS16550_MCR_RTS ) ); + + /* Flush any stale received data */ + while ( ns16550_data_ready ( uart ) ) + ns16550_receive ( uart ); + + return 0; +} + +/** 16550 UART operations */ +struct uart_operations ns16550_operations = { + .transmit = ns16550_transmit, + .data_ready = ns16550_data_ready, + .receive = ns16550_receive, + .init = ns16550_init, + .flush = ns16550_flush, +}; diff --git a/src/include/bits/ns16550.h b/src/include/bits/ns16550.h new file mode 100644 index 000000000..4b3e30c76 --- /dev/null +++ b/src/include/bits/ns16550.h @@ -0,0 +1,15 @@ +#ifndef _BITS_NS16550_H +#define _BITS_NS16550_H + +/** @file + * + * Dummy architecture-specific 16550-compatible UART + * + * This file is included only if the architecture does not provide its + * own version of this file. + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#endif /* _BITS_NS16550_H */ diff --git a/src/include/bits/uart.h b/src/include/bits/uart.h deleted file mode 100644 index e132d5c3d..000000000 --- a/src/include/bits/uart.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _BITS_UART_H -#define _BITS_UART_H - -/** @file - * - * Dummy architecture-specific UART - * - * This file is included only if the architecture does not provide its - * own version of this file. - * - */ - -FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); - -#endif /* _BITS_UART_H */ diff --git a/src/include/ipxe/errfile.h b/src/include/ipxe/errfile.h index d00191fbe..1a39af43f 100644 --- a/src/include/ipxe/errfile.h +++ b/src/include/ipxe/errfile.h @@ -109,6 +109,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define ERRFILE_spi_bit ( ERRFILE_DRIVER | 0x00130000 ) #define ERRFILE_nvsvpd ( ERRFILE_DRIVER | 0x00140000 ) #define ERRFILE_uart ( ERRFILE_DRIVER | 0x00150000 ) +#define ERRFILE_ns16550 ( ERRFILE_DRIVER | 0x00160000 ) #define ERRFILE_3c509 ( ERRFILE_DRIVER | 0x00200000 ) #define ERRFILE_bnx2 ( ERRFILE_DRIVER | 0x00210000 ) diff --git a/src/include/ipxe/gdbserial.h b/src/include/ipxe/gdbserial.h index 166eb4f0d..62cc16014 100644 --- a/src/include/ipxe/gdbserial.h +++ b/src/include/ipxe/gdbserial.h @@ -11,7 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); struct gdb_transport; -extern struct gdb_transport * gdbserial_configure ( unsigned int port, +extern struct gdb_transport * gdbserial_configure ( const char *port, unsigned int baud ); #endif /* _IPXE_GDBSERIAL_H */ diff --git a/src/include/ipxe/ns16550.h b/src/include/ipxe/ns16550.h new file mode 100644 index 000000000..f7bb55a84 --- /dev/null +++ b/src/include/ipxe/ns16550.h @@ -0,0 +1,112 @@ +#ifndef _IPXE_NS16550_H +#define _IPXE_NS16550_H + +/** @file + * + * 16550-compatible UART + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include + +/** Transmitter holding register */ +#define NS16550_THR 0x00 + +/** Receiver buffer register */ +#define NS16550_RBR 0x00 + +/** Interrupt enable register */ +#define NS16550_IER 0x01 + +/** FIFO control register */ +#define NS16550_FCR 0x02 +#define NS16550_FCR_FE 0x01 /**< FIFO enable */ + +/** Line control register */ +#define NS16550_LCR 0x03 +#define NS16550_LCR_WLS0 0x01 /**< Word length select bit 0 */ +#define NS16550_LCR_WLS1 0x02 /**< Word length select bit 1 */ +#define NS16550_LCR_STB 0x04 /**< Number of stop bits */ +#define NS16550_LCR_PEN 0x08 /**< Parity enable */ +#define NS16550_LCR_EPS 0x10 /**< Even parity select */ +#define NS16550_LCR_DLAB 0x80 /**< Divisor latch access bit */ + +#define NS16550_LCR_WORD_LEN(x) ( ( (x) - 5 ) << 0 ) /**< Word length */ +#define NS16550_LCR_STOP_BITS(x) ( ( (x) - 1 ) << 2 ) /**< Stop bits */ +#define NS16550_LCR_PARITY(x) ( ( (x) - 0 ) << 3 ) /**< Parity */ + +/** + * Calculate line control register value + * + * @v word_len Word length (5-8) + * @v parity Parity (0=none, 1=odd, 3=even) + * @v stop_bits Stop bits (1-2) + * @ret lcr Line control register value + */ +#define NS16550_LCR_WPS( word_len, parity, stop_bits ) \ + ( NS16550_LCR_WORD_LEN ( (word_len) ) | \ + NS16550_LCR_PARITY ( (parity) ) | \ + NS16550_LCR_STOP_BITS ( (stop_bits) ) ) + +/** Default LCR value: 8 data bits, no parity, one stop bit */ +#define NS16550_LCR_8N1 NS16550_LCR_WPS ( 8, 0, 1 ) + +/** Modem control register */ +#define NS16550_MCR 0x04 +#define NS16550_MCR_DTR 0x01 /**< Data terminal ready */ +#define NS16550_MCR_RTS 0x02 /**< Request to send */ + +/** Line status register */ +#define NS16550_LSR 0x05 +#define NS16550_LSR_DR 0x01 /**< Data ready */ +#define NS16550_LSR_THRE 0x20 /**< Transmitter holding reg. empty */ +#define NS16550_LSR_TEMT 0x40 /**< Transmitter empty */ + +/** Scratch register */ +#define NS16550_SCR 0x07 + +/** Divisor latch (least significant byte) */ +#define NS16550_DLL 0x00 + +/** Divisor latch (most significant byte) */ +#define NS16550_DLM 0x01 + +/** Maximum baud rate */ +#define NS16550_MAX_BAUD 115200 + +/** A 16550-compatible UART */ +struct ns16550_uart { + /** Generic UART */ + struct uart uart; + /** Register base address */ + void *base; + /** Baud rate divisor */ + uint16_t divisor; +}; + +#include + +/** Dummy COM1 UART for non-x86 platforms + * + * The architecture-independent config/serial.h header has long + * included the line + * + * #define COMCONSOLE COM1 + * + * which is meaningless on non-x86 platforms where there is no COM1 + * port. Allow COM1 to be treated as equivalent to "no UART" on + * non-x86 platforms, to avoid breaking existing build configurations. + */ +#ifndef COM1 +#define COM1 NULL +#endif + +void ns16550_write ( struct ns16550_uart *ns16550, unsigned int address, + uint8_t data ); +uint8_t ns16550_read ( struct ns16550_uart *ns16550, unsigned int address ); + +extern struct uart_operations ns16550_operations; + +#endif /* _IPXE_NS16550_H */ diff --git a/src/include/ipxe/serial.h b/src/include/ipxe/serial.h index 83be59c31..86a618670 100644 --- a/src/include/ipxe/serial.h +++ b/src/include/ipxe/serial.h @@ -11,6 +11,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include -extern struct uart serial_console; +extern struct uart *serial_console; #endif /* _IPXE_SERIAL_H */ diff --git a/src/include/ipxe/uart.h b/src/include/ipxe/uart.h index 86583ee2f..15adfa932 100644 --- a/src/include/ipxe/uart.h +++ b/src/include/ipxe/uart.h @@ -3,128 +3,174 @@ /** @file * - * 16550-compatible UART + * Generic UART * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include +#include +#include -/** Transmitter holding register */ -#define UART_THR 0x00 - -/** Receiver buffer register */ -#define UART_RBR 0x00 - -/** Interrupt enable register */ -#define UART_IER 0x01 +/** A generic UART */ +struct uart { + /** Reference count */ + struct refcnt refcnt; + /** Name */ + const char *name; + /** List of registered UARTs */ + struct list_head list; + + /** UART operations */ + struct uart_operations *op; + /** Driver-private data */ + void *priv; +}; -/** FIFO control register */ -#define UART_FCR 0x02 -#define UART_FCR_FE 0x01 /**< FIFO enable */ +/** UART operations */ +struct uart_operations { + /** + * Transmit byte + * + * @v uart UART + * @v byte Byte to transmit + * @ret rc Return status code + */ + void ( * transmit ) ( struct uart *uart, uint8_t byte ); + /** + * Check if data is ready + * + * @v uart UART + * @ret ready Data is ready + */ + int ( * data_ready ) ( struct uart *uart ); + /** + * Receive byte + * + * @v uart UART + * @ret byte Received byte + */ + uint8_t ( * receive ) ( struct uart *uart ); + /** + * Initialise UART + * + * @v uart UART + * @v baud Baud rate, or zero to leave unchanged + * @ret rc Return status code + */ + int ( * init ) ( struct uart *uart, unsigned int baud ); + /** + * Flush transmitted data + * + * @v uart UART + */ + void ( * flush ) ( struct uart *uart ); +}; -/** Line control register */ -#define UART_LCR 0x03 -#define UART_LCR_WLS0 0x01 /**< Word length select bit 0 */ -#define UART_LCR_WLS1 0x02 /**< Word length select bit 1 */ -#define UART_LCR_STB 0x04 /**< Number of stop bits */ -#define UART_LCR_PEN 0x08 /**< Parity enable */ -#define UART_LCR_EPS 0x10 /**< Even parity select */ -#define UART_LCR_DLAB 0x80 /**< Divisor latch access bit */ +/** + * Transmit byte + * + * @v uart UART + * @v byte Byte to transmit + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) void +uart_transmit ( struct uart *uart, uint8_t byte ) { -#define UART_LCR_WORD_LEN(x) ( ( (x) - 5 ) << 0 ) /**< Word length */ -#define UART_LCR_STOP_BITS(x) ( ( (x) - 1 ) << 2 ) /**< Stop bits */ -#define UART_LCR_PARITY(x) ( ( (x) - 0 ) << 3 ) /**< Parity */ + uart->op->transmit ( uart, byte ); +} /** - * Calculate line control register value + * Check if data is ready * - * @v word_len Word length (5-8) - * @v parity Parity (0=none, 1=odd, 3=even) - * @v stop_bits Stop bits (1-2) - * @ret lcr Line control register value + * @v uart UART + * @ret ready Data is ready */ -#define UART_LCR_WPS( word_len, parity, stop_bits ) \ - ( UART_LCR_WORD_LEN ( (word_len) ) | \ - UART_LCR_PARITY ( (parity) ) | \ - UART_LCR_STOP_BITS ( (stop_bits) ) ) - -/** Default LCR value: 8 data bits, no parity, one stop bit */ -#define UART_LCR_8N1 UART_LCR_WPS ( 8, 0, 1 ) +static inline __attribute__ (( always_inline )) int +uart_data_ready ( struct uart *uart ) { -/** Modem control register */ -#define UART_MCR 0x04 -#define UART_MCR_DTR 0x01 /**< Data terminal ready */ -#define UART_MCR_RTS 0x02 /**< Request to send */ + return uart->op->data_ready ( uart ); +} -/** Line status register */ -#define UART_LSR 0x05 -#define UART_LSR_DR 0x01 /**< Data ready */ -#define UART_LSR_THRE 0x20 /**< Transmitter holding register empty */ -#define UART_LSR_TEMT 0x40 /**< Transmitter empty */ +/** + * Receive byte + * + * @v uart UART + * @ret byte Received byte + */ +static inline __attribute__ (( always_inline )) uint8_t +uart_receive ( struct uart *uart ) { -/** Scratch register */ -#define UART_SCR 0x07 + return uart->op->receive ( uart ); +} -/** Divisor latch (least significant byte) */ -#define UART_DLL 0x00 +/** + * Initialise UART + * + * @v uart UART + * @v baud Baud rate, or zero to leave unchanged + * @ret rc Return status code + */ +static inline __attribute__ (( always_inline )) int +uart_init ( struct uart *uart, unsigned int baud ) { -/** Divisor latch (most significant byte) */ -#define UART_DLM 0x01 + return uart->op->init ( uart, baud ); +} -/** Maximum baud rate */ -#define UART_MAX_BAUD 115200 +/** + * Flush transmitted data + * + * @v uart UART + */ +static inline __attribute__ (( always_inline )) void +uart_flush ( struct uart *uart ) { -/** A 16550-compatible UART */ -struct uart { - /** I/O port base address */ - void *base; - /** Baud rate divisor */ - uint16_t divisor; -}; + uart->op->flush ( uart ); +} -/** Symbolic names for port indexes */ -enum uart_port { - COM1 = 1, - COM2 = 2, - COM3 = 3, - COM4 = 4, -}; +extern struct list_head uarts; +extern struct uart_operations null_uart_operations; -#include +/** + * Get reference to UART + * + * @v uart UART + * @ret uart UART + */ +static inline __attribute__ (( always_inline )) struct uart * +uart_get ( struct uart *uart ) { -void uart_write ( struct uart *uart, unsigned int addr, uint8_t data ); -uint8_t uart_read ( struct uart *uart, unsigned int addr ); -int uart_select ( struct uart *uart, unsigned int port ); + ref_get ( &uart->refcnt ); + return uart; +} /** - * Check if received data is ready + * Drop reference to UART * * @v uart UART - * @ret ready Data is ready */ -static inline int uart_data_ready ( struct uart *uart ) { - uint8_t lsr; +static inline __attribute__ (( always_inline )) void +uart_put ( struct uart *uart ) { - lsr = uart_read ( uart, UART_LSR ); - return ( lsr & UART_LSR_DR ); + ref_put ( &uart->refcnt ); } /** - * Receive data + * Nullify UART * * @v uart UART - * @ret data Data */ -static inline uint8_t uart_receive ( struct uart *uart ) { +static inline __attribute__ (( always_inline )) void +uart_nullify ( struct uart *uart ) { - return uart_read ( uart, UART_RBR ); + uart->op = &null_uart_operations; } -extern void uart_transmit ( struct uart *uart, uint8_t data ); -extern void uart_flush ( struct uart *uart ); -extern int uart_exists ( struct uart *uart ); -extern int uart_init ( struct uart *uart, unsigned int baud ); +extern struct uart * alloc_uart ( size_t priv_len ); +extern int uart_register ( struct uart *uart ); +extern int uart_register_fixed ( void ); +extern void uart_unregister ( struct uart *uart ); +extern struct uart * uart_find ( const char *name ); #endif /* _IPXE_UART_H */ -- cgit v1.2.3-55-g7522 From cca1cfd49ec3ac0ada90197d11118a99d16aed5b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 21 Jun 2025 23:11:56 +0100 Subject: [uart] Allow for dynamically registered 16550 UARTs Use the generic UART driver-private data pointer, rather than embedding the generic UART within the 16550 UART structure. Signed-off-by: Michael Brown --- src/arch/x86/core/x86_uart.c | 13 +++++++------ src/arch/x86/include/bits/ns16550.h | 16 ++++++++-------- src/arch/x86/interface/syslinux/comboot_call.c | 4 +--- src/drivers/uart/ns16550.c | 15 +++++---------- src/include/ipxe/ns16550.h | 2 -- 5 files changed, 21 insertions(+), 29 deletions(-) (limited to 'src/arch/x86/interface/syslinux') diff --git a/src/arch/x86/core/x86_uart.c b/src/arch/x86/core/x86_uart.c index 2580b931b..a1d643a58 100644 --- a/src/arch/x86/core/x86_uart.c +++ b/src/arch/x86/core/x86_uart.c @@ -35,13 +35,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** Define a fixed ISA UART */ #define ISA_UART( NAME, BASE ) \ - struct ns16550_uart NAME = { \ - .uart = { \ - .refcnt = REF_INIT ( ref_no_free ), \ - .name = #NAME, \ - .op = &ns16550_operations, \ - }, \ + static struct ns16550_uart ns16550_ ## NAME = { \ .base = ( ( void * ) (BASE) ), \ + }; \ + struct uart NAME = { \ + .refcnt = REF_INIT ( ref_no_free ), \ + .name = #NAME, \ + .op = &ns16550_operations, \ + .priv = &ns16550_ ## NAME, \ } /* Fixed ISA UARTs */ diff --git a/src/arch/x86/include/bits/ns16550.h b/src/arch/x86/include/bits/ns16550.h index 9f7d741ae..cc2bd84c1 100644 --- a/src/arch/x86/include/bits/ns16550.h +++ b/src/arch/x86/include/bits/ns16550.h @@ -46,15 +46,15 @@ ns16550_read ( struct ns16550_uart *ns16550, unsigned int address ) { #define COM4_BASE 0x2e8 /* Fixed ISA serial ports */ -extern struct ns16550_uart com1; -extern struct ns16550_uart com2; -extern struct ns16550_uart com3; -extern struct ns16550_uart com4; +extern struct uart com1; +extern struct uart com2; +extern struct uart com3; +extern struct uart com4; /* Fixed ISA serial port names */ -#define COM1 &com1.uart -#define COM2 &com2.uart -#define COM3 &com3.uart -#define COM4 &com4.uart +#define COM1 &com1 +#define COM2 &com2 +#define COM3 &com3 +#define COM4 &com4 #endif /* _BITS_NS16550_H */ diff --git a/src/arch/x86/interface/syslinux/comboot_call.c b/src/arch/x86/interface/syslinux/comboot_call.c index 97bdaeae3..c3e921075 100644 --- a/src/arch/x86/interface/syslinux/comboot_call.c +++ b/src/arch/x86/interface/syslinux/comboot_call.c @@ -447,9 +447,7 @@ static __asmcall __used void int22 ( struct i386_all_regs *ix86 ) { case 0x000B: /* Get Serial Console Configuration */ if ( serial_console ) { - struct ns16550_uart *comport = - container_of ( serial_console, - struct ns16550_uart, uart ); + struct ns16550_uart *comport = serial_console->priv; ix86->regs.dx = ( ( intptr_t ) comport->base ); ix86->regs.cx = comport->divisor; diff --git a/src/drivers/uart/ns16550.c b/src/drivers/uart/ns16550.c index 58a71261b..cf8c744c6 100644 --- a/src/drivers/uart/ns16550.c +++ b/src/drivers/uart/ns16550.c @@ -47,8 +47,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); * @v data Data */ static void ns16550_transmit ( struct uart *uart, uint8_t data ) { - struct ns16550_uart *ns16550 = - container_of ( uart, struct ns16550_uart, uart ); + struct ns16550_uart *ns16550 = uart->priv; unsigned int i; uint8_t lsr; @@ -71,8 +70,7 @@ static void ns16550_transmit ( struct uart *uart, uint8_t data ) { * @ret ready Data is ready */ static int ns16550_data_ready ( struct uart *uart ) { - struct ns16550_uart *ns16550 = - container_of ( uart, struct ns16550_uart, uart ); + struct ns16550_uart *ns16550 = uart->priv; uint8_t lsr; /* Check for receive data ready */ @@ -87,8 +85,7 @@ static int ns16550_data_ready ( struct uart *uart ) { * @ret data Data */ static uint8_t ns16550_receive ( struct uart *uart ) { - struct ns16550_uart *ns16550 = - container_of ( uart, struct ns16550_uart, uart ); + struct ns16550_uart *ns16550 = uart->priv; uint8_t rbr; /* Receive byte */ @@ -102,8 +99,7 @@ static uint8_t ns16550_receive ( struct uart *uart ) { * @v uart UART */ static void ns16550_flush ( struct uart *uart ) { - struct ns16550_uart *ns16550 = - container_of ( uart, struct ns16550_uart, uart ); + struct ns16550_uart *ns16550 = uart->priv; unsigned int i; uint8_t lsr; @@ -123,8 +119,7 @@ static void ns16550_flush ( struct uart *uart ) { * @ret rc Return status code */ static int ns16550_init ( struct uart *uart, unsigned int baud ) { - struct ns16550_uart *ns16550 = - container_of ( uart, struct ns16550_uart, uart ); + struct ns16550_uart *ns16550 = uart->priv; uint8_t dlm; uint8_t dll; diff --git a/src/include/ipxe/ns16550.h b/src/include/ipxe/ns16550.h index 3aaab6891..6699205e2 100644 --- a/src/include/ipxe/ns16550.h +++ b/src/include/ipxe/ns16550.h @@ -78,8 +78,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); /** A 16550-compatible UART */ struct ns16550_uart { - /** Generic UART */ - struct uart uart; /** Register base address */ void *base; /** Register shift */ -- cgit v1.2.3-55-g7522