memory.rs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. mod ext {
  2. extern "C" {
  3. pub fn mmap_read8(addr: u32) -> i32;
  4. pub fn mmap_read16(addr: u32) -> i32;
  5. pub fn mmap_read32(addr: u32) -> i32;
  6. pub fn mmap_write8(addr: u32, value: i32);
  7. pub fn mmap_write16(addr: u32, value: i32);
  8. pub fn mmap_write32(addr: u32, value: i32);
  9. pub fn mmap_write64(addr: u32, v0: i32, v1: i32);
  10. pub fn mmap_write128(addr: u32, v0: i32, v1: i32, v2: i32, v3: i32);
  11. }
  12. }
  13. use cpu::cpu::reg128;
  14. use cpu::global_pointers::memory_size;
  15. use cpu::vga;
  16. use page::Page;
  17. use std::alloc;
  18. use std::ptr;
  19. #[allow(non_upper_case_globals)]
  20. pub static mut mem8: *mut u8 = ptr::null_mut();
  21. #[no_mangle]
  22. pub fn allocate_memory(size: u32) -> u32 {
  23. unsafe {
  24. dbg_assert!(mem8.is_null());
  25. };
  26. dbg_log!("Allocate memory size={}m", size >> 20);
  27. let layout = alloc::Layout::from_size_align(size as usize, 0x1000).unwrap();
  28. let ptr = unsafe { alloc::alloc(layout) as u32 };
  29. unsafe {
  30. mem8 = ptr as *mut u8;
  31. };
  32. ptr
  33. }
  34. #[no_mangle]
  35. pub unsafe fn zero_memory(size: u32) { ptr::write_bytes(mem8, 0, size as usize); }
  36. #[allow(non_upper_case_globals)]
  37. pub static mut vga_mem8: *mut u8 = ptr::null_mut();
  38. #[allow(non_upper_case_globals)]
  39. pub static mut vga_memory_size: u32 = 0;
  40. #[no_mangle]
  41. pub fn svga_allocate_memory(size: u32) -> u32 {
  42. unsafe {
  43. dbg_assert!(vga_mem8.is_null());
  44. };
  45. let layout = alloc::Layout::from_size_align(size as usize, 0x1000).unwrap();
  46. let ptr = unsafe { alloc::alloc(layout) as u32 };
  47. dbg_assert!(
  48. size & (1 << 12 << 6) == 0,
  49. "size not aligned to dirty_bitmap"
  50. );
  51. unsafe {
  52. vga_mem8 = ptr as *mut u8;
  53. vga_memory_size = size;
  54. vga::dirty_bitmap.resize((size >> 12 >> 6) as usize, 0);
  55. };
  56. ptr
  57. }
  58. #[no_mangle]
  59. pub fn in_mapped_range(addr: u32) -> bool {
  60. return addr >= 0xA0000 && addr < 0xC0000 || addr >= unsafe { *memory_size };
  61. }
  62. pub const VGA_LFB_ADDRESS: u32 = 0xE0000000;
  63. pub fn in_svga_lfb(addr: u32) -> bool {
  64. addr >= VGA_LFB_ADDRESS && addr < unsafe { VGA_LFB_ADDRESS + vga_memory_size }
  65. }
  66. #[no_mangle]
  67. pub fn read8(addr: u32) -> i32 {
  68. if in_mapped_range(addr) {
  69. if in_svga_lfb(addr) {
  70. unsafe { *vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as i32 }
  71. }
  72. else {
  73. unsafe { ext::mmap_read8(addr) }
  74. }
  75. }
  76. else {
  77. read8_no_mmap_check(addr)
  78. }
  79. }
  80. pub fn read8_no_mmap_check(addr: u32) -> i32 { unsafe { *mem8.offset(addr as isize) as i32 } }
  81. #[no_mangle]
  82. pub fn read16(addr: u32) -> i32 {
  83. if in_mapped_range(addr) {
  84. if in_svga_lfb(addr) {
  85. unsafe { *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *const u16) as i32 }
  86. }
  87. else {
  88. unsafe { ext::mmap_read16(addr) }
  89. }
  90. }
  91. else {
  92. read16_no_mmap_check(addr)
  93. }
  94. }
  95. pub fn read16_no_mmap_check(addr: u32) -> i32 {
  96. unsafe { *(mem8.offset(addr as isize) as *mut u16) as i32 }
  97. }
  98. #[no_mangle]
  99. pub fn read32s(addr: u32) -> i32 {
  100. if in_mapped_range(addr) {
  101. if in_svga_lfb(addr) {
  102. unsafe { *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *const i32) }
  103. }
  104. else {
  105. unsafe { ext::mmap_read32(addr) }
  106. }
  107. }
  108. else {
  109. read32_no_mmap_check(addr)
  110. }
  111. }
  112. pub fn read32_no_mmap_check(addr: u32) -> i32 {
  113. unsafe { *(mem8.offset(addr as isize) as *mut i32) }
  114. }
  115. pub unsafe fn read64s(addr: u32) -> i64 {
  116. if in_mapped_range(addr) {
  117. if in_svga_lfb(addr) {
  118. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *const i64)
  119. }
  120. else {
  121. ext::mmap_read32(addr) as i64 | (ext::mmap_read32(addr + 4) as i64) << 32
  122. }
  123. }
  124. else {
  125. *(mem8.offset(addr as isize) as *mut i64)
  126. }
  127. }
  128. pub unsafe fn read128(addr: u32) -> reg128 {
  129. if in_mapped_range(addr) {
  130. if in_svga_lfb(addr) {
  131. reg128 {
  132. i64: [
  133. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *const i64),
  134. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS + 8) as isize) as *const i64),
  135. ],
  136. }
  137. }
  138. else {
  139. reg128 {
  140. i32: [
  141. ext::mmap_read32(addr + 0),
  142. ext::mmap_read32(addr + 4),
  143. ext::mmap_read32(addr + 8),
  144. ext::mmap_read32(addr + 12),
  145. ],
  146. }
  147. }
  148. }
  149. else {
  150. reg128 {
  151. i64: [
  152. *(mem8.offset(addr as isize) as *mut i64),
  153. *(mem8.offset(addr as isize).offset(8) as *mut i64),
  154. ],
  155. }
  156. }
  157. }
  158. #[no_mangle]
  159. pub unsafe fn write8(addr: u32, value: i32) {
  160. if in_mapped_range(addr) {
  161. mmap_write8(addr, value & 0xFF);
  162. }
  163. else {
  164. ::jit::jit_dirty_page(::jit::get_jit_state(), Page::page_of(addr));
  165. write8_no_mmap_or_dirty_check(addr, value);
  166. };
  167. }
  168. pub unsafe fn write8_no_mmap_or_dirty_check(addr: u32, value: i32) {
  169. *mem8.offset(addr as isize) = value as u8
  170. }
  171. #[no_mangle]
  172. pub unsafe fn write16(addr: u32, value: i32) {
  173. if in_mapped_range(addr) {
  174. mmap_write16(addr, value & 0xFFFF);
  175. }
  176. else {
  177. ::jit::jit_dirty_cache_small(addr, addr + 2);
  178. write16_no_mmap_or_dirty_check(addr, value);
  179. };
  180. }
  181. pub unsafe fn write16_no_mmap_or_dirty_check(addr: u32, value: i32) {
  182. *(mem8.offset(addr as isize) as *mut u16) = value as u16
  183. }
  184. #[no_mangle]
  185. pub unsafe fn write32(addr: u32, value: i32) {
  186. if in_mapped_range(addr) {
  187. mmap_write32(addr, value);
  188. }
  189. else {
  190. ::jit::jit_dirty_cache_small(addr, addr + 4);
  191. write32_no_mmap_or_dirty_check(addr, value);
  192. };
  193. }
  194. pub unsafe fn write32_no_mmap_or_dirty_check(addr: u32, value: i32) {
  195. *(mem8.offset(addr as isize) as *mut i32) = value
  196. }
  197. pub unsafe fn write64_no_mmap_or_dirty_check(addr: u32, value: u64) {
  198. *(mem8.offset(addr as isize) as *mut u64) = value
  199. }
  200. pub unsafe fn write128_no_mmap_or_dirty_check(addr: u32, value: reg128) {
  201. *(mem8.offset(addr as isize) as *mut reg128) = value
  202. }
  203. pub unsafe fn memset_no_mmap_or_dirty_check(addr: u32, value: u8, count: u32) {
  204. ptr::write_bytes(mem8.offset(addr as isize), value, count as usize);
  205. }
  206. pub unsafe fn memcpy_no_mmap_or_dirty_check(src_addr: u32, dst_addr: u32, count: u32) {
  207. dbg_assert!(u32::max(src_addr, dst_addr) - u32::min(src_addr, dst_addr) >= count);
  208. ptr::copy_nonoverlapping(
  209. mem8.offset(src_addr as isize),
  210. mem8.offset(dst_addr as isize),
  211. count as usize,
  212. )
  213. }
  214. pub unsafe fn memcpy_into_svga_lfb(src_addr: u32, dst_addr: u32, count: u32) {
  215. dbg_assert!(src_addr < *memory_size);
  216. dbg_assert!(in_svga_lfb(dst_addr));
  217. ptr::copy_nonoverlapping(
  218. mem8.offset(src_addr as isize),
  219. vga_mem8.offset((dst_addr - VGA_LFB_ADDRESS) as isize),
  220. count as usize,
  221. )
  222. }
  223. pub unsafe fn mmap_write8(addr: u32, value: i32) {
  224. if in_svga_lfb(addr) {
  225. vga::mark_dirty(addr);
  226. *vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) = value as u8
  227. }
  228. else {
  229. ext::mmap_write8(addr, value)
  230. }
  231. }
  232. pub unsafe fn mmap_write16(addr: u32, value: i32) {
  233. if in_svga_lfb(addr) {
  234. vga::mark_dirty(addr);
  235. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *mut u16) = value as u16
  236. }
  237. else {
  238. ext::mmap_write16(addr, value)
  239. }
  240. }
  241. pub unsafe fn mmap_write32(addr: u32, value: i32) {
  242. if in_svga_lfb(addr) {
  243. vga::mark_dirty(addr);
  244. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *mut i32) = value
  245. }
  246. else {
  247. ext::mmap_write32(addr, value)
  248. }
  249. }
  250. pub unsafe fn mmap_write64(addr: u32, value: u64) {
  251. if in_svga_lfb(addr) {
  252. vga::mark_dirty(addr);
  253. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *mut u64) = value
  254. }
  255. else {
  256. ext::mmap_write64(addr, value as i32, (value >> 32) as i32)
  257. }
  258. }
  259. pub unsafe fn mmap_write128(addr: u32, v0: u64, v1: u64) {
  260. if in_svga_lfb(addr) {
  261. vga::mark_dirty(addr);
  262. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS) as isize) as *mut u64) = v0;
  263. *(vga_mem8.offset((addr - VGA_LFB_ADDRESS + 8) as isize) as *mut u64) = v1
  264. }
  265. else {
  266. ext::mmap_write128(
  267. addr,
  268. v0 as i32,
  269. (v0 >> 32) as i32,
  270. v1 as i32,
  271. (v1 >> 32) as i32,
  272. )
  273. }
  274. }