1
0
Fork 0
forked from len0rd/rockbox

hwstub: Add atj213x support

Change-Id: Ic32200f9ab2c6977e503307a9cbe43a1328d0341
This commit is contained in:
Marcin Bukat 2014-09-23 13:30:17 +02:00
parent 791be56cff
commit d11704fed5
17 changed files with 4707 additions and 35 deletions

View file

@ -10,12 +10,12 @@ AS = $(TOOLCHAIN)as
OBJCOPY = $(TOOLCHAIN)objcopy OBJCOPY = $(TOOLCHAIN)objcopy
OBJDUMP = $(TOOLCHAIN)objdump OBJDUMP = $(TOOLCHAIN)objdump
CFLAGS = -Wundef -march=4kec -nostdlib -Os -c CFLAGS = -Wundef -march=mips32r2 -nostdlib -Os -c
OBJS = crt0.o test_bl.o OBJS = crt0.o test_bl.o
LDSCRIPT= test_bl.lds LDSCRIPT= test_bl.lds
LDFLAGS = -Wundef -march=4kec -T$(LDSCRIPT) -nostartfiles \ LDFLAGS = -Wundef -march=mips32r2 -T$(LDSCRIPT) -nostartfiles \
-nostdlib -Xlinker -Map=$(TARGET).map -nostdlib -Xlinker -Map=$(TARGET).map
all : $(TARGET).bin all : $(TARGET).bin

View file

@ -5,7 +5,7 @@
.set mips32r2 .set mips32r2
.set noreorder .set noreorder
.set noat // .set noat
.section .init.text,"ax",%progbits .section .init.text,"ax",%progbits
@ -18,50 +18,68 @@ load_addr:
addiu v0, ra, -12 # calc real load address addiu v0, ra, -12 # calc real load address
# account for branch delay slot # account for branch delay slot
# and very first 'di' instruction # and very first 'di' instruction
# setup caches
# 4-way, 256 sets, 16 bytes cacheline I/D
la t0, 0x80000000 # an idx op should use an unmappable address
ori t1, t0, 0x4000 # 16kB cache
mtc0 zero, C0_TAGLO
mtc0 zero, C0_TAGHI
ehb # execution hazard barrier
cache_init_loop:
cache ICIndexStTag, 0(t0) # index store icache tag
cache DCIndexStTag, 0(t0) # index store dcache tag
addiu t0, t0, 0x10
bne t0, t1, cache_init_loop
nop
li t0, 3 # enable cache for kseg0 accesses
mtc0 t0, C0_CONFIG
ehb
relocation:
la t0, relocstart la t0, relocstart
la t1, relocend la t1, relocend
beq t0, v0, entry_point # no relocation needed beq t0, v0, entry_point # no relocation needed
nop nop
reloc_loop: reloc_loop:
lw t2, 0(v0) # src lw s0, 0(v0) # src
addiu v0, 4 # inc src addr lw s1, 4(v0)
addiu t0, 4 # inc dst addr lw s2, 8(v0)
bne t0, t1, reloc_loop lw s3, 12(v0)
sw t2, -4(t0) # dst
sw s0, 0(t0) # dst
sw s1, 4(t0)
sw s2, 8(t0)
sw s3, 12(t0)
synci 0(t0) # dcache writeback invalidate
# icache invalidate
addiu t0, t0, 16 # inc dst addr
blt t0, t1, reloc_loop
addiu v0, v0, 16 # inc src addr
entry_point_jump: entry_point_jump:
la t0, entry_point la t0, entry_point
jr t0 jr.hb t0 # jump register with hazard barier
nop nop
entry_point: entry_point:
# setup caches
# 4-way, 256 sets, 16 bytes cacheline I/D
li t0, 3 # enable cache for kseg0 accesses
mtc0 t0, C0_CONFIG
la t0, 0x80000000 # an idx op should use an unmappable address
ori t1, t0, 0x4000 # 16kB cache
mtc0 zero, C0_TAGLO
mtc0 zero, C0_TAGHI
cache_init_loop:
cache 8, 0(t0) # index store icache tag
cache 9, 0(t0) # index store dcache tag
addiu t0, t0, 0x10
bne t0, t1, cache_init_loop
nop
# clear bss # clear bss
la t0, bssbegin la t0, bssbegin
la t1, bssend la t1, bssend
beq t0, t1, stack_setup
nop
clear_bss_loop: clear_bss_loop:
addiu t0, 4 addiu t0, 4
bne t0, t1, clear_bss_loop bne t0, t1, clear_bss_loop
sw zero, -4(t0) sw zero, -4(t0)
stack_setup:
# setup stack # setup stack
la sp, stackend la sp, stackend
la t0, stackbegin la t0, stackbegin

View file

