diff --git a/src/add-ons/kernel/debugger/Jamfile b/src/add-ons/kernel/debugger/Jamfile index 1e2f1a69de..675e619e47 100644 --- a/src/add-ons/kernel/debugger/Jamfile +++ b/src/add-ons/kernel/debugger/Jamfile @@ -1,5 +1,7 @@ SubDir HAIKU_TOP src add-ons kernel debugger ; SubInclude HAIKU_TOP src add-ons kernel debugger auto_stack_trace ; +SubInclude HAIKU_TOP src add-ons kernel debugger bochs ; SubInclude HAIKU_TOP src add-ons kernel debugger hangman ; SubInclude HAIKU_TOP src add-ons kernel debugger invalidate_on_exit ; +SubInclude HAIKU_TOP src add-ons kernel debugger laplinkll ; diff --git a/src/add-ons/kernel/debugger/bochs/Jamfile b/src/add-ons/kernel/debugger/bochs/Jamfile new file mode 100644 index 0000000000..095b6f5e8d --- /dev/null +++ b/src/add-ons/kernel/debugger/bochs/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src add-ons kernel debugger bochs ; + +UsePrivateHeaders kernel ; + +KernelAddon bochs : + bochs.cpp + ; diff --git a/src/add-ons/kernel/debugger/bochs/bochs.cpp b/src/add-ons/kernel/debugger/bochs/bochs.cpp new file mode 100644 index 0000000000..d7f6a2f68f --- /dev/null +++ b/src/add-ons/kernel/debugger/bochs/bochs.cpp @@ -0,0 +1,70 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol, revol@free.fr + */ + + +#include +#include +#include + +static isa_module_info *sISAModule; + + +static int +debugger_puts(const char *s, int32 length) +{ + int i; + for (i = 0; i < length; i++) + sISAModule->write_io_8(0xe9, s[i]); + return i; +} + + +static status_t +std_ops(int32 op, ...) +{ + void *handle; + bool load = true;//false; + + switch (op) { + case B_MODULE_INIT: + handle = load_driver_settings("kernel"); + if (handle) { + load = get_driver_boolean_parameter(handle, + "bochs_debug_output", load, true); + unload_driver_settings(handle); + } + if (load) { + if (get_module(B_ISA_MODULE_NAME, (module_info **)&sISAModule) < B_OK) + return B_ERROR; + } + return load ? B_OK : B_ERROR; + case B_MODULE_UNINIT: + put_module(B_ISA_MODULE_NAME); + return B_OK; + } + return B_BAD_VALUE; +} + + +static struct debugger_module_info sModuleInfo = { + { + "debugger/bochs/v1", + 0, + &std_ops + }, + NULL, + NULL, + debugger_puts, + NULL +}; + +module_info *modules[] = { + (module_info *)&sModuleInfo, + NULL +}; + diff --git a/src/add-ons/kernel/debugger/laplinkll/Jamfile b/src/add-ons/kernel/debugger/laplinkll/Jamfile new file mode 100644 index 0000000000..24aac22bdc --- /dev/null +++ b/src/add-ons/kernel/debugger/laplinkll/Jamfile @@ -0,0 +1,7 @@ +SubDir HAIKU_TOP src add-ons kernel debugger laplinkll ; + +UsePrivateHeaders kernel ; + +KernelAddon laplinkll : + laplinkll.c + ; diff --git a/src/add-ons/kernel/debugger/laplinkll/laplinkll.cpp b/src/add-ons/kernel/debugger/laplinkll/laplinkll.cpp new file mode 100644 index 0000000000..71d7257c41 --- /dev/null +++ b/src/add-ons/kernel/debugger/laplinkll/laplinkll.cpp @@ -0,0 +1,452 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol, revol@free.fr + * + * Copyright 2005, François Revol. + */ + +/* + Description: Implements a tty on top of the parallel port, + using PLIP-like byte-by-byte protocol. + Low level stuff. +*/ + + +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//XXX: move to Jamfile when adding driver +#define _BUILDING_kernel 1 + +#if _BUILDING_kernel +#include +#endif + +#include "laplinkll.h" + +enum { + st_sync = 0, // syncing... + st_lsb, + st_msb, + st_error +}; + +#pragma mark // raw access + +static inline uint8 read_status(uint32 port) +{ + uint8 val; + val = read_io_8(port+1); + return val; +} + +static inline void write_control(uint32 port, uint8 val) +{ + write_io_8(port+2, val); +} + +static inline void write_data(uint32 port, uint8 val) +{ + write_io_8(port, val); +} + +#pragma mark // framing + +status_t ll_send_sof(laplink_state *st) +{ + uint8 v; + int tries = LPTSOFTRIES; + if (st->rstate != st_sync || st->wstate != st_sync) + return B_TIMED_OUT; + // check for idle bus + if ((read_status(st->port) & 0xf8) != 0x80) + return B_TIMED_OUT; + // raise ACK + write_data(st->port, 0x08); + do { + spin(LPTSPIN); + v = read_status(st->port); + if (st->rstate != st_sync) + return B_TIMED_OUT; + if (tries-- == 0) + return B_TIMED_OUT; + } while (!(v & 0x08)); + st->wstate = st_lsb; + return B_OK; +} + +status_t ll_check_sof(laplink_state *st) +{ + uint8 v; + if (st->rstate != st_sync || st->wstate != st_sync) + return EINTR; + v = read_status(st->port); + if ((v & 0xf8) != 0xc0) + return EINTR; + return B_OK; +} + +status_t ll_ack_sof(laplink_state *st) +{ + write_data(st->port, 0x01); // ack the sof + st->rstate = st_lsb; + return B_OK; +} + +status_t ll_send_eof(laplink_state *st) +{ + /* + if (st->rstate != st_sync || st->wstate != st_sync) + return B_TIMED_OUT; + */ + st->rstate = st_sync; + st->wstate = st_sync; + write_data(st->port, 0x00); + return B_OK; +} + +#pragma mark // nibbles + +status_t ll_send_lnibble(laplink_state *st, uint8 v) +{ + int tries = LPTNIBTRIES; + uint8 s; + if (st->rstate != st_sync) + goto err; + if (st->wstate != st_lsb) + goto err; + write_data(st->port, v & 0x0f); + spin(10); + write_data(st->port, (v & 0x0f) | 0x10); + // wait for ack + do { + s = read_status(st->port); + if (tries-- == 0) + goto err; + spin(LPTSPIN); + } while (s & 0x80); + st->wstate = st_msb; + return B_OK; +err: + st->wstate = st_sync; + return B_TIMED_OUT; +} + +status_t ll_send_mnibble(laplink_state *st, uint8 v) +{ + int tries = LPTNIBTRIES; + uint8 s; + if (st->rstate != st_sync) + goto err; + if (st->wstate != st_msb) + goto err; + write_data(st->port, (v >> 4) | 0x10); + spin(10); + write_data(st->port, (v >> 4)); + // wait for ack + do { + s = read_status(st->port); + if (tries-- == 0) + goto err; + spin(LPTSPIN); + } while (!(s & 0x80)); + st->wstate = st_lsb;//st_sync; + return B_OK; +err: + st->wstate = st_sync; + return B_TIMED_OUT; +} + +status_t ll_wait_lnibble(laplink_state *st, uint8 *v) +{ + int tries = LPTNIBTRIES; + uint8 s; + // wait for data + do { + s = read_status(st->port); + if (tries-- == 0) + goto err; + spin(LPTSPIN); + } while ((s & 0x80) || (s != read_status(st->port))); + // get the nibble + *v = (s >> 3) & 0x0f; + st->rstate = st_msb; + // tell we got that one + write_data(st->port, 0x10); + return B_OK; +err: + st->rstate = st_sync; + return B_TIMED_OUT; +} + +status_t ll_wait_mnibble(laplink_state *st, uint8 *v) +{ + int tries = LPTNIBTRIES; + uint8 s; + // wait for data + do { + s = read_status(st->port); + if (tries-- == 0) + goto err; + spin(LPTSPIN); + } while (!(s & 0x80) || (s != read_status(st->port))); + // get the nibble + *v |= (s << (4-3)) & 0xf0; + st->rstate = st_sync; + // tell we got that one + write_data(st->port, 0x00); + return B_OK; +err: + st->rstate = st_sync; + return B_TIMED_OUT; +} + +#pragma mark // byte mode + +status_t ll_send_byte(laplink_state *st, uint8 v) +{ + status_t err; + err = ll_send_sof(st); + if (!err) + err = ll_send_lnibble(st, v); + if (!err) + err = ll_send_mnibble(st, v); + if (!err) + err = ll_send_eof(st); + return err; +} + +status_t ll_check_byte(laplink_state *st, uint8 *v) +{ + status_t err; + *v = 0; + err = ll_check_sof(st); + if (err) + return err; + err = ll_ack_sof(st); + if (!err) + err = ll_wait_lnibble(st, v); + if (!err) + err = ll_wait_mnibble(st, v); + if (!err) + err = ll_send_eof(st); + return err; +} + +status_t ll_wait_byte(laplink_state *st, uint8 *v) +{ + status_t err; + do { + spin(LPTSPIN); + err = ll_check_byte(st, v); + } while (err < B_OK);// } while (err == B_TIMED_OUT); + return err; +} + +#pragma mark // frame mode + +// unframed +static inline status_t ll_send_byte_uf(laplink_state *st, uint8 v) +{ + status_t err; + err = ll_send_lnibble(st, v); + if (!err) + err = ll_send_mnibble(st, v); + return err; +} + +status_t ll_get_byte_uf(laplink_state *st, uint8 *v) +{ + status_t err; + *v = 0; + err = ll_wait_lnibble(st, v); + if (!err) + err = ll_wait_mnibble(st, v); + return err; +} + +status_t ll_send_frame(laplink_state *st, const uint8 *buff, size_t *len) +{ + status_t err; + uint16 pktlen = *len; + uint8 cksum = 0; + *len = 0; + err = ll_send_sof(st); + if (err) + return err; + err = ll_send_byte_uf(st, pktlen & 0xff); + if (err) + goto err; + err = ll_send_byte_uf(st, pktlen >> 8); + if (err) + goto err; + for (*len = 0; *len < pktlen; (*len)++) { + err = ll_send_byte_uf(st, buff[*len]); + if (err) + goto err; + cksum += buff[*len]; + } + err = ll_send_byte_uf(st, cksum); + if (err) + goto err; + + /*err =*/ ll_send_eof(st); +err: + + if (err) { // back to idle + *len = 0; + ll_send_eof(st); + } + return err; +} + +status_t ll_check_frame(laplink_state *st, uint8 *buff, size_t *len) +{ + status_t err; + uint16 pktlen = 0; + uint16 wanted; + uint8 cksum = 0; + uint8 byte; + int i; + err = ll_check_sof(st); + if (err) + goto err; + err = ll_ack_sof(st); + if (err) + goto err; + // pktlen + err = ll_get_byte_uf(st, &byte); + if (err) + goto err; + pktlen = byte; + err = ll_get_byte_uf(st, &byte); + if (err) + goto err; + pktlen |= byte << 8; + cksum = 0; + /*if (pktlen > *len) { + dprintf("laplink: check_frame: packet truncated from %d to %d\n", pktlen, *len); + }*/ + wanted = MIN(pktlen, *len); + for (*len = 0; (*len < pktlen); (*len)++) { + err = ll_get_byte_uf(st, &byte); + if (err) + goto err; + if (*len < wanted) + buff[*len] = byte; + cksum += byte; + } + err = ll_get_byte_uf(st, &byte); + if (err) + goto err; + /* + if (cksum != byte) { + dprintf("laplink: check_frame: wrong cksum\n"); + }*/ +err: + ll_send_eof(st); + return err; +} + +status_t ll_wait_frame(laplink_state *st, uint8 *buff, size_t *len) +{ + status_t err; + do { + spin(LPTSPIN); + err = ll_check_frame(st, buff, len); + } while (err < B_OK);// } while (err == B_TIMED_OUT); + return err; +} + +#pragma mark // kdebug io handler + +#if _BUILDING_kernel +#define BUFFSZ 256 + +static laplink_state llst; +static char laplink_in_buf[BUFFSZ]; +static char *laplink_in_ptr; +static size_t laplink_in_avail; +static char laplink_out_buf[BUFFSZ]; + + +static status_t debug_init_laplink(void *kernel_settings) +{ + (void)kernel_settings; + llst.port = LPTBASE; + llst.rstate = st_sync; + llst.wstate = st_sync; + laplink_in_ptr = laplink_in_buf; + laplink_in_avail = 0; + return B_OK; +} + +static int debug_write_laplink(int f, const char *buf, int count) +{ + status_t err; + size_t len; + int tries; + int i, prev = 0; + + // fix up CR LF issues... to a local buffer (which will get truncated) + if (count > 1) { + for (i = 0; (i < BUFFSZ-1) && count; i++, buf++, count--) { + if ((*buf == '\n') && (prev != '\r')) + laplink_out_buf[i++] = '\r'; + laplink_out_buf[i] = *buf; + prev = *buf; + } + count = i; + buf = laplink_out_buf; + } + + tries = 5; + do { + len = count; + err = ll_send_frame(&llst, buf, &len); + } while (err && tries--); + if (err) + return 0; + return len; +} + +static int debug_read_laplink(void) +{ + status_t err = B_OK; + while (laplink_in_avail < 1) { + laplink_in_avail = BUFFSZ; + laplink_in_ptr = laplink_in_buf; + err = ll_wait_frame(&llst, laplink_in_buf, &laplink_in_avail); + if (err) + laplink_in_avail = 0; + } + laplink_in_avail--; + return *laplink_in_ptr++; +} + + +kdebug_io_handler laplink_debug_io = { + "laplink", + debug_init_laplink, + debug_write_laplink, + debug_read_laplink, + NULL, + NULL, + NULL +}; + + +#endif + diff --git a/src/add-ons/kernel/debugger/laplinkll/laplinkll.h b/src/add-ons/kernel/debugger/laplinkll/laplinkll.h new file mode 100644 index 0000000000..df0bf7f962 --- /dev/null +++ b/src/add-ons/kernel/debugger/laplinkll/laplinkll.h @@ -0,0 +1,57 @@ +/* + * Copyright 2008, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * François Revol, revol@free.fr + * + * Copyright 2005, François Revol. + */ + +/* + Description: Implements a tty on top of the parallel port, + using PLIP-like byte-by-byte protocol. + Low level stuff. +*/ + + +// LPT1 +#define LPTBASE 0x378 +#define LPTIRQ 7 +#define LPTDONGLE "/dev/misc/dongle/parallel1" +#define LPTSPIN 30 +#define LPTSOFTRIES 1000 +#define LPTNIBTRIES 100 +#define LAPLINK_MAX_FRAME 512 + +typedef struct laplink_state { + int32 port; + int32 irq; + + uint8 rstate; + uint8 wstate; +} laplink_state; + +// framing +extern status_t ll_send_sof(laplink_state *st); +extern status_t ll_check_sof(laplink_state *st); +extern status_t ll_ack_sof(laplink_state *st); +extern status_t ll_send_eof(laplink_state *st); + +// nibbles +extern status_t ll_send_lnibble(laplink_state *st, uint8 v); +extern status_t ll_send_mnibble(laplink_state *st, uint8 v); +extern status_t ll_wait_lnibble(laplink_state *st, uint8 *v); +extern status_t ll_wait_mnibble(laplink_state *st, uint8 *v); + +// byte mode +extern status_t ll_send_byte(laplink_state *st, uint8 v); +extern status_t ll_check_byte(laplink_state *st, uint8 *v); +extern status_t ll_wait_byte(laplink_state *st, uint8 *v); + +// frame mode +extern status_t ll_send_frame(laplink_state *st, const uint8 *buff, size_t *len); +extern status_t ll_check_frame(laplink_state *st, uint8 *buff, size_t *len); +extern status_t ll_wait_frame(laplink_state *st, uint8 *buff, size_t *len); + +