Ka-Ro Electronics GmbH
===========================================================
+ v1.5.3 (2012-02-15)
+ Changes:
+ all modules:
+ - fixed the trampoline code in redboot_linux_exec.c
+ TX53:
+ - fixed phys <-> virt address calculations
+ - added support for 2 memory banks (1GiB)
+ - fixed ATAG_MEM construction for banked memory
+ - fixed MMU mappings
+
v1.5.2 (2011-12-23)
Changes:
TX51:
__xtramp_end__ - __xtramp_start__);
asm volatile (
- CYGARC_HAL_MMU_OFF_X(%5)
"__xtramp_start__:\n"
+ "add pc, %5, #4\n" /* jump to copied trampoline code */
+ CYGARC_HAL_MMU_OFF_X(%5)
" cmp %1,%4;\n" // Default kernel load address. Relocate
" beq 2f;\n" // kernel image there if necessary, and
" cmp %2,#0;\n" // if size is non-zero
__tramp_end__ - __tramp_start__);
asm volatile (
- CYGARC_HAL_MMU_OFF(%5)
"__tramp_start__:\n"
+ "add pc, %5, #4\n" /* jump to copied trampoline code */
+ CYGARC_HAL_MMU_OFF(%5)
" cmp %1,%4;\n" // Default kernel load address. Relocate
" beq 2f;\n" // kernel image there if necessary, and
" cmp %2,#0;\n" // if size is non-zero
// Memory mapping details
#ifndef CYGARC_PHYSICAL_ADDRESS
-#define CYGARC_PHYSICAL_ADDRESS(x) (((unsigned long)x & 0x0FFFFFFF) + RAM_BANK0_BASE)
+#define CYGARC_PHYSICAL_ADDRESS(x) (((unsigned long)(x) & 0x0FFFFFFF) + RAM_BANK0_BASE)
#endif
//-----------------------------------------------------------------------------
str r9, [r10, #GPIO_GDIR]
LED_INIT
- LED_BLINK #1
init_clock_start:
init_clock
- LED_BLINK #2
+ LED_BLINK #1
Normal_Boot_Continue:
/*
orr sp, r1, r2
@ Create MMU tables
+
+ LED_BLINK #2
bl hal_mmu_init
LED_BLINK #3
.ltorg
.align 5
10:
+ LED_BLINK #4
.endm @ _platform_setup1
/* AIPS setup - Only setup MPROTx registers. The PACR default values are good.*/
1:
/* make sure change is effective */
ldr r1, [r0, #CLKCTL_CDHIPR]
- LED_BLINK #1
cmp r1, #0x0
bne 1b
/* make sure change is effective */
1:
ldr r1, [r0, #CLKCTL_CDHIPR]
- LED_BLINK #1
cmp r1, #0x0
bne 1b
subs r10, r10, #1
movmi pc, lr
- ldr r9, =(36000 / 10 / 10)
+ ldr r9, =(36000 / 10)
2:
subs r9, r9, #1
bne 2b
(((tWR + 1) / 2) << 9) | \
(((tCL + 3) - 4) << 4)) << 16)
.endif
-#define ESDSCR_MRS_VAL(cs) (mrs_val | ((1 << (cs)) << 8))
+#define ESDSCR_MRS_VAL(cs) (mrs_val | ((cs) << 3))
#define ESDCFG0_VAL ( \
(tRFC << 24) | \
.word 0 /* Bad Block marker offset in spare area */
fcb_end:
+#if BANK_ADDR_BITS > 1
+#define REDBOOT_RAM_START (RAM_BANK1_BASE + RAM_BANK1_SIZE - REDBOOT_OFFSET)
+#else
+#define REDBOOT_RAM_START (RAM_BANK0_BASE + RAM_BANK0_SIZE - REDBOOT_OFFSET)
+#endif
+
+#define redboot_v2p(v) ((v) - __text_start + REDBOOT_RAM_START)
+
.org 0x400
ivt_header:
.word CPU_2_BE_32((0xd1 << 24) | (32 << 8) | 0x40)
app_start_addr:
- .long reset_vector
+ .long redboot_v2p(reset_vector)
.long 0x0
dcd_ptr:
- .long dcd_hdr
+ .long redboot_v2p(dcd_hdr)
boot_data_ptr:
- .word boot_data
+ .word redboot_v2p(boot_data)
self_ptr:
- .word ivt_header
+ .word redboot_v2p(ivt_header)
app_code_csf:
.word 0x0
.word 0x0
boot_data:
- .long __text_start
+ .long redboot_v2p(__text_start)
image_len:
.long REDBOOT_IMAGE_SIZE
plugin:
#define UNCACHED_RAM_BASE_VIRT 0xB0000000
-#define SZ_128M 0x08000000
-#define SZ_256M 0x10000000
#define RAM_BANK0_BASE CSD0_BASE_ADDR
#define RAM_BANK1_BASE CSD1_BASE_ADDR
-#define RAM_BANK0_SIZE SZ_1G
+#define RAM_BANK0_SIZE SZ_512M
#if SDRAM_SIZE > RAM_BANK0_SIZE
#define RAM_BANK1_SIZE (SDRAM_SIZE - RAM_BANK0_SIZE)
#endif
#include CYGBLD_HAL_PLF_DEFS_H
#include <cyg/hal/hal_soc.h>
-#define CYGHWR_REDBOOT_LINUX_ATAG_MEM(_p_) \
- CYG_MACRO_START \
- { \
- extern unsigned int system_rev; \
- /* Next ATAG_MEM. */ \
- _p_->hdr.size = (sizeof(struct tag_mem32) + sizeof(struct tag_header))/sizeof(long); \
- _p_->hdr.tag = ATAG_MEM; \
- /* Round up so there's only one bit set in the memory size. \
- * Don't double it if it's already a power of two, though. \
- */ \
- _p_->u.mem.size = 1<<hal_msbindex(CYGMEM_REGION_ram_SIZE); \
- if (_p_->u.mem.size < CYGMEM_REGION_ram_SIZE) \
- _p_->u.mem.size <<= 1; \
- _p_->u.mem.start = CYGARC_PHYSICAL_ADDRESS(CYGMEM_REGION_ram); \
- _p_ = (struct tag *)((long *)_p_ + _p_->hdr.size); \
- _p_->hdr.size = ((sizeof(struct tag_revision)) + sizeof(struct tag_header))/sizeof(long); \
- _p_->hdr.tag = ATAG_REVISION; \
- _p_->u.revision.rev = system_rev; \
- } \
+#ifdef RAM_BANK1_SIZE
+#define CYGHWR_REDBOOT_LINUX_ATAG_MEM(_p_) \
+ CYG_MACRO_START \
+ { \
+ extern unsigned int system_rev; \
+ /* Next ATAG_MEM. */ \
+ _p_->hdr.size = (sizeof(struct tag_mem32) + \
+ sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_MEM; \
+ /* Round up so there's only one bit set in the memory size. \
+ * Don't double it if it's already a power of two, though. \
+ */ \
+ _p_->u.mem.size = 1<<hal_msbindex(RAM_BANK0_SIZE); \
+ if (_p_->u.mem.size < RAM_BANK0_SIZE) \
+ _p_->u.mem.size <<= 1; \
+ _p_->u.mem.start = RAM_BANK0_BASE; \
+ \
+ _p_ = (struct tag *)((long *)_p_ + _p_->hdr.size); \
+ \
+ /* Next ATAG_MEM. */ \
+ _p_->hdr.size = (sizeof(struct tag_mem32) + \
+ sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_MEM; \
+ /* Round up so there's only one bit set in the memory size. \
+ * Don't double it if it's already a power of two, though. \
+ */ \
+ _p_->u.mem.size = 1<<hal_msbindex(RAM_BANK1_SIZE); \
+ if (_p_->u.mem.size < RAM_BANK1_SIZE) \
+ _p_->u.mem.size <<= 1; \
+ _p_->u.mem.start = RAM_BANK1_BASE; \
+ \
+ _p_ = (struct tag *)((long *)_p_ + _p_->hdr.size); \
+ \
+ _p_->hdr.size = ((sizeof(struct tag_revision)) + \
+ sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_REVISION; \
+ _p_->u.revision.rev = system_rev; \
+ } \
CYG_MACRO_END
+#else
+#define CYGHWR_REDBOOT_LINUX_ATAG_MEM(_p_) \
+ CYG_MACRO_START \
+ { \
+ extern unsigned int system_rev; \
+ /* Next ATAG_MEM. */ \
+ _p_->hdr.size = (sizeof(struct tag_mem32) + \
+ sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_MEM; \
+ /* Round up so there's only one bit set in the memory size. \
+ * Don't double it if it's already a power of two, though. \
+ */ \
+ _p_->u.mem.size = 1<<hal_msbindex(RAM_BANK0_SIZE); \
+ if (_p_->u.mem.size < RAM_BANK0_SIZE) \
+ _p_->u.mem.size <<= 1; \
+ _p_->u.mem.start = RAM_BANK0_BASE; \
+ \
+ _p_ = (struct tag *)((long *)_p_ + _p_->hdr.size); \
+ \
+ _p_->hdr.size = ((sizeof(struct tag_revision)) + \
+ sizeof(struct tag_header))/sizeof(long); \
+ _p_->hdr.tag = ATAG_REVISION; \
+ _p_->u.revision.rev = system_rev; \
+ } \
+ CYG_MACRO_END
+#endif /* RAM_BANK1_SIZE */
#endif // CYGONCE_HAL_ARM_BOARD_PLF_IO_H
static unsigned long __inline__ hal_virt_to_phy(unsigned long virt)
{
- if (((virt & 0xF0000000) == CSD0_BASE_ADDR) ||
- ((virt & 0xF0000000) == UNCACHED_RAM_BASE_VIRT)) {
- virt &= ~0xF0000000;
+ if (((virt & 0xf0000000) >= CSD0_BASE_ADDR) &&
+ ((virt & 0xf0000000) < CSD0_BASE_ADDR + SDRAM_SIZE)) {
+ virt -= CSD0_BASE_ADDR;
+ } else if (((virt & 0xf0000000) >= UNCACHED_RAM_BASE_VIRT) &&
+ ((virt & 0xf0000000) < UNCACHED_RAM_BASE_VIRT + SDRAM_SIZE)) {
+ virt -= UNCACHED_RAM_BASE_VIRT;
}
- if (virt < SDRAM_SIZE) {
- return virt | (virt < RAM_BANK0_SIZE ? CSD0_BASE_ADDR : CSD1_BASE_ADDR);
+ if (virt < RAM_BANK0_SIZE) {
+ return virt + CSD0_BASE_ADDR;
+ } else if (virt < SDRAM_SIZE) {
+ return virt - RAM_BANK0_SIZE + CSD1_BASE_ADDR;
}
- if ((virt & 0xF0000000) == UNCACHED_RAM_BASE_VIRT) {
- if (virt >= RAM_BANK0_SIZE) {
- virt = virt - CSD0_BASE_ADDR + CSD1_BASE_ADDR - RAM_BANK0_SIZE;
- }
- }
- return virt;
+ return ~0;
}
/*
/* 0xb0000000 .. (0xb0000000 + SDRAM_SIZE) is
* uncacheable memory space which is mapped to SDRAM
*/
- if ((phy & 0xF0000000) == CSD0_BASE_ADDR) {
- phy = (phy - CSD0_BASE_ADDR) | UNCACHED_RAM_BASE_VIRT;
- }
- if ((phy & 0xF0000000) == CSD1_BASE_ADDR) {
- phy = (phy - CSD1_BASE_ADDR + CSD0_BASE_ADDR + RAM_BANK0_SIZE) | UNCACHED_RAM_BASE_VIRT;
+ if (((phy & 0xF0000000) >= CSD0_BASE_ADDR) &&
+ ((phy & 0xF0000000) < CSD0_BASE_ADDR + RAM_BANK0_SIZE)) {
+ return (phy - CSD0_BASE_ADDR) + UNCACHED_RAM_BASE_VIRT;
+#ifdef RAM_BANK1_SIZE
+ } else if (((phy & 0xF0000000) >= CSD1_BASE_ADDR) &&
+ ((phy & 0xF0000000) < CSD1_BASE_ADDR + RAM_BANK1_SIZE)) {
+ return (phy - CSD1_BASE_ADDR + RAM_BANK0_SIZE) + UNCACHED_RAM_BASE_VIRT;
+#endif
}
- return phy;
+ return ~0;
}
#endif // CYGONCE_HAL_BOARD_PLATFORM_PLF_MMAP_H
/* Physical Virtual Size Attributes access permissions Function */
/* Base Base MB cached? buffered? */
/* xxx00000 xxx00000 */
- X_ARM_MMU_SECTION(0x000, 0x200, 0x001, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Boot Rom */
-// X_ARM_MMU_SECTION(0x1FF, 0x1FF, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
- X_ARM_MMU_SECTION(0x180, 0x180, 0x080, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
+ X_ARM_MMU_SECTION(0x000, 0xfff, 0x001, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Boot Rom */
+ X_ARM_MMU_SECTION(0xF80, 0xF80, 0x001, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IRAM */
+ X_ARM_MMU_SECTION(0x180, 0x480, 0x080, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* IPUv3D */
X_ARM_MMU_SECTION(0x500, 0x500, 0x200, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* Internal Registers */
X_ARM_MMU_SECTION(SD_P0, 0x000, SD_S0, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
X_ARM_MMU_SECTION(SD_P0, SD_C0, SD_S0, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
X_ARM_MMU_SECTION(SD_P1, SD_C1, SD_S1, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
X_ARM_MMU_SECTION(SD_P1, SD_U1, SD_S1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* SDRAM */
/* make sure the last MiB in the upper bank of SDRAM (where RedBoot resides)
- * has a unity mapping (required when switching MMU on) */
+ * has a unity mapping (required when switching MMU on).
+ * This mapping will overwrite the last MiB of the uncached mapping above
+ * which will be restored in plf_hardware_init().
+ */
X_ARM_MMU_SECTION(SD_HI, SD_HI, 0x001, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RO_RO); /* SDRAM bank1 identity mapping */
#endif
X_ARM_MMU_SECTION(0xF40, 0xF40, 0x040, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); /* CS1 EIM control & NFC buffer */
void plf_hardware_init(void)
{
#ifdef RAM_BANK1_SIZE
- /* destroy mapping for high area in SDRAM */
- X_ARM_MMU_SECTION(SD_HI, 0, 0, 0, 0, ARM_ACCESS_PERM_NONE_NONE);
+ /* overwrite temporary mapping for high area in SDRAM with actual mapping */
+ X_ARM_MMU_SECTION(SD_P0 + SD_S0 - 1, SD_U0 + SD_S0 - 1, 1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW);
+ HAL_CACHE_FLUSH_ALL();
#endif
uart_gpio_init();
fec_gpio_init();
// Memory mapping details
#ifndef CYGARC_PHYSICAL_ADDRESS
-#define CYGARC_PHYSICAL_ADDRESS(x) (((unsigned long)x & 0x0FFFFFFF) + RAM_BANK0_BASE)
+#define CYGARC_PHYSICAL_ADDRESS(x) (((unsigned long)(x) & 0x0FFFFFFF) + RAM_BANK0_BASE)
#endif
//-----------------------------------------------------------------------------