Changeset 864a081 in mainline


Ignore:
Timestamp:
2011-05-24T03:40:00Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
bf49001
Parents:
5c460cc (diff), d4c472b (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.

Files:
2 added
1 deleted
43 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/ppc32/src/asm.S

    r5c460cc r864a081  
    5858.endm
    5959
     60.macro BAT_COMPUTE base size mask lower upper
     61        # less than 128 KB -> no BAT
     62       
     63        lis \upper, 0x0002
     64        cmpw \size, \upper
     65        blt no_bat
     66       
     67        # mask = total >> 18
     68       
     69        li \upper, 18
     70        srw \mask, \size, \upper
     71       
     72        # create Block Length mask by replicating
     73        # the leading logical one 14 times
     74       
     75        li \upper, 14
     76        mtctr \mask
     77        li \upper, 1
     78       
     79        0:
     80                # mask = (mask >> 1) | mask
     81               
     82                srw \lower, \mask, \upper
     83                or \mask, \mask, \lower
     84               
     85                bdnz 0b
     86       
     87        # mask = mask & 0x07ff
     88        # (BAT can map up to 256 MB)
     89       
     90        andi. \mask, \mask, 0x07ff
     91       
     92        # mask = (mask << 2) | 0x0002
     93        # (priviledged access only)
     94       
     95        li \upper, 2
     96        slw \mask, \mask, \upper
     97        ori \mask, \mask, 0x0002
     98       
     99        lis \upper, (0x8000 + \base)
     100        or \upper, \upper, \mask
     101       
     102        lis \lower, \base
     103        ori \lower, \lower, 0x0002
     104.endm
     105
    60106.global start
    61107.global halt
     
    247293        lwz r31, 4(r3)                # r31 = memory size
    248294       
    249         lis r29, 0x0002
    250         cmpw r31, r29
    251         blt no_bat                    # less than 128 KB -> no BAT
    252        
    253         li r29, 18
    254         srw r31, r31, r29             # r31 = total >> 18
    255        
    256         # create Block Length mask by replicating
    257         # the leading logical one 14 times
    258        
    259         li r29, 14
    260         mtctr r31
    261         li r29, 1
    262        
    263         bat_mask:
    264                 srw r30, r31, r29         # r30 = mask >> 1
    265                 or r31, r31, r30          # mask = mask | r30
    266                
    267                 bdnz bat_mask
    268        
    269         andi. r31, r31, 0x07ff        # mask = mask & 0x07ff (BAT can map up to 256 MB)
    270        
    271         li r29, 2
    272         slw r31, r31, r29             # mask = mask << 2
    273         ori r31, r31, 0x0002          # mask = mask | 0x0002 (priviledged access only)
    274        
    275         lis r29, 0x8000
    276         or r29, r29, r31
    277        
    278         lis r30, 0x0000
    279         ori r30, r30, 0x0002
    280        
    281         mtspr ibat0u, r29
    282         mtspr ibat0l, r30
    283        
    284         mtspr dbat0u, r29
    285         mtspr dbat0l, r30
     295        lis r30, 268435456@h
     296        ori r30, r30, 268435456@l     # r30 = 256 MB
     297       
     298        # BAT0
     299       
     300        # r29 = min(r31, r30)
     301       
     302        cmpw r31, r30
     303        blt bat0_r31
     304       
     305                mr r29, r30
     306                b bat0_r30
     307       
     308        bat0_r31:
     309       
     310                mr r29, r31
     311       
     312        bat0_r30:
     313       
     314        BAT_COMPUTE 0x0000 r29 r28 r27 r26
     315        mtspr ibat0u, r26
     316        mtspr ibat0l, r27
     317       
     318        mtspr dbat0u, r26
     319        mtspr dbat0l, r27
     320       
     321        # BAT1
     322       
     323        sub r31, r31, r29             # r31 = r31 - r29
     324       
     325        # r29 = min(r31, r30)
     326       
     327        cmpw r31, r30
     328        blt bat1_r31
     329       
     330                mr r29, r30
     331                b bat1_r30
     332       
     333        bat1_r31:
     334       
     335                mr r29, r31
     336       
     337        bat1_r30:
     338       
     339        BAT_COMPUTE 0x1000 r29 r28 r27 r26
     340        mtspr ibat1u, r26
     341        mtspr ibat1l, r27
     342       
     343        mtspr dbat1u, r26
     344        mtspr dbat1l, r27
     345       
     346        # BAT2
     347       
     348        sub r31, r31, r29             # r31 = r31 - r29
     349       
     350        # r29 = min(r31, r30)
     351       
     352        cmpw r31, r30
     353        blt bat2_r31
     354       
     355                mr r29, r30
     356                b bat2_r30
     357       
     358        bat2_r31:
     359       
     360                mr r29, r31
     361       
     362        bat2_r30:
     363       
     364        BAT_COMPUTE 0x2000 r29 r28 r27 r26
     365        mtspr ibat2u, r26
     366        mtspr ibat2l, r27
     367       
     368        mtspr dbat2u, r26
     369        mtspr dbat2l, r27
     370       
     371        # BAT3
     372       
     373        sub r31, r31, r29             # r31 = r31 - r29
     374       
     375        # r29 = min(r31, r30)
     376       
     377        cmpw r31, r30
     378        blt bat3_r31
     379       
     380                mr r29, r30
     381                b bat3_r30
     382       
     383        bat3_r31:
     384       
     385                mr r29, r31
     386       
     387        bat3_r30:
     388       
     389        BAT_COMPUTE 0x3000 r29 r28 r27 r26
     390        mtspr ibat3u, r26
     391        mtspr ibat3l, r27
     392       
     393        mtspr dbat3u, r26
     394        mtspr dbat3l, r27
    286395       
    287396        no_bat:
  • contrib/conf/arm32-qe.sh

    r5c460cc r864a081  
    11#!/bin/sh
    22
    3 qemu-system-arm -M integratorcp --kernel image.boot
     3qemu-system-arm $@ -M integratorcp --kernel image.boot
  • contrib/conf/ia32-qe.sh

    r5c460cc r864a081  
    88fi
    99
    10 qemu -m 32 -hda "$DISK_IMG" -cdrom image.iso -boot d
     10qemu $@ -m 32 -hda "$DISK_IMG" -cdrom image.iso -boot d
  • contrib/conf/ppc32-qe.sh

    r5c460cc r864a081  
    11#!/bin/sh
    22
    3 qemu-system-ppc -M mac99 -boot d -cdrom image.iso
     3qemu-system-ppc $@ -M mac99 -boot d -cdrom image.iso
  • kernel/arch/ia64/src/mm/tlb.c

    r5c460cc r864a081  
    481481       
    482482        page_table_lock(AS, true);
    483         t = page_mapping_find(AS, va);
     483        t = page_mapping_find(AS, va, true);
    484484        if (t) {
    485485                /*
     
    599599       
    600600        page_table_lock(AS, true);
    601         pte_t *entry = page_mapping_find(AS, va);
     601        pte_t *entry = page_mapping_find(AS, va, true);
    602602        if (entry) {
    603603                /*
     
    651651       
    652652        page_table_lock(AS, true);
    653         t = page_mapping_find(AS, va);
     653        t = page_mapping_find(AS, va, true);
    654654        ASSERT((t) && (t->p));
    655655        if ((t) && (t->p) && (t->w)) {
     
    684684       
    685685        page_table_lock(AS, true);
    686         t = page_mapping_find(AS, va);
     686        t = page_mapping_find(AS, va, true);
    687687        ASSERT((t) && (t->p));
    688688        if ((t) && (t->p) && (t->x)) {
     
    717717       
    718718        page_table_lock(AS, true);
    719         t = page_mapping_find(AS, va);
     719        t = page_mapping_find(AS, va, true);
    720720        ASSERT((t) && (t->p));
    721721        if ((t) && (t->p)) {
     
    753753         */
    754754        page_table_lock(AS, true);
    755         t = page_mapping_find(AS, va);
     755        t = page_mapping_find(AS, va, true);
    756756        ASSERT((t) && (t->p));
    757757        ASSERT(!t->w);
     
    778778       
    779779        page_table_lock(AS, true);
    780         t = page_mapping_find(AS, va);
     780        t = page_mapping_find(AS, va, true);
    781781        ASSERT(t);
    782782       
  • kernel/arch/mips32/src/mm/tlb.c

    r5c460cc r864a081  
    100100        mutex_unlock(&AS->lock);
    101101       
    102         page_table_lock(AS, true);
    103        
    104102        pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
    105103        if (!pte) {
     
    113111                         * or copy_to_uspace().
    114112                         */
    115                         page_table_unlock(AS, true);
    116113                        return;
    117114                default:
     
    144141        tlbwr();
    145142
    146         page_table_unlock(AS, true);
    147143        return;
    148144       
    149145fail:
    150         page_table_unlock(AS, true);
    151146        tlb_refill_fail(istate);
    152147}
     
    176171        index.value = cp0_index_read();
    177172
    178         page_table_lock(AS, true);     
    179        
    180173        /*
    181174         * Fail if the entry is not in TLB.
     
    197190                         * or copy_to_uspace().
    198191                         */
    199                         page_table_unlock(AS, true);                     
    200192                        return;
    201193                default:
     
    227219        tlbwi();
    228220
    229         page_table_unlock(AS, true);
    230221        return;
    231222       
    232223fail:
    233         page_table_unlock(AS, true);
    234224        tlb_invalid_fail(istate);
    235225}
     
    259249        index.value = cp0_index_read();
    260250
    261         page_table_lock(AS, true);     
    262        
    263251        /*
    264252         * Fail if the entry is not in TLB.
     
    280268                         * or copy_to_uspace().
    281269                         */
    282                         page_table_unlock(AS, true);                     
    283270                        return;
    284271                default:
     
    311298        tlbwi();
    312299
    313         page_table_unlock(AS, true);
    314300        return;
    315301       
    316302fail:
    317         page_table_unlock(AS, true);
    318303        tlb_modified_fail(istate);
    319304}
     
    364349        pte_t *pte;
    365350
    366         ASSERT(mutex_locked(&AS->lock));
    367 
    368351        hi.value = cp0_entry_hi_read();
    369352
     
    379362         * Check if the mapping exists in page tables.
    380363         */     
    381         pte = page_mapping_find(AS, badvaddr);
     364        pte = page_mapping_find(AS, badvaddr, true);
    382365        if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) {
    383366                /*
     
    393376                 * Resort to higher-level page fault handler.
    394377                 */
    395                 page_table_unlock(AS, true);
    396378                switch (rc = as_page_fault(badvaddr, access, istate)) {
    397379                case AS_PF_OK:
     
    400382                         * The mapping ought to be in place.
    401383                         */
    402                         page_table_lock(AS, true);
    403                         pte = page_mapping_find(AS, badvaddr);
     384                        pte = page_mapping_find(AS, badvaddr, true);
    404385                        ASSERT(pte && pte->p);
    405386                        ASSERT(pte->w || access != PF_ACCESS_WRITE);
     
    407388                        break;
    408389                case AS_PF_DEFER:
    409                         page_table_lock(AS, true);
    410390                        *pfrc = AS_PF_DEFER;
    411391                        return NULL;
    412392                        break;
    413393                case AS_PF_FAULT:
    414                         page_table_lock(AS, true);
    415394                        *pfrc = AS_PF_FAULT;
    416395                        return NULL;
  • kernel/arch/ppc32/Makefile.inc

    r5c460cc r864a081  
    5555        arch/$(KARCH)/src/mm/frame.c \
    5656        arch/$(KARCH)/src/mm/page.c \
     57        arch/$(KARCH)/src/mm/pht.c \
    5758        arch/$(KARCH)/src/mm/tlb.c \
    5859        arch/$(KARCH)/src/drivers/pic.c
  • kernel/arch/ppc32/include/mm/as.h

    r5c460cc r864a081  
    3636#define KERN_ppc32_AS_H_
    3737
     38#include <arch/mm/pht.h>
     39
    3840#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH  0
    3941
     
    5254#define as_create_arch(as, flags)       (as != as)
    5355#define as_deinstall_arch(as)
    54 #define as_invalidate_translation_cache(as, page, cnt)
     56
     57#define as_invalidate_translation_cache(as, page, cnt) \
     58        pht_invalidate((as), (page), (cnt))
    5559
    5660extern void as_arch_init(void);
  • kernel/arch/ppc32/include/mm/tlb.h

    r5c460cc r864a081  
    3737
    3838#include <arch/interrupt.h>
    39 #include <typedefs.h>
    4039
    4140#define WIMG_GUARDED    0x01
     
    7574} ptelo_t;
    7675
    77 extern void pht_init(void);
    78 extern void pht_refill(unsigned int, istate_t *);
    7976extern void tlb_refill(unsigned int, istate_t *);
    8077
  • kernel/arch/ppc32/src/interrupt.c

    r5c460cc r864a081  
    4242#include <arch/drivers/pic.h>
    4343#include <arch/mm/tlb.h>
     44#include <arch/mm/pht.h>
    4445#include <print.h>
    4546
  • kernel/arch/ppc32/src/mm/page.c

    r5c460cc r864a081  
    4343        if (config.cpu_active == 1)
    4444                page_mapping_operations = &pt_mapping_operations;
     45        as_switch(NULL, AS_KERNEL);
    4546}
    4647
  • kernel/arch/ppc32/src/mm/tlb.c

    r5c460cc r864a081  
    3333 */
    3434
    35 #include <mm/tlb.h>
    3635#include <arch/mm/tlb.h>
    37 #include <arch/interrupt.h>
    3836#include <interrupt.h>
    39 #include <mm/as.h>
    40 #include <mm/page.h>
    41 #include <arch.h>
    42 #include <print.h>
    43 #include <macros.h>
    44 #include <symtab.h>
    45 
    46 static unsigned int seed = 42;
    47 
    48 /** Try to find PTE for faulting address
    49  *
    50  * @param as       Address space.
    51  * @param lock     Lock/unlock the address space.
    52  * @param badvaddr Faulting virtual address.
    53  * @param access   Access mode that caused the fault.
    54  * @param istate   Pointer to interrupted state.
    55  * @param pfrc     Pointer to variable where as_page_fault() return code
    56  *                 will be stored.
    57  *
    58  * @return PTE on success, NULL otherwise.
    59  *
    60  */
    61 static pte_t *find_mapping_and_check(as_t *as, uintptr_t badvaddr, int access,
    62     istate_t *istate, int *pfrc)
    63 {
    64         ASSERT(mutex_locked(&as->lock));
    65 
    66         /*
    67          * Check if the mapping exists in page tables.
    68          */
    69         pte_t *pte = page_mapping_find(as, badvaddr);
    70         if ((pte) && (pte->present)) {
    71                 /*
    72                  * Mapping found in page tables.
    73                  * Immediately succeed.
    74                  */
    75                 return pte;
    76         } else {
    77                 /*
    78                  * Mapping not found in page tables.
    79                  * Resort to higher-level page fault handler.
    80                  */
    81                 page_table_unlock(as, true);
    82                
    83                 int rc = as_page_fault(badvaddr, access, istate);
    84                 switch (rc) {
    85                 case AS_PF_OK:
    86                         /*
    87                          * The higher-level page fault handler succeeded,
    88                          * The mapping ought to be in place.
    89                          */
    90                         page_table_lock(as, true);
    91                         pte = page_mapping_find(as, badvaddr);
    92                         ASSERT((pte) && (pte->present));
    93                         *pfrc = 0;
    94                         return pte;
    95                 case AS_PF_DEFER:
    96                         page_table_lock(as, true);
    97                         *pfrc = rc;
    98                         return NULL;
    99                 case AS_PF_FAULT:
    100                         page_table_lock(as, true);
    101                         *pfrc = rc;
    102                         return NULL;
    103                 default:
    104                         panic("Unexpected rc (%d).", rc);
    105                 }
    106         }
    107 }
    108 
    109 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
    110 {
    111         fault_if_from_uspace(istate, "PHT Refill Exception on %p.",
    112             (void *) badvaddr);
    113         panic_memtrap(istate, PF_ACCESS_UNKNOWN, badvaddr,
    114             "PHT Refill Exception.");
    115 }
    116 
    117 static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
    118 {
    119         uint32_t page = (vaddr >> 12) & 0xffff;
    120         uint32_t api = (vaddr >> 22) & 0x3f;
    121        
    122         uint32_t vsid = sr_get(vaddr);
    123         uint32_t sdr1 = sdr1_get();
    124        
    125         // FIXME: compute size of PHT exactly
    126         phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    127        
    128         /* Primary hash (xor) */
    129         uint32_t h = 0;
    130         uint32_t hash = vsid ^ page;
    131         uint32_t base = (hash & 0x3ff) << 3;
    132         uint32_t i;
    133         bool found = false;
    134        
    135         /* Find colliding PTE in PTEG */
    136         for (i = 0; i < 8; i++) {
    137                 if ((phte[base + i].v)
    138                     && (phte[base + i].vsid == vsid)
    139                     && (phte[base + i].api == api)
    140                     && (phte[base + i].h == 0)) {
    141                         found = true;
    142                         break;
    143                 }
    144         }
    145        
    146         if (!found) {
    147                 /* Find unused PTE in PTEG */
    148                 for (i = 0; i < 8; i++) {
    149                         if (!phte[base + i].v) {
    150                                 found = true;
    151                                 break;
    152                         }
    153                 }
    154         }
    155        
    156         if (!found) {
    157                 /* Secondary hash (not) */
    158                 uint32_t base2 = (~hash & 0x3ff) << 3;
    159                
    160                 /* Find colliding PTE in PTEG */
    161                 for (i = 0; i < 8; i++) {
    162                         if ((phte[base2 + i].v)
    163                             && (phte[base2 + i].vsid == vsid)
    164                             && (phte[base2 + i].api == api)
    165                             && (phte[base2 + i].h == 1)) {
    166                                 found = true;
    167                                 base = base2;
    168                                 h = 1;
    169                                 break;
    170                         }
    171                 }
    172                
    173                 if (!found) {
    174                         /* Find unused PTE in PTEG */
    175                         for (i = 0; i < 8; i++) {
    176                                 if (!phte[base2 + i].v) {
    177                                         found = true;
    178                                         base = base2;
    179                                         h = 1;
    180                                         break;
    181                                 }
    182                         }
    183                 }
    184                
    185                 if (!found)
    186                         i = RANDI(seed) % 8;
    187         }
    188        
    189         phte[base + i].v = 1;
    190         phte[base + i].vsid = vsid;
    191         phte[base + i].h = h;
    192         phte[base + i].api = api;
    193         phte[base + i].rpn = pte->pfn;
    194         phte[base + i].r = 0;
    195         phte[base + i].c = 0;
    196         phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
    197         phte[base + i].pp = 2; // FIXME
    198 }
    199 
    200 /** Process Instruction/Data Storage Exception
    201  *
    202  * @param n      Exception vector number.
    203  * @param istate Interrupted register context.
    204  *
    205  */
    206 void pht_refill(unsigned int n, istate_t *istate)
    207 {
    208         as_t *as = (AS == NULL) ? AS_KERNEL : AS;
    209         uintptr_t badvaddr;
    210        
    211         if (n == VECTOR_DATA_STORAGE)
    212                 badvaddr = istate->dar;
    213         else
    214                 badvaddr = istate->pc;
    215        
    216         page_table_lock(as, true);
    217        
    218         int pfrc;
    219         pte_t *pte = find_mapping_and_check(as, badvaddr,
    220             PF_ACCESS_READ /* FIXME */, istate, &pfrc);
    221        
    222         if (!pte) {
    223                 switch (pfrc) {
    224                 case AS_PF_FAULT:
    225                         page_table_unlock(as, true);
    226                         pht_refill_fail(badvaddr, istate);
    227                         return;
    228                 case AS_PF_DEFER:
    229                         /*
    230                          * The page fault came during copy_from_uspace()
    231                          * or copy_to_uspace().
    232                          */
    233                         page_table_unlock(as, true);
    234                         return;
    235                 default:
    236                         panic("Unexpected pfrc (%d).", pfrc);
    237                 }
    238         }
    239        
    240         /* Record access to PTE */
    241         pte->accessed = 1;
    242         pht_insert(badvaddr, pte);
    243        
    244         page_table_unlock(as, true);
    245 }
     37#include <typedefs.h>
    24638
    24739void tlb_refill(unsigned int n, istate_t *istate)
     
    28981void tlb_invalidate_all(void)
    29082{
    291         uint32_t index;
     83        asm volatile (
     84                "sync\n"
     85        );
     86       
     87        for (unsigned int i = 0; i < 0x00040000; i += 0x00001000) {
     88                asm volatile (
     89                        "tlbie %[i]\n"
     90                        :: [i] "r" (i)
     91                );
     92        }
    29293       
    29394        asm volatile (
    294                 "li %[index], 0\n"
    295                 "sync\n"
    296                
    297                 ".rept 64\n"
    298                 "       tlbie %[index]\n"
    299                 "       addi %[index], %[index], 0x1000\n"
    300                 ".endr\n"
    301                
    30295                "eieio\n"
    30396                "tlbsync\n"
    30497                "sync\n"
    305                 : [index] "=r" (index)
    30698        );
    30799}
     
    309101void tlb_invalidate_asid(asid_t asid)
    310102{
    311         uint32_t sdr1 = sdr1_get();
    312        
    313         // FIXME: compute size of PHT exactly
    314         phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000);
    315        
    316         size_t i;
    317         for (i = 0; i < 8192; i++) {
    318                 if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) &&
    319                     (phte[i].vsid < ((asid << 4) + 16)))
    320                         phte[i].v = 0;
    321         }
    322        
    323103        tlb_invalidate_all();
    324104}
     
    326106void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
    327107{
    328         // TODO
    329108        tlb_invalidate_all();
    330109}
  • kernel/arch/sparc64/src/mm/sun4u/as.c

    r5c460cc r864a081  
    4747#include <bitops.h>
    4848#include <macros.h>
     49#include <memstr.h>
    4950
    5051#endif /* CONFIG_TSB */
  • kernel/arch/sparc64/src/mm/sun4u/tlb.c

    r5c460cc r864a081  
    207207
    208208        page_table_lock(AS, true);
    209         t = page_mapping_find(AS, page_16k);
     209        t = page_mapping_find(AS, page_16k, true);
    210210        if (t && PTE_EXECUTABLE(t)) {
    211211                /*
     
    275275
    276276        page_table_lock(AS, true);
    277         t = page_mapping_find(AS, page_16k);
     277        t = page_mapping_find(AS, page_16k, true);
    278278        if (t) {
    279279                /*
     
    319319
    320320        page_table_lock(AS, true);
    321         t = page_mapping_find(AS, page_16k);
     321        t = page_mapping_find(AS, page_16k, true);
    322322        if (t && PTE_WRITABLE(t)) {
    323323                /*
  • kernel/arch/sparc64/src/mm/sun4v/as.c

    r5c460cc r864a081  
    5050#include <bitops.h>
    5151#include <macros.h>
     52#include <memstr.h>
    5253
    5354#endif /* CONFIG_TSB */
  • kernel/arch/sparc64/src/mm/sun4v/tlb.c

    r5c460cc r864a081  
    219219
    220220        page_table_lock(AS, true);
    221         t = page_mapping_find(AS, va);
     221        t = page_mapping_find(AS, va, true);
    222222
    223223        if (t && PTE_EXECUTABLE(t)) {
     
    275275
    276276        page_table_lock(AS, true);
    277         t = page_mapping_find(AS, va);
     277        t = page_mapping_find(AS, va, true);
    278278        if (t) {
    279279                /*
     
    317317
    318318        page_table_lock(AS, true);
    319         t = page_mapping_find(AS, va);
     319        t = page_mapping_find(AS, va, true);
    320320        if (t && PTE_WRITABLE(t)) {
    321321                /*
  • kernel/genarch/include/mm/page_pt.h

    r5c460cc r864a081  
    129129
    130130extern void page_mapping_insert_pt(as_t *, uintptr_t, uintptr_t, unsigned int);
    131 extern pte_t *page_mapping_find_pt(as_t *, uintptr_t);
     131extern pte_t *page_mapping_find_pt(as_t *, uintptr_t, bool);
    132132
    133133#endif
  • kernel/genarch/src/drivers/ega/ega.c

    r5c460cc r864a081  
    4141#include <mm/slab.h>
    4242#include <arch/mm/page.h>
    43 #include <synch/spinlock.h>
    4443#include <typedefs.h>
    4544#include <arch/asm.h>
  • kernel/genarch/src/mm/page_ht.c

    r5c460cc r864a081  
    5858static void ht_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    5959static void ht_mapping_remove(as_t *, uintptr_t);
    60 static pte_t *ht_mapping_find(as_t *, uintptr_t);
     60static pte_t *ht_mapping_find(as_t *, uintptr_t, bool);
    6161
    6262/**
     
    214214 * this call visible.
    215215 *
    216  * @param as   Address space to wich page belongs.
     216 * @param as   Address space to which page belongs.
    217217 * @param page Virtual address of the page to be demapped.
    218218 *
     
    237237/** Find mapping for virtual page in page hash table.
    238238 *
    239  * Find mapping for virtual page.
    240  *
    241  * @param as   Address space to wich page belongs.
    242  * @param page Virtual page.
     239 * @param as     Address space to which page belongs.
     240 * @param page   Virtual page.
     241 * @param nolock True if the page tables need not be locked.
    243242 *
    244243 * @return NULL if there is no such mapping; requested mapping otherwise.
    245244 *
    246245 */
    247 pte_t *ht_mapping_find(as_t *as, uintptr_t page)
     246pte_t *ht_mapping_find(as_t *as, uintptr_t page, bool nolock)
    248247{
    249248        sysarg_t key[2] = {
     
    252251        };
    253252
    254         ASSERT(page_table_locked(as));
     253        ASSERT(nolock || page_table_locked(as));
    255254       
    256255        link_t *cur = hash_table_find(&page_ht, key);
  • kernel/genarch/src/mm/page_pt.c

    r5c460cc r864a081  
    4848static void pt_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    4949static void pt_mapping_remove(as_t *, uintptr_t);
    50 static pte_t *pt_mapping_find(as_t *, uintptr_t);
     50static pte_t *pt_mapping_find(as_t *, uintptr_t, bool);
    5151
    5252page_mapping_operations_t pt_mapping_operations = {
     
    238238/** Find mapping for virtual page in hierarchical page tables.
    239239 *
    240  * Find mapping for virtual page.
    241  *
    242  * @param as   Address space to which page belongs.
    243  * @param page Virtual page.
     240 * @param as     Address space to which page belongs.
     241 * @param page   Virtual page.
     242 * @param nolock True if the page tables need not be locked.
    244243 *
    245244 * @return NULL if there is no such mapping; entry from PTL3 describing
     
    247246 *
    248247 */
    249 pte_t *pt_mapping_find(as_t *as, uintptr_t page)
     248pte_t *pt_mapping_find(as_t *as, uintptr_t page, bool nolock)
    250249{
    251         ASSERT(page_table_locked(as));
     250        ASSERT(nolock || page_table_locked(as));
    252251
    253252        pte_t *ptl0 = (pte_t *) PA2KA((uintptr_t) as->genarch.page_table);
  • kernel/generic/include/mm/page.h

    r5c460cc r864a081  
    3838#include <typedefs.h>
    3939#include <mm/as.h>
    40 #include <memstr.h>
     40#include <arch/mm/page.h>
     41
     42#define P2SZ(pages) \
     43        ((pages) << PAGE_WIDTH)
    4144
    4245/** Operations to manipulate page mappings. */
     
    4447        void (* mapping_insert)(as_t *, uintptr_t, uintptr_t, unsigned int);
    4548        void (* mapping_remove)(as_t *, uintptr_t);
    46         pte_t *(* mapping_find)(as_t *, uintptr_t);
     49        pte_t *(* mapping_find)(as_t *, uintptr_t, bool);
    4750} page_mapping_operations_t;
    4851
     
    5558extern void page_mapping_insert(as_t *, uintptr_t, uintptr_t, unsigned int);
    5659extern void page_mapping_remove(as_t *, uintptr_t);
    57 extern pte_t *page_mapping_find(as_t *, uintptr_t);
     60extern pte_t *page_mapping_find(as_t *, uintptr_t, bool);
    5861extern pte_t *page_table_create(unsigned int);
    5962extern void page_table_destroy(pte_t *);
  • kernel/generic/include/mm/tlb.h

    r5c460cc r864a081  
    8686extern void tlb_invalidate_asid(asid_t);
    8787extern void tlb_invalidate_pages(asid_t, uintptr_t, size_t);
     88
    8889#endif
    8990
  • kernel/generic/src/console/console.c

    r5c460cc r864a081  
    6060
    6161/** Kernel log initialized */
    62 static bool klog_inited = false;
     62static atomic_t klog_inited = {false};
    6363
    6464/** First kernel log characters */
     
    7575
    7676/** Kernel log spinlock */
    77 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "*klog_lock");
     77SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    7878
    7979/** Physical memory area used for klog buffer */
     
    166166       
    167167        event_set_unmask_callback(EVENT_KLOG, klog_update);
    168        
    169         spinlock_lock(&klog_lock);
    170         klog_inited = true;
    171         spinlock_unlock(&klog_lock);
     168        atomic_set(&klog_inited, true);
    172169}
    173170
     
    264261void klog_update(void)
    265262{
     263        if (!atomic_get(&klog_inited))
     264                return;
     265       
    266266        spinlock_lock(&klog_lock);
    267267       
    268         if ((klog_inited) && (klog_uspace > 0)) {
     268        if (klog_uspace > 0) {
    269269                if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    270270                    klog_uspace) == EOK)
     
    277277void putchar(const wchar_t ch)
    278278{
     279        bool ordy = ((stdout) && (stdout->op->write));
     280       
    279281        spinlock_lock(&klog_lock);
    280282       
    281         if ((klog_stored > 0) && (stdout) && (stdout->op->write)) {
    282                 /* Print charaters stored in kernel log */
    283                 size_t i;
    284                 for (i = klog_len - klog_stored; i < klog_len; i++)
    285                         stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
    286                 klog_stored = 0;
     283        /* Print charaters stored in kernel log */
     284        if (ordy) {
     285                while (klog_stored > 0) {
     286                        wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
     287                        klog_stored--;
     288                       
     289                        /*
     290                         * We need to give up the spinlock for
     291                         * the physical operation of writting out
     292                         * the character.
     293                         */
     294                        spinlock_unlock(&klog_lock);
     295                        stdout->op->write(stdout, tmp, silent);
     296                        spinlock_lock(&klog_lock);
     297                }
    287298        }
    288299       
     
    294305                klog_start = (klog_start + 1) % KLOG_LENGTH;
    295306       
    296         if ((stdout) && (stdout->op->write))
     307        if (!ordy) {
     308                if (klog_stored < klog_len)
     309                        klog_stored++;
     310        }
     311       
     312        /* The character is stored for uspace */
     313        if (klog_uspace < klog_len)
     314                klog_uspace++;
     315       
     316        spinlock_unlock(&klog_lock);
     317       
     318        if (ordy) {
     319                /*
     320                 * Output the character. In this case
     321                 * it should be no longer buffered.
     322                 */
    297323                stdout->op->write(stdout, ch, silent);
    298         else {
     324        } else {
    299325                /*
    300326                 * No standard output routine defined yet.
     
    306332                 * Note that the early_putc() function might be
    307333                 * a no-op on certain hardware configurations.
    308                  *
    309334                 */
    310335                early_putchar(ch);
    311                
    312                 if (klog_stored < klog_len)
    313                         klog_stored++;
    314         }
    315        
    316         /* The character is stored for uspace */
    317         if (klog_uspace < klog_len)
    318                 klog_uspace++;
    319        
    320         spinlock_unlock(&klog_lock);
     336        }
    321337       
    322338        /* Force notification on newline */
  • kernel/generic/src/mm/as.c

    r5c460cc r864a081  
    302302         * We don't want any area to have conflicts with NULL page.
    303303         */
    304         if (overlaps(addr, count << PAGE_WIDTH, (uintptr_t) NULL, PAGE_SIZE))
     304        if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))
    305305                return false;
    306306       
     
    329329                        mutex_lock(&area->lock);
    330330                       
    331                         if (overlaps(addr, count << PAGE_WIDTH,
    332                             area->base, area->pages << PAGE_WIDTH)) {
     331                        if (overlaps(addr, P2SZ(count), area->base,
     332                            P2SZ(area->pages))) {
    333333                                mutex_unlock(&area->lock);
    334334                                return false;
     
    346346                        mutex_lock(&area->lock);
    347347                       
    348                         if (overlaps(addr, count << PAGE_WIDTH,
    349                             area->base, area->pages << PAGE_WIDTH)) {
     348                        if (overlaps(addr, P2SZ(count), area->base,
     349                            P2SZ(area->pages))) {
    350350                                mutex_unlock(&area->lock);
    351351                                return false;
     
    366366                mutex_lock(&area->lock);
    367367               
    368                 if (overlaps(addr, count << PAGE_WIDTH,
    369                     area->base, area->pages << PAGE_WIDTH)) {
     368                if (overlaps(addr, P2SZ(count), area->base,
     369                    P2SZ(area->pages))) {
    370370                        mutex_unlock(&area->lock);
    371371                        return false;
     
    380380         */
    381381        if (!KERNEL_ADDRESS_SPACE_SHADOWED) {
    382                 return !overlaps(addr, count << PAGE_WIDTH,
    383                     KERNEL_ADDRESS_SPACE_START,
     382                return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START,
    384383                    KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START);
    385384        }
     
    474473       
    475474        btree_node_t *leaf;
    476         as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);
     475        as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va,
     476            &leaf);
    477477        if (area) {
    478478                /* va is the base address of an address space area */
     
    495495                mutex_lock(&area->lock);
    496496
    497                 size_t size = area->pages << PAGE_WIDTH;
    498                 if ((area->base <= va) && (va <= area->base + (size - 1)))
     497                if ((area->base <= va) &&
     498                    (va <= area->base + (P2SZ(area->pages) - 1)))
    499499                        return area;
    500500               
     
    506506         * Because of its position in the B+tree, it must have base < va.
    507507         */
    508         btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf);
     508        btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree,
     509            leaf);
    509510        if (lnode) {
    510511                area = (as_area_t *) lnode->value[lnode->keys - 1];
     
    512513                mutex_lock(&area->lock);
    513514               
    514                 if (va < area->base + (area->pages << PAGE_WIDTH))
     515                if (va <= area->base + (P2SZ(area->pages) - 1))
    515516                        return area;
    516517               
     
    577578       
    578579        if (pages < area->pages) {
    579                 uintptr_t start_free = area->base + (pages << PAGE_WIDTH);
     580                uintptr_t start_free = area->base + P2SZ(pages);
    580581               
    581582                /*
     
    590591                 */
    591592                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    592                     area->base + (pages << PAGE_WIDTH), area->pages - pages);
     593                    area->base + P2SZ(pages), area->pages - pages);
    593594               
    594595                /*
     
    613614                                size_t i = 0;
    614615                               
    615                                 if (overlaps(ptr, size << PAGE_WIDTH, area->base,
    616                                     pages << PAGE_WIDTH)) {
     616                                if (overlaps(ptr, P2SZ(size), area->base,
     617                                    P2SZ(pages))) {
    617618                                       
    618                                         if (ptr + (size << PAGE_WIDTH) <= start_free) {
     619                                        if (ptr + P2SZ(size) <= start_free) {
    619620                                                /*
    620621                                                 * The whole interval fits
     
    647648                               
    648649                                for (; i < size; i++) {
    649                                         pte_t *pte = page_mapping_find(as, ptr +
    650                                             (i << PAGE_WIDTH));
     650                                        pte_t *pte = page_mapping_find(as,
     651                                            ptr + P2SZ(i), false);
    651652                                       
    652653                                        ASSERT(pte);
     
    657658                                            (area->backend->frame_free)) {
    658659                                                area->backend->frame_free(area,
    659                                                     ptr + (i << PAGE_WIDTH),
     660                                                    ptr + P2SZ(i),
    660661                                                    PTE_GET_FRAME(pte));
    661662                                        }
    662663                                       
    663                                         page_mapping_remove(as, ptr +
    664                                             (i << PAGE_WIDTH));
     664                                        page_mapping_remove(as, ptr + P2SZ(i));
    665665                                }
    666666                        }
     
    671671                 */
    672672               
    673                 tlb_invalidate_pages(as->asid, area->base + (pages << PAGE_WIDTH),
     673                tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
    674674                    area->pages - pages);
    675675               
    676676                /*
    677                  * Invalidate software translation caches (e.g. TSB on sparc64).
    678                  */
    679                 as_invalidate_translation_cache(as, area->base +
    680                     (pages << PAGE_WIDTH), area->pages - pages);
     677                 * Invalidate software translation caches
     678                 * (e.g. TSB on sparc64, PHT on ppc32).
     679                 */
     680                as_invalidate_translation_cache(as, area->base + P2SZ(pages),
     681                    area->pages - pages);
    681682                tlb_shootdown_finalize(ipl);
    682683               
     
    797798                       
    798799                        for (size = 0; size < (size_t) node->value[i]; size++) {
    799                                 pte_t *pte =
    800                                     page_mapping_find(as, ptr + (size << PAGE_WIDTH));
     800                                pte_t *pte = page_mapping_find(as,
     801                                     ptr + P2SZ(size), false);
    801802                               
    802803                                ASSERT(pte);
     
    807808                                    (area->backend->frame_free)) {
    808809                                        area->backend->frame_free(area,
    809                                             ptr + (size << PAGE_WIDTH), PTE_GET_FRAME(pte));
     810                                            ptr + P2SZ(size),
     811                                            PTE_GET_FRAME(pte));
    810812                                }
    811813                               
    812                                 page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
     814                                page_mapping_remove(as, ptr + P2SZ(size));
    813815                        }
    814816                }
     
    822824       
    823825        /*
    824          * Invalidate potential software translation caches (e.g. TSB on
    825          * sparc64).
     826         * Invalidate potential software translation caches
     827         * (e.g. TSB on sparc64, PHT on ppc32).
    826828         */
    827829        as_invalidate_translation_cache(as, area->base, area->pages);
     
    897899        }
    898900       
    899         size_t src_size = src_area->pages << PAGE_WIDTH;
     901        size_t src_size = P2SZ(src_area->pages);
    900902        unsigned int src_flags = src_area->flags;
    901903        mem_backend_t *src_backend = src_area->backend;
     
    10941096        for (cur = area->used_space.leaf_head.next;
    10951097            cur != &area->used_space.leaf_head; cur = cur->next) {
    1096                 btree_node_t *node
    1097                     = list_get_instance(cur, btree_node_t, leaf_link);
     1098                btree_node_t *node = list_get_instance(cur, btree_node_t,
     1099                    leaf_link);
    10981100                btree_key_t i;
    10991101               
     
    11031105                       
    11041106                        for (size = 0; size < (size_t) node->value[i]; size++) {
    1105                                 pte_t *pte =
    1106                                     page_mapping_find(as, ptr + (size << PAGE_WIDTH));
     1107                                pte_t *pte = page_mapping_find(as,
     1108                                    ptr + P2SZ(size), false);
    11071109                               
    11081110                                ASSERT(pte);
     
    11131115                               
    11141116                                /* Remove old mapping */
    1115                                 page_mapping_remove(as, ptr + (size << PAGE_WIDTH));
     1117                                page_mapping_remove(as, ptr + P2SZ(size));
    11161118                        }
    11171119                }
     
    11251127       
    11261128        /*
    1127          * Invalidate potential software translation caches (e.g. TSB on
    1128          * sparc64).
     1129         * Invalidate potential software translation caches
     1130         * (e.g. TSB on sparc64, PHT on ppc32).
    11291131         */
    11301132        as_invalidate_translation_cache(as, area->base, area->pages);
     
    11591161                               
    11601162                                /* Insert the new mapping */
    1161                                 page_mapping_insert(as, ptr + (size << PAGE_WIDTH),
     1163                                page_mapping_insert(as, ptr + P2SZ(size),
    11621164                                    old_frame[frame_idx++], page_flags);
    11631165                               
     
    12401242         */
    12411243        pte_t *pte;
    1242         if ((pte = page_mapping_find(AS, page))) {
     1244        if ((pte = page_mapping_find(AS, page, false))) {
    12431245                if (PTE_PRESENT(pte)) {
    12441246                        if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) ||
     
    14811483       
    14821484        if (src_area) {
    1483                 size = src_area->pages << PAGE_WIDTH;
     1485                size = P2SZ(src_area->pages);
    14841486                mutex_unlock(&src_area->lock);
    14851487        } else
     
    15361538                if (page >= right_pg) {
    15371539                        /* Do nothing. */
    1538                 } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1539                     left_cnt << PAGE_WIDTH)) {
     1540                } else if (overlaps(page, P2SZ(count), left_pg,
     1541                    P2SZ(left_cnt))) {
    15401542                        /* The interval intersects with the left interval. */
    15411543                        return false;
    1542                 } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1543                     right_cnt << PAGE_WIDTH)) {
     1544                } else if (overlaps(page, P2SZ(count), right_pg,
     1545                    P2SZ(right_cnt))) {
    15441546                        /* The interval intersects with the right interval. */
    15451547                        return false;
    1546                 } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1547                     (page + (count << PAGE_WIDTH) == right_pg)) {
     1548                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1549                    (page + P2SZ(count) == right_pg)) {
    15481550                        /*
    15491551                         * The interval can be added by merging the two already
     
    15531555                        btree_remove(&area->used_space, right_pg, leaf);
    15541556                        goto success;
    1555                 } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1557                } else if (page == left_pg + P2SZ(left_cnt)) {
    15561558                        /*
    15571559                         * The interval can be added by simply growing the left
     
    15601562                        node->value[node->keys - 1] += count;
    15611563                        goto success;
    1562                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1564                } else if (page + P2SZ(count) == right_pg) {
    15631565                        /*
    15641566                         * The interval can be addded by simply moving base of
     
    15871589                 */
    15881590               
    1589                 if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1590                     right_cnt << PAGE_WIDTH)) {
     1591                if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) {
    15911592                        /* The interval intersects with the right interval. */
    15921593                        return false;
    1593                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1594                } else if (page + P2SZ(count) == right_pg) {
    15941595                        /*
    15951596                         * The interval can be added by moving the base of the
     
    16261627                if (page < left_pg) {
    16271628                        /* Do nothing. */
    1628                 } else if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1629                     left_cnt << PAGE_WIDTH)) {
     1629                } else if (overlaps(page, P2SZ(count), left_pg,
     1630                    P2SZ(left_cnt))) {
    16301631                        /* The interval intersects with the left interval. */
    16311632                        return false;
    1632                 } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1633                     right_cnt << PAGE_WIDTH)) {
     1633                } else if (overlaps(page, P2SZ(count), right_pg,
     1634                    P2SZ(right_cnt))) {
    16341635                        /* The interval intersects with the right interval. */
    16351636                        return false;
    1636                 } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1637                     (page + (count << PAGE_WIDTH) == right_pg)) {
     1637                } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1638                    (page + P2SZ(count) == right_pg)) {
    16381639                        /*
    16391640                         * The interval can be added by merging the two already
     
    16431644                        btree_remove(&area->used_space, right_pg, node);
    16441645                        goto success;
    1645                 } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1646                } else if (page == left_pg + P2SZ(left_cnt)) {
    16461647                        /*
    16471648                         * The interval can be added by simply growing the left
     
    16501651                        leaf->value[leaf->keys - 1] += count;
    16511652                        goto success;
    1652                 } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1653                } else if (page + P2SZ(count) == right_pg) {
    16531654                        /*
    16541655                         * The interval can be addded by simply moving base of
     
    16771678                 */
    16781679               
    1679                 if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1680                     left_cnt << PAGE_WIDTH)) {
     1680                if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) {
    16811681                        /* The interval intersects with the left interval. */
    16821682                        return false;
    1683                 } else if (left_pg + (left_cnt << PAGE_WIDTH) == page) {
     1683                } else if (left_pg + P2SZ(left_cnt) == page) {
    16841684                        /*
    16851685                         * The interval can be added by growing the left
     
    17161716                         */
    17171717                       
    1718                         if (overlaps(page, count << PAGE_WIDTH, left_pg,
    1719                             left_cnt << PAGE_WIDTH)) {
     1718                        if (overlaps(page, P2SZ(count), left_pg,
     1719                            P2SZ(left_cnt))) {
    17201720                                /*
    17211721                                 * The interval intersects with the left
     
    17231723                                 */
    17241724                                return false;
    1725                         } else if (overlaps(page, count << PAGE_WIDTH, right_pg,
    1726                             right_cnt << PAGE_WIDTH)) {
     1725                        } else if (overlaps(page, P2SZ(count), right_pg,
     1726                            P2SZ(right_cnt))) {
    17271727                                /*
    17281728                                 * The interval intersects with the right
     
    17301730                                 */
    17311731                                return false;
    1732                         } else if ((page == left_pg + (left_cnt << PAGE_WIDTH)) &&
    1733                             (page + (count << PAGE_WIDTH) == right_pg)) {
     1732                        } else if ((page == left_pg + P2SZ(left_cnt)) &&
     1733                            (page + P2SZ(count) == right_pg)) {
    17341734                                /*
    17351735                                 * The interval can be added by merging the two
     
    17391739                                btree_remove(&area->used_space, right_pg, leaf);
    17401740                                goto success;
    1741                         } else if (page == left_pg + (left_cnt << PAGE_WIDTH)) {
     1741                        } else if (page == left_pg + P2SZ(left_cnt)) {
    17421742                                /*
    17431743                                 * The interval can be added by simply growing
     
    17461746                                leaf->value[i - 1] += count;
    17471747                                goto success;
    1748                         } else if (page + (count << PAGE_WIDTH) == right_pg) {
     1748                        } else if (page + P2SZ(count) == right_pg) {
    17491749                                /*
    17501750                                 * The interval can be addded by simply moving
     
    18121812                        for (i = 0; i < leaf->keys; i++) {
    18131813                                if (leaf->key[i] == page) {
    1814                                         leaf->key[i] += count << PAGE_WIDTH;
     1814                                        leaf->key[i] += P2SZ(count);
    18151815                                        leaf->value[i] -= count;
    18161816                                        goto success;
     
    18221822        }
    18231823       
    1824         btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf);
     1824        btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space,
     1825            leaf);
    18251826        if ((node) && (page < leaf->key[0])) {
    18261827                uintptr_t left_pg = node->key[node->keys - 1];
    18271828                size_t left_cnt = (size_t) node->value[node->keys - 1];
    18281829               
    1829                 if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
    1830                     count << PAGE_WIDTH)) {
    1831                         if (page + (count << PAGE_WIDTH) ==
    1832                             left_pg + (left_cnt << PAGE_WIDTH)) {
     1830                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1831                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18331832                                /*
    18341833                                 * The interval is contained in the rightmost
     
    18391838                                node->value[node->keys - 1] -= count;
    18401839                                goto success;
    1841                         } else if (page + (count << PAGE_WIDTH) <
    1842                             left_pg + (left_cnt << PAGE_WIDTH)) {
     1840                        } else if (page + P2SZ(count) <
     1841                            left_pg + P2SZ(left_cnt)) {
     1842                                size_t new_cnt;
     1843
    18431844                                /*
    18441845                                 * The interval is contained in the rightmost
     
    18481849                                 * new interval.
    18491850                                 */
    1850                                 size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
    1851                                     (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
     1851                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1852                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18521853                                node->value[node->keys - 1] -= count + new_cnt;
    18531854                                btree_insert(&area->used_space, page +
    1854                                     (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1855                                    P2SZ(count), (void *) new_cnt, leaf);
    18551856                                goto success;
    18561857                        }
     
    18651866                size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
    18661867               
    1867                 if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
    1868                     count << PAGE_WIDTH)) {
    1869                         if (page + (count << PAGE_WIDTH) ==
    1870                             left_pg + (left_cnt << PAGE_WIDTH)) {
     1868                if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) {
     1869                        if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) {
    18711870                                /*
    18721871                                 * The interval is contained in the rightmost
     
    18761875                                leaf->value[leaf->keys - 1] -= count;
    18771876                                goto success;
    1878                         } else if (page + (count << PAGE_WIDTH) < left_pg +
    1879                             (left_cnt << PAGE_WIDTH)) {
     1877                        } else if (page + P2SZ(count) < left_pg +
     1878                            P2SZ(left_cnt)) {
     1879                                size_t new_cnt;
     1880
    18801881                                /*
    18811882                                 * The interval is contained in the rightmost
     
    18851886                                 * interval.
    18861887                                 */
    1887                                 size_t new_cnt = ((left_pg + (left_cnt << PAGE_WIDTH)) -
    1888                                     (page + (count << PAGE_WIDTH))) >> PAGE_WIDTH;
     1888                                new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1889                                    (page + P2SZ(count))) >> PAGE_WIDTH;
    18891890                                leaf->value[leaf->keys - 1] -= count + new_cnt;
    18901891                                btree_insert(&area->used_space, page +
    1891                                     (count << PAGE_WIDTH), (void *) new_cnt, leaf);
     1892                                    P2SZ(count), (void *) new_cnt, leaf);
    18921893                                goto success;
    18931894                        }
     
    19111912                         * to (i - 1) and i.
    19121913                         */
    1913                         if (overlaps(left_pg, left_cnt << PAGE_WIDTH, page,
    1914                             count << PAGE_WIDTH)) {
    1915                                 if (page + (count << PAGE_WIDTH) ==
    1916                                     left_pg + (left_cnt << PAGE_WIDTH)) {
     1914                        if (overlaps(left_pg, P2SZ(left_cnt), page,
     1915                            P2SZ(count))) {
     1916                                if (page + P2SZ(count) ==
     1917                                    left_pg + P2SZ(left_cnt)) {
    19171918                                        /*
    19181919                                         * The interval is contained in the
     
    19231924                                        leaf->value[i - 1] -= count;
    19241925                                        goto success;
    1925                                 } else if (page + (count << PAGE_WIDTH) <
    1926                                     left_pg + (left_cnt << PAGE_WIDTH)) {
     1926                                } else if (page + P2SZ(count) <
     1927                                    left_pg + P2SZ(left_cnt)) {
     1928                                        size_t new_cnt;
     1929
    19271930                                        /*
    19281931                                         * The interval is contained in the
     
    19321935                                         * also inserting a new interval.
    19331936                                         */
    1934                                         size_t new_cnt = ((left_pg +
    1935                                             (left_cnt << PAGE_WIDTH)) -
    1936                                             (page + (count << PAGE_WIDTH))) >>
     1937                                        new_cnt = ((left_pg + P2SZ(left_cnt)) -
     1938                                            (page + P2SZ(count))) >>
    19371939                                            PAGE_WIDTH;
    19381940                                        leaf->value[i - 1] -= count + new_cnt;
    19391941                                        btree_insert(&area->used_space, page +
    1940                                             (count << PAGE_WIDTH), (void *) new_cnt,
     1942                                            P2SZ(count), (void *) new_cnt,
    19411943                                            leaf);
    19421944                                        goto success;
     
    20342036                btree_key_t i;
    20352037                for (i = 0; (ret == 0) && (i < node->keys); i++) {
     2038                        uintptr_t addr;
     2039
    20362040                        as_area_t *area = (as_area_t *) node->value[i];
    20372041                       
    20382042                        mutex_lock(&area->lock);
    20392043                       
    2040                         uintptr_t addr =
    2041                             ALIGN_UP(area->base + (area->pages << PAGE_WIDTH),
     2044                        addr = ALIGN_UP(area->base + P2SZ(area->pages),
    20422045                            PAGE_SIZE);
    20432046                       
     
    20982101                       
    20992102                        info[area_idx].start_addr = area->base;
    2100                         info[area_idx].size = FRAMES2SIZE(area->pages);
     2103                        info[area_idx].size = P2SZ(area->pages);
    21012104                        info[area_idx].flags = area->flags;
    21022105                        ++area_idx;
     
    21362139                            " (%p - %p)\n", area, (void *) area->base,
    21372140                            area->pages, (void *) area->base,
    2138                             (void *) (area->base + FRAMES2SIZE(area->pages)));
     2141                            (void *) (area->base + P2SZ(area->pages)));
    21392142                        mutex_unlock(&area->lock);
    21402143                }
  • kernel/generic/src/mm/backend_anon.c

    r5c460cc r864a081  
    5050#include <typedefs.h>
    5151#include <align.h>
     52#include <memstr.h>
    5253#include <arch.h>
    5354
     
    121122                                page_table_lock(area->as, false);
    122123                                pte = page_mapping_find(area->as,
    123                                     base + j * PAGE_SIZE);
     124                                    base + P2SZ(j), false);
    124125                                ASSERT(pte && PTE_VALID(pte) &&
    125126                                    PTE_PRESENT(pte));
    126127                                btree_insert(&area->sh_info->pagemap,
    127                                     (base + j * PAGE_SIZE) - area->base,
     128                                    (base + P2SZ(j)) - area->base,
    128129                                    (void *) PTE_GET_FRAME(pte), NULL);
    129130                                page_table_unlock(area->as, false);
  • kernel/generic/src/mm/backend_elf.c

    r5c460cc r864a081  
    170170                        if (!(area->flags & AS_AREA_WRITE))
    171171                                if (base >= entry->p_vaddr &&
    172                                     base + count * PAGE_SIZE <= start_anon)
     172                                    base + P2SZ(count) <= start_anon)
    173173                                        continue;
    174174                       
     
    182182                                if (!(area->flags & AS_AREA_WRITE))
    183183                                        if (base >= entry->p_vaddr &&
    184                                             base + (j + 1) * PAGE_SIZE <=
    185                                             start_anon)
     184                                            base + P2SZ(j + 1) <= start_anon)
    186185                                                continue;
    187186                               
    188187                                page_table_lock(area->as, false);
    189188                                pte = page_mapping_find(area->as,
    190                                     base + j * PAGE_SIZE);
     189                                    base + P2SZ(j), false);
    191190                                ASSERT(pte && PTE_VALID(pte) &&
    192191                                    PTE_PRESENT(pte));
    193192                                btree_insert(&area->sh_info->pagemap,
    194                                     (base + j * PAGE_SIZE) - area->base,
     193                                    (base + P2SZ(j)) - area->base,
    195194                                    (void *) PTE_GET_FRAME(pte), NULL);
    196195                                page_table_unlock(area->as, false);
  • kernel/generic/src/mm/page.c

    r5c460cc r864a081  
    108108 * using flags. Allocate and setup any missing page tables.
    109109 *
    110  * @param as    Address space to wich page belongs.
     110 * @param as    Address space to which page belongs.
    111111 * @param page  Virtual address of the page to be mapped.
    112112 * @param frame Physical address of memory frame to which the mapping is
     
    135135 * this call visible.
    136136 *
    137  * @param as   Address space to wich page belongs.
     137 * @param as   Address space to which page belongs.
    138138 * @param page Virtual address of the page to be demapped.
    139139 *
     
    152152}
    153153
    154 /** Find mapping for virtual page
     154/** Find mapping for virtual page.
    155155 *
    156  * Find mapping for virtual page.
    157  *
    158  * @param as   Address space to wich page belongs.
    159  * @param page Virtual page.
     156 * @param as     Address space to which page belongs.
     157 * @param page   Virtual page.
     158 * @param nolock True if the page tables need not be locked.
    160159 *
    161160 * @return NULL if there is no such mapping; requested mapping
     
    163162 *
    164163 */
    165 NO_TRACE pte_t *page_mapping_find(as_t *as, uintptr_t page)
     164NO_TRACE pte_t *page_mapping_find(as_t *as, uintptr_t page, bool nolock)
    166165{
    167         ASSERT(page_table_locked(as));
     166        ASSERT(nolock || page_table_locked(as));
    168167       
    169168        ASSERT(page_mapping_operations);
    170169        ASSERT(page_mapping_operations->mapping_find);
    171170       
    172         return page_mapping_operations->mapping_find(as, page);
     171        return page_mapping_operations->mapping_find(as, page, nolock);
    173172}
    174173
  • kernel/generic/src/printf/vprintf.c

    r5c460cc r864a081  
    4141#include <typedefs.h>
    4242#include <str.h>
    43 
    44 IRQ_SPINLOCK_STATIC_INITIALIZE_NAME(printf_lock, "*printf_lock");
    4543
    4644static int vprintf_str_write(const char *str, size_t size, void *data)
     
    9391        };
    9492       
    95         irq_spinlock_lock(&printf_lock, true);
    96         int ret = printf_core(fmt, &ps, ap);
    97         irq_spinlock_unlock(&printf_lock, true);
    98        
    99         return ret;
     93        return printf_core(fmt, &ps, ap);
    10094}
    10195
  • kernel/generic/src/synch/futex.c

    r5c460cc r864a081  
    119119         */
    120120        page_table_lock(AS, true);
    121         t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
     121        t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), false);
    122122        if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
    123123                page_table_unlock(AS, true);
     
    155155         */
    156156        page_table_lock(AS, true);
    157         t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE));
     157        t = page_mapping_find(AS, ALIGN_DOWN(uaddr, PAGE_SIZE), false);
    158158        if (!t || !PTE_VALID(t) || !PTE_PRESENT(t)) {
    159159                page_table_unlock(AS, true);
  • kernel/generic/src/synch/spinlock.c

    r5c460cc r864a081  
    9696                 * run in a simulator) that caused problems with both
    9797                 * printf_lock and the framebuffer lock.
    98                  *
    9998                 */
    10099                if (lock->name[0] == '*')
  • kernel/test/mm/mapping1.c

    r5c460cc r864a081  
    3535#include <typedefs.h>
    3636#include <debug.h>
     37#include <arch.h>
    3738
    3839#define PAGE0  0x10000000
     
    5859        *((uint32_t *) frame1) = VALUE1;
    5960       
     61        page_table_lock(AS, true);
     62
    6063        TPRINTF("Mapping virtual address %p to physical address %p.\n",
    6164            (void *) PAGE0, (void *) KA2PA(frame0));
     
    6568            (void *) PAGE1, (void *) KA2PA(frame1));
    6669        page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
     70
     71        page_table_unlock(AS, true);
    6772       
    6873        v0 = *((uint32_t *) PAGE0);
  • uspace/app/tester/mm/common.c

    r5c460cc r864a081  
    135135}
    136136
     137static void check_consistency(const char *loc)
     138{
     139        /* Check heap consistency */
     140        void *prob = heap_check();
     141        if (prob != NULL) {
     142                TPRINTF("\nError: Heap inconsistency at %p in %s.\n",
     143                    prob, loc);
     144                TSTACKTRACE();
     145                error_flag = true;
     146        }
     147}
     148
    137149/** Checked malloc
    138150 *
     
    153165        /* Allocate the chunk of memory */
    154166        data = malloc(size);
     167        check_consistency("checked_malloc");
    155168        if (data == NULL)
    156169                return NULL;
     
    160173                TPRINTF("\nError: Allocated block overlaps with another "
    161174                    "previously allocated block.\n");
     175                TSTACKTRACE();
    162176                error_flag = true;
    163177        }
     
    198212        if (block->addr == NULL) {
    199213                free(block);
     214                check_consistency("alloc_block");
    200215                return NULL;
    201216        }
     
    228243        /* Free the memory */
    229244        free(block->addr);
     245        check_consistency("free_block (a)");
    230246        free(block);
     247        check_consistency("free_block (b)");
    231248}
    232249
     
    257274            pos < end; pos++)
    258275                *pos = block_expected_value(block, pos);
     276       
     277        check_consistency("fill_block");
    259278}
    260279
     
    273292                if (*pos != block_expected_value(block, pos)) {
    274293                        TPRINTF("\nError: Corrupted content of a data block.\n");
     294                        TSTACKTRACE();
    275295                        error_flag = true;
    276296                        return;
     
    296316        if (entry == NULL) {
    297317                TPRINTF("\nError: Corrupted list of allocated memory blocks.\n");
     318                TSTACKTRACE();
    298319                error_flag = true;
    299320        }
     
    325346        if (addr == NULL) {
    326347                free(area);
     348                check_consistency("map_area (a)");
    327349                return NULL;
    328350        }
     
    331353        if (area->addr == (void *) -1) {
    332354                free(area);
     355                check_consistency("map_area (b)");
    333356                return NULL;
    334357        }
     
    361384       
    362385        free(area);
     386        check_consistency("unmap_area");
    363387}
    364388
     
    389413            pos < end; pos++)
    390414                *pos = area_expected_value(area, pos);
    391 }
     415       
     416        check_consistency("fill_area");
     417}
  • uspace/app/tester/mm/malloc1.c

    r5c460cc r864a081  
    241241                                TPRINTF("A");
    242242                                fill_block(blk);
     243                                RETURN_IF_ERROR;
    243244                        }
    244245                       
  • uspace/app/tester/mm/malloc3.c

    r5c460cc r864a081  
    232232                                TPRINTF("A");
    233233                                fill_block(blk);
     234                                RETURN_IF_ERROR;
    234235                               
    235236                                if ((mem_blocks_count % AREA_GRANULARITY) == 0) {
    236237                                        mem_area_t *area = map_area(AREA_SIZE);
    237238                                        RETURN_IF_ERROR;
     239                                       
    238240                                        if (area != NULL) {
    239241                                                TPRINTF("*");
    240242                                                fill_area(area);
     243                                                RETURN_IF_ERROR;
    241244                                        } else
    242245                                                TPRINTF("F(*)");
  • uspace/app/tester/tester.h

    r5c460cc r864a081  
    3838#include <sys/types.h>
    3939#include <bool.h>
     40#include <stacktrace.h>
    4041
    4142#define IPC_TEST_SERVICE  10240
     
    5960                if (!test_quiet) { \
    6061                        fprintf(stderr, (format), ##__VA_ARGS__); \
     62                } \
     63        } while (0)
     64
     65#define TSTACKTRACE() \
     66        do { \
     67                if (!test_quiet) { \
     68                        stacktrace_print(); \
    6169                } \
    6270        } while (0)
  • uspace/lib/c/arch/ppc32/_link.ld.in

    r5c460cc r864a081  
    1010#endif
    1111        data PT_LOAD FLAGS(6);
     12        debug PT_NOTE;
    1213}
    1314
     
    5556        } :data
    5657       
     58#ifdef CONFIG_LINE_DEBUG
     59        .comment 0 : { *(.comment); } :debug
     60        .debug_abbrev 0 : { *(.debug_abbrev); } :debug
     61        .debug_aranges 0 : { *(.debug_aranges); } :debug
     62        .debug_info 0 : { *(.debug_info); } :debug
     63        .debug_line 0 : { *(.debug_line); } :debug
     64        .debug_loc 0 : { *(.debug_loc); } :debug
     65        .debug_pubnames 0 : { *(.debug_pubnames); } :debug
     66        .debug_pubtypes 0 : { *(.debug_pubtypes); } :debug
     67        .debug_ranges 0 : { *(.debug_ranges); } :debug
     68        .debug_str 0 : { *(.debug_str); } :debug
     69#endif
     70       
    5771        /DISCARD/ : {
    5872                *(*);
  • uspace/lib/c/generic/assert.c

    r5c460cc r864a081  
    3333#include <assert.h>
    3434#include <stdio.h>
     35#include <io/klog.h>
    3536#include <stdlib.h>
     37#include <atomic.h>
    3638#include <stacktrace.h>
     39#include <stdint.h>
     40
     41static atomic_t failed_asserts = {0};
    3742
    3843void assert_abort(const char *cond, const char *file, unsigned int line)
    3944{
     45        /*
     46         * Send the message safely to klog. Nested asserts should not occur.
     47         */
     48        klog_printf("Assertion failed (%s) in file \"%s\", line %u.\n",
     49            cond, file, line);
     50       
     51        /*
     52         * Check if this is a nested or parallel assert.
     53         */
     54        if (atomic_postinc(&failed_asserts))
     55                abort();
     56       
     57        /*
     58         * Attempt to print the message to standard output and display
     59         * the stack trace. These operations can theoretically trigger nested
     60         * assertions.
     61         */
    4062        printf("Assertion failed (%s) in file \"%s\", line %u.\n",
    4163            cond, file, line);
    4264        stacktrace_print();
     65       
    4366        abort();
    4467}
  • uspace/lib/c/generic/io/klog.c

    r5c460cc r864a081  
    3838#include <sys/types.h>
    3939#include <unistd.h>
     40#include <errno.h>
    4041#include <io/klog.h>
     42#include <io/printf_core.h>
    4143
    4244size_t klog_write(const void *buf, size_t size)
     
    5557}
    5658
     59/** Print formatted text to klog.
     60 *
     61 * @param fmt Format string
     62 *
     63 * \see For more details about format string see printf_core.
     64 *
     65 */
     66int klog_printf(const char *fmt, ...)
     67{
     68        va_list args;
     69        va_start(args, fmt);
     70       
     71        int ret = klog_vprintf(fmt, args);
     72       
     73        va_end(args);
     74       
     75        return ret;
     76}
     77
     78static int klog_vprintf_str_write(const char *str, size_t size, void *data)
     79{
     80        size_t wr = klog_write(str, size);
     81        return str_nlength(str, wr);
     82}
     83
     84static int klog_vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
     85{
     86        size_t offset = 0;
     87        size_t chars = 0;
     88       
     89        while (offset < size) {
     90                char buf[STR_BOUNDS(1)];
     91                size_t sz = 0;
     92               
     93                if (chr_encode(str[chars], buf, &sz, STR_BOUNDS(1)) == EOK)
     94                        klog_write(buf, sz);
     95               
     96                chars++;
     97                offset += sizeof(wchar_t);
     98        }
     99       
     100        return chars;
     101}
     102
     103/** Print formatted text to klog.
     104 *
     105 * @param fmt Format string
     106 * @param ap  Format parameters
     107 *
     108 * \see For more details about format string see printf_core.
     109 *
     110 */
     111int klog_vprintf(const char *fmt, va_list ap)
     112{
     113        printf_spec_t ps = {
     114                klog_vprintf_str_write,
     115                klog_vprintf_wstr_write,
     116                NULL
     117        };
     118       
     119        return printf_core(fmt, &ps, ap);
     120}
     121
    57122/** @}
    58123 */
  • uspace/lib/c/generic/io/vprintf.c

    r5c460cc r864a081  
    9696/** Print formatted text to stdout.
    9797 *
    98  * @param file Output stream
    99  * @param fmt  Format string
    100  * @param ap   Format parameters
     98 * @param fmt Format string
     99 * @param ap  Format parameters
    101100 *
    102101 * \see For more details about format string see printf_core.
  • uspace/lib/c/generic/malloc.c

    r5c460cc r864a081  
    7979        (sizeof(heap_block_head_t) + sizeof(heap_block_foot_t))
    8080
     81/** Overhead of each area. */
     82#define AREA_OVERHEAD(size) \
     83        (ALIGN_UP(size + sizeof(heap_area_t), BASE_ALIGN))
     84
    8185/** Calculate real size of a heap block.
    8286 *
     
    183187
    184188/** Next heap block to examine (next fit algorithm) */
    185 static heap_block_head_t *next = NULL;
     189static heap_block_head_t *next_fit = NULL;
    186190
    187191/** Futex for thread-safe heap manipulation */
    188192static futex_t malloc_futex = FUTEX_INITIALIZER;
     193
     194#ifndef NDEBUG
     195
     196#define malloc_assert(expr) \
     197        do { \
     198                if (!(expr)) {\
     199                        futex_up(&malloc_futex); \
     200                        assert_abort(#expr, __FILE__, __LINE__); \
     201                } \
     202        } while (0)
     203
     204#else /* NDEBUG */
     205
     206#define malloc_assert(expr)
     207
     208#endif /* NDEBUG */
    189209
    190210/** Initialize a heap block
     
    228248        heap_block_head_t *head = (heap_block_head_t *) addr;
    229249       
    230         assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
     250        malloc_assert(head->magic == HEAP_BLOCK_HEAD_MAGIC);
    231251       
    232252        heap_block_foot_t *foot = BLOCK_FOOT(head);
    233253       
    234         assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
    235         assert(head->size == foot->size);
     254        malloc_assert(foot->magic == HEAP_BLOCK_FOOT_MAGIC);
     255        malloc_assert(head->size == foot->size);
    236256}
    237257
     
    247267        heap_area_t *area = (heap_area_t *) addr;
    248268       
    249         assert(area->magic == HEAP_AREA_MAGIC);
    250         assert(addr == area->start);
    251         assert(area->start < area->end);
    252         assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
    253         assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
     269        malloc_assert(area->magic == HEAP_AREA_MAGIC);
     270        malloc_assert(addr == area->start);
     271        malloc_assert(area->start < area->end);
     272        malloc_assert(((uintptr_t) area->start % PAGE_SIZE) == 0);
     273        malloc_assert(((uintptr_t) area->end % PAGE_SIZE) == 0);
    254274}
    255275
     
    362382       
    363383        /* Eventually try to create a new area */
    364         return area_create(AREA_FIRST_BLOCK_HEAD(size));
     384        return area_create(AREA_OVERHEAD(size));
    365385}
    366386
     
    382402       
    383403        block_check((void *) last_head);
    384         assert(last_head->area == area);
     404        malloc_assert(last_head->area == area);
    385405       
    386406        if (last_head->free) {
     
    395415               
    396416                block_check((void *) first_head);
    397                 assert(first_head->area == area);
     417                malloc_assert(first_head->area == area);
    398418               
    399419                size_t shrink_size = ALIGN_DOWN(last_head->size, PAGE_SIZE);
     
    439459                        /* Update heap area parameters */
    440460                        area->end = end;
    441                        
    442                         /* Update block layout */
    443                         void *last = (void *) last_head;
    444                         size_t excess = (size_t) (area->end - last);
     461                        size_t excess = ((size_t) area->end) - ((size_t) last_head);
    445462                       
    446463                        if (excess > 0) {
     
    451468                                         * create a new free block.
    452469                                         */
    453                                         block_init(last, excess, true, area);
     470                                        block_init((void *) last_head, excess, true, area);
    454471                                } else {
    455472                                        /*
     
    470487        }
    471488       
    472         next = NULL;
     489        next_fit = NULL;
    473490}
    474491
     
    497514static void split_mark(heap_block_head_t *cur, const size_t size)
    498515{
    499         assert(cur->size >= size);
     516        malloc_assert(cur->size >= size);
    500517       
    501518        /* See if we should split the block. */
     
    533550{
    534551        area_check((void *) area);
    535         assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    536         assert((void *) first_block < area->end);
     552        malloc_assert((void *) first_block >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     553        malloc_assert((void *) first_block < area->end);
    537554       
    538555        for (heap_block_head_t *cur = first_block; (void *) cur < area->end;
     
    559576                                split_mark(cur, real_size);
    560577                               
    561                                 next = cur;
     578                                next_fit = cur;
    562579                                return addr;
    563580                        } else {
     
    611628                                                split_mark(next_head, real_size);
    612629                                               
    613                                                 next = next_head;
     630                                                next_fit = next_head;
    614631                                                return aligned;
    615632                                        } else {
     
    637654                                                        split_mark(cur, real_size);
    638655                                                       
    639                                                         next = cur;
     656                                                        next_fit = cur;
    640657                                                        return aligned;
    641658                                                }
     
    661678static void *malloc_internal(const size_t size, const size_t align)
    662679{
    663         assert(first_heap_area != NULL);
     680        malloc_assert(first_heap_area != NULL);
    664681       
    665682        if (align == 0)
     
    675692       
    676693        /* Try the next fit approach */
    677         split = next;
     694        split = next_fit;
    678695       
    679696        if (split != NULL) {
     
    786803       
    787804        block_check(head);
    788         assert(!head->free);
     805        malloc_assert(!head->free);
    789806       
    790807        heap_area_t *area = head->area;
    791808       
    792809        area_check(area);
    793         assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    794         assert((void *) head < area->end);
     810        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     811        malloc_assert((void *) head < area->end);
    795812       
    796813        void *ptr = NULL;
     
    831848                       
    832849                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    833                         next = NULL;
     850                        next_fit = NULL;
    834851                } else
    835852                        reloc = true;
     
    863880       
    864881        block_check(head);
    865         assert(!head->free);
     882        malloc_assert(!head->free);
    866883       
    867884        heap_area_t *area = head->area;
    868885       
    869886        area_check(area);
    870         assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
    871         assert((void *) head < area->end);
     887        malloc_assert((void *) head >= (void *) AREA_FIRST_BLOCK_HEAD(area));
     888        malloc_assert((void *) head < area->end);
    872889       
    873890        /* Mark the block itself as free. */
     
    904921}
    905922
     923void *heap_check(void)
     924{
     925        futex_down(&malloc_futex);
     926       
     927        if (first_heap_area == NULL) {
     928                futex_up(&malloc_futex);
     929                return (void *) -1;
     930        }
     931       
     932        /* Walk all heap areas */
     933        for (heap_area_t *area = first_heap_area; area != NULL;
     934            area = area->next) {
     935               
     936                /* Check heap area consistency */
     937                if ((area->magic != HEAP_AREA_MAGIC) ||
     938                    ((void *) area != area->start) ||
     939                    (area->start >= area->end) ||
     940                    (((uintptr_t) area->start % PAGE_SIZE) != 0) ||
     941                    (((uintptr_t) area->end % PAGE_SIZE) != 0)) {
     942                        futex_up(&malloc_futex);
     943                        return (void *) area;
     944                }
     945               
     946                /* Walk all heap blocks */
     947                for (heap_block_head_t *head = (heap_block_head_t *)
     948                    AREA_FIRST_BLOCK_HEAD(area); (void *) head < area->end;
     949                    head = (heap_block_head_t *) (((void *) head) + head->size)) {
     950                       
     951                        /* Check heap block consistency */
     952                        if (head->magic != HEAP_BLOCK_HEAD_MAGIC) {
     953                                futex_up(&malloc_futex);
     954                                return (void *) head;
     955                        }
     956                       
     957                        heap_block_foot_t *foot = BLOCK_FOOT(head);
     958                       
     959                        if ((foot->magic != HEAP_BLOCK_FOOT_MAGIC) ||
     960                            (head->size != foot->size)) {
     961                                futex_up(&malloc_futex);
     962                                return (void *) foot;
     963                        }
     964                }
     965        }
     966       
     967        futex_up(&malloc_futex);
     968       
     969        return NULL;
     970}
     971
    906972/** @}
    907973 */
  • uspace/lib/c/generic/thread.c

    r5c460cc r864a081  
    4444
    4545#ifndef THREAD_INITIAL_STACK_PAGES_NO
    46 #define THREAD_INITIAL_STACK_PAGES_NO 1
     46#define THREAD_INITIAL_STACK_PAGES_NO   2
    4747#endif
    4848
  • uspace/lib/c/include/io/klog.h

    r5c460cc r864a081  
    3737
    3838#include <sys/types.h>
     39#include <stdarg.h>
    3940
    4041extern size_t klog_write(const void *, size_t);
    4142extern void klog_update(void);
     43extern int klog_printf(const char *, ...);
     44extern int klog_vprintf(const char *, va_list);
    4245
    4346#endif
  • uspace/lib/c/include/malloc.h

    r5c460cc r864a081  
    4646extern void *realloc(const void *addr, const size_t size);
    4747extern void free(const void *addr);
     48extern void *heap_check(void);
    4849
    4950#endif
Note: See TracChangeset for help on using the changeset viewer.