initial push
This commit is contained in:
224
m68k/driver/ChangeLog
Normal file
224
m68k/driver/ChangeLog
Normal 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
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
946
m68k/driver/bdm-cpu32.c
Normal 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
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
1392
m68k/driver/bdm.c
Normal file
File diff suppressed because it is too large
Load Diff
268
m68k/driver/bdm.h
Normal file
268
m68k/driver/bdm.h
Normal 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_ */
|
||||
8
m68k/driver/freebsd/.cvsignore
Normal file
8
m68k/driver/freebsd/.cvsignore
Normal 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
|
||||
16
m68k/driver/freebsd/ChangeLog
Normal file
16
m68k/driver/freebsd/ChangeLog
Normal 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.
|
||||
|
||||
28
m68k/driver/freebsd/Makefile
Normal file
28
m68k/driver/freebsd/Makefile
Normal 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>
|
||||
39
m68k/driver/freebsd/README
Normal file
39
m68k/driver/freebsd/README
Normal 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
2
m68k/driver/freebsd/bdm
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
/sbin/kldload bdm
|
||||
20
m68k/driver/freebsd/bdm.8
Normal file
20
m68k/driver/freebsd/bdm.8
Normal 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
|
||||
500
m68k/driver/freebsd/freebsd-bdm.c
Normal file
500
m68k/driver/freebsd/freebsd-bdm.c
Normal 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
2
m68k/driver/freebsd/unbdm
Executable file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
/sbin/kldunload -n bdm.ko
|
||||
555
m68k/driver/ioperm/ioperm.c
Normal file
555
m68k/driver/ioperm/ioperm.c
Normal 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;
|
||||
}
|
||||
3
m68k/driver/linux-2.6/.cvsignore
Normal file
3
m68k/driver/linux-2.6/.cvsignore
Normal file
@@ -0,0 +1,3 @@
|
||||
*.cmd
|
||||
bdm.ko
|
||||
bdm.mod.c
|
||||
14
m68k/driver/linux-2.6/Makefile
Normal file
14
m68k/driver/linux-2.6/Makefile
Normal 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
374
m68k/driver/linux-2.6/bdm.c
Normal 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");
|
||||
83
m68k/driver/linux/ChangeLog
Normal file
83
m68k/driver/linux/ChangeLog
Normal 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
102
m68k/driver/linux/Makefile
Normal 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
|
||||
|
||||
441
m68k/driver/linux/linux-bdm.c
Normal file
441
m68k/driver/linux/linux-bdm.c
Normal 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");
|
||||
}
|
||||
}
|
||||
9
m68k/driver/openbsd/Makefile
Normal file
9
m68k/driver/openbsd/Makefile
Normal 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
|
||||
58
m68k/driver/openbsd/README
Normal file
58
m68k/driver/openbsd/README
Normal 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
|
||||
|
||||
|
||||
40
m68k/driver/openbsd/bdm-install.sh
Executable file
40
m68k/driver/openbsd/bdm-install.sh
Executable 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*
|
||||
443
m68k/driver/openbsd/openbsd-bdm.c
Normal file
443
m68k/driver/openbsd/openbsd-bdm.c
Normal 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
20
m68k/driver/sco/Makefile
Normal 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
1
m68k/driver/sco/Master
Normal file
@@ -0,0 +1 @@
|
||||
bdm Iocirw Hci bdm 0 0 0 4 -1
|
||||
8
m68k/driver/sco/Node
Normal file
8
m68k/driver/sco/Node
Normal 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
51
m68k/driver/sco/README
Normal 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
36
m68k/driver/sco/Space.c
Normal 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
4
m68k/driver/sco/System
Normal 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
276
m68k/driver/sco/sco.c
Normal 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
44
m68k/driver/win/ChangeLog
Normal 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
535
m68k/driver/win/win-bdm.c
Normal 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
103
m68k/driver/win/win-io.h
Normal 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
|
||||
Reference in New Issue
Block a user