forked from Imagelibrary/rtems
2002-02-27 Greg Menke <gregory.menke@gsfc.nasa.gov>
* start/start.S: Added kseg1 test to enable cache flush code * bsp_specs: Added -qnostartfile to disable including bsp's start.o * startup/bspstart.c: Made clear_cache actually work, tweaked cpu init to only turn on whats needed. * startup/gdb-support.c: Added calls to uart 2 for gdb stub I/O and a handy init function.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
2001-02-27 Joel Sherrill <joel@OARcorp.com>
|
||||
2002-02-27 Greg Menke <gregory.menke@gsfc.nasa.gov>
|
||||
|
||||
* startup/Makefile.am: Added rtems-stub-glue.c to C_FILES.
|
||||
* start/start.S: Added kseg1 test to enable cache flush code
|
||||
* bsp_specs: Added -qnostartfile to disable including bsp's start.o
|
||||
* startup/bspstart.c: Made clear_cache actually work, tweaked cpu
|
||||
init to only turn on whats needed.
|
||||
* startup/gdb-support.c: Added calls to uart 2 for gdb stub I/O and
|
||||
a handy init function.
|
||||
|
||||
2002-02-08 Joel Sherrill <joel@OARcorp.com>
|
||||
|
||||
|
||||
@@ -44,9 +44,10 @@ entered, else PMON jumps to the EEPROM address above, presuming a user
|
||||
program is located there.
|
||||
|
||||
The default output of an RTEMS link is an image linked to run from
|
||||
80020000, but has had its LMA shifted up to BFC40000. It is suitable
|
||||
for copying to S3 records or can be burned to ROMs in whatever manner
|
||||
the user desires.
|
||||
0x80020000. It is suitable for copying to S3 records or can be burned
|
||||
to ROMs in whatever manner the user desires. If you want to locate the
|
||||
image into ROM at some other address, use mips-rtems-objcopy to shift
|
||||
the LMA.
|
||||
|
||||
Operation
|
||||
=========
|
||||
@@ -67,7 +68,51 @@ linkcmds.
|
||||
|
||||
Before relocating the RTEMS image, the bsp startup routine attempts to
|
||||
configure the processor into a rational state. During this process,
|
||||
status characters are emitted at 19200N81 baud on UART port 0.
|
||||
status characters are emitted at 19200N81 on UART port 0.
|
||||
|
||||
The default link script simply places the image at 0x8002000 with
|
||||
LMA=VMA, which is conviently located in RAM on our board. You should
|
||||
probably consider creating your own linkcmds, putting things where you
|
||||
want and supply it as above.
|
||||
|
||||
The Mongoose V has a somewhat restricted cache configuration model; you
|
||||
can only flush it if the code which does so executes within noncached
|
||||
memory, in our case, code in kseg1. If you do so from elsewhere the
|
||||
code will appear to lock up, this is caused by the cache clearing
|
||||
routine making the instruction fetch always return 0, or nop- leaving
|
||||
the processor in an endless loop. The default start.S code detects if
|
||||
its booting from outside kseg1, it which case it disables the cache
|
||||
flush code. This means you cannot flush the cache with the bsp's
|
||||
functions if you boot your program from outside kseg1. A more subtle
|
||||
issue is the bsp keeps a pointer to the location in kseg1 where the
|
||||
bsp's cache flush code resides. This is advantageous because you can
|
||||
relocate the system anywhere and still control the cache, but might
|
||||
cause trouble if the boot image becomes inaccessible. If this is
|
||||
possible, you should probably consider rolling your own cache control &
|
||||
disabling the bsp's.
|
||||
|
||||
As stated above, if you boot from outside kseg1, the bsp disables the
|
||||
cache flush routines. This is not desirable in the long run because the
|
||||
Mongoose V remote debugger stub assumes it can flush caches when exiting
|
||||
an exception so it might not be able to update code/data properly,
|
||||
though it should still nominally function. However, if you're not using
|
||||
the remote debugger & don't care about flushing caches, then everything
|
||||
should run just fine.
|
||||
|
||||
Our approach has to been locate ROM in kseg1, link the code for VMA in
|
||||
RAM and relocate the LMA up into kseg1 ROM. Since the start.S code is
|
||||
position-independent, it will relocate the entire app down to the VMA
|
||||
region before starting things up with everything in its proper place.
|
||||
The cache clear code runs before relocation, so executes from ROM &
|
||||
things work.
|
||||
|
||||
You can prevent including the default start.S by adding;
|
||||
|
||||
-qnostartfile
|
||||
|
||||
to the link command line in addition to the "nolinkcmds" options above.
|
||||
Be sure to supply your replacement start.o.
|
||||
|
||||
|
||||
|
||||
Questions
|
||||
@@ -84,6 +129,51 @@ when sending them fast?
|
||||
somewhat faulty UART design.
|
||||
|
||||
|
||||
Status
|
||||
======
|
||||
Debugging
|
||||
=========
|
||||
|
||||
After getting Joel's initial port of the gdb stub to the Mongoose bsp, I
|
||||
worked up & tested this stub on our R3000 board. It seems to work OK.
|
||||
Our MIPS has 2 serial ports, the first being dedicated to the console, I
|
||||
chose to arrange the 2nd one for the remote gdb protocol. While this
|
||||
solution is somewhat specific to our board & bsp, I think the technique
|
||||
is quite generalizable.
|
||||
|
||||
The following is a code snippet to be included in the user program;
|
||||
|
||||
/***********************************************/
|
||||
|
||||
extern int mg5rdbgOpenGDBuart(int);
|
||||
extern void mg5rdbgCloseGDBuart(void);
|
||||
|
||||
|
||||
void setupgdb(void)
|
||||
{
|
||||
printf("Configuring remote GDB stub...\n");
|
||||
|
||||
/* initialize remote gdb support */
|
||||
if( mg5rdbgOpenGDBuart(-1) != RTEMS_SUCCESSFUL )
|
||||
{
|
||||
printf("Remote GDB stub is disabled.\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************/
|
||||
|
||||
It allows the program to decide if it wants gdb to be ready to pick up
|
||||
exceptions or not. The 2 extern functions are located in the MongooseV
|
||||
bsp inside gdb-support.c. They configure & initialize the 2nd serial
|
||||
port & invoke the vector initialization routine located in cpu_asm.
|
||||
Note, we call directly down into the MongooseV UART driver- its quite
|
||||
unfriendly to TERMIO. I chose this approach because I wanted to
|
||||
minimize dependence on the I/O subsystems because they might be in a
|
||||
state just short of collapsing if the program had done something bad to
|
||||
cause the exception.
|
||||
|
||||
If user code leaves the 2nd port alone, then things will work out OK.
|
||||
|
||||
Greg Menke
|
||||
2/27/2002
|
||||
|
||||
============================================================================
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
|
||||
*startfile:
|
||||
%{!qrtems: %(old_startfile)} %{qrtems: \
|
||||
%{!qrtems_debug: start.o%s} \
|
||||
%{qrtems_debug: start_g.o%s}}
|
||||
%{!qnostartfile: %{!qrtems_debug: start.o%s} \
|
||||
%{qrtems_debug: start_g.o%s}}}
|
||||
|
||||
*link:
|
||||
%(old_link) %{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e _start}
|
||||
|
||||
@@ -48,15 +48,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef HACKED_PMON
|
||||
#define PMON_UTIL_ROUTINES 0xbfc00200
|
||||
#define UTIL_WARMSTART_VECTOR 21*4
|
||||
#define UTIL_CPUINIT_VECTOR 22*4
|
||||
#define UTIL_CONFIGUART_VECTOR 23*4
|
||||
#define UTIL_PUTCHROM_VECTOR 24*4
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
** defined by linkcmds, pointing to the start of the relocation target
|
||||
** memory, referenced in this way so we can avoid defining it
|
||||
@@ -84,7 +75,6 @@
|
||||
.globl putch_rom
|
||||
_start:
|
||||
.set noreorder
|
||||
move k1,ra /* save ra so we can optionally return to caller */
|
||||
$LF1 = . + 8
|
||||
|
||||
/*
|
||||
@@ -131,6 +121,42 @@ _branch:
|
||||
jal t0
|
||||
nop
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Print 'b'. Show that we started.
|
||||
*/
|
||||
move t2,a1
|
||||
and t2,0xffff0000
|
||||
li a0,'b'
|
||||
la t0,putch_rom
|
||||
and t0,0x0000ffff
|
||||
or t0,t2
|
||||
jal t0
|
||||
nop
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
li k0,0
|
||||
li k1,0
|
||||
|
||||
move t1,a1
|
||||
nop
|
||||
li t2,0xa0000000 /* lower limit of kseg1 */
|
||||
li t3,0xbfffffff /* upper limit of kseg1 */
|
||||
|
||||
subu t0,t1,t2
|
||||
srl t0,31 /* shift high bit down to bit 0 */
|
||||
bnez t0,1f /* booting from below kseg1 */
|
||||
|
||||
subu t0,t3,t1
|
||||
srl t0,31 /* shift high bit down to bit 0 */
|
||||
bnez t0,1f /* booting from above kseg1 */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Call IcacheFlush. Masking used to call EEPROM address of IcacheFlush. Label is RAM label.
|
||||
*/
|
||||
@@ -139,6 +165,7 @@ _branch:
|
||||
la t0,IcacheFlush
|
||||
and t0,0x0000ffff
|
||||
or t0,t2
|
||||
move k0,t0 /* save cache flush in-prom address */
|
||||
jal t0
|
||||
nop
|
||||
|
||||
@@ -177,10 +204,12 @@ _branch:
|
||||
la t0,putch_rom
|
||||
and t0,0x0000ffff
|
||||
or t0,t2
|
||||
move k1,t0 /* save cache flush in-prom address */
|
||||
jal t0
|
||||
nop
|
||||
|
||||
|
||||
1:
|
||||
/*
|
||||
** Print ' RTEMS b'. Show that we are booting.
|
||||
*/
|
||||
@@ -277,16 +306,16 @@ _branch:
|
||||
la t0,putch_rom
|
||||
and t0,0x0000ffff
|
||||
or t0,t2
|
||||
jal t0
|
||||
jal t0
|
||||
nop
|
||||
|
||||
la a3, _edata
|
||||
la a3, _edata
|
||||
relocate:
|
||||
lw t0, (a1) /* load from EEPROM */
|
||||
addu a1, 4
|
||||
sw t0, (a2) /* store to RAM */
|
||||
addu a2, 4
|
||||
bne a2, a3, relocate /* copied all the way to edata? */
|
||||
lw t0, (a1) /* load from EEPROM */
|
||||
addu a1, 4
|
||||
sw t0, (a2) /* store to RAM */
|
||||
addu a2, 4
|
||||
bne a2, a3, relocate /* copied all the way to edata? */
|
||||
nop
|
||||
|
||||
/*
|
||||
@@ -317,11 +346,11 @@ _start_in_ram:
|
||||
/*
|
||||
** Print 'S'. Already in RAM no need to reference EEPROM address.
|
||||
*/
|
||||
li a0,'S'
|
||||
jal putch_rom
|
||||
li a0,'S'
|
||||
jal putch_rom
|
||||
nop
|
||||
|
||||
la gp, _gp /* set the global data pointer */
|
||||
la gp, _gp /* set the global data pointer */
|
||||
.end _start_in_ram
|
||||
|
||||
|
||||
@@ -341,12 +370,12 @@ zerobss:
|
||||
jal putch_rom
|
||||
nop
|
||||
|
||||
la v0, _fbss
|
||||
la v1, _end
|
||||
la v0, _fbss
|
||||
la v1, _end
|
||||
3:
|
||||
sw zero,0(v0)
|
||||
bltu v0,v1,3b
|
||||
addiu v0,v0,4 /* executed in delay slot */
|
||||
sw zero,0(v0)
|
||||
bltu v0,v1,3b
|
||||
addiu v0,v0,4 /* executed in delay slot */
|
||||
|
||||
la t0, _stack_init /* initialize stack so we */
|
||||
|
||||
@@ -368,8 +397,8 @@ zerobss:
|
||||
/*
|
||||
** Print 'Z'. Finished zeroing bss.
|
||||
*/
|
||||
li a0,'Z'
|
||||
jal putch_rom
|
||||
li a0,'Z'
|
||||
jal putch_rom
|
||||
nop
|
||||
|
||||
.end zerobss
|
||||
@@ -387,12 +416,26 @@ _init:
|
||||
/*
|
||||
** Print 'i'. Starting to initialize RTEMS.
|
||||
*/
|
||||
li a0, 'i'
|
||||
jal putch_rom
|
||||
li a0, 'i'
|
||||
jal putch_rom
|
||||
nop
|
||||
|
||||
move a0,zero /* set argc to 0 */
|
||||
jal boot_card /* call the program start function */
|
||||
|
||||
/*
|
||||
** Save the boot-time addresses of the I & D cache flush routines.
|
||||
** Note, if we're running from RAM, we cannot manipulate the cache
|
||||
** so we just disable the cache flush functions.
|
||||
*/
|
||||
la a0,_promIcache
|
||||
sw k0,0(a0)
|
||||
nop
|
||||
|
||||
la a0,_promDcache
|
||||
sw k1,0(a0)
|
||||
nop
|
||||
|
||||
move a0,zero /* set argc to 0 */
|
||||
jal boot_card /* call the program start function */
|
||||
nop
|
||||
|
||||
/*
|
||||
@@ -748,13 +791,77 @@ _cpuinit:
|
||||
.end _cpuinit
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
**
|
||||
** Keep the boot-time address of the I & D cache reset code for
|
||||
** later on. If we need to clear the I/D caches, we <must> run from
|
||||
** non-cached memory. This means the relocated versions are useless,
|
||||
** thankfully they are quite small.
|
||||
*/
|
||||
|
||||
_promIcache: .word 0
|
||||
_promDcache: .word 0
|
||||
|
||||
|
||||
|
||||
.globl promCopyIcacheFlush
|
||||
.ent promCopyIcacheFlush
|
||||
.set noreorder
|
||||
promCopyIcacheFlush:
|
||||
move a0,ra
|
||||
|
||||
la t1,_promIcache
|
||||
lw t0,0(t1)
|
||||
nop
|
||||
beqz t0,1f
|
||||
|
||||
jal t0
|
||||
nop
|
||||
|
||||
1: j a0
|
||||
nop
|
||||
.set reorder
|
||||
.end promCopyIcacheFlush
|
||||
|
||||
|
||||
|
||||
.globl promCopyDcacheFlush
|
||||
.ent promCopyDcacheFlush
|
||||
.set noreorder
|
||||
promCopyDcacheFlush:
|
||||
move a0,ra
|
||||
|
||||
la t1,_promDcache
|
||||
lw t0,0(t1)
|
||||
nop
|
||||
beqz t0,1f
|
||||
|
||||
jal t0
|
||||
nop
|
||||
|
||||
1: j a0
|
||||
nop
|
||||
.set reorder
|
||||
.end promCopyDcacheFlush
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
** Function Name: IcacheFlush
|
||||
** Description: This functions flushes the on chip icache.
|
||||
*/
|
||||
|
||||
.globl IcacheFlush
|
||||
.ent IcacheFlush
|
||||
.set noreorder
|
||||
IcacheFlush:
|
||||
|
||||
1:
|
||||
@@ -763,8 +870,6 @@ IcacheFlush:
|
||||
li t0, M_BIU
|
||||
lw t1, 0(t0)
|
||||
|
||||
.set noreorder
|
||||
|
||||
# Isolate I cache
|
||||
mfc0 t3, C0_SR /* Read Status Register */
|
||||
nop
|
||||
@@ -778,7 +883,7 @@ IcacheFlush:
|
||||
|
||||
icache_write:
|
||||
sw zero, 0(t8) /* Store zero to memory addres in t8 */
|
||||
addu t8, 4 /* Increment t8 addres by 4 */
|
||||
addu t8, 4 /* Increment t8 address by 4 */
|
||||
bltu t8, t9, icache_write /* check to see if we are done */
|
||||
nop
|
||||
|
||||
@@ -798,12 +903,12 @@ icache_write:
|
||||
** Description: This functions flushes the on chip dcache.
|
||||
*/
|
||||
|
||||
.globl DcacheFlush
|
||||
|
||||
.ent DcacheFlush
|
||||
.set noreorder
|
||||
DcacheFlush:
|
||||
|
||||
# isolate icache
|
||||
.set noreorder
|
||||
mfc0 t3,C0_SR
|
||||
nop
|
||||
or t0, t3, SR_ISC
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* The original table from the application and our copy of it with
|
||||
* some changes.
|
||||
@@ -87,69 +88,88 @@ void bsp_pretasking_hook(void)
|
||||
|
||||
void bsp_start( void )
|
||||
{
|
||||
extern int WorkspaceBase;
|
||||
extern void mips_install_isr_entries();
|
||||
extern void _sys_exit(int);
|
||||
extern int WorkspaceBase;
|
||||
extern void mips_install_isr_entries();
|
||||
extern void mips_gdb_stub_install(void);
|
||||
|
||||
/* Configure Number of Register Caches */
|
||||
|
||||
/* Configure Number of Register Caches */
|
||||
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
||||
Cpu_table.interrupt_stack_size = 4096;
|
||||
|
||||
Cpu_table.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
||||
Cpu_table.interrupt_stack_size = 4096;
|
||||
/* HACK -- tied to value linkcmds */
|
||||
if ( BSP_Configuration.work_space_size > (4096*1024) )
|
||||
_sys_exit( 1 );
|
||||
|
||||
/* HACK -- tied to value linkcmds */
|
||||
if ( BSP_Configuration.work_space_size > (4096*1024) )
|
||||
_sys_exit( 1 );
|
||||
BSP_Configuration.work_space_start = (void *) &WorkspaceBase;
|
||||
|
||||
BSP_Configuration.work_space_start = (void *) &WorkspaceBase;
|
||||
/* mask off any interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER, 0 );
|
||||
|
||||
/* mask off any interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER, 0 );
|
||||
/* reset the config register & clear any pending peripheral interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, MONGOOSEV_UART_CMD_RESET_BOTH_PORTS );
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
||||
|
||||
MONGOOSEV_WRITE( MONGOOSEV_WATCHDOG, 0xA0 );
|
||||
/* reset both timers */
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||
|
||||
/* reset the config register & clear any pending peripheral interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, MONGOOSEV_UART_CMD_RESET_BOTH_PORTS );
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||
|
||||
/* reset both timers */
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||
/* clear any pending interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_STATUS_REGISTER, 0xffffffff );
|
||||
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||
/* clear any writable bits in the cause register */
|
||||
mips_set_cause( 0 );
|
||||
|
||||
/* clear any pending interrupts */
|
||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_STATUS_REGISTER, 0xffffffff );
|
||||
/* set interrupt mask, but globally off. */
|
||||
|
||||
/* clear any writable bits in the cause register */
|
||||
mips_set_cause( 0 );
|
||||
/*
|
||||
** Bit 15 | Bit 14 | Bit 13 | Bit 12 | Bit 11 | Bit 10 | Bit 9 | Bit 8 |
|
||||
** periph | unused | FPU | unused | timer2 | timer1 | swint1 | swint2 |
|
||||
** extern | | | | | | | |
|
||||
**
|
||||
** 1 0 1 0 0 1 0 0
|
||||
**
|
||||
** 0x8C00 Enable only internal Mongoose V timers.
|
||||
** 0xA400 Enable Peripherial ints, FPU and timer1
|
||||
** 0x0400 Timer1 only
|
||||
*/
|
||||
|
||||
/* set interrupt mask, but globally off. */
|
||||
/* mips_set_sr( (SR_CU0 | SR_CU1 | 0xA400) ); */
|
||||
|
||||
/*
|
||||
** Bit 15 | Bit 14 | Bit 13 | Bit 12 | Bit 11 | Bit 10 | Bit 9 | Bit 8 |
|
||||
** periph | unused | FPU | unused | timer2 | timer1 | swint1 | swint2 |
|
||||
** extern | | | | | | | |
|
||||
**
|
||||
** 1 0 1 0 0 1 0 0
|
||||
**
|
||||
** 0x8C00 Enable only internal Mongoose V timers.
|
||||
** 0xA400 Enable Peripherial ints, FPU and timer1
|
||||
*/
|
||||
/* to start up, only enable coprocessor 0 & timer int. per-task
|
||||
** processor settings will be applied as they are created, this
|
||||
** is just to configure the processor for startup
|
||||
*/
|
||||
mips_set_sr( (SR_CU0 | 0x400) );
|
||||
|
||||
mips_set_sr( (SR_CU0 | SR_CU1 | 0xA400) );
|
||||
|
||||
mips_install_isr_entries();
|
||||
mips_install_isr_entries();
|
||||
}
|
||||
|
||||
|
||||
void clear_cache( void *address, size_t n )
|
||||
|
||||
|
||||
void clear_cache( void )
|
||||
{
|
||||
extern void promCopyIcacheFlush(void); /* from start.S */
|
||||
extern void promCopyDcacheFlush(void);
|
||||
|
||||
promCopyIcacheFlush();
|
||||
promCopyDcacheFlush();
|
||||
}
|
||||
|
||||
/* Structure filled in by get_mem_info. Only the size field is
|
||||
actually used (to clear bss), so the others aren't even filled in. */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
//Structure filled in by get_mem_info.
|
||||
|
||||
|
||||
struct s_mem
|
||||
{
|
||||
@@ -159,11 +179,14 @@ struct s_mem
|
||||
};
|
||||
|
||||
|
||||
|
||||
extern unsigned32 _RamSize;
|
||||
|
||||
void get_mem_info ( struct s_mem *mem )
|
||||
{
|
||||
mem->size = (unsigned32)&_RamSize;
|
||||
mem->icsize = MONGOOSEV_IC_SIZE;
|
||||
mem->dcsize = MONGOOSEV_DC_SIZE;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
@@ -13,16 +13,103 @@
|
||||
|
||||
#include <rtems.h>
|
||||
#include <rtems/bspIo.h>
|
||||
#include <libcpu/mongoose-v.h>
|
||||
|
||||
#include <rtems/libio.h>
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
||||
We're going to call right down into the uart driver because we're
|
||||
operating within an exception. if things are broken because something
|
||||
bad happened, this may be our last chance to debug before RTEMS goes
|
||||
mad, so we won't rely on the I/O subsystem to be operating. This is a
|
||||
little messy, but at least we're not talking right to the hardware.
|
||||
|
||||
*/
|
||||
|
||||
extern int mg5uart_set_attributes(int minor,const struct termios *t);
|
||||
extern int mg5uart_open(int major,int minor, void *arg);
|
||||
extern int mg5uart_close(int major,int minor, void *arg);
|
||||
extern void mg5uart_write_polled(int minor, char c );
|
||||
extern int mg5uart_inbyte_nonblocking_polled(int minor);
|
||||
|
||||
|
||||
extern void mips_gdb_stub_install(void);
|
||||
|
||||
|
||||
static int debugUartEnabled = 0;
|
||||
|
||||
|
||||
|
||||
int mg5rdbgOpenGDBuart(int breakoninit)
|
||||
{
|
||||
struct termios t;
|
||||
memset(&t,0,sizeof(struct termios));
|
||||
|
||||
if( mg5uart_open(0,1,NULL) != RTEMS_SUCCESSFUL )
|
||||
{
|
||||
printf("gdbstub: Failed to open UART port 2\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
t.c_cflag |= B19200;
|
||||
t.c_cflag |= CS8;
|
||||
if( mg5uart_set_attributes(1,&t) != 0 )
|
||||
{
|
||||
printf("gdbstub: Failed to configure UART 2 for 19200N82\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
debugUartEnabled = -1;
|
||||
|
||||
/* set up vectoring for gdb */
|
||||
mips_gdb_stub_install();
|
||||
|
||||
printf("gdbstub: Remote GDB stub listening on UART 2 at 19200N82\n");
|
||||
|
||||
if( breakoninit )
|
||||
{
|
||||
/*
|
||||
break to gdb. We'll wait there for the operator to get their gdb
|
||||
going, then they can 'continue' or do whatever.
|
||||
*/
|
||||
mips_break(0);
|
||||
}
|
||||
|
||||
printf("gdbstub: User code running\n");
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
|
||||
void mg5rdbgCloseGDBuart(void)
|
||||
{
|
||||
mg5uart_close(0,1,NULL);
|
||||
debugUartEnabled = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
char getDebugChar (void)
|
||||
{
|
||||
return 0;
|
||||
if( debugUartEnabled )
|
||||
{
|
||||
int rv;
|
||||
|
||||
while( (rv = mg5uart_inbyte_nonblocking_polled(1)) < 0 );
|
||||
return (char)rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void putDebugChar (char c)
|
||||
{
|
||||
/* big hack */
|
||||
printk( "%c" );
|
||||
if( debugUartEnabled )
|
||||
return mg5uart_write_polled(1,c);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ ClockRate = DEFINED(ClockRate) ? ClockRate : 12000000;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
romstore : ORIGIN = 0xbfc40000, LENGTH = 4M
|
||||
ram : ORIGIN = 0x80020000, LENGTH = 4M
|
||||
}
|
||||
|
||||
@@ -42,7 +41,8 @@ SECTIONS
|
||||
*(.rel.dyn)
|
||||
PROVIDE (__runtime_reloc_stop = .);
|
||||
*(.fini)
|
||||
} >ram AT>romstore
|
||||
*(.gcc_except_table)
|
||||
} >ram
|
||||
|
||||
.ctors :
|
||||
{
|
||||
@@ -66,7 +66,7 @@ SECTIONS
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
.dtors :
|
||||
{
|
||||
@@ -77,9 +77,9 @@ SECTIONS
|
||||
|
||||
etext = .;
|
||||
_etext = .;
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
|
||||
/* . = .; */
|
||||
|
||||
.rdata :
|
||||
{
|
||||
@@ -87,7 +87,7 @@ SECTIONS
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r*)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
.data :
|
||||
{
|
||||
@@ -96,7 +96,7 @@ SECTIONS
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d*)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
|
||||
.lit8 :
|
||||
@@ -106,29 +106,28 @@ SECTIONS
|
||||
_gp = . + 0x8000;
|
||||
__global = _gp;
|
||||
*(.lit8)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
.lit4 :
|
||||
{
|
||||
*(.lit4)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
.sdata :
|
||||
{
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s*)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
.sbss :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
edata = .;
|
||||
_edata = .;
|
||||
_fbss = .;
|
||||
*(.sbss)
|
||||
*(.scommon)
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
|
||||
.bss :
|
||||
@@ -148,7 +147,7 @@ SECTIONS
|
||||
WorkspaceBase = .;
|
||||
end = .;
|
||||
_end = .;
|
||||
} >ram AT>romstore
|
||||
} >ram
|
||||
|
||||
|
||||
/*
|
||||
@@ -158,29 +157,29 @@ SECTIONS
|
||||
*/
|
||||
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) } AT>romstore
|
||||
.line 0 : { *(.line) } AT>romstore
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) } AT>romstore
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) } AT>romstore
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) } AT>romstore
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) } AT>romstore
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info) } AT>romstore
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) } AT>romstore
|
||||
.debug_line 0 : { *(.debug_line) } AT>romstore
|
||||
.debug_frame 0 : { *(.debug_frame)} AT>romstore
|
||||
.debug_str 0 : { *(.debug_str) } AT>romstore
|
||||
.debug_loc 0 : { *(.debug_loc) } AT>romstore
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) } AT>romstore
|
||||
.debug_info 0 : { *(.debug_info) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame)}
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) } AT>romstore
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) } AT>romstore
|
||||
.debug_typenames 0 : { *(.debug_typenames) } AT>romstore
|
||||
.debug_varnames 0 : { *(.debug_varnames) } AT>romstore
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user