diff options
Diffstat (limited to 'arch/m68k/kernel/kgdb.c')
-rw-r--r-- | arch/m68k/kernel/kgdb.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/arch/m68k/kernel/kgdb.c b/arch/m68k/kernel/kgdb.c index cdbd250cd..be75defdb 100644 --- a/arch/m68k/kernel/kgdb.c +++ b/arch/m68k/kernel/kgdb.c @@ -189,6 +189,11 @@ #include <asm/amigahw.h> #include <asm/amigaints.h> #endif +#ifdef CONFIG_MAC +#include <linux/tty.h> +#include <asm/bootinfo.h> +#include <asm/macints.h> +#endif #undef DEBUG @@ -239,6 +244,15 @@ static unsigned char atari_scc_intr( void ); extern int amiga_ser_out( unsigned char c ); extern unsigned char amiga_ser_in( void ); #endif +#ifdef CONFIG_MAC +static unsigned char mac_scca_in( void ); +static unsigned char mac_scca_out( unsigned char c ); +static unsigned char mac_scca_intr( void ); +static unsigned char mac_sccb_in( void ); +static unsigned char mac_sccb_out( unsigned char c); +static unsigned char mac_sccb_intr( void ); +extern void mac_init_scc_port( int cflag, int port ); +#endif /************************* End of Prototypes **************************/ @@ -668,6 +682,31 @@ void kgdb_init(void) } #endif +#ifdef CONFIG_MAC + if (MACH_IS_MAC) { + if (!strcmp( m68k_debug_device, "ser" ) || + !strcmp( m68k_debug_device, "ser1" )) { + mac_init_scc_port( B9600|CS8, 0 ); + serial_in = mac_scca_in; + serial_out = mac_scca_out; + serial_intr = mac_scca_intr; + } else if (!strcmp( m68k_debug_device, "ser2" )) { + mac_init_scc_port( B9600|CS8, 1 ); + serial_in = mac_sccb_in; + serial_out = mac_sccb_out; + serial_intr = mac_sccb_intr; + } + } + if (!serial_in || !serial_out) { + if (*m68k_debug_device) + printk( "kgdb_init failed: no valid serial device!\n" ); + else + printk( "kgdb not enabled\n" ); + return; + } + request_irq(4, kgdb_intr, IRQ_TYPE_FAST, "kgdb", NULL); +#endif + #ifdef CONFIG_ATARI if (!serial_in || !serial_out) { if (*m68k_debug_device) @@ -781,8 +820,15 @@ __asm__ /* copy format/vector word */ " movew %a0@("FRAMEOFF_VECTOR"),%a1@("GDBOFF_VECTOR")\n" /* save FPU regs */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" + " jeq 1f\n" +#endif " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n" " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n" + "1:\n" +#endif /* CONFIG_M68KFPU_EMU_ONLY */ /* set stack to CPU frame */ " addl #"FRAMEOFF_SR",%a0\n" @@ -801,8 +847,15 @@ __asm__ /* after return, first restore FPU registers */ " movel #"SYMBOL_NAME_STR(kgdb_registers)",%a0\n" /* source */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" + " jeq 1f\n" +#endif " fmovemx %a0@("GDBOFF_FP0"),%fp0-%fp7\n" " fmoveml %a0@("GDBOFF_FPCTL"),%fpcr/%fpsr/%fpiar\n" + "1:\n" +#endif /* CONFIG_M68KFPU_EMU_ONLY */ /* set new stack pointer */ " movel %a0@("GDBOFF_A7"),%sp\n" " clrw %sp@-\n" /* fake format $0 frame */ @@ -849,8 +902,15 @@ __asm__ /* fake format 0 and vector 1 (translated to SIGINT) */ " movew #4,%a1@("GDBOFF_VECTOR")\n" /* save FPU regs */ +#ifndef CONFIG_M68KFPU_EMU_ONLY +#ifdef CONFIG_M68KFPU_EMU + " tstl "SYMBOL_NAME_STR(m68k_fputype)"\n" + " jeq 1f\n" +#endif " fmovemx %fp0-%fp7,%a1@("GDBOFF_FP0")\n" " fmoveml %fpcr/%fpsr/%fpiar,%a1@("GDBOFF_FPCTL")\n" + "1:\n" +#endif /* CONFIG_M68KFPU_EMU_ONLY */ /* pop off the CPU stack frame */ " addql #8,%sp\n" " movel %sp,%a1@("GDBOFF_A7")\n" /* save a7 now */ @@ -1192,3 +1252,111 @@ static unsigned char atari_scc_intr( void ) } #endif + +/* -------------------- Macintosh serial I/O -------------------- */ + +#ifdef CONFIG_MAC + +struct SCC + { + u_char cha_b_ctrl; + u_char char_dummy1; + u_char cha_a_ctrl; + u_char char_dummy2; + u_char cha_b_data; + u_char char_dummy3; + u_char cha_a_data; + }; + +#define scc (*((volatile struct SCC*)mac_bi_data.sccbase)) + +#define uSEC 1 +#define LONG_DELAY() \ + do { \ + int i; \ + for( i = 60*uSEC; i > 0; --i ) \ + barrier(); \ + } while(0) + +static unsigned char mac_sccb_out (unsigned char c) +{ + int i; + do { + LONG_DELAY(); + } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ + for( i = uSEC; i > 0; --i ) + barrier(); + scc.cha_b_data = c; +} + +static unsigned char mac_scca_out (unsigned char c) +{ + int i; + do { + LONG_DELAY(); + } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ + for( i = uSEC; i > 0; --i ) + barrier(); + scc.cha_a_data = c; +} + +static unsigned char mac_sccb_in( void ) +{ + do { + LONG_DELAY(); + } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ + LONG_DELAY(); + return( scc.cha_b_data ); +} + +static unsigned char mac_scca_in( void ) + +{ + do { + LONG_DELAY(); + } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */ + LONG_DELAY(); + return( scc.cha_a_data ); +} + +static unsigned char mac_sccb_intr( void ) + +{ unsigned char c, stat; + + LONG_DELAY(); + scc.cha_b_ctrl = 1; /* RR1 */ + LONG_DELAY(); + stat = scc.cha_b_ctrl; + LONG_DELAY(); + c = scc.cha_b_data; + LONG_DELAY(); + if (stat & 0x30) { + scc.cha_b_ctrl = 0x30; /* error reset for overrun and parity */ + LONG_DELAY(); + } + scc.cha_b_ctrl = 0x38; /* reset highest IUS */ + LONG_DELAY(); + return( c ); +} + +static unsigned char mac_scca_intr( void ) + +{ unsigned char c, stat; + + LONG_DELAY(); + scc.cha_a_ctrl = 1; /* RR1 */ + LONG_DELAY(); + stat = scc.cha_a_ctrl; + LONG_DELAY(); + c = scc.cha_a_data; + LONG_DELAY(); + if (stat & 0x30) { + scc.cha_a_ctrl = 0x30; /* error reset for overrun and parity */ + LONG_DELAY(); + } + scc.cha_a_ctrl = 0x38; /* reset highest IUS */ + LONG_DELAY(); + return( c ); +} + +#endif |