initialise a memory structure or smth

Signed-off-by: Amneesh Singh <natto@weirdnatto.in>
This commit is contained in:
2023-09-11 10:23:46 +05:30
parent 84c68a4e00
commit 332f0b87d6
26 changed files with 763 additions and 163 deletions

View File

@@ -1,21 +1,3 @@
enum class ArmInstructionFormat {
DataProcessingAndFsrTransfer,
Multiply,
MultiplyLong,
SingleDataSwap,
BranchAndExchange,
HalfwordDataTransferRegisterOffset,
HalfwordDataTransferImmediateOffset,
SingleDataTransfer,
Undefined,
BlockDataTransfer,
Branch,
CoprocessorDataTransfer,
CoprocessorDataOperation,
CoprocessorRegisterTransfer,
SoftwareInterrupt
};
enum class Condition {
EQ = 0b0000,
NE = 0b0001,
@@ -53,7 +35,7 @@ enum class OpCode {
MVN = 0b1111
};
enum class Shift {
enum class ShiftType {
LSL = 0b00,
LSR = 0b01,
ASR = 0b10,

View File

@@ -3,6 +3,19 @@
#include <algorithm>
#include <cstdio>
Cpu::Cpu(Bus bus)
: gpr(0)
, cpsr(0)
, spsr(0)
, bus(bus)
, gpr_banked({ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } })
, spsr_banked({ 0, 0, 0, 0, 0 }) {
cpsr.set_mode(Mode::System);
cpsr.set_irq_disabled(true);
cpsr.set_fiq_disabled(true);
cpsr.set_state(State::Arm);
}
/* change modes */
void
Cpu::chg_mode(Mode from, Mode to) {
@@ -92,13 +105,13 @@ Cpu::chg_mode(Mode from, Mode to) {
// set register
inline uint32_t&
Cpu::operator[](size_t idx) {
Cpu::operator[](uint8_t idx) {
// avoid unneeded complexity like index checks
return gpr[idx];
}
// get register
inline const uint32_t&
Cpu::operator[](size_t idx) const {
Cpu::operator[](uint8_t idx) const {
return gpr[idx];
}

View File

@@ -7,71 +7,57 @@
using std::size_t;
static constexpr size_t GPR_VISIBLE_COUNT = 16;
static constexpr size_t GPR_FIQ_BANKED_FIRST = 8;
static constexpr size_t GPR_FIQ_BANKED_COUNT = 7;
static constexpr size_t GPR_SVC_BANKED_FIRST = 13;
static constexpr size_t GPR_SVC_BANKED_COUNT = 2;
static constexpr size_t GPR_ABT_BANKED_FIRST = 13;
static constexpr size_t GPR_ABT_BANKED_COUNT = 2;
static constexpr size_t GPR_IRQ_BANKED_FIRST = 13;
static constexpr size_t GPR_IRQ_BANKED_COUNT = 2;
static constexpr size_t GPR_UND_BANKED_FIRST = 13;
static constexpr size_t GPR_UND_BANKED_COUNT = 2;
static constexpr size_t GPR_SYS_USR_BANKED_FIRST = 8;
static constexpr size_t GPR_SYS_USR_BANKED_COUNT = 7;
struct _GprBanked {
uint32_t fiq[GPR_FIQ_BANKED_COUNT];
uint32_t svc[GPR_SVC_BANKED_COUNT];
uint32_t abt[GPR_ABT_BANKED_COUNT];
uint32_t irq[GPR_IRQ_BANKED_COUNT];
uint32_t und[GPR_UND_BANKED_COUNT];
/* visible registers before the mode switch */
uint32_t old[GPR_SYS_USR_BANKED_COUNT];
};
typedef struct _GprBanked GprBanked;
struct _SpsrBanked {
Psr fiq;
Psr svc;
Psr abt;
Psr irq;
Psr und;
};
typedef struct _SpsrBanked SpsrBanked;
class Cpu {
public:
Cpu(Bus bus);
private:
static constexpr size_t GPR_FIQ_BANKED_FIRST = 8;
static constexpr size_t GPR_FIQ_BANKED_COUNT = 7;
static constexpr size_t GPR_SVC_BANKED_FIRST = 13;
static constexpr size_t GPR_SVC_BANKED_COUNT = 2;
static constexpr size_t GPR_ABT_BANKED_FIRST = 13;
static constexpr size_t GPR_ABT_BANKED_COUNT = 2;
static constexpr size_t GPR_IRQ_BANKED_FIRST = 13;
static constexpr size_t GPR_IRQ_BANKED_COUNT = 2;
static constexpr size_t GPR_UND_BANKED_FIRST = 13;
static constexpr size_t GPR_UND_BANKED_COUNT = 2;
static constexpr size_t GPR_SYS_USR_BANKED_FIRST = 8;
static constexpr size_t GPR_SYS_USR_BANKED_COUNT = 7;
static constexpr size_t GPR_VISIBLE_COUNT = 16;
uint32_t gpr[GPR_VISIBLE_COUNT]; // general purpose registers
GprBanked gpr_banked; // banked general purpose registers
SpsrBanked spsr_banked; // banked saved program status registers
Psr cpsr; // current program status register
Psr spsr; // status program status register
Bus bus;
struct {
uint32_t fiq[GPR_FIQ_BANKED_COUNT];
uint32_t svc[GPR_SVC_BANKED_COUNT];
uint32_t abt[GPR_ABT_BANKED_COUNT];
uint32_t irq[GPR_IRQ_BANKED_COUNT];
uint32_t und[GPR_UND_BANKED_COUNT];
// visible registers before the mode switch
uint32_t old[GPR_SYS_USR_BANKED_COUNT];
} gpr_banked; // banked general purpose registers
struct {
Psr fiq;
Psr svc;
Psr abt;
Psr irq;
Psr und;
} spsr_banked; // banked saved program status registers
void chg_mode(Mode from, Mode to);
uint32_t& operator[](size_t idx);
const uint32_t& operator[](size_t idx) const;
public:
Cpu(Bus bus)
: gpr(0)
, gpr_banked({ { 0 }, { 0 }, { 0 }, { 0 }, { 0 }, { 0 } })
, spsr_banked({ 0, 0, 0, 0, 0 })
, cpsr(0)
, spsr(0)
, bus(bus) {
cpsr.set_mode(Mode::System);
cpsr.set_irq_disabled(true);
cpsr.set_fiq_disabled(true);
cpsr.set_state(State::Arm);
}
uint32_t& operator[](uint8_t idx);
const uint32_t& operator[](uint8_t idx) const;
};

View File

@@ -1,5 +1,6 @@
lib_sources += files(
'cpu.cc'
'cpu.cc',
'psr.cc'
)
subdir('arm')

49
src/cpu/psr.cc Normal file
View File

@@ -0,0 +1,49 @@
#include "psr.hh"
#include "util/bits.hh"
Psr::Psr(uint32_t raw) {
psr = raw & PSR_CLEAR_RESERVED;
}
Mode
Psr::mode() const {
return static_cast<Mode>(psr & ~PSR_CLEAR_MODE);
}
void
Psr::set_mode(Mode mode) {
psr &= PSR_CLEAR_MODE;
psr |= static_cast<uint32_t>(mode);
}
bool
Psr::state() const {
return get_nth_bit(psr, 5);
}
void
Psr::set_state(State state) {
chg_nth_bit(psr, 5, static_cast<bool>(state));
}
#define GET_SET_NTH_BIT_FUNCTIONS(name, n) \
bool Psr::name() const { \
return get_nth_bit(psr, n); \
} \
void Psr::set_##name(bool val) { \
chg_nth_bit(psr, n, val); \
}
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled, 6)
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled, 7)
GET_SET_NTH_BIT_FUNCTIONS(v, 28);
GET_SET_NTH_BIT_FUNCTIONS(c, 29);
GET_SET_NTH_BIT_FUNCTIONS(z, 30);
GET_SET_NTH_BIT_FUNCTIONS(n, 31);
#undef GET_SET_NTH_BIT_FUNCTIONS

View File

@@ -1,55 +1,51 @@
#pragma once
#include "bits.hh"
#include "util/bits.hh"
#include "utility.hh"
#include <cstdint>
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xf00000ff;
static constexpr uint32_t PSR_CLEAR_MODE = 0x0b00000;
class Psr {
uint32_t psr;
public:
// clear the reserved bits i.e, [8:27]
Psr(uint32_t raw) { psr = raw & PSR_CLEAR_RESERVED; }
Psr(uint32_t raw);
// Mode : [4:0]
Mode mode() const { return static_cast<Mode>(psr & ~PSR_CLEAR_MODE); }
void set_mode(Mode mode) {
psr &= PSR_CLEAR_MODE;
psr |= static_cast<uint32_t>(mode);
}
Mode mode() const;
void set_mode(Mode mode);
// State : [5]
bool state() const { return get_nth_bit(psr, 5); }
void set_state(State state) {
chg_nth_bit(psr, 5, static_cast<bool>(state));
}
bool state() const;
void set_state(State state);
#define GET_SET_NTH_BIT_FUNCTIONS(name, n) \
bool name() const { return get_nth_bit(psr, n); } \
void set_##name(bool val) { chg_nth_bit(psr, n, val); }
#define GET_SET_NTH_BIT_FUNCTIONS(name) \
bool name() const; \
void set_##name(bool val);
// FIQ disable : [6]
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled, 6)
GET_SET_NTH_BIT_FUNCTIONS(fiq_disabled)
// IRQ disable : [7]
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled, 7)
GET_SET_NTH_BIT_FUNCTIONS(irq_disabled)
// Reserved bits : [27:8]
// Overflow flag : [28]
GET_SET_NTH_BIT_FUNCTIONS(v, 28);
GET_SET_NTH_BIT_FUNCTIONS(v)
// Carry flag : [29]
GET_SET_NTH_BIT_FUNCTIONS(c, 29);
GET_SET_NTH_BIT_FUNCTIONS(c)
// Zero flag : [30]
GET_SET_NTH_BIT_FUNCTIONS(z, 30);
GET_SET_NTH_BIT_FUNCTIONS(z)
// Negative flag : [30]
GET_SET_NTH_BIT_FUNCTIONS(n, 31);
GET_SET_NTH_BIT_FUNCTIONS(n)
#undef GET_SET_NTH_BIT_FUNCTIONS
private:
static constexpr uint32_t PSR_CLEAR_RESERVED = 0xf00000ff;
static constexpr uint32_t PSR_CLEAR_MODE = 0x0b00000;
uint32_t psr;
};