Changeset 827d73f in mainline for kernel


Ignore:
Timestamp:
2010-02-12T14:09:22Z (16 years ago)
Author:
Lukas Mejdrech <lukasmejdrech@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a70bda4
Parents:
918e9910 (diff), e70edd1 (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 the actual head

Location:
kernel
Files:
49 added
84 edited
4 moved

Legend:

Unmodified
Added
Removed
  • kernel/Makefile

    r918e9910 r827d73f  
    3333all: ../version ../Makefile.config ../config.h ../config.defs
    3434        -[ -f $(DEPEND) ] && mv -f $(DEPEND) $(DEPEND_PREV)
    35         $(MAKE) -f Makefile.build EXTRA_TOOL=$(EXTRA_TOOL)
     35        $(MAKE) -f Makefile.build PRECHECK=$(PRECHECK)
    3636
    3737clean:
    3838        rm -f $(DEPEND) $(DEPEND_PREV) $(RAW) $(BIN) $(MAP) $(JOB) $(MAP_PREV) $(DISASM) $(DUMP) $(REAL_MAP).* $(ARCH_INCLUDE) $(GENARCH_INCLUDE) arch/*/_link.ld
    3939        find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
    40         find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o.preproc' -follow -exec rm \{\} \;
  • kernel/Makefile.build

    r918e9910 r827d73f  
    5555        -fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
    5656        -finput-charset=UTF-8 -ffreestanding -fno-builtin -nostdlib -nostdinc \
    57         -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \
    58         -pipe
     57        -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes \
     58        -Werror-implicit-function-declaration -Werror -pipe
    5959
    6060ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
    6161        -ffreestanding -fno-builtin -nostdlib -nostdinc -Wall -Wmissing-prototypes \
    62         -Werror -wd170
     62        -Werror-implicit-function-declaration -Werror -wd170
    6363
    6464SUNCC_CFLAGS = -I$(INCLUDES) -xO$(OPTIMIZATION) \
     
    186186        generic/src/ddi/device.c \
    187187        generic/src/debug/symtab.c \
     188        generic/src/debug/stacktrace.c \
    188189        generic/src/interrupt/interrupt.c \
    189190        generic/src/main/main.c \
     
    375376%.o: %.S $(DEPEND)
    376377        $(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -c $< -o $@
     378ifeq ($(PRECHECK),y)
     379        $(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(GCC_CFLAGS) -D__ASM__
     380endif
    377381
    378382%.o: %.s $(DEPEND)
    379383        $(AS) $(AFLAGS) $< -o $@
     384ifeq ($(PRECHECK),y)
     385        $(JOBFILE) $(JOB) $< $@ as asm $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
     386endif
    380387
    381388#
     
    385392test/fpu/%.o: test/fpu/%.c $(DEPEND)
    386393        $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@
    387 ifeq ($(EXTRA_TOOL),stanse)
    388         ../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
     394ifeq ($(PRECHECK),y)
     395        $(JOBFILE) $(JOB) $< $@ cc test $(DEFS) $(CFLAGS) $(EXTRA_FLAGS)
    389396endif
    390397
     
    394401%.o: %.c $(DEPEND)
    395402        $(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@
    396 ifeq ($(EXTRA_TOOL),stanse)
    397         ../tools/jobfile.py $(JOB) $< $@ $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
     403ifeq ($(PRECHECK),y)
     404        $(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS)
    398405endif
    399406
     
    405412        $(LD) -T $(LINK) $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(EMPTY_MAP) -o $@ -Map $(MAP_PREV)
    406413        $(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
    407         tools/genmap.py $(MAP_PREV) $(DUMP) $@
     414        $(GENMAP) $(MAP_PREV) $(DUMP) $@
    408415       
    409416        # Do it once again, this time to get correct even the symbols
     
    413420        $(LD) -T $(LINK) $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SIZEOK_MAP) -o $@ -Map $(MAP_PREV)
    414421        $(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > $(DUMP)
    415         tools/genmap.py $(MAP_PREV) $(DUMP) $@
     422        $(GENMAP) $(MAP_PREV) $(DUMP) $@
    416423
    417424$(DEPEND): $(ARCH_INCLUDE) $(GENARCH_INCLUDE)
  • kernel/Makefile.common

    r918e9910 r827d73f  
    4444ARCH_INCLUDE = generic/include/arch
    4545GENARCH_INCLUDE = generic/include/genarch
     46
     47GENMAP = tools/genmap.py
     48JOBFILE = ../tools/jobfile.py
  • kernel/arch/amd64/Makefile.inc

    r918e9910 r827d73f  
    3838
    3939FPU_NO_CFLAGS = -mno-sse -mno-sse2
    40 CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables
     40CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables -fno-omit-frame-pointer
    4141GCC_CFLAGS += $(CMN1)
    4242ICC_CFLAGS += $(CMN1)
     
    6060        arch/$(KARCH)/src/boot/boot.S \
    6161        arch/$(KARCH)/src/boot/memmap.c \
     62        arch/$(KARCH)/src/debug/stacktrace.c \
     63        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    6264        arch/$(KARCH)/src/pm.c \
    6365        arch/$(KARCH)/src/context.S \
  • kernel/arch/amd64/_link.ld.in

    r918e9910 r827d73f  
    4444                *(COMMON);              /* global variables */
    4545
     46                . = ALIGN(8);
    4647                symbol_table = .;
    4748                *(symtab.*);            /* Symbol table, must be LAST symbol!*/
  • kernel/arch/amd64/include/asm.h

    r918e9910 r827d73f  
    6868}
    6969
    70 static inline void cpu_halt(void)
    71 {
    72         asm volatile (
    73                 "0:\n"
    74                 "       hlt\n"
    75                 "       jmp 0b\n"
    76         );
     70static inline void __attribute__((noreturn)) cpu_halt(void)
     71{
     72        while (true) {
     73                asm volatile (
     74                        "hlt\n"
     75                );
     76        }
    7777}
    7878
  • kernel/arch/amd64/include/context.h

    r918e9910 r827d73f  
    4646#define SP_DELTA     16
    4747
     48#define context_set(c, _pc, stack, size) \
     49        do { \
     50                (c)->pc = (uintptr_t) (_pc); \
     51                (c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
     52                (c)->rbp = 0; \
     53        } while (0)
     54
    4855#endif /* KERNEL */
    4956
  • kernel/arch/amd64/include/interrupt.h

    r918e9910 r827d73f  
    7070
    7171/** This is passed to interrupt handlers */
    72 typedef struct {
     72typedef struct istate {
    7373        uint64_t rax;
    7474        uint64_t rcx;
     
    8080        uint64_t r10;
    8181        uint64_t r11;
     82        uint64_t rbp;
    8283        uint64_t error_word;
    8384        uint64_t rip;
     
    101102        return istate->rip;
    102103}
     104static inline unative_t istate_get_fp(istate_t *istate)
     105{
     106        return istate->rbp;
     107}
    103108
    104109extern void (* disable_irqs_function)(uint16_t irqmask);
  • kernel/arch/amd64/src/amd64.c

    r918e9910 r827d73f  
    212212                        i8042_wire(i8042_instance, kbrd);
    213213                        trap_virtual_enable_irqs(1 << IRQ_KBD);
     214                        trap_virtual_enable_irqs(1 << IRQ_MOUSE);
    214215                }
    215216        }
     
    219220         * self-sufficient.
    220221         */
    221         sysinfo_set_item_val("kbd", NULL, true);
    222         sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
    223         sysinfo_set_item_val("kbd.address.physical", NULL,
     222        sysinfo_set_item_val("i8042", NULL, true);
     223        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     224        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     225        sysinfo_set_item_val("i8042.address.physical", NULL,
    224226            (uintptr_t) I8042_BASE);
    225         sysinfo_set_item_val("kbd.address.kernel", NULL,
     227        sysinfo_set_item_val("i8042.address.kernel", NULL,
    226228            (uintptr_t) I8042_BASE);
    227229#endif
     
    276278}
    277279
     280void irq_initialize_arch(irq_t *irq)
     281{
     282        (void) irq;
     283}
     284
    278285/** @}
    279286 */
  • kernel/arch/amd64/src/asm_utils.S

    r918e9910 r827d73f  
    2727#
    2828
    29 #define IREGISTER_SPACE 72
     29#define IREGISTER_SPACE 80
    3030
    3131#define IOFFSET_RAX     0x0
     
    3838#define IOFFSET_R10     0x38
    3939#define IOFFSET_R11     0x40
     40#define IOFFSET_RBP     0x48
    4041
    4142#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
     
    179180        movq %r10, IOFFSET_R10(%rsp)
    180181        movq %r11, IOFFSET_R11(%rsp)
     182        movq %rbp, IOFFSET_RBP(%rsp)
    181183.endm
    182184
     
    191193        movq IOFFSET_R10(%rsp), %r10
    192194        movq IOFFSET_R11(%rsp), %r11
     195        movq IOFFSET_RBP(%rsp), %rbp
    193196.endm
    194197
     
    235238        cld
    236239
     240        # Stop stack traces here
     241        xorq %rbp, %rbp
     242
    237243        movq $(\i), %rdi        # %rdi - first parameter
    238244        movq %rsp, %rsi         # %rsi - pointer to istate
  • kernel/arch/amd64/src/boot/boot.S

    r918e9910 r827d73f  
    174174        call arch_pre_main
    175175       
     176        # create the first stack frame
     177        pushq $0
     178        movq %rsp, %rbp
     179
    176180        call main_bsp
    177181       
     
    329333
    330334extended_cpuid_msg:
    331         .asciz "Extended CPUID not supported. System halted."
     335        .asciz "Error: Extended CPUID not supported -- CPU is not 64-bit. System halted."
    332336long_mode_msg:
    333         .asciz "64 bit long mode not supported. System halted."
     337        .asciz "Error: 64-bit long mode not supported. System halted."
    334338noexecute_msg:
    335         .asciz "No-execute pages not supported. System halted."
     339        .asciz "Error: No-execute pages not supported. System halted."
    336340fx_msg:
    337         .asciz "FXSAVE/FXRESTORE instructions not supported. System halted."
     341        .asciz "Error: FXSAVE/FXRESTORE instructions not supported. System halted."
    338342sse2_msg:
    339         .asciz "SSE2 instructions not supported. System halted."
     343        .asciz "Error: SSE2 instructions not supported. System halted."
  • kernel/arch/amd64/src/interrupt.c

    r918e9910 r827d73f  
    5353#include <ddi/irq.h>
    5454#include <symtab.h>
     55#include <stacktrace.h>
    5556
    5657/*
     
    8081            istate->r10, istate->r11);
    8182        printf("%%rsp=%#llx\n", &istate->stack[0]);
     83       
     84        stack_trace_istate(istate);
    8285}
    8386
  • kernel/arch/amd64/src/mm/page.c

    r918e9910 r827d73f  
    203203{
    204204        if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
    205                 panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
     205                panic("Unable to map physical memory %p (%d bytes).", physaddr,
     206                    size);
    206207       
    207208        uintptr_t virtaddr = PA2KA(last_frame);
  • kernel/arch/amd64/src/smp/ap.S

    r918e9910 r827d73f  
    9999start64:
    100100        movq (ctx), %rsp
     101        pushq $0
     102        movq %rsp, %rbp
    101103        call main_ap - AP_BOOT_OFFSET + BOOT_OFFSET   # never returns
    102104
  • kernel/arch/arm32/Makefile.inc

    r918e9910 r827d73f  
    3838ATSIGN = %
    3939
    40 GCC_CFLAGS += -fno-zero-initialized-in-bss
     40GCC_CFLAGS += -fno-zero-initialized-in-bss -mapcs-frame
    4141
    4242BITS = 32
     
    5757        arch/$(KARCH)/src/exception.c \
    5858        arch/$(KARCH)/src/userspace.c \
     59        arch/$(KARCH)/src/debug/stacktrace.c \
     60        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    5961        arch/$(KARCH)/src/mm/as.c \
    6062        arch/$(KARCH)/src/mm/frame.c \
  • kernel/arch/arm32/_link.ld.in

    r918e9910 r827d73f  
    3434                *(.sdata);
    3535                *(.reginfo);
     36                . = ALIGN(8);
    3637                symbol_table = .;
    3738                *(symtab.*);
  • kernel/arch/arm32/include/asm.h

    r918e9910 r827d73f  
    9696}
    9797
    98 extern void cpu_halt(void);
     98extern void cpu_halt(void) __attribute__((noreturn));
    9999extern void asm_delay_loop(uint32_t t);
    100100extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
  • kernel/arch/arm32/include/context.h

    r918e9910 r827d73f  
    4343#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
    4444
     45#define context_set(c, _pc, stack, size) \
     46        do { \
     47                (c)->pc = (uintptr_t) (_pc); \
     48                (c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
     49                (c)->fp = 0; \
     50        } while (0)
     51
    4552#ifndef __ASM__
    4653
     
    6269        uint32_t r9;
    6370        uint32_t r10;
    64         uint32_t r11;
     71        uint32_t fp;    /* r11 */
    6572       
    6673        ipl_t ipl;
  • kernel/arch/arm32/include/exception.h

    r918e9910 r827d73f  
    8686
    8787/** Struct representing CPU state saved when an exception occurs. */
    88 typedef struct {
     88typedef struct istate {
    8989        uint32_t spsr;
    9090        uint32_t sp;
     
    102102        uint32_t r9;
    103103        uint32_t r10;
    104         uint32_t r11;
     104        uint32_t fp;
    105105        uint32_t r12;
    106106
     
    133133}
    134134
     135static inline unative_t istate_get_fp(istate_t *istate)
     136{
     137        return istate->fp;
     138}
     139
    135140
    136141extern void install_exception_handlers(void);
  • kernel/arch/arm32/src/arm32.c

    r918e9910 r827d73f  
    155155void cpu_halt(void)
    156156{
    157         machine_cpu_halt();
     157        while (true)
     158                machine_cpu_halt();
    158159}
    159160
     
    162163{
    163164        /* not implemented */
    164         while (1);
     165        while (true);
    165166}
    166167
     
    179180}
    180181
     182void irq_initialize_arch(irq_t *irq)
     183{
     184        (void) irq;
     185}
     186
    181187/** @}
    182188 */
  • kernel/arch/arm32/src/exc_handler.S

    r918e9910 r827d73f  
    123123        stmfd r13!, {r2}
    1241242:
     125        # Stop stack traces here
     126        mov fp, #0
    125127.endm
    126128
  • kernel/arch/arm32/src/exception.c

    r918e9910 r827d73f  
    4242#include <print.h>
    4343#include <syscall/syscall.h>
     44#include <stacktrace.h>
    4445
    4546#ifdef MACHINE_testarm
     
    183184        printf(" r4: %x    r5: %x    r6: %x    r7: %x\n",
    184185            istate->r4, istate->r5, istate->r6, istate->r7);
    185         printf(" r8: %x    r8: %x   r10: %x   r11: %x\n",
    186             istate->r8, istate->r9, istate->r10, istate->r11);
     186        printf(" r8: %x    r8: %x   r10: %x    fp: %x\n",
     187            istate->r8, istate->r9, istate->r10, istate->fp);
    187188        printf(" r12: %x    sp: %x    lr: %x  spsr: %x\n",
    188189            istate->r12, istate->sp, istate->lr, istate->spsr);
    189190       
    190191        printf(" pc: %x\n", istate->pc);
     192
     193        stack_trace_istate(istate);
    191194}
    192195
  • kernel/arch/arm32/src/mm/page.c

    r918e9910 r827d73f  
    8888            KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
    8989                panic("Unable to map physical memory %p (%d bytes).",
    90                     physaddr, size)
     90                    physaddr, size);
    9191        }
    9292       
  • kernel/arch/arm32/src/mm/page_fault.c

    r918e9910 r827d73f  
    181181
    182182        if (ret == AS_PF_FAULT) {
     183                fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
    183184                print_istate(istate);
    184185                printf("page fault - pc: %x, va: %x, status: %x(%x), "
     
    186187                    access);
    187188               
    188                 fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
    189189                panic("Page fault.");
    190190        }
  • kernel/arch/arm32/src/start.S

    r918e9910 r827d73f  
    6969        bl arch_pre_main
    7070       
     71        #
     72        # Create the first stack frame.
     73        #
     74        mov fp, #0
     75        mov ip, sp
     76        push {fp, ip, lr, pc}
     77        sub fp, ip, #4
     78
    7179        bl main_bsp
    7280
  • kernel/arch/ia32/Makefile.inc

    r918e9910 r827d73f  
    7878        arch/$(KARCH)/src/context.S \
    7979        arch/$(KARCH)/src/debug/panic.s \
     80        arch/$(KARCH)/src/debug/stacktrace.c \
     81        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    8082        arch/$(KARCH)/src/delay.s \
    8183        arch/$(KARCH)/src/asm.S \
  • kernel/arch/ia32/_link.ld.in

    r918e9910 r827d73f  
    4242                hardcoded_unmapped_kdata_size = .;
    4343                LONG(unmapped_kdata_end - unmapped_kdata_start);
     44                . = ALIGN(8);
    4445                symbol_table = .;
    4546                *(symtab.*);            /* Symbol table, must be LAST symbol! */
  • kernel/arch/ia32/include/asm.h

    r918e9910 r827d73f  
    6060 *
    6161 */
    62 static inline void cpu_halt(void)
    63 {
    64         asm volatile (
    65                 "0:\n"
    66                 "       hlt\n"
    67                 "       jmp 0b\n"
    68         );
     62static inline __attribute__((noreturn)) void cpu_halt(void)
     63{
     64        while (true) {
     65                asm volatile (
     66                        "hlt\n"
     67                );
     68        }
    6969}
    7070
  • kernel/arch/ia32/include/context.h

    r918e9910 r827d73f  
    4949#define SP_DELTA        (8 + STACK_ITEM_SIZE)
    5050
     51#define context_set(c, _pc, stack, size) \
     52        do { \
     53                (c)->pc = (uintptr_t) (_pc); \
     54                (c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA; \
     55                (c)->ebp = 0; \
     56        } while (0)
     57
    5158#endif /* KERNEL */
    5259
  • kernel/arch/ia32/include/interrupt.h

    r918e9910 r827d73f  
    6969#define VECTOR_DEBUG_IPI                (IVT_FREEBASE + 2)
    7070
    71 typedef struct {
     71typedef struct istate {
    7272        uint32_t eax;
    7373        uint32_t ecx;
    7474        uint32_t edx;
     75        uint32_t ebp;
    7576
    7677        uint32_t gs;
     
    102103}
    103104
     105static inline unative_t istate_get_fp(istate_t *istate)
     106{
     107        return istate->ebp;
     108}
     109
    104110extern void (* disable_irqs_function)(uint16_t irqmask);
    105111extern void (* enable_irqs_function)(uint16_t irqmask);
  • kernel/arch/ia32/src/asm.S

    r918e9910 r827d73f  
    269269        pushl %gs
    270270
     271        pushl %ebp
    271272        pushl %edx
    272273        pushl %ecx
     
    278279        movw %ax, %es
    279280
    280         cld
     281        # stop stack traces here
     282        xorl %ebp, %ebp
    281283
    282284        pushl %esp          # *istate
     
    290292        popl %ecx
    291293        popl %edx
     294        popl %ebp
    292295       
    293296        popl %gs
  • kernel/arch/ia32/src/boot/boot.S

    r918e9910 r827d73f  
    9494        pushl grub_eax
    9595        call arch_pre_main
     96
     97        # Create the first stack frame
     98        pushl $0
     99        movl %esp, %ebp
    96100       
    97101        call main_bsp
  • kernel/arch/ia32/src/ia32.c

    r918e9910 r827d73f  
    170170                        i8042_wire(i8042_instance, kbrd);
    171171                        trap_virtual_enable_irqs(1 << IRQ_KBD);
     172                        trap_virtual_enable_irqs(1 << IRQ_MOUSE);
    172173                }
    173174        }
     
    177178         * self-sufficient.
    178179         */
    179         sysinfo_set_item_val("kbd", NULL, true);
    180         sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
    181         sysinfo_set_item_val("kbd.address.physical", NULL,
     180        sysinfo_set_item_val("i8042", NULL, true);
     181        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     182        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     183        sysinfo_set_item_val("i8042.address.physical", NULL,
    182184            (uintptr_t) I8042_BASE);
    183         sysinfo_set_item_val("kbd.address.kernel", NULL,
     185        sysinfo_set_item_val("i8042.address.kernel", NULL,
    184186            (uintptr_t) I8042_BASE);
    185187#endif
     
    232234}
    233235
     236void irq_initialize_arch(irq_t *irq)
     237{
     238        (void) irq;
     239}
     240
    234241/** @}
    235242 */
  • kernel/arch/ia32/src/interrupt.c

    r918e9910 r827d73f  
    5353#include <ddi/irq.h>
    5454#include <symtab.h>
     55#include <stacktrace.h>
    5556
    5657/*
     
    7980        printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]);
    8081        printf("       %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]);
     82
     83        stack_trace_istate(istate);
    8184}
    8285
  • kernel/arch/ia32/src/mm/page.c

    r918e9910 r827d73f  
    8080{
    8181        if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
    82                 panic("Unable to map physical memory %p (%d bytes).", physaddr, size)
     82                panic("Unable to map physical memory %p (%d bytes).", physaddr, size);
    8383       
    8484        uintptr_t virtaddr = PA2KA(last_frame);
  • kernel/arch/ia32/src/smp/ap.S

    r918e9910 r827d73f  
    7878        addl $0x80000000, %esp                  # PA2KA(ctx.sp)
    7979       
     80        pushl $0                                # create the first stack frame
     81        movl %esp, %ebp
     82
    8083        jmpl $KTEXT, $main_ap
    8184
  • kernel/arch/ia64/Makefile.inc

    r918e9910 r827d73f  
    5353        arch/$(KARCH)/src/context.S \
    5454        arch/$(KARCH)/src/cpu/cpu.c \
     55        arch/$(KARCH)/src/debug/stacktrace.c \
     56        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    5557        arch/$(KARCH)/src/ivt.S \
    5658        arch/$(KARCH)/src/interrupt.c \
  • kernel/arch/ia64/_link.ld.in

    r918e9910 r827d73f  
    3737                *(COMMON);
    3838
     39                . = ALIGN(8);
    3940                symbol_table = .;
    4041                *(symtab.*);            /* Symbol table, must be LAST symbol!*/
  • kernel/arch/ia64/include/asm.h

    r918e9910 r827d73f  
    428428}
    429429
    430 extern void cpu_halt(void);
     430extern void cpu_halt(void) __attribute__((noreturn));
    431431extern void cpu_sleep(void);
    432432extern void asm_delay_loop(uint32_t t);
  • kernel/arch/ia64/include/context.h

    r918e9910 r827d73f  
    4848 */
    4949#define SP_DELTA        (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
    50 
    51 #ifdef context_set
    52 #undef context_set
    53 #endif
    5450
    5551/* RSE stack starts at the bottom of memory stack. */
  • kernel/arch/ia64/include/interrupt.h

    r918e9910 r827d73f  
    7272#define EOI  0  /**< The actual value doesn't matter. */
    7373
    74 typedef struct {
     74typedef struct istate {
    7575        uint128_t f2;
    7676        uint128_t f3;
     
    143143}
    144144
     145static inline unative_t istate_get_fp(istate_t *istate)
     146{
     147        return 0;       /* FIXME */
     148}
     149
    145150static inline int istate_from_uspace(istate_t *istate)
    146151{
  • kernel/arch/ia64/include/mm/asid.h

    r918e9910 r827d73f  
    5050 * but those extra bits are not used by the kernel.
    5151 */
    52 #define RIDS_PER_ASID           7
     52#define RIDS_PER_ASID           8
    5353
    5454#define RID_MAX                 262143          /* 2^18 - 1 */
    55 #define RID_KERNEL              0
    56 #define RID_INVALID             1
     55#define RID_KERNEL7             7
    5756
    58 #define ASID2RID(asid, vrn)     (((asid)>RIDS_PER_ASID)?(((asid)*RIDS_PER_ASID)+(vrn)):(asid))
    59 #define RID2ASID(rid)           ((rid)/RIDS_PER_ASID)
     57#define ASID2RID(asid, vrn) \
     58        ((asid) * RIDS_PER_ASID + (vrn))
    6059
    61 #define ASID_MAX_ARCH           (RID_MAX/RIDS_PER_ASID)
     60#define RID2ASID(rid) \
     61        ((rid) / RIDS_PER_ASID)
     62
     63#define ASID_MAX_ARCH           (RID_MAX / RIDS_PER_ASID)
    6264
    6365#endif
  • kernel/arch/ia64/src/debug/stacktrace_asm.S

    r918e9910 r827d73f  
    11#
    2 # Copyright (c) 2009 Jakub Jermar
     2# Copyright (c) 2010 Jakub Jermar
    33# All rights reserved.
    44#
     
    3030
    3131.global frame_pointer_get
    32 .global frame_pointer_prev
    33 .global frame_pointer_validate
    34 .global return_address_get
    3532.global program_counter_get
    3633
    3734frame_pointer_get:
    38 frame_pointer_prev:
    39 frame_pointer_validate:
    40 return_address_get:
     35        mov r8 = r0
     36        br.ret.sptk.many b0
     37
    4138program_counter_get:
    4239        mov r8 = r0
  • kernel/arch/ia64/src/ia64.c

    r918e9910 r827d73f  
    4444#include <arch/stack.h>
    4545#include <arch/mm/page.h>
     46#include <interrupt.h>
    4647#include <mm/as.h>
    4748#include <config.h>
     
    203204        }
    204205       
    205         sysinfo_set_item_val("kbd", NULL, true);
    206         sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
    207         sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
    208         sysinfo_set_item_val("kbd.address.physical", NULL,
     206        sysinfo_set_item_val("i8042", NULL, true);
     207        sysinfo_set_item_val("i8042.inr_a", NULL, IRQ_KBD);
     208        sysinfo_set_item_val("i8042.inr_b", NULL, IRQ_MOUSE);
     209        sysinfo_set_item_val("i8042.address.physical", NULL,
    209210            (uintptr_t) I8042_BASE);
    210         sysinfo_set_item_val("kbd.address.kernel", NULL,
     211        sysinfo_set_item_val("i8042.address.kernel", NULL,
    211212            (uintptr_t) I8042_BASE);
    212213#endif
     
    280281}
    281282
     283void irq_initialize_arch(irq_t *irq)
     284{
     285        (void) irq;
     286}
     287
    282288/** @}
    283289 */
  • kernel/arch/ia64/src/mm/page.c

    r918e9910 r827d73f  
    7171
    7272        /*
    73          * First set up kernel region register.
    74          * This is redundant (see start.S) but we keep it here just for sure.
    75          */
    76         rr.word = rr_read(VRN_KERNEL);
    77         rr.map.ve = 0;                  /* disable VHPT walker */
    78         rr.map.ps = PAGE_WIDTH;
    79         rr.map.rid = ASID2RID(ASID_KERNEL, VRN_KERNEL);
    80         rr_write(VRN_KERNEL, rr.word);
    81         srlz_i();
    82         srlz_d();
    83 
    84         /*
    85          * And setup the rest of region register.
     73         * Set up kernel region registers.
     74         * VRN_KERNEL has already been set in start.S.
     75         * For paranoia reasons, we set it again.
    8676         */
    8777        for(i = 0; i < REGION_REGISTERS; i++) {
    88                 /* skip kernel rr */
    89                 if (i == VRN_KERNEL)
    90                         continue;
    91        
    9278                rr.word = rr_read(i);
    9379                rr.map.ve = 0;          /* disable VHPT walker */
    94                 rr.map.rid = RID_KERNEL;
     80                rr.map.rid = ASID2RID(ASID_KERNEL, i);
    9581                rr.map.ps = PAGE_WIDTH;
    9682                rr_write(i, rr.word);
  • kernel/arch/ia64/src/start.S

    r918e9910 r827d73f  
    7474        movl r10 = (RR_MASK)
    7575        and r9 = r10, r9
    76         movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
     76        movl r10 = (((RID_KERNEL7) << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
    7777        or r9 = r10, r9
    7878       
  • kernel/arch/mips32/Makefile.inc

    r918e9910 r827d73f  
    7070        arch/$(KARCH)/src/debugger.c \
    7171        arch/$(KARCH)/src/cpu/cpu.c \
     72        arch/$(KARCH)/src/debug/stacktrace.c \
     73        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    7274        arch/$(KARCH)/src/mm/frame.c \
    7375        arch/$(KARCH)/src/mm/page.c \
  • kernel/arch/mips32/_link.ld.in

    r918e9910 r827d73f  
    3838                *(.bss);                        /* uninitialized static variables */
    3939                *(COMMON);                      /* global variables */
     40                . = ALIGN(8);
    4041                symbol_table = .;
    4142                *(symtab.*);
  • kernel/arch/mips32/include/asm.h

    r918e9910 r827d73f  
    6666}
    6767
    68 extern void cpu_halt(void);
     68extern void cpu_halt(void) __attribute__((noreturn));
    6969extern void asm_delay_loop(uint32_t t);
    7070extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
  • kernel/arch/mips32/include/context.h

    r918e9910 r827d73f  
    2727 */
    2828
    29 /** @addtogroup mips32 
     29/** @addtogroup mips32
    3030 * @{
    3131 */
     
    4242 * Put one item onto the stack to support get_stack_base() and align it up.
    4343 */
    44 #define SP_DELTA        (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
    45 
     44#define SP_DELTA  (0 + ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT))
    4645
    4746#ifndef __ASM__
    4847
    4948#include <arch/types.h>
     49
     50#define context_set(ctx, pc, stack, size) \
     51    context_set_generic(ctx, pc, stack, size)
    5052
    5153/*
  • kernel/arch/mips32/include/exception.h

    r918e9910 r827d73f  
    5858#define EXC_VCED        31
    5959
    60 typedef struct {
     60typedef struct istate {
    6161        uint32_t at;
    6262        uint32_t v0;
     
    102102        return istate->epc;
    103103}
     104static inline unative_t istate_get_fp(istate_t *istate)
     105{
     106        return 0;       /* FIXME */
     107}
    104108
    105109extern void exception(istate_t *istate);
  • kernel/arch/mips32/src/debug/stacktrace_asm.S

    r918e9910 r827d73f  
    11#
    2 # Copyright (c) 2009 Jakub Jermar
     2# Copyright (c) 2010 Jakub Jermar
    33# All rights reserved.
    44#
     
    3333
    3434.global frame_pointer_get
    35 .global frame_pointer_prev
    36 .global frame_pointer_validate
    37 .global return_address_get
    3835.global program_counter_get
    3936
    4037frame_pointer_get:
    41 frame_pointer_prev:
    42 frame_pointer_validate:
    43 return_address_get:
     38        j $ra
     39        xor $v0, $v0
     40
    4441program_counter_get:
    4542        j $ra
  • kernel/arch/mips32/src/mips32.c

    r918e9910 r827d73f  
    4646#include <sysinfo/sysinfo.h>
    4747#include <arch/interrupt.h>
     48#include <interrupt.h>
    4849#include <console/chardev.h>
    4950#include <arch/barrier.h>
     
    257258}
    258259
     260void irq_initialize_arch(irq_t *irq)
     261{
     262        (void) irq;
     263}
     264
    259265/** @}
    260266 */
  • kernel/arch/ppc32/Makefile.inc

    r918e9910 r827d73f  
    4646        arch/$(KARCH)/src/context.S \
    4747        arch/$(KARCH)/src/debug/panic.s \
     48        arch/$(KARCH)/src/debug/stacktrace.c \
     49        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    4850        arch/$(KARCH)/src/fpu_context.S \
    4951        arch/$(KARCH)/src/boot/boot.S \
  • kernel/arch/ppc32/_link.ld.in

    r918e9910 r827d73f  
    5151                *(COMMON);      /* global variables */
    5252               
     53                . = ALIGN(8);
    5354                symbol_table = .;
    5455                *(symtab.*);    /* Symbol table, must be LAST symbol!*/
  • kernel/arch/ppc32/include/asm.h

    r918e9910 r827d73f  
    2727 */
    2828
    29 /** @addtogroup ppc32   
     29/** @addtogroup ppc32
    3030 * @{
    3131 */
     
    146146}
    147147
    148 void cpu_halt(void);
    149 void asm_delay_loop(uint32_t t);
    150 
     148extern void cpu_halt(void) __attribute__((noreturn));
     149extern void asm_delay_loop(uint32_t t);
    151150extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
    152151
    153152static inline void pio_write_8(ioport8_t *port, uint8_t v)
    154153{
    155         *port = v;     
     154        *port = v;
    156155}
    157156
    158157static inline void pio_write_16(ioport16_t *port, uint16_t v)
    159158{
    160         *port = v;     
     159        *port = v;
    161160}
    162161
    163162static inline void pio_write_32(ioport32_t *port, uint32_t v)
    164163{
    165         *port = v;     
     164        *port = v;
    166165}
    167166
    168167static inline uint8_t pio_read_8(ioport8_t *port)
    169168{
    170         return *port; 
     169        return *port;
    171170}
    172171
    173172static inline uint16_t pio_read_16(ioport16_t *port)
    174173{
    175         return *port; 
     174        return *port;
    176175}
    177176
    178177static inline uint32_t pio_read_32(ioport32_t *port)
    179178{
    180         return *port; 
     179        return *port;
    181180}
    182181
  • kernel/arch/ppc32/include/context.h

    r918e9910 r827d73f  
    2727 */
    2828
    29 /** @addtogroup ppc32   
     29/** @addtogroup ppc32
    3030 * @{
    3131 */
     
    3838#include <arch/types.h>
    3939
    40 #define SP_DELTA        16
     40#define SP_DELTA  16
     41
     42#define context_set(ctx, pc, stack, size) \
     43    context_set_generic(ctx, pc, stack, size)
    4144
    4245typedef struct {
     
    6871       
    6972        ipl_t ipl;
    70 } __attribute__ ((packed)) context_t;
     73} __attribute__((packed)) context_t;
    7174
    7275#endif
  • kernel/arch/ppc32/include/exception.h

    r918e9910 r827d73f  
    3939#include <arch/regutils.h>
    4040
    41 typedef struct {
     41typedef struct istate {
    4242        uint32_t r0;
    4343        uint32_t r2;
     
    9898}
    9999
     100static inline unative_t istate_get_fp(istate_t *istate)
     101{
     102        return istate->sp;
     103}
     104
    100105#endif
    101106
  • kernel/arch/ppc32/src/debug/stacktrace_asm.S

    r918e9910 r827d73f  
    11#
    2 # Copyright (c) 2005 Martin Decky
     2# Copyright (c) 2010 Jakub Jermar
    33# All rights reserved.
    44#
     
    2727#
    2828
     29.text
    2930
    30 ## Common names
    31 #
     31.global frame_pointer_get
     32.global program_counter_get
    3233
    33 LIBC_PREFIX = ../libc
    34 DEPEND = Makefile.depend
    35 DEPEND_PREV = $(DEPEND).prev
    36 LIBFS = libfs.a
     34frame_pointer_get:
     35        blr
     36
     37program_counter_get:
     38        blr
  • kernel/arch/ppc32/src/mm/page.c

    r918e9910 r827d73f  
    5151            KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
    5252                panic("Unable to map physical memory %p (%" PRIs " bytes).",
    53                     physaddr, size)
     53                    physaddr, size);
    5454       
    5555        uintptr_t virtaddr = PA2KA(last_frame);
  • kernel/arch/ppc32/src/ppc32.c

    r918e9910 r827d73f  
    3939#include <genarch/kbrd/kbrd.h>
    4040#include <arch/interrupt.h>
     41#include <interrupt.h>
    4142#include <genarch/fb/fb.h>
    4243#include <genarch/fb/visuals.h>
     
    4748#include <proc/uarg.h>
    4849#include <console/console.h>
     50#include <sysinfo/sysinfo.h>
    4951#include <ddi/irq.h>
    5052#include <arch/drivers/pic.h>
     
    5860
    5961bootinfo_t bootinfo;
     62
     63static cir_t pic_cir;
     64static void *pic_cir_arg;
    6065
    6166/** Performs ppc32-specific initialization before main_bsp() is called. */
     
    186191        if (assigned_address) {
    187192                /* Initialize PIC */
    188                 cir_t cir;
    189                 void *cir_arg;
    190                 pic_init(assigned_address[0].addr, PAGE_SIZE, &cir, &cir_arg);
    191                
     193                pic_init(assigned_address[0].addr, PAGE_SIZE, &pic_cir,
     194                    &pic_cir_arg);
     195
    192196#ifdef CONFIG_MAC_KBD
    193197                uintptr_t pa = assigned_address[0].addr + 0x16000;
     
    201205                /* Initialize I/O controller */
    202206                cuda_instance_t *cuda_instance =
    203                     cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
     207                    cuda_init(cuda, IRQ_CUDA, pic_cir, pic_cir_arg);
    204208                if (cuda_instance) {
    205209                        kbrd_instance_t *kbrd_instance = kbrd_init();
     
    211215                        }
    212216                }
     217
     218                /*
     219                 * This is the necessary evil until the userspace driver is entirely
     220                 * self-sufficient.
     221                 */
     222                sysinfo_set_item_val("cuda", NULL, true);
     223                sysinfo_set_item_val("cuda.inr", NULL, IRQ_CUDA);
     224                sysinfo_set_item_val("cuda.address.physical", NULL, pa);
     225                sysinfo_set_item_val("cuda.address.kernel", NULL,
     226                    (uintptr_t) cuda);
    213227#endif
    214228        }
     
    216230        /* Consider only a single device for now */
    217231        return false;
     232}
     233
     234void irq_initialize_arch(irq_t *irq)
     235{
     236        irq->cir = pic_cir;
     237        irq->cir_arg = pic_cir_arg;
     238        irq->preack = true;
    218239}
    219240
  • kernel/arch/sparc64/Makefile.inc

    r918e9910 r827d73f  
    5454ARCH_SOURCES = \
    5555        arch/$(KARCH)/src/cpu/cpu.c \
     56        arch/$(KARCH)/src/debug/stacktrace.c \
     57        arch/$(KARCH)/src/debug/stacktrace_asm.S \
    5658        arch/$(KARCH)/src/asm.S \
    5759        arch/$(KARCH)/src/panic.S \
  • kernel/arch/sparc64/_link.ld.in

    r918e9910 r827d73f  
    3636                *(COMMON);                  /* global variables */
    3737               
     38                . = ALIGN(8);
    3839                symbol_table = .;
    3940                *(symtab.*);                /* Symbol table, must be LAST symbol!*/
  • kernel/arch/sparc64/include/asm.h

    r918e9910 r827d73f  
    430430}
    431431
    432 extern void cpu_halt(void);
     432extern void cpu_halt(void) __attribute__((noreturn));
    433433extern void cpu_sleep(void);
    434434extern void asm_delay_loop(const uint32_t usec);
  • kernel/arch/sparc64/include/context.h

    r918e9910 r827d73f  
    4242#define SP_DELTA        (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
    4343
    44 #ifdef context_set
    45 #undef context_set
    46 #endif
    47 
    4844#define context_set(c, _pc, stack, size)                        \
    4945        (c)->pc = ((uintptr_t) _pc) - 8;                        \
  • kernel/arch/sparc64/include/interrupt.h

    r918e9910 r827d73f  
    5050};             
    5151
    52 typedef struct {
     52typedef struct istate {
    5353        uint64_t        tnpc;
    5454        uint64_t        tpc;
     
    7171}
    7272
     73static inline unative_t istate_get_fp(istate_t *istate)
     74{
     75        return 0;       /* TODO */
     76}
     77
    7378#endif
    7479
  • kernel/arch/sparc64/src/debug/stacktrace_asm.S

    r918e9910 r827d73f  
    11#
    2 # Copyright (c) 2005 Martin Decky
     2# Copyright (c) 2010 Jakub Jermar
    33# All rights reserved.
    44#
     
    2727#
    2828
     29.text
    2930
    30 ## Common names
    31 #
     31.global frame_pointer_get
     32.global program_counter_get
    3233
    33 LIBC_PREFIX = ../libc
    34 DEPEND = Makefile.depend
    35 DEPEND_PREV = $(DEPEND).prev
    36 LIBSOFTINT = libsoftint.a
     34frame_pointer_get:
     35        retl
     36        nop
     37
     38program_counter_get:
     39        retl
     40        nop
     41
  • kernel/arch/sparc64/src/sparc64.c

    r918e9910 r827d73f  
    4444#include <arch/mm/page.h>
    4545#include <arch/stack.h>
     46#include <interrupt.h>
    4647#include <genarch/ofw/ofw_tree.h>
    4748#include <userspace.h>
     
    166167}
    167168
     169void irq_initialize_arch(irq_t *irq)
     170{
     171        (void) irq;
     172}
     173
    168174/** @}
    169175 */
  • kernel/generic/include/context.h

    r918e9910 r827d73f  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    3939#include <arch/context.h>
    4040
     41#define context_set_generic(ctx, _pc, stack, size) \
     42        (ctx)->pc = (uintptr_t) (_pc); \
     43        (ctx)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
    4144
    42 #ifndef context_set
    43 #define context_set(c, _pc, stack, size)        \
    44         (c)->pc = (uintptr_t) (_pc);            \
    45         (c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
    46 #endif /* context_set */
    47 
    48 extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
    49 extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
     45extern int context_save_arch(context_t *ctx) __attribute__((returns_twice));
     46extern void context_restore_arch(context_t *ctx) __attribute__((noreturn));
    5047
    5148/** Save register context.
     
    7370 * saved like that would therefore lead to a disaster.
    7471 *
    75  * @param c             Context structure.
     72 * @param ctx Context structure.
    7673 *
    77  * @return              context_save() returns 1, context_restore() returns 0.
     74 * @return context_save() returns 1, context_restore() returns 0.
     75 *
    7876 */
    79 #define context_save(c)   context_save_arch(c)
     77#define context_save(ctx)  context_save_arch(ctx)
    8078
    8179/** Restore register context.
     
    8886 * being return value.
    8987 *
    90  * @param c             Context structure.
     88 * @param ctx Context structure.
    9189 */
    92 static inline void context_restore(context_t *c)
     90static inline void context_restore(context_t *ctx)
    9391{
    94         context_restore_arch(c);
     92        context_restore_arch(ctx);
    9593}
    9694
  • kernel/generic/include/debug.h

    r918e9910 r827d73f  
    7575#       define LOG(format, ...) \
    7676                printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
    77                         __LINE__, ##__VA_ARGS__);
     77                    __LINE__, ##__VA_ARGS__);
    7878#else
    7979#       define LOG(format, ...)
     
    9292                { \
    9393                        printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
    94                         __LINE__); \
     94                            __LINE__); \
    9595                        fnc; \
    9696                }
  • kernel/generic/include/func.h

    r918e9910 r827d73f  
    4141extern atomic_t haltstate;
    4242
    43 extern void halt(void);
     43extern void halt(void) __attribute__((noreturn));
    4444extern unative_t atoi(const char *text);
    4545extern void order(const uint64_t val, uint64_t *rv, char *suffix);
  • kernel/generic/include/interrupt.h

    r918e9910 r827d73f  
    4242#include <arch.h>
    4343#include <ddi/irq.h>
     44#include <stacktrace.h>
    4445
    4546typedef void (* iroutine)(int n, istate_t *istate);
    4647
    47 #define fault_if_from_uspace(istate, fmt, ...) \
    48 { \
    49         if (istate_from_uspace(istate)) { \
    50                 task_t *task = TASK; \
    51                 printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \
    52                 printf(fmt "\n", ##__VA_ARGS__); \
    53                 task_kill(task->taskid); \
    54                 thread_exit(); \
    55         } \
    56 }
    57 
     48extern void fault_if_from_uspace(istate_t *istate, char *fmt, ...);
    5849extern iroutine exc_register(int n, const char *name, iroutine f);
    5950extern void exc_dispatch(int n, istate_t *t);
    6051void exc_init(void);
     52
     53extern void irq_initialize_arch(irq_t *irq);
    6154
    6255#endif
  • kernel/generic/include/ipc/event_types.h

    r918e9910 r827d73f  
    3737
    3838typedef enum event_type {
     39        /** New data available in kernel log */
    3940        EVENT_KLOG = 0,
     41        /** Returning from kernel console to userspace */
    4042        EVENT_KCONSOLE,
     43        /** A thread has faulted and will be terminated */
     44        EVENT_FAULT,
    4145        EVENT_END
    4246} event_type_t;
  • kernel/generic/include/macros.h

    r918e9910 r827d73f  
    8484#define STRING_ARG(arg)  #arg
    8585
    86 #define LOWER32(arg)  ((arg) & 0xffffffff)
    87 #define UPPER32(arg)  (((arg) >> 32) & 0xffffffff)
     86#define LOWER32(arg)  (((uint64_t) (arg)) & 0xffffffff)
     87#define UPPER32(arg)  (((((uint64_t) arg)) >> 32) & 0xffffffff)
    8888
    8989#define MERGE_LOUP32(lo, up) \
  • kernel/generic/include/mm/as.h

    r918e9910 r827d73f  
    3636#define KERN_AS_H_
    3737
     38#ifdef KERNEL
     39#include <arch/types.h>
     40#else
     41#include <sys/types.h>
     42#endif
     43
    3844/** Address space area flags. */
    3945#define AS_AREA_READ            1
     
    4147#define AS_AREA_EXEC            4
    4248#define AS_AREA_CACHEABLE       8
     49
     50/** Address space area info exported to userspace. */
     51typedef struct {
     52        /** Starting address */
     53        uintptr_t start_addr;
     54
     55        /** Area size */
     56        size_t size;
     57
     58        /** Area flags */
     59        int flags;
     60} as_area_info_t;
    4361
    4462#ifdef KERNEL
     
    268286
    269287/* Introspection functions. */
     288extern void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize);
    270289extern void as_print(as_t *as);
    271290
  • kernel/generic/include/panic.h

    r918e9910 r827d73f  
    3636#define KERN_PANIC_H_
    3737
     38#include <stacktrace.h>
     39#include <print.h>
     40
    3841#ifdef CONFIG_DEBUG
    3942#       define panic(format, ...) \
    40                 panic_printf("Kernel panic in %s() at %s:%u: " format "\n", \
    41                 __func__, __FILE__, __LINE__, ##__VA_ARGS__);
     43                do { \
     44                        printf("Kernel panic in %s() at %s:%u.\n", \
     45                            __func__, __FILE__, __LINE__); \
     46                        stack_trace(); \
     47                        panic_printf("Panic message: " format "\n", \
     48                            ##__VA_ARGS__);\
     49                } while (0)
    4250#else
    4351#       define panic(format, ...) \
  • kernel/generic/include/symtab.h

    r918e9910 r827d73f  
    4545};
    4646
    47 extern int symtab_name_lookup(unative_t addr, char **name);
    48 extern char *symtab_fmt_name_lookup(unative_t addr);
    49 extern int symtab_addr_lookup(const char *name, uintptr_t *addr);
    50 extern void symtab_print_search(const char *name);
    51 extern int symtab_compl(char *input, size_t size);
     47extern int symtab_name_lookup(uintptr_t, char **, uintptr_t *);
     48extern char *symtab_fmt_name_lookup(uintptr_t);
     49extern int symtab_addr_lookup(const char *, uintptr_t *);
     50extern void symtab_print_search(const char *);
     51extern int symtab_compl(char *, size_t);
    5252
    5353#ifdef CONFIG_SYMTAB
  • kernel/generic/include/udebug/udebug.h

    r918e9910 r827d73f  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    8383UDEBUG_M_ARGS_READ,
    8484
     85/** Read thread's userspace register state (istate_t).
     86 *
     87 * - ARG2 - thread identification
     88 * - ARG3 - destination address in the caller's address space
     89 *
     90 * or, on error, retval will be
     91 * - ENOENT - thread does not exist
     92 * - EBUSY - register state not available
     93 */
     94UDEBUG_M_REGS_READ,
     95
    8596/** Read the list of the debugged tasks's threads.
    8697 *
     
    97108UDEBUG_M_THREAD_READ,
    98109
     110/** Read the name of the debugged task.
     111 *
     112 * - ARG2 - destination address in the caller's address space
     113 * - ARG3 - size of receiving buffer in bytes
     114 *
     115 * The kernel fills the buffer with a non-terminated string.
     116 *
     117 * - ARG2 - number of bytes that were actually copied
     118 * - ARG3 - number of bytes of the complete data
     119 *
     120 */
     121UDEBUG_M_NAME_READ,
     122
     123/** Read the list of the debugged task's address space areas.
     124 *
     125 * - ARG2 - destination address in the caller's address space
     126 * - ARG3 - size of receiving buffer in bytes
     127 *
     128 * The kernel fills the buffer with a series of as_area_info_t structures.
     129 * Upon answer, the kernel will set:
     130 *
     131 * - ARG2 - number of bytes that were actually copied
     132 * - ARG3 - number of bytes of the complete data
     133 *
     134 */
     135UDEBUG_M_AREAS_READ,
     136
    99137/** Read the debugged tasks's memory.
    100138 *
     
    108146} udebug_method_t;
    109147
    110                                
     148
    111149typedef enum {
    112150        UDEBUG_EVENT_FINISHED = 1,      /**< Debuging session has finished */
     
    139177
    140178#include <synch/mutex.h>
     179#include <synch/condvar.h>
    141180#include <arch/interrupt.h>
    142181#include <atomic.h>
     
    181220        bool stoppable;         /**< thread is stoppable */
    182221        bool active;            /**< thread is in a debugging session */
     222        condvar_t active_cv;
    183223} udebug_thread_t;
    184224
     
    202242
    203243int udebug_task_cleanup(struct task *ta);
     244void udebug_thread_fault(void);
    204245
    205246#endif
  • kernel/generic/include/udebug/udebug_ops.h

    r918e9910 r827d73f  
    4545int udebug_stop(thread_t *t, call_t *call);
    4646
    47 int udebug_thread_read(void **buffer, size_t buf_size, size_t *n);
     47int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
     48    size_t *needed);
     49int udebug_name_read(char **data, size_t *data_size);
    4850int udebug_args_read(thread_t *t, void **buffer);
     51
     52int udebug_regs_read(thread_t *t, void **buffer);
    4953
    5054int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer);
  • kernel/generic/src/console/kconsole.c

    r918e9910 r827d73f  
    543543                if (str_lcmp(hlp->name, cmdline + start,
    544544                    max(str_length(hlp->name),
    545                     str_nlength(cmdline + start, (size_t) (end - start) - 1))) == 0) {
     545                    str_nlength(cmdline + start, (size_t) (end - start)))) == 0) {
    546546                        cmd = hlp;
    547547                        break;
  • kernel/generic/src/ddi/irq.c

    r918e9910 r827d73f  
    7474#include <synch/spinlock.h>
    7575#include <console/console.h>
     76#include <interrupt.h>
    7677#include <memstr.h>
    7778#include <arch.h>
     
    169170        irq->inr = -1;
    170171        irq->devno = -1;
     172
     173        irq_initialize_arch(irq);
    171174}
    172175
  • kernel/generic/src/debug/symtab.c

    r918e9910 r827d73f  
    4646/** Get name of a symbol that seems most likely to correspond to address.
    4747 *
    48  * @param addr Address.
    49  * @param name Place to store pointer to the symbol name.
     48 * @param addr          Address.
     49 * @param name          Place to store pointer to the symbol name.
     50 * @param offset        Place to store offset from the symbol address.
    5051 *
    5152 * @return Zero on success or negative error code, ENOENT if not found,
     
    5354 *
    5455 */
    55 int symtab_name_lookup(unative_t addr, char **name)
     56int symtab_name_lookup(uintptr_t addr, char **name, uintptr_t *offset)
    5657{
    5758#ifdef CONFIG_SYMTAB
     
    6566        if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) {
    6667                *name = symbol_table[i - 1].symbol_name;
     68                if (offset)
     69                        *offset = addr -
     70                            uint64_t_le2host(symbol_table[i - 1].address_le);
    6771                return EOK;
    6872        }
     
    8892 *
    8993 */
    90 char *symtab_fmt_name_lookup(unative_t addr)
     94char *symtab_fmt_name_lookup(uintptr_t addr)
    9195{
    9296        char *name;
    93         int rc = symtab_name_lookup(addr, &name);
     97        int rc = symtab_name_lookup(addr, &name, NULL);
    9498       
    9599        switch (rc) {
  • kernel/generic/src/interrupt/interrupt.c

    r918e9910 r827d73f  
    4444#include <console/console.h>
    4545#include <console/cmd.h>
     46#include <ipc/event.h>
     47#include <synch/mutex.h>
     48#include <time/delay.h>
     49#include <macros.h>
    4650#include <panic.h>
    4751#include <print.h>
     
    107111        fault_if_from_uspace(istate, "Unhandled exception %d.", n);
    108112        panic("Unhandled exception %d.", n);
     113}
     114
     115/** Terminate thread and task if exception came from userspace. */
     116void fault_if_from_uspace(istate_t *istate, char *fmt, ...)
     117{
     118        task_t *task = TASK;
     119        va_list args;
     120
     121        if (!istate_from_uspace(istate))
     122                return;
     123
     124        printf("Task %s (%" PRIu64 ") killed due to an exception at "
     125            "program counter %p.\n", task->name, task->taskid,
     126            istate_get_pc(istate));
     127
     128        stack_trace_istate(istate);
     129
     130        printf("Kill message: ");
     131        va_start(args, fmt);
     132        vprintf(fmt, args);
     133        va_end(args);
     134        printf("\n");
     135
     136        /*
     137         * Userspace can subscribe for FAULT events to take action
     138         * whenever a thread faults. (E.g. take a dump, run a debugger).
     139         * The notification is always available, but unless Udebug is enabled,
     140         * that's all you get.
     141         */
     142        if (event_is_subscribed(EVENT_FAULT)) {
     143                /* Notify the subscriber that a fault occurred. */
     144                event_notify_3(EVENT_FAULT, LOWER32(TASK->taskid),
     145                    UPPER32(TASK->taskid), (unative_t) THREAD);
     146
     147#ifdef CONFIG_UDEBUG
     148                /* Wait for a debugging session. */
     149                udebug_thread_fault();
     150#endif
     151        }
     152
     153        task_kill(task->taskid);
     154        thread_exit();
    109155}
    110156
  • kernel/generic/src/ipc/ipc.c

    r918e9910 r827d73f  
    212212 *
    213213 * @param call          Call structure to be answered.
    214  */
    215 static void _ipc_answer_free_call(call_t *call)
     214 * @param selflocked    If true, then TASK->answebox is locked.
     215 */
     216static void _ipc_answer_free_call(call_t *call, bool selflocked)
    216217{
    217218        answerbox_t *callerbox = call->callerbox;
     219        bool do_lock = ((!selflocked) || callerbox != (&TASK->answerbox));
    218220
    219221        call->flags |= IPC_CALL_ANSWERED;
     
    226228        }
    227229
    228         spinlock_lock(&callerbox->lock);
     230        if (do_lock)
     231                spinlock_lock(&callerbox->lock);
    229232        list_append(&call->link, &callerbox->answers);
    230         spinlock_unlock(&callerbox->lock);
     233        if (do_lock)
     234                spinlock_unlock(&callerbox->lock);
    231235        waitq_wakeup(&callerbox->wq, WAKEUP_FIRST);
    232236}
     
    244248        spinlock_unlock(&box->lock);
    245249        /* Send back answer */
    246         _ipc_answer_free_call(call);
     250        _ipc_answer_free_call(call, false);
    247251}
    248252
     
    261265        atomic_inc(&phone->active_calls);
    262266        IPC_SET_RETVAL(call->data, err);
    263         _ipc_answer_free_call(call);
     267        _ipc_answer_free_call(call, false);
    264268}
    265269
     
    300304                if (call->flags & IPC_CALL_FORWARDED) {
    301305                        IPC_SET_RETVAL(call->data, EFORWARD);
    302                         _ipc_answer_free_call(call);
     306                        _ipc_answer_free_call(call, false);
    303307                } else {
    304308                        if (phone->state == IPC_PHONE_HUNGUP)
     
    455459
    456460                IPC_SET_RETVAL(call->data, EHANGUP);
    457                 _ipc_answer_free_call(call);
     461                _ipc_answer_free_call(call, true);
    458462        }
    459463}
  • kernel/generic/src/mm/as.c

    r918e9910 r827d73f  
    19201920}
    19211921
     1922/** Get list of adress space areas.
     1923 *
     1924 * @param as            Address space.
     1925 * @param obuf          Place to save pointer to returned buffer.
     1926 * @param osize         Place to save size of returned buffer.
     1927 */
     1928void as_get_area_info(as_t *as, as_area_info_t **obuf, size_t *osize)
     1929{
     1930        ipl_t ipl;
     1931        size_t area_cnt, area_idx, i;
     1932        link_t *cur;
     1933
     1934        as_area_info_t *info;
     1935        size_t isize;
     1936
     1937        ipl = interrupts_disable();
     1938        mutex_lock(&as->lock);
     1939
     1940        /* First pass, count number of areas. */
     1941
     1942        area_cnt = 0;
     1943
     1944        for (cur = as->as_area_btree.leaf_head.next;
     1945            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     1946                btree_node_t *node;
     1947
     1948                node = list_get_instance(cur, btree_node_t, leaf_link);
     1949                area_cnt += node->keys;
     1950        }
     1951
     1952        isize = area_cnt * sizeof(as_area_info_t);
     1953        info = malloc(isize, 0);
     1954
     1955        /* Second pass, record data. */
     1956
     1957        area_idx = 0;
     1958
     1959        for (cur = as->as_area_btree.leaf_head.next;
     1960            cur != &as->as_area_btree.leaf_head; cur = cur->next) {
     1961                btree_node_t *node;
     1962
     1963                node = list_get_instance(cur, btree_node_t, leaf_link);
     1964
     1965                for (i = 0; i < node->keys; i++) {
     1966                        as_area_t *area = node->value[i];
     1967
     1968                        ASSERT(area_idx < area_cnt);
     1969                        mutex_lock(&area->lock);
     1970
     1971                        info[area_idx].start_addr = area->base;
     1972                        info[area_idx].size = FRAMES2SIZE(area->pages);
     1973                        info[area_idx].flags = area->flags;
     1974                        ++area_idx;
     1975
     1976                        mutex_unlock(&area->lock);
     1977                }
     1978        }
     1979
     1980        mutex_unlock(&as->lock);
     1981        interrupts_restore(ipl);
     1982
     1983        *obuf = info;
     1984        *osize = isize;
     1985}
     1986
     1987
    19221988/** Print out information about address space.
    19231989 *
  • kernel/generic/src/udebug/udebug.c

    r918e9910 r827d73f  
    6969        mutex_initialize(&ut->lock, MUTEX_PASSIVE);
    7070        waitq_initialize(&ut->go_wq);
     71        condvar_initialize(&ut->active_cv);
    7172
    7273        ut->go_call = NULL;
     
    446447                                waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
    447448                        }
     449                        mutex_unlock(&t->udebug.lock);
     450                        condvar_broadcast(&t->udebug.active_cv);
     451                } else {
     452                        mutex_unlock(&t->udebug.lock);
    448453                }
    449                 mutex_unlock(&t->udebug.lock);
    450454        }
    451455
     
    456460}
    457461
     462/** Wait for debugger to handle a fault in this thread.
     463 *
     464 * When a thread faults and someone is subscribed to the FAULT kernel event,
     465 * this function is called to wait for a debugging session to give userspace
     466 * a chance to examine the faulting thead/task. When the debugging session
     467 * is over, this function returns (so that thread/task cleanup can continue).
     468 */
     469void udebug_thread_fault(void)
     470{
     471        udebug_stoppable_begin();
     472
     473        /* Wait until a debugger attends to us. */
     474        mutex_lock(&THREAD->udebug.lock);
     475        while (!THREAD->udebug.active)
     476                condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
     477        mutex_unlock(&THREAD->udebug.lock);
     478
     479        /* Make sure the debugging session is over before proceeding. */
     480        mutex_lock(&THREAD->udebug.lock);
     481        while (THREAD->udebug.active)
     482                condvar_wait(&THREAD->udebug.active_cv, &THREAD->udebug.lock);
     483        mutex_unlock(&THREAD->udebug.lock);
     484
     485        udebug_stoppable_end();
     486}
    458487
    459488/** @}
  • kernel/generic/src/udebug/udebug_ipc.c

    r918e9910 r827d73f  
    4141#include <proc/task.h>
    4242#include <proc/thread.h>
     43#include <mm/as.h>
    4344#include <arch.h>
    4445#include <errno.h>
     
    165166static void udebug_receive_thread_read(call_t *call)
    166167{
     168        uintptr_t uspace_addr;
     169        size_t buf_size;
     170        void *buffer;
     171        size_t copied, needed;
     172        int rc;
     173
     174        uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
     175        buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
     176
     177        /*
     178         * Read thread list. Variable n will be filled with actual number
     179         * of threads times thread-id size.
     180         */
     181        rc = udebug_thread_read(&buffer, buf_size, &copied, &needed);
     182        if (rc < 0) {
     183                IPC_SET_RETVAL(call->data, rc);
     184                ipc_answer(&TASK->kb.box, call);
     185                return;
     186        }
     187
     188        /*
     189         * Make use of call->buffer to transfer data to caller's userspace
     190         */
     191
     192        IPC_SET_RETVAL(call->data, 0);
     193        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     194           same code in process_answer() can be used
     195           (no way to distinguish method in answer) */
     196        IPC_SET_ARG1(call->data, uspace_addr);
     197        IPC_SET_ARG2(call->data, copied);
     198        IPC_SET_ARG3(call->data, needed);
     199        call->buffer = buffer;
     200
     201        ipc_answer(&TASK->kb.box, call);
     202}
     203
     204/** Process a NAME_READ call.
     205 *
     206 * Returns a string containing the name of the task.
     207 *
     208 * @param call  The call structure.
     209 */
     210static void udebug_receive_name_read(call_t *call)
     211{
    167212        unative_t uspace_addr;
    168213        unative_t to_copy;
    169         unsigned total_bytes;
    170         unsigned buf_size;
    171         void *buffer;
    172         size_t n;
    173         int rc;
     214        size_t data_size;
     215        size_t buf_size;
     216        void *data;
    174217
    175218        uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
     
    177220
    178221        /*
    179          * Read thread list. Variable n will be filled with actual number
    180          * of threads times thread-id size.
    181          */
    182         rc = udebug_thread_read(&buffer, buf_size, &n);
    183         if (rc < 0) {
    184                 IPC_SET_RETVAL(call->data, rc);
    185                 ipc_answer(&TASK->kb.box, call);
    186                 return;
    187         }
    188 
    189         total_bytes = n;
    190 
    191         /* Copy MAX(buf_size, total_bytes) bytes */
    192 
    193         if (buf_size > total_bytes)
    194                 to_copy = total_bytes;
     222         * Read task name.
     223         */
     224        udebug_name_read((char **) &data, &data_size);
     225
     226        /* Copy MAX(buf_size, data_size) bytes */
     227
     228        if (buf_size > data_size)
     229                to_copy = data_size;
    195230        else
    196231                to_copy = buf_size;
     
    207242        IPC_SET_ARG2(call->data, to_copy);
    208243
    209         IPC_SET_ARG3(call->data, total_bytes);
    210         call->buffer = buffer;
    211 
    212         ipc_answer(&TASK->kb.box, call);
    213 }
     244        IPC_SET_ARG3(call->data, data_size);
     245        call->buffer = data;
     246
     247        ipc_answer(&TASK->kb.box, call);
     248}
     249
     250/** Process an AREAS_READ call.
     251 *
     252 * Returns a list of address space areas in the current task, as an array
     253 * of as_area_info_t structures.
     254 *
     255 * @param call  The call structure.
     256 */
     257static void udebug_receive_areas_read(call_t *call)
     258{
     259        unative_t uspace_addr;
     260        unative_t to_copy;
     261        size_t data_size;
     262        size_t buf_size;
     263        void *data;
     264
     265        uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */
     266        buf_size = IPC_GET_ARG3(call->data);    /* Dest. buffer size */
     267
     268        /*
     269         * Read area list.
     270         */
     271        as_get_area_info(AS, (as_area_info_t **) &data, &data_size);
     272
     273        /* Copy MAX(buf_size, data_size) bytes */
     274
     275        if (buf_size > data_size)
     276                to_copy = data_size;
     277        else
     278                to_copy = buf_size;
     279
     280        /*
     281         * Make use of call->buffer to transfer data to caller's userspace
     282         */
     283
     284        IPC_SET_RETVAL(call->data, 0);
     285        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     286           same code in process_answer() can be used
     287           (no way to distinguish method in answer) */
     288        IPC_SET_ARG1(call->data, uspace_addr);
     289        IPC_SET_ARG2(call->data, to_copy);
     290
     291        IPC_SET_ARG3(call->data, data_size);
     292        call->buffer = data;
     293
     294        ipc_answer(&TASK->kb.box, call);
     295}
     296
    214297
    215298/** Process an ARGS_READ call.
     
    250333        ipc_answer(&TASK->kb.box, call);
    251334}
     335
     336/** Receive a REGS_READ call.
     337 *
     338 * Reads the thread's register state (istate structure).
     339 */
     340static void udebug_receive_regs_read(call_t *call)
     341{
     342        thread_t *t;
     343        unative_t uspace_addr;
     344        unative_t to_copy;
     345        void *buffer;
     346        int rc;
     347
     348        t = (thread_t *) IPC_GET_ARG2(call->data);
     349
     350        rc = udebug_regs_read(t, &buffer);
     351        if (rc < 0) {
     352                IPC_SET_RETVAL(call->data, rc);
     353                ipc_answer(&TASK->kb.box, call);
     354                return;
     355        }
     356
     357        /*
     358         * Make use of call->buffer to transfer data to caller's userspace
     359         */
     360
     361        uspace_addr = IPC_GET_ARG3(call->data);
     362        to_copy = sizeof(istate_t);
     363
     364        IPC_SET_RETVAL(call->data, 0);
     365        /* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that
     366           same code in process_answer() can be used
     367           (no way to distinguish method in answer) */
     368        IPC_SET_ARG1(call->data, uspace_addr);
     369        IPC_SET_ARG2(call->data, to_copy);
     370
     371        call->buffer = buffer;
     372
     373        ipc_answer(&TASK->kb.box, call);
     374}
     375
    252376
    253377/** Process an MEM_READ call.
     
    331455                udebug_receive_thread_read(call);
    332456                break;
     457        case UDEBUG_M_NAME_READ:
     458                udebug_receive_name_read(call);
     459                break;
     460        case UDEBUG_M_AREAS_READ:
     461                udebug_receive_areas_read(call);
     462                break;
    333463        case UDEBUG_M_ARGS_READ:
    334464                udebug_receive_args_read(call);
    335465                break;
     466        case UDEBUG_M_REGS_READ:
     467                udebug_receive_regs_read(call);
     468                break;
    336469        case UDEBUG_M_MEM_READ:
    337470                udebug_receive_mem_read(call);
  • kernel/generic/src/udebug/udebug_ops.c

    r918e9910 r827d73f  
    4646#include <errno.h>
    4747#include <print.h>
     48#include <string.h>
    4849#include <syscall/copy.h>
    4950#include <ipc/ipc.h>
     
    209210
    210211                mutex_lock(&t->udebug.lock);
    211                 if ((t->flags & THREAD_FLAG_USPACE) != 0)
     212                if ((t->flags & THREAD_FLAG_USPACE) != 0) {
    212213                        t->udebug.active = true;
    213                 mutex_unlock(&t->udebug.lock);
     214                        mutex_unlock(&t->udebug.lock);
     215                        condvar_broadcast(&t->udebug.active_cv);
     216                } else {
     217                        mutex_unlock(&t->udebug.lock);
     218                }
    214219        }
    215220
     
    355360 *
    356361 * If the sequence is longer than @a buf_size bytes, only as much hashes
    357  * as can fit are copied. The number of thread hashes copied is stored
    358  * in @a n.
     362 * as can fit are copied. The number of bytes copied is stored in @a stored.
     363 * The total number of thread bytes that could have been saved had there been
     364 * enough space is stored in @a needed.
    359365 *
    360366 * The rationale for having @a buf_size is that this function is only
     
    364370 * @param buffer        The buffer for storing thread hashes.
    365371 * @param buf_size      Buffer size in bytes.
    366  * @param n             The actual number of hashes copied will be stored here.
    367  */
    368 int udebug_thread_read(void **buffer, size_t buf_size, size_t *n)
     372 * @param stored        The actual number of bytes copied will be stored here.
     373 * @param needed        Total number of hashes that could have been saved.
     374 */
     375int udebug_thread_read(void **buffer, size_t buf_size, size_t *stored,
     376    size_t *needed)
    369377{
    370378        thread_t *t;
    371379        link_t *cur;
    372380        unative_t tid;
    373         unsigned copied_ids;
     381        size_t copied_ids;
     382        size_t extra_ids;
    374383        ipl_t ipl;
    375384        unative_t *id_buffer;
     
    380389
    381390        /* Allocate a buffer to hold thread IDs */
    382         id_buffer = malloc(buf_size, 0);
     391        id_buffer = malloc(buf_size + 1, 0);
    383392
    384393        mutex_lock(&TASK->udebug.lock);
     
    396405        max_ids = buf_size / sizeof(unative_t);
    397406        copied_ids = 0;
     407        extra_ids = 0;
    398408
    399409        /* FIXME: make sure the thread isn't past debug shutdown... */
    400410        for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
    401                 /* Do not write past end of buffer */
    402                 if (copied_ids >= max_ids) break;
    403 
    404411                t = list_get_instance(cur, thread_t, th_link);
    405412
     
    409416
    410417                /* Not interested in kernel threads. */
    411                 if ((flags & THREAD_FLAG_USPACE) != 0) {
     418                if ((flags & THREAD_FLAG_USPACE) == 0)
     419                        continue;
     420
     421                if (copied_ids < max_ids) {
    412422                        /* Using thread struct pointer as identification hash */
    413423                        tid = (unative_t) t;
    414424                        id_buffer[copied_ids++] = tid;
     425                } else {
     426                        extra_ids++;
    415427                }
    416428        }
     
    422434
    423435        *buffer = id_buffer;
    424         *n = copied_ids * sizeof(unative_t);
     436        *stored = copied_ids * sizeof(unative_t);
     437        *needed = (copied_ids + extra_ids) * sizeof(unative_t);
     438
     439        return 0;
     440}
     441
     442/** Read task name.
     443 *
     444 * Returns task name as non-terminated string in a newly allocated buffer.
     445 * Also returns the size of the data.
     446 *
     447 * @param data          Place to store pointer to newly allocated block.
     448 * @param data_size     Place to store size of the data.
     449 *
     450 * @returns             EOK.
     451 */
     452int udebug_name_read(char **data, size_t *data_size)
     453{
     454        size_t name_size;
     455
     456        name_size = str_size(TASK->name) + 1;
     457        *data = malloc(name_size, 0);
     458        *data_size = name_size;
     459
     460        memcpy(*data, TASK->name, name_size);
    425461
    426462        return 0;
     
    437473 * this function will fail with an EINVAL error code.
    438474 *
    439  * @param buffer        The buffer for storing thread hashes.
     475 * @param t             Thread where call arguments are to be read.
     476 * @param buffer        Place to store pointer to new buffer.
     477 * @return              EOK on success, ENOENT if @a t is invalid, EINVAL
     478 *                      if thread state is not valid for this operation.
    440479 */
    441480int udebug_args_read(thread_t *t, void **buffer)
     
    469508}
    470509
     510/** Read the register state of the thread.
     511 *
     512 * The contents of the thread's istate structure are copied to a newly
     513 * allocated buffer and a pointer to it is written to @a buffer. The size of
     514 * the buffer will be sizeof(istate_t).
     515 *
     516 * Currently register state cannot be read if the thread is inside a system
     517 * call (as opposed to an exception). This is an implementation limit.
     518 *
     519 * @param t             Thread whose state is to be read.
     520 * @param buffer        Place to store pointer to new buffer.
     521 * @return              EOK on success, ENOENT if @a t is invalid, EINVAL
     522 *                      if thread is not in valid state, EBUSY if istate
     523 *                      is not available.
     524 */
     525int udebug_regs_read(thread_t *t, void **buffer)
     526{
     527        istate_t *state, *state_buf;
     528        int rc;
     529
     530        /* Prepare a buffer to hold the data. */
     531        state_buf = malloc(sizeof(istate_t), 0);
     532
     533        /* On success, this will lock t->udebug.lock */
     534        rc = _thread_op_begin(t, false);
     535        if (rc != EOK) {
     536                return rc;
     537        }
     538
     539        state = t->udebug.uspace_state;
     540        if (state == NULL) {
     541                _thread_op_end(t);
     542                return EBUSY;
     543        }
     544
     545        /* Copy to the allocated buffer */
     546        memcpy(state_buf, state, sizeof(istate_t));
     547
     548        _thread_op_end(t);
     549
     550        *buffer = (void *) state_buf;
     551        return 0;
     552}
     553
    471554/** Read the memory of the debugged task.
    472555 *
Note: See TracChangeset for help on using the changeset viewer.