- 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:
@@ -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 {
|
||||
|
||||
@@ -51,3 +51,6 @@ KernelMergeObject kernel_arch_m68k.o :
|
||||
:
|
||||
$(TARGET_KERNEL_PIC_CCFLAGS) -Wno-unused
|
||||
;
|
||||
|
||||
CreateAsmStructOffsetsHeader asm_offsets.h : asm_offsets.cpp ;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user