hal_platform_setup.h
来自「eCos操作系统源码」· C头文件 代码 · 共 909 行 · 第 1/2 页
H
909 行
#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 Red Hat, Inc.// Copyright (C) 2002 Gary Thomas//// 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: gthomas// Date: 2000-10-10// Purpose: Intel IOP310 platform specific support routines// Description: // Usage: #include <cyg/hal/hal_platform_setup.h>////####DESCRIPTIONEND####////===========================================================================*/#include <pkgconf/system.h> // System-wide configuration info#include <cyg/hal/hal_mmu.h> // MMU definitions#include <cyg/hal/hal_mm.h> // More MMU definitions#include CYGBLD_HAL_VARIANT_H // Variant specific configuration#include CYGBLD_HAL_PLATFORM_H // Platform specific configuration#include <cyg/hal/hal_iop310.h> // Platform specific hardware definitions// 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 0xc0, 0xf9, 0xa4, 0xb0 ;\ .byte 0x99, 0x92, 0x82, 0xf8 ;\ .byte 0x80, 0x90, 0x88, 0x83 ;\ .byte 0xa7, 0xa1, 0x86, 0x8e ;\ 667: ;\ ldr r0, =666b ;\ add r0, r0, #\x ;\ ldrb r1, [r0] ;\ ldr r0, =DISPLAY_RIGHT ;\ str r1, [r0]#undef CYGHWR_LED_MACRO// The main useful output of this file is PLATFORM_SETUP1: it invokes lots// of other stuff (may depend on RAM or ROM start). The other stuff is// divided into further macros to make it easier to manage what's enabled// when.#if defined(CYG_HAL_STARTUP_ROM)#define PLATFORM_SETUP1 _platform_setup1//#define CYGHWR_HAL_ARM_HAS_MMU#else#define PLATFORM_SETUP1#endif#define RAM_BASE 0xa0000000#define DRAM_SIZE (512*1024*1024) // max size of available SDRAM#define DCACHE_SIZE (32*1024) // size of the Dcache// Reserved area for battery backup SDRAM memory test// This area is not zeroed out by initialization code#define SDRAM_BATTERY_TEST_BASE 0xA1FFFFF0 // base address of last 16 memory locations in a 32MB SDRAM // Display 'lvalue:rvalue' on the hex display // lvalue and rvalue must be of the form 'DISPLAY_x' // where 'x' is a hex digit from 0-F. .macro HEX_DISPLAY reg0, reg1, lvalue, rvalue ldr \reg0, =DISPLAY_LEFT // display left digit ldr \reg1, =\lvalue str \reg1, [\reg0] ldr \reg0, =DISPLAY_RIGHT ldr \reg1, =\rvalue // display right digit str \reg1, [\reg0] .endm // Trigger the logic analyzer by writing a particular // address, and triggering on that address. .macro TRIGGER_LA_ON_ADDRESS address, reg0, reg1 mrc p15, 0, \reg0, c1, c0, 0 // read ARM control register // CPWAIT \reg0 ldr \reg1, =\address str \reg0, [\reg1] .endm // Delay a bit .macro DELAY_FOR cycles, reg0 ldr \reg0, =\cycles subs \reg0, \reg0, #1 subne pc, pc, #0xc .endm // wait for coprocessor write complete .macro CPWAIT reg mrc p15,0,\reg,c2,c0,0 mov \reg,\reg sub pc,pc,#4 .endm // form a first-level section entry .macro FL_SECTION_ENTRY base,x,ap,p,d,c,b .word (\base << 20) | (\x << 12) | (\ap << 10) | (\p << 9) |\ (\d << 5) | (\c << 3) | (\b << 2) | 2 .endm // form a first-level page table entry .macro FL_PT_ENTRY base,p,d // I wanted to use logical operations here, but since I am using symbols later // to fill in the parameters, I had to use addition to force the assembler to // do it right .word \base + (\p << 9) + (\d << 5) + 1 .endm // form a second level small page entry .macro SL_SMPAGE_ENTRY base,ap3,ap2,ap1,ap0,c,b .word (\base << 12) | (\ap3 << 10) | (\ap2 << 8) | (\ap1 << 6) |\ (\ap0 << 4) | (\c << 3) | (\b << 2) | 2 .endm // form a second level extended small page entry .macro SL_XSMPAGE_ENTRY base,x,ap,c,b .word (\base << 12) | (\x << 6) | (\ap << 4) | (\c << 3) | (\b << 2) | 3 .endm // start of platform setup .macro _platform_setup1 // This is where we wind up immediately after reset. On the IOP310, we have // to jump around a hole in flash which runs from 0x00001000 - 0x0001fff. // The start of _platform_setup1 will be below 0x1000 and since we need to // align the mmu table on a 16k boundary, we just branch around the page // table which we will locate at FLASH_BASE+0x4000. b _real_platform_setup .p2align 13 // the following alignment creates the mmu table at address 0x4000. mmu_table: // 1MB of FLASH with i80312 MMRs mapped in using 4K small pages so we can // set the access permission on flash and memory-mapped registers properly. FL_PT_ENTRY mmu_table_flashbase,0,0 // Remaining 7MB of FLASH // rw, cacheable, non-bufferable .set __base,1 .rept 7 FL_SECTION_ENTRY __base,0,3,0,0,1,0 .set __base,__base+1 .endr // nothing interesting here (Address Translation) .rept 0xA00 - 0x8 FL_SECTION_ENTRY __base,0,3,0,0,0,0 .set __base,__base+1 .endr // up to 512MB ECC SDRAM mapped 1-to-1 // first 1MB mapped in 4K chunks // x=c=b=1 FL_PT_ENTRY mmu_table_rambase,1,0 .set __base,__base+1 .rept 0xC00 - 0xA01 FL_SECTION_ENTRY __base,1,3,1,0,1,1 .set __base,__base+1 .endr // Cache flush region. // Don't need physical memory, just a cached area. .rept 0xD00 - 0xC00 FL_SECTION_ENTRY __base,0,3,0,0,1,1 .set __base,__base+1 .endr // Alias for first 1MB of FLASH // rw, cacheable, non-bufferable FL_SECTION_ENTRY 0x000,0,3,0,0,1,0 .set __base,__base+1 // Invalid .rept 0xE00 - 0xD01 .word 0 .set __base,__base+1 .endr // Uncached and unbuffered alias for first 256MB of SDRAM. This // area can be used by device drivers for DMA operations. Buffers // should be cache aligned. .set __base,0xA00 .rept 0xF00 - 0xE00 FL_SECTION_ENTRY __base,0,3,1,0,0,0 .set __base,__base+1 .endr // only I/O at 0xFE8xxxxx .set __base,0xF00 .rept 0x1000 - 0xF00 FL_SECTION_ENTRY __base,0,3,0,0,0,0 .set __base,__base+1 .endr // Immediately after the above table (at 0x8000) is the // second level page table which breaks up the lowest 1MB // of physical memory into 4KB sized virtual pages. These // pages work around a hole in flash (0x1000-0x1fff) used // by the Yavapai companion chip internal registers. mmu_table_flashbase: // Virtual address 0 (Flash boot code). // Map 4k page at 0x00000000 virt --> 0xA0000000 physical // This allows us to have a writable vector table. // Read-Write, cacheable, bufferable SL_XSMPAGE_ENTRY 0xa0000,1,3,1,1 // Virtual address 0x1000 (Memory mapped registers) // Map 1-to-1, but don't cache or buffer // Read-Write, non-cacheable, non-bufferable .set __base,1 SL_SMPAGE_ENTRY __base,3,3,3,3,0,0 .set __base,__base+1 // Virtual address 0x2000-0x100000 (remainder of flash1) // Read-Write, cacheable, non-bufferable .rept 0x100 - 0x2 SL_SMPAGE_ENTRY __base,3,3,3,3,1,0 .set __base,__base+1 .endr // Now is the second level table for the first megabyte // of DRAM. mmu_table_rambase: // Map first meg of SDRAM // Read-Write, cacheable, bufferable .set __base,0xA0000 .rept 0x100 SL_XSMPAGE_ENTRY __base,1,3,1,1 .set __base,__base+1 .endr_real_platform_setup: // Drain write and fill buffer mcr p15,0,r0,c7,c10,4 CPWAIT r0 // Disable write buffer coalescing mrc p15,0,r0,c1,c0,1 orr r0,r0,#1 // set the disable bit mcr p15,0,r0,c1,c0,1 CPWAIT r0 // Delay appx 60 ms to let battery-backup reset complete DELAY_FOR 0x400000, r0 // Eventually we will be able to check a register bit // to determine when this is complete HEX_DISPLAY r0, r1, DISPLAY_0, DISPLAY_1 // // *** I2C interface initialization *** // // Setup I2C Slave Address Register ldr r1, =I2C_DEVID // Load slave address r1. ldr r2, =ISAR_ADDR // Load address of the I2C Slave Address Register in r2. ldr r3, =0x0000007f // Load mask in r3. and r1, r3, r3 // The mask zeroes the 25 MSBs of r1 just to make sure. str r3, [r2] // Save the value 0x02 (I2C_DEVID) in the register. // Setup I2C Clock Count Register ldr r2, =ICCR_ADDR // Load the address of the I2C Clock Control Register in r2. ldr r3, =0x0000014d // Set for 5.05 us transition time at 66MHz (0x14D = 333). str r3, [r2] // Save the value in the register. // Enable I2C Interface Unit - status will be polled ldr r2, =ICR_ADDR // Load the address of the Control Register in r2. ldr r1, =ICR_GCALL // Disable General Call (will be master) ldr r3, =ICR_ENB // Enable I2C unit ). orr r1, r3, r1 // OR the two and store in R1 ldr r3, =ICR_SCLENB // Enable I2C Clock Generator disabled orr r1, r3, r1 // OR the two and store in R1 str r1, [r2] // Save the value to the Control Register. // // *** Now read the SPD Data *** // // Pointers to I2C Registers ldr r11, =ICR_ADDR // Load the address of the I2C Control Register in r11. ldr r12, =ISR_ADDR // Load the address of the I2C Status Register in r12. ldr r13, =IDBR_ADDR // Load the address of the I2C Data Buffer Register in r13. // Initialize byte counters ldr r6, =0x00000000 // Counter incremented before byte is read ldr r7, =0x00000040 // Number of bytes to read in the Presence Detect EEPROM of SDRAM: 64 bytes ldr r5, =0x00000000 // R5 has running checksum calculation ldr r9, =I2C_TIMOUT // Timeout limit in case EEPROM does not respond // At the end of all this, R4 has DRAM size, R8 has bank count, and R10 has Bank size ldr r10,=0x00000000 // Bank size ldr r8, =0x00000000 // Bank count ldr r4, =0x00000000 // SDRAM size /* FREE REGISTERS ARE R0 - R3 */ // *** Put out address, with WRITE mode *** // Set SDRAM module address and write mode ldr 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, [r13] // Store to data register // Initiate dummy write to set EEPROM pointer to 0 ldr r1, [r11] // read the current Control Register value orr r1, r1, #ICR_START // Set start bit orr r1, r1, #ICR_TRANSFER // Set transfer bit - bit is self_clearing str r1, [r11] // Store to control register // Wait for transmit empty status ldr r1, =0x00000000 // Initialize I2C timeout counter 0: add r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1) cmp r1, r9 beq i2c_error // Kick out of SDRAM initialization if timeout occurs ldr r0, [r12] // Load I2C Status Reg into R0 ands r3, r0, #ISR_EMPTY // Bit #6 is checked: IDBR Transmit Empty beq 0b str r0, [r12] // Write back status to clear // *** Write pointer register on EEPROM to 0x00000000 *** // Set SDRAM module EEPROM address to 0 ldr r1, =0x00000000 // Load base address of SDRAM module EEPROM str r1, [r13] // Store to data register // Send address to EEPROM ldr r1, [r11] // read the current Control Register value bic r1, r1, #ICR_START // No start bit (already started) orr r1, r1, #ICR_TRANSFER // Set transfer bit - bit is self_clearing str r1, [r11] // Store to control register // Wait for transmit empty status ldr r1, =0x00000000 // Initialize I2C timeout counter 0: add r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1) cmp r1, r9 beq i2c_error // Kick out of SDRAM initialization if timeout occurs ldr r0, [r12] // Load I2C Status Reg into R0 - ld (r12), r10 ands r3, r0, #ISR_EMPTY // Bit #6 is checked: IDBR Transmit Empty beq 0b str r0, [r12] // Write back status to clear // *** Read SDRAM PD data *** // *** Put out address, with READ mode *** // Set SDRAM module address and read mode ldr r0, =SDRAM_DEVID // Load slave address for SDRAM module (0xA2) orr r1, r0, #IDBR_MODE // Set read bit (bit #0) str r1, [r13] // Store to data register // Send next read request ldr r1, [r11] // read the current Control Register value orr r1, r1, #ICR_START // Set start bit orr r1, r1, #ICR_TRANSFER // Set transfer bit - bit is self_clearing str r1, [r11] // Store to control register // Wait for transmit empty status ldr r1, =0x00000000 // Initialize I2C timeout counter 0: add r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1) cmp r1, r9 beq i2c_error // Kick out of SDRAM initialization if timeout occurs ldr r0, [r12] // Load I2C Status Reg into R0 - ld (r12), r10 ands r3, r0, #ISR_EMPTY // Bit #6 is checked: IDBR Transmit Empty beq 0b str r0, [r12] // Write back status to clear sdram_loop: add r6, r6, #1 // Increment byte counter // *** READ the next Byte!!! *** ldr r1, [r11] // read the current Control Register value bic r1, r1, #ICR_START // No start bit (already started) orr r1, r1, #ICR_TRANSFER // Set transfer bit - bit is self_clearing // we have to set NACK before reading the last bit cmp r6, r7 // r7 = 64 (decimal) so if r6 = 64, this is the last byte to be read bne 1f // If bytes left, skip ahead orr r1, r1, #ICR_ACK // Set NACK if this is the last byte orr r1, r1, #ICR_STOP // Set STOP if this is the last byte 1: str r1, [r11] // Store to control register // Wait for read full status ldr r1, =0x00000000 // Initialize I2C timeout counter 0: add r1, r1, #1 // Increment I2C timeout counter (r1 = r1 + 1) cmp r1, r9 beq i2c_error // Kick out of SDRAM initialization if timeout occurs ldr r0, [r12] // Load I2C Status Reg into R0 ands r3, r0, #ISR_FULL // Bit #6 is checked: IDBR Transmit Empty beq 0b str r0, [r12] // Write back status to clear // Read the data byte ldr r1, [r13] // Read the byte ldr r2, =CHECKSUM_BYTE cmp r6, r2 // is it the CHECKSUM byte??? beq 1f add r5, r5, r1 // Add it to the checksum if not the checksum byte bal 2f // skip checksum comparison 1: ldr r0, =0xff // If this is the checksum byte, compare it
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?