1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-04-21 12:27:27 +03:00

Adding lm32 demo to SAKC project

This commit is contained in:
Carlos Camargo
2010-05-25 21:49:58 -05:00
parent 26b0c73a84
commit 61d4408f2a
145 changed files with 27924 additions and 1501 deletions

View File

@@ -0,0 +1,50 @@
LM32_CC=lm32-elf-gcc
LM32_LD=lm32-elf-ld
LM32_OBJCOPY=lm32-elf-objcopy
LM32_OBJDUMP=lm32-elf-objdump
SREC2VRAM ?= ../../tools/srec2vram/srec2vram
VRAMFILE=image.ram
CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled
LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld
SEGMENTS = -j .text -j .rodata -j .data
all: $(VRAMFILE)
crt0ram.o: crt0ram.S
$(LM32_CC) $(CFLAGS) -c crt0ram.S
main.o: main.c
$(LM32_CC) $(CFLAGS) -c main.c
soc-hw.o: soc-hw.c
$(LM32_CC) $(CFLAGS) -c soc-hw.c
image: crt0ram.o main.o soc-hw.o
$(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o soc-hw.o
image.lst: image
$(LM32_OBJDUMP) -h -S $< > $@
image.bin: image
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.bin
image.srec: image image.lst
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec
$(VHDLFILE): image.srec
$(SREC2VHDL) image.srec > $(VHDLFILE)
$(VRAMFILE): image.srec
$(SREC2VRAM) image.srec 0x00000000 0x1000 > $(VRAMFILE)
clean:
rm -f image image.lst image.bin image.srec image.map *.o *.d
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

View File

@@ -0,0 +1,85 @@
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Exception handlers - Must be 32 bytes long. */
.section .text, "ax", @progbits
.global _start
.global irq_enable, irq_disable, irq_mask, jump, halt
_start:
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
nop
_crt0:
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
/* Clear BSS */
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
.clearBSS:
be r1, r3, .callMain
sw (r1+0), r0
addi r1, r1, 4
bi .clearBSS
.callMain:
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
irq_enable:
mvi r1, 1
wcsr IE, r1
ret
irq_mask:
mvi r1, 0x0000000f
wcsr IM, r1
ret
irq_disable:
mvi r1, 0
wcsr IE, r1
ret
jump:
b r1
halt:
bi halt

View File

@@ -0,0 +1 @@
crt0ram.o: crt0ram.S

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,44 @@
S00C0000696D6167652E62696E89
S113000098000000D00000007801000038210000B2
S1130010D0E10000F80000033400000034000000C8
S1130020781C00003B9C0FFC781A00003B5A02A08D
S11300307801000038210298780300003863029C9C
S1130040442300045820000034210004E3FFFFFD92
S1130050340100003402000034030000F800001DE5
S113006034010001D0010000C3A000003401000FDE
S1130070D0210000C3A0000034010000D001000022
S1130080C3A00000C0200000E0000000379CFFF87F
S11300905B8B00085B9D0004F80000573C2B0008B4
S11300A0F8000055B56108003C2B0008F800005228
S11300B0B56108003C2B0008F800004FB56108004A
S11300C02B9D00042B8B0008379C0008C3A0000064
S11300D0379CFFE45B8B001C5B8C00185B8D001469
S11300E05B8E00105B8F000C5B9000085B9D00042E
S11300F0F8000040340D00673401002A340E007506
S1130100340F006478100000442D0008442E0016BB
S1130110442F000ABA00080038210270F800004891
S1130120F80000355C2DFFFAFBFFFFD9FBFFFFD67B
S1130130F8000031E3FFFFFCFBFFFFD5B8205800B7
S1130140FBFFFFD3B5616000516CFFF64161000015
S1130150356B0001F8000031558BFFFDF8000026D7
S1130160E3FFFFF1FBFFFFCAB8205800FBFFFFC805
S1130170B5616000516CFFEBF800001F31610000B5
S1130180356B0001558BFFFDF800001BE3FFFFE614
S113019078020000384202903803C350284200001D
S11301A0882308005841001034010000584100140D
S11301B03401000A5841000C2841000C20210001A0
S11301C04420FFFEC3A00000780100003821029003
S11301D0282100003802C3505822000434020000D1
S11301E0582200083402000E58220000C3A0000068
S11301F0C3A00000780100003821028C28220000EE
S113020028410000202100014420FFFE2841000471
S1130210202100FFC3A00000780200003842028CB5
S113022028430000202100FF286200002042001023
S11302305C40FFFE58610004C3A00000402400009D
S11302404480000B780200003842028C28430000EE
S113025028620000204200105C40FFFE5864000445
S113026034210001402400005C82FFFAC3A0000096
S11302702A2A53414B432F626F6F746C6F6164651C
S10F0280722A2A203E200D0A0000000013
S10F028CF0000000F0010000F00200008F
S9030000FC

View File

@@ -0,0 +1,454 @@
image: file format elf32-lm32
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000270 00000000 00000000 00000054 2**2
CONTENTS, ALLOC, LOAD, CODE
1 .rodata 0000001c 00000270 00000270 000002c4 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .data 0000000c 0000028c 0000028c 000002e0 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .bss 00000004 00000298 00000298 000002ec 2**2
ALLOC
4 .debug_abbrev 00000219 00000000 00000000 000002ec 2**0
CONTENTS, READONLY, DEBUGGING
5 .debug_info 000003d0 00000000 00000000 00000505 2**0
CONTENTS, READONLY, DEBUGGING
6 .debug_line 000002d8 00000000 00000000 000008d5 2**0
CONTENTS, READONLY, DEBUGGING
7 .debug_frame 000000a0 00000000 00000000 00000bb0 2**2
CONTENTS, READONLY, DEBUGGING
8 .debug_loc 000000fb 00000000 00000000 00000c50 2**0
CONTENTS, READONLY, DEBUGGING
9 .debug_pubnames 000000bc 00000000 00000000 00000d4b 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_aranges 00000040 00000000 00000000 00000e07 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_ranges 00000018 00000000 00000000 00000e47 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_str 0000017b 00000000 00000000 00000e5f 2**0
CONTENTS, READONLY, DEBUGGING
13 .comment 00000011 00000000 00000000 00000fda 2**0
CONTENTS, READONLY
Disassembly of section .text:
00000000 <_ftext>:
0: 98 00 00 00 xor r0,r0,r0
4: d0 00 00 00 wcsr IE,r0
8: 78 01 00 00 mvhi r1,0x0
c: 38 21 00 00 ori r1,r1,0x0
10: d0 e1 00 00 wcsr EBA,r1
14: f8 00 00 03 calli 20 <_crt0>
18: 34 00 00 00 nop
1c: 34 00 00 00 nop
00000020 <_crt0>:
20: 78 1c 00 00 mvhi sp,0x0
24: 3b 9c 0f fc ori sp,sp,0xffc
28: 78 1a 00 00 mvhi gp,0x0
2c: 3b 5a 02 a0 ori gp,gp,0x2a0
30: 78 01 00 00 mvhi r1,0x0
34: 38 21 02 98 ori r1,r1,0x298
38: 78 03 00 00 mvhi r3,0x0
3c: 38 63 02 9c ori r3,r3,0x29c
00000040 <.clearBSS>:
40: 44 23 00 04 be r1,r3,50 <.callMain>
44: 58 20 00 00 sw (r1+0),r0
48: 34 21 00 04 addi r1,r1,4
4c: e3 ff ff fd bi 40 <.clearBSS>
00000050 <.callMain>:
50: 34 01 00 00 mvi r1,0
54: 34 02 00 00 mvi r2,0
58: 34 03 00 00 mvi r3,0
5c: f8 00 00 1d calli d0 <main>
00000060 <irq_enable>:
60: 34 01 00 01 mvi r1,1
64: d0 01 00 00 wcsr IE,r1
68: c3 a0 00 00 ret
0000006c <irq_mask>:
6c: 34 01 00 0f mvi r1,15
70: d0 21 00 00 wcsr IM,r1
74: c3 a0 00 00 ret
00000078 <irq_disable>:
78: 34 01 00 00 mvi r1,0
7c: d0 01 00 00 wcsr IE,r1
80: c3 a0 00 00 ret
00000084 <jump>:
84: c0 20 00 00 b r1
00000088 <halt>:
88: e0 00 00 00 bi 88 <halt>
0000008c <read_uint32>:
*/
#include "soc-hw.h"
/* prototypes */
uint32_t read_uint32()
{
8c: 37 9c ff f8 addi sp,sp,-8
90: 5b 8b 00 08 sw (sp+8),r11
94: 5b 9d 00 04 sw (sp+4),ra
uint32_t val = 0, i;
for (i = 0; i < 4; i++) {
val <<= 8;
val += (uint8_t)uart_getchar();
98: f8 00 00 57 calli 1f4 <uart_getchar>
uint32_t read_uint32()
{
uint32_t val = 0, i;
for (i = 0; i < 4; i++) {
val <<= 8;
9c: 3c 2b 00 08 sli r11,r1,8
val += (uint8_t)uart_getchar();
a0: f8 00 00 55 calli 1f4 <uart_getchar>
a4: b5 61 08 00 add r1,r11,r1
uint32_t read_uint32()
{
uint32_t val = 0, i;
for (i = 0; i < 4; i++) {
val <<= 8;
a8: 3c 2b 00 08 sli r11,r1,8
val += (uint8_t)uart_getchar();
ac: f8 00 00 52 calli 1f4 <uart_getchar>
b0: b5 61 08 00 add r1,r11,r1
uint32_t read_uint32()
{
uint32_t val = 0, i;
for (i = 0; i < 4; i++) {
val <<= 8;
b4: 3c 2b 00 08 sli r11,r1,8
val += (uint8_t)uart_getchar();
b8: f8 00 00 4f calli 1f4 <uart_getchar>
}
return val;
}
bc: b5 61 08 00 add r1,r11,r1
c0: 2b 9d 00 04 lw ra,(sp+4)
c4: 2b 8b 00 08 lw r11,(sp+8)
c8: 37 9c 00 08 addi sp,sp,8
cc: c3 a0 00 00 ret
000000d0 <main>:
int main(int argc, char **argv)
{
d0: 37 9c ff e4 addi sp,sp,-28
d4: 5b 8b 00 1c sw (sp+28),r11
d8: 5b 8c 00 18 sw (sp+24),r12
dc: 5b 8d 00 14 sw (sp+20),r13
e0: 5b 8e 00 10 sw (sp+16),r14
e4: 5b 8f 00 0c sw (sp+12),r15
e8: 5b 90 00 08 sw (sp+8),r16
ec: 5b 9d 00 04 sw (sp+4),ra
int8_t *p;
uint8_t c;
// Initialize UART
uart_init();
f0: f8 00 00 40 calli 1f0 <uart_init>
c = '*'; // print msg on first iteration
for(;;) {
uint32_t start, size;
switch (c) {
f4: 34 0d 00 67 mvi r13,103
{
int8_t *p;
uint8_t c;
// Initialize UART
uart_init();
f8: 34 01 00 2a mvi r1,42
c = '*'; // print msg on first iteration
for(;;) {
uint32_t start, size;
switch (c) {
fc: 34 0e 00 75 mvi r14,117
100: 34 0f 00 64 mvi r15,100
case 'g': // goto
start = read_uint32();
jump(start);
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
104: 78 10 00 00 mvhi r16,0x0
c = '*'; // print msg on first iteration
for(;;) {
uint32_t start, size;
switch (c) {
108: 44 2d 00 08 be r1,r13,128 <main+0x58>
10c: 44 2e 00 16 be r1,r14,164 <main+0x94>
110: 44 2f 00 0a be r1,r15,138 <main+0x68>
case 'g': // goto
start = read_uint32();
jump(start);
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
114: ba 00 08 00 mv r1,r16
118: 38 21 02 70 ori r1,r1,0x270
11c: f8 00 00 48 calli 23c <uart_putstr>
break;
};
c = uart_getchar();
120: f8 00 00 35 calli 1f4 <uart_getchar>
c = '*'; // print msg on first iteration
for(;;) {
uint32_t start, size;
switch (c) {
124: 5c 2d ff fa bne r1,r13,10c <main+0x3c>
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
uart_putchar( *p );
break;
case 'g': // goto
start = read_uint32();
128: fb ff ff d9 calli 8c <read_uint32>
jump(start);
12c: fb ff ff d6 calli 84 <jump>
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
break;
};
c = uart_getchar();
130: f8 00 00 31 calli 1f4 <uart_getchar>
134: e3 ff ff fc bi 124 <main+0x54>
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
*p = uart_getchar();
break;
case 'd': // download
start = read_uint32();
138: fb ff ff d5 calli 8c <read_uint32>
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
13c: b8 20 58 00 mv r11,r1
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
*p = uart_getchar();
break;
case 'd': // download
start = read_uint32();
size = read_uint32();
140: fb ff ff d3 calli 8c <read_uint32>
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
144: b5 61 60 00 add r12,r11,r1
148: 51 6c ff f6 bgeu r11,r12,120 <main+0x50>
uart_putchar( *p );
14c: 41 61 00 00 lbu r1,(r11+0)
*p = uart_getchar();
break;
case 'd': // download
start = read_uint32();
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
150: 35 6b 00 01 addi r11,r11,1
uart_putchar( *p );
154: f8 00 00 31 calli 218 <uart_putchar>
*p = uart_getchar();
break;
case 'd': // download
start = read_uint32();
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
158: 55 8b ff fd bgu r12,r11,14c <main+0x7c>
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
break;
};
c = uart_getchar();
15c: f8 00 00 26 calli 1f4 <uart_getchar>
160: e3 ff ff f1 bi 124 <main+0x54>
for(;;) {
uint32_t start, size;
switch (c) {
case 'u': // upload
start = read_uint32();
164: fb ff ff ca calli 8c <read_uint32>
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
168: b8 20 58 00 mv r11,r1
uint32_t start, size;
switch (c) {
case 'u': // upload
start = read_uint32();
size = read_uint32();
16c: fb ff ff c8 calli 8c <read_uint32>
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
170: b5 61 60 00 add r12,r11,r1
174: 51 6c ff eb bgeu r11,r12,120 <main+0x50>
*p = uart_getchar();
178: f8 00 00 1f calli 1f4 <uart_getchar>
17c: 31 61 00 00 sb (r11+0),r1
switch (c) {
case 'u': // upload
start = read_uint32();
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
180: 35 6b 00 01 addi r11,r11,1
184: 55 8b ff fd bgu r12,r11,178 <main+0xa8>
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
break;
};
c = uart_getchar();
188: f8 00 00 1b calli 1f4 <uart_getchar>
18c: e3 ff ff e6 bi 124 <main+0x54>
00000190 <sleep>:
void sleep(int msec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000)*msec;
190: 78 02 00 00 mvhi r2,0x0
194: 38 42 02 90 ori r2,r2,0x290
198: 38 03 c3 50 mvu r3,0xc350
19c: 28 42 00 00 lw r2,(r2+0)
1a0: 88 23 08 00 mul r1,r1,r3
1a4: 58 41 00 10 sw (r2+16),r1
timer0->counter1 = 0;
1a8: 34 01 00 00 mvi r1,0
1ac: 58 41 00 14 sw (r2+20),r1
timer0->tcr1 = TIMER_EN | TIMER_IRQEN;
1b0: 34 01 00 0a mvi r1,10
1b4: 58 41 00 0c sw (r2+12),r1
do {
//halt();
tcr = timer0->tcr1;
1b8: 28 41 00 0c lw r1,(r2+12)
} while ( ! (tcr & TIMER_TRIG) );
1bc: 20 21 00 01 andi r1,r1,0x1
1c0: 44 20 ff fe be r1,r0,1b8 <sleep+0x28>
}
1c4: c3 a0 00 00 ret
000001c8 <tic_init>:
void tic_init()
{
// Setup timer0.0
timer0->compare0 = (FCPU/1000);
1c8: 78 01 00 00 mvhi r1,0x0
1cc: 38 21 02 90 ori r1,r1,0x290
1d0: 28 21 00 00 lw r1,(r1+0)
1d4: 38 02 c3 50 mvu r2,0xc350
1d8: 58 22 00 04 sw (r1+4),r2
timer0->counter0 = 0;
1dc: 34 02 00 00 mvi r2,0
1e0: 58 22 00 08 sw (r1+8),r2
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
1e4: 34 02 00 0e mvi r2,14
1e8: 58 22 00 00 sw (r1+0),r2
}
1ec: c3 a0 00 00 ret
000001f0 <uart_init>:
//uart0->lcr = 0x03; // Line Control Register: 8N1
//uart0->mcr = 0x00; // Modem Control Register
// Setup Divisor register (Fclk / Baud)
//uart0->div = (FCPU/(57600*16));
}
1f0: c3 a0 00 00 ret
000001f4 <uart_getchar>:
char uart_getchar()
{
1f4: 78 01 00 00 mvhi r1,0x0
1f8: 38 21 02 8c ori r1,r1,0x28c
1fc: 28 22 00 00 lw r2,(r1+0)
while (! (uart0->ucr & UART_DR)) ;
200: 28 41 00 00 lw r1,(r2+0)
204: 20 21 00 01 andi r1,r1,0x1
208: 44 20 ff fe be r1,r0,200 <uart_getchar+0xc>
return uart0->rxtx;
20c: 28 41 00 04 lw r1,(r2+4)
}
210: 20 21 00 ff andi r1,r1,0xff
214: c3 a0 00 00 ret
00000218 <uart_putchar>:
void uart_putchar(char c)
{
218: 78 02 00 00 mvhi r2,0x0
21c: 38 42 02 8c ori r2,r2,0x28c
220: 28 43 00 00 lw r3,(r2+0)
224: 20 21 00 ff andi r1,r1,0xff
while (uart0->ucr & UART_BUSY) ;
228: 28 62 00 00 lw r2,(r3+0)
22c: 20 42 00 10 andi r2,r2,0x10
230: 5c 40 ff fe bne r2,r0,228 <uart_putchar+0x10>
uart0->rxtx = c;
234: 58 61 00 04 sw (r3+4),r1
}
238: c3 a0 00 00 ret
0000023c <uart_putstr>:
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
23c: 40 24 00 00 lbu r4,(r1+0)
240: 44 80 00 0b be r4,r0,26c <uart_putstr+0x30>
244: 78 02 00 00 mvhi r2,0x0
248: 38 42 02 8c ori r2,r2,0x28c
24c: 28 43 00 00 lw r3,(r2+0)
return uart0->rxtx;
}
void uart_putchar(char c)
{
while (uart0->ucr & UART_BUSY) ;
250: 28 62 00 00 lw r2,(r3+0)
254: 20 42 00 10 andi r2,r2,0x10
258: 5c 40 ff fe bne r2,r0,250 <uart_putstr+0x14>
uart0->rxtx = c;
25c: 58 64 00 04 sw (r3+4),r4
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
uart_putchar(*c);
c++;
260: 34 21 00 01 addi r1,r1,1
}
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
264: 40 24 00 00 lbu r4,(r1+0)
268: 5c 82 ff fa bne r4,r2,250 <uart_putstr+0x14>
26c: c3 a0 00 00 ret

View File

@@ -0,0 +1,127 @@
Memory Configuration
Name Origin Length Attributes
bram 0x00000000 0x00001000
*default* 0x00000000 0xffffffff
Linker script and memory map
0x00000000 __DYNAMIC = 0x0
0x00000000 _BRAM_START = 0x0
0x00001000 _BRAM_SIZE = 0x1000
0x00001000 _BRAM_END = (_BRAM_START + _BRAM_SIZE)
.text 0x00000000 0x270
0x00000000 _ftext = .
*(.text .stub .text.* .gnu.linkonce.t.*)
.text 0x00000000 0x8c crt0ram.o
0x00000000 _start
0x00000060 irq_enable
0x0000006c irq_mask
0x00000078 irq_disable
0x00000084 jump
0x00000088 halt
.text 0x0000008c 0x104 main.o
0x0000008c read_uint32
0x000000d0 main
.text 0x00000190 0xe0 soc-hw.o
0x00000190 sleep
0x000001c8 tic_init
0x000001f0 uart_init
0x000001f4 uart_getchar
0x00000218 uart_putchar
0x0000023c uart_putstr
0x00000270 _etext = .
.rodata 0x00000270 0x1c
0x00000270 . = ALIGN (0x4)
0x00000270 _frodata = .
*(.rodata .rodata.* .gnu.linkonce.r.*)
.rodata.str1.4
0x00000270 0x1c main.o
*(.rodata1)
0x0000028c _erodata = .
.data 0x0000028c 0xc
0x0000028c . = ALIGN (0x4)
0x0000028c _fdata = .
*(.data .data.* .gnu.linkonce.d.*)
.data 0x0000028c 0x0 crt0ram.o
.data 0x0000028c 0x0 main.o
.data 0x0000028c 0xc soc-hw.o
0x0000028c uart0
0x00000290 timer0
0x00000294 gpio0
*(.data1)
0x000002a0 _gp = ALIGN (0x10)
*(.sdata .sdata.* .gnu.linkonce.s.*)
0x00000298 _edata = .
.bss 0x00000298 0x4
0x00000298 . = ALIGN (0x4)
0x00000298 _fbss = .
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
.bss 0x00000298 0x0 crt0ram.o
.bss 0x00000298 0x0 main.o
.bss 0x00000298 0x4 soc-hw.o
0x00000298 msec
*(COMMON)
0x0000029c _ebss = .
0x0000029c _end = .
0x00000ffc PROVIDE (_fstack, 0xffc)
LOAD crt0ram.o
LOAD main.o
LOAD soc-hw.o
OUTPUT(image elf32-lm32)
.debug_abbrev 0x00000000 0x219
.debug_abbrev 0x00000000 0xcd main.o
.debug_abbrev 0x000000cd 0x14c soc-hw.o
.debug_info 0x00000000 0x3d0
.debug_info 0x00000000 0x121 main.o
.debug_info 0x00000121 0x2af soc-hw.o
.debug_line 0x00000000 0x2d8
.debug_line 0x00000000 0x18f main.o
.debug_line 0x0000018f 0x149 soc-hw.o
.debug_frame 0x00000000 0xa0
.debug_frame 0x00000000 0x30 main.o
.debug_frame 0x00000030 0x70 soc-hw.o
.debug_loc 0x00000000 0xfb
.debug_loc 0x00000000 0xb7 main.o
.debug_loc 0x000000b7 0x44 soc-hw.o
.debug_pubnames
0x00000000 0xbc
.debug_pubnames
0x00000000 0x2b main.o
.debug_pubnames
0x0000002b 0x91 soc-hw.o
.debug_aranges 0x00000000 0x40
.debug_aranges
0x00000000 0x20 main.o
.debug_aranges
0x00000020 0x20 soc-hw.o
.debug_ranges 0x00000000 0x18
.debug_ranges 0x00000000 0x18 main.o
.debug_str 0x00000000 0x17b
.debug_str 0x00000000 0xb8 main.o
0xd0 (size before relaxing)
.debug_str 0x000000b8 0xc3 soc-hw.o
0x157 (size before relaxing)
.comment 0x00000000 0x11
.comment 0x00000000 0x11 main.o
0x12 (size before relaxing)
.comment 0x00000000 0x12 soc-hw.o

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,44 @@
S00D0000696D6167652E7372656314
S113000098000000D00000007801000038210000B2
S1130010D0E10000F80000033400000034000000C8
S1130020781C00003B9C0FFC781A00003B5A02A08D
S11300307801000038210298780300003863029C9C
S1130040442300045820000034210004E3FFFFFD92
S1130050340100003402000034030000F800001DE5
S113006034010001D0010000C3A000003401000FDE
S1130070D0210000C3A0000034010000D001000022
S1130080C3A00000C0200000E0000000379CFFF87F
S11300905B8B00085B9D0004F80000573C2B0008B4
S11300A0F8000055B56108003C2B0008F800005228
S11300B0B56108003C2B0008F800004FB56108004A
S11300C02B9D00042B8B0008379C0008C3A0000064
S11300D0379CFFE45B8B001C5B8C00185B8D001469
S11300E05B8E00105B8F000C5B9000085B9D00042E
S11300F0F8000040340D00673401002A340E007506
S1130100340F006478100000442D0008442E0016BB
S1130110442F000ABA00080038210270F800004891
S1130120F80000355C2DFFFAFBFFFFD9FBFFFFD67B
S1130130F8000031E3FFFFFCFBFFFFD5B8205800B7
S1130140FBFFFFD3B5616000516CFFF64161000015
S1130150356B0001F8000031558BFFFDF8000026D7
S1130160E3FFFFF1FBFFFFCAB8205800FBFFFFC805
S1130170B5616000516CFFEBF800001F31610000B5
S1130180356B0001558BFFFDF800001BE3FFFFE614
S113019078020000384202903803C350284200001D
S11301A0882308005841001034010000584100140D
S11301B03401000A5841000C2841000C20210001A0
S11301C04420FFFEC3A00000780100003821029003
S11301D0282100003802C3505822000434020000D1
S11301E0582200083402000E58220000C3A0000068
S11301F0C3A00000780100003821028C28220000EE
S113020028410000202100014420FFFE2841000471
S1130210202100FFC3A00000780200003842028CB5
S113022028430000202100FF286200002042001023
S11302305C40FFFE58610004C3A00000402400009D
S11302404480000B780200003842028C28430000EE
S113025028620000204200105C40FFFE5864000445
S113026034210001402400005C82FFFAC3A0000096
S11302702A2A53414B432F626F6F746C6F6164651C
S10F0280722A2A203E200D0A0000000013
S10F028CF0000000F0010000F00200008F
S9030000FC

View File

@@ -0,0 +1,59 @@
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
__DYNAMIC = 0;
_BRAM_START = 0x00000000;
_BRAM_SIZE = 0x1000;
_BRAM_END = _BRAM_START + _BRAM_SIZE;
MEMORY {
bram : ORIGIN = 0x00000000, LENGTH = 0x1000 /* 4k */
}
SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > bram
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > bram
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > bram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
_ebss = .;
_end = .;
} > bram
}
PROVIDE(_fstack = ORIGIN(bram) + LENGTH(bram) - 4);

View File

@@ -0,0 +1,57 @@
/**
* Primitive first stage bootloader
*
*
*/
#include "soc-hw.h"
/* prototypes */
uint32_t read_uint32()
{
uint32_t val = 0, i;
for (i = 0; i < 4; i++) {
val <<= 8;
val += (uint8_t)uart_getchar();
}
return val;
}
int main(int argc, char **argv)
{
int8_t *p;
uint8_t c;
// Initialize UART
uart_init();
c = '*'; // print msg on first iteration
for(;;) {
uint32_t start, size;
switch (c) {
case 'u': // upload
start = read_uint32();
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
*p = uart_getchar();
break;
case 'd': // download
start = read_uint32();
size = read_uint32();
for (p = (int8_t *) start; p < (int8_t *) (start+size); p++)
uart_putchar( *p );
break;
case 'g': // goto
start = read_uint32();
jump(start);
break;
default:
uart_putstr("**SAKC/bootloader** > \r\n");
break;
};
c = uart_getchar();
}
}

View File

@@ -0,0 +1 @@
main.o: main.c soc-hw.h

Binary file not shown.

View File

@@ -0,0 +1,69 @@
#include "soc-hw.h"
uart_t *uart0 = (uart_t *) 0xF0000000;
timer_t *timer0 = (timer_t *) 0xF0010000;
gpio_t *gpio0 = (gpio_t *) 0xF0020000;
// uint32_t *sram0 = (uint32_t *) 0x40000000;
uint32_t msec = 0;
/***************************************************************************
* General utility functions
*/
void sleep(int msec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000)*msec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN | TIMER_IRQEN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
void tic_init()
{
// Setup timer0.0
timer0->compare0 = (FCPU/1000);
timer0->counter0 = 0;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
}
/***************************************************************************
* UART Functions
*/
void uart_init()
{
//uart0->ier = 0x00; // Interrupt Enable Register
//uart0->lcr = 0x03; // Line Control Register: 8N1
//uart0->mcr = 0x00; // Modem Control Register
// Setup Divisor register (Fclk / Baud)
//uart0->div = (FCPU/(57600*16));
}
char uart_getchar()
{
while (! (uart0->ucr & UART_DR)) ;
return uart0->rxtx;
}
void uart_putchar(char c)
{
while (uart0->ucr & UART_BUSY) ;
uart0->rxtx = c;
}
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
uart_putchar(*c);
c++;
}
}

View File

@@ -0,0 +1 @@
soc-hw.o: soc-hw.c soc-hw.h

View File

@@ -0,0 +1,108 @@
#ifndef SPIKEHW_H
#define SPIKEHW_H
#define PROMSTART 0x00000000
#define RAMSTART 0x00000800
#define RAMSIZE 0x400
#define RAMEND (RAMSTART + RAMSIZE)
#define RAM_START 0x40000000
#define RAM_SIZE 0x04000000
#define FCPU 50000000
#define UART_RXBUFSIZE 32
/****************************************************************************
* Types
*/
typedef unsigned int uint32_t; // 32 Bit
typedef signed int int32_t; // 32 Bit
typedef unsigned char uint8_t; // 8 Bit
typedef signed char int8_t; // 8 Bit
/****************************************************************************
* Interrupt handling
*/
typedef void(*isr_ptr_t)(void);
void irq_enable();
void irq_disable();
void irq_set_mask(uint32_t mask);
uint32_t irq_get_mak();
void isr_init();
void isr_register(int irq, isr_ptr_t isr);
void isr_unregister(int irq);
/****************************************************************************
* General Stuff
*/
void halt();
void jump(uint32_t addr);
/****************************************************************************
* Timer
*/
#define TIMER_EN 0x08 // Enable Timer
#define TIMER_AR 0x04 // Auto-Reload
#define TIMER_IRQEN 0x02 // IRQ Enable
#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR)
typedef struct {
volatile uint32_t tcr0;
volatile uint32_t compare0;
volatile uint32_t counter0;
volatile uint32_t tcr1;
volatile uint32_t compare1;
volatile uint32_t counter1;
} timer_t;
void msleep(uint32_t msec);
void nsleep(uint32_t nsec);
void tic_init();
/***************************************************************************
* GPIO0
*/
typedef struct {
volatile uint32_t ctrl;
volatile uint32_t dummy1;
volatile uint32_t dummy2;
volatile uint32_t dummy3;
volatile uint32_t in;
volatile uint32_t out;
volatile uint32_t oe;
} gpio_t;
/***************************************************************************
* UART0
*/
#define UART_DR 0x01 // RX Data Ready
#define UART_ERR 0x02 // RX Error
#define UART_BUSY 0x10 // TX Busy
typedef struct {
volatile uint32_t ucr;
volatile uint32_t rxtx;
} uart_t;
void uart_init();
void uart_putchar(char c);
void uart_putstr(char *str);
char uart_getchar();
/***************************************************************************
* Pointer to actual components
*/
extern timer_t *timer0;
extern uart_t *uart0;
extern gpio_t *gpio0;
extern uint32_t *sram0;
#endif // SPIKEHW_H

Binary file not shown.

View File

@@ -0,0 +1,50 @@
LM32_CC=lm32-elf-gcc
LM32_LD=lm32-elf-ld
LM32_OBJCOPY=lm32-elf-objcopy
LM32_OBJDUMP=lm32-elf-objdump
SREC2VRAM ?= ../../tools/srec2vram/srec2vram
VRAMFILE=image.ram
CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled
LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld
SEGMENTS = -j .text -j .rodata -j .data
all: $(VRAMFILE)
crt0ram.o: crt0ram.S
$(LM32_CC) $(CFLAGS) -c crt0ram.S
main.o: main.c
$(LM32_CC) $(CFLAGS) -c main.c
spike_hw.o: spike_hw.c
$(LM32_CC) $(CFLAGS) -c spike_hw.c
image: crt0ram.o main.o spike_hw.o
$(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o spike_hw.o
image.lst: image
$(LM32_OBJDUMP) -h -S $< > $@
image.bin: image
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.bin
image.srec: image image.lst
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec
$(VHDLFILE): image.srec
$(SREC2VHDL) image.srec > $(VHDLFILE)
$(VRAMFILE): image.srec
$(SREC2VRAM) image.srec 0x00000000 0x1000 > $(VRAMFILE)
clean:
rm -f image image.lst image.bin image.srec image.map *.o *.d
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

View File

@@ -0,0 +1,166 @@
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Exception handlers - Must be 32 bytes long. */
.section .text, "ax", @progbits
.global _start
.global irq_enable, irq_disable, irq_mask, jump, halt
_start:
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
nop
_crt0:
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
/* Clear BSS */
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
.clearBSS:
be r1, r3, .callMain
sw (r1+0), r0
addi r1, r1, 4
bi .clearBSS
.callMain:
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
irq_enable:
mvi r1, 1
wcsr IE, r1
ret
irq_mask:
mvi r1, 0x0000000f
wcsr IM, r1
ret
irq_disable:
mvi r1, 0
wcsr IE, r1
ret
jump:
b r1
halt:
bi halt
/* Save all registers onto the stack */
_save_all:
addi sp, sp, -128
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
sw (sp+44), r11
sw (sp+48), r12
sw (sp+52), r13
sw (sp+56), r14
sw (sp+60), r15
sw (sp+64), r16
sw (sp+68), r17
sw (sp+72), r18
sw (sp+76), r19
sw (sp+80), r20
sw (sp+84), r21
sw (sp+88), r22
sw (sp+92), r23
sw (sp+96), r24
sw (sp+100), r25
sw (sp+104), r26
sw (sp+108), r27
#endif
sw (sp+120), ea
sw (sp+124), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+128)
sw (sp+116), r1
mv r1, sp
addi r1, r1, 128
sw (sp+112), r1
ret
/* Restore all registers and return from exception */
_restore_all_and_return:
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
#endif
lw ra, (sp+116)
lw ea, (sp+120)
lw ba, (sp+124)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
eret

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,59 @@
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
__DYNAMIC = 0;
_BRAM_START = 0x00000000;
_BRAM_SIZE = 0x1000;
_BRAM_END = _BRAM_START + _BRAM_SIZE;
MEMORY {
bram : ORIGIN = 0x00000000, LENGTH = 0x1000 /* 4k */
}
SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > bram
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > bram
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > bram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
_ebss = .;
_end = .;
} > bram
}
PROVIDE(_fstack = ORIGIN(bram) + LENGTH(bram) - 4);

View File

@@ -0,0 +1,105 @@
/**
* DDR Phase Shifter
*/
#include "spike_hw.h"
/******************************************************************************
* Control DDR phase shift
*/
inline int ps_ready()
{
return (gpio0->in & (1 << 16)); // return 1 when ready, 0 otherwise
}
inline void ps_inc()
{
uint32_t tmp;
while ( ! ps_ready() );
tmp = gpio0->out;
gpio0->out = tmp | (1 << 16);
gpio0->out = tmp;
while ( ! ps_ready() );
}
inline void ps_dec()
{
uint32_t tmp;
while ( ! ps_ready() );
tmp = gpio0->out;
gpio0->out = tmp | (1 << 17);
gpio0->out = tmp;
while ( ! ps_ready() );
}
/******************************************************************************
* Simple memory tester
*
* Returns -1 on error, 0 when OK.
*/
inline int memtest(uint32_t size)
{
volatile uint32_t *p;
int res = 0;
for (p=(uint32_t *)RAM_START; p<(uint32_t *)(RAM_START+size); p++) {
*p = (uint32_t) p;
}
for (p=(uint32_t *)RAM_START; p<(uint32_t *)(RAM_START+size); p++) {
if (*p != (uint32_t)p) {
res = -1;
}
}
return res;
}
void scan_phase(int dir, uint32_t size)
{
int i;
for (i=0; i<=255; i++) {
if (memtest(size) == 0)
uart_putchar('O');
else
uart_putchar('-');
if (dir == 1) ps_inc(); else ps_dec();
}
}
int main(int argc, char **argv)
{
uint32_t scan_size = 16*1024; // scan 16 kByte
// Initialize stuff
uart_init();
uart_putstr("\r\n\r\n** SOC-LM32 DDR PAHSER **\n\n");
uart_putstr("'O' => Memtest OK ; '-' => Memtest failed\n\n");
uart_putstr("Press [u] for upward scan, [d] for downward\n");
for(;;) {
uint8_t c = uart_getchar();
switch (c) {
case 'u': // scan upward
scan_phase(1, scan_size);
break;
case 'd': // scan downward
scan_phase(-1, scan_size);
break;
}
}
}

View File

@@ -0,0 +1,68 @@
#include "spike_hw.h"
uart_t *uart0 = (uart_t *) 0xF0000000;
timer_t *timer0 = (timer_t *) 0xF0010000;
gpio_t *gpio0 = (gpio_t *) 0xF0020000;
uint32_t msec = 0;
/***************************************************************************
* General utility functions
*/
void sleep(int msec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000)*msec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN | TIMER_IRQEN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
void tic_init()
{
// Setup timer0.0
timer0->compare0 = (FCPU/1000);
timer0->counter0 = 0;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
}
/***************************************************************************
* UART Functions
*/
void uart_init()
{
//uart0->ier = 0x00; // Interrupt Enable Register
//uart0->lcr = 0x03; // Line Control Register: 8N1
//uart0->mcr = 0x00; // Modem Control Register
// Setup Divisor register (Fclk / Baud)
//uart0->div = (FCPU/(57600*16));
}
char uart_getchar()
{
while (! (uart0->ucr & UART_DR)) ;
return uart0->rxtx;
}
void uart_putchar(char c)
{
while (uart0->ucr & UART_BUSY) ;
uart0->rxtx = c;
}
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
uart_putchar(*c);
c++;
}
}

View File

@@ -0,0 +1,108 @@
#ifndef SPIKEHW_H
#define SPIKEHW_H
#define PROMSTART 0x00000000
#define RAMSTART 0x00000800
#define RAMSIZE 0x400
#define RAMEND (RAMSTART + RAMSIZE)
#define RAM_START 0x40000000
#define RAM_SIZE 0x04000000
#define FCPU 50000000
#define UART_RXBUFSIZE 32
/****************************************************************************
* Types
*/
typedef unsigned int uint32_t; // 32 Bit
typedef signed int int32_t; // 32 Bit
typedef unsigned char uint8_t; // 8 Bit
typedef signed char int8_t; // 8 Bit
/****************************************************************************
* Interrupt handling
*/
typedef void(*isr_ptr_t)(void);
void irq_enable();
void irq_disable();
void irq_set_mask(uint32_t mask);
uint32_t irq_get_mak();
void isr_init();
void isr_register(int irq, isr_ptr_t isr);
void isr_unregister(int irq);
/****************************************************************************
* General Stuff
*/
void halt();
void jump(uint32_t addr);
/****************************************************************************
* Timer
*/
#define TIMER_EN 0x08 // Enable Timer
#define TIMER_AR 0x04 // Auto-Reload
#define TIMER_IRQEN 0x02 // IRQ Enable
#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR)
typedef struct {
volatile uint32_t tcr0;
volatile uint32_t compare0;
volatile uint32_t counter0;
volatile uint32_t tcr1;
volatile uint32_t compare1;
volatile uint32_t counter1;
} timer_t;
void msleep(uint32_t msec);
void nsleep(uint32_t nsec);
void tic_init();
/***************************************************************************
* GPIO0
*/
typedef struct {
volatile uint32_t ctrl;
volatile uint32_t dummy1;
volatile uint32_t dummy2;
volatile uint32_t dummy3;
volatile uint32_t in;
volatile uint32_t out;
volatile uint32_t oe;
} gpio_t;
/***************************************************************************
* UART0
*/
#define UART_DR 0x01 // RX Data Ready
#define UART_ERR 0x02 // RX Error
#define UART_BUSY 0x10 // TX Busy
typedef struct {
volatile uint32_t ucr;
volatile uint32_t rxtx;
} uart_t;
void uart_init();
void uart_putchar(char c);
void uart_putstr(char *str);
char uart_getchar();
/***************************************************************************
* Pointer to actual components
*/
extern timer_t *timer0;
extern uart_t *uart0;
extern gpio_t *gpio0;
extern uint32_t *sram0;
#endif // SPIKEHW_H

View File

@@ -0,0 +1,43 @@
LM32_CC=lm32-elf-gcc
LM32_LD=lm32-elf-ld
LM32_OBJCOPY=lm32-elf-objcopy
LM32_OBJDUMP=lm32-elf-objdump
SREC2VRAM ?= ../../tools/srec2vram/srec2vram
VRAMFILE=image.ram
CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled
LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld
SEGMENTS = -j .boot -j .text -j .rodata -j .data
all: image.srec $(VRAMFILE)
%.o: %.S
$(LM32_CC) $(CFLAGS) -c $<
%.o: %.c
$(LM32_CC) $(CFLAGS) -c $<
image: crt0gdb.o main.o soc-hw.o gdb.o gdb_uart.o
$(LM32_LD) $(LDFLAGS) -Map image.map -N -o image $^
image.lst: image
$(LM32_OBJDUMP) -h -S $< > $@
image.bin: image
$(LM32_OBJCOPY) $(SEGMENTS) -O binary image image.bin
image.srec: image image.lst
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec
$(VRAMFILE): image.srec
$(SREC2VRAM) image.srec 0x40000000 0x100000 > $(VRAMFILE)
clean:
rm -f image image.lst image.bin image.srec image.map *.o *.d
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

View File

@@ -0,0 +1,290 @@
/*
* LatticeMico32 GDB C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Exception handlers - Must be 32 bytes long. */
.section .boot, "ax", @progbits
.global _start
_start:
_reset_handler:
bi _crt0
nop
nop
nop
nop
nop
nop
nop
_breakpoint_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ba
mvi r1, 1
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _b_restore_all_and_return
_instruction_bus_error_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ea
mvi r1, 2
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _e_restore_all_and_return
_watchpoint_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ba
mvi r1, 3
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _b_restore_all_and_return
_data_bus_error_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ea
mvi r1, 4
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _e_restore_all_and_return
_divide_by_zero_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ea
mvi r1, 5
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _e_restore_all_and_return
_interrupt_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ea
mvi r1, 6
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _e_restore_all_and_return
_system_call_handler:
sw (sp+0), ra
calli _save_all
sw (sp+128), ea
mvi r1, 7
sw (sp+132), r1
mv r1, sp
calli _handle_exception
bi _e_restore_all_and_return
/* Program starts here */
_crt0:
/* Clear r0 */
xor r0, r0, r0
/* Clear all other regs (needed so that simulations match) */
mvi r1, 0
mvi r2, 0
mvi r3, 0
mvi r4, 0
mvi r5, 0
mvi r6, 0
mvi r7, 0
mvi r8, 0
mvi r9, 0
mvi r10, 0
mvi r11, 0
mvi r12, 0
mvi r13, 0
mvi r14, 0
mvi r15, 0
mvi r16, 0
mvi r17, 0
mvi r18, 0
mvi r19, 0
mvi r20, 0
mvi r21, 0
mvi r22, 0
mvi r23, 0
mvi r24, 0
mvi r25, 0
mvi r26, 0
mvi r27, 0
mvi r28, 0
mvi r29, 0
mvi r30, 0
mvi r31, 0
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
/* Clear BSS */
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
.clearBSS:
be r1, r3, .callMain
sw (r1+0), r0
addi r1, r1, 4
bi .clearBSS
.callMain:
mvi r1, 0
mvi r2, 0
mvi r3, 0
/* Enter debug exception handler */
mvhi ba, hi(main)
ori ba, ba, lo(main)
bi _breakpoint_handler
/* Save all registers onto the stack */
_save_all:
addi sp, sp, -136
sw (sp+0), r0
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
sw (sp+44), r11
sw (sp+48), r12
sw (sp+52), r13
sw (sp+56), r14
sw (sp+60), r15
sw (sp+64), r16
sw (sp+68), r17
sw (sp+72), r18
sw (sp+76), r19
sw (sp+80), r20
sw (sp+84), r21
sw (sp+88), r22
sw (sp+92), r23
sw (sp+96), r24
sw (sp+100), r25
sw (sp+104), r26
sw (sp+108), r27
sw (sp+120), ea
sw (sp+124), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+136)
sw (sp+116), r1
mv r1, sp
addi r1, r1, 136
sw (sp+112), r1
ret
/* Restore all registers and return from exception */
_e_restore_all_and_return:
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
lw ra, (sp+116)
lw ba, (sp+124)
/* Restore EA from PC */
lw ea, (sp+128)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
eret
/* Restore all registers and return from breakpoint */
_b_restore_all_and_return:
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
lw ra, (sp+116)
lw ea, (sp+120)
/* Restore BA from PC */
lw ba, (sp+128)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
bret

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/*
* LatticeMico32 GDB I/O.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _LM32_GDB_H
#define _LM32_GDB_H
/* Write a single character to debug host */
void _gdb_write_char (char);
/* Read and return a single character from debug host */
char _gdb_read_char (void);
/* Acknowledge interrupt that caused CPU to enter debug mode */
void _gdb_ack_interrupt (void);
#endif /* _LM32_GDB_H */

View File

@@ -0,0 +1,23 @@
#include "soc-hw.h"
/* Write a single character to debug host */
void
_gdb_write_char (char c)
{
uart_putchar(c);
}
/* Read and return a single character from debug host */
char
_gdb_read_char (void)
{
return uart_getchar();
}
/* Acknowledge specified interrupt that caused CPU to enter debug mode */
void
_gdb_ack_interrupt (void)
{
/* ACK interrupt */
/*__asm__ ("wcsr\tIA, %0" : : "d" (1 << interrupt));*/
}

View File

@@ -0,0 +1,5 @@
void _gdb_write_char (char c);
char _gdb_read_char (void);
void _gdb_ack_interrupt (void) ;

View File

@@ -0,0 +1,67 @@
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
__DYNAMIC = 0;
_RAM_START = 0x40000000;
_RAM_SIZE = 0x100000;
_RAM_END = _RAM_START + _RAM_SIZE;
MEMORY {
ram : ORIGIN = 0x40000000, LENGTH = 0x100000 /* 1M */
}
SECTIONS
{
.boot :
{
_fboot = .;
*(.boot)
_eboot = .;
} > ram
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > ram
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > ram
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
_ebss = .;
_end = .;
} > ram
}
PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4);

View File

@@ -0,0 +1,20 @@
#include "soc-hw.h"
void main()
{
gpio0->oe = 0x000000ff;
for(;;) {
int i;
for(i=0; i<8; i++) {
uint32_t out1, out2;
out1 = 0x01 << i;
out2 = 0x80 >> i;
gpio0->out = out1 | out2;
msleep(100);
}
}
}

View File

@@ -0,0 +1,133 @@
#include "soc-hw.h"
uart_t *uart0 = (uart_t *) 0xf0000000;
timer_t *timer0 = (timer_t *) 0xf0010000;
gpio_t *gpio0 = (gpio_t *) 0xF0020000;
isr_ptr_t isr_table[32];
void tic_isr();
/***************************************************************************
* IRQ handling
*/
void isr_null()
{
}
void irq_handler(uint32_t pending)
{
int i;
for(i=0; i<32; i++) {
if (pending & 0x01) (*isr_table[i])();
pending >>= 1;
}
}
void isr_init()
{
int i;
for(i=0; i<32; i++)
isr_table[i] = &isr_null;
}
void isr_register(int irq, isr_ptr_t isr)
{
isr_table[irq] = isr;
}
void isr_unregister(int irq)
{
isr_table[irq] = &isr_null;
}
/***************************************************************************
* TIMER Functions
*/
void msleep(uint32_t msec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000)*msec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
void nsleep(uint32_t nsec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000000)*nsec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
uint32_t tic_msec;
void tic_isr()
{
tic_msec++;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
}
void tic_init()
{
tic_msec = 0;
// Setup timer0.0
timer0->compare0 = (FCPU/10000);
timer0->counter0 = 0;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
isr_register(1, &tic_isr);
}
/***************************************************************************
* UART Functions
*/
void uart_init()
{
//uart0->ier = 0x00; // Interrupt Enable Register
//uart0->lcr = 0x03; // Line Control Register: 8N1
//uart0->mcr = 0x00; // Modem Control Register
// Setup Divisor register (Fclk / Baud)
//uart0->div = (FCPU/(57600*16));
}
char uart_getchar()
{
while (! (uart0->ucr & UART_DR)) ;
return uart0->rxtx;
}
void uart_putchar(char c)
{
while (uart0->ucr & UART_BUSY) ;
uart0->rxtx = c;
}
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
uart_putchar(*c);
c++;
}
}

View File

@@ -0,0 +1,108 @@
#ifndef SPIKEHW_H
#define SPIKEHW_H
#define PROMSTART 0x00000000
#define RAMSTART 0x00000800
#define RAMSIZE 0x400
#define RAMEND (RAMSTART + RAMSIZE)
#define RAM_START 0x40000000
#define RAM_SIZE 0x04000000
#define FCPU 50000000
#define UART_RXBUFSIZE 32
/****************************************************************************
* Types
*/
typedef unsigned int uint32_t; // 32 Bit
typedef signed int int32_t; // 32 Bit
typedef unsigned char uint8_t; // 8 Bit
typedef signed char int8_t; // 8 Bit
/****************************************************************************
* Interrupt handling
*/
typedef void(*isr_ptr_t)(void);
void irq_enable();
void irq_disable();
void irq_set_mask(uint32_t mask);
uint32_t irq_get_mak();
void isr_init();
void isr_register(int irq, isr_ptr_t isr);
void isr_unregister(int irq);
/****************************************************************************
* General Stuff
*/
void halt();
void jump(uint32_t addr);
/****************************************************************************
* Timer
*/
#define TIMER_EN 0x08 // Enable Timer
#define TIMER_AR 0x04 // Auto-Reload
#define TIMER_IRQEN 0x02 // IRQ Enable
#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR)
typedef struct {
volatile uint32_t tcr0;
volatile uint32_t compare0;
volatile uint32_t counter0;
volatile uint32_t tcr1;
volatile uint32_t compare1;
volatile uint32_t counter1;
} timer_t;
void msleep(uint32_t msec);
void nsleep(uint32_t nsec);
void tic_init();
/***************************************************************************
* GPIO0
*/
typedef struct {
volatile uint32_t ctrl;
volatile uint32_t dummy1;
volatile uint32_t dummy2;
volatile uint32_t dummy3;
volatile uint32_t in;
volatile uint32_t out;
volatile uint32_t oe;
} gpio_t;
/***************************************************************************
* UART0
*/
#define UART_DR 0x01 // RX Data Ready
#define UART_ERR 0x02 // RX Error
#define UART_BUSY 0x10 // TX Busy
typedef struct {
volatile uint32_t ucr;
volatile uint32_t rxtx;
} uart_t;
void uart_init();
void uart_putchar(char c);
void uart_putstr(char *str);
char uart_getchar();
/***************************************************************************
* Pointer to actual components
*/
extern timer_t *timer0;
extern uart_t *uart0;
extern gpio_t *gpio0;
extern uint32_t *sram0;
#endif // SPIKEHW_H

View File

@@ -0,0 +1,6 @@
#!/bin/sh
lm32-elf-gdb image << ENDL
target remote /dev/ttyUSB0
ENDL

View File

@@ -0,0 +1,46 @@
LM32_CC=lm32-elf-gcc
LM32_LD=lm32-elf-ld
LM32_OBJCOPY=lm32-elf-objcopy
LM32_OBJDUMP=lm32-elf-objdump
SREC2VRAM ?= ../../tools/srec2vram/srec2vram
VRAMFILE=image.ram
CFLAGS=-MMD -O2 -Wall -g -s -fomit-frame-pointer -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled
LDFLAGS=-nostdlib -nodefaultlibs -Tlinker.ld
SEGMENTS = -j .text -j .rodata -j .data
all: image.srec $(VRAMFILE)
crt0ram.o: crt0ram.S
$(LM32_CC) $(CFLAGS) -c crt0ram.S
main.o: main.c
$(LM32_CC) $(CFLAGS) -c main.c
soc-hw.o: soc-hw.c
$(LM32_CC) $(CFLAGS) -c soc-hw.c
image: crt0ram.o main.o soc-hw.o linker.ld Makefile
$(LM32_LD) $(LDFLAGS) -Map image.map -N -o image crt0ram.o main.o soc-hw.o
image.lst: image
$(LM32_OBJDUMP) -h -S $< > $@
image.bin: image
$(LM32_OBJCOPY) $(SEGMENTS) -O binary image image.bin
image.srec: image image.lst
$(LM32_OBJCOPY) $(SEGMENTS) -O srec image image.srec
$(VRAMFILE): image.srec
$(SREC2VRAM) image.srec 0x40000000 0x1000 > $(VRAMFILE)
clean:
rm -f image image.lst image.bin image.srec image.map *.o *.d
DEPS := $(wildcard *.d)
ifneq ($(DEPS),)
include $(DEPS)
endif

View File

@@ -0,0 +1,249 @@
/*
* LatticeMico32 C startup code.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/* Exception handlers - Must be 32 bytes long. */
.section .text, "ax", @progbits
.global _start
.global irq_enable, irq_disable, irq_set_mask, irq_get_mask
.global jump, halt
.global get_sp, get_gp
_start:
_reset_handler:
xor r0, r0, r0
wcsr IE, r0
mvhi r1, hi(_reset_handler)
ori r1, r1, lo(_reset_handler)
wcsr EBA, r1
calli _crt0
nop
nop
_breakpoint_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_ibuserror_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_watchpoint_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_dbuserror_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_divzero_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_interrupt_handler:
sw (sp+0), ra
calli _save_all
rcsr r1, IP
calli irq_handler
mvhi r1, 0xffff
ori r1, r1, 0xffff
wcsr IP, r1
bi _restore_all_and_eret
_scall_handler:
nop
nop
nop
nop
nop
nop
nop
nop
_crt0:
/* Setup stack and global pointer */
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
mvhi gp, hi(_gp)
ori gp, gp, lo(_gp)
/* Clear BSS */
mvhi r1, hi(_fbss)
ori r1, r1, lo(_fbss)
mvhi r3, hi(_ebss)
ori r3, r3, lo(_ebss)
.clearBSS:
be r1, r3, .callMain
sw (r1+0), r0
addi r1, r1, 4
bi .clearBSS
.callMain:
mvi r1, 0
mvi r2, 0
mvi r3, 0
calli main
irq_enable:
mvi r1, 1
wcsr IE, r1
ret
irq_disable:
mvi r1, 0
wcsr IE, r1
ret
irq_set_mask:
wcsr IM, r1
ret
irq_get_mask:
rcsr r1, IM
ret
jump:
b r1
halt:
bi halt
/* Save all registers onto the stack */
_save_all:
addi sp, sp, -128
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
sw (sp+16), r4
sw (sp+20), r5
sw (sp+24), r6
sw (sp+28), r7
sw (sp+32), r8
sw (sp+36), r9
sw (sp+40), r10
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
sw (sp+44), r11
sw (sp+48), r12
sw (sp+52), r13
sw (sp+56), r14
sw (sp+60), r15
sw (sp+64), r16
sw (sp+68), r17
sw (sp+72), r18
sw (sp+76), r19
sw (sp+80), r20
sw (sp+84), r21
sw (sp+88), r22
sw (sp+92), r23
sw (sp+96), r24
sw (sp+100), r25
sw (sp+104), r26
sw (sp+108), r27
#endif
sw (sp+120), ea
sw (sp+124), ba
/* ra and sp need special handling, as they have been modified */
lw r1, (sp+128)
sw (sp+116), r1
mv r1, sp
addi r1, r1, 128
sw (sp+112), r1
ret
/* Restore all registers and return from exception */
_restore_all_and_eret:
lw r1, (sp+4)
lw r2, (sp+8)
lw r3, (sp+12)
lw r4, (sp+16)
lw r5, (sp+20)
lw r6, (sp+24)
lw r7, (sp+28)
lw r8, (sp+32)
lw r9, (sp+36)
lw r10, (sp+40)
#ifdef MICO32_FULL_CONTEXT_SAVE_RESTORE
lw r11, (sp+44)
lw r12, (sp+48)
lw r13, (sp+52)
lw r14, (sp+56)
lw r15, (sp+60)
lw r16, (sp+64)
lw r17, (sp+68)
lw r18, (sp+72)
lw r19, (sp+76)
lw r20, (sp+80)
lw r21, (sp+84)
lw r22, (sp+88)
lw r23, (sp+92)
lw r24, (sp+96)
lw r25, (sp+100)
lw r26, (sp+104)
lw r27, (sp+108)
#endif
lw ra, (sp+116)
lw ea, (sp+120)
lw ba, (sp+124)
/* Stack pointer must be restored last, in case it has been updated */
lw sp, (sp+112)
eret
get_sp:
mv r1, sp
ret
get_gp:
mv r1, gp
ret

View File

@@ -0,0 +1,59 @@
OUTPUT_FORMAT("elf32-lm32")
ENTRY(_start)
__DYNAMIC = 0;
_RAM_START = 0x40000000;
_RAM_SIZE = 0x1000;
_RAM_END = _RAM_START + _RAM_SIZE;
MEMORY {
ram : ORIGIN = 0x40000000, LENGTH = 0x1000 /* 4k */
}
SECTIONS
{
.text :
{
_ftext = .;
*(.text .stub .text.* .gnu.linkonce.t.*)
_etext = .;
} > ram
.rodata :
{
. = ALIGN(4);
_frodata = .;
*(.rodata .rodata.* .gnu.linkonce.r.*)
*(.rodata1)
_erodata = .;
} > ram
.data :
{
. = ALIGN(4);
_fdata = .;
*(.data .data.* .gnu.linkonce.d.*)
*(.data1)
_gp = ALIGN(16);
*(.sdata .sdata.* .gnu.linkonce.s.*)
_edata = .;
} > ram
.bss :
{
. = ALIGN(4);
_fbss = .;
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
_ebss = .;
_end = .;
} > ram
}
PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 4);

