⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boot_loader_epcs_bits_stratix_ii.s

📁 在altera de1的板子上安装fat12fat16fat32文件系统
💻 S
字号:
// file: boot_laoder_epcs_bits_stratix_ii.S
// asmsyntax=nios2
//
// Copyright 2006 Altera Corporation, San Jose, California, USA.
// All rights reserved.
//
// Stratix II support added by jrk, 2006.01.26:
// - FPGA device-family-specific code moved to
//   separate sources.
// - This file contains EPCS boot routines
//   specific to the Stratix II device family
//   only; support for other device families
//   is provided in separate sources, so that
//   separate (and thus small) boot loader
//   executables will be built.
//

#include "boot_loader.h"

    .global sub_find_payload_epcs

// |
// | Let the code begin
// |

    .text

// |
// | Find_Payload for EPCS (Stratix II edition):
// |
// | The process:
// |  1) Open the EPCS at zero (where device-config lives)
// |
// |  2) We see a byte other than 0xFF, prior to where non-0xFF Stratix II
// |     configuration data is expected (byte[32]), in which case we're
// |     not looking at a device configuration. Instead we assume we must
// |     be looking at a boot loader record. Skip the whole "length
// |     of the configuration" calculation, and start loading.
// |
// |  3) We find that the bitstream targets a Stratix-II device. Extract
// |     the precise FPGA configuration length. Close/re-open the EPCS device
// |     after the FPGA configuration before returning to load.
// |
// |  4) We don't find anything other than 0xFF's before where we expect
// |     Stratix II data, or, our attempts to verify that what appears to
// |     be Stratix II data fail. In these cases we have no other recourse
// |     than to hang.
// |
// | A note about nomenclature in this code's documentation: data[N] refers to
// | Nth unit of data, assuming that you start counting at zero.
// |

sub_find_payload_epcs:
    // Fix-up and save return-address
    addi    r_findp_return_address, return_address_less_4, 4

  //
  // Compute the address of the EPCS control/status register block.
  //
  // This is 1024 bytes (targeting Stratix II) from the very *start*
  // of this program.
  //
  // Note: On Cyclone I/II its 512 bytes; the Stratix II boot loader
  // is just a hair too big to fit into 512. The enterprising engineer
  // with an appreciation for tightly-wound and barely-readable code
  // may wish to further optimize this. After stariing at the code for
  // an hour I figured, after optimizations, I'd still be a few instructions
  // over the top. I tried.
  //
  // | dvb adds: Since the code must be aligned on a 1024-byte
  // | boundary, we simply take our current address, and round up
  // | to the next 1024-byte boundary.
  //
  // | for debugging purposes, you may define EPCS_REGS_BASE
  // | to be the epcs registers base. Otherwise, it is presumed
  // | to be the first 1024-byte-boundary after this very code/
  //
    nextpc  r_findp_temp

#ifdef EPCS_REGS_BASE
    movhi   r_epcs_base_address, %hi(EPCS_REGS_BASE)
    addi    r_epcs_base_address, r_epcs_base_address, %lo(EPCS_REGS_BASE)
#else
    ori     r_epcs_base_address, r_findp_temp, 1023
    addi    r_epcs_base_address, r_epcs_base_address, 1
#endif

    //
    // 1) Open EPCS-device at flash-offset zero.
    //
    movi    r_flash_ptr, 0
    nextpc  return_address_less_4
    br      sub_epcs_open_address

    //
    // 2) Attempt to find software boot record
    //

    // Search until we expect Stratix II data to start
    movi    r_findp_count, 32

    // What we'll accept until we see the pattern
    movi    r_findp_temp, 0xFF

fp_look_for_software_boot_record:
    nextpc  return_address_less_4
    br      sub_read_byte_from_flash_epcs

    // Did we see something other than an 0xFF?
    bne     r_read_byte_return_value, r_findp_temp, fp_short_circuit

    // Update the loop counter, and loop
    subi    r_findp_count, r_findp_count, 1
    bne     r_findp_count, r_zero, fp_look_for_software_boot_record

    //
    // 3) We didn't find a boot record. Is there a Stratix II bitstream?
    //
    //    The 7-bit Stratix II Software-Device ID code is stored in bit[1]*
    //    of bytes [59..52] of the configuration data. Device IDs in the
    //    range 0x91..0x96 (inclusive) indicate that the configuration data
    //    targets Stratix II.
    //
    //    * Data is stored in EPCS backwards; each byte is reversed. Thus,
    //      if we're looking for data bit[1] we will actually grab bit[6].

    // Close & re-open EPCS where we expect the device ID code to start
    movi    r_flash_ptr, 52
    nextpc  return_address_less_4
    br      sub_epcs_close
    nextpc  return_address_less_4
    br      sub_epcs_open_address

    // Number of bytes we'll traverse to get the device ID (one bit each)
    movi    r_findp_count, 8

    // Clear the register we'll construct the ID into
    movi    r_findp_pattern, 0

