From bdbf279d0f8d9b3f470be5150f33e4c9b0bade3a Mon Sep 17 00:00:00 2001 From: Mariano Alvira Date: Wed, 22 Apr 2009 14:55:40 -0400 Subject: [PATCH] tmr imts works. I'm not thrilled with how the interrupts and modes are set... but I'm not sure what to do about it. The big problem is that I have to be in user mode to service irqs, but I can't enable and disable F and I in usermode. All I can do is an swi and then have handler which lets me enable or disable them (like a mini-syscall). --- Makefile | 6 +-- config.mk | 2 +- include/isr.h | 2 +- src/isr.c | 8 ++-- src/start.S | 112 +++++++++++++++++++++++++++++------------------ tests/tmr-ints.c | 22 ++++++++-- 6 files changed, 98 insertions(+), 54 deletions(-) diff --git a/Makefile b/Makefile index dc29499dc..1f12d73dd 100644 --- a/Makefile +++ b/Makefile @@ -63,14 +63,14 @@ all: src/start.o src/isr.o $(ALL) tests/nvm-read.obj: src/maca.o src/nvm.o tests/rftest-rx.obj: src/maca.o src/nvm.o tests/rftest-tx.obj: src/maca.o src/nvm.o -tests/tmr-ints.obj: src/interrupt-utils.o src/sys-interrupt.o src/isr.o +tests/tmr-ints.obj: src/isr.o NOTHUMB_CPPFLAGS := $(DBGFLAGS) $(OPTFLAGS) $(RELFLAGS) \ -D__KERNEL__ -DTEXT_BASE=$(TEXT_BASE) \ -I$(TOPDIR)/include \ -fno-builtin -ffreestanding -nostdinc -isystem \ $(gccincdir) -pipe -NOTHUMB_CPPFLAGS_EXTRA = -march=armv4t -mlong-calls -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ +NOTHUMB_CPPFLAGS_EXTRA = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ #-mthumb-interwork src/isr.o: src/isr.c @@ -88,7 +88,7 @@ src/isr.o: src/isr.c %.dis: %.obj $(OBJDUMP) -SD $< > $@ -%.obj: $(LDSCRIPT) %.o src/interrupt-utils.o +%.obj: $(LDSCRIPT) %.o #src/interrupt-utils.o $(LD) $(LDFLAGS) $(AOBJS) \ --start-group $(PLATFORM_LIBS) --end-group \ -Map $*.map $^ -o $@ diff --git a/config.mk b/config.mk index 3fb973e44..b5f092959 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 -ffunction-sections -msoft-float -PLATFORM_CPPFLAGS = -march=armv4t -mlong-calls -mcallee-super-interworking -mthumb -mthumb-interwork -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ +PLATFORM_CPPFLAGS = -march=armv4t -mlong-calls -mtune=arm7tdmi-s -DCONFIG_ARM -D__ARM__ #-mcallee-super-interworking -mthumb -mthumb-interwork TEXT_BASE = 0x00400000 ######################################################################### diff --git a/include/isr.h b/include/isr.h index 4939d42c4..0583ffc7e 100644 --- a/include/isr.h +++ b/include/isr.h @@ -13,7 +13,7 @@ #define no_isrs() no_tmr_isr(); -#define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) +#define enable_tmr_irq() *(volatile uint32_t *)(INTENNUM) = 5; #define no_tmr_isr() void tmr_isr(void) { return; } extern void tmr_isr(void); diff --git a/src/isr.c b/src/isr.c index 5b27130a0..913374208 100644 --- a/src/isr.c +++ b/src/isr.c @@ -1,15 +1,15 @@ #include "embedded_types.h" -#include "interrupt-utils.h" +//#include "interrupt-utils.h" #include "isr.h" #define reg32(x) (*(volatile uint32_t *)(x)) -__attribute__ ((interrupt("IRQ"))) +//__attribute__ ((interrupt("IRQ"))) void isr(void) { // ISR_ENTRY(); /* check for TMR0 interrupt */ -// tmr_isr(); // led turns off if I have this, indicating that the isr does jump to tmr_isr + tmr_isr(); // led turns off if I have this, indicating that the isr does jump to tmr_isr // if(reg32(INTSRC) & (1<<5)) { tmr_isr(); } // asm("SUBS PC,R14_IRQ,#4") // enableIRQ(); // I think this is necessary, but the LED never turns off when I have this @@ -17,4 +17,6 @@ void isr(void) /* putting anything in here breaks the other code :( */ +// asm("ldmfd sp!, {r0-r12,lr}"); +// enableIRQ(); } diff --git a/src/start.S b/src/start.S index 2e17e424e..cbed1189a 100644 --- a/src/start.S +++ b/src/start.S @@ -23,15 +23,33 @@ * MA 02111-1307 USA */ +/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */ + + .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ + .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ + + .equ USR_MODE, 0x10 + .equ FIQ_MODE, 0x11 + .equ IRQ_MODE, 0x12 + .equ SVC_MODE, 0x13 + .equ ABT_MODE, 0x17 + .equ UND_MODE, 0x1B + .equ SYS_MODE, 0x1F + .equ usr_stack_size, 256*4 + .equ irq_stack_size, 128*4 + .equ fiq_stack_size, 128*4 + .equ und_stack_size, 32*4 + .equ abt_stack_size, 32*4 + .equ sup_stack_size, 32*4 + /* ************************************************************************* * * Jump vector table as in table 3.1 in [1] * ************************************************************************* - */ - + */ .set base, . .set _rom_data_init, 0x108d0 @@ -72,7 +90,37 @@ ROM_var_end: .word 0 .code 32 .align _begin: + + ldr r1,=_system_stack + msr cpsr_c,#(SVC_MODE | I_BIT | F_BIT) + add r1,r1,#sup_stack_size + mov sp,r1 + + msr cpsr_c,#(IRQ_MODE | I_BIT | F_BIT) + add r1,r1,#irq_stack_size + mov sp,r1 + + msr cpsr_c,#(FIQ_MODE | I_BIT | F_BIT) + add r1,r1,#fiq_stack_size + mov sp,r1 + + msr cpsr_c,#(ABT_MODE | I_BIT | F_BIT) + add r1,r1,#abt_stack_size + mov sp,r1 + + msr cpsr_c,#(UND_MODE | I_BIT | F_BIT) + add r1,r1,#und_stack_size + mov sp,r1 + +// msr cpsr_c,#(USR_MODE | I_BIT | F_BIT) +// add r1,r1,#usr_stack_size +// mov sp,r1 + + bl _rom_data_init+.-base + msr cpsr_c,#(SVC_MODE) // turn on interrupts --- for debug only + msr cpsr_c,#(USR_MODE) // turn on interrupts --- for debug only +// swi b main _undefined_instruction: .word undefined_instruction @@ -82,9 +130,8 @@ _data_abort: .word data_abort _not_used: .word not_used _irq: .word irq _fiq: .word fiq - .balignl 16,0xdeadbeef - - + .balignl 16,0xdeadbeef + /* ************************************************************************* * @@ -105,6 +152,10 @@ _TEXT_BASE: _armboot_start: .word _start +_system_stack: + . = . + usr_stack_size + irq_stack_size + fiq_stack_size + und_stack_size + abt_stack_size + sup_stack_size + + /* * These are defined in the board-specific linker script. */ @@ -118,6 +169,8 @@ _bss_end: _start_armboot: .word main + + /* ************************************************************************* * @@ -139,42 +192,6 @@ cpu_init_crit: ************************************************************************* */ -@ -@ 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 @@ -197,8 +214,18 @@ not_used: .align 5 irq: + push {lr} + movs lr,pc b isr - .align 5 + pop {lr} + subs pc,r14,#4 // suggested irq return cmd +// STMFD sp!, {r0-r12,lr} +// MOVNE lr,pc +// ldr r0, =isr +// BX r0 +// LDMFD r13!, {r0-r12,r14} +// MOVS PC, R14 +// subs pc, r14, #4 fiq: .align 5 @@ -206,3 +233,4 @@ fiq: .globl reset_cpu reset_cpu: mov pc, r0 + diff --git a/tests/tmr-ints.c b/tests/tmr-ints.c index acb324c64..1fc7fe024 100644 --- a/tests/tmr-ints.c +++ b/tests/tmr-ints.c @@ -47,7 +47,7 @@ #define reg16(x) (*(volatile uint16_t *)(x)) #include "embedded_types.h" -#include "sys-interrupt.h" +//#include "sys-interrupt.h" #include "isr.h" @@ -76,9 +76,22 @@ void tmr_isr(void) { } + +/* void enIRQ(void) { */ +/* asm volatile ( */ +/* ".code 32;" */ +/* "msr cpsr_c,#0x10;" */ +/* ".code 16;" */ +/* ); */ +/* } */ + + __attribute__ ((section ("startup"))) void main(void) { +// *(volatile uint32_t *)0x80020010 = 0x20; +// *(volatile uint32_t *)0x80020034 = 0xffff; //force an int. + /* pin direction */ led_init(); @@ -94,8 +107,8 @@ void main(void) { #define OUT_MODE 0 /* OFLAG is asserted while counter is active */ reg16(TMR_ENBL) = 0; /* tmrs reset to enabled */ - reg16(TMR0_SCTRL) = 0; - reg16(TMR0_CSCTRL) =0x0040; + reg16(TMR0_SCTRL) = 0; + reg16(TMR0_CSCTRL) =0x0040; reg16(TMR0_LOAD) = 0; /* reload to zero */ reg16(TMR0_COMP_UP) = 18750; /* trigger a reload at the end */ reg16(TMR0_CMPLD1) = 18750; /* compare 1 triggered reload level, 10HZ maybe? */ @@ -106,7 +119,8 @@ void main(void) { led_on(); enable_tmr_irq(); - enableIRQ(); + +// enIRQ(); while(1) { /* sit here and let the interrupts do the work */