initial push

This commit is contained in:
Bernd Mueller
2026-06-17 13:44:30 +02:00
commit adfd70813f
372 changed files with 146450 additions and 0 deletions

224
m68k/driver/ChangeLog Normal file
View File

@@ -0,0 +1,224 @@
2004-04-24 Bernardo Innocenti <bernie@develer.com>
* bdm.c: Fix CPU32 with ICD cable. Contributed by Aaron J. Grier
<aaron@frye.com>.
2004-04-18 Bernardo Innocenti <bernie@develer.com>
* openbsd/openbsd-bdm.c: Add OpenBSD driver derived from the FreeBSD
driver by an unknown author. Contributed by Aaron J. Grier
<aaron@frye.com>.
2001-12-12 Chris Johns <cjohns@ybertec.com.au>
* bdm.c: ICD step fix from Thomas Andrews (tandrews@mindspring.co.za).
2001-04-15 Chris Johns <cjohns@cybertec.com.au>
* bdm.c: Merged Keith Outwater performance changes into the driver.
2000-11-15 Chris Johns <ccj@acm.org>
* bdm.h:
The driver ver, cpu type and if type ioctls were the wrong size.
* bdm.h: New version.
* bdm.c: Changes to support FreeBSD's memcpy in kernel type operations.
Fixed a bug with return of error codes in the ioctl handler.
2000-09-02 Chris Johns <ccj@acm.org>
* bdm.c: ICD fixes from Alexander Aganichev <aaganichev@hypercom.com>.
* bdm.h: New version.
Fixed ICD spelling. Patch from Alexander Aganichev <aaganichev@hypercom.com>.
2000-08-31 Chris Johns <ccj@acm.org>
* bdm.h: New version.
22000-08-03 Chris Johns <ccj@acm.org>
* bdm.h: New minor version number.
* bdm.c:
Changed the CF ctrl port init value to 0x00. This value is correct.
Merged an IDC patch from Adam Kropelin <akropel1@rochester.rr.com>.
2000-06-27 Chris Johns <ccj@acm.org>
* bdm.c: Changed the control register default value to 0x0f which
allowed the driver to work on a DELL 500MHz Pentium III
machine.
2000-06-25 Chris Johns <ccj@acm.org>
* bdm.h: New version for the CF long reset.
* bdm.c:
Slowed the reset down on the Coldfire. The PLL needs time to up.
2000-05-31 Chris Johns <ccj@acm.org>
* bdm.c, bdm.h: Support for IDC added.
2000-05-27 Chris Johns <ccj@acm.org>
* bdm.c: Change all bdm* functions to bdmDev* to stop clashes
Win9x builds.
2000-05-18 Chris Johns <ccj@acm.org>
* bdm.h: Error bits as shifted values.
New version.
2000-05-17 Chris Johns <ccj@acm.org>
* bdm.c: Moved Coldfire variables in struct BDM for multi port support.
Added Coldfire debug module version detection and then
selection of PST support based on it. Ver B uses PST (5307).
Longer reset delays.
Removed setting the DSI signal to 0 on each bit.
Added support to detect false halt conditions by attempting
to read the PC twice. If you can the target has halted.
The cache is invalidated only if it is enabled.
Debug trace clean ups.
2000-03-30 Chris Johns <ccj@acm.org>
* bdm.h: Added the timeout error code. This is used by the remote
interface.
* bdm.c: Changed the delay in the hardware init for the CPU32.
2000-03-30 Chris Johns <ccj@acm.org>
* Makefile: Added the USE_PST support. Moved to clean OS structure.
* linux-bdm.c: New file.
12000-03-30 Chris Johns <ccj@acm.org>
* bdm.h: Added the timeout error code. This is used by the remote
interface.
* bdm.c: Changed the delay in the hardware init for the CPU32.
1999-10-23 Chris Johns <ccj@acm.org>
* bdm.c:
Remved the Linux specific parts to allow easier OS integration.
* bdm.h: Merged in the SCO changes.
1999-05-25 source <ccj@acm.org>
* Makefile:
It seems that depmod complains about unresolved symbols even
when the driver loads and works properly. I don't know what's
changed in Linux to cause this, but for now just get rid of
the depmod.
1999-03-18 Chris Johns <ccj@acm.org>
* bdm.c: Add support for 2.2.xx kernels.
Fri Jan 15 05:43:55 1999 Chris Johns <ccj@acm.org>
* bdm.c:
Added Coldfire support to invalidate the cache when get status detects
a change of state from running to stopped, or when go or step commands
are issued.
Sat Jan 9 03:04:03 1999 Chris Johns <ccj@acm.org>
* bdm.c: Remove the `sti()' calls in the `bdm_sleep' function.
Tue Jan 5 07:39:40 1999 Chris Johns <ccj@acm.org>
* bdm.h, bdm.c: Merged David Fiddes 5307 bkpt signal hold patch.
Sat Dec 12 04:23:28 1998 Chris Johns <ccj@acm.org>
* bdm.c: Fixed the region control logic in open.
Fixed printing csr.
Extended some of the timeouts in the CF driver.
Fixed some incorrect labels.
Fixed a lock up bug after a bus error.
* bdm.h: New version.
* Makefile: Fixed the modversions.
Sat Oct 31 05:06:15 1998 Chris Johns <ccj@acm.org>
* Makefile: Always over-write the installed header and lib.
* bdm.c: Fixed tabs, and forced the SR to be 16bit.
Sun Oct 18 04:38:00 1998 Chris Johns <ccj@acm.org>
* bdm.c: Added support for generating a bus if no repsonse is
always being returned from the BDM module.
Wed Oct 14 14:32:04 1998 Chris Johns <ccj@acm.org>
* bdm.c: Mask pending interrupts in single-step mode.
Fixed the status handling. It now uses the csr register. It is cached
to handle the fact the status bits are set for only one read.
Wed Oct 14 10:55:33 1998 Chris Johns <ccj@acm.org>
* bdm.c:
Added support for the Coldfire BDM and P&E interface. This has only
been tested inthe 5206.
* bdm.h: Added support for the Coldfire BDM.
* Makefile: Changed the prefix to the default of /usr.
Fri Oct 31 20:58:23 1997 eric <eric@skatter.usask.ca>
* Makefile: Fit into RTEMS distribution.
Thu Aug 21 15:38:28 1997 eric <eric@skatter.usask.ca>
* bdm.c: Fix up error on minor device check in bdm_open.
Remove erroneous comment in init_module.
Improve log messages in init_module.
Wed Jun 11 16:59:06 1997 eric <eric@skatter.usask.ca>
* bdm.c:
Removed code which sent an extra BDM_FILL_CMD for word or byte values.
Cleaned up some formatting.
Wed Feb 19 17:15:06 1997 eric <eric@skatter.usask.ca>
* bdm.c, bdm.h: Add `set debug level' ioctl.
Fri Feb 7 15:10:49 1997 eric <eric@skatter.usask.ca>
* Makefile: Add a single `prefix'.
Make directories if necessary when installing.
* bdm.c: Clean up some debugging messages.
Thu Feb 6 22:08:52 1997 eric <eric@skatter.usask.ca>
* Makefile: Add module installation to install target.
* bdm.c: Don't release ports that have been stolen from another driver.
* bdm.c:
Install driver even if I/O ports are claimed by some other driver.
I don't really like doing this, but the alternative would be to
require that the parallel port (LP) driver be unloaded before
the BDM driver could be loaded.
* bdm.c: More init_module message cleanup.
* bdm.c: Fix up init_module message.
* Makefile, bdm.c, bdm.h: Initial revision

1108
m68k/driver/bdm-cf-pe.c Normal file

File diff suppressed because it is too large Load Diff

946
m68k/driver/bdm-cpu32.c Normal file
View File

