initial import of early start of a cc32rs512 COS project
This commit is contained in:
commit
6942f3cf66
|
@ -0,0 +1,28 @@
|
|||
#ifndef _MEMORY_H
|
||||
#define _MEMORY_H
|
||||
|
||||
#define __arch_getb(a) (*(volatile unsigned char *)(a))
|
||||
#define __arch_getw(a) (*(volatile unsigned short *)(a))
|
||||
#define __arch_getl(a) (*(volatile unsigned int *)(a))
|
||||
|
||||
#define __arch_putb(v,a) (*(volatile unsigned char *)(a) = (v))
|
||||
#define __arch_putw(v,a) (*(volatile unsigned short *)(a) = (v))
|
||||
#define __arch_putl(v,a) (*(volatile unsigned int *)(a) = (v))
|
||||
|
||||
#define __raw_writeb(v,a) __arch_putb(v,a)
|
||||
#define __raw_writew(v,a) __arch_putw(v,a)
|
||||
#define __raw_writel(v,a) __arch_putl(v,a)
|
||||
|
||||
#define __raw_readb(a) __arch_getb(a)
|
||||
#define __raw_readw(a) __arch_getw(a)
|
||||
#define __raw_readl(a) __arch_getl(a)
|
||||
|
||||
#define writeb(v,a) __arch_putb(v,a)
|
||||
#define writew(v,a) __arch_putw(v,a)
|
||||
#define writel(v,a) __arch_putl(v,a)
|
||||
|
||||
#define readb(a) __arch_getb(a)
|
||||
#define readw(a) __arch_getw(a)
|
||||
#define readl(a) __arch_getl(a)
|
||||
|
||||
#endif /* _MEMORY_H */
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
CROSS_COMPILE = arm-elf-
|
||||
|
||||
CC = $(CROSS_COMPILE)gcc
|
||||
SIZE = $(CROSS_COMPILE)size
|
||||
STRIP = $(CROSS_COMPILE)strip
|
||||
OBJCOPY = $(CROSS_COMPILE)objcopy
|
||||
|
||||
OPTIMIZATION = -Os
|
||||
|
||||
ASM_OBJECTS = cc32/start.o
|
||||
|
||||
C_OBJECTS = main.o cc32/cc32_flcon.o cc32/cc32_irq.o cc32/iso7816_slave.o
|
||||
|
||||
|
||||
CFLAGS = -Wall -ffunction-sections -fno-exceptions -nostartfiles -nostdlib #-mthumb
|
||||
CFLAGS += -I../include
|
||||
CFLAGS += -g $(OPTIMIZATION)
|
||||
|
||||
LDFLAGS = -g $(OPTIMIZATION) -nostartfiles -Wl,--gc-sections
|
||||
|
||||
target: $(ASM_OBJECTS) $(C_OBJECTS)
|
||||
$(CC) $(LDFLAGS) -T"cc32/CC32RS512.lds" -o $@.elf $^
|
||||
|
||||
$(ASM_OBJECTS): %.o: %.s Makefile
|
||||
$(CC) $(ASFLAGS) -c -o $@ $<
|
||||
|
||||
$(C_OBJECTS): %.o: %.c Makefile
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
clean:
|
||||
@rm $(ASM_OBJECTS) $(C_OBJECTS) target.elf
|
|
@ -0,0 +1,126 @@
|
|||
/* Memory Definitions */
|
||||
|
||||
|
||||
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
|
||||
OUTPUT_ARCH(arm)
|
||||
ENTRY(exceptions)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00080000
|
||||
RAM (rw) : ORIGIN = 0x000C0000, LENGTH = 0x00004000
|
||||
STACK (rw) : ORIGIN = 0x000C4000, LENGTH = 0x00000000
|
||||
}
|
||||
|
||||
/* Section Definitions */
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text.exceptions : {
|
||||
PROVIDE(exceptions = .);
|
||||
KEEP(*(.text.exceptions))
|
||||
*(.text.exceptions)
|
||||
} > FLASH
|
||||
|
||||
/* first section is .text which is used for code */
|
||||
.text : {
|
||||
* (.text)
|
||||
* (.glue_7)
|
||||
* (.glue_7t)
|
||||
. = ALIGN(4);
|
||||
} >FLASH
|
||||
PROVIDE(_text_start = ADDR(.text));
|
||||
PROVIDE(_text_end = ADDR(.text) + SIZEOF(.text));
|
||||
|
||||
.ctors : {
|
||||
LONG(SIZEOF(.ctors) / 4 - 2)
|
||||
KEEP(*(SORT(.ctors)))
|
||||
LONG(0)
|
||||
} >FLASH
|
||||
PROVIDE(_ctor_start = LOADADDR(.ctors));
|
||||
PROVIDE(_ctor_end = LOADADDR(.ctors) + SIZEOF(.ctors));
|
||||
|
||||
.dtors : {
|
||||
LONG(SIZEOF(.dtors) / 4 - 2)
|
||||
KEEP(*(SORT(.dtors)))
|
||||
LONG(0)
|
||||
} >FLASH
|
||||
PROVIDE(_dtor_start = LOADADDR(.dtors));
|
||||
PROVIDE(_dtor_end = LOADADDR(.dtors) + SIZEOF(.dtors));
|
||||
|
||||
.rodata : {
|
||||
* (.rodata*)
|
||||
} > FLASH
|
||||
PROVIDE(_rodata_start = ADDR(.rodata));
|
||||
PROVIDE(_rodata_end = ADDR(.rodata) + SIZEOF(.rodata));
|
||||
|
||||
.got : {
|
||||
. = ALIGN(4);
|
||||
*(.got)
|
||||
*(.got.plt) *(.igot.plt) *(.got) *(.igot)
|
||||
. = ALIGN(4);
|
||||
} > FLASH
|
||||
PROVIDE(_got_start = ADDR(.got));
|
||||
PROVIDE(_got_end = ADDR(.got) + SIZEOF(.got));
|
||||
|
||||
.data : {
|
||||
_data = . ;
|
||||
* (.vectram)
|
||||
* (.data)
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
PROVIDE(__data_start = LOADADDR(.data));
|
||||
PROVIDE(__data_end = LOADADDR(.data) + SIZEOF(.data));
|
||||
PROVIDE(_data_start = ADDR(.data));
|
||||
PROVIDE(_data_end = ADDR(.data) + SIZEOF(.data));
|
||||
|
||||
/* .bss section which is used for uninitialized data */
|
||||
.bss (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.bss)
|
||||
. = ALIGN(4);
|
||||
} > RAM
|
||||
PROVIDE(__bss_start = ADDR(.bss));
|
||||
PROVIDE(__bss_end = ADDR(.bss) + SIZEOF(.bss));
|
||||
PROVIDE(_bss_start = __bss_start);
|
||||
PROVIDE(_bss_end = __bss_end);
|
||||
|
||||
. = ALIGN(4);
|
||||
_end = .;
|
||||
PROVIDE(end = .);
|
||||
|
||||
/* Stabs debugging sections. */
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
/* DWARF debug sections.
|
||||
Symbols in the DWARF debugging sections are relative to the beginning
|
||||
of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* ChipCity CC32RS512 Flash controller driver
|
||||
*
|
||||
* Copyright (C) 2012 Harald Welte <laforge@gnumonks.org>
|
||||
*
|
||||
* 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 or
|
||||
* (at your option) version 3 of the License.
|
||||
*
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cc32_irq.h"
|
||||
#include "cc32_flcon.h"
|
||||
|
||||
#define CC32_FLCON_BASE 0x0f2000
|
||||
|
||||
enum cc32_flcon_reg {
|
||||
FLCON = 0x00,
|
||||
FLSDP1 = 0x04,
|
||||
FLSDP2 = 0x08,
|
||||
FLSTS = 0x0C,
|
||||
FLBUF = 0x10,
|
||||
};
|
||||
|
||||
#define FLCON_REG(x) (uint32_t *)((uint8_t *)CC32_FLCON_BASE + x)
|
||||
|
||||
|
||||
int cc32_flash_erase(uint32_t offset, uint16_t page_size)
|
||||
{
|
||||
switch (page_size) {
|
||||
case 256:
|
||||
*FLCON_REG(FLCON) = (1 << 3);
|
||||
break;
|
||||
case 512:
|
||||
*FLCON_REG(FLCON) = (0 << 3);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we program/erase the first page, we have to disable the interrupt */
|
||||
if (offset < page_size)
|
||||
cc32_irq_disable(IRQ_FLCON);
|
||||
|
||||
/* clear all flags */
|
||||
*FLCON_REG(FLSTS) = 3;
|
||||
|
||||
*FLCON_REG(FLSDP1) = 0x55;
|
||||
*FLCON_REG(FLSDP2) = 0xAA;
|
||||
|
||||
*(uint32_t *)offset = 0xFF;
|
||||
|
||||
while (!(*FLCON_REG(FLSTS) & 1)) {}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cc32_flash_program(uint32_t offset, uint16_t page_size, uint32_t *buffer)
|
||||
{
|
||||
switch (page_size) {
|
||||
case 256:
|
||||
*FLCON_REG(FLCON) = (1 << 3);
|
||||
break;
|
||||
case 512:
|
||||
*FLCON_REG(FLCON) = (0 << 3);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* if we program/erase the first page, we have to disable the interrupt */
|
||||
if (offset < page_size)
|
||||
cc32_irq_disable(IRQ_FLCON);
|
||||
|
||||
/* clear all flags */
|
||||
*FLCON_REG(FLSTS) = 3;
|
||||
|
||||
*FLCON_REG(FLBUF) = offset;
|
||||
*FLCON_REG(FLSDP1) = 0xAA;
|
||||
*FLCON_REG(FLSDP2) = 0x55;
|
||||
|
||||
*(uint32_t *)offset = 0x00;
|
||||
|
||||
while (!(*FLCON_REG(FLSTS) & 1)) {}
|
||||
|
||||
/* clear flag */
|
||||
*FLCON_REG(FLSTS) |= 1;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
int cc32_flash_erase(uint32_t offset, uint16_t page_size);
|
||||
int cc32_flash_program(uint32_t offset, uint16_t page_size, uint32_t *buffer);
|
|
@ -0,0 +1,40 @@
|
|||
|
||||
#include "cc32_irq.h"
|
||||
|
||||
#define CC32_SYSC_BASE 0x0F0000
|
||||
|
||||
enum cc32_sysc_reg {
|
||||
SCCM0 = 0x00,
|
||||
SCSYS = 0x04,
|
||||
SCCKOUT = 0x20,
|
||||
SCRSTFLG = 0x28,
|
||||
SCRSTEN = 0x2C,
|
||||
SCSFTRST = 0x30,
|
||||
SCRSTCON0 = 0x34,
|
||||
SCRSTCON4 = 0x38,
|
||||
SCSLEEP = 0x3C,
|
||||
SCGCON = 0x40,
|
||||
SCINTSTS = 0x44,
|
||||
SCINTEN = 0x48,
|
||||
SCGINT0 = 0x5C,
|
||||
SCGLEV = 0x64,
|
||||
SCWUT = 0x68,
|
||||
SCCM4 = 0x7C,
|
||||
};
|
||||
|
||||
#define SYSC_REG(x) (uint32_t *)((uint8_t *)CC32_SYSC_BASE + x)
|
||||
|
||||
void cc32_irq_enable(enum cc32_irq irq)
|
||||
{
|
||||
*SYSC_REG(SCINTEN) |= (1 << irq);
|
||||
}
|
||||
|
||||
void cc32_irq_disable(enum cc32_irq irq)
|
||||
{
|
||||
*SYSC_REG(SCINTEN) &= ~(1 << irq);
|
||||
}
|
||||
|
||||
void cc32_irq_register(enum cc32_irq irq, void (*handler)(enum cc32_irq irq))
|
||||
{
|
||||
/* FIXME */
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef _CC32_IRQ_H
|
||||
#define _CC32_IRQ_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
enum cc32_irq {
|
||||
IRQ_TIMER0 = 2,
|
||||
IRQ_TIMER1 = 3,
|
||||
IRQ_TIMER2 = 4,
|
||||
IRQ_FLCON = 6,
|
||||
IRQ_UART = 8,
|
||||
IRQ_GPIO = 11,
|
||||
IRQ_SPI = 13,
|
||||
IRQ_SCU = 15,
|
||||
IRQ_MCU = 17,
|
||||
IRQ_DES = 19,
|
||||
IRQ_AES = 20,
|
||||
IRQ_DMA = 22,
|
||||
IRQ_ISO7816_MST = 26,
|
||||
IRQ_WUT = 27,
|
||||
IRQ_RSA = 28,
|
||||
};
|
||||
|
||||
void cc32_irq_enable(enum cc32_irq irq);
|
||||
void cc32_irq_disable(enum cc32_irq irq);
|
||||
void cc32_irq_register(enum cc32_irq irq, void (*handler)(enum cc32_irq irq));
|
||||
|
||||
#endif
|
|
@ -0,0 +1,128 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <memory.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "cc32_irq.h"
|
||||
|
||||
enum iso_slave_reg {
|
||||
ISOCON = 0x00,
|
||||
ISOCON1 = 0x04,
|
||||
ISOCON2 = 0x08,
|
||||
ISOSTS = 0x0c,
|
||||
ISOBRC = 0x10,
|
||||
ISOBUF = 0x14,
|
||||
ISODIO = 0x18,
|
||||
ISOMSK = 0x1c,
|
||||
ISODMACON = 0x30,
|
||||
ISODMASTS = 0x34,
|
||||
ISODMABFAD = 0x38,
|
||||
ISODMABFLEN = 0x3c,
|
||||
ISODMABFPT = 0x40,
|
||||
ISODMAMSK = 0x44,
|
||||
ISOTCON = 0x50,
|
||||
ISOTDAT = 0x54,
|
||||
ISOTRLD = 0x58,
|
||||
ISOTMSK = 0x5c,
|
||||
ISONULL = 0x60,
|
||||
};
|
||||
|
||||
#define CC32_BASE_UART 0x0F8800
|
||||
#define UART_REG(n) (CC32_BASE_UART+(n))
|
||||
|
||||
#define ISOCON_TR (1 << 5)
|
||||
#define ISOCON_TACT (1 << 4)
|
||||
|
||||
#define ISOSTS_TBE (1 << 0)
|
||||
#define ISOSTS_RBF (1 << 1)
|
||||
#define ISOSTS_PE (1 << 2)
|
||||
#define ISOSTS_OE (1 << 3)
|
||||
|
||||
#define ISOCON2_SBIT (1 << 7)
|
||||
|
||||
#define ISOBRC_DI(x) ((x) & 0xf)
|
||||
#define ISOBRC_FI(x) (((x) & 0xf) << 4)
|
||||
|
||||
struct iso_slave_state {
|
||||
uint8_t fi;
|
||||
uint8_t di;
|
||||
};
|
||||
static struct iso_slave_state iss;
|
||||
|
||||
/* will be called from FIQ mode */
|
||||
static void slave_irq(uint8_t irq)
|
||||
{
|
||||
//FIXME
|
||||
}
|
||||
|
||||
int iso7816_slave_fi_di(uint8_t fi, uint8_t di)
|
||||
{
|
||||
writel(ISOBRC_DI(di) | ISOBRC_FI(fi), UART_REG(ISOBRC));
|
||||
iss.fi = fi;
|
||||
iss.di = di;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iso7816_slave_tx_ch(uint8_t ch)
|
||||
{
|
||||
writel(ISOCON_TR, UART_REG(ISOCON));
|
||||
writel(ch, UART_REG(ISOBUF));
|
||||
|
||||
if (readl(UART_REG(ISOSTS)) & ISOSTS_PE) {
|
||||
writel(ISOSTS_PE, UART_REG(ISOSTS));
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
while (readl(UART_REG(ISOCON)) & ISOCON_TACT) { }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iso7816_slave_tx5(const uint8_t *data)
|
||||
{
|
||||
iso7816_slave_tx_ch(data[0]);
|
||||
iso7816_slave_tx_ch(data[1]);
|
||||
iso7816_slave_tx_ch(data[2]);
|
||||
iso7816_slave_tx_ch(data[3]);
|
||||
iso7816_slave_tx_ch(data[4]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int iso7816_slave_tx(const uint8_t *data, uint8_t len)
|
||||
{
|
||||
int i;
|
||||
/* FIXME: fiq/dma ? */
|
||||
|
||||
writel(ISOCON_TR, UART_REG(ISOCON));
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (iso7816_slave_tx_ch(data[i]) < 0)
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
int iso7816_slave_init(void)
|
||||
{
|
||||
/* receive mode */
|
||||
writel(0, UART_REG(ISOCON));
|
||||
/* up to 6 times re-transmission */
|
||||
writel(6 | ISOCON2_SBIT, UART_REG(ISOCON1));
|
||||
/* T=0 mode */
|
||||
writel(0, UART_REG(ISOCON2));
|
||||
/* clear status bits, if any */
|
||||
writel(ISOSTS_PE|ISOSTS_OE, UART_REG(ISOSTS));
|
||||
/* disable SBIT interrupt */
|
||||
writel(ISOCON2_SBIT, UART_REG(ISOMSK));
|
||||
|
||||
/* Initial Fi/Di setting */
|
||||
iso7816_slave_fi_di(1, 1);
|
||||
|
||||
cc32_irq_register(IRQ_UART, &slave_irq);
|
||||
//cc32_irq_enable(IRQ_UART);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _ISO7816_SLAVE_H
|
||||
#define _ISO7816_SLAVE_H
|
||||
|
||||
int iso7816_slave_init(void);
|
||||
int iso7816_slave_tx(const uint8_t *data, uint8_t len);
|
||||
int iso7816_slave_tx_ch(uint8_t ch);
|
||||
int iso7816_slave_tx5(const uint8_t *data);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,215 @@
|
|||
/* low-level startup outines for CC32RS512 / ARM7TDMI
|
||||
* (C) 2006-2012 by Harald Welte <hwelte@hmw-consulting.de>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
/* Configurable values */
|
||||
|
||||
.equ ROM_Start, 0x0 /* Base address of ROM(flash) */
|
||||
.equ RAM_Start, 0x0C0000 /* Base address of RAM */
|
||||
.equ RAM_Size, 0x4000 /* For CC32RS512 */
|
||||
|
||||
.equ SVC_Stack_Size, 128
|
||||
.equ IRQ_Stack_Size, 128
|
||||
.equ FIQ_Stack_Size, 128
|
||||
.equ ABT_Stack_Size, 128
|
||||
.equ SYS_Stack_Size, 256
|
||||
|
||||
/* Computed Values */
|
||||
|
||||
.equ FIQ_Stack, RAM_Limit
|
||||
.equ IRQ_Stack, FIQ_Stack-FIQ_Stack_Size
|
||||
.equ ABT_Stack, IRQ_Stack-IRQ_Stack_Size
|
||||
.equ SVC_Stack, ABT_Stack-ABT_Stack_Size
|
||||
.equ SYS_Stack, SVC_Stack-SVC_Stack_Size
|
||||
|
||||
.equ RAM_Limit, RAM_Start+RAM_Size
|
||||
|
||||
|
||||
/* Exception Vectors in RAM */
|
||||
|
||||
.text
|
||||
.arm
|
||||
.section .vectram, "ax"
|
||||
|
||||
#;------------------------------------------------------------------------------
|
||||
#;- Section Definition
|
||||
#;-----------------
|
||||
#;- Section
|
||||
#;- .internal_ram_top Top_Stack: used by the cstartup for vector initalisation
|
||||
#;- management defined by ld and affect from ldscript
|
||||
#;------------------------------------------------------------------------------
|
||||
.section .internal_ram_top
|
||||
.code 32
|
||||
.align 0
|
||||
.global Top_Stack
|
||||
Top_Stack:
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
*- Area Definition
|
||||
*------------------------------------------------------------------------------
|
||||
* .text is used instead of .section .text so it works with arm-aout too. */
|
||||
.section .text.exceptions
|
||||
.text
|
||||
.global exceptions
|
||||
exceptions:
|
||||
/*------------------------------------------------------------------------------
|
||||
//*- Exception vectors
|
||||
//*--------------------
|
||||
//*- These vectors can be read at address 0 or at RAM address
|
||||
//*- They ABSOLUTELY requires to be in relative addresssing mode in order to
|
||||
//*- guarantee a valid jump. For the moment, all are just looping.
|
||||
//*- If an exception occurs before remap, this would result in an infinite loop.
|
||||
//*- To ensure if a exeption occurs before start application to infinite loop.
|
||||
//*------------------------------------------------------------------------------*/
|
||||
|
||||
B InitReset /* 0x00 Reset handler */
|
||||
undefvec:
|
||||
B undefvec /* 0x04 Undefined Instruction */
|
||||
swivec:
|
||||
B swivec /* 0x08 Software Interrupt */
|
||||
pabtvec:
|
||||
B pabtvec /* 0x0C Prefetch Abort */
|
||||
dabtvec:
|
||||
b dabtvec /* 0x10 Data Abort */
|
||||
rsvdvec:
|
||||
b rsvdvec /* 0x14 reserved */
|
||||
irqvec:
|
||||
b IRQ_Handler_Entry /* 0x18 IRQ */
|
||||
fiqvec:
|
||||
b FIQ_Handler_Entry /* 0x1c FIQ */
|
||||
|
||||
.global IRQ_Handler_Entry
|
||||
.func IRQ_Handler_Entry
|
||||
|
||||
FIQ_Handler_Entry:
|
||||
|
||||
b FIQ_Handler_Entry
|
||||
|
||||
/*- Save and r0 in FIQ_Register */
|
||||
/* FIXME: ISO7816 Slave driver */
|
||||
|
||||
/*- Restore the Program Counter using the LR_fiq directly in the PC */
|
||||
subs pc, lr, #4
|
||||
|
||||
IRQ_Handler_Entry:
|
||||
b IRQ_Handler_Entry
|
||||
|
||||
/*- Manage Exception Entry */
|
||||
/*- Adjust and save LR_irq in IRQ stack */
|
||||
sub lr, lr, #4
|
||||
stmfd sp!, {lr}
|
||||
|
||||
/* FIXME */
|
||||
|
||||
/*- Restore adjusted LR_irq from IRQ stack directly in the PC */
|
||||
ldmia sp!, {pc}^
|
||||
|
||||
.size IRQ_Handler_Entry, . - IRQ_Handler_Entry
|
||||
.endfunc
|
||||
.align 0
|
||||
.RAM_TOP:
|
||||
.word Top_Stack
|
||||
|
||||
|
||||
.global _startup
|
||||
.func _startup
|
||||
InitReset:
|
||||
|
||||
.equ MPUDisable, 0xfffffffe
|
||||
|
||||
/* Disable memory protection unit */
|
||||
mrc p15, 0, r0, c1, c0, 0
|
||||
and r0, r0, #MPUDisable
|
||||
mcr p15, 0, r0, c1, c0, 0
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
//*- Top of Stack Definition
|
||||
//*-------------------------
|
||||
//*- Interrupt and Supervisor Stack are located at the top of internal memory in
|
||||
//*- order to speed the exception handling context saving and restoring.
|
||||
//*- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
|
||||
//*------------------------------------------------------------------------------*/
|
||||
|
||||
.EQU ARM_MODE_FIQ, 0x11
|
||||
.EQU ARM_MODE_IRQ, 0x12
|
||||
.EQU ARM_MODE_SVC, 0x13
|
||||
.EQU ARM_MODE_ABT, 0x17
|
||||
.EQU ARM_MODE_SYS, 0x1F
|
||||
|
||||
.EQU I_BIT, 0x80
|
||||
.EQU F_BIT, 0x40
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
//*- Setup the stack for each mode
|
||||
//*-------------------------------*/
|
||||
ldr r13, =FIQ_Stack
|
||||
mov r0, r13
|
||||
|
||||
/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/
|
||||
msr CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
|
||||
mov r13, r0
|
||||
sub r0, r0, #FIQ_Stack_Size
|
||||
|
||||
/*- Set up Interrupt Mode and set IRQ Mode Stack*/
|
||||
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
|
||||
mov r13, r0 /* Init stack IRQ */
|
||||
sub r0, r0, #IRQ_Stack_Size
|
||||
|
||||
/*- Set up Abort Mode and set Supervisor Mode Stack*/
|
||||
msr CPSR_c, #ARM_MODE_ABT | I_BIT | F_BIT
|
||||
mov r13, r0 /* Init stack Sup */
|
||||
sub r0, r0, #ABT_Stack_Size
|
||||
|
||||
/*- Set up Supervisor Mode and set Supervisor Mode Stack*/
|
||||
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
|
||||
mov r13, r0 /* Init stack Sup */
|
||||
sub r0, r0, #SVC_Stack_Size
|
||||
|
||||
/*- Set up System Mode and Enable Interrupts and FIQ */
|
||||
msr CPSR_c, #ARM_MODE_SYS
|
||||
mov r13, r0
|
||||
|
||||
# Clear .bss section (Zero init)
|
||||
MOV R0, #0
|
||||
LDR R1, =__bss_start
|
||||
LDR R2, =__bss_end
|
||||
LoopZI: CMP R1, R2
|
||||
STRLO R0, [R1], #4
|
||||
BLO LoopZI
|
||||
|
||||
/* prepare c function call to main */
|
||||
mov r0, #0 /* argc = 0 */
|
||||
ldr lr, =exit
|
||||
ldr r10, =main
|
||||
|
||||
bx r10
|
||||
|
||||
.size InitReset,.-InitReset
|
||||
.endfunc
|
||||
|
||||
/* "exit" dummy to avoid sbrk write read etc. needed by the newlib default "exit" */
|
||||
.global exit
|
||||
.func exit
|
||||
exit:
|
||||
b .
|
||||
.size exit, . - exit
|
||||
.endfunc
|
||||
|
||||
|
||||
.end
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cc32/cc32_flcon.h"
|
||||
#include "cc32/cc32_irq.h"
|
||||
#include "cc32/iso7816_slave.h"
|
||||
|
||||
#define BASE_ISO7816_SLAVE 0x0F8800
|
||||
|
||||
const uint8_t atr[] = "ThisIsNotAnATR\n";
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
/* we generally don't want interrupts yet */
|
||||
cc32_irq_disable(IRQ_FLCON | IRQ_UART);
|
||||
char *atr2 = "12345";
|
||||
|
||||
iso7816_slave_init();
|
||||
|
||||
iso7816_slave_tx_ch('H');
|
||||
iso7816_slave_tx_ch('W');
|
||||
iso7816_slave_tx_ch('H');
|
||||
iso7816_slave_tx_ch('W');
|
||||
|
||||
//iso7816_slave_tx(atr2, 5);
|
||||
|
||||
iso7816_slave_tx_ch(atr2[0]);
|
||||
iso7816_slave_tx_ch(atr2[1]);
|
||||
iso7816_slave_tx_ch(atr2[2]);
|
||||
iso7816_slave_tx_ch(atr2[3]);
|
||||
iso7816_slave_tx_ch(atr2[4]);
|
||||
|
||||
iso7816_slave_tx5(atr2);
|
||||
|
||||
if (iso7816_slave_tx(atr, sizeof(atr)) < 0)
|
||||
cc32_flash_erase(10*256, 256);
|
||||
|
||||
while (1) {
|
||||
//cc32_flash_erase(10*256, 256);
|
||||
}
|
||||
}
|
Reference in New Issue