[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[MiNT] [PATCH] FreeMiNT on native ColdFire
Hello.
Here is the long awaited patch for FreeMiNT on native ColdFire.
Basically, it allows running mintv4e.prg over EmuTOS for ColdFire.
In that case, everything is 100% ColdFire. Nothing is emulated, it is as
fast as possible.
The big advantage is that in that native mode, there is no cheat, the whole
ColdFire features are available from supervisor mode and kernel modules. New
kernel modules could be written right now for the FireBee specific hardware.
The drawback is that native ColdFire mode allows only to run 100% ColdFire
MiNT programs. Any classic 680x0 binary will die with an Illegal Instruction
exception.
Of course, mintv4e.prg is still compatible with FireTOS. If 680x0 emulation
is detected, it is used for specific supervisor instructions (exception
stack frame format, rte, cache management...). Only supervisor instructions
are emulated, so there is almost no performance loss.
Best of all, all that emulation mess is hidden in the kernel itself.
ColdFire kernel modules and user programs can run equally well on FireTOS or
EmuTOS :-)
Currently, the FireBee FEC (ethernet) driver cleanly fails to load on EmuTOS
because it uses FireTOS specific features (the DMA API). But we will find a
solution for that.
native_coldfire.patch
Added support for native ColdFire. Contributed by Vincent Riviere.
Alan or Helmut, please commit!
--
Vincent Rivière
diff -aurN -x CVS freemint.orig/sys/arch/check_exc.c freemint/sys/arch/check_exc.c
--- freemint.orig/sys/arch/check_exc.c 2011-07-30 21:20:59.000000000 +0200
+++ freemint/sys/arch/check_exc.c 2012-09-21 22:15:56.218750000 +0200
@@ -536,16 +536,28 @@
long _cdecl
check_priv(struct privilege_violation_stackframe *frame)
{
+ bool emulate_obsolete_instructions = true;
ushort opcode;
opcode = *frame->pc;
UNUSED(opcode);
+
+#ifdef __mcoldfire__
+ if (!coldfire_68k_emulation)
+ {
+ /* Fortunately, pure ColdFire programs are brand new
+ * and does not contain any obsolete instruction.
+ */
+ emulate_obsolete_instructions = false;
+ }
+#endif
+
# ifndef M68000
/* Emulate the "move from sr" instruction,
* which is not privileged on 68000, and privileged later.
* Thus many programs (even Thing Desktop) execute it in
* user mode, if they need an access to the condition codes.
*/
- if ((opcode & MODE_REG_MASK) == MOVE_FROM_SR)
+ if (emulate_obsolete_instructions && (opcode & MODE_REG_MASK) == MOVE_FROM_SR)
{
ushort mode, reg;
diff -aurN -x CVS freemint.orig/sys/arch/check_exc.h freemint/sys/arch/check_exc.h
--- freemint.orig/sys/arch/check_exc.h 2007-07-13 23:32:49.000000000 +0200
+++ freemint/sys/arch/check_exc.h 2012-09-18 19:48:40.875000000 +0200
@@ -289,6 +289,16 @@
} bottom;
};
+/* ColdFire exception stack frame */
+struct coldfire_frame
+{
+ ulong data_reg[8];
+ ulong addr_reg[7];
+ ushort format_word;
+ ushort sr;
+ ushort *pc;
+};
+
struct m68k_stack_frames
{
union {
@@ -300,6 +310,7 @@
struct mc68030_bus_frame_long m68030_lbus;
struct mc68040_bus_frame m68040_bus;
struct mc68060_bus_frame m68060_bus;
+ struct coldfire_frame coldfire;
} type;
};
diff -aurN -x CVS freemint.orig/sys/arch/context.S freemint/sys/arch/context.S
--- freemint.orig/sys/arch/context.S 2011-06-16 11:25:06.000000000 +0200
+++ freemint/sys/arch/context.S 2012-09-21 22:19:23.953125000 +0200
@@ -93,6 +93,26 @@
lea 12(sp),a1 // start of the interesting stack area
move.w (a1)+,d0 // 68000 fake frame format
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s build_68k
+
+ move.w (a1)+,C_SFMT(a0) // save format/vector word of context
+ move.w (a1)+,d0 // get SR of context
+ move.w d0,C_SR(a0) // save it
+ move.l (a1)+,C_PC(a0) // save PC of context
+
+ move.w C_SFMT(a0),d1
+ andi.l #0x3000,d1 // keep the filler size bits
+ beq.s build_stack_fixed
+ addq.l #2,a1 // assume 2-byte filler after the exception frame
+build_stack_fixed:
+
+ // TODO FPU
+
+ bra.s short1
+build_68k:
+#endif
#ifdef M68000
move.w (0x59e).w,d1 // get process frame flag
bne.s nojunk // we have some junk on the stack
@@ -253,7 +273,17 @@
// valid assumption, in which case the above FPU code is redundant, the
// next line is not however!
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s save_68k
+
+ move.w #0x4000,C_SFMT(a0) // standard frame/vector word
+
+ bra.s save_ptrace
+save_68k:
+#endif
clr.w C_SFMT(a0) // mark as a 4 word stack frame
+save_ptrace:
clr.b C_PTRACE(a0) // no pending traces, thanks!
lea 8(sp),a1
@@ -310,6 +340,22 @@
// pmove C_TC(a0),tc // restore MMU control register
//noprot3:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s restore_68k
+
+ // TODO FPU
+
+ move.l C_PC(a0),-(sp) // push the PC
+ move.w C_SR(a0),-(sp) // push the status register
+ move.w #0x4000,-(sp) // push the frame/vector word
+ // Since we are just going to return using rte very soon,
+ // we can push a standard frame/vector word instead of C_SFMT(a0),
+ // so we don't have to add any extra filler byte.
+
+ bra.s restore_check_trace
+restore_68k:
+#endif
#ifdef M68000
tst.w (0x59e).w // test longframe (AKP)
beq.s short3
@@ -391,6 +437,7 @@
short3:
move.l C_PC(a0),-(sp) // push the PC
move.w C_SR(a0),-(sp) // push the status register
+restore_check_trace:
tst.b C_PTRACE(a0) // check for a pending trace
movem.l (a0),d0-d7/a0-a6 // restore registers d0-d7/a0-a6
beq.s notrace
@@ -445,6 +492,22 @@
noprot4:
#endif
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s change_68k
+
+ // TODO FPU
+
+ move.l C_PC(a0),-(sp) // push the PC
+ move.w C_SR(a0),-(sp) // push the status register
+ move.w #0x4000,-(sp) // push the frame/vector word
+ // Since we are just going to return using rte very soon,
+ // we can push a standard frame/vector word instead of C_SFMT(a0),
+ // so we don't have to add any extra filler byte.
+
+ bra.s change_check_trace
+change_68k:
+#endif
#ifdef M68000
tst.w (0x59e).w // test longframe (AKP)
beq.s short6
@@ -528,6 +591,7 @@
short6:
move.l C_PC(a0),-(sp) // push the PC
move.w C_SR(a0),-(sp) // push status register
+change_check_trace:
tst.b C_PTRACE(a0) // check for a pending trace
movem.l (a0),d0-d7/a0-a6 // restore registers d0-d7/a0-a6
beq.s notrace2
diff -aurN -x CVS freemint.orig/sys/arch/cpu.S freemint/sys/arch/cpu.S
--- freemint.orig/sys/arch/cpu.S 2011-09-18 23:23:34.091726500 +0200
+++ freemint/sys/arch/cpu.S 2012-09-21 22:51:59.125000000 +0200
@@ -22,9 +22,15 @@
_get_superscalar:
#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s get_superscalar_68k
+ rts // nothing to do
+get_superscalar_68k:
+#endif
+#ifdef __mcoldfire__
moveq #60,d1
cmp.w _mcpu+2,d1
- bpl.s ssret
+ bhi.s ssret
#else
cmp.w #60,_mcpu+2
bmi.s ssret
@@ -43,6 +49,10 @@
_is_superscalar:
clr.w d0
#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ beq.s ssret // not superscalar
+#endif
+#ifdef __mcoldfire__
moveq #60,d1
cmp.w _mcpu+2,d1
bpl.s ssret
@@ -94,6 +104,18 @@
#else
movem.l d0-d1/a0-a3,-(sp)
#endif
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s init_cache_68k
+
+ lea _cache_coldfire,a0
+ movea.l a0,a3
+ lea clq,a1
+ movea.l a1,a2
+
+ bra.s icset
+init_cache_68k:
+#endif
move.l _mcpu,d0
beq icquit
cmp.w #10,d0
@@ -195,6 +217,10 @@
// Set the CACR according to the Cache Control Word and Mask
_ccw_set:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ beq clq // currently unsupported
+#endif
tst.w hascaches
#ifdef __mcoldfire__
beq clq
@@ -266,6 +292,13 @@
// Extract Cache Control Word from the CACR
_ccw_get:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s ccw_get_68k
+ moveq #0x0007,d0 // rough approximation
+ rts
+ccw_get_68k:
+#endif
tst.w hascaches
beq.s clq
#ifdef __mcoldfire__
@@ -296,6 +329,13 @@
// get default Cache Control Mask for currently used CPU
_ccw_getdmask:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s ccw_getdmask_68k
+ moveq #0x0007,d0 // rough approximation
+ rts
+ccw_getdmask_68k:
+#endif
move.l _mcpu,d0 // high word assumed 0
divu.w #5,d0
and.l #0x0000ffff,d0 // better to be safe...
@@ -749,6 +789,46 @@
dc.w 0xF478 // this is "cpusha dc"
dc.w 0xF498 // this is "cinva ic"
rts
+
+#ifdef __mcoldfire__
+_cache_coldfire: // ColdFire cache
+ // This code comes from the MCF547x Reference Manual
+ // Section 7.11 Cache Management
+ //
+ // The ColdFire has no cinva instruction.
+ // Instead, cpushl writes the modified cache data to the RAM
+ // then invalidates the caches (data + instruction) except if
+ // the bits DDPI and IDPI have been set in the CACR.
+ //
+ // The ColdFire V4e core has a 32 kB instruction cache
+ // and a 32 kB data cache. Both caches have the same structure.
+ // The data is stored in "Line" elements of 16 bytes.
+ // The Lines are stored in a 2D array of 4 Ways * 512 Sets.
+ //
+ // The following changes have been made to the original code:
+ // - flush both caches with "cpushl bc" instead of "cpushl dc"
+ // - flush the 512 Sets (original code forgot the last one)
+
+ nop // synchronize/flush store buffer
+ moveq.l #0,d0 // initialize way counter
+ moveq.l #0,d1 // initialize set counter
+ move.l d0,a0 // initialize cpushl pointer
+
+setloop:
+ cpushl bc,(a0) // push cache line a0 (both caches)
+ add.l #0x0010,a0 // increment set index by 1
+ addq.l #1,d1 // increment set counter
+ cmpi.l #512,d1 // are sets for this way done?
+ bne.s setloop
+
+ moveq.l #0,d1 // set counter to zero again
+ addq.l #1,d0 // increment to next way
+ move.l d0,a0 // set = 0, way = d0
+ cmpi.l #4,d0 // flushed all the ways?
+ bne.s setloop
+ rts
+#endif /* COLDFIRE */
+
// ---------------------------------------------------
// log2phys
diff -aurN -x CVS freemint.orig/sys/arch/detect.S freemint/sys/arch/detect.S
--- freemint.orig/sys/arch/detect.S 2011-06-03 10:56:48.000000000 +0200
+++ freemint/sys/arch/detect.S 2012-09-21 22:56:04.187500000 +0200
@@ -261,8 +261,8 @@
//
_detect_cpu:
-#ifdef COLDFIRE
- moveq #60,d0
+#ifdef __mcoldfire__
+ moveq #60,d0 // only true when coldfire_68k_emulation = true
#else
movem.l a0-a2/d1-d2,-(sp)
@@ -384,8 +384,8 @@
.globl _mcpu
_detect_fpu:
-#ifdef COLDFIRE
- moveq #0,d0
+#ifdef __mcoldfire__
+ moveq #0,d0 // TODO ColdFire FPU
#else
movem.l a0-a2/d1,-(sp)
move.l sp,a0 // save the ssp
diff -aurN -x CVS freemint.orig/sys/arch/init_mach.c freemint/sys/arch/init_mach.c
--- freemint.orig/sys/arch/init_mach.c 2011-06-16 11:25:06.000000000 +0200
+++ freemint/sys/arch/init_mach.c 2012-09-26 19:57:33.531250000 +0200
@@ -174,6 +174,14 @@
break;
}
# endif
+
+#ifdef __mcoldfire__
+ case COOKIE__CPU:
+ {
+ coldfire_68k_emulation = true;
+ break;
+ }
+#endif
}
jar++;
@@ -303,7 +311,11 @@
machine = "Atari TT";
break;
case FALCON:
+#ifdef __mcoldfire__
+ machine = "FireBee";
+#else
machine = "Atari Falcon";
+#endif
break;
case MILAN_C:
machine = "Milan";
@@ -333,6 +345,14 @@
_fpu = " no ";
+#ifdef __mcoldfire__
+ if (!coldfire_68k_emulation)
+ {
+ fpu_type = "ColdFire V4e";
+ _fpu = "/";
+ }
+ else
+#endif
if (fpu)
{
switch (fputype >> 16)
@@ -360,57 +380,70 @@
}
}
- _cpu = "m68k";
- _mmu = "";
-
- switch (mcpu)
+#ifdef __mcoldfire__
+ UNUSED(buf);
+
+ if (!coldfire_68k_emulation)
{
- case 0:
- cpu_type = "68000";
- _cpu = cpu_type;
- _mmu = "";
- break;
- case 10:
- cpu_type = "68010";
- _cpu = cpu_type;
- _mmu = "";
- break;
- case 20:
- cpu_type = "68020";
- _cpu = cpu_type;
- _mmu = "";
- break;
- case 30:
- cpu_type = mmu_type = "68030";
- _cpu = cpu_type;
- _mmu = "/MMU";
- break;
- case 40:
- cpu_type = mmu_type = "68040";
- _cpu = cpu_type;
- _mmu = "/MMU";
- break;
- case 60:
+ cpu_type = mmu_type = "ColdFire V4e";
+ _cpu = cpu_type;
+ _mmu = "/MMU";
+ }
+ else
+#endif
+ {
+ _cpu = "m68k";
+ _mmu = "";
+
+ switch (mcpu)
{
- ulong pcr;
-
- __asm__
- (
- ".word 0x4e7a,0x0808;"
- "movl %%d0,%0"
- : "=d"(pcr)
- :
- : "d0"
- );
-
- ksprintf (buf, sizeof (buf), "68%s060 rev.%ld",
- pcr & 0x10000 ? "LC/EC" : "",
- (pcr >> 8) & 0xff);
-
- cpu_type = mmu_type = "68060";
- _cpu = buf;
- _mmu = "/MMU";
- break;
+ case 0:
+ cpu_type = "68000";
+ _cpu = cpu_type;
+ _mmu = "";
+ break;
+ case 10:
+ cpu_type = "68010";
+ _cpu = cpu_type;
+ _mmu = "";
+ break;
+ case 20:
+ cpu_type = "68020";
+ _cpu = cpu_type;
+ _mmu = "";
+ break;
+ case 30:
+ cpu_type = mmu_type = "68030";
+ _cpu = cpu_type;
+ _mmu = "/MMU";
+ break;
+ case 40:
+ cpu_type = mmu_type = "68040";
+ _cpu = cpu_type;
+ _mmu = "/MMU";
+ break;
+ case 60:
+ {
+ ulong pcr;
+
+ __asm__
+ (
+ ".word 0x4e7a,0x0808;"
+ "movl %%d0,%0"
+ : "=d"(pcr)
+ :
+ : "d0"
+ );
+
+ ksprintf (buf, sizeof (buf), "68%s060 rev.%ld",
+ pcr & 0x10000 ? "LC/EC" : "",
+ (pcr >> 8) & 0xff);
+
+ cpu_type = mmu_type = "68060";
+ _cpu = buf;
+ _mmu = "/MMU";
+ break;
+ }
}
}
diff -aurN -x CVS freemint.orig/sys/arch/intr.S freemint/sys/arch/intr.S
--- freemint.orig/sys/arch/intr.S 2011-06-13 09:52:06.000000000 +0200
+++ freemint/sys/arch/intr.S 2012-09-26 21:16:36.765625000 +0200
@@ -82,13 +82,30 @@
move.w d0,vblcnt
bra.s L_novbl
L_vbl:
+ // set up an exception stack frame for VBL emulation
+ tst.w _coldfire_68k_emulation
+ bne.s L_frame060
+
+ // set up a ColdFire stack frame
subq.l #8,sp
move.l 8(sp),(sp) // move the d0 backup on the top of the stack
- clr.w 10(sp) // set up a jump to VBL emulation
+ move.w #0x4000,4(sp) // format/vector word
+ move.w sr,d0
+ move.w d0,6(sp) // return sr
move.l #_mint_vbl,d0
- move.l d0,6(sp)
+ move.l d0,8(sp) // return pc
+ bra.s L_novbl
+
+L_frame060:
+ // set up a 68060 stack frame
+ subq.l #8,sp
+ move.l 8(sp),(sp) // move the d0 backup on the top of the stack
move.w sr,d0
- move.w d0,4(sp)
+ move.w d0,4(sp) // return sr
+ move.l #_mint_vbl,d0
+ move.l d0,6(sp) // return pc
+ clr.w 10(sp) // format/vector word
+
L_novbl:
move.l (sp)+,d0 // restore register
move.l _old_5ms.w(pc),-(sp) // push old vector & save a bit of memory
@@ -276,8 +293,21 @@
// "VBL" things go here (50 times per second at IPL 3)
-txit: btst #2,24(sp) // don't perform if saved IPL is higher than 3 (bit 2 set)
+txit:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s txit_68k
+
+ btst #2,26(sp) // don't perform if saved IPL is higher than 3 (bit 2 set)
bne.s L_popnout
+
+ bra.s L_vbl_emu
+txit_68k:
+#endif
+ btst #2,24(sp) // don't perform if saved IPL is higher than 3 (bit 2 set)
+ bne.s L_popnout
+
+L_vbl_emu:
move.w #0x2400,sr // lower the current IPL
// floppy stuff
@@ -354,8 +384,19 @@
// Process' time has expired, check if we can preempt
L_expired:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s L_expired_68k
+
+ btst #5,2(sp) // user mode?
+ bne.s L_out // no -- switching is not possible
+
+ bra.s L_expired2
+L_expired_68k:
+#endif
btst #5,(sp) // user mode?
bne.s L_out // no -- switching is not possible
+L_expired2:
tst.w (0x043e).w // test floppy disk lock variable
bne.s L_out // if locked, can't switch
#ifdef __mcoldfire__
@@ -717,7 +758,17 @@
move.l _curproc,a0
move.l sp,P_EXCSSP(a0)
addq.l #4,P_EXCSSP(a0)
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s do_sig_68k
+
+ move.l 8(sp),P_EXCPC(a0)
+ bra.s do_sig_restore
+
+do_sig_68k:
+#endif
move.l 6(sp),P_EXCPC(a0)
+do_sig_restore:
move.l (sp)+,a0
tst.w _in_kernel // are we already in the kernel?
@@ -780,6 +831,15 @@
move.l a2,-(sp)
move.l _curproc,a0
move.l P_EXCSSP(a0),a1 // a1 is now exception_ssp
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s mmu_sigbus_68k
+
+ // TODO ColdFire MMU
+
+ bra.s ms_goon
+mmu_sigbus_68k:
+#endif
#if !defined(M68040) && !defined(M68060)
move.w 0xA(a1),d0 // d0 is SSW
btst #6,d0 // read or write?
@@ -1204,26 +1264,33 @@
dc.l 0
_new_trace:
#ifdef __mcoldfire__
+ move.l a0,-(sp)
move.l d0,-(sp)
- btst #5,4(sp) // only check when called from supervisor mode
+
+ tst.w _coldfire_68k_emulation
+ bne.s cf_68k_trace
+
+ lea 10(sp),a0 // native coldfire: sr, pc
+ bra.s cf_trace
+
+cf_68k_trace:
+ lea 8(sp),a0 // 68K emulation: sr, pc
+
+cf_trace:
+ btst #5,(a0) // only check when called from supervisor mode
beq.s S_1
- move.l #_mint_dos,d0
- cmp.l 6(sp),d0 // lets not trace the kernel !
+ move.l 2(a0),d0 // pc
+ cmp.l #_mint_dos,d0 // lets not trace the kernel !
beq.s S_2
- move.l #_mint_xbios,d0
- cmp.l 6(sp),d0
+ cmp.l #_mint_xbios,d0
beq.s S_2
- move.l #_mint_bios,d0
- cmp.l 6(sp),d0
+ cmp.l #_mint_bios,d0
beq.s S_2
- move.l #_new_divzero,d0
- cmp.l 6(sp),d0
+ cmp.l #_new_divzero,d0
beq.s S_2
- move.l #_new_trapv,d0
- cmp.l 6(sp),d0
+ cmp.l #_new_trapv,d0
beq.s S_2
- move.l #_new_chk,d0
- cmp.l 6(sp),d0
+ cmp.l #_new_chk,d0
beq.s S_2
// add any other non-traceable entities here...
@@ -1233,12 +1300,14 @@
move.l #_sigtrap,d0
move.l d0,_sig_routine
move.l (sp)+,d0
+ move.l (sp)+,a0
bra Do_sig
-S_2: move.w 4(sp),d0
+S_2: move.w (a0),d0
and.l #0x3fff,d0 // clear both trace bits
- move.w d0,4(sp)
+ move.w d0,(a0)
move.l (sp)+,d0
+ move.l (sp)+,a0
#else
btst #5,(sp) // only check when called from supervisor mode
beq.s S_1
diff -aurN -x CVS freemint.orig/sys/arch/kernfs_mach.c freemint/sys/arch/kernfs_mach.c
--- freemint.orig/sys/arch/kernfs_mach.c 2001-06-13 22:21:36.000000000 +0200
+++ freemint/sys/arch/kernfs_mach.c 2012-09-19 01:13:53.890625000 +0200
@@ -59,6 +59,13 @@
clockfactor = 0;
+#ifdef __mcoldfire__
+ if (!coldfire_68k_emulation)
+ {
+ clockfactor = 2; // Experimentally almost accurate
+ }
+ else
+#endif
switch (mcpu)
{
case 20:
diff -aurN -x CVS freemint.orig/sys/arch/sig_mach.c freemint/sys/arch/sig_mach.c
--- freemint.orig/sys/arch/sig_mach.c 2011-06-16 11:25:06.000000000 +0200
+++ freemint/sys/arch/sig_mach.c 2012-09-21 23:11:30.218750000 +0200
@@ -134,11 +134,7 @@
/* set a new system stack, with a bit of buffer space */
oldstack = curproc->sysstack;
-# ifdef COLDFIRE
newstack = ((unsigned long) &newcurrent) - 0x40UL - 12UL - 0x100UL;
-# else
- newstack = ((unsigned long) &newcurrent) - 0x40UL - 12UL - 0x100UL;
-# endif
if (newstack < (unsigned long) curproc->stack + ISTKSIZE + 256)
{
ALERT("stack overflow");
@@ -307,11 +303,7 @@
else
{
unwound_stack = 0;
-# ifdef COLDFIRE
- oldctxt = (CONTEXT *) (((long) &frame[2]) + 0x40 + 0x100);
-# else
oldctxt = (CONTEXT *) (((long) &frame[2]) + 0x40 + 0x100);
-# endif
if (oldctxt->regs[0] != CTXT_MAGIC)
{
FATAL ("p_sigreturn: corrupted context");
diff -aurN -x CVS freemint.orig/sys/arch/syscall.S freemint/sys/arch/syscall.S
--- freemint.orig/sys/arch/syscall.S 2011-06-13 09:52:06.000000000 +0200
+++ freemint/sys/arch/syscall.S 2012-09-21 23:17:38.234375000 +0200
@@ -224,6 +224,22 @@
bra reentrant_trap
norm_xbios:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s LX_68k
+
+ btst #5,2(sp) // test for user/super mode
+ beq.s LX_usr
+
+ move.w (sp),d1 // format/vector word
+ andi.l #0x3000,d1 // keep the filler size bits
+ beq.s LX_stack_fixed
+ moveq #2,d1 // assume 2-byte filler after the exception frame
+LX_stack_fixed:
+ lea 8(sp,d1.l),a1
+ bra.s LX_check
+LX_68k:
+#endif
btst #5,(sp) // test for user/super mode
beq.s LX_usr
#ifndef M68000
@@ -376,8 +392,19 @@
tst.w _bconbdev // is BIOS buffering on?
bmi L_bios // no, skip all this
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s L_68k
+
+ btst #5,2(sp) // test for user/super mode
+ bne L_bios // if super, goto L_bios
+
+ bra.s L_user
+L_68k:
+#endif
btst #5,(sp) // test for user/super mode
bne.s L_bios // if super, goto L_bios
+L_user:
tst.w _proc_clock // are we about to be preempted?
beq.s L_bios
@@ -684,8 +711,10 @@
norm_trap2:
#ifdef __mcoldfire__
+ move.l a0,-(sp) // backup a0
lea _in_kernel,a0
bset #0x07,(a0)
+ move.l (sp)+,a0 // restore a0
#else
bset #0x07,_in_kernel
#endif
@@ -785,6 +814,17 @@
.text
_trap_1_emu:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s TE_D_68K
+
+ move.w sr,d0
+ move.w d0,-(sp) // return sr
+ move.w #0x4000,-(sp) // format/vector word
+
+ bra.s TE_D_JMP_OLD
+TE_D_68K:
+#endif
#ifdef M68000
tst.w (0x059e).w // test longframe
beq.s TE_D
@@ -799,6 +839,7 @@
#else
move.w sr,-(sp)
#endif
+TE_D_JMP_OLD:
#if !(defined(M68000) || defined(__mcoldfire__))
jmp ([_old_dos])
#else
@@ -809,6 +850,20 @@
// Ozk: we cannot use D0/D1 becaues the ugly VDI and AES
// passes paremters in these registers.
_trap_2_emu:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s TE_AV_68K
+
+ subq.l #6,sp
+ move.w d0,(sp) // backup d0
+ move.w #0x4000,2(sp) // format/vector word
+ move.w sr,d0
+ move.w d0,4(sp) // return sr
+ move.w (sp)+,d0 // restore d0
+
+ bra.s TE_AV_JMP_OLD
+TE_AV_68K:
+#endif
#ifdef M68000
tst.w (0x059e).w
beq.s TE_AV
@@ -826,6 +881,7 @@
#else
move.w sr,-(sp)
#endif
+TE_AV_JMP_OLD:
#if !(defined(M68000) || defined(__mcoldfire__))
jmp ([_old_trap2])
#else
@@ -834,6 +890,17 @@
#endif
_trap_13_emu:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s TE_B_68K
+
+ move.w sr,d0
+ move.w d0,-(sp) // return sr
+ move.w #0x4000,-(sp) // format/vector word
+
+ bra.s TE_B_JMP_OLD
+TE_B_68K:
+#endif
#ifdef M68000
tst.w (0x059e).w // test longframe
beq.s TE_B
@@ -848,6 +915,7 @@
#else
move.w sr,-(sp)
#endif
+TE_B_JMP_OLD:
#if !(defined(M68000) || defined(__mcoldfire__))
jmp ([_old_bios])
#else
@@ -856,6 +924,17 @@
#endif
_trap_14_emu:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s TE_X_68K
+
+ move.w sr,d0
+ move.w d0,-(sp) // return sr
+ move.w #0x4000,-(sp) // format/vector word
+
+ bra.s TE_X_JMP_OLD
+TE_X_68K:
+#endif
#ifdef M68000
tst.w (0x059e).w // test longframe
beq.s TE_X
@@ -870,6 +949,7 @@
#else
move.w sr,-(sp)
#endif
+TE_X_JMP_OLD:
#if !(defined(M68000) || defined(__mcoldfire__))
jmp ([_old_xbios])
#else
@@ -1138,6 +1218,18 @@
// 68000 not tested (with M68000)
//
reentrant_trap:
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s reent_68k
+
+ move.w (a0),d1 // format/vector word
+ addq.l #2+2+4,a0 // skip format/vector word, sr and pc
+ andi.l #0x3000,d1 // keep the filler size bits
+ beq.s reent_fpu
+ addq.l #2,a0 // assume 2-byte filler after the exception frame
+ bra.s reent_fpu
+reent_68k:
+#endif
#ifdef M68000
addq.l #2+4,a0
tst.w (0x59e).w
@@ -1147,6 +1239,7 @@
#else
addq.l #2+4+2,a0
#endif
+reent_fpu:
// Save hardware registers (CPU/FPU)
tst.w _fpu
beq.s reent_fpu_saved
@@ -1357,6 +1450,18 @@
// Since we're not interested in the stack now,
// we wont bother with it. VDI/AES passes args in D0/D1.
#ifdef TRAP2_STACK_PARAMS
+#ifdef __mcoldfire__
+ tst.w _coldfire_68k_emulation
+ bne.s reent2_68k
+
+ move.w (a0),d1 // format/vector word
+ addq.l #2+2+4,a0 // skip format/vector word, sr and pc
+ andi.l #0x3000,d1 // keep the filler size bits
+ beq.s reent2_fpu
+ addq.l #2,a0 // assume 2-byte filler after the exception frame
+ bra.s reent2_fpu
+reent2_68k:
+#endif
#ifdef M68000
addq.l #2+4,a0
tst.w (0x59e).w
@@ -1367,6 +1472,7 @@
addq.l #2+4+2,a0
#endif
#endif
+reent2_fpu:
// Save hardware registers (CPU/FPU)
tst.w _fpu
beq.s reent2_fpu_saved
diff -aurN -x CVS freemint.orig/sys/arch/v4epatch.S freemint/sys/arch/v4epatch.S
--- freemint.orig/sys/arch/v4epatch.S 2007-03-19 22:05:48.000000000 +0100
+++ freemint/sys/arch/v4epatch.S 2012-09-18 23:30:42.937500000 +0200
@@ -1,4 +1,4 @@
-#ifdef COLDFIRE
+#ifdef __mcoldfire__
.data
diff -aurN -x CVS freemint.orig/sys/cookie.c freemint/sys/cookie.c
--- freemint.orig/sys/cookie.c 2012-02-25 09:53:45.218750000 +0100
+++ freemint/sys/cookie.c 2012-09-26 19:45:00.125000000 +0200
@@ -185,20 +185,26 @@
newcookie = (struct cookie *) attach_region (rootproc, newjar_region);
# endif
- /* set the hardware detected CPU and FPU rather
- * than trust the TOS
- */
- TRACE(("_CPU cookie = %08lx", mcpu));
+#ifdef __mcoldfire__
+ /* do not set _CPU and _FPU on native ColdFire */
+ if (coldfire_68k_emulation)
+#endif
+ {
+ /* set the hardware detected CPU and FPU rather
+ * than trust the TOS
+ */
+ TRACE(("_CPU cookie = %08lx", mcpu));
- newcookie[i].tag = COOKIE__CPU;
- newcookie[i].value = mcpu;
- i++;
+ newcookie[i].tag = COOKIE__CPU;
+ newcookie[i].value = mcpu;
+ i++;
- TRACE(("_FPU cookie = %08lx", fputype));
+ TRACE(("_FPU cookie = %08lx", fputype));
- newcookie[i].tag = COOKIE__FPU;
- newcookie[i].value = fputype;
- i++;
+ newcookie[i].tag = COOKIE__FPU;
+ newcookie[i].value = fputype;
+ i++;
+ }
/* We install basic Atari cookies, if these ain't
* there, assuming we're on an old ST.
diff -aurN -x CVS freemint.orig/sys/global.c freemint/sys/global.c
--- freemint.orig/sys/global.c 2012-02-25 09:53:45.234375000 +0100
+++ freemint/sys/global.c 2012-09-16 22:49:20.341298000 +0200
@@ -42,6 +42,9 @@
long mcpu = 0;
long pmmu = 0;
short fpu = 0;
+#ifdef __mcoldfire__
+bool coldfire_68k_emulation = false;
+#endif
short secure_mode = 0;
unsigned long c20ms = 0;
diff -aurN -x CVS freemint.orig/sys/global.h freemint/sys/global.h
--- freemint.orig/sys/global.h 2012-02-25 09:53:45.234375000 +0100
+++ freemint/sys/global.h 2012-09-16 22:53:12.091298000 +0200
@@ -63,6 +63,14 @@
*/
extern short fpu; /* flag if fpu is present */
+#ifdef __mcoldfire__
+/* When true, we have a ColdFire CPU running a 68K emulation layer.
+ * So ColdFire supervisor instructions are not available.
+ * We also have 68K exception stack frames, not native ColdFire ones.
+ */
+extern bool coldfire_68k_emulation;
+#endif
+
/* if this variable is set, then we have "secure mode" enabled; that
* means only the superuser may access some functions those may be
* critical for system security.
diff -aurN -x CVS freemint.orig/sys/memory.c freemint/sys/memory.c
--- freemint.orig/sys/memory.c 2012-03-22 19:56:56.515625000 +0100
+++ freemint/sys/memory.c 2012-09-26 19:49:52.187500000 +0200
@@ -37,8 +37,8 @@
# include "proc.h"
-# ifdef COLDFIRE
-extern void patch_memset_purec(BASEPAGE *b);
+# ifdef __mcoldfire__
+extern void patch_memset_purec(BASEPAGE *b);
# endif
struct screen
@@ -1614,9 +1614,18 @@
DEBUG (("load_region: return region = %lx", reg));
SANITY_CHECK_MAPS ();
-#ifdef COLDFIRE
- patch_memset_purec(b);
+
+#ifdef __mcoldfire__
+ if (coldfire_68k_emulation)
+ {
+ /* Unfortunately, a few 680x0 user instructions can't be
+ * emulated via illegal instruction handler on ColdFire,
+ * so they require to be dynamically patched.
+ */
+ patch_memset_purec(b);
+ }
#endif
+
return reg;
}
diff -aurN -x CVS freemint.orig/sys/xbios.c freemint/sys/xbios.c
--- freemint.orig/sys/xbios.c 2011-06-16 11:25:05.000000000 +0200
+++ freemint/sys/xbios.c 2012-09-18 23:41:19.218750000 +0200
@@ -116,9 +116,6 @@
usrarg3 = arg3;
usrarg4 = arg4;
usrarg5 = arg5;
-#ifdef COLDFIRE
-/* return (*usrcall)((long) usrcall, usrarg1, usrarg2, usrarg3, usrarg4, usrarg5); */
-#endif
SIGACTION(get_curproc(), 0).sa_handler = (long) do_usrcall;
savesr = syscall->sr; /* save old super/user mode flag */
syscall->sr |= 0x2000; /* set supervisor mode */