1 /* Base class for devices that are memory-mapped into the CPU's
2 address space.
3 Copyright 2001, 2003 Brian R. Gaeke.
4 Copyright 2002 Paul Twohey.
5
6 This file is part of VMIPS.
7
8 VMIPS is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2 of the License, or (at your
11 option) any later version.
12
13 VMIPS is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with VMIPS; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
22 /* Routines implementing memory mappings for devices which support
23 * memory-mapped I/O. */
24
25 #include "accesstypes.h"
26 #include "range.h"
27 #include "devicemap.h"
28 #include "cpu.h"
29 #include "vmips.h"
30 #include "mapper.h"
31 #include <cstdlib>
32
33 uint16
fetch_halfword(uint32 offset,DeviceExc * client)34 DeviceMap::fetch_halfword(uint32 offset, DeviceExc *client)
35 {
36 uint32 word_data = fetch_word(offset & ~0x03, DATALOAD, client);
37 word_data = machine->physmem->host_to_mips_word(word_data);
38 uint32 halfword_offset_in_word = ((offset & 0x02) >> 1);
39 if (!machine->cpu->is_bigendian()) {
40 halfword_offset_in_word = 1 - halfword_offset_in_word;
41 }
42 uint16 rv;
43 switch (halfword_offset_in_word) {
44 case 0: rv = (word_data >> 16) & 0xffff; break;
45 case 1: rv = word_data & 0xffff; break;
46 default: abort();
47 }
48 rv = machine->physmem->mips_to_host_halfword(rv);
49 return rv;
50 }
51
52 uint8
fetch_byte(uint32 offset,DeviceExc * client)53 DeviceMap::fetch_byte(uint32 offset, DeviceExc *client)
54 {
55 uint32 word_data = fetch_word(offset & ~0x03, DATALOAD, client);
56 word_data = machine->physmem->host_to_mips_word(word_data);
57 uint32 byte_offset_in_word = (offset & 0x03);
58 if (!machine->cpu->is_bigendian()) {
59 byte_offset_in_word = 3 - byte_offset_in_word;
60 }
61 uint8 rv;
62 switch (byte_offset_in_word) {
63 case 0: rv = (word_data >> 24) & 0xff; break;
64 case 1: rv = (word_data >> 16) & 0xff; break;
65 case 2: rv = (word_data >> 8) & 0xff; break;
66 case 3: rv = word_data & 0xff; break;
67 default: abort();
68 }
69 return rv;
70 }
71
72 void
store_halfword(uint32 offset,uint16 data,DeviceExc * client)73 DeviceMap::store_halfword(uint32 offset, uint16 data, DeviceExc *client)
74 {
75 const uint32 word_offset = offset & 0xfffffffc;
76 uint32 halfword_offset_in_word = ((offset & 0x02) >> 1);
77 uint32 word_data = 0;
78 if (!machine->cpu->is_bigendian()) {
79 halfword_offset_in_word = 1 - halfword_offset_in_word;
80 }
81 data = machine->physmem->host_to_mips_halfword(data);
82 switch (halfword_offset_in_word) {
83 case 0: word_data = (data << 16) & 0xffff0000; break;
84 case 1: word_data = data & 0x0000ffff; break;
85 default: abort();
86 }
87 word_data = machine->physmem->mips_to_host_word(word_data);
88 store_word(word_offset, word_data, client);
89 }
90
91 void
store_byte(uint32 offset,uint8 data,DeviceExc * client)92 DeviceMap::store_byte(uint32 offset, uint8 data, DeviceExc *client)
93 {
94 const uint32 word_offset = offset & 0xfffffffc;
95 uint32 byte_offset_in_word = (offset & 0x03);
96 uint32 word_data = 0;
97 if (!machine->cpu->is_bigendian()) {
98 byte_offset_in_word = 3 - byte_offset_in_word;
99 }
100 switch (byte_offset_in_word) {
101 case 0: word_data = (data << 24) & 0xff000000; break;
102 case 1: word_data = (data << 16) & 0x00ff0000; break;
103 case 2: word_data = (data << 8) & 0x0000ff00; break;
104 case 3: word_data = data & 0x000000ff; break;
105 default: abort();
106 }
107 word_data = machine->physmem->mips_to_host_word(word_data);
108 store_word(word_offset, word_data, client);
109 }
110
111 bool
canRead(uint32 offset)112 DeviceMap::canRead(uint32 offset)
113 {
114 return true;
115 }
116
117 bool
canWrite(uint32 offset)118 DeviceMap::canWrite(uint32 offset)
119 {
120 return true;
121 }
122