Skip to content
This repository was archived by the owner on Feb 10, 2021. It is now read-only.

Commit 1c70119

Browse files
committed
Introduce dispatching address spaces
1 parent 8fd5760 commit 1c70119

File tree

1 file changed

+270
-7
lines changed

1 file changed

+270
-7
lines changed

software/src/e2/main.c

Lines changed: 270 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,293 @@
1+
#include <string.h>
12
#include <stdlib.h>
23
#include <stdio.h>
34

45
#include "processor.h"
56

67

8+
typedef struct RootAS RootAS;
9+
typedef struct Segment Segment;
10+
11+
struct Segment {
12+
AddressSpace as;
13+
uint64_t bottom, top;
14+
uint8_t *image;
15+
};
16+
17+
struct RootAS {
18+
AddressSpace as;
19+
Segment rom_seg;
20+
};
21+
22+
23+
uint64_t
24+
rom_fetch_dword(AddressSpace *as, uint64_t addr) {
25+
Segment *s = (Segment *)as;
26+
int i;
27+
28+
if(addr & 7) {
29+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
30+
return 0xCCCCCCCCCCCCCCCC;
31+
}
32+
33+
i = (int)(addr - s->bottom);
34+
return (
35+
(uint64_t)(s->image[i])
36+
| (((uint64_t)(s->image[i+1])) << 8)
37+
| (((uint64_t)(s->image[i+2])) << 16)
38+
| (((uint64_t)(s->image[i+3])) << 24)
39+
| (((uint64_t)(s->image[i+4])) << 32)
40+
| (((uint64_t)(s->image[i+5])) << 40)
41+
| (((uint64_t)(s->image[i+6])) << 48)
42+
| (((uint64_t)(s->image[i+7])) << 56)
43+
);
44+
}
45+
46+
uint32_t
47+
rom_fetch_word(AddressSpace *as, uint64_t addr) {
48+
Segment *s = (Segment *)as;
49+
int i;
50+
51+
if(addr & 3) {
52+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
53+
return 0xCCCCCCCC;
54+
}
55+
56+
i = (int)(addr - s->bottom);
57+
return (
58+
s->image[i]
59+
| (s->image[i+1] << 8)
60+
| (s->image[i+2] << 16)
61+
| (s->image[i+3] << 24)
62+
);
63+
}
64+
65+
uint16_t
66+
rom_fetch_hword(AddressSpace *as, uint64_t addr) {
67+
Segment *s = (Segment *)as;
68+
int i;
69+
70+
if(addr & 1) {
71+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
72+
return 0xCCCC;
73+
}
74+
75+
i = (int)(addr - s->bottom);
76+
return (
77+
s->image[i]
78+
| (s->image[i+1] << 8)
79+
);
80+
}
81+
82+
uint8_t
83+
rom_fetch_byte(AddressSpace *as, uint64_t addr) {
84+
Segment *s = (Segment *)as;
85+
int i;
86+
87+
i = (int)(addr - s->bottom);
88+
return s->image[i];
89+
}
90+
91+
void
92+
rom_store_dword(AddressSpace *as, uint64_t addr, uint64_t datum) {
93+
if(addr & 7) {
94+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
95+
}
96+
/* Do nothing, for we are ROM. */
97+
}
98+
99+
void
100+
rom_store_word(AddressSpace *as, uint64_t addr, uint32_t datum) {
101+
if(addr & 3) {
102+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
103+
}
104+
/* Do nothing, for we are ROM. */
105+
}
106+
107+
void
108+
rom_store_hword(AddressSpace *as, uint64_t addr, uint16_t datum) {
109+
if(addr & 1) {
110+
fprintf(stderr, "TODO: raise a misalignment trap to the processor\n");
111+
}
112+
/* Do nothing, for we are ROM. */
113+
}
114+
115+
void
116+
rom_store_byte(AddressSpace *as, uint64_t addr, uint8_t datum) {
117+
/* Do nothing, for we are ROM. */
118+
}
119+
120+
struct IAddressSpace rom_segment_interface = {
121+
.fetch_dword = rom_fetch_dword,
122+
.fetch_word = rom_fetch_word,
123+
.fetch_hword = rom_fetch_hword,
124+
.fetch_byte = rom_fetch_byte,
125+
.store_dword = rom_store_dword,
126+
.store_word = rom_store_word,
127+
.store_hword = rom_store_hword,
128+
.store_byte = rom_store_byte,
129+
};
130+
131+
132+
uint64_t
133+
root_fetch_dword(AddressSpace *as, uint64_t addr) {
134+
RootAS *root = (RootAS *)as;
135+
136+
fprintf(stderr, "$%016llX @D\n", addr);
137+
138+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top))
139+
return root->rom_seg.as.i->fetch_dword(&root->rom_seg.as, addr);
140+
141+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
142+
return 0xCCCCCCCCCCCCCCCC;
143+
}
144+
7145
uint32_t
8-
my_fetch_word(AddressSpace *as, uint64_t addr) {
9-
fprintf(stderr, "A=$%016llX\n", addr);
146+
root_fetch_word(AddressSpace *as, uint64_t addr) {
147+
RootAS *root = (RootAS *)as;
148+
149+
fprintf(stderr, "$%016llX @W\n", addr);
150+
151+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top))
152+
return root->rom_seg.as.i->fetch_word(&root->rom_seg.as, addr);
153+
154+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
10155
return 0xCCCCCCCC;
11156
}
12157

