Ignore:
Timestamp:
May 25, 2014, 5:35:37 PM (10 years ago)
Author:
cfuguet
Message:

tsar_boot:

  • Important optimization in the reset_elf_loader function.
  • Implementation of pread function which uses bytes addressing to read disk.
  • pread function alternates between direct tranfer from disk to memory and from disk to a memory cache block based on alignment of byte address, i.e., when file offset is aligned to disk block (512 bytes), pread uses DMA capacity of disk to transfer directly to memory, otherwise it passes before by a memory cache block and then performs a memcpy to transfer data to final destination.
  • the cache block used by pread function, allows to treat succeeding reads on the same block without accessing the disk.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/softs/tsar_boot/src/reset_utils.c

    r691 r701  
    99#include <reset_utils.h>
    1010
     11/*
     12 * pread(size_t file_offset, void* buf, size_t nbyte, size_t offset)
     13 *
     14 * read from disk into buffer "nbyte" bytes from (file_offset + offset)
     15 *
     16 * \param file_offset: Disk relative offset of file
     17 * \param buf: Destination buffer
     18 * \param nbyte: Number of bytes to read
     19 * \param offset: File relative offset
     20 *
     21 * \note Absolute disk offset (in bytes) is (file_offset + offset)
     22 */
     23int pread(size_t file_offset, void *buf, size_t nbyte, size_t offset) {
     24    if (nbyte == 0) return 0;
     25
     26    /*
     27     * Cache block data buffer and cached block index
     28     */
     29    static struct aligned_blk blk_buf;
     30    static int blk_buf_idx = -1;
     31
     32    char *dst;
     33    int offset_blk;
     34    int unaligned_nbyte;
     35    int read_nbyte;
     36
     37    dst = (char*) buf;
     38
     39    /*
     40     * Offset parameter is relative to file, therefore compute disk relative
     41     * offset (in bytes)
     42     */
     43    offset += file_offset;
     44
     45    /*
     46     * Read unaligned bytes at start of segment passing by block cache
     47     */
     48    offset_blk = (offset / BLOCK_SIZE);
     49    offset = (offset % BLOCK_SIZE);
     50    unaligned_nbyte = BLOCK_SIZE - offset;
     51    read_nbyte = 0;
     52    if (offset) {
     53        /*
     54         * Check cache block hit: if miss, read new block else, use cache block
     55         * data
     56         */
     57        if (offset_blk != blk_buf_idx) {
     58            if (reset_ioc_read(offset_blk, (void*)&blk_buf, 1)) {
     59                return -1;
     60            }
     61        }
     62        blk_buf_idx = offset_blk;
     63        read_nbyte = (nbyte > unaligned_nbyte) ? unaligned_nbyte : nbyte;
     64        memcpy((void*)dst, (void*)&blk_buf.b[offset], read_nbyte);
     65        nbyte -= read_nbyte;
     66        offset_blk += 1;
     67    }
     68
     69    /*
     70     * Read aligned bytes directly to buffer
     71     */
     72    size_t nblk = nbyte / BLOCK_SIZE;
     73    if (nblk) {
     74        if (reset_ioc_read(offset_blk, (void*)&dst[read_nbyte], nblk)) {
     75            return -1;
     76        }
     77        read_nbyte += (nblk * BLOCK_SIZE);
     78        nbyte -= read_nbyte;
     79        offset_blk += nblk;
     80    }
     81
     82    /*
     83     * Read unaligned bytes at the end of segment passing by block cache
     84     */
     85    if (nbyte) {
     86        if (reset_ioc_read(offset_blk, (void*)&blk_buf, 1)) {
     87            return -1;
     88        }
     89        blk_buf_idx = offset_blk;
     90        memcpy((void*)&dst[read_nbyte], (void*)&blk_buf, nbyte);
     91        read_nbyte += nbyte;
     92    }
     93    return read_nbyte;
     94}
     95
    1196/********************************************************************
    1297 * proctime()
     
    31116 *
    32117 ********************************************************************/
    33 void * memcpy(void *_dst, const void *_src, unsigned int size)
     118void* memcpy(void *_dst, const void *_src, size_t n)
    34119{
    35120    unsigned int *dst = _dst;
     
    37122    if ( !((unsigned int)dst & 3) && !((unsigned int)src & 3) )
    38123    {
    39         while (size > 3)
     124        while (n > 3)
    40125        {
    41126            *dst++ = *src++;
    42             size -= 4;
     127            n -= 4;
    43128        }
    44129    }
     
    46131    unsigned char *cdst = (unsigned char*) dst;
    47132    unsigned char *csrc = (unsigned char*) src;
    48 
    49     while (size--)
     133    while (n--)
    50134    {
    51135        *cdst++ = *csrc++;
     
    64148 *
    65149 ********************************************************************/
    66 void * memset(void *_dst, const int value, unsigned int size)
    67 {
    68     unsigned char val = (unsigned char) value;
    69     int word = (val << 24) | (val << 16) | (val << 8 ) | val;
     150void* memset(void *_dst, int c, size_t len)
     151{
     152    if (len == 0) return _dst;
     153
     154    unsigned char val = (unsigned char) c;
     155    unsigned int word = (val << 24) | (val << 16) | (val << 8 ) | val;
    70156
    71157    /*
     
    76162    if ( !((unsigned int)dst & 3) )
    77163    {
    78         while (size > 3)
     164        while (len > 3)
    79165        {
    80166            *dst++ = word;
    81             size -= 4;
     167            len -= 4;
    82168        }
    83169    }
     
    87173     * or size is smaller than 4
    88174     */
    89     char* cdst = (char*) _dst;
    90     while(size--)
    91     {
    92         *cdst++ = (char) value;
     175    unsigned char* cdst = (unsigned char*) _dst;
     176    while(len--)
     177    {
     178        *cdst++ = (unsigned char) c;
    93179    }
    94180
    95181    return _dst;
     182}
     183
     184/********************************************************************
     185 * check_elf_header(Elf32_Ehdr*)
     186 *
     187 * Verify that ELF file is valid and that the number of program
     188 * headers does not exceed the defined maximum
     189 *
     190 * \param ehdr : ELF header pointer
     191 *
     192 ********************************************************************/
     193void check_elf_header(Elf32_Ehdr *ehdr)
     194{
     195    /*
     196     * Verification of ELF Magic Number
     197     */
     198    if ((ehdr->e_ident[EI_MAG0] != ELFMAG0) ||
     199        (ehdr->e_ident[EI_MAG1] != ELFMAG1) ||
     200        (ehdr->e_ident[EI_MAG2] != ELFMAG2) ||
     201        (ehdr->e_ident[EI_MAG3] != ELFMAG3))
     202    {
     203        reset_puts("[RESET ERROR] Unrecognized file format (not an ELF format)\n");
     204        reset_exit();
     205    }
     206
     207    /*
     208     * Verification of Program Headers table size. It must be
     209     * smaller than the work size allocated for the
     210     * elf_pht[PHDR_ARRAY_SIZE] array
     211     */
     212    if (ehdr->e_phnum > PHDR_ARRAY_SIZE)
     213    {
     214        reset_puts("[RESET ERROR] ELF PHDR table size too large\n");
     215        reset_exit();
     216    }
    96217}
    97218
     
    108229    reset_puts("- type   : ");
    109230    reset_putx(elf_phdr_ptr->p_type);
    110 
    111231    reset_puts("\n- offset : ");
    112232    reset_putx(elf_phdr_ptr->p_offset);
    113 
    114233    reset_puts("\n- vaddr  : ");
    115234    reset_putx(elf_phdr_ptr->p_vaddr);
    116 
    117235    reset_puts("\n- paddr  : ");
    118236    reset_putx(elf_phdr_ptr->p_paddr);
    119 
    120237    reset_puts("\n- filesz : ");
    121238    reset_putx(elf_phdr_ptr->p_filesz);
    122 
    123239    reset_puts("\n- memsz  : ");
    124240    reset_putx(elf_phdr_ptr->p_memsz);
    125 
    126241    reset_puts("\n- flags  : ");
    127242    reset_putx(elf_phdr_ptr->p_flags);
    128 
    129243    reset_puts("\n- align  : ");
    130244    reset_putx(elf_phdr_ptr->p_align);
     245    reset_puts("\n");
    131246}
    132247
     
    139254 ********************************************************************/
    140255#if USE_IOB
    141 void reset_mcc_invalidate ( const void * buffer,
    142                             unsigned int size)
    143 {
    144     unsigned int * mcc_address = (unsigned int *)MCC_PADDR_BASE;
     256void reset_mcc_invalidate (const void * buffer, size_t size)
     257{
     258    addr_t *mcc_address = (addr_t*)MCC_PADDR_BASE;
    145259
    146260    // get the hard lock assuring exclusive access to MEMC
     
    167281 ********************************************************************/
    168282#if (CACHE_COHERENCE == 0) || USE_IOB
    169 void reset_buf_invalidate ( const void * buffer,
    170                             unsigned int line_size,
    171                             unsigned int size)
     283void reset_buf_invalidate (const void * buffer, size_t line_size, size_t size)
    172284{
    173285    unsigned int i;
Note: See TracChangeset for help on using the changeset viewer.