ds1225y.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * QEMU NVRAM emulation for DS1225Y chip
  3. *
  4. * Copyright (c) 2007-2008 Hervé Poussineau
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. #include "hw.h"
  25. #include "mips.h"
  26. #include "nvram.h"
  27. //#define DEBUG_NVRAM
  28. typedef struct ds1225y_t
  29. {
  30. uint32_t chip_size;
  31. QEMUFile *file;
  32. uint8_t *contents;
  33. uint8_t protection;
  34. } ds1225y_t;
  35. static uint32_t nvram_readb (void *opaque, target_phys_addr_t addr)
  36. {
  37. ds1225y_t *s = opaque;
  38. uint32_t val;
  39. val = s->contents[addr];
  40. #ifdef DEBUG_NVRAM
  41. printf("nvram: read 0x%x at " TARGET_FMT_lx "\n", val, addr);
  42. #endif
  43. return val;
  44. }
  45. static uint32_t nvram_readw (void *opaque, target_phys_addr_t addr)
  46. {
  47. uint32_t v;
  48. v = nvram_readb(opaque, addr);
  49. v |= nvram_readb(opaque, addr + 1) << 8;
  50. return v;
  51. }
  52. static uint32_t nvram_readl (void *opaque, target_phys_addr_t addr)
  53. {
  54. uint32_t v;
  55. v = nvram_readb(opaque, addr);
  56. v |= nvram_readb(opaque, addr + 1) << 8;
  57. v |= nvram_readb(opaque, addr + 2) << 16;
  58. v |= nvram_readb(opaque, addr + 3) << 24;
  59. return v;
  60. }
  61. static void nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t val)
  62. {
  63. ds1225y_t *s = opaque;
  64. #ifdef DEBUG_NVRAM
  65. printf("nvram: write 0x%x at " TARGET_FMT_lx "\n", val, addr);
  66. #endif
  67. s->contents[addr] = val & 0xff;
  68. if (s->file) {
  69. qemu_fseek(s->file, addr, SEEK_SET);
  70. qemu_put_byte(s->file, (int)val);
  71. qemu_fflush(s->file);
  72. }
  73. }
  74. static void nvram_writew (void *opaque, target_phys_addr_t addr, uint32_t val)
  75. {
  76. nvram_writeb(opaque, addr, val & 0xff);
  77. nvram_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  78. }
  79. static void nvram_writel (void *opaque, target_phys_addr_t addr, uint32_t val)
  80. {
  81. nvram_writeb(opaque, addr, val & 0xff);
  82. nvram_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  83. nvram_writeb(opaque, addr + 2, (val >> 16) & 0xff);
  84. nvram_writeb(opaque, addr + 3, (val >> 24) & 0xff);
  85. }
  86. static void nvram_writeb_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
  87. {
  88. ds1225y_t *s = opaque;
  89. if (s->protection != 7) {
  90. #ifdef DEBUG_NVRAM
  91. printf("nvram: prevent write of 0x%x at " TARGET_FMT_lx "\n", val, addr);
  92. #endif
  93. return;
  94. }
  95. nvram_writeb(opaque, addr, val);
  96. }
  97. static void nvram_writew_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
  98. {
  99. nvram_writeb_protected(opaque, addr, val & 0xff);
  100. nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff);
  101. }
  102. static void nvram_writel_protected (void *opaque, target_phys_addr_t addr, uint32_t val)
  103. {
  104. nvram_writeb_protected(opaque, addr, val & 0xff);
  105. nvram_writeb_protected(opaque, addr + 1, (val >> 8) & 0xff);
  106. nvram_writeb_protected(opaque, addr + 2, (val >> 16) & 0xff);
  107. nvram_writeb_protected(opaque, addr + 3, (val >> 24) & 0xff);
  108. }
  109. static CPUReadMemoryFunc *nvram_read[] = {
  110. &nvram_readb,
  111. &nvram_readw,
  112. &nvram_readl,
  113. };
  114. static CPUWriteMemoryFunc *nvram_write[] = {
  115. &nvram_writeb,
  116. &nvram_writew,
  117. &nvram_writel,
  118. };
  119. static CPUWriteMemoryFunc *nvram_write_protected[] = {
  120. &nvram_writeb_protected,
  121. &nvram_writew_protected,
  122. &nvram_writel_protected,
  123. };
  124. /* Initialisation routine */
  125. void *ds1225y_init(target_phys_addr_t mem_base, const char *filename)
  126. {
  127. ds1225y_t *s;
  128. int mem_indexRW, mem_indexRP;
  129. QEMUFile *file;
  130. s = qemu_mallocz(sizeof(ds1225y_t));
  131. s->chip_size = 0x2000; /* Fixed for ds1225y chip: 8 KiB */
  132. s->contents = qemu_mallocz(s->chip_size);
  133. s->protection = 7;
  134. /* Read current file */
  135. file = qemu_fopen(filename, "rb");
  136. if (file) {
  137. /* Read nvram contents */
  138. qemu_get_buffer(file, s->contents, s->chip_size);
  139. qemu_fclose(file);
  140. }
  141. s->file = qemu_fopen(filename, "wb");
  142. if (s->file) {
  143. /* Write back contents, as 'wb' mode cleaned the file */
  144. qemu_put_buffer(s->file, s->contents, s->chip_size);
  145. qemu_fflush(s->file);
  146. }
  147. /* Read/write memory */
  148. mem_indexRW = cpu_register_io_memory(0, nvram_read, nvram_write, s);
  149. cpu_register_physical_memory(mem_base, s->chip_size, mem_indexRW);
  150. /* Read/write protected memory */
  151. mem_indexRP = cpu_register_io_memory(0, nvram_read, nvram_write_protected, s);
  152. cpu_register_physical_memory(mem_base + s->chip_size, s->chip_size, mem_indexRP);
  153. return s;
  154. }