158+
uint16_t
159+
root_fetch_hword(AddressSpace *as, uint64_t addr) {
160+
RootAS *root = (RootAS *)as;
161+
162+
fprintf(stderr, "$%016llX @H\n", addr);
163+
164+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top))
165+
return root->rom_seg.as.i->fetch_dword(&root->rom_seg.as, addr);
166+
167+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
168+
return 0xCCCC;
169+
}
170+
171+
uint8_t
172+
root_fetch_byte(AddressSpace *as, uint64_t addr) {
173+
RootAS *root = (RootAS *)as;
174+
175+
fprintf(stderr, "$%016llX @B\n", addr);
176+
177+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top))
178+
return root->rom_seg.as.i->fetch_dword(&root->rom_seg.as, addr);
179+
180+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
181+
return 0xCC;
182+
}
183+
184+
void
185+
root_store_dword(AddressSpace *as, uint64_t addr, uint64_t datum) {
186+
RootAS *root = (RootAS *)as;
187+
188+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top)) {
189+
root->rom_seg.as.i->store_dword(&root->rom_seg.as, addr, datum);
190+
return;
191+
}
192+
193+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
194+
}
195+
196+
void
197+
root_store_word(AddressSpace *as, uint64_t addr, uint32_t datum) {
198+
RootAS *root = (RootAS *)as;
199+
200+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top)) {
201+
root->rom_seg.as.i->store_word(&root->rom_seg.as, addr, datum);
202+
return;
203+
}
204+
205+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
206+
}
207+
208+
void
209+
root_store_hword(AddressSpace *as, uint64_t addr, uint16_t datum) {
210+
RootAS *root = (RootAS *)as;
211+
212+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top)) {
213+
root->rom_seg.as.i->store_hword(&root->rom_seg.as, addr, datum);
214+
return;
215+
}
216+
217+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
218+
}
219+
220+
void
221+
root_store_byte(AddressSpace *as, uint64_t addr, uint8_t datum) {
222+
RootAS *root = (RootAS *)as;
223+
224+
if((root->rom_seg.bottom <= addr) && (addr < root->rom_seg.top)) {
225+
root->rom_seg.as.i->store_byte(&root->rom_seg.as, addr, datum);
226+
return;
227+
}
228+
229+
fprintf(stderr, "TODO: raise access error trap to CPU\n");
230+
}
231+
232+
struct IAddressSpace root_interface = {
233+
.fetch_dword = root_fetch_dword,
234+
.fetch_word = root_fetch_word,
235+
.fetch_hword = root_fetch_hword,
236+
.fetch_byte = root_fetch_byte,
237+
.store_dword = root_store_dword,
238+
.store_word = root_store_word,
239+
.store_hword = root_store_hword,
240+
.store_byte = root_store_byte,
241+
};
242+
243+
void
244+
dispose_root_address_space(RootAS *ras) {
245+
if(ras) {
246+
if(ras->rom_seg.image) free(ras->rom_seg.image);
247+
free(ras);
248+
}
249+
}
250+
251+
RootAS *
252+
new_root_address_space(void) {
253+
RootAS *ras = (RootAS *)(malloc(sizeof(RootAS)));
254+
if(ras) {
255+
memset(ras, 0, sizeof(RootAS));
256+
ras->as.i = &root_interface;
257+
258+
ras->rom_seg.as.i = &rom_segment_interface;
259+
ras->rom_seg.bottom = 0x0000000000000000;
260+
ras->rom_seg.top = 0x0000000000100000;
261+
ras->rom_seg.image = malloc(ras->rom_seg.top - ras->rom_seg.bottom);
262+
if(!ras->rom_seg.image) {
263+
fprintf(stderr, "cannot allocate 1MB ROM image\n");
264+
dispose_root_address_space(ras);
265+
return NULL;
266+
}
267+
}
268+
return ras;
269+
}
270+
271+
13272
int
14273
main(int argc, char *argv[]) {
15274
Processor *p;
16-
IAddressSpace my_ias = {
17-
.fetch_word = &my_fetch_word,
18-
};
275+
RootAS *root_as;
19276

20-
AddressSpace as = { &my_ias, };
277+
root_as = new_root_address_space();
278+
if(!root_as) {
279+
fprintf(stderr, "cannot create root address space.\n");
280+
exit(1);
281+
}
21282

22-
p = new_processor(&as);
283+
p = new_processor(&root_as->as);
23284
if(!p) {
24285
fprintf(stderr, "cannot create processor.\n");
25286
exit(1);
26287
}
27288

289+
p->pc = 0; // KCP53000B cold-starts at address 0.
290+
28291
while(1) {
29292
step(p);
30293
}

0 commit comments

Comments
 (0)