property.c 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. #include <sys/time.h>
  2. #include <arpa/inet.h>
  3. #include <assert.h>
  4. #include "pci.h"
  5. #include "tools.h"
  6. #include "model.h"
  7. #include "error.h"
  8. int pcilib_property_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *regval) {
  9. int err;
  10. const pcilib_register_bank_description_t *b = bank_ctx->bank;
  11. int access = b->access / 8;
  12. pcilib_view_t view = addr / access;
  13. pcilib_value_t val = {0};
  14. if (addr % access) {
  15. pcilib_error("Can't perform unaligned access to property register (the address is 0x%lx and alligment requirement is %u)", addr, access);
  16. return PCILIB_ERROR_INVALID_ARGUMENT;
  17. }
  18. if ((view == PCILIB_VIEW_INVALID)||(view >= ctx->num_views))
  19. return PCILIB_ERROR_INVALID_ARGUMENT;
  20. if ((ctx->views[view]->flags&PCILIB_VIEW_FLAG_REGISTER) == 0) {
  21. pcilib_error("Accessing invalid register %u (associated view %u does not provide register functionality)", addr, view);
  22. return PCILIB_ERROR_INVALID_REQUEST;
  23. }
  24. if ((ctx->views[view]->mode&PCILIB_ACCESS_R) == 0) {
  25. pcilib_error("Read access is not allowed to register %u (view %u)", addr, view);
  26. return PCILIB_ERROR_NOTPERMITED;
  27. }
  28. err = pcilib_get_property(ctx, ctx->views[view]->name, &val);
  29. if (err) return err;
  30. *regval = pcilib_get_value_as_register_value(ctx, &val, &err);
  31. return err;
  32. }
  33. int pcilib_property_registers_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t regval) {
  34. int err;
  35. const pcilib_register_bank_description_t *b = bank_ctx->bank;
  36. int access = b->access / 8;
  37. pcilib_view_t view = addr / access;
  38. pcilib_value_t val = {0};
  39. if (addr % access) {
  40. pcilib_error("Can't perform unaligned access to property register (the address is 0x%lx and alligment requirement is %u)", addr, access);
  41. return PCILIB_ERROR_INVALID_ARGUMENT;
  42. }
  43. if ((view == PCILIB_VIEW_INVALID)||(view >= ctx->num_views))
  44. return PCILIB_ERROR_INVALID_ARGUMENT;
  45. if ((ctx->views[view]->flags&PCILIB_VIEW_FLAG_REGISTER) == 0) {
  46. pcilib_error("Accessing invalid register %u (associated view %u does not provide register functionality)", addr, view);
  47. return PCILIB_ERROR_INVALID_REQUEST;
  48. }
  49. if ((ctx->views[view]->mode&PCILIB_ACCESS_W) == 0) {
  50. pcilib_error("Write access is not allowed to register %u (view %u)", addr, view);
  51. return PCILIB_ERROR_NOTPERMITED;
  52. }
  53. err = pcilib_set_value_from_register_value(ctx, &val, regval);
  54. if (err) return err;
  55. return pcilib_set_property(ctx, ctx->views[view]->name, &val);
  56. }