Changeset 1f12fab in mainline


Ignore:
Timestamp:
2013-10-07T20:00:34Z (10 years ago)
Author:
Jakub Klama <jakub.klama@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a73ebf0
Parents:
80d9d83
Message:

First attempt to implement preemptive trap handlers
and switch to userspace. Preemptive traps are needed
for at least page faults, as page fault handling code
can trigger window underflow/overflow exceptions.

This commit also introduces userspace window buffer
for saving userspace register windows (just as in
sparc64).

These changes are unfinished and far from working
correctly.

Files:
1 added
15 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc32/include/arch/arch.h

    r80d9d83 r1f12fab  
    4141#include <typedefs.h>
    4242
     43#define NWINDOWS        8
     44
    4345/* ASI assignments: */
    4446#define ASI_CACHEMISS   0x01
     
    6365} bootinfo_t;
    6466
    65 void arch_pre_main(bootinfo_t *bootinfo);
     67extern uintptr_t kernel_sp;
     68extern uintptr_t uspace_wbuf;
     69
     70extern void arch_pre_main(void *unused, bootinfo_t *bootinfo);
    6671
    6772#endif
  • kernel/arch/sparc32/include/arch/elf.h

    r80d9d83 r1f12fab  
    2727 */
    2828
    29 /** @addtogroup abs32le
     29/** @addtogroup sparc32
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_abs32le_ELF_H_
    36 #define KERN_abs32le_ELF_H_
     35#ifndef KERN_sparc32_ELF_H_
     36#define KERN_sparc32_ELF_H_
    3737
    38 #define ELF_MACHINE        EM_NO
    39 #define ELF_DATA_ENCODING  ELFDATA2LSB
     38#define ELF_MACHINE        EM_SPARC
     39#define ELF_DATA_ENCODING  ELFDATA2MSB
    4040#define ELF_CLASS          ELFCLASS32
    4141
  • kernel/arch/sparc32/include/arch/istate.h

    r80d9d83 r1f12fab  
    2727 */
    2828
    29 /** @addtogroup abs32leinterrupt
     29/** @addtogroup sparc32interrupt
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_abs32le_ISTATE_H_
    36 #define KERN_abs32le_ISTATE_H_
     35#ifndef KERN_sparc32_ISTATE_H_
     36#define KERN_sparc32_ISTATE_H_
    3737
    3838#include <trace.h>
     
    5454 */
    5555typedef struct istate {
    56         uintptr_t ip;
    57         uintptr_t fp;
     56        uintptr_t pstate;
     57        uintptr_t pc;
     58        uintptr_t npc;
    5859        uint32_t stack[];
    5960} istate_t;
     
    6465        /* On real hardware this checks whether the interrupted
    6566           context originated from user space. */
    66        
    67         return !(istate->ip & UINT32_C(0x80000000));
     67
     68        return !(istate->pc & UINT32_C(0x80000000));
    6869}
    6970
     
    7475        /* On real hardware this sets the instruction pointer. */
    7576       
    76         istate->ip = retaddr;
     77        istate->pc = retaddr;
    7778}
    7879
     
    8283        /* On real hardware this returns the instruction pointer. */
    8384       
    84         return istate->ip;
     85        return istate->pc;
    8586}
    8687
     
    9091        /* On real hardware this returns the frame pointer. */
    9192       
    92         return istate->fp;
     93        return 0;//istate->fp;
    9394}
    9495
  • kernel/arch/sparc32/include/arch/mm/tlb.h

    r80d9d83 r1f12fab  
    11/*
    2  * Copyright (c) 2010 Martin Decky
     2 * Copyright (c) 2013 Jakub Klama
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup abs32lemm
     29/** @addtogroup sparc32mm
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_abs32le_TLB_H_
    36 #define KERN_abs32le_TLB_H_
     35#ifndef KERN_sparc32_TLB_H_
     36#define KERN_sparc32_TLB_H_
     37
     38#define MMU_CONTROL             0x000
     39#define MMU_CONTEXT_TABLE       0x100
     40#define MMU_CONTEXT             0x200
     41#define MMU_FAULT_STATUS        0x300
     42#define MMU_FAULT_ADDRESS       0x400
    3743
    3844#endif
  • kernel/arch/sparc32/include/arch/proc/thread.h

    r80d9d83 r1f12fab  
    11/*
    2  * Copyright (c) 2010 Martin Decky
     2 * Copyright (c) 2013 Jakub Klama
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup abs32leproc
     29/** @addtogroup sparc32proc
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef KERN_abs32le_THREAD_H_
    36 #define KERN_abs32le_THREAD_H_
     35#ifndef KERN_sparc32_THREAD_H_
     36#define KERN_sparc32_THREAD_H_
    3737
    3838#include <typedefs.h>
    3939
    4040typedef struct {
     41        /** Buffer for register windows with userspace content. */
     42        uint8_t *uspace_window_buffer;
    4143} thread_arch_t;
    42 
    43 #define thr_constructor_arch(thr)
    44 #define thr_destructor_arch(thr)
    4544
    4645#endif
  • kernel/arch/sparc32/src/exception.c

    r80d9d83 r1f12fab  
    4848void instruction_access_exception(int n, istate_t *istate)
    4949{
    50         fault_if_from_uspace(istate, "%s.", __func__);
    51         panic_badtrap(istate, n, "%s.", __func__);
     50        page_fault(n, istate);
     51//      fault_if_from_uspace(istate, "%s.", __func__);
     52//      panic_badtrap(istate, n, "%s.", __func__);
    5253}
    5354
     
    104105void data_access_exception(int n, istate_t *istate)
    105106{
    106         fault_if_from_uspace(istate, "%s.", __func__);
    107         panic_badtrap(istate, n, "%s.", __func__);
     107        page_fault(n, istate);
     108//      fault_if_from_uspace(istate, "%s.", __func__);
     109//      panic_badtrap(istate, n, "%s.", __func__);
    108110}
    109111
     
    111113void data_access_error(int n, istate_t *istate)
    112114{
    113         fault_if_from_uspace(istate, "%s.", __func__);
    114         panic_badtrap(istate, n, "%s.", __func__);
     115        page_fault(n, istate);
     116//      fault_if_from_uspace(istate, "%s.", __func__);
     117//      panic_badtrap(istate, n, "%s.", __func__);
    115118}
    116119
     
    118121void data_store_error(int n, istate_t *istate)
    119122{
    120         fault_if_from_uspace(istate, "%s.", __func__);
    121         panic_badtrap(istate, n, "%s.", __func__);
     123        page_fault(n, istate);
     124//      fault_if_from_uspace(istate, "%s.", __func__);
     125//      panic_badtrap(istate, n, "%s.", __func__);
    122126}
    123127/** Handle data_access_error. (0x2c) */
  • kernel/arch/sparc32/src/mm/frame.c

    r80d9d83 r1f12fab  
    6060                    BOOT_PT_START_FRAME + BOOT_PT_SIZE_FRAMES,
    6161                    ZONE_AVAILABLE | ZONE_LOWMEM);
     62
     63                printf("low_zone: %d frames\n", SIZE2FRAMES(size));
    6264        } else {
    6365                pfn_t conf = zone_external_conf_alloc(SIZE2FRAMES(size));
     
    6567                        zone_create(ADDR2PFN(base), SIZE2FRAMES(size), conf,
    6668                            ZONE_AVAILABLE | ZONE_HIGHMEM);
     69
     70                printf("high zone: %d frames\n", SIZE2FRAMES(size));
    6771        }
    68        
     72
     73        printf("free: %d\n", frame_total_free_get());
    6974}
    7075
     
    8186        /* blacklist boot page table */
    8287        frame_mark_unavailable(BOOT_PT_START_FRAME, BOOT_PT_SIZE_FRAMES);
     88        printf("free: %d\n", frame_total_free_get());
    8389        //machine_frame_init();
    8490}
  • kernel/arch/sparc32/src/mm/page.c

    r80d9d83 r1f12fab  
    3434
    3535#include <arch/mm/page.h>
     36#include <arch/mm/page_fault.h>
     37#include <arch/mm/tlb.h>
    3638#include <genarch/mm/page_pt.h>
    3739#include <arch/mm/frame.h>
     
    7577
    7678        /* Switch MMU to new context table */
    77         asi_u32_write(ASI_MMUREGS, 0x100, KA2PA(as_context_table) >> 4);
     79        asi_u32_write(ASI_MMUREGS, MMU_CONTEXT_TABLE, KA2PA(as_context_table) >> 4);
    7880
    7981        //boot_page_table_free();
     
    8284void page_fault(unsigned int n __attribute__((unused)), istate_t *istate)
    8385{
     86        uint32_t fault_status = asi_u32_read(ASI_MMUREGS, MMU_FAULT_STATUS);
     87        uintptr_t fault_address = asi_u32_read(ASI_MMUREGS, MMU_FAULT_ADDRESS);
     88        mmu_fault_status_t *fault = (mmu_fault_status_t *)&fault_status;
     89        mmu_fault_type_t type = (mmu_fault_type_t)fault->ft;
     90
     91        printf("page fault on address 0x%08x, status 0x%08x\n", fault_address, fault_status);
     92
     93        if (type == FAULT_TYPE_LOAD_USER_DATA) 
     94                as_page_fault(fault_address, PF_ACCESS_READ, istate);
     95
     96        if (type == FAULT_TYPE_EXECUTE_USER)
     97                as_page_fault(fault_address, PF_ACCESS_EXEC, istate);
     98
     99        if (type == FAULT_TYPE_STORE_USER_DATA || type == FAULT_TYPE_STORE_USER_INSTRUCTION)
     100                as_page_fault(fault_address, PF_ACCESS_WRITE, istate);
    84101}
    85102
  • kernel/arch/sparc32/src/proc/scheduler.c

    r80d9d83 r1f12fab  
    11/*
    2  * Copyright (c) 2010 Martin Decky
     2 * Copyright (c) 2013 Jakub Klama
    33 * All rights reserved.
    44 *
     
    3434
    3535#include <proc/scheduler.h>
     36#include <proc/thread.h>
     37#include <arch.h>
     38#include <arch/arch.h>
    3639
    3740void before_task_runs_arch(void)
     
    4144void before_thread_runs_arch(void)
    4245{
     46        kernel_sp = (uintptr_t) THREAD->kstack + STACK_SIZE;
     47        uspace_wbuf = (uintptr_t) THREAD->arch.uspace_window_buffer;
    4348}
    4449
  • kernel/arch/sparc32/src/proc/thread.c

    r80d9d83 r1f12fab  
    3333 */
    3434
     35#include <arch/regwin.h>
    3536#include <proc/thread.h>
     37
     38void thr_constructor_arch(thread_t *t)
     39{
     40        t->arch.uspace_window_buffer = NULL;
     41}
     42
     43void thr_destructor_arch(thread_t *t)
     44{
     45        if (t->arch.uspace_window_buffer) {
     46                uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
     47                /*
     48                 * Mind the possible alignment of the userspace window buffer
     49                 * belonging to a killed thread.
     50                 */
     51                free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
     52        }
     53}
    3654
    3755void thread_create_arch(thread_t *t)
    3856{
     57        if ((t->uspace) && (!t->arch.uspace_window_buffer))
     58                {
     59                /*
     60                 * The thread needs userspace window buffer and the object
     61                 * returned from the slab allocator doesn't have any.
     62                 */
     63                t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
     64        } else {
     65                uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
     66
     67                /*
     68                 * Mind the possible alignment of the userspace window buffer
     69                 * belonging to a killed thread.
     70                 */
     71                t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
     72                    UWB_ASIZE);
     73        }
    3974}
    4075
  • kernel/arch/sparc32/src/sparc32.c

    r80d9d83 r1f12fab  
    5656char memcpy_to_uspace_failover_address;
    5757
    58 void arch_pre_main(bootinfo_t *bootinfo)
     58void arch_pre_main(void *unused, bootinfo_t *bootinfo)
    5959{
    6060        init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS);
  • kernel/arch/sparc32/src/start.S

    r80d9d83 r1f12fab  
    3131.global kernel_image_start
    3232.global early_putchar
     33.global kernel_sp
     34.global uspace_wbuf
    3335
    3436kernel_image_start:
     
    6870        nop
    6971
     72kernel_sp:
     73.space 4
     74
     75uspace_wbuf:
     76.space 4
     77
    7078.align 16
    7179.space 4096
  • kernel/arch/sparc32/src/trap_table.S

    r80d9d83 r1f12fab  
    3333.global trap_table
    3434.global reset_trap
     35.global preemptible_trap
    3536.global window_overflow_trap
    3637.global window_underflow_trap
     
    116117        rett %l2
    117118
    118 #define TRAP(_vector, _handler) \
     119preemptible_trap:
     120        /* Enable traps */
     121        mov %psr, %l0
     122        or %l0, (1 << 5), %l0
     123        mov %l0, %psr
     124
     125        /* Check whether previous mode was usermode */
     126        and %l0, (1 << 6), %l0
     127        cmp %l0, 0
     128        bne 1f
     129        nop
     130
     131        /* Set up stack */
     132        set kernel_sp, %l4
     133        ld [%l4], %sp
     134        mov %sp, %fp
     1351:      sub %sp, 112, %sp
     136
     137        /* Save trap data on stack */
     138        st %l1, [%fp - 4]
     139        st %l2, [%fp - 8]
     140        st %l0, [%fp - 12]
     141
     142        /* Jump to actual subroutine */
     143        mov 1, %o0
     144        jmp %g1
     145        sub %fp, 12, %o1
     146
     147        /* Return from handler */
     148        ld [%fp - 4], %l1
     149        ld [%fp - 8], %l2
     150        jmp %l1
     151        rett %l2
     152
     153#define STRAP(_vector, _handler) \
    119154        .org trap_table + _vector * TRAP_ENTRY_SIZE; \
    120155        mov %psr, %l0 ; \
    121156        sethi %hi(_handler), %l4 ; \
    122         jmp %l4 + %lo(_handler); \
    123         mov _vector, %l3 ;
     157        jmp %lo(_handler) + %l4 ; \
     158        nop
     159
     160#define TRAP(_vector, _handler) \
     161        .org trap_table + _vector * TRAP_ENTRY_SIZE; \
     162        sethi %hi(_handler), %g1 ; \
     163        b preemptible_trap ; \
     164        or %g1, %lo(_handler), %g1 ;
    124165
    125166#define INTERRUPT(_vector, _priority) \
     
    141182        TRAP(0x3, privileged_instruction)
    142183        TRAP(0x4, fp_disabled)
    143         TRAP(0x5, window_overflow_trap)
    144         TRAP(0x6, window_underflow_trap)
     184        STRAP(0x5, window_overflow_trap)
     185        STRAP(0x6, window_underflow_trap)
    145186        TRAP(0x7, mem_address_not_aligned)
    146187        TRAP(0x8, fp_exception)
  • kernel/arch/sparc32/src/userspace.c

    r80d9d83 r1f12fab  
    3636#include <typedefs.h>
    3737#include <arch.h>
     38#include <arch/asm.h>
    3839#include <abi/proc/uarg.h>
    3940#include <mm/as.h>
     
    4142void userspace(uspace_arg_t *kernel_uarg)
    4243{
     44        printf("userspace(): entry=%p, stack=%p, stacksize=%d\n", kernel_uarg->uspace_entry, kernel_uarg->uspace_stack, kernel_uarg->uspace_stack_size);
    4345        /* On real hardware this switches the CPU to user
    4446           space mode and jumps to kernel_uarg->uspace_entry. */
    45        
     47
     48        uint32_t psr = psr_read();
     49
     50        psr &= ~(1 << 7);
     51        psr &= ~(1 << 6);
     52
     53        asm volatile (
     54                "mov %[stack], %%sp\n"
     55                "mov %[psr], %%psr\n"
     56                "nop\n"
     57                "jmp %[entry]\n"
     58                "nop\n" :: [entry] "r" (kernel_uarg->uspace_entry),
     59                           [psr] "r" (psr),
     60                           [stack] "r" (kernel_uarg->uspace_stack + kernel_uarg->uspace_stack_size));
     61
    4662        while (true);
    4763}
  • uspace/lib/c/arch/sparc32/src/entry.s

    r80d9d83 r1f12fab  
    4444        save %sp, -176, %sp
    4545# XXX   flushw
    46         add %g0, -0x7ff, %fp
     46#       add %g0, -0x7ff, %fp
     47        set 0x80000000, %fp
    4748       
    4849        # Pass pcb_ptr as the first argument to __main()
Note: See TracChangeset for help on using the changeset viewer.