Changeset 32e8cd1 in mainline
- Timestamp:
- 2013-12-28T17:16:44Z (11 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c1023bcb
- Parents:
- f6f22cdb
- Location:
- kernel/arch/sparc32
- Files:
-
- 1 deleted
- 50 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc32/Makefile.inc
rf6f22cdb r32e8cd1 29 29 BFD = binary 30 30 31 ifeq ($(COMPILER),gcc_cross)32 ifeq ($(CROSS_TARGET),arm32)33 ATSIGN = %34 endif35 36 ifeq ($(CROSS_TARGET),mips32)37 GCC_CFLAGS += -mno-abicalls38 endif39 endif40 41 31 BITS = 32 42 32 ENDIANESS = BE … … 45 35 arch/$(KARCH)/src/start.S \ 46 36 arch/$(KARCH)/src/trap_table.S \ 47 arch/$(KARCH)/src/regwin_test.S \48 37 arch/$(KARCH)/src/context.S \ 49 38 arch/$(KARCH)/src/debug/stacktrace.c \ 50 39 arch/$(KARCH)/src/debug/stacktrace_asm.S \ 51 40 arch/$(KARCH)/src/proc/scheduler.c \ 52 41 arch/$(KARCH)/src/proc/task.c \ … … 64 53 arch/$(KARCH)/src/mm/frame.c \ 65 54 arch/$(KARCH)/src/mm/page.c \ 66 arch/$(KARCH)/src/mm/tlb.c \55 arch/$(KARCH)/src/mm/tlb.c 67 56 68 57 ifeq ($(MACHINE),leon3) 69 ARCH_SOURCES += arch/$(KARCH)/src/machine/leon3/leon3.c 58 ARCH_SOURCES += \ 59 arch/$(KARCH)/src/machine/leon3/leon3.c 70 60 endif 71 61 -
kernel/arch/sparc32/_link.ld.in
rf6f22cdb r32e8cd1 1 #define KERNEL_LOAD_ADDRESS0x80a000001 #define KERNEL_LOAD_ADDRESS 0x80a00000 2 2 3 3 ENTRY(kernel_image_start) … … 5 5 SECTIONS { 6 6 . = KERNEL_LOAD_ADDRESS; 7 7 8 .text : { 8 9 ktext_start = .; … … 10 11 ktext_end = .; 11 12 } 13 12 14 .data : { 13 15 kdata_start = .; … … 30 32 *(symtab.*); 31 33 } 34 32 35 .sbss : { 33 36 *(.sbss); -
kernel/arch/sparc32/include/arch/ambapp.h
rf6f22cdb r32e8cd1 36 36 #define KERN_sparc32_AMBAPP_H_ 37 37 38 typedef struct 39 { 38 typedef struct { 40 39 /* Primary serial port location */ 41 40 uintptr_t uart_base; -
kernel/arch/sparc32/include/arch/arch.h
rf6f22cdb r32e8cd1 42 42 #include <arch/istate.h> 43 43 44 #define NWINDOWS844 #define NWINDOWS 8 45 45 46 46 /* ASI assignments: */ 47 #define ASI_CACHEMISS0x0148 #define ASI_CACHECTRL0x0249 #define ASI_MMUCACHE0x1050 #define ASI_MMUREGS0x1951 #define ASI_MMUBYPASS0x1c52 #define ASI_MMUFLUSH0x1847 #define ASI_CACHEMISS 0x01 48 #define ASI_CACHECTRL 0x02 49 #define ASI_MMUCACHE 0x10 50 #define ASI_MMUREGS 0x19 51 #define ASI_MMUBYPASS 0x1c 52 #define ASI_MMUFLUSH 0x18 53 53 54 54 #define TASKMAP_MAX_RECORDS 32 55 55 #define CPUMAP_MAX_RECORDS 32 56 56 57 #define BOOTINFO_TASK_NAME_BUFLEN 3257 #define BOOTINFO_TASK_NAME_BUFLEN 32 58 58 59 59 typedef struct { … … 75 75 } bootinfo_t; 76 76 77 extern void arch_pre_main(void * unused, bootinfo_t *bootinfo);78 extern void write_to_invalid(uint32_t l0, uint32_t l1, uint32_t l2);79 extern void read_from_invalid(uint32_t * l0, uint32_t *l1, uint32_t *l2);80 extern void preemptible_save_uspace(uintptr_t sp, istate_t *istate);81 extern void preemptible_restore_uspace(uintptr_t sp, istate_t *istate);77 extern void arch_pre_main(void *, bootinfo_t *); 78 extern void write_to_invalid(uint32_t, uint32_t, uint32_t); 79 extern void read_from_invalid(uint32_t *, uint32_t *, uint32_t *); 80 extern void preemptible_save_uspace(uintptr_t, istate_t *); 81 extern void preemptible_restore_uspace(uintptr_t, istate_t *); 82 82 extern void flush_windows(void); 83 83 -
kernel/arch/sparc32/include/arch/asm.h
rf6f22cdb r32e8cd1 43 43 NO_TRACE static inline void asm_delay_loop(uint32_t usec) 44 44 { 45 // FIXME TODO 45 46 } 46 47 47 48 NO_TRACE static inline __attribute__((noreturn)) void cpu_halt(void) 48 49 { 49 /* On real hardware this should stop processing further 50 instructions on the CPU (and possibly putting it into 51 low-power mode) without any possibility of exitting 52 this function. */ 53 50 // FIXME TODO 54 51 while (true); 55 52 } … … 57 54 NO_TRACE static inline void cpu_sleep(void) 58 55 { 59 /* On real hardware this should put the CPU into low-power 60 mode. However, the CPU is free to continue processing 61 futher instructions any time. The CPU also wakes up 62 upon an interrupt. */ 56 // FIXME TODO 63 57 } 64 58 … … 68 62 } 69 63 70 /** Word to port71 *72 * Output word to port73 *74 * @param port Port to write to75 * @param val Value to write76 *77 */78 64 NO_TRACE static inline void pio_write_16(ioport16_t *port, uint16_t val) 79 65 { … … 81 67 } 82 68 83 /** Double word to port84 *85 * Output double word to port86 *87 * @param port Port to write to88 * @param val Value to write89 *90 */91 69 NO_TRACE static inline void pio_write_32(ioport32_t *port, uint32_t val) 92 70 { … … 94 72 } 95 73 96 /** Byte from port97 *98 * Get byte from port99 *100 * @param port Port to read from101 * @return Value read102 *103 */104 74 NO_TRACE static inline uint8_t pio_read_8(ioport8_t *port) 105 75 { … … 107 77 } 108 78 109 /** Word from port110 *111 * Get word from port112 *113 * @param port Port to read from114 * @return Value read115 *116 */117 79 NO_TRACE static inline uint16_t pio_read_16(ioport16_t *port) 118 80 { … … 120 82 } 121 83 122 /** Double word from port123 *124 * Get double word from port125 *126 * @param port Port to read from127 * @return Value read128 *129 */130 84 NO_TRACE static inline uint32_t pio_read_32(ioport32_t *port) 131 85 { … … 133 87 } 134 88 135 NO_TRACE static inline uint32_t psr_read( )89 NO_TRACE static inline uint32_t psr_read(void) 136 90 { 137 91 uint32_t v; 138 92 139 93 asm volatile ( 140 94 "mov %%psr, %[v]\n" 141 95 : [v] "=r" (v) 142 96 ); 143 144 return v; 145 } 146 147 NO_TRACE static inline uint32_t wim_read( )97 98 return v; 99 } 100 101 NO_TRACE static inline uint32_t wim_read(void) 148 102 { 149 103 uint32_t v; 150 104 151 105 asm volatile ( 152 106 "mov %%wim, %[v]\n" 153 107 : [v] "=r" (v) 154 108 ); 155 156 return v; 157 } 158 159 NO_TRACE static inline uint32_t asi_u32_read( int asi, uintptr_t va)109 110 return v; 111 } 112 113 NO_TRACE static inline uint32_t asi_u32_read(unsigned int asi, uintptr_t va) 160 114 { 161 115 uint32_t v; 162 116 163 117 asm volatile ( 164 118 "lda [%[va]] %[asi], %[v]\n" 165 119 : [v] "=r" (v) 166 120 : [va] "r" (va), 167 [asi] "i" ((unsigned int) asi) 168 ); 169 170 return v; 171 } 172 173 NO_TRACE static inline void asi_u32_write(int asi, uintptr_t va, uint32_t v) 121 [asi] "i" (asi) 122 ); 123 124 return v; 125 } 126 127 NO_TRACE static inline void asi_u32_write(unsigned int asi, uintptr_t va, 128 uint32_t v) 174 129 { 175 130 asm volatile ( … … 177 132 :: [v] "r" (v), 178 133 [va] "r" (va), 179 [asi] "i" ( (unsigned int)asi)134 [asi] "i" (asi) 180 135 : "memory" 181 136 ); … … 200 155 NO_TRACE static inline ipl_t interrupts_enable(void) 201 156 { 157 psr_reg_t psr; 158 psr.value = psr_read(); 159 202 160 ipl_t pil; 203 204 psr_reg_t psr;205 psr.value = psr_read();206 161 pil = psr.pil; 207 psr.pil = 0xf; 162 163 psr.pil = 0x0f; 208 164 psr_write(psr.value); 209 165 210 166 return pil; 211 167 } … … 213 169 NO_TRACE static inline ipl_t interrupts_disable(void) 214 170 { 171 psr_reg_t psr; 172 psr.value = psr_read(); 173 215 174 ipl_t pil; 216 217 psr_reg_t psr;218 psr.value = psr_read();219 175 pil = psr.pil; 176 220 177 psr.pil = 0; 221 178 psr_write(psr.value); 222 179 223 180 return pil; 224 181 } -
kernel/arch/sparc32/include/arch/atomic.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_ATOMIC_H_36 #define KERN_ abs32le_ATOMIC_H_35 #ifndef KERN_sparc32_ATOMIC_H_ 36 #define KERN_sparc32_ATOMIC_H_ 37 37 38 38 #include <typedefs.h> … … 47 47 REQUIRES(val->count < ATOMIC_COUNT_MAX) 48 48 { 49 /* On real hardware the increment has to be done 50 as an atomic action. */ 51 49 // FIXME TODO 52 50 val->count++; 53 51 } … … 58 56 REQUIRES(val->count > ATOMIC_COUNT_MIN) 59 57 { 60 /* On real hardware the decrement has to be done 61 as an atomic action. */ 62 58 // FIXME TODO 63 59 val->count--; 64 60 } … … 69 65 REQUIRES(val->count < ATOMIC_COUNT_MAX) 70 66 { 71 /* On real hardware both the storing of the previous 72 value and the increment have to be done as a single 73 atomic action. */ 67 // FIXME TODO 74 68 75 69 atomic_count_t prev = val->count; … … 84 78 REQUIRES(val->count > ATOMIC_COUNT_MIN) 85 79 { 86 /* On real hardware both the storing of the previous 87 value and the decrement have to be done as a single 88 atomic action. */ 80 // FIXME TODO 89 81 90 82 atomic_count_t prev = val->count; … … 101 93 REQUIRES_EXTENT_MUTABLE(val) 102 94 { 103 /* On real hardware the retrieving of the original 104 value and storing 1 have to be done as a single 105 atomic action. */ 95 // FIXME TODO 106 96 107 97 atomic_count_t prev = val->count; … … 114 104 REQUIRES_EXTENT_MUTABLE(val) 115 105 { 106 // FIXME TODO 107 116 108 do { 117 109 while (val->count); -
kernel/arch/sparc32/include/arch/barrier.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_BARRIER_H_36 #define KERN_ abs32le_BARRIER_H_35 #ifndef KERN_sparc32_BARRIER_H_ 36 #define KERN_sparc32_BARRIER_H_ 37 37 38 /* 39 * Provisions are made to prevent compiler from reordering instructions itself. 40 */ 38 // FIXME TODO 41 39 42 40 #define CS_ENTER_BARRIER() -
kernel/arch/sparc32/include/arch/context.h
rf6f22cdb r32e8cd1 56 56 */ 57 57 typedef struct { 58 uintptr_t sp; 59 uintptr_t pc; 58 uintptr_t sp; /* %o6 */ 59 uintptr_t pc; /* %o7 */ 60 60 uint32_t i0; 61 61 uint32_t i1; … … 64 64 uint32_t i4; 65 65 uint32_t i5; 66 uintptr_t fp; 66 uintptr_t fp; /* %i6 */ 67 67 uintptr_t i7; 68 68 uint32_t l0; -
kernel/arch/sparc32/include/arch/context_offset.h
rf6f22cdb r32e8cd1 31 31 #define KERN_sparc32_CONTEXT_OFFSET_H_ 32 32 33 #define OFFSET_SP 34 #define OFFSET_PC 35 #define OFFSET_I0 36 #define OFFSET_I1 37 #define OFFSET_I2 38 #define OFFSET_I3 39 #define OFFSET_I4 40 #define OFFSET_I5 41 #define OFFSET_FP 42 #define OFFSET_I7 43 #define OFFSET_L0 44 #define OFFSET_L1 45 #define OFFSET_L2 46 #define OFFSET_L3 47 #define OFFSET_L4 48 #define OFFSET_L5 49 #define OFFSET_L6 50 #define OFFSET_L7 33 #define OFFSET_SP 0 34 #define OFFSET_PC 4 35 #define OFFSET_I0 8 36 #define OFFSET_I1 12 37 #define OFFSET_I2 16 38 #define OFFSET_I3 20 39 #define OFFSET_I4 24 40 #define OFFSET_I5 28 41 #define OFFSET_FP 32 42 #define OFFSET_I7 36 43 #define OFFSET_L0 40 44 #define OFFSET_L1 44 45 #define OFFSET_L2 48 46 #define OFFSET_L3 52 47 #define OFFSET_L4 56 48 #define OFFSET_L5 60 49 #define OFFSET_L6 64 50 #define OFFSET_L7 68 51 51 52 52 #ifndef KERNEL 53 # define OFFSET_TP 72 53 54 #define OFFSET_TP 72 55 54 56 #endif 57 55 58 #ifdef __ASM__ 56 59 -
kernel/arch/sparc32/include/arch/cpu.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_CPU_H_36 #define KERN_ abs32le_CPU_H_35 #ifndef KERN_sparc32_CPU_H_ 36 #define KERN_sparc32_CPU_H_ 37 37 38 /*39 * On real hardware this structure stores40 * information specific to the current41 * CPU model.42 */43 38 typedef struct { 44 39 } cpu_arch_t; -
kernel/arch/sparc32/include/arch/cycle.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_CYCLE_H_36 #define KERN_ abs32le_CYCLE_H_35 #ifndef KERN_sparc32_CYCLE_H_ 36 #define KERN_sparc32_CYCLE_H_ 37 37 38 38 #include <trace.h> … … 40 40 NO_TRACE static inline uint64_t get_cycle(void) 41 41 { 42 // FIXME TODO 42 43 return 0; 43 44 } -
kernel/arch/sparc32/include/arch/exception.h
rf6f22cdb r32e8cd1 38 38 #define KERN_sparc32_EXCEPTION_H_ 39 39 40 #define TT_INSTRUCTION_ACCESS_EXCEPTION 41 #define TT_I NSTRUCTION_ACCESS_MMU_MISS 0x3c42 #define TT_ INSTRUCTION_ACCESS_ERROR 0x2143 #define TT_ ILLEGAL_INSTRUCTION 0x0244 #define TT_ PRIVILEGED_INSTRUCTION 0x0345 #define TT_ FP_DISABLED 0x0846 #define TT_ DIVISION_BY_ZERO 0x2a47 #define TT_DATA_ACCESS_E XCEPTION 0x0948 #define TT_D ATA_ACCESS_MMU_MISS 0x2c49 #define TT_DATA_ACCESS_ ERROR 0x2950 #define TT_ MEM_ADDRESS_NOT_ALIGNED 0x0740 #define TT_INSTRUCTION_ACCESS_EXCEPTION 0x01 41 #define TT_ILLEGAL_INSTRUCTION 0x02 42 #define TT_PRIVILEGED_INSTRUCTION 0x03 43 #define TT_MEM_ADDRESS_NOT_ALIGNED 0x07 44 #define TT_FP_DISABLED 0x08 45 #define TT_DATA_ACCESS_EXCEPTION 0x09 46 #define TT_INSTRUCTION_ACCESS_ERROR 0x21 47 #define TT_DATA_ACCESS_ERROR 0x29 48 #define TT_DIVISION_BY_ZERO 0x2a 49 #define TT_DATA_ACCESS_MMU_MISS 0x2c 50 #define TT_INSTRUCTION_ACCESS_MMU_MISS 0x3c 51 51 52 52 #ifndef __ASM__ 53 53 54 /*#include <arch/interrupt.h>*/ 54 extern void instruction_access_exception(int, istate_t *); 55 extern void instruction_access_error(int, istate_t *); 56 extern void illegal_instruction(int, istate_t *); 57 extern void privileged_instruction(int, istate_t *); 58 extern void fp_disabled(int, istate_t *); 59 extern void fp_exception(int, istate_t *); 60 extern void tag_overflow(int, istate_t *); 61 extern void division_by_zero(int, istate_t *); 62 extern void data_access_exception(int, istate_t *); 63 extern void data_access_error(int, istate_t *); 64 extern void data_access_mmu_miss(int, istate_t *); 65 extern void data_store_error(int, istate_t *); 66 extern void mem_address_not_aligned(int, istate_t *); 55 67 56 extern void instruction_access_exception(int n, istate_t *istate); 57 extern void instruction_access_error(int n, istate_t *istate); 58 extern void illegal_instruction(int n, istate_t *istate); 59 extern void privileged_instruction(int n, istate_t *istate); 60 extern void fp_disabled(int n, istate_t *istate); 61 extern void fp_exception(int n, istate_t *istate); 62 extern void tag_overflow(int n, istate_t *istate); 63 extern void division_by_zero(int n, istate_t *istate); 64 extern void data_access_exception(int n, istate_t *istate); 65 extern void data_access_error(int n, istate_t *istate); 66 extern void data_access_mmu_miss(int n, istate_t *istate); 67 extern void data_store_error(int n, istate_t *istate); 68 extern void mem_address_not_aligned(int n, istate_t *istate); 69 extern sysarg_t syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id); 70 extern void irq_exception(unsigned int nr, istate_t *istate); 68 extern sysarg_t syscall(sysarg_t, sysarg_t, sysarg_t, sysarg_t, sysarg_t, 69 sysarg_t, sysarg_t); 70 extern void irq_exception(unsigned int, istate_t *); 71 71 72 72 #endif /* !__ASM__ */ -
kernel/arch/sparc32/include/arch/faddr.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ -
kernel/arch/sparc32/include/arch/fpu_context.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_FPU_CONTEXT_H_36 #define KERN_ abs32le_FPU_CONTEXT_H_35 #ifndef KERN_sparc32_FPU_CONTEXT_H_ 36 #define KERN_sparc32_FPU_CONTEXT_H_ 37 37 38 38 #include <typedefs.h> … … 40 40 #define FPU_CONTEXT_ALIGN 16 41 41 42 /*43 * On real hardware this stores the FPU registers44 * which are part of the CPU context.45 */46 42 typedef struct { 47 43 } fpu_context_t; -
kernel/arch/sparc32/include/arch/interrupt.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leinterrupt29 /** @addtogroup sparc32interrupt 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_INTERRUPT_H_36 #define KERN_ abs32le_INTERRUPT_H_35 #ifndef KERN_sparc32_INTERRUPT_H_ 36 #define KERN_sparc32_INTERRUPT_H_ 37 37 38 38 #include <typedefs.h> -
kernel/arch/sparc32/include/arch/istate.h
rf6f22cdb r32e8cd1 49 49 #endif /* KERNEL */ 50 50 51 /*52 * On real hardware this stores the registers which53 * need to be preserved during interupts.54 */55 51 typedef struct istate { 56 52 uintptr_t pstate; … … 63 59 REQUIRES_EXTENT_MUTABLE(istate) 64 60 { 65 /* On real hardware this checks whether the interrupted66 context originated from user space. */67 68 61 return !(istate->pc & UINT32_C(0x80000000)); 69 62 } … … 73 66 WRITES(&istate->ip) 74 67 { 75 /* On real hardware this sets the instruction pointer. */76 77 68 istate->pc = retaddr; 78 69 } … … 81 72 REQUIRES_EXTENT_MUTABLE(istate) 82 73 { 83 /* On real hardware this returns the instruction pointer. */84 85 74 return istate->pc; 86 75 } … … 89 78 REQUIRES_EXTENT_MUTABLE(istate) 90 79 { 91 /* On real hardware this returns the frame pointer. */ 92 93 return 0;//istate->fp; 80 return 0; 94 81 } 95 82 -
kernel/arch/sparc32/include/arch/machine/leon3/leon3.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup sparc32leon3 LEON330 * 31 * @ingroup arm3229 /** @addtogroup sparc32leon3 30 * @brief LEON3 System-on-chip. 31 * @ingroup sparc32 32 32 * @{ 33 33 */ 34 34 35 #ifndef KERN_sparc32_ leon3_H_36 #define KERN_sparc32_ leon3_H_35 #ifndef KERN_sparc32_LEON3_H_ 36 #define KERN_sparc32_LEON3_H_ 37 37 38 38 #include <arch/machine_func.h> 39 39 40 #define LEON3_SDRAM_START 0x40000000 41 #define LEON3_IRQ_COUNT 15 42 40 43 extern struct sparc_machine_ops leon3_machine_ops; 41 42 #define LEON3_SDRAM_START 0x4000000043 #define LEON3_IRQ_COUNT 1544 44 45 45 #endif -
kernel/arch/sparc32/include/arch/machine_func.h
rf6f22cdb r32e8cd1 32 32 */ 33 33 /** @file 34 * 34 * @brief Declarations of machine specific functions. 35 35 * 36 * These functions enable to differentiate more kinds of ARMemulators37 * or CPUs. It's the same concept as "arch" functions on the architecture38 * 36 * These functions enable to differentiate more kinds of SPARC emulators 37 * or CPUs. It is the same concept as "arch" functions on the architecture 38 * level. 39 39 */ 40 40 … … 66 66 extern void machine_ops_init(void); 67 67 68 /** Map sHW devices to the kernel address space using #hw_map. */68 /** Map HW devices to the kernel address space using #hw_map. */ 69 69 extern void machine_init(bootinfo_t *); 70 70 71 72 /** Starts timer. */ 71 /** Start timer. */ 73 72 extern void machine_timer_irq_start(void); 74 73 75 76 /** Halts CPU. */ 74 /** Halt CPU. */ 77 75 extern void machine_cpu_halt(void); 78 76 79 77 /** Get extents of available memory. 80 78 * 81 * @param start 82 * @param size 79 * @param start Place to store memory start address. 80 * @param size Place to store memory size. 83 81 */ 84 82 extern void machine_get_memory_extents(uintptr_t *start, size_t *size); … … 91 89 extern void machine_irq_exception(unsigned int exc_no, istate_t *istate); 92 90 93 94 /* 95 * Machine specific frame initialization 96 */ 91 /** Machine specific frame initialization */ 97 92 extern void machine_frame_init(void); 98 93 99 /* 100 * configure the serial line output device. 101 */ 94 /* Configure the serial line output device. */ 102 95 extern void machine_output_init(void); 103 96 104 /* 105 * configure the serial line input device. 106 */ 97 /** Configure the serial line input device. */ 107 98 extern void machine_input_init(void); 108 99 109 100 extern size_t machine_get_irq_count(void); 110 101 111 extern const char * 102 extern const char *machine_get_platform_name(void); 112 103 113 104 #endif -
kernel/arch/sparc32/include/arch/mm/as.h
rf6f22cdb r32e8cd1 55 55 #define as_invalidate_translation_cache(as, page, cnt) 56 56 57 uintptr_t as_context_table;57 extern uintptr_t as_context_table; 58 58 59 59 extern void as_arch_init(void); -
kernel/arch/sparc32/include/arch/mm/frame.h
rf6f22cdb r32e8cd1 33 33 */ 34 34 35 #ifndef KERN_ abs32le_FRAME_H_36 #define KERN_ abs32le_FRAME_H_35 #ifndef KERN_sparc32_FRAME_H_ 36 #define KERN_sparc32_FRAME_H_ 37 37 38 38 #define FRAME_WIDTH 12 /* 4K */ … … 41 41 #include <typedefs.h> 42 42 43 #define PHYSMEM_START_ADDR0x4000000043 #define PHYSMEM_START_ADDR 0x40000000 44 44 45 #define BOOT_PT_ADDRESS0x4000800046 #define BOOT_PT_START_FRAME(BOOT_PT_ADDRESS >> FRAME_WIDTH)47 #define BOOT_PT_SIZE_FRAMES145 #define BOOT_PT_ADDRESS 0x40008000 46 #define BOOT_PT_START_FRAME (BOOT_PT_ADDRESS >> FRAME_WIDTH) 47 #define BOOT_PT_SIZE_FRAMES 1 48 48 49 49 extern void frame_low_arch_init(void); -
kernel/arch/sparc32/include/arch/mm/km.h
rf6f22cdb r32e8cd1 38 38 #include <typedefs.h> 39 39 40 #define KM_SPARC32_IDENTITY_STARTUINT32_C(0x80000000)41 #define KM_SPARC32_IDENTITY_SIZEUINT32_C(0x70000000)40 #define KM_SPARC32_IDENTITY_START UINT32_C(0x80000000) 41 #define KM_SPARC32_IDENTITY_SIZE UINT32_C(0x70000000) 42 42 43 #define KM_SPARC32_NON_IDENTITY_STARTUINT32_C(0xf0000000)44 #define KM_SPARC32_NON_IDENTITY_SIZEUINT32_C(0xff00000)43 #define KM_SPARC32_NON_IDENTITY_START UINT32_C(0xf0000000) 44 #define KM_SPARC32_NON_IDENTITY_SIZE UINT32_C(0xff00000) 45 45 46 46 extern void km_identity_arch_init(void); -
kernel/arch/sparc32/include/arch/mm/page.h
rf6f22cdb r32e8cd1 48 48 #define PA2KA(x) (((uintptr_t) (x)) + UINT32_C(0x40000000)) 49 49 50 #define PTE_ET_INVALID051 #define PTE_ET_DESCRIPTOR152 #define PTE_ET_ENTRY253 54 #define PTE_ACC_USER_RO_KERNEL_RO055 #define PTE_ACC_USER_RW_KERNEL_RW156 #define PTE_ACC_USER_RX_KERNEL_RX257 #define PTE_ACC_USER_RWX_KERNEL_RWX358 #define PTE_ACC_USER_XO_KERNEL_XO459 #define PTE_ACC_USER_RO_KERNEL_RW560 #define PTE_ACC_USER_NO_KERNEL_RX661 #define PTE_ACC_USER_NO_KERNEL_RWX750 #define PTE_ET_INVALID 0 51 #define PTE_ET_DESCRIPTOR 1 52 #define PTE_ET_ENTRY 2 53 54 #define PTE_ACC_USER_RO_KERNEL_RO 0 55 #define PTE_ACC_USER_RW_KERNEL_RW 1 56 #define PTE_ACC_USER_RX_KERNEL_RX 2 57 #define PTE_ACC_USER_RWX_KERNEL_RWX 3 58 #define PTE_ACC_USER_XO_KERNEL_XO 4 59 #define PTE_ACC_USER_RO_KERNEL_RW 5 60 #define PTE_ACC_USER_NO_KERNEL_RX 6 61 #define PTE_ACC_USER_NO_KERNEL_RWX 7 62 62 63 63 /* Number of entries in each level. */ … … 143 143 /** Page Table Descriptor. */ 144 144 typedef struct { 145 unsigned int table_pointer : 30;146 unsigned int et : 2;145 unsigned int table_pointer : 30; 146 unsigned int et : 2; 147 147 } __attribute__((packed)) ptd_t; 148 148 149 149 /** Page Table Entry. */ 150 150 typedef struct { 151 unsigned int frame_address : 24;152 unsigned int cacheable : 1;153 unsigned int modified : 1;154 unsigned int referenced : 1;155 unsigned int acc : 3;156 unsigned int et : 2;151 unsigned int frame_address : 24; 152 unsigned int cacheable : 1; 153 unsigned int modified : 1; 154 unsigned int referenced : 1; 155 unsigned int acc : 3; 156 unsigned int et : 2; 157 157 } __attribute__((packed)) pte_t; 158 158 … … 163 163 NO_TRACE static inline bool pte_is_writeable(pte_t *pt) 164 164 { 165 return ( 166 pt->acc == PTE_ACC_USER_RW_KERNEL_RW || 167 pt->acc == PTE_ACC_USER_RWX_KERNEL_RWX || 168 pt->acc == PTE_ACC_USER_RO_KERNEL_RW || 169 pt->acc == PTE_ACC_USER_NO_KERNEL_RWX 170 ); 165 return ((pt->acc == PTE_ACC_USER_RW_KERNEL_RW) || 166 (pt->acc == PTE_ACC_USER_RWX_KERNEL_RWX) || 167 (pt->acc == PTE_ACC_USER_RO_KERNEL_RW) || 168 (pt->acc == PTE_ACC_USER_NO_KERNEL_RWX)); 171 169 } 172 170 173 171 NO_TRACE static inline bool pte_is_executable(pte_t *pt) 174 172 { 175 return ( 176 pt->acc != PTE_ACC_USER_RO_KERNEL_RO && 177 pt->acc != PTE_ACC_USER_RW_KERNEL_RW && 178 pt->acc != PTE_ACC_USER_RO_KERNEL_RW 179 ); 173 return ((pt->acc != PTE_ACC_USER_RO_KERNEL_RO) && 174 (pt->acc != PTE_ACC_USER_RW_KERNEL_RW) && 175 (pt->acc != PTE_ACC_USER_RO_KERNEL_RW)); 180 176 } 181 177 … … 184 180 { 185 181 pte_t *p = &pt[i]; 186 187 bool notpresent = p->et == 0; 188 189 return ( 190 (p->cacheable << PAGE_CACHEABLE_SHIFT) | 191 (notpresent << PAGE_PRESENT_SHIFT) | 192 ((p->acc != PTE_ACC_USER_NO_KERNEL_RX && p->acc != PTE_ACC_USER_NO_KERNEL_RWX) << PAGE_USER_SHIFT) | 193 (1 << PAGE_READ_SHIFT) | 194 (( 195 p->acc == PTE_ACC_USER_RW_KERNEL_RW || 196 p->acc == PTE_ACC_USER_RWX_KERNEL_RWX || 197 p->acc == PTE_ACC_USER_RO_KERNEL_RW || 198 p->acc == PTE_ACC_USER_NO_KERNEL_RWX 199 ) << PAGE_WRITE_SHIFT) | 200 (( 201 p->acc != PTE_ACC_USER_RO_KERNEL_RO && 202 p->acc != PTE_ACC_USER_RW_KERNEL_RW && 203 p->acc != PTE_ACC_USER_RO_KERNEL_RW 204 ) << PAGE_EXEC_SHIFT) | 205 (1 << PAGE_GLOBAL_SHIFT) 206 ); 182 183 bool notpresent = (p->et == 0); 184 185 return ((p->cacheable << PAGE_CACHEABLE_SHIFT) | 186 (notpresent << PAGE_PRESENT_SHIFT) | 187 (((p->acc != PTE_ACC_USER_NO_KERNEL_RX) && 188 (p->acc != PTE_ACC_USER_NO_KERNEL_RWX)) << PAGE_USER_SHIFT) | 189 (1 << PAGE_READ_SHIFT) | 190 (((p->acc == PTE_ACC_USER_RW_KERNEL_RW) || 191 (p->acc == PTE_ACC_USER_RWX_KERNEL_RWX) || 192 (p->acc == PTE_ACC_USER_RO_KERNEL_RW) || 193 (p->acc == PTE_ACC_USER_NO_KERNEL_RWX)) << PAGE_WRITE_SHIFT) | 194 (((p->acc != PTE_ACC_USER_RO_KERNEL_RO) && 195 (p->acc != PTE_ACC_USER_RW_KERNEL_RW) && 196 (p->acc != PTE_ACC_USER_RO_KERNEL_RW)) << PAGE_EXEC_SHIFT) | 197 (1 << PAGE_GLOBAL_SHIFT)); 207 198 } 208 199 … … 213 204 pte_t *p = &pt[i]; 214 205 215 p->et = (flags & PAGE_NOT_PRESENT) 216 ? PTE_ET_INVALID 217 : PTE_ET_DESCRIPTOR; 206 p->et = (flags & PAGE_NOT_PRESENT) ? 207 PTE_ET_INVALID : PTE_ET_DESCRIPTOR; 218 208 } 219 209 … … 223 213 { 224 214 pte_t *p = &pt[i]; 225 215 226 216 p->et = PTE_ET_ENTRY; 227 217 p->acc = PTE_ACC_USER_NO_KERNEL_RWX; … … 240 230 } 241 231 } 242 232 243 233 if (flags & PAGE_NOT_PRESENT) 244 234 p->et = PTE_ET_INVALID; 245 235 246 236 p->cacheable = (flags & PAGE_CACHEABLE) != 0; 247 237 } … … 252 242 { 253 243 pte_t *p = &pt[i]; 254 244 255 245 p->et = PTE_ET_DESCRIPTOR; 256 246 } … … 261 251 { 262 252 pte_t *p = &pt[i]; 263 253 264 254 p->et = PTE_ET_ENTRY; 265 255 } -
kernel/arch/sparc32/include/arch/mm/page_fault.h
rf6f22cdb r32e8cd1 50 50 typedef struct { 51 51 unsigned int : 14; 52 unsigned int ebe : 8;53 unsigned int l : 2;54 unsigned int at : 3;55 unsigned int ft : 3;56 unsigned int fav : 1;57 unsigned int ow : 1;52 unsigned int ebe : 8; 53 unsigned int l : 2; 54 unsigned int at : 3; 55 unsigned int ft : 3; 56 unsigned int fav : 1; 57 unsigned int ow : 1; 58 58 } __attribute__((packed)) mmu_fault_status_t; 59 59 -
kernel/arch/sparc32/include/arch/mm/tlb.h
rf6f22cdb r32e8cd1 36 36 #define KERN_sparc32_TLB_H_ 37 37 38 #define MMU_CONTROL0x00039 #define MMU_CONTEXT_TABLE0x10040 #define MMU_CONTEXT0x20041 #define MMU_FAULT_STATUS0x30042 #define MMU_FAULT_ADDRESS0x40038 #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 43 43 44 44 #endif -
kernel/arch/sparc32/include/arch/proc/task.h
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leproc29 /** @addtogroup sparc32proc 30 30 * @{ 31 31 */ … … 33 33 */ 34 34 35 #ifndef KERN_ abs32le_TASK_H_36 #define KERN_ abs32le_TASK_H_35 #ifndef KERN_sparc32_TASK_H_ 36 #define KERN_sparc32_TASK_H_ 37 37 38 38 #include <typedefs.h> 39 39 #include <adt/bitmap.h> 40 40 41 /*42 * On real hardware this structure stores task information43 * specific to the architecture.44 */45 41 typedef struct { 46 42 } task_arch_t; -
kernel/arch/sparc32/include/arch/register.h
rf6f22cdb r32e8cd1 42 42 uint32_t value; 43 43 struct { 44 unsigned int impl : 4;45 unsigned int ver : 4;46 unsigned int icc : 4;44 unsigned int impl : 4; 45 unsigned int ver : 4; 46 unsigned int icc : 4; 47 47 unsigned int : 6; 48 unsigned int ec : 1;49 unsigned int ef : 1;50 unsigned int pil : 4;51 unsigned int s : 1;52 unsigned int ps : 1;53 unsigned int et : 1;54 unsigned int cwp : 5;55 } __attribute__ 48 unsigned int ec : 1; 49 unsigned int ef : 1; 50 unsigned int pil : 4; 51 unsigned int s : 1; 52 unsigned int ps : 1; 53 unsigned int et : 1; 54 unsigned int cwp : 5; 55 } __attribute__((packed)); 56 56 } psr_reg_t; 57 57 -
kernel/arch/sparc32/include/arch/regwin.h
rf6f22cdb r32e8cd1 42 42 #include <align.h> 43 43 44 #define UWB_ALIGNMENT 1024 44 /* Window Save Area offsets. */ 45 #define L0_OFFSET 0 46 #define L1_OFFSET 4 47 #define L2_OFFSET 8 48 #define L3_OFFSET 12 49 #define L4_OFFSET 16 50 #define L5_OFFSET 20 51 #define L6_OFFSET 24 52 #define L7_OFFSET 28 53 #define I0_OFFSET 32 54 #define I1_OFFSET 36 55 #define I2_OFFSET 40 56 #define I3_OFFSET 44 57 #define I4_OFFSET 48 58 #define I5_OFFSET 52 59 #define I6_OFFSET 56 60 #define I7_OFFSET 60 45 61 46 /* Window Save Area offsets. */ 47 #define L0_OFFSET 0 48 #define L1_OFFSET 4 49 #define L2_OFFSET 8 50 #define L3_OFFSET 12 51 #define L4_OFFSET 16 52 #define L5_OFFSET 20 53 #define L6_OFFSET 24 54 #define L7_OFFSET 28 55 #define I0_OFFSET 32 56 #define I1_OFFSET 36 57 #define I2_OFFSET 40 58 #define I3_OFFSET 44 59 #define I4_OFFSET 48 60 #define I5_OFFSET 52 61 #define I6_OFFSET 56 62 #define I7_OFFSET 60 63 64 /* Uspace Window Buffer constants. */ 65 #define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE) 66 #define UWB_ALIGNMENT 1024 67 #define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT) 62 /* User space Window Buffer constants. */ 63 #define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE) 64 #define UWB_ALIGNMENT 1024 65 #define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT) 68 66 69 67 #endif -
kernel/arch/sparc32/include/arch/stack.h
rf6f22cdb r32e8cd1 39 39 #include <config.h> 40 40 41 #define MEM_STACK_SIZE 41 #define MEM_STACK_SIZE STACK_SIZE 42 42 43 #define STACK_ITEM_SIZE 4 44 45 /** According to SPARC Compliance Definition, every stack frame is 16-byte aligned. */ 46 #define STACK_ALIGNMENT 8 43 #define STACK_ITEM_SIZE 4 44 #define STACK_ALIGNMENT 8 47 45 48 46 /** 49 47 * 16-extended-word save area for %i[0-7] and %l[0-7] registers. 50 48 */ 51 #define STACK_WINDOW_SAVE_AREA_SIZE 49 #define STACK_WINDOW_SAVE_AREA_SIZE (16 * STACK_ITEM_SIZE) 52 50 53 51 /** 54 52 * Six extended words for first six arguments. 55 53 */ 56 #define STACK_ARG_SAVE_AREA_SIZE 54 #define STACK_ARG_SAVE_AREA_SIZE (6 * STACK_ITEM_SIZE) 57 55 58 /* 56 /** 59 57 * Offsets of arguments on stack. 60 58 */ 61 #define STACK_ARG0 62 #define STACK_ARG1 63 #define STACK_ARG2 64 #define STACK_ARG3 65 #define STACK_ARG4 66 #define STACK_ARG5 67 #define STACK_ARG6 59 #define STACK_ARG0 0 60 #define STACK_ARG1 4 61 #define STACK_ARG2 8 62 #define STACK_ARG3 12 63 #define STACK_ARG4 16 64 #define STACK_ARG5 20 65 #define STACK_ARG6 24 68 66 69 67 #endif -
kernel/arch/sparc32/include/arch/trap.h
rf6f22cdb r32e8cd1 36 36 #define KERN_sparc32_TRAP_H_ 37 37 38 #define TRAP_ENTRY_SIZE1639 #define TRAP_TABLE_COUNT25640 #define TRAP_TABLE_SIZE(TRAP_ENTRY_SIZE * TRAP_TABLE_COUNT)38 #define TRAP_ENTRY_SIZE 16 39 #define TRAP_TABLE_COUNT 256 40 #define TRAP_TABLE_SIZE (TRAP_ENTRY_SIZE * TRAP_TABLE_COUNT) 41 41 42 42 #ifndef __ASM__ 43 43 44 extern void *trap_table; 45 44 46 #endif 45 47 -
kernel/arch/sparc32/include/arch/types.h
rf6f22cdb r32e8cd1 33 33 */ 34 34 35 #ifndef KERN_sparc32 le_TYPES_H_36 #define KERN_sparc32 le_TYPES_H_35 #ifndef KERN_sparc32_TYPES_H_ 36 #define KERN_sparc32_TYPES_H_ 37 37 38 38 #define ATOMIC_COUNT_MIN UINT32_MIN -
kernel/arch/sparc32/src/context.S
rf6f22cdb r32e8cd1 45 45 # them there even if e.g. the thread is migrated to another processor. 46 46 # 47 #flushw 48 mov 7, %g1 49 1: subcc %g1, 1, %g1 50 bg 1b 51 save %sp, -64, %sp 52 47 48 ## flushw 53 49 mov 7, %g1 54 1: subcc %g1, 1, %g1 55 bg 1b 56 restore 57 50 1: 51 subcc %g1, 1, %g1 52 bg 1b 53 54 save %sp, -64, %sp 55 56 mov 7, %g1 57 1: 58 subcc %g1, 1, %g1 59 bg 1b 60 61 restore 62 58 63 CONTEXT_SAVE_ARCH_CORE %o0 59 64 retl … … 70 75 # spills. 71 76 # 72 #rdpr %pstate, %l0 73 #andn %l0, PSTATE_IE_BIT, %l1 74 #wrpr %l1, %pstate 75 #wrpr %g0, 0, %canrestore 76 #wrpr %g0, 0, %otherwin 77 #wrpr %g0, NWINDOWS - 2, %cansave 78 #wrpr %l0, %pstate 77 78 ## rdpr %pstate, %l0 79 ## andn %l0, PSTATE_IE_BIT, %l1 80 ## wrpr %l1, %pstate 81 ## wrpr %g0, 0, %canrestore 82 ## wrpr %g0, 0, %otherwin 83 ## wrpr %g0, NWINDOWS - 2, %cansave 84 ## wrpr %l0, %pstate 85 79 86 mov 7, %g1 80 1: subcc %g1, 1, %g1 81 bg 1b 82 save %sp, -64, %sp 83 87 1: 88 subcc %g1, 1, %g1 89 bg 1b 90 91 save %sp, -64, %sp 92 84 93 mov 7, %g1 85 1: subcc %g1, 1, %g1 86 bg 1b 87 restore 88 94 1: 95 subcc %g1, 1, %g1 96 bg 1b 97 98 restore 99 89 100 CONTEXT_RESTORE_ARCH_CORE %o0 90 101 retl -
kernel/arch/sparc32/src/cpu/cpu.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 38 38 #include <print.h> 39 39 #include <fpu_context.h> 40 41 40 42 41 void fpu_disable(void) … … 56 55 } 57 56 58 void cpu_print_report(cpu_t *cpu)57 void cpu_print_report(cpu_t *cpu) 59 58 { 60 59 } -
kernel/arch/sparc32/src/ddi/ddi.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leddi29 /** @addtogroup sparc32ddi 30 30 * @{ 31 31 */ -
kernel/arch/sparc32/src/debug/stacktrace.c
rf6f22cdb r32e8cd1 37 37 #include <syscall/copy.h> 38 38 #include <typedefs.h> 39 40 39 #include <arch.h> 41 40 #include <arch/stack.h> 42 41 43 #define FRAME_OFFSET_FP_PREV 44 #define FRAME_OFFSET_RA 42 #define FRAME_OFFSET_FP_PREV 14 43 #define FRAME_OFFSET_RA 15 45 44 46 extern void alloc_window_and_flush(void); 45 static void alloc_window_and_flush(void) 46 { 47 // FIXME TODO 48 } 47 49 48 50 bool kernel_stack_trace_context_validate(stack_trace_context_t *ctx) 49 51 { 50 52 uintptr_t kstack; 51 uint32_t l1, l2; 53 uint32_t l1 54 uint32_t l2; 52 55 53 56 read_from_invalid(&kstack, &l1, &l2); 54 57 kstack -= 128; 55 56 if ( THREAD&& (ctx->fp == kstack))58 59 if ((THREAD) && (ctx->fp == kstack)) 57 60 return false; 58 return ctx->fp != 0; 61 62 return (ctx->fp != 0); 59 63 } 60 64 -
kernel/arch/sparc32/src/exception.c
rf6f22cdb r32e8cd1 56 56 { 57 57 page_fault(n, istate); 58 // fault_if_from_uspace(istate, "%s.", __func__);59 // panic_badtrap(istate, n, "%s.", __func__);60 58 } 61 59 … … 113 111 { 114 112 page_fault(n, istate); 115 // fault_if_from_uspace(istate, "%s.", __func__);116 // panic_badtrap(istate, n, "%s.", __func__);117 113 } 118 114 … … 121 117 { 122 118 page_fault(n, istate); 123 // fault_if_from_uspace(istate, "%s.", __func__);124 // panic_badtrap(istate, n, "%s.", __func__);125 119 } 126 120 … … 129 123 { 130 124 page_fault(n, istate); 131 // fault_if_from_uspace(istate, "%s.", __func__);132 // panic_badtrap(istate, n, "%s.", __func__);133 125 } 126 134 127 /** Handle data_access_error. (0x2c) */ 135 128 void data_access_mmu_miss(int n, istate_t *istate) … … 146 139 } 147 140 148 sysarg_t syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5, sysarg_t a6, sysarg_t id) 141 sysarg_t syscall(sysarg_t a1, sysarg_t a2, sysarg_t a3, sysarg_t a4, 142 sysarg_t a5, sysarg_t a6, sysarg_t id) 149 143 { 150 // printf("syscall %d\n", id);151 // printf("args: 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", a1, a2, a3, a4, a5, a6);152 // if (id == 0x4f) {153 // flush_windows();154 // return 0;155 // }156 157 144 return syscall_handler(a1, a2, a3, a4, a5, a6, id); 158 145 } -
kernel/arch/sparc32/src/machine/leon3/leon3.c
rf6f22cdb r32e8cd1 38 38 #include <arch/asm.h> 39 39 #include <arch/machine_func.h> 40 41 40 #include <arch/machine/leon3/leon3.h> 42 43 41 #include <genarch/drivers/grlib/uart.h> 44 42 #include <genarch/drivers/grlib/irqmp.h> 45 43 #include <genarch/srln/srln.h> 46 47 44 #include <func.h> 48 45 #include <config.h> … … 70 67 static const char *leon3_get_platform_name(void); 71 68 72 struct leon3_machine_t 73 { 69 struct leon3_machine_t { 74 70 bootinfo_t *bootinfo; 75 71 outdev_t *scons_dev; 76 72 grlib_irqmp_t irqmp; 77 //grlib_timer_t timer;78 73 }; 79 74 80 75 struct sparc_machine_ops leon3_machine_ops = { 81 leon3_init,82 leon3_cpu_halt,83 leon3_get_memory_extents,84 leon3_timer_start,85 leon3_irq_exception,86 leon3_output_init,87 leon3_input_init,88 leon3_get_irq_count,89 leon3_get_platform_name76 .machine_init = leon3_init, 77 .machine_cpu_halt = leon3_cpu_halt, 78 .machine_get_memory_extents = leon3_get_memory_extents, 79 .machine_timer_irq_start = leon3_timer_start, 80 .machine_irq_exception = leon3_irq_exception, 81 .machine_output_init = leon3_output_init, 82 .machine_input_init = leon3_input_init, 83 .machine_get_irq_count = leon3_get_irq_count, 84 .machine_get_platform_name = leon3_get_platform_name 90 85 }; 91 86 … … 95 90 { 96 91 machine.bootinfo = bootinfo; 97 98 92 grlib_irqmp_init(&machine.irqmp, bootinfo); 99 93 } … … 101 95 static void leon3_cpu_halt(void) 102 96 { 103 for (;;); 97 // FIXME TODO 98 while (1); 104 99 } 105 100 … … 107 102 { 108 103 *start = LEON3_SDRAM_START; 109 *size = 64 * 1024 * 1024;//machine.bootinfo->memsize; 104 *size = 64 * 1024 * 1024; 105 // FIXME: *size = machine.bootinfo->memsize; 110 106 } 111 107 112 108 static void leon3_timer_start(void) 113 109 { 114 //machine.timer = grlib_timer_init(machine.bootinfo->timer_base, machine.bootinfo->timer_irq); 110 // FIXME: 111 // machine.timer = 112 // grlib_timer_init(machine.bootinfo->timer_base, 113 // machine.bootinfo->timer_irq); 115 114 } 116 115 117 static void leon3_irq_exception(unsigned int exc _no, istate_t *istate)116 static void leon3_irq_exception(unsigned int exc, istate_t *istate) 118 117 { 119 118 int irqnum = grlib_irqmp_inum_get(&machine.irqmp); 120 119 121 120 grlib_irqmp_clear(&machine.irqmp, irqnum); 122 121 123 122 irq_t *irq = irq_dispatch_and_lock(irqnum); 124 123 if (irq) { … … 131 130 static void leon3_output_init(void) 132 131 { 133 printf("leon3_output_init\n"); 134 printf("machine.bootinfo=%p, machine.bootinfo->uart_base=0x%08x\n", machine.bootinfo, machine.bootinfo->uart_base); 135 136 machine.scons_dev = grlib_uart_init(machine.bootinfo->uart_base, machine.bootinfo->uart_irq); 137 132 machine.scons_dev = 133 grlib_uart_init(machine.bootinfo->uart_base, 134 machine.bootinfo->uart_irq); 135 138 136 if (machine.scons_dev) 139 137 stdout_wire(machine.scons_dev); … … 148 146 /* Create input device. */ 149 147 scons_inst = (void *)machine.scons_dev->data; 150 148 151 149 srln_instance_t *srln_instance = srln_init(); 152 150 if (srln_instance) { … … 154 152 indev_t *srln = srln_wire(srln_instance, sink); 155 153 grlib_uart_input_wire(scons_inst, srln); 156 154 157 155 /* Enable interrupts from UART */ 158 grlib_irqmp_unmask(&machine.irqmp, machine.bootinfo->uart_irq); 156 grlib_irqmp_unmask(&machine.irqmp, 157 machine.bootinfo->uart_irq); 159 158 } 160 159 } … … 171 170 return "LEON3"; 172 171 } 173 174 -
kernel/arch/sparc32/src/machine_func.c
rf6f22cdb r32e8cd1 31 31 */ 32 32 /** @file 33 * 33 * @brief Definitions of machine specific functions. 34 34 * 35 * These functions enable to differentiate more kinds of sparcemulators36 * 37 * 35 * These functions enable to differentiate more kinds of SPARC emulators 36 * or CPUs. It's the same concept as "arch" functions on the architecture 37 * level. 38 38 */ 39 39 … … 54 54 } 55 55 56 /** Map sHW devices to the kernel address space using #hw_map. */56 /** Map HW devices to the kernel address space using #hw_map. */ 57 57 void machine_init(bootinfo_t *bootinfo) 58 58 { 59 (machine_ops->machine_init)(bootinfo);59 machine_ops->machine_init(bootinfo); 60 60 } 61 61 62 63 /** Starts timer. */ 62 /** Start timer. */ 64 63 void machine_timer_irq_start(void) 65 64 { 66 (machine_ops->machine_timer_irq_start)();65 machine_ops->machine_timer_irq_start(); 67 66 } 68 67 69 70 /** Halts CPU. */ 68 /** Halt CPU. */ 71 69 void machine_cpu_halt(void) 72 70 { 73 (machine_ops->machine_cpu_halt)();71 machine_ops->machine_cpu_halt(); 74 72 } 75 73 76 74 /** Get extents of available memory. 77 75 * 78 * @param start Place to store memory start address. 79 * @param size Place to store memory size. 76 * @param start Place to store memory start address. 77 * @param size Place to store memory size. 78 * 80 79 */ 81 80 void machine_get_memory_extents(uintptr_t *start, size_t *size) 82 81 { 83 (machine_ops->machine_get_memory_extents)(start, size);82 machine_ops->machine_get_memory_extents(start, size); 84 83 } 85 84 86 85 /** Interrupt exception handler. 87 86 * 88 * @param exc _noInterrupt exception number.87 * @param exc Interrupt exception number. 89 88 * @param istate Saved processor state. 89 * 90 90 */ 91 void machine_irq_exception(unsigned int exc _no, istate_t *istate)91 void machine_irq_exception(unsigned int exc, istate_t *istate) 92 92 { 93 (machine_ops->machine_irq_exception)(exc_no, istate);93 machine_ops->machine_irq_exception(exc, istate); 94 94 } 95 95 96 /* 97 * configure the output device. 98 */ 96 /** Configure the output device. */ 99 97 void machine_output_init(void) 100 98 { 101 (machine_ops->machine_output_init)();99 machine_ops->machine_output_init(); 102 100 } 103 101 104 /* 105 * configure the input device. 106 */ 102 /** Configure the input device. */ 107 103 void machine_input_init(void) 108 104 { 109 (machine_ops->machine_input_init)();105 machine_ops->machine_input_init(); 110 106 } 111 107 … … 113 109 size_t machine_get_irq_count(void) 114 110 { 115 return (machine_ops->machine_get_irq_count)();111 return machine_ops->machine_get_irq_count(); 116 112 } 117 113 118 const char * 114 const char *machine_get_platform_name(void) 119 115 { 120 116 if (machine_ops->machine_get_platform_name) 121 117 return machine_ops->machine_get_platform_name(); 118 122 119 return NULL; 123 120 } 121 124 122 /** @} 125 123 */ -
kernel/arch/sparc32/src/mm/as.c
rf6f22cdb r32e8cd1 38 38 #include <genarch/mm/page_pt.h> 39 39 40 static ptd_t context_table[ASID_MAX_ARCH] __attribute__((aligned 40 static ptd_t context_table[ASID_MAX_ARCH] __attribute__((aligned(1024))); 41 41 42 42 void as_arch_init(void) 43 43 { 44 44 as_operations = &as_pt_operations; 45 as_context_table = (uintptr_t) &context_table;45 as_context_table = (uintptr_t) &context_table; 46 46 } 47 47 48 48 void as_install_arch(as_t *as) 49 49 { 50 printf("as_install_arch(asid=%d)\n", as->asid); 51 printf("genarch.page_table=%p\n", as->genarch.page_table); 52 53 context_table[as->asid].table_pointer = (uintptr_t)as->genarch.page_table >> 6; 50 context_table[as->asid].table_pointer = 51 (uintptr_t) as->genarch.page_table >> 6; 54 52 context_table[as->asid].et = PTE_ET_DESCRIPTOR; 55 53 asi_u32_write(ASI_MMUREGS, 0x200, as->asid); -
kernel/arch/sparc32/src/mm/frame.c
rf6f22cdb r32e8cd1 46 46 uintptr_t base; 47 47 size_t size; 48 49 48 machine_get_memory_extents(&base, &size); 50 49 51 50 base = ALIGN_UP(base, FRAME_SIZE); 52 51 size = ALIGN_DOWN(size, FRAME_SIZE); … … 54 53 if (!frame_adjust_zone_bounds(low, &base, &size)) 55 54 return; 56 55 57 56 if (low) { 58 57 zone_create(ADDR2PFN(base), SIZE2FRAMES(size), 59 58 BOOT_PT_START_FRAME + BOOT_PT_SIZE_FRAMES, 60 59 ZONE_AVAILABLE | ZONE_LOWMEM); 61 62 printf("low_zone: %d frames\n", SIZE2FRAMES(size));63 60 } else { 64 61 pfn_t conf = zone_external_conf_alloc(SIZE2FRAMES(size)); … … 66 63 zone_create(ADDR2PFN(base), SIZE2FRAMES(size), conf, 67 64 ZONE_AVAILABLE | ZONE_HIGHMEM); 68 69 printf("high zone: %d frames\n", SIZE2FRAMES(size));70 65 } 71 72 printf("free: %d\n", frame_total_free_get());73 66 } 74 67 75 68 void physmem_print(void) 76 69 { 77 70 // FIXME TODO 78 71 } 79 72 … … 82 75 { 83 76 frame_common_arch_init(true); 84 85 /* blacklist boot page table */77 78 /* Blacklist boot page table */ 86 79 frame_mark_unavailable(BOOT_PT_START_FRAME, BOOT_PT_SIZE_FRAMES); 87 printf("free: %d\n", frame_total_free_get());88 //machine_frame_init();89 80 } 90 81 … … 95 86 } 96 87 97 /** Frees the boot page table. */98 /*void boot_page_table_free(void)99 {100 unsigned int i;101 for (i = 0; i < BOOT_PT_SIZE_FRAMES; i++)102 frame_free(i * FRAME_SIZE + BOOT_PT_ADDRESS);103 }*/104 105 88 /** @} 106 89 */ -
kernel/arch/sparc32/src/mm/page.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32lemm29 /** @addtogroup sparc32mm 30 30 * @{ 31 31 */ … … 57 57 int flags = PAGE_CACHEABLE | PAGE_EXEC; 58 58 page_mapping_operations = &pt_mapping_operations; 59 59 60 60 page_table_lock(AS_KERNEL, true); 61 61 62 62 /* Kernel identity mapping */ 63 //FIXME: We need to consider the possibility that 64 //identity_base > identity_size and physmem_end. 65 //This might lead to overflow if identity_size is too big. 63 // FIXME: 64 // We need to consider the possibility that 65 // identity_base > identity_size and physmem_end. 66 // This might lead to overflow if identity_size is too big. 66 67 for (uintptr_t cur = PHYSMEM_START_ADDR; 67 68 cur < min(KA2PA(config.identity_base) + 68 69 config.identity_size, config.physmem_end); 69 70 cur += FRAME_SIZE) 70 71 page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); 71 72 72 73 73 page_table_unlock(AS_KERNEL, true); 74 74 as_switch(NULL, AS_KERNEL); 75 76 // printf("as_context_table=0x%08x\n", as_context_table); 77 75 78 76 /* Switch MMU to new context table */ 79 77 asi_u32_write(ASI_MMUREGS, MMU_CONTEXT_TABLE, KA2PA(as_context_table) >> 4); 80 81 //boot_page_table_free();82 78 } 83 79 … … 86 82 uint32_t fault_status = asi_u32_read(ASI_MMUREGS, MMU_FAULT_STATUS); 87 83 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->at; 90 91 // printf("page fault on address 0x%08x, status 0x%08x, type %d\n", fault_address, fault_status, type); 92 93 if (type == FAULT_TYPE_LOAD_USER_DATA || 94 type == FAULT_TYPE_LOAD_SUPERVISOR_DATA) 84 mmu_fault_status_t *fault = (mmu_fault_status_t *) &fault_status; 85 mmu_fault_type_t type = (mmu_fault_type_t) fault->at; 86 87 if ((type == FAULT_TYPE_LOAD_USER_DATA) || 88 (type == FAULT_TYPE_LOAD_SUPERVISOR_DATA)) 95 89 as_page_fault(fault_address, PF_ACCESS_READ, istate); 96 90 97 if ( type == FAULT_TYPE_EXECUTE_USER ||98 type == FAULT_TYPE_EXECUTE_SUPERVISOR)91 if ((type == FAULT_TYPE_EXECUTE_USER) || 92 (type == FAULT_TYPE_EXECUTE_SUPERVISOR)) 99 93 as_page_fault(fault_address, PF_ACCESS_EXEC, istate); 100 94 101 if ( type == FAULT_TYPE_STORE_USER_DATA||102 type == FAULT_TYPE_STORE_USER_INSTRUCTION||103 type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION||104 type == FAULT_TYPE_STORE_SUPERVISOR_DATA)95 if ((type == FAULT_TYPE_STORE_USER_DATA) || 96 (type == FAULT_TYPE_STORE_USER_INSTRUCTION) || 97 (type == FAULT_TYPE_STORE_SUPERVISOR_INSTRUCTION) || 98 (type == FAULT_TYPE_STORE_SUPERVISOR_DATA)) 105 99 as_page_fault(fault_address, PF_ACCESS_WRITE, istate); 106 100 } -
kernel/arch/sparc32/src/mm/tlb.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32lemm29 /** @addtogroup sparc32mm 30 30 * @{ 31 31 */ … … 45 45 } 46 46 47 void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt) 47 void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, 48 size_t cnt) 48 49 { 49 50 tlb_invalidate_all(); -
kernel/arch/sparc32/src/proc/scheduler.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leproc29 /** @addtogroup sparc32proc 30 30 * @{ 31 31 */ … … 58 58 uint32_t l7; 59 59 read_from_invalid(&kernel_sp, &uspace_wbuf, &l7); 60 THREAD->arch.uspace_window_buffer = (uint8_t *) uspace_wbuf;60 THREAD->arch.uspace_window_buffer = (uint8_t *) uspace_wbuf; 61 61 } 62 62 } -
kernel/arch/sparc32/src/proc/task.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leproc29 /** @addtogroup sparc32proc 30 30 * @{ 31 31 */ -
kernel/arch/sparc32/src/proc/thread.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32leproc29 /** @addtogroup sparc32proc 30 30 * @{ 31 31 */ … … 64 64 } else { 65 65 uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; 66 66 67 67 /* 68 68 * Mind the possible alignment of the userspace window buffer -
kernel/arch/sparc32/src/smp/ipi.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ -
kernel/arch/sparc32/src/smp/smp.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ -
kernel/arch/sparc32/src/sparc32.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 38 38 #include <arch/asm.h> 39 39 #include <arch/machine_func.h> 40 41 40 #include <func.h> 42 41 #include <config.h> … … 54 53 #include <str.h> 55 54 56 char memcpy_from_uspace_failover_address;57 char memcpy_to_uspace_failover_address;58 bootinfo_t machine_bootinfo;55 static char memcpy_from_uspace_failover_address; 56 static char memcpy_to_uspace_failover_address; 57 static bootinfo_t machine_bootinfo; 59 58 60 59 void arch_pre_main(void *unused, bootinfo_t *bootinfo) … … 62 61 init.cnt = min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); 63 62 memcpy(&machine_bootinfo, bootinfo, sizeof(machine_bootinfo)); 64 65 size_t i; 66 for (i = 0; i < init.cnt; i++) { 63 64 for (size_t i = 0; i < init.cnt; i++) { 67 65 init.tasks[i].paddr = KA2PA(bootinfo->tasks[i].addr); 68 66 init.tasks[i].size = bootinfo->tasks[i].size; … … 70 68 bootinfo->tasks[i].name); 71 69 } 72 70 73 71 machine_ops_init(); 74 72 } … … 82 80 void arch_post_mm_init(void) 83 81 { 84 /* Test register windows */85 write_to_invalid(0xdeadbeef, 0xcafebabe, 0);86 func1();87 88 82 machine_init(&machine_bootinfo); 89 83 90 84 if (config.cpu_active == 1) { 91 85 /* Initialize IRQ routing */ … … 95 89 zone_merge_all(); 96 90 } 97 91 98 92 machine_output_init(); 99 93 } … … 110 104 void arch_post_smp_init(void) 111 105 { 112 // machine_input_init();113 106 } 114 107 -
kernel/arch/sparc32/src/start.S
rf6f22cdb r32e8cd1 38 38 set trap_table, %g1 39 39 mov %g1, %tbr 40 41 mov %psr, %g1! Initialize WIM42 add 43 and 44 set 45 sll 46 mov%g3, %wim47 48 or 49 or %g1, 0xf00, %g1! PIL50 wr%g1, %psr51 52 set 53 mov 54 sub 55 56 mov 57 set 58 set 59 set 40 41 mov %psr, %g1 ! Initialize WIM 42 add %g1, 1, %g2 43 and %g2, 0x7, %g2 44 set 1, %g3 45 sll %g3, %g2, %g3 46 mov %g3, %wim 47 48 or %g1, 0x20, %g1 49 or %g1, 0xf00, %g1 ! PIL 50 wr %g1, %psr 51 52 set boot_stack, %sp 53 mov %sp, %fp 54 sub %sp, 96, %sp 55 56 mov %o1, %l1 57 set 0xdeadbeef, %o0 58 set 0xdeadbeef, %o1 59 set 0, %o2 60 60 call write_to_invalid 61 61 nop 62 63 mov 62 63 mov %l1, %o1 64 64 call arch_pre_main 65 65 nop 66 66 67 67 call main_bsp 68 68 nop … … 72 72 cmp %o0, '\n' 73 73 bne skip 74 74 75 set '\r', %l1 75 76 sta %l1, [%l0] 0x1c 76 skip: sta %o0, [%l0] 0x1c 77 retl 78 nop 77 78 skip: 79 sta %o0, [%l0] 0x1c 80 retl 81 nop 79 82 80 83 kernel_sp: -
kernel/arch/sparc32/src/trap_table.S
rf6f22cdb r32e8cd1 46 46 clr \reg 47 47 mov %wim, %g5 48 1: andcc %g5, 1, %g0 49 bne 2f 50 nop 51 srl %g5, 1, %g5 52 inc \reg 53 b 1b 54 2: nop 55 48 49 1: 50 andcc %g5, 1, %g0 51 bne 2f 52 nop 53 srl %g5, 1, %g5 54 inc \reg 55 b 1b 56 57 2: 58 nop 56 59 .endm 57 60 … … 63 66 .macro switch_to_invalid saved_wim, saved_psr 64 67 get_wim_number %l3 65 mov %wim, \saved_wim 66 mov %g0, %wim 67 mov %psr, \saved_psr 68 mov %wim, \saved_wim ! save WIM 69 mov %g0, %wim ! clear WIM 70 mov %psr, \saved_psr ! read PSR 68 71 and \saved_psr, 0xfffffff0, %l4 69 or %l4, %l3, %l3 70 mov %l3, %psr 71 nop 72 nop 73 nop 74 nop 75 .endm 72 or %l4, %l3, %l3 ! set CWP 73 mov %l3, %psr ! write PSR 74 nop 75 nop 76 nop 77 nop ! wait for PSR to be effective 78 .endm 76 79 77 80 .macro switch_back wim, psr 78 mov \wim, %wim 79 mov \psr, %psr 81 mov \wim, %wim ! saved WIM 82 mov \psr, %psr ! saved PSR 80 83 nop 81 84 nop … … 89 92 sll %l3, 7, %l4 90 93 srl %l3, 1, %l3 91 or 94 or %l3, %l4, %l3 92 95 and %l3, 0xff, %l3 93 96 mov %g0, %wim 94 97 95 98 mov %l5, %g5 96 99 mov %l6, %g6 97 100 mov %l7, %g7 98 101 99 102 save 100 std %l0, [%sp + 101 std %l2, [%sp + 103 std %l0, [%sp + 0] 104 std %l2, [%sp + 8] 102 105 std %l4, [%sp + 16] 103 106 std %l6, [%sp + 24] … … 117 120 sll %l3, 7, %l4 118 121 srl %l3, 1, %l3 119 or 122 or %l3, %l4, %l3 120 123 and %l3, 0xff, %l3 121 124 mov %g0, %wim 122 125 mov \uwb, %g3 123 126 124 127 mov %l5, %g5 125 128 mov %l6, %g6 126 129 mov %l7, %g7 127 130 128 131 save 129 std %l0, [%g3 + 130 std %l2, [%g3 + 132 std %l0, [%g3 + 0] 133 std %l2, [%g3 + 8] 131 134 std %l4, [%g3 + 16] 132 135 std %l6, [%g3 + 24] … … 148 151 srl %l3, 7, %l4 149 152 sll %l3, 1, %l3 150 or 153 or %l3, %l4, %l3 151 154 and %l3, 0xff, %l3 152 155 … … 160 163 mov %g6, %l6 161 164 mov %g7, %l7 162 save 163 164 165 166 167 168 169 170 171 165 save 166 167 ldd [%sp + 0], %l0 168 ldd [%sp + 8], %l2 169 ldd [%sp + 16], %l4 170 ldd [%sp + 24], %l6 171 ldd [%sp + 32], %i0 172 ldd [%sp + 40], %i2 173 ldd [%sp + 48], %i4 174 ldd [%sp + 56], %i6 172 175 save 173 176 … … 179 182 srl %l3, 7, %l4 180 183 sll %l3, 1, %l3 181 or 184 or %l3, %l4, %l3 182 185 and %l3, 0xff, %l3 183 186 184 187 mov %g0, %wim 185 188 restore … … 191 194 mov %g6, %l6 192 195 mov %g7, %l7 193 save 194 196 save 197 195 198 sub \uwb, 64, \uwb 196 ldd [\uwb + 197 ldd [\uwb + 199 ldd [\uwb + 0], %l0 200 ldd [\uwb + 8], %l2 198 201 ldd [\uwb + 16], %l4 199 202 ldd [\uwb + 24], %l6 … … 203 206 ldd [\uwb + 56], %i6 204 207 save 205 208 206 209 mov %l3, %wim 207 210 .endm … … 261 264 window_overflow_trap: 262 265 mov %g7, %l0 263 266 264 267 /* Check whether previous mode was usermode */ 265 268 mov %psr, %l4 … … 268 271 bne 1f 269 272 nop 270 271 /* userspace: */ 272 /* time to check whether desired stack page is mapped 273 * on the MMU. if so, process with saving window directly. 274 * if not, go to preemptible trap handler */ 273 274 /* User space: */ 275 276 /* 277 * Time to check whether desired stack page is mapped 278 * on the MMU. If so, process with saving window directly. 279 * If not, go to preemptible trap handler. 280 */ 275 281 mov %wim, %g5 276 282 mov %g0, %wim … … 279 285 restore 280 286 mov %g5, %wim 281 287 282 288 /* Check beginning of %sp */ 283 289 and %g4, 0xfffff000, %l4 … … 286 292 bne 1f 287 293 nop 288 289 /* prepare args for preemptible handler */294 295 /* Prepare args for preemptible handler */ 290 296 mov %g4, %o0 291 297 set preemptible_save_uspace, %o2 292 298 b preemptible_trap 293 299 nop 294 300 295 301 /* Check end of %sp */ 296 302 add %g4, 56, %g4 … … 300 306 bne 1f 301 307 nop 302 303 /* prepare args for preemptible handler */308 309 /* Prepare args for preemptible handler */ 304 310 mov %g4, %o0 305 311 set preemptible_save_uspace, %o2 306 312 b preemptible_trap 307 313 nop 308 309 /* kernel: */ 310 1: /* rotate WIM on bit right, we have 8 windows */ 311 mov %wim, %l3 312 sll %l3, 7, %l4 313 srl %l3, 1, %l3 314 or %l3, %l4, %l3 315 and %l3, 0xff, %l3 316 317 /* disable WIM traps */ 318 mov %g0,%wim 319 nop; nop; nop 320 321 /* Save invalid window data */ 322 mov %l5, %g5 ! kernel stack pointer 323 mov %l6, %g6 ! kernel wbuf 324 mov %l7, %g7 325 326 327 /* we should check whether window needs to be saved 328 * to kernel stack or uwb 329 */ 330 cmp %g7, 0 331 bne 2f 332 nop 333 334 /* dump registers to stack */ 314 315 /* Kernel: */ 316 317 1: 318 /* Rotate WIM on bit right, we have 8 windows */ 319 mov %wim, %l3 320 sll %l3, 7, %l4 321 srl %l3, 1, %l3 322 or %l3, %l4, %l3 323 and %l3, 0xff, %l3 324 325 /* Disable WIM traps */ 326 mov %g0,%wim 327 nop; nop; nop 328 329 /* Save invalid window data */ 330 mov %l5, %g5 ! kernel stack pointer 331 mov %l6, %g6 ! kernel wbuf 332 mov %l7, %g7 333 334 /* 335 * We should check whether window needs to be saved 336 * to kernel stack or uwb. 337 */ 338 cmp %g7, 0 339 bne 2f 340 nop 341 342 /* Dump registers to stack */ 335 343 save 336 std %l0, [%sp + 337 std %l2, [%sp + 344 std %l0, [%sp + 0] 345 std %l2, [%sp + 8] 338 346 std %l4, [%sp + 16] 339 347 std %l6, [%sp + 24] … … 344 352 b 3f 345 353 nop 346 347 /* dump registers to uwb */ 348 2: save 349 std %l0, [%g6 + 0] 350 std %l2, [%g6 + 8] 351 std %l4, [%g6 + 16] 352 std %l6, [%g6 + 24] 353 std %i0, [%g6 + 32] 354 std %i2, [%g6 + 40] 355 std %i4, [%g6 + 48] 356 std %i6, [%g6 + 56] 357 add %g6, 64, %g6 358 359 /* check whether it's the last user window to be saved */ 360 and %g7, 0x7, %l5 361 mov %psr, %l4 362 and %l4, 0x7, %l4 363 cmp %l5, %l4 364 bne 3f 365 nop 366 367 /* clear uspace window mark */ 354 355 /* Dump registers to uwb */ 356 2: 357 save 358 std %l0, [%g6 + 0] 359 std %l2, [%g6 + 8] 360 std %l4, [%g6 + 16] 361 std %l6, [%g6 + 24] 362 std %i0, [%g6 + 32] 363 std %i2, [%g6 + 40] 364 std %i4, [%g6 + 48] 365 std %i6, [%g6 + 56] 366 add %g6, 64, %g6 367 368 /* Check whether it's the last user window to be saved */ 369 and %g7, 0x7, %l5 370 mov %psr, %l4 371 and %l4, 0x7, %l4 372 cmp %l5, %l4 373 bne 3f 374 nop 375 376 /* Clear uspace window mark */ 368 377 clr %g7 369 370 3: /* back to where we should be */ 371 mov %g5, %l5 372 mov %g6, %l6 373 mov %g7, %l7 374 restore 375 376 /* set new value of window */ 377 mov %l3,%wim 378 nop; nop; nop 379 380 /* go home */ 381 mov %l0, %g7 382 jmp %l1 383 rett %l2 378 379 3: 380 /* Back to where we should be */ 381 mov %g5, %l5 382 mov %g6, %l6 383 mov %g7, %l7 384 restore 385 386 /* Set new value of window */ 387 mov %l3,%wim 388 nop; nop; nop 389 390 /* Go home */ 391 mov %l0, %g7 392 jmp %l1 393 rett %l2 384 394 385 395 window_underflow_trap: 386 396 mov %g7, %l0 387 397 388 398 /* Check whether previous mode was usermode */ 389 399 mov %psr, %l4 … … 392 402 bne 1f 393 403 nop 394 395 /* userspace: */ 396 /* time to check whether desired stack page is mapped 397 * on the MMU. if so, process with saving window directly. 398 * if not, go to preemptible trap handler */ 404 405 /* User space: */ 406 407 /* 408 * Time to check whether desired stack page is mapped 409 * on the MMU. If so, process with saving window directly. 410 * If not, go to preemptible trap handler. 411 */ 399 412 mov %wim, %g5 400 413 mov %g0, %wim … … 410 423 bne 1f 411 424 nop 412 413 /* prepare args for preemptible handler */425 426 /* Prepare args for preemptible handler */ 414 427 mov %g4, %o0 415 428 set preemptible_restore_uspace, %o2 416 429 b preemptible_trap 417 430 nop 418 419 /* rotate WIM on bit LEFT, we have 8 windows */ 420 1: mov %wim,%l3 421 srl %l3,7,%l4 422 sll %l3,1,%l3 423 or %l3,%l4,%l3 424 and %l3, 0xff,%l3 425 426 /* disable WIM traps */ 427 mov %g0,%wim 428 nop; nop; nop 429 430 /* kernel: */ 431 432 433 1: 434 /* Rotate WIM on bit LEFT, we have 8 windows */ 435 mov %wim, %l3 436 srl %l3, 7, %l4 437 sll %l3, 1, %l3 438 or %l3, %l4, %l3 439 and %l3, 0xff, %l3 440 441 /* Disable WIM traps */ 442 mov %g0, %wim 443 nop; nop; nop 444 445 /* Kernel: */ 431 446 restore 432 447 restore 433 mov %l5, %g5 434 mov %l6, %g6 448 mov %l5, %g5 ! kernel stack pointer 449 mov %l6, %g6 ! kernel wbuf 435 450 mov %l7, %g7 436 437 ldd [%sp +0], %l0438 ldd [%sp +8], %l2439 440 441 442 443 444 451 452 ldd [%sp + 0], %l0 453 ldd [%sp + 8], %l2 454 ldd [%sp + 16], %l4 455 ldd [%sp + 24], %l6 456 ldd [%sp + 32], %i0 457 ldd [%sp + 40], %i2 458 ldd [%sp + 48], %i4 459 ldd [%sp + 56], %i6 445 460 b 2f 446 461 nop 447 448 2: /* Restore invalid window data */ 449 restore 450 mov %g5, %l5 451 mov %g6, %l6 452 mov %g7, %l7 453 save 454 save 455 save 456 457 /* Set new value of window */ 458 mov %l3,%wim 459 nop; nop; nop 460 461 /* go home */ 462 mov %l0, %g7 463 jmp %l1 464 rett %l2 462 463 2: 464 /* Restore invalid window data */ 465 restore 466 mov %g5, %l5 467 mov %g6, %l6 468 mov %g7, %l7 469 save 470 save 471 save 472 473 /* Set new value of window */ 474 mov %l3, %wim 475 nop; nop; nop 476 477 /* Go home */ 478 mov %l0, %g7 479 jmp %l1 480 rett %l2 465 481 466 482 flush_windows: 467 mov 7, %g1468 1: subcc %g1, 1, %g1469 bg 1b470 save %sp, -64, %sp471 472 483 mov 7, %g1 473 1: subcc %g1, 1, %g1 474 bg 1b 475 restore 476 477 retl 478 nop 484 1: 485 subcc %g1, 1, %g1 486 bg 1b 487 save %sp, -64, %sp 488 489 mov 7, %g1 490 1: 491 subcc %g1, 1, %g1 492 bg 1b 493 restore 494 495 retl 496 nop 479 497 480 498 preemptible_trap: 481 499 /* Save %g7 */ 482 500 mov %g7, %l0 483 501 484 502 /* Check whether we landed in invalid window */ 485 503 get_wim_number %g6 … … 488 506 bne 4f 489 507 nop 490 491 /* We are in invalid window. Check whether previous mode was usermode */508 509 /* We are in invalid window. Check whether previous mode was usermode. */ 492 510 if_from_kernel 3f 493 494 /* Trap originated from us pace */511 512 /* Trap originated from user space */ 495 513 /* Kernel stack pointer is at %l5, uwb is at %l6 */ 496 514 inline_save_uspace %l6 497 498 /* set uspace window mark */515 516 /* Set uspace window mark */ 499 517 mov %psr, %l7 500 518 inc %l7 … … 503 521 b 4f 504 522 nop 505 506 3: /* Trap originated from kernel */ 507 inline_save_kernel 508 509 4: /* Check whether previous mode was usermode */ 510 if_from_kernel 5f 511 523 524 3: 525 /* Trap originated from kernel */ 526 inline_save_kernel 527 528 4: 529 /* Check whether previous mode was user mode */ 530 if_from_kernel 5f 531 512 532 /* Load kernel stack pointer from invalid window */ 513 533 switch_to_invalid %g5, %g6 514 534 515 535 /* set uspace window mark */ 516 536 mov %g6, %l7 … … 518 538 and %l7, 0x7, %l7 519 539 or %l7, 0x10, %l7 520 540 521 541 /* Save stack pointer */ 522 542 mov %l5, %g7 523 543 switch_back %g5, %g6 524 544 mov %g7, %sp 525 // mov %sp, %fp 526 527 5: /* Set up stack frame */ 528 sub %sp, 128, %sp 529 530 /* Save trap data on stack */ 531 mov %psr, %l5 532 st %l1, [%sp + 92] 533 st %l2, [%sp + 96] 534 st %l5, [%sp + 100] 535 st %g1, [%sp + 104] 536 st %g2, [%sp + 108] 537 st %g3, [%sp + 112] 538 st %g4, [%sp + 116] 539 st %l0, [%sp + 120] 540 541 /* Enable traps */ 542 mov %psr, %l0 543 or %l0, (1 << 5), %l0 544 mov %l0, %psr 545 nop 546 nop 547 nop 548 nop 549 550 /* Get UWB address */ 551 // switch_to_invalid %g5, %g6 552 // mov %l6, %g1 553 // switch_back %g5, %g6 554 555 # /* Flush windows to stack */ 556 call flush_windows 557 nop 558 /* 559 get_wim_number %g2 560 get_cwp %g5 561 mov %psr, %g6 562 563 sub %g2, 1, %g4 564 and %g4, 0x7, %g4 565 0: mov %g0, %wim 566 cmp %g5, %g4 567 be 0f 568 nop 569 570 restore 571 add %g1, 64, %g1 572 std %l0, [%g1 + 0] 573 std %l2, [%g1 + 8] 574 std %l4, [%g1 + 16] 575 std %l6, [%g1 + 24] 576 std %i0, [%g1 + 32] 577 std %l2, [%g1 + 40] 578 std %l4, [%g1 + 48] 579 std %l6, [%g1 + 56] 580 inc %g5 581 and %g5, 0x7, %g5 582 ba 0b 583 nop 584 585 0: inc %g4 586 and %g4, 0x7, %g4 587 clr %g5 588 inc %g5 589 sll %g5, %g4, %g5 590 591 * Write values to invalid window and switch back * 592 mov %g7, %l5 593 mov %g1, %l6 594 clr %l7 595 switch_back %g5, %g6 596 */ 597 598 /* Jump to actual subroutine */ 599 call %o2 600 add %sp, 128, %o1 601 602 /* Return from handler */ 603 ld [%sp + 92], %l1 604 ld [%sp + 96], %l2 605 ld [%sp + 100], %l0 606 mov %l0, %psr 607 nop 608 nop 609 nop 610 nop 611 nop 612 613 /* If trap originated from uspace, clear uspace window mark and save uwb address for future use */ 614 if_from_kernel 9f 615 switch_to_invalid %g5, %g6 616 clr %l7 617 mov %l5, %g2 618 mov %l6, %g7 619 switch_back %g5, %g6 620 mov %g7, %g1 621 622 /* If trap originated from uspace, restore all windows from UWB */ 623 /* UWB pointer is at %g1 */ 624 0: mov %g0, %wim 625 clr %g5 626 andcc %g1, UWB_ALIGNMENT - 1, %g0 627 bz 0f 628 nop 629 545 ## mov %sp, %fp 546 547 5: 548 /* Set up stack frame */ 549 sub %sp, 128, %sp 550 551 /* Save trap data on stack */ 552 mov %psr, %l5 553 st %l1, [%sp + 92] 554 st %l2, [%sp + 96] 555 st %l5, [%sp + 100] 556 st %g1, [%sp + 104] 557 st %g2, [%sp + 108] 558 st %g3, [%sp + 112] 559 st %g4, [%sp + 116] 560 st %l0, [%sp + 120] 561 562 /* Enable traps */ 563 mov %psr, %l0 564 or %l0, (1 << 5), %l0 565 mov %l0, %psr 566 nop 567 nop 568 nop 569 nop 570 571 /* Get UWB address */ 572 ## switch_to_invalid %g5, %g6 573 ## mov %l6, %g1 574 ## switch_back %g5, %g6 575 576 /* Flush windows to stack */ 577 call flush_windows 578 nop 579 580 /* Jump to actual subroutine */ 581 call %o2 582 add %sp, 128, %o1 583 584 /* Return from handler */ 585 ld [%sp + 92], %l1 586 ld [%sp + 96], %l2 587 ld [%sp + 100], %l0 588 mov %l0, %psr 589 nop 590 nop 591 nop 592 nop 593 nop 594 595 /* 596 * If trap originated from user space, clear user space window mark 597 * and save uwb address for future use. 598 */ 599 if_from_kernel 9f 600 switch_to_invalid %g5, %g6 601 clr %l7 602 mov %l5, %g2 603 mov %l6, %g7 604 switch_back %g5, %g6 605 mov %g7, %g1 606 607 /* If trap originated from user space, restore all windows from UWB */ 608 /* UWB pointer is at %g1 */ 609 0: 610 mov %g0, %wim 611 clr %g5 612 andcc %g1, UWB_ALIGNMENT - 1, %g0 613 bz 0f 614 nop 615 630 616 restore 631 617 sub %g1, 64, %g1 632 ldd [%g1 + 633 ldd [%g1 + 618 ldd [%g1 + 0], %l0 619 ldd [%g1 + 8], %l2 634 620 ldd [%g1 + 16], %l4 635 621 ldd [%g1 + 24], %l6 … … 642 628 ba 0b 643 629 nop 644 645 /* We've restored all uspace windows. Now time to 646 * fix CWP and WIM 630 631 /* 632 * We've restored all uspace windows. Now time to 633 * fix CWP and WIM. 647 634 */ 648 0: restore 649 get_cwp %g7 650 clr %g5 651 inc %g5 652 sll %g5, %g7, %g5 653 654 /* Write values to invalid window and switch back */ 655 mov %g2, %l5 656 mov %g1, %l6 657 clr %l7 658 switch_back %g5, %g6 659 660 mov %sp, %l3 661 sub %g2, 128, %sp 662 ld [%sp + 104], %g1 663 ld [%sp + 108], %g2 664 ld [%sp + 112], %g3 665 ld [%sp + 116], %g4 666 ld [%sp + 120], %g7 667 mov %l3, %sp 668 b 10f 669 nop 670 671 9: inline_restore_kernel 672 673 ld [%sp + 104], %g1 674 ld [%sp + 108], %g2 675 ld [%sp + 112], %g3 676 ld [%sp + 116], %g4 677 ld [%sp + 120], %g7 678 679 10: jmp %l1 680 rett %l2 635 0: 636 restore 637 get_cwp %g7 638 clr %g5 639 inc %g5 640 sll %g5, %g7, %g5 641 642 /* Write values to invalid window and switch back */ 643 mov %g2, %l5 644 mov %g1, %l6 645 clr %l7 646 switch_back %g5, %g6 647 648 mov %sp, %l3 649 sub %g2, 128, %sp 650 ld [%sp + 104], %g1 651 ld [%sp + 108], %g2 652 ld [%sp + 112], %g3 653 ld [%sp + 116], %g4 654 ld [%sp + 120], %g7 655 mov %l3, %sp 656 b 10f 657 nop 658 659 9: 660 inline_restore_kernel 661 ld [%sp + 104], %g1 662 ld [%sp + 108], %g2 663 ld [%sp + 112], %g3 664 ld [%sp + 116], %g4 665 ld [%sp + 120], %g7 666 667 10: 668 jmp %l1 669 rett %l2 681 670 682 671 interrupt_trap: 683 672 /* Save %g7 */ 684 673 mov %g7, %l0 685 674 686 675 /* Check whether we landed in invalid window */ 687 676 get_wim_number %g6 … … 690 679 bne 4f 691 680 nop 692 693 /* We are in invalid window. Check whether previous mode was user mode */681 682 /* We are in invalid window. Check whether previous mode was user mode */ 694 683 if_from_kernel 3f 695 696 /* Trap originated from us pace */684 685 /* Trap originated from user space */ 697 686 /* Kernel stack pointer is at %l5, uwb is at %l6 */ 698 687 inline_save_uspace %l6 699 700 /* set uspace window mark */688 689 /* Set uspace window mark */ 701 690 mov %psr, %l7 702 691 inc %l7 … … 705 694 b 4f 706 695 nop 707 708 3: /* Trap originated from kernel */ 709 inline_save_kernel 710 711 4: /* Check whether previous mode was usermode */ 712 if_from_kernel 5f 713 714 /* Load kernel stack pointer from invalid window */ 715 switch_to_invalid %g5, %g6 716 717 /* set uspace window mark */ 718 mov %g6, %l7 719 inc %l7 720 and %l7, 0x7, %l7 721 or %l7, 0x10, %l7 722 723 /* Save stack pointer */ 724 mov %l5, %g7 725 switch_back %g5, %g6 726 mov %g7, %sp 727 // mov %sp, %fp 728 729 5: /* Set up stack frame */ 730 sub %sp, 128, %sp 731 732 /* Save trap data on stack */ 733 mov %psr, %l5 734 st %l1, [%sp + 92] 735 st %l2, [%sp + 96] 736 st %l5, [%sp + 100] 737 st %g1, [%sp + 104] 738 st %g2, [%sp + 108] 739 st %g3, [%sp + 112] 740 st %g4, [%sp + 116] 741 st %l0, [%sp + 120] 742 743 /* Enable traps */ 744 mov %psr, %l0 745 or %l0, (1 << 5), %l0 746 mov %l0, %psr 747 nop 748 nop 749 nop 750 nop 751 752 /* Flush windows to stack */ 753 call flush_windows 754 nop 755 756 /* Jump to actual subroutine */ 757 mov %g2, %o0 758 call irq_exception 759 add %sp, 128, %o1 760 761 /* Return from handler */ 762 ld [%sp + 92], %l1 763 ld [%sp + 96], %l2 764 ld [%sp + 100], %l0 765 mov %l0, %psr 766 nop 767 nop 768 nop 769 nop 770 nop 771 772 /* If trap originated from uspace, clear uspace window mark and save uwb address for future use */ 773 if_from_kernel 6f 774 switch_to_invalid %g5, %g6 775 clr %l7 776 mov %l5, %g2 777 mov %l6, %g7 778 switch_back %g5, %g6 779 mov %g7, %g1 780 781 /* If trap originated from uspace, restore all windows from UWB */ 782 /* UWB pointer is at %g1 */ 783 0: mov %g0, %wim 784 clr %g5 785 andcc %g1, UWB_ALIGNMENT - 1, %g0 786 bz 0f 787 nop 788 789 restore 790 sub %g1, 64, %g1 791 ldd [%g1 + 0], %l0 792 ldd [%g1 + 8], %l2 793 ldd [%g1 + 16], %l4 794 ldd [%g1 + 24], %l6 795 ldd [%g1 + 32], %i0 796 ldd [%g1 + 40], %i2 797 ldd [%g1 + 48], %i4 798 ldd [%g1 + 56], %i6 799 inc %g5 800 and %g5, 0x7, %g5 801 ba 0b 802 nop 803 804 /* We've restored all uspace windows. Now time to 805 * fix CWP and WIM 696 697 3: 698 /* Trap originated from kernel */ 699 inline_save_kernel 700 701 4: 702 /* Check whether previous mode was user mode */ 703 if_from_kernel 5f 704 705 /* Load kernel stack pointer from invalid window */ 706 switch_to_invalid %g5, %g6 707 708 /* Set user space window mark */ 709 mov %g6, %l7 710 inc %l7 711 and %l7, 0x7, %l7 712 or %l7, 0x10, %l7 713 714 /* Save stack pointer */ 715 mov %l5, %g7 716 switch_back %g5, %g6 717 mov %g7, %sp 718 ## mov %sp, %fp 719 720 5: 721 /* Set up stack frame */ 722 sub %sp, 128, %sp 723 724 /* Save trap data on stack */ 725 mov %psr, %l5 726 st %l1, [%sp + 92] 727 st %l2, [%sp + 96] 728 st %l5, [%sp + 100] 729 st %g1, [%sp + 104] 730 st %g2, [%sp + 108] 731 st %g3, [%sp + 112] 732 st %g4, [%sp + 116] 733 st %l0, [%sp + 120] 734 735 /* Enable traps */ 736 mov %psr, %l0 737 or %l0, (1 << 5), %l0 738 mov %l0, %psr 739 nop 740 nop 741 nop 742 nop 743 744 /* Flush windows to stack */ 745 call flush_windows 746 nop 747 748 /* Jump to actual subroutine */ 749 mov %g2, %o0 750 call irq_exception 751 add %sp, 128, %o1 752 753 /* Return from handler */ 754 ld [%sp + 92], %l1 755 ld [%sp + 96], %l2 756 ld [%sp + 100], %l0 757 mov %l0, %psr 758 nop 759 nop 760 nop 761 nop 762 nop 763 764 /* 765 * If trap originated from user space, clear user space window mark 766 * and save uwb address for future use. 767 */ 768 if_from_kernel 6f 769 switch_to_invalid %g5, %g6 770 clr %l7 771 mov %l5, %g2 772 mov %l6, %g7 773 switch_back %g5, %g6 774 mov %g7, %g1 775 776 /* If trap originated from user space, restore all windows from UWB */ 777 /* UWB pointer is at %g1 */ 778 0: 779 mov %g0, %wim 780 clr %g5 781 andcc %g1, UWB_ALIGNMENT - 1, %g0 782 bz 0f 783 nop 784 785 restore 786 sub %g1, 64, %g1 787 ldd [%g1 + 0], %l0 788 ldd [%g1 + 8], %l2 789 ldd [%g1 + 16], %l4 790 ldd [%g1 + 24], %l6 791 ldd [%g1 + 32], %i0 792 ldd [%g1 + 40], %i2 793 ldd [%g1 + 48], %i4 794 ldd [%g1 + 56], %i6 795 inc %g5 796 and %g5, 0x7, %g5 797 ba 0b 798 nop 799 800 /* 801 * We've restored all user space windows. Now time to 802 * fix CWP and WIM. 806 803 */ 807 0: restore 808 get_cwp %g7 809 clr %g5 810 inc %g5 811 sll %g5, %g7, %g5 812 813 /* Write values to invalid window and switch back */ 814 mov %g2, %l5 815 mov %g1, %l6 816 clr %l7 817 switch_back %g5, %g6 818 819 /* If next window is invalid, do inline restore */ 820 6: get_wim_number %g6 821 get_cwp %g7 822 inc %g7 823 and %g7, 0x7, %g7 824 cmp %g6, %g7 825 bne 8f 826 827 if_from_kernel 7f 828 829 inline_restore_uspace %g1 830 switch_to_invalid %g5, %g6 831 mov %g1, %l6 832 switch_back %g5, %g6 833 b 8f 834 nop 835 836 7: inline_restore_kernel 837 838 8: ld [%sp + 104], %g1 839 ld [%sp + 108], %g2 840 ld [%sp + 112], %g3 841 ld [%sp + 116], %g4 842 ld [%sp + 120], %g7 843 jmp %l1 844 rett %l2 845 804 0: 805 restore 806 get_cwp %g7 807 clr %g5 808 inc %g5 809 sll %g5, %g7, %g5 810 811 /* Write values to invalid window and switch back */ 812 mov %g2, %l5 813 mov %g1, %l6 814 clr %l7 815 switch_back %g5, %g6 816 817 /* If next window is invalid, do inline restore */ 818 6: 819 get_wim_number %g6 820 get_cwp %g7 821 inc %g7 822 and %g7, 0x7, %g7 823 cmp %g6, %g7 824 bne 8f 825 826 if_from_kernel 7f 827 828 inline_restore_uspace %g1 829 switch_to_invalid %g5, %g6 830 mov %g1, %l6 831 switch_back %g5, %g6 832 b 8f 833 nop 834 835 7: 836 inline_restore_kernel 837 838 8: 839 ld [%sp + 104], %g1 840 ld [%sp + 108], %g2 841 ld [%sp + 112], %g3 842 ld [%sp + 116], %g4 843 ld [%sp + 120], %g7 844 jmp %l1 845 rett %l2 846 846 847 847 syscall_trap: 848 848 /* Save %g7 */ 849 849 mov %g7, %l0 850 850 851 851 /* Check whether we landed in invalid window */ 852 852 get_wim_number %g6 … … 855 855 bne 4f 856 856 nop 857 858 /* We are in invalid window. Check whether previous mode was user mode */857 858 /* We are in invalid window. Check whether previous mode was user mode */ 859 859 if_from_kernel 3f 860 861 /* Trap originated from us pace */860 861 /* Trap originated from user space */ 862 862 /* Kernel stack pointer is at %l5, uwb is at %l6 */ 863 863 inline_save_uspace %l6 864 865 /* set uspace window mark */864 865 /* Set user space window mark */ 866 866 mov %psr, %l7 867 867 inc %l7 … … 870 870 b 4f 871 871 nop 872 873 3: /* Trap originated from kernel */ 874 inline_save_kernel 875 876 4: /* Check whether previous mode was usermode */ 877 if_from_kernel 5f 878 879 /* Load kernel stack pointer from invalid window */ 880 switch_to_invalid %g5, %g6 881 882 /* set uspace window mark */ 883 mov %g6, %l7 884 inc %l7 885 and %l7, 0x7, %l7 886 or %l7, 0x10, %l7 887 888 /* Save stack pointer */ 889 mov %l5, %g7 890 switch_back %g5, %g6 891 mov %g7, %sp 892 // mov %sp, %fp 893 894 5: /* Set up stack frame */ 895 sub %sp, 128, %sp 896 897 /* Save trap data on stack */ 898 mov %psr, %l5 899 st %l1, [%sp + 92] 900 st %l2, [%sp + 96] 901 st %l5, [%sp + 100] 902 st %g1, [%sp + 104] 903 st %g2, [%sp + 108] 904 st %g3, [%sp + 112] 905 st %g4, [%sp + 116] 906 st %l0, [%sp + 120] 907 908 /* Enable traps */ 909 mov %psr, %l0 910 or %l0, (1 << 5), %l0 911 mov %l0, %psr 912 nop 913 nop 914 nop 915 nop 916 917 /* Flush windows */ 918 call flush_windows 919 nop 920 921 /* Jump to actual subroutine */ 922 sub %o0, 0x80, %o0 923 st %o0, [ %sp + 92 ] 924 mov %i0, %o0 925 mov %i1, %o1 926 mov %i2, %o2 927 mov %i3, %o3 928 mov %i4, %o4 929 call syscall 930 mov %i5, %o5 931 932 /* Return from handler */ 933 ld [%sp + 92], %l1 934 ld [%sp + 96], %l2 935 ld [%sp + 100], %l0 936 mov %o0, %i0 937 mov %psr, %l1 938 and %l1, 0xf, %l1 939 and %l0, 0xfffffff0, %l0 940 or %l0, %l1, %l0 941 mov %l0, %psr 942 nop 943 nop 944 nop 945 nop 946 nop 947 948 /* If trap originated from uspace, clear uspace window mark and save uwb address for future use */ 949 if_from_kernel 8f 950 switch_to_invalid %g5, %g6 951 mov %l5, %g2 952 mov %l6, %g1 953 mov %l7, %g7 954 switch_back %g5, %g6 955 956 /* If trap originated from uspace, restore all windows from UWB */ 957 /* UWB pointer is at %g1 */ 958 0: mov %g0, %wim 959 clr %g5 960 andcc %g1, UWB_ALIGNMENT - 1, %g0 961 bz 0f 962 nop 963 964 restore 965 sub %g1, 64, %g1 966 ldd [%g1 + 0], %l0 967 ldd [%g1 + 8], %l2 968 ldd [%g1 + 16], %l4 969 ldd [%g1 + 24], %l6 970 ldd [%g1 + 32], %i0 971 ldd [%g1 + 40], %i2 972 ldd [%g1 + 48], %i4 973 ldd [%g1 + 56], %i6 974 inc %g5 975 and %g5, 0x7, %g5 976 ba 0b 977 nop 978 979 /* We've restored all uspace windows. Now time to 980 * fix CWP and WIM 981 */ 982 0: restore 983 get_cwp %g7 984 clr %g5 985 inc %g5 986 sll %g5, %g7, %g5 987 988 /* Write values to invalid window and switch back */ 989 mov %g2, %l5 990 mov %g1, %l6 991 clr %l7 992 switch_back %g5, %g6 993 994 8: mov %sp, %l1 995 sub %g2, 128, %sp 996 ld [%sp + 104], %g1 997 ld [%sp + 108], %g2 998 ld [%sp + 112], %g3 999 ld [%sp + 116], %g4 1000 ld [%sp + 120], %g7 1001 mov %l1, %sp 1002 jmp %l2 1003 rett %l2 + 4 1004 1005 #define STRAP(_vector, _handler) \ 872 873 3: 874 /* Trap originated from kernel */ 875 inline_save_kernel 876 877 4: 878 /* Check whether previous mode was user mode */ 879 if_from_kernel 5f 880 881 /* Load kernel stack pointer from invalid window */ 882 switch_to_invalid %g5, %g6 883 884 /* Set user space window mark */ 885 mov %g6, %l7 886 inc %l7 887 and %l7, 0x7, %l7 888 or %l7, 0x10, %l7 889 890 /* Save stack pointer */ 891 mov %l5, %g7 892 switch_back %g5, %g6 893 mov %g7, %sp 894 ## mov %sp, %fp 895 896 5: 897 /* Set up stack frame */ 898 sub %sp, 128, %sp 899 900 /* Save trap data on stack */ 901 mov %psr, %l5 902 st %l1, [%sp + 92] 903 st %l2, [%sp + 96] 904 st %l5, [%sp + 100] 905 st %g1, [%sp + 104] 906 st %g2, [%sp + 108] 907 st %g3, [%sp + 112] 908 st %g4, [%sp + 116] 909 st %l0, [%sp + 120] 910 911 /* Enable traps */ 912 mov %psr, %l0 913 or %l0, (1 << 5), %l0 914 mov %l0, %psr 915 nop 916 nop 917 nop 918 nop 919 920 /* Flush windows */ 921 call flush_windows 922 nop 923 924 /* Jump to actual subroutine */ 925 sub %o0, 0x80, %o0 926 st %o0, [%sp + 92] 927 mov %i0, %o0 928 mov %i1, %o1 929 mov %i2, %o2 930 mov %i3, %o3 931 mov %i4, %o4 932 call syscall 933 mov %i5, %o5 934 935 /* Return from handler */ 936 ld [%sp + 92], %l1 937 ld [%sp + 96], %l2 938 ld [%sp + 100], %l0 939 mov %o0, %i0 940 mov %psr, %l1 941 and %l1, 0xf, %l1 942 and %l0, 0xfffffff0, %l0 943 or %l0, %l1, %l0 944 mov %l0, %psr 945 nop 946 nop 947 nop 948 nop 949 nop 950 951 /* 952 * If trap originated from user space, clear user space window mark 953 * and save uwb address for future use. 954 */ 955 if_from_kernel 8f 956 switch_to_invalid %g5, %g6 957 mov %l5, %g2 958 mov %l6, %g1 959 mov %l7, %g7 960 switch_back %g5, %g6 961 962 /* If trap originated from user space, restore all windows from UWB */ 963 /* UWB pointer is at %g1 */ 964 0: 965 mov %g0, %wim 966 clr %g5 967 andcc %g1, UWB_ALIGNMENT - 1, %g0 968 bz 0f 969 nop 970 971 restore 972 sub %g1, 64, %g1 973 ldd [%g1 + 0], %l0 974 ldd [%g1 + 8], %l2 975 ldd [%g1 + 16], %l4 976 ldd [%g1 + 24], %l6 977 ldd [%g1 + 32], %i0 978 ldd [%g1 + 40], %i2 979 ldd [%g1 + 48], %i4 980 ldd [%g1 + 56], %i6 981 inc %g5 982 and %g5, 0x7, %g5 983 ba 0b 984 nop 985 986 /* 987 * We've restored all user space windows. Now time to 988 * fix CWP and WIM. 989 */ 990 0: 991 restore 992 get_cwp %g7 993 clr %g5 994 inc %g5 995 sll %g5, %g7, %g5 996 997 /* Write values to invalid window and switch back */ 998 mov %g2, %l5 999 mov %g1, %l6 1000 clr %l7 1001 switch_back %g5, %g6 1002 1003 8: 1004 mov %sp, %l1 1005 sub %g2, 128, %sp 1006 ld [%sp + 104], %g1 1007 ld [%sp + 108], %g2 1008 ld [%sp + 112], %g3 1009 ld [%sp + 116], %g4 1010 ld [%sp + 120], %g7 1011 mov %l1, %sp 1012 jmp %l2 1013 rett %l2 + 4 1014 1015 #define STRAP(_vector, _handler) \ 1006 1016 .org trap_table + _vector * TRAP_ENTRY_SIZE; \ 1007 1017 mov %psr, %l0 ; \ … … 1010 1020 nop 1011 1021 1012 #define 1022 #define TRAP(_vector, _handler) \ 1013 1023 .org trap_table + _vector * TRAP_ENTRY_SIZE; \ 1014 1024 set _vector, %o0 ; \ … … 1017 1027 or %o2, %lo(_handler), %o2 ; 1018 1028 1019 #define 1029 #define SYSCALL(_vector) \ 1020 1030 .org trap_table + _vector * TRAP_ENTRY_SIZE; \ 1021 1031 set _vector, %o0 ; \ … … 1023 1033 nop ; 1024 1034 1025 #define 1035 #define INTERRUPT(_vector, _priority) \ 1026 1036 .org trap_table + _vector * TRAP_ENTRY_SIZE; \ 1027 1037 mov %psr, %l0 ; \ … … 1030 1040 nop ; 1031 1041 1032 #define 1042 #define BADTRAP(_vector) \ 1033 1043 .org trap_table + _vector * TRAP_ENTRY_SIZE ; \ 1034 1044 ta 0 ; … … 1054 1064 BADTRAP(0x10) 1055 1065 INTERRUPT(0x11, 1) 1056 1057 1058 1059 1060 1061 1062 1063 1066 INTERRUPT(0x12, 2) 1067 INTERRUPT(0x13, 3) 1068 INTERRUPT(0x14, 4) 1069 INTERRUPT(0x15, 5) 1070 INTERRUPT(0x16, 6) 1071 INTERRUPT(0x17, 7) 1072 INTERRUPT(0x18, 8) 1073 INTERRUPT(0x19, 9) 1064 1074 INTERRUPT(0x1a, 10) 1065 1075 INTERRUPT(0x1b, 11) … … 1068 1078 INTERRUPT(0x1e, 14) 1069 1079 INTERRUPT(0x1f, 15) 1070 1071 1072 1073 1074 1075 1076 1077 1078 1080 TRAP(0x21, instruction_access_error) 1081 BADTRAP(0x22) 1082 BADTRAP(0x23) 1083 BADTRAP(0x24) 1084 BADTRAP(0x25) 1085 BADTRAP(0x26) 1086 BADTRAP(0x27) 1087 BADTRAP(0x28) 1088 TRAP(0x29, data_access_error) 1079 1089 TRAP(0x2a, division_by_zero) 1080 1090 TRAP(0x2b, data_store_error) … … 1211 1221 SYSCALL(0xae) 1212 1222 SYSCALL(0xaf) 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1223 SYSCALL(0xb0) 1224 SYSCALL(0xb1) 1225 SYSCALL(0xb2) 1226 SYSCALL(0xb3) 1227 SYSCALL(0xb4) 1228 SYSCALL(0xb5) 1229 SYSCALL(0xb6) 1230 SYSCALL(0xb7) 1231 SYSCALL(0xb8) 1232 SYSCALL(0xb9) 1233 SYSCALL(0xba) 1234 SYSCALL(0xbb) 1235 SYSCALL(0xbc) 1236 SYSCALL(0xbd) 1237 SYSCALL(0xbe) 1238 SYSCALL(0xbf) 1239 SYSCALL(0xc0) 1240 SYSCALL(0xc1) 1241 SYSCALL(0xc2) 1242 SYSCALL(0xc3) 1243 SYSCALL(0xc4) 1244 SYSCALL(0xc5) 1245 SYSCALL(0xc6) 1246 SYSCALL(0xc7) 1247 SYSCALL(0xc8) 1248 SYSCALL(0xc9) 1249 SYSCALL(0xca) 1250 SYSCALL(0xcb) 1251 SYSCALL(0xcc) 1252 SYSCALL(0xcd) 1253 SYSCALL(0xce) 1254 SYSCALL(0xcf) -
kernel/arch/sparc32/src/userspace.c
rf6f22cdb r32e8cd1 27 27 */ 28 28 29 /** @addtogroup abs32le29 /** @addtogroup sparc32 30 30 * @{ 31 31 */ … … 42 42 void userspace(uspace_arg_t *kernel_uarg) 43 43 { 44 // printf("userspace(): entry=%p, stack=%p, stacksize=%d\n", kernel_uarg->uspace_entry, kernel_uarg->uspace_stack, kernel_uarg->uspace_stack_size);45 /* On real hardware this switches the CPU to user46 space mode and jumps to kernel_uarg->uspace_entry. */47 48 uint32_t l0, l1, l2;49 44 uint32_t psr = psr_read(); 50 uint8_t wim;51 52 45 psr &= ~(1 << 7); 53 46 psr &= ~(1 << 6); 54 47 55 48 /* Read invalid window variables */ 49 uint32_t l0; 50 uint32_t l1; 51 uint32_t l2; 56 52 read_from_invalid(&l0, &l1, &l2); 57 53 58 54 /* Make current window invalid */ 59 wim = (psr & 0x7) + 1;55 uint8_t wim = (psr & 0x7) + 1; 60 56 wim = (1 << wim) | (1 >> (8 - wim)); 61 57 62 58 asm volatile ( 63 59 "flush\n" … … 71 67 "ld %[arg], %%o1\n" 72 68 "jmp %[entry]\n" 73 "mov %[psr], %%psr\n" :: [entry] "r" (kernel_uarg->uspace_entry), 74 [arg] "m" (kernel_uarg->uspace_uarg), 75 [psr] "r" (psr), 76 [wim] "r" ((uint32_t)wim), 77 [v0] "m" (l0), 78 [v1] "m" (l1), 79 [v2] "m" (l2), 80 [stack] "r" (kernel_uarg->uspace_stack + kernel_uarg->uspace_stack_size - 64) : "%g3", "%g4"); 81 82 while (true); 69 "mov %[psr], %%psr\n" 70 :: [entry] "r" (kernel_uarg->uspace_entry), 71 [arg] "m" (kernel_uarg->uspace_uarg), 72 [psr] "r" (psr), 73 [wim] "r" ((uint32_t)wim), 74 [v0] "m" (l0), 75 [v1] "m" (l1), 76 [v2] "m" (l2), 77 [stack] "r" (kernel_uarg->uspace_stack + 78 kernel_uarg->uspace_stack_size - 64) 79 : "%g3", "%g4" 80 ); 81 82 while (1); 83 83 } 84 84
Note:
See TracChangeset
for help on using the changeset viewer.