@ -5,7 +5,7 @@ SECTIONS
{ {
.text 0xa0001000 : .text 0x80000000 :
{ {
relocstart = .; relocstart = .;
*(.init.text*) *(.init.text*)
@ -21,6 +21,7 @@ SECTIONS
.bss : .bss :
{ {
. = ALIGN(4);
bssbegin = .; bssbegin = .;
*(.sbss*) *(.sbss*)
*(.bss*) *(.bss*)
@ -31,6 +32,7 @@ SECTIONS
.stack (NOLOAD) : .stack (NOLOAD) :
{ {
. = ALIGN(4);
stackbegin = .; stackbegin = .;
. += 0x2000; . += 0x2000;
stackend = .; stackend = .;

View file

@ -109,6 +109,7 @@ struct hwstub_pp_desc_t
#define HWSTUB_TARGET_STMP ('S' | 'T' << 8 | 'M' << 16 | 'P' << 24) #define HWSTUB_TARGET_STMP ('S' | 'T' << 8 | 'M' << 16 | 'P' << 24)
#define HWSTUB_TARGET_RK27 ('R' | 'K' << 8 | '2' << 16 | '7' << 24) #define HWSTUB_TARGET_RK27 ('R' | 'K' << 8 | '2' << 16 | '7' << 24)
#define HWSTUB_TARGET_PP ('P' | 'P' << 8 | ' ' << 16 | ' ' << 24) #define HWSTUB_TARGET_PP ('P' | 'P' << 8 | ' ' << 16 | ' ' << 24)
#define HWSTUB_TARGET_ATJ ('A' | 'T' << 8 | 'J' << 16 | ' ' << 24)
struct hwstub_target_desc_t struct hwstub_target_desc_t
{ {

View file

@ -2,6 +2,11 @@
asm/arm/memcpy.S asm/arm/memcpy.S
asm/arm/memmove.S asm/arm/memmove.S
asm/arm/memset.S asm/arm/memset.S
#elif defined(CPU_MIPS)
asm/mips/memcpy.S
asm/mips/memset.S
#else
#error "Unimplemented ISA"
#endif #endif
main.c main.c
logf.c logf.c
@ -19,4 +24,8 @@ rk27xx/target.c
pp/crt0.S pp/crt0.S
pp/target.c pp/target.c
usb_drv_arc.c usb_drv_arc.c
#elif defined(CONFIG_ATJ213X)
atj213x/crt0.S
atj213x/target.c
atj213x/usb_drv_atj213x.c
#endif #endif

View file

@ -0,0 +1,153 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
* This file was originally part of the GNU C Library
* Contributed to glibc by Hartvig Ekner <hartvige@mips.com>, 2002
* Adapted for Rockbox by Maurus Cuelenaere, 2009
* memmove() adapted after linux kernel by Marcin Bukat, 2014
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "mips.h"
/* void *memcpy(void *s1, const void *s2, size_t n); */
#ifdef ROCKBOX_BIG_ENDIAN
# define LWHI lwl /* high part is left in big-endian */
# define SWHI swl /* high part is left in big-endian */
# define LWLO lwr /* low part is right in big-endian */
# define SWLO swr /* low part is right in big-endian */
#else
# define LWHI lwr /* high part is right in little-endian */
# define SWHI swr /* high part is right in little-endian */
# define LWLO lwl /* low part is left in little-endian */
# define SWLO swl /* low part is left in little-endian */
#endif
.section .icode, "ax", %progbits
.global memcpy
.type memcpy, %function
.global mempcpy
.type mempcpy, %function
.set noreorder
mempcpy:
slti t0, a2, 8 # Less than 8?
bne t0, zero, last8
addu v0, a0, a2 # exit value = s1 + n
b 1f
xor t0, a1, a0 # Find a0/a1 displacement (fill delay)
memcpy:
slti t0, a2, 8 # Less than 8?
bne t0, zero, last8
move v0, a0 # Setup exit value before too late
xor t0, a1, a0 # Find a0/a1 displacement
1: andi t0, 0x3
bne t0, zero, shift # Go handle the unaligned case
subu t1, zero, a1
andi t1, 0x3 # a0/a1 are aligned, but are we
beq t1, zero, chk8w # starting in the middle of a word?
subu a2, t1
LWHI t0, 0(a1) # Yes we are... take care of that
addu a1, t1
SWHI t0, 0(a0)
addu a0, t1
chk8w:
andi t0, a2, 0x1f # 32 or more bytes left?
beq t0, a2, chk1w
subu a3, a2, t0 # Yes
addu a3, a1 # a3 = end address of loop
move a2, t0 # a2 = what will be left after loop
lop8w:
lw t0, 0(a1) # Loop taking 8 words at a time
lw t1, 4(a1)
lw t2, 8(a1)
lw t3, 12(a1)
lw t4, 16(a1)
lw t5, 20(a1)
lw t6, 24(a1)
lw t7, 28(a1)
addiu a0, 32
addiu a1, 32
sw t0, -32(a0)
sw t1, -28(a0)
sw t2, -24(a0)
sw t3, -20(a0)
sw t4, -16(a0)
sw t5, -12(a0)
sw t6, -8(a0)
bne a1, a3, lop8w
sw t7, -4(a0)
chk1w:
andi t0, a2, 0x3 # 4 or more bytes left?
beq t0, a2, last8
subu a3, a2, t0 # Yes, handle them one word at a time
addu a3, a1 # a3 again end address
move a2, t0
lop1w:
lw t0, 0(a1)
addiu a0, 4
addiu a1, 4
bne a1, a3, lop1w
sw t0, -4(a0)
last8:
blez a2, lst8e # Handle last 8 bytes, one at a time
addu a3, a2, a1
lst8l:
lb t0, 0(a1)
addiu a0, 1
addiu a1, 1
bne a1, a3, lst8l
sb t0, -1(a0)
lst8e:
jr ra # Bye, bye
nop
shift:
subu a3, zero, a0 # Src and Dest unaligned
andi a3, 0x3 # (unoptimized case...)
beq a3, zero, shft1
subu a2, a3 # a2 = bytes left
LWHI t0, 0(a1) # Take care of first odd part
LWLO t0, 3(a1)
addu a1, a3
SWHI t0, 0(a0)
addu a0, a3
shft1:
andi t0, a2, 0x3
subu a3, a2, t0
addu a3, a1
shfth:
LWHI t1, 0(a1) # Limp through, word by word
LWLO t1, 3(a1)
addiu a0, 4
addiu a1, 4
bne a1, a3, shfth
sw t1, -4(a0)
b last8 # Handle anything which may be left
move a2, t0
.set reorder

View file

@ -0,0 +1,239 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* This file was originally part of the Linux/MIPS GNU C Library
* Copyright (C) 1998 by Ralf Baechle
* Adapted for Rockbox by Maurus Cuelenaere, 2009
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "mips.h"
#define FILL256(dst, offset, val) \
sw val, (offset + 0x00)(dst); \
sw val, (offset + 0x04)(dst); \
sw val, (offset + 0x08)(dst); \
sw val, (offset + 0x0c)(dst); \
sw val, (offset + 0x10)(dst); \
sw val, (offset + 0x14)(dst); \
sw val, (offset + 0x18)(dst); \
sw val, (offset + 0x1c)(dst); \
sw val, (offset + 0x20)(dst); \
sw val, (offset + 0x24)(dst); \
sw val, (offset + 0x28)(dst); \
sw val, (offset + 0x2c)(dst); \
sw val, (offset + 0x30)(dst); \
sw val, (offset + 0x34)(dst); \
sw val, (offset + 0x38)(dst); \
sw val, (offset + 0x3c)(dst); \
sw val, (offset + 0x40)(dst); \
sw val, (offset + 0x44)(dst); \
sw val, (offset + 0x48)(dst); \
sw val, (offset + 0x4c)(dst); \
sw val, (offset + 0x50)(dst); \
sw val, (offset + 0x54)(dst); \
sw val, (offset + 0x58)(dst); \
sw val, (offset + 0x5c)(dst); \
sw val, (offset + 0x60)(dst); \
sw val, (offset + 0x64)(dst); \
sw val, (offset + 0x68)(dst); \
sw val, (offset + 0x6c)(dst); \
sw val, (offset + 0x70)(dst); \
sw val, (offset + 0x74)(dst); \
sw val, (offset + 0x78)(dst); \
sw val, (offset + 0x7c)(dst); \
sw val, (offset + 0x80)(dst); \
sw val, (offset + 0x84)(dst); \
sw val, (offset + 0x88)(dst); \
sw val, (offset + 0x8c)(dst); \
sw val, (offset + 0x90)(dst); \
sw val, (offset + 0x94)(dst); \
sw val, (offset + 0x98)(dst); \
sw val, (offset + 0x9c)(dst); \
sw val, (offset + 0xa0)(dst); \
sw val, (offset + 0xa4)(dst); \
sw val, (offset + 0xa8)(dst); \
sw val, (offset + 0xac)(dst); \
sw val, (offset + 0xb0)(dst); \
sw val, (offset + 0xb4)(dst); \
sw val, (offset + 0xb8)(dst); \
sw val, (offset + 0xbc)(dst); \
sw val, (offset + 0xc0)(dst); \
sw val, (offset + 0xc4)(dst); \
sw val, (offset + 0xc8)(dst); \
sw val, (offset + 0xcc)(dst); \
sw val, (offset + 0xd0)(dst); \
sw val, (offset + 0xd4)(dst); \
sw val, (offset + 0xd8)(dst); \
sw val, (offset + 0xdc)(dst); \
sw val, (offset + 0xe0)(dst); \
sw val, (offset + 0xe4)(dst); \
sw val, (offset + 0xe8)(dst); \
sw val, (offset + 0xec)(dst); \
sw val, (offset + 0xf0)(dst); \
sw val, (offset + 0xf4)(dst); \
sw val, (offset + 0xf8)(dst); \
sw val, (offset + 0xfc)(dst);
#define FILL128(dst, offset, val) \
sw val, (offset + 0x00)(dst); \
sw val, (offset + 0x04)(dst); \
sw val, (offset + 0x08)(dst); \
sw val, (offset + 0x0c)(dst); \
sw val, (offset + 0x10)(dst); \
sw val, (offset + 0x14)(dst); \
sw val, (offset + 0x18)(dst); \
sw val, (offset + 0x1c)(dst); \
sw val, (offset + 0x20)(dst); \
sw val, (offset + 0x24)(dst); \
sw val, (offset + 0x28)(dst); \
sw val, (offset + 0x2c)(dst); \
sw val, (offset + 0x30)(dst); \
sw val, (offset + 0x34)(dst); \
sw val, (offset + 0x38)(dst); \
sw val, (offset + 0x3c)(dst); \
sw val, (offset + 0x40)(dst); \
sw val, (offset + 0x44)(dst); \
sw val, (offset + 0x48)(dst); \
sw val, (offset + 0x4c)(dst); \
sw val, (offset + 0x50)(dst); \
sw val, (offset + 0x54)(dst); \
sw val, (offset + 0x58)(dst); \
sw val, (offset + 0x5c)(dst); \
sw val, (offset + 0x60)(dst); \
sw val, (offset + 0x64)(dst); \
sw val, (offset + 0x68)(dst); \
sw val, (offset + 0x6c)(dst); \
sw val, (offset + 0x70)(dst); \
sw val, (offset + 0x74)(dst); \
sw val, (offset + 0x78)(dst); \
sw val, (offset + 0x7c)(dst);
#define FILL64(dst, offset, val) \
sw val, (offset + 0x00)(dst); \
sw val, (offset + 0x04)(dst); \
sw val, (offset + 0x08)(dst); \
sw val, (offset + 0x0c)(dst); \
sw val, (offset + 0x10)(dst); \
sw val, (offset + 0x14)(dst); \
sw val, (offset + 0x18)(dst); \
sw val, (offset + 0x1c)(dst); \
sw val, (offset + 0x20)(dst); \
sw val, (offset + 0x24)(dst); \
sw val, (offset + 0x28)(dst); \
sw val, (offset + 0x2c)(dst); \
sw val, (offset + 0x30)(dst); \
sw val, (offset + 0x34)(dst); \
sw val, (offset + 0x38)(dst); \
sw val, (offset + 0x3c)(dst);
#define FILL32(dst, offset, val) \
sw val, (offset + 0x00)(dst); \
sw val, (offset + 0x04)(dst); \
sw val, (offset + 0x08)(dst); \
sw val, (offset + 0x0c)(dst); \
sw val, (offset + 0x10)(dst); \
sw val, (offset + 0x14)(dst); \
sw val, (offset + 0x18)(dst); \
sw val, (offset + 0x1c)(dst);
#define FILL 64
#define F_FILL FILL64
#ifdef ROCKBOX_BIG_ENDIAN
# define SWHI swl /* high part is left in big-endian */
#else
# define SWHI swr /* high part is right in little-endian */
#endif
/*
* memset(void *s, int c, size_t n)
*
* a0: start of area to clear
* a1: char to fill with
* a2: size of area to clear
*/
.section .icode, "ax", %progbits
.global memset
.type memset, %function
.set noreorder
.align 5
memset:
beqz a1, 1f
move v0, a0 /* result */
andi a1, 0xff /* spread fillword */
sll t1, a1, 8
or a1, t1
sll t1, a1, 16
or a1, t1
1:
sltiu t0, a2, 4 /* very small region? */
bnez t0, small_memset
andi t0, a0, 3 /* aligned? */
beqz t0, 1f
subu t0, 4 /* alignment in bytes */
SWHI a1, (a0) /* make word aligned */
subu a0, t0 /* word align ptr */
addu a2, t0 /* correct size */
1: ori t1, a2, (FILL-1) /* # of full blocks */
xori t1, (FILL-1)
beqz t1, memset_partial /* no block to fill */
andi t0, a2, (FILL-4)
addu t1, a0 /* end address */
.set reorder
1: addiu a0, FILL
F_FILL( a0, -FILL, a1 )
bne t1, a0, 1b
.set noreorder
memset_partial:
la t1, 2f /* where to start */
subu t1, t0
jr t1
addu a0, t0 /* dest ptr */
F_FILL( a0, -FILL, a1 ) /* ... but first do words ... */
2: andi a2, 3 /* 0 <= n <= 3 to go */
beqz a2, 1f
addu a0, a2 /* What's left */
SWHI a1, -1(a0)
1: jr ra
move a2, zero
small_memset:
beqz a2, 2f
addu t1, a0, a2
1: addiu a0, 1 /* fill bytewise */
bne t1, a0, 1b
sb a1, -1(a0)
2: jr ra /* done */
move a2, zero
.set reorder

View file

@ -0,0 +1,14 @@
#
# common
#
CC=mipsel-elf-gcc
LD=mipsel-elf-gcc
AS=mipsel-elf-gcc
OC=mipsel-elf-objcopy
DEFINES=
INCLUDES=-I$(CURDIR)
GCCOPTS=-march=mips32r2 -G0 -msoft-float
BUILD_DIR=$(CURDIR)/build/
ROOT_DIR=$(CURDIR)/..
include ../hwstub.make

View file

@ -0,0 +1,385 @@
#define PMU_BASE 0xB0000000
#define PMU_CTL (*(volatile uint32_t *)(PMU_BASE + 0x00))
#define PMU_CTL_BL_EN (1<<15)
#define PMU_LRADC (*(volatile uint32_t *)(PMU_BASE + 0x04))
#define PMU_CHG (*(volatile uint32_t *)(PMU_BASE + 0x08))
#define PMU_CHG_PBLS (1<<15)
#define PMU_CHG_PBLS_PWM (1<<15)
#define PMU_CHG_PBLS_BL_NDR (0<<15)
#define PMU_CHG_PPHS (1<<14)
#define PMU_CHG_PPHS_HIGH (1<<14)
#define PMU_CHG_PPHS_LOW (0<<14)
#define PMU_CHG_PDUT(x) (((x) & 0x1f) << 8)
#define PMU_CHG_PDOUT_MASK (0x1f << 8)
#define CMU_BASE 0xB0010000
#define CMU_COREPLL (*(volatile uint32_t *)(CMU_BASE + 0x00))
#define CMU_DSPPLL (*(volatile uint32_t *)(CMU_BASE + 0x04))
#define CMU_AUDIOPLL (*(volatile uint32_t *)(CMU_BASE + 0x08))
#define CMU_BUSCLK (*(volatile uint32_t *)(CMU_BASE + 0x0C))
#define CMU_SDRCLK (*(volatile uint32_t *)(CMU_BASE + 0x10))
#define CMU_ATACLK (*(volatile uint32_t *)(CMU_BASE + 0x04))
#define CMU_NANDCLK (*(volatile uint32_t *)(CMU_BASE + 0x18))
#define CMU_SDCLK (*(volatile uint32_t *)(CMU_BASE + 0x1C))
#define CMU_MHACLK (*(volatile uint32_t *)(CMU_BASE + 0x20))
#define CMU_BTCLK (*(volatile uint32_t *)(CMU_BASE + 0x24))
#define CMU_IRCLK (*(volatile uint32_t *)(CMU_BASE + 0x28))
#define CMU_UART2CLK (*(volatile uint32_t *)(CMU_BASE + 0x2C))
#define CMU_DMACLK (*(volatile uint32_t *)(CMU_BASE + 0x30))
#define CMU_FMCLK (*(volatile uint32_t *)(CMU_BASE + 0x34))
#define CMU_FMCLK_BCKE (1<<5)
#define CMI_FMCLK_BCKS (1<<4)
#define CMU_FMCLK_BCKS_32K (0<<4)
#define CMU_FMCLK_BCKS_3M (1<<4)
#define CMU_FMCLK_BCLK_MASK (CMI_FMCLK_BCKS | (3<<2))
#define CMU_FMCLK_BCLK_3M (CMU_FMCLK_BCKS_3M | (0<<2))
#define CMU_FMCLK_BCLK_1_5M (CMU_FMCLK_BCKS_3M | (1<<2))
#define CMU_FMCLK_BCLK_750K (CMU_FMCLK_BCKS_3M | (2<<2))
#define CMU_FMCLK_BCLK_375K (CMU_FMCLK_BCKS_3M | (3<<2))
#define CMU_FMCLK_BCLK_32K (0<<2)
#define CMU_FMCLK_BCLK_16K (1<<2)
#define CMU_FMCLK_BCLK_8K (2<<2)
#define CMU_FMCLK_BCLK_4K (3<<2)
#define CMU_MCACLK (*(volatile uint32_t *)(CMU_BASE + 0x38))
#define CMU_DEVCLKEN (*(volatile uint32_t *)(CMU_BASE + 0x80))
#define CMU_DEVRST (*(volatile uint32_t *)(CMU_BASE + 0x84))
#define RTC_BASE 0xB0018000
#define RTC_CTL (*(volatile uint32_t *)(RTC_BASE + 0x00))
#define RTC_DHMS (*(volatile uint32_t *)(RTC_BASE + 0x04))
#define RTC_YMD (*(volatile uint32_t *)(RTC_BASE + 0x08))
#define RTC_DHMSALM (*(volatile uint32_t *)(RTC_BASE + 0x0C))
#define RTC_YMDALM (*(volatile uint32_t *)(RTC_BASE + 0x10))
#define RTC_WDCTL (*(volatile uint32_t *)(RTC_BASE + 0x14))
#define RTC_WDCTL_CLR (1<<0)
#define RTC_T0CTL (*(volatile uint32_t *)(RTC_BASE + 0x18))
#define RTC_T0 (*(volatile uint32_t *)(RTC_BASE + 0x1C))
#define RTC_T1CTL (*(volatile uint32_t *)(RTC_BASE + 0x20))
#define RTC_T1 (*(volatile uint32_t *)(RTC_BASE + 0x24))
#define INTC_BASE 0xB0020000
#define INTC_PD (*(volatile uint32_t *)(INTC_BASE + 0x00))
#define INTC_MSK (*(volatile uint32_t *)(INTC_BASE + 0x04))
#define INTC_CFG0 (*(volatile uint32_t *)(INTC_BASE + 0x08))
#define INTC_CFG1 (*(volatile uint32_t *)(INTC_BASE + 0x0C))
#define INTC_CFG2 (*(volatile uint32_t *)(INTC_BASE + 0x10))
#define INTC_EXTCTL (*(volatile uint32_t *)(INTC_BASE + 0x14))
#define SRAMOC_BASE 0xB0030000
#define SRAMOC_CTL (*(volatile uint32_t *)(SRAMOC_BASE + 0x00))
#define SRAMOC_STAT (*(volatile uint32_t *)(SRAMOC_BASE + 0x04))
#define BOOT_BASE 0xB00380000
#define BOOT_NORCTL (*(volatile uint32_t *)(BOOT_BASE + 0x00))
#define BOOT_BROMCTL (*(volatile uint32_t *)(BOOT_BASE + 0x04))
#define BOOT_CHIPID (*(volatile uint32_t *)(BOOT_BASE + 0x08))
#define PCNT_BASE 0xB0040000
#define PCNT_CTL (*(volatile uint32_t *)(PCNT_BASE + 0x00))
#define PCNT_PC0 (*(volatile uint32_t *)(PCNT_BASE + 0x04))
#define PCNT_PC1 (*(volatile uint32_t *)(PCNT_BASE + 0x08))
#define DSP_BASE 0xB0050000
#define DSP_HDR0 (*(volatile uint32_t *)(DSP_BASE + 0x00))
#define DSP_HDR1 (*(volatile uint32_t *)(DSP_BASE + 0x04))
#define DSP_HDR2 (*(volatile uint32_t *)(DSP_BASE + 0x08))
#define DSP_HDR3 (*(volatile uint32_t *)(DSP_BASE + 0x0C))
#define DSP_HDR4 (*(volatile uint32_t *)(DSP_BASE + 0x10))
#define DSP_HDR5 (*(volatile uint32_t *)(DSP_BASE + 0x14))
#define DSP_HSR6 (*(volatile uint32_t *)(DSP_BASE + 0x18))
#define DSP_HSR7 (*(volatile uint32_t *)(DSP_BASE + 0x1C))
#define DSP_CTL (*(volatile uint32_t *)(DSP_BASE + 0x20))
#define DMAC_BASE(n) (0xB0060000 + (n<<5))
#define DMAC_CTL (*(volatile uint32_t *)(DMAC_BASE(0) + 0x00))
#define DMAC_IRQEN (*(volatile uint32_t *)(DMAC_BASE(0) + 0x04))
#define DMAC_IRQPD (*(volatile uint32_t *)(DMAC_BASE(0) + 0x08))
/* n in range 0-7 */
#define DMA_MODE(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x100))
#define DMA_SRC(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x104))
#define DMA_DST(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x108))
#define DMA_CNT(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x10C))
#define DMA_REM(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x110))
#define DMA_CMD(n) (*(volatile uint32_t *)(DMAC_BASE(n) + 0x114))
#define SDR_BASE 0xB0070000
#define SDR_CTL (*(volatile uint32_t *)(SDR_BASE + 0x00))
#define SDR_ADDRCFG (*(volatile uint32_t *)(SDR_BASE + 0x04))
#define SDR_EN (*(volatile uint32_t *)(SDR_BASE + 0x08))
#define SDR_CMD (*(volatile uint32_t *)(SDR_BASE + 0x0C))
#define SDR_STAT (*(volatile uint32_t *)(SDR_BASE + 0x10))
#define SDR_RFSH (*(volatile uint32_t *)(SDR_BASE + 0x14))
#define SDR_MODE (*(volatile uint32_t *)(SDR_BASE + 0x18))
#define SDR_MOBILE (*(volatile uint32_t *)(SDR_BASE + 0x1C))
#define MCA_BASE 0xB0080000
#define MCA_CTL (*(volatile uint32_t *)(MCA_BASE + 0x00))
#define ATA_BASE 0xB0090000
#define ATA_CONFIG (*(volatile uint32_t *)(ATA_BASE + 0x00))
#define ATA_UDMACTL (*(volatile uint32_t *)(ATA_BASE + 0x04))
#define ATA_DATA (*(volatile uint32_t *)(ATA_BASE + 0x08))
#define ATA_FEATURE (*(volatile uint32_t *)(ATA_BASE + 0x0C))
#define ATA_SECCNT (*(volatile uint32_t *)(ATA_BASE + 0x10))
#define ATA_SECNUM (*(volatile uint32_t *)(ATA_BASE + 0x14))
#define ATA_CLDLOW (*(volatile uint32_t *)(ATA_BASE + 0x18))
#define ATA_CLDHI (*(volatile uint32_t *)(ATA_BASE + 0x1C))
#define ATA_HEAD (*(volatile uint32_t *)(ATA_BASE + 0x20))
#define ATA_CMD (*(volatile uint32_t *)(ATA_BASE + 0x24))
#define ATA_BYTECNT (*(volatile uint32_t *)(ATA_BASE + 0x28))
#define ATA_FIFOCTL (*(volatile uint32_t *)(ATA_BASE + 0x2C))
#define ATA_FIFOCFG (*(volatile uint32_t *)(ATA_BASE + 0x30))
#define ATA_ADDRDEC (*(volatile uint32_t *)(ATA_BASE + 0x34))
#define ATA_IRQCTL (*(volatile uint32_t *)(ATA_BASE + 0x38))
#define NAND_BASE 0xB00A0000
#define NAND_CTL (*(volatile uint32_t *)(NAND_BASE + 0x00))
#define NAND_STATUS (*(volatile uint32_t *)(NAND_BASE + 0x04))
#define NAND_FIFOTIM (*(volatile uint32_t *)(NAND_BASE + 0x08))
#define NAND_CLKCTL (*(volatile uint32_t *)(NAND_BASE + 0x0C))
#define NAND_BYTECNT (*(volatile uint32_t *)(NAND_BASE + 0x10))
#define NAND_ADDRLO1234 (*(volatile uint32_t *)(NAND_BASE + 0x14))
#define NAND_ADDRLO56 (*(volatile uint32_t *)(NAND_BASE + 0x18))
#define NAND_ADDRHI1234 (*(volatile uint32_t *)(NAND_BASE + 0x1C))
#define NAND_ADDRHI56 (*(volatile uint32_t *)(NAND_BASE + 0x20))
#define NAND_BUF0 (*(volatile uint32_t *)(NAND_BASE + 0x24))
#define NAND_BUF1 (*(volatile uint32_t *)(NAND_BASE + 0x28))
#define NAND_CMD (*(volatile uint32_t *)(NAND_BASE + 0x2C))
#define NAND_ECCCTL (*(volatile uint32_t *)(NAND_BASE + 0x30))
#define NAND_HAMECC0 (*(volatile uint32_t *)(NAND_BASE + 0x34))
#define NAND_HAMECC1 (*(volatile uint32_t *)(NAND_BASE + 0x38))
#define NAND_HAMECC2 (*(volatile uint32_t *)(NAND_BASE + 0x3C))
#define NAND_HAMCEC (*(volatile uint32_t *)(NAND_BASE + 0x40))
#define NAND_RSE0 (*(volatile uint32_t *)(NAND_BASE + 0x44))
#define NAND_RSE1 (*(volatile uint32_t *)(NAND_BASE + 0x48))
#define NAND_RSE2 (*(volatile uint32_t *)(NAND_BASE + 0x4C))
#define NAND_RSE3 (*(volatile uint32_t *)(NAND_BASE + 0x50))
#define NAND_RSPS0 (*(volatile uint32_t *)(NAND_BASE + 0x54))
#define NAND_RSPS1 (*(volatile uint32_t *)(NAND_BASE + 0x58))
#define NAND_RSPS2 (*(volatile uint32_t *)(NAND_BASE + 0x5C))
#define NAND_FIFODATA (*(volatile uint32_t *)(NAND_BASE + 0x60))
#define NAND_DEBUG (*(volatile uint32_t *)(NAND_BASE + 0x70))
#define SD_BASE 0xB00B0000
#define SD_CTL (*(volatile uint32_t *)(SD_BASE + 0x00))
#define SD_CMDRSP (*(volatile uint32_t *)(SD_BASE + 0x04))
#define SD_RW (*(volatile uint32_t *)(SD_BASE + 0x08))
#define SD_FIFOCTL (*(volatile uint32_t *)(SD_BASE + 0x0C))
#define SD_CMD (*(volatile uint32_t *)(SD_BASE + 0x10))
#define SD_ARG (*(volatile uint32_t *)(SD_BASE + 0x14))
#define SD_CRC7 (*(volatile uint32_t *)(SD_BASE + 0x18))
#define SD_RSPBUF0 (*(volatile uint32_t *)(SD_BASE + 0x1C))
#define SD_RSPBUF1 (*(volatile uint32_t *)(SD_BASE + 0x20))
#define SD_RSPBUF2 (*(volatile uint32_t *)(SD_BASE + 0x24))
#define SD_RSPBUF3 (*(volatile uint32_t *)(SD_BASE + 0x28))
#define SD_RSPBUF4 (*(volatile uint32_t *)(SD_BASE + 0x2C))
#define SD_DAT (*(volatile uint32_t *)(SD_BASE + 0x30))
#define SD_CLK (*(volatile uint32_t *)(SD_BASE + 0x34))
#define SD_BYTECNT (*(volatile uint32_t *)(SD_BASE + 0x38))
#define MHA_BASE 0xB00C0000
#define MHA_CTL (*(volatile uint32_t *)(MHA_BASE + 0x00))
#define MHA_CFG (*(volatile uint32_t *)(MHA_BASE + 0x04))
#define MHA_DCSCL01 (*(volatile uint32_t *)(MHA_BASE + 0x10))
#define MHA_DCSCL23 (*(volatile uint32_t *)(MHA_BASE + 0x14))
#define MHA_DCSCL45 (*(volatile uint32_t *)(MHA_BASE + 0x18))
#define MHA_DCSCL67 (*(volatile uint32_t *)(MHA_BASE + 0x1C))
#define MHA_QSCL (*(volatile uint32_t *)(MHA_BASE + 0x20))
#define BT_BASE 0xB00D0000
#define BT_MODESEL (*(volatile uint32_t *)(BT_BASE + 0x00))
#define BT_FIFODAT (*(volatile uint32_t *)(BT_BASE + 0x04))
/* video Encoder */
#define BT_VEICTL (*(volatile uint32_t *)(BT_BASE + 0x08))
#define BT_VEIVSEPOF (*(volatile uint32_t *)(BT_BASE + 0x14))
#define BT_VEIVSEPEF (*(volatile uint32_t *)(BT_BASE + 0x18))
#define BT_VEIFTP (*(volatile uint32_t *)(BT_BASE + 0x24))
#define BT_VEIFIFOCTL (*(volatile uint32_t *)(BT_BASE + 0x30))
/* Video Decoder */
#define BT_VDICTL (*(volatile uint32_t *)(BT_BASE + 0x08))
#define BT_VDIHSPOS (*(volatile uint32_t *)(BT_BASE + 0x0C))
#define BT_VDIHEPOS (*(volatile uint32_t *)(BT_BASE + 0x10))
#define BT_VDIVSEPOF (*(volatile uint32_t *)(BT_BASE + 0x14))
#define BT_VDIVSEPEF (*(volatile uint32_t *)(BT_BASE + 0x18))
#define BT_VDIIRQSTA (*(volatile uint32_t *)(BT_BASE + 0x28))
#define BT_VDIXYDAT (*(volatile uint32_t *)(BT_BASE + 0x2C))
#define BT_VDIFIFOCTL (*(volatile uint32_t *)(BT_BASE + 0x30))
/* CMOS Sensor Interface */
#define BT_CSICTL (*(volatile uint32_t *)(BT_BASE + 0x08))
#define BT_CSIHSPOS (*(volatile uint32_t *)(BT_BASE + 0x0C))
#define BT_CSIHEPOS (*(volatile uint32_t *)(BT_BASE + 0x10))
#define BT_CSIVSPOS (*(volatile uint32_t *)(BT_BASE + 0x1C))
#define BT_CSIVEPOS (*(volatile uint32_t *)(BT_BASE + 0x20))
#define BT_CSIIRQSTA (*(volatile uint32_t *)(BT_BASE + 0x28))
#define BT_CSIXYDAT (*(volatile uint32_t *)(BT_BASE + 0x2C))
#define BT_CSIFIFOCTL (*(volatile uint32_t *)(BT_BASE + 0x30))
/* TS */
#define BT_TSICTL (*(volatile uint32_t *)(BT_BASE + 0x08))
#define BT_TSIFIFOCTL (*(volatile uint32_t *)(BT_BASE + 0x30))
/* Integrated Video Encoder */
#define BT_IVECTL (*(volatile uint32_t *)(BT_BASE + 0x34))
#define BT_IVEOUTCTL (*(volatile uint32_t *)(BT_BASE + 0x38))
#define BT_IVECOTCTL (*(volatile uint32_t *)(BT_BASE + 0x3C))
#define BT_IVEBRGCTL (*(volatile uint32_t *)(BT_BASE + 0x40))
#define BT_IVECSATCTL (*(volatile uint32_t *)(BT_BASE + 0x44))
#define BT_IVECBURCTL (*(volatile uint32_t *)(BT_BASE + 0x48))
#define BT_IVESYNCAMCTL (*(volatile uint32_t *)(BT_BASE + 0x4C))
#define OTG_BASE 0xB00E0000
#define OTG_OUT0BC (*(volatile uint8_t *)(OTG_BASE + 0x00)) // ok (byte count?)
#define OTG_IN0BC (*(volatile uint8_t *)(OTG_BASE + 0x01)) // ok (byte count?)
#define OTG_EP0CS (*(volatile uint8_t *)(OTG_BASE + 0x02)) // ok
#define EP_NAK (1<<1) // from rt source
#define EP0_IN_BUSY (1<<2)
#define EP0_OUT_BUSY (1<<3)
#define OTG_OUT1CON (*(volatile uint8_t *)(OTG_BASE + 0x0A)) // ok
#define OTG_OUT1CS (*(volatile uint8_t *)(OTG_BASE + 0x0B)) // missing in rt
#define OTG_OUT2CON (*(volatile uint8_t *)(OTG_BASE + 0x12)) // missing in sdk
#define OTG_OUT2CS (*(volatile uint8_t *)(OTG_BASE + 0x13)) // deduced
#define OTG_IN2BCL (*(volatile uint8_t *)(OTG_BASE + 0x14)) // missing in rt
#define OTG_IN2BCH (*(volatile uint8_t *)(OTG_BASE + 0x15)) // missing in rt
#define OTG_IN2CON (*(volatile uint8_t *)(OTG_BASE + 0x16)) // ok
#define OTG_IN2CS (*(volatile uint8_t *)(OTG_BASE + 0x17)) //
#define OTG_FIFO1DAT (*(volatile uint32_t *)(OTG_BASE + 0x84)) // missing in rt
#define OTG_FIFO2DAT (*(volatile uint32_t *)(OTG_BASE + 0x88)) // missing in rt
#define OTG_EP0INDAT (*(volatile uint32_t *)(OTG_BASE + 0x100)) // ok
#define OTG_EP0OUTDAT (*(volatile uint32_t *)(OTG_BASE + 0x140)) // ok
#define OTG_SETUPDAT (*(volatile uint32_t *)(OTG_BASE + 0x180)) // ok
#define OTG_IN04IRQ (*(volatile uint8_t *)(OTG_BASE + 0x188))
#define OTG_OUT04IRQ (*(volatile uint8_t *)(OTG_BASE + 0x18a))
#define OTG_USBIRQ (*(volatile uint8_t *)(OTG_BASE + 0x18C)) // ok
#define OTG_IN04IEN (*(volatile uint8_t *)(OTG_BASE + 0x194))
#define OTG_OUT04IEN (*(volatile uint8_t *)(OTG_BASE + 0x196))
#define OTG_USBIEN (*(volatile uint8_t *)(OTG_BASE + 0x198)) // ok
#define OTG_IVECT (*(volatile uint8_t *)(OTG_BASE + 0x1A0)) // missing in rt
#define OTG_ENDPRST (*(volatile uint8_t *)(OTG_BASE + 0x1A2)) // ok
#define OTG_USBCS (*(volatile uint8_t *)(OTG_BASE + 0x1A3)) // ok
#define SOFT_DISCONN (1<<6) // set for soft disconnect
#define OTG_FIFOCTL (*(volatile uint8_t *)(OTG_BASE + 0x1A8)) // ok
#define OTG_OTGIRQ (*(volatile uint8_t *)(OTG_BASE + 0x1BC))
#define OTG_FSMSTAT (*(volatile uint8_t *)(OTG_BASE + 0x1BD))
#define OTG_CTRL (*(volatile uint8_t *)(OTG_BASE + 0x1BE))
#define OTG_STAT (*(volatile uint8_t *)(OTG_BASE + 0x1BF))
#define OTG_OTGIEN (*(volatile uint8_t *)(OTG_BASE + 0x1C0))
#define OTG_TAAIDLBDIS (*(volatile uint8_t *)(OTG_BASE + 0x1C1))
#define OTG_TAWAITBCON (*(volatile uint8_t *)(OTG_BASE + 0x1C2))
#define OTG_TBVBUSPLS (*(volatile uint8_t *)(OTG_BASE + 0x1C3))
#define OTG_TBVBUSDISPLS (*(volatile uint8_t *)(OTG_BASE + 0x1C7))
#define OTG_HCIN1MAXPCKL (*(volatile uint8_t *)(OTG_BASE + 0x1E2))
#define OTG_HCIN1MAXPCKH (*(volatile uint8_t *)(OTG_BASE + 0x1E3))
#define OTG_OUT1STADDR (*(volatile uint8_t *)(OTG_BASE + 0x304))
#define OTG_IN2STADDR (*(volatile uint8_t *)(OTG_BASE + 0x348))
#define OTG_HCOUT2MAXPCKL (*(volatile uint8_t *)(OTG_BASE + 0x3E4))
#define OTG_HCOUT2MAXPCKH (*(volatile uint8_t *)(OTG_BASE + 0x3E5))
#define OTG_USBEIRQ (*(volatile uint8_t *)(OTG_BASE + 0x400))
#define OTG_DMAEPSEL (*(volatile uint8_t *)(OTG_BASE + 0x40C))
#define YUV2RGB_BASE 0xB00F0000
#define YUV2RGB_CTL (*(volatile uint32_t *)(YUV2RGB_BASE + 0x00))
#define YUV2RGB_FIFODATA (*(volatile uint32_t *)(YUV2RGB_BASE + 0x04))
#define YUV2RGB_CLKCTL (*(volatile uint32_t *)(YUV2RGB_BASE + 0x08))
#define YUV2RGB_FRAMECOUNT (*(volatile uint32_t *)(YUV2RGB_BASE + 0x0C))
#define DAC_BASE 0xB0100000
#define DAC_CTL (*(volatile uint32_t *)(DAC_BASE + 0x00))
#define DAC_FIFOCTL (*(volatile uint32_t *)(DAC_BASE + 0x04))
#define DAC_DAT (*(volatile uint32_t *)(DAC_BASE + 0x08))
#define DAC_DEBUG (*(volatile uint32_t *)(DAC_BASE + 0x0C))
#define DAC_ANALOG (*(volatile uint32_t *)(DAC_BASE + 0x10))
#define ADC_BASE 0xB0110000
#define ADC_CTL (*(volatile uint32_t *)(ADC_BASE + 0x00))
#define ADC_FIFOCTL (*(volatile uint32_t *)(ADC_BASE + 0x04))
#define ADC_DAT (*(volatile uint32_t *)(ADC_BASE + 0x08))
#define ADC_DEBUG (*(volatile uint32_t *)(ADC_BASE + 0x0C))
#define ADC_ANALOG (*(volatile uint32_t *)(ADC_BASE + 0x10))
#define TP_BASE 0xB0120000
#define TP_CTL (*(volatile uint32_t *)(TP_BASE + 0x00))
#define TP_DAT (*(volatile uint32_t *)(TP_BASE + 0x04))
#define SPDIF_BASE 0xB0140000
#define SPDIF_CTL (*(volatile uint32_t *)(SPDIF_BASE + 0x00))
#define SPDIF_STAT (*(volatile uint32_t *)(SPDIF_BASE + 0x04))
#define SPDIF_TXDAT (*(volatile uint32_t *)(SPDIF_BASE + 0x08))
#define SPDIF_RXDAT (*(volatile uint32_t *)(SPDIF_BASE + 0x0C))
#define SPDIF_TXCSTAT (*(volatile uint32_t *)(SPDIF_BASE + 0x10))
#define SPDIF_RXCSTAT (*(volatile uint32_t *)(SPDIF_BASE + 0x14))
#define PCM_BASE 0xB0150000
#define PCM_CTL (*(volatile uint32_t *)(PCM_BASE + 0x00))
#define PCM_STAT (*(volatile uint32_t *)(PCM_BASE + 0x04))
#define PCM_RXDAT (*(volatile uint32_t *)(PCM_BASE + 0x08))
#define PCM_TXDAT (*(volatile uint32_t *)(PCM_BASE + 0x0C))
/* n = 0,1 */
#define UART_BASE(n) (0xB0160000 + (n<<5))
#define UART_CTL(n) (*(volatile uint32_t *)(UART_BASE(n) + 0x00))
#define UART_RXDAT(n) (*(volatile uint32_t *)(UART_BASE(n) + 0x04))
#define UART_TXDAT(n) (*(volatile uint32_t *)(UART_BASE(n) + 0x08))
#define UART_STAT(n) (*(volatile uint32_t *)(UART_BASE(n) + 0x0C))
#define IR_PL (*(volatile uint32_t *)(UART_BASE(0) + 0x10))
#define IR_RBC (*(volatile uint32_t *)(UART_BASE(0) + 0x14))
/* n = 0,1 */
#define I2C_BASE(n) (0xB0180000 + (n<<5))
#define I2C_CTL(n) (*(volatile uint32_t *)(I2C_BASE(n) + 0x00))
#define I2C_CLKDIV(n) (*(volatile uint32_t *)(I2C_BASE(n) + 0x04))
#define I2C_STAT(n) (*(volatile uint32_t *)(I2C_BASE(n) + 0x08))
#define I2C_ADDR(n) (*(volatile uint32_t *)(I2C_BASE(n) + 0x0C))
#define I2C_DAT(n) (*(volatile uint32_t *)(I2C_BASE(n) + 0x10))
#define SPI_BASE 0xB0190000
#define SPI_CTL (*(volatile uint32_t *)(SPI_BASE + 0x00))
#define SPI_CLKDIV (*(volatile uint32_t *)(SPI_BASE + 0x04))
#define SPI_STAT (*(volatile uint32_t *)(SPI_BASE + 0x08))
#define SPI_RXDAT (*(volatile uint32_t *)(SPI_BASE + 0x0C))
#define SPI_TXDAT (*(volatile uint32_t *)(SPI_BASE + 0x10))
#define KEY_BASE 0xB01A0000
#define KEY_CTL (*(volatile uint32_t *)(KEY_BASE + 0x00))
#define KEY_DAT0 (*(volatile uint32_t *)(KEY_BASE + 0x04))
#define KEY_DAT1 (*(volatile uint32_t *)(KEY_BASE + 0x08))
#define KEY_DAT2 (*(volatile uint32_t *)(KEY_BASE + 0x0C))
#define KEY_DAT3 (*(volatile uint32_t *)(KEY_BASE + 0x10))
#define GPIO_BASE 0xB01C0000
#define GPIO_AOUTEN (*(volatile uint32_t *)(GPIO_BASE + 0x00))
#define GPIO_AINEN (*(volatile uint32_t *)(GPIO_BASE + 0x04))
#define GPIO_ADAT (*(volatile uint32_t *)(GPIO_BASE + 0x08))
#define GPIO_BOUTEN (*(volatile uint32_t *)(GPIO_BASE + 0x0C))
#define GPIO_BINEN (*(volatile uint32_t *)(GPIO_BASE + 0x10))
#define GPIO_BDAT (*(volatile uint32_t *)(GPIO_BASE + 0x14))
#define GPIO_MFCTL0 (*(volatile uint32_t *)(GPIO_BASE + 0x18))
#define GPIO_MFCTL1 (*(volatile uint32_t *)(GPIO_BASE + 0x1C))

View file

@ -0,0 +1,206 @@
#include "mips.h"
.extern main
.global start
.set mips32r2
.set noreorder
.section .init.text,"ax",%progbits
start:
di # disable interrupts
bltzal zero, load_addr # ra = PC + 8, branch not taken
nop
load_addr:
addiu v0, ra, -12 # calc real load address
# account for branch delay slot
# and very first 'di' instruction
la t0, 0x80000000 # an idx op should use an unmappable address
ori t1, t0, 0x4000 # 16kB cache
mtc0 zero, C0_TAGLO
mtc0 zero, C0_TAGHI
cache_init_loop:
cache ICIndexStTag, 0(t0) # index store icache tag
cache DCIndexStTag, 0(t0) # index store dcache tag
bne t0, t1, cache_init_loop
addiu t0, t0, 0x10
li t0, 3 # enable cache for kseg0 accesses
mtc0 t0, C0_CONFIG
ehb
la t0, relocstart
la t1, relocend
beq t0, v0, entry_point # no relocation needed
nop
reloc_loop:
lw s0, 0(v0) # src
lw s1, 4(v0)
lw s2, 8(v0)
lw s3, 12(v0)
sw s0, 0(t0) # dst
sw s1, 4(t0)
sw s2, 8(t0)
sw s3, 12(t0)
synci 0(t0) # dcache writeback invalidate
# icache invalidate
addiu t0, t0, 16 # inc dst addr
blt t0, t1, reloc_loop
addiu v0, v0, 16 # inc src addr
entry_point_jump:
la t0, entry_point
jr.hb t0
nop
entry_point:
intc_setup:
li t0, 0xb0020000 # INTC base
lw zero, 4(t0) # INTC_MSK mask all interrupt sources
core_irq_setup:
li t0, 0x00404000 # BEV=1 for C0_EBASE setup, IM6=1, IE=0
mtc0 t0, C0_STATUS
la t0, _irqbase # vectors base address must be 4k aligned
mtc0 t0, C0_EBASE
li t0, 0x00004000
mtc0 t0, C0_STATUS # BEV=0, IM6=1, IE=0
li t1, 0x08800000
mtc0 t1, C0_CAUSE # DC=1, IV=1
mtc0 zero,C0_INTCTL # VS = 0
# clear bss
la t0, bssbegin
la t1, bssend
beq t0, t1, stack_setup
nop
clear_bss_loop:
sw zero, 0(t0)
bne t0, t1, clear_bss_loop
addiu t0, 4
stack_setup:
# setup stack
la k0, irqstackend
la sp, stackend
la t0, stackbegin
li t1, 0xdeadbeef
stack_munge_loop:
sw t1, 0(t0)
bne t0, sp, stack_munge_loop
addiu t0, 4
# jump to C code with enabled interrupts
la t0, main
jr.hb t0
ei
.set at
.set reorder
/* s0-s7 not saved as this are callee saved registers
* CO_STATUS is not saved as nested interrupts are not supported
*
* Separate irqstack is used for context save and irq processing
* k0 holds the address of the top of this stack and k1 is used
* to hold original sp value. Since we do not support nesting
* there is nothing to worry about
*/
.extern INT_UDC
.global irq_handler
.set mips32r2
.set noreorder
.set noat
.section .irq_vector,"ax",%progbits
irq_handler:
move k1, sp
move sp, k0
addiu sp, sp, -84
/* context save */
sw AT, 0(sp)
sw v0, 4(sp)
sw v1, 8(sp)
sw a0, 12(sp)
sw a1, 16(sp)
sw a2, 20(sp)
sw a3, 24(sp)
sw t0, 28(sp)
sw t1, 32(sp)
sw t2, 36(sp)
sw t3, 40(sp)
sw t4, 44(sp)
sw t5, 48(sp)
sw t6, 52(sp)
sw t7, 56(sp)
sw t8, 60(sp)
sw t9, 64(sp)
sw fp, 68(sp)
sw ra, 72(sp)
mfhi t0
mflo t1
sw t0, 76(sp)
sw t1, 80(sp)
/* handle interrupt */
lui t0, 0xb002 /* INTC base */
lw a0, 0(t0) /* INTC_PD */
lw a1, 4(t0) /* INTC_MSK */
and a0, a0, a1 /* mask */
andi a0, a0, 0x10 /* UDC flag */
beq a0, zero, restore
nop
/* irq dispatch */
la a0, INT_UDC
jalr a0
nop
restore:
/* context restore */
lw t0, 76(sp)
lw t1, 80(sp)
mthi t0
mtlo t1
lw AT, 0(sp)
lw v0, 4(sp)
lw v1, 8(sp)
lw a0, 12(sp)
lw a1, 16(sp)
lw a2, 20(sp)
lw a3, 24(sp)
lw t0, 28(sp)
lw t1, 32(sp)
lw t2, 36(sp)
lw t3, 40(sp)
lw t4, 44(sp)
lw t5, 48(sp)
lw t6, 52(sp)
lw t7, 56(sp)
lw t8, 60(sp)
lw t9, 64(sp)
lw fp, 68(sp)
lw ra, 72(sp)
addiu sp, sp, 84
move sp, k1
eret
.set reorder
.set at

View file

@ -0,0 +1,70 @@
#include "config.h"
ENTRY(main)
OUTPUT_ARCH(mips)
STARTUP(atj213x/crt0.o)
MEMORY
{
DRAM : ORIGIN = DRAM_ORIG, LENGTH = DRAM_SIZE
IRAM : ORIGIN = IRAM_ORIG, LENGTH = IRAM_SIZE
}
SECTIONS
{
.init.text :
{
_irqbase = .;
relocstart = .;
oc_codestart = .;
*(.init.text*)
} > IRAM
.exception.text (IRAM_ORIG + 0x200) :
{
*(.irq_vector*)
} > IRAM
.text :
{
*(.text*)
*(.icode*)
} > IRAM
.data :
{
*(.rodata*)
*(.data*)
*(.rel.dyn)
relocend = .;
} > IRAM
.stack (NOLOAD) :
{
. = ALIGN(4);
stackbegin = .;
oc_stackstart = .;
. += 0x2000;
stackend = .;
irqstackbegin = .;
. += 0x400;
irqstackend = .;
oc_stackend = .;
} > IRAM
.bss (NOLOAD) :
{
bssbegin = .;
*(.sbss*)
*(.bss*)
*(COMMON)
*(.scommon*)
bssend = .;
oc_codeend = .;
oc_bufferstart = .;
} > IRAM
.end IRAM_ORIG+IRAM_SIZE (NOLOAD) :
{
oc_bufferend = .;
} > IRAM
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,820 @@
/**************************************************************************
* *
* PROJECT : MIPS port for uC/OS-II *
* *
* MODULE : MIPS.h *
* *
* AUTHOR : Michael Anburaj *
* URL : http://geocities.com/michaelanburaj/ *
* EMAIL: michaelanburaj@hotmail.com *
* *
* PROCESSOR : MIPS 4Kc (32 bit RISC) - ATLAS board *
* *
* TOOL-CHAIN : SDE & Cygnus *
* *
* DESCRIPTION : *
* MIPS processor definitions. *
* The basic CPU definitions are found in the file archdefs.h, which *
* is included by mips.h. *
* *
* mips.h implements aliases for some of the definitions in archdefs.h *
* and adds various definitions. *
* *
**************************************************************************/
#ifndef __MIPS_H__
#define __MIPS_H__
#include "mips-archdefs.h"
/* ********************************************************************* */
/* Module configuration */
/* ********************************************************************* */
/* Interface macro & data definition */
#ifndef MSK
#define MSK(n) ((1 << (n)) - 1)
#endif
/* CPU registers */
#define SYS_CPUREG_ZERO 0
#define SYS_CPUREG_AT 1
#define SYS_CPUREG_V0 2
#define SYS_CPUREG_V1 3
#define SYS_CPUREG_A0 4
#define SYS_CPUREG_A1 5
#define SYS_CPUREG_A2 6
#define SYS_CPUREG_A3 7
#define SYS_CPUREG_T0 8
#define SYS_CPUREG_T1 9
#define SYS_CPUREG_T2 10
#define SYS_CPUREG_T3 11
#define SYS_CPUREG_T4 12
#define SYS_CPUREG_T5 13
#define SYS_CPUREG_T6 14
#define SYS_CPUREG_T7 15
#define SYS_CPUREG_S0 16
#define SYS_CPUREG_S1 17
#define SYS_CPUREG_S2 18
#define SYS_CPUREG_S3 19
#define SYS_CPUREG_S4 20
#define SYS_CPUREG_S5 21
#define SYS_CPUREG_S6 22
#define SYS_CPUREG_S7 23
#define SYS_CPUREG_T8 24
#define SYS_CPUREG_T9 25
#define SYS_CPUREG_K0 26
#define SYS_CPUREG_K1 27
#define SYS_CPUREG_GP 28
#define SYS_CPUREG_SP 29
#define SYS_CPUREG_S8 30
#define SYS_CPUREG_FP SYS_CPUREG_S8
#define SYS_CPUREG_RA 31
/* CPU register fp ($30) has an alias s8 */
#define s8 fp
/* Aliases for System Control Coprocessor (CP0) registers */
#define C0_INDEX C0_Index
#define C0_RANDOM C0_Random
#define C0_ENTRYLO0 C0_EntryLo0
#define C0_ENTRYLO1 C0_EntryLo1
#define C0_CONTEXT C0_Context
#define C0_PAGEMASK C0_PageMask
#define C0_WIRED C0_Wired
#define C0_BADVADDR C0_BadVAddr
#define C0_COUNT C0_Count
#define C0_ENTRYHI C0_EntryHi
#define C0_COMPARE C0_Compare
#define C0_STATUS C0_Status
#define C0_CAUSE C0_Cause
#ifdef C0_PRID /* ArchDefs has an obsolete def. of C0_PRID */
#undef C0_PRID
#endif
#define C0_PRID C0_PRId
#define C0_CONFIG C0_Config
#define C0_CONFIG1 C0_Config1
#define C0_LLADDR C0_LLAddr
#define C0_WATCHLO C0_WatchLo
#define C0_WATCHHI C0_WatchHi
#define C0_DEBUG C0_Debug
#define C0_PERFCNT C0_PerfCnt
#define C0_ERRCTL C0_ErrCtl
#define C0_CACHEERR C0_CacheErr
#define C0_TAGLO C0_TagLo
#define C0_DATALO C0_DataLo
#define C0_TAGHI C0_TagHi
#define C0_DATAHI C0_DataHi
#define C0_ERROREPC C0_ErrorEPC
#if 0
#define C0_DESAVE C0_DESAVE
#define C0_EPC C0_EPC
#define C0_DEPC C0_DEPC
#endif
/* System Control Coprocessor (CP0) registers select fields */
#define C0_INDEX_SEL 0 /* TLB Index */
#define C0_RANDOM_SEL 0 /* TLB Random */
#define C0_TLBLO0_SEL 0 /* TLB EntryLo0 */
#define C0_TLBLO1_SEL 0 /* TLB EntryLo1 */
#define C0_CONTEXT_SEL 0 /* Context */
#define C0_PAGEMASK_SEL 0 /* TLB PageMask */
#define C0_WIRED_SEL 0 /* TLB Wired */
#define C0_BADVADDR_SEL 0 /* Bad Virtual Address */
#define C0_COUNT_SEL 0 /* Count */
#define C0_ENTRYHI_SEL 0 /* TLB EntryHi */
#define C0_COMPARE_SEL 0 /* Compare */
#define C0_STATUS_SEL 0 /* Processor Status */
#define C0_CAUSE_SEL 0 /* Exception Cause */
#define C0_EPC_SEL 0 /* Exception PC */
#define C0_PRID_SEL 0 /* Processor Revision Indentifier */
#define C0_CONFIG_SEL 0 /* Config */
#define C0_CONFIG1_SEL 1 /* Config1 */
#define C0_LLADDR_SEL 0 /* LLAddr */
#define C0_WATCHLO_SEL 0 /* WatchpointLo */
#define C0_WATCHHI_SEL 0 /* WatchpointHi */
#define C0_DEBUG_SEL 0 /* EJTAG Debug Register */
#define C0_DEPC_SEL 0 /* Program counter at last EJTAG debug exception */
#define C0_PERFCNT_SEL 0 /* Performance counter interface */
#define C0_ERRCTL_SEL 0 /* ERRCTL */
#define C0_CACHEERR_SEL 0 /* CacheErr */
#define C0_TAGLO_SEL 0 /* TagLo */
#define C0_DATALO_SEL 1 /* DataLo */
#define C0_DTAGLO_SEL 2 /* DTagLo */
#define C0_TAGHI_SEL 0 /* TagHi */
#define C0_DATAHI_SEL 1 /* DataHi */
#define C0_DTAGHI_SEL 2 /* DTagHi */
#define C0_ERROREPC_SEL 0 /* ErrorEPC */
#define C0_DESAVE_SEL 0 /* EJTAG dbg exc. save register */
/* C0_CONFIG register encoding */
#define C0_CONFIG_M_SHF S_ConfigMore
#define C0_CONFIG_M_MSK M_ConfigMore
#define C0_CONFIG_M_BIT C0_CONFIG_M_MSK
#define C0_CONFIG_BE_SHF S_ConfigBE
#define C0_CONFIG_BE_MSK M_ConfigBE
#define C0_CONFIG_BE_BIT C0_CONFIG_BE_MSK
#define C0_CONFIG_AT_SHF S_ConfigAT
#define C0_CONFIG_AT_MSK M_ConfigAT
#define C0_CONFIG_AT_MIPS32 K_ConfigAT_MIPS32
#define C0_CONFIG_AT_MIPS64_32ADDR K_ConfigAT_MIPS64S
#define C0_CONFIG_AT_MIPS64 K_ConfigAT_MIPS64
#define C0_CONFIG_AR_SHF S_ConfigAR
#define C0_CONFIG_AR_MSK M_ConfigAR
#define C0_CONFIG_MT_SHF S_ConfigMT
#define C0_CONFIG_MT_MSK M_ConfigMT
#define C0_CONFIG_MT_NONE K_ConfigMT_NoMMU
#define C0_CONFIG_MT_TLB K_ConfigMT_TLBMMU
#define C0_CONFIG_MT_BAT K_ConfigMT_BATMMU
#define C0_CONFIG_MT_NON_STD K_ConfigMT_FMMMU
#define C0_CONFIG_K0_SHF S_ConfigK0
#define C0_CONFIG_K0_MSK M_ConfigK0
#define C0_CONFIG_K0_WTHRU_NOALLOC K_CacheAttrCWTnWA
#define C0_CONFIG_K0_WTHRU_ALLOC K_CacheAttrCWTWA
#define C0_CONFIG_K0_UNCACHED K_CacheAttrU
#define C0_CONFIG_K0_NONCOHERENT K_CacheAttrCN
#define C0_CONFIG_K0_COHERENTXCL K_CacheAttrCCE
#define C0_CONFIG_K0_COHERENTXCLW K_CacheAttrCCS
#define C0_CONFIG_K0_COHERENTUPD K_CacheAttrCCU
#define C0_CONFIG_K0_UNCACHED_ACCEL K_CacheAttrUA
/* WC field.
*
* This feature is present specifically to support configuration
* testing of the core in a lead vehicle, and is not supported
* in any other environment. Attempting to use this feature
* outside of the scope of a lead vehicle is a violation of the
* MIPS Architecture, and may cause unpredictable operation of
* the processor.
*/
#define C0_CONFIG_WC_SHF 19
#define C0_CONFIG_WC_MSK (MSK(1) << C0_CONFIG_WC_SHF)
#define C0_CONFIG_WC_BIT C0_CONFIG_WC_MSK
/* C0_CONFIG1 register encoding */
#define C0_CONFIG1_MMUSIZE_SHF S_Config1MMUSize
#define C0_CONFIG1_MMUSIZE_MSK M_Config1MMUSize
#define C0_CONFIG1_IS_SHF S_Config1IS
#define C0_CONFIG1_IS_MSK M_Config1IS
#define C0_CONFIG1_IL_SHF S_Config1IL
#define C0_CONFIG1_IL_MSK M_Config1IL
#define C0_CONFIG1_IA_SHF S_Config1IA
#define C0_CONFIG1_IA_MSK M_Config1IA
#define C0_CONFIG1_DS_SHF S_Config1DS
#define C0_CONFIG1_DS_MSK M_Config1DS
#define C0_CONFIG1_DL_SHF S_Config1DL
#define C0_CONFIG1_DL_MSK M_Config1DL
#define C0_CONFIG1_DA_SHF S_Config1DA
#define C0_CONFIG1_DA_MSK M_Config1DA
#define C0_CONFIG1_WR_SHF S_Config1WR
#define C0_CONFIG1_WR_MSK M_Config1WR
#define C0_CONFIG1_WR_BIT C0_CONFIG1_WR_MSK
#define C0_CONFIG1_CA_SHF S_Config1CA
#define C0_CONFIG1_CA_MSK M_Config1CA
#define C0_CONFIG1_CA_BIT C0_CONFIG1_CA_MSK
#define C0_CONFIG1_EP_SHF S_Config1EP
#define C0_CONFIG1_EP_MSK M_Config1EP
#define C0_CONFIG1_EP_BIT C0_CONFIG1_EP_MSK
#define C0_CONFIG1_FP_SHF S_Config1FP
#define C0_CONFIG1_FP_MSK M_Config1FP
#define C0_CONFIG1_FP_BIT C0_CONFIG1_FP_MSK
/* C0_STATUS register encoding */
#define C0_STATUS_CU3_SHF S_StatusCU3
#define C0_STATUS_CU3_MSK M_StatusCU3
#define C0_STATUS_CU3_BIT C0_STATUS_CU3_MSK
#define C0_STATUS_CU2_SHF S_StatusCU2
#define C0_STATUS_CU2_MSK M_StatusCU2
#define C0_STATUS_CU2_BIT C0_STATUS_CU2_MSK
#define C0_STATUS_CU1_SHF S_StatusCU1
#define C0_STATUS_CU1_MSK M_StatusCU1
#define C0_STATUS_CU1_BIT C0_STATUS_CU1_MSK
#define C0_STATUS_CU0_SHF S_StatusCU1
#define C0_STATUS_CU0_MSK M_StatusCU1
#define C0_STATUS_CU0_BIT C0_STATUS_CU0_MSK
#define C0_STATUS_RP_SHF S_StatusRP
#define C0_STATUS_RP_MSK M_StatusRP
#define C0_STATUS_RP_BIT C0_STATUS_RP_MSK
#define C0_STATUS_FR_SHF S_StatusFR
#define C0_STATUS_FR_MSK M_StatusFR
#define C0_STATUS_FR_BIT C0_STATUS_FR_MSK
#define C0_STATUS_RE_SHF S_StatusRE
#define C0_STATUS_RE_MSK M_StatusRE
#define C0_STATUS_RE_BIT C0_STATUS_RE_MSK
#define C0_STATUS_BEV_SHF S_StatusBEV
#define C0_STATUS_BEV_MSK M_StatusBEV
#define C0_STATUS_BEV_BIT C0_STATUS_BEV_MSK
#define C0_STATUS_TS_SHF S_StatusTS
#define C0_STATUS_TS_MSK M_StatusTS
#define C0_STATUS_TS_BIT C0_STATUS_TS_MSK
#define C0_STATUS_SR_SHF S_StatusSR
#define C0_STATUS_SR_MSK M_StatusSR
#define C0_STATUS_SR_BIT C0_STATUS_SR_MSK
#define C0_STATUS_NMI_SHF S_StatusNMI
#define C0_STATUS_NMI_MSK M_StatusNMI
#define C0_STATUS_NMI_BIT C0_STATUS_NMI_MSK
#define C0_STATUS_IM_SHF S_StatusIM
#define C0_STATUS_IM_MSK M_StatusIM
/* Note that the the definitions below indicate the interrupt number
* rather than the mask.
* (0..1 for SW interrupts and 2...7 for HW interrupts)
*/
#define C0_STATUS_IM_SW0 (S_StatusIM0 - S_StatusIM)
#define C0_STATUS_IM_SW1 (S_StatusIM1 - S_StatusIM)
#define C0_STATUS_IM_HW0 (S_StatusIM2 - S_StatusIM)
#define C0_STATUS_IM_HW1 (S_StatusIM3 - S_StatusIM)
#define C0_STATUS_IM_HW2 (S_StatusIM4 - S_StatusIM)
#define C0_STATUS_IM_HW3 (S_StatusIM5 - S_StatusIM)
#define C0_STATUS_IM_HW4 (S_StatusIM6 - S_StatusIM)
#define C0_STATUS_IM_HW5 (S_StatusIM7 - S_StatusIM)
/* Max interrupt code */
#define C0_STATUS_IM_MAX C0_STATUS_IM_HW5
#define C0_STATUS_KSU_SHF S_StatusKSU
#define C0_STATUS_KSU_MSK M_StatusKSU
#define C0_STATUS_UM_SHF S_StatusUM
#define C0_STATUS_UM_MSK M_StatusUM
#define C0_STATUS_UM_BIT C0_STATUS_UM_MSK
#define C0_STATUS_ERL_SHF S_StatusERL
#define C0_STATUS_ERL_MSK M_StatusERL
#define C0_STATUS_ERL_BIT C0_STATUS_ERL_MSK
#define C0_STATUS_EXL_SHF S_StatusEXL
#define C0_STATUS_EXL_MSK M_StatusEXL
#define C0_STATUS_EXL_BIT C0_STATUS_EXL_MSK
#define C0_STATUS_IE_SHF S_StatusIE
#define C0_STATUS_IE_MSK M_StatusIE
#define C0_STATUS_IE_BIT C0_STATUS_IE_MSK
/* C0_PRID register encoding */
#define C0_PRID_OPT_SHF S_PRIdCoOpt
#define C0_PRID_OPT_MSK M_PRIdCoOpt
#define C0_PRID_COMP_SHF S_PRIdCoID
#define C0_PRID_COMP_MSK M_PRIdCoID
#define C0_PRID_COMP_MIPS K_PRIdCoID_MIPS
#define C0_PRID_COMP_NOT_MIPS32_64 0
#define C0_PRID_PRID_SHF S_PRIdImp
#define C0_PRID_PRID_MSK M_PRIdImp
/* Jade */
#define C0_PRID_PRID_4Kc K_PRIdImp_Jade
#define C0_PRID_PRID_4Kmp K_PRIdImp_JadeLite /* 4Km/4Kp */
/* Emerald */
#define C0_PRID_PRID_4KEc K_PRIdImp_4KEc
#define C0_PRID_PRID_4KEmp K_PRIdImp_4KEmp
/* Coral */
#define C0_PRID_PRID_4KSc K_PRIdImp_4KSc
/* Opal */
#define C0_PRID_PRID_5K K_PRIdImp_Opal
/* Ruby */
#define C0_PRID_PRID_20Kc K_PRIdImp_Ruby
/* Other CPUs */
#define C0_PRID_PRID_R4000 K_PRIdImp_R4000
#define C0_PRID_PRID_RM52XX K_PRIdImp_R5200
#define C0_PRID_PRID_RM70XX 0x27
#define C0_PRID_REV_SHF S_PRIdRev
#define C0_PRID_REV_MSK M_PRIdRev
#define MIPS_4Kc ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_4Kc << \
C0_PRID_PRID_SHF) \
)
#define MIPS_4Kmp ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_4Kmp << \
C0_PRID_PRID_SHF) \
)
#define MIPS_4KEc ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_4KEc << \
C0_PRID_PRID_SHF) \
)
#define MIPS_4KEmp ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_4KEmp << \
C0_PRID_PRID_SHF) \
)
#define MIPS_4KSc ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_4KSc << \
C0_PRID_PRID_SHF) \
)
#define MIPS_5K ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_5K << \
C0_PRID_PRID_SHF) \
)
#define MIPS_20Kc ( (C0_PRID_COMP_MIPS << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_20Kc << \
C0_PRID_PRID_SHF) \
)
#define QED_RM52XX ( (C0_PRID_COMP_NOT_MIPS32_64 << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_RM52XX << \
C0_PRID_PRID_SHF) \
)
#define QED_RM70XX ( (C0_PRID_COMP_NOT_MIPS32_64 << \
C0_PRID_COMP_SHF) | \
(C0_PRID_PRID_RM70XX << \
C0_PRID_PRID_SHF) \
)
/* C0_ENTRYHI register encoding */
#define C0_ENTRYHI_VPN2_SHF S_EntryHiVPN2
#define C0_ENTRYHI_VPN2_MSK M_EntryHiVPN2
#define C0_ENTRYHI_ASID_SHF S_EntryHiASID
#define C0_ENTRYHI_ASID_MSK M_EntryHiASID
/* C0_CAUSE register encoding */
#define C0_CAUSE_BD_SHF S_CauseBD
#define C0_CAUSE_BD_MSK M_CauseBD
#define C0_CAUSE_BD_BIT C0_CAUSE_BD_MSK
#define C0_CAUSE_CE_SHF S_CauseCE
#define C0_CAUSE_CE_MSK M_CauseCE
#define C0_CAUSE_IV_SHF S_CauseIV
#define C0_CAUSE_IV_MSK M_CauseIV
#define C0_CAUSE_IV_BIT C0_CAUSE_IV_MSK
#define C0_CAUSE_WP_SHF S_CauseWP
#define C0_CAUSE_WP_MSK M_CauseWP
#define C0_CAUSE_WP_BIT C0_CAUSE_WP_MSK
#define C0_CAUSE_IP_SHF S_CauseIP
#define C0_CAUSE_IP_MSK M_CauseIP
#define C0_CAUSE_CODE_SHF S_CauseExcCode
#define C0_CAUSE_CODE_MSK M_CauseExcCode
#define C0_CAUSE_CODE_INT EX_INT
#define C0_CAUSE_CODE_MOD EX_MOD
#define C0_CAUSE_CODE_TLBL EX_TLBL
#define C0_CAUSE_CODE_TLBS EX_TLBS
#define C0_CAUSE_CODE_ADEL EX_ADEL
#define C0_CAUSE_CODE_ADES EX_ADES
#define C0_CAUSE_CODE_IBE EX_IBE
#define C0_CAUSE_CODE_DBE EX_DBE
#define C0_CAUSE_CODE_SYS EX_SYS
#define C0_CAUSE_CODE_BP EX_BP
#define C0_CAUSE_CODE_RI EX_RI
#define C0_CAUSE_CODE_CPU EX_CPU
#define C0_CAUSE_CODE_OV EX_OV
#define C0_CAUSE_CODE_TR EV_TR
#define C0_CAUSE_CODE_FPE EX_FPE
#define C0_CAUSE_CODE_WATCH EX_WATCH
#define C0_CAUSE_CODE_MCHECK EX_MCHECK
/* Max cause code */
#define C0_CAUSE_CODE_MAX EX_MCHECK
/* C0_PAGEMASK register encoding */
#define C0_PAGEMASK_MASK_SHF S_PageMaskMask
#define C0_PAGEMASK_MASK_MSK M_PageMaskMask
#define C0_PAGEMASK_MASK_4K K_PageMask4K
#define C0_PAGEMASK_MASK_16K K_PageMask16K
#define C0_PAGEMASK_MASK_64K K_PageMask64K
#define C0_PAGEMASK_MASK_256K K_PageMask256K
#define C0_PAGEMASK_MASK_1M K_PageMask1M
#define C0_PAGEMASK_MASK_4M K_PageMask4M
#define C0_PAGEMASK_MASK_16M K_PageMask16M
/* C0_ENTRYLO0 register encoding (equiv. to C0_ENTRYLO1) */
#define C0_ENTRYLO0_PFN_SHF S_EntryLoPFN
#define C0_ENTRYLO0_PFN_MSK M_EntryLoPFN
#define C0_ENTRYLO0_C_SHF S_EntryLoC
#define C0_ENTRYLO0_C_MSK M_EntryLoC
#define C0_ENTRYLO0_D_SHF S_EntryLoD
#define C0_ENTRYLO0_D_MSK M_EntryLoD
#define C0_ENTRYLO0_V_SHF S_EntryLoV
#define C0_ENTRYLO0_V_MSK M_EntryLoV
#define C0_ENTRYLO0_G_SHF S_EntryLoG
#define C0_ENTRYLO0_G_MSK M_EntryLoG
/* FPU (CP1) FIR register encoding */
#define C1_FIR_3D_SHF S_FIRConfig3D
#define C1_FIR_3D_MSK M_FIRConfig3D
#define C1_FIR_PS_SHF S_FIRConfigPS
#define C1_FIR_PS_MSK M_FIRConfigPS
#define C1_FIR_D_SHF S_FIRConfigD
#define C1_FIR_D_MSK M_FIRConfigD
#define C1_FIR_S_SHF S_FIRConfigS
#define C1_FIR_S_MSK M_FIRConfigS
#define C1_FIR_PRID_SHF S_FIRImp
#define C1_FIR_PRID_MSK M_FIRImp
#define C1_FIR_REV_SHF S_FIRRev
#define C1_FIR_REV_MSK M_FIRRev
/* FPU (CP1) FCSR control/status register */
#define C1_FCSR_FCC_SHF S_FCSRFCC7_1
#define C1_FCSR_FCC_MSK M_FCSRFCC7_1
#define C1_FCSR_FS_SHF S_FCSRFS
#define C1_FCSR_FS_MSK M_FCSRFS
#define C1_FCSR_FS_BIT C1_FCSR_FS_MSK
#define C1_FCSR_CC_SHF S_FCSRCC
#define C1_FCSR_CC_MSK M_FCSRCC
#define C1_FCSR_IMPL_SHF S_FCSRImpl
#define C1_FCSR_IMPL_MSK M_FCSRImpl
#define C1_FCSR_EXC_SHF S_FCSRExc
#define C1_FCSR_EXC_MSK M_FCSRExc
#define C1_FCSR_ENA_SHF S_FCSREna
#define C1_FCSR_ENA_MSK M_FCSREna
#define C1_FCSR_FLG_SHF S_FCSRFlg
#define C1_FCSR_FLG_MSK M_FCSRFlg
#define C1_FCSR_RM_SHF S_FCSRRM
#define C1_FCSR_RM_MSK M_FCSRRM
#define C1_FCSR_RM_RN K_FCSRRM_RN
#define C1_FCSR_RM_RZ K_FCSRRM_RZ
#define C1_FCSR_RM_RP K_FCSRRM_RP
#define C1_FCSR_RM_RM K_FCSRRM_RM
/* cache operations */
#define CACHE_OP( code, type ) ( ((code) << 2) | (type) )
#define ICACHE_INDEX_INVALIDATE CACHE_OP(0x0, 0)
#define ICACHE_INDEX_LOAD_TAG CACHE_OP(0x1, 0)
#define ICACHE_INDEX_STORE_TAG CACHE_OP(0x2, 0)
#define DCACHE_INDEX_WRITEBACK_INVALIDATE CACHE_OP(0x0, 1)
#define DCACHE_INDEX_LOAD_TAG CACHE_OP(0x1, 1)
#define DCACHE_INDEX_STORE_TAG CACHE_OP(0x2, 1)
#define SCACHE_INDEX_STORE_TAG CACHE_OP(0x2, 3)
#define ICACHE_ADDR_HIT_INVALIDATE CACHE_OP(0x4, 0)
#define ICACHE_ADDR_FILL CACHE_OP(0x5, 0)
#define ICACHE_ADDR_FETCH_LOCK CACHE_OP(0x7, 0)
#define DCACHE_ADDR_HIT_INVALIDATE CACHE_OP(0x4, 1)
#define DCACHE_ADDR_HIT_WRITEBACK_INVALIDATE CACHE_OP(0x5, 1)
#define DCACHE_ADDR_HIT_WRITEBACK CACHE_OP(0x6, 1)
#define DCACHE_ADDR_FETCH_LOCK CACHE_OP(0x7, 1)
#define SCACHE_ADDR_HIT_WRITEBACK_INVALIDATE CACHE_OP(0x5, 3)
/* Workaround for bug in early revisions of MIPS 4K family of
* processors. Only relevant in early engineering samples of test
* chips (RTL revision <= 3.0).
*
* The bug is described in :
*
* MIPS32 4K(tm) Processor Core Family RTL Errata Sheet
* MIPS Document No: MD00003
*
* The bug is identified as : C16
*/
#ifndef SET_MIPS0
#define SET_MIPS0()
#define SET_PUSH()
#define SET_POP()
#endif
#define ICACHE_INVALIDATE_WORKAROUND(reg) \
SET_PUSH(); \
SET_MIPS0(); \
la reg, 999f; \
SET_POP(); \
cache ICACHE_ADDR_FILL, 0(reg); \
sync; \
nop; nop; nop; nop; \
999:
/* EMPTY_PIPELINE is used for the below cache invalidation operations.
* When $I is invalidated, there will still be operations in the
* pipeline. We make sure these are 'nop' operations.
*/
#define EMPTY_PIPELINE nop; nop; nop; nop
#define ICACHE_INDEX_INVALIDATE_OP(index,scratch) \
ICACHE_INVALIDATE_WORKAROUND(scratch); \
cache ICACHE_INDEX_INVALIDATE, 0(index); \
EMPTY_PIPELINE
#define ICACHE_ADDR_INVALIDATE_OP(addr,scratch) \
ICACHE_INVALIDATE_WORKAROUND(scratch); \
cache ICACHE_ADDR_HIT_INVALIDATE, 0(addr); \
EMPTY_PIPELINE
/* The sync used in the below macro is there in case we are installing
* a new instruction (flush $D, sync, invalidate $I sequence).
*/
#define SCACHE_ADDR_HIT_WB_INVALIDATE_OP(reg) \
cache SCACHE_ADDR_HIT_WRITEBACK_INVALIDATE, 0(reg); \
sync; \
EMPTY_PIPELINE
/* Config1 cache field decoding */
#define CACHE_CALC_SPW(s) ( 64 << (s) )
#define CACHE_CALC_LS(l) ( (l) ? 2 << (l) : 0 )
#define CACHE_CALC_BPW(l,s) ( CACHE_CALC_LS(l) * CACHE_CALC_SPW(s) )
#define CACHE_CALC_ASSOC(a) ( (a) + 1 )
/**** Move from/to Coprocessor operations ****/
/* We use ssnop instead of nop operations in order to handle
* superscalar CPUs.
* The "sll zero,zero,1" notation is compiler backwards compatible.
*/
#define SSNOP sll zero,zero,1
#define NOPS SSNOP; SSNOP; SSNOP; SSNOP
#define MFLO(dst) \
mflo dst;\
NOPS
/* Workaround for bug in early revisions of MIPS 4K family of
* processors.
*
* This concerns the nop instruction before mtc0 in the
* MTC0 macro below.
*
* The bug is described in :
*
* MIPS32 4K(tm) Processor Core Family RTL Errata Sheet
* MIPS Document No: MD00003
*
* The bug is identified as : C27
*/
#define MTC0(src, dst) \
nop; \
mtc0 src,dst;\
NOPS
#define DMTC0(src, dst) \
nop; \
dmtc0 src,dst;\
NOPS
#define MFC0(dst, src) \
mfc0 dst,src;\
NOPS
#define DMFC0(dst, src) \
dmfc0 dst,src;\
NOPS
#define MFC0_SEL_OPCODE(dst, src, sel)\
.##word (0x40000000 | ((dst)<<16) | ((src)<<11) | (sel));\
NOPS
#define MTC0_SEL_OPCODE(dst, src, sel)\
.##word (0x40800000 | ((dst)<<16) | ((src)<<11) | (sel));\
NOPS
#define LDC1(dst, src, offs)\
.##word (0xd4000000 | ((src)<<21) | ((dst)<<16) | (offs))
#define SDC1(src, dst, offs)\
.##word (0xf4000000 | ((dst)<<21) | ((src)<<16) | (offs))
/* Instruction opcode fields */
#define OPC_SPECIAL 0x0
#define OPC_REGIM 0x1
#define OPC_J 0x2
#define OPC_JAL 0x3
#define OPC_BEQ 0x4
#define OPC_BNE 0x5
#define OPC_BLEZ 0x6
#define OPC_BGTZ 0x7
#define OPC_COP1 0x11
#define OPC_JALX 0x1D
#define OPC_BEQL 0x14
#define OPC_BNEL 0x15
#define OPC_BLEZL 0x16
#define OPC_BGTZL 0x17
/* Instruction function fields */
#define FUNC_JR 0x8
#define FUNC_JALR 0x9
/* Instruction rt fields */
#define RT_BLTZ 0x0
#define RT_BGEZ 0x1
#define RT_BLTZL 0x2
#define RT_BGEZL 0x3
#define RT_BLTZAL 0x10
#define RT_BGEZAL 0x11
#define RT_BLTZALL 0x12
#define RT_BGEZALL 0x13
/* Instruction rs fields */
#define RS_BC1 0x08
/* Access macros for instruction fields */
#define MIPS_OPCODE( instr) ((instr) >> 26)
#define MIPS_FUNCTION(instr) ((instr) & MSK(6))
#define MIPS_RT(instr) (((instr) >> 16) & MSK(5))
#define MIPS_RS(instr) (((instr) >> 21) & MSK(5))
#define MIPS_OFFSET(instr) ((instr) & 0xFFFF)
#define MIPS_TARGET(instr) ((instr) & MSK(26))
/* Instructions */
#define OPCODE_DERET 0x4200001f
#define OPCODE_BREAK 0x0005000d
#define OPCODE_NOP 0
#define OPCODE_JUMP(addr) ( (OPC_J << 26) | (((addr) >> 2) & 0x3FFFFFF) )
#define DERET .##word OPCODE_DERET
/* MIPS16e opcodes and instruction field access macros */
#define MIPS16E_OPCODE(inst) (((inst) >> 11) & 0x1f)
#define MIPS16E_I8_FUNCTION(inst) (((inst) >> 8) & 0x7)
#define MIPS16E_X(inst) (((inst) >> 26) & 0x1)
#define MIPS16E_RR_FUNCTION(inst) (((inst) >> 0) & 0x1f)
#define MIPS16E_RY(inst) (((inst) >> 5) & 0x3)
#define MIPS16E_OPC_EXTEND 0x1e
#define MIPS16E_OPC_JAL_X 0x03
#define MIPS16E_OPC_B 0x02
#define MIPS16E_OPC_BEQZ 0x04
#define MIPS16E_OPC_BNEZ 0x05
#define MIPS16E_OPC_I8 0x0c
#define MIPS16E_I8_FUNC_BTEQZ 0x00
#define MIPS16E_I8_FUNC_BTNEZ 0x01
#define MIPS16E_X_JALX 0x01
#define MIPS16E_OPC_RR 0x1d
#define MIPS16E_RR_FUNC_JALRC 0x00
#define MIPS16E_RR_RY_JRRX 0x00
#define MIPS16E_RR_RY_JRRA 0x01
#define MIPS16E_RR_RY_JALR 0x02
#define MIPS16E_RR_RY_JRCRX 0x04
#define MIPS16E_RR_RY_JRCRA 0x05
#define MIPS16E_RR_RY_JALRC 0x06
#define MIPS16E_OPCODE_BREAK 0xE805
#define MIPS16E_OPCODE_NOP 0x6500
/* MIPS reset vector */
#define MIPS_RESET_VECTOR 0x1fc00000
/* Clock periods per count register increment */
#define MIPS4K_COUNT_CLK_PER_CYCLE 2
#define MIPS5K_COUNT_CLK_PER_CYCLE 2
#define MIPS20Kc_COUNT_CLK_PER_CYCLE 1
/**** MIPS 4K/5K families specific fields of CONFIG register ****/
#define C0_CONFIG_MIPS4K5K_K23_SHF S_ConfigK23
#define C0_CONFIG_MIPS4K5K_K23_MSK (MSK(3) << C0_CONFIG_MIPS4K5K_K23_SHF)
#define C0_CONFIG_MIPS4K5K_KU_SHF S_ConfigKU
#define C0_CONFIG_MIPS4K5K_KU_MSK (MSK(3) << C0_CONFIG_MIPS4K5K_KU_SHF)
/**** MIPS 20Kc specific fields of CONFIG register ****/
#define C0_CONFIG_MIPS20KC_EC_SHF 28
#define C0_CONFIG_MIPS20KC_EC_MSK (MSK(3) << C0_CONFIG_MIPS20KC_EC_SHF)
#define C0_CONFIG_MIPS20KC_DD_SHF 27
#define C0_CONFIG_MIPS20KC_DD_MSK (MSK(1) << C0_CONFIG_MIPS20KC_DD_SHF)
#define C0_CONFIG_MIPS20KC_DD_BIT C0_CONFIG_MIPS20KC_DD_MSK
#define C0_CONFIG_MIPS20KC_LP_SHF 26
#define C0_CONFIG_MIPS20KC_LP_MSK (MSK(1) << C0_CONFIG_MIPS20KC_LP_SHF)
#define C0_CONFIG_MIPS20KC_LP_BIT C0_CONFIG_MIPS20KC_LP_MSK
#define C0_CONFIG_MIPS20KC_SP_SHF 25
#define C0_CONFIG_MIPS20KC_SP_MSK (MSK(1) << C0_CONFIG_MIPS20KC_SP_SHF)
#define C0_CONFIG_MIPS20KC_SP_BIT C0_CONFIG_MIPS20KC_SP_MSK
#define C0_CONFIG_MIPS20KC_TI_SHF 24
#define C0_CONFIG_MIPS20KC_TI_MSK (MSK(1) << C0_CONFIG_MIPS20KC_TI_SHF)
#define C0_CONFIG_MIPS20KC_TI_BIT C0_CONFIG_MIPS20KC_TI_MSK
/* ********************************************************************* */
/* Interface function definition */
/* ********************************************************************* */
#endif /* #ifndef __MIPS_H__ */

