Changeset 8b863a62 in mainline for kernel/generic/src


Ignore:
Timestamp:
2014-04-16T17:14:06Z (12 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f857e8b
Parents:
dba3e2c (diff), 70b570c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes

Location:
kernel/generic/src
Files:
1 added
1 deleted
39 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/adt/bitmap.c

    rdba3e2c r8b863a62  
    3535 *
    3636 * This file implements bitmap ADT and provides functions for
    37  * setting and clearing ranges of bits.
     37 * setting and clearing ranges of bits and for finding ranges
     38 * of unset bits.
    3839 */
    3940
     
    4445#include <macros.h>
    4546
    46 #define ALL_ONES        0xff
    47 #define ALL_ZEROES      0x00
     47#define ALL_ONES    0xff
     48#define ALL_ZEROES  0x00
     49
     50/** Unchecked version of bitmap_get()
     51 *
     52 * This version of bitmap_get() does not do any boundary checks.
     53 *
     54 * @param bitmap  Bitmap to access.
     55 * @param element Element to access.
     56 *
     57 * @return Bit value of the element in the bitmap.
     58 *
     59 */
     60static unsigned int bitmap_get_fast(bitmap_t *bitmap, size_t element)
     61{
     62        size_t byte = element / BITMAP_ELEMENT;
     63        uint8_t mask = 1 << (element & BITMAP_REMAINER);
     64       
     65        return !!((bitmap->bits)[byte] & mask);
     66}
     67
     68/** Get bitmap size
     69 *
     70 * Return the size (in bytes) required for the bitmap.
     71 *
     72 * @param elements   Number bits stored in bitmap.
     73 *
     74 * @return Size (in bytes) required for the bitmap.
     75 *
     76 */
     77size_t bitmap_size(size_t elements)
     78{
     79        size_t size = elements / BITMAP_ELEMENT;
     80       
     81        if ((elements % BITMAP_ELEMENT) != 0)
     82                size++;
     83       
     84        return size;
     85}
    4886
    4987/** Initialize bitmap.
     
    5189 * No portion of the bitmap is set or cleared by this function.
    5290 *
    53  * @param bitmap        Bitmap structure.
    54  * @param map           Address of the memory used to hold the map.
    55  * @param bits          Number of bits stored in bitmap.
    56  */
    57 void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits)
    58 {
    59         bitmap->map = map;
    60         bitmap->bits = bits;
     91 * @param bitmap     Bitmap structure.
     92 * @param elements   Number of bits stored in bitmap.
     93 * @param data       Address of the memory used to hold the map.
     94 *                   The optional 2nd level bitmap follows the 1st
     95 *                   level bitmap.
     96 *
     97 */
     98void bitmap_initialize(bitmap_t *bitmap, size_t elements, void *data)
     99{
     100        bitmap->elements = elements;
     101        bitmap->bits = (uint8_t *) data;
     102        bitmap->next_fit = 0;
    61103}
    62104
    63105/** Set range of bits.
    64106 *
    65  * @param bitmap        Bitmap structure.
    66  * @param start         Starting bit.
    67  * @param bits          Number of bits to set.
    68  */
    69 void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits)
    70 {
    71         size_t i = 0;
    72         size_t aligned_start;
    73         size_t lub;     /* leading unaligned bits */
    74         size_t amb;     /* aligned middle bits */
    75         size_t tab;     /* trailing aligned bits */
    76        
    77         ASSERT(start + bits <= bitmap->bits);
    78        
    79         aligned_start = ALIGN_UP(start, 8);
    80         lub = min(aligned_start - start, bits);
    81         amb = bits > lub ? bits - lub : 0;
    82         tab = amb % 8;
    83        
    84         if (!bits)
     107 * @param bitmap Bitmap structure.
     108 * @param start  Starting bit.
     109 * @param count  Number of bits to set.
     110 *
     111 */
     112void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t count)
     113{
     114        ASSERT(start + count <= bitmap->elements);
     115       
     116        if (count == 0)
    85117                return;
    86 
    87         if (start + bits < aligned_start) {
     118       
     119        size_t start_byte = start / BITMAP_ELEMENT;
     120        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
     121       
     122        /* Leading unaligned bits */
     123        size_t lub = min(aligned_start - start, count);
     124       
     125        /* Aligned middle bits */
     126        size_t amb = (count > lub) ? (count - lub) : 0;
     127       
     128        /* Trailing aligned bits */
     129        size_t tab = amb % BITMAP_ELEMENT;
     130       
     131        if (start + count < aligned_start) {
    88132                /* Set bits in the middle of byte. */
    89                 bitmap->map[start / 8] |= ((1 << lub) - 1) << (start & 7);
     133                bitmap->bits[start_byte] |=
     134                    ((1 << lub) - 1) << (start & BITMAP_REMAINER);
    90135                return;
    91136        }
     
    93138        if (lub) {
    94139                /* Make sure to set any leading unaligned bits. */
    95                 bitmap->map[start / 8] |= ~((1 << (8 - lub)) - 1);
    96         }
    97         for (i = 0; i < amb / 8; i++) {
     140                bitmap->bits[start_byte] |=
     141                    ~((1 << (BITMAP_ELEMENT - lub)) - 1);
     142        }
     143       
     144        size_t i;
     145       
     146        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    98147                /* The middle bits can be set byte by byte. */
    99                 bitmap->map[aligned_start / 8 + i] = ALL_ONES;
    100         }
     148                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] =
     149                    ALL_ONES;
     150        }
     151       
    101152        if (tab) {
    102153                /* Make sure to set any trailing aligned bits. */
    103                 bitmap->map[aligned_start / 8 + i] |= (1 << tab) - 1;
    104         }
    105        
     154                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] |=
     155                    (1 << tab) - 1;
     156        }
    106157}
    107158
    108159/** Clear range of bits.
    109160 *
    110  * @param bitmap        Bitmap structure.
    111  * @param start         Starting bit.
    112  * @param bits          Number of bits to clear.
    113  */
    114 void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits)
    115 {
    116         size_t i = 0;
    117         size_t aligned_start;
    118         size_t lub;     /* leading unaligned bits */
    119         size_t amb;     /* aligned middle bits */
    120         size_t tab;     /* trailing aligned bits */
    121        
    122         ASSERT(start + bits <= bitmap->bits);
    123        
    124         aligned_start = ALIGN_UP(start, 8);
    125         lub = min(aligned_start - start, bits);
    126         amb = bits > lub ? bits - lub : 0;
    127         tab = amb % 8;
    128 
    129         if (!bits)
     161 * @param bitmap Bitmap structure.
     162 * @param start  Starting bit.
     163 * @param count  Number of bits to clear.
     164 *
     165 */
     166void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t count)
     167{
     168        ASSERT(start + count <= bitmap->elements);
     169       
     170        if (count == 0)
    130171                return;
    131 
    132         if (start + bits < aligned_start) {
     172       
     173        size_t start_byte = start / BITMAP_ELEMENT;
     174        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
     175       
     176        /* Leading unaligned bits */
     177        size_t lub = min(aligned_start - start, count);
     178       
     179        /* Aligned middle bits */
     180        size_t amb = (count > lub) ? (count - lub) : 0;
     181       
     182        /* Trailing aligned bits */
     183        size_t tab = amb % BITMAP_ELEMENT;
     184       
     185        if (start + count < aligned_start) {
    133186                /* Set bits in the middle of byte */
    134                 bitmap->map[start / 8] &= ~(((1 << lub) - 1) << (start & 7));
     187                bitmap->bits[start_byte] &=
     188                    ~(((1 << lub) - 1) << (start & BITMAP_REMAINER));
    135189                return;
    136190        }
    137 
     191       
    138192        if (lub) {
    139193                /* Make sure to clear any leading unaligned bits. */
    140                 bitmap->map[start / 8] &= (1 << (8 - lub)) - 1;
    141         }
    142         for (i = 0; i < amb / 8; i++) {
     194                bitmap->bits[start_byte] &=
     195                    (1 << (BITMAP_ELEMENT - lub)) - 1;
     196        }
     197       
     198        size_t i;
     199       
     200        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    143201                /* The middle bits can be cleared byte by byte. */
    144                 bitmap->map[aligned_start / 8 + i] = ALL_ZEROES;
    145         }
     202                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] =
     203                    ALL_ZEROES;
     204        }
     205       
    146206        if (tab) {
    147207                /* Make sure to clear any trailing aligned bits. */
    148                 bitmap->map[aligned_start / 8 + i] &= ~((1 << tab) - 1);
    149         }
    150 
     208                bitmap->bits[aligned_start / BITMAP_ELEMENT + i] &=
     209                    ~((1 << tab) - 1);
     210        }
     211       
     212        bitmap->next_fit = start_byte;
    151213}
    152214
    153215/** Copy portion of one bitmap into another bitmap.
    154216 *
    155  * @param dst           Destination bitmap.
    156  * @param src           Source bitmap.
    157  * @param bits          Number of bits to copy.
    158  */
    159 void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits)
    160 {
     217 * @param dst   Destination bitmap.
     218 * @param src   Source bitmap.
     219 * @param count Number of bits to copy.
     220 *
     221 */
     222void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t count)
     223{
     224        ASSERT(count <= dst->elements);
     225        ASSERT(count <= src->elements);
     226       
    161227        size_t i;
    162228       
    163         ASSERT(bits <= dst->bits);
    164         ASSERT(bits <= src->bits);
    165        
    166         for (i = 0; i < bits / 8; i++)
    167                 dst->map[i] = src->map[i];
    168        
    169         if (bits % 8) {
    170                 bitmap_clear_range(dst, i * 8, bits % 8);
    171                 dst->map[i] |= src->map[i] & ((1 << (bits % 8)) - 1);
    172         }
     229        for (i = 0; i < count / BITMAP_ELEMENT; i++)
     230                dst->bits[i] = src->bits[i];
     231       
     232        if (count % BITMAP_ELEMENT) {
     233                bitmap_clear_range(dst, i * BITMAP_ELEMENT,
     234                    count % BITMAP_ELEMENT);
     235                dst->bits[i] |= src->bits[i] &
     236                    ((1 << (count % BITMAP_ELEMENT)) - 1);
     237        }
     238}
     239
     240static int constraint_satisfy(size_t index, size_t base, size_t constraint)
     241{
     242        return (((base + index) & constraint) == 0);
     243}
     244
     245/** Find a continuous zero bit range
     246 *
     247 * Find a continuous zero bit range in the bitmap. The address
     248 * computed as the sum of the index of the first zero bit and
     249 * the base argument needs to be compliant with the constraint
     250 * (those bits that are set in the constraint cannot be set in
     251 * the address).
     252 *
     253 * If the index argument is non-NULL, the continuous zero range
     254 * is set and the index of the first bit is stored to index.
     255 * Otherwise the bitmap stays untouched.
     256 *
     257 * @param bitmap     Bitmap structure.
     258 * @param count      Number of continuous zero bits to find.
     259 * @param base       Address of the first bit in the bitmap.
     260 * @param prefered   Prefered address to start searching from.
     261 * @param constraint Constraint for the address of the first zero bit.
     262 * @param index      Place to store the index of the first zero
     263 *                   bit. Can be NULL (in which case the bitmap
     264 *                   is not modified).
     265 *
     266 * @return Non-zero if a continuous range of zero bits satisfying
     267 *         the constraint has been found.
     268 * @return Zero otherwise.
     269 *
     270 */
     271int bitmap_allocate_range(bitmap_t *bitmap, size_t count, size_t base,
     272    size_t prefered, size_t constraint, size_t *index)
     273{
     274        if (count == 0)
     275                return false;
     276       
     277        size_t size = bitmap_size(bitmap->elements);
     278        size_t next_fit = bitmap->next_fit;
     279       
     280        /*
     281         * Adjust the next-fit value according to the address
     282         * the caller prefers to start the search at.
     283         */
     284        if ((prefered > base) && (prefered < base + bitmap->elements)) {
     285                size_t prefered_fit = (prefered - base) / BITMAP_ELEMENT;
     286               
     287                if (prefered_fit > next_fit)
     288                        next_fit = prefered_fit;
     289        }
     290       
     291        for (size_t pos = 0; pos < size; pos++) {
     292                size_t byte = (next_fit + pos) % size;
     293               
     294                /* Skip if the current byte has all bits set */
     295                if (bitmap->bits[byte] == ALL_ONES)
     296                        continue;
     297               
     298                size_t byte_bit = byte * BITMAP_ELEMENT;
     299               
     300                for (size_t bit = 0; bit < BITMAP_ELEMENT; bit++) {
     301                        size_t i = byte_bit + bit;
     302                       
     303                        if (i >= bitmap->elements)
     304                                break;
     305                       
     306                        if (!constraint_satisfy(i, base, constraint))
     307                                continue;
     308                       
     309                        if (!bitmap_get_fast(bitmap, i)) {
     310                                size_t continuous = 1;
     311                               
     312                                for (size_t j = 1; j < count; j++) {
     313                                        if ((i + j < bitmap->elements) &&
     314                                            (!bitmap_get_fast(bitmap, i + j)))
     315                                                continuous++;
     316                                        else
     317                                                break;
     318                                }
     319                               
     320                                if (continuous == count) {
     321                                        if (index != NULL) {
     322                                                bitmap_set_range(bitmap, i, count);
     323                                                bitmap->next_fit = i / BITMAP_ELEMENT;
     324                                                *index = i;
     325                                        }
     326                                       
     327                                        return true;
     328                                } else
     329                                        i += continuous;
     330                        }
     331                }
     332        }
     333       
     334        return false;
    173335}
    174336
  • kernel/generic/src/adt/btree.c

    rdba3e2c r8b863a62  
    10311031       
    10321032        printf("Printing list of leaves:\n");
    1033         list_foreach(t->leaf_list, cur) {
    1034                 btree_node_t *node;
    1035                
    1036                 node = list_get_instance(cur, btree_node_t, leaf_link);
    1037                
     1033        list_foreach(t->leaf_list, leaf_link, btree_node_t, node) {
    10381034                ASSERT(node);
    10391035               
  • kernel/generic/src/adt/hash_table.c

    rdba3e2c r8b863a62  
    117117        ASSERT(chain < h->entries);
    118118       
    119         list_foreach(h->entry[chain], cur) {
     119        link_t *cur = list_first(&h->entry[chain]);
     120        while (cur != NULL) {
    120121                if (h->op->compare(key, h->max_keys, cur)) {
    121122                        /*
     
    124125                        return cur;
    125126                }
     127                cur = list_next(cur, &h->entry[chain]);
    126128        }
    127129       
  • kernel/generic/src/adt/list.c

    rdba3e2c r8b863a62  
    101101        unsigned int count = 0;
    102102       
    103         list_foreach(*list, link) {
     103        link_t *link = list_first(list);
     104        while (link != NULL) {
    104105                count++;
     106                link = list_next(link, list);
    105107        }
    106108       
  • kernel/generic/src/console/chardev.c

    rdba3e2c r8b863a62  
    9494{
    9595        if (atomic_get(&haltstate)) {
    96                 /* If we are here, we are hopefully on the processor that
     96                /*
     97                 * If we are here, we are hopefully on the processor that
    9798                 * issued the 'halt' command, so proceed to read the character
    9899                 * directly from input
     
    115116        waitq_sleep(&indev->wq);
    116117        irq_spinlock_lock(&indev->lock, true);
    117         wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
     118        wchar_t ch = indev->buffer[(indev->index - indev->counter) %
     119            INDEV_BUFLEN];
    118120        indev->counter--;
    119121        irq_spinlock_unlock(&indev->lock, true);
    120122       
    121123        return ch;
     124}
     125
     126/** Signal out-of-band condition
     127 *
     128 * @param indev  Input character device.
     129 * @param signal Out-of-band condition to signal.
     130 *
     131 */
     132void indev_signal(indev_t *indev, indev_signal_t signal)
     133{
     134        if ((indev != NULL) && (indev->op != NULL) &&
     135            (indev->op->signal != NULL))
     136                indev->op->signal(indev, signal);
    122137}
    123138
  • kernel/generic/src/console/cmd.c

    rdba3e2c r8b863a62  
    4545#include <console/kconsole.h>
    4646#include <print.h>
     47#include <log.h>
    4748#include <panic.h>
    4849#include <typedefs.h>
     
    639640        for (i = 0; basic_commands[i]; i++) {
    640641                if (!cmd_register(basic_commands[i])) {
    641                         printf("Cannot register command %s\n",
     642                        log(LF_OTHER, LVL_ERROR,
     643                            "Cannot register command %s",
    642644                            basic_commands[i]->name);
    643645                }
     
    656658       
    657659        size_t len = 0;
    658         list_foreach(cmd_list, cur) {
    659                 cmd_info_t *hlp;
    660                 hlp = list_get_instance(cur, cmd_info_t, link);
    661                
     660        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    662661                spinlock_lock(&hlp->lock);
    663662                if (str_length(hlp->name) > len)
     
    668667        unsigned int _len = (unsigned int) len;
    669668        if ((_len != len) || (((int) _len) < 0)) {
    670                 printf("Command length overflow\n");
     669                log(LF_OTHER, LVL_ERROR, "Command length overflow");
    671670                return 1;
    672671        }
    673672       
    674         list_foreach(cmd_list, cur) {
    675                 cmd_info_t *hlp;
    676                 hlp = list_get_instance(cur, cmd_info_t, link);
    677                
     673        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    678674                spinlock_lock(&hlp->lock);
    679675                printf("%-*s %s\n", _len, hlp->name, hlp->description);
     
    912908        spinlock_lock(&cmd_lock);
    913909       
    914         list_foreach(cmd_list, cur) {
    915                 cmd_info_t *hlp;
    916                
    917                 hlp = list_get_instance(cur, cmd_info_t, link);
     910        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    918911                spinlock_lock(&hlp->lock);
    919912               
  • kernel/generic/src/console/console.c

    rdba3e2c r8b863a62  
    5252#include <errno.h>
    5353#include <str.h>
    54 #include <abi/klog.h>
    55 
    56 #define KLOG_PAGES    8
    57 #define KLOG_LENGTH   (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
     54#include <abi/kio.h>
     55
     56#define KIO_PAGES    8
     57#define KIO_LENGTH   (KIO_PAGES * PAGE_SIZE / sizeof(wchar_t))
    5858
    5959/** Kernel log cyclic buffer */
    60 wchar_t klog[KLOG_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     60wchar_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
    6161
    6262/** Kernel log initialized */
    63 static atomic_t klog_inited = {false};
     63static atomic_t kio_inited = {false};
    6464
    6565/** First kernel log characters */
    66 static size_t klog_start = 0;
     66static size_t kio_start = 0;
    6767
    6868/** Number of valid kernel log characters */
    69 static size_t klog_len = 0;
     69static size_t kio_len = 0;
    7070
    7171/** Number of stored (not printed) kernel log characters */
    72 static size_t klog_stored = 0;
     72static size_t kio_stored = 0;
    7373
    7474/** Number of stored kernel log characters for uspace */
    75 static size_t klog_uspace = 0;
     75static size_t kio_uspace = 0;
    7676
    7777/** Kernel log spinlock */
    78 SPINLOCK_STATIC_INITIALIZE_NAME(klog_lock, "klog_lock");
    79 
    80 /** Physical memory area used for klog buffer */
    81 static parea_t klog_parea;
     78SPINLOCK_INITIALIZE_NAME(kio_lock, "kio_lock");
     79
     80/** Physical memory area used for kio buffer */
     81static parea_t kio_parea;
    8282
    8383static indev_t stdin_sink;
    8484static outdev_t stdout_source;
    8585
     86static void stdin_signal(indev_t *, indev_signal_t);
     87
    8688static indev_operations_t stdin_ops = {
    87         .poll = NULL
     89        .poll = NULL,
     90        .signal = stdin_signal
    8891};
    8992
    9093static void stdout_write(outdev_t *, wchar_t);
    9194static void stdout_redraw(outdev_t *);
     95static void stdout_scroll_up(outdev_t *);
     96static void stdout_scroll_down(outdev_t *);
    9297
    9398static outdev_operations_t stdout_ops = {
    9499        .write = stdout_write,
    95         .redraw = stdout_redraw
     100        .redraw = stdout_redraw,
     101        .scroll_up = stdout_scroll_up,
     102        .scroll_down = stdout_scroll_down
    96103};
    97104
     
    113120}
    114121
     122static void stdin_signal(indev_t *indev, indev_signal_t signal)
     123{
     124        switch (signal) {
     125        case INDEV_SIGNAL_SCROLL_UP:
     126                if (stdout != NULL)
     127                        stdout_scroll_up(stdout);
     128                break;
     129        case INDEV_SIGNAL_SCROLL_DOWN:
     130                if (stdout != NULL)
     131                        stdout_scroll_down(stdout);
     132                break;
     133        }
     134}
     135
    115136void stdout_wire(outdev_t *outdev)
    116137{
     
    125146static void stdout_write(outdev_t *dev, wchar_t ch)
    126147{
    127         list_foreach(dev->list, cur) {
    128                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     148        list_foreach(dev->list, link, outdev_t, sink) {
    129149                if ((sink) && (sink->op->write))
    130150                        sink->op->write(sink, ch);
     
    134154static void stdout_redraw(outdev_t *dev)
    135155{
    136         list_foreach(dev->list, cur) {
    137                 outdev_t *sink = list_get_instance(cur, outdev_t, link);
     156        list_foreach(dev->list, link, outdev_t, sink) {
    138157                if ((sink) && (sink->op->redraw))
    139158                        sink->op->redraw(sink);
     159        }
     160}
     161
     162static void stdout_scroll_up(outdev_t *dev)
     163{
     164        list_foreach(dev->list, link, outdev_t, sink) {
     165                if ((sink) && (sink->op->scroll_up))
     166                        sink->op->scroll_up(sink);
     167        }
     168}
     169
     170static void stdout_scroll_down(outdev_t *dev)
     171{
     172        list_foreach(dev->list, link, outdev_t, sink) {
     173                if ((sink) && (sink->op->scroll_down))
     174                        sink->op->scroll_down(sink);
    140175        }
    141176}
     
    148183 *
    149184 */
    150 void klog_init(void)
    151 {
    152         void *faddr = (void *) KA2PA(klog);
     185void kio_init(void)
     186{
     187        void *faddr = (void *) KA2PA(kio);
    153188       
    154189        ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
    155190       
    156         klog_parea.pbase = (uintptr_t) faddr;
    157         klog_parea.frames = SIZE2FRAMES(sizeof(klog));
    158         klog_parea.unpriv = false;
    159         klog_parea.mapped = false;
    160         ddi_parea_register(&klog_parea);
    161        
    162         sysinfo_set_item_val("klog.faddr", NULL, (sysarg_t) faddr);
    163         sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
    164        
    165         event_set_unmask_callback(EVENT_KLOG, klog_update);
    166         atomic_set(&klog_inited, true);
     191        kio_parea.pbase = (uintptr_t) faddr;
     192        kio_parea.frames = SIZE2FRAMES(sizeof(kio));
     193        kio_parea.unpriv = false;
     194        kio_parea.mapped = false;
     195        ddi_parea_register(&kio_parea);
     196       
     197        sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);
     198        sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);
     199       
     200        event_set_unmask_callback(EVENT_KIO, kio_update);
     201        atomic_set(&kio_inited, true);
    167202}
    168203
     
    231266                        }
    232267                }
     268               
    233269                if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
    234270                        putchar(ch);
     
    249285}
    250286
    251 void klog_update(void *event)
    252 {
    253         if (!atomic_get(&klog_inited))
     287void kio_update(void *event)
     288{
     289        if (!atomic_get(&kio_inited))
    254290                return;
    255291       
    256         spinlock_lock(&klog_lock);
    257        
    258         if (klog_uspace > 0) {
    259                 if (event_notify_3(EVENT_KLOG, true, klog_start, klog_len,
    260                     klog_uspace) == EOK)
    261                         klog_uspace = 0;
    262         }
    263        
    264         spinlock_unlock(&klog_lock);
     292        spinlock_lock(&kio_lock);
     293       
     294        if (kio_uspace > 0) {
     295                if (event_notify_3(EVENT_KIO, true, kio_start, kio_len,
     296                    kio_uspace) == EOK)
     297                        kio_uspace = 0;
     298        }
     299       
     300        spinlock_unlock(&kio_lock);
     301}
     302
     303/** Flush characters that are stored in the output buffer
     304 *
     305 */
     306void kio_flush(void)
     307{
     308        bool ordy = ((stdout) && (stdout->op->write));
     309       
     310        if (!ordy)
     311                return;
     312
     313        spinlock_lock(&kio_lock);
     314
     315        /* Print characters that weren't printed earlier */
     316        while (kio_stored > 0) {
     317                wchar_t tmp = kio[(kio_start + kio_len - kio_stored) % KIO_LENGTH];
     318                kio_stored--;
     319
     320                /*
     321                 * We need to give up the spinlock for
     322                 * the physical operation of writing out
     323                 * the character.
     324                 */
     325                spinlock_unlock(&kio_lock);
     326                stdout->op->write(stdout, tmp);
     327                spinlock_lock(&kio_lock);
     328        }
     329
     330        spinlock_unlock(&kio_lock);
     331}
     332
     333/** Put a character into the output buffer.
     334 *
     335 * The caller is required to hold kio_lock
     336 */
     337void kio_push_char(const wchar_t ch)
     338{
     339        kio[(kio_start + kio_len) % KIO_LENGTH] = ch;
     340        if (kio_len < KIO_LENGTH)
     341                kio_len++;
     342        else
     343                kio_start = (kio_start + 1) % KIO_LENGTH;
     344       
     345        if (kio_stored < kio_len)
     346                kio_stored++;
     347       
     348        /* The character is stored for uspace */
     349        if (kio_uspace < kio_len)
     350                kio_uspace++;
    265351}
    266352
     
    269355        bool ordy = ((stdout) && (stdout->op->write));
    270356       
    271         spinlock_lock(&klog_lock);
    272        
    273         /* Print charaters stored in kernel log */
    274         if (ordy) {
    275                 while (klog_stored > 0) {
    276                         wchar_t tmp = klog[(klog_start + klog_len - klog_stored) % KLOG_LENGTH];
    277                         klog_stored--;
    278                        
    279                         /*
    280                          * We need to give up the spinlock for
    281                          * the physical operation of writting out
    282                          * the character.
    283                          */
    284                         spinlock_unlock(&klog_lock);
    285                         stdout->op->write(stdout, tmp);
    286                         spinlock_lock(&klog_lock);
    287                 }
    288         }
    289        
    290         /* Store character in the cyclic kernel log */
    291         klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
    292         if (klog_len < KLOG_LENGTH)
    293                 klog_len++;
    294         else
    295                 klog_start = (klog_start + 1) % KLOG_LENGTH;
     357        spinlock_lock(&kio_lock);
     358        kio_push_char(ch);
     359        spinlock_unlock(&kio_lock);
     360       
     361        /* Output stored characters */
     362        kio_flush();
    296363       
    297364        if (!ordy) {
    298                 if (klog_stored < klog_len)
    299                         klog_stored++;
    300         }
    301        
    302         /* The character is stored for uspace */
    303         if (klog_uspace < klog_len)
    304                 klog_uspace++;
    305        
    306         spinlock_unlock(&klog_lock);
    307        
    308         if (ordy) {
    309                 /*
    310                  * Output the character. In this case
    311                  * it should be no longer buffered.
    312                  */
    313                 stdout->op->write(stdout, ch);
    314         } else {
    315365                /*
    316366                 * No standard output routine defined yet.
     
    328378        /* Force notification on newline */
    329379        if (ch == '\n')
    330                 klog_update(NULL);
     380                kio_update(NULL);
    331381}
    332382
     
    336386 *
    337387 */
    338 sysarg_t sys_klog(int cmd, const void *buf, size_t size)
     388sysarg_t sys_kio(int cmd, const void *buf, size_t size)
    339389{
    340390        char *data;
     
    342392
    343393        switch (cmd) {
    344         case KLOG_UPDATE:
    345                 klog_update(NULL);
     394        case KIO_UPDATE:
     395                kio_update(NULL);
    346396                return EOK;
    347         case KLOG_WRITE:
    348         case KLOG_COMMAND:
     397        case KIO_WRITE:
     398        case KIO_COMMAND:
    349399                break;
    350400        default:
     
    368418               
    369419                switch (cmd) {
    370                 case KLOG_WRITE:
     420                case KIO_WRITE:
    371421                        printf("%s", data);
    372422                        break;
    373                 case KLOG_COMMAND:
     423                case KIO_COMMAND:
    374424                        if (!stdin)
    375425                                break;
  • kernel/generic/src/console/kconsole.c

    rdba3e2c r8b863a62  
    5353#include <func.h>
    5454#include <str.h>
    55 #include <macros.h>
    5655#include <sysinfo/sysinfo.h>
    5756#include <ddi/device.h>
     
    119118         * Make sure the command is not already listed.
    120119         */
    121         list_foreach(cmd_list, cur) {
    122                 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
    123                
     120        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    124121                if (hlp == cmd) {
    125122                        /* The command is already there. */
     
    613610        cmd_info_t *cmd = NULL;
    614611       
    615         list_foreach(cmd_list, cur) {
    616                 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
     612        list_foreach(cmd_list, link, cmd_info_t, hlp) {
    617613                spinlock_lock(&hlp->lock);
    618614               
  • kernel/generic/src/cpu/cpu.c

    rdba3e2c r8b863a62  
    7373                size_t i;
    7474                for (i = 0; i < config.cpu_count; i++) {
    75                         cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES,
    76                             FRAME_LOWMEM | FRAME_KA | FRAME_ATOMIC);
     75                        uintptr_t stack_phys = frame_alloc(STACK_FRAMES,
     76                            FRAME_LOWMEM | FRAME_ATOMIC, STACK_SIZE - 1);
     77                        if (!stack_phys)
     78                                panic("Cannot allocate CPU stack.");
     79                       
     80                        cpus[i].stack = (uint8_t *) PA2KA(stack_phys);
    7781                        cpus[i].id = i;
    7882                       
    7983                        irq_spinlock_initialize(&cpus[i].lock, "cpus[].lock");
    8084                       
    81                         unsigned int j;
    82                         for (j = 0; j < RQ_COUNT; j++) {
     85                        for (unsigned int j = 0; j < RQ_COUNT; j++) {
    8386                                irq_spinlock_initialize(&cpus[i].rq[j].lock, "cpus[].rq[].lock");
    8487                                list_initialize(&cpus[i].rq[j].rq);
  • kernel/generic/src/ddi/ddi.c

    rdba3e2c r8b863a62  
    121121        backend_data.base = phys;
    122122        backend_data.frames = pages;
     123        backend_data.anonymous = false;
    123124       
    124125        /*
     
    314315
    315316NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
    316     unsigned int flags, void **phys)
     317    unsigned int flags, uintptr_t *phys)
    317318{
    318319        ASSERT(TASK);
     
    322323}
    323324
    324 NO_TRACE static int dmamem_map_anonymous(size_t size, unsigned int map_flags,
    325     unsigned int flags, void **phys, uintptr_t *virt, uintptr_t bound)
     325NO_TRACE static int dmamem_map_anonymous(size_t size, uintptr_t constraint,
     326    unsigned int map_flags, unsigned int flags, uintptr_t *phys,
     327    uintptr_t *virt, uintptr_t bound)
    326328{
    327329        ASSERT(TASK);
    328330       
    329         size_t pages = SIZE2FRAMES(size);
    330         uint8_t order;
    331        
    332         /* We need the 2^order >= pages */
    333         if (pages == 1)
    334                 order = 0;
    335         else
    336                 order = fnzb(pages - 1) + 1;
    337        
    338         *phys = frame_alloc_noreserve(order, 0);
    339         if (*phys == NULL)
     331        size_t frames = SIZE2FRAMES(size);
     332        *phys = frame_alloc(frames, FRAME_ATOMIC, constraint);
     333        if (*phys == 0)
    340334                return ENOMEM;
    341335       
    342336        mem_backend_data_t backend_data;
    343         backend_data.base = (uintptr_t) *phys;
    344         backend_data.frames = pages;
     337        backend_data.base = *phys;
     338        backend_data.frames = frames;
     339        backend_data.anonymous = true;
    345340       
    346341        if (!as_area_create(TASK->as, map_flags, size,
    347342            AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
    348                 frame_free_noreserve((uintptr_t) *phys);
     343                frame_free(*phys, frames);
    349344                return ENOMEM;
    350345        }
     
    361356NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)
    362357{
    363         // TODO: implement unlocking & unmap
    364         return EOK;
     358        return as_area_destroy(TASK->as, virt);
    365359}
    366360
     
    373367                 */
    374368               
    375                 void *phys;
     369                uintptr_t phys;
    376370                int rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags,
    377371                    flags, &phys);
     
    390384                 */
    391385               
    392                 void *phys;
     386                uintptr_t constraint;
     387                int rc = copy_from_uspace(&constraint, phys_ptr,
     388                    sizeof(constraint));
     389                if (rc != EOK)
     390                        return rc;
     391               
     392                uintptr_t phys;
    393393                uintptr_t virt = (uintptr_t) -1;
    394                 int rc = dmamem_map_anonymous(size, map_flags, flags,
     394                rc = dmamem_map_anonymous(size, constraint, map_flags, flags,
    395395                    &phys, &virt, bound);
    396396                if (rc != EOK)
  • kernel/generic/src/debug/panic.c

    rdba3e2c r8b863a62  
    9696        printf("THE=%p: ", THE);
    9797        if (THE != NULL) {
    98                 printf("pe=%" PRIun " thr=%p task=%p cpu=%p as=%p"
     98                printf("pd=%" PRIun " thread=%p task=%p cpu=%p as=%p"
    9999                    " magic=%#" PRIx32 "\n", THE->preemption_disabled,
    100100                    THE->thread, THE->task, THE->cpu, THE->as, THE->magic);
     101               
     102                if (THE->thread != NULL)
     103                        printf("thread=\"%s\"\n", THE->thread->name);
     104               
     105                if (THE->task != NULL)
     106                        printf("task=\"%s\"\n", THE->task->name);
    101107        } else
    102108                printf("invalid\n");
  • kernel/generic/src/debug/stacktrace.c

    rdba3e2c r8b863a62  
    3939#include <print.h>
    4040
    41 #define STACK_FRAMES_MAX        20
     41#define STACK_FRAMES_MAX  20
    4242
    4343void stack_trace_ctx(stack_trace_ops_t *ops, stack_trace_context_t *ctx)
     
    4949        uintptr_t pc;
    5050       
    51         while (cnt++ < STACK_FRAMES_MAX &&
    52             ops->stack_trace_context_validate(ctx)) {
     51        while ((cnt++ < STACK_FRAMES_MAX) &&
     52            (ops->stack_trace_context_validate(ctx))) {
    5353                if (ops->symbol_resolve &&
    5454                    ops->symbol_resolve(ctx->pc, &symbol, &offset)) {
  • kernel/generic/src/ipc/ipc.c

    rdba3e2c r8b863a62  
    774774static void ipc_print_call_list(list_t *list)
    775775{
    776         list_foreach(*list, cur) {
    777                 call_t *call = list_get_instance(cur, call_t, ab_link);
    778                
     776        list_foreach(*list, ab_link, call_t, call) {
    779777#ifdef __32_BITS__
    780778                printf("%10p ", call);
  • kernel/generic/src/ipc/ipcrsc.c

    rdba3e2c r8b863a62  
    151151        irq_spinlock_lock(&TASK->answerbox.lock, true);
    152152       
    153         list_foreach(TASK->answerbox.dispatched_calls, lst) {
    154                 call_t *call = list_get_instance(lst, call_t, ab_link);
     153        list_foreach(TASK->answerbox.dispatched_calls, ab_link, call_t, call) {
    155154                if ((sysarg_t) call == callid) {
    156155                        result = call;
  • kernel/generic/src/lib/func.c

    rdba3e2c r8b863a62  
    3737
    3838#include <func.h>
    39 #include <print.h>
     39#include <log.h>
    4040#include <cpu.h>
    4141#include <arch/asm.h>
     
    7272       
    7373        if (CPU)
    74                 printf("cpu%u: halted\n", CPU->id);
     74                log(LF_OTHER, LVL_NOTE, "cpu%u: halted", CPU->id);
    7575        else
    76                 printf("cpu: halted\n");
     76                log(LF_OTHER, LVL_NOTE, "cpu: halted");
    7777       
    7878        cpu_halt();
  • kernel/generic/src/lib/memfnc.c

    rdba3e2c r8b863a62  
    1         /*
     1/*
    22 * Copyright (c) 2011 Martin Decky
    33 * All rights reserved.
  • kernel/generic/src/lib/ra.c

    rdba3e2c r8b863a62  
    391391
    392392        irq_spinlock_lock(&arena->lock, true);
    393         list_foreach(arena->spans, cur) {
    394                 ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
    395 
     393        list_foreach(arena->spans, span_link, ra_span_t, span) {
    396394                base = ra_span_alloc(span, size, alignment);
    397395                if (base)
     
    407405{
    408406        irq_spinlock_lock(&arena->lock, true);
    409         list_foreach(arena->spans, cur) {
    410                 ra_span_t *span = list_get_instance(cur, ra_span_t, span_link);
    411 
     407        list_foreach(arena->spans, span_link, ra_span_t, span) {
    412408                if (iswithin(span->base, span->size, base, size)) {
    413409                        ra_span_free(span, base, size);
  • kernel/generic/src/lib/rd.c

    rdba3e2c r8b863a62  
    3838 */
    3939
    40 #include <print.h>
     40#include <log.h>
    4141#include <lib/rd.h>
    4242#include <mm/frame.h>
     
    6868        sysinfo_set_item_val("rd.address.physical", NULL, (sysarg_t) base);
    6969       
    70         printf("RAM disk at %p (size %zu bytes)\n", (void *) base, size);
     70        log(LF_OTHER, LVL_NOTE, "RAM disk at %p (size %zu bytes)", (void *) base,
     71            size);
    7172}
    7273
  • kernel/generic/src/main/kinit.c

    rdba3e2c r8b863a62  
    5959#include <mm/km.h>
    6060#include <print.h>
     61#include <log.h>
    6162#include <memstr.h>
    6263#include <console/console.h>
     
    140141                                thread_ready(thread);
    141142                        } else
    142                                 printf("Unable to create kcpulb thread for cpu%u\n", i);
     143                                log(LF_OTHER, LVL_ERROR,
     144                                    "Unable to create kcpulb thread for cpu%u", i);
    143145                }
    144146        }
     
    156158                thread_ready(thread);
    157159        else
    158                 printf("Unable to create kload thread\n");
     160                log(LF_OTHER, LVL_ERROR, "Unable to create kload thread");
    159161       
    160162#ifdef CONFIG_KCONSOLE
     
    168170                        thread_ready(thread);
    169171                else
    170                         printf("Unable to create kconsole thread\n");
     172                        log(LF_OTHER, LVL_ERROR,
     173                            "Unable to create kconsole thread");
    171174        }
    172175#endif /* CONFIG_KCONSOLE */
     
    210213        for (i = 0; i < init.cnt; i++) {
    211214                if (init.tasks[i].paddr % FRAME_SIZE) {
    212                         printf("init[%zu]: Address is not frame aligned\n", i);
     215                        log(LF_OTHER, LVL_ERROR,
     216                            "init[%zu]: Address is not frame aligned", i);
    213217                        programs[i].task = NULL;
    214218                        continue;
     
    273277                        init_rd((void *) init.tasks[i].paddr, init.tasks[i].size);
    274278                } else
    275                         printf("init[%zu]: Init binary load failed "
    276                             "(error %d, loader status %u)\n", i, rc,
     279                        log(LF_OTHER, LVL_ERROR,
     280                            "init[%zu]: Init binary load failed "
     281                            "(error %d, loader status %u)", i, rc,
    277282                            programs[i].loader_status);
    278283        }
  • kernel/generic/src/main/main.c

    rdba3e2c r8b863a62  
    6262#include <console/kconsole.h>
    6363#include <console/console.h>
     64#include <log.h>
    6465#include <cpu.h>
    6566#include <align.h>
     
    281282        ipc_init();
    282283        event_init();
    283         klog_init();
     284        kio_init();
     285        log_init();
    284286        stats_init();
    285287       
  • kernel/generic/src/main/shutdown.c

    rdba3e2c r8b863a62  
    3939#include <func.h>
    4040#include <print.h>
     41#include <log.h>
    4142
    4243void reboot(void)
     
    4546       
    4647#ifdef CONFIG_DEBUG
    47         printf("Rebooting the system\n");
     48        log(LF_OTHER, LVL_DEBUG, "Rebooting the system");
    4849#endif
    4950       
  • kernel/generic/src/mm/as.c

    rdba3e2c r8b863a62  
    488488       
    489489        /* Eventually check the addresses behind each area */
    490         list_foreach(as->as_area_btree.leaf_list, cur) {
    491                 btree_node_t *node =
    492                     list_get_instance(cur, btree_node_t, leaf_link);
     490        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
    493491               
    494492                for (btree_key_t i = 0; i < node->keys; i++) {
     
    521519        return (uintptr_t) -1;
    522520}
     521
     522/** Remove reference to address space area share info.
     523 *
     524 * If the reference count drops to 0, the sh_info is deallocated.
     525 *
     526 * @param sh_info Pointer to address space area share info.
     527 *
     528 */
     529NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
     530{
     531        bool dealloc = false;
     532       
     533        mutex_lock(&sh_info->lock);
     534        ASSERT(sh_info->refcount);
     535       
     536        if (--sh_info->refcount == 0) {
     537                dealloc = true;
     538               
     539                /*
     540                 * Now walk carefully the pagemap B+tree and free/remove
     541                 * reference from all frames found there.
     542                 */
     543                list_foreach(sh_info->pagemap.leaf_list, leaf_link,
     544                    btree_node_t, node) {
     545                        btree_key_t i;
     546                       
     547                        for (i = 0; i < node->keys; i++)
     548                                frame_free((uintptr_t) node->value[i], 1);
     549                }
     550               
     551        }
     552        mutex_unlock(&sh_info->lock);
     553       
     554        if (dealloc) {
     555                if (sh_info->backend && sh_info->backend->destroy_shared_data) {
     556                        sh_info->backend->destroy_shared_data(
     557                            sh_info->backend_shared_data);
     558                }
     559                btree_destroy(&sh_info->pagemap);
     560                free(sh_info);
     561        }
     562}
     563
    523564
    524565/** Create address space area of common attributes.
     
    568609        }
    569610
    570         if (overflows_into_positive(*base, size))
     611        if (overflows_into_positive(*base, size)) {
     612                mutex_unlock(&as->lock);
    571613                return NULL;
     614        }
    572615
    573616        if (!check_area_conflicts(as, *base, pages, guarded, NULL)) {
     
    586629        area->resident = 0;
    587630        area->base = *base;
     631        area->backend = backend;
    588632        area->sh_info = NULL;
    589         area->backend = backend;
    590633       
    591634        if (backend_data)
     
    593636        else
    594637                memsetb(&area->backend_data, sizeof(area->backend_data), 0);
    595        
     638
     639        share_info_t *si = NULL;
     640
     641        /*
     642         * Create the sharing info structure.
     643         * We do this in advance for every new area, even if it is not going
     644         * to be shared.
     645         */
     646        if (!(attrs & AS_AREA_ATTR_PARTIAL)) {
     647                si = (share_info_t *) malloc(sizeof(share_info_t), 0);
     648                mutex_initialize(&si->lock, MUTEX_PASSIVE);
     649                si->refcount = 1;
     650                si->shared = false;
     651                si->backend_shared_data = NULL;
     652                si->backend = backend;
     653                btree_create(&si->pagemap);
     654
     655                area->sh_info = si;
     656       
     657                if (area->backend && area->backend->create_shared_data) {
     658                        if (!area->backend->create_shared_data(area)) {
     659                                free(area);
     660                                mutex_unlock(&as->lock);
     661                                sh_info_remove_reference(si);
     662                                return NULL;
     663                        }
     664                }
     665        }
     666
    596667        if (area->backend && area->backend->create) {
    597668                if (!area->backend->create(area)) {
    598669                        free(area);
    599670                        mutex_unlock(&as->lock);
     671                        if (!(attrs & AS_AREA_ATTR_PARTIAL))
     672                                sh_info_remove_reference(si);
    600673                        return NULL;
    601674                }
    602675        }
    603        
     676
    604677        btree_create(&area->used_space);
    605678        btree_insert(&as->as_area_btree, *base, (void *) area,
     
    711784        }
    712785       
    713         if (area->sh_info) {
     786        mutex_lock(&area->sh_info->lock);
     787        if (area->sh_info->shared) {
    714788                /*
    715789                 * Remapping of shared address space areas
    716790                 * is not supported.
    717791                 */
     792                mutex_unlock(&area->sh_info->lock);
    718793                mutex_unlock(&area->lock);
    719794                mutex_unlock(&as->lock);
    720795                return ENOTSUP;
    721796        }
     797        mutex_unlock(&area->sh_info->lock);
    722798       
    723799        size_t pages = SIZE2FRAMES((address - area->base) + size);
     
    883959}
    884960
    885 /** Remove reference to address space area share info.
    886  *
    887  * If the reference count drops to 0, the sh_info is deallocated.
    888  *
    889  * @param sh_info Pointer to address space area share info.
    890  *
    891  */
    892 NO_TRACE static void sh_info_remove_reference(share_info_t *sh_info)
    893 {
    894         bool dealloc = false;
    895        
    896         mutex_lock(&sh_info->lock);
    897         ASSERT(sh_info->refcount);
    898        
    899         if (--sh_info->refcount == 0) {
    900                 dealloc = true;
    901                
    902                 /*
    903                  * Now walk carefully the pagemap B+tree and free/remove
    904                  * reference from all frames found there.
    905                  */
    906                 list_foreach(sh_info->pagemap.leaf_list, cur) {
    907                         btree_node_t *node
    908                             = list_get_instance(cur, btree_node_t, leaf_link);
    909                         btree_key_t i;
    910                        
    911                         for (i = 0; i < node->keys; i++)
    912                                 frame_free((uintptr_t) node->value[i]);
    913                 }
    914                
    915         }
    916         mutex_unlock(&sh_info->lock);
    917        
    918         if (dealloc) {
    919                 btree_destroy(&sh_info->pagemap);
    920                 free(sh_info);
    921         }
    922 }
    923 
    924961/** Destroy address space area.
    925962 *
     
    956993         * Visit only the pages mapped by used_space B+tree.
    957994         */
    958         list_foreach(area->used_space.leaf_list, cur) {
    959                 btree_node_t *node;
     995        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     996            node) {
    960997                btree_key_t i;
    961998               
    962                 node = list_get_instance(cur, btree_node_t, leaf_link);
    963999                for (i = 0; i < node->keys; i++) {
    9641000                        uintptr_t ptr = node->key[i];
     
    10041040        area->attributes |= AS_AREA_ATTR_PARTIAL;
    10051041       
    1006         if (area->sh_info)
    1007                 sh_info_remove_reference(area->sh_info);
     1042        sh_info_remove_reference(area->sh_info);
    10081043       
    10091044        mutex_unlock(&area->lock);
     
    10921127         */
    10931128        share_info_t *sh_info = src_area->sh_info;
    1094         if (!sh_info) {
    1095                 sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0);
    1096                 mutex_initialize(&sh_info->lock, MUTEX_PASSIVE);
    1097                 sh_info->refcount = 2;
    1098                 btree_create(&sh_info->pagemap);
    1099                 src_area->sh_info = sh_info;
    1100                
     1129       
     1130        mutex_lock(&sh_info->lock);
     1131        sh_info->refcount++;
     1132        bool shared = sh_info->shared;
     1133        sh_info->shared = true;
     1134        mutex_unlock(&sh_info->lock);
     1135
     1136        if (!shared) {
    11011137                /*
    11021138                 * Call the backend to setup sharing.
     1139                 * This only happens once for each sh_info.
    11031140                 */
    11041141                src_area->backend->share(src_area);
    1105         } else {
    1106                 mutex_lock(&sh_info->lock);
    1107                 sh_info->refcount++;
    1108                 mutex_unlock(&sh_info->lock);
    11091142        }
    11101143       
     
    12251258        }
    12261259       
    1227         if ((area->sh_info) || (area->backend != &anon_backend)) {
    1228                 /* Copying shared areas not supported yet */
     1260        if (area->backend != &anon_backend) {
    12291261                /* Copying non-anonymous memory not supported yet */
    12301262                mutex_unlock(&area->lock);
     
    12321264                return ENOTSUP;
    12331265        }
     1266
     1267        mutex_lock(&area->sh_info->lock);
     1268        if (area->sh_info->shared) {
     1269                /* Copying shared areas not supported yet */
     1270                mutex_unlock(&area->sh_info->lock);
     1271                mutex_unlock(&area->lock);
     1272                mutex_unlock(&as->lock);
     1273                return ENOTSUP;
     1274        }
     1275        mutex_unlock(&area->sh_info->lock);
    12341276       
    12351277        /*
     
    12381280        size_t used_pages = 0;
    12391281       
    1240         list_foreach(area->used_space.leaf_list, cur) {
    1241                 btree_node_t *node
    1242                     = list_get_instance(cur, btree_node_t, leaf_link);
     1282        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     1283            node) {
    12431284                btree_key_t i;
    12441285               
     
    12641305        size_t frame_idx = 0;
    12651306       
    1266         list_foreach(area->used_space.leaf_list, cur) {
    1267                 btree_node_t *node = list_get_instance(cur, btree_node_t,
    1268                     leaf_link);
     1307        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     1308            node) {
    12691309                btree_key_t i;
    12701310               
     
    13161356        frame_idx = 0;
    13171357       
    1318         list_foreach(area->used_space.leaf_list, cur) {
    1319                 btree_node_t *node
    1320                     = list_get_instance(cur, btree_node_t, leaf_link);
     1358        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     1359            node) {
    13211360                btree_key_t i;
    13221361               
     
    21822221        size_t area_cnt = 0;
    21832222       
    2184         list_foreach(as->as_area_btree.leaf_list, cur) {
    2185                 btree_node_t *node =
    2186                     list_get_instance(cur, btree_node_t, leaf_link);
     2223        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
     2224            node) {
    21872225                area_cnt += node->keys;
    21882226        }
     
    21952233        size_t area_idx = 0;
    21962234       
    2197         list_foreach(as->as_area_btree.leaf_list, cur) {
    2198                 btree_node_t *node =
    2199                     list_get_instance(cur, btree_node_t, leaf_link);
     2235        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
     2236            node) {
    22002237                btree_key_t i;
    22012238               
     
    22312268       
    22322269        /* Print out info about address space areas */
    2233         list_foreach(as->as_area_btree.leaf_list, cur) {
    2234                 btree_node_t *node
    2235                     = list_get_instance(cur, btree_node_t, leaf_link);
     2270        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
     2271            node) {
    22362272                btree_key_t i;
    22372273               
  • kernel/generic/src/mm/backend_anon.c

    rdba3e2c r8b863a62  
    7676        .page_fault = anon_page_fault,
    7777        .frame_free = anon_frame_free,
     78
     79        .create_shared_data = NULL,
     80        .destroy_shared_data = NULL
    7881};
    7982
     
    118121         */
    119122        mutex_lock(&area->sh_info->lock);
    120         list_foreach(area->used_space.leaf_list, cur) {
    121                 btree_node_t *node;
     123        list_foreach(area->used_space.leaf_list, leaf_link, btree_node_t,
     124            node) {
    122125                unsigned int i;
    123126               
    124                 node = list_get_instance(cur, btree_node_t, leaf_link);
    125127                for (i = 0; i < node->keys; i++) {
    126128                        uintptr_t base = node->key[i];
     
    191193                return AS_PF_FAULT;
    192194
    193         if (area->sh_info) {
     195        mutex_lock(&area->sh_info->lock);
     196        if (area->sh_info->shared) {
    194197                btree_node_t *leaf;
    195198               
     
    201204                 * mapping, a new frame is allocated and the mapping is created.
    202205                 */
    203                 mutex_lock(&area->sh_info->lock);
    204206                frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
    205207                    upage - area->base, &leaf);
     
    233235                }
    234236                frame_reference_add(ADDR2PFN(frame));
    235                 mutex_unlock(&area->sh_info->lock);
    236237        } else {
    237238
     
    255256                         * Reserve the memory for this page now.
    256257                         */
    257                         if (!reserve_try_alloc(1))
     258                        if (!reserve_try_alloc(1)) {
     259                                mutex_unlock(&area->sh_info->lock);
    258260                                return AS_PF_SILENT;
     261                        }
    259262                }
    260263
     
    263266                km_temporary_page_put(kpage);
    264267        }
     268        mutex_unlock(&area->sh_info->lock);
    265269       
    266270        /*
     
    295299                 * the normal unreserving frame_free().
    296300                 */
    297                 frame_free(frame);
     301                frame_free(frame, 1);
    298302        } else {
    299303                /*
     
    302306                 * manipulate the reserve or it would be given back twice.
    303307                 */
    304                 frame_free_noreserve(frame);
     308                frame_free_noreserve(frame, 1);
    305309        }
    306310}
  • kernel/generic/src/mm/backend_elf.c

    rdba3e2c r8b863a62  
    7575        .page_fault = elf_page_fault,
    7676        .frame_free = elf_frame_free,
     77
     78        .create_shared_data = NULL,
     79        .destroy_shared_data = NULL
    7780};
    7881
     
    274277        start_anon = entry->p_vaddr + entry->p_filesz;
    275278
    276         if (area->sh_info) {
     279        mutex_lock(&area->sh_info->lock);
     280        if (area->sh_info->shared) {
    277281                bool found = false;
    278282
     
    281285                 */
    282286               
    283                 mutex_lock(&area->sh_info->lock);
    284287                frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
    285288                    upage - area->base, &leaf);
     
    384387        }
    385388
    386         if (dirty && area->sh_info) {
     389        if (dirty && area->sh_info->shared) {
    387390                frame_reference_add(ADDR2PFN(frame));
    388391                btree_insert(&area->sh_info->pagemap, upage - area->base,
     
    390393        }
    391394
    392         if (area->sh_info)
    393                 mutex_unlock(&area->sh_info->lock);
     395        mutex_unlock(&area->sh_info->lock);
    394396
    395397        page_mapping_insert(AS, upage, frame, as_area_get_flags(area));
     
    429431                         * data.
    430432                         */
    431                         frame_free_noreserve(frame);
     433                        frame_free_noreserve(frame, 1);
    432434                }
    433435        } else {
     
    437439                 * anonymous). In any case, a frame needs to be freed.
    438440                 */
    439                 frame_free_noreserve(frame);
     441                frame_free_noreserve(frame, 1);
    440442        }
    441443}
  • kernel/generic/src/mm/backend_phys.c

    rdba3e2c r8b863a62  
    5555static bool phys_is_shareable(as_area_t *);
    5656
     57static int phys_page_fault(as_area_t *, uintptr_t, pf_access_t);
    5758
    58 static int phys_page_fault(as_area_t *, uintptr_t, pf_access_t);
     59static bool phys_create_shared_data(as_area_t *);
     60static void phys_destroy_shared_data(void *);
     61
     62typedef struct {
     63        uintptr_t base;
     64        size_t frames; 
     65} phys_shared_data_t;
    5966
    6067mem_backend_t phys_backend = {
     
    6976        .page_fault = phys_page_fault,
    7077        .frame_free = NULL,
     78       
     79        .create_shared_data = phys_create_shared_data,
     80        .destroy_shared_data = phys_destroy_shared_data
    7181};
     82
    7283
    7384bool phys_create(as_area_t *area)
     
    92103void phys_destroy(as_area_t *area)
    93104{
    94         /* Nothing to do. */
     105        /*
     106         * Nothing to do.
     107         * The anonymous frames, if any, are released in
     108         * phys_destroy_shared_data().
     109         */
    95110}
    96111
     
    138153}
    139154
     155bool phys_create_shared_data(as_area_t *area)
     156{
     157        /*
     158         * For anonymous phys areas, create the shared data.
     159         */
     160        if (area->backend_data.anonymous) {
     161                phys_shared_data_t *data;
     162
     163                data = (phys_shared_data_t *) malloc(sizeof(*data), 0);
     164
     165                data->base = area->backend_data.base;
     166                data->frames = area->backend_data.frames;
     167                area->sh_info->backend_shared_data = data;
     168        }
     169
     170        return true;
     171}
     172
     173void phys_destroy_shared_data(void *opaque_data)
     174{
     175        phys_shared_data_t *data = (phys_shared_data_t *) opaque_data;
     176
     177        if (data) {
     178                frame_free(data->base, data->frames);
     179                free(data);
     180        }
     181}
     182
    140183/** @}
    141184 */
  • kernel/generic/src/mm/frame.c

    rdba3e2c r8b863a62  
    3838 *
    3939 * This file contains the physical frame allocator and memory zone management.
    40  * The frame allocator is built on top of the buddy allocator.
    41  *
    42  * @see buddy.c
     40 * The frame allocator is built on top of the two-level bitmap structure.
     41 *
    4342 */
    4443
     
    5554#include <arch.h>
    5655#include <print.h>
     56#include <log.h>
    5757#include <align.h>
    5858#include <mm/slab.h>
     
    9292}
    9393
    94 NO_TRACE static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
    95 {
    96         return (frame - zone->frames);
    97 }
    98 
    9994/** Initialize frame structure.
    10095 *
     
    10499NO_TRACE static void frame_initialize(frame_t *frame)
    105100{
    106         frame->refcount = 1;
    107         frame->buddy_order = 0;
     101        frame->refcount = 0;
     102        frame->parent = NULL;
    108103}
    109104
     
    127122{
    128123        if (zones.count + 1 == ZONES_MAX) {
    129                 printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
     124                log(LF_OTHER, LVL_ERROR, "Maximum zone count %u exceeded!",
     125                    ZONES_MAX);
    130126                return (size_t) -1;
    131127        }
     
    147143                            (!iswithin(zones.info[i].base, zones.info[i].count,
    148144                            base, count))) {
    149                                 printf("Zone (%p, %p) overlaps "
    150                                     "with previous zone (%p %p)!\n",
     145                                log(LF_OTHER, LVL_WARN,
     146                                    "Zone (%p, %p) overlaps "
     147                                    "with previous zone (%p %p)!",
    151148                                    (void *) PFN2ADDR(base), (void *) PFN2ADDR(count),
    152149                                    (void *) PFN2ADDR(zones.info[i].base),
     
    161158       
    162159        /* Move other zones up */
    163         size_t j;
    164         for (j = zones.count; j > i; j--) {
     160        for (size_t j = zones.count; j > i; j--)
    165161                zones.info[j] = zones.info[j - 1];
    166                 if (zones.info[j].buddy_system != NULL)
    167                         zones.info[j].buddy_system->data =
    168                             (void *) &zones.info[j];
    169         }
    170162       
    171163        zones.count++;
     
    237229}
    238230
    239 /** @return True if zone can allocate specified order */
    240 NO_TRACE static bool zone_can_alloc(zone_t *zone, uint8_t order)
    241 {
     231/** @return True if zone can allocate specified number of frames */
     232NO_TRACE static bool zone_can_alloc(zone_t *zone, size_t count,
     233    pfn_t constraint)
     234{
     235        /*
     236         * The function bitmap_allocate_range() does not modify
     237         * the bitmap if the last argument is NULL.
     238         */
     239       
    242240        return ((zone->flags & ZONE_AVAILABLE) &&
    243             buddy_system_can_alloc(zone->buddy_system, order));
    244 }
    245 
    246 /** Find a zone that can allocate order frames.
     241            bitmap_allocate_range(&zone->bitmap, count, zone->base,
     242            FRAME_LOWPRIO, constraint, NULL));
     243}
     244
     245/** Find a zone that can allocate specified number of frames
     246 *
     247 * This function searches among all zones. Assume interrupts are
     248 * disabled and zones lock is locked.
     249 *
     250 * @param count      Number of free frames we are trying to find.
     251 * @param flags      Required flags of the zone.
     252 * @param constraint Indication of bits that cannot be set in the
     253 *                   physical frame number of the first allocated frame.
     254 * @param hint       Preferred zone.
     255 *
     256 * @return Zone that can allocate specified number of frames.
     257 * @return -1 if no zone can satisfy the request.
     258 *
     259 */
     260NO_TRACE static size_t find_free_zone_all(size_t count, zone_flags_t flags,
     261    pfn_t constraint, size_t hint)
     262{
     263        for (size_t pos = 0; pos < zones.count; pos++) {
     264                size_t i = (pos + hint) % zones.count;
     265               
     266                /* Check whether the zone meets the search criteria. */
     267                if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags))
     268                        continue;
     269               
     270                /* Check if the zone can satisfy the allocation request. */
     271                if (zone_can_alloc(&zones.info[i], count, constraint))
     272                        return i;
     273        }
     274       
     275        return (size_t) -1;
     276}
     277
     278/** Check if frame range  priority memory
     279 *
     280 * @param pfn   Starting frame.
     281 * @param count Number of frames.
     282 *
     283 * @return True if the range contains only priority memory.
     284 *
     285 */
     286NO_TRACE static bool is_high_priority(pfn_t base, size_t count)
     287{
     288        return (base + count <= FRAME_LOWPRIO);
     289}
     290
     291/** Find a zone that can allocate specified number of frames
     292 *
     293 * This function ignores zones that contain only high-priority
     294 * memory. Assume interrupts are disabled and zones lock is locked.
     295 *
     296 * @param count      Number of free frames we are trying to find.
     297 * @param flags      Required flags of the zone.
     298 * @param constraint Indication of bits that cannot be set in the
     299 *                   physical frame number of the first allocated frame.
     300 * @param hint       Preferred zone.
     301 *
     302 * @return Zone that can allocate specified number of frames.
     303 * @return -1 if no low-priority zone can satisfy the request.
     304 *
     305 */
     306NO_TRACE static size_t find_free_zone_lowprio(size_t count, zone_flags_t flags,
     307    pfn_t constraint, size_t hint)
     308{       
     309        for (size_t pos = 0; pos < zones.count; pos++) {
     310                size_t i = (pos + hint) % zones.count;
     311               
     312                /* Skip zones containing only high-priority memory. */
     313                if (is_high_priority(zones.info[i].base, zones.info[i].count))
     314                        continue;
     315               
     316                /* Check whether the zone meets the search criteria. */
     317                if (!ZONE_FLAGS_MATCH(zones.info[i].flags, flags))
     318                        continue;
     319               
     320                /* Check if the zone can satisfy the allocation request. */
     321                if (zone_can_alloc(&zones.info[i], count, constraint))
     322                        return i;
     323        }
     324       
     325        return (size_t) -1;
     326}
     327
     328/** Find a zone that can allocate specified number of frames
    247329 *
    248330 * Assume interrupts are disabled and zones lock is
    249331 * locked.
    250332 *
    251  * @param order Size (2^order) of free space we are trying to find.
    252  * @param flags Required flags of the target zone.
    253  * @param hind  Preferred zone.
    254  *
    255  */
    256 NO_TRACE static size_t find_free_zone(uint8_t order, zone_flags_t flags,
    257     size_t hint)
     333 * @param count      Number of free frames we are trying to find.
     334 * @param flags      Required flags of the target zone.
     335 * @param constraint Indication of bits that cannot be set in the
     336 *                   physical frame number of the first allocated frame.
     337 * @param hint       Preferred zone.
     338 *
     339 * @return Zone that can allocate specified number of frames.
     340 * @return -1 if no zone can satisfy the request.
     341 *
     342 */
     343NO_TRACE static size_t find_free_zone(size_t count, zone_flags_t flags,
     344    pfn_t constraint, size_t hint)
    258345{
    259346        if (hint >= zones.count)
    260347                hint = 0;
    261348       
    262         size_t i = hint;
    263         do {
    264                 /*
    265                  * Check whether the zone meets the search criteria.
    266                  */
    267                 if (ZONE_FLAGS_MATCH(zones.info[i].flags, flags)) {
    268                         /*
    269                          * Check if the zone has 2^order frames area available.
    270                          */
    271                         if (zone_can_alloc(&zones.info[i], order))
    272                                 return i;
    273                 }
    274                
    275                 i++;
    276                 if (i >= zones.count)
    277                         i = 0;
    278                
    279         } while (i != hint);
    280        
    281         return (size_t) -1;
    282 }
    283 
    284 /**************************/
    285 /* Buddy system functions */
    286 /**************************/
    287 
    288 /** Buddy system find_block implementation.
    289  *
    290  * Find block that is parent of current list.
    291  * That means go to lower addresses, until such block is found
    292  *
    293  * @param order Order of parent must be different then this
    294  *              parameter!!
    295  *
    296  */
    297 NO_TRACE static link_t *zone_buddy_find_block(buddy_system_t *buddy,
    298     link_t *child, uint8_t order)
    299 {
    300         frame_t *frame = list_get_instance(child, frame_t, buddy_link);
    301         zone_t *zone = (zone_t *) buddy->data;
    302        
    303         size_t index = frame_index(zone, frame);
    304         do {
    305                 if (zone->frames[index].buddy_order != order)
    306                         return &zone->frames[index].buddy_link;
    307         } while (index-- > 0);
    308        
    309         return NULL;
    310 }
    311 
    312 /** Buddy system find_buddy implementation.
    313  *
    314  * @param buddy Buddy system.
    315  * @param block Block for which buddy should be found.
    316  *
    317  * @return Buddy for given block if found.
    318  *
    319  */
    320 NO_TRACE static link_t *zone_buddy_find_buddy(buddy_system_t *buddy,
    321     link_t *block)
    322 {
    323         frame_t *frame = list_get_instance(block, frame_t, buddy_link);
    324         zone_t *zone = (zone_t *) buddy->data;
    325         ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),
    326             frame->buddy_order));
    327        
    328         bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
    329        
    330         size_t index;
    331         if (is_left) {
    332                 index = (frame_index(zone, frame)) +
    333                     (1 << frame->buddy_order);
    334         } else {  /* is_right */
    335                 index = (frame_index(zone, frame)) -
    336                     (1 << frame->buddy_order);
    337         }
    338        
    339         if (frame_index_valid(zone, index)) {
    340                 if ((zone->frames[index].buddy_order == frame->buddy_order) &&
    341                     (zone->frames[index].refcount == 0)) {
    342                         return &zone->frames[index].buddy_link;
    343                 }
    344         }
    345        
    346         return NULL;
    347 }
    348 
    349 /** Buddy system bisect implementation.
    350  *
    351  * @param buddy Buddy system.
    352  * @param block Block to bisect.
    353  *
    354  * @return Right block.
    355  *
    356  */
    357 NO_TRACE static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
    358 {
    359         frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
    360         frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
    361        
    362         return &frame_r->buddy_link;
    363 }
    364 
    365 /** Buddy system coalesce implementation.
    366  *
    367  * @param buddy   Buddy system.
    368  * @param block_1 First block.
    369  * @param block_2 First block's buddy.
    370  *
    371  * @return Coalesced block (actually block that represents lower
    372  *         address).
    373  *
    374  */
    375 NO_TRACE static link_t *zone_buddy_coalesce(buddy_system_t *buddy,
    376     link_t *block_1, link_t *block_2)
    377 {
    378         frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
    379         frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link);
    380        
    381         return ((frame1 < frame2) ? block_1 : block_2);
    382 }
    383 
    384 /** Buddy system set_order implementation.
    385  *
    386  * @param buddy Buddy system.
    387  * @param block Buddy system block.
    388  * @param order Order to set.
    389  *
    390  */
    391 NO_TRACE static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
    392     uint8_t order)
    393 {
    394         list_get_instance(block, frame_t, buddy_link)->buddy_order = order;
    395 }
    396 
    397 /** Buddy system get_order implementation.
    398  *
    399  * @param buddy Buddy system.
    400  * @param block Buddy system block.
    401  *
    402  * @return Order of block.
    403  *
    404  */
    405 NO_TRACE static uint8_t zone_buddy_get_order(buddy_system_t *buddy,
    406     link_t *block)
    407 {
    408         return list_get_instance(block, frame_t, buddy_link)->buddy_order;
    409 }
    410 
    411 /** Buddy system mark_busy implementation.
    412  *
    413  * @param buddy Buddy system.
    414  * @param block Buddy system block.
    415  *
    416  */
    417 NO_TRACE static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t *block)
    418 {
    419         list_get_instance(block, frame_t, buddy_link)->refcount = 1;
    420 }
    421 
    422 /** Buddy system mark_available implementation.
    423  *
    424  * @param buddy Buddy system.
    425  * @param block Buddy system block.
    426  *
    427  */
    428 NO_TRACE static void zone_buddy_mark_available(buddy_system_t *buddy,
    429     link_t *block)
    430 {
    431         list_get_instance(block, frame_t, buddy_link)->refcount = 0;
    432 }
    433 
    434 static buddy_system_operations_t zone_buddy_system_operations = {
    435         .find_buddy = zone_buddy_find_buddy,
    436         .bisect = zone_buddy_bisect,
    437         .coalesce = zone_buddy_coalesce,
    438         .set_order = zone_buddy_set_order,
    439         .get_order = zone_buddy_get_order,
    440         .mark_busy = zone_buddy_mark_busy,
    441         .mark_available = zone_buddy_mark_available,
    442         .find_block = zone_buddy_find_block
    443 };
     349        /*
     350         * Prefer zones with low-priority memory over
     351         * zones with high-priority memory.
     352         */
     353       
     354        size_t znum = find_free_zone_lowprio(count, flags, constraint, hint);
     355        if (znum != (size_t) -1)
     356                return znum;
     357       
     358        /* Take all zones into account */
     359        return find_free_zone_all(count, flags, constraint, hint);
     360}
    444361
    445362/******************/
     
    447364/******************/
    448365
     366/** Return frame from zone. */
     367NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t index)
     368{
     369        ASSERT(index < zone->count);
     370       
     371        return &zone->frames[index];
     372}
     373
    449374/** Allocate frame in particular zone.
    450375 *
     
    452377 * Panics if allocation is impossible.
    453378 *
    454  * @param zone  Zone to allocate from.
    455  * @param order Allocate exactly 2^order frames.
     379 * @param zone       Zone to allocate from.
     380 * @param count      Number of frames to allocate
     381 * @param constraint Indication of bits that cannot be set in the
     382 *                   physical frame number of the first allocated frame.
    456383 *
    457384 * @return Frame index in zone.
    458385 *
    459386 */
    460 NO_TRACE static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
     387NO_TRACE static size_t zone_frame_alloc(zone_t *zone, size_t count,
     388    pfn_t constraint)
    461389{
    462390        ASSERT(zone->flags & ZONE_AVAILABLE);
    463391       
    464         /* Allocate frames from zone buddy system */
    465         link_t *link = buddy_system_alloc(zone->buddy_system, order);
    466        
    467         ASSERT(link);
     392        /* Allocate frames from zone */
     393        size_t index;
     394        int avail = bitmap_allocate_range(&zone->bitmap, count, zone->base,
     395            FRAME_LOWPRIO, constraint, &index);
     396       
     397        ASSERT(avail);
     398       
     399        /* Update frame reference count */
     400        for (size_t i = 0; i < count; i++) {
     401                frame_t *frame = zone_get_frame(zone, index + i);
     402               
     403                ASSERT(frame->refcount == 0);
     404                frame->refcount = 1;
     405        }
    468406       
    469407        /* Update zone information. */
    470         zone->free_count -= (1 << order);
    471         zone->busy_count += (1 << order);
    472        
    473         /* Frame will be actually a first frame of the block. */
    474         frame_t *frame = list_get_instance(link, frame_t, buddy_link);
    475        
    476         /* Get frame address */
    477         return make_frame_index(zone, frame);
     408        zone->free_count -= count;
     409        zone->busy_count += count;
     410       
     411        return index;
    478412}
    479413
     
    482416 * Assume zone is locked and is available for deallocation.
    483417 *
    484  * @param zone      Pointer to zone from which the frame is to be freed.
    485  * @param frame_idx Frame index relative to zone.
    486  *
    487  * @return          Number of freed frames.
    488  *
    489  */
    490 NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t frame_idx)
     418 * @param zone  Pointer to zone from which the frame is to be freed.
     419 * @param index Frame index relative to zone.
     420 *
     421 * @return Number of freed frames.
     422 *
     423 */
     424NO_TRACE static size_t zone_frame_free(zone_t *zone, size_t index)
    491425{
    492426        ASSERT(zone->flags & ZONE_AVAILABLE);
    493427       
    494         frame_t *frame = &zone->frames[frame_idx];
    495         size_t size = 0;
    496        
    497         ASSERT(frame->refcount);
     428        frame_t *frame = zone_get_frame(zone, index);
     429       
     430        ASSERT(frame->refcount > 0);
    498431       
    499432        if (!--frame->refcount) {
    500                 size = 1 << frame->buddy_order;
    501                 buddy_system_free(zone->buddy_system, &frame->buddy_link);             
     433                bitmap_set(&zone->bitmap, index, 0);
     434               
    502435                /* Update zone information. */
    503                 zone->free_count += size;
    504                 zone->busy_count -= size;
    505         }
    506        
    507         return size;
    508 }
    509 
    510 /** Return frame from zone. */
    511 NO_TRACE static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
    512 {
    513         ASSERT(frame_idx < zone->count);
    514         return &zone->frames[frame_idx];
     436                zone->free_count++;
     437                zone->busy_count--;
     438               
     439                return 1;
     440        }
     441       
     442        return 0;
    515443}
    516444
    517445/** Mark frame in zone unavailable to allocation. */
    518 NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
     446NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t index)
    519447{
    520448        ASSERT(zone->flags & ZONE_AVAILABLE);
    521449       
    522         frame_t *frame = zone_get_frame(zone, frame_idx);
    523         if (frame->refcount)
     450        frame_t *frame = zone_get_frame(zone, index);
     451        if (frame->refcount > 0)
    524452                return;
    525453       
    526         link_t *link __attribute__ ((unused));
    527        
    528         link = buddy_system_alloc_block(zone->buddy_system,
    529             &frame->buddy_link);
    530        
    531         ASSERT(link);
     454        frame->refcount = 1;
     455        bitmap_set_range(&zone->bitmap, index, 1);
     456       
    532457        zone->free_count--;
    533458        reserve_force_alloc(1);
     
    536461/** Merge two zones.
    537462 *
    538  * Expect buddy to point to space at least zone_conf_size large.
    539463 * Assume z1 & z2 are locked and compatible and zones lock is
    540464 * locked.
    541465 *
    542  * @param z1     First zone to merge.
    543  * @param z2     Second zone to merge.
    544  * @param old_z1 Original date of the first zone.
    545  * @param buddy  Merged zone buddy.
     466 * @param z1       First zone to merge.
     467 * @param z2       Second zone to merge.
     468 * @param old_z1   Original data of the first zone.
     469 * @param confdata Merged zone configuration data.
    546470 *
    547471 */
    548472NO_TRACE static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1,
    549     buddy_system_t *buddy)
     473    void *confdata)
    550474{
    551475        ASSERT(zones.info[z1].flags & ZONE_AVAILABLE);
     
    562486        zones.info[z1].free_count += zones.info[z2].free_count;
    563487        zones.info[z1].busy_count += zones.info[z2].busy_count;
    564         zones.info[z1].buddy_system = buddy;
    565        
    566         uint8_t order = fnzb(zones.info[z1].count);
    567         buddy_system_create(zones.info[z1].buddy_system, order,
    568             &zone_buddy_system_operations, (void *) &zones.info[z1]);
    569        
    570         zones.info[z1].frames =
    571             (frame_t *) ((uint8_t *) zones.info[z1].buddy_system
    572             + buddy_conf_size(order));
    573        
    574         /* This marks all frames busy */
    575         size_t i;
    576         for (i = 0; i < zones.info[z1].count; i++)
    577                 frame_initialize(&zones.info[z1].frames[i]);
    578        
    579         /* Copy frames from both zones to preserve full frame orders,
    580          * parents etc. Set all free frames with refcount = 0 to 1, because
    581          * we add all free frames to buddy allocator later again, clearing
    582          * order to 0. Don't set busy frames with refcount = 0, as they
    583          * will not be reallocated during merge and it would make later
    584          * problems with allocation/free.
     488       
     489        bitmap_initialize(&zones.info[z1].bitmap, zones.info[z1].count,
     490            confdata + (sizeof(frame_t) * zones.info[z1].count));
     491        bitmap_clear_range(&zones.info[z1].bitmap, 0, zones.info[z1].count);
     492       
     493        zones.info[z1].frames = (frame_t *) confdata;
     494       
     495        /*
     496         * Copy frames and bits from both zones to preserve parents, etc.
    585497         */
    586         for (i = 0; i < old_z1->count; i++)
     498       
     499        for (size_t i = 0; i < old_z1->count; i++) {
     500                bitmap_set(&zones.info[z1].bitmap, i,
     501                    bitmap_get(&old_z1->bitmap, i));
    587502                zones.info[z1].frames[i] = old_z1->frames[i];
    588        
    589         for (i = 0; i < zones.info[z2].count; i++)
    590                 zones.info[z1].frames[base_diff + i]
    591                     = zones.info[z2].frames[i];
    592        
    593         i = 0;
    594         while (i < zones.info[z1].count) {
    595                 if (zones.info[z1].frames[i].refcount) {
    596                         /* Skip busy frames */
    597                         i += 1 << zones.info[z1].frames[i].buddy_order;
    598                 } else {
    599                         /* Free frames, set refcount = 1
    600                          * (all free frames have refcount == 0, we need not
    601                          * to check the order)
    602                          */
    603                         zones.info[z1].frames[i].refcount = 1;
    604                         zones.info[z1].frames[i].buddy_order = 0;
    605                         i++;
    606                 }
    607         }
    608        
    609         /* Add free blocks from the original zone z1 */
    610         while (zone_can_alloc(old_z1, 0)) {
    611                 /* Allocate from the original zone */
    612                 pfn_t frame_idx = zone_frame_alloc(old_z1, 0);
    613                
    614                 /* Free the frame from the merged zone */
    615                 frame_t *frame = &zones.info[z1].frames[frame_idx];
    616                 frame->refcount = 0;
    617                 buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
    618         }
    619        
    620         /* Add free blocks from the original zone z2 */
    621         while (zone_can_alloc(&zones.info[z2], 0)) {
    622                 /* Allocate from the original zone */
    623                 pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0);
    624                
    625                 /* Free the frame from the merged zone */
    626                 frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx];
    627                 frame->refcount = 0;
    628                 buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
     503        }
     504       
     505        for (size_t i = 0; i < zones.info[z2].count; i++) {
     506                bitmap_set(&zones.info[z1].bitmap, base_diff + i,
     507                    bitmap_get(&zones.info[z2].bitmap, i));
     508                zones.info[z1].frames[base_diff + i] =
     509                    zones.info[z2].frames[i];
    629510        }
    630511}
     
    649530        size_t cframes = SIZE2FRAMES(zone_conf_size(count));
    650531       
    651         if ((pfn < zones.info[znum].base)
    652             || (pfn >= zones.info[znum].base + zones.info[znum].count))
     532        if ((pfn < zones.info[znum].base) ||
     533            (pfn >= zones.info[znum].base + zones.info[znum].count))
    653534                return;
    654535       
    655         frame_t *frame __attribute__ ((unused));
    656 
    657         frame = &zones.info[znum].frames[pfn - zones.info[znum].base];
    658         ASSERT(!frame->buddy_order);
    659        
    660         size_t i;
    661         for (i = 0; i < cframes; i++) {
    662                 zones.info[znum].busy_count++;
     536        for (size_t i = 0; i < cframes; i++)
    663537                (void) zone_frame_free(&zones.info[znum],
    664538                    pfn - zones.info[znum].base + i);
    665         }
    666 }
    667 
    668 /** Reduce allocated block to count of order 0 frames.
    669  *
    670  * The allocated block needs 2^order frames. Reduce all frames
    671  * in the block to order 0 and free the unneeded frames. This means that
    672  * when freeing the previously allocated block starting with frame_idx,
    673  * you have to free every frame.
    674  *
    675  * @param znum      Zone.
    676  * @param frame_idx Index the first frame of the block.
    677  * @param count     Allocated frames in block.
    678  *
    679  */
    680 NO_TRACE static void zone_reduce_region(size_t znum, pfn_t frame_idx,
    681     size_t count)
    682 {
    683         ASSERT(zones.info[znum].flags & ZONE_AVAILABLE);
    684         ASSERT(frame_idx + count < zones.info[znum].count);
    685        
    686         uint8_t order = zones.info[znum].frames[frame_idx].buddy_order;
    687         ASSERT((size_t) (1 << order) >= count);
    688        
    689         /* Reduce all blocks to order 0 */
    690         size_t i;
    691         for (i = 0; i < (size_t) (1 << order); i++) {
    692                 frame_t *frame = &zones.info[znum].frames[i + frame_idx];
    693                 frame->buddy_order = 0;
    694                 if (!frame->refcount)
    695                         frame->refcount = 1;
    696                 ASSERT(frame->refcount == 1);
    697         }
    698        
    699         /* Free unneeded frames */
    700         for (i = count; i < (size_t) (1 << order); i++)
    701                 (void) zone_frame_free(&zones.info[znum], i + frame_idx);
    702539}
    703540
     
    719556        bool ret = true;
    720557       
    721         /* We can join only 2 zones with none existing inbetween,
     558        /*
     559         * We can join only 2 zones with none existing inbetween,
    722560         * the zones have to be available and with the same
    723561         * set of flags
     
    733571            + zones.info[z2].count));
    734572       
    735         uint8_t order;
    736         if (cframes == 1)
    737                 order = 0;
    738         else
    739                 order = fnzb(cframes - 1) + 1;
    740        
    741573        /* Allocate merged zone data inside one of the zones */
    742574        pfn_t pfn;
    743         if (zone_can_alloc(&zones.info[z1], order)) {
    744                 pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order);
    745         } else if (zone_can_alloc(&zones.info[z2], order)) {
    746                 pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order);
     575        if (zone_can_alloc(&zones.info[z1], cframes, 0)) {
     576                pfn = zones.info[z1].base +
     577                    zone_frame_alloc(&zones.info[z1], cframes, 0);
     578        } else if (zone_can_alloc(&zones.info[z2], cframes, 0)) {
     579                pfn = zones.info[z2].base +
     580                    zone_frame_alloc(&zones.info[z2], cframes, 0);
    747581        } else {
    748582                ret = false;
     
    752586        /* Preserve original data from z1 */
    753587        zone_t old_z1 = zones.info[z1];
    754         old_z1.buddy_system->data = (void *) &old_z1;
    755588       
    756589        /* Do zone merging */
    757         buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn));
    758         zone_merge_internal(z1, z2, &old_z1, buddy);
    759        
    760         /* Free unneeded config frames */
    761         zone_reduce_region(z1, pfn - zones.info[z1].base, cframes);
     590        zone_merge_internal(z1, z2, &old_z1, (void *) PA2KA(PFN2ADDR(pfn)));
    762591       
    763592        /* Subtract zone information from busy frames */
     
    772601       
    773602        /* Move zones down */
    774         size_t i;
    775         for (i = z2 + 1; i < zones.count; i++) {
     603        for (size_t i = z2 + 1; i < zones.count; i++)
    776604                zones.info[i - 1] = zones.info[i];
    777                 if (zones.info[i - 1].buddy_system != NULL)
    778                         zones.info[i - 1].buddy_system->data =
    779                             (void *) &zones.info[i - 1];
    780         }
    781605       
    782606        zones.count--;
     
    797621void zone_merge_all(void)
    798622{
    799         size_t i = 0;
     623        size_t i = 1;
     624       
    800625        while (i < zones.count) {
    801                 if (!zone_merge(i, i + 1))
     626                if (!zone_merge(i - 1, i))
    802627                        i++;
    803628        }
     
    806631/** Create new frame zone.
    807632 *
    808  * @param zone  Zone to construct.
    809  * @param buddy Address of buddy system configuration information.
    810  * @param start Physical address of the first frame within the zone.
    811  * @param count Count of frames in zone.
    812  * @param flags Zone flags.
     633 * @param zone     Zone to construct.
     634 * @param start    Physical address of the first frame within the zone.
     635 * @param count    Count of frames in zone.
     636 * @param flags    Zone flags.
     637 * @param confdata Configuration data of the zone.
    813638 *
    814639 * @return Initialized zone.
    815640 *
    816641 */
    817 NO_TRACE static void zone_construct(zone_t *zone, buddy_system_t *buddy,
    818     pfn_t start, size_t count, zone_flags_t flags)
     642NO_TRACE static void zone_construct(zone_t *zone, pfn_t start, size_t count,
     643    zone_flags_t flags, void *confdata)
    819644{
    820645        zone->base = start;
     
    823648        zone->free_count = count;
    824649        zone->busy_count = 0;
    825         zone->buddy_system = buddy;
    826650       
    827651        if (flags & ZONE_AVAILABLE) {
    828652                /*
    829                  * Compute order for buddy system and initialize
     653                 * Initialize frame bitmap (located after the array of
     654                 * frame_t structures in the configuration space).
    830655                 */
    831                 uint8_t order = fnzb(count);
    832                 buddy_system_create(zone->buddy_system, order,
    833                     &zone_buddy_system_operations, (void *) zone);
    834                
    835                 /* Allocate frames _after_ the confframe */
    836                
    837                 /* Check sizes */
    838                 zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system +
    839                     buddy_conf_size(order));
    840                
    841                 size_t i;
    842                 for (i = 0; i < count; i++)
     656               
     657                bitmap_initialize(&zone->bitmap, count, confdata +
     658                    (sizeof(frame_t) * count));
     659                bitmap_clear_range(&zone->bitmap, 0, count);
     660               
     661                /*
     662                 * Initialize the array of frame_t structures.
     663                 */
     664               
     665                zone->frames = (frame_t *) confdata;
     666               
     667                for (size_t i = 0; i < count; i++)
    843668                        frame_initialize(&zone->frames[i]);
    844                
    845                 /* Stuffing frames */
    846                 for (i = 0; i < count; i++) {
    847                         zone->frames[i].refcount = 0;
    848                         buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
    849                 }
    850         } else
     669        } else {
     670                bitmap_initialize(&zone->bitmap, 0, NULL);
    851671                zone->frames = NULL;
     672        }
    852673}
    853674
     
    861682size_t zone_conf_size(size_t count)
    862683{
    863         return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
     684        return (count * sizeof(frame_t) + bitmap_size(count));
    864685}
    865686
     
    867688pfn_t zone_external_conf_alloc(size_t count)
    868689{
    869         size_t size = zone_conf_size(count);
    870         size_t order = ispwr2(size) ? fnzb(size) : (fnzb(size) + 1);
    871 
    872         return ADDR2PFN((uintptr_t) frame_alloc(order - FRAME_WIDTH,
    873             FRAME_LOWMEM | FRAME_ATOMIC));
     690        size_t frames = SIZE2FRAMES(zone_conf_size(count));
     691       
     692        return ADDR2PFN((uintptr_t)
     693            frame_alloc(frames, FRAME_LOWMEM | FRAME_ATOMIC, 0));
    874694}
    875695
     
    879699 * @param count     Size of zone in frames.
    880700 * @param confframe Where configuration frames are supposed to be.
    881  *                  Automatically checks, that we will not disturb the
     701 *                  Automatically checks that we will not disturb the
    882702 *                  kernel and possibly init. If confframe is given
    883703 *                  _outside_ this zone, it is expected, that the area is
     
    896716       
    897717        if (flags & ZONE_AVAILABLE) {  /* Create available zone */
    898                 /* Theoretically we could have NULL here, practically make sure
     718                /*
     719                 * Theoretically we could have NULL here, practically make sure
    899720                 * nobody tries to do that. If some platform requires, remove
    900721                 * the assert
    901722                 */
    902723                ASSERT(confframe != ADDR2PFN((uintptr_t ) NULL));
    903 
     724               
    904725                /* Update the known end of physical memory. */
    905726                config.physmem_end = max(config.physmem_end, PFN2ADDR(start + count));
    906727               
    907                 /* If confframe is supposed to be inside our zone, then make sure
     728                /*
     729                 * If confframe is supposed to be inside our zone, then make sure
    908730                 * it does not span kernel & init
    909731                 */
    910732                size_t confcount = SIZE2FRAMES(zone_conf_size(count));
     733               
    911734                if ((confframe >= start) && (confframe < start + count)) {
    912735                        for (; confframe < start + count; confframe++) {
     
    921744                               
    922745                                bool overlap = false;
    923                                 size_t i;
    924                                 for (i = 0; i < init.cnt; i++)
     746                                for (size_t i = 0; i < init.cnt; i++) {
    925747                                        if (overlaps(addr, PFN2ADDR(confcount),
    926748                                            init.tasks[i].paddr,
     
    929751                                                break;
    930752                                        }
     753                                }
     754                               
    931755                                if (overlap)
    932756                                        continue;
     
    945769                }
    946770               
    947                 buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe));
    948                 zone_construct(&zones.info[znum], buddy, start, count, flags);
     771                void *confdata = (void *) PA2KA(PFN2ADDR(confframe));
     772                zone_construct(&zones.info[znum], start, count, flags, confdata);
    949773               
    950774                /* If confdata in zone, mark as unavailable */
    951775                if ((confframe >= start) && (confframe < start + count)) {
    952                         size_t i;
    953                         for (i = confframe; i < confframe + confcount; i++)
     776                        for (size_t i = confframe; i < confframe + confcount; i++)
    954777                                zone_mark_unavailable(&zones.info[znum],
    955778                                    i - zones.info[znum].base);
     
    967790                return (size_t) -1;
    968791        }
    969         zone_construct(&zones.info[znum], NULL, start, count, flags);
     792       
     793        zone_construct(&zones.info[znum], start, count, flags, NULL);
    970794       
    971795        irq_spinlock_unlock(&zones.lock, true);
     
    1009833}
    1010834
    1011 /** Allocate power-of-two frames of physical memory.
    1012  *
    1013  * @param order Allocate exactly 2^order frames.
    1014  * @param flags Flags for host zone selection and address processing.
    1015  * @param pzone Preferred zone.
     835/** Allocate frames of physical memory.
     836 *
     837 * @param count      Number of continuous frames to allocate.
     838 * @param flags      Flags for host zone selection and address processing.
     839 * @param constraint Indication of physical address bits that cannot be
     840 *                   set in the address of the first allocated frame.
     841 * @param pzone      Preferred zone.
    1016842 *
    1017843 * @return Physical address of the allocated frame.
    1018844 *
    1019845 */
    1020 void *frame_alloc_generic(uint8_t order, frame_flags_t flags, size_t *pzone)
    1021 {
    1022         size_t size = ((size_t) 1) << order;
     846uintptr_t frame_alloc_generic(size_t count, frame_flags_t flags,
     847    uintptr_t constraint, size_t *pzone)
     848{
     849        ASSERT(count > 0);
     850       
    1023851        size_t hint = pzone ? (*pzone) : 0;
     852        pfn_t frame_constraint = ADDR2PFN(constraint);
    1024853       
    1025854        /*
    1026855         * If not told otherwise, we must first reserve the memory.
    1027856         */
    1028         if (!(flags & FRAME_NO_RESERVE)) 
    1029                 reserve_force_alloc(size);
    1030 
     857        if (!(flags & FRAME_NO_RESERVE))
     858                reserve_force_alloc(count);
     859       
    1031860loop:
    1032861        irq_spinlock_lock(&zones.lock, true);
     
    1035864         * First, find suitable frame zone.
    1036865         */
    1037         size_t znum = find_free_zone(order,
    1038             FRAME_TO_ZONE_FLAGS(flags), hint);
    1039        
    1040         /* If no memory, reclaim some slab memory,
    1041            if it does not help, reclaim all */
     866        size_t znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
     867            frame_constraint, hint);
     868       
     869        /*
     870         * If no memory, reclaim some slab memory,
     871         * if it does not help, reclaim all.
     872         */
    1042873        if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
    1043874                irq_spinlock_unlock(&zones.lock, true);
     
    1046877               
    1047878                if (freed > 0)
    1048                         znum = find_free_zone(order,
    1049                             FRAME_TO_ZONE_FLAGS(flags), hint);
     879                        znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
     880                            frame_constraint, hint);
    1050881               
    1051882                if (znum == (size_t) -1) {
     
    1055886                       
    1056887                        if (freed > 0)
    1057                                 znum = find_free_zone(order,
    1058                                     FRAME_TO_ZONE_FLAGS(flags), hint);
     888                                znum = find_free_zone(count, FRAME_TO_ZONE_FLAGS(flags),
     889                                    frame_constraint, hint);
    1059890                }
    1060891        }
     
    1063894                if (flags & FRAME_ATOMIC) {
    1064895                        irq_spinlock_unlock(&zones.lock, true);
     896                       
    1065897                        if (!(flags & FRAME_NO_RESERVE))
    1066                                 reserve_free(size);
    1067                         return NULL;
     898                                reserve_free(count);
     899                       
     900                        return 0;
    1068901                }
    1069902               
    1070 #ifdef CONFIG_DEBUG
    1071903                size_t avail = frame_total_free_get_internal();
    1072 #endif
    1073904               
    1074905                irq_spinlock_unlock(&zones.lock, true);
    1075906               
    1076907                if (!THREAD)
    1077                         panic("Cannot wait for memory to become available.");
     908                        panic("Cannot wait for %zu frames to become available "
     909                            "(%zu available).", count, avail);
    1078910               
    1079911                /*
     
    1082914               
    1083915#ifdef CONFIG_DEBUG
    1084                 printf("Thread %" PRIu64 " waiting for %zu frames, "
    1085                     "%zu available.\n", THREAD->tid, size, avail);
     916                log(LF_OTHER, LVL_DEBUG,
     917                    "Thread %" PRIu64 " waiting for %zu frames "
     918                    "%zu available.", THREAD->tid, count, avail);
    1086919#endif
    1087920               
    1088921                /*
    1089                  * Since the mem_avail_mtx is an active mutex, we need to disable interrupts
    1090                  * to prevent deadlock with TLB shootdown.
     922                 * Since the mem_avail_mtx is an active mutex, we need to
     923                 * disable interrupts to prevent deadlock with TLB shootdown.
    1091924                 */
    1092925                ipl_t ipl = interrupts_disable();
     
    1094927               
    1095928                if (mem_avail_req > 0)
    1096                         mem_avail_req = min(mem_avail_req, size);
     929                        mem_avail_req = min(mem_avail_req, count);
    1097930                else
    1098                         mem_avail_req = size;
     931                        mem_avail_req = count;
     932               
    1099933                size_t gen = mem_avail_gen;
    1100934               
     
    1106940               
    1107941#ifdef CONFIG_DEBUG
    1108                 printf("Thread %" PRIu64 " woken up.\n", THREAD->tid);
     942                log(LF_OTHER, LVL_DEBUG, "Thread %" PRIu64 " woken up.",
     943                    THREAD->tid);
    1109944#endif
    1110945               
     
    1112947        }
    1113948       
    1114         pfn_t pfn = zone_frame_alloc(&zones.info[znum], order)
    1115             + zones.info[znum].base;
     949        pfn_t pfn = zone_frame_alloc(&zones.info[znum], count,
     950            frame_constraint) + zones.info[znum].base;
    1116951       
    1117952        irq_spinlock_unlock(&zones.lock, true);
     
    1120955                *pzone = znum;
    1121956       
    1122         if (flags & FRAME_KA)
    1123                 return (void *) PA2KA(PFN2ADDR(pfn));
    1124        
    1125         return (void *) PFN2ADDR(pfn);
    1126 }
    1127 
    1128 void *frame_alloc(uint8_t order, frame_flags_t flags)
    1129 {
    1130         return frame_alloc_generic(order, flags, NULL);
    1131 }
    1132 
    1133 void *frame_alloc_noreserve(uint8_t order, frame_flags_t flags)
    1134 {
    1135         return frame_alloc_generic(order, flags | FRAME_NO_RESERVE, NULL);
    1136 }
    1137 
    1138 /** Free a frame.
    1139  *
    1140  * Find respective frame structure for supplied physical frame address.
    1141  * Decrement frame reference count. If it drops to zero, move the frame
    1142  * structure to free list.
    1143  *
    1144  * @param frame Physical Address of of the frame to be freed.
     957        return PFN2ADDR(pfn);
     958}
     959
     960uintptr_t frame_alloc(size_t count, frame_flags_t flags, uintptr_t constraint)
     961{
     962        return frame_alloc_generic(count, flags, constraint, NULL);
     963}
     964
     965/** Free frames of physical memory.
     966 *
     967 * Find respective frame structures for supplied physical frames.
     968 * Decrement each frame reference count. If it drops to zero, mark
     969 * the frames as available.
     970 *
     971 * @param start Physical Address of the first frame to be freed.
     972 * @param count Number of frames to free.
    1145973 * @param flags Flags to control memory reservation.
    1146974 *
    1147975 */
    1148 void frame_free_generic(uintptr_t frame, frame_flags_t flags)
    1149 {
    1150         size_t size;
     976void frame_free_generic(uintptr_t start, size_t count, frame_flags_t flags)
     977{
     978        size_t freed = 0;
    1151979       
    1152980        irq_spinlock_lock(&zones.lock, true);
    1153981       
    1154         /*
    1155          * First, find host frame zone for addr.
    1156          */
    1157         pfn_t pfn = ADDR2PFN(frame);
    1158         size_t znum = find_zone(pfn, 1, 0);
    1159 
    1160         ASSERT(znum != (size_t) -1);
    1161        
    1162         size = zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
     982        for (size_t i = 0; i < count; i++) {
     983                /*
     984                 * First, find host frame zone for addr.
     985                 */
     986                pfn_t pfn = ADDR2PFN(start) + i;
     987                size_t znum = find_zone(pfn, 1, 0);
     988               
     989                ASSERT(znum != (size_t) -1);
     990               
     991                freed += zone_frame_free(&zones.info[znum],
     992                    pfn - zones.info[znum].base);
     993        }
    1163994       
    1164995        irq_spinlock_unlock(&zones.lock, true);
     
    1166997        /*
    1167998         * Signal that some memory has been freed.
     999         * Since the mem_avail_mtx is an active mutex,
     1000         * we need to disable interruptsto prevent deadlock
     1001         * with TLB shootdown.
    11681002         */
    1169 
    1170        
    1171         /*
    1172          * Since the mem_avail_mtx is an active mutex, we need to disable interrupts
    1173          * to prevent deadlock with TLB shootdown.
    1174          */
     1003       
    11751004        ipl_t ipl = interrupts_disable();
    11761005        mutex_lock(&mem_avail_mtx);
     1006       
    11771007        if (mem_avail_req > 0)
    1178                 mem_avail_req -= min(mem_avail_req, size);
     1008                mem_avail_req -= min(mem_avail_req, freed);
    11791009       
    11801010        if (mem_avail_req == 0) {
     
    11821012                condvar_broadcast(&mem_avail_cv);
    11831013        }
     1014       
    11841015        mutex_unlock(&mem_avail_mtx);
    11851016        interrupts_restore(ipl);
    11861017       
    11871018        if (!(flags & FRAME_NO_RESERVE))
    1188                 reserve_free(size);
    1189 }
    1190 
    1191 void frame_free(uintptr_t frame)
    1192 {
    1193         frame_free_generic(frame, 0);
    1194 }
    1195 
    1196 void frame_free_noreserve(uintptr_t frame)
    1197 {
    1198         frame_free_generic(frame, FRAME_NO_RESERVE);
     1019                reserve_free(freed);
     1020}
     1021
     1022void frame_free(uintptr_t frame, size_t count)
     1023{
     1024        frame_free_generic(frame, count, 0);
     1025}
     1026
     1027void frame_free_noreserve(uintptr_t frame, size_t count)
     1028{
     1029        frame_free_generic(frame, count, FRAME_NO_RESERVE);
    11991030}
    12001031
     
    12301061        irq_spinlock_lock(&zones.lock, true);
    12311062       
    1232         size_t i;
    1233         for (i = 0; i < count; i++) {
     1063        for (size_t i = 0; i < count; i++) {
    12341064                size_t znum = find_zone(start + i, 1, 0);
     1065               
    12351066                if (znum == (size_t) -1)  /* PFN not found */
    12361067                        continue;
     
    12571088        /* Tell the architecture to create some memory */
    12581089        frame_low_arch_init();
     1090       
    12591091        if (config.cpu_active == 1) {
    12601092                frame_mark_unavailable(ADDR2PFN(KA2PA(config.base)),
     
    12631095                    SIZE2FRAMES(config.stack_size));
    12641096               
    1265                 size_t i;
    1266                 for (i = 0; i < init.cnt; i++) {
    1267                         pfn_t pfn = ADDR2PFN(init.tasks[i].paddr);
    1268                         frame_mark_unavailable(pfn,
     1097                for (size_t i = 0; i < init.cnt; i++)
     1098                        frame_mark_unavailable(ADDR2PFN(init.tasks[i].paddr),
    12691099                            SIZE2FRAMES(init.tasks[i].size));
    1270                 }
    12711100               
    12721101                if (ballocs.size)
     
    12741103                            SIZE2FRAMES(ballocs.size));
    12751104               
    1276                 /* Black list first frame, as allocating NULL would
     1105                /*
     1106                 * Blacklist first frame, as allocating NULL would
    12771107                 * fail in some places
    12781108                 */
    12791109                frame_mark_unavailable(0, 1);
    12801110        }
     1111       
    12811112        frame_high_arch_init();
    12821113}
     
    12841115/** Adjust bounds of physical memory region according to low/high memory split.
    12851116 *
    1286  * @param low[in]       If true, the adjustment is performed to make the region
    1287  *                      fit in the low memory. Otherwise the adjustment is
    1288  *                      performed to make the region fit in the high memory.
    1289  * @param basep[inout]  Pointer to a variable which contains the region's base
    1290  *                      address and which may receive the adjusted base address.
    1291  * @param sizep[inout]  Pointer to a variable which contains the region's size
    1292  *                      and which may receive the adjusted size.
    1293  * @retun               True if the region still exists even after the
    1294  *                      adjustment, false otherwise.
     1117 * @param low[in]      If true, the adjustment is performed to make the region
     1118 *                     fit in the low memory. Otherwise the adjustment is
     1119 *                     performed to make the region fit in the high memory.
     1120 * @param basep[inout] Pointer to a variable which contains the region's base
     1121 *                     address and which may receive the adjusted base address.
     1122 * @param sizep[inout] Pointer to a variable which contains the region's size
     1123 *                     and which may receive the adjusted size.
     1124 *
     1125 * @return True if the region still exists even after the adjustment.
     1126 * @return False otherwise.
     1127 *
    12951128 */
    12961129bool frame_adjust_zone_bounds(bool low, uintptr_t *basep, size_t *sizep)
    12971130{
    12981131        uintptr_t limit = KA2PA(config.identity_base) + config.identity_size;
    1299 
     1132       
    13001133        if (low) {
    13011134                if (*basep > limit)
    13021135                        return false;
     1136               
    13031137                if (*basep + *sizep > limit)
    13041138                        *sizep = limit - *basep;
     
    13061140                if (*basep + *sizep <= limit)
    13071141                        return false;
     1142               
    13081143                if (*basep <= limit) {
    13091144                        *sizep -= limit - *basep;
     
    13111146                }
    13121147        }
     1148       
    13131149        return true;
    13141150}
     
    13221158       
    13231159        uint64_t total = 0;
    1324         size_t i;
    1325         for (i = 0; i < zones.count; i++)
     1160       
     1161        for (size_t i = 0; i < zones.count; i++)
    13261162                total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    13271163       
     
    13461182        *free = 0;
    13471183       
    1348         size_t i;
    1349         for (i = 0; i < zones.count; i++) {
     1184        for (size_t i = 0; i < zones.count; i++) {
    13501185                *total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
    13511186               
     
    13751210        /*
    13761211         * Because printing may require allocation of memory, we may not hold
    1377          * the frame allocator locks when printing zone statistics.  Therefore,
     1212         * the frame allocator locks when printing zone statistics. Therefore,
    13781213         * we simply gather the statistics under the protection of the locks and
    13791214         * print the statistics when the locks have been released.
     
    13841219         */
    13851220       
    1386         size_t i;
    1387         for (i = 0;; i++) {
     1221        size_t free_lowmem = 0;
     1222        size_t free_highmem = 0;
     1223        size_t free_highprio = 0;
     1224       
     1225        for (size_t i = 0;; i++) {
    13881226                irq_spinlock_lock(&zones.lock, true);
    13891227               
     
    13931231                }
    13941232               
    1395                 uintptr_t base = PFN2ADDR(zones.info[i].base);
     1233                pfn_t fbase = zones.info[i].base;
     1234                uintptr_t base = PFN2ADDR(fbase);
    13961235                size_t count = zones.info[i].count;
    13971236                zone_flags_t flags = zones.info[i].flags;
     
    13991238                size_t busy_count = zones.info[i].busy_count;
    14001239               
     1240                bool available = ((flags & ZONE_AVAILABLE) != 0);
     1241                bool lowmem = ((flags & ZONE_LOWMEM) != 0);
     1242                bool highmem = ((flags & ZONE_HIGHMEM) != 0);
     1243                bool highprio = is_high_priority(fbase, count);
     1244               
     1245                if (available) {
     1246                        if (lowmem)
     1247                                free_lowmem += free_count;
     1248                       
     1249                        if (highmem)
     1250                                free_highmem += free_count;
     1251                       
     1252                        if (highprio) {
     1253                                free_highprio += free_count;
     1254                        } else {
     1255                                /*
     1256                                 * Walk all frames of the zone and examine
     1257                                 * all high priority memory to get accurate
     1258                                 * statistics.
     1259                                 */
     1260                               
     1261                                for (size_t index = 0; index < count; index++) {
     1262                                        if (is_high_priority(fbase + index, 0)) {
     1263                                                if (!bitmap_get(&zones.info[i].bitmap, index))
     1264                                                        free_highprio++;
     1265                                        } else
     1266                                                break;
     1267                                }
     1268                        }
     1269                }
     1270               
    14011271                irq_spinlock_unlock(&zones.lock, true);
    1402                
    1403                 bool available = ((flags & ZONE_AVAILABLE) != 0);
    14041272               
    14051273                printf("%-4zu", i);
     
    14261294                printf("\n");
    14271295        }
     1296       
     1297        printf("\n");
     1298       
     1299        uint64_t size;
     1300        const char *size_suffix;
     1301       
     1302        bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
     1303            false);
     1304        printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
     1305            free_lowmem, size, size_suffix);
     1306       
     1307        bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
     1308            false);
     1309        printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
     1310            free_highmem, size, size_suffix);
     1311       
     1312        bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
     1313            false);
     1314        printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
     1315            free_highprio, size, size_suffix);
    14281316}
    14291317
     
    14381326        size_t znum = (size_t) -1;
    14391327       
    1440         size_t i;
    1441         for (i = 0; i < zones.count; i++) {
     1328        for (size_t i = 0; i < zones.count; i++) {
    14421329                if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) {
    14431330                        znum = i;
     
    14521339        }
    14531340       
    1454         uintptr_t base = PFN2ADDR(zones.info[i].base);
    1455         zone_flags_t flags = zones.info[i].flags;
    1456         size_t count = zones.info[i].count;
    1457         size_t free_count = zones.info[i].free_count;
    1458         size_t busy_count = zones.info[i].busy_count;
     1341        size_t free_lowmem = 0;
     1342        size_t free_highmem = 0;
     1343        size_t free_highprio = 0;
     1344       
     1345        pfn_t fbase = zones.info[znum].base;
     1346        uintptr_t base = PFN2ADDR(fbase);
     1347        zone_flags_t flags = zones.info[znum].flags;
     1348        size_t count = zones.info[znum].count;
     1349        size_t free_count = zones.info[znum].free_count;
     1350        size_t busy_count = zones.info[znum].busy_count;
     1351       
     1352        bool available = ((flags & ZONE_AVAILABLE) != 0);
     1353        bool lowmem = ((flags & ZONE_LOWMEM) != 0);
     1354        bool highmem = ((flags & ZONE_HIGHMEM) != 0);
     1355        bool highprio = is_high_priority(fbase, count);
     1356       
     1357        if (available) {
     1358                if (lowmem)
     1359                        free_lowmem = free_count;
     1360               
     1361                if (highmem)
     1362                        free_highmem = free_count;
     1363               
     1364                if (highprio) {
     1365                        free_highprio = free_count;
     1366                } else {
     1367                        /*
     1368                         * Walk all frames of the zone and examine
     1369                         * all high priority memory to get accurate
     1370                         * statistics.
     1371                         */
     1372                       
     1373                        for (size_t index = 0; index < count; index++) {
     1374                                if (is_high_priority(fbase + index, 0)) {
     1375                                        if (!bitmap_get(&zones.info[znum].bitmap, index))
     1376                                                free_highprio++;
     1377                                } else
     1378                                        break;
     1379                        }
     1380                }
     1381        }
    14591382       
    14601383        irq_spinlock_unlock(&zones.lock, true);
    1461        
    1462         bool available = ((flags & ZONE_AVAILABLE) != 0);
    14631384       
    14641385        uint64_t size;
    14651386        const char *size_suffix;
     1387       
    14661388        bin_order_suffix(FRAMES2SIZE(count), &size, &size_suffix, false);
    14671389       
    1468         printf("Zone number:       %zu\n", znum);
    1469         printf("Zone base address: %p\n", (void *) base);
    1470         printf("Zone size:         %zu frames (%" PRIu64 " %s)\n", count,
     1390        printf("Zone number:             %zu\n", znum);
     1391        printf("Zone base address:       %p\n", (void *) base);
     1392        printf("Zone size:               %zu frames (%" PRIu64 " %s)\n", count,
    14711393            size, size_suffix);
    1472         printf("Zone flags:        %c%c%c%c%c\n",
     1394        printf("Zone flags:              %c%c%c%c%c\n",
    14731395            available ? 'A' : '-',
    14741396            (flags & ZONE_RESERVED) ? 'R' : '-',
     
    14801402                bin_order_suffix(FRAMES2SIZE(busy_count), &size, &size_suffix,
    14811403                    false);
    1482                 printf("Allocated space:   %zu frames (%" PRIu64 " %s)\n",
     1404                printf("Allocated space:         %zu frames (%" PRIu64 " %s)\n",
    14831405                    busy_count, size, size_suffix);
     1406               
    14841407                bin_order_suffix(FRAMES2SIZE(free_count), &size, &size_suffix,
    14851408                    false);
    1486                 printf("Available space:   %zu frames (%" PRIu64 " %s)\n",
     1409                printf("Available space:         %zu frames (%" PRIu64 " %s)\n",
    14871410                    free_count, size, size_suffix);
     1411               
     1412                bin_order_suffix(FRAMES2SIZE(free_lowmem), &size, &size_suffix,
     1413                    false);
     1414                printf("Available low memory:    %zu frames (%" PRIu64 " %s)\n",
     1415                    free_lowmem, size, size_suffix);
     1416               
     1417                bin_order_suffix(FRAMES2SIZE(free_highmem), &size, &size_suffix,
     1418                    false);
     1419                printf("Available high memory:   %zu frames (%" PRIu64 " %s)\n",
     1420                    free_highmem, size, size_suffix);
     1421               
     1422                bin_order_suffix(FRAMES2SIZE(free_highprio), &size, &size_suffix,
     1423                    false);
     1424                printf("Available high priority: %zu frames (%" PRIu64 " %s)\n",
     1425                    free_highprio, size, size_suffix);
    14881426        }
    14891427}
  • kernel/generic/src/mm/km.c

    rdba3e2c r8b863a62  
    239239uintptr_t km_temporary_page_get(uintptr_t *framep, frame_flags_t flags)
    240240{
    241         uintptr_t frame;
    242         uintptr_t page;
    243 
    244241        ASSERT(THREAD);
    245242        ASSERT(framep);
    246243        ASSERT(!(flags & ~(FRAME_NO_RESERVE | FRAME_ATOMIC)));
    247 
     244       
    248245        /*
    249246         * Allocate a frame, preferably from high memory.
    250247         */
    251         frame = (uintptr_t) frame_alloc(ONE_FRAME,
    252             FRAME_HIGHMEM | FRAME_ATOMIC | flags);
     248        uintptr_t page;
     249        uintptr_t frame =
     250            frame_alloc(1, FRAME_HIGHMEM | FRAME_ATOMIC | flags, 0);
    253251        if (frame) {
    254252                page = km_map(frame, PAGE_SIZE,
    255253                    PAGE_READ | PAGE_WRITE | PAGE_CACHEABLE);
    256                 ASSERT(page);   // FIXME
     254               
     255                // FIXME
     256                ASSERT(page);
    257257        } else {
    258                 frame = (uintptr_t) frame_alloc(ONE_FRAME,
    259                     FRAME_LOWMEM | flags);
     258                frame = frame_alloc(1, FRAME_LOWMEM | flags, 0);
    260259                if (!frame)
    261260                        return (uintptr_t) NULL;
     261               
    262262                page = PA2KA(frame);
    263263        }
    264 
     264       
    265265        *framep = frame;
    266         return page;   
     266        return page;
    267267}
    268268
  • kernel/generic/src/mm/page.c

    rdba3e2c r8b863a62  
    169169}
    170170
    171 int page_find_mapping(uintptr_t virt, void **phys)
     171int page_find_mapping(uintptr_t virt, uintptr_t *phys)
    172172{
    173173        page_table_lock(AS, true);
     
    179179        }
    180180       
    181         *phys = (void *) PTE_GET_FRAME(pte) +
     181        *phys = PTE_GET_FRAME(pte) +
    182182            (virt - ALIGN_DOWN(virt, PAGE_SIZE));
    183183       
     
    193193 *
    194194 */
    195 sysarg_t sys_page_find_mapping(uintptr_t virt, void *phys_ptr)
    196 {
    197         void *phys;
     195sysarg_t sys_page_find_mapping(uintptr_t virt, uintptr_t *phys_ptr)
     196{
     197        uintptr_t phys;
    198198        int rc = page_find_mapping(virt, &phys);
    199199        if (rc != EOK)
  • kernel/generic/src/mm/slab.c

    rdba3e2c r8b863a62  
    182182        size_t zone = 0;
    183183       
    184         void *data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
    185         if (!data) {
     184        uintptr_t data_phys =
     185            frame_alloc_generic(cache->frames, flags, 0, &zone);
     186        if (!data_phys)
    186187                return NULL;
    187         }
     188       
     189        void *data = (void *) PA2KA(data_phys);
    188190       
    189191        slab_t *slab;
     
    193195                slab = slab_alloc(slab_extern_cache, flags);
    194196                if (!slab) {
    195                         frame_free(KA2PA(data));
     197                        frame_free(KA2PA(data), cache->frames);
    196198                        return NULL;
    197199                }
    198200        } else {
    199                 fsize = (PAGE_SIZE << cache->order);
     201                fsize = FRAMES2SIZE(cache->frames);
    200202                slab = data + fsize - sizeof(*slab);
    201203        }
     
    203205        /* Fill in slab structures */
    204206        size_t i;
    205         for (i = 0; i < ((size_t) 1 << cache->order); i++)
     207        for (i = 0; i < cache->frames; i++)
    206208                frame_set_parent(ADDR2PFN(KA2PA(data)) + i, slab, zone);
    207209       
     
    225227NO_TRACE static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
    226228{
    227         frame_free(KA2PA(slab->start));
     229        frame_free(KA2PA(slab->start), slab->cache->frames);
    228230        if (!(cache->flags & SLAB_CACHE_SLINSIDE))
    229231                slab_free(slab_extern_cache, slab);
     
    231233        atomic_dec(&cache->allocated_slabs);
    232234       
    233         return (1 << cache->order);
     235        return cache->frames;
    234236}
    235237
     
    558560{
    559561        if (cache->flags & SLAB_CACHE_SLINSIDE)
    560                 return ((PAGE_SIZE << cache->order)
    561                     - sizeof(slab_t)) / cache->size;
     562                return (FRAMES2SIZE(cache->frames) - sizeof(slab_t)) /
     563                    cache->size;
    562564        else
    563                 return (PAGE_SIZE << cache->order) / cache->size;
     565                return FRAMES2SIZE(cache->frames) / cache->size;
    564566}
    565567
     
    570572{
    571573        size_t objects = comp_objects(cache);
    572         size_t ssize = PAGE_SIZE << cache->order;
     574        size_t ssize = FRAMES2SIZE(cache->frames);
    573575       
    574576        if (cache->flags & SLAB_CACHE_SLINSIDE)
     
    634636                cache->flags |= SLAB_CACHE_SLINSIDE;
    635637       
    636         /* Minimum slab order */
    637         size_t pages = SIZE2FRAMES(cache->size);
    638        
    639         /* We need the 2^order >= pages */
    640         if (pages == 1)
    641                 cache->order = 0;
    642         else
    643                 cache->order = fnzb(pages - 1) + 1;
     638        /* Minimum slab frames */
     639        cache->frames = SIZE2FRAMES(cache->size);
    644640       
    645641        while (badness(cache) > SLAB_MAX_BADNESS(cache))
    646                 cache->order += 1;
     642                cache->frames <<= 1;
    647643       
    648644        cache->objects = comp_objects(cache);
     
    810806       
    811807        size_t frames = 0;
    812         list_foreach(slab_cache_list, cur) {
    813                 slab_cache_t *cache = list_get_instance(cur, slab_cache_t, link);
     808        list_foreach(slab_cache_list, link, slab_cache_t, cache) {
    814809                frames += _slab_reclaim(cache, flags);
    815810        }
     
    871866               
    872867                const char *name = cache->name;
    873                 uint8_t order = cache->order;
     868                size_t frames = cache->frames;
    874869                size_t size = cache->size;
    875870                size_t objects = cache->objects;
     
    881876                irq_spinlock_unlock(&slab_cache_lock, true);
    882877               
    883                 printf("%-18s %8zu %8u %8zu %8ld %8ld %8ld %-5s\n",
    884                     name, size, (1 << order), objects, allocated_slabs,
     878                printf("%-18s %8zu %8zu %8zu %8ld %8ld %8ld %-5s\n",
     879                    name, size, frames, objects, allocated_slabs,
    885880                    cached_objs, allocated_objs,
    886881                    flags & SLAB_CACHE_SLINSIDE ? "in" : "out");
     
    936931        irq_spinlock_lock(&slab_cache_lock, false);
    937932       
    938         list_foreach(slab_cache_list, cur) {
    939                 slab_cache_t *slab = list_get_instance(cur, slab_cache_t, link);
     933        list_foreach(slab_cache_list, link, slab_cache_t, slab) {
    940934                if ((slab->flags & SLAB_CACHE_MAGDEFERRED) !=
    941935                    SLAB_CACHE_MAGDEFERRED)
  • kernel/generic/src/proc/program.c

    rdba3e2c r8b863a62  
    4949#include <lib/elf_load.h>
    5050#include <errno.h>
    51 #include <print.h>
     51#include <log.h>
    5252#include <syscall/copy.h>
    5353#include <proc/program.h>
     
    155155               
    156156                program_loader = image_addr;
    157                 printf("Program loader at %p\n", (void *) image_addr);
     157                log(LF_OTHER, LVL_NOTE, "Program loader at %p", (void *) image_addr);
    158158               
    159159                return EOK;
     
    181181        if (!loader) {
    182182                as_destroy(as);
    183                 printf("Cannot spawn loader as none was registered\n");
     183                log(LF_OTHER, LVL_ERROR,
     184                    "Cannot spawn loader as none was registered");
    184185                return ENOENT;
    185186        }
     
    189190        if (prg->loader_status != EE_OK) {
    190191                as_destroy(as);
    191                 printf("Cannot spawn loader (%s)\n",
     192                log(LF_OTHER, LVL_ERROR, "Cannot spawn loader (%s)",
    192193                    elf_error(prg->loader_status));
    193194                return ENOENT;
  • kernel/generic/src/proc/scheduler.c

    rdba3e2c r8b863a62  
    6161#include <cpu.h>
    6262#include <print.h>
     63#include <log.h>
    6364#include <debug.h>
    6465#include <stacktrace.h>
     
    517518       
    518519#ifdef SCHEDULER_VERBOSE
    519         printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
    520             ", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority,
     520        log(LF_OTHER, LVL_DEBUG,
     521            "cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64
     522            ", nrdy=%" PRIua ")", CPU->id, THREAD->tid, THREAD->priority,
    521523            THREAD->ticks, atomic_get(&CPU->nrdy));
    522524#endif
     
    663665                               
    664666#ifdef KCPULB_VERBOSE
    665                                 printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, "
    666                                     "nrdy=%ld, avg=%ld\n", CPU->id, t->tid,
     667                                log(LF_OTHER, LVL_DEBUG,
     668                                    "kcpulb%u: TID %" PRIu64 " -> cpu%u, "
     669                                    "nrdy=%ld, avg=%ld", CPU->id, t->tid,
    667670                                    CPU->id, atomic_get(&CPU->nrdy),
    668671                                    atomic_get(&nrdy) / config.cpu_active);
     
    739742                       
    740743                        printf("\trq[%u]: ", i);
    741                         list_foreach(cpus[cpu].rq[i].rq, cur) {
    742                                 thread_t *thread = list_get_instance(cur,
    743                                     thread_t, rq_link);
     744                        list_foreach(cpus[cpu].rq[i].rq, rq_link, thread_t,
     745                            thread) {
    744746                                printf("%" PRIu64 "(%s) ", thread->tid,
    745747                                    thread_states[thread->state]);
  • kernel/generic/src/proc/task.c

    rdba3e2c r8b863a62  
    452452       
    453453        /* Current values of threads */
    454         list_foreach(task->threads, cur) {
    455                 thread_t *thread = list_get_instance(cur, thread_t, th_link);
    456                
     454        list_foreach(task->threads, th_link, thread_t, thread) {
    457455                irq_spinlock_lock(&thread->lock, false);
    458456               
     
    484482         */
    485483       
    486         list_foreach(task->threads, cur) {
    487                 thread_t *thread = list_get_instance(cur, thread_t, th_link);
     484        list_foreach(task->threads, th_link, thread_t, thread) {
    488485                bool sleeping = false;
    489486               
  • kernel/generic/src/proc/thread.c

    rdba3e2c r8b863a62  
    192192        kmflags &= ~FRAME_HIGHMEM;
    193193       
    194         thread->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
    195         if (!thread->kstack) {
     194        uintptr_t stack_phys =
     195            frame_alloc(STACK_FRAMES, kmflags, STACK_SIZE - 1);
     196        if (!stack_phys) {
    196197#ifdef CONFIG_FPU
    197198                if (thread->saved_fpu_context)
     
    201202        }
    202203       
     204        thread->kstack = (uint8_t *) PA2KA(stack_phys);
     205       
    203206#ifdef CONFIG_UDEBUG
    204207        mutex_initialize(&thread->udebug.lock, MUTEX_PASSIVE);
     
    216219        thr_destructor_arch(thread);
    217220       
    218         frame_free(KA2PA(thread->kstack));
     221        frame_free(KA2PA(thread->kstack), STACK_FRAMES);
    219222       
    220223#ifdef CONFIG_FPU
  • kernel/generic/src/synch/futex.c

    rdba3e2c r8b863a62  
    274274        mutex_lock(&TASK->futexes_lock);
    275275
    276         list_foreach(TASK->futexes.leaf_list, cur) {
    277                 btree_node_t *node;
     276        list_foreach(TASK->futexes.leaf_list, leaf_link, btree_node_t, node) {
    278277                unsigned int i;
    279278               
    280                 node = list_get_instance(cur, btree_node_t, leaf_link);
    281279                for (i = 0; i < node->keys; i++) {
    282280                        futex_t *ftx;
  • kernel/generic/src/syscall/syscall.c

    rdba3e2c r8b863a62  
    5656#include <console/console.h>
    5757#include <udebug/udebug.h>
     58#include <log.h>
    5859
    5960/** Dispatch system call */
     
    8687                rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
    8788        } else {
    88                 printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
     89                log(LF_OTHER, LVL_ERROR,
     90                    "Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
    8991                task_kill_self(true);
    9092        }
     
    120122syshandler_t syscall_table[SYSCALL_END] = {
    121123        /* System management syscalls. */
    122         (syshandler_t) sys_klog,
     124        (syshandler_t) sys_kio,
    123125        (syshandler_t) sys_tls_set,
    124126       
     
    190192       
    191193        /* Kernel console syscalls. */
    192         (syshandler_t) sys_debug_activate_console
     194        (syshandler_t) sys_debug_activate_console,
     195       
     196        (syshandler_t) sys_klog,
    193197};
    194198
  • kernel/generic/src/sysinfo/stats.c

    rdba3e2c r8b863a62  
    175175       
    176176        /* Walk the B+ tree and count pages */
    177         list_foreach(as->as_area_btree.leaf_list, cur) {
    178                 btree_node_t *node =
    179                     list_get_instance(cur, btree_node_t, leaf_link);
    180                
     177        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t,
     178            node) {
    181179                unsigned int i;
    182180                for (i = 0; i < node->keys; i++) {
     
    218216       
    219217        /* Walk the B+ tree and count pages */
    220         list_foreach(as->as_area_btree.leaf_list, cur) {
    221                 btree_node_t *node =
    222                     list_get_instance(cur, btree_node_t, leaf_link);
    223                
     218        list_foreach(as->as_area_btree.leaf_list, leaf_link, btree_node_t, node) {
    224219                unsigned int i;
    225220                for (i = 0; i < node->keys; i++) {
  • kernel/generic/src/time/clock.c

    rdba3e2c r8b863a62  
    8181void clock_counter_init(void)
    8282{
    83         void *faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
    84         if (!faddr)
     83        uintptr_t faddr = frame_alloc(1, FRAME_ATOMIC, 0);
     84        if (faddr == 0)
    8585                panic("Cannot allocate page for clock.");
    8686       
     
    9191        uptime->useconds = 0;
    9292       
    93         clock_parea.pbase = (uintptr_t) faddr;
     93        clock_parea.pbase = faddr;
    9494        clock_parea.frames = 1;
    9595        clock_parea.unpriv = true;
  • kernel/generic/src/udebug/udebug.c

    rdba3e2c r8b863a62  
    406406       
    407407        /* Finish debugging of all userspace threads */
    408         list_foreach(task->threads, cur) {
    409                 thread_t *thread = list_get_instance(cur, thread_t, th_link);
    410                
     408        list_foreach(task->threads, th_link, thread_t, thread) {
    411409                mutex_lock(&thread->udebug.lock);
    412410               
  • kernel/generic/src/udebug/udebug_ops.c

    rdba3e2c r8b863a62  
    196196        /* Set udebug.active on all of the task's userspace threads. */
    197197       
    198         list_foreach(TASK->threads, cur) {
    199                 thread_t *thread = list_get_instance(cur, thread_t, th_link);
    200                
     198        list_foreach(TASK->threads, th_link, thread_t, thread) {
    201199                mutex_lock(&thread->udebug.lock);
    202200                if (thread->uspace) {
     
    389387       
    390388        /* FIXME: make sure the thread isn't past debug shutdown... */
    391         list_foreach(TASK->threads, cur) {
    392                 thread_t *thread = list_get_instance(cur, thread_t, th_link);
    393                
     389        list_foreach(TASK->threads, th_link, thread_t, thread) {
    394390                irq_spinlock_lock(&thread->lock, false);
    395391                bool uspace = thread->uspace;
Note: See TracChangeset for help on using the changeset viewer.