Changeset ca62f86 in mainline for kernel


Ignore:
Timestamp:
2013-09-09T17:52:40Z (12 years ago)
Author:
Jakub Klama <jakub.klama@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f7bb6d1
Parents:
6ad185d (diff), a1ecb88 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
kernel
Files:
32 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/src/ddi/ddi.c

    r6ad185d rca62f86  
    4242#include <errno.h>
    4343#include <arch/cpu.h>
     44#include <cpu.h>
    4445#include <arch.h>
    4546#include <align.h>
     
    5859int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
    5960{
    60         size_t bits = ioaddr + size;
    61         if (bits > IO_PORTS)
     61        size_t elements = ioaddr + size;
     62        if (elements > IO_PORTS)
    6263                return ENOENT;
    6364       
    64         if (task->arch.iomap.bits < bits) {
     65        if (task->arch.iomap.elements < elements) {
    6566                /*
    6667                 * The I/O permission bitmap is too small and needs to be grown.
    6768                 */
    6869               
    69                 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
    70                 if (!newmap)
     70                void *store = malloc(bitmap_size(elements, 0), FRAME_ATOMIC);
     71                if (!store)
    7172                        return ENOMEM;
    7273               
    7374                bitmap_t oldiomap;
    74                 bitmap_initialize(&oldiomap, task->arch.iomap.map,
     75                bitmap_initialize(&oldiomap, task->arch.iomap.elements, 0,
    7576                    task->arch.iomap.bits);
    76                 bitmap_initialize(&task->arch.iomap, newmap, bits);
     77               
     78                bitmap_initialize(&task->arch.iomap, elements, 0, store);
    7779               
    7880                /*
    7981                 * Mark the new range inaccessible.
    8082                 */
    81                 bitmap_set_range(&task->arch.iomap, oldiomap.bits,
    82                     bits - oldiomap.bits);
     83                bitmap_set_range(&task->arch.iomap, oldiomap.elements,
     84                    elements - oldiomap.elements);
    8385               
    8486                /*
     
    8890                if (oldiomap.bits) {
    8991                        bitmap_copy(&task->arch.iomap, &oldiomap,
    90                             oldiomap.bits);
    91                         free(oldiomap.map);
     92                            oldiomap.elements);
     93                       
     94                        free(oldiomap.bits);
    9295                }
    9396        }
     
    9699         * Enable the range and we are done.
    97100         */
    98         bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
     101        bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, size);
    99102       
    100103        /*
     
    118121        /* First, copy the I/O Permission Bitmap. */
    119122        irq_spinlock_lock(&TASK->lock, false);
     123       
    120124        size_t ver = TASK->arch.iomapver;
    121         size_t bits = TASK->arch.iomap.bits;
    122         if (bits) {
    123                 ASSERT(TASK->arch.iomap.map);
     125        size_t elements = TASK->arch.iomap.elements;
     126       
     127        if (elements > 0) {
     128                ASSERT(TASK->arch.iomap.bits);
    124129               
    125130                bitmap_t iomap;
    126                 bitmap_initialize(&iomap, CPU->arch.tss->iomap,
    127                     TSS_IOMAP_SIZE * 8);
    128                 bitmap_copy(&iomap, &TASK->arch.iomap, bits);
     131                bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8, 0,
     132                    CPU->arch.tss->iomap);
     133                bitmap_copy(&iomap, &TASK->arch.iomap, elements);
    129134               
    130135                /*
     
    132137                 * I/O access.
    133138                 */
    134                 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
     139                bitmap_set_range(&iomap, elements,
     140                    ALIGN_UP(elements, 8) - elements);
     141               
    135142                /*
    136143                 * It is safe to set the trailing eight bits because of the
    137144                 * extra convenience byte in TSS_IOMAP_SIZE.
    138145                 */
    139                 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
     146                bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
    140147        }
     148       
    141149        irq_spinlock_unlock(&TASK->lock, false);
    142150       
    143151        /*
    144152         * Second, adjust TSS segment limit.
    145          * Take the extra ending byte will all bits set into account.
     153         * Take the extra ending byte with all bits set into account.
    146154         */
    147155        ptr_16_64_t cpugdtr;
     
    149157       
    150158        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    151         gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
     159        size_t size = bitmap_size(elements, 0);
     160        gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
    152161        gdtr_load(&cpugdtr);
    153162       
  • kernel/arch/amd64/src/proc/task.c

    r6ad185d rca62f86  
    3434
    3535#include <proc/task.h>
     36#include <typedefs.h>
     37#include <adt/bitmap.h>
    3638#include <mm/slab.h>
    37 #include <typedefs.h>
    3839
    3940/** Perform amd64 specific task initialization.
     
    4546{
    4647        task->arch.iomapver = 0;
    47         bitmap_initialize(&task->arch.iomap, NULL, 0);
     48        bitmap_initialize(&task->arch.iomap, 0, 0, NULL);
    4849}
    4950
     
    5556void task_destroy_arch(task_t *task)
    5657{
    57         if (task->arch.iomap.map)
    58                 free(task->arch.iomap.map);
     58        if (task->arch.iomap.bits != NULL)
     59                free(task->arch.iomap.bits);
    5960}
    6061
  • kernel/arch/arm32/include/arch/asm.h

    r6ad185d rca62f86  
    3838
    3939#include <typedefs.h>
     40#include <arch/cp15.h>
    4041#include <arch/stack.h>
    4142#include <config.h>
     
    5152 * chapter 2.3.8 p.2-22 (52 in the PDF)
    5253 *
    53  * @note Although mcr p15, 0, R0, c7, c0, 4 is defined in ARM Architecture
    54  * reference manual for armv4/5 CP15 implementation is mandatory only for
    55  * armv6+.
     54 * @note Although CP15WFI (mcr p15, 0, R0, c7, c0, 4) is defined in ARM
     55 * Architecture reference manual for armv4/5, CP15 implementation is mandatory
     56 * only for armv6+.
    5657 */
    5758NO_TRACE static inline void cpu_sleep(void)
     
    6061        asm volatile ( "wfe" );
    6162#elif defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_arm926ej_s) | defined(PROCESSOR_arm920t)
    62         asm volatile ( "mcr p15, 0, R0, c7, c0, 4" );
     63        WFI_write(0);
    6364#endif
    6465}
  • kernel/arch/arm32/include/arch/cp15.h

    r6ad185d rca62f86  
    171171        CCSIDR_LINESIZE_MASK = 0x7,
    172172        CCSIDR_LINESIZE_SHIFT = 0,
     173#define CCSIDR_SETS(val) \
     174        (((val >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK) + 1)
     175#define CCSIDR_WAYS(val) \
     176        (((val >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK) + 1)
     177/* The register value is log(linesize_in_words) - 2 */
     178#define CCSIDR_LINESIZE_LOG(val) \
     179        (((val >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK) + 2 + 2)
    173180};
    174181CONTROL_REG_GEN_READ(CCSIDR, c0, 1, c0, 0);
     
    187194        CLIDR_UNI_CACHE = 0x4,
    188195        CLIDR_CACHE_MASK = 0x7,
    189 #define CLIDR_CACHE(level, val)   ((val >> (level - 1) * 3) & CLIDR_CACHE_MASK)
     196/** levels counted from 0 */
     197#define CLIDR_CACHE(level, val)   ((val >> (level * 3)) & CLIDR_CACHE_MASK)
    190198};
    191199CONTROL_REG_GEN_READ(CLIDR, c0, 1, c0, 1);
     
    293301
    294302/* Memory protection and control registers */
     303enum {
     304        TTBR_ADDR_MASK = 0xffffff80,
     305        TTBR_NOS_FLAG = 1 << 5,
     306        TTBR_RGN_MASK = 0x3 << 3,
     307        TTBR_RGN_NO_CACHE = 0x0 << 3,
     308        TTBR_RGN_WBWA_CACHE = 0x1 << 3,
     309        TTBR_RGN_WT_CACHE = 0x2 << 3,
     310        TTBR_RGN_WB_CACHE = 0x3 << 3,
     311        TTBR_S_FLAG = 1 << 1,
     312        TTBR_C_FLAG = 1 << 0,
     313};
    295314CONTROL_REG_GEN_READ(TTBR0, c2, 0, c0, 0);
    296315CONTROL_REG_GEN_WRITE(TTBR0, c2, 0, c0, 0);
     
    363382
    364383CONTROL_REG_GEN_WRITE(DCIMVAC, c7, 0, c6, 1);
    365 CONTROL_REG_GEN_WRITE(DCIMSW, c7, 0, c6, 2);
     384CONTROL_REG_GEN_WRITE(DCISW, c7, 0, c6, 2);
    366385
    367386CONTROL_REG_GEN_WRITE(ATS1CPR, c7, 0, c8, 0);
     
    369388CONTROL_REG_GEN_WRITE(ATS1CUR, c7, 0, c8, 2);
    370389CONTROL_REG_GEN_WRITE(ATS1CUW, c7, 0, c8, 3);
    371 CONTROL_REG_GEN_WRITE(ATS1NSOPR, c7, 0, c8, 4);
    372 CONTROL_REG_GEN_WRITE(ATS1NSOPW, c7, 0, c8, 5);
    373 CONTROL_REG_GEN_WRITE(ATS1NSOUR, c7, 0, c8, 6);
    374 CONTROL_REG_GEN_WRITE(ATS1NSOUW, c7, 0, c8, 7);
     390CONTROL_REG_GEN_WRITE(ATS12NSOPR, c7, 0, c8, 4);
     391CONTROL_REG_GEN_WRITE(ATS12NSOPW, c7, 0, c8, 5);
     392CONTROL_REG_GEN_WRITE(ATS12NSOUR, c7, 0, c8, 6);
     393CONTROL_REG_GEN_WRITE(ATS12NSOUW, c7, 0, c8, 7);
    375394
    376395
  • kernel/arch/arm32/include/arch/mm/page.h

    r6ad185d rca62f86  
    4141#include <arch/exception.h>
    4242#include <arch/barrier.h>
     43#include <arch/cp15.h>
    4344#include <trace.h>
    4445
     
    9596/* Set PTE address accessors for each level. */
    9697#define SET_PTL0_ADDRESS_ARCH(ptl0) \
    97         (set_ptl0_addr((pte_t *) (ptl0)))
     98        set_ptl0_addr((pte_t *) (ptl0))
    9899#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
    99         (((pte_t *) (ptl0))[(i)].l0.coarse_table_addr = (a) >> 10)
     100        set_ptl1_addr((pte_t*) (ptl0), i, a)
    100101#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
    101102#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
    102103#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
    103         (((pte_t *) (ptl3))[(i)].l1.frame_base_addr = (a) >> 12)
     104        set_ptl3_addr((pte_t*) (ptl3), i, a)
    104105
    105106/* Get PTE flags accessors for each level. */
     
    129130        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    130131
     132
     133#define pt_coherence(page) pt_coherence_m(page, 1)
     134
    131135#if defined(PROCESSOR_ARCH_armv6) | defined(PROCESSOR_ARCH_armv7_a)
    132136#include "page_armv6.h"
     
    137141#endif
    138142
     143/** Sets the address of level 0 page table.
     144 *
     145 * @param pt Pointer to the page table to set.
     146 *
     147 * Page tables are always in cacheable memory.
     148 * Make sure the memory type is correct, and in sync with:
     149 * init_boot_pt (boot/arch/arm32/src/mm.c)
     150 * init_ptl0_section (boot/arch/arm32/src/mm.c)
     151 * set_pt_level1_flags (kernel/arch/arm32/include/arch/mm/page_armv6.h)
     152 */
     153NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
     154{
     155        uint32_t val = (uint32_t)pt & TTBR_ADDR_MASK;
     156        val |= TTBR_RGN_WBWA_CACHE | TTBR_C_FLAG;
     157        TTBR0_write(val);
     158}
     159
     160NO_TRACE static inline void set_ptl1_addr(pte_t *pt, size_t i, uintptr_t address)
     161{
     162        pt[i].l0.coarse_table_addr = address >> 10;
     163        pt_coherence(&pt[i].l0);
     164}
     165
     166NO_TRACE static inline void set_ptl3_addr(pte_t *pt, size_t i, uintptr_t address)
     167{
     168        pt[i].l1.frame_base_addr = address >> 12;
     169        pt_coherence(&pt[i].l1);
     170}
     171
    139172#endif
    140173
  • kernel/arch/arm32/include/arch/mm/page_armv4.h

    r6ad185d rca62f86  
    120120#define PTE_DESCRIPTOR_SMALL_PAGE       2
    121121
    122 
    123 /** Sets the address of level 0 page table.
    124  *
    125  * @param pt Pointer to the page table to set.
    126  *
    127  */
    128 NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
    129 {
    130         asm volatile (
    131                 "mcr p15, 0, %[pt], c2, c0, 0\n"
    132                 :: [pt] "r" (pt)
    133         );
    134 }
    135 
     122#define pt_coherence_m(pt, count) \
     123do { \
     124        for (unsigned i = 0; i < count; ++i) \
     125                DCCMVAU_write((uintptr_t)(pt + i)); \
     126        read_barrier(); \
     127} while (0)
    136128
    137129/** Returns level 0 page table entry flags.
     
    223215       
    224216        /* default access permission */
    225         p->access_permission_0 = p->access_permission_1 = 
     217        p->access_permission_0 = p->access_permission_1 =
    226218            p->access_permission_2 = p->access_permission_3 =
    227219            PTE_AP_USER_NO_KERNEL_RW;
     
    229221        if (flags & PAGE_USER)  {
    230222                if (flags & PAGE_READ) {
    231                         p->access_permission_0 = p->access_permission_1 = 
    232                             p->access_permission_2 = p->access_permission_3 = 
     223                        p->access_permission_0 = p->access_permission_1 =
     224                            p->access_permission_2 = p->access_permission_3 =
    233225                            PTE_AP_USER_RO_KERNEL_RW;
    234226                }
    235227                if (flags & PAGE_WRITE) {
    236                         p->access_permission_0 = p->access_permission_1 = 
    237                             p->access_permission_2 = p->access_permission_3 = 
    238                             PTE_AP_USER_RW_KERNEL_RW; 
     228                        p->access_permission_0 = p->access_permission_1 =
     229                            p->access_permission_2 = p->access_permission_3 =
     230                            PTE_AP_USER_RW_KERNEL_RW;
    239231                }
    240232        }
  • kernel/arch/arm32/include/arch/mm/page_armv6.h

    r6ad185d rca62f86  
    4040#error "Do not include arch specific page.h directly use generic page.h instead"
    4141#endif
     42
    4243
    4344/* Macros for querying the last-level PTE entries. */
     
    125126#define PTE_DESCRIPTOR_SMALL_PAGE_NX    3
    126127
    127 /** Sets the address of level 0 page table.
    128  *
    129  * @param pt Pointer to the page table to set.
    130  *
    131  */
    132 NO_TRACE static inline void set_ptl0_addr(pte_t *pt)
    133 {
    134         asm volatile (
    135                 "mcr p15, 0, %[pt], c2, c0, 0\n"
    136                 :: [pt] "r" (pt)
    137         );
    138 }
     128
     129/**
     130 * For an ARMv7 implementation that does not include the Large Physical Address Extension,
     131 * and in implementations of architecture versions before ARMv7, if the translation tables
     132 * are held in Write-Back Cacheable memory, the caches must be cleaned to the point of
     133 * unification after writing to the translation tables and before the DSB instruction. This
     134 * ensures that the updated translation table are visible to a hardware translation table walk.
     135 *
     136 * Therefore, an example instruction sequence for writing a translation table entry,
     137 * covering changes to the instruction
     138 * or data mappings in a uniprocessor system is:
     139 * STR rx, [Translation table entry]
     140 * ; write new entry to the translation table
     141 * Clean cache line [Translation table entry] : This operation is not required with the
     142 * ; Multiprocessing Extensions.
     143 * DSB
     144 * ; ensures visibility of the data cleaned from the D Cache
     145 * Invalidate TLB entry by MVA (and ASID if non-global) [page address]
     146 * Invalidate BTC
     147 * DSB
     148 * ; ensure completion of the Invalidate TLB operation
     149 * ISB
     150 * ; ensure table changes visible to instruction fetch
     151 *
     152 * ARM Architecture reference chp. B3.10.1 p. B3-1375
     153 * @note: see TTRB0/1 for pt memory type
     154 */
     155#define pt_coherence_m(pt, count) \
     156do { \
     157        for (unsigned i = 0; i < count; ++i) \
     158                DCCMVAU_write((uintptr_t)(pt + i)); \
     159        read_barrier(); \
     160} while (0)
    139161
    140162
     
    206228                p->ns = 0;
    207229        }
     230        pt_coherence(p);
    208231}
    209232
     
    232255                        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE_NX;
    233256        }
    234        
    235         /* tex=0 buf=1 and cache=1 => normal memory
    236          * tex=0 buf=1 and cache=0 => shareable device mmio
    237          */
    238         p->cacheable = (flags & PAGE_CACHEABLE);
    239         p->bufferable = 1;
    240         p->tex = 0;
     257
     258        if (flags & PAGE_CACHEABLE) {
     259                /*
     260                 * Write-through, no write-allocate memory, see ch. B3.8.2
     261                 * (p. B3-1358) of ARM Architecture reference manual.
     262                 * Make sure the memory type is correct, and in sync with:
     263                 * init_boot_pt (boot/arch/arm32/src/mm.c)
     264                 * init_ptl0_section (boot/arch/arm32/src/mm.c)
     265                 * set_ptl0_addr (kernel/arch/arm32/include/arch/mm/page.h)
     266                 */
     267                p->tex = 5;
     268                p->cacheable = 0;
     269                p->bufferable = 1;
     270        } else {
     271                /*
     272                 * Shareable device memory, see ch. B3.8.2 (p. B3-1358) of
     273                 * ARM Architecture reference manual.
     274                 */
     275                p->tex = 0;
     276                p->cacheable = 0;
     277                p->bufferable = 1;
     278        }
    241279       
    242280        /* Shareable is ignored for devices (non-cacheable),
    243          * turn it on for normal memory. */
    244         p->shareable = 1;
     281         * turn it off for normal memory. */
     282        p->shareable = 0;
    245283       
    246284        p->non_global = !(flags & PAGE_GLOBAL);
     
    256294                        p->access_permission_1 = PTE_AP1_RO;
    257295        }
     296        pt_coherence(p);
    258297}
    259298
     
    264303        p->should_be_zero_0 = 0;
    265304        p->should_be_zero_1 = 0;
    266         write_barrier();
    267305        p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
     306        pt_coherence(p);
    268307}
    269308
     
    273312
    274313        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
     314        pt_coherence(p);
    275315}
    276316
  • kernel/arch/arm32/src/cpu/cpu.c

    r6ad185d rca62f86  
    157157#endif
    158158#ifdef PROCESSOR_ARCH_armv7_a
    159          /* ICache coherency is elaborate on in barrier.h.
     159         /* ICache coherency is elaborated on in barrier.h.
    160160          * VIPT and PIPT caches need maintenance only on code modify,
    161161          * so it should be safe for general use.
     
    166166                control_reg |=
    167167                    SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG;
     168        } else {
     169                control_reg &=
     170                    ~(SCTLR_INST_CACHE_EN_FLAG | SCTLR_BRANCH_PREDICT_EN_FLAG);
    168171        }
    169172#endif
     
    204207#ifdef PROCESSOR_ARCH_armv7_a
    205208        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    206         const unsigned ls_log = 2 +
    207             ((CCSIDR_read() >> CCSIDR_LINESIZE_SHIFT) & CCSIDR_LINESIZE_MASK);
    208         return ls_log + 2; //return log2(bytes)
     209        const uint32_t ccsidr = CCSIDR_read();
     210        return CCSIDR_LINESIZE_LOG(ccsidr);
    209211#endif
    210212        return 0;
     
    217219#ifdef PROCESSOR_ARCH_armv7_a
    218220        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    219         const unsigned ways = 1 +
    220             ((CCSIDR_read() >> CCSIDR_ASSOC_SHIFT) & CCSIDR_ASSOC_MASK);
    221         return ways;
     221        const uint32_t ccsidr = CCSIDR_read();
     222        return CCSIDR_WAYS(ccsidr);
    222223#endif
    223224        return 0;
     
    229230#ifdef PROCESSOR_ARCH_armv7_a
    230231        CSSELR_write((level & CCSELR_LEVEL_MASK) << CCSELR_LEVEL_SHIFT);
    231         const unsigned sets = 1 +
    232             ((CCSIDR_read() >> CCSIDR_NUMSETS_SHIFT) & CCSIDR_NUMSETS_MASK);
    233         return sets;
     232        const uint32_t ccsidr = CCSIDR_read();
     233        return CCSIDR_SETS(ccsidr);
    234234#endif
    235235        return 0;
     
    241241#ifdef PROCESSOR_ARCH_armv7_a
    242242        const uint32_t val = CLIDR_read();
    243         for (unsigned i = 1; i <= 7; ++i) {
     243        for (unsigned i = 0; i < 8; ++i) {
    244244                const unsigned ctype = CLIDR_CACHE(i, val);
    245245                switch (ctype) {
     
    280280                const unsigned ways = dcache_ways(i);
    281281                const unsigned sets = dcache_sets(i);
    282                 const unsigned way_shift =  31 - log2(ways);
     282                const unsigned way_shift = 32 - log2(ways);
    283283                const unsigned set_shift = dcache_linesize_log(i);
    284284                dcache_clean_manual(i, false, ways, sets, way_shift, set_shift);
     
    293293                const unsigned ways = dcache_ways(i);
    294294                const unsigned sets = dcache_sets(i);
    295                 const unsigned way_shift =  31 - log2(ways);
     295                const unsigned way_shift = 32 - log2(ways);
    296296                const unsigned set_shift = dcache_linesize_log(i);
    297297                dcache_clean_manual(i, true, ways, sets, way_shift, set_shift);
  • kernel/arch/arm32/src/mach/beagleboardxm/beagleboardxm.c

    r6ad185d rca62f86  
    8585static void bb_timer_irq_handler(irq_t *irq)
    8686{
     87        amdm37x_gpt_irq_ack(&beagleboard.timer);
     88
    8789        /*
    8890         * We are holding a lock which prevents preemption.
    8991         * Release the lock, call clock() and reacquire the lock again.
    9092         */
    91         amdm37x_gpt_irq_ack(&beagleboard.timer);
    9293        spinlock_unlock(&irq->lock);
    9394        clock();
     
    147148{
    148149        const unsigned inum = amdm37x_irc_inum_get(beagleboard.irc_addr);
    149         amdm37x_irc_irq_ack(beagleboard.irc_addr);
    150150
    151151        irq_t *irq = irq_dispatch_and_lock(inum);
     
    159159                    CPU->id, inum);
    160160        }
     161        /** amdm37x manual ch. 12.5.2 (p. 2428) places irc ack at the end
     162         * of ISR. DO this to avoid strange behavior. */
     163        amdm37x_irc_irq_ack(beagleboard.irc_addr);
    161164}
    162165
  • kernel/arch/arm32/src/mm/tlb.c

    r6ad185d rca62f86  
    3737#include <arch/mm/asid.h>
    3838#include <arch/asm.h>
     39#include <arch/cp15.h>
    3940#include <typedefs.h>
    4041#include <arch/mm/page.h>
     42#include <arch/cache.h>
    4143
    4244/** Invalidate all entries in TLB.
     
    4648void tlb_invalidate_all(void)
    4749{
    48         asm volatile (
    49                 "eor r1, r1\n"
    50                 "mcr p15, 0, r1, c8, c7, 0\n"
    51                 ::: "r1"
    52         );
     50        TLBIALL_write(0);
     51        /*
     52         * "A TLB maintenance operation is only guaranteed to be complete after
     53         * the execution of a DSB instruction."
     54         * "An ISB instruction, or a return from an exception, causes the
     55         * effect of all completed TLB maintenance operations that appear in
     56         * program order before the ISB or return from exception to be visible
     57         * to all subsequent instructions, including the instruction fetches
     58         * for those instructions."
     59         * ARM Architecture reference Manual ch. B3.10.1 p. B3-1374 B3-1375
     60         */
     61        read_barrier();
     62        inst_barrier();
    5363}
    5464
     
    6070{
    6171        tlb_invalidate_all();
     72        // TODO: why not TLBIASID_write(asid) ?
    6273}
    6374
     
    6576 *
    6677 * @param page Virtual adress of the page
    67  */ 
     78 */
    6879static inline void invalidate_page(uintptr_t page)
    6980{
    70         asm volatile (
    71                 "mcr p15, 0, %[page], c8, c7, 1\n"
    72                 :: [page] "r" (page)
    73         );
     81        //TODO: What about TLBIMVAA?
     82        TLBIMVA_write(page);
     83        /*
     84         * "A TLB maintenance operation is only guaranteed to be complete after
     85         * the execution of a DSB instruction."
     86         * "An ISB instruction, or a return from an exception, causes the
     87         * effect of all completed TLB maintenance operations that appear in
     88         * program order before the ISB or return from exception to be visible
     89         * to all subsequent instructions, including the instruction fetches
     90         * for those instructions."
     91         * ARM Architecture reference Manual ch. B3.10.1 p. B3-1374 B3-1375
     92         */
     93        read_barrier();
     94        inst_barrier();
    7495}
    7596
     
    83104void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
    84105{
    85         unsigned int i;
    86 
    87         for (i = 0; i < cnt; i++)
     106        for (unsigned i = 0; i < cnt; i++)
    88107                invalidate_page(page + i * PAGE_SIZE);
    89108}
  • kernel/arch/ia32/src/ddi/ddi.c

    r6ad185d rca62f86  
    5959int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
    6060{
    61         size_t bits = ioaddr + size;
    62         if (bits > IO_PORTS)
     61        size_t elements = ioaddr + size;
     62        if (elements > IO_PORTS)
    6363                return ENOENT;
    6464       
    65         if (task->arch.iomap.bits < bits) {
     65        if (task->arch.iomap.elements < elements) {
    6666                /*
    6767                 * The I/O permission bitmap is too small and needs to be grown.
    6868                 */
    6969               
    70                 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);
    71                 if (!newmap)
     70                void *store = malloc(bitmap_size(elements, 0), FRAME_ATOMIC);
     71                if (!store)
    7272                        return ENOMEM;
    7373               
    7474                bitmap_t oldiomap;
    75                 bitmap_initialize(&oldiomap, task->arch.iomap.map,
     75                bitmap_initialize(&oldiomap, task->arch.iomap.elements, 0,
    7676                    task->arch.iomap.bits);
    77                 bitmap_initialize(&task->arch.iomap, newmap, bits);
     77               
     78                bitmap_initialize(&task->arch.iomap, elements, 0, store);
    7879               
    7980                /*
    8081                 * Mark the new range inaccessible.
    8182                 */
    82                 bitmap_set_range(&task->arch.iomap, oldiomap.bits,
    83                     bits - oldiomap.bits);
     83                bitmap_set_range(&task->arch.iomap, oldiomap.elements,
     84                    elements - oldiomap.elements);
    8485               
    8586                /*
     
    8990                if (oldiomap.bits) {
    9091                        bitmap_copy(&task->arch.iomap, &oldiomap,
    91                             oldiomap.bits);
    92                         free(oldiomap.map);
     92                            oldiomap.elements);
     93                       
     94                        free(oldiomap.bits);
    9395                }
    9496        }
     
    9799         * Enable the range and we are done.
    98100         */
    99         bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
     101        bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, size);
    100102       
    101103        /*
     
    119121        /* First, copy the I/O Permission Bitmap. */
    120122        irq_spinlock_lock(&TASK->lock, false);
     123       
    121124        size_t ver = TASK->arch.iomapver;
    122         size_t bits = TASK->arch.iomap.bits;
    123         if (bits) {
    124                 ASSERT(TASK->arch.iomap.map);
     125        size_t elements = TASK->arch.iomap.elements;
     126       
     127        if (elements > 0) {
     128                ASSERT(TASK->arch.iomap.bits);
    125129               
    126130                bitmap_t iomap;
    127                 bitmap_initialize(&iomap, CPU->arch.tss->iomap,
    128                     TSS_IOMAP_SIZE * 8);
    129                 bitmap_copy(&iomap, &TASK->arch.iomap, bits);
     131                bitmap_initialize(&iomap, TSS_IOMAP_SIZE * 8, 0,
     132                    CPU->arch.tss->iomap);
     133                bitmap_copy(&iomap, &TASK->arch.iomap, elements);
    130134               
    131135                /*
     
    133137                 * I/O access.
    134138                 */
    135                 bitmap_set_range(&iomap, bits, ALIGN_UP(bits, 8) - bits);
     139                bitmap_set_range(&iomap, elements,
     140                    ALIGN_UP(elements, 8) - elements);
     141               
    136142                /*
    137143                 * It is safe to set the trailing eight bits because of the
    138144                 * extra convenience byte in TSS_IOMAP_SIZE.
    139145                 */
    140                 bitmap_set_range(&iomap, ALIGN_UP(bits, 8), 8);
     146                bitmap_set_range(&iomap, ALIGN_UP(elements, 8), 8);
    141147        }
     148       
    142149        irq_spinlock_unlock(&TASK->lock, false);
    143150       
     
    150157       
    151158        descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base;
    152         gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits));
     159        size_t size = bitmap_size(elements, 0);
     160        gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + size);
    153161        gdtr_load(&cpugdtr);
    154162       
  • kernel/arch/ia32/src/mm/frame.c

    r6ad185d rca62f86  
    4747
    4848#define PHYSMEM_LIMIT32  UINT64_C(0x100000000)
     49#define PHYSMEM_LIMIT_DMA   UINT64_C(0x1000000)
    4950
    5051size_t hardcoded_unmapped_ktext_size = 0;
     
    9192                                else
    9293                                        conf = minconf;
    93                                 zone_create(pfn, count, conf,
    94                                     ZONE_AVAILABLE | ZONE_LOWMEM);
     94
     95                                if ((pfn * PAGE_SIZE) < PHYSMEM_LIMIT_DMA) {
     96                                        size_t dma_count = min(
     97                                            PHYSMEM_LIMIT_DMA / PAGE_SIZE - pfn,
     98                                            count);
     99                                        zone_create(pfn, dma_count, conf,
     100                                            ZONE_AVAILABLE | ZONE_DMA);
     101                                        count -= dma_count;
     102                                        pfn += dma_count;
     103                                }
     104
     105                                conf = pfn;
     106                                if (count) {
     107                                        zone_create(pfn, count, conf,
     108                                            ZONE_AVAILABLE | ZONE_LOWMEM);
     109                                }
    95110                        } else {
    96111                                conf = zone_external_conf_alloc(count);
    97                                 if (conf != 0)
     112                                if (conf != 0) {
    98113                                        zone_create(pfn, count, conf,
    99114                                            ZONE_AVAILABLE | ZONE_HIGHMEM);
     115                                }
    100116                        }
    101117                } else if ((e820table[i].type == MEMMAP_MEMORY_ACPI) ||
  • kernel/arch/ia32/src/proc/task.c

    r6ad185d rca62f86  
    4040/** Perform ia32 specific task initialization.
    4141 *
    42  * @param t Task to be initialized.
     42 * @param task Task to be initialized.
     43 *
    4344 */
    44 void task_create_arch(task_t *t)
     45void task_create_arch(task_t *task)
    4546{
    46         t->arch.iomapver = 0;
    47         bitmap_initialize(&t->arch.iomap, NULL, 0);
     47        task->arch.iomapver = 0;
     48        bitmap_initialize(&task->arch.iomap, 0, 0, NULL);
    4849}
    4950
    5051/** Perform ia32 specific task destruction.
    5152 *
    52  * @param t Task to be initialized.
     53 * @param task Task to be initialized.
     54 *
    5355 */
    54 void task_destroy_arch(task_t *t)
     56void task_destroy_arch(task_t *task)
    5557{
    56         if (t->arch.iomap.map)
    57                 free(t->arch.iomap.map);
     58        if (task->arch.iomap.bits != NULL)
     59                free(task->arch.iomap.bits);
    5860}
    5961
  • kernel/arch/ia64/src/ddi/ddi.c

    r6ad185d rca62f86  
    5656{
    5757        if (!task->arch.iomap) {
    58                 uint8_t *map;
    59 
    6058                task->arch.iomap = malloc(sizeof(bitmap_t), 0);
    61                 map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0);
    62                 if(!map)
     59                if (task->arch.iomap == NULL)
    6360                        return ENOMEM;
    64                 bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES);
     61               
     62                void *store = malloc(bitmap_size(IO_MEMMAP_PAGES, 0), 0);
     63                if (store == NULL)
     64                        return ENOMEM;
     65               
     66                bitmap_initialize(task->arch.iomap, IO_MEMMAP_PAGES, 0, store);
    6567                bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES);
    6668        }
     
    6971        size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
    7072        bitmap_set_range(task->arch.iomap, iopage, size / 4);
    71 
     73       
    7274        return 0;
    7375}
  • kernel/arch/sparc64/include/arch/mm/frame.h

    r6ad185d rca62f86  
    4646#endif
    4747
     48#ifndef __ASM__
     49
     50#include <typedefs.h>
     51
     52extern uintptr_t end_of_identity;
     53
     54extern void frame_low_arch_init(void);
     55extern void frame_high_arch_init(void);
     56#define physmem_print()
     57
     58#endif
     59
    4860#endif
    4961
  • kernel/arch/sparc64/include/arch/mm/sun4u/frame.h

    r6ad185d rca62f86  
    7272typedef union frame_address frame_address_t;
    7373
    74 extern uintptr_t end_of_identity;
    75 
    76 extern void frame_low_arch_init(void);
    77 extern void frame_high_arch_init(void);
    78 #define physmem_print()
    79 
    8074#endif
    8175
  • kernel/arch/sparc64/include/arch/mm/sun4v/frame.h

    r6ad185d rca62f86  
    4242#define FRAME_SIZE              (1 << FRAME_WIDTH)
    4343
    44 #ifndef __ASM__
    45 
    46 #include <typedefs.h>
    47 
    48 extern void frame_low_arch_init(void);
    49 extern void frame_high_arch_init(void);
    50 #define physmem_print()
    51 
    52 #endif
    53 
    5444#endif
    5545
  • kernel/arch/sparc64/include/arch/trap/sun4v/mmu.h

    r6ad185d rca62f86  
    102102        nop
    103103
     104        /* exclude pages beyond the end of memory from the identity mapping */
     105        sethi %hi(end_of_identity), %g4
     106        ldx [%g4 + %lo(end_of_identity)], %g4
     107        cmp %g1, %g4
     108        bgeu %xcc, 0f
     109        nop
     110
    104111        /*
    105112         * Installing the identity does not fit into 32 instructions, call
  • kernel/arch/sparc64/src/mm/sun4v/frame.c

    r6ad185d rca62f86  
    101101         */
    102102        frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
     103
     104        /* PA2KA will work only on low-memory. */
     105        end_of_identity = PA2KA(config.physmem_end - FRAME_SIZE) + PAGE_SIZE;
    103106}
    104107
  • kernel/arch/sparc64/src/mm/sun4v/tlb.c

    r6ad185d rca62f86  
    251251        uintptr_t va = DMISS_ADDRESS(page_and_ctx);
    252252        uint16_t ctx = DMISS_CONTEXT(page_and_ctx);
     253        as_t *as = AS;
    253254
    254255        if (ctx == ASID_KERNEL) {
     
    256257                        /* NULL access in kernel */
    257258                        panic("NULL pointer dereference.");
     259                } else if (va >= end_of_identity) {
     260                        /* Kernel non-identity */
     261                        as = AS_KERNEL;
     262                } else {
     263                        panic("Unexpected kernel page fault.");
    258264                }
    259                 panic("Unexpected kernel page fault.");
    260         }
    261 
    262         t = page_mapping_find(AS, va, true);
     265        }
     266
     267        t = page_mapping_find(as, va, true);
    263268        if (t) {
    264269                /*
     
    295300        uintptr_t va = DMISS_ADDRESS(page_and_ctx);
    296301        uint16_t ctx = DMISS_CONTEXT(page_and_ctx);
    297 
    298         t = page_mapping_find(AS, va, true);
     302        as_t *as = AS;
     303
     304        if (ctx == ASID_KERNEL)
     305                as = AS_KERNEL;
     306
     307        t = page_mapping_find(as, va, true);
    299308        if (t && PTE_WRITABLE(t)) {
    300309                /*
  • kernel/arch/sparc64/src/sun4v/start.S

    r6ad185d rca62f86  
    345345        .quad 0
    346346
     347/*
     348 * This variable is used by the fast_data_access_MMU_miss trap handler.
     349 * In runtime, it is modified to contain the address of the end of physical
     350 * memory.
     351 */
     352.global end_of_identity
     353end_of_identity:
     354        .quad -1
     355
    347356.global kernel_8k_tlb_data_template
    348357kernel_8k_tlb_data_template:
  • kernel/genarch/include/genarch/drivers/amdm37x/gpt.h

    r6ad185d rca62f86  
    3939#include <typedefs.h>
    4040#include <mm/km.h>
     41#include <time/clock.h>
    4142
    4243/* AMDM37x TRM p. 2740 */
     
    128129#define AMDM37x_GPT_TCLR_CE_FLAG  (1 << 6)
    129130#define AMDM37x_GPT_TCLR_SCPWM  (1 << 7)
    130 #define AMDM37x_GPT_TCLR_TCM_MASK  (0x3)
    131 #define AMDM37x_GPT_TCLR_TCM_SHIFT  (8)
    132 #define AMDM37x_GPT_TCLR_TRG_MASK  (0x3)
    133 #define AMDM37x_GPT_TCLR_TRG_SHIFT (10)
     131#define AMDM37x_GPT_TCLR_TCM_MASK  (0x3 << 8)
     132#define AMDM37x_GPT_TCLR_TCM_NO_CAPTURE   (0x0 << 8)
     133#define AMDM37x_GPT_TCLR_TCM_RAISE_CAPTURE   (0x1 << 8)
     134#define AMDM37x_GPT_TCLR_TCM_FALL_CAPTURE   (0x2 << 8)
     135#define AMDM37x_GPT_TCLR_TCM_BOTH_CAPTURE   (0x3 << 8)
     136#define AMDM37x_GPT_TCLR_TRG_MASK  (0x3 << 10)
     137#define AMDM37x_GPT_TCLR_TRG_NO  (0x0 << 10)
     138#define AMDM37x_GPT_TCLR_TRG_OVERFLOW  (0x1 << 10)
     139#define AMDM37x_GPT_TCLR_TRG_OVERMATCH  (0x2 << 10)
    134140#define AMDM37x_GPT_TCLR_PT_FLAG  (1 << 12)
    135141#define AMDM37x_GPT_TCLR_CAPT_MODE_FLAG  (1 << 13)
     
    209215        timer->regs = (void*) km_map(ioregs, iosize, PAGE_NOT_CACHEABLE);
    210216
     217        /* Reset the timer */
     218        timer->regs->tiocp_cfg |= AMDM37x_GPT_TIOCP_CFG_SOFTRESET_FLAG;
     219
     220        while (!(timer->regs->tistat & AMDM37x_GPT_TISTAT_RESET_DONE_FLAG));
     221
    211222        /* Set autoreload */
    212         timer->regs->tclr = AMDM37x_GPT_TCLR_AR_FLAG;
     223        timer->regs->tclr |= AMDM37x_GPT_TCLR_AR_FLAG;
    213224
    214225        timer->special_available = (
     
    216227            (ioregs == AMDM37x_GPT2_BASE_ADDRESS) ||
    217228            (ioregs == AMDM37x_GPT10_BASE_ADDRESS));
     229        /* Select reload value */
    218230        timer->regs->tldr = 0xffffffff - (32768 / hz) + 1;
     231        /* Set current counter value */
    219232        timer->regs->tccr = 0xffffffff - (32768 / hz) + 1;
     233
    220234        if (timer->special_available) {
    221                 /* Set values for according to formula (manual p. 2733) */
     235                /* Set values according to formula (manual p. 2733) */
    222236                /* Use temporary variables for easier debugging */
    223237                const uint32_t tpir =
    224238                    ((32768 / hz + 1) * 1000000) - (32768000L * (1000 / hz));
    225239                const uint32_t tnir =
    226                     ((32768 / hz) * 1000000) - (32768000 * (1000 / hz));
     240                    ((32768 / hz) * 1000000) - (32768000L * (1000 / hz));
    227241                timer->regs->tpir = tpir;
    228242                timer->regs->tnir = tnir;
     
    241255}
    242256
    243 static inline void amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
     257static inline bool amdm37x_gpt_irq_ack(amdm37x_gpt_t* timer)
    244258{
    245259        ASSERT(timer);
    246260        ASSERT(timer->regs);
    247261        /* Clear all pending interrupts */
    248         timer->regs->tisr = timer->regs->tisr;
     262        const uint32_t tisr = timer->regs->tisr;
     263        timer->regs->tisr = tisr;
     264        return tisr != 0;
    249265}
    250266
  • kernel/genarch/src/mm/page_pt.c

    r6ad185d rca62f86  
    112112                 */
    113113                write_barrier();
    114                 SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));       
     114                SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));
    115115        }
    116116       
     
    180180         * Destroy the mapping.
    181181         * Setting to PAGE_NOT_PRESENT is not sufficient.
    182          */
     182         * But we need SET_FRAME for possible PT coherence maintenance.
     183         * At least on ARM.
     184         */
     185        //TODO: Fix this inconsistency
     186        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), PAGE_NOT_PRESENT);
    183187        memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
    184188       
  • kernel/generic/include/adt/bitmap.h

    r6ad185d rca62f86  
    3838#include <typedefs.h>
    3939
    40 #define BITS2BYTES(bits)        (bits ? ((((bits)-1)>>3)+1) : 0)
     40#define BITMAP_ELEMENT   8
     41#define BITMAP_REMAINER  7
    4142
    4243typedef struct {
    43         uint8_t *map;
    44         size_t bits;
     44        size_t elements;
     45        uint8_t *bits;
     46       
     47        size_t block_size;
     48        uint8_t *blocks;
    4549} bitmap_t;
    4650
    47 extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits);
    48 extern void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits);
    49 extern void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits);
    50 extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits);
     51static inline void bitmap_set(bitmap_t *bitmap, size_t element,
     52    unsigned int value)
     53{
     54        if (element < bitmap->elements) {
     55                /*
     56                 * The 2nd level bitmap is conservative.
     57                 * Make sure we update it properly.
     58                 */
     59               
     60                if (value) {
     61                        bitmap->bits[element / BITMAP_ELEMENT] |=
     62                            (1 << (element & BITMAP_REMAINER));
     63                } else {
     64                        bitmap->bits[element / BITMAP_ELEMENT] &=
     65                            ~(1 << (element & BITMAP_REMAINER));
     66                       
     67                        if (bitmap->block_size > 0) {
     68                                size_t block = element / bitmap->block_size;
     69                               
     70                                bitmap->blocks[block / BITMAP_ELEMENT] &=
     71                                    ~(1 << (block & BITMAP_REMAINER));
     72                        }
     73                }
     74        }
     75}
    5176
    52 static inline int bitmap_get(bitmap_t *bitmap, size_t bit)
     77static inline unsigned int bitmap_get(bitmap_t *bitmap, size_t element)
    5378{
    54         if(bit >= bitmap->bits)
     79        if (element >= bitmap->elements)
    5580                return 0;
    5681       
    57         return !! ((bitmap->map)[bit/8] & (1 << (bit & 7)));
     82        return !!((bitmap->bits)[element / BITMAP_ELEMENT] &
     83            (1 << (element & BITMAP_REMAINER)));
    5884}
    5985
     86extern size_t bitmap_size(size_t, size_t);
     87extern void bitmap_initialize(bitmap_t *, size_t, size_t, void *);
     88
     89extern void bitmap_set_range(bitmap_t *, size_t, size_t);
     90extern void bitmap_clear_range(bitmap_t *, size_t, size_t);
     91
     92extern int bitmap_find_range(bitmap_t *, size_t, size_t, size_t);
     93extern int bitmap_allocate_range(bitmap_t *, size_t, size_t, size_t, size_t *);
     94extern void bitmap_free_range(bitmap_t *, size_t, size_t);
     95extern void bitmap_copy(bitmap_t *, bitmap_t *, size_t);
    6096
    6197#endif
  • kernel/generic/include/adt/list.h

    r6ad185d rca62f86  
    11/*
    22 * Copyright (c) 2001-2004 Jakub Jermar
    3  * Copyright (c) 2011 Jiri Svoboda
     3 * Copyright (c) 2013 Jiri Svoboda
    44 * All rights reserved.
    55 *
     
    6565
    6666#define list_get_instance(link, type, member) \
    67         ((type *) (((void *)(link)) - ((void *) &(((type *) NULL)->member))))
     67        ((type *) (((void *)(link)) - list_link_to_void(&(((type *) NULL)->member))))
    6868
    6969#define list_foreach(list, iterator) \
     
    281281}
    282282
     283/** Verify that argument type is a pointer to link_t (at compile time).
     284 *
     285 * This can be used to check argument type in a macro.
     286 */
     287static inline const void *list_link_to_void(const link_t *link)
     288{
     289        return link;
     290}
     291
    283292extern int list_member(const link_t *, const list_t *);
    284293extern void list_concat(list_t *, list_t *);
  • kernel/generic/include/mm/as.h

    r6ad185d rca62f86  
    250250extern int as_area_change_flags(as_t *, unsigned int, uintptr_t);
    251251
     252//TODO REMOVE!
     253extern as_area_t * find_locked_area(as_t *as, uintptr_t va);
     254
    252255extern unsigned int as_area_get_flags(as_area_t *);
    253256extern bool as_area_check_access(as_area_t *, pf_access_t);
  • kernel/generic/include/mm/frame.h

    r6ad185d rca62f86  
    6363/** Allocate a frame which cannot be identity-mapped. */
    6464#define FRAME_HIGHMEM     0x20
     65/** Allocate a frame which needs to be from DMA zone. */
     66#define FRAME_DMA         0x40
    6567
    6668typedef uint8_t zone_flags_t;
     
    7779/** Zone contains memory that cannot be identity-mapped */
    7880#define ZONE_HIGHMEM    0x10
     81/** Zone contains memory suitable for old ISA DMA */
     82#define ZONE_DMA        0x20
    7983
    8084/** Mask of zone bits that must be matched exactly. */
     
    8286
    8387#define FRAME_TO_ZONE_FLAGS(ff) \
    84         ((((ff) & FRAME_LOWMEM) ? ZONE_LOWMEM : \
     88        ((((ff) & FRAME_DMA) ? ZONE_DMA : \
     89            (((ff) & FRAME_LOWMEM) ? ZONE_LOWMEM : \
    8590            (((ff) & FRAME_HIGHMEM) ? ZONE_HIGHMEM : \
    86             ZONE_LOWMEM /* | ZONE_HIGHMEM */)) | \
    87             ZONE_AVAILABLE) 
     91            ZONE_LOWMEM /* | ZONE_HIGHMEM */))) | \
     92            ZONE_AVAILABLE)
    8893
    8994#define ZONE_FLAGS_MATCH(zf, f) \
  • kernel/generic/src/adt/bitmap.c

    r6ad185d rca62f86  
    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.
     39 *
     40 * The bitmap ADT can optionally implement a two-level hierarchy
     41 * for faster range searches. The second level bitmap (of blocks)
     42 * is not precise, but conservative. This means that if the block
     43 * bit is set, it guarantees that all bits in the block are set.
     44 * But if the block bit is unset, nothing can be said about the
     45 * bits in the block.
     46 *
    3847 */
    3948
     
    4453#include <macros.h>
    4554
    46 #define ALL_ONES        0xff
    47 #define ALL_ZEROES      0x00
     55#define ALL_ONES    0xff
     56#define ALL_ZEROES  0x00
     57
     58/** Get bitmap size
     59 *
     60 * Return the size (in bytes) required for the bitmap.
     61 *
     62 * @param elements   Number bits stored in bitmap.
     63 * @param block_size Block size of the 2nd level bitmap.
     64 *                   If set to zero, no 2nd level is used.
     65 *
     66 * @return Size (in bytes) required for the bitmap.
     67 *
     68 */
     69size_t bitmap_size(size_t elements, size_t block_size)
     70{
     71        size_t size = elements / BITMAP_ELEMENT;
     72       
     73        if ((elements % BITMAP_ELEMENT) != 0)
     74                size++;
     75       
     76        if (block_size > 0) {
     77                size += elements / block_size;
     78               
     79                if ((elements % block_size) != 0)
     80                        size++;
     81        }
     82       
     83        return size;
     84}
    4885
    4986/** Initialize bitmap.
     
    5188 * No portion of the bitmap is set or cleared by this function.
    5289 *
    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;
    61 }
    62 
    63 /** Set range of bits.
    64  *
    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)
    85                 return;
    86 
    87         if (start + bits < aligned_start) {
     90 * @param bitmap     Bitmap structure.
     91 * @param elements   Number of bits stored in bitmap.
     92 * @param block_size Block size of the 2nd level bitmap.
     93 *                   If set to zero, no 2nd level is used.
     94 * @param data       Address of the memory used to hold the map.
     95 *                   The optional 2nd level bitmap follows the 1st
     96 *                   level bitmap.
     97 *
     98 */
     99void bitmap_initialize(bitmap_t *bitmap, size_t elements, size_t block_size,
     100    void *data)
     101{
     102        bitmap->elements = elements;
     103        bitmap->bits = (uint8_t *) data;
     104       
     105        if (block_size > 0) {
     106                bitmap->block_size = block_size;
     107                bitmap->blocks = bitmap->bits +
     108                    bitmap_size(elements, 0);
     109        } else {
     110                bitmap->block_size = 0;
     111                bitmap->blocks = NULL;
     112        }
     113}
     114
     115static void bitmap_set_range_internal(uint8_t *bits, size_t start, size_t count)
     116{
     117        if (count == 0)
     118                return;
     119       
     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                bits[start / BITMAP_ELEMENT] |=
     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                bits[start / BITMAP_ELEMENT] |=
     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                bits[aligned_start / BITMAP_ELEMENT + i] = ALL_ONES;
     149        }
     150       
    101151        if (tab) {
    102152                /* Make sure to set any trailing aligned bits. */
    103                 bitmap->map[aligned_start / 8 + i] |= (1 << tab) - 1;
    104         }
    105        
    106 }
    107 
    108 /** Clear range of bits.
    109  *
    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)
    130                 return;
    131 
    132         if (start + bits < aligned_start) {
     153                bits[aligned_start / BITMAP_ELEMENT + i] |= (1 << tab) - 1;
     154        }
     155}
     156
     157/** Set range of bits.
     158 *
     159 * @param bitmap Bitmap structure.
     160 * @param start  Starting bit.
     161 * @param count  Number of bits to set.
     162 *
     163 */
     164void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t count)
     165{
     166        ASSERT(start + count <= bitmap->elements);
     167       
     168        bitmap_set_range_internal(bitmap->bits, start, count);
     169       
     170        if (bitmap->block_size > 0) {
     171                size_t aligned_start = ALIGN_UP(start, bitmap->block_size);
     172               
     173                /* Leading unaligned bits */
     174                size_t lub = min(aligned_start - start, count);
     175               
     176                /* Aligned middle bits */
     177                size_t amb = (count > lub) ? (count - lub) : 0;
     178               
     179                size_t aligned_size = amb / bitmap->block_size;
     180               
     181                bitmap_set_range_internal(bitmap->blocks, aligned_start,
     182                    aligned_size);
     183        }
     184}
     185
     186static void bitmap_clear_range_internal(uint8_t *bits, size_t start,
     187    size_t count)
     188{
     189        if (count == 0)
     190                return;
     191       
     192        size_t aligned_start = ALIGN_UP(start, BITMAP_ELEMENT);
     193       
     194        /* Leading unaligned bits */
     195        size_t lub = min(aligned_start - start, count);
     196       
     197        /* Aligned middle bits */
     198        size_t amb = (count > lub) ? (count - lub) : 0;
     199       
     200        /* Trailing aligned bits */
     201        size_t tab = amb % BITMAP_ELEMENT;
     202       
     203        if (start + count < aligned_start) {
    133204                /* Set bits in the middle of byte */
    134                 bitmap->map[start / 8] &= ~(((1 << lub) - 1) << (start & 7));
    135                 return;
    136         }
    137 
     205                bits[start / BITMAP_ELEMENT] &=
     206                    ~(((1 << lub) - 1) << (start & BITMAP_REMAINER));
     207                return;
     208        }
     209       
    138210        if (lub) {
    139211                /* 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++) {
     212                bits[start / BITMAP_ELEMENT] &=
     213                    (1 << (BITMAP_ELEMENT - lub)) - 1;
     214        }
     215       
     216        size_t i;
     217       
     218        for (i = 0; i < amb / BITMAP_ELEMENT; i++) {
    143219                /* The middle bits can be cleared byte by byte. */
    144                 bitmap->map[aligned_start / 8 + i] = ALL_ZEROES;
    145         }
     220                bits[aligned_start / BITMAP_ELEMENT + i] = ALL_ZEROES;
     221        }
     222       
    146223        if (tab) {
    147224                /* Make sure to clear any trailing aligned bits. */
    148                 bitmap->map[aligned_start / 8 + i] &= ~((1 << tab) - 1);
    149         }
    150 
     225                bits[aligned_start / BITMAP_ELEMENT + i] &= ~((1 << tab) - 1);
     226        }
     227}
     228
     229/** Clear range of bits.
     230 *
     231 * @param bitmap Bitmap structure.
     232 * @param start  Starting bit.
     233 * @param count  Number of bits to clear.
     234 *
     235 */
     236void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t count)
     237{
     238        ASSERT(start + count <= bitmap->elements);
     239       
     240        bitmap_clear_range_internal(bitmap->bits, start, count);
     241       
     242        if (bitmap->block_size > 0) {
     243                size_t aligned_start = start / bitmap->block_size;
     244               
     245                size_t aligned_end = (start + count) / bitmap->block_size;
     246               
     247                if (((start + count) % bitmap->block_size) != 0)
     248                        aligned_end++;
     249               
     250                size_t aligned_size = aligned_end - aligned_start;
     251               
     252                bitmap_clear_range_internal(bitmap->blocks, aligned_start,
     253                    aligned_size);
     254        }
    151255}
    152256
    153257/** Copy portion of one bitmap into another bitmap.
    154258 *
    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 {
     259 * @param dst   Destination bitmap.
     260 * @param src   Source bitmap.
     261 * @param count Number of bits to copy.
     262 *
     263 */
     264void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t count)
     265{
     266        ASSERT(count <= dst->elements);
     267        ASSERT(count <= src->elements);
     268       
    161269        size_t i;
    162270       
    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);
     271        for (i = 0; i < count / BITMAP_ELEMENT; i++)
     272                dst->bits[i] = src->bits[i];
     273       
     274        if (count % BITMAP_ELEMENT) {
     275                bitmap_clear_range(dst, i * BITMAP_ELEMENT,
     276                    count % BITMAP_ELEMENT);
     277                dst->bits[i] |= src->bits[i] &
     278                    ((1 << (count % BITMAP_ELEMENT)) - 1);
    172279        }
    173280}
  • kernel/generic/src/console/kconsole.c

    r6ad185d rca62f86  
    5353#include <func.h>
    5454#include <str.h>
    55 #include <macros.h>
    5655#include <sysinfo/sysinfo.h>
    5756#include <ddi/device.h>
  • kernel/generic/src/ddi/ddi.c

    r6ad185d rca62f86  
    336336                order = fnzb(pages - 1) + 1;
    337337       
    338         *phys = frame_alloc_noreserve(order, 0);
     338        *phys = frame_alloc_noreserve(order, FRAME_DMA);
    339339        if (*phys == NULL)
    340340                return ENOMEM;
     
    361361NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)
    362362{
    363         // TODO: implement unlocking & unmap
    364         return EOK;
     363        // TODO: This is an ugly hack
     364        as_t *as = TASK->as;
     365
     366        mutex_lock(&as->lock);
     367        as_area_t *area = find_locked_area(as, virt);
     368        if (!area) {
     369                mutex_unlock(&as->lock);
     370                return ENOENT;
     371        }
     372        frame_free_noreserve(area->backend_data.base);
     373        area->backend_data.base = 0;
     374        area->backend_data.frames = 0;
     375        mutex_unlock(&area->lock);
     376        mutex_unlock(&as->lock);
     377
     378        return as_area_destroy(as, virt);
    365379}
    366380
  • kernel/generic/src/mm/as.c

    r6ad185d rca62f86  
    672672       
    673673        return NULL;
     674}
     675
     676/** UGLY! UGLY! UGLY! */
     677// TODO: REMOVE ASAP!
     678as_area_t * find_locked_area(as_t *as, uintptr_t va)
     679{
     680        return find_area_and_lock(as, va);
    674681}
    675682
  • kernel/generic/src/mm/frame.c

    r6ad185d rca62f86  
    518518NO_TRACE static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
    519519{
    520         ASSERT(zone->flags & ZONE_AVAILABLE);
     520        if (!(zone->flags & ZONE_AVAILABLE))
     521                return;
     522//      ASSERT(zone->flags & ZONE_AVAILABLE);
    521523       
    522524        frame_t *frame = zone_get_frame(zone, frame_idx);
     
    935937                        }
    936938                       
    937                         if (confframe >= start + count)
    938                                 panic("Cannot find configuration data for zone.");
     939                        if (confframe >= start + count) {
     940                                flags &= ~ZONE_AVAILABLE;
     941                                goto nonavail;
     942//                              panic("Cannot find configuration data for zone.");
     943                        }
    939944                }
    940945               
     
    960965                return znum;
    961966        }
    962        
     967nonavail:
     968        (void)0; // label trick
    963969        /* Non-available zone */
    964970        size_t znum = zones_insert_zone(start, count, flags);
Note: See TracChangeset for help on using the changeset viewer.