@@ -0,0 +1,946 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 1995 W. Eric Norum
* Copyright (C) 1998-2008 Chris Johns
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* 107 North Road
* Saskatoon, Saskatchewan, CANADA
* S7N 5C6
*
* eric@skatter.usask.ca
*
* Coldfire support by:
* Chris Johns
* chris@contemporary.net.au
*
*/
/*
* PD (Eric's) CPU32 Interface
*
* Parallel port bit assignments
*
* Status register (bits 0-2 not used):
* +---+---+---+---+---+---+---+---+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* +---+---+---+---+---+---+---+---+
* | | | | |
* | | | | +--- Target FREEZE line
* | | | | 1 - Target is in background mode
* | | | | 0 - Target is not background mode
* | | | |
* | | | +------- Not used
* | | |
* | | +----------- Serial data from target
* | | 1 - `0' from target
* | | 0 - `1' from target
* | |
* | +--------------- Target power
* | 1 - Target power is ON
* | 0 - Target power is OFF
* |
* +------------------- Target connected
* 1 - Target is connected
* 0 - Target is not connected
*
* Control register (bits 4-7 not used):
* +---+---+---+---+
* | 3 | 2 | 1 | 0 |
* +---+---+---+---+
* | | | |
* | | | +--- Target BKPT* /DSCLK line
* | | | Write 1 - Drive BKPT* /DSCLK line LOW
* | | | Write 0 - Allow BKPT* /DSCLK line to go HIGH
* | | | Allow flip-flop to control BKPT* /DSCLK line
* | | |
* | | +------- Target RESET* line
* | | Write 1 - Force RESET* LOW
* | | Write 0 - Allow monitoring of RESET*
* | | Read 1 - RESET* is LOW
* | | Read 0 - RESET* is HIGH
* | |
* | +----------- Serial data to target
* | Write 0 - Send `0' to target
* | Write 1 - Send `1' to target
* |
* +--------------- Control single-step flip-flop
* Write 1 - Clear flip-flop
* BKPT* /DSCLK is controlled by bit 0.
* Write 0 - Allow flip-flop operation
* Falling edge of IFETCH* /DSI clocks a `1'
* into the flip-flop and drive BKPT* /DSCLK
* LOW, causing a breakpoint.
*/
#define CPU32_PD_SR_CONNECTED (0x80)
#define CPU32_PD_SR_POWERED (0x40)
#define CPU32_PD_SR_DATA_BAR (0x20)
#define CPU32_PD_SR_FROZEN (0x08)
#define CPU32_PD_CR_NOT_SINGLESTEP (0x08)
#define CPU32_PD_CR_DATA (0x04)
#define CPU32_PD_CR_FORCE_RESET (0x02)
#define CPU32_PD_CR_RESET_STATUS (0x02)
#define CPU32_PD_CR_CLOCKBAR_BKPT (0x01)
/*
* ICD interface.
*
* Parallel port bit assignments
*
* Status register
* +---+---+---+---+---+---+---+---+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* +---+---+---+---+---+---+---+---+
* | | | | |
* | | | | +--- Not used
* | | | +------- Not used
* | | +----------- Not used
* | |
* | +--------------- Target FREEZE line
* | 1 - Target is in background mode
* | 0 - Target is not background mode
* |
* +------------------- Serial data from target
* 1 - `0' from target
* 0 - `1' from target
*
* Data register
* +---+---+---+---+---+---+---+---+
* | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
* +---+---+---+---+---+---+---+---+
* | | | | | | | |
* | | | | | | | +--- Serial data to target
* | | | | | | | Write 1: Send 1 to target
* | | | | | | | Write 0: Send 0 to target
* | | | | | | | Signal gets to target, if OE is 1
* | | | | | | | and target is in FREEZE mode
* | | | | | | |
* | | | | | | +------- Clock
* | | | | | | if target in freeze mode, then:
* | | | | | | Write 1: drive BKPT* /DSCLK 1
* | | | | | | Write 0: drive BKPT* /DSCLK 0
* | | | | | |
* | | | | | +----------- BREAK
* | | | | | if target not in freeze mode, then:
* | | | | | Write 0: drive BKPT* /DSCLK 0
* | | | | | line determines single stepping
* | | | | | on leaving BGND mode:
* | | | | | Write 0: do single step
* | | | | | Write 1: continue normally
* | | | | |
* | | | | +--------------- RESET
* | | | | Write 0: pull reset low
* | | | | Write 1: release reset line
* | | | |
* | | | +--- OE
* | | | Write 0 - DSI is tristated
* | | | Write 1 - DSI pin is forced to level of serial data
* | | |
* | | +------- LED
* | | Write 1 - turn on LED
* | | Write 0 - turn off LED
* | |
* | +----------- ERROR
* | Write 0 - BERR output is tristated
* | Write 1 - BERR is pulled low
* |
* +--------------- spare
*/
#define CPU32_ICD_DSI (1 << 0) /* data shift input Host->MCU */
#define CPU32_ICD_DSCLK (1 << 1) /* data shift clock / breakpoint pin */
#define CPU32_ICD_STEP_OUT (1 << 2) /* set low to force breakpoint */
#define CPU32_ICD_RST_OUT (1 << 3) /* set low to force reset on MCU */
#define CPU32_ICD_OE (1 << 4) /* set to a 1 to enable DSI */
#define CPU32_ICD_FORCE_BERR (1 << 6) /* set to a 1 to force BERR on target */
#define CPU32_ICD_FREEZE (1 << 6) /* */
#define CPU32_ICD_DSO (1 << 7) /* */
/*
************************************************************************
* CPU32 for PD/ICD interface support routines *
************************************************************************
*/
/*
* CPU32 system register mapping. See bdm.h for the user values.
*/
static int cpu32_sysreg_map[BDM_REG_VBR + 1] =
{ 0x0, /* BDM_REG_RPC */
0x1, /* BDM_REG_PCC */
0xb, /* BDM_REG_SR */
0xc, /* BDM_REG_USP */
0xd, /* BDM_REG_SSP */
0xe, /* BDM_REG_SFC */
0xf, /* BDM_REG_DFC */
0x8, /* BDM_REG_ATEMP */
0x9, /* BDM_REG_FAR */
0xa /* BDM_REG_VBR */
};
/* need by cpu32_read_sysreg() */
static int cpu32_write_sysreg (struct BDM *self, struct BDMioctl *ioc, int mode);
static int cpu32_icd_stop_chip (struct BDM *self);
/*
* Clock a word to/from the target
*/
static int
cpu32_serial_clock (struct BDM *self, unsigned short wval, int holdback)
{
return (self->serial_clock) (self, wval, holdback);
}
/*
* Get target status
*/
static int
cpu32_pd_get_status (struct BDM *self)
{
unsigned char sr = inb (self->statusPort);
int ret;
if (!(sr & CPU32_PD_SR_CONNECTED))
ret = BDM_TARGETNC;
else if (!(sr & CPU32_PD_SR_POWERED))
ret = BDM_TARGETPOWER;
else
ret = (sr & CPU32_PD_SR_FROZEN ? BDM_TARGETSTOPPED : 0) |
(inb (self->controlPort) & CPU32_PD_CR_RESET_STATUS ? BDM_TARGETRESET : 0);
if (self->debugFlag > 1)
PRINTF (" cpu32_pd_get_status -- Status Port:0x%02x Status:0x%04x\n",
sr, ret);
return ret;
}
/*
* Hardware initialization
*/
static int
cpu32_pd_init_hardware (struct BDM *self)
{
int status;
/*
* Force breakpoint
*/
outb (CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (100);
outb (CPU32_PD_CR_FORCE_RESET | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
bdm_sleep (HZ / 100);
outb (CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (10);
outb (CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (100);
status = cpu32_pd_get_status (self);
if (self->debugFlag)
PRINTF (" cpu32_pd_init_hardware: status:0x%02x control port:0x%02x\n",
status, inb (self->controlPort));
return status;
}
/*
* Clock a word to/from the target
*/
static int
cpu32_pd_serial_clock (struct BDM *self, unsigned short wval, int holdback)
{
unsigned long shiftRegister;
unsigned char dataBit;
unsigned int counter;
unsigned int status = cpu32_pd_get_status (self);
if (status & BDM_TARGETRESET)
return BDM_FAULT_RESET;
if (status & BDM_TARGETNC)
return BDM_FAULT_CABLE;
if (status & BDM_TARGETPOWER)
return BDM_FAULT_POWER;
shiftRegister = wval;
counter = 17 - holdback;
while (counter--) {
dataBit = ((shiftRegister & 0x10000) ? CPU32_PD_CR_DATA : 0);
shiftRegister <<= 1;
outb (dataBit | CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT,
self->controlPort);
bdm_delay (self->delayTimer + 1);
if ((inb (self->statusPort) & CPU32_PD_SR_DATA_BAR) == 0)
shiftRegister |= 1;
outb (dataBit | CPU32_PD_CR_NOT_SINGLESTEP, self->controlPort);
bdm_delay ((self->delayTimer >> 1) + 1);
}
self->readValue = shiftRegister & 0x1FFFF;
if (self->debugFlag)
PRINTF (" cpu32_pd_serial_clock -- send 0x%05x receive 0x%05x\n",
wval, self->readValue);
if (self->readValue & 0x10000) {
if (self->readValue == 0x10001)
return BDM_FAULT_BERR;
else if (self->readValue != 0x10000)
return BDM_FAULT_NVC;
}
return 0;
}
/*
* Restart chip and stop on first instruction fetch
*/
static int
cpu32_pd_restart_chip (struct BDM *self)
{
int check;
if (self->debugFlag)
PRINTF (" cpu32_pd_restart_chip\n");
outb (CPU32_PD_CR_FORCE_RESET | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (10);
outb (CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (10);
outb (CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
for (check = 0 ; check < 1000 ; check++) {
if (inb (self->statusPort) & CPU32_PD_SR_FROZEN)
return 0;
}
return BDM_FAULT_RESPONSE;
}
/*
* Restart chip and disable background debugging mode
*/
static int
cpu32_pd_release_chip (struct BDM *self)
{
if (self->debugFlag)
PRINTF (" cpu32_pd_release_chip\n");
outb (CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_FORCE_RESET, self->controlPort);
udelay (10);
outb (CPU32_PD_CR_NOT_SINGLESTEP, self->controlPort);
return 0;
}
/*
* Restart chip, enable background debugging mode, halt on first fetch
*
* The software from the Motorola BBS tries to have the target
* chip begin execution, but that doesn't work very reliably.
* The RESETH* line rises rather slowly, so sometimes the BKPT* / DSCLK
* would be seen low, and sometimes it wouldn't.
*/
static int
cpu32_pd_reset_chip (struct BDM *self)
{
if (self->debugFlag)
PRINTF (" cpu32_pd_reset_chip\n");
outb (CPU32_PD_CR_CLOCKBAR_BKPT | CPU32_PD_CR_FORCE_RESET,
self->controlPort);
udelay (10);
outb (CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
udelay (10);
outb (CPU32_PD_CR_CLOCKBAR_BKPT | CPU32_PD_CR_NOT_SINGLESTEP,
self->controlPort);
return 0;
}
/*
* Force the target into background debugging mode
*/
static int
cpu32_pd_stop_chip (struct BDM *self)
{
int check;
if (self->debugFlag)
PRINTF (" cpu32_pd_stop_chip\n");
if (inb (self->statusPort) & CPU32_PD_SR_FROZEN)
return 0;
outb (CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT,
self->controlPort);
for (check = 0 ; check < 1000 ; check++) {
if (inb (self->statusPort) & CPU32_PD_SR_FROZEN)
return 0;
}
return BDM_FAULT_RESPONSE;
}
/*
* Make the target execute a single instruction and
* reenter background debugging mode
*/
static int
cpu32_pd_step_chip (struct BDM *self)
{
int check;
unsigned char dataBit;
int err;
if (self->debugFlag)
PRINTF (" cpu32_pd_step_chip\n");
err = cpu32_serial_clock (self, BDM_GO_CMD, 1);
if (err)
return err;
/*
* Send the last bit of the command
*/
dataBit = (BDM_GO_CMD & 0x1) ? CPU32_PD_CR_DATA : 0;
outb (dataBit | CPU32_PD_CR_NOT_SINGLESTEP | CPU32_PD_CR_CLOCKBAR_BKPT,
self->controlPort);
bdm_delay (self->delayTimer + 1);
/*
* Enable single-step
*/
outb (dataBit | CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
bdm_delay (1);
outb (dataBit, self->controlPort);
/*
* Wait for step to complete
* The software from the Motorola BBS doesn't do this, but
* omitting the `outb' operation leaves a race condition the
* next time cpu32_serial_clock is called.
*
* The first output operation in bdmSerialClock sends
* `dataBit | CPU32_CR_NOT_SINGLESTEP | CPU32_CR_CLOCKBAR_BKPT' to the
* control port. If the flip flop in the external circuit
* clears before the `CPU32_CR_CLOCKBAR_BKPT' pin of the '132 goes
* low, there is a narrow glitch on the BKPT* / DSCLK pin, which
* clocks a garbage bit into the target chip.
*/
for (check = 0 ; check < 1000 ; check++) {
if (inb (self->statusPort) & CPU32_PD_SR_FROZEN) {
outb (CPU32_PD_CR_CLOCKBAR_BKPT, self->controlPort);
return 0;
}
}
return BDM_FAULT_RESPONSE;
}
/*
* Get target status
*/
static int
cpu32_icd_get_status (struct BDM *self)
{
unsigned char sr = inb (self->statusPort);
int ret;
ret = sr & CPU32_ICD_FREEZE ? BDM_TARGETSTOPPED : 0;
if (self->debugFlag > 1)
PRINTF (" cpu32_icd_get_status -- Status Port:0x%02x Status:0x%04x\n",
sr, ret);
return ret;
}
/*
* Hardware initialization
*/
static int
cpu32_icd_init_hardware (struct BDM *self)
{
int status;
/*
* Force breakpoint
*/
outb (CPU32_ICD_STEP_OUT | CPU32_ICD_DSCLK | CPU32_ICD_RST_OUT, self->dataPort);
udelay (10);
status = cpu32_icd_get_status (self);
if (self->debugFlag)
PRINTF (" cpu32_icd_init_hardware: status:0x%02x, data port:0x%02x\n",
status, inb (self->dataPort));
return status;
}
/*
* Clock a word to/from the target
*/
static int
cpu32_icd_serial_clock (struct BDM *self, unsigned short wval, int holdback)
{
unsigned long shiftRegister;
unsigned char dataBit;
unsigned int counter;
unsigned int status = cpu32_icd_get_status (self);
if (status & BDM_TARGETRESET)
return BDM_FAULT_RESET;
if (status & BDM_TARGETNC)
return BDM_FAULT_CABLE;
if (status & BDM_TARGETPOWER)
return BDM_FAULT_POWER;
if(!(status & BDM_TARGETSTOPPED)) {
if (self->debugFlag)
PRINTF (" cpu32_icd_serial_clock -- stop target first\n");
if (cpu32_icd_stop_chip (self) == BDM_FAULT_RESPONSE) {
if (self->debugFlag)
PRINTF (" cpu32_icd_serial_clock -- can\'t stop it\n");
return BDM_FAULT_RESPONSE;
}
}
shiftRegister = wval;
counter = 17 - holdback;
while (counter--) {
dataBit = ((shiftRegister & 0x10000) ? CPU32_ICD_DSI : 0);
shiftRegister <<= 1;
outb (dataBit | CPU32_ICD_RST_OUT | CPU32_ICD_OE | CPU32_ICD_STEP_OUT,
self->dataPort);
bdm_delay (self->delayTimer + 1);
if ((inb (self->statusPort) & CPU32_ICD_DSO) == 0)
shiftRegister |= 1;
outb (dataBit | CPU32_ICD_RST_OUT | CPU32_ICD_OE | CPU32_ICD_STEP_OUT | CPU32_ICD_DSCLK,
self->dataPort);
bdm_delay ((self->delayTimer >> 1) + 1);
}
if (holdback == 0) {
outb (CPU32_ICD_RST_OUT | CPU32_ICD_STEP_OUT | CPU32_ICD_DSCLK,
self->dataPort);
bdm_delay (self->delayTimer + 1);
}
outb (CPU32_ICD_RST_OUT | CPU32_ICD_STEP_OUT | CPU32_ICD_DSCLK,
self->dataPort);
self->readValue = shiftRegister & 0x1FFFF;
if (self->debugFlag)
PRINTF (" cpu32_icd_serial_clock -- send 0x%05x, receive 0x%05x\n",
wval, self->readValue);
if (self->readValue & 0x10000) {
if (self->readValue == 0x10001)
return BDM_FAULT_BERR;
else if (self->readValue != 0x10000)
return BDM_FAULT_NVC;
}
return 0;
}
/*
* Force the target into background debugging mode
*/
static int
cpu32_icd_stop_chip (struct BDM *self)
{
int check;
int pass;
if (self->debugFlag)
PRINTF (" cpu32_icd_stop_chip: ");
/* if FREEZE is already high, we're stopped and we're done here */
if (inb (self->statusPort) & CPU32_ICD_FREEZE) {
if (self->debugFlag)
PRINTF ("already stopped\n");
return 0;
}
/* try multiple times... */
for (pass = 0; pass < 14; pass++) {
/* even times, simply assert DSCLK and RESET */
if (pass%2 == 0) {
outb (CPU32_ICD_DSCLK | CPU32_ICD_RST_OUT, self->dataPort);
}
/* odd times, yank BERR as well, in case the target is wedged */
else {
outb (CPU32_ICD_DSCLK | CPU32_ICD_RST_OUT | CPU32_ICD_FORCE_BERR,
self->dataPort);
}
/* now hang around and wait for the freeze line to come up
* XXX we're depending on a nop loop for timing? arrrgh!
*/
for (check = 0 ; check < (1000 + ((pass+1)%2) * 9000) ; check++) {
if (inb (self->statusPort) & CPU32_ICD_FREEZE) {
/* if freeze line is high we're OK
* XXX let reset go too?
*/
if (self->debugFlag)
PRINTF("stopped after %d bdm_delays\n", check);
outb (CPU32_ICD_RST_OUT, self->dataPort);
return 0;
}
bdm_delay (10);
}
}
/* we've failed... */
outb (CPU32_ICD_RST_OUT, self->dataPort);
if (self->debugFlag)
PRINTF("failed!\n");
return BDM_FAULT_RESPONSE;
}
/*
* Restart chip and stop on first instruction fetch
*/
static int
cpu32_icd_restart_chip (struct BDM *self)
{
if (self->debugFlag)
PRINTF (" cpu32_icd_restart_chip\n");
outb (CPU32_ICD_DSCLK, self->dataPort);
udelay (1);
return cpu32_icd_stop_chip (self);
}
/*
* Restart chip and disable background debugging mode
*/
static int
cpu32_icd_release_chip (struct BDM *self)
{
if (self->debugFlag)
PRINTF (" cpu32_icd_release_chip\n");
outb (CPU32_ICD_DSCLK | CPU32_ICD_STEP_OUT, self->dataPort);
udelay (10);
outb (CPU32_ICD_DSCLK | CPU32_ICD_RST_OUT | CPU32_ICD_STEP_OUT, self->dataPort);
udelay (10);
return 0;
}
/*
* Restart chip, enable background debugging mode, halt on first fetch
*
* The software from the Motorola BBS tries to have the target
* chip begin execution, but that doesn't work very reliably.
* The RESETH* line rises rather slowly, so sometimes the BKPT* / DSCLK
* would be seen low, and sometimes it wouldn't.
*/
static int
cpu32_icd_reset_chip (struct BDM *self)
{
if (self->debugFlag)
PRINTF (" cpu32_icd_reset_chip\n");
/*
* Assert RESET*, BKPT*, and BREAK*
*/
outb (0, self->dataPort);
udelay (100);
/*
* Deassert RESET (CPU must see BKPT* asserted at rising edge of RESET*)
* Leaving BKPT* and BREAK* asserted gets us ready for first data txfer
* as per Figure 7-8 in CPU32RM/AD
*/
outb (CPU32_ICD_RST_OUT, self->dataPort);
udelay (100);
return 0;
}
/*
* Make the target execute a single instruction and
* reenter background debugging mode
*/
static int
cpu32_icd_step_chip (struct BDM *self)
{
unsigned char dataBit;
int err;
if (self->debugFlag)
PRINTF (" cpu32_step_chip\n");
err = cpu32_serial_clock (self, BDM_GO_CMD, 1);
if (err)
return err;
/*
* Send the last bit of the command
*/
dataBit = (BDM_GO_CMD & 0x1) ? CPU32_ICD_DSI : 0;
outb (dataBit | CPU32_ICD_OE | CPU32_ICD_STEP_OUT | CPU32_ICD_RST_OUT,
self->dataPort);
bdm_delay (self->delayTimer + 1);
outb (dataBit | CPU32_ICD_OE | CPU32_ICD_RST_OUT, self->dataPort);
bdm_delay (1);
/* Raise CPU32_ICD_DSCLK before dropping CPU32_ICD_OEA */
outb (CPU32_ICD_DSCLK | CPU32_ICD_OE | CPU32_ICD_RST_OUT, self->dataPort);
bdm_delay (1);
outb (CPU32_ICD_DSCLK | CPU32_ICD_RST_OUT, self->dataPort);
return cpu32_icd_stop_chip (self);
}
/*
* Read system register
*/
static int
cpu32_read_sysreg (struct BDM *self, struct BDMioctl *ioc, int mode)
{
int err, cmd;
unsigned short msw, lsw;
/*
* CPU32 MBAR require sfc support, make it look like
* a register.
*/
if (ioc->address == BDM_REG_MBAR) {
struct BDMioctl mbar_ioc;
unsigned long sfc;
mbar_ioc.address = BDM_REG_SFC;
if ((err = cpu32_read_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
sfc = mbar_ioc.value;
mbar_ioc.address = BDM_REG_SFC;
mbar_ioc.value = 7;
if ((err = cpu32_write_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
mbar_ioc.address = 0x3FF00;
if ((err = bdmDrvReadLongWord (self, &mbar_ioc)) < 0)
return err;
ioc->value = mbar_ioc.value;
mbar_ioc.address = BDM_REG_SFC;
mbar_ioc.value = sfc;
if ((err = cpu32_write_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
return 0;
}
if (ioc->address > BDM_REG_VBR)
return BDM_FAULT_NVC;
if (mode != BDM_SYS_REG_MODE_MAPPED)
cmd = ioc->address & 0xffff;
else
cmd = cpu32_sysreg_map[ioc->address];
if (cmd == -1) {
ioc->value = 0;
if (self->debugFlag)
PRINTF (" cpu32_read_sysreg - Reg(%d):0x%x is not mapped; ignored\n",
mode, ioc->address);
return 0;
}
cmd |= BDM_RSREG_CMD;
if (((err = cpu32_serial_clock (self, cmd, 0)) != 0) ||
((err = bdmBitBashFetchWord (self, &msw)) != 0) ||
((err = bdmBitBashFetchWord (self, &lsw)) != 0))
return err;
ioc->value = (msw << 16) | lsw;
return 0;
}
/*
* Write system register
*/
static int
cpu32_write_sysreg (struct BDM *self, struct BDMioctl *ioc, int mode)
{
int err, cmd;
/*
* CPU32 MBAR require dfc support, make it look like
* a register.
*/
if (ioc->address == BDM_REG_MBAR) {
struct BDMioctl mbar_ioc;
unsigned long dfc;
mbar_ioc.address = BDM_REG_DFC;
if ((err = cpu32_read_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
dfc = mbar_ioc.value;
mbar_ioc.address = BDM_REG_DFC;
mbar_ioc.value = 7;
if ((err = cpu32_write_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
mbar_ioc.address = 0x3FF00;
mbar_ioc.value = ioc->value;
if ((err = bdmDrvWriteLongWord (self, &mbar_ioc)) < 0)
return err;
mbar_ioc.address = BDM_REG_DFC;
mbar_ioc.value = dfc;
if ((err = cpu32_write_sysreg (self, &mbar_ioc,
BDM_SYS_REG_MODE_MAPPED)) < 0)
return err;
return 0;
}
if (ioc->address > BDM_REG_VBR)
return BDM_FAULT_NVC;
if (mode != BDM_SYS_REG_MODE_MAPPED)
cmd = ioc->address & 0xffff;
else
cmd = cpu32_sysreg_map[ioc->address];
cmd = BDM_WSREG_CMD;
if (((err = cpu32_serial_clock (self, cmd, 0)) != 0) ||
((err = cpu32_serial_clock (self, ioc->value >> 16, 0)) != 0) ||
((err = cpu32_serial_clock (self, ioc->value, 0)) != 0))
return err;
return 0;
}
/*
* Generate a bus error for the ICD interface
*/
static int
cpu32_icd_gen_bus_error (struct BDM *self)
{
if (self->debugFlag)
PRINTF(" cpu32_icd_gen_bus_error\n");
outb (CPU32_ICD_FORCE_BERR | CPU32_ICD_RST_OUT, self->dataPort);
udelay (400);
outb (CPU32_ICD_RST_OUT, self->dataPort);
return BDM_FAULT_BERR;
}
/*
* Generate a bus error as the access has failed. This is
* not supported on the CPU32 with PD interface.
* (the 7-chip PD interface generates it automatically in hardware
*/
static int
cpu32_gen_bus_error (struct BDM *self)
{
if (self->debugFlag > 1)
PRINTF(" cpu32_gen_bus_error\n");
return 0;
}
/*
* Restart target execution
*/
static int
cpu32_run_chip (struct BDM *self)
{
return cpu32_serial_clock (self, BDM_GO_CMD, 0);
}
#ifdef BDM_BIT_BASH_PORT
/*
* Bit Bash the BDM port. No status checks. I assume you know what is happening at
* a low level with the BDM hardware if you are using this interface.
*/
static int
cpu32_bit_bash (struct BDM *self, unsigned short mask, unsigned short bits)
{
unsigned char ctrl_port = 0;
if (self->debugFlag)
PRINTF (" cpu32_bit_bash: mask=%04x, bits=%04x\n", mask, bits);
self->bit_bash_bits &= ~mask;
self->bit_bash_bits |= bits;
if (self->bit_bash_bits & BDM_BB_RESET)
ctrl_port |= CPU32_CR_FORCE_RESET;
if ((self->bit_bash_bits & BDM_BB_BKPT) == 0)
ctrl_port |= CPU32_CR_CLOCKBAR_BKPT;
return 0;
}
#endif
/*
* Initialise the BDM structure for a CPU32
*/
static int
cpu32_pd_init_self (struct BDM *self)
{
int reg;
self->processor = BDM_CPU32;
self->interface = BDM_CPU32_ERIC;
self->get_status = cpu32_pd_get_status;
self->init_hardware = cpu32_pd_init_hardware;
self->serial_clock = cpu32_pd_serial_clock;
self->gen_bus_error = cpu32_gen_bus_error;
self->read_sysreg = cpu32_read_sysreg;
self->write_sysreg = cpu32_write_sysreg;
self->restart_chip = cpu32_pd_restart_chip;
self->release_chip = cpu32_pd_release_chip;
self->reset_chip = cpu32_pd_reset_chip;
self->stop_chip = cpu32_pd_stop_chip;
self->run_chip = cpu32_run_chip;
self->step_chip = cpu32_pd_step_chip;
#ifdef BDM_BIT_BASH_PORT
self->bit_bash = cpu32_bit_bash;
self->bit_bash_bits = 0;
#endif
for (reg = 0; reg < BDM_MAX_SYSREG; reg++)
self->shadow_sysreg[reg] = 0;
return 0;
}
static int
cpu32_icd_init_self (struct BDM *self)
{
int reg;
self->processor = BDM_CPU32;
self->interface = BDM_CPU32_ICD;
self->get_status = cpu32_icd_get_status;
self->init_hardware = cpu32_icd_init_hardware;
self->serial_clock = cpu32_icd_serial_clock;
self->gen_bus_error = cpu32_icd_gen_bus_error;
self->restart_chip = cpu32_icd_restart_chip;
self->release_chip = cpu32_icd_release_chip;
self->reset_chip = cpu32_icd_reset_chip;
self->stop_chip = cpu32_icd_stop_chip;
self->run_chip = cpu32_run_chip;
self->step_chip = cpu32_icd_step_chip;
self->fill_buf = bdmBitBashFillBuf;
self->send_buf = bdmBitBashSendBuf;
self->read_sysreg = cpu32_read_sysreg;
self->read_proreg = bdmBitBashReadProcessorRegister;
self->read_long_word = bdmBitBashReadLongWord;
self->read_word = bdmBitBashReadWord;
self->read_byte = bdmBitBashReadByte;
self->write_sysreg = cpu32_write_sysreg;
self->write_proreg = bdmBitBashWriteProcessorRegister;
self->write_long_word = bdmBitBashWriteLongWord;
self->write_word = bdmBitBashWriteWord;
self->write_byte = bdmBitBashWriteByte;
#ifdef BDM_BIT_BASH_PORT
self->bit_bash = cpu32_bit_bash;
self->bit_bash_bits = 0;
#endif
for (reg = 0; reg < BDM_MAX_SYSREG; reg++)
self->shadow_sysreg[reg] = 0;
return 0;
}

1100
m68k/driver/bdm-tblcf.c Normal file

File diff suppressed because it is too large Load Diff

1392
m68k/driver/bdm.c Normal file

File diff suppressed because it is too large Load Diff

268
m68k/driver/bdm.h Normal file
View File

@@ -0,0 +1,268 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 1995 W. Eric Norum
* Copyright (C) 1998 Chris Johns
*
* Based on:
* 1. `A Background Debug Mode Driver Package for Motorola's
* 16- and 32-Bit Microcontrollers', Scott Howard, Motorola
* Canada, 1993.
* 2. `Linux device driver for public domain BDM Interface',
* M. Schraut, Technische Universitaet Muenchen, Lehrstuhl
* fuer Prozessrechner, 1995.
*
* Extended to support the ColdFire BDM interface using the P&E
* module which comes with the EVB. Currently only tested with the
* 5206 (5V) device.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* 107 North Road
* Saskatoon, Saskatchewan, CANADA
* S7N 5C6
*
* eric@skatter.usask.ca
*
* Coldfire support by:
* Chris Johns
* chris@contemporary.net.au
*
*/
#ifndef _BDM_H_
#define _BDM_H_
/*
* Version of the driver.
*/
#define BDM_DRV_VERSION 0x020d
/*
* Hook for Linux kernel
*/
#define BDM_MAJOR_NUMBER 34
/*
* Allocation of the minor numbers. The number of minors per interface
* must be a factor of 2.
*/
#define BDM_MINORS_PER_IFACE 4
#define BDM_IFACE_MINOR(m) (m & (BDM_MINORS_PER_IFACE - 1))
#define BDM_IFACE(m) (m / BDM_MINORS_PER_IFACE)
#define BDM_NUM_OF_MINORS (BDM_NUM_OF_IFACES * BDM_MINORS_PER_IFACE)
/*
* Processors
*/
#define BDM_CPU32 0
#define BDM_COLDFIRE 1
/*
* Interfaces, used of offset the major number.
*/
#define BDM_CPU32_ERIC 0
#define BDM_CPU32_PD BDM_CPU32_ERIC
#define BDM_COLDFIRE_PE 1
#define BDM_CPU32_ICD 2
#define BDM_COLDFIRE_TBLCF 3
#define BDM_NUM_OF_IFACES 4 /* last */
/*
* Error codes
*/
#define BDM_FAULT_UNKNOWN 210
#define BDM_FAULT_POWER 211
#define BDM_FAULT_CABLE 212
#define BDM_FAULT_RESPONSE 213
#define BDM_FAULT_RESET 214
#define BDM_FAULT_PORT 215
#define BDM_FAULT_BERR 216
#define BDM_FAULT_NVC 217
#define BDM_FAULT_TIMEOUT 218
#define BDM_FAULT_FORCED_TA 219
/*
* Structure for I/O requests
* Address and value are in host-endian order
*/
struct BDMioctl {
unsigned long int address;
unsigned long int value;
};
/*
* The ioctl codes. If these change insure the remote client and server
* interfaces are kept in sync. Assumes Cygwin does not define Win32.
*/
#if !defined (_IO)
#if defined (__WIN32__)
#include <winsock2.h>
#else
#include <sys/ioctl.h>
#endif
#endif
/*
* If the OS does not provide any ioctl support as found on
* some Unix systems then provide something.
*/
#if !defined (_IO)
#undef _IOR
#undef _IOW
#undef _IOWR
#define _IO(x,y) ((x<<8)|y|0x00000)
#define _IOR(x,y,t) ((x<<8)|y|0x10000)
#define _IOW(x,y,t) ((x<<8)|y|0x20000)
#define _IOWR(x,y,t) ((x<<8)|y|0x30000)
#endif
#if !defined (_IOWR)
#if !defined (IOC_OUTIN)
#define IOC_OUTIN 0x10000000 /* copy in parameters */
#endif
#define _IOWR(x,y,t) (IOC_OUTIN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
#endif
#define BDM_INIT _IO('B', 0)
#define BDM_RESET_CHIP _IO('B', 1)
#define BDM_RESTART_CHIP _IO('B', 2)
#define BDM_STOP_CHIP _IO('B', 3)
#define BDM_STEP_CHIP _IO('B', 4)
#define BDM_GET_STATUS _IOR('B', 5, int)
#define BDM_SPEED _IOW('B', 6, int)
#define BDM_DEBUG _IOW('B', 7, int)
#define BDM_RELEASE_CHIP _IO('B', 8)
#define BDM_GO _IO('B', 9)
/*
* Input/output requests
*/
/*
* Addition for general register access.
*
* Note, the control and debug registers has been added at the start
* so the other allocated number do not change.
*/
#define BDM_READ_CTLREG _IOWR('B', 16, struct BDMioctl)
#define BDM_WRITE_CTLREG _IOW('B', 17, struct BDMioctl)
#define BDM_READ_DBREG _IOWR('B', 18, struct BDMioctl)
#define BDM_WRITE_DBREG _IOW('B', 19, struct BDMioctl)
#define BDM_READ_REG _IOWR('B', 20, struct BDMioctl)
#define BDM_READ_SYSREG _IOWR('B', 21, struct BDMioctl)
#define BDM_READ_LONGWORD _IOWR('B', 22, struct BDMioctl)
#define BDM_READ_WORD _IOWR('B', 23, struct BDMioctl)
#define BDM_READ_BYTE _IOWR('B', 24, struct BDMioctl)
#define BDM_WRITE_REG _IOW('B', 25, struct BDMioctl)
#define BDM_WRITE_SYSREG _IOW('B', 26, struct BDMioctl)
#define BDM_WRITE_LONGWORD _IOW('B', 27, struct BDMioctl)
#define BDM_WRITE_WORD _IOW('B', 28, struct BDMioctl)
#define BDM_WRITE_BYTE _IOW('B', 29, struct BDMioctl)
/*
* Detect the driver version, processor or interface type
*/
#define BDM_GET_DRV_VER _IOR('B', 30, int)
#define BDM_GET_CPU_TYPE _IOR('B', 31, int)
#define BDM_GET_IF_TYPE _IOR('B', 32, int)
/*
* Coldfire specific call to control the use of the
* PST signals. This is only needed on 5206e targets that
* use the PST signals for IO.
*/
#define BDM_GET_CF_PST _IOR('B', 33, int)
#define BDM_SET_CF_PST _IOR('B', 34, int)
/*
* bits in status word returned by BDM_GET_STATUS ioctl
*/
#define BDM_TARGETRESET (1 << 0) /* Target reset */
#define BDM_TARGETHALT (1 << 1) /* Target halt */
#define BDM_TARGETSTOPPED (1 << 2) /* Target stopped */
#define BDM_TARGETPOWER (1 << 3) /* Power failed */
#define BDM_TARGETNC (1 << 4) /* Target not connected */
/*
* Register codes for BDM_READ_SYSREG/BDM_WRITE_SYSREG ioctls
*
* These are the control and debug registers for the CPU32 and
* Coldfire processor.
*
* These are ony logical numbers not the actual registers values used
* on the BDM port. The driver maps these to the correct command and
* register pair .
*
* Using only the one call keeps the changes to Eric's library and gdb
* code to a minimum.
*
* The WR only registers are shadowed in the driver.
*/
#define BDM_REG_RPC 0x0 /* CPU32, Coldfire */
#define BDM_REG_PCC 0x1 /* CPU32 */
#define BDM_REG_SR 0x2 /* CPU32, Coldfire */
#define BDM_REG_USP 0x3 /* CPU32 */
#define BDM_REG_SSP 0x4 /* CPU32 */
#define BDM_REG_SFC 0x5 /* CPU32 */
#define BDM_REG_DFC 0x6 /* CPU32 */
#define BDM_REG_ATEMP 0x7 /* CPU32 */
#define BDM_REG_FAR 0x8 /* CPU32 */
#define BDM_REG_VBR 0x9 /* CPU32, Coldfire */
#define BDM_REG_CACR 0xa /* Coldfire */
#define BDM_REG_ACR0 0xb /* Coldfire */
#define BDM_REG_ACR1 0xc /* Coldfire */
#define BDM_REG_RAMBAR 0xd /* Coldfire */
#define BDM_REG_MBAR 0xe /* Coldfire */
#define BDM_REG_CSR 0xf /* Coldfire */
#define BDM_REG_AATR 0x10 /* WR only, Coldfire */
#define BDM_REG_TDR 0x11 /* WR only, Coldfire */
#define BDM_REG_PBR 0x12 /* WR only, Coldfire */
#define BDM_REG_PBMR 0x13 /* WR only, Coldfire */
#define BDM_REG_ABHR 0x14 /* WR only, Coldfire */
#define BDM_REG_ABLR 0x15 /* WR only, Coldfire */
#define BDM_REG_DBR 0x16 /* WR only, Coldfire */
#define BDM_REG_DBMR 0x17 /* WR only, Coldfire */
#define BDM_MAX_SYSREG (BDM_REG_DBMR + 1)
/*
* Register codes for BDM_READ_REG/BDM_WRITE_REG ioctls
*/
#define BDM_REG_D0 0x0
#define BDM_REG_D1 0x1
#define BDM_REG_D2 0x2
#define BDM_REG_D3 0x3
#define BDM_REG_D4 0x4
#define BDM_REG_D5 0x5
#define BDM_REG_D6 0x6
#define BDM_REG_D7 0x7
#define BDM_REG_A0 0x8
#define BDM_REG_A1 0x9
#define BDM_REG_A2 0xa
#define BDM_REG_A3 0xb
#define BDM_REG_A4 0xc
#define BDM_REG_A5 0xd
#define BDM_REG_A6 0xe
#define BDM_REG_A7 0xf /* use this for the stack pointer */
#endif /* _BDM_H_ */

View File

@@ -0,0 +1,8 @@
bus_if.h
device_if.h
isa_if.h
setdefs.h
setdef0.c
setdef1.c
bdm.ko
bdm.8.gz

View File

@@ -0,0 +1,16 @@
2001-02-03 Chris Johns <ccj@acm.org>
* bdm.8,
bus_if.h,
.cvsignore,
device_if.h,
freebsd-bdm.c,
isa_if.h,
Makefile,
setdef0.c,
setdef1.c,
setdefs.h,
unbdm,
README:
New file.

View File

@@ -0,0 +1,28 @@
# $Id: Makefile,v 1.1 2003/06/02 15:15:54 codewiz Exp $
#
# James Housley's FreeBSD kernel module makefile.
#
.PATH: ${.CURDIR}
KERN = /usr/src/sys/kern
KMOD = bdm
SRCS = bus_if.h device_if.h isa_if.h freebsd-bdm.c
MAN8 = bdm.8
CFLAGS += -DBDM_MODULE -Wall -I..
machine:
@${ECHO} ${.TARGET} "->" /usr/src/sys/i386/include; \
ln -s /usr/src/sys/i386/include ${.TARGET}
@:
@${ECHO} ${.TARGET} "->" /usr/src/sys; \
ln -s /usr/src/sys ${.TARGET}
afterinstall:
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/bdm ${DESTDIR}/usr/bin
${INSTALL} -c -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
${.CURDIR}/unbdm ${DESTDIR}/usr/bin
.include <bsd.kmod.mk>

View File

@@ -0,0 +1,39 @@
Motorola Background Debug Mode Driver for FreeBSD
By Greg Tunnock <gtunnock@RedfernNetworks.com> on 5-Sep-00.
Redfern Broadband Networks, Eveleigh, NSW, Australia
http://www.RedfernNetworks.com
The BDM driver is built as a FreeBSD kernel module. Not as a driver that
can be linked into the kernel. The BDM kernel module is loaded and unloaded
at runtime, with the bdm and unbdm scripts.
The BDM kernel module is built as part of the FreeBSD kernel sources. The
/usr/src/sys sources distribution needs to be installed before the BDM
kernel module can be built. The Makefile assumes the kernel sources are
installed at /usr/src/sys.
The device special files need to be created as root, with
../../local_scripts/MAKEDEV.
The BDM kernel module has been built and tested with FreeBSD 4.0, the
Coldfire processor and P&E Coldfire interface.
To build:
$ make
To install (as root):
# make install
# ../../local_scripts/MAKEDEV
To load BDM kernel module:
$ /usr/bin/bdm
To unload BDM kernel module:
$ /usr/bin/unbdm

2
m68k/driver/freebsd/bdm Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
/sbin/kldload bdm

20
m68k/driver/freebsd/bdm.8 Normal file
View File

@@ -0,0 +1,20 @@
.\"
.Dd June 19, 1997
.Dt BDM 8
.Os FreeBSD
.Sh NAME
.Nm bdm
.Nd load the background debug module driver kernel module
.Sh SYNOPSIS
.Nm bdm
.Sh DESCRIPTION
The
.Nm
utility loads the background debug module driver kernel module.
.Sh FILES
.Bl -tag -width /lkm/bdm_mod.o
.It Pa /lkm/bdm_mod.o
background debug module loadable kernel module.
.Sh "SEE ALSO"
.Xr lkm 4 ,
.Xr modload 8

View File

@@ -0,0 +1,500 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 2000 James Housley
* Copyright (C) 2000 Chris Johns
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* FreeBSD support by: (Started May 9, 2000)
* James Housley
* The Housleys dot Net
* 65 Frank's Lane
* Hanover, MA 02339, USA
*
* jim@thehousleys.net
*
* Chris Johns & Greg Tunnock
* Redfern Broadband Networks.
* Continued FreeBSD port, Sep 2000
* This porting effort has been made possible by Redfern Broadband
* Networks.
*
* ccj@acm.org
*
*/
#define BDM_DEFAULT_DEBUG 0
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <sys/uio.h>
#include <sys/syslog.h>
#ifdef DEVFS
#include <sys/devfsext.h>
#endif /*DEVFS*/
#include <machine/clock.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
#include <i386/isa/isa.h>
#include <i386/isa/isa_device.h>
#include <i386/isa/timerreg.h>
#include <sys/errno.h>
#include <unistd.h>
#include <sys/ioccom.h>
/*
************************************************************************
* FreeBSD Driver Structures *
************************************************************************
*/
#define UNIT(d) ((unsigned int)(minor(d) & 0x07))
/*
************************************************************************
* UNIX driver support routines *
************************************************************************
*/
/*
* Function prototypes.
*/
static int init_module (void);
static void os_lock_module (void);
static void os_unlock_module (void);
static int bdmprobe (void);
static void bdmattach (void);
static void bdmdetach (void);
static void bdm_outb (int port, int value);
/*
* Delay for a while so target can keep up.
*/
static void
bdm_delay (int counter)
{
while (counter--) {
__asm volatile ("nop");
}
}
/*
* Wait a longer while .
*/
static char BDMsleep;
static void
bdm_sleep (u_int time)
{
tsleep((void *)&BDMsleep, ((PZERO + 8)| PCATCH), "bdmslp", (int)time);
}
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
static int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
return 0;
}
static int
os_release_io_ports (unsigned int base, unsigned int num)
{
return 0;
}
static int
os_copy_in (void *dst, void *src, int size)
{
(void)memcpy(dst, src, (size_t)size);
return 0;
}
static int
os_copy_out (void *dst, void *src, int size)
{
(void)memcpy(dst, src, (size_t)size);
return 0;
}
/**
* Moves data from user-space address to kernel-space address.
*
* This is provide for Operating Systems with separate move and copy
* strategies. If an OS doesn't have a move strategy this function will
* be the same as os_copy_in().
*
* Param dst Kernel-space address to copy to.
* Param src User-space address to copy from.
* Param size Number of bytes to copy.
*
* Returns 0 if successful.
*/
static int
os_move_in (void *dst, void *src, int size)
{
return uiomove((caddr_t)dst, size, (struct uio *)src);
}
#define BUF_INCREMENTED_BY_MOVE_IN
/**
* Moves data from kernel-space address to user-space address.
*
* This is provide for Operating Systems with separate move and copy
* strategies. If an OS doesn't have a move strategy this function will
* be the same as os_copy_out().
*
* Param dst User-space address to copy to.
* Param src Kernel-space address to copy from.
* Param size Number of bytes to copy.
*
* Returns 0 if successful.
*/
static int
os_move_out (void *dst, void *src, int size)
{
return uiomove((caddr_t)src, size, (struct uio *)dst);
}
#define BUF_INCREMENTED_BY_MOVE_OUT
static void
os_lock_module ()
{
}
static void
os_unlock_module ()
{
}
/*
* Big hack to get around differences in outb
*/
static void
bdm_outb (int port, int value)
{
outb (port, value);
}
#undef outb
#define outb(value, port) bdm_outb (port, value)
/*
************************************************************************
* Mappings to FreeBSD *
************************************************************************
*/
#define PRINTF printf
#define udelay(x) DELAY (x)
#define MINOR(x) minor (x)
#define HZ hz
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "../bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int
freebsd_bdm_open (dev_t dev, int flags, int fmt, struct proc *p)
{
return bdm_open (MINOR (dev));
}
static int
freebsd_bdm_close (dev_t dev, int fflag, int devtype, struct proc *p)
{
return bdm_close (MINOR (dev));
}
static int
freebsd_bdm_read (dev_t dev, struct uio *uio, int flag)
{
return bdm_read (UNIT (dev), (char *)uio, uio->uio_resid);
}
static int
freebsd_bdm_write (dev_t dev, struct uio * uio, int ioflag)
{
return bdm_write (UNIT (dev), (char *)uio, uio->uio_resid);
}
static int
freebsd_bdm_ioctl (dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
{
return bdm_ioctl (UNIT(dev), cmd, (unsigned long)arg);
}
/*
* Driver entry points
*/
static int bdm_dev_registered = 0;
void cleanup_module (void);
/*
* Hook driver into kernel
*/
static int
init_module ()
{
int minor;
PRINTF ("bdm_init_module %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
bdm_dev_registered = 1;
/*
* Set up port numbers
*/
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
int port;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor)) {
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x2bc; break; /* LPT4, ccj - made this up :-) */
default:
PRINTF ("BDM driver has no address for LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
cleanup_module ();
return EIO;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
bdm_delay (50);
if (inb (port) != 0x00) {
self->exists = 0;
if (self->debugFlag)
PRINTF ("BDM driver cannot detect LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
continue;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
PRINTF ("BDM driver has no interface for minor number\n");
cleanup_module ();
return EIO;
}
}
return 0;
}
/*
* Unhook module from kernel
*/
void
cleanup_module (void)
{
int minor;
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
struct BDM *self = &bdm_device_info[minor];
if (self->exists && self->portsAreMine)
;
}
if (bdm_dev_registered) {
bdm_dev_registered = 0;
PRINTF ("BDM driver unregistered.\n");
}
}
#ifdef KLD_MODULE
#include <sys/exec.h>
#include <sys/sysent.h>
#define CDEV_MAJOR 34
static struct cdevsw bdm_cdevsw = {
freebsd_bdm_open, /* open */
freebsd_bdm_close, /* close */
freebsd_bdm_read, /* read */
freebsd_bdm_write, /* write */
freebsd_bdm_ioctl, /* ioctl */
nopoll, /* poll */
nommap, /* mmap */
nostrategy, /* strategy */
"bdm", /* name */
CDEV_MAJOR, /* major */
nodump, /* dump */
nopsize, /* psize */
0, /* flags */
-1 /* bmaj */
};
/*
* Table of BDM devices.
*/
static struct {
char *name; /* Name in /dev. */
int minor; /* Device minor number. */
dev_t dev; /* Device structure, once attached. */
} bdm_devs[] = {
{ "bdmcpu320", 0, 0 },
{ "bdmcpu321", 1, 0 },
{ "bdmcpu322", 2, 0 },
{ "bdmcf0", 4, 0 },
{ "bdmcf1", 5, 0 },
{ "bdmcf2", 6, 0 },
{ "bdmicd0", 8, 0 },
{ "bdmicd1", 9, 0 },
{ "bdmicd2", 10, 0 }
};
#define NUMOF_DEVS (sizeof(bdm_devs)/sizeof(bdm_devs[0]))
static int
bdmprobe ()
{
/* For now, always report the BDM driver is able to drive the BDM hardware. */
return 0;
}
static void
bdmattach ()
{
int i;
for (i = 0; i < NUMOF_DEVS; i++) {
bdm_devs[i].dev
= make_dev(&bdm_cdevsw, bdm_devs[i].minor, 0, 0, 0666, bdm_devs[i].name);
}
}
static void
bdmdetach()
{
int i;
for (i = 0; i < NUMOF_DEVS; i++) {
if (bdm_devs[i].dev) {
destroy_dev(bdm_devs[i].dev);
bdm_devs[i].dev = 0;
}
}
}
static int
bdm_load(void)
{
int err;
PRINTF("BDM init_module\n %s\n %s\n %s\n",
"$RCSfile: freebsd-bdm.c,v $", "$Revision: 1.2 $", "$Date: 2003/09/20 22:21:16 $");
PRINTF(" Version %s\n Compiled at %s %s\n",
"PD-interface",
__DATE__, __TIME__);
err = bdmprobe ();
if (err) {
PRINTF ("BDM driver: probe failed\n");
return err;
}
bdmattach ();
err = init_module();
if (err) {
PRINTF ("BDM driver: load failed\n");
bdmdetach ();
return err;
}
PRINTF ("BDM driver: loaded\n");
return 0;
}
static int
bdm_unload(void)
{
bdmdetach ();
PRINTF ("BDM driver: unloaded\n");
return 0;
}
static int
bdm_mod_event(module_t mod, int type, void *data)
{
switch (type) {
case MOD_LOAD:
return bdm_load();
case MOD_UNLOAD:
return bdm_unload();
default:
break;
}
return 0;
}
static moduledata_t bdm_mod = {
"bdm",
bdm_mod_event,
NULL,
};
DECLARE_MODULE(bdm, bdm_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
#endif /* KLD_MODULE */

2
m68k/driver/freebsd/unbdm Executable file
View File

@@ -0,0 +1,2 @@
#!/bin/sh
/sbin/kldunload -n bdm.ko

555
m68k/driver/ioperm/ioperm.c Normal file
View File

@@ -0,0 +1,555 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 2003 Chris Johns
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* I/O Permssion support by:
* Chris Johns
* cjohns@users.sourceforge.net
*
*/
#include <config.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#ifdef HAVE_IOPERM
#include <sys/io.h>
#endif
#include <sys/param.h>
#include <sys/stat.h>
#include "tblcf.h"
#include "tblcf_usb.h"
#ifdef __FreeBSD__
#include <machine/cpufunc.h>
/*
* Need to swap around the parameters to the outb call to match Linux.
*/
static inline void fb_outb (u_int port, u_char data)
{
outb (port, data);
}
#undef outb
#define outb(d, p) fb_outb(p, d)
#endif
#define BDM_DEFAULT_DEBUG 0
static int debugLevel = BDM_DEFAULT_DEBUG;
#ifndef HAVE_IOPERM
static FILE* dev_io_handle;
#endif
/*
************************************************************************
* Override the C library function. *
************************************************************************
*/
int
driver_close (int fd)
{
return close (fd);
}
int
driver_read (int fd, char *buf, size_t count)
{
return read (fd, buf, count);
}
int
driver_write (int fd, char *buf, size_t count)
{
return write (fd, buf, count);
}
int
driver_ioctl (int fd, unsigned long int request, ...)
{
va_list args;
unsigned long *arg;
va_start (args, request);
arg = va_arg (args, unsigned long *);
return ioctl (fd, request, arg);
}
int
driver_open (const char *pathname, int flags)
{
return open (pathname, flags);
}
#define open ioperm_bdm_open
#define close ioperm_bdm_close
#define ioctl ioperm_bdm_ioctl
#define read ioperm_bdm_read
#define write ioperm_bdm_write
/*
************************************************************************
* Add the missing the write/read define. *
************************************************************************
*/
#define IOC_OUTIN 0x10000000 /* copy in parameters */
//#define _IOWR(x,y,t) (IOC_OUTIN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|(x<<8)|y)
/*
************************************************************************
* Unix driver support routines *
************************************************************************
*/
#define udelay usleep
/*
* Delay for a while so target can keep up.
*/
void
bdm_delay (int counter)
{
volatile unsigned long junk;
while (counter--) {
junk++;
}
}
#ifndef HZ
#define HZ 1000
#endif
/*
* Delay specified number of milliseconds
*/
void
bdm_sleep (unsigned long time)
{
usleep (time * (100 * (1000 / HZ)));
}
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
/*
* I am told ioperm handles this.
*/
return 0;
}
int
os_release_io_ports (unsigned int base, unsigned int num)
{
return 0;
}
#define os_move_in os_copy_in
int
os_copy_in (void *dst, void *src, int size)
{
/*
* We run in the application and talk directly to the hardware.
*/
memcpy (dst, src, size);
return 0;
}
#define os_move_out os_copy_out
int
os_copy_out (void *dst, void *src, int size)
{
memcpy (dst, src, size);
return 0;
}
void
os_lock_module ()
{
}
void
os_unlock_module ()
{
}
#ifdef interface
#undef interface
#endif
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int bdm_dev_registered = 0;
static int bdm_driver_open = 0;
/*
* Unhook module from kernel
*/
static void
bdm_cleanup_module (int fd)
{
if (bdm_dev_registered)
{
if ((fd >= 0) &&
(((unsigned) fd) < (sizeof (bdm_device_info) / sizeof (*bdm_device_info))))
{
struct BDM *self = &bdm_device_info[fd];
#ifdef HAVE_IOPERM
ioperm (self->portBase, 3, 0);
#else
if (dev_io_handle)
{
fclose (dev_io_handle);
dev_io_handle = NULL;
}
#endif
bdm_dev_registered = 0;
#ifdef BDM_VER_MESSAGE
bdmInfo ("BDM driver unregistered.\n");
#endif
}
}
else
driver_close (fd);
}
/*
* Try and get access to the port via ioperm. If you fail flag this and let
* the library try for a real driver.
*/
int
ioperm_bdm_init (int minor)
{
unsigned short port;
unsigned char data;
struct BDM *self;
#ifdef BDM_VER_MESSAGE
bdmInfo ("bdm_init %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
#endif
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor))
{
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x9400; break; /* PCI parallel port cards */
default:
bdmInfo ("BDM driver has no address for LPT%d.\n",
BDM_IFACE_MINOR (minor) + 1);
errno = EIO;
return -1;
}
/*
* Set up the port.
*/
self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Try the ioperm() call to claim standard parallel ports.
*
* For PCI parallel port adaptors in extended IO space, use
* iopl() instead.
*/
#ifdef HAVE_IOPERM
if (port < 0x400)
{
if (ioperm (port, 3, 1) < 0)
return -1;
}
else
{
if (iopl(3) != 0)
return -1;
}
#else
if (!dev_io_handle)
{
dev_io_handle = fopen("/dev/io", "rw");
if (!dev_io_handle)
return -1;
}
#endif
/*
* See if the port exists
*/
self->exists = 1;
bdm_dev_registered = 1;
outb (0x00, port);
udelay (50);
data = inb (port);
if (data != 0x00)
{
self->exists = 0;
if (self->debugFlag)
bdmInfo ("BDM driver cannot detect LPT%d.\n",
BDM_IFACE_MINOR (minor) + 1);
bdm_cleanup_module (minor);
errno = EIO;
return -3;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor))
{
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
bdmInfo ("BDM driver has no interface for minor number\n");
bdm_cleanup_module (minor);
errno = EIO;
return -1;
}
return 0;
}
/*
* The device is a device name of the form /dev/bdmcpu320 or
* /dev/bdmcf0 where the /dev/bdm must be present
* the next field can be cpu32 or cf followed by
* a number which is the port.
*
* It can also be a udev created symlink to the USB bus node.
*/
static int remoteOpen (const char *name);
int
ioperm_bdm_open (const char *devname, int flags, ...)
{
const char* device = devname;
int port = -1;
int result = 0;
if (bdm_dev_registered)
{
bdmInfo ("BDM driver is already registered (Please report to BDM project).\n");
errno = EIO;
return -2;
}
if (strncmp (device, "/dev/bdm", sizeof ("/dev/bdm") - 1) == 0)
{
device += sizeof ("/dev/bdm") - 1;
if (strncmp (device, "cpu32", 5) == 0)
{
port = 0;
device += 5; /* s.b. 5 */
}
else if (strncmp (device, "icd", 3) == 0)
{
port = 8;
device += 3;
}
else if (strncmp (device, "cf", 2) == 0)
{
port = 4;
device += 2;
}
else
{
errno = ENOENT;
result = -1;
}
if (result == 0)
{
port += strtoul (device, 0, 0);
result = ioperm_bdm_init (port);
}
}
if ((result == 0) && (port == -1))
{
bdmInfo ("trying usb driver: %s\n", devname);
result = usb_bdm_init (device);
if (result < -1)
return -1;
port = 0;
}
/*
* See if the ioperm or usb call failed. Try to open the driver. If no
* driver is found, prepend localhost and try for a local server.
* This make an /dev/bdmcf0 open automatically attempt to open a
* bdmServer. This local server may be using ioperm or usb so no driver.
*/
if (result < 0)
{
if (result == -1)
{
int fd;
bdmInfo ("trying kernel driver: %s\n", devname);
if ((fd = driver_open (devname, flags)) < 0) {
if ((strlen (devname) + sizeof ("localhost")) < 128)
{
char lname[128];
strcpy (lname, "localhost:");
strcat (lname, devname);
bdmInfo ("trying bdm server: %s\n", lname);
return remoteOpen (lname);
}
return -1;
}
bdm_driver_open = 1;
return fd;
}
return -1;
}
errno = bdm_open (port);
if (errno)
return -1;
bdm_dev_registered = 1;
return port;
}
int
ioperm_bdm_close (int fd)
{
if (bdm_driver_open)
{
bdm_driver_open = 0;
return driver_close (fd);
}
bdm_close (fd);
bdm_cleanup_module (fd);
return 0;
}
unsigned long
ioperm_bdm_read (int fd, char *buf, unsigned long count)
{
if (bdm_driver_open)
return driver_read (fd, buf, count);
errno = bdm_read (fd, buf, count);
if (errno)
return -1;
return count;
}
unsigned long
ioperm_bdm_write (int fd, char *buf, unsigned long count)
{
if (bdm_driver_open)
return driver_write (fd, buf, count);
errno = bdm_write (fd, buf, count);
if (errno)
return -1;
return count;
}
int
ioperm_bdm_ioctl (int fd, unsigned int cmd, ...)
{
va_list args;
unsigned long *arg;
int iarg;
int err = 0;
va_start (args, cmd);
arg = va_arg (args, unsigned long *);
if (bdm_driver_open)
return driver_ioctl (fd, cmd, arg);
/*
* Pick up the argument
*/
if (!bdm_dev_registered) {
switch (cmd) {
case BDM_DEBUG:
err = os_copy_in ((void*) &iarg, (void*) arg, sizeof iarg);
break;
}
if (err)
return err;
if (debugLevel > 3)
bdmInfo ("ioperm_bdm_ioctl cmd:0x%08x\n", cmd);
switch (cmd) {
case BDM_DEBUG:
debugLevel = iarg;
break;
}
}
errno = bdm_ioctl (fd, cmd, (unsigned long) arg);
if (errno)
return -1;
return 0;
}

View File

@@ -0,0 +1,3 @@
*.cmd
bdm.ko
bdm.mod.c

View File

@@ -0,0 +1,14 @@
ifneq ($(KERNELRELEASE),)
obj-m := bdm.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
install:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules_install
endif

374
m68k/driver/linux-2.6/bdm.c Normal file
View File

@@ -0,0 +1,374 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 1995 W. Eric Norum
* Copyright (C) 1998 Chris Johns
*
* Based on:
* 1. `A Background Debug Mode Driver Package for Motorola's
* 16- and 32-Bit Microcontrollers', Scott Howard, Motorola
* Canada, 1993.
* 2. `Linux device driver for public domain BDM Interface',
* M. Schraut, Technische Universitaet Muenchen, Lehrstuhl
* fuer Prozessrechner, 1995.
*
* Extended to support the ColdFire BDM interface using the P&E
* module which comes with the EVB. Currently only tested with the
* 5206 (5V) device.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* 107 North Road
* Saskatoon, Saskatchewan, CANADA
* S7N 5C6
*
* eric@skatter.usask.ca
*
* Coldfire support by:
* Chris Johns
* Objective Design Systems
* 35 Cairo Street
* Cammeray, Sydney, 2062, Australia
*
* ccj@acm.org
*
* 22/10/1999 -- CCJ (ccj@acm.org)
* Move the linux specific parts into a separate directory
* and file.
*
* 17/05/2003 -- Bernardo Innocenti <bernie@develer.com>
* Port to kernel 2.5.x
*/
#define BDM_DEFAULT_DEBUG 0
#include <linux/autoconf.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
/*
************************************************************************
* UNIX driver support routines *
************************************************************************
*/
/*
* Delay for a while so target can keep up.
*/
static void
bdm_delay (int counter)
{
while (counter--) {
asm volatile ("nop");
}
}
/*
* Wait a longer while .
*/
static void
bdm_sleep (u_int time)
{
current->state = TASK_INTERRUPTIBLE;
schedule_timeout (time);
}
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
static int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
if (!request_region (base, 4, name))
return EBUSY;
return 0;
}
static int
os_release_io_ports (unsigned int base, unsigned int num)
{
release_region (base, 4);
return 0;
}
#define os_move_in os_copy_in
static int
os_copy_in (void *dst, void *src, int size)
{
if (copy_from_user (dst, src, size))
return EFAULT;
return 0;
}
#define os_move_out os_copy_out
static int
os_copy_out (void *dst, void *src, int size)
{
if (copy_to_user (dst, src, size))
return EFAULT;
return 0;
}
static void
os_lock_module (void)
{
/* FIXME: we should check for failure here! */
try_module_get(THIS_MODULE);
}
static void
os_unlock_module (void)
{
module_put(THIS_MODULE);
}
/*
************************************************************************
* Mapping to Linux kernel functions *
************************************************************************
*/
#define PRINTF printk
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "../bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int
linux_bdm_open (struct inode *inode, struct file *file)
{
return -bdm_open (iminor(inode));
}
/*
* The old Linux driver set the control port back to the value it
* had when the device was opened. This is good when the port is
* being shared between the BDM interface and a printer, but has
* the unfortunate side effect of freezing the target. This makes
* it inconvenient to use the debugger, or a downloader program,
* since the target freezes as soon as the debugger, or downloader,
* exits.
*/
static int
linux_bdm_release (struct inode *inode, struct file *file)
{
bdm_close (iminor(inode));
return 0;
}
static ssize_t
linux_bdm_read (struct file *file, char *buf, size_t count, loff_t *offp)
{
int err;
err = bdm_read (iminor(file->f_dentry->d_inode), buf, count);
if (err)
return -err;
return count;
}
static ssize_t
linux_bdm_write (struct file *file, const char *buf, size_t count, loff_t *offp)
{
int err;
err = bdm_write (iminor(file->f_dentry->d_inode), (char*) buf, count);
if (err)
return -err;
return count;
}
static int
linux_bdm_ioctl (struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
return -bdm_ioctl (iminor(inode), cmd, arg);
}
/*
* Driver entry points
*/
static struct file_operations bdm_fops;
static int bdm_dev_registered = 0;
static void linux_bdm_exit(void);
/*
* Hook driver into kernel
*/
static int __init
linux_bdm_init (void)
{
unsigned int minor;
printk ("bdm_init_module %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
/*
* Set up entry points
* This used to be done with a static initializer, but the layout
* of the structure seems to change substantially between kernel
* versions.
*/
memset (&bdm_fops, 0, sizeof bdm_fops);
bdm_fops.read = linux_bdm_read;
bdm_fops.write = linux_bdm_write;
bdm_fops.ioctl = linux_bdm_ioctl;
bdm_fops.open = linux_bdm_open;
bdm_fops.release = linux_bdm_release;
/*
* Register with kernel
*/
if (register_chrdev (BDM_MAJOR_NUMBER, "bdm", &bdm_fops)) {
printk ("Unable to get major number %d for BDM driver.\n", BDM_MAJOR_NUMBER);
return -EIO;
}
bdm_dev_registered = 1;
/*
* Set up port numbers
*/
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
int port;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor)) {
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x9400; break; /* PCI parallel port card (bernie) */
default:
printk ("BDM driver has no address for LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
linux_bdm_exit();
return -EIO;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
udelay (50);
if (inb (port) != 0x00) {
self->exists = 0;
if (self->debugFlag)
printk ("BDM driver cannot detect LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
continue;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
printk ("BDM driver has no interface for minor number\n");
cleanup_module();
return -EIO;
}
}
return 0;
}
/*
* Unhook module from kernel
*/
static void __exit
linux_bdm_exit (void)
{
unsigned int minor;
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
struct BDM *self = &bdm_device_info[minor];
if (self->exists && self->portsAreMine)
release_region (self->portBase, 4);
}
if (bdm_dev_registered) {
bdm_dev_registered = 0;
if (unregister_chrdev (BDM_MAJOR_NUMBER, "bdm"))
printk ("Unable to unregister BDM driver.\n");
else
printk ("BDM driver unregistered.\n");
}
}
module_init(linux_bdm_init);
module_exit(linux_bdm_exit);
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,83 @@
2001-04-25 Chris Johns <cjohns@cybertec.com.au>
* linux-bdm.c: Still need the config modules check.
* Makefile: Do not force module versions on. Detect it now.
* linux-bdm.c:
Use config.h (autoconfig.h) to detect if module version numbers are
enabled. On RH7.0 you still get warnings.
2001-04-22 Chris Johns <cjohns@cybertec.com.au>
* Makefile: Changed to better support RH7.0 systems.
2001-02-03 Chris Johns <cjohns@cybertec.com.au>
* linux-bdm.c: Changed to support the new memory move interface.
2000-09-03 Chris Johns <ccj@acm.org>
* linux-bdm.c: Fixed the ICD spelling.
22000-08-03 Chris Johns <ccj@acm.org>
* linux-bdm.c:
Merged a patch from Frank Haverkamp <haver@ibr.cs.tu-bs.de> which
makes the driver more robust in the face of kernel data
structure changes.
2000-06-27 Chris Johns <ccj@acm.org>
* Makefile: Use a full path to depmod as `/sbin' may not be in root's
path when doing an install.
2000-05-31 Chris Johns <ccj@acm.org>
* Makefile:
Added the system include path incase another gcc is installed.
Removed the PST define. It is automatic now.
* linux-bdm.c: Support for the IDC interface.
2000-03-30 Chris Johns <ccj@acm.org>
* Makefile: Added the USE_PST support. Moved to clean OS structure.
* linux-bdm.c: New file.
1999-05-25 eric <>
* Makefile:
It seems that depmod complains about unresolved symbols even
when the driver loads and works properly. I don't know what's
changed in Linux to cause this, but for now just get rid of
the depmod.
1998-12-12 Chris Johns <ccj@acm.org>
* Makefile: Fixed the modversions.
1998-10-31 Chris Johns <ccj@acm.org>
* Makefile: Always over-write the installed header and lib.
1998-10-14 Chris Johns <ccj@acm.org>
* Makefile: Changed the prefix to the default of /usr.
1997-11-01 eric <>
* Makefile: Fit into RTEMS distribution.
1997-02-08 eric <>
* Makefile: Add a single `prefix'.
Make directories if necessary when installing.
1997-02-07 eric <>
* Makefile: Add module installation to install target.
* Makefile: New file.

102
m68k/driver/linux/Makefile Normal file
View File

@@ -0,0 +1,102 @@
#*******************************************************************
# Motorola m68k BDM Driver for Linux Kernel and GNU Debugger
#
# Makefile-mod - Makefile for regular compilation
# through Linux kernel rules
#
# This file must be renamed or linked to Makefile
#
# (C) Copyright 1999 by Pavel Pisa
#
# The BDM driver is distributed under the Gnu General Public Licence.
# See file COPYING for details.
#*******************************************************************/
# Use "make MODULE_NAME=foobar" if you want to give the driver module
# a different name. This might be useful if you want to install both,
# Chris's and Pavel's drivers at the same machine.
DEFAULT_MODULE_NAME=m68k-bdm
MODULE_NAME=$(DEFAULT_MODULE_NAME)
ifneq ($(MODULE_NAME),linux-bdm)
CLEAN_MODULE_TEMP=rm -f $(MODULE_NAME).c
endif
# currently running kernel
CURRENT=$(shell uname -r)
KERNEL_NEW=$(shell if [ -d /lib/modules/$(CURRENT)/build ] ; \
then echo yes ; else echo no ; fi )
# Where to look for kernel
#KERNEL_LOCATION=/usr/src/linux
#KERNEL_LOCATION=/usr/src/kernel/$(CURRENT)
#KERNEL_LOCATION=/lib/modules/$(CURRENT)/build
#KERNEL_LOCATION=/usr/src/linux-2.2.19
#KERNEL_LOCATION=/usr/src/linux-2.5.60
ifndef KERNEL_LOCATION
ifeq ($(KERNEL_NEW),yes)
KERNEL_LOCATION=/lib/modules/$(CURRENT)/build
MODULE_CHAR_LOC=/lib/modules/$(CURRENT)/kernel/drivers/char
else
KERNEL_LOCATION=/usr/src/linux
MODULE_CHAR_LOC=/lib/modules/$(CURRENT)/misc
endif
endif
# Test for latest 2.5.xx and future 2.6.xx kernels
KERNEL_VERSION := $(shell awk -F\" '/REL/ {print $$2}' \
$(KERNEL_LOCATION)/include/linux/version.h | awk -F\- '{print $$1}')
KERNEL_MODULE_V26 := $(shell echo $(KERNEL_VERSION) \
| sed -n 's/^.*2\.[5-9]\..*$$/yes/p')
# Target object file if any
O_TARGET :=
# Regular object files
O_OBJS = $(MODULE_NAME).o
# Objects with exported symbols (-DEXPORT_SYMTAB)
OX_OBJS =
# Module objects
M_OBJS = $(O_OBJS)
# Module only objects with exported symbols (-DEXPORT_SYMTAB)
MX_OBJS =
# Kernel only objects
L_OBJS =
# Kernel only objects with exported symbols (-DEXPORT_SYMTAB)
LX_OBJS =
# Additional CFLAGS
EXTRA_CFLAGS =
# Linux 2.4.2 build system needs next
obj-m += $(O_OBJS)
ifndef KERNEL_MODULE_V26
FINAL_MODULE_OBJS=$(obj-m)
else
FINAL_MODULE_OBJS=$(obj-m:%.o=%.ko)
endif
all : make_this_module
install : install_this_module
$(MODULE_NAME).c: linux-bdm.c ../bdm.c ../bdm.h
cp $< $@
make_this_module: $(MODULE_NAME).c
DIR=`pwd`; (cd $(KERNEL_LOCATION); make SUBDIRS=$$DIR modules)
$(CLEAN_MODULE_TEMP)
install_this_module: make_this_module
su -c "mkdir -v -p $(MODULE_CHAR_LOC) && cp -v $(FINAL_MODULE_OBJS) $(MODULE_CHAR_LOC)"
$(CLEAN_MODULE_TEMP)
clean:
rm -f $(M_OBJS) $(MX_OBJS) *.ko .*.o.flags .*.o.cmd .*.ko.cmd .depend *~
ifndef KERNEL_MODULE_V26
export TOPDIR=$(KERNEL_LOCATION)
include $(KERNEL_LOCATION)/Rules.make
endif

View File

@@ -0,0 +1,441 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 1995 W. Eric Norum
* Copyright (C) 1998 Chris Johns
*
* Based on:
* 1. `A Background Debug Mode Driver Package for Motorola's
* 16- and 32-Bit Microcontrollers', Scott Howard, Motorola
* Canada, 1993.
* 2. `Linux device driver for public domain BDM Interface',
* M. Schraut, Technische Universitaet Muenchen, Lehrstuhl
* fuer Prozessrechner, 1995.
*
* Extended to support the ColdFire BDM interface using the P&E
* module which comes with the EVB. Currently only tested with the
* 5206 (5V) device.
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* University of Saskatchewan
* 107 North Road
* Saskatoon, Saskatchewan, CANADA
* S7N 5C6
*
* eric@skatter.usask.ca
*
* Coldfire support by:
* Chris Johns
* Objective Design Systems
* 35 Cairo Street
* Cammeray, Sydney, 2062, Australia
*
* ccj@acm.org
*
* 22/10/1999 -- CCJ (ccj@acm.org)
* Move the linux specific parts into a separate directory
* and file.
*/
#define BDM_DEFAULT_DEBUG 0
#include <linux/config.h>
#if CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/fs.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/mm.h>
#include <linux/delay.h>
#include <asm/io.h>
#include <asm/segment.h>
#if (LINUX_VERSION_CODE > 131336)
#include <asm/uaccess.h>
#endif /* LINUX_VERSION_CODE */
#include <linux/errno.h>
/*
************************************************************************
* UNIX driver support routines *
************************************************************************
*/
/*
* Delay for a while so target can keep up.
*/
static void
bdm_delay (int counter)
{
while (counter--) {
asm volatile ("nop");
}
}
/*
* Wait a longer while .
*/
static void
bdm_sleep (u_int time)
{
current->state = TASK_INTERRUPTIBLE;
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
schedule_timeout (time);
#else
current->timeout = jiffies + time;
schedule ();
#endif
}
/*
************************************************************************
* Some Linux driver compatability code - for older kernels *
************************************************************************
*/
#if (LINUX_VERSION_CODE < 131336)
static int copy_from_user (void *to, const void *from_user, unsigned long len)
{
int error;
error = verify_area (VERIFY_READ, from_user, len);
if (error)
return len;
memcpy_fromfs (to, from_user, len);
return 0;
}
static int copy_to_user (void *to_user, const void *from, unsigned long len)
{
int error;
error = verify_area (VERIFY_WRITE, to_user, len);
if (error)
return len;
memcpy_tofs (to_user, from, len);
return 0;
}
#endif /* LINUX_VERSION_CODE */
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
static int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
if (check_region (base, 4))
return EBUSY;
request_region (base, 4, name);
return 0;
}
static int
os_release_io_ports (unsigned int base, unsigned int num)
{
release_region (base, 4);
return 0;
}
#define os_move_in os_copy_in
static int
os_copy_in (void *dst, void *src, int size)
{
if (copy_from_user (dst, src, size))
return EFAULT;
return 0;
}
#define os_move_out os_copy_out
static int
os_copy_out (void *dst, void *src, int size)
{
if (copy_to_user (dst, src, size))
return EFAULT;
return 0;
}
static void
os_lock_module (void)
{
MOD_INC_USE_COUNT;
}
static void
os_unlock_module (void)
{
MOD_DEC_USE_COUNT;
}
/*
************************************************************************
* Mapping to Linux kernel functions *
************************************************************************
*/
#define PRINTF printk
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "../bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int
linux_bdm_open (struct inode *inode, struct file *file)
{
return -bdm_open (MINOR (inode->i_rdev));
}
/*
* The old Linux driver set the control port back to the value it
* had when the device was opened. This is good when the port is
* being shared between the BDM interface and a printer, but has
* the unfortunate side effect of freezing the target. This makes
* it inconvenient to use the debugger, or a downloader program,
* since the target freezes as soon as the debugger, or downloader,
* exits.
*/
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
static int
linux_bdm_release (struct inode *inode, struct file *file)
#else
static void
linux_bdm_release (struct inode *inode, struct file *file)
#endif
{
bdm_close (MINOR (inode->i_rdev));
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
return 0;
#endif
}
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
static ssize_t
linux_bdm_read (struct file *file, char *buf, size_t count, loff_t *offp)
#else
static int
linux_bdm_read (struct inode *inode, struct file *file, char *buf, int count)
#endif
{
unsigned int minor;
int err;
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
minor = MINOR (file->f_dentry->d_inode->i_rdev);
#else
minor = MINOR (inode->i_rdev);
#endif
err = bdm_read (minor, buf, count);
if (err)
return -err;
return count;
}
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
static ssize_t
linux_bdm_write (struct file *file, const char *buf, size_t count, loff_t *offp)
#else
static int
linux_bdm_write (struct inode *inode, struct file *file, const char *buf, int count)
#endif
{
unsigned int minor;
int err;
#if (LINUX_VERSION_CODE > 0x020101) /* 2.1.1 ?? */
minor = MINOR (file->f_dentry->d_inode->i_rdev);
#else
minor = MINOR (inode->i_rdev);
#endif
err = bdm_write (minor, (char*) buf, count);
if (err)
return -err;
return count;
}
static int
linux_bdm_ioctl (struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
return -bdm_ioctl (MINOR (inode->i_rdev), cmd, arg);
}
/*
* Driver entry points
*/
static struct file_operations bdm_fops;
static int bdm_dev_registered = 0;
void cleanup_module (void);
/*
* Hook driver into kernel
*/
int
init_module (void)
{
unsigned int minor;
printk ("bdm_init_module %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
/*
* Set up entry points
* This used to be done with a static initializer, but the layout
* of the structure seems to change substantially between kernel
* versions.
*/
memset (&bdm_fops, 0, sizeof bdm_fops);
bdm_fops.read = linux_bdm_read;
bdm_fops.write = linux_bdm_write;
bdm_fops.ioctl = linux_bdm_ioctl;
bdm_fops.open = linux_bdm_open;
bdm_fops.release = linux_bdm_release;
/*
* Register with kernel
*/
if (register_chrdev (BDM_MAJOR_NUMBER, "bdm", &bdm_fops)) {
printk ("Unable to get major number %d for BDM driver.\n", BDM_MAJOR_NUMBER);
return -EIO;
}
bdm_dev_registered = 1;
/*
* Set up port numbers
*/
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
int port;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor)) {
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x2bc; break; /* LPT4, ccj - made this up :-) */
default:
printk ("BDM driver has no address for LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
cleanup_module();
return -EIO;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
udelay (50);
if (inb (port) != 0x00) {
self->exists = 0;
if (self->debugFlag)
printk ("BDM driver cannot detect LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
continue;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
printk ("BDM driver has no interface for minor number\n");
cleanup_module();
return -EIO;
}
}
return 0;
}
/*
* Unhook module from kernel
*/
void
cleanup_module (void)
{
unsigned int minor;
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
struct BDM *self = &bdm_device_info[minor];
if (self->exists && self->portsAreMine)
release_region (self->portBase, 4);
}
if (bdm_dev_registered) {
bdm_dev_registered = 0;
if (unregister_chrdev (BDM_MAJOR_NUMBER, "bdm"))
printk ("Unable to unregister BDM driver.\n");
else
printk ("BDM driver unregistered.\n");
}
}

View File

@@ -0,0 +1,9 @@
COMPILEHEADERS?=/var/obj/amd/kaben2/var/obj/NetBSD/1.6/src/sys/arch/i386/compile/GENERIC
KERNELHEADERS?=/projects/NetBSD/1.6/src/sys
openbsd-bdm.o: openbsd-bdm.c ../bdm.c
cc -O2 -D_KERNEL \
-I$(COMPILEHEADERS) -I$(KERNELHEADERS) -c openbsd-bdm.c
clean:
rm openbsd-bdm.o

View File

@@ -0,0 +1,58 @@
Motorola Background Debug Mode Driver for OpenBSD
The BDM driver is built as a OpenBSD loadable kernel module, not as
a driver that can be linked into the kernel. The BDM kernel module
is loaded and unloaded at runtime, with the modload and modunload
commands.
The BDM kernel module has been built and tested with OpenBSD 2.9,
the Coldfire processor and P&E Coldfire interface. The code is
a port of the current FreeBSD driver.
To build:
=========
- ensure kernel was builit with 'option LKM'
- ensure /etc/rc.securelevel securelevel=-1 to allow loading modules
- compile driver using following command
cc -O2 -D_KERNEL -I/sys -c openbsd-bdm.c
To install (as root):
=====================
- mkdir /usr/lkm
- cp openbsd-bdm.o /usr/lkm/.
- cp bdm-install.sh /usr/lkm/.
- add the following to /etc/rc.securelevel (for auto load on startup)
if [ -r /usr/lkm/openbsd-bdm.o ]
then
echo -n ' openbsd-bdm'
/sbin/modload -o bdm.o -ebdm -p /usr/lkm/bdm-install.sh /usr/lkm/openbsd-bdm.o >/dev/null
fi
- add the following to /etc/rc.shutdown (for auto unload on shutdown)
if [ -r /usr/lkm/openbsd-bdm.o ]
then
/sbin/modunload -n bdm >/dev/null
fi
To load BDM kernel module:
==========================
- modload -o bdm.o -ebdm -p bdm-install.sh openbsd-bdm.o
To unload BDM kernel module:
============================
- modunload -n bdm
To build gdb5.0:
================
- apply gdb-bdm patches
- edit $GDBSRC/gdb/configure.host
- copy following netbsd line to add support for openbsd host
i[3456]86-*-netbsd*) ... to
i[3456]86-*-openbsd*) ...
- build gdb using standard configure/make all/make install

View File

@@ -0,0 +1,40 @@
#!/bin/sh
MAJOR=`modstat -n bdm | tail -1 | awk '{print $3}'`
if [ ! -c /dev/bdmcpu320 ]
then
mknod -m 666 /dev/bdmcpu320 c $MAJOR 0
fi
if [ ! -c /dev/bdmcpu321 ]
then
mknod -m 666 /dev/bdmcpu321 c $MAJOR 1
fi
if [ ! -c /dev/bdmcpu322 ]
then
mknod -m 666 /dev/bdmcpu322 c $MAJOR 2
fi
if [ ! -c /dev/bdmcf0 ]
then
mknod -m 666 /dev/bdmcf0 c $MAJOR 4
fi
if [ ! -c /dev/bdmcf1 ]
then
mknod -m 666 /dev/bdmcf1 c $MAJOR 5
fi
if [ ! -c /dev/bdmcf2 ]
then
mknod -m 666 /dev/bdmcf2 c $MAJOR 6
fi
if [ ! -c /dev/bdmidc0 ]
then
mknod -m 666 /dev/bdmidc0 c $MAJOR 8
fi
if [ ! -c /dev/bdmidc1 ]
then
mknod -m 666 /dev/bdmidc1 c $MAJOR 9
fi
if [ ! -c /dev/bdmidc2 ]
then
mknod -m 666 /dev/bdmidc2 c $MAJOR 10
fi
echo "created bdm devices, major number $MAJOR"
ls -l /dev/bdm*

View File

@@ -0,0 +1,443 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 2000 James Housley
* Copyright (C) 2000 Chris Johns
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* FreeBSD support by: (Started May 9, 2000)
* James Housley
* The Housleys dot Net
* 65 Frank's Lane
* Hanover, MA 02339, USA
*
* jim@thehousleys.net
*
* Chris Johns & Greg Tunnock
* Redfern Broadband Networks.
* Continued FreeBSD port, Sep 2000
* This porting effort has been made possible by Redfern Broadband
* Networks.
*
* ccj@acm.org
*
*/
#define BDM_DEFAULT_DEBUG 0
#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/systm.h>
#include <sys/ioctl.h>
#include <sys/exec.h>
#include <sys/conf.h>
#include <sys/lkm.h>
#include <sys/proc.h>
#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/uio.h>
#include <sys/syslog.h>
#include <uvm/uvm.h>
#include <uvm/uvm_param.h>
#include <uvm/uvm_pmap.h>
#include <sys/errno.h>
#include <sys/ioccom.h>
/*
************************************************************************
* OpenBSD Driver Structures *
************************************************************************
*/
#define UNIT(d) ((unsigned int)(minor(d) & 0x07))
/*
************************************************************************
* UNIX driver support routines *
************************************************************************
*/
/*
* Function prototypes.
*/
static int init_module (void);
static void os_lock_module (void);
static void os_unlock_module (void);
static int bdmprobe (void);
static void bdmattach (void);
static void bdmdetach (void);
static void bdm_outb (int port, int value);
/*
* Delay for a while so target can keep up.
*/
static void
bdm_delay (int counter)
{
while (counter--) {
__asm volatile ("nop");
}
}
/*
* Wait a longer while .
*/
static char BDMsleep;
static void
bdm_sleep (u_int time)
{
tsleep((void *)&BDMsleep, ((PZERO + 8)| PCATCH), "bdmslp", (int)time);
}
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
static int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
return 0;
}
static int
os_release_io_ports (unsigned int base, unsigned int num)
{
return 0;
}
static int
os_copy_in (void *dst, void *src, int size)
{
(void)memcpy(dst, src, (size_t)size);
return 0;
}
static int
os_copy_out (void *dst, void *src, int size)
{
(void)memcpy(dst, src, (size_t)size);
return 0;
}
/**
* Moves data from user-space address to kernel-space address.
*
* This is provide for Operating Systems with separate move and copy
* strategies. If an OS doesn't have a move strategy this function will
* be the same as os_copy_in().
*
* Param dst Kernel-space address to copy to.
* Param src User-space address to copy from.
* Param size Number of bytes to copy.
*
* Returns 0 if successful.
*/
static int
os_move_in (void *dst, void *src, int size)
{
return uiomove((caddr_t)dst, size, (struct uio *)src);
}
#define BUF_INCREMENTED_BY_MOVE_IN
/**
* Moves data from kernel-space address to user-space address.
*
* This is provide for Operating Systems with separate move and copy
* strategies. If an OS doesn't have a move strategy this function will
* be the same as os_copy_out().
*
* Param dst User-space address to copy to.
* Param src Kernel-space address to copy from.
* Param size Number of bytes to copy.
*
* Returns 0 if successful.
*/
static int
os_move_out (void *dst, void *src, int size)
{
return uiomove((caddr_t)src, size, (struct uio *)dst);
}
#define BUF_INCREMENTED_BY_MOVE_OUT
static void
os_lock_module ()
{
}
static void
os_unlock_module ()
{
}
/*
* Big hack to get around differences in outb
*/
static void
bdm_outb (int port, int value)
{
outb (port, value);
}
#undef outb
#define outb(value, port) bdm_outb (port, value)
/*
************************************************************************
* Mappings to OpenBSD *
************************************************************************
*/
#define PRINTF printf
#define udelay(x) DELAY (x)
#define MINOR(x) minor (x)
#define HZ hz
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "../bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int
openbsd_bdm_open (dev_t dev, int flags, int fmt, struct proc *p)
{
return bdm_open (MINOR (dev));
}
static int
openbsd_bdm_close (dev_t dev, int fflag, int devtype, struct proc *p)
{
return bdm_close (MINOR (dev));
}
static int
openbsd_bdm_read (dev_t dev, struct uio *uio, int flag)
{
return bdm_read (MINOR (dev), (char *)uio, uio->uio_resid);
}
static int
openbsd_bdm_write (dev_t dev, struct uio * uio, int ioflag)
{
return bdm_write (MINOR (dev), (char *)uio, uio->uio_resid);
}
static int
openbsd_bdm_ioctl (dev_t dev, u_long cmd, caddr_t arg, int flag, struct proc *p)
{
return bdm_ioctl (MINOR (dev), cmd, (unsigned long)arg);
}
/*
* Driver entry points
*/
static int bdm_dev_registered = 0;
void cleanup_module (void);
/*
* Hook driver into kernel
*/
static int
init_module ()
{
int minor;
PRINTF ("bdm_init_module %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
bdm_dev_registered = 1;
/*
* Set up port numbers
*/
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
int port;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor)) {
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x2bc; break; /* LPT4, ccj - made this up :-) */
default:
PRINTF ("BDM driver has no address for LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
cleanup_module ();
return EIO;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
bdm_delay (50);
if (inb (port) != 0x00) {
self->exists = 0;
if (self->debugFlag)
PRINTF ("BDM driver cannot detect LPT%d.\n", BDM_IFACE_MINOR (minor) + 1);
continue;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
PRINTF ("BDM driver has no interface for minor number\n");
cleanup_module ();
return EIO;
}
}
return 0;
}
/*
* Unhook module from kernel
*/
void
cleanup_module (void)
{
int minor;
for (minor = 0 ;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]) ;
minor++) {
struct BDM *self = &bdm_device_info[minor];
if (self->exists && self->portsAreMine)
;
}
if (bdm_dev_registered) {
bdm_dev_registered = 0;
PRINTF ("BDM driver unregistered.\n");
}
}
static struct cdevsw openbsd_devsw =
{
openbsd_bdm_open, /* open */
openbsd_bdm_close, /* close */
openbsd_bdm_read, /* read */
openbsd_bdm_write, /* write */
openbsd_bdm_ioctl, /* ioctl */
(void *)nullop, /* stop */
(void *)NULL, /* tty */
(void *)nullop, /* select */
(void *)nullop, /* mmap */
NULL /* strategy */
};
MOD_DEV("bdm", LM_DT_CHAR, BDM_MAJOR_NUMBER, &openbsd_devsw)
static int
bdmprobe ()
{
/* For now, always report the BDM driver is able to drive the BDM hardware. */
return 0;
}
static int
bdm_load(void)
{
int err;
PRINTF("BDM init_module\n %s\n %s\n %s\n",
"$RCSfile: openbsd-bdm.c,v $", "$Revision: 1.1 $", "$Date: 2004/04/18 16:51:21 $");
PRINTF(" Version %s\n Compiled at %s %s\n",
"PD-interface",
__DATE__, __TIME__);
err = bdmprobe ();
if (err) {
PRINTF ("BDM driver: probe failed\n");
return err;
}
err = init_module();
if (err) {
PRINTF ("BDM driver: load failed\n");
return err;
}
PRINTF ("BDM driver: loaded\n");
return 0;
}
static int
bdm_unload(void)
{
PRINTF ("BDM driver: unloaded\n");
return 0;
}
static int
bdm_handler(struct lkm_table *lkmtp, int cmd)
{
int iStatus = 0;
struct lkm_dev *args = lkmtp->private.lkm_dev;
switch ( cmd ) {
case LKM_E_LOAD:
iStatus = bdm_load();
break;
case LKM_E_UNLOAD:
iStatus = bdm_unload();
break;
}
return ( iStatus );
}
int bdm(struct lkm_table *lkmtp, int cmd, int ver)
{
DISPATCH(lkmtp, cmd, ver, bdm_handler, lkm_nofunc, lkm_nofunc);
}

20
m68k/driver/sco/Makefile Normal file
View File

@@ -0,0 +1,20 @@
CFLAGS= -DSCO -D_INKERNEL=1 -DUSE_PST=1 -I..
DRIVER= bdm
all: Driver.o
Driver.o: ../bdm.h ../bdm.c sco.c
$(CC) $(CFLAGS) -c -o Driver.o sco.c
install: Driver.o
if /etc/conf/bin/idcheck -p $(DRIVER); \
then \
/etc/conf/bin/idinstall -k -a $(DRIVER); \
else \
/etc/conf/bin/idinstall -k -u $(DRIVER); \
fi
clean:
rm -f Driver.o

1
m68k/driver/sco/Master Normal file
View File

@@ -0,0 +1 @@
bdm Iocirw Hci bdm 0 0 0 4 -1

8
m68k/driver/sco/Node Normal file
View File

@@ -0,0 +1,8 @@
bdm bdmcp0 c 0
bdm bdmcp1 c 1
bdm bdmcp2 c 2
bdm bdmcp3 c 3
bdm bdmcf0 c 4
bdm bdmcf1 c 5
bdm bdmcf2 c 6
bdm bdmcf3 c 7

51
m68k/driver/sco/README Normal file
View File

@@ -0,0 +1,51 @@
How to use the SCO BDM driver
-----------------------------
1. Type "make" to build the driver. I have only tested it when compiled
with the SCO compiler. It does compile with "gcc", so you may be in
luck if thats the path taht you follow.
2. Edit "System" and set the entry that corresponds to your parallel port
to 'Y'.
3. Login as root and type "make install". This will put the driver into
the kernel.
4. Re-build the kernel by running "/etc/conf/bin/idbuild -y" as root, and
the reboot to activate the driver.
5. Build yourself a GDB with BDM support (documented somewhere else :-)
6. Run gdb on the executable you want to debug. At the prompt turn on BDM
with "target bdm /dev/XXXX". The driver automatically installs all the
possible devices in /dev:
/dev/bdmcp0 - CPU32 on LP0
/dev/bdmcp1 - CPU32 on LP1
/dev/bdmcp2 - CPU32 on LP2
/dev/bdmcp3 - CPU32 on LP3
/dev/bdmcf0 - Coldfire on LP0
/dev/bdmcf1 - Coldfire on LP1
/dev/bdmcf2 - Coldfire on LP2
/dev/bdmcf3 - Coldfire on LP3
7. Happy debugging.
Compiling the rest of the tree
------------------------------
1. The Makfile in the lib directory needs the ranlib removed and some
other options like -Wall taken out for the SCO compiler.
2. The Makefile in the test directory needs the "-lbfd -liberty" taken
out.
3. If you do want to use parts of the library that require the BFD library
then you will have to work through that on your own :-)
Copyright (C) 1999 David McCullough (davidm@stallion.oz.au)

36
m68k/driver/sco/Space.c Normal file
View File

@@ -0,0 +1,36 @@
/****************************************************************************/
/*
* Do all our LP setup through the standard System/Sdevice setup
*/
/****************************************************************************/
#include "config.h"
/****************************************************************************/
unsigned int bdm_ports[] = {
#ifdef BDM_0
BDM_0_SIOA,
#else
-1,
#endif
#ifdef BDM_1
BDM_1_SIOA,
#else
-1,
#endif
#ifdef BDM_2
BDM_2_SIOA,
#else
-1,
#endif
#ifdef BDM_3
BDM_3_SIOA,
#else
-1,
#endif
};
int bdm_debug_level = 0;
/****************************************************************************/

4
m68k/driver/sco/System Normal file
View File

@@ -0,0 +1,4 @@
bdm Y 0 0 0 0 378 37b 0 0
bdm N 1 0 0 0 278 27b 0 0
bdm N 2 0 0 0 3bc 3bf 0 0
bdm N 3 0 0 0 2bc 2bf 0 0

276
m68k/driver/sco/sco.c Normal file
View File

@@ -0,0 +1,276 @@
/****************************************************************************/
/*
* Motorola Background Debug Mode Driver for SCO based on the linux one
* which it needs to compile.
*
* Copyright (C) 1999 David McCullough (davidm@stallion.oz.au)
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 22/10/1999 -- CCJ (ccj@acm.org)
* Altered to match the split driver code.
*
*/
#define BDM_DEFAULT_DEBUG 0
#include <sys/param.h>
#include <sys/types.h>
#include <sys/immu.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/sysmacros.h>
#include <sys/errno.h>
#include <sys/conf.h>
#include "bdm.h"
/****************************************************************************
* UNIX driver support routines *
****************************************************************************/
/*
* Big hack to get around differences in outb under SCO
*/
void
bdm_outb (int port, int value)
{
outb (port, value);
}
#define outb(value, port) bdm_outb (port, value)
/****************************************************************************
* Other tings we need to compile *
****************************************************************************/
#define PRINTF printf
#define udelay(x) bdm_delay (x)
#define MINOR(x) minor (x)
/****************************************************************************
* Delay for a while so target can keep up. *
****************************************************************************/
static void
bdm_delay (int counter)
{
while (counter--)
__asm ("nop");
}
/****************************************************************************
* Wait a longer while. This function sleeps *
****************************************************************************/
static void
bdm_sleep (u_int time)
{
delay(time);
}
/****************************************************************************
* OS worker functions. *
****************************************************************************/
static int
os_claim_io_ports (unsigned int base, unsigned int num)
{
return 0;
}
static int
os_release_io_ports (unsigned int base, unsigned int num)
{
return 0;
}
static int
os_copy_in (void *dst, void *src, int size)
{
if (copyin (src, dst, size) < 0)
return EFAULT;
return 0;
}
static int
os_copy_out (void *dst, void *src, int size)
{
if (copyout (src, dst, size) < 0)
return EFAULT;
return 0;
}
static void
os_lock_module ()
{
}
static void
os_unlock_module ()
{
}
/****************************************************************************
* Include the BBM code *
****************************************************************************/
#include "bdm.c"
/****************************************************************************
* The real driver code starts here *
****************************************************************************/
int
bdminit ()
{
int minor, found;
static char hex_digit[] = "0123456789ABCDEF";
/*
* Set up port numbers
*/
found = 0;
for (minor = 0;
minor < (sizeof bdm_device_info / sizeof bdm_device_info[0]);
minor++) {
extern int bdm_ports[], bdm_debug_level; /* see Space.c */
int port, i;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level. I use a variable
* here so I can set it with a debugger or just change
* space.c and rebuild the kernel.
*/
self->debugFlag = bdm_debug_level;
/*
* Choose a port number
*/
i = BDM_IFACE_MINOR (minor);
if (i >= 0 && i < 4)
port = bdm_ports[i];
else
port = -1;
if (port == -1) {
self->exists = 0;
continue;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
udelay (50);
if (inb (port) != 0x00) {
self->exists = -1;
if (self->debugFlag)
printk("BDM driver cannot detect device %d(addr=0x%x).\n",
BDM_IFACE_MINOR(minor), port);
}
bcopy ("bdm\0\0\0", self->name, 6);
self->name[4] = hex_digit[(minor & 0xf0) >> 4];
self->name[5] = hex_digit[minor & 0xf];
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
default:
self->exists = -2;
if (self->debugFlag)
printk("BDM driver has no interface for minor number %d\n",
minor);
break;
}
if (self->exists) {
printcfg("bdm", port, 4, -1, -1,
"%d minor=%d v%d.%d, " __DATE__ ", " __TIME__,
self->exists, minor,
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
found++;
if (self->exists < 0)
self->exists = 0;
}
}
if (!found)
printcfg("bdm", 0, 0, -1, -1,
"NO-PORTS v%d.%d, " __DATE__ ", " __TIME__,
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
return(0);
}
/******************************************************************************/
int
bdmopen (dev_t dev, int flag, int type)
{
u.u_error = bdm_open (MINOR(dev));
return 0;
}
/******************************************************************************/
int
bdmclose (dev_t dev, int flag, int type)
{
u.u_error = bdm_close (MINOR(dev));
return 0;
}
/******************************************************************************/
int
bdmioctl (dev_t dev, int cmd, int arg, int mode)
{
u.u_error = bdm_ioctl (MINOR(dev), cmd, arg);
return 0;
}
/******************************************************************************/
int
bdmread (dev_t dev)
{
u.u_error = bdm_read (MINOR (dev), u.u_base, u.u_count);
u.u_base += u.u_count;
u.u_count = 0;
return(0);
}
/******************************************************************************/
int
bdmwrite (dev_t dev)
{
u.u_error = bdm_write (MINOR (dev), u.u_base, u.u_count);
u.u_base += u.u_count;
u.u_count = 0;
return (0);
}
/******************************************************************************/

44
m68k/driver/win/ChangeLog Normal file
View File

@@ -0,0 +1,44 @@
2002-02-10 Chris Johns <cjohns@cybertec.com.au>
* win-bdm.c:
Do not provide a stat as it effects programs using stat, eg Insight.
2001-09-01 Chris Johns <cjohns@cybertec.com.au>
* win-bdm.c: Fixed the GiveIO patches to compile under Cygwin.
2001-04-15 Chris Johns <cjohns@cybertec.com.au>
* win9x-bdm.c:
Merged in the changes from Rick Haubenstricker <rickh@perceptron.com> to
support NT and the GiveIO driver. This file should be moved to win-bdm.c
and the lib makefile updated but it is a change that is not important.
2001-02-03 Chris Johns <ccj@acm.org>
* win9x-bdm.c:
Enabled support for TCP, so the driver supports remote connections.
2000-09-02 Chris Johns <ccj@acm.org>
* win9x-bdm.c:
Fixed cpu32 support. Patch from Howard Loewen <loewenhw@mb.sympatico.ca>.
22000-06-27 Chris Johns <ccj@acm.org>
* win9x-bdm.c: The usleep takes micro seconds and it was being given
milli seconds. Delays did not work.
2000-06-07 Chris Johns <ccj@acm.org>
* win9x-bdm.c:
Moved the open/close etc definitions to this file from the lib.
2000-05-31 Chris Johns <ccj@acm.org>
* win9x-bdm.c: Support for the IDC interface.
2000-05-27 Chris Johns <ccj@acm.org>
* win9x-io.h, win9x-bdm.c: New file.

535
m68k/driver/win/win-bdm.c Normal file
View File

@@ -0,0 +1,535 @@
/*
* Motorola Background Debug Mode Driver
* Copyright (C) 1998-2007 Chris Johns
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Windows support by:
* Chris Johns
* Contemporary Software
* chris@contemporary.net.au
*
* Michael Cooper
* Integrated Chipware
* 1861 Wiehle Ave.
* Reston, Virginia 20190, USA
* mikec@chipware.com
*
* Rick Haubenstricker
* Perceptron, Inc
* 47827 Halyard Dr
* Plymouth, Michigan 48170, USA
* rickh@perceptron.com
*
*/
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <windows.h>
#include <win/win-io.h>
#define BDM_DEFAULT_DEBUG 0
static int debugLevel = BDM_DEFAULT_DEBUG;
/*
************************************************************************
* Override the C library function. *
************************************************************************
*/
int
win32_remote_close (int fd)
{
return close (fd);
}
int
win32_remote_read (int fd, char *buf, size_t count)
{
return read (fd, buf, count);
}
int
win32_remote_write (int fd, char *buf, size_t count)
{
return write (fd, buf, count);
}
int
stat (const char *file_name, struct stat *buf)
{
if (strncmp (file_name, "/dev/bdm", sizeof ("/dev/bdm") - 1) == 0 )
{
return 0 ;
}
else /* Check for real file */
{
int fd = open(file_name,O_RDONLY);
if ( fd > 0 )
{
int status = fstat(fd, buf);
close(fd);
return status;
}
else
{
return fd;
}
}
}
#define open win_bdm_open
#define close win_bdm_close
#define ioctl win_bdm_ioctl
#define read win_bdm_read
#define write win_bdm_write
/*
************************************************************************
* Windows driver support routines *
************************************************************************
*/
#define udelay usleep
#if !defined (__CYGWIN__)
#ifndef HZ
#define HZ 100
#endif
void
usleep(int usecs)
{
LARGE_INTEGER lpc;
LONGLONG lpc2;
LONGLONG current_usecs;
LONGLONG final_usecs;
static int first_time = 1;
static LARGE_INTEGER lpf;
static LONGLONG lpf2;
/*
* First time through, get frequency of high-resolution
* performance counter (value is counts per second)
*/
if (first_time) {
QueryPerformanceFrequency (&lpf);
lpf2 = *(LONGLONG *) &lpf;
first_time = 0;
}
/*
* Get current value of high-resolution performance counter
* (value in counts)
*/
QueryPerformanceCounter (&lpc);
lpc2 = *(LONGLONG *)&lpc;
/*
* Calculate desired final time in usecs
*/
final_usecs = ((lpc2 * (LONGLONG) 1000000) / lpf2) + (LONGLONG) usecs;
/*
* Loop until current count when converted to usecs is greater
* than final time
*/
do {
/*
* Get current value of high-resolution performance
* counter (value in counts)
*/
QueryPerformanceCounter (&lpc);
lpc2 = *(LONGLONG *) &lpc;
/*
* Calculate current time in usecs
*/
current_usecs = (lpc2 * (LONGLONG) 1000000 / lpf2);
}
while (current_usecs < final_usecs);
}
#endif
/*
* Delay for a while so target can keep up.
*/
void
bdm_delay (int counter)
{
while (counter--) {
#if defined (__GNUC__)
asm volatile ("nop");
#else
__asm nop
#endif
}
}
/*
* Delay specified number of milliseconds
*/
void
bdm_sleep (unsigned long time)
{
usleep (time * (1000 * (100 / HZ)));
}
/*
************************************************************************
* OS worker functions. *
************************************************************************
*/
int
os_claim_io_ports (char *name, unsigned int base, unsigned int num)
{
/*
* FIXME: Not sure what happens here. Dos Win9x how someelse has
* port through some sort of virtual device driver thingy ?
*/
return 0;
}
int
os_release_io_ports (unsigned int base, unsigned int num)
{
/*
* FIXME: See comment above.
*/
return 0;
}
#define os_move_in os_copy_in
int
os_copy_in (void *dst, void *src, int size)
{
/*
* We run in the application and talk directly to the hardware.
*/
memcpy (dst, src, size);
return 0;
}
#define os_move_out os_copy_out
int
os_copy_out (void *dst, void *src, int size)
{
memcpy (dst, src, size);
return 0;
}
void
os_lock_module ()
{
}
void
os_unlock_module ()
{
}
#ifdef interface
#undef interface
#endif
/*
************************************************************************
* Include the driver code *
************************************************************************
*/
#include "bdm.c"
/*
************************************************************************
* Good old-fashioned UNIX driver entry points *
************************************************************************
*/
static int bdm_dev_registered = 0;
/*
* Unhook module from kernel
*/
static void bdm_cleanup_module (void)
{
if (bdm_dev_registered) {
bdm_dev_registered = 0;
fprintf (stderr, "BDM driver unregistered.\n");
}
}
/*
* Basically just detect the port.
*/
int
win_bdm_init ()
{
int minor;
HANDLE h;
OSVERSIONINFO osvi;
BOOL bOsVersionInfoEx;
if (bdm_dev_registered)
return 0;
/*
* Determine which operating system in use, if NT or 2000,
* we need to enable the port.
*/
ZeroMemory (&osvi, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!(bOsVersionInfoEx = GetVersionEx ((LPOSVERSIONINFO) &osvi))) {
/*
* If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO.
*/
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) {
fprintf (stderr, "error: unsupported Windows version.\n");
errno = EIO;
return -1;
}
}
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
/*
* Open access to parallel port using giveio
*/
h = CreateFile ("\\\\.\\giveio", GENERIC_READ, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
fprintf (stderr, "error: could not access the GiveIO device.\n");
errno = EIO;
return -1;
}
CloseHandle (h);
}
#ifdef BDM_VER_MESSAGE
fprintf (stderr, "bdm_init %d.%d, " __DATE__ ", " __TIME__ "\n",
BDM_DRV_VERSION >> 8, BDM_DRV_VERSION & 0xff);
#endif
/*
* Set up port numbers
*/
for (minor = 0 ;
minor < (sizeof(bdm_device_info) / sizeof(bdm_device_info[0])) ;
minor++) {
unsigned short port;
struct BDM *self = &bdm_device_info[minor];
/*
* First set the default debug level.
*/
self->debugFlag = BDM_DEFAULT_DEBUG;
/*
* Choose a port number
*/
switch (BDM_IFACE_MINOR (minor)) {
case 0: port = 0x378; break; /* LPT1 */
case 1: port = 0x278; break; /* LPT2 */
case 2: port = 0x3bc; break; /* LPT3 */
case 3: port = 0x2bc; break; /* LPT4, ccj - made this up :-) */
default:
fprintf (stderr, "BDM driver has no address for LPT%d.\n",
BDM_IFACE_MINOR (minor) + 1);
bdm_cleanup_module();
errno = EIO;
return -1;
}
/*
* See if the port exists
*/
self->exists = 1;
outb (0x00, port);
udelay (50);
if (inb (port) != 0x00) {
self->exists = 0;
if (self->debugFlag)
fprintf (stderr, "BDM driver cannot detect LPT%d.\n",
BDM_IFACE_MINOR (minor) + 1);
continue;
}
sprintf (self->name, "bdm%d", minor);
self->portBase = self->dataPort = port;
self->statusPort = port + 1;
self->controlPort = port + 2;
self->delayTimer = 0;
switch (BDM_IFACE (minor)) {
case BDM_CPU32_PD: cpu32_pd_init_self (self); break;
case BDM_CPU32_ICD: cpu32_icd_init_self (self); break;
case BDM_COLDFIRE_PE: cf_pe_init_self (self); break;
case BDM_COLDFIRE_TBLCF: break;
default:
fprintf (stderr, "BDM driver has no interface for minor number\n");
bdm_cleanup_module();
errno = EIO;
return -1;
}
}
bdm_dev_registered = 1;
return 0;
}
/*
* The device is a device name of the form /dev/bdmcpu320 or
* /dev/bdmcf0 where the /dev/bdm must be present
* the next field can be cpu32 or cf followed by
* a number which is the port.
*/
int
win_bdm_open (const char *device, int flags, ...)
{
int port = 0;
if (strncmp (device, "/dev/bdm", sizeof ("/dev/bdm") - 1) == 0)
{
if (win_bdm_init () < 0)
return -1;
device += sizeof ("/dev/bdm") - 1;
if (strncmp (device, "cpu32", 5) == 0)
{
port = 0;
device += 5; /* s.b. 5 */
}
/* Allow ICD access under cygwin */
else if (strncmp (device, "icd", 3) == 0)
{
port = 8;
device += 3;
}
else if (strncmp (device, "cf", 2) == 0)
{
port = 4;
device += 2;
}
else
{
errno = ENOENT;
return -1;
}
port += strtoul (device, 0, 0);
}
else
{
if (usb_bdm_init (device) < 0)
return -1;
}
errno = bdm_open (port);
if (errno)
return -1;
return port;
}
int
win_bdm_close (int fd)
{
bdm_close (fd);
return 0;
}
unsigned long
win_bdm_read (int fd, char *buf, unsigned long count)
{
errno = bdm_read (fd, buf, count);
if (errno)
return -1;
return count;
}
unsigned long
win_bdm_write (int fd, char *buf, unsigned long count)
{
errno = bdm_write (fd, buf, count);
if (errno)
return -1;
return count;
}
int
win_bdm_ioctl (int fd, unsigned int cmd, ...)
{
va_list args;
unsigned long *arg;
int iarg;
int err = 0;
va_start (args, cmd);
arg = va_arg (args, unsigned long *);
/*
* Pick up the argument
*/
if (!bdm_dev_registered) {
switch (cmd) {
case BDM_DEBUG:
err = os_copy_in ((void*) &iarg, (void*) arg, sizeof iarg);
break;
}
if (err)
return err;
if (debugLevel > 3)
fprintf (stderr, "win_bdm_ioctl cmd:0x%08x\n", cmd);
switch (cmd) {
case BDM_DEBUG:
debugLevel = iarg;
break;
}
}
errno = bdm_ioctl (fd, cmd, (unsigned long) arg);
if (errno)
return -1;
return 0;
}

103
m68k/driver/win/win-io.h Normal file
View File

@@ -0,0 +1,103 @@
#ifndef _ASM_IO_H
#define _ASM_IO_H
/*
* From the Linux kernel with the kernel section removed.
*/
/*
* This file contains the definitions for the x86 IO instructions
* inb/inw/inl/outb/outw/outl and the "string versions" of the same
* (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
* versions of the single-IO instructions (inb_p/inw_p/..).
*
* This file is not meant to be obfuscating: it's just complicated
* to (a) handle it all in a way that makes gcc able to optimize it
* as well as possible and (b) trying to avoid writing the same thing
* over and over again with slight variations and possibly making a
* mistake somewhere.
*/
/*
* Thanks to James van Artsdalen for a better timing-fix than
* the two short jumps: using outb's to a nonexistent port seems
* to guarantee better timings even on fast machines.
*
* On the other hand, I'd like to be sure of a non-existent port:
* I feel a bit unsafe about using 0x80 (should be safe, though)
*
* Linus
*/
/*
* Bit simplified and optimized by Jan Hubicka
*/
#ifdef SLOW_IO_BY_JUMPING
#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
#else
#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
#endif
#ifdef REALLY_SLOW_IO
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
#else
#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
#endif
/*
* Talk about misusing macros..
*/
#define __OUT1(s,x) \
extern inline void out##s(unsigned x value, unsigned short port) {
#define __OUT2(s,s1,s2) \
__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
#define __OUT(s,s1,x) \
__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
#define __IN1(s) \
extern inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
#define __IN2(s,s1,s2) \
__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
#define __IN(s,s1,i...) \
__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
#define __INS(s) \
extern inline void ins##s(unsigned short port, void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; ins" #s \
: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define __OUTS(s) \
extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
{ __asm__ __volatile__ ("cld ; rep ; outs" #s \
: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
#define RETURN_TYPE unsigned char
__IN(b,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned short
__IN(w,"")
#undef RETURN_TYPE
#define RETURN_TYPE unsigned int
__IN(l,"")
#undef RETURN_TYPE
__OUT(b,"b",char)
__OUT(w,"w",short)
__OUT(l,,int)
__INS(b)
__INS(w)
__INS(l)
__OUTS(b)
__OUTS(w)
__OUTS(l)
#endif