diff --git a/PDP11/pdp11_hk.c b/PDP11/pdp11_hk.c index 3163cc83..4ada5a28 100644 --- a/PDP11/pdp11_hk.c +++ b/PDP11/pdp11_hk.c @@ -68,8 +68,6 @@ extern uint32 cpu_opt; #endif -extern uint16 *M; - #define HK_NUMDR 8 /* #drives */ #define HK_NUMCY6 411 /* cyl/drive */ #define HK_NUMCY7 815 /* cyl/drive */ @@ -1569,6 +1567,8 @@ return pdp11_bad_block (uptr, HK_NUMSC, HK_NUMWD); #if defined (VM_PDP11) +extern uint16 *M; + /* Device bootstrap - does not clear CSR when done */ #define BOOT_START 02000 /* start */ diff --git a/VAX/vax610_defs.h b/VAX/vax610_defs.h index 990f2a2b..41b18070 100644 --- a/VAX/vax610_defs.h +++ b/VAX/vax610_defs.h @@ -322,22 +322,6 @@ typedef struct { extern int32 sys_model; -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -356,4 +340,8 @@ t_stat cpu_show_leds (FILE *st, UNIT *uptr, int32 val, void *desc); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax610_sysdev.c b/VAX/vax610_sysdev.c index b597d735..a9072c05 100644 --- a/VAX/vax610_sysdev.c +++ b/VAX/vax610_sysdev.c @@ -60,9 +60,6 @@ extern DEVICE vc_dev, lk_dev, vs_dev; int32 conisp, conpc, conpsl; /* console reg */ int32 sys_model = 0; /* MicroVAX or VAXstation */ char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */ -static const int32 insert[4] = { - 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF - }; static struct boot_dev boot_tab[] = { { "RQ", "DUA", 0x00415544 }, /* DUAn */ diff --git a/VAX/vax630_defs.h b/VAX/vax630_defs.h index 26c05007..0898b954 100644 --- a/VAX/vax630_defs.h +++ b/VAX/vax630_defs.h @@ -374,22 +374,6 @@ typedef struct { #define LOG_CPU_R 0x2 /* REI */ #define LOG_CPU_P 0x4 /* context */ -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -412,4 +396,8 @@ extern t_stat sysd_show_leds (FILE *st, UNIT *uptr, int32 val, void *desc); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax630_sysdev.c b/VAX/vax630_sysdev.c index e3804ae2..faca7c67 100644 --- a/VAX/vax630_sysdev.c +++ b/VAX/vax630_sysdev.c @@ -149,9 +149,6 @@ int32 ka_mser = 0; /* KA630 mem sys err */ int32 ka_cear = 0; /* KA630 cpu err */ int32 ka_dear = 0; /* KA630 dma err */ static uint32 rom_delay = 0; -static const int32 insert[4] = { - 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF - }; t_bool ka_diag_full = FALSE; t_bool ka_hltenab = TRUE; /* Halt Enable / Autoboot flag */ diff --git a/VAX/vax730_defs.h b/VAX/vax730_defs.h index 258aaac3..4ee98617 100644 --- a/VAX/vax730_defs.h +++ b/VAX/vax730_defs.h @@ -342,22 +342,6 @@ typedef struct { #define BOOT_TK 18 #define BOOT_TD 64 -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -379,4 +363,8 @@ void sbi_set_errcnf (void); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax730_sys.c b/VAX/vax730_sys.c index 0d641ba4..17b465a1 100644 --- a/VAX/vax730_sys.c +++ b/VAX/vax730_sys.c @@ -382,7 +382,7 @@ return; longword of data */ -int32 ReadReg (int32 pa, int32 lnt) +int32 ReadReg (uint32 pa, int32 lnt) { int32 nexus, val; @@ -408,7 +408,7 @@ return 0; none */ -void WriteReg (int32 pa, int32 val, int32 lnt) +void WriteReg (uint32 pa, int32 val, int32 lnt) { int32 nexus; diff --git a/VAX/vax750_cmi.c b/VAX/vax750_cmi.c index bac47aa6..c96ee652 100644 --- a/VAX/vax750_cmi.c +++ b/VAX/vax750_cmi.c @@ -446,7 +446,7 @@ return; longword of data */ -int32 ReadReg (int32 pa, int32 lnt) +int32 ReadReg (uint32 pa, int32 lnt) { int32 nexus, val; @@ -473,7 +473,7 @@ return 0; none */ -void WriteReg (int32 pa, int32 val, int32 lnt) +void WriteReg (uint32 pa, int32 val, int32 lnt) { int32 nexus; diff --git a/VAX/vax750_defs.h b/VAX/vax750_defs.h index e3c57104..75893301 100644 --- a/VAX/vax750_defs.h +++ b/VAX/vax750_defs.h @@ -388,22 +388,6 @@ typedef struct { #define BOOT_CI 32 #define BOOT_TD 64 -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -435,4 +419,8 @@ void sbi_set_errcnf (void); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax780_defs.h b/VAX/vax780_defs.h index 1c1bf9ee..1d093971 100644 --- a/VAX/vax780_defs.h +++ b/VAX/vax780_defs.h @@ -401,22 +401,6 @@ typedef struct { #define BOOT_TK 18 #define BOOT_CS 64 -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -448,4 +432,8 @@ void sbi_set_errcnf (void); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax780_sbi.c b/VAX/vax780_sbi.c index 02e56bb4..a8a99085 100644 --- a/VAX/vax780_sbi.c +++ b/VAX/vax780_sbi.c @@ -502,7 +502,7 @@ return; longword of data */ -int32 ReadReg (int32 pa, int32 lnt) +int32 ReadReg (uint32 pa, int32 lnt) { int32 nexus, val; @@ -529,7 +529,7 @@ return 0; none */ -void WriteReg (int32 pa, int32 val, int32 lnt) +void WriteReg (uint32 pa, int32 val, int32 lnt) { int32 nexus; diff --git a/VAX/vax860_abus.c b/VAX/vax860_abus.c index 60284a9c..c359014f 100644 --- a/VAX/vax860_abus.c +++ b/VAX/vax860_abus.c @@ -587,7 +587,7 @@ return; longword of data */ -int32 ReadReg (int32 pa, int32 lnt) +int32 ReadReg (uint32 pa, int32 lnt) { int32 val; @@ -610,7 +610,7 @@ return 0; none */ -void WriteReg (int32 pa, int32 val, int32 lnt) +void WriteReg (uint32 pa, int32 val, int32 lnt) { if (ADDR_IS_SBIA (pa)) { /* SBI adapter space? */ sbia_wr (pa, val, lnt); diff --git a/VAX/vax860_defs.h b/VAX/vax860_defs.h index b7f833bc..96849184 100644 --- a/VAX/vax860_defs.h +++ b/VAX/vax860_defs.h @@ -434,22 +434,6 @@ typedef struct { #define BOOT_TK 18 #define BOOT_CS 64 -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -481,4 +465,8 @@ void sbi_set_errcnf (void); #include "pdp11_io_lib.h" +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index 1d98cb5b..92c20a7b 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -397,7 +397,7 @@ t_stat cpu_set_idle (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_show_idle (FILE *st, UNIT *uptr, int32 val, void *desc); char *cpu_description (DEVICE *dptr); int32 cpu_get_vsw (int32 sw); -SIM_INLINE int32 get_istr (int32 lnt, int32 acc); +static SIM_INLINE int32 get_istr (int32 lnt, int32 acc); int32 ReadOcta (int32 va, int32 *opnd, int32 j, int32 acc); t_bool cpu_show_opnd (FILE *st, InstHistory *h, int32 line); t_stat cpu_idle_svc (UNIT *uptr); @@ -3133,7 +3133,7 @@ for ( ;; ) { so any translation errors are real. */ -SIM_INLINE int32 get_istr (int32 lnt, int32 acc) +static SIM_INLINE int32 get_istr (int32 lnt, int32 acc) { int32 bo = PC & 3; int32 sc, val, t; diff --git a/VAX/vax_mmu.c b/VAX/vax_mmu.c index d9550335..20f2763c 100644 --- a/VAX/vax_mmu.c +++ b/VAX/vax_mmu.c @@ -50,13 +50,9 @@ */ #include "vax_defs.h" +#include "vax_mmu.h" #include -typedef struct { - int32 tag; /* tag */ - int32 pte; /* pte */ - } TLBENT; - extern uint32 *M; extern int32 PSL; extern int32 mapen; @@ -66,16 +62,11 @@ extern int32 P1BR, P1LR; extern int32 SBR, SLR; extern int32 SISR; extern jmp_buf save_env; -extern UNIT cpu_unit; int32 d_p0br, d_p0lr; /* dynamic copies */ int32 d_p1br, d_p1lr; /* altered per ucode */ int32 d_sbr, d_slr; -extern int32 mchk_va, mchk_ref; /* for mcheck */ TLBENT stlb[VA_TBSIZE], ptlb[VA_TBSIZE]; -static const int32 insert[4] = { - 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF - }; static const int32 cvtacc[16] = { 0, 0, TLB_ACCW (KERN)+TLB_ACCR (KERN), TLB_ACCR (KERN), @@ -136,355 +127,6 @@ DEVICE tlb_dev = { &tlb_description }; -/* Read and write virtual - - These routines logically fall into three phases: - - 1. Look up the virtual address in the translation buffer, calling - the fill routine on a tag mismatch or access mismatch (invalid - tlb entries have access = 0 and thus always mismatch). The - fill routine handles all errors. If the resulting physical - address is aligned, do an aligned physical read or write. - 2. Test for unaligned across page boundaries. If cross page, look - up the physical address of the second page. If not cross page, - the second physical address is the same as the first. - 3. Using the two physical addresses, do an unaligned read or - write, with three cases: unaligned long, unaligned word within - a longword, unaligned word crossing a longword boundary. - - Note that these routines do not handle quad or octa references. -*/ - -/* Read virtual - - Inputs: - va = virtual address - lnt = length code (BWL) - acc = access code (KESU) - Output: - returned data, right justified in 32b longword -*/ - -int32 Read (uint32 va, int32 lnt, int32 acc) -{ -int32 vpn, off, tbi, pa; -int32 pa1, bo, sc, wl, wh; -TLBENT xpte; - -mchk_va = va; -if (mapen) { /* mapping on? */ - vpn = VA_GETVPN (va); /* get vpn, offset */ - off = VA_GETOFF (va); - tbi = VA_GETTBI (vpn); - xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ - if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || - ((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0))) - xpte = fill (va, lnt, acc, NULL); /* fill if needed */ - pa = (xpte.pte & TLB_PFN) | off; /* get phys addr */ - } -else { - pa = va & PAMASK; - off = 0; - } -if ((pa & (lnt - 1)) == 0) { /* aligned? */ - if (lnt >= L_LONG) /* long, quad? */ - return ReadL (pa); - if (lnt == L_WORD) /* word? */ - return ReadW (pa); - return ReadB (pa); /* byte */ - } -if (mapen && ((uint32)(off + lnt) > VA_PAGSIZE)) { /* cross page? */ - vpn = VA_GETVPN (va + lnt); /* vpn 2nd page */ - tbi = VA_GETTBI (vpn); - xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ - if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || - ((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0))) - xpte = fill (va + lnt, lnt, acc, NULL); /* fill if needed */ - pa1 = ((xpte.pte & TLB_PFN) | VA_GETOFF (va + 4)) & ~03; - } -else pa1 = ((pa + 4) & PAMASK) & ~03; /* not cross page */ -bo = pa & 3; -if (lnt >= L_LONG) { /* lw unaligned? */ - sc = bo << 3; - wl = ReadU (pa, L_LONG - bo); /* read both fragments */ - wh = ReadU (pa1, bo); /* extract */ - return ((wl | (wh << (32 - sc))) & LMASK); - } -else if (bo == 1) /* read within lw */ - return ReadU (pa, L_WORD); -else { - wl = ReadU (pa, L_BYTE); /* word cross lw */ - wh = ReadU (pa1, L_BYTE); /* read, extract */ - return (wl | (wh << 8)); - } -} - -/* Write virtual - - Inputs: - va = virtual address - val = data to be written, right justified in 32b lw - lnt = length code (BWL) - acc = access code (KESU) - Output: - none -*/ - -void Write (uint32 va, int32 val, int32 lnt, int32 acc) -{ -int32 vpn, off, tbi, pa; -int32 pa1, bo, sc; -TLBENT xpte; - -mchk_va = va; -if (mapen) { - vpn = VA_GETVPN (va); - off = VA_GETOFF (va); - tbi = VA_GETTBI (vpn); - xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ - if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || - ((xpte.pte & TLB_M) == 0)) - xpte = fill (va, lnt, acc, NULL); - pa = (xpte.pte & TLB_PFN) | off; - } -else { - pa = va & PAMASK; - off = 0; - } -if ((pa & (lnt - 1)) == 0) { /* aligned? */ - if (lnt >= L_LONG) /* long, quad? */ - WriteL (pa, val); - else if (lnt == L_WORD) /* word? */ - WriteW (pa, val); - else WriteB (pa, val); /* byte */ - return; - } -if (mapen && ((uint32)(off + lnt) > VA_PAGSIZE)) { - vpn = VA_GETVPN (va + 4); - tbi = VA_GETTBI (vpn); - xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ - if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || - ((xpte.pte & TLB_M) == 0)) - xpte = fill (va + lnt, lnt, acc, NULL); - pa1 = ((xpte.pte & TLB_PFN) | VA_GETOFF (va + 4)) & ~03; - } -else pa1 = ((pa + 4) & PAMASK) & ~03; -bo = pa & 3; -if (lnt >= L_LONG) { - sc = bo << 3; - WriteU (pa, val & insert[L_LONG - bo], L_LONG - bo); - WriteU (pa1, (val >> (32 - sc)) & insert[bo], bo); - } -else if (bo == 1) /* read within lw */ - WriteU (pa, val & WMASK, L_WORD); -else { /* word cross lw */ - WriteU (pa, val & BMASK, L_BYTE); - WriteU (pa1, (val >> 8) & BMASK, L_BYTE); - } -return; -} - -/* Test access to a byte (VAX PROBEx) */ - -int32 Test (uint32 va, int32 acc, int32 *status) -{ -int32 vpn, off, tbi; -TLBENT xpte; - -*status = PR_OK; /* assume ok */ -if (mapen) { /* mapping on? */ - vpn = VA_GETVPN (va); /* get vpn, off */ - off = VA_GETOFF (va); - tbi = VA_GETTBI (vpn); - xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ - if ((xpte.pte & acc) && (xpte.tag == vpn)) /* TB hit, acc ok? */ - return (xpte.pte & TLB_PFN) | off; - xpte = fill (va, L_BYTE, acc, status); /* fill TB */ - if (*status == PR_OK) - return (xpte.pte & TLB_PFN) | off; - else return -1; - } -return va & PAMASK; /* ret phys addr */ -} - -/* Read aligned physical (in virtual context, unless indicated) - - Inputs: - pa = physical address, naturally aligned - Output: - returned data, right justified in 32b longword -*/ - -SIM_INLINE int32 ReadB (uint32 pa) -{ -int32 dat; - -if (ADDR_IS_MEM (pa)) - dat = M[pa >> 2]; -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - dat = ReadIO (pa, L_BYTE); - else dat = ReadReg (pa, L_BYTE); - } -return ((dat >> ((pa & 3) << 3)) & BMASK); -} - -SIM_INLINE int32 ReadW (uint32 pa) -{ -int32 dat; - -if (ADDR_IS_MEM (pa)) - dat = M[pa >> 2]; -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - dat = ReadIO (pa, L_WORD); - else dat = ReadReg (pa, L_WORD); - } -return ((dat >> ((pa & 2)? 16: 0)) & WMASK); -} - -SIM_INLINE int32 ReadL (uint32 pa) -{ -if (ADDR_IS_MEM (pa)) - return M[pa >> 2]; -mchk_ref = REF_V; -if (ADDR_IS_IO (pa)) - return ReadIO (pa, L_LONG); -return ReadReg (pa, L_LONG); -} - -SIM_INLINE int32 ReadLP (uint32 pa) -{ -if (ADDR_IS_MEM (pa)) - return M[pa >> 2]; -mchk_va = pa; -mchk_ref = REF_P; -if (ADDR_IS_IO (pa)) - return ReadIO (pa, L_LONG); -return ReadReg (pa, L_LONG); -} - -/* Read unaligned physical (in virtual context) - - Inputs: - pa = physical address - lnt = length in bytes (1, 2, or 3) - Output: - returned data -*/ - -int32 ReadU (uint32 pa, int32 lnt) -{ -int32 dat; -int32 sc = (pa & 3) << 3; -if (ADDR_IS_MEM (pa)) - dat = M[pa >> 2]; -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - dat = ReadIOU (pa, lnt); - else dat = ReadRegU (pa, lnt); - } -return ((dat >> sc) & insert[lnt]); -} - -/* Write aligned physical (in virtual context, unless indicated) - - Inputs: - pa = physical address, naturally aligned - val = data to be written, right justified in 32b longword - Output: - none -*/ - -SIM_INLINE void WriteB (uint32 pa, int32 val) -{ -if (ADDR_IS_MEM (pa)) { - int32 id = pa >> 2; - int32 sc = (pa & 3) << 3; - int32 mask = 0xFF << sc; - M[id] = (M[id] & ~mask) | (val << sc); - } -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - WriteIO (pa, val, L_BYTE); - else WriteReg (pa, val, L_BYTE); - } -return; -} - -SIM_INLINE void WriteW (uint32 pa, int32 val) -{ -if (ADDR_IS_MEM (pa)) { - int32 id = pa >> 2; - M[id] = (pa & 2)? (M[id] & 0xFFFF) | (val << 16): - (M[id] & ~0xFFFF) | val; - } -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - WriteIO (pa, val, L_WORD); - else WriteReg (pa, val, L_WORD); - } -return; -} - -SIM_INLINE void WriteL (uint32 pa, int32 val) -{ -if (ADDR_IS_MEM (pa)) - M[pa >> 2] = val; -else { - mchk_ref = REF_V; - if (ADDR_IS_IO (pa)) - WriteIO (pa, val, L_LONG); - else WriteReg (pa, val, L_LONG); - } -return; -} - -void WriteLP (uint32 pa, int32 val) -{ -if (ADDR_IS_MEM (pa)) - M[pa >> 2] = val; -else { - mchk_va = pa; - mchk_ref = REF_P; - if (ADDR_IS_IO (pa)) - WriteIO (pa, val, L_LONG); - else WriteReg (pa, val, L_LONG); - } -return; -} - -/* Write unaligned physical (in virtual context) - - Inputs: - pa = physical address - val = data to be written, right justified in 32b longword - lnt = length (1, 2, or 3 bytes) - Output: - none -*/ - -void WriteU (uint32 pa, int32 val, int32 lnt) -{ -if (ADDR_IS_MEM (pa)) { - int32 bo = pa & 3; - int32 sc = bo << 3; - M[pa >> 2] = (M[pa >> 2] & ~(insert[lnt] << sc)) | ((val & insert[lnt]) << sc); - } -else { - mchk_ref = REF_V; - if ADDR_IS_IO (pa) - WriteIOU (pa, val, lnt); - else WriteRegU (pa, val, lnt); - } -return; -} - /* TLB fill diff --git a/VAX/vax_mmu.h b/VAX/vax_mmu.h new file mode 100644 index 00000000..5122b84b --- /dev/null +++ b/VAX/vax_mmu.h @@ -0,0 +1,434 @@ +/* vax_mmu.h - VAX memory management (inlined) + + Copyright (c) 1998-2013, Robert M Supnik + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of Robert M Supnik shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. + + 29-Nov-13 RMS Reworked unaligned flows + 24-Oct-12 MB Added support for KA620 virtual addressing + 21-Jul-08 RMS Removed inlining support + 28-May-08 RMS Inlined physical memory routines + 29-Apr-07 RMS Added address masking for system page table reads + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) + 30-Sep-04 RMS Comment and formating changes + 19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS + 01-Jun-03 RMS Fixed compilation problem with USE_ADDR64 + + This module contains the instruction simulators for + + Read - read virtual + Write - write virtual + ReadL(P) - read aligned physical longword (physical context) + WriteL(P) - write aligned physical longword (physical context) + ReadB(W) - read aligned physical byte (word) + WriteB(W) - write aligned physical byte (word) + Test - test acccess + +*/ + +#ifndef VAX_MMU_H_ +#define VAX_MMU_H_ 1 + +#include "vax_defs.h" +#include + +typedef struct { + int32 tag; /* tag */ + int32 pte; /* pte */ + } TLBENT; + +extern uint32 *M; +extern int32 mapen; +extern UNIT cpu_unit; + +extern int32 mchk_va, mchk_ref; /* for mcheck */ +extern TLBENT stlb[VA_TBSIZE], ptlb[VA_TBSIZE]; + +static const int32 insert[4] = { + 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF + }; + +extern int32 ReadIO (uint32 pa, int32 lnt); +extern void WriteIO (uint32 pa, int32 val, int32 lnt); +extern int32 ReadReg (uint32 pa, int32 lnt); +extern void WriteReg (uint32 pa, int32 val, int32 lnt); +extern TLBENT fill (uint32 va, int32 lnt, int32 acc, int32 *stat); +static SIM_INLINE int32 ReadU (uint32 pa, int32 lnt); +static SIM_INLINE void WriteU (uint32 pa, int32 val, int32 lnt); +static SIM_INLINE int32 ReadB (uint32 pa); +static SIM_INLINE int32 ReadW (uint32 pa); +static SIM_INLINE int32 ReadL (uint32 pa); +static SIM_INLINE int32 ReadLP (uint32 pa); +static SIM_INLINE void WriteB (uint32 pa, int32 val); +static SIM_INLINE void WriteW (uint32 pa, int32 val); +static SIM_INLINE void WriteL (uint32 pa, int32 val); + +/* Read and write virtual + + These routines logically fall into three phases: + + 1. Look up the virtual address in the translation buffer, calling + the fill routine on a tag mismatch or access mismatch (invalid + tlb entries have access = 0 and thus always mismatch). The + fill routine handles all errors. If the resulting physical + address is aligned, do an aligned physical read or write. + 2. Test for unaligned across page boundaries. If cross page, look + up the physical address of the second page. If not cross page, + the second physical address is the same as the first. + 3. Using the two physical addresses, do an unaligned read or + write, with three cases: unaligned long, unaligned word within + a longword, unaligned word crossing a longword boundary. + + Note that these routines do not handle quad or octa references. +*/ + +/* Read virtual + + Inputs: + va = virtual address + lnt = length code (BWL) + acc = access code (KESU) + Output: + returned data, right justified in 32b longword +*/ + +static SIM_INLINE int32 Read (uint32 va, int32 lnt, int32 acc) +{ +int32 vpn, off, tbi, pa; +int32 pa1, bo, sc, wl, wh; +TLBENT xpte; + +mchk_va = va; +if (mapen) { /* mapping on? */ + vpn = VA_GETVPN (va); /* get vpn, offset */ + off = VA_GETOFF (va); + tbi = VA_GETTBI (vpn); + xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ + if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || + ((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0))) + xpte = fill (va, lnt, acc, NULL); /* fill if needed */ + pa = (xpte.pte & TLB_PFN) | off; /* get phys addr */ + } +else { + pa = va & PAMASK; + off = 0; + } +if ((pa & (lnt - 1)) == 0) { /* aligned? */ + if (lnt >= L_LONG) /* long, quad? */ + return ReadL (pa); + if (lnt == L_WORD) /* word? */ + return ReadW (pa); + return ReadB (pa); /* byte */ + } +if (mapen && ((uint32)(off + lnt) > VA_PAGSIZE)) { /* cross page? */ + vpn = VA_GETVPN (va + lnt); /* vpn 2nd page */ + tbi = VA_GETTBI (vpn); + xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ + if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || + ((acc & TLB_WACC) && ((xpte.pte & TLB_M) == 0))) + xpte = fill (va + lnt, lnt, acc, NULL); /* fill if needed */ + pa1 = ((xpte.pte & TLB_PFN) | VA_GETOFF (va + 4)) & ~03; + } +else pa1 = ((pa + 4) & PAMASK) & ~03; /* not cross page */ +bo = pa & 3; +if (lnt >= L_LONG) { /* lw unaligned? */ + sc = bo << 3; + wl = ReadU (pa, L_LONG - bo); /* read both fragments */ + wh = ReadU (pa1, bo); /* extract */ + return ((wl | (wh << (32 - sc))) & LMASK); + } +else if (bo == 1) /* read within lw */ + return ReadU (pa, L_WORD); +else { + wl = ReadU (pa, L_BYTE); /* word cross lw */ + wh = ReadU (pa1, L_BYTE); /* read, extract */ + return (wl | (wh << 8)); + } +} + +/* Write virtual + + Inputs: + va = virtual address + val = data to be written, right justified in 32b lw + lnt = length code (BWL) + acc = access code (KESU) + Output: + none +*/ + +static SIM_INLINE void Write (uint32 va, int32 val, int32 lnt, int32 acc) +{ +int32 vpn, off, tbi, pa; +int32 pa1, bo, sc; +TLBENT xpte; + +mchk_va = va; +if (mapen) { + vpn = VA_GETVPN (va); + off = VA_GETOFF (va); + tbi = VA_GETTBI (vpn); + xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ + if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || + ((xpte.pte & TLB_M) == 0)) + xpte = fill (va, lnt, acc, NULL); + pa = (xpte.pte & TLB_PFN) | off; + } +else { + pa = va & PAMASK; + off = 0; + } +if ((pa & (lnt - 1)) == 0) { /* aligned? */ + if (lnt >= L_LONG) /* long, quad? */ + WriteL (pa, val); + else if (lnt == L_WORD) /* word? */ + WriteW (pa, val); + else WriteB (pa, val); /* byte */ + return; + } +if (mapen && ((uint32)(off + lnt) > VA_PAGSIZE)) { + vpn = VA_GETVPN (va + 4); + tbi = VA_GETTBI (vpn); + xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ + if (((xpte.pte & acc) == 0) || (xpte.tag != vpn) || + ((xpte.pte & TLB_M) == 0)) + xpte = fill (va + lnt, lnt, acc, NULL); + pa1 = ((xpte.pte & TLB_PFN) | VA_GETOFF (va + 4)) & ~03; + } +else pa1 = ((pa + 4) & PAMASK) & ~03; +bo = pa & 3; +if (lnt >= L_LONG) { + sc = bo << 3; + WriteU (pa, val & insert[L_LONG - bo], L_LONG - bo); + WriteU (pa1, (val >> (32 - sc)) & insert[bo], bo); + } +else if (bo == 1) /* read within lw */ + WriteU (pa, val & WMASK, L_WORD); +else { /* word cross lw */ + WriteU (pa, val & BMASK, L_BYTE); + WriteU (pa1, (val >> 8) & BMASK, L_BYTE); + } +return; +} + +/* Test access to a byte (VAX PROBEx) */ + +static SIM_INLINE int32 Test (uint32 va, int32 acc, int32 *status) +{ +int32 vpn, off, tbi; +TLBENT xpte; + +*status = PR_OK; /* assume ok */ +if (mapen) { /* mapping on? */ + vpn = VA_GETVPN (va); /* get vpn, off */ + off = VA_GETOFF (va); + tbi = VA_GETTBI (vpn); + xpte = (va & VA_S0)? stlb[tbi]: ptlb[tbi]; /* access tlb */ + if ((xpte.pte & acc) && (xpte.tag == vpn)) /* TB hit, acc ok? */ + return (xpte.pte & TLB_PFN) | off; + xpte = fill (va, L_BYTE, acc, status); /* fill TB */ + if (*status == PR_OK) + return (xpte.pte & TLB_PFN) | off; + else return -1; + } +return va & PAMASK; /* ret phys addr */ +} + +/* Read aligned physical (in virtual context, unless indicated) + + Inputs: + pa = physical address, naturally aligned + Output: + returned data, right justified in 32b longword +*/ + +static SIM_INLINE int32 ReadB (uint32 pa) +{ +int32 dat; + +if (ADDR_IS_MEM (pa)) + dat = M[pa >> 2]; +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + dat = ReadIO (pa, L_BYTE); + else dat = ReadReg (pa, L_BYTE); + } +return ((dat >> ((pa & 3) << 3)) & BMASK); +} + +static SIM_INLINE int32 ReadW (uint32 pa) +{ +int32 dat; + +if (ADDR_IS_MEM (pa)) + dat = M[pa >> 2]; +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + dat = ReadIO (pa, L_WORD); + else dat = ReadReg (pa, L_WORD); + } +return ((dat >> ((pa & 2)? 16: 0)) & WMASK); +} + +static SIM_INLINE int32 ReadL (uint32 pa) +{ +if (ADDR_IS_MEM (pa)) + return M[pa >> 2]; +mchk_ref = REF_V; +if (ADDR_IS_IO (pa)) + return ReadIO (pa, L_LONG); +return ReadReg (pa, L_LONG); +} + +static SIM_INLINE int32 ReadLP (uint32 pa) +{ +if (ADDR_IS_MEM (pa)) + return M[pa >> 2]; +mchk_va = pa; +mchk_ref = REF_P; +if (ADDR_IS_IO (pa)) + return ReadIO (pa, L_LONG); +return ReadReg (pa, L_LONG); +} + +/* Read unaligned physical (in virtual context) + + Inputs: + pa = physical address + lnt = length in bytes (1, 2, or 3) + Output: + returned data +*/ + +static SIM_INLINE int32 ReadU (uint32 pa, int32 lnt) +{ +int32 dat; +int32 sc = (pa & 3) << 3; +if (ADDR_IS_MEM (pa)) + dat = M[pa >> 2]; +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + dat = ReadIOU (pa, lnt); + else dat = ReadRegU (pa, lnt); + } +return ((dat >> sc) & insert[lnt]); +} + +/* Write aligned physical (in virtual context, unless indicated) + + Inputs: + pa = physical address, naturally aligned + val = data to be written, right justified in 32b longword + Output: + none +*/ + +static SIM_INLINE void WriteB (uint32 pa, int32 val) +{ +if (ADDR_IS_MEM (pa)) { + int32 id = pa >> 2; + int32 sc = (pa & 3) << 3; + int32 mask = 0xFF << sc; + M[id] = (M[id] & ~mask) | (val << sc); + } +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + WriteIO (pa, val, L_BYTE); + else WriteReg (pa, val, L_BYTE); + } +return; +} + +static SIM_INLINE void WriteW (uint32 pa, int32 val) +{ +if (ADDR_IS_MEM (pa)) { + int32 id = pa >> 2; + M[id] = (pa & 2)? (M[id] & 0xFFFF) | (val << 16): + (M[id] & ~0xFFFF) | val; + } +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + WriteIO (pa, val, L_WORD); + else WriteReg (pa, val, L_WORD); + } +return; +} + +static SIM_INLINE void WriteL (uint32 pa, int32 val) +{ +if (ADDR_IS_MEM (pa)) + M[pa >> 2] = val; +else { + mchk_ref = REF_V; + if (ADDR_IS_IO (pa)) + WriteIO (pa, val, L_LONG); + else WriteReg (pa, val, L_LONG); + } +return; +} + +static SIM_INLINE void WriteLP (uint32 pa, int32 val) +{ +if (ADDR_IS_MEM (pa)) + M[pa >> 2] = val; +else { + mchk_va = pa; + mchk_ref = REF_P; + if (ADDR_IS_IO (pa)) + WriteIO (pa, val, L_LONG); + else WriteReg (pa, val, L_LONG); + } +return; +} + +/* Write unaligned physical (in virtual context) + + Inputs: + pa = physical address + val = data to be written, right justified in 32b longword + lnt = length (1, 2, or 3 bytes) + Output: + none +*/ + +static SIM_INLINE void WriteU (uint32 pa, int32 val, int32 lnt) +{ +if (ADDR_IS_MEM (pa)) { + int32 bo = pa & 3; + int32 sc = bo << 3; + M[pa >> 2] = (M[pa >> 2] & ~(insert[lnt] << sc)) | ((val & insert[lnt]) << sc); + } +else { + mchk_ref = REF_V; + if ADDR_IS_IO (pa) + WriteIOU (pa, val, lnt); + else WriteRegU (pa, val, lnt); + } +return; +} + +#endif /* VAX_MMU_H_ */ diff --git a/VAX/vax_sysdev.c b/VAX/vax_sysdev.c index a3622841..c006919b 100644 --- a/VAX/vax_sysdev.c +++ b/VAX/vax_sysdev.c @@ -233,9 +233,6 @@ int32 ssc_adsm[2] = { 0 }; /* addr strobes */ int32 ssc_adsk[2] = { 0 }; int32 cdg_dat[CDASIZE >> 2]; /* cache data */ static uint32 rom_delay = 0; -static const int32 insert[4] = { - 0x00000000, 0x000000FF, 0x0000FFFF, 0x00FFFFFF - }; t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); diff --git a/VAX/vaxmod_defs.h b/VAX/vaxmod_defs.h index d06a4341..bc491b08 100644 --- a/VAX/vaxmod_defs.h +++ b/VAX/vaxmod_defs.h @@ -410,22 +410,6 @@ typedef struct { #define LOG_CPU_R 0x2 /* REI */ #define LOG_CPU_P 0x4 /* context */ -/* Function prototypes for virtual memory interface */ - -int32 Read (uint32 va, int32 lnt, int32 acc); -void Write (uint32 va, int32 val, int32 lnt, int32 acc); - -/* Function prototypes for physical memory interface (inlined) */ - -SIM_INLINE int32 ReadB (uint32 pa); -SIM_INLINE int32 ReadW (uint32 pa); -SIM_INLINE int32 ReadL (uint32 pa); -SIM_INLINE int32 ReadLP (uint32 pa); -SIM_INLINE void WriteB (uint32 pa, int32 val); -SIM_INLINE void WriteW (uint32 pa, int32 val); -SIM_INLINE void WriteL (uint32 pa, int32 val); -void WriteLP (uint32 pa, int32 val); - /* Function prototypes for I/O */ int32 Map_ReadB (uint32 ba, int32 bc, uint8 *buf); @@ -445,4 +429,8 @@ int32 ReadRegU (uint32 pa, int32 lnt); void WriteIOU (uint32 pa, int32 val, int32 lnt); void WriteRegU (uint32 pa, int32 val, int32 lnt); +/* Function prototypes for virtual and physical memory interface (inlined) */ + +#include "vax_mmu.h" + #endif diff --git a/Visual Studio Projects/MicroVAX1.vcproj b/Visual Studio Projects/MicroVAX1.vcproj index a6a94f09..670a57de 100644 --- a/Visual Studio Projects/MicroVAX1.vcproj +++ b/Visual Studio Projects/MicroVAX1.vcproj @@ -466,6 +466,10 @@ RelativePath="..\VAX\vax_defs.h" > + + - @@ -120,9 +117,6 @@ - @@ -472,6 +466,10 @@ RelativePath="..\VAX\vax_defs.h" > + + + + diff --git a/Visual Studio Projects/VAX730.vcproj b/Visual Studio Projects/VAX730.vcproj index e4393d77..e5966337 100644 --- a/Visual Studio Projects/VAX730.vcproj +++ b/Visual Studio Projects/VAX730.vcproj @@ -153,10 +153,10 @@ AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;"../../pthreads/Pre-built.2/lib/";"../../windows-build/PCRE/lib/"" GenerateDebugInformation="false" SubSystem="1" - OptimizeReferences="2" - EnableCOMDATFolding="2" StackReserveSize="10485760" StackCommitSize="10485760" + OptimizeReferences="2" + EnableCOMDATFolding="2" RandomizedBaseAddress="1" DataExecutionPrevention="0" TargetMachine="1" @@ -452,6 +452,10 @@ RelativePath="..\VAX\vax_defs.h" > + + + + + + + + + +