View File

@@ -0,0 +1,151 @@
/**
*
*/
#include "soc-hw.h"
inline void writeint(uint32_t val)
{
uint32_t i, digit;
for (i=0; i<8; i++) {
digit = (val & 0xf0000000) >> 28;
if (digit >= 0xA)
uart_putchar('A'+digit-10);
else
uart_putchar('0'+digit);
val <<= 4;
}
}
void test2() {
uart_putchar('b');
}
void test() {
uart_putchar('a');
test2();
uart_putchar('c');
}
char glob[] = "Global";
volatile uint32_t *p;
volatile uint8_t *p2;
extern uint32_t tic_msec;
int main()
{
char test2[] = "Lokalerstr";
char *str = test2;
uint32_t i;
// for (i = 0; i < 4; i++)
// test2[i] = 'l';
// glob[0] = 'g';
// Initialize stuff
uart_init();
// Say Hello!
uart_putstr( "** Spike Test Firmware **\n" );
// Initialize TIC
isr_init();
tic_init();
irq_set_mask( 0x00000002 );
irq_enable();
// Say Hello!
uart_putstr( "Timer Interrupt instelled.\n" );
// Do some trivial tests
uart_putstr( "Subroutine-Return Test: " );
test();
uart_putchar('\n');
uart_putstr( "Local-Pointer Test:" );
for (;*str; str++) {
uart_putchar(*str);
}
uart_putchar('\n');
uart_putstr( "Global-Pointer Test:" );
str = glob;
for (;*str; str++) {
uart_putchar(*str);
}
uart_putchar('\n');
uart_putstr( "Stack Pointer : " );
writeint(get_sp());
uart_putchar('\n');
uart_putstr( "Global Pointer: " );
writeint(get_gp());
uart_putchar('\n');
uart_putstr( "Timer Test (1s): " );
for(i=0; i<4; i++) {
uart_putstr("tic...");
msleep(1000);
}
uart_putchar('\n');
uart_putstr( "Timer Interrupt counter: " );
writeint( tic_msec );
uart_putchar('\n');
int val = tic_msec;
uart_putstr( "Shift: " );
writeint( val );
uart_putstr(" <-> ");
for(i=0; i<32; i++) {
if (val & 0x80000000)
uart_putchar( '1' );
else
uart_putchar( '0' );
val <<= 1;
}
uart_putstr("\r\n");
uart_putstr( "GPIO Test..." );
gpio0->oe = 0x000000ff;
for(;;) {
for(i=0; i<8; i++) {
uint32_t out1, out2;
out1 = 0x01 << i;
out2 = 0x80 >> i;
gpio0->out = out1 | out2;
msleep(100);
}
}
/*
uart_putstr( "Memory Dump: " );
uint32_t *start = (uint32_t *)0x40000000;
uint32_t *end = (uint32_t *)0x40000100;
uint32_t *p;
for (p=start; p<end; p++) {
if (((uint32_t)p & 12) == 0) {
uart_putstr("\r\n[");
writeint((uint32_t) p);
uart_putchar(']');
}
uart_putchar(' ');
writeint(*p);
}
*/
uart_putstr("Entering Echo Test...\n");
while (1) {
uart_putchar(uart_getchar());
}
}

