diff -Nru linux/arch/mips/sibyte/swarm/dbg_io.c.orig linux/arch/mips/sibyte/swarm/dbg_io.c --- linux/arch/mips/sibyte/swarm/dbg_io.c.orig Wed Dec 12 15:21:14 2001 +++ linux/arch/mips/sibyte/swarm/dbg_io.c Thu Dec 13 14:33:59 2001 @@ -0,0 +1,157 @@ +/* + * kgdb debug routines for swarm board. + * + * Copyright (C) 2001 MontaVista Software Inc. + * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + */ + +/* -------------------- BEGINNING OF CONFIG --------------------- */ +#include +#if defined(CONFIG_SMP) +#warn "kgdb is not quite ready for SMP yet!" +#endif + +/* + * We use the second serial port for kgdb traffic. + * 115200, 8, N, 1. + */ + +#define DUART_BASE 0xb0060200 +#define BAUD_RATE 115200 +#define DATA_BITS 8 /* or 7 */ +#define PARITY 0 /* 1: odd, 2: even */ +#define STOP_BITS 1 /* or 2 */ + +static int duart_initialized = 0; /* 0: need to be init'ed by kgdb */ + +/* -------------------- END OF CONFIG --------------------- */ + +#include + +#define MODE1 0x00 +#define MODE2 0x10 +#define STATUS 0x20 +#define CLK_SEL 0x30 +#define CMD 0x50 +#define RX_HOLD 0x60 +#define TX_HOLD 0x70 + +#define VAL_STATUS_RX_RDY (1 << 0) +#define VAL_STATUS_TX_RDY (1 << 2) + +#define duart_out(reg, val) out64(val, DUART_BASE + reg) +#define duart_in(reg) in64(DUART_BASE + reg) + +void putDebugChar(unsigned char c); +unsigned char getDebugChar(void); +static void +duart_init(int baud, int data, int parity, int stop) +{ + unsigned int mode1 = 0; + unsigned int mode2 = 0; + unsigned int clk_divisor; + + /* data */ + switch (data) { + case 8: + break; + case 7: + mode1 |= 2; + break; + default: /* panic */ + break; + } + + /* parity */ + switch (parity) { + case 0: + mode1 |= 2 << 3; + break; + case 1: /* odd */ + mode1 |= 1 << 2; + break; + case 2: /* even */ + break; + default: /* panic */ + break; + } + + /* stop */ + switch (stop) { + case 1: + break; + case 2: + mode2 |= 1 << 3; + default: /* panic */ + break; + } + + /* data */ + switch (baud) { + case 200: + case 300: + case 1200: + clk_divisor = 4095; + break; + case 1800: + clk_divisor = 2776; + break; + case 2400: + clk_divisor = 2082; + break; + case 4800: + clk_divisor = 1040; + break; + case 9600: + clk_divisor = 519; + break; + case 19200: + clk_divisor = 259; + break; + case 38400: + clk_divisor = 129; + break; + case 57600: + clk_divisor = 85; + break; + case 115200: + clk_divisor = 42; + break; + default: /* panic */ + break; + } + + duart_out(MODE1, mode1); + duart_out(MODE2, mode2); + duart_out(CLK_SEL, clk_divisor); + + duart_out(CMD, 1 | (1 << 2)); /* enable rx and tx */ +} + +void +putDebugChar(unsigned char c) +{ + if (!duart_initialized) { + duart_initialized = 1; + duart_init(BAUD_RATE, DATA_BITS, PARITY, STOP_BITS); + } + while ((duart_in(STATUS) & VAL_STATUS_TX_RDY) == 0) ; + duart_out(TX_HOLD, c); +} + +unsigned char +getDebugChar(void) +{ + if (!duart_initialized) { + duart_initialized = 1; + duart_init(BAUD_RATE, DATA_BITS, PARITY, STOP_BITS); + } + while ((duart_in(STATUS) & VAL_STATUS_RX_RDY) == 0) ; + return duart_in(RX_HOLD); +}