diff options
-rw-r--r-- | riscv/devices.h | 9 | ||||
-rw-r--r-- | riscv/ns16550.cc | 8 | ||||
-rw-r--r-- | riscv/plic.cc | 128 |
3 files changed, 61 insertions, 84 deletions
diff --git a/riscv/devices.h b/riscv/devices.h index bccda34..0030da8 100644 --- a/riscv/devices.h +++ b/riscv/devices.h @@ -78,7 +78,7 @@ class clint_t : public abstract_device_t { #define PLIC_MAX_DEVICES 1024 -struct plic_context { +struct plic_context_t { uint32_t num; processor_t *proc; bool mmode; @@ -89,7 +89,6 @@ struct plic_context { uint8_t pending_priority[PLIC_MAX_DEVICES]; uint32_t claimed[PLIC_MAX_DEVICES/32]; }; -typedef struct plic_context plic_context_t; class plic_t : public abstract_device_t, public abstract_interrupt_controller_t { public: @@ -106,12 +105,12 @@ class plic_t : public abstract_device_t, public abstract_interrupt_controller_t uint32_t max_prio; uint8_t priority[PLIC_MAX_DEVICES]; uint32_t level[PLIC_MAX_DEVICES/32]; - uint32_t context_best_pending(plic_context_t *c); - void context_update(plic_context_t *context); + uint32_t context_best_pending(const plic_context_t *c); + void context_update(const plic_context_t *context); uint32_t context_claim(plic_context_t *c); bool priority_read(reg_t offset, uint32_t *val); bool priority_write(reg_t offset, uint32_t val); - bool context_enable_read(plic_context_t *context, + bool context_enable_read(const plic_context_t *context, reg_t offset, uint32_t *val); bool context_enable_write(plic_context_t *context, reg_t offset, uint32_t val); diff --git a/riscv/ns16550.cc b/riscv/ns16550.cc index 37af568..7bc1d20 100644 --- a/riscv/ns16550.cc +++ b/riscv/ns16550.cc @@ -133,8 +133,6 @@ void ns16550_t::update_interrupt(void) uint8_t ns16550_t::rx_byte(void) { - uint8_t ret = 0; - if (rx_queue.empty()) { lsr &= ~UART_LSR_DR; return 0; @@ -146,7 +144,7 @@ uint8_t ns16550_t::rx_byte(void) return 0; } - ret = rx_queue.front(); + uint8_t ret = rx_queue.front(); rx_queue.pop(); if (rx_queue.empty()) { lsr &= ~UART_LSR_DR; @@ -296,15 +294,13 @@ bool ns16550_t::store(reg_t addr, size_t len, const uint8_t* bytes) void ns16550_t::tick(void) { - int rc; - if (!(fcr & UART_FCR_ENABLE_FIFO) || (mcr & UART_MCR_LOOP) || (UART_QUEUE_SIZE <= rx_queue.size())) { return; } - rc = canonical_terminal_t::read(); + int rc = canonical_terminal_t::read(); if (rc < 0) { return; } diff --git a/riscv/plic.cc b/riscv/plic.cc index 2d08c8e..0cdcebb 100644 --- a/riscv/plic.cc +++ b/riscv/plic.cc @@ -69,9 +69,7 @@ plic_t::plic_t(std::vector<processor_t*>& procs, bool smode, uint32_t ndev) : procs(procs), contexts(procs.size() * (smode ? 2 : 1)) { - size_t i; size_t contexts_per_hart = smode ? 2 : 1; - plic_context_t *c; num_ids = ndev + 1; num_ids_word = num_ids / 32; @@ -81,8 +79,8 @@ plic_t::plic_t(std::vector<processor_t*>& procs, bool smode, uint32_t ndev) memset(priority, 0, sizeof(priority)); memset(level, 0, sizeof(level)); - for (i = 0; i < contexts.size(); i++) { - c = &contexts[i]; + for (size_t i = 0; i < contexts.size(); i++) { + plic_context_t* c = &contexts[i]; c->num = i; c->proc = procs[i / contexts_per_hart]; if (smode) { @@ -97,18 +95,18 @@ plic_t::plic_t(std::vector<processor_t*>& procs, bool smode, uint32_t ndev) } } -uint32_t plic_t::context_best_pending(plic_context_t *c) +uint32_t plic_t::context_best_pending(const plic_context_t *c) { uint8_t best_id_prio = 0; - uint32_t i, j, id, best_id = 0; + uint32_t best_id = 0; - for (i = 0; i < num_ids_word; i++) { + for (uint32_t i = 0; i < num_ids_word; i++) { if (!c->pending[i]) { continue; } - for (j = 0; j < 32; j++) { - id = i * 32 + j; + for (uint32_t j = 0; j < 32; j++) { + uint32_t id = i * 32 + j; if ((num_ids <= id) || !(c->pending[i] & (1 << j)) || (c->claimed[i] & (1 << j))) { @@ -126,7 +124,7 @@ uint32_t plic_t::context_best_pending(plic_context_t *c) return best_id; } -void plic_t::context_update(plic_context_t *c) +void plic_t::context_update(const plic_context_t *c) { uint32_t best_id = context_best_pending(c); reg_t mask = c->mmode ? MIP_MEIP : MIP_SEIP; @@ -173,7 +171,7 @@ bool plic_t::priority_write(reg_t offset, uint32_t val) return true; } -bool plic_t::context_enable_read(plic_context_t *c, +bool plic_t::context_enable_read(const plic_context_t *c, reg_t offset, uint32_t *val) { uint32_t id_word = offset >> 2; @@ -189,29 +187,22 @@ bool plic_t::context_enable_read(plic_context_t *c, bool plic_t::context_enable_write(plic_context_t *c, reg_t offset, uint32_t val) { - uint8_t id_prio; - uint32_t i, id, id_mask; uint32_t id_word = offset >> 2; - uint32_t old_val, new_val, xor_val; if (num_ids_word < id_word) { return false; } - old_val = c->enable[id_word]; - new_val = val; - - if (id_word == 0) { - new_val &= ~0x1; - } + uint32_t old_val = c->enable[id_word]; + uint32_t new_val = id_word == 0 ? val & ~(uint32_t)1 : val; + uint32_t xor_val = old_val ^ new_val; c->enable[id_word] = new_val; - xor_val = old_val ^ new_val; - for (i = 0; i < 32; i++) { - id = id_word * 32 + i; - id_mask = 1 << i; - id_prio = priority[id]; + for (uint32_t i = 0; i < 32; i++) { + uint32_t id = id_word * 32 + i; + uint32_t id_mask = 1 << i; + uint8_t id_prio = priority[id]; if (!(xor_val & id_mask)) { continue; } @@ -233,50 +224,45 @@ bool plic_t::context_enable_write(plic_context_t *c, bool plic_t::context_read(plic_context_t *c, reg_t offset, uint32_t *val) { - bool ret = true; - switch (offset) { - case CONTEXT_THRESHOLD: - *val = c->priority_threshold; - break; - case CONTEXT_CLAIM: - *val = context_claim(c); - break; - default: - ret = false; - break; + case CONTEXT_THRESHOLD: + *val = c->priority_threshold; + return true; + case CONTEXT_CLAIM: + *val = context_claim(c); + return true; + default: + return false; }; - - return ret; } bool plic_t::context_write(plic_context_t *c, reg_t offset, uint32_t val) { - uint32_t id_word, id_mask; bool ret = true, update = false; switch (offset) { - case CONTEXT_THRESHOLD: - val &= ((1 << PLIC_PRIO_BITS) - 1); - if (val <= max_prio) - c->priority_threshold = val; - else - update = true; - break; - case CONTEXT_CLAIM: - id_word = val / 32; - id_mask = 1 << (val % 32); - if ((val < num_ids) && - (c->enable[id_word] & id_mask)) { - c->claimed[id_word] &= ~id_mask; - update = true; + case CONTEXT_THRESHOLD: + val &= ((1 << PLIC_PRIO_BITS) - 1); + if (val <= max_prio) + c->priority_threshold = val; + else + update = true; + break; + case CONTEXT_CLAIM: { + uint32_t id_word = val / 32; + uint32_t id_mask = 1 << (val % 32); + if ((val < num_ids) && + (c->enable[id_word] & id_mask)) { + c->claimed[id_word] &= ~id_mask; + update = true; + } + break; } - break; - default: - ret = false; - update = true; - break; + default: + ret = false; + update = true; + break; }; if (update) { @@ -288,17 +274,13 @@ bool plic_t::context_write(plic_context_t *c, void plic_t::set_interrupt_level(uint32_t id, int lvl) { - uint8_t i, id_prio, id_word; - uint32_t id_mask; - plic_context_t *c = NULL; - if (id <= 0 || num_ids <= id) { return; } - id_prio = priority[id]; - id_word = id / 32; - id_mask = 1 << (id % 32); + uint8_t id_prio = priority[id]; + uint32_t id_word = id / 32; + uint32_t id_mask = 1 << (id % 32); if (lvl) { level[id_word] |= id_mask; @@ -312,8 +294,8 @@ void plic_t::set_interrupt_level(uint32_t id, int lvl) * handle this we auto-clear edge-triggered interrupts * when PLIC context CLAIM register is read. */ - for (i = 0; i < contexts.size(); i++) { - c = &contexts[i]; + for (size_t i = 0; i < contexts.size(); i++) { + plic_context_t* c = &contexts[i]; if (c->enable[id_word] & id_mask) { if (lvl) { @@ -333,7 +315,7 @@ void plic_t::set_interrupt_level(uint32_t id, int lvl) bool plic_t::load(reg_t addr, size_t len, uint8_t* bytes) { bool ret = false; - uint32_t cntx, val = 0; + uint32_t val = 0; /* Only 32bit loads supported */ if (len != 4) { @@ -343,13 +325,13 @@ bool plic_t::load(reg_t addr, size_t len, uint8_t* bytes) if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { ret = priority_read(addr, &val); } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { - cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + uint32_t cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; if (cntx < contexts.size()) { ret = context_enable_read(&contexts[cntx], addr, &val); } } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { - cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + uint32_t cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; if (cntx < contexts.size()) { ret = context_read(&contexts[cntx], addr, &val); @@ -366,7 +348,7 @@ bool plic_t::load(reg_t addr, size_t len, uint8_t* bytes) bool plic_t::store(reg_t addr, size_t len, const uint8_t* bytes) { bool ret = false; - uint32_t cntx, val; + uint32_t val; /* Only 32bit stores supported */ if (len != 4) { @@ -378,12 +360,12 @@ bool plic_t::store(reg_t addr, size_t len, const uint8_t* bytes) if (PRIORITY_BASE <= addr && addr < ENABLE_BASE) { ret = priority_write(addr, val); } else if (ENABLE_BASE <= addr && addr < CONTEXT_BASE) { - cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; + uint32_t cntx = (addr - ENABLE_BASE) / ENABLE_PER_HART; addr -= cntx * ENABLE_PER_HART + ENABLE_BASE; if (cntx < contexts.size()) ret = context_enable_write(&contexts[cntx], addr, val); } else if (CONTEXT_BASE <= addr && addr < REG_SIZE) { - cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; + uint32_t cntx = (addr - CONTEXT_BASE) / CONTEXT_PER_HART; addr -= cntx * CONTEXT_PER_HART + CONTEXT_BASE; if (cntx < contexts.size()) ret = context_write(&contexts[cntx], addr, val); |