View File

@@ -0,0 +1,133 @@
#include "soc-hw.h"
uart_t *uart0 = (uart_t *) 0xf0000000;
timer_t *timer0 = (timer_t *) 0xf0010000;
gpio_t *gpio0 = (gpio_t *) 0xF0020000;
isr_ptr_t isr_table[32];
void tic_isr();
/***************************************************************************
* IRQ handling
*/
void isr_null()
{
}
void irq_handler(uint32_t pending)
{
int i;
for(i=0; i<32; i++) {
if (pending & 0x01) (*isr_table[i])();
pending >>= 1;
}
}
void isr_init()
{
int i;
for(i=0; i<32; i++)
isr_table[i] = &isr_null;
}
void isr_register(int irq, isr_ptr_t isr)
{
isr_table[irq] = isr;
}
void isr_unregister(int irq)
{
isr_table[irq] = &isr_null;
}
/***************************************************************************
* TIMER Functions
*/
void msleep(uint32_t msec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000)*msec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
void nsleep(uint32_t nsec)
{
uint32_t tcr;
// Use timer0.1
timer0->compare1 = (FCPU/1000000)*nsec;
timer0->counter1 = 0;
timer0->tcr1 = TIMER_EN;
do {
//halt();
tcr = timer0->tcr1;
} while ( ! (tcr & TIMER_TRIG) );
}
uint32_t tic_msec;
void tic_isr()
{
tic_msec++;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
}
void tic_init()
{
tic_msec = 0;
// Setup timer0.0
timer0->compare0 = (FCPU/10000);
timer0->counter0 = 0;
timer0->tcr0 = TIMER_EN | TIMER_AR | TIMER_IRQEN;
isr_register(1, &tic_isr);
}
/***************************************************************************
* UART Functions
*/
void uart_init()
{
//uart0->ier = 0x00; // Interrupt Enable Register
//uart0->lcr = 0x03; // Line Control Register: 8N1
//uart0->mcr = 0x00; // Modem Control Register
// Setup Divisor register (Fclk / Baud)
//uart0->div = (FCPU/(57600*16));
}
char uart_getchar()
{
while (! (uart0->ucr & UART_DR)) ;
return uart0->rxtx;
}
void uart_putchar(char c)
{
while (uart0->ucr & UART_BUSY) ;
uart0->rxtx = c;
}
void uart_putstr(char *str)
{
char *c = str;
while(*c) {
uart_putchar(*c);
c++;
}
}

