Changeset e3c762cd in mainline for arch


Ignore:
Timestamp:
2006-05-05T11:59:19Z (19 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
de07bcf
Parents:
22cf454d
Message:

Complete implementation of copy_from_uspace() and copy_to_uspace()
for amd64 and ia32. Other architectures still compile and run,
but need to implement their own assembly-only memcpy(), memcpy_from_uspace(),
memcpy_to_uspace() and their failover parts. For these architectures
only dummy implementations are provided.

Location:
arch
Files:
19 edited

Legend:

Unmodified
Added
Removed
  • arch/amd64/include/interrupt.h

    r22cf454d re3c762cd  
    8787};
    8888
     89static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     90{
     91        istate->rip = retaddr;
     92}
     93
    8994extern void (* disable_irqs_function)(__u16 irqmask);
    9095extern void (* enable_irqs_function)(__u16 irqmask);
  • arch/amd64/src/asm_utils.S

    r22cf454d re3c762cd  
    6161        jmp printf
    6262
    63 .global memcpy
    64 memcpy:
    65         jmp _memcpy
    66        
    6763.global cpuid
    6864.global has_cpuid
     
    7066.global read_efer_flag
    7167.global set_efer_flag
    72        
     68.global memcpy
     69.global memcpy_from_uspace
     70.global memcpy_to_uspace
     71.global memcpy_from_uspace_failover_address
     72.global memcpy_to_uspace_failover_address
     73
     74#define MEMCPY_DST      %rdi
     75#define MEMCPY_SRC      %rsi
     76#define MEMCPY_SIZE     %rdx
     77
     78/**
     79 * Copy memory from/to userspace.
     80 *
     81 * This is almost conventional memcpy().
     82 * The difference is that there is a failover part
     83 * to where control is returned from a page fault if
     84 * the page fault occurs during copy_from_uspace()
     85 * or copy_to_uspace().
     86 *
     87 * @param MEMCPY_DST    Destination address.
     88 * @param MEMCPY_SRC    Source address.
     89 * @param MEMCPY_SIZE   Number of bytes to copy.
     90 *
     91 * @retrun MEMCPY_SRC on success, 0 on failure.
     92 */
     93memcpy:
     94memcpy_from_uspace:
     95memcpy_to_uspace:
     96        movq MEMCPY_SRC, %rax
     97
     98        movq MEMCPY_SIZE, %rcx
     99        shrq $3, %rcx                   /* size / 8 */
     100       
     101        rep movsq                       /* copy as much as possible word by word */
     102
     103        movq MEMCPY_SIZE, %rcx
     104        andq $7, %rcx                   /* size % 8 */
     105        jz 0f
     106       
     107        rep movsb                       /* copy the rest byte by byte */
     108       
     1090:
     110        ret                             /* return MEMCPY_SRC, success */
     111
     112memcpy_from_uspace_failover_address:
     113memcpy_to_uspace_failover_address:
     114        xorq %rax, %rax                 /* return 0, failure */
     115        ret
     116
    73117## Determine CPUID support
    74118#
  • arch/amd64/src/mm/page.c

    r22cf454d re3c762cd  
    167167       
    168168        page = read_cr2();
    169         if (!as_page_fault(page)) {
     169        if (as_page_fault(page, istate) == AS_PF_FAULT) {
    170170                print_info_errcode(n, istate);
    171171                printf("Page fault address: %llX\n", page);
  • arch/ia32/include/interrupt.h

    r22cf454d re3c762cd  
    8484};
    8585
     86static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     87{
     88        istate->eip = retaddr;
     89}
     90
    8691extern void (* disable_irqs_function)(__u16 irqmask);
    8792extern void (* enable_irqs_function)(__u16 irqmask);
  • arch/ia32/src/asm.S

    r22cf454d re3c762cd  
    3838.global enable_l_apic_in_msr
    3939.global interrupt_handlers
     40.global memcpy
     41.global memcpy_from_uspace
     42.global memcpy_from_uspace_failover_address
     43.global memcpy_to_uspace
     44.global memcpy_to_uspace_failover_address
     45
     46
     47#define MEMCPY_DST      4
     48#define MEMCPY_SRC      8
     49#define MEMCPY_SIZE     12
     50
     51/** Copy memory to/from userspace.
     52 *
     53 * This is almost conventional memcpy().
     54 * The difference is that there is a failover part
     55 * to where control is returned from a page fault
     56 * if the page fault occurs during copy_from_uspace()
     57 * or copy_to_uspace().
     58 *
     59 * @param MEMCPY_DST(%esp)      Destination address.
     60 * @param MEMCPY_SRC(%esp)      Source address.
     61 * @param MEMCPY_SIZE(%esp)     Size.
     62 *
     63 * @return MEMCPY_SRC(%esp) on success and 0 on failure.
     64 */
     65memcpy:
     66memcpy_from_uspace:
     67memcpy_to_uspace:
     68        movl %edi, %edx                         /* save %edi */
     69        movl %esi, %eax                         /* save %esi */
     70       
     71        movl MEMCPY_SIZE(%esp), %ecx
     72        shrl $2, %ecx                           /* size / 4 */
     73       
     74        movl MEMCPY_DST(%esp), %edi
     75        movl MEMCPY_SRC(%esp), %esi
     76       
     77        rep movsl                               /* copy as much as possible word by word */
     78
     79        movl MEMCPY_SIZE(%esp), %ecx
     80        andl $3, %ecx                           /* size % 4 */
     81        jz 0f
     82       
     83        rep movsb                               /* copy the rest byte by byte */
     84
     850:
     86        movl %edx, %edi
     87        movl %eax, %esi
     88        movl MEMCPY_SRC(%esp), %eax             /* MEMCPY_SRC(%esp), success */
     89        ret
     90       
     91/*
     92 * We got here from as_page_fault() after the memory operations
     93 * above had caused a page fault.
     94 */
     95memcpy_from_uspace_failover_address:
     96memcpy_to_uspace_failover_address:
     97        movl %edx, %edi
     98        movl %eax, %esi
     99        xorl %eax, %eax                         /* return 0, failure */
     100        ret
    40101
    41102## Turn paging on
  • arch/ia32/src/boot/boot.S

    r22cf454d re3c762cd  
    3535#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
    3636
    37 
    38 
    39 
    40 
    41 
    42 
    43 
    44 
    4537.section K_TEXT_START, "ax"
    4638
     
    436428#endif 
    437429
    438 
    439 
    440430.section K_DATA_START, "aw", @progbits
    441 
    442 
    443431
    444432.align 4096
  • arch/ia32/src/interrupt.c

    r22cf454d re3c762cd  
    145145
    146146        page = read_cr2();
    147         if (!as_page_fault(page)) {
     147        if (as_page_fault(page, istate) == AS_PF_FAULT) {
    148148                PRINT_INFO_ERRCODE(istate);
    149149                printf("page fault address: %#x\n", page);
  • arch/ia64/include/interrupt.h

    r22cf454d re3c762cd  
    107107};
    108108
     109static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     110{
     111        /* TODO */
     112}
     113
    109114extern void *ivt;
    110115
  • arch/ia64/src/asm.S

    r22cf454d re3c762cd  
    3131.text
    3232
     33/** Copy memory from/to userspace.
     34 *
     35 * @param in0 Destination address.
     36 * @param in1 Source address.
     37 * @param in2 Number of byte to copy.
     38 */
    3339.global memcpy
     40.global memcpy_from_uspace
     41.global memcpy_to_uspace
     42.global memcpy_from_uspace_failover_address
     43.global memcpy_to_uspace_failover_address
    3444memcpy:
     45memcpy_from_uspace:
     46memcpy_to_uspace:
    3547        br _memcpy
     48       
     49memcpy_from_uspace_failover_address:
     50memcpy_to_uspace_failover_address:
     51        br memcpy_from_uspace_failover_address
    3652
    3753.global memsetb
  • arch/ia64/src/mm/tlb.c

    r22cf454d re3c762cd  
    448448                 */
    449449                page_table_unlock(AS, true);
    450                 if (!as_page_fault(va)) {
     450                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    451451                        panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, istate->cr_ifa, rr.map.rid, istate->cr_iip);
    452452                }
     
    494494                 */
    495495                page_table_unlock(AS, true);
    496                 if (!as_page_fault(va)) {
     496                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    497497                        panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
    498498                }
     
    609609        } else {
    610610                page_table_unlock(AS, true);
    611                 if (!as_page_fault(va)) {
     611                if (as_page_fault(va, istate) == AS_PF_FAULT) {
    612612                        panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rr.map.rid);
    613613                }
  • arch/mips32/include/exception.h

    r22cf454d re3c762cd  
    9494};
    9595
     96static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     97{
     98        /* TODO */
     99}
     100
    96101extern void exception(istate_t *istate);
    97102extern void tlb_refill_entry(void);
  • arch/mips32/src/asm.S

    r22cf454d re3c762cd  
    5858        nop
    5959
     60
    6061.global memcpy
     62.global memcpy_from_uspace
     63.global memcpy_to_uspace
     64.global memcpy_from_uspace_failover_address
     65.global memcpy_to_uspace_failover_address
    6166memcpy:
     67memcpy_from_uspace:
     68memcpy_to_uspace:
    6269        j _memcpy
    6370        nop
     71
     72memcpy_from_uspace_failover_address:
     73memcpy_to_uspace_failover_address:
     74        j memcpy_from_uspace_failover_address
     75        nop
     76
     77
    6478
    6579.macro fpu_gp_save reg ctx
  • arch/mips32/src/mm/tlb.c

    r22cf454d re3c762cd  
    4545static void tlb_modified_fail(istate_t *istate);
    4646
    47 static pte_t *find_mapping_and_check(__address badvaddr);
     47static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc);
    4848
    4949static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, __address pfn);
     
    9292        __address badvaddr;
    9393        pte_t *pte;
     94        int pfrc;
    9495
    9596        badvaddr = cp0_badvaddr_read();
     
    101102        page_table_lock(AS, true);
    102103
    103         pte = find_mapping_and_check(badvaddr);
    104         if (!pte)
    105                 goto fail;
     104        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     105        if (!pte) {
     106                switch (pfrc) {
     107                case AS_PF_FAULT:
     108                        goto fail;
     109                        break;
     110                case AS_PF_DEFER:
     111                        /*
     112                         * The page fault came during copy_from_uspace()
     113                         * or copy_to_uspace().
     114                         */
     115                        page_table_unlock(AS, true);
     116                        return;
     117                default:
     118                        panic("unexpected pfrc (%d)\n", pfrc);
     119                }
     120        }
    106121
    107122        /*
     
    149164        entry_hi_t hi;
    150165        pte_t *pte;
     166        int pfrc;
    151167
    152168        badvaddr = cp0_badvaddr_read();
     
    171187        }
    172188
    173         pte = find_mapping_and_check(badvaddr);
    174         if (!pte)
    175                 goto fail;
     189        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     190        if (!pte) {
     191                switch (pfrc) {
     192                case AS_PF_FAULT:
     193                        goto fail;
     194                        break;
     195                case AS_PF_DEFER:
     196                        /*
     197                         * The page fault came during copy_from_uspace()
     198                         * or copy_to_uspace().
     199                         */
     200                        page_table_unlock(AS, true);                     
     201                        return;
     202                default:
     203                        panic("unexpected pfrc (%d)\n", pfrc);
     204                }
     205        }
    176206
    177207        /*
     
    218248        entry_hi_t hi;
    219249        pte_t *pte;
     250        int pfrc;
    220251
    221252        badvaddr = cp0_badvaddr_read();
     
    240271        }
    241272
    242         pte = find_mapping_and_check(badvaddr);
    243         if (!pte)
    244                 goto fail;
     273        pte = find_mapping_and_check(badvaddr, istate, &pfrc);
     274        if (!pte) {
     275                switch (pfrc) {
     276                case AS_PF_FAULT:
     277                        goto fail;
     278                        break;
     279                case AS_PF_DEFER:
     280                        /*
     281                         * The page fault came during copy_from_uspace()
     282                         * or copy_to_uspace().
     283                         */
     284                        page_table_unlock(AS, true);                     
     285                        return;
     286                default:
     287                        panic("unexpected pfrc (%d)\n", pfrc);
     288                }
     289        }
    245290
    246291        /*
     
    322367 *
    323368 * @param badvaddr Faulting virtual address.
     369 * @param istate Pointer to interrupted state.
     370 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
    324371 *
    325372 * @return PTE on success, NULL otherwise.
    326373 */
    327 pte_t *find_mapping_and_check(__address badvaddr)
     374pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfrc)
    328375{
    329376        entry_hi_t hi;
     
    351398                return pte;
    352399        } else {
     400                int rc;
     401               
    353402                /*
    354403                 * Mapping not found in page tables.
     
    356405                 */
    357406                page_table_unlock(AS, true);
    358                 if (as_page_fault(badvaddr)) {
     407                switch (rc = as_page_fault(badvaddr, istate)) {
     408                case AS_PF_OK:
    359409                        /*
    360410                         * The higher-level page fault handler succeeded,
     
    365415                        ASSERT(pte && pte->p);
    366416                        return pte;
    367                 } else {
     417                        break;
     418                case AS_PF_DEFER:
     419                        page_table_lock(AS, true);
     420                        *pfrc = AS_PF_DEFER;
     421                        return NULL;
     422                        break;
     423                case AS_PF_FAULT:
    368424                        page_table_lock(AS, true);
    369425                        printf("Page fault.\n");
     426                        *pfrc = AS_PF_FAULT;
    370427                        return NULL;
     428                        break;
     429                default:
     430                        panic("unexpected rc (%d)\n", rc);
    371431                }
    372432               
  • arch/ppc32/include/exception.h

    r22cf454d re3c762cd  
    7777};
    7878
     79static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     80{
     81        /* TODO */
     82}
     83
    7984#endif
  • arch/ppc32/include/interrupt.h

    r22cf454d re3c762cd  
    3030#define __ppc32_INTERRUPT_H__
    3131
     32#include <arch/exception.h>
     33
    3234#define IRQ_COUNT       1
    3335#define IVT_ITEMS   15
  • arch/ppc32/src/asm.S

    r22cf454d re3c762cd  
    3636.global memsetb
    3737.global memcpy
     38.global memcpy_from_uspace
     39.global memcpy_to_uspace
     40.global memcpy_from_uspace_failover_address
     41.global memcpy_to_uspace_failover_address
    3842
    3943userspace_asm:
     
    234238
    235239memcpy:
     240memcpy_from_uspace:
     241memcpy_to_uspace:
     242
    236243        srwi. r7, r5, 3
    237244        addi r6, r3, -4
     
    294301        mtctr r7
    295302        b 1b
     303
     304memcpy_from_uspace_failover_address:
     305memcpy_to_uspace_failover_address:
     306        b memcpy_from_uspace_failover_address
  • arch/ppc32/src/mm/tlb.c

    r22cf454d re3c762cd  
    6969 *
    7070 * @param badvaddr Faulting virtual address.
     71 * @param istate Pointer to interrupted state.
     72 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
    7173 * @return         PTE on success, NULL otherwise.
    7274 *
    7375 */
    74 static pte_t *find_mapping_and_check(__address badvaddr)
     76static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
    7577{
    7678        /*
     
    8587                return pte;
    8688        } else {
     89                int rc;
     90       
    8791                /*
    8892                 * Mapping not found in page tables.
     
    9094                 */
    9195                page_table_unlock(AS, true);
    92                 if (as_page_fault(badvaddr)) {
     96                switch (rc = as_page_fault(badvaddr, istate)) {
     97                case AS_PF_OK:
    9398                        /*
    9499                         * The higher-level page fault handler succeeded,
     
    99104                        ASSERT((pte) && (pte->p));
    100105                        return pte;
    101                 } else {
     106                        break;
     107                case AS_PF_DEFER:
     108                        page_table_lock(AS, true);
     109                        *pfcr = rc;
     110                        return NULL;
     111                        break;
     112                case AS_PF_FAULT:
    102113                        page_table_lock(AS, true);
    103114                        printf("Page fault.\n");
     115                        *pfcr = rc;
    104116                        return NULL;
    105                 }
    106                
     117                        break;
     118                default:
     119                        panic("unexpected rc (%d)\n", rc);
     120                        break;
     121                }       
    107122        }
    108123}
     
    140155        __u32 hash;
    141156        __u32 i;
     157        int pfcr;
    142158       
    143159        if (data) {
     
    155171        page_table_lock(AS, true);
    156172       
    157         pte = find_mapping_and_check(badvaddr);
    158         if (!pte)
    159                 goto fail;
     173        pte = find_mapping_and_check(badvaddr, istate, &pfcr);
     174        if (!pte) {
     175                switch (pfcr) {
     176                case AS_PF_FAULT:
     177                        goto fail;
     178                        break;
     179                case AS_PF_DEFER:
     180                        /*
     181                         * The page fault came during copy_from_uspace()
     182                         * or copy_to_uspace().
     183                         */
     184                        page_table_unlock(AS, true);
     185                        return;
     186                default:
     187                        panic("Unexpected pfrc (%d)\n", pfcr);
     188                        break;
     189                }
     190        }
    160191
    161192        /* Record access to PTE */
  • arch/sparc64/include/interrupt.h

    r22cf454d re3c762cd  
    3131
    3232#include <typedefs.h>
     33#include <arch/types.h>
    3334
    3435#define IRQ_COUNT       1       /* TODO */
     
    4445#define trap_virtual_eoi()
    4546
     47struct istate {
     48};
     49
     50static inline void istate_set_retaddr(istate_t *istate, __address retaddr)
     51{
     52        /* TODO */
     53}
     54
    4655extern void interrupt_register(int n, const char *name, iroutine f);
    4756
  • arch/sparc64/src/asm.S

    r22cf454d re3c762cd  
    3030
    3131.global memcpy
     32.global memcpy_from_uspace
     33.global memcpy_to_uspace
     34.global memcpy_from_uspace_failover_address
     35.global memcpy_to_uspace_failover_address
    3236.global memsetb
    3337
    3438memcpy:
     39memcpy_from_uspace:
     40memcpy_to_uspace:
     41
    3542        b _memcpy
     43        nop
     44
     45memcpy_from_uspace_failover_address:
     46memcpy_to_uspace_failover_address:
     47        b memcpy_from_uspace_failover_address
    3648        nop
    3749
Note: See TracChangeset for help on using the changeset viewer.