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>
|
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.
|
program is located there.
|
||||||
|
|
||||||
The default output of an RTEMS link is an image linked to run from
|
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
|
0x80020000. It is suitable for copying to S3 records or can be burned
|
||||||
for copying to S3 records or can be burned to ROMs in whatever manner
|
to ROMs in whatever manner the user desires. If you want to locate the
|
||||||
the user desires.
|
image into ROM at some other address, use mips-rtems-objcopy to shift
|
||||||
|
the LMA.
|
||||||
|
|
||||||
Operation
|
Operation
|
||||||
=========
|
=========
|
||||||
@@ -67,7 +68,51 @@ linkcmds.
|
|||||||
|
|
||||||
Before relocating the RTEMS image, the bsp startup routine attempts to
|
Before relocating the RTEMS image, the bsp startup routine attempts to
|
||||||
configure the processor into a rational state. During this process,
|
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
|
Questions
|
||||||
@@ -84,6 +129,51 @@ when sending them fast?
|
|||||||
somewhat faulty UART design.
|
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:
|
*startfile:
|
||||||
%{!qrtems: %(old_startfile)} %{qrtems: \
|
%{!qrtems: %(old_startfile)} %{qrtems: \
|
||||||
%{!qrtems_debug: start.o%s} \
|
%{!qnostartfile: %{!qrtems_debug: start.o%s} \
|
||||||
%{qrtems_debug: start_g.o%s}}
|
%{qrtems_debug: start_g.o%s}}}
|
||||||
|
|
||||||
*link:
|
*link:
|
||||||
%(old_link) %{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e _start}
|
%(old_link) %{!qrtems: %(old_link)} %{qrtems: -dc -dp -N -e _start}
|
||||||
|
|||||||
@@ -48,15 +48,6 @@
|
|||||||
#endif
|
#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
|
** defined by linkcmds, pointing to the start of the relocation target
|
||||||
** memory, referenced in this way so we can avoid defining it
|
** memory, referenced in this way so we can avoid defining it
|
||||||
@@ -84,7 +75,6 @@
|
|||||||
.globl putch_rom
|
.globl putch_rom
|
||||||
_start:
|
_start:
|
||||||
.set noreorder
|
.set noreorder
|
||||||
move k1,ra /* save ra so we can optionally return to caller */
|
|
||||||
$LF1 = . + 8
|
$LF1 = . + 8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -131,6 +121,42 @@ _branch:
|
|||||||
jal t0
|
jal t0
|
||||||
nop
|
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.
|
** Call IcacheFlush. Masking used to call EEPROM address of IcacheFlush. Label is RAM label.
|
||||||
*/
|
*/
|
||||||
@@ -139,6 +165,7 @@ _branch:
|
|||||||
la t0,IcacheFlush
|
la t0,IcacheFlush
|
||||||
and t0,0x0000ffff
|
and t0,0x0000ffff
|
||||||
or t0,t2
|
or t0,t2
|
||||||
|
move k0,t0 /* save cache flush in-prom address */
|
||||||
jal t0
|
jal t0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@@ -177,10 +204,12 @@ _branch:
|
|||||||
la t0,putch_rom
|
la t0,putch_rom
|
||||||
and t0,0x0000ffff
|
and t0,0x0000ffff
|
||||||
or t0,t2
|
or t0,t2
|
||||||
|
move k1,t0 /* save cache flush in-prom address */
|
||||||
jal t0
|
jal t0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
|
||||||
|
1:
|
||||||
/*
|
/*
|
||||||
** Print ' RTEMS b'. Show that we are booting.
|
** Print ' RTEMS b'. Show that we are booting.
|
||||||
*/
|
*/
|
||||||
@@ -277,16 +306,16 @@ _branch:
|
|||||||
la t0,putch_rom
|
la t0,putch_rom
|
||||||
and t0,0x0000ffff
|
and t0,0x0000ffff
|
||||||
or t0,t2
|
or t0,t2
|
||||||
jal t0
|
jal t0
|
||||||
nop
|
nop
|
||||||
|
|
||||||
la a3, _edata
|
la a3, _edata
|
||||||
relocate:
|
relocate:
|
||||||
lw t0, (a1) /* load from EEPROM */
|
lw t0, (a1) /* load from EEPROM */
|
||||||
addu a1, 4
|
addu a1, 4
|
||||||
sw t0, (a2) /* store to RAM */
|
sw t0, (a2) /* store to RAM */
|
||||||
addu a2, 4
|
addu a2, 4
|
||||||
bne a2, a3, relocate /* copied all the way to edata? */
|
bne a2, a3, relocate /* copied all the way to edata? */
|
||||||
nop
|
nop
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -317,11 +346,11 @@ _start_in_ram:
|
|||||||
/*
|
/*
|
||||||
** Print 'S'. Already in RAM no need to reference EEPROM address.
|
** Print 'S'. Already in RAM no need to reference EEPROM address.
|
||||||
*/
|
*/
|
||||||
li a0,'S'
|
li a0,'S'
|
||||||
jal putch_rom
|
jal putch_rom
|
||||||
nop
|
nop
|
||||||
|
|
||||||
la gp, _gp /* set the global data pointer */
|
la gp, _gp /* set the global data pointer */
|
||||||
.end _start_in_ram
|
.end _start_in_ram
|
||||||
|
|
||||||
|
|
||||||
@@ -341,12 +370,12 @@ zerobss:
|
|||||||
jal putch_rom
|
jal putch_rom
|
||||||
nop
|
nop
|
||||||
|
|
||||||
la v0, _fbss
|
la v0, _fbss
|
||||||
la v1, _end
|
la v1, _end
|
||||||
3:
|
3:
|
||||||
sw zero,0(v0)
|
sw zero,0(v0)
|
||||||
bltu v0,v1,3b
|
bltu v0,v1,3b
|
||||||
addiu v0,v0,4 /* executed in delay slot */
|
addiu v0,v0,4 /* executed in delay slot */
|
||||||
|
|
||||||
la t0, _stack_init /* initialize stack so we */
|
la t0, _stack_init /* initialize stack so we */
|
||||||
|
|
||||||
@@ -368,8 +397,8 @@ zerobss:
|
|||||||
/*
|
/*
|
||||||
** Print 'Z'. Finished zeroing bss.
|
** Print 'Z'. Finished zeroing bss.
|
||||||
*/
|
*/
|
||||||
li a0,'Z'
|
li a0,'Z'
|
||||||
jal putch_rom
|
jal putch_rom
|
||||||
nop
|
nop
|
||||||
|
|
||||||
.end zerobss
|
.end zerobss
|
||||||
@@ -387,12 +416,26 @@ _init:
|
|||||||
/*
|
/*
|
||||||
** Print 'i'. Starting to initialize RTEMS.
|
** Print 'i'. Starting to initialize RTEMS.
|
||||||
*/
|
*/
|
||||||
li a0, 'i'
|
li a0, 'i'
|
||||||
jal putch_rom
|
jal putch_rom
|
||||||
nop
|
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
|
nop
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -748,13 +791,77 @@ _cpuinit:
|
|||||||
.end _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
|
** Function Name: IcacheFlush
|
||||||
** Description: This functions flushes the on chip icache.
|
** Description: This functions flushes the on chip icache.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.globl IcacheFlush
|
|
||||||
.ent IcacheFlush
|
.ent IcacheFlush
|
||||||
|
.set noreorder
|
||||||
IcacheFlush:
|
IcacheFlush:
|
||||||
|
|
||||||
1:
|
1:
|
||||||
@@ -763,8 +870,6 @@ IcacheFlush:
|
|||||||
li t0, M_BIU
|
li t0, M_BIU
|
||||||
lw t1, 0(t0)
|
lw t1, 0(t0)
|
||||||
|
|
||||||
.set noreorder
|
|
||||||
|
|
||||||
# Isolate I cache
|
# Isolate I cache
|
||||||
mfc0 t3, C0_SR /* Read Status Register */
|
mfc0 t3, C0_SR /* Read Status Register */
|
||||||
nop
|
nop
|
||||||
@@ -778,7 +883,7 @@ IcacheFlush:
|
|||||||
|
|
||||||
icache_write:
|
icache_write:
|
||||||
sw zero, 0(t8) /* Store zero to memory addres in t8 */
|
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 */
|
bltu t8, t9, icache_write /* check to see if we are done */
|
||||||
nop
|
nop
|
||||||
|
|
||||||
@@ -798,12 +903,12 @@ icache_write:
|
|||||||
** Description: This functions flushes the on chip dcache.
|
** Description: This functions flushes the on chip dcache.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.globl DcacheFlush
|
|
||||||
.ent DcacheFlush
|
.ent DcacheFlush
|
||||||
|
.set noreorder
|
||||||
DcacheFlush:
|
DcacheFlush:
|
||||||
|
|
||||||
# isolate icache
|
# isolate icache
|
||||||
.set noreorder
|
|
||||||
mfc0 t3,C0_SR
|
mfc0 t3,C0_SR
|
||||||
nop
|
nop
|
||||||
or t0, t3, SR_ISC
|
or t0, t3, SR_ISC
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The original table from the application and our copy of it with
|
* The original table from the application and our copy of it with
|
||||||
* some changes.
|
* some changes.
|
||||||
@@ -87,69 +88,88 @@ void bsp_pretasking_hook(void)
|
|||||||
|
|
||||||
void bsp_start( void )
|
void bsp_start( void )
|
||||||
{
|
{
|
||||||
extern int WorkspaceBase;
|
extern void _sys_exit(int);
|
||||||
extern void mips_install_isr_entries();
|
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.pretasking_hook = bsp_pretasking_hook; /* init libc, etc. */
|
||||||
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
Cpu_table.postdriver_hook = bsp_postdriver_hook;
|
||||||
Cpu_table.interrupt_stack_size = 4096;
|
Cpu_table.interrupt_stack_size = 4096;
|
||||||
|
|
||||||
/* HACK -- tied to value linkcmds */
|
/* HACK -- tied to value linkcmds */
|
||||||
if ( BSP_Configuration.work_space_size > (4096*1024) )
|
if ( BSP_Configuration.work_space_size > (4096*1024) )
|
||||||
_sys_exit( 1 );
|
_sys_exit( 1 );
|
||||||
|
|
||||||
BSP_Configuration.work_space_start = (void *) &WorkspaceBase;
|
BSP_Configuration.work_space_start = (void *) &WorkspaceBase;
|
||||||
|
|
||||||
/* mask off any interrupts */
|
/* mask off any interrupts */
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER, 0 );
|
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_FUNCTION_INTERRUPT_MASK_REGISTER, 0 );
|
||||||
|
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_WATCHDOG, 0xA0 );
|
/* 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 );
|
||||||
|
|
||||||
/* reset the config register & clear any pending peripheral interrupts */
|
/* reset both timers */
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, MONGOOSEV_UART_CMD_RESET_BOTH_PORTS );
|
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_COMMAND_REGISTER, 0 );
|
|
||||||
|
|
||||||
/* reset both timers */
|
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
||||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
||||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER1_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
|
||||||
|
|
||||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_INITIAL_COUNTER_REGISTER, 0xffffffff );
|
/* clear any pending interrupts */
|
||||||
MONGOOSEV_WRITE_REGISTER( MONGOOSEV_TIMER2_BASE, MONGOOSEV_TIMER_CONTROL_REGISTER, 0);
|
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_STATUS_REGISTER, 0xffffffff );
|
||||||
|
|
||||||
/* clear any pending interrupts */
|
/* clear any writable bits in the cause register */
|
||||||
MONGOOSEV_WRITE( MONGOOSEV_PERIPHERAL_STATUS_REGISTER, 0xffffffff );
|
mips_set_cause( 0 );
|
||||||
|
|
||||||
/* clear any writable bits in the cause register */
|
/* set interrupt mask, but globally off. */
|
||||||
mips_set_cause( 0 );
|
|
||||||
|
|
||||||
/* set interrupt mask, but globally off. */
|
/*
|
||||||
|
** 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
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
mips_set_sr( (SR_CU0 | SR_CU1 | 0xA400) );
|
/* 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_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
|
struct s_mem
|
||||||
{
|
{
|
||||||
@@ -159,11 +179,14 @@ struct s_mem
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern unsigned32 _RamSize;
|
extern unsigned32 _RamSize;
|
||||||
|
|
||||||
void get_mem_info ( struct s_mem *mem )
|
void get_mem_info ( struct s_mem *mem )
|
||||||
{
|
{
|
||||||
mem->size = (unsigned32)&_RamSize;
|
mem->size = (unsigned32)&_RamSize;
|
||||||
|
mem->icsize = MONGOOSEV_IC_SIZE;
|
||||||
|
mem->dcsize = MONGOOSEV_DC_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -13,16 +13,103 @@
|
|||||||
|
|
||||||
#include <rtems.h>
|
#include <rtems.h>
|
||||||
#include <rtems/bspIo.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)
|
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)
|
void putDebugChar (char c)
|
||||||
{
|
{
|
||||||
/* big hack */
|
if( debugUartEnabled )
|
||||||
printk( "%c" );
|
return mg5uart_write_polled(1,c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ ClockRate = DEFINED(ClockRate) ? ClockRate : 12000000;
|
|||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
romstore : ORIGIN = 0xbfc40000, LENGTH = 4M
|
|
||||||
ram : ORIGIN = 0x80020000, LENGTH = 4M
|
ram : ORIGIN = 0x80020000, LENGTH = 4M
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +41,8 @@ SECTIONS
|
|||||||
*(.rel.dyn)
|
*(.rel.dyn)
|
||||||
PROVIDE (__runtime_reloc_stop = .);
|
PROVIDE (__runtime_reloc_stop = .);
|
||||||
*(.fini)
|
*(.fini)
|
||||||
} >ram AT>romstore
|
*(.gcc_except_table)
|
||||||
|
} >ram
|
||||||
|
|
||||||
.ctors :
|
.ctors :
|
||||||
{
|
{
|
||||||
@@ -66,7 +66,7 @@ SECTIONS
|
|||||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
KEEP (*(SORT(.ctors.*)))
|
KEEP (*(SORT(.ctors.*)))
|
||||||
KEEP (*(.ctors))
|
KEEP (*(.ctors))
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
.dtors :
|
.dtors :
|
||||||
{
|
{
|
||||||
@@ -77,9 +77,9 @@ SECTIONS
|
|||||||
|
|
||||||
etext = .;
|
etext = .;
|
||||||
_etext = .;
|
_etext = .;
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
|
|
||||||
/* . = .; */
|
|
||||||
|
|
||||||
.rdata :
|
.rdata :
|
||||||
{
|
{
|
||||||
@@ -87,7 +87,7 @@ SECTIONS
|
|||||||
*(.rodata)
|
*(.rodata)
|
||||||
*(.rodata.*)
|
*(.rodata.*)
|
||||||
*(.gnu.linkonce.r*)
|
*(.gnu.linkonce.r*)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
.data :
|
.data :
|
||||||
{
|
{
|
||||||
@@ -96,7 +96,7 @@ SECTIONS
|
|||||||
*(.data)
|
*(.data)
|
||||||
*(.data.*)
|
*(.data.*)
|
||||||
*(.gnu.linkonce.d*)
|
*(.gnu.linkonce.d*)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
|
|
||||||
.lit8 :
|
.lit8 :
|
||||||
@@ -106,29 +106,28 @@ SECTIONS
|
|||||||
_gp = . + 0x8000;
|
_gp = . + 0x8000;
|
||||||
__global = _gp;
|
__global = _gp;
|
||||||
*(.lit8)
|
*(.lit8)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
.lit4 :
|
.lit4 :
|
||||||
{
|
{
|
||||||
*(.lit4)
|
*(.lit4)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
.sdata :
|
.sdata :
|
||||||
{
|
{
|
||||||
*(.sdata)
|
*(.sdata)
|
||||||
*(.sdata.*)
|
*(.sdata.*)
|
||||||
*(.gnu.linkonce.s*)
|
*(.gnu.linkonce.s*)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
.sbss :
|
.sbss :
|
||||||
{
|
{
|
||||||
. = ALIGN(4);
|
|
||||||
edata = .;
|
edata = .;
|
||||||
_edata = .;
|
_edata = .;
|
||||||
_fbss = .;
|
_fbss = .;
|
||||||
*(.sbss)
|
*(.sbss)
|
||||||
*(.scommon)
|
*(.scommon)
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
@@ -148,7 +147,7 @@ SECTIONS
|
|||||||
WorkspaceBase = .;
|
WorkspaceBase = .;
|
||||||
end = .;
|
end = .;
|
||||||
_end = .;
|
_end = .;
|
||||||
} >ram AT>romstore
|
} >ram
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -158,29 +157,29 @@ SECTIONS
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* DWARF 1 */
|
/* DWARF 1 */
|
||||||
.debug 0 : { *(.debug) } AT>romstore
|
.debug 0 : { *(.debug) }
|
||||||
.line 0 : { *(.line) } AT>romstore
|
.line 0 : { *(.line) }
|
||||||
|
|
||||||
/* GNU DWARF 1 extensions */
|
/* GNU DWARF 1 extensions */
|
||||||
.debug_srcinfo 0 : { *(.debug_srcinfo) } AT>romstore
|
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||||
.debug_sfnames 0 : { *(.debug_sfnames) } AT>romstore
|
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||||
|
|
||||||
/* DWARF 1.1 and DWARF 2 */
|
/* DWARF 1.1 and DWARF 2 */
|
||||||
.debug_aranges 0 : { *(.debug_aranges) } AT>romstore
|
.debug_aranges 0 : { *(.debug_aranges) }
|
||||||
.debug_pubnames 0 : { *(.debug_pubnames) } AT>romstore
|
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||||
|
|
||||||
/* DWARF 2 */
|
/* DWARF 2 */
|
||||||
.debug_info 0 : { *(.debug_info) } AT>romstore
|
.debug_info 0 : { *(.debug_info) }
|
||||||
.debug_abbrev 0 : { *(.debug_abbrev) } AT>romstore
|
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||||
.debug_line 0 : { *(.debug_line) } AT>romstore
|
.debug_line 0 : { *(.debug_line) }
|
||||||
.debug_frame 0 : { *(.debug_frame)} AT>romstore
|
.debug_frame 0 : { *(.debug_frame)}
|
||||||
.debug_str 0 : { *(.debug_str) } AT>romstore
|
.debug_str 0 : { *(.debug_str) }
|
||||||
.debug_loc 0 : { *(.debug_loc) } AT>romstore
|
.debug_loc 0 : { *(.debug_loc) }
|
||||||
.debug_macinfo 0 : { *(.debug_macinfo) } AT>romstore
|
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||||
|
|
||||||
/* SGI/MIPS DWARF 2 extensions */
|
/* SGI/MIPS DWARF 2 extensions */
|
||||||
.debug_weaknames 0 : { *(.debug_weaknames) } AT>romstore
|
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||||
.debug_funcnames 0 : { *(.debug_funcnames) } AT>romstore
|
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||||
.debug_typenames 0 : { *(.debug_typenames) } AT>romstore
|
.debug_typenames 0 : { *(.debug_typenames) }
|
||||||
.debug_varnames 0 : { *(.debug_varnames) } AT>romstore
|
.debug_varnames 0 : { *(.debug_varnames) }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user