#include <mach_assert.h>
#include <string.h>
#include <mach/boolean.h>
#include <mach/i386/vm_types.h>
#include <mach/i386/vm_param.h>
#include <kern/kern_types.h>
#include <kern/misc_protos.h>
#include <vm/pmap.h>
#include <i386/param.h>
#include <i386/misc_protos.h>
#define value_64bit(value) ((value) & 0xFFFFFFFF00000000LL)
#define low32(x) ((unsigned int)((x) & 0x00000000FFFFFFFFLL))
void
bzero_phys(addr64_t p, uint32_t len)
{
bzero((char *)phystokv(low32(p)), len);
}
extern void flush_dcache(vm_offset_t addr, unsigned count, int phys);
kern_return_t copyp2p(vm_offset_t source, vm_offset_t dest, unsigned int size, unsigned int flush_action) {
switch(flush_action) {
case 1:
flush_dcache(source, size, 1);
break;
case 2:
flush_dcache(dest, size, 1);
break;
case 3:
flush_dcache(source, size, 1);
flush_dcache(dest, size, 1);
break;
}
bcopy_phys((addr64_t)source, (addr64_t)dest, (vm_size_t)size);
switch(flush_action) {
case 1:
flush_dcache(source, size, 1);
break;
case 2:
flush_dcache(dest, size, 1);
break;
case 3:
flush_dcache(source, size, 1);
flush_dcache(dest, size, 1);
break;
}
return KERN_SUCCESS;
}
#if 0
kern_return_t
copyp2v(char *from, char *to, unsigned int size) {
return(copyout(phystokv(from), to, size));
}
#endif
#if 0
kern_return_t
copyv2p(char *from, char *to, unsigned int size) {
return(copyin(from, phystokv(to), size));
}
#endif
void
bcopy_phys(addr64_t from, addr64_t to, vm_size_t bytes)
{
if ( value_64bit(from) || value_64bit(to)) panic("bcopy_phys: 64 bit value");
bcopy((char *)phystokv(low32(from)),
(char *)phystokv(low32(to)), bytes);
}
void
ovbcopy(
const char *from,
char *to,
vm_size_t bytes)
{
if (from + bytes <= to || to + bytes <= from || to == from)
bcopy_no_overwrite(from, to, bytes);
else if (from > to)
bcopy_no_overwrite(from, to, bytes);
else {
from += bytes - 1;
to += bytes - 1;
while (bytes-- > 0)
*to-- = *from--;
}
}
void
bcopy(
const char *from,
char *to,
vm_size_t bytes)
{
ovbcopy(from, to, bytes);
}
int bcmp(
const char *a,
const char *b,
vm_size_t len)
{
if (len == 0)
return 0;
do
if (*a++ != *b++)
break;
while (--len);
return len;
}
int
memcmp(s1, s2, n)
register char *s1, *s2;
register n;
{
while (--n >= 0)
if (*s1++ != *s2++)
return (*--s1 - *--s2);
return (0);
}
size_t
strlen(
register const char *string)
{
register const char *ret = string;
while (*string++ != '\0')
continue;
return string - 1 - ret;
}
#include <libkern/OSAtomic.h>
uint32_t
hw_atomic_add(
uint32_t *dest,
uint32_t delt)
{
uint32_t oldValue;
uint32_t newValue;
do {
oldValue = *dest;
newValue = (oldValue + delt);
} while (!OSCompareAndSwap((UInt32)oldValue,
(UInt32)newValue, (UInt32 *)dest));
return newValue;
}
uint32_t
hw_atomic_sub(
uint32_t *dest,
uint32_t delt)
{
uint32_t oldValue;
uint32_t newValue;
do {
oldValue = *dest;
newValue = (oldValue - delt);
} while (!OSCompareAndSwap((UInt32)oldValue,
(UInt32)newValue, (UInt32 *)dest));
return newValue;
}
uint32_t
hw_atomic_or(
uint32_t *dest,
uint32_t mask)
{
uint32_t oldValue;
uint32_t newValue;
do {
oldValue = *dest;
newValue = (oldValue | mask);
} while (!OSCompareAndSwap((UInt32)oldValue,
(UInt32)newValue, (UInt32 *)dest));
return newValue;
}
uint32_t
hw_atomic_and(
uint32_t *dest,
uint32_t mask)
{
uint32_t oldValue;
uint32_t newValue;
do {
oldValue = *dest;
newValue = (oldValue & mask);
} while (!OSCompareAndSwap((UInt32)oldValue,
(UInt32)newValue, (UInt32 *)dest));
return newValue;
}
uint32_t
hw_compare_and_store(
uint32_t oldval,
uint32_t newval,
uint32_t *dest)
{
return OSCompareAndSwap((UInt32)oldval, (UInt32)newval, (UInt32 *)dest);
}
#if MACH_ASSERT
void machine_callstack(
natural_t *buf,
vm_size_t callstack_max)
{
}
#endif
void fillPage(ppnum_t pa, unsigned int fill)
{
unsigned int *addr = (unsigned int *)phystokv(i386_ptob(pa));
int i;
int cnt = NBPG/sizeof(unsigned int);
for (i = 0; i < cnt ; i++ )
*addr++ = fill;
}
#define cppvPHYS (cppvPsnk|cppvPsrc)
kern_return_t copypv(addr64_t source, addr64_t sink, unsigned int size, int which)
{
char *src32, *dst32;
if (value_64bit(source) | value_64bit(sink)) panic("copypv: 64 bit value");
src32 = (char *)low32(source);
dst32 = (char *)low32(sink);
if (which & cppvFsrc) flush_dcache(source, size, 1);
if (which & cppvFsnk) flush_dcache(sink, size, 1);
switch (which & cppvPHYS) {
case cppvPHYS:
bcopy_phys(source, sink, (vm_size_t)size);
break;
case cppvPsnk:
if (which & cppvKmap)
bcopy(src32, (char *)phystokv(dst32), size);
else
copyin(src32, (char *)phystokv(dst32), size);
break;
case cppvPsrc:
if (which & cppvKmap)
bcopy((char *)phystokv(src32), dst32, size);
else
copyout((char *)phystokv(src32), dst32, size);
break;
default:
panic("copypv: both virtual");
}
if (which & cppvFsrc) flush_dcache(source, size, 1);
if (which & cppvFsnk) flush_dcache(sink, size, 1);
return KERN_SUCCESS;
}
void flush_dcache64(addr64_t addr, unsigned count, int phys)
{
}
void invalidate_icache64(addr64_t addr, unsigned cnt, int phys)
{
}
void switch_to_serial_console(void)
{
}
addr64_t vm_last_addr;
void
mapping_set_mod(ppnum_t pn)
{
pmap_set_modify(pn);
}
boolean_t
mutex_preblock(
mutex_t *mutex,
thread_t thread)
{
return (FALSE);
}