diff --git a/Makefile b/Makefile index dba449c52..3d4a2a3f2 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ AOBJS = COBJS = $(patsubst %.c,%.o,$(wildcard src/*.c)) TESTS = $(wildcard tests/*.c) TARGETS = $(patsubst %.c,%.o,$(TESTS)) - +#TARGETS = tests/blink-white.o # Add GCC lib PLATFORM_LIBS += --no-warn-mismatch -L $(shell dirname `$(CC) $(CFLAGS) -print-libgcc-file-name`) -lgcc @@ -54,11 +54,15 @@ PLATFORM_LIBS += --no-warn-mismatch -L $(shell dirname `$(CC) $(CFLAGS) -print-l ######################################################################### #ALL = blink.srec blink.bin blink.dis blink.System.map -ALL = $(TARGETS) $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis) +ALL = $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis) .PRECIOUS: $(COBJS) $(TARGETS) $(TESTS:.c=.obj) -all: $(COBJS) $(ALL) +all: src/start.o $(ALL) + +tests/nvm-read.obj: src/maca.o +tests/rftest-rx.obj: src/maca.o +tests/rftest-tx.obj: src/maca.o %.srec: %.obj $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ @@ -70,12 +74,12 @@ all: $(COBJS) $(ALL) $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@ %.dis: %.obj - $(OBJDUMP) -DS $< > $@ + $(OBJDUMP) -D $< > $@ -%.obj: $(AOBJS) $(COBJS) $(TARGETS) $(LDSCRIPT) - $(LD) $(LDFLAGS) $(AOBJS) $(COBJS) \ +%.obj: $(LDSCRIPT) %.o + $(LD) $(LDFLAGS) $(AOBJS) \ --start-group $(PLATFORM_LIBS) --end-group \ - -Map $*.map $*.o -o $@ + -Map $*.map $^ -o $@ %.System.map: %.obj diff --git a/boot.lds b/boot.lds index c9f49a561..5b6ae7aef 100644 --- a/boot.lds +++ b/boot.lds @@ -32,7 +32,7 @@ SECTIONS . = ALIGN(4); .text : { - *(startup) + src/start.o (.text) *(.text) } diff --git a/config.mk b/config.mk index 5ed41231c..7352f6d74 100644 --- a/config.mk +++ b/config.mk @@ -26,7 +26,7 @@ # clean the slate ... PLATFORM_LDFLAGS = PLATFORM_RELFLAGS = -fno-strict-aliasing -fno-common -ffixed-r8 -msoft-float -PLATFORM_CPPFLAGS = -march=armv4 -mtune=arm7tdmi -DCONFIG_ARM -D__ARM__ +PLATFORM_CPPFLAGS = -march=armv4t -mcallee-super-interworking -mthumb -mtune=arm7tdmi-s -mthumb-interwork -DCONFIG_ARM -D__ARM__ TEXT_BASE = 0x00400000 ######################################################################### diff --git a/doc/ws-dis b/doc/ws-dis index a57a38dd4..dc2808932 100644 --- a/doc/ws-dis +++ b/doc/ws-dis @@ -5402,8 +5402,8 @@ Disassembly of section P2: 4031a0: 0040544c .word 0x0040544c 004031a4 : - 4031a4: 6801 ldr r1, [r0, #0] // r1 gets where r0 points - 4031a6: 1d00 adds r0, r0, #4 // increment pointer by 4 bytes + 4031a4: 6801 ldr r1, [r0, #0] // r1 gets where r0 points r1 = *r0 + 4031a6: 1d00 adds r0, r0, #4 // increment pointer by 4 bytes r0 += 4 4031a8: 4a17 ldr r2, [pc, #92] (403208 ) //r2 gets 403208: 00140001 .word 0x00140001 4031aa: 4291 cmp r1, r2 // compare r1 with r2 4031ac: d303 bcc.n 4031b6 //branch to 1: if lower @@ -5415,41 +5415,53 @@ Disassembly of section P2: 4031b8: d215 bcs.n 4031e6 // branch to 2: if high or equal 4031ba: 2900 cmp r1, #0 // check if zero (r1 is address?) 4031bc: d106 bne.n 4031cc // branch to 3: to if != 0 - 4031be: 6800 ldr r0, [r0, #0] + 4031be: 6800 ldr r0, [r0, #0] // if == 0 do delay 4031c0: 0880 lsrs r0, r0, #2 4031c2: 0001 lsls r1, r0, #0 4031c4: 1e48 subs r0, r1, #1 4031c6: 2900 cmp r1, #0 4031c8: d1fb bne.n 4031c2 - 4031ca: e7f2 b.n 4031b2 - 4031cc: 2901 cmp r1, #1 // 3: - 4031ce: d118 bne.n 403202 - 4031d0: 6802 ldr r2, [r0, #0] - 4031d2: 6841 ldr r1, [r0, #4] - 4031d4: 3008 adds r0, #8 - 4031d6: 680b ldr r3, [r1, #0] - 4031d8: 4393 bics r3, r2 - 4031da: 6800 ldr r0, [r0, #0] - 4031dc: 4002 ands r2, r0 - 4031de: 431a orrs r2, r3 - 4031e0: 600a str r2, [r1, #0] - 4031e2: 2004 movs r0, #4 + 4031ca: e7f2 b.n 4031b2 + 4031cc: 2901 cmp r1, #1 // at this point r1 is between 1 and 15 inclusive + 4031ce: d118 bne.n 403202 // if !=1 return + +0x00000001 command +0xaaaaaaaa +0xbbbbbbbb +0xcccccccc + + 4031d0: 6802 ldr r2, [r0, #0] // r2 = 0xaaaaaaaa + 4031d2: 6841 ldr r1, [r0, #4] // r1 = 0xbbbbbbbb + 4031d4: 3008 adds r0, #8 // r0 points to c + 4031d6: 680b ldr r3, [r1, #0] // r3 = *0xbbbbbbbb + 4031d8: 4393 bics r3, r2 // r3 = *0xbbbbbbbb & ~(0xaaaaaaaa) + 4031da: 6800 ldr r0, [r0, #0] // r0 = 0xcccccccc + 4031dc: 4002 ands r2, r0 // r2 &= r0 + 4031de: 431a orrs r2, r3 // r2 = (0xaaaaaaaa & 0xcccccccc) | (*0xbbbbbbbb & ~(0xaaaaaaaa)) + 4031e0: 600a str r2, [r1, #0] // store back in B + +uint32_t buf[] +if (buf[0] == 0x00000001) { + *buf[2] = (*buf[2] & ~buf[1]) | (buf[3] & buf[1]); +} + + 4031e2: 2004 movs r0, #4 // return 4 bytes processed 4031e4: 4770 bx lr - 4031e6: 4a09 ldr r2, [pc, #36] (40320c ) //2: - 4031e8: 4291 cmp r1, r2 - 4031ea: d20a bcs.n 403202 + 4031e6: 4a09 ldr r2, [pc, #36] (40320c ) //2: r2=0x0000fff1 + 4031e8: 4291 cmp r1, r2 // r1 >=16 + 4031ea: d20a bcs.n 403202 // if r1 >= 0xfff1 then return 0 4031ec: 4a08 ldr r2, [pc, #32] (403210 ) - 4031ee: 4291 cmp r1, r2 - 4031f0: d007 beq.n 403202 - 4031f2: 0909 lsrs r1, r1, #4 - 4031f4: 1e49 subs r1, r1, #1 - 4031f6: 0609 lsls r1, r1, #24 + 4031ee: 4291 cmp r1, r2 // + 4031f0: d007 beq.n 403202 if 0xe0f (end of file) return 0 + 4031f2: 0909 lsrs r1, r1, #4 // r1 = r1>>4 + 4031f4: 1e49 subs r1, r1, #1 // r1 = r1 - 1 + 4031f6: 0609 lsls r1, r1, #24 // mask 4031f8: 0e09 lsrs r1, r1, #24 - 4031fa: 4a06 ldr r2, [pc, #24] (403214 ) - 4031fc: 6800 ldr r0, [r0, #0] - 4031fe: 5450 strb r0, [r2, r1] + 4031fa: 4a06 ldr r2, [pc, #24] (403214 ) r2 = &u8RamValues + 4031fc: 6800 ldr r0, [r0, #0] // r0 = next value in buffer 2nd half of pair + 4031fe: 5450 strb r0, [r2, r1] // store this in u8RamValues 403200: e7d7 b.n 4031b2 - 403202: 2000 movs r0, #0 + 403202: 2000 movs r0, #0 // return 0 403204: 4770 bx lr 403206: 46c0 nop (mov r8, r8) 403208: 00140001 .word 0x00140001 @@ -5506,42 +5518,52 @@ Disassembly of section P2: 40327a: 4288 cmp r0, r1 40327c: d105 bne.n 40328a //branch to 2: if != 40327e: a802 add r0, sp, #8 - 403280: 88c1 ldrh r1, [r0, #6] + 403280: 88c1 ldrh r1, [r0, #6] // sp+8 0x00000abc sp+12 0x0100 03fc r1 = 0x0100 = 256 403282: 22ff movs r2, #255 403284: 1c92 adds r2, r2, #2 - 403286: 4291 cmp r1, r2 - 403288: d303 bcc.n 403292 - 40328a: 2001 movs r0, #1 // 2: + 403286: 4291 cmp r1, r2 // compare r1 to 257 + 403288: d303 bcc.n 403292 // if r1 < 257 (it is) goto 3: + 40328a: 2001 movs r0, #1 // 2: if r1 > 256 lock flash and return 0 40328c: f403 fefa bl 7084 403290: e7e0 b.n 403254 - 403292: 2408 movs r4, #8 - 403294: 8885 ldrh r5, [r0, #4] - 403296: 1f2d subs r5, r5, #4 - 403298: e006 b.n 4032a8 + + 403292: 2408 movs r4, #8 // 3: r4 = 8 + 403294: 8885 ldrh r5, [r0, #4] // r5 = 0x03fc + 403296: 1f2d subs r5, r5, #4 // r5 = r5 - 4 = 0x03f8 + 403298: e006 b.n 4032a8 // goto 4: + +// top of loop 40329a: a806 add r0, sp, #24 40329c: f7ff ff82 bl 4031a4 // so it looks like flash has entries it exectues... 4032a0: 2800 cmp r0, #0 - 4032a2: d00f beq.n 4032c4 - 4032a4: 0080 lsls r0, r0, #2 - 4032a6: 1824 adds r4, r4, r0 - 4032a8: 42ac cmp r4, r5 + 4032a2: d00f beq.n 4032c4 // if executeentry returned 0, goto 6: + 4032a4: 0080 lsls r0, r0, #2 // r0 = return value from executeentry * 4 + 4032a6: 1824 adds r4, r4, r0 // add number of bytes executed to r4 + + 4032a8: 42ac cmp r4, r5 // 4: if r4 >= r5 goto unlock_exit 4032aa: d210 bcs.n 4032ce - 4032ac: 2010 movs r0, #16 + + 4032ac: 2010 movs r0, #16 // 16 bytes = 4 commands 4032ae: b501 push {r0, lr} - 4032b0: 1933 adds r3, r6, r4 - 4032b2: aa08 add r2, sp, #32 + 4032b0: 1933 adds r3, r6, r4 // r6=0x1f000 + r4 offset + 4032b2: aa08 add r2, sp, #32 // buffer is on the stack 4032b4: a802 add r0, sp, #8 - 4032b6: 7801 ldrb r1, [r0, #0] - 4032b8: 2000 movs r0, #0 + 4032b6: 7801 ldrb r1, [r0, #0] // type from nv_detect + 4032b8: 2000 movs r0, #0 // arg0 4032ba: f403 fd55 bl 6d68 +// err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, 0x1F000, NBYTES); + + 4032be: b002 add sp, #8 4032c0: 2800 cmp r0, #0 - 4032c2: d0ea beq.n 40329a - 4032c4: 2001 movs r0, #1 + 4032c2: d0ea beq.n 40329a // if it worked, goto top of loop + 4032c4: 2001 movs r0, #1 // 6: lock and return 4032c6: f403 fedd bl 7084 4032ca: 0020 lsls r0, r4, #0 4032cc: e003 b.n 4032d6 - 4032ce: 2001 movs r0, #1 + + + 4032ce: 2001 movs r0, #1 // 5: 4032d0: f403 fed8 bl 7084 4032d4: 1d20 adds r0, r4, #4 4032d6: b00a add sp, #40 //exit: diff --git a/include/maca.h b/include/maca.h index ba263de5c..4be48cc06 100644 --- a/include/maca.h +++ b/include/maca.h @@ -407,6 +407,7 @@ typedef union maca_maskirq_reg_tag void reset_maca(void); void init_phy(void); +void vreg_init(void); void ResumeMACASync(void); void radio_init(void); void set_power(uint8_t power); diff --git a/include/nvm.h b/include/nvm.h new file mode 100644 index 000000000..edae0030d --- /dev/null +++ b/include/nvm.h @@ -0,0 +1,40 @@ +#ifndef NVM_H +#define NVM_H + +typedef enum +{ + gNvmType_NoNvm_c, + gNvmType_SST_c, + gNvmType_ST_c, + gNvmType_ATM_c, + gNvmType_Max_c +} nvmType_t; + + +typedef enum +{ + gNvmErrNoError_c = 0, + gNvmErrInvalidInterface_c, + gNvmErrInvalidNvmType_c, + gNvmErrInvalidPointer_c, + gNvmErrWriteProtect_c, + gNvmErrVerifyError_c, + gNvmErrAddressSpaceOverflow_c, + gNvmErrBlankCheckError_c, + gNvmErrRestrictedArea_c, + gNvmErrMaxError_c +} nvmErr_t; + +typedef enum +{ + gNvmInternalInterface_c, + gNvmExternalInterface_c, + gNvmInterfaceMax_c +} nvmInterface_t; + +/* ROM code seems to be THUMB */ +/* need to be in a THUMB block before calling them */ +volatile nvmErr_t (*nvm_detect)(nvmInterface_t nvmInterface,nvmType_t* pNvmType) = 0x00006cb9; +volatile nvmErr_t (*nvm_read)(nvmInterface_t nvmInterface , nvmType_t nvmType , void *pDest, uint32_t address, uint32_t numBytes) = 0x00006d69; +volatile void(*nvm_setsvar)(uint32_t zero_for_awesome) = 0x00007085; +#endif //NVM_H diff --git a/src/maca.c b/src/maca.c index cf711c973..558fc593e 100644 --- a/src/maca.c +++ b/src/maca.c @@ -1,3 +1,4 @@ +#include "embedded_types.h" #include "maca.h" #define reg(x) (*(volatile uint32_t *)(x)) @@ -319,9 +320,9 @@ const uint8_t ctov_4c[16] = { /* tested good */ #define ADDR_CHAN1 0x80009800 -#define ADDR_CHAN2 ADDR_CHAN1+12 -#define ADDR_CHAN3 ADDR_CHAN1+16 -#define ADDR_CHAN4 ADDR_CHAN1+48 +#define ADDR_CHAN2 (ADDR_CHAN1+12) +#define ADDR_CHAN3 (ADDR_CHAN1+16) +#define ADDR_CHAN4 (ADDR_CHAN1+48) void set_channel(uint8_t chan) { volatile uint32_t tmp; diff --git a/src/start.S b/src/start.S new file mode 100644 index 000000000..ec6f93444 --- /dev/null +++ b/src/start.S @@ -0,0 +1,208 @@ +/* + * armboot - Startup Code for ARM720 CPU-core + * + * Copyright (c) 2001 Marius Gröger + * Copyright (c) 2002 Alex Züpke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +/* + ************************************************************************* + * + * Jump vector table as in table 3.1 in [1] + * + ************************************************************************* + */ + + +.set base, . +.set _rom_data_init, 0x108d0 + + + .globl _start +_start: b _begin + ldr pc, _undefined_instruction + ldr pc, _software_interrupt + ldr pc, _prefetch_abort + ldr pc, _data_abort + ldr pc, _not_used + ldr pc, _irq + ldr pc, _fiq + +/* these vectors are used for rom patching */ +.org 0x20 +.code 16 +_RPTV_0_START: + bx lr /* do nothing */ + +.org 0x60 +_RPTV_1_START: + bx lr /* do nothing */ + +.org 0xa0 +_RPTV_2_START: + bx lr /* do nothing */ + +.org 0xe0 +_RPTV_3_START: + bx lr /* do nothing */ + +.org 0x120 +ROM_var_start: .word 0 +.org 0x7ff +ROM_var_end: .word 0 +.code 32 +.align +_begin: + bl _rom_data_init+.-base + b main + +_undefined_instruction: .word undefined_instruction +_software_interrupt: .word software_interrupt +_prefetch_abort: .word prefetch_abort +_data_abort: .word data_abort +_not_used: .word not_used +_irq: .word irq +_fiq: .word fiq + .balignl 16,0xdeadbeef + + +/* + ************************************************************************* + * + * Startup Code (reset vector) + * + * do important init only if we don't start from memory! + * relocate armboot to ram + * setup stack + * jump to second stage + * + ************************************************************************* + */ + +_TEXT_BASE: + .word TEXT_BASE + +.globl _armboot_start +_armboot_start: + .word _start + +/* + * These are defined in the board-specific linker script. + */ +.globl _bss_start +_bss_start: + .word __bss_start + +.globl _bss_end +_bss_end: + .word _end + +_start_armboot: .word main + +/* + ************************************************************************* + * + * CPU_init_critical registers + * + ************************************************************************* + */ + +cpu_init_crit: + # actually do nothing for now! + mov pc, lr + + +/* + ************************************************************************* + * + * Interrupt handling + * + ************************************************************************* + */ + +@ +@ IRQ stack frame. +@ +#define S_FRAME_SIZE 72 + +#define S_OLD_R0 68 +#define S_PSR 64 +#define S_PC 60 +#define S_LR 56 +#define S_SP 52 + +#define S_IP 48 +#define S_FP 44 +#define S_R10 40 +#define S_R9 36 +#define S_R8 32 +#define S_R7 28 +#define S_R6 24 +#define S_R5 20 +#define S_R4 16 +#define S_R3 12 +#define S_R2 8 +#define S_R1 4 +#define S_R0 0 + +#define MODE_SVC 0x13 +#define I_BIT 0x80 + + + .macro get_irq_stack @ setup IRQ stack + ldr sp, IRQ_STACK_START + .endm + + .macro get_fiq_stack @ setup FIQ stack + ldr sp, FIQ_STACK_START + .endm + +/* + * exception handlers + */ + .align 5 +undefined_instruction: + + .align 5 +software_interrupt: + + .align 5 +prefetch_abort: + nop + .align 5 +data_abort: + + .align 5 +not_used: + + + .align 5 +irq: + + .align 5 +fiq: + + .align 5 + +.globl reset_cpu +reset_cpu: + mov pc, r0 diff --git a/tests/nvm-read.c b/tests/nvm-read.c new file mode 100644 index 000000000..efbd22f64 --- /dev/null +++ b/tests/nvm-read.c @@ -0,0 +1,121 @@ +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 + +#include "embedded_types.h" +#include "nvm.h" +#include "maca.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +#define DELAY 400000 + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + +#define NBYTES 1024 +__attribute__ ((section ("startup"))) +void main(void) { + nvmType_t type=0; + nvmErr_t err; + uint32_t buf[NBYTES/4]; + uint32_t i; + + *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100; + + /* Restore UART regs. to default */ + /* in case there is still bootloader state leftover */ + + reg(UART1_CON) = 0x0000c800; /* mask interrupts, 16 bit sample --- helps explain the baud rate */ + + /* INC = 767; MOD = 9999 works: 115200 @ 24 MHz 16 bit sample */ + #define INC 767 + #define MOD 9999 + reg(UART1_BR) = INC<<16 | MOD; + + /* see Section 11.5.1.2 Alternate Modes */ + /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ + /* From the datasheet: "The peripheral function will control operation of the pad IF */ + /* THE PERIPHERAL IS ENABLED. */ + reg(UART1_CON) = 0x00000003; /* enable receive and transmit */ + reg(GPIO_FUNC_SEL0) = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ + + vreg_init(); + +// puts("CRM status: 0x"); +// put_hex32(reg(0x80003018)); +// puts("\n\r"); + + puts("Detecting internal nvm\n\r"); + + err = nvm_detect(gNvmInternalInterface_c, &type); + + puts("nvm_detect returned: 0x"); + put_hex(err); + puts(" type is: 0x"); + put_hex32(type); + puts("\n\r"); + + nvm_setsvar(0); + + err = nvm_read(gNvmInternalInterface_c, type, (uint8_t *)buf, 0x1F000, NBYTES); + puts("nvm_read returned: 0x"); + put_hex(err); + puts("\n\r"); + + for(i=0; i> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +}