Changeset 48197c1 in mainline


Ignore:
Timestamp:
2017-06-15T19:04:29Z (7 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ce6e001
Parents:
5cbccd4
Message:

xhci: completed register access macros (+tests)

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • boot/Makefile.common

    r5cbccd4 r48197c1  
    235235        $(USPACE_PATH)/lib/posix/test-libposix \
    236236        $(USPACE_PATH)/lib/uri/test-liburi \
     237        $(USPACE_PATH)/drv/bus/usb/xhci/test-xhci \
    237238        $(USPACE_PATH)/app/bdsh/test-bdsh
    238239
  • uspace/drv/bus/usb/xhci/Makefile

    r5cbccd4 r48197c1  
    4747        main.c
    4848
     49TEST_SOURCES = \
     50        test/reg-ops.c
     51
    4952include $(USPACE_PREFIX)/Makefile.common
  • uspace/drv/bus/usb/xhci/hw_struct/regs.h

    r5cbccd4 r48197c1  
    4545 * provide flexible interface abstracting from the real storage of given
    4646 * register, but to avoid having to specify several constants per register.
    47  *
    48  * The key thing here is the order of macro expansion, expanding one argument
    49  * as more arguments (comma delimited) for another macro.
    50  */
     47 */
     48
     49#define XHCI_PIO_CHANGE_UDELAY 5
    5150
    5251#define host2xhci(size, val) host2uint##size##_t_le((val))
    5352#define xhci2host(size, val) uint##size##_t_le2host((val))
    5453
    55 #define XHCI_REG_RD_FIELD(ptr, size) \
    56         xhci2host(size, pio_read_##size((ptr)))
    57 
    58 #define XHCI_REG_RD_RANGE(ptr, size, hi, lo) \
    59         BIT_RANGE_EXTRACT(uint##size##_t, hi, lo, XHCI_REG_RD_FIELD((ptr), size))
    60 
    61 #define XHCI_REG_RD_FLAG(ptr, size, offset) \
    62         XHCI_REG_RD_RANGE((ptr), size, offset, offset)
    63 
     54/*
     55 * These four are the main macros to be used.
     56 * Semantics is usual - READ reads value, WRITE changes value, SET sets
     57 * selected bits, CLEAR clears selected bits to 0.
     58 *
     59 * The key thing here is the order of macro expansion, expanding the reg_spec
     60 * argument as more arguments (comma delimited) for the inner macro.
     61 */
     62#define XHCI_REG_RD(reg_set, reg_spec)         XHCI_REG_RD_INNER(reg_set, reg_spec)
     63#define XHCI_REG_WR(reg_set, reg_spec, value)  XHCI_REG_WR_INNER(reg_set, value, reg_spec)
     64#define XHCI_REG_SET(reg_set, reg_spec, value) XHCI_REG_SET_INNER(reg_set, value, reg_spec)
     65#define XHCI_REG_CLR(reg_set, reg_spec, value) XHCI_REG_CLR_INNER(reg_set, value, reg_spec)
     66
     67/*
     68 * These take a pointer to the field, and selects the type-specific macro.
     69 */
    6470#define XHCI_REG_RD_INNER(reg_set, field, size, type, ...) \
    6571        XHCI_REG_RD_##type(&((reg_set)->field), size, ##__VA_ARGS__)
    6672
    67 #define XHCI_REG_RD(reg_set, reg_spec) XHCI_REG_RD_INNER(reg_set, reg_spec)
    68 
    69 #define XHCI_REG_SET_FIELD(ptr, value, size) \
    70         pio_write_##size((ptr), host2xhci(size, value))
    71 
    72 #define XHCI_REG_SET_RANGE(ptr, value, size, hi, lo) \
    73         pio_change_##size((ptr), host2xhci(size, (value) << (lo)), host2xhci(size, BIT_RANGE(uint##size##_t, hi, lo)), 5);
    74 
    75 #define XHCI_REG_SET_FLAG(ptr, value, size, offset) \
    76         XHCI_REG_SET_RANGE(ptr, value, size, offset, offset)
     73#define XHCI_REG_WR_INNER(reg_set, value, field, size, type, ...) \
     74        XHCI_REG_WR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
    7775
    7876#define XHCI_REG_SET_INNER(reg_set, value, field, size, type, ...) \
    7977        XHCI_REG_SET_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
    8078
    81 #define XHCI_REG_SET(reg_set, reg_spec) XHCI_REG_SET_INNER(reg_set, value, reg_spec)
     79#define XHCI_REG_CLR_INNER(reg_set, value, field, size, type, ...) \
     80        XHCI_REG_CLR_##type(&(reg_set)->field, value, size, ##__VA_ARGS__)
     81
     82/*
     83 * Field handling is the easiest. Just do it with whole field.
     84 */
     85#define XHCI_REG_RD_FIELD(ptr, size)         xhci2host(size, pio_read_##size((ptr)))
     86#define XHCI_REG_WR_FIELD(ptr, value, size)  pio_write_##size((ptr), host2xhci(size, value))
     87#define XHCI_REG_SET_FIELD(ptr, value, size) pio_set_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
     88#define XHCI_REG_CLR_FIELD(ptr, value, size) pio_clear_##size((ptr), host2xhci(size, value), XHCI_PIO_CHANGE_UDELAY);
     89
     90/*
     91 * Flags are just trivial case of ranges.
     92 */
     93#define XHCI_REG_RD_FLAG(ptr, size, offset)         XHCI_REG_RD_RANGE((ptr), size, (offset), (offset))
     94#define XHCI_REG_WR_FLAG(ptr, value, size, offset)  XHCI_REG_WR_RANGE((ptr), (value), size, (offset), (offset))
     95#define XHCI_REG_SET_FLAG(ptr, value, size, offset) XHCI_REG_SET_RANGE((ptr), (value), size, (offset), (offset))
     96#define XHCI_REG_CLR_FLAG(ptr, value, size, offset) XHCI_REG_CLR_RANGE((ptr), (value), size, (offset), (offset))
     97
     98/*
     99 * Ranges are the most difficult. We need to play around with bitmasks.
     100 */
     101#define XHCI_REG_RD_RANGE(ptr, size, hi, lo) \
     102        BIT_RANGE_EXTRACT(uint##size##_t, (hi), (lo), XHCI_REG_RD_FIELD((ptr), size))
     103
     104#define XHCI_REG_WR_RANGE(ptr, value, size, hi, lo) \
     105        pio_change_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, (hi), (lo), (value))), \
     106                host2xhci(size, BIT_RANGE(uint##size##_t, (hi), (lo))), \
     107                XHCI_PIO_CHANGE_UDELAY);
     108
     109#define XHCI_REG_SET_RANGE(ptr, value, size, hi, lo) \
     110        pio_set_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, (hi), (lo), (value))), \
     111                XHCI_PIO_CHANGE_UDELAY);
     112
     113#define XHCI_REG_CLR_RANGE(ptr, value, size, hi, lo) \
     114        pio_clear_##size((ptr), host2xhci(size, BIT_RANGE_INSERT(uint##size##_t, (hi), (lo), (value))), \
     115                XHCI_PIO_CHANGE_UDELAY);
    82116
    83117/*
  • uspace/lib/c/include/bitops.h

    r5cbccd4 r48197c1  
    5454#define BIT_RANGE_EXTRACT(type, hi, lo, value) \
    5555    (((value) >> (lo)) & BIT_RRANGE(type, (hi) - (lo) + 1))
     56
     57/** Insert @a value between bits @a hi .. @a lo. */
     58#define BIT_RANGE_INSERT(type, hi, lo, value) \
     59    (((value) & BIT_RRANGE(type, (hi) - (lo) + 1)) << (lo))
    5660
    5761/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
Note: See TracChangeset for help on using the changeset viewer.