- add fpu states

- add needed asm_offsets
- start of exception handling


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26073 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol
2008-06-22 01:36:52 +00:00
parent feeb7a7124
commit 35471ac53e
7 changed files with 196 additions and 64 deletions
+83 -2
View File
@@ -5,10 +5,17 @@
#ifndef _KERNEL_ARCH_M68K_CPU_H
#define _KERNEL_ARCH_M68K_CPU_H
#ifndef _ASSEMBLER
#include <arch/m68k/arch_thread_types.h>
#include <kernel.h>
#endif // !_ASSEMBLER
#ifndef _ASSEMBLER
/* 68k has many different possible stack frames, differentiated by a 4 bit number,
* but they also depend on the cpu type.
@@ -195,11 +202,83 @@ struct mc680x0_frame {
};
};
struct mc680x0_null_fpu_state {
uint8 version; // 0
uint8 type; // undefined
uint16 dummy;
};
struct mc680x0_type_00_fpu_state {
uint8 version;
uint8 type; // 0
uint16 dummy;
};
struct mc680x0_type_28_fpu_state {
uint8 version;
uint8 type; // 0x28
uint16 dummy;
// XXX: replace dummies
uint32 dummies[0x28/4];
};
struct mc680x0_type_60_fpu_state {
uint8 version;
uint8 type; // 0x60
uint16 dummy;
// XXX: replace dummies
uint32 dummies[0x60/4];
};
//XXX: those are 040, add others
// biggest known:
struct mc68882_type_d4_fpu_state {
uint8 version;
uint8 type; // 0xd4
uint16 dummy;
// XXX: replace dummies
uint32 dummies[0xd4/4];
};
struct mc680x0_fpu_state {
union {
struct {
uint8 version;
uint8 type; // 0x60
uint16 dummy;
};
struct mc680x0_null_fpu_state null;
struct mc680x0_type_00_fpu_state type_00;
struct mc680x0_type_28_fpu_state type_28;
struct mc680x0_type_60_fpu_state type_60;
struct mc68882_type_d4_fpu_state type_d4;
};
};
// 96-bit format
struct mc680x0_fp_data_reg {
uint8 data[12];
};
struct mc680x0_fp_control_regs {
uint32 fpcr;
uint32 fpsr;
uint32 fpiar;
};
#warning M68K: check for missing regs/movem
struct iframe {
// XXX: fp_frame ?
/* fpu data registers */
#warning M68K: sizeof(fp*)
struct mc680x0_fp_data_reg fp[8];
/* fpu control registers */
struct mc680x0_fp_control_regs fpc;
/* fpu state */
struct mc680x0_fpu_state fpu;
/* data and address registers */
// XXX: order depends on movem
uint32 d[8];
uint32 a[7];
/* cpu exception frame, including sr, pc, format and vector */
@@ -438,4 +517,6 @@ extern int arch_platform;
SPRG3: TLS base pointer (only for userland threads)
*/
#endif // !_ASSEMBLER
#endif /* _KERNEL_ARCH_PPC_CPU_H */
@@ -5,6 +5,8 @@
#ifndef KERNEL_ARCH_M68K_THREAD_TYPES_H
#define KERNEL_ARCH_M68K_THREAD_TYPES_H
#include <kernel.h>
#define IFRAME_TRACE_DEPTH 4
struct iframe_stack {
+3
View File
@@ -51,3 +51,6 @@ KernelMergeObject kernel_arch_m68k.o :
:
$(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
;
CreateAsmStructOffsetsHeader asm_offsets.h : asm_offsets.cpp ;
+2 -2
View File
@@ -6,9 +6,9 @@
* Distributed under the terms of the NewOS License.
*/
#define FUNCTION(x) .global x; .type x,@function; x
#include <arch/m68k/arch_cpu.h>
#define MSR_EXCEPTIONS_ENABLED 15
#define FUNCTION(x) .global x; .type x,@function; x
.text
@@ -5,11 +5,25 @@
* Copyright 2003, Travis Geiselbrecht. All rights reserved.
* Distributed under the terms of the NewOS License.
*/
#include "asm_offsets.h"
#define FUNCTION(x) .global x; .type x,@function; x
#define LOCAL_FUNCTION(x) .type x,@function; x
/* General exception handling concept:
Starting with 68020 the vector offset (=vector number * 4) is part
of the all exception frame types, so we can easily have a common
asm stub for all of them, which calls m68k_exception_entry in
arch_int.cpp.
Also, m68k doesn't disable the mmu on interrupt as ppc does,
which makes things simpler.
----ppc
The PPC architecture specifies entry point offsets for the various
exceptions in the first two physical pages. We put a short piece of code
(VEC_ENTRY()) into each exception vector. It calls exception_vector_common,
@@ -72,6 +86,51 @@
/* exception vector definitions */
/* this one just returns */
FUNCTION(__m68k_exception_noop):
rte
/* see arch_asm.S for ctx switch */
FUNCTION(__m68k_exception_common):
/* save regs */
movem.l %d0-%d7/%a0-%a7,-(%sp) /* push the iframe address */
/* save fp */
sub.l #FPU_STATE_sizeof,%sp
fsave (%sp)
tst.b (%sp) /* check for a null state */
beq null_sav_1 /* yes */
fmovem %fpcr/%fpsr/%fpiar,-(%sp)
fmovem %fp0-%fp7,-(%sp)
bra null_sav_2
null_sav_1:
sub.l #IFRAME_fpu-IFRAME_fp,%sp
null_sav_2:
bsr m68k_exception_entry /* call C entry */
/* restore fp */
tst.b IFRAME_fpu-IFRAME_fp(%sp) /* check for a null state */
beq null_res_1 /* yes */
fmovem (%sp)+,%fp0-%fp7
fmovem (%sp)+,%fpcr/%fpsr/%fpiar
bra null_res_2
null_res_1:
add.l #IFRAME_fpu-IFRAME_fp,%sp
null_res_2:
/* restore fp */
frestore (%sp)
add.l #FPU_STATE_sizeof,%sp
/* restore regs */
movem.l (%sp)+,%d0-%d7/%a0-%a7
rte
#if 0 /* PPC */
/* code in each exception vector */
#define VEC_ENTRY() \
mtsprg1 %r1 ; /* temporarily save r1 in SPRG1 */ \
@@ -437,3 +496,4 @@ __restore_regs_and_rfi:
/* return from interrupt */
rfi
#endif /* PPC */
+35 -53
View File
@@ -28,11 +28,26 @@
#include <vm.h>
#include <vm_address_space.h>
#include <vm_priv.h>
#include <string.h>
#warning M68K: writeme!
//#define TRACE_ARCH_INT
#ifdef TRACE_ARCH_INT
# define TRACE(x) dprintf x
#else
# define TRACE(x) ;
#endif
typedef void (*m68k_exception_handler)(void);
#define M68K_EXCEPTION_VECTOR_COUNT 256
m68k_exception_handler gExceptionVectors[M68K_EXCEPTION_VECTOR_COUNT];
// defined in arch_exceptions.S
extern "C" void __m68k_exception_noop(void);
extern "C" void __m68k_exception_common(void);
extern int __irqvec_start;
extern int __irqvec_end;
@@ -100,15 +115,16 @@ print_iframe(struct iframe *frame)
}
extern "C" void m68k_exception_entry(int vector, struct iframe *iframe);
extern "C" void m68k_exception_entry(struct iframe *iframe);
void
m68k_exception_entry(int vector, struct iframe *iframe)
m68k_exception_entry(struct iframe *iframe)
{
int vector = iframe->cpu.vector >> 2;
int ret = B_HANDLED_INTERRUPT;
if (vector != 0x900) {
if (vector != -1) {
dprintf("m68k_exception_entry: time %lld vector 0x%x, iframe %p, "
"srr0: %p\n", system_time(), vector, iframe, (void*)iframe->srr0);
"pc: %p\n", system_time(), vector, iframe, (void*)iframe->cpu.pc);
}
struct thread *thread = thread_get_current_thread();
@@ -120,14 +136,11 @@ m68k_exception_entry(int vector, struct iframe *iframe)
m68k_push_iframe(&gBootFrameStack, iframe);
switch (vector) {
case 0x100: // system reset
case 0: // system reset
panic("system reset exception\n");
break;
case 0x200: // machine check
panic("machine check exception\n");
break;
case 0x300: // DSI
case 0x400: // ISI
case 2: // bus error
case 3: // address error
{
bool kernelDebugger = debug_debugger_running();
@@ -174,7 +187,16 @@ m68k_exception_entry(int vector, struct iframe *iframe)
break;
}
case 0x500: // external interrupt
case 24: // spurious interrupt
dprintf("spurious interrupt\n");
break;
case 25: // autovector interrupt
case 26: // autovector interrupt
case 27: // autovector interrupt
case 28: // autovector interrupt
case 29: // autovector interrupt
case 30: // autovector interrupt
case 31: // autovector interrupt
{
if (!sPIC) {
panic("m68k_exception_entry(): external interrupt although we "
@@ -193,50 +215,10 @@ dprintf("handling I/O interrupts done\n");
break;
}
case 0x600: // alignment exception
panic("alignment exception: unimplemented\n");
break;
case 0x700: // program exception
panic("program exception: unimplemented\n");
break;
case 0x800: // FP unavailable exception
panic("FP unavailable exception: unimplemented\n");
break;
case 0x900: // decrementer exception
ret = timer_interrupt();
break;
case 0xc00: // system call
panic("system call exception: unimplemented\n");
break;
case 0xd00: // trace exception
panic("trace exception: unimplemented\n");
break;
case 0xe00: // FP assist exception
panic("FP assist exception: unimplemented\n");
break;
case 0xf00: // performance monitor exception
panic("performance monitor exception: unimplemented\n");
break;
case 0xf20: // altivec unavailable exception
panic("alitivec unavailable exception: unimplemented\n");
break;
case 0x1000:
case 0x1100:
case 0x1200:
panic("TLB miss exception: unimplemented\n");
break;
case 0x1300: // instruction address exception
panic("instruction address exception: unimplemented\n");
break;
case 0x1400: // system management exception
panic("system management exception: unimplemented\n");
break;
case 0x1600: // altivec assist exception
panic("altivec assist exception: unimplemented\n");
break;
case 0x1700: // thermal management exception
panic("thermal management exception: unimplemented\n");
break;
case 9: // trace
default:
dprintf("unhandled exception type 0x%x\n", vector);
print_iframe(iframe);
+11 -7
View File
@@ -35,6 +35,14 @@ dummy()
DEFINE_OFFSET_MACRO(THREAD, thread, kernel_stack_top);
DEFINE_OFFSET_MACRO(THREAD, thread, fault_handler);
// struct iframe
DEFINE_OFFSET_MACRO(IFRAME, iframe, fp);
DEFINE_OFFSET_MACRO(IFRAME, iframe, fpc);
DEFINE_OFFSET_MACRO(IFRAME, iframe, fpu);
DEFINE_OFFSET_MACRO(IFRAME, iframe, d);
DEFINE_OFFSET_MACRO(IFRAME, iframe, a);
DEFINE_OFFSET_MACRO(IFRAME, iframe, cpu);
#if 0
// struct iframe
DEFINE_OFFSET_MACRO(IFRAME, iframe, cs);
DEFINE_OFFSET_MACRO(IFRAME, iframe, eax);
@@ -44,17 +52,13 @@ dummy()
DEFINE_OFFSET_MACRO(IFRAME, iframe, eip);
DEFINE_OFFSET_MACRO(IFRAME, iframe, flags);
DEFINE_OFFSET_MACRO(IFRAME, iframe, user_esp);
#endif
// struct vm86_iframe
DEFINE_SIZEOF_MACRO(VM86_IFRAME, vm86_iframe);
DEFINE_OFFSET_MACRO(VM86_IFRAME, vm86_iframe, flags);
DEFINE_SIZEOF_MACRO(FPU_STATE, mc680x0_fpu_state);
DEFINE_SIZEOF_MACRO(FPU_DATA_REG, mc680x0_fp_data_reg);
// struct syscall_info
DEFINE_SIZEOF_MACRO(SYSCALL_INFO, syscall_info);
DEFINE_OFFSET_MACRO(SYSCALL_INFO, syscall_info, function);
DEFINE_OFFSET_MACRO(SYSCALL_INFO, syscall_info, parameter_size);
// struct x86_optimized_functions
DEFINE_OFFSET_MACRO(X86_OPTIMIZED_FUNCTIONS, x86_optimized_functions,
memcpy);
}