#include "regs.h"
void enable_mmu(unsigned long ttb);
void init_ttb(unsigned long *ttb_base);
void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa);
void memset(char *buf, char ch, int size);
void memcpy(char *dst, char *src, int size);
void do_irq(unsigned long regs[]);
void (*printf)(char *, ...) = 0x43e11434;
void main(void)
{
unsigned long vector_base = 0xffff0000;
unsigned long tt_base = 0x73000000;
unsigned long *pdo_irq = 0x75000000;
extern unsigned long vectors_start, vectors_end;
memset(tt_base, 0x00, 16 * 1024);
mmap(tt_base, vector_base, 0x70000000);
enable_mmu(tt_base);
memcpy(vector_base, vectors_start, 0x100);
*pdo_irq = do_irq;
//让cpu开中断,cpu可以接收中断,要关闭cpu的中断用cpsid
//一条指令就可以完成对特殊功能寄存器的写操作,以前代码:
//mrs r0,cpsr
//bic r0,r0,#0x80 //清掉最高位
//msr cpsr,r0
__asm__ __volatile__ (
"cpsie i "
);
//-------------------------------------------------------------------------
// 使能GIC中断
ICCICR_CPU0 = 1;
ICCPMR_CPU0 = 0xff; // Priority Unmask All Interrupt
//------------ Eint26 for K1 irqID is 64-----------------
ICDDCR = 1;
// 64号中断优先级,the Zero is Highest priority
// 该寄存器中每个中断号占8位,64号中断就在ICDIPTR16寄存器当中
ICDIPR16_CPU0 = ~(0xff << 0);
// 64号中断给哪个cpu发,该寄存器中每个中断号占8位,64号中断就在ICDIPTR16寄存器当中
// 给cpu0发在ICDIPTR16_CPU0寄存器里面要写上,for CPU0, refer PG815
// 如果给cpu1、cpu3两个发既要在ICDIPTR16_CPU0上写上也要在ICDIPTR16_CPU3上写入
ICDIPTR16_CPU0 = (1 << 0);
// enable interrupt 0,每个中断号占一位,64号中断在ICDISER2当中
ICDISER2_CPU0 = (1 << 0);
//-------------------------------------------------------------------------
//使能外部中断控制器,设置中断引脚;内部中断不用这些设置(timer,watchdog中断等)
GPX3CON &= ~(0x7 << 8);
GPX3CON |= (0xf << 8); //Configure as Exint43_2 --- EINT26
EXT_INT43CON &= ~(0x7 << 8);
EXT_INT43CON &= ~(0x3 << 8); //设置触发边沿:rising edge
EXT_INT43_MASK &= ~(0x1 << 2); //enable ExtINT43_2 --- EINT26 for K1
}
void do_irq(unsigned long regs[])
{
if (EXT_INT43_PEND & (1 << 2)) { //产看是不是发生中断
printf("ExtInt43_2 ");
EXT_INT43_PEND |= (1 << 2); //清除中断
}
}
void enable_mmu(unsigned long ttb)
{
unsigned long c1_flags;
init_ttb(ttb);
c1_flags = 1 | (1 << 3) | ( 1 << 11) | ( 1 << 13) | (1 << 28);
__asm__ __volatile__ (
"mvn r0, #0 "
"mcr p15, 0, r0, c3, c0, 0 "
"mcr p15, 0, %1, c2, c0, 0 " //configure ttb
"mrc p15, 0, r0, c1, c0, 0 "
"orr %0, r0, %0 "
"mcr p15, 0, %0, c1, c0, 0 " //enable mmu
:
: "r" (c1_flags), "r" (ttb)
: "r0"
);
}
void init_ttb(unsigned long *ttb_base)
{
unsigned long va, pa;
for (va = 0x00000000; va < 0x10000000; va += 0x100000) { //Others
pa = va;
ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;
}
for (va = 0x10000000; va < 0x14000000; va += 0x100000) { //SFR
pa = va;
ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;
}
for (va = 0x40000000; va < 0x80000000; va += 0x100000) { //DRAM
pa = va;
ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;
}
}
void mmap(unsigned long *ttb_base, unsigned long va, unsigned long pa)
{
ttb_base[ va >> 20] = (pa & 0xfff00000) | 2;
}
void memset(char *buf, char ch, int size)
{
int i;
for (i = 0; i < size; i ++)
buf[i] = ch;
}
void memcpy(char *dst, char *src, int size)
{
int i;
for (i = 0; i < size; i ++)
dst[i] = src[i];
}
__asm__ (
"vectors: "
"b reset "
"b und "
"b swi "
"b pre_abt "
"b dat_abt "
".word 0 "
"b irq "
"b fiq "
"reset: "
"und: "
"mov sp, #0x74000000 "
"stmfd sp!, {r0-r12, lr} "
"mov r0, sp "
"mov r3, #0x74000000 "
"ldr r3, [r3] "
"blx r3 "
"mov sp, #0x74000000 "
"ldmea sp, {r0-r12, pc}^ "
"swi: "
"pre_abt: "
"dat_abt: "
"fiq: "
"irq: "
"mov sp, #0x75000000 "
"sub lr, lr, #4 "
"stmfd sp!, {r0-r12, lr} "
"mov r0, sp "
"mov r3, #0x75000000 "
"ldr r3, [r3] "
"blx r3 "
"mov sp, #0x75000000 "
"ldmea sp, {r0-r12, pc}^ "
"EOV: "
"vectors_start: "
".word vectors "
"vectors_end: "
".word EOV "
);
===================================================================
Makefile文件:
default:
arm-linux-gcc -c test.c -o test.o
arm-linux-ld -Ttext=0x70003000 test.o -o test
arm-linux-objcopy -O binary test test.bin
clean:
rm -f test.o test test.bin *~
===============================================================
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』