- no full featured xcpt for bootloaders
- clear bss git-svn-id: http://moon:8086/svn/mips@29 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
@@ -31,34 +31,34 @@ ROMGEN=$(MIPS_HOME)/tools/romgen
|
|||||||
|
|
||||||
all: bootloader_flash
|
all: bootloader_flash
|
||||||
|
|
||||||
libsys: startup_boot.S kernel_boot.S libsys_boot.c ../libsys/xcpt.c
|
libsys: startup_boot.S kernel_boot.S libsys_boot.c
|
||||||
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
$(CC) $(CFLAGS) -c startup_boot.S -o startup.o
|
||||||
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
$(CC) $(CFLAGS) -c kernel_boot.S -o kernel.o
|
||||||
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
$(CC) $(CFLAGS) -c libsys_boot.c -o libsys.o
|
||||||
$(CC) $(CFLAGS) -c ../libsys/xcpt.c -o xcpt.o
|
|
||||||
|
|
||||||
bootloader: libsys bootloader.c
|
bootloader: libsys bootloader.c
|
||||||
$(CC) $(CFLAGS) -g -c bootloader.c
|
$(CC) $(CFLAGS) -g -c bootloader.c
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o xcpt.o libsys.o bootloader.o -o $@.elf $(LIBS) >$@.map
|
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o libsys.o bootloader.o -o $@.elf $(LIBS) >$@.map
|
||||||
$(OBJDUMP) -D $@.elf > $@.dis
|
$(OBJDUMP) -D $@.elf > $@.dis
|
||||||
$(OBJCOPY) $@.elf -O binary $@.ROM.bin
|
$(OBJCOPY) $@.elf -j ROM --output-target=binary $@.ROM.bin
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||||
$(ROMGEN) $@.ROM.bin 10 $(ENDIAN_FLAGS)
|
$(ROMGEN) $@.ROM.bin 11 $(ENDIAN_FLAGS)
|
||||||
|
|
||||||
bootloader_flash: libsys bootloader_with_flash.c
|
bootloader_flash: libsys bootloader_with_flash.c
|
||||||
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
||||||
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
$(CC) $(CFLAGS) -g -c ../cfiflash.c
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o $@.elf $(LIBS) >$@.map
|
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o libsys.o cfiflash.o bootloader_with_flash.o -o $@.elf $(LIBS) >$@.map
|
||||||
$(OBJDUMP) -D $@.elf > $@.dis
|
$(OBJDUMP) -D $@.elf > $@.dis
|
||||||
$(OBJCOPY) $@.elf -O binary $@.ROM.bin
|
$(OBJCOPY) $@.elf -j ROM --output-target=binary $@.ROM.bin
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||||
$(ROMGEN) $@.ROM.bin 11 $(ENDIAN_FLAGS)
|
$(ROMGEN) $@.ROM.bin 11 $(ENDIAN_FLAGS)
|
||||||
|
|
||||||
test: libsys test.c ../libsys/irq.c ../libsys/xcpt.c
|
test: libsys test.c ../libsys/irq.c ../libsys/kernel.S ../libsys/xcpt.c
|
||||||
$(CC) $(CFLAGS) -g -c test.c
|
$(CC) $(CFLAGS) -g -c test.c
|
||||||
$(CC) $(CFLAGS) -g -c ../libsys/irq.c
|
$(CC) $(CFLAGS) -g -c ../libsys/irq.c
|
||||||
$(CC) $(CFLAGS) -g -c ../libsys/xcpt.c
|
$(CC) $(CFLAGS) -g -c ../libsys/kernel.S
|
||||||
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o libsys.o irq.o xcpt.o test.o -o $@.elf $(LIBS) >$@.map
|
$(CC) $(CFLAGS) -c ../libsys/xcpt.c -o xcpt.o
|
||||||
|
$(LD) $(LFLAGS) $(LIB_DIRS) startup.o kernel.o irq.o xcpt.o libsys.o test.o -o $@.elf $(LIBS) >$@.map
|
||||||
$(OBJDUMP) -D $@.elf > $@.dis
|
$(OBJDUMP) -D $@.elf > $@.dis
|
||||||
$(OBJCOPY) $@.elf -j ROM --output-target=binary $@.ROM.bin
|
$(OBJCOPY) $@.elf -j ROM --output-target=binary $@.ROM.bin
|
||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ SECTIONS
|
|||||||
.data ORIGIN(ram) :
|
.data ORIGIN(ram) :
|
||||||
{
|
{
|
||||||
_ram_start = ALIGN(4);
|
_ram_start = ALIGN(4);
|
||||||
*(.*data) *(.*bss) *(.*common)
|
__bss_start = ALIGN(4);
|
||||||
|
*(.*bss)
|
||||||
|
_end = ALIGN(4);
|
||||||
} > ram
|
} > ram
|
||||||
|
|
||||||
.flash ORIGIN(flash) :
|
.flash ORIGIN(flash) :
|
||||||
|
|||||||
+23
-170
@@ -1,6 +1,3 @@
|
|||||||
#include <regdef.h>
|
|
||||||
#include <xcpt_asm.h>
|
|
||||||
|
|
||||||
.file "kernel.S"
|
.file "kernel.S"
|
||||||
|
|
||||||
.section .ktext,"ax"
|
.section .ktext,"ax"
|
||||||
@@ -16,178 +13,34 @@
|
|||||||
addiu $sp, -4
|
addiu $sp, -4
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
LEAF(_xcpt_handler)
|
_exc_handler:
|
||||||
|
|
||||||
.set noreorder
|
.set noreorder
|
||||||
.set noat
|
|
||||||
/* Note: exceptions do not save and restore registers k0 and k1.
|
|
||||||
* on entry, k1 = exception class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* allocate exception stack frame (on 8-byte boundary) */
|
# Set Error LED and ExcCode LEDs
|
||||||
subu k1, sp, XCP_SIZE
|
# Get Cause
|
||||||
srl k1, 3 /* shift right/left -> alligned on boundary */
|
mfc0 $26, $13
|
||||||
sll k1, 3
|
li $27, 0xC0000000
|
||||||
|
srl $26, 2
|
||||||
|
andi $26, 0x000F
|
||||||
|
or $26, $27
|
||||||
|
la $27, sys_led_port
|
||||||
|
sw $26, 0($27)
|
||||||
|
|
||||||
/* save enough registers to get by */
|
# wait for all interrupts = 0
|
||||||
sw AT, XCP_AT(k1)
|
$w4x: mfc0 $26, $13
|
||||||
sw v0, XCP_V0(k1)
|
nop
|
||||||
sw v1, XCP_V1(k1)
|
srl $26, 8
|
||||||
sw a0, XCP_A0(k1)
|
andi $26, 0xFF
|
||||||
sw a1, XCP_A1(k1)
|
bnez $26, $w4x
|
||||||
sw a2, XCP_A2(k1)
|
|
||||||
sw a3, XCP_A3(k1)
|
|
||||||
sw sp, XCP_SP(k1)
|
|
||||||
sw ra, XCP_RA(k1)
|
|
||||||
|
|
||||||
/* get coprocessor 0 exception state */
|
|
||||||
mfc0 a0, CP0_CR
|
|
||||||
mfc0 a1, CP0_SR
|
|
||||||
mfc0 a2, CP0_BADDR
|
|
||||||
mfc0 a3, CP0_EPC
|
|
||||||
|
|
||||||
/* we can safely use AT now */
|
|
||||||
.set at
|
|
||||||
|
|
||||||
/* switch to using sp to point at exception frame */
|
|
||||||
move sp, k1
|
|
||||||
|
|
||||||
/* nothing sensible to store for k0/k1, store zero */
|
|
||||||
sw zero, XCP_K0(sp)
|
|
||||||
sw zero, XCP_K1(sp)
|
|
||||||
|
|
||||||
/* we are now interruptible: dump all remaining state
|
|
||||||
* into the exception stack frame.
|
|
||||||
*/
|
|
||||||
/* coprocessor exception state */
|
|
||||||
sw a0, XCP_CR(sp)
|
|
||||||
sw a1, XCP_SR(sp)
|
|
||||||
sw a2, XCP_BADDR(sp)
|
|
||||||
sw a3, XCP_EPC(sp)
|
|
||||||
|
|
||||||
/* mdhi and mdlo */
|
|
||||||
mfhi v0
|
|
||||||
mflo v1
|
|
||||||
sw v0, XCP_MDHI(sp)
|
|
||||||
sw v1, XCP_MDLO(sp)
|
|
||||||
|
|
||||||
/* Save all the other general registers.
|
|
||||||
* We save zero, s0-s7 and s8 as well, as instruction emulators (e.g. FP
|
|
||||||
* operations) and debuggers rely on all registers stored together in
|
|
||||||
* well-defined structure.
|
|
||||||
*/
|
|
||||||
sw zero, XCP_ZERO(sp)
|
|
||||||
sw t0, XCP_T0(sp)
|
|
||||||
sw t1, XCP_T1(sp)
|
|
||||||
sw t2, XCP_T2(sp)
|
|
||||||
sw t3, XCP_T3(sp)
|
|
||||||
sw t4, XCP_T4(sp)
|
|
||||||
sw t5, XCP_T5(sp)
|
|
||||||
sw t6, XCP_T6(sp)
|
|
||||||
sw t7, XCP_T7(sp)
|
|
||||||
sw s0, XCP_S0(sp)
|
|
||||||
sw s1, XCP_S1(sp)
|
|
||||||
sw s2, XCP_S2(sp)
|
|
||||||
sw s3, XCP_S3(sp)
|
|
||||||
sw s4, XCP_S4(sp)
|
|
||||||
sw s5, XCP_S5(sp)
|
|
||||||
sw s6, XCP_S6(sp)
|
|
||||||
sw s7, XCP_S7(sp)
|
|
||||||
sw t8, XCP_T8(sp)
|
|
||||||
sw t9, XCP_T9(sp)
|
|
||||||
sw gp, XCP_GP(sp)
|
|
||||||
sw s8, XCP_S8(sp)
|
|
||||||
|
|
||||||
/* I don't know what the following does. [rb] */
|
|
||||||
/* load our _gp pointer */
|
|
||||||
# la gp, _gp
|
|
||||||
|
|
||||||
/* and call the C exception handler */
|
|
||||||
move a0, sp # arg1 = &xcp
|
|
||||||
subu sp, 16 # (arg save area)
|
|
||||||
j _xcpt_call
|
|
||||||
move ra, zero # fake return address
|
|
||||||
|
|
||||||
/* This strange call to _xcpt_call with zero return address is to
|
|
||||||
* help exception-aware debuggers to trace back over the exception event.
|
|
||||||
* We are basically interposing a bogus stackframe (with a zero return
|
|
||||||
* address) between the C exception handler and the actual machine
|
|
||||||
* exception.
|
|
||||||
*/
|
|
||||||
$xcptrest:
|
|
||||||
.set noat
|
|
||||||
add AT, sp, 16
|
|
||||||
|
|
||||||
/* at points to exception frame */
|
|
||||||
$xcptrestother:
|
|
||||||
/* restore all state */
|
|
||||||
/* restore most general registers */
|
|
||||||
lw t0, XCP_T0(AT)
|
|
||||||
lw t1, XCP_T1(AT)
|
|
||||||
lw t2, XCP_T2(AT)
|
|
||||||
lw t3, XCP_T3(AT)
|
|
||||||
lw t4, XCP_T4(AT)
|
|
||||||
lw t5, XCP_T5(AT)
|
|
||||||
lw t6, XCP_T6(AT)
|
|
||||||
lw t7, XCP_T7(AT)
|
|
||||||
lw s0, XCP_S0(AT)
|
|
||||||
lw s1, XCP_S1(AT)
|
|
||||||
lw s2, XCP_S2(AT)
|
|
||||||
lw s3, XCP_S3(AT)
|
|
||||||
lw s4, XCP_S4(AT)
|
|
||||||
lw s5, XCP_S5(AT)
|
|
||||||
lw s6, XCP_S6(AT)
|
|
||||||
lw s7, XCP_S7(AT)
|
|
||||||
lw t8, XCP_T8(AT)
|
|
||||||
lw t9, XCP_T9(AT)
|
|
||||||
lw gp, XCP_GP(AT)
|
|
||||||
lw s8, XCP_S8(AT)
|
|
||||||
|
|
||||||
/* mdhi and mdlo */
|
|
||||||
lw v0, XCP_MDHI(AT)
|
|
||||||
lw v1, XCP_MDLO(AT)
|
|
||||||
mthi v0
|
|
||||||
mtlo v1
|
|
||||||
|
|
||||||
/* remaining general registers */
|
|
||||||
lw a0, XCP_A0(AT)
|
|
||||||
lw a1, XCP_A1(AT)
|
|
||||||
lw a2, XCP_A2(AT)
|
|
||||||
lw a3, XCP_A3(AT)
|
|
||||||
lw ra, XCP_RA(AT)
|
|
||||||
|
|
||||||
/* restore the exception-time status register */
|
|
||||||
.set noreorder
|
|
||||||
lw v0, XCP_SR(AT)
|
|
||||||
nop
|
nop
|
||||||
mtc0 v0, CP0_SR
|
|
||||||
lw v1, XCP_V1(AT)
|
|
||||||
lw v0, XCP_V0(AT)
|
|
||||||
lw sp, XCP_SP(AT)
|
|
||||||
|
|
||||||
/* we are not uninterruptible and can use k1 safely */
|
# Get return address
|
||||||
lw k1, XCP_EPC(AT)
|
mfc0 $26, $14
|
||||||
lw AT, XCP_AT(AT)
|
|
||||||
mtc0 k1, CP0_EPC
|
# Return
|
||||||
j k1
|
nop
|
||||||
|
jr $26
|
||||||
rfe
|
rfe
|
||||||
|
|
||||||
.set reorder
|
.set reorder
|
||||||
.set at
|
|
||||||
END(_xcpt_handler)
|
|
||||||
|
|
||||||
|
|
||||||
LEAF(_xcpt_call)
|
|
||||||
/* on entry: a0 == &xcp */
|
|
||||||
subu sp, 24
|
|
||||||
sw ra, 16(sp)
|
|
||||||
|
|
||||||
/* punt out to _xcpt_deliver */
|
|
||||||
jal _xcpt_deliver
|
|
||||||
nop
|
|
||||||
lw ra, 16(sp)
|
|
||||||
addu sp, 24
|
|
||||||
beqz ra, $xcptrest
|
|
||||||
nop
|
|
||||||
j ra
|
|
||||||
nop
|
|
||||||
END(_xcpt_call)
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ void _exit(int reason)
|
|||||||
void libsys_init()
|
void libsys_init()
|
||||||
{
|
{
|
||||||
// Initialzie interrupt support
|
// Initialzie interrupt support
|
||||||
interrupt_init();
|
// interrupt_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MIPS specific
|
// MIPS specific
|
||||||
@@ -110,10 +110,9 @@ void _putchar(char c)
|
|||||||
writechar(c);
|
writechar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sputs(char *pStr)
|
int sputs(char const *pStr)
|
||||||
{
|
{
|
||||||
char *start;
|
char const *start = pStr;
|
||||||
start = pStr;
|
|
||||||
|
|
||||||
while(*pStr)
|
while(*pStr)
|
||||||
_putchar(*(pStr++));
|
_putchar(*(pStr++));
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ uint32_t CP0_PRID_read(void);
|
|||||||
char readchar(void);
|
char readchar(void);
|
||||||
void writechar(char c);
|
void writechar(char c);
|
||||||
int write(int file, char *ptr, int len);
|
int write(int file, char *ptr, int len);
|
||||||
int sputs(char *pStr);
|
int sputs(char const *pStr);
|
||||||
void print_byte(char byte);
|
void print_byte(char byte);
|
||||||
void print_word(int word);
|
void print_word(int word);
|
||||||
void PrintBuffer8(uint8_t *pBuf, int nbpr, int len);
|
void PrintBuffer8(uint8_t *pBuf, int nbpr, int len);
|
||||||
|
|||||||
@@ -27,6 +27,14 @@ _start:
|
|||||||
# Invalidate D-Cache
|
# Invalidate D-Cache
|
||||||
cop0 34
|
cop0 34
|
||||||
|
|
||||||
|
# zero bss
|
||||||
|
la $8, __bss_start
|
||||||
|
la $9, _end
|
||||||
|
$zeroise:
|
||||||
|
sw $0, 0($8)
|
||||||
|
bne $8, $9, $zeroise
|
||||||
|
addiu $8, 4
|
||||||
|
|
||||||
_init:
|
_init:
|
||||||
# Call libsys_init
|
# Call libsys_init
|
||||||
la $k0, libsys_init
|
la $k0, libsys_init
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ void main()
|
|||||||
|
|
||||||
// UART: enable RX interrupt
|
// UART: enable RX interrupt
|
||||||
*pUART0_stat |= (1 << 6);
|
*pUART0_stat |= (1 << 6);
|
||||||
|
|
||||||
|
CP0_SR_write(0x0060000D);
|
||||||
interrupt_enable(3);
|
interrupt_enable(3);
|
||||||
|
|
||||||
sputs("Hello, world!\n");
|
sputs("Hello, world!\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user