2 * Copyright 2008-2010, Ingo Weinhold <ingo_weinhold@gmx.de>.
3 * All rights reserved. Distributed under the terms of the MIT License.
7 #include "generic_vm_physical_page_ops.h"
10 #include <util/AutoLock.h>
14 generic_vm_memset_physical(phys_addr_t address
, int value
, phys_size_t length
)
16 ThreadCPUPinner
_(thread_get_current_thread());
19 phys_addr_t pageOffset
= address
% B_PAGE_SIZE
;
20 addr_t virtualAddress
;
22 status_t error
= vm_get_physical_page_current_cpu(address
- pageOffset
,
23 &virtualAddress
, &handle
);
27 size_t toSet
= min_c(length
, B_PAGE_SIZE
- pageOffset
);
28 memset((void*)(virtualAddress
+ pageOffset
), value
, toSet
);
30 vm_put_physical_page_current_cpu(virtualAddress
, handle
);
41 generic_vm_memcpy_from_physical(void* _to
, phys_addr_t from
, size_t length
,
44 uint8
* to
= (uint8
*)_to
;
45 phys_addr_t pageOffset
= from
% B_PAGE_SIZE
;
47 ThreadCPUPinner
_(thread_get_current_thread());
50 size_t toCopy
= min_c(length
, B_PAGE_SIZE
- pageOffset
);
52 addr_t virtualAddress
;
54 status_t error
= vm_get_physical_page_current_cpu(from
- pageOffset
,
55 &virtualAddress
, &handle
);
60 error
= user_memcpy(to
, (void*)(virtualAddress
+ pageOffset
),
63 memcpy(to
, (void*)(virtualAddress
+ pageOffset
), toCopy
);
65 vm_put_physical_page_current_cpu(virtualAddress
, handle
);
81 generic_vm_memcpy_to_physical(phys_addr_t to
, const void* _from
, size_t length
,
84 const uint8
* from
= (const uint8
*)_from
;
85 phys_addr_t pageOffset
= to
% B_PAGE_SIZE
;
87 ThreadCPUPinner
_(thread_get_current_thread());
90 size_t toCopy
= min_c(length
, B_PAGE_SIZE
- pageOffset
);
92 addr_t virtualAddress
;
94 status_t error
= vm_get_physical_page_current_cpu(to
- pageOffset
,
95 &virtualAddress
, &handle
);
100 error
= user_memcpy((void*)(virtualAddress
+ pageOffset
), from
,
103 memcpy((void*)(virtualAddress
+ pageOffset
), from
, toCopy
);
105 vm_put_physical_page_current_cpu(virtualAddress
, handle
);
120 /*! NOTE: If this function is used, vm_get_physical_page_current_cpu() must not
121 be blocking, since we need to call it twice and could thus deadlock.
124 generic_vm_memcpy_physical_page(phys_addr_t to
, phys_addr_t from
)
126 ThreadCPUPinner
_(thread_get_current_thread());
131 status_t error
= vm_get_physical_page_current_cpu(from
, &fromVirtual
,
134 panic("generic_vm_memcpy_physical_page(): Failed to map source page!");
138 // map destination page
141 error
= vm_get_physical_page_current_cpu(to
, &toVirtual
, &toHandle
);
143 // both pages are mapped -- copy
144 memcpy((void*)toVirtual
, (const void*)fromVirtual
, B_PAGE_SIZE
);
145 vm_put_physical_page_current_cpu(toVirtual
, toHandle
);
147 panic("generic_vm_memcpy_physical_page(): Failed to map destination "
151 vm_put_physical_page_current_cpu(fromVirtual
, fromHandle
);