suword64 and csuword64. Needed by ELF64 stuff...
This commit is contained in:
parent
ffb378a3fa
commit
bf3da2ae48
@ -47,6 +47,59 @@ __FBSDID("$FreeBSD$");
|
||||
#include <machine/elf.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#ifdef __mips_n64
|
||||
struct sysentvec elf64_freebsd_sysvec = {
|
||||
.sv_size = SYS_MAXSYSCALL,
|
||||
.sv_table = sysent,
|
||||
.sv_mask = 0,
|
||||
.sv_sigsize = 0,
|
||||
.sv_sigtbl = NULL,
|
||||
.sv_errsize = 0,
|
||||
.sv_errtbl = NULL,
|
||||
.sv_transtrap = NULL,
|
||||
.sv_fixup = __elfN(freebsd_fixup),
|
||||
.sv_sendsig = sendsig,
|
||||
.sv_sigcode = sigcode,
|
||||
.sv_szsigcode = &szsigcode,
|
||||
.sv_prepsyscall = NULL,
|
||||
.sv_name = "FreeBSD ELF64",
|
||||
.sv_coredump = __elfN(coredump),
|
||||
.sv_imgact_try = NULL,
|
||||
.sv_minsigstksz = MINSIGSTKSZ,
|
||||
.sv_pagesize = PAGE_SIZE,
|
||||
.sv_minuser = VM_MIN_ADDRESS,
|
||||
.sv_maxuser = VM_MAXUSER_ADDRESS,
|
||||
.sv_usrstack = USRSTACK,
|
||||
.sv_psstrings = PS_STRINGS,
|
||||
.sv_stackprot = VM_PROT_ALL,
|
||||
.sv_copyout_strings = exec_copyout_strings,
|
||||
.sv_setregs = exec_setregs,
|
||||
.sv_fixlimit = NULL,
|
||||
.sv_maxssiz = NULL,
|
||||
.sv_flags = SV_ABI_FREEBSD | SV_LP64
|
||||
};
|
||||
|
||||
static Elf64_Brandinfo freebsd_brand_info = {
|
||||
.brand = ELFOSABI_FREEBSD,
|
||||
.machine = EM_MIPS,
|
||||
.compat_3_brand = "FreeBSD",
|
||||
.emul_path = NULL,
|
||||
.interp_path = "/libexec/ld-elf.so.1",
|
||||
.sysvec = &elf64_freebsd_sysvec,
|
||||
.interp_newpath = NULL,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
SYSINIT(elf64, SI_SUB_EXEC, SI_ORDER_ANY,
|
||||
(sysinit_cfunc_t) elf64_insert_brand_entry,
|
||||
&freebsd_brand_info);
|
||||
|
||||
void
|
||||
elf64_dump_thread(struct thread *td __unused, void *dst __unused,
|
||||
size_t *off __unused)
|
||||
{
|
||||
}
|
||||
#else
|
||||
struct sysentvec elf32_freebsd_sysvec = {
|
||||
.sv_size = SYS_MAXSYSCALL,
|
||||
.sv_table = sysent,
|
||||
@ -98,6 +151,7 @@ elf32_dump_thread(struct thread *td __unused, void *dst __unused,
|
||||
size_t *off __unused)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Process one elf relocation with addend. */
|
||||
static int
|
||||
|
@ -314,6 +314,8 @@ pmap_bootstrap(void)
|
||||
}
|
||||
}
|
||||
|
||||
Maxmem = atop(phys_avail[i - 1]);
|
||||
|
||||
if (bootverbose) {
|
||||
printf("Physical memory chunk(s):\n");
|
||||
for (i = 0; phys_avail[i + 1] != 0; i += 2) {
|
||||
@ -325,6 +327,7 @@ pmap_bootstrap(void)
|
||||
(uintmax_t) phys_avail[i + 1] - 1,
|
||||
(uintmax_t) size, (uintmax_t) size / PAGE_SIZE);
|
||||
}
|
||||
printf("Maxmem is 0x%0lx\n", ptoa(Maxmem));
|
||||
}
|
||||
/*
|
||||
* Steal the message buffer from the beginning of memory.
|
||||
@ -398,21 +401,15 @@ pmap_bootstrap(void)
|
||||
for (i = 0, pte = pgtab; i < (nkpt * NPTEPG); i++, pte++)
|
||||
*pte = PTE_G;
|
||||
|
||||
printf("Va=0x%x Ve=%x\n", virtual_avail, virtual_end);
|
||||
/*
|
||||
* The segment table contains the KVA of the pages in the second
|
||||
* level page table.
|
||||
*/
|
||||
printf("init kernel_segmap va >> = %d nkpt:%d\n",
|
||||
(virtual_avail >> SEGSHIFT),
|
||||
nkpt);
|
||||
for (i = 0, j = (virtual_avail >> SEGSHIFT); i < nkpt; i++, j++)
|
||||
kernel_segmap[j] = (pd_entry_t)(pgtab + (i * NPTEPG));
|
||||
|
||||
for (i = 0; phys_avail[i + 2]; i += 2)
|
||||
continue;
|
||||
printf("avail_start:0x%x avail_end:0x%x\n",
|
||||
phys_avail[0], phys_avail[i + 1]);
|
||||
|
||||
/*
|
||||
* The kernel's pmap is statically allocated so we don't have to use
|
||||
@ -1793,8 +1790,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
|
||||
* Page Directory table entry not valid, we need a new PT page
|
||||
*/
|
||||
if (pte == NULL) {
|
||||
panic("pmap_enter: invalid page directory, pdir=%p, va=0x%x\n",
|
||||
(void *)pmap->pm_segtab, va);
|
||||
panic("pmap_enter: invalid page directory, pdir=%p, va=%p\n",
|
||||
(void *)pmap->pm_segtab, (void *)va);
|
||||
}
|
||||
pa = VM_PAGE_TO_PHYS(m);
|
||||
om = NULL;
|
||||
@ -1855,7 +1852,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
|
||||
mpte->wire_count--;
|
||||
KASSERT(mpte->wire_count > 0,
|
||||
("pmap_enter: missing reference to page table page,"
|
||||
" va: 0x%x", va));
|
||||
" va: %p", (void *)va));
|
||||
}
|
||||
} else
|
||||
pmap->pm_stats.resident_count++;
|
||||
@ -1917,7 +1914,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m,
|
||||
if (origpte & PTE_M) {
|
||||
KASSERT((origpte & PTE_RW),
|
||||
("pmap_enter: modified page not writable:"
|
||||
" va: 0x%x, pte: 0x%lx", va, origpte));
|
||||
" va: %p, pte: 0x%lx", (void *)va, origpte));
|
||||
if (page_is_managed(opa))
|
||||
vm_page_dirty(om);
|
||||
}
|
||||
@ -2254,7 +2251,7 @@ pmap_zero_page(vm_page_t m)
|
||||
#endif
|
||||
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
|
||||
|
||||
va = MIPS_PHYS_TO_UNCACHED(phys);
|
||||
va = MIPS_PHYS_TO_CACHED(phys);
|
||||
|
||||
bzero((caddr_t)va, PAGE_SIZE);
|
||||
mips_dcache_wbinv_range(va, PAGE_SIZE);
|
||||
@ -2310,7 +2307,7 @@ pmap_zero_page_area(vm_page_t m, int off, int size)
|
||||
} else
|
||||
#endif
|
||||
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
|
||||
va = MIPS_PHYS_TO_UNCACHED(phys);
|
||||
va = MIPS_PHYS_TO_CACHED(phys);
|
||||
bzero((char *)(caddr_t)va + off, size);
|
||||
mips_dcache_wbinv_range(va + off, size);
|
||||
} else {
|
||||
@ -2349,7 +2346,7 @@ pmap_zero_page_idle(vm_page_t m)
|
||||
} else
|
||||
#endif
|
||||
if (phys < MIPS_KSEG0_LARGEST_PHYS) {
|
||||
va = MIPS_PHYS_TO_UNCACHED(phys);
|
||||
va = MIPS_PHYS_TO_CACHED(phys);
|
||||
bzero((caddr_t)va, PAGE_SIZE);
|
||||
mips_dcache_wbinv_range(va, PAGE_SIZE);
|
||||
} else {
|
||||
@ -2835,11 +2832,12 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||
return (void *)MIPS_PHYS_TO_KSEG1(pa);
|
||||
else {
|
||||
offset = pa & PAGE_MASK;
|
||||
size = roundup(size, PAGE_SIZE);
|
||||
size = roundup(size + offset, PAGE_SIZE);
|
||||
|
||||
va = kmem_alloc_nofault(kernel_map, size);
|
||||
if (!va)
|
||||
panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
|
||||
pa = trunc_page(pa);
|
||||
for (tmpva = va; size > 0;) {
|
||||
pmap_kenter(tmpva, pa);
|
||||
size -= PAGE_SIZE;
|
||||
@ -2854,6 +2852,18 @@ pmap_mapdev(vm_offset_t pa, vm_size_t size)
|
||||
void
|
||||
pmap_unmapdev(vm_offset_t va, vm_size_t size)
|
||||
{
|
||||
vm_offset_t base, offset, tmpva;
|
||||
|
||||
/* If the address is within KSEG1 then there is nothing to do */
|
||||
if (va >= MIPS_KSEG1_START && va <= MIPS_KSEG1_END)
|
||||
return;
|
||||
|
||||
base = trunc_page(va);
|
||||
offset = va & PAGE_MASK;
|
||||
size = roundup(size + offset, PAGE_SIZE);
|
||||
for (tmpva = base; tmpva < base + size; tmpva += PAGE_SIZE)
|
||||
pmap_kremove(tmpva);
|
||||
kmem_free(kernel_map, base, size);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2990,7 +3000,7 @@ pmap_pid_dump(int pid)
|
||||
pde = &pmap->pm_segtab[i];
|
||||
if (pde && pmap_pde_v(pde)) {
|
||||
for (j = 0; j < 1024; j++) {
|
||||
unsigned va = base +
|
||||
vm_offset_t va = base +
|
||||
(j << PAGE_SHIFT);
|
||||
|
||||
pte = pmap_pte(pmap, va);
|
||||
@ -3000,8 +3010,9 @@ pmap_pid_dump(int pid)
|
||||
|
||||
pa = mips_tlbpfn_to_paddr(*pte);
|
||||
m = PHYS_TO_VM_PAGE(pa);
|
||||
printf("va: 0x%x, pt: 0x%x, h: %d, w: %d, f: 0x%x",
|
||||
va, pa,
|
||||
printf("va: %p, pt: %p, h: %d, w: %d, f: 0x%x",
|
||||
(void *)va,
|
||||
(void *)pa,
|
||||
m->hold_count,
|
||||
m->wire_count,
|
||||
m->flags);
|
||||
|
@ -460,8 +460,10 @@ ALEAF(fuibyte)
|
||||
sw zero, U_PCB_ONFAULT(v1)
|
||||
END(fubyte)
|
||||
|
||||
LEAF(suword)
|
||||
XLEAF(suword32)
|
||||
LEAF(suword32)
|
||||
#ifndef __mips_n64
|
||||
XLEAF(suword)
|
||||
#endif
|
||||
blt a0, zero, fswberr # make sure address is in user space
|
||||
li v0, FSWBERR
|
||||
GET_CPU_PCPU(v1)
|
||||
@ -471,44 +473,36 @@ XLEAF(suword32)
|
||||
sw zero, U_PCB_ONFAULT(v1)
|
||||
j ra
|
||||
move v0, zero
|
||||
END(suword)
|
||||
END(suword32)
|
||||
|
||||
/*
|
||||
* XXXMIPS: ATM it's the same as casuword32, but MIPS64 will require
|
||||
* own implementation
|
||||
* casuword(9)
|
||||
* <v0>u_long casuword(<a0>u_long *p, <a1>u_long oldval, <a2>u_long newval)
|
||||
*/
|
||||
ENTRY(casuword)
|
||||
#ifdef __mips_n64
|
||||
LEAF(suword64)
|
||||
XLEAF(suword)
|
||||
blt a0, zero, fswberr # make sure address is in user space
|
||||
li v0, FSWBERR
|
||||
GET_CPU_PCPU(v1)
|
||||
lw v1, PC_CURPCB(v1)
|
||||
sw v0, U_PCB_ONFAULT(v1)
|
||||
1:
|
||||
move t0, a2
|
||||
ll v0, 0(a0)
|
||||
bne a1, v0, 2f
|
||||
nop
|
||||
sc t0, 0(a0) # store word
|
||||
beqz t0, 1b
|
||||
nop
|
||||
j 3f
|
||||
nop
|
||||
2:
|
||||
li v0, -1
|
||||
3:
|
||||
sd a1, 0(a0) # store word
|
||||
sw zero, U_PCB_ONFAULT(v1)
|
||||
jr ra
|
||||
nop
|
||||
END(casuword)
|
||||
j ra
|
||||
move v0, zero
|
||||
END(suword64)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* casuword(9)
|
||||
* <v0>u_long casuword(<a0>u_long *p, <a1>u_long oldval, <a2>u_long newval)
|
||||
*/
|
||||
/*
|
||||
* casuword32(9)
|
||||
* <v0>uint32_t casuword(<a0>uint32_t *p, <a1>uint32_t oldval,
|
||||
* <a2>uint32_t newval)
|
||||
*/
|
||||
ENTRY(casuword32)
|
||||
LEAF(casuword32)
|
||||
#ifndef __mips_n64
|
||||
XLEAF(casuword)
|
||||
#endif
|
||||
blt a0, zero, fswberr # make sure address is in user space
|
||||
li v0, FSWBERR
|
||||
GET_CPU_PCPU(v1)
|
||||
@ -532,6 +526,33 @@ ENTRY(casuword32)
|
||||
nop
|
||||
END(casuword32)
|
||||
|
||||
#ifdef __mips_n64
|
||||
LEAF(casuword64)
|
||||
XLEAF(casuword)
|
||||
blt a0, zero, fswberr # make sure address is in user space
|
||||
li v0, FSWBERR
|
||||
GET_CPU_PCPU(v1)
|
||||
lw v1, PC_CURPCB(v1)
|
||||
sw v0, U_PCB_ONFAULT(v1)
|
||||
1:
|
||||
move t0, a2
|
||||
lld v0, 0(a0)
|
||||
bne a1, v0, 2f
|
||||
nop
|
||||
scd t0, 0(a0) # store double word
|
||||
beqz t0, 1b
|
||||
nop
|
||||
j 3f
|
||||
nop
|
||||
2:
|
||||
li v0, -1
|
||||
3:
|
||||
sw zero, U_PCB_ONFAULT(v1)
|
||||
jr ra
|
||||
nop
|
||||
END(casuword64)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* unused in FreeBSD */
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user