View file

@ -0,0 +1,12 @@
#define CONFIG_ATJ213X
#define IRAM_ORIG 0x94040000 /* KSEG1 cached unmapped */
#define IRAM_SIZE 0x18000
#define DRAM_ORIG 0x80000000 /* KSEG1 cached unmapped */
#define DRAM_SIZE 0x800000
#define CPU_MIPS
/* something provides define
* #define mips 1
* which breaks paths badly
*/
#undef mips

View file

@ -0,0 +1,113 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Marcin Bukat
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "stddef.h"
#include "target.h"
#include "system.h"
#include "logf.h"
#include "atj213x.h"
#define CORE_FREQ 7500000
#define HZ 1000000
static void backlight_init(void)
{
/* backlight clock enable, select backlight clock as 32kHz */
CMU_FMCLK = (CMU_FMCLK & ~(CMU_FMCLK_BCLK_MASK)) | CMU_FMCLK_BCKE | CMU_FMCLK_BCLK_32K;
/* baclight enable */
PMU_CTL |= PMU_CTL_BL_EN;
/* pwm output, phase high, some initial duty cycle set as 24/32 */
PMU_CHG = ((PMU_CHG & ~PMU_CHG_PDOUT_MASK)| PMU_CHG_PBLS_PWM | PMU_CHG_PPHS_HIGH | PMU_CHG_PDUT(24));
}
void backlight_set(int level)
{
/* set duty cycle in 1/32 units */
PMU_CHG = ((PMU_CHG & ~PMU_CHG_PDOUT_MASK) | PMU_CHG_PDUT(level));
}
void target_udelay(int us)
{
unsigned int i = us * (CORE_FREQ / 2000000);
asm volatile (
".set noreorder \n"
"1: \n"
"bnez %0, 1b \n"
"addiu %0, %0, -1 \n"
".set reorder \n"
: "=r" (i)
: "0" (i)
);
}
void target_mdelay(int ms)
{
return target_udelay(ms * 1000);
}
void blink(int cnt)
{
int i;
for (i=0; i<cnt; i++)
{
backlight_set(0);
target_mdelay(300);
backlight_set(24);
target_mdelay(300);
}
}
void target_init(void)
{
RTC_WDCTL = (RTC_WDCTL & ~(1<<4))|(1<<6)|1; /* disable WDT */
/* Configure USB interrupt as IP6. IP6 is unmasked in crt0.S */
INTC_CFG0 = 0;
INTC_CFG1 = 0;
INTC_CFG2 = (1<<4);
/* mask all interrupts to avoid pending irq servicing */
INTC_MSK = 0;
backlight_init();
}
struct hwstub_target_desc_t __attribute__((aligned(2))) target_descriptor =
{
sizeof(struct hwstub_target_desc_t),
HWSTUB_DT_TARGET,
HWSTUB_TARGET_ATJ,
"ATJ213X"
};
void target_get_desc(int desc, void **buffer)
{
(void) desc;
*buffer = NULL;
}
void target_get_config_desc(void *buffer, int *size)
{
(void) buffer;
(void) size;
}

