📄 hal_platform_setup.h
字号:
#ifndef CYGONCE_HAL_PLATFORM_SETUP_H
#define CYGONCE_HAL_PLATFORM_SETUP_H
/*=============================================================================
//
// hal_platform_setup.h
//
// Platform specific support for HAL (assembly code)
//
//=============================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
//
// eCos 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) any later version.
//
// eCos 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 eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//=============================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s): msalter
// Contributors: msalter
// Date: 2001-12-03
// Purpose: Intel XScale IQ80321 platform specific support routines
// Description:
// Usage: #include <cyg/hal/hal_platform_setup.h>
// Only used by "vectors.S"
//
//####DESCRIPTIONEND####
//
//===========================================================================*/
#include <pkgconf/system.h> // System-wide configuration info
#include CYGBLD_HAL_VARIANT_H // Variant specific configuration
#include CYGBLD_HAL_PLATFORM_H // Platform specific configuration
#include <cyg/hal/hal_verde.h> // Variant specific hardware definitions
#include <cyg/hal/hal_mmu.h> // MMU definitions
#include <cyg/hal/hal_mm.h> // more MMU definitions
#include <cyg/hal/iq80321.h> // Platform specific hardware definitions
#include <cyg/hal/hal_spd.h>
#if defined(CYG_HAL_STARTUP_ROM)
#define PLATFORM_SETUP1 _platform_setup1
#define PLATFORM_EXTRAS <cyg/hal/hal_platform_extras.h>
#define CYGHWR_HAL_ARM_HAS_MMU
.macro NOPs count
.rept \count
nop
nop
.endr
.endm
// ------------------------------------------------------------------------
// Define macro used to diddle the LEDs during early initialization.
// Can use r0+r1. Argument in \x.
#define CYGHWR_LED_MACRO \
b 667f ;\
666: ;\
.byte DISPLAY_0, DISPLAY_1, DISPLAY_2, DISPLAY_3 ;\
.byte DISPLAY_4, DISPLAY_5, DISPLAY_6, DISPLAY_7 ;\
.byte DISPLAY_8, DISPLAY_9, DISPLAY_A, DISPLAY_B ;\
.byte DISPLAY_C, DISPLAY_D, DISPLAY_E, DISPLAY_F ;\
667: ;\
ldr r0, =666b ;\
add r0, r0, #\x ;\
ldrb r1, [r0] ;\
ldr r0, =DISPLAY_RIGHT ;\
str r1, [r0]
#define PAUSE \
ldr r1,=0x8000; \
555: sub r1,r1,#1; \
cmp r1,#0; \
bne 555b;
#define DCACHE_SIZE (32 * 1024)
// ------------------------------------------------------------------------
// MCU Register Values
// ------------------------------------------------------------------------
// This macro represents the initial startup code for the platform
.macro _platform_setup1
// This is where we wind up immediately after reset. At this point, we
// are executing from the boot address (0x00000000), not the eventual
// flash address. Do some basic setup using position independent code
// then switch to real flash address
// FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
// This is a quick and dirty workaround to an apparent gas/ld
// bug. The computed UNMAPPED_PTR(reset_vector) is off by 0x20.
.rept 0x20/4
nop
.endr
// FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME FIXME
ldr r0,=(CPSR_IRQ_DISABLE|CPSR_FIQ_DISABLE|CPSR_SUPERVISOR_MODE)
msr cpsr, r0
// enable coprocessor access
ldr r0, =0x20c1 // CP13,CP7,CP6,CP0
mcr p15, 0, r0, c15, c1, 0
// Drain write and fill buffer
mcr p15, 0, r0, c7, c10, 4
CPWAIT r0
// Setup PBIU chip selects
ldr r8, =PBIU_PBCR
ldr r2, =PBLR_SZ_4K
ldr r1, =IQ80321_UART_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_8
str r1, [r8, #0x10] // PBIU_PBAR1
str r2, [r8, #0x14] // PBIU_PBLR1
ldr r1, =IQ80321_DISPLAY_RIGHT_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_32
str r1, [r8, #0x18] // PBIU_PBAR2
str r2, [r8, #0x1C] // PBIU_PBLR2
ldr r1, =IQ80321_DISPLAY_LEFT_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_32
str r1, [r8, #0x20] // PBIU_PBAR3
str r2, [r8, #0x24] // PBIU_PBLR3
ldr r1, =IQ80321_ROTARY_SWITCH_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_32
str r1, [r8, #0x28] // PBIU_PBAR4
str r2, [r8, #0x2C] // PBIU_PBLR4
ldr r1, =IQ80321_BATTERY_STATUS_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_32
str r1, [r8, #0x30] // PBIU_PBAR5
str r2, [r8, #0x34] // PBIU_PBLR5
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_A, DISPLAY_1
// ====================================================================
// Enable the Icache
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #MMU_Control_I
mcr p15, 0, r0, c1, c0, 0
CPWAIT r0
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_A, DISPLAY_2
// ====================================================================
// value to write into PBIU_PBAR0 to establish runtime flash address
ldr r1, =IQ80321_FLASH_ADDR | PBAR_FLASH | PBAR_RCWAIT_20 | PBAR_ADWAIT_20 | PBAR_BUS_16
// value to write into PBIU_PBLR0 to establish runtime flash address
ldr r2, =PBLR_SZ_8M
// value to load into pc to jump to real runtime address
ldr r7, =1f
ldr r9, =IQ80321_DISPLAY_RIGHT_ADDR
ldr r10,=IQ80321_DISPLAY_LEFT_ADDR
ldr r11,=DISPLAY_F
b icache_boundary
.p2align 5
icache_boundary:
// Here is where we switch from boot address (0x000000000) to the
// actual flash runtime address. We align to cache boundary so we
// execute from cache during the switchover. Cachelines are 8 words.
str r1, [r8, #0x08] // PBIU_PBAR0
str r2, [r8, #0x0c] // PBIU_PBLR0
nop
nop
mov pc, r7
str r11, [r9] // We should never reach this point. If we do,
str r11, [r10] // display FF and loop forever.
0: b 0b
1:
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_A, DISPLAY_3
// ====================================================================
// Set the TTB register
ldr r0, =mmu_table
mcr p15, 0, r0, c2, c0, 0
// Enable permission checks in all domains
ldr r0, =0x55555555
mcr p15, 0, r0, c3, c0, 0
// Enable the MMU
mrc p15, 0, r0, c1, c0, 0
orr r0, r0, #MMU_Control_M
orr r0, r0, #MMU_Control_R
mcr p15, 0, r0, c1, c0, 0
CPWAIT r0
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_A, DISPLAY_4
// ====================================================================
//
// *** I2C interface initialization ***
//
// Pointers to I2C Registers
ldr r11, =I2C_BASE0 // base address of the I2C unit
// Write 0 to avoid interfering with I2C bus.
// (See GPIO section in 80321 manual)
ldr r2, =GPIO_GPOD
mov r3, #0
strb r3, [r2]
// Reset I2C Unit
mov r1, #ICR_RESET
str r1, [r11, #I2C_ICR0]
ldr r1, =0x7ff
str r1, [r11, #I2C_ISR0]
mov r1, #0
str r1, [r11, #I2C_ICR0]
// Setup I2C Slave Address Register
mov r1, #I2C_DEVID // Load slave address r1.
str r1, [r11, #I2C_ISAR0] // Save the value 0x02 (I2C_DEVID) in the register.
// Enable I2C Interface Unit - status will be polled
ldr r1, =ICR_GCALL | ICR_ENB | ICR_SCLENB
str r1, [r11, #I2C_ICR0]
//
// *** Now read the SPD Data ***
//
// Initialize regs for loop
mov r4, #0 // SDRAM size
mov r5, #0 // R5 has running checksum calculation
mov r6, #0 // Counter incremented before byte is read
mov r7, #64 // Number of bytes to read in the Presence Detect EEPROM of SDRAM
mov r8, #0 // Flags: b0-b6 == bankcnt, b7 = x16 flag
mov r9, #RFR_15_6us // Refresh rate (assume normal 15.6us)
mov r10, #0 // Bank size
mov r14, #0 // ECC flag
ldr r0, [r11, #I2C_ISR0] // Load I2C Status Reg into R0
str r0, [r11, #I2C_ISR0] // Clear status
/* FREE REGISTERS ARE R0 - R3 */
// *** Put out address, with WRITE mode ***
// Set SDRAM module address and write mode
mov r1, #SDRAM_DEVID // Load slave address for SDRAM module. 0xA2 (Presence Detect Data)
bic r1, r1, #IDBR_MODE // Clear read bit (bit #0)
str r1, [r11, #I2C_IDBR0] // Store to data register
// Initiate dummy write to set EEPROM pointer to 0
ldr r1, [r11, #I2C_ICR0] // read the current Control Register value
bic r1, r1, #ICR_STOP // No stop bit
orr r1, r1, #ICR_START | ICR_TRANSFER
str r1, [r11, #I2C_ICR0] // Store to control register
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_9, DISPLAY_0
// ====================================================================
// Wait for transmit empty status
mov r1, #I2C_TIMOUT // Initialize I2C timeout counter
0: subs r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1)
beq i2c_error // Kick out of SDRAM initialization if timeout occurs
ldr r0, [r11, #I2C_ISR0] // Load I2C Status Reg into R0
ands r3, r0, #ISR_EMPTY // Bit #6 is checked, IDBR Transmit Empty
beq 0b // If bit = 0 then branch to 0 and check again
str r0, [r11, #I2C_ISR0] // Write back status to clear
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_9, DISPLAY_1
// ====================================================================
// Write pointer register on EEPROM to 0x00000000
mov r1, #0 // Load base address of SDRAM module EEPROM
str r1, [r11, #I2C_IDBR0] // Store to data register
// Send address to EEPROM
ldr r1, [r11, #I2C_ICR0] // read the current Control Register value
bic r1, r1, #ICR_START | ICR_STOP
orr r1, r1, #ICR_TRANSFER // Set transfer bit - bit is self_clearing
str r1, [r11, #I2C_ICR0] // Store to control register
// ====================================================================
HEX_DISPLAY r0, r1, DISPLAY_9, DISPLAY_2
// ====================================================================
// Wait for transmit empty status
mov r1, #I2C_TIMOUT // Initialize I2C timeout counter
0: subs r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -