Changeset 694ca93f in mainline for kernel


Ignore:
Timestamp:
2011-05-01T19:34:26Z (15 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e26444
Parents:
1ff896e (diff), 042fbe0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Location:
kernel
Files:
3 added
5 deleted
62 edited
1 moved

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r1ff896e r694ca93f  
    134134#
    135135AFLAGS =
    136 LFLAGS = -N -T $(LINK) -M
     136LFLAGS = -n -T $(LINK) -M
    137137
    138138#
     
    226226        generic/src/proc/task.c \
    227227        generic/src/proc/the.c \
    228         generic/src/proc/tasklet.c \
    229228        generic/src/syscall/syscall.c \
    230229        generic/src/syscall/copy.c \
     230        generic/src/mm/reserve.c \
    231231        generic/src/mm/buddy.c \
    232232        generic/src/mm/frame.c \
     
    240240        generic/src/lib/func.c \
    241241        generic/src/lib/memstr.c \
     242        generic/src/lib/memfnc.c \
    242243        generic/src/lib/sort.c \
    243244        generic/src/lib/str.c \
     
    381382                generic/src/main/kinit.c \
    382383                generic/src/proc/the.c \
    383                 generic/src/proc/tasklet.c \
    384384                generic/src/mm/frame.c \
    385385                generic/src/mm/page.c \
  • kernel/arch/abs32le/include/types.h

    r1ff896e r694ca93f  
    4040
    4141typedef uint32_t size_t;
     42typedef int32_t ssize_t;
    4243
    4344typedef uint32_t uintptr_t;
  • kernel/arch/amd64/Makefile.inc

    r1ff896e r694ca93f  
    3333
    3434FPU_NO_CFLAGS = -mno-sse -mno-sse2
    35 CMN1 = -m64 -mcmodel=large -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
     35
     36#
     37# FIXME:
     38#
     39# The -fno-optimize-sibling-calls should be removed as soon as a bug
     40# in GCC concerning the "large" memory model and tail call optimization
     41# is fixed.
     42#
     43# If GCC generates a code for tail call, instead of generating ..
     44#
     45#   jmp *fnc
     46#
     47# it generates an assembly code with an illegal immediate prefix:
     48#
     49#   jmp *$fnc
     50#
     51
     52CMN1 = -m64 -mcmodel=large -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer -fno-optimize-sibling-calls
    3653GCC_CFLAGS += $(CMN1)
    3754ICC_CFLAGS += $(CMN1)
  • kernel/arch/amd64/_link.ld.in

    r1ff896e r694ca93f  
    2626        .mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)) : AT (SIZEOF(.unmapped)) {
    2727                ktext_start = .;
    28                 *(.text);
     28                *(.text .text.*);
    2929                ktext_end = .;
    3030               
    3131                kdata_start = .;
    32                 *(.data);       /* initialized data */
    33                 *(.rodata*);    /* string literals */
     32                *(.data);              /* initialized data */
     33                *(.rodata .rodata.*);  /* string literals */
    3434                hardcoded_load_address = .;
    3535                QUAD(PA2KA(BOOT_OFFSET));
  • kernel/arch/amd64/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint64_t size_t;
     39typedef int64_t ssize_t;
    3940
    4041typedef uint64_t uintptr_t;
  • kernel/arch/amd64/src/asm.S

    r1ff896e r694ca93f  
    3737.global read_efer_flag
    3838.global set_efer_flag
    39 .global memsetb
    40 .global memsetw
    41 .global memcpy
    4239.global memcpy_from_uspace
    4340.global memcpy_to_uspace
     
    4643.global early_putchar
    4744
    48 /* Wrapper for generic memsetb */
    49 memsetb:
    50         jmp _memsetb
    51 
    52 /* Wrapper for generic memsetw */
    53 memsetw:
    54         jmp _memsetw
    55 
    5645#define MEMCPY_DST   %rdi
    5746#define MEMCPY_SRC   %rsi
     
    7463 *
    7564 */
    76 memcpy:
    7765memcpy_from_uspace:
    7866memcpy_to_uspace:
  • kernel/arch/arm32/include/types.h

    r1ff896e r694ca93f  
    4444
    4545typedef uint32_t size_t;
     46typedef int32_t ssize_t;
    4647
    4748typedef uint32_t uintptr_t;
  • kernel/arch/arm32/src/asm.S

    r1ff896e r694ca93f  
    2929.text
    3030
    31 .global memsetb
    32 .global memsetw
    33 .global memcpy
    3431.global memcpy_from_uspace
    3532.global memcpy_to_uspace
     
    3835.global early_putchar
    3936
    40 memsetb:
    41         b _memsetb
    42 
    43 memsetw:
    44         b _memsetw
    45 
    46 memcpy:
    4737memcpy_from_uspace:
    4838memcpy_to_uspace:
  • kernel/arch/arm32/src/exception.c

    r1ff896e r694ca93f  
    3535
    3636#include <arch/exception.h>
    37 #include <arch/memstr.h>
    3837#include <arch/regutils.h>
    3938#include <arch/machine_func.h>
  • kernel/arch/arm32/src/mach/integratorcp/integratorcp.c

    r1ff896e r694ca93f  
    292292                .y = 480,
    293293                .scan = 2560,
    294                 .visual = VISUAL_BGR_0_8_8_8,
     294                .visual = VISUAL_RGB_8_8_8_0,
    295295        };
    296296       
  • kernel/arch/ia32/_link.ld.in

    r1ff896e r694ca93f  
    2525        .mapped (PA2KA(BOOT_OFFSET)+SIZEOF(.unmapped)): AT (SIZEOF(.unmapped)) {
    2626                ktext_start = .;
    27                 *(.text);
     27                *(.text .text.*);
    2828                ktext_end = .;
    2929               
    3030                kdata_start = .;
    3131                *(.data);               /* initialized data */
    32                 *(.rodata*);            /* string literals */
     32                *(.rodata .rodata.*);   /* string literals */
    3333                *(COMMON);              /* global variables */
    3434                hardcoded_load_address = .;
  • kernel/arch/ia32/include/barrier.h

    r1ff896e r694ca93f  
    5454NO_TRACE static inline void cpuid_serialization(void)
    5555{
     56#ifndef __IN_SHARED_LIBC__
    5657        asm volatile (
    5758                "xorl %%eax, %%eax\n"
     
    5960                ::: "eax", "ebx", "ecx", "edx", "memory"
    6061        );
     62#else
     63        /* Must not clobber PIC register ebx */
     64        asm volatile (
     65                "movl %%ebx, %%esi\n"
     66                "xorl %%eax, %%eax\n"
     67                "cpuid\n"
     68                "movl %%esi, %%ebx\n"
     69                ::: "eax", "ecx", "edx", "esi", "memory"
     70        );
     71#endif
    6172}
    6273
  • kernel/arch/ia32/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint32_t size_t;
     39typedef int32_t ssize_t;
    3940
    4041typedef uint32_t uintptr_t;
  • kernel/arch/ia32/src/asm.S

    r1ff896e r694ca93f  
    3838.global paging_on
    3939.global enable_l_apic_in_msr
    40 .global memsetb
    41 .global memsetw
    42 .global memcpy
    4340.global memcpy_from_uspace
    4441.global memcpy_from_uspace_failover_address
     
    4744.global early_putchar
    4845
    49 /* Wrapper for generic memsetb */
    50 memsetb:
    51         jmp _memsetb
    52 
    53 /* Wrapper for generic memsetw */
    54 memsetw:
    55         jmp _memsetw
    56 
    5746#define MEMCPY_DST   4
    5847#define MEMCPY_SRC   8
     
    7463 *
    7564 */
    76 memcpy:
    7765memcpy_from_uspace:
    7866memcpy_to_uspace:
  • kernel/arch/ia32/src/cpu/cpu.c

    r1ff896e r694ca93f  
    9292void cpu_arch_init(void)
    9393{
    94         cpuid_extended_feature_info efi;
    9594        cpu_info_t info;
    9695        uint32_t help = 0;
     
    104103       
    105104        CPU->arch.fi.word = info.cpuid_edx;
    106         efi.word = info.cpuid_ecx;
    107105       
    108106        if (CPU->arch.fi.bits.fxsr)
  • kernel/arch/ia64/_link.ld.in

    r1ff896e r694ca93f  
    1616                ktext_start = .;
    1717                *(K_TEXT_START);
    18                 *(.text)
     18                *(.text .text.*)
    1919                ktext_end = .;
    2020               
     
    3030                hardcoded_kdata_size = .;
    3131                QUAD(kdata_end - kdata_start);
     32                __gp = .;
    3233                *(.got .got.*)
    3334                *(.sdata)
     
    3637                *(.bss)
    3738                *(COMMON);
    38 
     39               
    3940                . = ALIGN(8);
    40                 symbol_table = .;
    41                 *(symtab.*);            /* Symbol table, must be LAST symbol!*/
    42 
     41                symbol_table = .;
     42                *(symtab.*);            /* Symbol table, must be LAST symbol!*/
     43               
    4344                kdata_end = .;
    4445        }
    45 
     46       
    4647        /DISCARD/ : {
    4748                *(*);
    4849        }
    49 
    5050}
  • kernel/arch/ia64/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint64_t size_t;
     39typedef int64_t ssize_t;
    3940
    4041typedef uint64_t uintptr_t;
  • kernel/arch/ia64/src/asm.S

    r1ff896e r694ca93f  
    3030
    3131.text
    32 .global memcpy
    3332.global memcpy_from_uspace
    3433.global memcpy_to_uspace
     
    3938 *
    4039 * This memcpy() has been taken from the assembler output of
    41  * the generic _memcpy() and modified to have the failover part.
     40 * a plain C implementation of memcpy() modified to have the
     41 * failover part.
    4242 *
    4343 * @param in0 Destination address.
     
    4646 *
    4747 */
    48 memcpy:
    4948memcpy_from_uspace:
    5049memcpy_to_uspace:
     
    141140        br.ret.sptk.many rp
    142141
    143 .global memsetb
    144 memsetb:
    145         br _memsetb
    146 
    147 .global memsetw
    148 memsetw:
    149         br _memsetw
    150 
    151142.global cpu_halt
    152143cpu_halt:
  • kernel/arch/ia64/src/ivt.S

    r1ff896e r694ca93f  
    391391
    392392    /* 10. call handler */
    393         movl r1 = kernel_image_start
     393        movl r1 = __gp
    394394   
    395395        mov b1 = loc2
  • kernel/arch/ia64/src/mm/tlb.c

    r1ff896e r694ca93f  
    475475void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
    476476{
    477         region_register_t rr;
    478         rid_t rid;
    479477        uintptr_t va;
    480478        pte_t *t;
    481479       
    482480        va = istate->cr_ifa; /* faulting address */
    483         rr.word = rr_read(VA2VRN(va));
    484         rid = rr.map.rid;
    485481       
    486482        page_table_lock(AS, true);
     
    649645void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
    650646{
    651         region_register_t rr;
    652         rid_t rid;
    653647        uintptr_t va;
    654648        pte_t *t;
    655649       
    656650        va = istate->cr_ifa;  /* faulting address */
    657         rr.word = rr_read(VA2VRN(va));
    658         rid = rr.map.rid;
    659651       
    660652        page_table_lock(AS, true);
     
    686678void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
    687679{
    688         region_register_t rr;
    689         rid_t rid;
    690680        uintptr_t va;
    691681        pte_t *t;
    692682       
    693683        va = istate->cr_ifa;  /* faulting address */
    694         rr.word = rr_read(VA2VRN(va));
    695         rid = rr.map.rid;
    696684       
    697685        page_table_lock(AS, true);
     
    723711void data_access_bit_fault(uint64_t vector, istate_t *istate)
    724712{
    725         region_register_t rr;
    726         rid_t rid;
    727713        uintptr_t va;
    728714        pte_t *t;
    729715       
    730716        va = istate->cr_ifa;  /* faulting address */
    731         rr.word = rr_read(VA2VRN(va));
    732         rid = rr.map.rid;
    733717       
    734718        page_table_lock(AS, true);
     
    760744void data_access_rights_fault(uint64_t vector, istate_t *istate)
    761745{
    762         region_register_t rr;
    763         rid_t rid;
    764746        uintptr_t va;
    765747        pte_t *t;
    766748       
    767749        va = istate->cr_ifa;  /* faulting address */
    768         rr.word = rr_read(VA2VRN(va));
    769         rid = rr.map.rid;
    770750       
    771751        /*
     
    792772void page_not_present(uint64_t vector, istate_t *istate)
    793773{
    794         region_register_t rr;
    795         rid_t rid;
    796774        uintptr_t va;
    797775        pte_t *t;
    798776       
    799777        va = istate->cr_ifa;  /* faulting address */
    800         rr.word = rr_read(VA2VRN(va));
    801         rid = rr.map.rid;
    802778       
    803779        page_table_lock(AS, true);
  • kernel/arch/ia64/src/start.S

    r1ff896e r694ca93f  
    174174       
    175175        # Initialize gp (Global Pointer) register
    176         movl gp = kernel_image_start
     176        movl gp = __gp
    177177       
    178         #       
     178        #
    179179        # Initialize bootinfo on BSP.
    180180        #
  • kernel/arch/mips32/include/atomic.h

    r1ff896e r694ca93f  
    9191                "       sc %0, %1\n"
    9292                "       beqz %0, 1b\n"
     93                "       nop\n"
    9394                "2:\n"
    9495                : "=&r" (tmp),
  • kernel/arch/mips32/include/cp0.h

    r1ff896e r694ca93f  
    7070  { \
    7171      uint32_t retval; \
    72       asm("mfc0 %0, $" #reg : "=r"(retval)); \
     72      asm volatile ("mfc0 %0, $" #reg : "=r"(retval)); \
    7373      return retval; \
    7474  }
     
    7676#define GEN_WRITE_CP0(nm,reg) static inline void cp0_ ##nm##_write(uint32_t val) \
    7777 { \
    78     asm("mtc0 %0, $" #reg : : "r"(val) ); \
     78    asm volatile ("mtc0 %0, $" #reg : : "r"(val) ); \
    7979 }
    8080
  • kernel/arch/mips32/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint32_t size_t;
     39typedef int32_t ssize_t;
    3940
    4041typedef uint32_t uintptr_t;
  • kernel/arch/mips32/src/asm.S

    r1ff896e r694ca93f  
    5757        nop
    5858
    59 .global memsetb
    60 memsetb:
    61         j _memsetb
    62         nop
    63 
    64 .global memsetw
    65 memsetw:
    66         j _memsetw
    67         nop
    68 
    69 .global memcpy
    7059.global memcpy_from_uspace
    7160.global memcpy_to_uspace
    7261.global memcpy_from_uspace_failover_address
    7362.global memcpy_to_uspace_failover_address
    74 memcpy:
    7563memcpy_from_uspace:
    7664memcpy_to_uspace:
  • kernel/arch/mips32/src/mm/frame.c

    r1ff896e r694ca93f  
    8888        /* gxemul devices */
    8989        if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
    90             0x10000000, MB2SIZE(256)))
     90            0x10000000, MiB2SIZE(256)))
    9191                return false;
    9292#endif
  • kernel/arch/ppc32/_link.ld.in

    r1ff896e r694ca93f  
    3636                kdata_start = .;
    3737                *(K_DATA_START);
    38                 *(.rodata);
    39                 *(.rodata.*);
     38                *(.rodata .rodata.*);
    4039                *(.data);       /* initialized data */
    4140                *(.sdata);
  • kernel/arch/ppc32/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint32_t size_t;
     39typedef int32_t ssize_t;
    3940
    4041typedef uint32_t uintptr_t;
  • kernel/arch/ppc32/src/asm.S

    r1ff896e r694ca93f  
    3535.global iret
    3636.global iret_syscall
    37 .global memsetb
    38 .global memsetw
    39 .global memcpy
    4037.global memcpy_from_uspace
    4138.global memcpy_to_uspace
     
    208205        rfi
    209206
    210 memsetb:
    211         b _memsetb
    212 
    213 memsetw:
    214         b _memsetw
    215 
    216 memcpy:
    217207memcpy_from_uspace:
    218208memcpy_to_uspace:
  • kernel/arch/sparc64/_link.ld.in

    r1ff896e r694ca93f  
    1515                ktext_start = .;
    1616                *(K_TEXT_START)
    17                 *(.text);
     17                *(.text .text.*);
    1818                ktext_end = .;
    1919               
    2020                kdata_start = .;
    2121                *(K_DATA_START)
    22                 *(.rodata);
    23                 *(.rodata.*);
     22                *(.rodata .rodata.*);
    2423                *(.data);                   /* initialized data */
    2524                *(.sdata);
  • kernel/arch/sparc64/include/cpu.h

    r1ff896e r694ca93f  
    5959#include <arch/asm.h>
    6060
    61 #ifdef CONFIG_SMP
    62 #include <arch/mm/cache.h>
    63 #endif
    64 
    65 
    6661#if defined (SUN4U)
    6762#include <arch/sun4u/cpu.h>
  • kernel/arch/sparc64/include/sun4u/cpu.h

    r1ff896e r694ca93f  
    6060#include <trace.h>
    6161
    62 #ifdef CONFIG_SMP
    63 #include <arch/mm/cache.h>
    64 #endif
    65 
    6662typedef struct {
    6763        uint32_t mid;              /**< Processor ID as read from
  • kernel/arch/sparc64/include/types.h

    r1ff896e r694ca93f  
    3737
    3838typedef uint64_t size_t;
     39typedef int64_t ssize_t;
    3940
    4041typedef uint64_t uintptr_t;
  • kernel/arch/sparc64/src/asm.S

    r1ff896e r694ca93f  
    3434.register %g2, #scratch
    3535.register %g3, #scratch
    36 
    37 /*
    38  * This is the assembly language version of our _memcpy() generated by gcc.
    39  */
    40 .global memcpy
    41 memcpy:
    42         mov %o0, %o3  /* save dst */
    43         add %o1, 7, %g1
    44         and %g1, -8, %g1
    45         cmp %o1, %g1
    46         be,pn %xcc, 3f
    47         add %o0, 7, %g1
    48         mov 0, %g3
    49        
    50         0:
    51        
    52                 brz,pn %o2, 2f
    53                 mov 0, %g2
    54        
    55         1:
    56        
    57                 ldub [%g3 + %o1], %g1
    58                 add %g2, 1, %g2
    59                 cmp %o2, %g2
    60                 stb %g1, [%g3 + %o0]
    61                 bne,pt %xcc, 1b
    62                 mov %g2, %g3
    63        
    64         2:
    65        
    66                 jmp %o7 + 8  /* exit point */
    67                 mov %o3, %o0
    68        
    69         3:
    70        
    71                 and %g1, -8, %g1
    72                 cmp %o0, %g1
    73                 bne,pt %xcc, 0b
    74                 mov 0, %g3
    75                 srlx %o2, 3, %g4
    76                 brz,pn %g4, 5f
    77                 mov 0, %g5
    78        
    79         4:
    80        
    81                 sllx %g3, 3, %g2
    82                 add %g5, 1, %g3
    83                 ldx [%o1 + %g2], %g1
    84                 mov %g3, %g5
    85                 cmp %g4, %g3
    86                 bne,pt %xcc, 4b
    87                 stx %g1, [%o0 + %g2]
    88        
    89         5:
    90        
    91                 and %o2, 7, %o2
    92                 brz,pn %o2, 2b
    93                 sllx %g4, 3, %g1
    94                 mov 0, %g2
    95                 add %g1, %o0, %o0
    96                 add %g1, %o1, %g4
    97                 mov 0, %g3
    98        
    99         6:
    100        
    101                 ldub [%g2 + %g4], %g1
    102                 stb %g1, [%g2 + %o0]
    103                 add %g3, 1, %g2
    104                 cmp %o2, %g2
    105                 bne,pt %xcc, 6b
    106                 mov %g2, %g3
    107                
    108                 jmp %o7 + 8  /* exit point */
    109                 mov %o3, %o0
    11036
    11137/*
     
    264190        mov %g0, %o0  /* return 0 on failure */
    265191
    266 .global memsetb
    267 memsetb:
    268         ba %xcc, _memsetb
    269         nop
    270 
    271 .global memsetw
    272 memsetw:
    273         ba %xcc, _memsetw
    274         nop
    275 
    276192.global early_putchar
    277193early_putchar:
  • kernel/arch/sparc64/src/mm/sun4u/as.c

    r1ff896e r694ca93f  
    4343
    4444#include <arch/mm/tsb.h>
    45 #include <arch/memstr.h>
    4645#include <arch/asm.h>
    4746#include <mm/frame.h>
  • kernel/arch/sparc64/src/mm/sun4v/as.c

    r1ff896e r694ca93f  
    4646
    4747#include <arch/mm/tsb.h>
    48 #include <arch/memstr.h>
    4948#include <arch/asm.h>
    5049#include <mm/frame.h>
  • kernel/arch/sparc64/src/smp/sun4v/smp.c

    r1ff896e r694ca93f  
    11/*
    22 * Copyright (c) 2006 Jakub Jermar
    3  * Copyright (c) 2009 Pavel Rimsky 
     3 * Copyright (c) 2009 Pavel Rimsky
    44 * All rights reserved.
    55 *
     
    439439        if (waitq_sleep_timeout(&ap_completion_wq, 10000000, SYNCH_FLAGS_NONE) ==
    440440            ESYNCH_TIMEOUT)
    441                 printf("%s: waiting for processor (cpuid = %" PRIu32 ") timed out\n",
     441                printf("%s: waiting for processor (cpuid = %" PRIu64 ") timed out\n",
    442442                    __func__, cpuid);
    443443       
  • kernel/arch/sparc64/src/sun4v/start.S

    r1ff896e r694ca93f  
    296296         * Create the first stack frame.
    297297         */
    298         save %sp, -(STACK_WINDWO_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
     298        save %sp, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
    299299        flushw
    300300        add %g0, -STACK_BIAS, %fp
  • kernel/arch/sparc64/src/trap/sun4v/interrupt.c

    r1ff896e r694ca93f  
    111111                        ((void (*)(void)) data1)();
    112112                } else {
    113                         printf("Spurious interrupt on %d, data = %" PRIx64 ".\n",
     113                        printf("Spurious interrupt on %" PRIu64 ", data = %" PRIx64 ".\n",
    114114                            CPU->arch.id, data1);
    115115                }
  • kernel/genarch/Makefile.inc

    r1ff896e r694ca93f  
    122122endif
    123123
    124 ifeq ($(CONFIG_PL050),y)
    125         GENARCH_SOURCES += \
    126                 genarch/src/kbrd/kbrd_pl050.c \
    127                 genarch/src/kbrd/scanc_pl050.c
    128 endif
    129 
    130124ifeq ($(CONFIG_MAC_KBD),y)
    131125        GENARCH_SOURCES += \
  • kernel/genarch/src/drivers/via-cuda/cuda.c

    r1ff896e r694ca93f  
    239239        cuda_instance_t *instance = irq->instance;
    240240        cuda_t *dev = instance->cuda;
    241         uint8_t data, b;
    242 
     241        uint8_t b;
     242       
    243243        b = pio_read_8(&dev->b);
    244         data = pio_read_8(&dev->sr);
    245 
     244        pio_read_8(&dev->sr);
     245       
    246246        if ((b & TREQ) == 0) {
    247247                instance->xstate = cx_receive;
     
    251251                cuda_send_start(instance);
    252252        }
    253 
    254         memcpy(buf, instance->rcv_buf, instance->bidx);
    255         *len = instance->bidx;
     253       
     254        memcpy(buf, instance->rcv_buf, instance->bidx);
     255        *len = instance->bidx;
    256256        instance->bidx = 0;
    257257}
  • kernel/genarch/src/ofw/ebus.c

    r1ff896e r694ca93f  
    3939#include <genarch/ofw/ebus.h>
    4040#include <genarch/ofw/pci.h>
    41 #include <arch/memstr.h>
    4241#include <str.h>
    4342#include <panic.h>
  • kernel/genarch/src/ofw/fhc.c

    r1ff896e r694ca93f  
    3939#include <genarch/ofw/fhc.h>
    4040#include <arch/drivers/fhc.h>
    41 #include <arch/memstr.h>
    4241#include <str.h>
    4342#include <panic.h>
  • kernel/genarch/src/ofw/ofw_tree.c

    r1ff896e r694ca93f  
    3737
    3838#include <genarch/ofw/ofw_tree.h>
    39 #include <arch/memstr.h>
    4039#include <mm/slab.h>
     40#include <memstr.h>
    4141#include <str.h>
    4242#include <panic.h>
  • kernel/genarch/src/ofw/pci.c

    r1ff896e r694ca93f  
    4040#include <arch/drivers/pci.h>
    4141#include <arch/trap/interrupt.h>
    42 #include <arch/memstr.h>
    4342#include <str.h>
    4443#include <panic.h>
  • kernel/genarch/src/ofw/upa.c

    r1ff896e r694ca93f  
    3838#include <genarch/ofw/ofw_tree.h>
    3939#include <genarch/ofw/upa.h>
    40 #include <arch/memstr.h>
    4140#include <func.h>
    4241#include <panic.h>
  • kernel/generic/include/ipc/ipc.h

    r1ff896e r694ca93f  
    115115 */
    116116#define IPC_FF_ROUTE_FROM_ME  (1 << 0)
     117
     118/* Data transfer flags. */
     119#define IPC_XF_NONE             0
     120
     121/** Restrict the transfer size if necessary. */
     122#define IPC_XF_RESTRICT         (1 << 0)
    117123
    118124/** Kernel IPC interfaces
  • kernel/generic/include/lib/memfnc.h

    r1ff896e r694ca93f  
    11/*
    2  * Copyright (c) 2005 Sergey Bondari
     2 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup ia32
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_ia32_MEMSTR_H_
    36 #define KERN_ia32_MEMSTR_H_
     35#ifndef KERN_LIB_MEMFNC_H_
     36#define KERN_LIB_MEMFNC_H_
    3737
    38 #define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     38#include <typedefs.h>
    3939
    40 extern void memsetw(void *, size_t, uint16_t);
    41 extern void memsetb(void *, size_t, uint8_t);
     40extern void *memset(void *, int, size_t);
     41extern void *memcpy(void *, const void *, size_t);
    4242
    4343#endif
  • kernel/generic/include/macros.h

    r1ff896e r694ca93f  
    9595        overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
    9696
    97 #define SIZE2KB(size)  ((size) >> 10)
    98 #define SIZE2MB(size)  ((size) >> 20)
    99 
    100 #define KB2SIZE(kb)  ((kb) << 10)
    101 #define MB2SIZE(mb)  ((mb) << 20)
     97#define KiB2SIZE(kb)  ((kb) << 10)
     98#define MiB2SIZE(mb)  ((mb) << 20)
    10299
    103100#define STRING(arg)      STRING_ARG(arg)
  • kernel/generic/include/memstr.h

    r1ff896e r694ca93f  
    3737
    3838#include <typedefs.h>
    39 #include <arch/memstr.h>
    4039
    41 /*
    42  * Architecture independent variants.
    43  */
    44 extern void *_memcpy(void *dst, const void *src, size_t cnt);
    45 extern void _memsetb(void *dst, size_t cnt, uint8_t x);
    46 extern void _memsetw(void *dst, size_t cnt, uint16_t x);
    47 extern void *memmove(void *dst, const void *src, size_t cnt);
     40#define memset(dst, val, cnt)  __builtin_memset((dst), (val), (cnt))
     41#define memcpy(dst, src, cnt)  __builtin_memcpy((dst), (src), (cnt))
     42
     43extern void memsetb(void *, size_t, uint8_t);
     44extern void memsetw(void *, size_t, uint16_t);
     45extern void *memmove(void *, const void *, size_t);
    4846
    4947#endif
  • kernel/generic/include/mm/as.h

    r1ff896e r694ca93f  
    238238/** Address space area backend structure. */
    239239typedef struct mem_backend {
     240        bool (* create)(as_area_t *);
     241        bool (* resize)(as_area_t *, size_t);
     242        void (* share)(as_area_t *);
     243        void (* destroy)(as_area_t *);
     244
    240245        int (* page_fault)(as_area_t *, uintptr_t, pf_access_t);
    241246        void (* frame_free)(as_area_t *, uintptr_t, uintptr_t);
    242         void (* share)(as_area_t *);
    243247} mem_backend_t;
    244248
  • kernel/generic/include/mm/frame.h

    r1ff896e r694ca93f  
    6262
    6363/** Convert the frame address to kernel VA. */
    64 #define FRAME_KA          0x01
     64#define FRAME_KA          0x1
    6565/** Do not panic and do not sleep on failure. */
    66 #define FRAME_ATOMIC      0x02
     66#define FRAME_ATOMIC      0x2
    6767/** Do not start reclaiming when no free memory. */
    68 #define FRAME_NO_RECLAIM  0x04
     68#define FRAME_NO_RECLAIM  0x4
     69/** Do not reserve / unreserve memory. */
     70#define FRAME_NO_RESERVE  0x8
    6971
    7072typedef uint8_t zone_flags_t;
    7173
    7274/** Available zone (free for allocation) */
    73 #define ZONE_AVAILABLE  0x00
     75#define ZONE_AVAILABLE  0x0
    7476/** Zone is reserved (not available for allocation) */
    75 #define ZONE_RESERVED   0x08
     77#define ZONE_RESERVED   0x8
    7678/** Zone is used by firmware (not available for allocation) */
    7779#define ZONE_FIRMWARE   0x10
     
    8587        uint8_t buddy_order;  /**< Buddy system block order */
    8688        link_t buddy_link;    /**< Link to the next free block inside
    87                                one order */
     89                                   one order */
    8890        void *parent;         /**< If allocated by slab, this points there */
    8991} frame_t;
     
    9193typedef struct {
    9294        pfn_t base;                    /**< Frame_no of the first frame
    93                                         in the frames array */
     95                                            in the frames array */
    9496        size_t count;                  /**< Size of zone */
    9597        size_t free_count;             /**< Number of free frame_t
    96                                         structures */
     98                                            structures */
    9799        size_t busy_count;             /**< Number of busy frame_t
    98                                         structures */
     100                                            structures */
    99101        zone_flags_t flags;            /**< Type of the zone */
    100102       
    101103        frame_t *frames;               /**< Array of frame_t structures
    102                                         in this zone */
     104                                            in this zone */
    103105        buddy_system_t *buddy_system;  /**< Buddy system for the zone */
    104106} zone_t;
     
    146148    ((~(((sysarg_t) -1) << (order)) & (index)) == 0)
    147149#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
    148     (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
     150    (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
    149151#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
    150     (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
     152    (((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
    151153#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
    152     (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
     154    (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
    153155#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
    154     (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
    155 
    156 #define frame_alloc(order, flags) \
    157     frame_alloc_generic(order, flags, NULL)
     156    (((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
    158157
    159158extern void frame_init(void);
    160159extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
     160extern void *frame_alloc(uint8_t, frame_flags_t);
     161extern void *frame_alloc_noreserve(uint8_t, frame_flags_t);
     162extern void frame_free_generic(uintptr_t, frame_flags_t);
    161163extern void frame_free(uintptr_t);
     164extern void frame_free_noreserve(uintptr_t);
    162165extern void frame_reference_add(pfn_t);
    163166
    164 extern size_t find_zone(pfn_t frame, size_t count, size_t hint);
     167extern size_t find_zone(pfn_t, size_t, size_t);
    165168extern size_t zone_create(pfn_t, size_t, pfn_t, zone_flags_t);
    166169extern void *frame_get_parent(pfn_t, size_t);
  • kernel/generic/include/str.h

    r1ff896e r694ca93f  
    9999extern int str_uint64(const char *, char **, unsigned int, bool, uint64_t *);
    100100
    101 extern void order_suffix(const uint64_t val, uint64_t *rv, char *suffix);
     101extern void order_suffix(const uint64_t, uint64_t *, char *);
     102extern void bin_order_suffix(const uint64_t, uint64_t *, const char **, bool);
    102103
    103104#endif
  • kernel/generic/src/ipc/sysipc.c

    r1ff896e r694ca93f  
    426426        case IPC_M_DATA_READ: {
    427427                size_t size = IPC_GET_ARG2(call->data);
    428                 if ((size <= 0 || (size > DATA_XFER_LIMIT)))
     428                if (size <= 0)
    429429                        return ELIMIT;
    430                
     430                if (size > DATA_XFER_LIMIT) {
     431                        int flags = IPC_GET_ARG3(call->data);
     432                        if (flags & IPC_XF_RESTRICT)
     433                                IPC_SET_ARG2(call->data, DATA_XFER_LIMIT);
     434                        else
     435                                return ELIMIT;
     436                }
    431437                break;
    432438        }
     
    435441                size_t size = IPC_GET_ARG2(call->data);
    436442               
    437                 if (size > DATA_XFER_LIMIT)
    438                         return ELIMIT;
     443                if (size > DATA_XFER_LIMIT) {
     444                        int flags = IPC_GET_ARG3(call->data);
     445                        if (flags & IPC_XF_RESTRICT) {
     446                                size = DATA_XFER_LIMIT;
     447                                IPC_SET_ARG2(call->data, size);
     448                        } else
     449                                return ELIMIT;
     450                }
    439451               
    440452                call->buffer = (uint8_t *) malloc(size, 0);
  • kernel/generic/src/lib/memstr.c

    r1ff896e r694ca93f  
    2828 */
    2929
    30 /** @addtogroup generic 
     30/** @addtogroup generic
    3131 * @{
    3232 */
     
    3434/**
    3535 * @file
    36  * @brief       Memory string operations.
     36 * @brief Memory string operations.
    3737 *
    38  * This file provides architecture independent functions to manipulate blocks of
    39  * memory. These functions are optimized as much as generic functions of this
    40  * type can be. However, architectures are free to provide even more optimized
    41  * versions of these functions.
     38 * This file provides architecture independent functions to manipulate blocks
     39 * of memory. These functions are optimized as much as generic functions of
     40 * this type can be.
    4241 */
    4342
    4443#include <memstr.h>
    4544#include <typedefs.h>
    46 #include <align.h>
    4745
    48 /** Copy block of memory.
     46/** Fill block of memory.
    4947 *
    50  * Copy cnt bytes from src address to dst address.  The copying is done
    51  * word-by-word and then byte-by-byte.  The source and destination memory areas
    52  * cannot overlap.
     48 * Fill cnt bytes at dst address with the value val.
    5349 *
    54  * @param src           Source address to copy from.
    55  * @param dst           Destination address to copy to.
    56  * @param cnt           Number of bytes to copy.
     50 * @param dst Destination address to fill.
     51 * @param cnt Number of bytes to fill.
     52 * @param val Value to fill.
    5753 *
    58  * @return              Destination address.
    5954 */
    60 void *_memcpy(void *dst, const void *src, size_t cnt)
     55void memsetb(void *dst, size_t cnt, uint8_t val)
    6156{
    62         unsigned int i, j;
     57        memset(dst, val, cnt);
     58}
     59
     60/** Fill block of memory.
     61 *
     62 * Fill cnt words at dst address with the value val. The filling
     63 * is done word-by-word.
     64 *
     65 * @param dst Destination address to fill.
     66 * @param cnt Number of words to fill.
     67 * @param val Value to fill.
     68 *
     69 */
     70void memsetw(void *dst, size_t cnt, uint16_t val)
     71{
     72        size_t i;
     73        uint16_t *ptr = (uint16_t *) dst;
    6374       
    64         if (ALIGN_UP((uintptr_t) src, sizeof(sysarg_t)) != (uintptr_t) src ||
    65             ALIGN_UP((uintptr_t) dst, sizeof(sysarg_t)) != (uintptr_t) dst) {
    66                 for (i = 0; i < cnt; i++)
    67                         ((uint8_t *) dst)[i] = ((uint8_t *) src)[i];
    68         } else {
    69                 for (i = 0; i < cnt / sizeof(sysarg_t); i++)
    70                         ((sysarg_t *) dst)[i] = ((sysarg_t *) src)[i];
    71                
    72                 for (j = 0; j < cnt % sizeof(sysarg_t); j++)
    73                         ((uint8_t *)(((sysarg_t *) dst) + i))[j] =
    74                             ((uint8_t *)(((sysarg_t *) src) + i))[j];
    75         }
    76                
    77         return (char *) dst;
     75        for (i = 0; i < cnt; i++)
     76                ptr[i] = val;
    7877}
    7978
    8079/** Move memory block with possible overlapping.
    8180 *
    82  * Copy cnt bytes from src address to dst address. The source and destination
    83  * memory areas may overlap.
     81 * Copy cnt bytes from src address to dst address. The source
     82 * and destination memory areas may overlap.
    8483 *
    85  * @param src           Source address to copy from.
    86  * @param dst           Destination address to copy to.
    87  * @param cnt           Number of bytes to copy.
     84 * @param dst Destination address to copy to.
     85 * @param src Source address to copy from.
     86 * @param cnt Number of bytes to copy.
    8887 *
    89  * @return              Destination address.
     88 * @return Destination address.
     89 *
    9090 */
    91 void *memmove(void *dst, const void *src, size_t n)
     91void *memmove(void *dst, const void *src, size_t cnt)
    9292{
    93         const uint8_t *sp;
    94         uint8_t *dp;
    95 
    9693        /* Nothing to do? */
    9794        if (src == dst)
    9895                return dst;
    99 
     96       
    10097        /* Non-overlapping? */
    101         if (dst >= src + n || src >= dst + n) {
    102                 return memcpy(dst, src, n);
    103         }
    104 
     98        if ((dst >= src + cnt) || (src >= dst + cnt))
     99                return memcpy(dst, src, cnt);
     100       
     101        uint8_t *dp;
     102        const uint8_t *sp;
     103       
    105104        /* Which direction? */
    106105        if (src > dst) {
    107106                /* Forwards. */
     107                dp = dst;
    108108                sp = src;
    109                 dp = dst;
    110 
    111                 while (n-- != 0)
     109               
     110                while (cnt-- != 0)
    112111                        *dp++ = *sp++;
    113112        } else {
    114113                /* Backwards. */
    115                 sp = src + (n - 1);
    116                 dp = dst + (n - 1);
    117 
    118                 while (n-- != 0)
     114                dp = dst + (cnt - 1);
     115                sp = src + (cnt - 1);
     116               
     117                while (cnt-- != 0)
    119118                        *dp-- = *sp--;
    120119        }
    121 
     120       
    122121        return dst;
    123 }
    124 
    125 /** Fill block of memory
    126  *
    127  * Fill cnt bytes at dst address with the value x.  The filling is done
    128  * byte-by-byte.
    129  *
    130  * @param dst           Destination address to fill.
    131  * @param cnt           Number of bytes to fill.
    132  * @param x             Value to fill.
    133  *
    134  */
    135 void _memsetb(void *dst, size_t cnt, uint8_t x)
    136 {
    137         unsigned int i;
    138         uint8_t *p = (uint8_t *) dst;
    139        
    140         for (i = 0; i < cnt; i++)
    141                 p[i] = x;
    142 }
    143 
    144 /** Fill block of memory.
    145  *
    146  * Fill cnt words at dst address with the value x.  The filling is done
    147  * word-by-word.
    148  *
    149  * @param dst           Destination address to fill.
    150  * @param cnt           Number of words to fill.
    151  * @param x             Value to fill.
    152  *
    153  */
    154 void _memsetw(void *dst, size_t cnt, uint16_t x)
    155 {
    156         unsigned int i;
    157         uint16_t *p = (uint16_t *) dst;
    158        
    159         for (i = 0; i < cnt; i++)
    160                 p[i] = x;       
    161122}
    162123
  • kernel/generic/src/lib/str.c

    r1ff896e r694ca93f  
    922922void order_suffix(const uint64_t val, uint64_t *rv, char *suffix)
    923923{
    924         if (val > 10000000000000000000ULL) {
    925                 *rv = val / 1000000000000000000ULL;
     924        if (val > UINT64_C(10000000000000000000)) {
     925                *rv = val / UINT64_C(1000000000000000000);
    926926                *suffix = 'Z';
    927         } else if (val > 1000000000000000000ULL) {
    928                 *rv = val / 1000000000000000ULL;
     927        } else if (val > UINT64_C(1000000000000000000)) {
     928                *rv = val / UINT64_C(1000000000000000);
    929929                *suffix = 'E';
    930         } else if (val > 1000000000000000ULL) {
    931                 *rv = val / 1000000000000ULL;
     930        } else if (val > UINT64_C(1000000000000000)) {
     931                *rv = val / UINT64_C(1000000000000);
    932932                *suffix = 'T';
    933         } else if (val > 1000000000000ULL) {
    934                 *rv = val / 1000000000ULL;
     933        } else if (val > UINT64_C(1000000000000)) {
     934                *rv = val / UINT64_C(1000000000);
    935935                *suffix = 'G';
    936         } else if (val > 1000000000ULL) {
    937                 *rv = val / 1000000ULL;
     936        } else if (val > UINT64_C(1000000000)) {
     937                *rv = val / UINT64_C(1000000);
    938938                *suffix = 'M';
    939         } else if (val > 1000000ULL) {
    940                 *rv = val / 1000ULL;
     939        } else if (val > UINT64_C(1000000)) {
     940                *rv = val / UINT64_C(1000);
    941941                *suffix = 'k';
    942942        } else {
     
    946946}
    947947
     948void bin_order_suffix(const uint64_t val, uint64_t *rv, const char **suffix,
     949    bool fixed)
     950{
     951        if (val > UINT64_C(1152921504606846976)) {
     952                *rv = val / UINT64_C(1125899906842624);
     953                *suffix = "EiB";
     954        } else if (val > UINT64_C(1125899906842624)) {
     955                *rv = val / UINT64_C(1099511627776);
     956                *suffix = "TiB";
     957        } else if (val > UINT64_C(1099511627776)) {
     958                *rv = val / UINT64_C(1073741824);
     959                *suffix = "GiB";
     960        } else if (val > UINT64_C(1073741824)) {
     961                *rv = val / UINT64_C(1048576);
     962                *suffix = "MiB";
     963        } else if (val > UINT64_C(1048576)) {
     964                *rv = val / UINT64_C(1024);
     965                *suffix = "KiB";
     966        } else {
     967                *rv = val;
     968                if (fixed)
     969                        *suffix = "B  ";
     970                else
     971                        *suffix = "B";
     972        }
     973}
     974
    948975/** @}
    949976 */
  • kernel/generic/src/main/main.c

    r1ff896e r694ca93f  
    5858#include <proc/thread.h>
    5959#include <proc/task.h>
    60 #include <proc/tasklet.h>
    6160#include <main/kinit.h>
    6261#include <main/version.h>
     
    217216        tlb_init();
    218217        ddi_init();
    219         tasklet_init();
    220218        arch_post_mm_init();
    221219        arch_pre_smp_init();
     
    225223        slab_enable_cpucache();
    226224       
    227         printf("Detected %u CPU(s), %" PRIu64 " MiB free memory\n",
    228             config.cpu_count, SIZE2MB(zones_total_size()));
     225        uint64_t size;
     226        const char *size_suffix;
     227        bin_order_suffix(zones_total_size(), &size, &size_suffix, false);
     228        printf("Detected %u CPU(s), %" PRIu64 " %s free memory\n",
     229            config.cpu_count, size, size_suffix);
    229230       
    230231        cpu_init();
  • kernel/generic/src/mm/as.c

    r1ff896e r694ca93f  
    8080#include <arch/interrupt.h>
    8181
    82 #ifdef CONFIG_VIRT_IDX_DCACHE
    83 #include <arch/mm/cache.h>
    84 #endif /* CONFIG_VIRT_IDX_DCACHE */
    85 
    8682/**
    8783 * Each architecture decides what functions will be used to carry out
     
    447443        else
    448444                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
     445       
     446        if (area->backend && area->backend->create) {
     447                if (!area->backend->create(area)) {
     448                        free(area);
     449                        mutex_unlock(&as->lock);
     450                        return NULL;
     451                }
     452        }
    449453       
    450454        btree_create(&area->used_space);
     
    690694        }
    691695       
     696        if (area->backend && area->backend->resize) {
     697                if (!area->backend->resize(area, pages)) {
     698                        mutex_unlock(&area->lock);
     699                        mutex_unlock(&as->lock);
     700                        return ENOMEM;
     701                }
     702        }
     703       
    692704        area->pages = pages;
    693705       
     
    756768                return ENOENT;
    757769        }
     770
     771        if (area->backend && area->backend->destroy)
     772                area->backend->destroy(area);
    758773       
    759774        uintptr_t base = area->base;
  • kernel/generic/src/mm/backend_anon.c

    r1ff896e r694ca93f  
    3939#include <mm/as.h>
    4040#include <mm/page.h>
     41#include <mm/reserve.h>
    4142#include <genarch/mm/page_pt.h>
    4243#include <genarch/mm/page_ht.h>
     
    5152#include <arch.h>
    5253
    53 #ifdef CONFIG_VIRT_IDX_DCACHE
    54 #include <arch/mm/cache.h>
    55 #endif
    56 
    57 static int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
    58 static void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame);
    59 static void anon_share(as_area_t *area);
     54static bool anon_create(as_area_t *);
     55static bool anon_resize(as_area_t *, size_t);
     56static void anon_share(as_area_t *);
     57static void anon_destroy(as_area_t *);
     58
     59static int anon_page_fault(as_area_t *, uintptr_t, pf_access_t);
     60static void anon_frame_free(as_area_t *, uintptr_t, uintptr_t);
    6061
    6162mem_backend_t anon_backend = {
     63        .create = anon_create,
     64        .resize = anon_resize,
     65        .share = anon_share,
     66        .destroy = anon_destroy,
     67
    6268        .page_fault = anon_page_fault,
    6369        .frame_free = anon_frame_free,
    64         .share = anon_share
    6570};
     71
     72bool anon_create(as_area_t *area)
     73{
     74        return reserve_try_alloc(area->pages);
     75}
     76
     77bool anon_resize(as_area_t *area, size_t new_pages)
     78{
     79        if (new_pages > area->pages)
     80                return reserve_try_alloc(new_pages - area->pages);
     81        else if (new_pages < area->pages)
     82                reserve_free(area->pages - new_pages);
     83
     84        return true;
     85}
     86
     87/** Share the anonymous address space area.
     88 *
     89 * Sharing of anonymous area is done by duplicating its entire mapping
     90 * to the pagemap. Page faults will primarily search for frames there.
     91 *
     92 * The address space and address space area must be already locked.
     93 *
     94 * @param area Address space area to be shared.
     95 */
     96void anon_share(as_area_t *area)
     97{
     98        link_t *cur;
     99
     100        ASSERT(mutex_locked(&area->as->lock));
     101        ASSERT(mutex_locked(&area->lock));
     102
     103        /*
     104         * Copy used portions of the area to sh_info's page map.
     105         */
     106        mutex_lock(&area->sh_info->lock);
     107        for (cur = area->used_space.leaf_head.next;
     108            cur != &area->used_space.leaf_head; cur = cur->next) {
     109                btree_node_t *node;
     110                unsigned int i;
     111               
     112                node = list_get_instance(cur, btree_node_t, leaf_link);
     113                for (i = 0; i < node->keys; i++) {
     114                        uintptr_t base = node->key[i];
     115                        size_t count = (size_t) node->value[i];
     116                        unsigned int j;
     117                       
     118                        for (j = 0; j < count; j++) {
     119                                pte_t *pte;
     120                       
     121                                page_table_lock(area->as, false);
     122                                pte = page_mapping_find(area->as,
     123                                    base + j * PAGE_SIZE);
     124                                ASSERT(pte && PTE_VALID(pte) &&
     125                                    PTE_PRESENT(pte));
     126                                btree_insert(&area->sh_info->pagemap,
     127                                    (base + j * PAGE_SIZE) - area->base,
     128                                    (void *) PTE_GET_FRAME(pte), NULL);
     129                                page_table_unlock(area->as, false);
     130
     131                                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
     132                                frame_reference_add(pfn);
     133                        }
     134
     135                }
     136        }
     137        mutex_unlock(&area->sh_info->lock);
     138}
     139
     140void anon_destroy(as_area_t *area)
     141{
     142        reserve_free(area->pages);
     143}
     144
    66145
    67146/** Service a page fault in the anonymous memory address space area.
     
    115194                        }
    116195                        if (allocate) {
    117                                 frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
     196                                frame = (uintptr_t) frame_alloc_noreserve(
     197                                    ONE_FRAME, 0);
    118198                                memsetb((void *) PA2KA(frame), FRAME_SIZE, 0);
    119199                               
     
    145225                 *   the different causes
    146226                 */
    147                 frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
     227                frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0);
    148228                memsetb((void *) PA2KA(frame), FRAME_SIZE, 0);
    149229        }
     
    174254        ASSERT(mutex_locked(&area->lock));
    175255
    176         frame_free(frame);
    177 }
    178 
    179 /** Share the anonymous address space area.
    180  *
    181  * Sharing of anonymous area is done by duplicating its entire mapping
    182  * to the pagemap. Page faults will primarily search for frames there.
    183  *
    184  * The address space and address space area must be already locked.
    185  *
    186  * @param area Address space area to be shared.
    187  */
    188 void anon_share(as_area_t *area)
    189 {
    190         link_t *cur;
    191 
    192         ASSERT(mutex_locked(&area->as->lock));
    193         ASSERT(mutex_locked(&area->lock));
    194 
    195         /*
    196          * Copy used portions of the area to sh_info's page map.
    197          */
    198         mutex_lock(&area->sh_info->lock);
    199         for (cur = area->used_space.leaf_head.next;
    200             cur != &area->used_space.leaf_head; cur = cur->next) {
    201                 btree_node_t *node;
    202                 unsigned int i;
    203                
    204                 node = list_get_instance(cur, btree_node_t, leaf_link);
    205                 for (i = 0; i < node->keys; i++) {
    206                         uintptr_t base = node->key[i];
    207                         size_t count = (size_t) node->value[i];
    208                         unsigned int j;
    209                        
    210                         for (j = 0; j < count; j++) {
    211                                 pte_t *pte;
    212                        
    213                                 page_table_lock(area->as, false);
    214                                 pte = page_mapping_find(area->as,
    215                                     base + j * PAGE_SIZE);
    216                                 ASSERT(pte && PTE_VALID(pte) &&
    217                                     PTE_PRESENT(pte));
    218                                 btree_insert(&area->sh_info->pagemap,
    219                                     (base + j * PAGE_SIZE) - area->base,
    220                                     (void *) PTE_GET_FRAME(pte), NULL);
    221                                 page_table_unlock(area->as, false);
    222 
    223                                 pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
    224                                 frame_reference_add(pfn);
    225                         }
    226 
    227                 }
    228         }
    229         mutex_unlock(&area->sh_info->lock);
     256        frame_free_noreserve(frame);
    230257}
    231258
  • kernel/generic/src/mm/backend_elf.c

    r1ff896e r694ca93f  
    4343#include <mm/slab.h>
    4444#include <mm/page.h>
     45#include <mm/reserve.h>
    4546#include <genarch/mm/page_pt.h>
    4647#include <genarch/mm/page_ht.h>
     
    5152#include <arch/barrier.h>
    5253
    53 #ifdef CONFIG_VIRT_IDX_DCACHE
    54 #include <arch/mm/cache.h>
    55 #endif
    56 
    57 static int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
    58 static void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame);
    59 static void elf_share(as_area_t *area);
     54static bool elf_create(as_area_t *);
     55static bool elf_resize(as_area_t *, size_t);
     56static void elf_share(as_area_t *);
     57static void elf_destroy(as_area_t *);
     58
     59static int elf_page_fault(as_area_t *, uintptr_t, pf_access_t);
     60static void elf_frame_free(as_area_t *, uintptr_t, uintptr_t);
    6061
    6162mem_backend_t elf_backend = {
     63        .create = elf_create,
     64        .resize = elf_resize,
     65        .share = elf_share,
     66        .destroy = elf_destroy,
     67
    6268        .page_fault = elf_page_fault,
    6369        .frame_free = elf_frame_free,
    64         .share = elf_share
    6570};
    6671
    67 /** Service a page fault in the ELF backend address space area.
    68  *
    69  * The address space area and page tables must be already locked.
    70  *
    71  * @param area          Pointer to the address space area.
    72  * @param addr          Faulting virtual address.
    73  * @param access        Access mode that caused the fault (i.e.
    74  *                      read/write/exec).
    75  *
    76  * @return              AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK
    77  *                      on success (i.e. serviced).
    78  */
    79 int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
    80 {
    81         elf_header_t *elf = area->backend_data.elf;
     72static size_t elf_nonanon_pages_get(as_area_t *area)
     73{
    8274        elf_segment_header_t *entry = area->backend_data.segment;
    83         btree_node_t *leaf;
    84         uintptr_t base, frame, page, start_anon;
    85         size_t i;
    86         bool dirty = false;
    87 
    88         ASSERT(page_table_locked(AS));
    89         ASSERT(mutex_locked(&area->lock));
    90 
    91         if (!as_area_check_access(area, access))
    92                 return AS_PF_FAULT;
    93 
    94         ASSERT((addr >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) &&
    95             (addr < entry->p_vaddr + entry->p_memsz));
    96         i = (addr - ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) >> PAGE_WIDTH;
    97         base = (uintptr_t)
    98             (((void *) elf) + ALIGN_DOWN(entry->p_offset, PAGE_SIZE));
    99 
    100         /* Virtual address of faulting page*/
    101         page = ALIGN_DOWN(addr, PAGE_SIZE);
    102 
    103         /* Virtual address of the end of initialized part of segment */
    104         start_anon = entry->p_vaddr + entry->p_filesz;
    105 
    106         if (area->sh_info) {
    107                 bool found = false;
    108 
    109                 /*
    110                  * The address space area is shared.
    111                  */
    112                
    113                 mutex_lock(&area->sh_info->lock);
    114                 frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
    115                     page - area->base, &leaf);
    116                 if (!frame) {
    117                         unsigned int i;
    118 
    119                         /*
    120                          * Workaround for valid NULL address.
    121                          */
    122 
    123                         for (i = 0; i < leaf->keys; i++) {
    124                                 if (leaf->key[i] == page - area->base) {
    125                                         found = true;
    126                                         break;
    127                                 }
    128                         }
    129                 }
    130                 if (frame || found) {
    131                         frame_reference_add(ADDR2PFN(frame));
    132                         page_mapping_insert(AS, addr, frame,
    133                             as_area_get_flags(area));
    134                         if (!used_space_insert(area, page, 1))
    135                                 panic("Cannot insert used space.");
    136                         mutex_unlock(&area->sh_info->lock);
    137                         return AS_PF_OK;
    138                 }
    139         }
    140 
    141         /*
    142          * The area is either not shared or the pagemap does not contain the
    143          * mapping.
    144          */
    145         if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) {
    146                 /*
    147                  * Initialized portion of the segment. The memory is backed
    148                  * directly by the content of the ELF image. Pages are
    149                  * only copied if the segment is writable so that there
    150                  * can be more instantions of the same memory ELF image
    151                  * used at a time. Note that this could be later done
    152                  * as COW.
    153                  */
    154                 if (entry->p_flags & PF_W) {
    155                         frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
    156                         memcpy((void *) PA2KA(frame),
    157                             (void *) (base + i * FRAME_SIZE), FRAME_SIZE);
    158                         if (entry->p_flags & PF_X) {
    159                                 smc_coherence_block((void *) PA2KA(frame),
    160                                     FRAME_SIZE);
    161                         }
    162                         dirty = true;
    163                 } else {
    164                         frame = KA2PA(base + i * FRAME_SIZE);
    165                 }       
    166         } else if (page >= start_anon) {
    167                 /*
    168                  * This is the uninitialized portion of the segment.
    169                  * It is not physically present in the ELF image.
    170                  * To resolve the situation, a frame must be allocated
    171                  * and cleared.
    172                  */
    173                 frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
    174                 memsetb((void *) PA2KA(frame), FRAME_SIZE, 0);
    175                 dirty = true;
    176         } else {
    177                 size_t pad_lo, pad_hi;
    178                 /*
    179                  * The mixed case.
    180                  *
    181                  * The middle part is backed by the ELF image and
    182                  * the lower and upper parts are anonymous memory.
    183                  * (The segment can be and often is shorter than 1 page).
    184                  */
    185                 if (page < entry->p_vaddr)
    186                         pad_lo = entry->p_vaddr - page;
    187                 else
    188                         pad_lo = 0;
    189 
    190                 if (start_anon < page + PAGE_SIZE)
    191                         pad_hi = page + PAGE_SIZE - start_anon;
    192                 else
    193                         pad_hi = 0;
    194 
    195                 frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
    196                 memcpy((void *) (PA2KA(frame) + pad_lo),
    197                     (void *) (base + i * FRAME_SIZE + pad_lo),
    198                     FRAME_SIZE - pad_lo - pad_hi);
    199                 if (entry->p_flags & PF_X) {
    200                         smc_coherence_block((void *) (PA2KA(frame) + pad_lo),
    201                             FRAME_SIZE - pad_lo - pad_hi);
    202                 }
    203                 memsetb((void *) PA2KA(frame), pad_lo, 0);
    204                 memsetb((void *) (PA2KA(frame) + FRAME_SIZE - pad_hi), pad_hi,
    205                     0);
    206                 dirty = true;
    207         }
    208 
    209         if (dirty && area->sh_info) {
    210                 frame_reference_add(ADDR2PFN(frame));
    211                 btree_insert(&area->sh_info->pagemap, page - area->base,
    212                     (void *) frame, leaf);
    213         }
    214 
    215         if (area->sh_info)
    216                 mutex_unlock(&area->sh_info->lock);
    217 
    218         page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
    219         if (!used_space_insert(area, page, 1))
    220                 panic("Cannot insert used space.");
    221 
    222         return AS_PF_OK;
    223 }
    224 
    225 /** Free a frame that is backed by the ELF backend.
    226  *
    227  * The address space area and page tables must be already locked.
    228  *
    229  * @param area          Pointer to the address space area.
    230  * @param page          Page that is mapped to frame. Must be aligned to
    231  *                      PAGE_SIZE.
    232  * @param frame         Frame to be released.
    233  *
    234  */
    235 void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
    236 {
    237         elf_segment_header_t *entry = area->backend_data.segment;
    238         uintptr_t start_anon;
    239 
    240         ASSERT(page_table_locked(area->as));
    241         ASSERT(mutex_locked(&area->lock));
    242 
    243         ASSERT(page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE));
    244         ASSERT(page < entry->p_vaddr + entry->p_memsz);
    245 
    246         start_anon = entry->p_vaddr + entry->p_filesz;
    247 
    248         if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) {
    249                 if (entry->p_flags & PF_W) {
    250                         /*
    251                          * Free the frame with the copy of writable segment
    252                          * data.
    253                          */
    254                         frame_free(frame);
    255                 }
    256         } else {
    257                 /*
    258                  * The frame is either anonymous memory or the mixed case (i.e.
    259                  * lower part is backed by the ELF image and the upper is
    260                  * anonymous). In any case, a frame needs to be freed.
    261                  */
    262                 frame_free(frame);
    263         }
     75        uintptr_t first = ALIGN_UP(entry->p_vaddr, PAGE_SIZE);
     76        uintptr_t last = ALIGN_DOWN(entry->p_vaddr + entry->p_filesz,
     77            PAGE_SIZE);
     78
     79        if (entry->p_flags & PF_W)
     80                return 0;
     81
     82        if (last < first)
     83                return 0;
     84
     85        return last - first;
     86}
     87
     88bool elf_create(as_area_t *area)
     89{
     90        size_t nonanon_pages = elf_nonanon_pages_get(area);
     91
     92        if (area->pages <= nonanon_pages)
     93                return true;
     94       
     95        return reserve_try_alloc(area->pages - nonanon_pages);
     96}
     97
     98bool elf_resize(as_area_t *area, size_t new_pages)
     99{
     100        size_t nonanon_pages = elf_nonanon_pages_get(area);
     101
     102        if (new_pages > area->pages) {
     103                /* The area is growing. */
     104                if (area->pages >= nonanon_pages)
     105                        return reserve_try_alloc(new_pages - area->pages);
     106                else if (new_pages > nonanon_pages)
     107                        return reserve_try_alloc(new_pages - nonanon_pages);
     108        } else if (new_pages < area->pages) {
     109                /* The area is shrinking. */
     110                if (new_pages >= nonanon_pages)
     111                        reserve_free(area->pages - new_pages);
     112                else if (area->pages > nonanon_pages)
     113                        reserve_free(nonanon_pages - new_pages);
     114        }
     115       
     116        return true;
    264117}
    265118
     
    352205}
    353206
     207void elf_destroy(as_area_t *area)
     208{
     209        size_t nonanon_pages = elf_nonanon_pages_get(area);
     210
     211        if (area->pages > nonanon_pages)
     212                reserve_free(area->pages - nonanon_pages);
     213}
     214
     215/** Service a page fault in the ELF backend address space area.
     216 *
     217 * The address space area and page tables must be already locked.
     218 *
     219 * @param area          Pointer to the address space area.
     220 * @param addr          Faulting virtual address.
     221 * @param access        Access mode that caused the fault (i.e.
     222 *                      read/write/exec).
     223 *
     224 * @return              AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK
     225 *                      on success (i.e. serviced).
     226 */
     227int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
     228{
     229        elf_header_t *elf = area->backend_data.elf;
     230        elf_segment_header_t *entry = area->backend_data.segment;
     231        btree_node_t *leaf;
     232        uintptr_t base, frame, page, start_anon;
     233        size_t i;
     234        bool dirty = false;
     235
     236        ASSERT(page_table_locked(AS));
     237        ASSERT(mutex_locked(&area->lock));
     238
     239        if (!as_area_check_access(area, access))
     240                return AS_PF_FAULT;
     241       
     242        if (addr < ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE))
     243                return AS_PF_FAULT;
     244       
     245        if (addr >= entry->p_vaddr + entry->p_memsz)
     246                return AS_PF_FAULT;
     247       
     248        i = (addr - ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) >> PAGE_WIDTH;
     249        base = (uintptr_t)
     250            (((void *) elf) + ALIGN_DOWN(entry->p_offset, PAGE_SIZE));
     251
     252        /* Virtual address of faulting page*/
     253        page = ALIGN_DOWN(addr, PAGE_SIZE);
     254
     255        /* Virtual address of the end of initialized part of segment */
     256        start_anon = entry->p_vaddr + entry->p_filesz;
     257
     258        if (area->sh_info) {
     259                bool found = false;
     260
     261                /*
     262                 * The address space area is shared.
     263                 */
     264               
     265                mutex_lock(&area->sh_info->lock);
     266                frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
     267                    page - area->base, &leaf);
     268                if (!frame) {
     269                        unsigned int i;
     270
     271                        /*
     272                         * Workaround for valid NULL address.
     273                         */
     274
     275                        for (i = 0; i < leaf->keys; i++) {
     276                                if (leaf->key[i] == page - area->base) {
     277                                        found = true;
     278                                        break;
     279                                }
     280                        }
     281                }
     282                if (frame || found) {
     283                        frame_reference_add(ADDR2PFN(frame));
     284                        page_mapping_insert(AS, addr, frame,
     285                            as_area_get_flags(area));
     286                        if (!used_space_insert(area, page, 1))
     287                                panic("Cannot insert used space.");
     288                        mutex_unlock(&area->sh_info->lock);
     289                        return AS_PF_OK;
     290                }
     291        }
     292
     293        /*
     294         * The area is either not shared or the pagemap does not contain the
     295         * mapping.
     296         */
     297        if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) {
     298                /*
     299                 * Initialized portion of the segment. The memory is backed
     300                 * directly by the content of the ELF image. Pages are
     301                 * only copied if the segment is writable so that there
     302                 * can be more instantions of the same memory ELF image
     303                 * used at a time. Note that this could be later done
     304                 * as COW.
     305                 */
     306                if (entry->p_flags & PF_W) {
     307                        frame = (uintptr_t)frame_alloc_noreserve(ONE_FRAME, 0);
     308                        memcpy((void *) PA2KA(frame),
     309                            (void *) (base + i * FRAME_SIZE), FRAME_SIZE);
     310                        if (entry->p_flags & PF_X) {
     311                                smc_coherence_block((void *) PA2KA(frame),
     312                                    FRAME_SIZE);
     313                        }
     314                        dirty = true;
     315                } else {
     316                        frame = KA2PA(base + i * FRAME_SIZE);
     317                }       
     318        } else if (page >= start_anon) {
     319                /*
     320                 * This is the uninitialized portion of the segment.
     321                 * It is not physically present in the ELF image.
     322                 * To resolve the situation, a frame must be allocated
     323                 * and cleared.
     324                 */
     325                frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0);
     326                memsetb((void *) PA2KA(frame), FRAME_SIZE, 0);
     327                dirty = true;
     328        } else {
     329                size_t pad_lo, pad_hi;
     330                /*
     331                 * The mixed case.
     332                 *
     333                 * The middle part is backed by the ELF image and
     334                 * the lower and upper parts are anonymous memory.
     335                 * (The segment can be and often is shorter than 1 page).
     336                 */
     337                if (page < entry->p_vaddr)
     338                        pad_lo = entry->p_vaddr - page;
     339                else
     340                        pad_lo = 0;
     341
     342                if (start_anon < page + PAGE_SIZE)
     343                        pad_hi = page + PAGE_SIZE - start_anon;
     344                else
     345                        pad_hi = 0;
     346
     347                frame = (uintptr_t) frame_alloc_noreserve(ONE_FRAME, 0);
     348                memcpy((void *) (PA2KA(frame) + pad_lo),
     349                    (void *) (base + i * FRAME_SIZE + pad_lo),
     350                    FRAME_SIZE - pad_lo - pad_hi);
     351                if (entry->p_flags & PF_X) {
     352                        smc_coherence_block((void *) (PA2KA(frame) + pad_lo),
     353                            FRAME_SIZE - pad_lo - pad_hi);
     354                }
     355                memsetb((void *) PA2KA(frame), pad_lo, 0);
     356                memsetb((void *) (PA2KA(frame) + FRAME_SIZE - pad_hi), pad_hi,
     357                    0);
     358                dirty = true;
     359        }
     360
     361        if (dirty && area->sh_info) {
     362                frame_reference_add(ADDR2PFN(frame));
     363                btree_insert(&area->sh_info->pagemap, page - area->base,
     364                    (void *) frame, leaf);
     365        }
     366
     367        if (area->sh_info)
     368                mutex_unlock(&area->sh_info->lock);
     369
     370        page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
     371        if (!used_space_insert(area, page, 1))
     372                panic("Cannot insert used space.");
     373
     374        return AS_PF_OK;
     375}
     376
     377/** Free a frame that is backed by the ELF backend.
     378 *
     379 * The address space area and page tables must be already locked.
     380 *
     381 * @param area          Pointer to the address space area.
     382 * @param page          Page that is mapped to frame. Must be aligned to
     383 *                      PAGE_SIZE.
     384 * @param frame         Frame to be released.
     385 *
     386 */
     387void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
     388{
     389        elf_segment_header_t *entry = area->backend_data.segment;
     390        uintptr_t start_anon;
     391
     392        ASSERT(page_table_locked(area->as));
     393        ASSERT(mutex_locked(&area->lock));
     394
     395        ASSERT(page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE));
     396        ASSERT(page < entry->p_vaddr + entry->p_memsz);
     397
     398        start_anon = entry->p_vaddr + entry->p_filesz;
     399
     400        if (page >= entry->p_vaddr && page + PAGE_SIZE <= start_anon) {
     401                if (entry->p_flags & PF_W) {
     402                        /*
     403                         * Free the frame with the copy of writable segment
     404                         * data.
     405                         */
     406                        frame_free_noreserve(frame);
     407                }
     408        } else {
     409                /*
     410                 * The frame is either anonymous memory or the mixed case (i.e.
     411                 * lower part is backed by the ELF image and the upper is
     412                 * anonymous). In any case, a frame needs to be freed.
     413                 */
     414                frame_free_noreserve(frame);
     415        }
     416}
     417
    354418/** @}
    355419 */
  • kernel/generic/src/mm/backend_phys.c

    r1ff896e r694ca93f  
    4848#include <align.h>
    4949
    50 static int phys_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access);
    51 static void phys_share(as_area_t *area);
     50static bool phys_create(as_area_t *);
     51static void phys_share(as_area_t *);
     52static void phys_destroy(as_area_t *);
     53
     54static int phys_page_fault(as_area_t *, uintptr_t, pf_access_t);
    5255
    5356mem_backend_t phys_backend = {
     57        .create = phys_create,
     58        .resize = NULL,
     59        .share = phys_share,
     60        .destroy = phys_destroy,
     61
    5462        .page_fault = phys_page_fault,
    5563        .frame_free = NULL,
    56         .share = phys_share
    5764};
     65
     66bool phys_create(as_area_t *area)
     67{
     68        return true;
     69}
     70
     71/** Share address space area backed by physical memory.
     72 *
     73 * Do actually nothing as sharing of address space areas
     74 * that are backed up by physical memory is very easy.
     75 * Note that the function must be defined so that
     76 * as_area_share() will succeed.
     77 */
     78void phys_share(as_area_t *area)
     79{
     80        ASSERT(mutex_locked(&area->as->lock));
     81        ASSERT(mutex_locked(&area->lock));
     82}
     83
     84
     85void phys_destroy(as_area_t *area)
     86{
     87        /* Nothing to do. */
     88}
    5889
    5990/** Service a page fault in the address space area backed by physical memory.
     
    88119}
    89120
    90 /** Share address space area backed by physical memory.
    91  *
    92  * Do actually nothing as sharing of address space areas
    93  * that are backed up by physical memory is very easy.
    94  * Note that the function must be defined so that
    95  * as_area_share() will succeed.
    96  */
    97 void phys_share(as_area_t *area)
    98 {
    99         ASSERT(mutex_locked(&area->as->lock));
    100         ASSERT(mutex_locked(&area->lock));
    101 }
    102 
    103121/** @}
    104122 */
  • kernel/generic/src/mm/frame.c

    r1ff896e r694ca93f  
    4545#include <typedefs.h>
    4646#include <mm/frame.h>
     47#include <mm/reserve.h>
    4748#include <mm/as.h>
    4849#include <panic.h>
     
    5960#include <macros.h>
    6061#include <config.h>
     62#include <str.h>
    6163
    6264zones_t zones;
     
    472474 * @param frame_idx Frame index relative to zone.
    473475 *
    474  */
    475 NO_TRACE static void zone_frame_free(zone_t *zone, size_t frame_idx)
     476 * @return          Number of freed frames.
     477 *
     478 */
     479NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
    476480{
    477481        ASSERT(zone_flags_available(zone->flags));
    478482       
    479483        frame_t *frame = &zone->frames[frame_idx];
    480        
    481         /* Remember frame order */
    482         uint8_t order = frame->buddy_order;
     484        size_t size = 0;
    483485       
    484486        ASSERT(frame->refcount);
    485487       
    486488        if (!--frame->refcount) {
    487                 buddy_system_free(zone->buddy_system, &frame->buddy_link);
    488                
     489                size = 1 << frame->buddy_order;
     490                buddy_system_free(zone->buddy_system, &frame->buddy_link);             
    489491                /* Update zone information. */
    490                 zone->free_count += (1 << order);
    491                 zone->busy_count -= (1 << order);
    492         }
     492                zone->free_count += size;
     493                zone->busy_count -= size;
     494        }
     495       
     496        return size;
    493497}
    494498
     
    516520        ASSERT(link);
    517521        zone->free_count--;
     522        reserve_force_alloc(1);
    518523}
    519524
     
    645650        for (i = 0; i < cframes; i++) {
    646651                zones.info[znum].busy_count++;
    647                 zone_frame_free(&zones.info[znum],
     652                (void) zone_frame_free(&zones.info[znum],
    648653                    pfn - zones.info[znum].base + i);
    649654        }
     
    683688        /* Free unneeded frames */
    684689        for (i = count; i < (size_t) (1 << order); i++)
    685                 zone_frame_free(&zones.info[znum], i + frame_idx);
     690                (void) zone_frame_free(&zones.info[znum], i + frame_idx);
    686691}
    687692
     
    695700 * not to be 2^order size. Once the allocator is running it is no longer
    696701 * possible, merged configuration data occupies more space :-/
    697  *
    698  * The function uses
    699702 *
    700703 */
     
    837840                        buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
    838841                }
     842
     843                /* "Unreserve" new frames. */
     844                reserve_free(count);
    839845        } else
    840846                zone->frames = NULL;
     
    9991005        size_t hint = pzone ? (*pzone) : 0;
    10001006       
     1007        /*
     1008         * If not told otherwise, we must first reserve the memory.
     1009         */
     1010        if (!(flags & FRAME_NO_RESERVE))
     1011                reserve_force_alloc(size);
     1012
    10011013loop:
    10021014        irq_spinlock_lock(&zones.lock, true);
     
    10331045                if (flags & FRAME_ATOMIC) {
    10341046                        irq_spinlock_unlock(&zones.lock, true);
     1047                        if (!(flags & FRAME_NO_RESERVE))
     1048                                reserve_free(size);
    10351049                        return NULL;
    10361050                }
     
    10881102}
    10891103
     1104void *frame_alloc(uint8_t order, frame_flags_t flags)
     1105{
     1106        return frame_alloc_generic(order, flags, NULL);
     1107}
     1108
     1109void *frame_alloc_noreserve(uint8_t order, frame_flags_t flags)
     1110{
     1111        return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, NULL);
     1112}
     1113
    10901114/** Free a frame.
    10911115 *
     
    10951119 *
    10961120 * @param frame Physical Address of of the frame to be freed.
    1097  *
    1098  */
    1099 void frame_free(uintptr_t frame)
    1100 {
     1121 * @param flags Flags to control memory reservation.
     1122 *
     1123 */
     1124void frame_free_generic(uintptr_t frame, frame_flags_t flags)
     1125{
     1126        size_t size;
     1127       
    11011128        irq_spinlock_lock(&zones.lock, true);
    11021129       
     
    11061133        pfn_t pfn = ADDR2PFN(frame);
    11071134        size_t znum = find_zone(pfn, 1, 0);
     1135
    11081136       
    11091137        ASSERT(znum != (size_t) -1);
    11101138       
    1111         zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
     1139        size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
    11121140       
    11131141        irq_spinlock_unlock(&zones.lock, true);
     
    11181146        mutex_lock(&mem_avail_mtx);
    11191147        if (mem_avail_req > 0)
    1120                 mem_avail_req--;
     1148                mem_avail_req -= min(mem_avail_req, size);
    11211149       
    11221150        if (mem_avail_req == 0) {
     
    11251153        }
    11261154        mutex_unlock(&mem_avail_mtx);
     1155       
     1156        if (!(flags & FRAME_NO_RESERVE))
     1157                reserve_free(size);
     1158}
     1159
     1160void frame_free(uintptr_t frame)
     1161{
     1162        frame_free_generic(frame, 0);
     1163}
     1164
     1165void frame_free_noreserve(uintptr_t frame)
     1166{
     1167        frame_free_generic(frame, FRAME_NO_RESERVE);
    11271168}
    11281169
     
    13551396        bool available = zone_flags_available(flags);
    13561397       
     1398        uint64_t size;
     1399        const char *size_suffix;
     1400        bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false);
     1401       
    13571402        printf("Zone number:       %zu\n", znum);
    13581403        printf("Zone base address: %p\n", (void *) base);
    1359         printf("Zone size:         %zu frames (%zu KiB)\n", count,
    1360             SIZE2KB(FRAMES2SIZE(count)));
     1404        printf("Zone size:         %zu frames (%" PRIu64 " %s)\n", count,
     1405            size, size_suffix);
    13611406        printf("Zone flags:        %c%c%c\n",
    13621407            available ? 'A' : ' ',
     
    13651410       
    13661411        if (available) {
    1367                 printf("Allocated space:   %zu frames (%zu KiB)\n",
    1368                     busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
    1369                 printf("Available space:   %zu frames (%zu KiB)\n",
    1370                     free_count, SIZE2KB(FRAMES2SIZE(free_count)));
     1412                bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix,
     1413                    false);
     1414                printf("Allocated space:   %zu frames (%" PRIu64 " %s)\n",
     1415                    busy_count, size, size_suffix);
     1416                bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix,
     1417                    false);
     1418                printf("Available space:   %zu frames (%" PRIu64 " %s)\n",
     1419                    free_count, size, size_suffix);
    13711420        }
    13721421}
  • kernel/generic/src/proc/scheduler.c

    r1ff896e r694ca93f  
    354354       
    355355        /*
    356          * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, VM
     356         * Through the 'THE' structure, we keep track of THREAD, TASK, CPU, AS
    357357         * and preemption counter. At this point THE could be coming either
    358358         * from THREAD's or CPU's stack.
Note: See TracChangeset for help on using the changeset viewer.