Changeset da68871a in mainline for kernel


Ignore:
Timestamp:
2012-08-08T08:46:22Z (13 years ago)
Author:
Adam Hraska <adam.hraska+hos@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
30c0826
Parents:
bc216a0 (diff), 1d01cca (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:

Merged changes from mainline.

Location:
kernel
Files:
3 added
37 edited

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    rbc216a0 rda68871a  
    197197        generic/src/console/chardev.c \
    198198        generic/src/console/console.c \
     199        generic/src/console/prompt.c \
    199200        generic/src/cpu/cpu.c \
    200201        generic/src/cpu/cpu_mask.c \
  • kernel/arch/abs32le/include/mm/page.h

    rbc216a0 rda68871a  
    105105        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
    106106
     107/* Set PTE present bit accessors for each level. */
     108#define SET_PTL1_PRESENT_ARCH(ptl0, i)  \
     109        set_pt_present((pte_t *) (ptl0), (size_t) (i))
     110#define SET_PTL2_PRESENT_ARCH(ptl1, i)
     111#define SET_PTL3_PRESENT_ARCH(ptl2, i)
     112#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     113        set_pt_present((pte_t *) (ptl3), (size_t) (i))
     114
    107115/* Macros for querying the last level entries. */
    108116#define PTE_VALID_ARCH(p) \
     
    173181}
    174182
     183NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     184    WRITES(ARRAY_RANGE(pt, PTL0_ENTRIES_ARCH))
     185    REQUIRES_ARRAY_MUTABLE(pt, PTL0_ENTRIES_ARCH)
     186{
     187        pte_t *p = &pt[i];
     188
     189        p->present = 1;
     190}
     191
    175192extern void page_arch_init(void);
    176193extern void page_fault(unsigned int, istate_t *);
  • kernel/arch/amd64/include/mm/page.h

    rbc216a0 rda68871a  
    119119        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
    120120
     121/* Set PTE present bit accessors for each level. */
     122#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
     123        set_pt_present((pte_t *) (ptl0), (size_t) (i))
     124#define SET_PTL2_PRESENT_ARCH(ptl1, i) \
     125        set_pt_present((pte_t *) (ptl1), (size_t) (i))
     126#define SET_PTL3_PRESENT_ARCH(ptl2, i) \
     127        set_pt_present((pte_t *) (ptl2), (size_t) (i))
     128#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     129        set_pt_present((pte_t *) (ptl3), (size_t) (i))
     130
    121131/* Macros for querying the last-level PTE entries. */
    122132#define PTE_VALID_ARCH(p) \
     
    215225}
    216226
     227NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     228{
     229        pte_t *p = &pt[i];
     230
     231        p->present = 1;
     232}
     233
    217234extern void page_arch_init(void);
    218235extern void page_fault(unsigned int, istate_t *);
  • kernel/arch/amd64/src/asm.S

    rbc216a0 rda68871a  
    362362         */
    363363        call syscall_handler
    364        
     364
     365        /*
     366         * Test if the saved return address is canonical and not-kernel.
     367         * We do this by looking at the 16 most significant bits
     368         * of the saved return address (two bytes at offset 6).
     369         */
     370        testw $0xffff, ISTATE_OFFSET_RIP+6(%rsp)
     371        jnz bad_rip
     372
    365373        cli
    366374       
     
    388396        sysretq
    389397
     398bad_rip:
     399        movq %rsp, %rdi
     400        movabs $bad_rip_msg, %rsi
     401        xorb %al, %al
     402        callq fault_from_uspace
     403        /* not reached */
     404       
     405bad_rip_msg:
     406        .asciz "Invalid instruction pointer."
     407
    390408/** Print Unicode character to EGA display.
    391409 *
  • kernel/arch/amd64/src/boot/multiboot.S

    rbc216a0 rda68871a  
    7676
    7777multiboot_image_start:
     78        cli
    7879        cld
    7980       
     
    8182        movl $START_STACK, %esp
    8283       
    83         /* Initialize Global Descriptor Table register */
     84        /*
     85         * Initialize Global Descriptor Table and
     86         * Interrupt Descriptor Table registers
     87         */
    8488        lgdtl bootstrap_gdtr
     89        lidtl bootstrap_idtr
    8590       
    8691        /* Kernel data + stack */
     
    645650.section K_DATA_START, "aw", @progbits
    646651
     652.global bootstrap_idtr
     653bootstrap_idtr:
     654        .word 0
     655        .long 0
     656
    647657.global bootstrap_gdtr
    648658bootstrap_gdtr:
  • kernel/arch/amd64/src/boot/multiboot2.S

    rbc216a0 rda68871a  
    116116
    117117multiboot2_image_start:
     118        cli
    118119        cld
    119120       
     
    121122        movl $START_STACK, %esp
    122123       
    123         /* Initialize Global Descriptor Table register */
     124        /*
     125         * Initialize Global Descriptor Table and
     126         * Interrupt Descriptor Table registers
     127         */
    124128        lgdtl bootstrap_gdtr
     129        lidtl bootstrap_idtr
    125130       
    126131        /* Kernel data + stack */
  • kernel/arch/amd64/src/boot/vesa_ret.inc

    rbc216a0 rda68871a  
    11.code32
    22vesa_init_protected:
     3        cli
    34        cld
    45       
  • kernel/arch/amd64/src/mm/page.c

    rbc216a0 rda68871a  
    5757        uintptr_t cur;
    5858        unsigned int identity_flags =
    59             PAGE_CACHEABLE | PAGE_EXEC | PAGE_GLOBAL | PAGE_WRITE;
     59            PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_EXEC | PAGE_WRITE | PAGE_READ;
    6060               
    6161        page_mapping_operations = &pt_mapping_operations;
  • kernel/arch/arm32/include/mm/page.h

    rbc216a0 rda68871a  
    4040#include <mm/mm.h>
    4141#include <arch/exception.h>
     42#include <arch/barrier.h>
    4243#include <trace.h>
    4344
     
    109110#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
    110111        set_pt_level1_flags((pte_t *) (ptl3), (size_t) (i), (x))
     112
     113/* Set PTE present bit accessors for each level. */
     114#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
     115        set_pt_level0_present((pte_t *) (ptl0), (size_t) (i))
     116#define SET_PTL2_PRESENT_ARCH(ptl1, i)
     117#define SET_PTL3_PRESENT_ARCH(ptl2, i)
     118#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     119        set_pt_level1_present((pte_t *) (ptl3), (size_t) (i))
    111120
    112121/* Macros for querying the last-level PTE entries. */
     
    267276}
    268277
     278NO_TRACE static inline void set_pt_level0_present(pte_t *pt, size_t i)
     279{
     280        pte_level0_t *p = &pt[i].l0;
     281
     282        p->should_be_zero = 0;
     283        write_barrier();
     284        p->descriptor_type = PTE_DESCRIPTOR_COARSE_TABLE;
     285}
    269286
    270287/** Sets flags of level 1 page table entry.
     
    283300        pte_level1_t *p = &pt[i].l1;
    284301       
    285         if (flags & PAGE_NOT_PRESENT) {
     302        if (flags & PAGE_NOT_PRESENT)
    286303                p->descriptor_type = PTE_DESCRIPTOR_NOT_PRESENT;
    287                 p->access_permission_3 = 1;
    288         } else {
     304        else
    289305                p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
    290                 p->access_permission_3 = p->access_permission_0;
    291         }
    292306       
    293307        p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
     
    312326}
    313327
    314 
     328NO_TRACE static inline void set_pt_level1_present(pte_t *pt, size_t i)
     329{
     330        pte_level1_t *p = &pt[i].l1;
     331
     332        p->descriptor_type = PTE_DESCRIPTOR_SMALL_PAGE;
     333}
     334       
    315335extern void page_arch_init(void);
    316336
    317 
    318337#endif /* __ASM__ */
    319338
  • kernel/arch/ia32/include/mm/page.h

    rbc216a0 rda68871a  
    115115        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
    116116
     117/* Set PTE present bit accessors for each level. */
     118#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
     119        set_pt_present((pte_t *) (ptl0), (size_t) (i))
     120#define SET_PTL2_PRESENT_ARCH(ptl1, i)
     121#define SET_PTL3_PRESENT_ARCH(ptl2, i)
     122#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     123        set_pt_present((pte_t *) (ptl3), (size_t) (i))
     124
    117125/* Macros for querying the last level entries. */
    118126#define PTE_VALID_ARCH(p) \
     
    194202}
    195203
     204NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     205{
     206        pte_t *p = &pt[i];
     207
     208        p->present = 1;
     209}
     210
    196211extern void page_arch_init(void);
    197212extern void page_fault(unsigned int, istate_t *);
  • kernel/arch/ia32/src/boot/multiboot.S

    rbc216a0 rda68871a  
    7373
    7474multiboot_image_start:
     75        cli
    7576        cld
    7677       
     
    7879        movl $START_STACK, %esp
    7980       
    80         /* Initialize Global Descriptor Table register */
     81        /*
     82         * Initialize Global Descriptor Table and
     83         * Interrupt Descriptor Table registers
     84         */
    8185        lgdtl bootstrap_gdtr
     86        lidtl bootstrap_idtr
    8287       
    8388        /* Kernel data + stack */
     
    701706page_directory:
    702707        .space 4096, 0
     708
     709.global bootstrap_idtr
     710bootstrap_idtr:
     711        .word 0
     712        .long 0
    703713
    704714.global bootstrap_gdtr
  • kernel/arch/ia32/src/boot/multiboot2.S

    rbc216a0 rda68871a  
    114114
    115115multiboot2_image_start:
     116        cli
    116117        cld
    117118       
     
    119120        movl $START_STACK, %esp
    120121       
    121         /* Initialize Global Descriptor Table register */
     122        /*
     123         * Initialize Global Descriptor Table and
     124         * Interrupt Descriptor Table registers
     125         */
    122126        lgdtl bootstrap_gdtr
     127        lidtl bootstrap_idtr
    123128       
    124129        /* Kernel data + stack */
  • kernel/arch/ia32/src/boot/vesa_prot.inc

    rbc216a0 rda68871a  
    8888                /* Returned back to protected mode */
    8989               
     90                /*
     91                 * Initialize Global Descriptor Table and
     92                 * Interrupt Descriptor Table registers
     93                 */
     94                lgdtl bootstrap_gdtr
     95                lidtl bootstrap_idtr
     96               
    9097                movzx %ax, %ecx
    9198                mov %ecx, KA2PA(bfb_scanline)
  • kernel/arch/ia32/src/boot/vesa_real.inc

    rbc216a0 rda68871a  
    3030.code32
    3131vesa_init:
     32        lidtl vesa_idtr
    3233        jmp $GDT_SELECTOR(VESA_INIT_DES), $vesa_init_real - vesa_init
     34
     35vesa_idtr:
     36        .word 0x3ff
     37        .long 0
    3338
    3439.code16
  • kernel/arch/ia32/src/boot/vesa_ret.inc

    rbc216a0 rda68871a  
    11.code32
    22vesa_init_protected:
     3        cli
    34        cld
    45       
  • kernel/arch/ia32/src/mm/page.c

    rbc216a0 rda68871a  
    7171        for (cur = 0; cur < min(config.identity_size, config.physmem_end);
    7272            cur += FRAME_SIZE) {
    73                 flags = PAGE_CACHEABLE | PAGE_WRITE;
    74                 if ((PA2KA(cur) >= config.base) &&
    75                     (PA2KA(cur) < config.base + config.kernel_size))
    76                         flags |= PAGE_GLOBAL;
     73                flags = PAGE_GLOBAL | PAGE_CACHEABLE | PAGE_WRITE | PAGE_READ;
    7774                page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
    7875        }
  • kernel/arch/ia32/src/smp/apic.c

    rbc216a0 rda68871a  
    259259}
    260260
    261 static void ipi_wait_for_idle(void)
     261/* Waits for the destination cpu to accept the previous ipi. */
     262static void l_apic_wait_for_delivery(void)
    262263{
    263264        icr_t icr;
    264265       
    265         /* Wait for the destination cpu to accept the previous ipi. */
    266266        do {
    267267                icr.lo = l_apic[ICRlo];
     
    281281
    282282        /* Wait for a destination cpu to accept our previous ipi. */
    283         ipi_wait_for_idle();
     283        l_apic_wait_for_delivery();
    284284       
    285285        icr.lo = l_apic[ICRlo];
     
    298298        l_apic[ICRlo] = icr.lo;
    299299       
    300 #ifdef CONFIG_DEBUG
    301         icr.lo = l_apic[ICRlo];
    302         if (icr.delivs == DELIVS_PENDING) {
    303                 printf("IPI is pending.\n");
    304         }
    305 #endif
    306        
    307300        return apic_poll_errors();
    308301}
     
    320313
    321314        /* Wait for a destination cpu to accept our previous ipi. */
    322         ipi_wait_for_idle();
     315        l_apic_wait_for_delivery();
    323316       
    324317        icr.lo = l_apic[ICRlo];
     
    332325        l_apic[ICRlo] = icr.lo;
    333326       
    334         icr.lo = l_apic[ICRlo];
    335         if (icr.delivs == DELIVS_PENDING) {
    336 #ifdef CONFIG_DEBUG
    337                 printf("IPI is pending.\n");
    338 #endif
    339         }
    340        
    341327        return apic_poll_errors();
    342328}
     
    379365                return 0;
    380366       
     367        l_apic_wait_for_delivery();
     368
    381369        icr.lo = l_apic[ICRlo];
    382         if (icr.delivs == DELIVS_PENDING) {
    383 #ifdef CONFIG_DEBUG
    384                 printf("IPI is pending.\n");
    385 #endif
    386         }
    387        
    388370        icr.delmod = DELMOD_INIT;
    389371        icr.destmod = DESTMOD_PHYS;
     
    518500        dfr.model = MODEL_FLAT;
    519501        l_apic[DFR] = dfr.value;
    520        
    521         if (CPU->arch.id != l_apic_id()) {
    522 #ifdef CONFIG_DEBUG
    523                 printf("lapic error: LAPIC ID (%" PRIu8 ") and hw ID assigned by BSP"
    524                         " (%u) differ. Correcting to LAPIC ID.\n", l_apic_id(),
    525                         CPU->arch.id);
    526 #endif
    527                 CPU->arch.id = l_apic_id();
    528         }
    529        
    530502}
    531503
  • kernel/arch/ia64/Makefile.inc

    rbc216a0 rda68871a  
    3030BFD_ARCH = ia64-elf64
    3131
    32 CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127
     32#
     33# FIXME:
     34#
     35# The -fno-selective-scheduling and -fno-selective-scheduling2 options
     36# should be removed as soon as a bug in GCC concerning unchecked
     37# speculative loads is fixed.
     38#
     39# See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53975 for reference.
     40#
     41
     42CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 -fno-selective-scheduling -fno-selective-scheduling2
    3343GCC_CFLAGS += $(CMN1)
    3444ICC_CFLAGS += $(CMN1)
  • kernel/arch/mips32/Makefile.inc

    rbc216a0 rda68871a  
    2929BFD_ARCH = mips
    3030BFD = binary
    31 GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
     31GCC_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=32
    3232
    3333BITS = 32
     
    4848        BFD_NAME = elf32-tradlittlemips
    4949        ENDIANESS = LE
    50         GCC_CFLAGS += -mhard-float
    5150endif
    5251
  • kernel/arch/mips32/include/mm/page.h

    rbc216a0 rda68871a  
    128128        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
    129129
     130/* Set PTE present bit accessors for each level. */
     131#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
     132        set_pt_present((pte_t *) (ptl0), (size_t) (i))
     133#define SET_PTL2_PRESENT_ARCH(ptl1, i)
     134#define SET_PTL3_PRESENT_ARCH(ptl2, i)
     135#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     136        set_pt_present((pte_t *) (ptl3), (size_t) (i))
     137
    130138/* Last-level info macros. */
    131139#define PTE_VALID_ARCH(pte)                     (*((uint32_t *) (pte)) != 0)
     
    182190}
    183191
     192NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     193{
     194        pte_t *p = &pt[i];
     195
     196        p->p = 1;
     197}
     198       
     199
    184200extern void page_arch_init(void);
    185201
  • kernel/arch/mips64/Makefile.inc

    rbc216a0 rda68871a  
    2929BFD_ARCH = mips:4000
    3030BFD = binary
    31 GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
     31GCC_CFLAGS += -msoft-float -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 -mabi=64
    3232AFLAGS = -64
    3333
     
    4040        BFD_NAME = elf64-tradlittlemips
    4141        ENDIANESS = LE
    42         GCC_CFLAGS += -mhard-float
    4342endif
    4443
  • kernel/arch/ppc32/include/mm/page.h

    rbc216a0 rda68871a  
    128128#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
    129129        set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
     130
     131/* Set PTE present accessors for each level. */
     132#define SET_PTL1_PRESENT_ARCH(ptl0, i) \
     133        set_pt_present((pte_t *) (ptl0), (size_t) (i))
     134
     135#define SET_PTL2_PRESENT_ARCH(ptl1, i)
     136#define SET_PTL3_PRESENT_ARCH(ptl2, i)
     137
     138#define SET_FRAME_PRESENT_ARCH(ptl3, i) \
     139        set_pt_present((pte_t *) (ptl3), (size_t) (i))
    130140
    131141/* Macros for querying the last-level PTEs. */
     
    175185}
    176186
     187NO_TRACE static inline void set_pt_present(pte_t *pt, size_t i)
     188{
     189        pte_t *entry = &pt[i];
     190
     191        entry->present = 1;
     192}
     193
    177194extern void page_arch_init(void);
    178195
  • kernel/arch/sparc64/src/smp/sun4u/ipi.c

    rbc216a0 rda68871a  
    124124                        (void) interrupts_disable();
    125125                }
    126         } while (done);
     126        } while (!done);
    127127       
    128128        preemption_enable();
  • kernel/genarch/include/mm/page_pt.h

    rbc216a0 rda68871a  
    115115
    116116/*
     117 * These macros are provided to set the present bit within the page tables.
     118 *
     119 */
     120#define SET_PTL1_PRESENT(ptl0, i)   SET_PTL1_PRESENT_ARCH(ptl0, i)
     121#define SET_PTL2_PRESENT(ptl1, i)   SET_PTL2_PRESENT_ARCH(ptl1, i)
     122#define SET_PTL3_PRESENT(ptl2, i)   SET_PTL3_PRESENT_ARCH(ptl2, i)
     123#define SET_FRAME_PRESENT(ptl3, i)  SET_FRAME_PRESENT_ARCH(ptl3, i)
     124
     125/*
    117126 * Macros for querying the last-level PTEs.
    118127 *
  • kernel/genarch/src/mm/page_ht.c

    rbc216a0 rda68871a  
    4545#include <typedefs.h>
    4646#include <arch/asm.h>
     47#include <arch/barrier.h>
    4748#include <synch/spinlock.h>
    4849#include <arch.h>
     
    207208                pte->page = ALIGN_DOWN(page, PAGE_SIZE);
    208209                pte->frame = ALIGN_DOWN(frame, FRAME_SIZE);
     210
     211                write_barrier();
    209212               
    210213                hash_table_insert(&page_ht, key, &pte->link);
  • kernel/genarch/src/mm/page_pt.c

    rbc216a0 rda68871a  
    4343#include <arch/mm/page.h>
    4444#include <arch/mm/as.h>
     45#include <arch/barrier.h>
    4546#include <typedefs.h>
    4647#include <arch/asm.h>
     
    8687                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt));
    8788                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page),
    88                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     89                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    8990                    PAGE_WRITE);
     91                write_barrier();
     92                SET_PTL1_PRESENT(ptl0, PTL0_INDEX(page));
    9093        }
    9194       
     
    98101                SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt));
    99102                SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page),
    100                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     103                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    101104                    PAGE_WRITE);
     105                write_barrier();
     106                SET_PTL2_PRESENT(ptl1, PTL1_INDEX(page));       
    102107        }
    103108       
     
    110115                SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt));
    111116                SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page),
    112                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
     117                    PAGE_NOT_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    113118                    PAGE_WRITE);
     119                write_barrier();
     120                SET_PTL3_PRESENT(ptl2, PTL2_INDEX(page));
    114121        }
    115122       
     
    117124       
    118125        SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(page), frame);
    119         SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags);
     126        SET_FRAME_FLAGS(ptl3, PTL3_INDEX(page), flags | PAGE_NOT_PRESENT);
     127        write_barrier();
     128        SET_FRAME_PRESENT(ptl3, PTL3_INDEX(page));
    120129}
    121130
     
    279288        if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
    280289                return NULL;
     290
     291        read_barrier();
    281292       
    282293        pte_t *ptl1 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page)));
    283294        if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT)
    284295                return NULL;
     296
     297#if (PTL1_ENTRIES != 0)
     298        read_barrier();
     299#endif
    285300       
    286301        pte_t *ptl2 = (pte_t *) PA2KA(GET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page)));
    287302        if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT)
    288303                return NULL;
     304
     305#if (PTL2_ENTRIES != 0)
     306        read_barrier();
     307#endif
    289308       
    290309        pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
     
    346365                SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(addr), KA2PA(l1));
    347366                SET_PTL1_FLAGS(ptl0, PTL0_INDEX(addr),
    348                     PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE |
    349                     PAGE_WRITE);
     367                    PAGE_PRESENT | PAGE_USER | PAGE_CACHEABLE |
     368                    PAGE_EXEC | PAGE_WRITE | PAGE_READ);
    350369        }
    351370}
  • kernel/generic/include/debug.h

    rbc216a0 rda68871a  
    3737
    3838#include <panic.h>
    39 #include <symtab.h>
     39#include <symtab_lookup.h>
    4040
    4141#define CALLER  ((uintptr_t) __builtin_return_address(0))
  • kernel/generic/include/interrupt.h

    rbc216a0 rda68871a  
    3838#include <arch/interrupt.h>
    3939#include <print.h>
     40#include <stdarg.h>
    4041#include <typedefs.h>
    4142#include <proc/task.h>
     
    5859extern exc_table_t exc_table[];
    5960
     61extern void fault_from_uspace(istate_t *, const char *, ...);
    6062extern void fault_if_from_uspace(istate_t *, const char *, ...)
    6163    PRINTF_ATTRIBUTE(2, 3);
  • kernel/generic/include/ipc/irq.h

    rbc216a0 rda68871a  
    3737
    3838/** Maximum number of IPC IRQ programmed I/O ranges. */
    39 #define IRQ_MAX_RANGE_COUNT     8
     39#define IRQ_MAX_RANGE_COUNT  8
    4040
    4141/** Maximum length of IPC IRQ program. */
    42 #define IRQ_MAX_PROG_SIZE  20
     42#define IRQ_MAX_PROG_SIZE  256
    4343
    4444#include <ipc/ipc.h>
  • kernel/generic/include/symtab.h

    rbc216a0 rda68871a  
    3636#define KERN_SYMTAB_H_
    3737
    38 #include <typedefs.h>
     38#include <symtab_lookup.h>
     39#include <console/chardev.h>
    3940
    40 #define MAX_SYMBOL_NAME  64
    41 
    42 struct symtab_entry {
    43         uint64_t address_le;
    44         char symbol_name[MAX_SYMBOL_NAME];
    45 };
    46 
    47 extern int symtab_name_lookup(uintptr_t, const char **, uintptr_t *);
    48 extern const char *symtab_fmt_name_lookup(uintptr_t);
    49 extern int symtab_addr_lookup(const char *, uintptr_t *);
    5041extern void symtab_print_search(const char *);
    51 extern int symtab_compl(char *, size_t);
    52 
    53 #ifdef CONFIG_SYMTAB
    54 
    55 /** Symtable linked together by build process
    56  *
    57  */
    58 extern struct symtab_entry symbol_table[];
    59 
    60 #endif /* CONFIG_SYMTAB */
     42extern int symtab_compl(char *, size_t, indev_t *);
    6143
    6244#endif
  • kernel/generic/src/console/kconsole.c

    rbc216a0 rda68871a  
    4343#include <console/chardev.h>
    4444#include <console/cmd.h>
     45#include <console/prompt.h>
    4546#include <print.h>
    4647#include <panic.h>
     
    202203 *
    203204 */
    204 NO_TRACE static int cmdtab_compl(char *input, size_t size)
     205NO_TRACE static int cmdtab_compl(char *input, size_t size, indev_t *indev)
    205206{
    206207        const char *name = input;
    207208       
    208209        size_t found = 0;
     210       
     211        /*
     212         * Maximum Match Length: Length of longest matching common
     213         * substring in case more than one match is found.
     214         */
     215        size_t max_match_len = size;
     216        size_t max_match_len_tmp = size;
     217        size_t input_len = str_length(input);
    209218        link_t *pos = NULL;
    210219        const char *hint;
    211220        char *output = malloc(MAX_CMDLINE, 0);
     221        size_t hints_to_show = MAX_TAB_HINTS - 1;
     222        size_t total_hints_shown = 0;
     223        bool continue_showing_hints = true;
    212224       
    213225        output[0] = 0;
     
    219231                pos = pos->next;
    220232                found++;
     233        }
     234       
     235        /*
     236         * If the number of possible completions is more than MAX_TAB_HINTS,
     237         * ask the user whether to display them or not.
     238         */
     239        if (found > MAX_TAB_HINTS) {
     240                printf("\n");
     241                continue_showing_hints =
     242                    console_prompt_display_all_hints(indev, found);
    221243        }
    222244       
     
    226248                while (cmdtab_search_one(name, &pos)) {
    227249                        cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
    228                         printf("%s (%s)\n", hlp->name, hlp->description);
     250                       
     251                        if (continue_showing_hints) {
     252                                printf("%s (%s)\n", hlp->name, hlp->description);
     253                                --hints_to_show;
     254                                ++total_hints_shown;
     255                               
     256                                if ((hints_to_show == 0) && (total_hints_shown != found)) {
     257                                        /* Ask user to continue */
     258                                        continue_showing_hints =
     259                                            console_prompt_more_hints(indev, &hints_to_show);
     260                                }
     261                        }
     262                       
    229263                        pos = pos->next;
    230                 }
     264                       
     265                        for (max_match_len_tmp = 0;
     266                            (output[max_match_len_tmp] ==
     267                            hlp->name[input_len + max_match_len_tmp]) &&
     268                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
     269                       
     270                        max_match_len = max_match_len_tmp;
     271                }
     272               
     273                /* Keep only the characters common in all completions */
     274                output[max_match_len] = 0;
    231275        }
    232276       
     
    281325                                continue;
    282326                       
    283                         /* Find the beginning of the word
    284                            and copy it to tmp */
     327                        /*
     328                         * Find the beginning of the word
     329                         * and copy it to tmp
     330                         */
    285331                        size_t beg;
    286332                        for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
     
    295341                        if (beg == 0) {
    296342                                /* Command completion */
    297                                 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     343                                found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    298344                        } else {
    299345                                /* Symbol completion */
    300                                 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
     346                                found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE), indev);
    301347                        }
    302348                       
    303349                        if (found == 0)
    304350                                continue;
    305                        
    306                         if (found > 1) {
    307                                 /* No unique hint, list was printed */
    308                                 printf("%s> ", prompt);
    309                                 printf("%ls", current);
    310                                 print_cc('\b', wstr_length(current) - position);
    311                                 continue;
    312                         }
    313                        
    314                         /* We have a hint */
    315                        
     351
     352                        /*
     353                         * We have hints, possibly many. In case of more than one hint,
     354                         * tmp will contain the common prefix.
     355                         */
    316356                        size_t off = 0;
    317357                        size_t i = 0;
     
    319359                                if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE))
    320360                                        break;
     361                               
    321362                                i++;
    322363                        }
     364                       
     365                        if (found > 1) {
     366                                /* No unique hint, list was printed */
     367                                printf("%s> ", prompt);
     368                                printf("%ls", current);
     369                                position += str_length(tmp);
     370                                print_cc('\b', wstr_length(current) - position);
     371                                continue;
     372                        }
     373                       
     374                        /* We have a hint */
    323375                       
    324376                        printf("%ls", current + position);
     
    541593/** Parse command line.
    542594 *
    543  * @param cmdline Command line as read from input device. 
     595 * @param cmdline Command line as read from input device.
    544596 * @param size    Size (in bytes) of the string.
    545597 *
  • kernel/generic/src/debug/symtab.c

    rbc216a0 rda68871a  
    4343#include <typedefs.h>
    4444#include <errno.h>
     45#include <console/prompt.h>
    4546
    4647/** Get name of a symbol that seems most likely to correspond to address.
     
    209210 *
    210211 */
    211 int symtab_compl(char *input, size_t size)
     212int symtab_compl(char *input, size_t size, indev_t *indev)
    212213{
    213214#ifdef CONFIG_SYMTAB
     
    227228        char output[MAX_SYMBOL_NAME];
    228229       
     230        /*
     231         * Maximum Match Length: Length of longest matching common substring in
     232         * case more than one match is found.
     233         */
     234        size_t max_match_len = size;
     235        size_t max_match_len_tmp = size;
     236        size_t input_len = str_length(input);
     237        char *sym_name;
     238        size_t hints_to_show = MAX_TAB_HINTS - 1;
     239        size_t total_hints_shown = 0;
     240        bool continue_showing_hints = true;
     241       
    229242        output[0] = 0;
     243       
     244        while ((hint = symtab_search_one(name, &pos)))
     245                pos++;
     246       
     247        pos = 0;
    230248       
    231249        while ((hint = symtab_search_one(name, &pos))) {
     
    235253                pos++;
    236254                found++;
     255        }
     256       
     257        /*
     258         * If the number of possible completions is more than MAX_TAB_HINTS,
     259         * ask the user whether to display them or not.
     260         */
     261        if (found > MAX_TAB_HINTS) {
     262                printf("\n");
     263                continue_showing_hints =
     264                    console_prompt_display_all_hints(indev, found);
    237265        }
    238266       
     
    241269                pos = 0;
    242270                while (symtab_search_one(name, &pos)) {
    243                         printf("%s\n", symbol_table[pos].symbol_name);
     271                        sym_name = symbol_table[pos].symbol_name;
    244272                        pos++;
     273                       
     274                        if (continue_showing_hints) {
     275                                /* We are still showing hints */
     276                                printf("%s\n", sym_name);
     277                                --hints_to_show;
     278                                ++total_hints_shown;
     279                               
     280                                if ((hints_to_show == 0) && (total_hints_shown != found)) {
     281                                        /* Ask the user to continue */
     282                                        continue_showing_hints =
     283                                            console_prompt_more_hints(indev, &hints_to_show);
     284                                }
     285                        }
     286                       
     287                        for (max_match_len_tmp = 0;
     288                            (output[max_match_len_tmp] ==
     289                            sym_name[input_len + max_match_len_tmp]) &&
     290                            (max_match_len_tmp < max_match_len); ++max_match_len_tmp);
     291                       
     292                        max_match_len = max_match_len_tmp;
    245293                }
     294               
     295                /* Keep only the characters common in all completions */
     296                output[max_match_len] = 0;
    246297        }
    247298       
  • kernel/generic/src/interrupt/interrupt.c

    rbc216a0 rda68871a  
    5050#include <panic.h>
    5151#include <print.h>
     52#include <stdarg.h>
    5253#include <symtab.h>
    5354#include <proc/thread.h>
     
    163164}
    164165
    165 /** Terminate thread and task if exception came from userspace.
    166  *
    167  */
    168 NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
    169 {
    170         if (!istate_from_uspace(istate))
    171                 return;
    172        
     166static NO_TRACE void fault_from_uspace_core(istate_t *istate, const char *fmt, va_list args)
     167{
    173168        printf("Task %s (%" PRIu64 ") killed due to an exception at "
    174169            "program counter %p.\n", TASK->name, TASK->taskid,
     
    179174       
    180175        printf("Kill message: ");
     176        vprintf(fmt, args);
     177        printf("\n");
     178       
     179        task_kill_self(true);
     180}
     181
     182/** Terminate thread and task after the exception came from userspace.
     183 *
     184 */
     185NO_TRACE void fault_from_uspace(istate_t *istate, const char *fmt, ...)
     186{
     187        va_list args;
     188
     189        va_start(args, fmt);
     190        fault_from_uspace_core(istate, fmt, args);
     191        va_end(args);
     192}
     193
     194/** Terminate thread and task if exception came from userspace.
     195 *
     196 */
     197NO_TRACE void fault_if_from_uspace(istate_t *istate, const char *fmt, ...)
     198{
     199        if (!istate_from_uspace(istate))
     200                return;
    181201       
    182202        va_list args;
    183203        va_start(args, fmt);
    184         vprintf(fmt, args);
     204        fault_from_uspace_core(istate, fmt, args);
    185205        va_end(args);
    186         printf("\n");
    187        
    188         task_kill_self(true);
    189206}
    190207
  • kernel/generic/src/ipc/irq.c

    rbc216a0 rda68871a  
    3939 * when interrupt is detected. The application may provide a simple 'top-half'
    4040 * handler as part of its registration, which can perform simple operations
    41  * (read/write port/memory, add information to notification ipc message).
     41 * (read/write port/memory, add information to notification IPC message).
    4242 *
    4343 * The structure of a notification message is as follows:
    4444 * - IMETHOD: interface and method as registered by
    4545 *            the SYS_IRQ_REGISTER syscall
    46  * - ARG1: payload modified by a 'top-half' handler
    47  * - ARG2: payload modified by a 'top-half' handler
    48  * - ARG3: payload modified by a 'top-half' handler
    49  * - ARG4: payload modified by a 'top-half' handler
    50  * - ARG5: payload modified by a 'top-half' handler
     46 * - ARG1: payload modified by a 'top-half' handler (scratch[1])
     47 * - ARG2: payload modified by a 'top-half' handler (scratch[2])
     48 * - ARG3: payload modified by a 'top-half' handler (scratch[3])
     49 * - ARG4: payload modified by a 'top-half' handler (scratch[4])
     50 * - ARG5: payload modified by a 'top-half' handler (scratch[5])
    5151 * - in_phone_hash: interrupt counter (may be needed to assure correct order
    5252 *                  in multithreaded drivers)
     
    8787static void ranges_unmap(irq_pio_range_t *ranges, size_t rangecount)
    8888{
    89         size_t i;
    90 
    91         for (i = 0; i < rangecount; i++) {
     89        for (size_t i = 0; i < rangecount; i++) {
    9290#ifdef IO_SPACE_BOUNDARY
    9391                if ((void *) ranges[i].base >= IO_SPACE_BOUNDARY)
     
    10098    irq_cmd_t *cmds, size_t cmdcount)
    10199{
    102         uintptr_t *pbase;
    103         size_t i, j;
    104 
    105100        /* Copy the physical base addresses aside. */
    106         pbase = malloc(rangecount * sizeof(uintptr_t), 0);
    107         for (i = 0; i < rangecount; i++)
     101        uintptr_t *pbase = malloc(rangecount * sizeof(uintptr_t), 0);
     102        for (size_t i = 0; i < rangecount; i++)
    108103                pbase[i] = ranges[i].base;
    109 
     104       
    110105        /* Map the PIO ranges into the kernel virtual address space. */
    111         for (i = 0; i < rangecount; i++) {
     106        for (size_t i = 0; i < rangecount; i++) {
    112107#ifdef IO_SPACE_BOUNDARY
    113108                if ((void *) ranges[i].base < IO_SPACE_BOUNDARY)
     
    122117                }
    123118        }
    124 
     119       
    125120        /* Rewrite the pseudocode addresses from physical to kernel virtual. */
    126         for (i = 0; i < cmdcount; i++) {
     121        for (size_t i = 0; i < cmdcount; i++) {
    127122                uintptr_t addr;
    128123                size_t size;
    129 
     124               
    130125                /* Process only commands that use an address. */
    131126                switch (cmds[i].cmd) {
    132127                case CMD_PIO_READ_8:
    133                 case CMD_PIO_WRITE_8:
    134                 case CMD_PIO_WRITE_A_8:
     128                case CMD_PIO_WRITE_8:
     129                case CMD_PIO_WRITE_A_8:
    135130                        size = 1;
    136131                        break;
    137                 case CMD_PIO_READ_16:
    138                 case CMD_PIO_WRITE_16:
    139                 case CMD_PIO_WRITE_A_16:
     132                case CMD_PIO_READ_16:
     133                case CMD_PIO_WRITE_16:
     134                case CMD_PIO_WRITE_A_16:
    140135                        size = 2;
    141136                        break;
    142                 case CMD_PIO_READ_32:
    143                 case CMD_PIO_WRITE_32:
    144                 case CMD_PIO_WRITE_A_32:
     137                case CMD_PIO_READ_32:
     138                case CMD_PIO_WRITE_32:
     139                case CMD_PIO_WRITE_A_32:
    145140                        size = 4;
    146141                        break;
     
    149144                        continue;
    150145                }
    151 
     146               
    152147                addr = (uintptr_t) cmds[i].addr;
    153148               
     149                size_t j;
    154150                for (j = 0; j < rangecount; j++) {
    155 
    156151                        /* Find the matching range. */
    157152                        if (!iswithin(pbase[j], ranges[j].size, addr, size))
    158153                                continue;
    159 
     154                       
    160155                        /* Switch the command to a kernel virtual address. */
    161156                        addr -= pbase[j];
    162157                        addr += ranges[j].base;
    163 
     158                       
    164159                        cmds[i].addr = (void *) addr;
    165160                        break;
    166161                }
    167 
     162               
    168163                if (j == rangecount) {
    169164                        /*
     
    176171                }
    177172        }
    178 
     173       
    179174        free(pbase);
     175        return EOK;
     176}
     177
     178/** Statically check the top-half pseudocode
     179 *
     180 * Check the top-half pseudocode for invalid or unsafe
     181 * constructs.
     182 *
     183 */
     184static int code_check(irq_cmd_t *cmds, size_t cmdcount)
     185{
     186        for (size_t i = 0; i < cmdcount; i++) {
     187                /*
     188                 * Check for accepted ranges.
     189                 */
     190                if (cmds[i].cmd >= CMD_LAST)
     191                        return EINVAL;
     192               
     193                if (cmds[i].srcarg >= IPC_CALL_LEN)
     194                        return EINVAL;
     195               
     196                if (cmds[i].dstarg >= IPC_CALL_LEN)
     197                        return EINVAL;
     198               
     199                switch (cmds[i].cmd) {
     200                case CMD_PREDICATE:
     201                        /*
     202                         * Check for control flow overflow.
     203                         * Note that jumping just beyond the last
     204                         * command is a correct behaviour.
     205                         */
     206                        if (i + cmds[i].value > cmdcount)
     207                                return EINVAL;
     208                       
     209                        break;
     210                default:
     211                        break;
     212                }
     213        }
     214       
    180215        return EOK;
    181216}
     
    207242        irq_pio_range_t *ranges = NULL;
    208243        irq_cmd_t *cmds = NULL;
    209 
     244       
    210245        irq_code_t *code = malloc(sizeof(*code), 0);
    211246        int rc = copy_from_uspace(code, ucode, sizeof(*code));
     
    222257        if (rc != EOK)
    223258                goto error;
    224 
     259       
    225260        cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0);
    226261        rc = copy_from_uspace(cmds, code->cmds,
     
    228263        if (rc != EOK)
    229264                goto error;
    230 
     265       
     266        rc = code_check(cmds, code->cmdcount);
     267        if (rc != EOK)
     268                goto error;
     269       
    231270        rc = ranges_map_and_apply(ranges, code->rangecount, cmds,
    232271            code->cmdcount);
    233272        if (rc != EOK)
    234273                goto error;
    235 
     274       
    236275        code->ranges = ranges;
    237276        code->cmds = cmds;
    238 
     277       
    239278        return code;
    240 
     279       
    241280error:
    242281        if (cmds)
    243282                free(cmds);
     283       
    244284        if (ranges)
    245285                free(ranges);
     286       
    246287        free(code);
    247288        return NULL;
     
    250291/** Register an answerbox as a receiving end for IRQ notifications.
    251292 *
    252  * @param box           Receiving answerbox.
    253  * @param inr           IRQ number.
    254  * @param devno         Device number.
    255  * @param imethod       Interface and method to be associated with the
    256  *                      notification.
    257  * @param ucode         Uspace pointer to top-half pseudocode.
    258  * @return              EOK on success or a negative error code.
     293 * @param box     Receiving answerbox.
     294 * @param inr     IRQ number.
     295 * @param devno   Device number.
     296 * @param imethod Interface and method to be associated with the
     297 *                notification.
     298 * @param ucode   Uspace pointer to top-half pseudocode.
     299 *
     300 * @return EOK on success or a negative error code.
    259301 *
    260302 */
     
    266308                (sysarg_t) devno
    267309        };
    268 
     310       
    269311        if ((inr < 0) || (inr > last_inr))
    270312                return ELIMIT;
     
    329371/** Unregister task from IRQ notification.
    330372 *
    331  * @param box           Answerbox associated with the notification.
    332  * @param inr           IRQ number.
    333  * @param devno         Device number.
    334  * @return              EOK on success or a negative error code.
     373 * @param box   Answerbox associated with the notification.
     374 * @param inr   IRQ number.
     375 * @param devno Device number.
     376 *
     377 * @return EOK on success or a negative error code.
     378 *
    335379 */
    336380int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
     
    340384                (sysarg_t) devno
    341385        };
    342 
     386       
    343387        if ((inr < 0) || (inr > last_inr))
    344388                return ELIMIT;
     
    436480                /* Remove from the hash table. */
    437481                hash_table_remove(&irq_uspace_hash_table, key, 2);
    438 
     482               
    439483                /*
    440484                 * Release both locks so that we can free the pseudo code.
     
    442486                irq_spinlock_unlock(&box->irq_lock, false);
    443487                irq_spinlock_unlock(&irq_uspace_hash_table_lock, true);
    444 
     488               
    445489                code_free(irq->notif_cfg.code);
    446490                free(irq);
     
    492536       
    493537        for (size_t i = 0; i < code->cmdcount; i++) {
    494                 uint32_t dstval;
    495                
    496538                uintptr_t srcarg = code->cmds[i].srcarg;
    497539                uintptr_t dstarg = code->cmds[i].dstarg;
    498540               
    499                 if (srcarg >= IPC_CALL_LEN)
    500                         break;
    501                
    502                 if (dstarg >= IPC_CALL_LEN)
    503                         break;
    504        
    505541                switch (code->cmds[i].cmd) {
    506542                case CMD_PIO_READ_8:
    507                         dstval = pio_read_8((ioport8_t *) code->cmds[i].addr);
    508                         if (dstarg)
    509                                 scratch[dstarg] = dstval;
     543                        scratch[dstarg] =
     544                            pio_read_8((ioport8_t *) code->cmds[i].addr);
    510545                        break;
    511546                case CMD_PIO_READ_16:
    512                         dstval = pio_read_16((ioport16_t *) code->cmds[i].addr);
    513                         if (dstarg)
    514                                 scratch[dstarg] = dstval;
     547                        scratch[dstarg] =
     548                            pio_read_16((ioport16_t *) code->cmds[i].addr);
    515549                        break;
    516550                case CMD_PIO_READ_32:
    517                         dstval = pio_read_32((ioport32_t *) code->cmds[i].addr);
    518                         if (dstarg)
    519                                 scratch[dstarg] = dstval;
     551                        scratch[dstarg] =
     552                            pio_read_32((ioport32_t *) code->cmds[i].addr);
    520553                        break;
    521554                case CMD_PIO_WRITE_8:
     
    532565                        break;
    533566                case CMD_PIO_WRITE_A_8:
    534                         if (srcarg) {
    535                                 pio_write_8((ioport8_t *) code->cmds[i].addr,
    536                                     (uint8_t) scratch[srcarg]);
    537                         }
     567                        pio_write_8((ioport8_t *) code->cmds[i].addr,
     568                            (uint8_t) scratch[srcarg]);
    538569                        break;
    539570                case CMD_PIO_WRITE_A_16:
    540                         if (srcarg) {
    541                                 pio_write_16((ioport16_t *) code->cmds[i].addr,
    542                                     (uint16_t) scratch[srcarg]);
    543                         }
     571                        pio_write_16((ioport16_t *) code->cmds[i].addr,
     572                            (uint16_t) scratch[srcarg]);
    544573                        break;
    545574                case CMD_PIO_WRITE_A_32:
    546                         if (srcarg) {
    547                                 pio_write_32((ioport32_t *) code->cmds[i].addr,
    548                                     (uint32_t) scratch[srcarg]);
    549                         }
    550                         break;
    551                 case CMD_BTEST:
    552                         if ((srcarg) && (dstarg)) {
    553                                 dstval = scratch[srcarg] & code->cmds[i].value;
    554                                 scratch[dstarg] = dstval;
    555                         }
     575                        pio_write_32((ioport32_t *) code->cmds[i].addr,
     576                            (uint32_t) scratch[srcarg]);
     577                        break;
     578                case CMD_LOAD:
     579                        scratch[dstarg] = code->cmds[i].value;
     580                        break;
     581                case CMD_AND:
     582                        scratch[dstarg] = scratch[srcarg] &
     583                            code->cmds[i].value;
    556584                        break;
    557585                case CMD_PREDICATE:
    558                         if ((srcarg) && (!scratch[srcarg])) {
     586                        if (scratch[srcarg] == 0)
    559587                                i += code->cmds[i].value;
    560                                 continue;
    561                         }
     588                       
    562589                        break;
    563590                case CMD_ACCEPT:
     
    582609{
    583610        ASSERT(irq);
    584 
     611       
    585612        ASSERT(interrupts_disabled());
    586613        ASSERT(irq_spinlock_locked(&irq->lock));
  • kernel/generic/src/lib/str.c

    rbc216a0 rda68871a  
    457457 *
    458458 * Do a char-by-char comparison of two NULL-terminated strings.
    459  * The strings are considered equal iff they consist of the same
    460  * characters on the minimum of their lengths.
     459 * The strings are considered equal iff their length is equal
     460 * and both strings consist of the same sequence of characters.
     461 *
     462 * A string S1 is less than another string S2 if it has a character with
     463 * lower value at the first character position where the strings differ.
     464 * If the strings differ in length, the shorter one is treated as if
     465 * padded by characters with a value of zero.
    461466 *
    462467 * @param s1 First string to compare.
    463468 * @param s2 Second string to compare.
    464469 *
    465  * @return 0 if the strings are equal, -1 if first is smaller,
    466  *         1 if second smaller.
     470 * @return 0 if the strings are equal, -1 if the first is less than the second,
     471 *         1 if the second is less than the first.
    467472 *
    468473 */
     
    495500 *
    496501 * Do a char-by-char comparison of two NULL-terminated strings.
    497  * The strings are considered equal iff they consist of the same
    498  * characters on the minimum of their lengths and the length limit.
     502 * The strings are considered equal iff
     503 * min(str_length(s1), max_len) == min(str_length(s2), max_len)
     504 * and both strings consist of the same sequence of characters,
     505 * up to max_len characters.
     506 *
     507 * A string S1 is less than another string S2 if it has a character with
     508 * lower value at the first character position where the strings differ.
     509 * If the strings differ in length, the shorter one is treated as if
     510 * padded by characters with a value of zero. Only the first max_len
     511 * characters are considered.
    499512 *
    500513 * @param s1      First string to compare.
     
    502515 * @param max_len Maximum number of characters to consider.
    503516 *
    504  * @return 0 if the strings are equal, -1 if first is smaller,
    505  *         1 if second smaller.
     517 * @return 0 if the strings are equal, -1 if the first is less than the second,
     518 *         1 if the second is less than the first.
    506519 *
    507520 */
  • kernel/generic/src/mm/as.c

    rbc216a0 rda68871a  
    665665               
    666666                page_table_lock(as, false);
    667                
    668                 /*
    669                  * Start TLB shootdown sequence.
    670                  */
    671                 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid,
    672                     area->base + P2SZ(pages), area->pages - pages);
    673667               
    674668                /*
     
    726720                                }
    727721                               
     722                                /*
     723                                 * Start TLB shootdown sequence.
     724                                 *
     725                                 * The sequence is rather short and can be
     726                                 * repeated multiple times. The reason is that
     727                                 * we don't want to have used_space_remove()
     728                                 * inside the sequence as it may use a blocking
     729                                 * memory allocation for its B+tree. Blocking
     730                                 * while holding the tlblock spinlock is
     731                                 * forbidden and would hit a kernel assertion.
     732                                 */
     733
     734                                ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES,
     735                                    as->asid, area->base + P2SZ(pages),
     736                                    area->pages - pages);
     737               
    728738                                for (; i < size; i++) {
    729739                                        pte_t *pte = page_mapping_find(as,
     
    743753                                        page_mapping_remove(as, ptr + P2SZ(i));
    744754                                }
     755               
     756                                /*
     757                                 * Finish TLB shootdown sequence.
     758                                 */
     759               
     760                                tlb_invalidate_pages(as->asid,
     761                                    area->base + P2SZ(pages),
     762                                    area->pages - pages);
     763               
     764                                /*
     765                                 * Invalidate software translation caches
     766                                 * (e.g. TSB on sparc64, PHT on ppc32).
     767                                 */
     768                                as_invalidate_translation_cache(as,
     769                                    area->base + P2SZ(pages),
     770                                    area->pages - pages);
     771                                tlb_shootdown_finalize(ipl);
    745772                        }
    746773                }
    747                
    748                 /*
    749                  * Finish TLB shootdown sequence.
    750                  */
    751                
    752                 tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),
    753                     area->pages - pages);
    754                
    755                 /*
    756                  * Invalidate software translation caches
    757                  * (e.g. TSB on sparc64, PHT on ppc32).
    758                  */
    759                 as_invalidate_translation_cache(as, area->base + P2SZ(pages),
    760                     area->pages - pages);
    761                 tlb_shootdown_finalize(ipl);
    762                
    763774                page_table_unlock(as, false);
    764775        } else {
  • kernel/generic/src/mm/tlb.c

    rbc216a0 rda68871a  
    162162       
    163163        size_t i;
    164         for (i = 0; i < CPU->tlb_messages_count; CPU->tlb_messages_count--) {
     164        for (i = 0; i < CPU->tlb_messages_count; i++) {
    165165                tlb_invalidate_type_t type = CPU->tlb_messages[i].type;
    166166                asid_t asid = CPU->tlb_messages[i].asid;
     
    188188        }
    189189       
     190        CPU->tlb_messages_count = 0;
    190191        irq_spinlock_unlock(&CPU->lock, false);
    191192        CPU->tlb_active = true;
Note: See TracChangeset for help on using the changeset viewer.