-
Notifications
You must be signed in to change notification settings - Fork 0
/
user_mapping.cpp
168 lines (123 loc) · 4.93 KB
/
user_mapping.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
user_mapping.cpp - Virtual memory mapping created in userspace
Copyright (C) 2011, 2012 Magnus Öberg
The license for this program is dual license:
AROS Public License, version 1.1 or later (APL1.1+)
AND
GNU Lesser General Public License, version 2.1 or later (LGPL2.1+)
Dual licensing means for this program that anyone that wants to use,
modify or distribute all or parts of this program can choose the best
suiting license of APL1.1+ or LGPL2.1+ and must follow the terms described
in that license. Choosing only one license disables the other license and
references to the disabled license in code and documentation may be removed.
This text paragraph should be removed at the same time. It is also permitted
to keep this exact dual licensing. The copyrights are not affected by
selecting only one license and remain in full.
-- APL conditions --
The contents of this file are subject to the AROS Public License Version 1.1
(the "License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.aros.org/license.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
the specific language governing rights and limitations under the License.
-- LGPL conditions --
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301 USA
--
*/
#include "emumiga.h"
namespace emumiga {
user_mapping::user_mapping(uint32_t length, uint8_t *real_memory):
virtual_mapping(length), real_memory(real_memory)
{
DEBUG(5) dprintf("user_mapping::user_mapping() called. this=%p, length=%d, real_memory=%p\n", this, length, real_memory);
this->type = TYPE_USER;
}
user_mapping::~user_mapping()
{
DEBUG(5) dprintf("user_mapping::~user_mapping() called. this=%p\n", this);
FreeVec(real_memory);
}
user_mapping *user_mapping::create(uint32_t length)
{
DEBUG(5) dprintf("user_mapping::create() called. length=%d\n", length);
uint8_t *mem = (uint8_t *)AllocVec(length, MEMF_PUBLIC|MEMF_CLEAR);
if(!mem)
return NULL;
user_mapping *mapping = new user_mapping(length, mem);
if(!mapping) {
FreeVec(mem);
return NULL;
}
emulator *emu = emulator::getEmulator();
uint32_t new_address = emu->v_space.add_mapping(mapping);
// TODO: Add to r_space too?
if(new_address == 0xFFFFFFFF) {
delete mapping;
return NULL;
}
return mapping;
}
int user_mapping::mem_access(uint32_t address, uint32_t len, uint8_t *buffer, int read)
{
DEBUG(7) dprintf("user_mapping::mem_access() called. this=%p, address=0x%x, len=%d, buffer=%p, read=%d\n", this, address, len, buffer, read);
uint32_t end, blockend, blocklen;
virtual_object *object;
int retc;
end = address + len;
if(end < address)
return EINVAL;
while(address < end) {
object = vobjlist.find_containing(address, &blocklen);
if(object != NULL) {
// Object, delegate access
blockend = address + blocklen;
if(blockend > end)
blockend = end;
blocklen = blockend-address;
retc = object->mem_access(address, blocklen, buffer, read);
if(retc)
return retc;
address += blocklen;
buffer += blocklen;
} else {
// No object, just binary data
if(read)
*buffer = real_memory[address - this->address];
else
real_memory[address - this->address] = *buffer;
address++;
buffer++;
}
}
return 0;
}
int user_mapping::print_symbol(uint32_t address, char *str, int str_length)
{
static symbol const map_symbols[] = {
{0, "user"}, {0, NULL}
};
DEBUG(7) dprintf("user_mapping::print_symbol() called. this=%p, address=0x%x, str=%p, str_length=%d\n", this, address, str, str_length);
return print_symbol_std(&map_symbols[0], address, str, str_length);
}
uint8_t *user_mapping::get_real_buffer(uint32_t address, uint32_t length)
{
// In range?
if(address < this->address || this->address+this->length < address+length)
return NULL;
if(vobjlist.contains_objects(address, length))
return NULL;
return real_memory + (address - this->address);
}
} // namespace emumiga