View file

@ -0,0 +1,267 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2014 by Marcin Bukat
Amaury Pouly
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "usb_drv.h"
#include "config.h"
#include "memory.h"
#include "target.h"
#include "atj213x.h"
#define USB_FULL_SPEED 0
#define USB_HIGH_SPEED 1
volatile bool setup_data_valid = false;
volatile int udc_speed = USB_FULL_SPEED;
static void usb_copy_from(void *ptr, volatile void *reg, size_t sz)
{
uint32_t *p = ptr;
volatile uint32_t *rp = reg;
/* do not overflow the destination buffer ! */
while(sz >= 4)
{
*p++ = *rp++;
sz -= 4;
}
if(sz == 0)
return;
/* reminder */
uint32_t cache = *rp;
uint8_t *p8 = (void *)p;
while(sz-- > 0)
{
*p8++ = cache;
cache >>= 8;
}
}
static void usb_copy_to(volatile void *reg, void *ptr, size_t sz)
{
uint32_t *p = ptr;
volatile uint32_t *rp = reg;
sz = (sz + 3) / 4;
/* read may overflow the source buffer but
* it will not overwrite anything
*/
while(sz-- > 0)
*rp++ = *p++;
}
void INT_UDC(void)
{
/* get possible sources */
unsigned int usbirq = OTG_USBIRQ;
unsigned int otgirq = OTG_OTGIRQ;
#if 0
unsigned int usbeirq = OTG_USBEIRQ;
unsigned int epinirq = OTG_IN04IRQ;
unsigned int epoutirq = OTG_OUT04IRQ;
#endif
/* HS, Reset, Setup */
if (usbirq)
{
if (usbirq & (1<<5))
{
/* HS irq */
udc_speed = USB_HIGH_SPEED;
}
else if (usbirq & (1<<4))
{
/* Reset */
udc_speed = USB_FULL_SPEED;
/* clear all pending irqs */
OTG_OUT04IRQ = 0xff;
OTG_IN04IRQ = 0xff;
}
else if (usbirq & (1<<0))
{
/* Setup data valid */
setup_data_valid = true;
}
/* clear irq flags */
OTG_USBIRQ = usbirq;
}
#if 0
if (epoutirq)
{
OTG_OUT04IRQ = epoutirq;
}
if (epinirq)
{
OTG_IN04IRQ = epinirq;
}
#endif
if (otgirq)
{
OTG_OTGIRQ = otgirq;
}
OTG_USBEIRQ = 0x50;
}
void usb_drv_init(void)
{
OTG_USBCS |= 0x40; /* soft disconnect */
OTG_ENDPRST = 0x10; /* reset all ep fifos */
OTG_ENDPRST = 0x70;
OTG_ENDPRST = 0x00;
OTG_ENDPRST = 0x60;
OTG_USBIRQ = 0xff; /* clear all pending interrupts */
OTG_OTGIRQ = 0xff;
OTG_IN04IRQ = 0xff;
OTG_OUT04IRQ = 0xff;
OTG_USBEIRQ = 0x50; /* UDC ? with 0x40 there is irq storm */
OTG_USBIEN = (1<<5) | (1<<4) | (1<<0); /* HS, Reset, Setup_data */
OTG_OTGIEN = 0;
/* disable interrupts from ep0 */
OTG_IN04IEN = 0;
OTG_OUT04IEN = 0;
/* unmask UDC interrupt in interrupt controller */
INTC_MSK = (1<<4);
target_mdelay(100);
OTG_USBCS &= ~0x40; /* soft connect */
}
int usb_drv_recv_setup(struct usb_ctrlrequest *req)
{
while (!setup_data_valid)
;
usb_copy_from(req, &OTG_SETUPDAT, sizeof(struct usb_ctrlrequest));
setup_data_valid = false;
return 0;
}
int usb_drv_port_speed(void)
{
return (int)udc_speed;
}
/* Set the address (usually it's in a register).
* There is a problem here: some controller want the address to be set between
* control out and ack and some want to wait for the end of the transaction.
* In the first case, you need to write some code special code when getting
* setup packets and ignore this function (have a look at other drives)
*/
void usb_drv_set_address(int address)
{
(void)address;
/* UDC sets this automaticaly */
}
/* TODO: Maybe adapt to irq scheme */
int usb_drv_send(int endpoint, void *ptr, int length)
{
(void)endpoint;
int xfer_size, cnt = length;
while (cnt)
{
xfer_size = MIN(cnt, 64);
/* copy data to ep0in buffer */
usb_copy_to(&OTG_EP0INDAT, ptr, xfer_size);
/* this marks data as ready to send */
OTG_IN0BC = xfer_size;
/* wait for the transfer end */
while(OTG_EP0CS & 0x04)
;
cnt -= xfer_size;
ptr += xfer_size;
}
/* ZLP stage */
if((length % 64) == 0)
OTG_EP0CS = 2;
return 0;
}
/* TODO: Maybe adapt to irq scheme */
int usb_drv_recv(int endpoint, void* ptr, int length)
{
(void)endpoint;
int xfer_size, cnt = 0;
while (cnt < length)
{
/* Arm receiving buffer by writing
* any value to OUT0BC. This sets
* OUT_BUSY bit in EP0CS until the data
* are correctly received and ACK'd
*/
OTG_OUT0BC = 0;
while (OTG_EP0CS & 0x08)
;
xfer_size = OTG_OUT0BC;
usb_copy_from(ptr, &OTG_EP0OUTDAT, xfer_size);
cnt += xfer_size;
ptr += xfer_size;
if (xfer_size < 64)
break;
}
/* ZLP stage */
if (length == 0)
OTG_EP0CS = 2;
return cnt;
}
void usb_drv_stall(int endpoint, bool stall, bool in)
{
(void)endpoint;
(void)in;
/* only EP0 in hwstub */
if (stall)
OTG_EP0CS |= 1;
else
OTG_EP0CS &= ~1;
}
void usb_drv_exit(void)
{
}

