Ignore:
Timestamp:
2013-09-29T06:56:33Z (12 years ago)
Author:
Beniamino Galvani <b.galvani@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a9bd960d
Parents:
3deb0155 (diff), 13be2583 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/device/hw_res_parsed.c

    r3deb0155 rdd0c8a0  
    3838#include <errno.h>
    3939
    40 static void hw_res_parse_add_irq(hw_res_list_parsed_t *out, hw_resource_t *res,
    41     int flags)
     40static void hw_res_parse_add_dma_channel(hw_res_list_parsed_t *out,
     41    const hw_resource_t *res, int flags)
     42{
     43        assert(res);
     44        assert((res->type == DMA_CHANNEL_8) || (res->type == DMA_CHANNEL_16));
     45       
     46        const unsigned channel = (res->type == DMA_CHANNEL_8) ?
     47            res->res.dma_channel.dma8 : res->res.dma_channel.dma16;
     48        const size_t count = out->dma_channels.count;
     49        const int keep_duplicit = flags & HW_RES_KEEP_DUPLICIT;
     50       
     51        if (!keep_duplicit) {
     52                for (size_t i = 0; i < count; ++i) {
     53                        if (out->dma_channels.channels[i] == channel)
     54                                return;
     55                }
     56        }
     57       
     58        out->dma_channels.channels[count] = channel;
     59        ++out->dma_channels.count;
     60}
     61
     62static void hw_res_parse_add_irq(hw_res_list_parsed_t *out,
     63    const hw_resource_t *res, int flags)
    4264{
    4365        assert(res && (res->type == INTERRUPT));
     
    5880}
    5981
     82static uint64_t absolutize(uint64_t addr, bool relative, uint64_t base)
     83{
     84        if (!relative)
     85                return addr;
     86        else
     87                return addr + base;
     88}
     89
     90static uint64_t relativize(uint64_t addr, bool relative, uint64_t base)
     91{
     92        if (relative)
     93                return addr;
     94        else
     95                return addr - base;
     96}
     97
    6098static void hw_res_parse_add_io_range(hw_res_list_parsed_t *out,
    61     hw_resource_t *res, int flags)
    62 {
     99    const pio_window_t *win, const hw_resource_t *res, int flags)
     100{
     101        endianness_t endianness;
     102        uint64_t absolute;
     103        uint64_t relative;
     104        size_t size;
     105
    63106        assert(res && (res->type == IO_RANGE));
    64107       
    65         uint64_t address = res->res.io_range.address;
    66         endianness_t endianness = res->res.io_range.endianness;
    67         size_t size = res->res.io_range.size;
     108        absolute = absolutize(res->res.io_range.address,
     109            res->res.io_range.relative, win->io.base);
     110        relative = relativize(res->res.io_range.address,
     111            res->res.io_range.relative, win->io.base);
     112        size = res->res.io_range.size;
     113        endianness = res->res.io_range.endianness;
    68114       
    69115        if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
     
    75121        if (!keep_duplicit) {
    76122                for (size_t i = 0; i < count; i++) {
    77                         uint64_t s_address = out->io_ranges.ranges[i].address;
    78                         size_t s_size = out->io_ranges.ranges[i].size;
     123                        uint64_t s_address;
     124                        size_t s_size;
     125
     126                        s_address = RNGABS(out->io_ranges.ranges[i]);
     127                        s_size = RNGSZ(out->io_ranges.ranges[i]);
    79128                       
    80                         if ((address == s_address) && (size == s_size))
    81                                 return;
    82                 }
    83         }
    84        
    85         out->io_ranges.ranges[count].address = address;
     129                        if ((absolute == s_address) && (size == s_size))
     130                                return;
     131                }
     132        }
     133       
     134        RNGABS(out->io_ranges.ranges[count]) = absolute;
     135        RNGREL(out->io_ranges.ranges[count]) = relative;
     136        RNGSZ(out->io_ranges.ranges[count]) = size;
    86137        out->io_ranges.ranges[count].endianness = endianness;
    87         out->io_ranges.ranges[count].size = size;
    88138        out->io_ranges.count++;
    89139}
    90140
    91141static void hw_res_parse_add_mem_range(hw_res_list_parsed_t *out,
    92     hw_resource_t *res, int flags)
    93 {
     142    const pio_window_t *win, const hw_resource_t *res, int flags)
     143{
     144        endianness_t endianness;
     145        uint64_t absolute;
     146        uint64_t relative;
     147        size_t size;
     148       
    94149        assert(res && (res->type == MEM_RANGE));
    95150       
    96         uint64_t address = res->res.mem_range.address;
    97         endianness_t endianness = res->res.mem_range.endianness;
    98         size_t size = res->res.mem_range.size;
     151        absolute = absolutize(res->res.mem_range.address,
     152            res->res.mem_range.relative, win->mem.base);
     153        relative = relativize(res->res.mem_range.address,
     154            res->res.mem_range.relative, win->mem.base);
     155        size = res->res.mem_range.size;
     156        endianness = res->res.mem_range.endianness;
    99157       
    100158        if ((size == 0) && (!(flags & HW_RES_KEEP_ZERO_AREA)))
     
    106164        if (!keep_duplicit) {
    107165                for (size_t i = 0; i < count; ++i) {
    108                         uint64_t s_address = out->mem_ranges.ranges[i].address;
    109                         size_t s_size = out->mem_ranges.ranges[i].size;
     166                        uint64_t s_address;
     167                        size_t s_size;
     168
     169                        s_address = RNGABS(out->mem_ranges.ranges[i]);;
     170                        s_size = RNGSZ(out->mem_ranges.ranges[i]);
    110171                       
    111                         if ((address == s_address) && (size == s_size))
    112                                 return;
    113                 }
    114         }
    115        
    116         out->mem_ranges.ranges[count].address = address;
     172                        if ((absolute == s_address) && (size == s_size))
     173                                return;
     174                }
     175        }
     176       
     177        RNGABS(out->mem_ranges.ranges[count]) = absolute;
     178        RNGREL(out->mem_ranges.ranges[count]) = relative;
     179        RNGSZ(out->mem_ranges.ranges[count]) = size;
    117180        out->mem_ranges.ranges[count].endianness = endianness;
    118         out->mem_ranges.ranges[count].size = size;
    119181        out->mem_ranges.count++;
    120182}
     
    122184/** Parse list of hardware resources
    123185 *
    124  * @param      hw_resources Original structure resource
    125  * @param[out] out          Output parsed resources
    126  * @param      flags        Flags of the parsing.
    127  *                          HW_RES_KEEP_ZERO_AREA for keeping
    128  *                          zero-size areas, HW_RES_KEEP_DUPLICITIES
    129  *                          for keep duplicit areas
     186 * @param      win          PIO window.
     187 * @param      res          Original structure resource.
     188 * @param[out] out          Output parsed resources.
     189 * @param      flags        Flags of the parsing:
     190 *                          HW_RES_KEEP_ZERO_AREA for keeping zero-size areas,
     191 *                          HW_RES_KEEP_DUPLICITIES to keep duplicit areas.
    130192 *
    131193 * @return EOK if succeed, error code otherwise.
    132194 *
    133195 */
    134 int hw_res_list_parse(hw_resource_list_t *hw_resources,
    135     hw_res_list_parsed_t *out, int flags)
    136 {
    137         if ((!hw_resources) || (!out))
     196int hw_res_list_parse(const pio_window_t *win,
     197    const hw_resource_list_t *res, hw_res_list_parsed_t *out, int flags)
     198{
     199        if (!res || !out)
    138200                return EINVAL;
    139201       
    140         size_t res_count = hw_resources->count;
     202        size_t res_count = res->count;
    141203        hw_res_list_parsed_clean(out);
    142204       
    143         out->irqs.irqs = malloc(res_count * sizeof(int));
    144         out->io_ranges.ranges = malloc(res_count * sizeof(io_range_t));
    145         out->mem_ranges.ranges = malloc(res_count * sizeof(mem_range_t));
     205        out->irqs.irqs = calloc(res_count, sizeof(int));
     206        out->dma_channels.channels = calloc(res_count, sizeof(int));
     207        out->io_ranges.ranges = calloc(res_count, sizeof(io_range_t));
     208        out->mem_ranges.ranges = calloc(res_count, sizeof(mem_range_t));
     209        if (!out->irqs.irqs || !out->dma_channels.channels ||
     210            !out->io_ranges.ranges || !out->mem_ranges.ranges) {
     211                hw_res_list_parsed_clean(out);
     212                return ENOMEM;
     213        }
    146214       
    147215        for (size_t i = 0; i < res_count; ++i) {
    148                 hw_resource_t *resource = &(hw_resources->resources[i]);
     216                const hw_resource_t *resource = &res->resources[i];
    149217               
    150218                switch (resource->type) {
     
    153221                        break;
    154222                case IO_RANGE:
    155                         hw_res_parse_add_io_range(out, resource, flags);
     223                        hw_res_parse_add_io_range(out, win, resource, flags);
    156224                        break;
    157225                case MEM_RANGE:
    158                         hw_res_parse_add_mem_range(out, resource, flags);
     226                        hw_res_parse_add_mem_range(out, win, resource, flags);
     227                        break;
     228                case DMA_CHANNEL_8:
     229                case DMA_CHANNEL_16:
     230                        hw_res_parse_add_dma_channel(out, resource, flags);
    159231                        break;
    160232                default:
     233                        hw_res_list_parsed_clean(out);
    161234                        return EINVAL;
    162235                }
     
    183256    hw_res_list_parsed_t *hw_res_parsed, int flags)
    184257{
     258        pio_window_t pio_window;
     259        int rc;
     260
    185261        if (!hw_res_parsed)
    186262                return EBADMEM;
     
    188264        hw_resource_list_t hw_resources;
    189265        hw_res_list_parsed_clean(hw_res_parsed);
    190         bzero(&hw_resources, sizeof(hw_resource_list_t));
    191        
    192         int rc = hw_res_get_resource_list(sess, &hw_resources);
     266        memset(&hw_resources, 0, sizeof(hw_resource_list_t));
     267
     268        rc = pio_window_get(sess, &pio_window);
     269        if (rc != EOK)
     270                return rc;
     271       
     272        rc = hw_res_get_resource_list(sess, &hw_resources);
    193273        if (rc != EOK)
    194274                return rc;
    195        
    196         rc = hw_res_list_parse(&hw_resources, hw_res_parsed, flags);
     275
     276        rc = hw_res_list_parse(&pio_window, &hw_resources, hw_res_parsed,
     277            flags);
    197278        hw_res_clean_resource_list(&hw_resources);
    198279       
Note: See TracChangeset for help on using the changeset viewer.