aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorLeon Alrae <leon.alrae@imgtec.com>2016-03-25 13:49:34 +0000
committerLeon Alrae <leon.alrae@imgtec.com>2016-03-30 09:14:00 +0100
commit25a611e3e4a560c034c942527c643dfc990c7491 (patch)
treecd36f52c064b2a255c218b17808d4aab41d58940 /hw
parent40dc9dc3394d2796341aeda6cd14bac46ce24735 (diff)
hw/mips: implement ITC Storage - Bypass View
Bypass View does not cause issuing thread to block and does not affect any of the cells state bit. Read from a FIFO cell returns the value of the oldest entry. Store to a FIFO cell changes the value of the newest entry. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
Diffstat (limited to 'hw')
-rw-r--r--hw/misc/mips_itu.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index 595d2d2fa7..8461d2379b 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -182,6 +182,27 @@ static void QEMU_NORETURN block_thread_and_exit(ITCStorageCell *c)
cpu_loop_exit(current_cpu);
}
+/* ITC Bypass View */
+
+static inline uint64_t view_bypass_read(ITCStorageCell *c)
+{
+ if (c->tag.FIFO) {
+ return c->data[c->fifo_out];
+ } else {
+ return c->data[0];
+ }
+}
+
+static inline void view_bypass_write(ITCStorageCell *c, uint64_t val)
+{
+ if (c->tag.FIFO && (c->tag.FIFOPtr > 0)) {
+ int idx = (c->fifo_out + c->tag.FIFOPtr - 1) % ITC_CELL_DEPTH;
+ c->data[idx] = val;
+ }
+
+ /* ignore a write to the semaphore cell */
+}
+
/* ITC Control View */
static inline uint64_t view_control_read(ITCStorageCell *c)
@@ -348,6 +369,9 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
uint64_t ret = -1;
switch (view) {
+ case ITCVIEW_BYPASS:
+ ret = view_bypass_read(cell);
+ break;
case ITCVIEW_CONTROL:
ret = view_control_read(cell);
break;
@@ -380,6 +404,9 @@ static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data,
ITCView view = get_itc_view(addr);
switch (view) {
+ case ITCVIEW_BYPASS:
+ view_bypass_write(cell, data);
+ break;
case ITCVIEW_CONTROL:
view_control_write(cell, data);
break;