View file

@ -178,17 +178,17 @@ static void handle_std_dev_desc(struct usb_ctrlrequest *req)
case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_OTHER_SPEED_CONFIG:
case USB_DT_CONFIG: case USB_DT_CONFIG:
{ {
int max_packet_size; /* int max_packet_size; */
/* config desc */ /* config desc */
if((req->wValue >> 8) ==USB_DT_CONFIG) if((req->wValue >> 8) == USB_DT_CONFIG)
{ {
max_packet_size = (usb_drv_port_speed() ? 512 : 64); /* max_packet_size = (usb_drv_port_speed() ? 512 : 64); */
config_descriptor.bDescriptorType = USB_DT_CONFIG; config_descriptor.bDescriptorType = USB_DT_CONFIG;
} }
else else
{ {
max_packet_size = (usb_drv_port_speed() ? 64 : 512); /* max_packet_size = (usb_drv_port_speed() ? 64 : 512); */
config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG; config_descriptor.bDescriptorType = USB_DT_OTHER_SPEED_CONFIG;
} }
size = sizeof(struct usb_config_descriptor); size = sizeof(struct usb_config_descriptor);
@ -411,10 +411,13 @@ static void handle_exec(struct usb_ctrlrequest *req)
if(exec->bmFlags & HWSTUB_EXEC_CALL) if(exec->bmFlags & HWSTUB_EXEC_CALL)
{ {
#ifdef CPU_ARM #if defined(CPU_ARM)
/* in case of call, respond after return */ /* in case of call, respond after return */
asm volatile("blx %0\n" : : "r"(addr) : "memory"); asm volatile("blx %0\n" : : "r"(addr) : "memory");
usb_drv_send(EP_CONTROL, NULL, 0); usb_drv_send(EP_CONTROL, NULL, 0);
#elif defined(CPU_MIPS)
asm volatile("jalr %0\nnop\n" : : "r"(addr) : "memory");
usb_drv_send(EP_CONTROL, NULL, 0);
#else #else
#warning call is unsupported on this platform #warning call is unsupported on this platform
usb_drv_stall(EP_CONTROL, true, true); usb_drv_stall(EP_CONTROL, true, true);
@ -425,9 +428,11 @@ static void handle_exec(struct usb_ctrlrequest *req)
/* in case of jump, respond immediately and disconnect usb */ /* in case of jump, respond immediately and disconnect usb */
usb_drv_send(EP_CONTROL, NULL, 0); usb_drv_send(EP_CONTROL, NULL, 0);
usb_drv_exit(); usb_drv_exit();
#ifdef CPU_ARM #if defined(CPU_ARM)
asm volatile("bx %0\n" : : "r" (addr) : "memory"); asm volatile("bx %0\n" : : "r" (addr) : "memory");
#else #elif defined(CPU_MIPS)
asm volatile("jr %0\nnop\n" : : "r" (addr) : "memory");
#else
#warning jump is unsupported on this platform #warning jump is unsupported on this platform
usb_drv_stall(EP_CONTROL, true, true); usb_drv_stall(EP_CONTROL, true, true);
#endif #endif