View File

@@ -0,0 +1,108 @@
#ifndef SPIKEHW_H
#define SPIKEHW_H
#define PROMSTART 0x00000000
#define RAMSTART 0x00000800
#define RAMSIZE 0x400
#define RAMEND (RAMSTART + RAMSIZE)
#define RAM_START 0x40000000
#define RAM_SIZE 0x04000000
#define FCPU 50000000
#define UART_RXBUFSIZE 32
/****************************************************************************
* Types
*/
typedef unsigned int uint32_t; // 32 Bit
typedef signed int int32_t; // 32 Bit
typedef unsigned char uint8_t; // 8 Bit
typedef signed char int8_t; // 8 Bit
/****************************************************************************
* Interrupt handling
*/
typedef void(*isr_ptr_t)(void);
void irq_enable();
void irq_disable();
void irq_set_mask(uint32_t mask);
uint32_t irq_get_mak();
void isr_init();
void isr_register(int irq, isr_ptr_t isr);
void isr_unregister(int irq);
/****************************************************************************
* General Stuff
*/
void halt();
void jump(uint32_t addr);
/****************************************************************************
* Timer
*/
#define TIMER_EN 0x08 // Enable Timer
#define TIMER_AR 0x04 // Auto-Reload
#define TIMER_IRQEN 0x02 // IRQ Enable
#define TIMER_TRIG 0x01 // Triggered (reset when writing to TCR)
typedef struct {
volatile uint32_t tcr0;
volatile uint32_t compare0;
volatile uint32_t counter0;
volatile uint32_t tcr1;
volatile uint32_t compare1;
volatile uint32_t counter1;
} timer_t;
void msleep(uint32_t msec);
void nsleep(uint32_t nsec);
void tic_init();
/***************************************************************************
* GPIO0
*/
typedef struct {
volatile uint32_t ctrl;
volatile uint32_t dummy1;
volatile uint32_t dummy2;
volatile uint32_t dummy3;
volatile uint32_t in;
volatile uint32_t out;
volatile uint32_t oe;
} gpio_t;
/***************************************************************************
* UART0
*/
#define UART_DR 0x01 // RX Data Ready
#define UART_ERR 0x02 // RX Error
#define UART_BUSY 0x10 // TX Busy
typedef struct {
volatile uint32_t ucr;
volatile uint32_t rxtx;
} uart_t;
void uart_init();
void uart_putchar(char c);
void uart_putstr(char *str);
char uart_getchar();
/***************************************************************************
* Pointer to actual components
*/
extern timer_t *timer0;
extern uart_t *uart0;
extern gpio_t *gpio0;
extern uint32_t *sram0;
#endif // SPIKEHW_H