memory_alpha.cc Source File

Back to the index.

memory_alpha.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2006-2011 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #include "cpu.h"
33 #include "machine.h"
34 #include "memory.h"
35 #include "misc.h"
36 
37 #include "thirdparty/alpha_rpb.h"
38 
39 
40 /*
41  * alpha_translate_v2p():
42  */
43 int alpha_translate_v2p(struct cpu *cpu, uint64_t vaddr,
44  uint64_t *return_paddr, int flags)
45 {
46  uint64_t base = cpu->cd.alpha.pcb.apcb_ptbr << ALPHA_PAGESHIFT;
47  bool userMode = cpu->cd.alpha.ps & ALPHA_PSL_USERMODE;
48  // uint64_t vptptr = cpu->cd.alpha.vptptr;
49 
50  // TODO: From the Alpha "arm_book.book":
51  // IF {SEXT(VA<63:VA_SIZE>) NEQ SEXT(VA<VA_SIZE-1>} THEN
52  // {initiate Access Violation fault}
53  // IF (VIRBND in use) THEN
54  // IF (VA LTU VIRBND) THEN
55  // ptbr_value <- PTBR
56  // ELSE
57  // ptbr_value <- SYSPTBR
58  // ELSE
59  // ptbr_value <- PTBR
60 
61  /* Kernel direct-mapped space (OSF/1, NetBSD): */
62  if (!userMode && (vaddr >= ALPHA_K0SEG_BASE && vaddr <= ALPHA_K0SEG_END)) {
63  *return_paddr = vaddr & 0x000003ffffffffffULL;
64  return 2;
65  }
66 
67  /*
68  * UGLY hack for now:
69  *
70  * Before virtual memory has been set up, ptbr is most likely zero.
71  * In that case, simply map everything vaddr == paddr.
72  */
73  if (!userMode && base == 0) {
74  *return_paddr = vaddr & 0x000003ffffffffffULL;
75 if (vaddr == 0xfffffffd80000000ULL) {
76  fatal("Alpha kernel virtual memory seems to want to be used. Not yet implemented.\n");
77  exit(1);
78 }
79 #if 1
80  if ((vaddr & ~0x7fff) == 0x0000000010000000ULL)
81  *return_paddr = (vaddr & 0x7fff) + HWRPB_PADDR;
82 
83  if ((vaddr & ~0xffffff) == 0xfffffe0000000000ULL)
84  *return_paddr = 0x7efa000 + (vaddr & 0xffffff);
85 
86  /* At 0x20000000, NetBSD stores 8KB temp prom data */
87  if ((vaddr & ~0x1fff) == 0x0000000020000000ULL)
88  *return_paddr = (vaddr & 0x1fff) + PROM_ARGSPACE_PADDR;
89 #endif
90  return 2;
91  }
92 
93  // debug("base = 0x%016"PRIx64"\n", base);
94 if (vaddr == 0xfffffffd80000000ULL) fatal("AYONA3\n");
95 
96  uint64_t addr, pte1, pte2, pte3;
97  int i1, i2, i3;
98  unsigned char *pt_entry_ptr;
99  const int pageSizeShift = 13;
100  // const int pageSize = 1 << pageSizeShift;
101  const int bitsPerLevel = 10;
102  const int maskPerLevel = (1 << bitsPerLevel) - 1;
103 
104  i1 = (vaddr >> (pageSizeShift + 2 * bitsPerLevel)) & maskPerLevel;
105  i2 = (vaddr >> (pageSizeShift + 1 * bitsPerLevel)) & maskPerLevel;
106  i3 = (vaddr >> (pageSizeShift + 0 * bitsPerLevel)) & maskPerLevel;
107 
108  // debug("vaddr=%016llx i1=0x%x i2=0x%x i3=0x%x\n", (long long)vaddr, i1, i2, i3);
109 
110  addr = base + i1 * sizeof(uint64_t);
111 
112  pt_entry_ptr = memory_paddr_to_hostaddr(cpu->mem, addr, 0);
113  if (pt_entry_ptr == NULL)
114  goto not_found;
115 
116  pte1 = *(uint64_t *)(pt_entry_ptr);
117  pte1 = LE64_TO_HOST(pte1);
118 
119  // debug("pte1 = 0x%016"PRIx64"\n", pte1);
120  if (!(pte1 & ALPHA_PTE_VALID)) {
121  // TODO:
122  // IF level1_pte<KRE> EQ 0 THEN
123  // {initiate Access Violation fault}
124  // ELSE
125  // {initiate Translation Not Valid fault}
126 
127  // fatal("TODO: pte1 not valid.\n");
128  goto not_found;
129  }
130 
131  addr = ((pte1 >> 32) << ALPHA_PAGESHIFT) + (i2 * sizeof(uint64_t));
132 
133  pt_entry_ptr = memory_paddr_to_hostaddr(cpu->mem, addr, 0);
134  if (pt_entry_ptr == NULL)
135  goto not_found;
136 
137  pte2 = *(uint64_t *)(pt_entry_ptr);
138  pte2 = LE64_TO_HOST(pte2);
139 
140  // debug("pte2 = 0x%016"PRIx64"\n", pte2);
141  if (!(pte2 & ALPHA_PTE_VALID)) {
142  // TODO:
143  // IF level2_pte<KRE> EQ 0 THEN
144  // {initiate Access Violation fault}
145  // ELSE
146  // {initiate Translation Not Valid fault}
147 
148  fatal("TODO: pte2 not valid.\n");
149  goto not_found;
150  }
151 
152  addr = ((pte2 >> 32) << ALPHA_PAGESHIFT) + (i3 * sizeof(uint64_t));
153 
154  pt_entry_ptr = memory_paddr_to_hostaddr(cpu->mem, addr, 0);
155  if (pt_entry_ptr == NULL)
156  goto not_found;
157 
158  pte3 = *(uint64_t *)(pt_entry_ptr);
159  pte3 = LE64_TO_HOST(pte3);
160 
161  // debug("pte3 = 0x%016"PRIx64"\n", pte3);
162 
163  if (!(pte3 & ALPHA_PTE_VALID)) {
164  fatal("TODO: pte3 not valid.\n");
165  goto not_found;
166  }
167 
168  (*return_paddr) = ALPHA_PTE_TO_PFN(pte3) << pageSizeShift;
169 
170  // TODO.
171  return 2;
172 
173 not_found:
174  /* No match. */
175  fatal("[ alpha_translate_v2p: 0x%016" PRIx64" wasn't found ]\n", vaddr);
176 abort();
177  exit(1);
178  return 0;
179 }
180 
void fatal(const char *fmt,...)
Definition: main.cc:152
#define LE64_TO_HOST(x)
Definition: misc.h:188
int alpha_translate_v2p(struct cpu *cpu, uint64_t vaddr, uint64_t *return_paddr, int flags)
Definition: memory_alpha.cc:43
union cpu::@1 cd
struct memory * mem
Definition: cpu.h:362
#define PROM_ARGSPACE_PADDR
Definition: alpha_rpb.h:45
#define HWRPB_PADDR
Definition: alpha_rpb.h:46
#define ALPHA_PTE_VALID
Definition: alpha_cpu.h:217
struct alpha_pcb pcb
Definition: cpu_alpha.h:171
uint64_t apcb_ptbr
Definition: alpha_cpu.h:64
#define ALPHA_K0SEG_END
Definition: alpha_cpu.h:210
#define ALPHA_K0SEG_BASE
Definition: alpha_cpu.h:209
#define ALPHA_PAGESHIFT
Definition: cpu_alpha.h:140
#define ALPHA_PTE_TO_PFN(pte)
Definition: alpha_cpu.h:239
uint32_t addr
uint64_t ps
Definition: cpu_alpha.h:164
Definition: cpu.h:326
struct alpha_cpu alpha
Definition: cpu.h:440
#define ALPHA_PSL_USERMODE
Definition: alpha_cpu.h:103
unsigned char * memory_paddr_to_hostaddr(struct memory *mem, uint64_t paddr, int writeflag)
Definition: memory.cc:495

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13