176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef LIBRM_H 276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LIBRM_H 376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 476d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanFILE_LICENCE ( GPL2_OR_LATER ); 576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Segment selectors as used in our protected-mode GDTs. 776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Don't change these unless you really know what you're doing. 976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define VIRTUAL_CS 0x08 1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define VIRTUAL_DS 0x10 1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHYSICAL_CS 0x18 1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHYSICAL_DS 0x20 1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REAL_CS 0x28 1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REAL_DS 0x30 1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#if 0 1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LONG_CS 0x38 1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define LONG_DS 0x40 2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifndef ASSEMBLY 2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#ifdef UACCESS_LIBRM 2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define UACCESS_PREFIX_librm 2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#else 2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define UACCESS_PREFIX_librm __librm_ 2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif 2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Variables in librm.S */ 3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern unsigned long virt_offset; 3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Convert physical address to user pointer 3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v phys_addr Physical address 3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret userptr User pointer 3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline userptr_t 4076d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, phys_to_user ) ( unsigned long phys_addr ) { 4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( phys_addr - virt_offset ); 4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Convert user buffer to physical address 4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v userptr User pointer 4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v offset Offset from user pointer 4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret phys_addr Physical address 5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline unsigned long 5276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, user_to_phys ) ( userptr_t userptr, off_t offset ) { 5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( userptr + offset + virt_offset ); 5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline userptr_t 5776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, virt_to_user ) ( volatile const void *addr ) { 5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return trivial_virt_to_user ( addr ); 5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline void * 6276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, user_to_virt ) ( userptr_t userptr, off_t offset ) { 6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return trivial_user_to_virt ( userptr, offset ); 6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline userptr_t 6776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, userptr_add ) ( userptr_t userptr, off_t offset ) { 6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return trivial_userptr_add ( userptr, offset ); 6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline void 7276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, memcpy_user ) ( userptr_t dest, off_t dest_off, 7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman userptr_t src, off_t src_off, 7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t len ) { 7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman trivial_memcpy_user ( dest, dest_off, src, src_off, len ); 7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline void 7976d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, memmove_user ) ( userptr_t dest, off_t dest_off, 8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman userptr_t src, off_t src_off, 8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman size_t len ) { 8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman trivial_memmove_user ( dest, dest_off, src, src_off, len ); 8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline void 8676d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, memset_user ) ( userptr_t buffer, off_t offset, 8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int c, size_t len ) { 8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman trivial_memset_user ( buffer, offset, c, len ); 8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline size_t 9276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, strlen_user ) ( userptr_t buffer, off_t offset ) { 9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return trivial_strlen_user ( buffer, offset ); 9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline off_t 9776d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanUACCESS_INLINE ( librm, memchr_user ) ( userptr_t buffer, off_t offset, 9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman int c, size_t len ) { 9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return trivial_memchr_user ( buffer, offset, c, len ); 10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/****************************************************************************** 10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Access to variables in .data16 and .text16 10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern char *data16; 11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern char *text16; 11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __data16( variable ) \ 11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".data16" ) )) \ 11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _data16_ ## variable __asm__ ( #variable ) 11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __data16_array( variable, array ) \ 11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".data16" ) )) \ 11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _data16_ ## variable array __asm__ ( #variable ) 11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __bss16( variable ) \ 12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".bss16" ) )) \ 12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _data16_ ## variable __asm__ ( #variable ) 12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __bss16_array( variable, array ) \ 12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".bss16" ) )) \ 12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _data16_ ## variable array __asm__ ( #variable ) 12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __text16( variable ) \ 12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".text16.data" ) )) \ 13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _text16_ ## variable __asm__ ( #variable ) 13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __text16_array( variable, array ) \ 13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman __attribute__ (( section ( ".text16.data" ) )) \ 13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman _text16_ ## variable array __asm__ ( #variable ) 13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __use_data16( variable ) \ 13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( * ( ( typeof ( _data16_ ## variable ) * ) \ 13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman & ( data16 [ ( size_t ) & ( _data16_ ## variable ) ] ) ) ) 13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __use_text16( variable ) \ 14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( * ( ( typeof ( _text16_ ## variable ) * ) \ 14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman & ( text16 [ ( size_t ) & ( _text16_ ## variable ) ] ) ) ) 14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __from_data16( pointer ) \ 14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( ( unsigned int ) \ 14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( ( ( void * ) (pointer) ) - ( ( void * ) data16 ) ) ) 14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define __from_text16( pointer ) \ 14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( ( unsigned int ) \ 15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ( ( ( void * ) (pointer) ) - ( ( void * ) text16 ) ) ) 15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Variables in librm.S, present in the normal data segment */ 15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t rm_sp; 15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t rm_ss; 15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t __data16 ( rm_cs ); 15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define rm_cs __use_data16 ( rm_cs ) 15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t __text16 ( rm_ds ); 15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define rm_ds __use_text16 ( rm_ds ) 15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* Functions that librm expects to be able to link to. Included here 16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * so that the compiler will catch prototype mismatches. 16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void gateA20_set ( void ); 16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/** 16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * Convert segment:offset address to user buffer 16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * 16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v segment Real-mode segment 16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @v offset Real-mode offset 17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman * @ret buffer User buffer 17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman */ 17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanstatic inline __always_inline userptr_t 17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanreal_to_user ( unsigned int segment, unsigned int offset ) { 17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman return ( phys_to_user ( ( segment << 4 ) + offset ) ); 17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman} 17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern uint16_t copy_user_to_rm_stack ( userptr_t data, size_t size ); 17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmanextern void remove_user_from_rm_stack ( userptr_t data, size_t size ); 17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* TEXT16_CODE: declare a fragment of code that resides in .text16 */ 18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define TEXT16_CODE( asm_code_str ) \ 18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ".section \".text16\", \"ax\", @progbits\n\t" \ 18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ".code16\n\t" \ 18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm_code_str "\n\t" \ 18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ".code32\n\t" \ 18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman ".previous\n\t" 18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* REAL_CODE: declare a fragment of code that executes in real mode */ 18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define REAL_CODE( asm_code_str ) \ 19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "pushl $1f\n\t" \ 19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "call real_call\n\t" \ 19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "addl $4, %%esp\n\t" \ 19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman TEXT16_CODE ( "\n1:\n\t" \ 19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm_code_str \ 19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "\n\t" \ 19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "ret\n\t" ) 19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman/* PHYS_CODE: declare a fragment of code that executes in flat physical mode */ 19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#define PHYS_CODE( asm_code_str ) \ 20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "call _virt_to_phys\n\t" \ 20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman asm_code_str \ 20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman "call _phys_to_virt\n\t" 20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* ASSEMBLY */ 20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman 20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman#endif /* LIBRM_H */ 207