3B2: Remove unused code, move static declarations

This change cleans up warnings issued when compiled with
-Wall.

- Removed unused functions and variables.
- Moved static declarations out of headers and into source files
- Added braces around initialization where suggested.
This commit is contained in:
Seth Morabito 2018-08-19 11:57:28 -07:00
parent 5ae2e4c49d
commit 71ee25be1a
17 changed files with 319 additions and 387 deletions

View file

@ -33,6 +33,43 @@
#define MAX_SUB_RETURN_SKIP 9
/* Static function declarations */
static uint32 cpu_effective_address(operand * op);
static uint32 cpu_read_op(operand * op);
static void cpu_write_op(operand * op, t_uint64 val);
static void cpu_set_nz_flags(t_uint64 data, operand * op);
static void cpu_calc_ints();
static SIM_INLINE void cpu_on_normal_exception(uint8 isc);
static SIM_INLINE void cpu_on_stack_exception(uint8 isc);
static SIM_INLINE void cpu_on_process_exception(uint8 isc);
static SIM_INLINE void cpu_on_reset_exception(uint8 isc);
static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2);
static SIM_INLINE void clear_instruction(instr *inst);
static SIM_INLINE int8 op_type(operand *op);
static SIM_INLINE t_bool op_signed(operand *op);
static SIM_INLINE uint32 sign_extend_b(uint8 val);
static SIM_INLINE uint32 sign_extend_h(uint16 val);
static SIM_INLINE t_bool cpu_z_flag();
static SIM_INLINE t_bool cpu_n_flag();
static SIM_INLINE t_bool cpu_c_flag();
static SIM_INLINE t_bool cpu_v_flag();
static SIM_INLINE void cpu_set_z_flag(t_bool val);
static SIM_INLINE void cpu_set_n_flag(t_bool val);
static SIM_INLINE void cpu_set_c_flag(t_bool val);
static SIM_INLINE void cpu_set_v_flag(t_bool val);
static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op);
static SIM_INLINE uint8 cpu_execution_level();
static SIM_INLINE void cpu_push_word(uint32 val);
static SIM_INLINE uint32 cpu_pop_word();
static SIM_INLINE void irq_push_word(uint32 val);
static SIM_INLINE uint32 irq_pop_word();
static SIM_INLINE void cpu_context_switch_1(uint32 pcbp);
static SIM_INLINE void cpu_context_switch_2(uint32 pcbp);
static SIM_INLINE void cpu_context_switch_3(uint32 pcbp);
static SIM_INLINE t_bool op_is_psw(operand *op);
static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst);
static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst);
/* RO memory. */
uint32 *ROM = NULL;
@ -3436,43 +3473,6 @@ static SIM_INLINE t_bool op_signed(operand *op) {
return (op_type(op) == WD || op_type(op) == HW || op_type(op) == SB);
}
static SIM_INLINE t_bool is_byte_immediate(operand * oper)
{
return oper->mode == 6 && oper->reg == 15;
}
static SIM_INLINE t_bool is_halfword_immediate(operand * oper)
{
return oper->mode == 5 && oper->reg == 15;
}
static SIM_INLINE t_bool is_word_immediate(operand * oper)
{
return oper->mode == 4 && oper->reg == 15;
}
static SIM_INLINE t_bool is_positive_literal(operand * oper)
{
return (oper->mode == 0 ||
oper->mode == 1 ||
oper->mode == 2);
}
static SIM_INLINE t_bool is_negative_literal(operand * oper)
{
return oper->mode == 15;
}
/* Returns true if the operand may not be used as a destination */
static SIM_INLINE t_bool invalid_destination(operand * oper)
{
return (is_byte_immediate(oper) ||
is_halfword_immediate(oper) ||
is_word_immediate(oper) ||
is_positive_literal(oper) ||
is_negative_literal(oper));
}
static SIM_INLINE uint32 sign_extend_b(uint8 val)
{
if (val & 0x80)
@ -3480,11 +3480,6 @@ static SIM_INLINE uint32 sign_extend_b(uint8 val)
return (uint32) val;
}
static SIM_INLINE uint32 zero_extend_b(uint8 val)
{
return (uint32) val & BYTE_MASK;
}
static SIM_INLINE uint32 sign_extend_h(uint16 val)
{
if (val & 0x8000)
@ -3492,11 +3487,6 @@ static SIM_INLINE uint32 sign_extend_h(uint16 val)
return (uint32) val;
}
static SIM_INLINE uint32 zero_extend_h(uint16 val)
{
return (uint32) val & HALF_MASK;
}
/*
* Returns the current CPU execution level.
*/
@ -3639,11 +3629,6 @@ static SIM_INLINE t_bool op_is_psw(operand *op)
return (op->mode == 4 && op->reg == NUM_PSW);
}
static SIM_INLINE t_bool op_is_sp(operand *op)
{
return op->reg == NUM_SP;
}
static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst)
{
t_uint64 result;

View file

@ -414,58 +414,6 @@ instr *cpu_next_instruction(void);
uint8 decode_instruction(instr *instr);
void cpu_on_interrupt(uint16 vec);
static uint32 cpu_effective_address(operand * op);
static uint32 cpu_read_op(operand * op);
static void cpu_write_op(operand * op, t_uint64 val);
static void cpu_set_nz_flags(t_uint64 data, operand * op);
static void cpu_calc_ints();
static SIM_INLINE void cpu_on_normal_exception(uint8 isc);
static SIM_INLINE void cpu_on_stack_exception(uint8 isc);
static SIM_INLINE void cpu_on_process_exception(uint8 isc);
static SIM_INLINE void cpu_on_reset_exception(uint8 isc);
static SIM_INLINE void cpu_perform_gate(uint32 index1, uint32 index2);
static SIM_INLINE t_bool mem_exception();
static SIM_INLINE void clear_exceptions();
static SIM_INLINE void set_psw_tm(t_bool val);
static SIM_INLINE void clear_instruction(instr *inst);
static SIM_INLINE int8 op_type(operand *op);
static SIM_INLINE t_bool op_signed(operand *op);
static SIM_INLINE t_bool is_byte_immediate(operand * oper);
static SIM_INLINE t_bool is_halfword_immediate(operand * oper);
static SIM_INLINE t_bool is_word_immediate(operand * oper);
static SIM_INLINE t_bool is_positive_literal(operand * oper);
static SIM_INLINE t_bool is_negative_literal(operand * oper);
static SIM_INLINE t_bool invalid_destination(operand * oper);
static SIM_INLINE uint32 sign_extend_n(uint8 val);
static SIM_INLINE uint32 sign_extend_b(uint8 val);
static SIM_INLINE uint32 zero_extend_b(uint8 val);
static SIM_INLINE uint32 sign_extend_h(uint16 val);
static SIM_INLINE uint32 zero_extend_h(uint16 val);
static SIM_INLINE t_bool cpu_z_flag();
static SIM_INLINE t_bool cpu_n_flag();
static SIM_INLINE t_bool cpu_c_flag();
static SIM_INLINE t_bool cpu_v_flag();
static SIM_INLINE void cpu_set_z_flag(t_bool val);
static SIM_INLINE void cpu_set_n_flag(t_bool val);
static SIM_INLINE void cpu_set_c_flag(t_bool val);
static SIM_INLINE void cpu_set_v_flag(t_bool val);
static SIM_INLINE void cpu_set_v_flag_op(t_uint64 val, operand *op);
static SIM_INLINE uint8 cpu_execution_level();
static SIM_INLINE void cpu_set_execution_level(uint8 level);
static SIM_INLINE void cpu_push_word(uint32 val);
static SIM_INLINE uint32 cpu_pop_word();
static SIM_INLINE void irq_push_word(uint32 val);
static SIM_INLINE uint32 irq_pop_word();
static SIM_INLINE void cpu_context_switch_1(uint32 pcbp);
static SIM_INLINE void cpu_context_switch_2(uint32 pcbp);
static SIM_INLINE void cpu_context_switch_3(uint32 pcbp);
static SIM_INLINE t_bool op_is_psw(operand *op);
static SIM_INLINE t_bool op_is_sp(operand *op);
static SIM_INLINE uint32 cpu_next_pc();
static SIM_INLINE void add(t_uint64 a, t_uint64 b, operand *dst);
static SIM_INLINE void sub(t_uint64 a, t_uint64 b, operand *dst);
/* Helper macros */
#define MOD(A,B,OP1,OP2,SZ) { \

View file

@ -61,6 +61,11 @@ extern UNIT cio_unit;
#define ATOW(arr,i) ((uint32)arr[i+3] + ((uint32)arr[i+2] << 8) + \
((uint32)arr[i+1] << 16) + ((uint32)arr[i] << 24))
/* Static function declarations */
static t_stat ctc_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
static t_stat ctc_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
static t_stat ctc_show_queue_common(FILE *st, UNIT *uptr, int32 val, CONST void *desc, t_bool rq);
static uint8 int_cid; /* Interrupting card ID */
static uint8 int_subdev; /* Interrupting subdevice */
static t_bool ctc_conf = FALSE; /* Has a CTC card been configured? */
@ -262,7 +267,7 @@ static void ctc_cmd(uint8 cid,
uint8 sec_buf[512];
int32 b, i, j;
t_seccnt secrw = 0;
struct vtoc vtoc = {0};
struct vtoc vtoc = {{0}};
struct pdinfo pdinfo = {0};
t_stat result;

View file

@ -151,9 +151,4 @@ void ctc_sysgen(uint8 cid);
void ctc_express(uint8 cid);
void ctc_full(uint8 cid);
/* Largely here for debugging purposes */
static t_stat ctc_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
static t_stat ctc_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
static t_stat ctc_show_queue_common(FILE *st, UNIT *uptr, int32 val, CONST void *desc, t_bool rq);
#endif /* _3B2_CTC_H_ */

View file

@ -357,17 +357,11 @@ typedef struct {
uint8 status;
} DMA_STATE;
/* global symbols from DMA */
extern DMA_STATE dma_state;
static SIM_INLINE uint32 dma_address(uint8 channel, uint32 offset, t_bool r) {
uint32 addr;
addr = (PHYS_MEM_BASE + dma_state.channels[channel].addr + offset);
/* The top bit of the page address is a R/W bit, so we mask it here */
addr |= (uint32) (((uint32)dma_state.channels[channel].page & 0x7f) << 16);
return addr;
}
extern DEVICE dmac_dev;
uint32 dma_address(uint8 channel, uint32 offset, t_bool r);
/* global symbols from the CSR */
extern uint16 csr_data;

View file

@ -60,6 +60,14 @@ dmac_dma_handler device_dma_handlers[] = {
{0, 0, NULL, NULL, NULL }
};
uint32 dma_address(uint8 channel, uint32 offset, t_bool r) {
uint32 addr;
addr = (PHYS_MEM_BASE + dma_state.channels[channel].addr + offset);
/* The top bit of the page address is a R/W bit, so we mask it here */
addr |= (uint32) (((uint32)dma_state.channels[channel].page & 0x7f) << 16);
return addr;
}
t_stat dmac_reset(DEVICE *dptr)
{
int i;

View file

@ -53,6 +53,9 @@
#define ID_SIS_WAIT 142
#define ID_CMD_WAIT 140
/* Static function declarations */
static SIM_INLINE t_lba id_lba(uint16 cyl, uint8 head, uint8 sec);
/* Data FIFO pointer - Read */
uint8 id_dpr = 0;
/* Data FIFO pointer - Write */

View file

@ -184,6 +184,4 @@ void id_handle_data(uint8 val);
void id_handle_command(uint8 val);
void id_after_dma();
static SIM_INLINE t_lba id_lba(uint16 cyl, uint8 head, uint8 sec);
#endif

View file

@ -30,10 +30,11 @@
#include "3b2_if.h"
/*
* TODO: Macros used for debugging timers. Remove when debugging is complete.
*/
double if_start_time;
/* Static function declarations */
static SIM_INLINE void if_set_irq();
static SIM_INLINE void if_clear_irq();
static SIM_INLINE void if_cancel_pending_irq();
static SIM_INLINE uint32 if_buf_offset();
#ifndef MAX
#define MAX(x,y) ((x) > (y) ? (x) : (y))

View file

@ -124,10 +124,6 @@ extern t_bool if_irq;
/* Function prototypes */
static SIM_INLINE void if_set_irq();
static SIM_INLINE void if_clear_irq();
static SIM_INLINE void if_cancel_pending_irq();
static SIM_INLINE uint32 if_buf_offset();
t_stat if_svc(UNIT *uptr);
t_stat if_reset(DEVICE *dptr);
uint32 if_read(uint32 pa, size_t size);

View file

@ -32,7 +32,7 @@
#define CRC_POLYNOMIAL 0xEDB88320
CIO_STATE cio[CIO_SLOTS] = { 0 };
CIO_STATE cio[CIO_SLOTS] = {{0}};
struct iolink iotable[] = {
{ MMUBASE, MMUBASE+MMUSIZE, &mmu_read, &mmu_write },

View file

@ -31,6 +31,9 @@
#include "3b2_iu.h"
#include "sim_tmxr.h"
/* Static function declarations */
static SIM_INLINE void iu_w_cmd(uint8 portno, uint8 val);
/*
* The 3B2/400 has two on-board serial ports, labeled CONSOLE and
* CONTTY. The CONSOLE port is (naturally) the system console. The

View file

@ -212,9 +212,4 @@ void iu_txrdy_a_irq();
void iu_txrdy_b_irq();
void iu_dma(uint8 channel, uint32 service_address);
static SIM_INLINE void iu_w_buf(uint8 portno, uint8 val);
static SIM_INLINE void iu_w_cmd(uint8 portno, uint8 val);
static SIM_INLINE void iu_update_rxi(uint8 c);
static SIM_INLINE void iu_update_txi();
#endif

View file

@ -59,6 +59,255 @@ DEVICE mmu_dev = {
DEV_DEBUG, 0, sys_deb_tab
};
/*
* Find an SD in the cache.
*/
static SIM_INLINE t_stat get_sdce(uint32 va, uint32 *sd0, uint32 *sd1)
{
uint32 tag, sdch, sdcl;
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
tag = SD_TAG(va);
sdch = mmu_state.sdch[ci];
sdcl = mmu_state.sdcl[ci];
if ((sdch & SD_GOOD_MASK) && SDCE_TAG(sdcl) == tag) {
*sd0 = SDCE_TO_SD0(sdch, sdcl);
*sd1 = SDCE_TO_SD1(sdch);
return SCPE_OK;
}
return SCPE_NXM;
}
/*
* Find a PD in the cache. Sets both the PD and the cached access
* permissions.
*/
static SIM_INLINE t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc)
{
uint32 tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
tag = PD_TAG(va);
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag. */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
*pd = PDCXH_TO_PD(pdclh);
*pd_acc = PDCXL_TO_ACC(pdcll);
return SCPE_OK;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
*pd = PDCXH_TO_PD(pdcrh);
*pd_acc = PDCXL_TO_ACC(pdcrl);
return SCPE_OK;
}
return SCPE_NXM;
}
static SIM_INLINE void put_sdce(uint32 va, uint32 sd0, uint32 sd1)
{
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
mmu_state.sdcl[ci] = SD_TO_SDCL(va, sd0);
mmu_state.sdch[ci] = SD_TO_SDCH(sd0, sd1);
}
static SIM_INLINE void put_pdce(uint32 va, uint32 sd0, uint32 pd)
{
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
/* Cache Replacement Algorithm
* (from the WE32101 MMU Information Manual)
*
* 1. If G==0 for the left-hand entry, the new PD is cached in the
* left-hand entry and the U bit (left-hand side) is cleared to
* 0.
*
* 2. If G==1 for the left-hand entry, and G==0 for the right-hand
* entry, the new PD is cached in the right-hand entry and the
* U bit (left-hand side) is set to 1.
*
* 3. If G==1 for both entries, the U bit in the left-hand entry
* is examined. If U==0, the new PD is cached in the right-hand
* entry of the PDC row and U is set to 1. If U==1, it is
* cached in the left-hand entry and U is cleared to 0.
*/
if ((mmu_state.pdclh[ci] & PD_GOOD_MASK) == 0) {
/* Use the left entry */
mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK;
} else if ((mmu_state.pdcrh[ci] & PD_GOOD_MASK) == 0) {
/* Use the right entry */
mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] |= PDCLH_USED_MASK;
} else {
/* Pick the least-recently-replaced side */
if (mmu_state.pdclh[ci] & PDCLH_USED_MASK) {
mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK;
} else {
mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] |= PDCLH_USED_MASK;
}
}
}
static SIM_INLINE void flush_sdce(uint32 va)
{
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
if (mmu_state.sdch[ci] & SD_GOOD_MASK) {
mmu_state.sdch[ci] &= ~SD_GOOD_MASK;
}
}
static SIM_INLINE void flush_pdce(uint32 va)
{
uint32 tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
tag = PD_TAG(va);
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag. */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
mmu_state.pdclh[ci] &= ~PD_GOOD_MASK;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
mmu_state.pdcrh[ci] &= ~PD_GOOD_MASK;
}
}
static SIM_INLINE void flush_cache_sec(uint8 sec)
{
int i;
for (i = 0; i < NUM_SDCE; i++) {
mmu_state.sdch[(sec * NUM_SDCE) + i] &= ~SD_GOOD_MASK;
}
for (i = 0; i < NUM_PDCE; i++) {
mmu_state.pdclh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK;
mmu_state.pdcrh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK;
}
}
static SIM_INLINE void flush_caches()
{
uint8 i;
for (i = 0; i < NUM_SEC; i++) {
flush_cache_sec(i);
}
}
static SIM_INLINE t_stat mmu_check_perm(uint8 flags, uint8 r_acc)
{
switch(MMU_PERM(flags)) {
case 0: /* No Access */
return SCPE_NXM;
case 1: /* Exec Only */
if (r_acc != ACC_IF && r_acc != ACC_IFAD) {
return SCPE_NXM;
}
return SCPE_OK;
case 2: /* Read / Execute */
if (r_acc != ACC_AF && r_acc != ACC_OF &&
r_acc != ACC_IF && r_acc != ACC_IFAD &&
r_acc != ACC_MT) {
return SCPE_NXM;
}
return SCPE_OK;
default:
return SCPE_OK;
}
}
/*
* Update the M (modified) or R (referenced) bit the SD and cache
*/
static SIM_INLINE void mmu_update_sd(uint32 va, uint32 mask)
{
uint32 sd0;
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
/* We go back to main memory to find the SD because the SD may
have been loaded from cache, which is lossy. */
sd0 = pread_w(SD_ADDR(va));
pwrite_w(SD_ADDR(va), sd0|mask);
/* There is no 'R' bit in the SD cache, only an 'M' bit. */
if (mask == SD_M_MASK) {
mmu_state.sdch[ci] |= mask;
}
}
/*
* Update the M (modified) or R (referenced) bit the PD and cache
*/
static SIM_INLINE void mmu_update_pd(uint32 va, uint32 pd_addr, uint32 mask)
{
uint32 pd, tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
tag = PD_TAG(va);
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
/* We go back to main memory to find the PD because the PD may
have been loaded from cache, which is lossy. */
pd = pread_w(pd_addr);
pwrite_w(pd_addr, pd|mask);
/* Update in the cache */
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag, then
update the appropriate bit */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
mmu_state.pdclh[ci] |= mask;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
mmu_state.pdcrh[ci] |= mask;
}
}
t_stat mmu_init(DEVICE *dptr)
{
flush_caches();

View file

@ -355,255 +355,6 @@ t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
#define SHOULD_UPDATE_PD_M_BIT(pd) \
(r_acc == ACC_W && !((pd) & PD_M_MASK))
/*
* Find an SD in the cache.
*/
static SIM_INLINE t_stat get_sdce(uint32 va, uint32 *sd0, uint32 *sd1)
{
uint32 tag, sdch, sdcl;
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
tag = SD_TAG(va);
sdch = mmu_state.sdch[ci];
sdcl = mmu_state.sdcl[ci];
if ((sdch & SD_GOOD_MASK) && SDCE_TAG(sdcl) == tag) {
*sd0 = SDCE_TO_SD0(sdch, sdcl);
*sd1 = SDCE_TO_SD1(sdch);
return SCPE_OK;
}
return SCPE_NXM;
}
/*
* Find a PD in the cache. Sets both the PD and the cached access
* permissions.
*/
static SIM_INLINE t_stat get_pdce(uint32 va, uint32 *pd, uint8 *pd_acc)
{
uint32 tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
tag = PD_TAG(va);
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag. */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
*pd = PDCXH_TO_PD(pdclh);
*pd_acc = PDCXL_TO_ACC(pdcll);
return SCPE_OK;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
*pd = PDCXH_TO_PD(pdcrh);
*pd_acc = PDCXL_TO_ACC(pdcrl);
return SCPE_OK;
}
return SCPE_NXM;
}
static SIM_INLINE void put_sdce(uint32 va, uint32 sd0, uint32 sd1)
{
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
mmu_state.sdcl[ci] = SD_TO_SDCL(va, sd0);
mmu_state.sdch[ci] = SD_TO_SDCH(sd0, sd1);
}
static SIM_INLINE void put_pdce(uint32 va, uint32 sd0, uint32 pd)
{
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
/* Cache Replacement Algorithm
* (from the WE32101 MMU Information Manual)
*
* 1. If G==0 for the left-hand entry, the new PD is cached in the
* left-hand entry and the U bit (left-hand side) is cleared to
* 0.
*
* 2. If G==1 for the left-hand entry, and G==0 for the right-hand
* entry, the new PD is cached in the right-hand entry and the
* U bit (left-hand side) is set to 1.
*
* 3. If G==1 for both entries, the U bit in the left-hand entry
* is examined. If U==0, the new PD is cached in the right-hand
* entry of the PDC row and U is set to 1. If U==1, it is
* cached in the left-hand entry and U is cleared to 0.
*/
if ((mmu_state.pdclh[ci] & PD_GOOD_MASK) == 0) {
/* Use the left entry */
mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK;
} else if ((mmu_state.pdcrh[ci] & PD_GOOD_MASK) == 0) {
/* Use the right entry */
mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] |= PDCLH_USED_MASK;
} else {
/* Pick the least-recently-replaced side */
if (mmu_state.pdclh[ci] & PDCLH_USED_MASK) {
mmu_state.pdcll[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdclh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] &= ~PDCLH_USED_MASK;
} else {
mmu_state.pdcrl[ci] = SD_TO_PDCXL(va, sd0);
mmu_state.pdcrh[ci] = PD_TO_PDCXH(pd, sd0);
mmu_state.pdclh[ci] |= PDCLH_USED_MASK;
}
}
}
static SIM_INLINE void flush_sdce(uint32 va)
{
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
if (mmu_state.sdch[ci] & SD_GOOD_MASK) {
mmu_state.sdch[ci] &= ~SD_GOOD_MASK;
}
}
static SIM_INLINE void flush_pdce(uint32 va)
{
uint32 tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
tag = PD_TAG(va);
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag. */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
mmu_state.pdclh[ci] &= ~PD_GOOD_MASK;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
mmu_state.pdcrh[ci] &= ~PD_GOOD_MASK;
}
}
static SIM_INLINE void flush_cache_sec(uint8 sec)
{
int i;
for (i = 0; i < NUM_SDCE; i++) {
mmu_state.sdch[(sec * NUM_SDCE) + i] &= ~SD_GOOD_MASK;
}
for (i = 0; i < NUM_PDCE; i++) {
mmu_state.pdclh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK;
mmu_state.pdcrh[(sec * NUM_PDCE) + i] &= ~PD_GOOD_MASK;
}
}
static SIM_INLINE void flush_caches()
{
uint8 i;
for (i = 0; i < NUM_SEC; i++) {
flush_cache_sec(i);
}
}
static SIM_INLINE t_stat mmu_check_perm(uint8 flags, uint8 r_acc)
{
switch(MMU_PERM(flags)) {
case 0: /* No Access */
return SCPE_NXM;
case 1: /* Exec Only */
if (r_acc != ACC_IF && r_acc != ACC_IFAD) {
return SCPE_NXM;
}
return SCPE_OK;
case 2: /* Read / Execute */
if (r_acc != ACC_AF && r_acc != ACC_OF &&
r_acc != ACC_IF && r_acc != ACC_IFAD &&
r_acc != ACC_MT) {
return SCPE_NXM;
}
return SCPE_OK;
default:
return SCPE_OK;
}
}
/*
* Update the M (modified) or R (referenced) bit the SD and cache
*/
static SIM_INLINE void mmu_update_sd(uint32 va, uint32 mask)
{
uint32 sd0;
uint8 ci;
ci = (SID(va) * NUM_SDCE) + SD_IDX(va);
/* We go back to main memory to find the SD because the SD may
have been loaded from cache, which is lossy. */
sd0 = pread_w(SD_ADDR(va));
pwrite_w(SD_ADDR(va), sd0|mask);
/* There is no 'R' bit in the SD cache, only an 'M' bit. */
if (mask == SD_M_MASK) {
mmu_state.sdch[ci] |= mask;
}
}
/*
* Update the M (modified) or R (referenced) bit the PD and cache
*/
static SIM_INLINE void mmu_update_pd(uint32 va, uint32 pd_addr, uint32 mask)
{
uint32 pd, tag, pdcll, pdclh, pdcrl, pdcrh;
uint8 ci;
tag = PD_TAG(va);
ci = (SID(va) * NUM_PDCE) + PD_IDX(va);
/* We go back to main memory to find the PD because the PD may
have been loaded from cache, which is lossy. */
pd = pread_w(pd_addr);
pwrite_w(pd_addr, pd|mask);
/* Update in the cache */
/* Left side */
pdcll = mmu_state.pdcll[ci];
pdclh = mmu_state.pdclh[ci];
/* Right side */
pdcrl = mmu_state.pdcrl[ci];
pdcrh = mmu_state.pdcrh[ci];
/* Search L and R to find a good entry with a matching tag, then
update the appropriate bit */
if ((pdclh & PD_GOOD_MASK) && PDCXL_TAG(pdcll) == tag) {
mmu_state.pdclh[ci] |= mask;
} else if ((pdcrh & PD_GOOD_MASK) && PDCXL_TAG(pdcrl) == tag) {
mmu_state.pdcrh[ci] |= mask;
}
}
/* Special functions for reading operands and examining memory
safely */
t_stat read_operand(uint32 va, uint8 *val);

View file

@ -44,6 +44,10 @@
#include "3b2_ports.h"
/* Static function declarations */
static t_stat ports_show_queue_common(FILE *st, UNIT *uptr, int32 val,
CONST void *desc, t_bool rq);
extern CIO_STATE cio[CIO_SLOTS];
extern UNIT cio_unit;

View file

@ -231,7 +231,4 @@ void ports_sysgen(uint8 cid);
void ports_express(uint8 cid);
void ports_full(uint8 cid);
static t_stat ports_show_queue_common(FILE *st, UNIT *uptr, int32 val,
CONST void *desc, t_bool rq);
#endif /* _3B2_PORTS_H_ */