fp_assemble_device_id:
    // Read sequential byte from EPCS
    nextpc  return_address_less_4
    br      sub_read_byte_from_flash_epcs

    // Mask off all but bit[6] as described above
    andi    r_read_byte_return_value, r_read_byte_return_value, 0x40

    // Shift to the MSB position of the 8-bit value we're constructing
    // (the data we're after is being read LSB first)
    slli    r_read_byte_return_value, r_read_byte_return_value, 0x1

    // Shift result register & capture new data into bit[7]
    srli    r_findp_pattern, r_findp_pattern, 0x1
    or      r_findp_pattern, r_findp_pattern, r_read_byte_return_value

    // Update loop counter & loop
    subi    r_findp_count, r_findp_count, 1
    bne     r_findp_count, r_zero, fp_assemble_device_id

    // We now have an 8-bit device ID stored in r_findp_pattern. Validate it.

    // Less than 0x91 or more than 0x96? Not valid.
    movi    r_findp_temp, 0x91
    bltu    r_findp_pattern, r_findp_temp, sub_epcs_hang_forever
    movi    r_findp_temp, 0x96
    bgtu    r_findp_pattern, r_findp_temp, sub_epcs_hang_forever

    //
    // If we arrive at this point we have verified that there is valid-looking
    // Stratix II configuration data. Extract its length.
    //
    // Like searching for the Software-Device ID code, the configuration
    // bitstream length is encoded in a particular bit of a run of bytes.
    // While the total length field is 32 bits, the maximum size of a
    // valid Stratix II bitsream fits into 26.
    //
    // Examine only these 26 bits, which reside in bit[3] of byte[33]
    // (for the most significant 26th bit), followed by the range of bits
    // made up of bit[2] of bytes[72..48]. The above note about EPCS
    // bit reversal still applies (so we're really looking at bits[4] and [5],
    // respectively.
    //

    // First, loop through bits in bytes [48..72] - LSB of the length first
    // Number of bytes we'll traverse to get the length
    movi    r_findp_count, 25

    // Clear the register we'll construct the length into
    movi    r_findp_temp, 0

    // Close & re-open EPCS where we will start extracting the length
    movi    r_flash_ptr, 48
    nextpc  return_address_less_4
    br      sub_epcs_close
    nextpc  return_address_less_4
    br      sub_epcs_open_address

fp_assemble_configuration_length:
    // Read sequential byte from EPCS
    nextpc  return_address_less_4
    br      sub_read_byte_from_flash_epcs

    // Mask off all but bit[5] as described above
    andi    r_read_byte_return_value, r_read_byte_return_value, 0x20

    // Shift to the MSB position of the value we're constructing
    // (which happens to be 20 bits left of the bit we're working with)
    // (the data we're after is being read LSB first)... this may
    // seem backwards (it is), but the sub_read_byte_from_flash_epcs
    // routine auto increments the EPCS addres for us; thus the cleanest
    // implementation is to load data from sequential addresses, LSB first.
    slli    r_read_byte_return_value, r_read_byte_return_value, 20

    // Shift result register & capture new data into bit[25]
    srli    r_findp_temp, r_findp_temp, 0x1
    or      r_findp_temp, r_findp_temp, r_read_byte_return_value

    // Update loop counter & loop
    subi    r_findp_count, r_findp_count, 1
    bne     r_findp_count, r_zero, fp_assemble_configuration_length

    // We've assembled 25 bits of the length; 1 to go. This last bit is
    // located in bit[3] of byte[33] as described above

    // Close & re-open EPCS @ byte[33]
    movi    r_flash_ptr, 33
    nextpc  return_address_less_4
    br      sub_epcs_close
    nextpc  return_address_less_4
    br      sub_epcs_open_address

    // Grab the byte
    nextpc  return_address_less_4
    br      sub_read_byte_from_flash_epcs

    // Mask off all but bit[4]
    andi    r_read_byte_return_value, r_read_byte_return_value, 0x10

    // Shift result register & capture new data into bit[25]
    slli    r_read_byte_return_value, r_read_byte_return_value, 21
    srli    r_findp_temp, r_findp_temp, 1
    or      r_findp_temp, r_findp_temp, r_read_byte_return_value

    // Put extracted length in the flash pointer
    mov     r_flash_ptr, r_findp_temp

    //
    // Finally, it turns out the length was given in BITS.  Round-up
    // to the next byte, and convert to bytes
    //
    addi    r_flash_ptr, r_flash_ptr, 7      // r_flash_ptr += 7
    srli    r_flash_ptr, r_flash_ptr, 3      // r_flash_ptr /= 8;

fp_short_circuit:
    // Close the EPCS device
    nextpc  return_address_less_4
    br      sub_epcs_close

    // Open it up again (at r_flash_ptr)
    nextpc  return_address_less_4
    br      sub_epcs_open_address

    // Return; EPCS is now ready for boot-loading business
    jmp     r_findp_return_address

// end of file

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -