diff options
author | Leon Alrae <leon.alrae@imgtec.com> | 2016-03-25 13:49:34 +0000 |
---|---|---|
committer | Leon Alrae <leon.alrae@imgtec.com> | 2016-03-30 09:14:00 +0100 |
commit | 25a611e3e4a560c034c942527c643dfc990c7491 (patch) | |
tree | cd36f52c064b2a255c218b17808d4aab41d58940 /hw | |
parent | 40dc9dc3394d2796341aeda6cd14bac46ce24735 (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.c | 27 |
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; |